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:
Diffstat (limited to 'intern')
-rw-r--r--intern/CMakeLists.txt5
-rw-r--r--intern/SConscript5
-rw-r--r--intern/audaspace/CMakeLists.txt8
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.cpp8
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.h2
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.cpp12
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.h2
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.h2
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.cpp6
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.h2
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.cpp10
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.cpp4
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.h9
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp8
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h18
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp8
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterReader.h8
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.h7
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.cpp10
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.h2
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.h2
-rw-r--r--intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h (renamed from intern/audaspace/intern/AUD_ReferenceHandler.cpp)46
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.h5
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.h2
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.h2
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.h2
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.cpp2
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.h2
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.cpp10
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.h2
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.h2
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.cpp8
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.cpp10
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.h9
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.h4
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp380
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h14
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp170
-rw-r--r--intern/audaspace/SConscript2
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp8
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h6
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp2
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h6
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.cpp14
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.h7
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.h7
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp146
-rw-r--r--intern/audaspace/intern/AUD_C-API.h4
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.cpp8
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.h4
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.cpp52
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.h2
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.cpp8
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.h4
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.h2
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.cpp14
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.h6
-rw-r--r--intern/audaspace/intern/AUD_FileWriter.cpp10
-rw-r--r--intern/audaspace/intern/AUD_FileWriter.h9
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h10
-rw-r--r--intern/audaspace/intern/AUD_IFactory.h5
-rw-r--r--intern/audaspace/intern/AUD_ILockable.h21
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleFactory.h4
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleReader.h2
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.h4
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.h2
-rw-r--r--intern/audaspace/intern/AUD_Mixer.h3
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.h8
-rw-r--r--intern/audaspace/intern/AUD_MutexLock.h24
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp8
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h4
-rw-r--r--intern/audaspace/intern/AUD_Reference.h275
-rw-r--r--intern/audaspace/intern/AUD_ResampleReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_ResampleReader.h2
-rw-r--r--intern/audaspace/intern/AUD_Sequencer.cpp176
-rw-r--r--intern/audaspace/intern/AUD_Sequencer.h206
-rw-r--r--intern/audaspace/intern/AUD_SequencerEntry.cpp57
-rw-r--r--intern/audaspace/intern/AUD_SequencerEntry.h15
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.cpp126
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.h62
-rw-r--r--intern/audaspace/intern/AUD_SequencerHandle.cpp28
-rw-r--r--intern/audaspace/intern/AUD_SequencerHandle.h10
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.cpp69
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.h14
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.cpp4
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.h2
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.cpp4
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.h2
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp172
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.h22
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.cpp8
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.h9
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.cpp8
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.h6
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.cpp2
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.h6
-rw-r--r--intern/bsp/CMakeLists.txt3
-rw-r--r--intern/bsp/extern/CSG_BooleanOps.h8
-rw-r--r--intern/bsp/intern/BOP_CarveInterface.cpp19
-rw-r--r--intern/container/CMakeLists.txt5
-rw-r--r--intern/container/CTR_HashedPtr.h23
-rw-r--r--intern/container/CTR_List.h112
-rw-r--r--intern/container/CTR_Map.h84
-rw-r--r--intern/container/CTR_TaggedIndex.h15
-rw-r--r--intern/container/CTR_TaggedSetOps.h61
-rw-r--r--intern/container/CTR_UHeap.h307
-rw-r--r--intern/container/intern/CTR_List.cpp127
-rw-r--r--intern/cycles/CMakeLists.txt10
-rw-r--r--intern/cycles/SConscript2
-rw-r--r--intern/cycles/app/CMakeLists.txt4
-rw-r--r--intern/cycles/app/cycles_test.cpp2
-rw-r--r--intern/cycles/app/cycles_xml.cpp1
-rw-r--r--intern/cycles/blender/CCL_api.h6
-rw-r--r--intern/cycles/blender/CMakeLists.txt2
-rw-r--r--intern/cycles/blender/addon/__init__.py14
-rw-r--r--intern/cycles/blender/addon/engine.py8
-rw-r--r--intern/cycles/blender/addon/enums.py3
-rw-r--r--intern/cycles/blender/addon/osl.py127
-rw-r--r--intern/cycles/blender/addon/properties.py31
-rw-r--r--intern/cycles/blender/addon/ui.py23
-rw-r--r--intern/cycles/blender/blender_camera.cpp212
-rw-r--r--intern/cycles/blender/blender_mesh.cpp267
-rw-r--r--intern/cycles/blender/blender_object.cpp117
-rw-r--r--intern/cycles/blender/blender_particles.cpp213
-rw-r--r--intern/cycles/blender/blender_python.cpp228
-rw-r--r--intern/cycles/blender/blender_session.cpp104
-rw-r--r--intern/cycles/blender/blender_session.h2
-rw-r--r--intern/cycles/blender/blender_shader.cpp171
-rw-r--r--intern/cycles/blender/blender_sync.cpp49
-rw-r--r--intern/cycles/blender/blender_sync.h18
-rw-r--r--intern/cycles/blender/blender_util.h97
-rw-r--r--intern/cycles/bvh/CMakeLists.txt1
-rw-r--r--intern/cycles/bvh/bvh_node.h2
-rw-r--r--intern/cycles/cmake/external_libs.cmake27
-rw-r--r--intern/cycles/device/CMakeLists.txt1
-rw-r--r--intern/cycles/device/device.cpp26
-rw-r--r--intern/cycles/device/device.h8
-rw-r--r--intern/cycles/device/device_cpu.cpp40
-rw-r--r--intern/cycles/device/device_cuda.cpp26
-rw-r--r--intern/cycles/device/device_intern.h10
-rw-r--r--intern/cycles/device/device_multi.cpp10
-rw-r--r--intern/cycles/device/device_network.cpp8
-rw-r--r--intern/cycles/device/device_opencl.cpp17
-rw-r--r--intern/cycles/device/device_task.cpp2
-rw-r--r--intern/cycles/device/device_task.h1
-rw-r--r--intern/cycles/kernel/CMakeLists.txt37
-rw-r--r--intern/cycles/kernel/closure/bsdf.h (renamed from intern/cycles/kernel/svm/bsdf.h)0
-rw-r--r--intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h (renamed from intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h)50
-rw-r--r--intern/cycles/kernel/closure/bsdf_diffuse.h (renamed from intern/cycles/kernel/svm/bsdf_diffuse.h)63
-rw-r--r--intern/cycles/kernel/closure/bsdf_microfacet.h (renamed from intern/cycles/kernel/svm/bsdf_microfacet.h)170
-rw-r--r--intern/cycles/kernel/closure/bsdf_oren_nayar.h (renamed from intern/cycles/kernel/svm/bsdf_oren_nayar.h)37
-rw-r--r--intern/cycles/kernel/closure/bsdf_phong_ramp.h140
-rw-r--r--intern/cycles/kernel/closure/bsdf_reflection.h (renamed from intern/cycles/kernel/svm/bsdf_reflection.h)31
-rw-r--r--intern/cycles/kernel/closure/bsdf_refraction.h (renamed from intern/cycles/kernel/svm/bsdf_refraction.h)27
-rw-r--r--intern/cycles/kernel/closure/bsdf_transparent.h (renamed from intern/cycles/kernel/svm/bsdf_transparent.h)21
-rw-r--r--intern/cycles/kernel/closure/bsdf_ward.h (renamed from intern/cycles/kernel/svm/bsdf_ward.h)74
-rw-r--r--intern/cycles/kernel/closure/bsdf_westin.h (renamed from intern/cycles/kernel/svm/bsdf_westin.h)83
-rw-r--r--intern/cycles/kernel/closure/emissive.h (renamed from intern/cycles/kernel/svm/emissive.h)12
-rw-r--r--intern/cycles/kernel/closure/volume.h (renamed from intern/cycles/kernel/svm/volume.h)20
-rw-r--r--intern/cycles/kernel/kernel_attribute.h2
-rw-r--r--intern/cycles/kernel/kernel_bvh.h173
-rw-r--r--intern/cycles/kernel/kernel_camera.h10
-rw-r--r--intern/cycles/kernel/kernel_displace.h3
-rw-r--r--intern/cycles/kernel/kernel_emission.h7
-rw-r--r--intern/cycles/kernel/kernel_light.h9
-rw-r--r--intern/cycles/kernel/kernel_mbvh.h394
-rw-r--r--intern/cycles/kernel/kernel_montecarlo.h2
-rw-r--r--intern/cycles/kernel/kernel_object.h112
-rw-r--r--intern/cycles/kernel/kernel_path.h25
-rw-r--r--intern/cycles/kernel/kernel_projection.h2
-rw-r--r--intern/cycles/kernel/kernel_qbvh.h413
-rw-r--r--intern/cycles/kernel/kernel_shader.h97
-rw-r--r--intern/cycles/kernel/kernel_triangle.h15
-rw-r--r--intern/cycles/kernel/kernel_types.h57
-rw-r--r--intern/cycles/kernel/osl/CMakeLists.txt17
-rw-r--r--intern/cycles/kernel/osl/background.cpp44
-rw-r--r--intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp190
-rw-r--r--intern/cycles/kernel/osl/bsdf_diffuse.cpp195
-rw-r--r--intern/cycles/kernel/osl/bsdf_microfacet.cpp558
-rw-r--r--intern/cycles/kernel/osl/bsdf_oren_nayar.cpp142
-rw-r--r--intern/cycles/kernel/osl/bsdf_phong.cpp287
-rw-r--r--intern/cycles/kernel/osl/bsdf_phong_ramp.cpp (renamed from intern/cycles/kernel/osl/bssrdf.cpp)81
-rw-r--r--intern/cycles/kernel/osl/bsdf_reflection.cpp113
-rw-r--r--intern/cycles/kernel/osl/bsdf_refraction.cpp125
-rw-r--r--intern/cycles/kernel/osl/bsdf_transparent.cpp102
-rw-r--r--intern/cycles/kernel/osl/bsdf_ward.cpp230
-rw-r--r--intern/cycles/kernel/osl/bsdf_westin.cpp251
-rw-r--r--intern/cycles/kernel/osl/debug.cpp85
-rw-r--r--intern/cycles/kernel/osl/emissive.cpp38
-rw-r--r--intern/cycles/kernel/osl/nodes/node_object_info.osl33
-rw-r--r--intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl44
-rw-r--r--intern/cycles/kernel/osl/osl_closures.cpp153
-rw-r--r--intern/cycles/kernel/osl/osl_closures.h177
-rw-r--r--intern/cycles/kernel/osl/osl_globals.h6
-rw-r--r--intern/cycles/kernel/osl/osl_services.cpp551
-rw-r--r--intern/cycles/kernel/osl/osl_services.h22
-rw-r--r--intern/cycles/kernel/osl/osl_shader.cpp148
-rw-r--r--intern/cycles/kernel/osl/osl_shader.h3
-rw-r--r--intern/cycles/kernel/osl/vol_subsurface.cpp141
-rw-r--r--intern/cycles/kernel/shaders/CMakeLists.txt (renamed from intern/cycles/kernel/osl/nodes/CMakeLists.txt)22
-rw-r--r--intern/cycles/kernel/shaders/node_add_closure.osl (renamed from intern/cycles/kernel/osl/nodes/node_add_closure.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_ambient_occlusion.osl27
-rw-r--r--intern/cycles/kernel/shaders/node_attribute.osl (renamed from intern/cycles/kernel/osl/nodes/node_attribute.osl)4
-rw-r--r--intern/cycles/kernel/shaders/node_background.osl (renamed from intern/cycles/kernel/osl/nodes/node_background.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_brick_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_brick_texture.osl)21
-rw-r--r--intern/cycles/kernel/shaders/node_brightness.osl (renamed from intern/cycles/kernel/osl/nodes/node_brightness.osl)12
-rw-r--r--intern/cycles/kernel/shaders/node_bump.osl (renamed from intern/cycles/kernel/osl/nodes/node_bump.osl)21
-rw-r--r--intern/cycles/kernel/shaders/node_camera.osl (renamed from intern/cycles/kernel/osl/nodes/node_camera.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_checker_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_checker_texture.osl)12
-rw-r--r--intern/cycles/kernel/shaders/node_color.h (renamed from intern/cycles/kernel/osl/nodes/node_color.h)0
-rw-r--r--intern/cycles/kernel/shaders/node_combine_rgb.osl (renamed from intern/cycles/kernel/osl/nodes/node_combine_rgb.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_color.osl (renamed from intern/cycles/kernel/osl/nodes/node_convert_from_color.osl)4
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_float.osl (renamed from intern/cycles/kernel/osl/nodes/node_convert_from_float.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_int.osl36
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_normal.osl (renamed from intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl)4
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_point.osl (renamed from intern/cycles/kernel/osl/nodes/node_convert_from_point.osl)4
-rw-r--r--intern/cycles/kernel/shaders/node_convert_from_vector.osl (renamed from intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl)4
-rw-r--r--intern/cycles/kernel/shaders/node_diffuse_bsdf.osl (renamed from intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_emission.osl (renamed from intern/cycles/kernel/osl/nodes/node_emission.osl)6
-rw-r--r--intern/cycles/kernel/shaders/node_environment_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_environment_texture.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_fresnel.h (renamed from intern/cycles/kernel/osl/nodes/node_fresnel.h)0
-rw-r--r--intern/cycles/kernel/shaders/node_fresnel.osl (renamed from intern/cycles/kernel/osl/nodes/node_fresnel.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_gamma.osl (renamed from intern/cycles/kernel/osl/nodes/node_gamma.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_geometry.osl (renamed from intern/cycles/kernel/osl/nodes/node_geometry.osl)19
-rw-r--r--intern/cycles/kernel/shaders/node_glass_bsdf.osl (renamed from intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl)16
-rw-r--r--intern/cycles/kernel/shaders/node_glossy_bsdf.osl (renamed from intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl)12
-rw-r--r--intern/cycles/kernel/shaders/node_gradient_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_gradient_texture.osl)28
-rw-r--r--intern/cycles/kernel/shaders/node_holdout.osl (renamed from intern/cycles/kernel/osl/nodes/node_holdout.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_hsv.osl (renamed from intern/cycles/kernel/osl/nodes/node_hsv.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_image_texture.osl120
-rw-r--r--intern/cycles/kernel/shaders/node_invert.osl (renamed from intern/cycles/kernel/osl/nodes/node_invert.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_layer_weight.osl (renamed from intern/cycles/kernel/osl/nodes/node_blend_weight.osl)22
-rw-r--r--intern/cycles/kernel/shaders/node_light_falloff.osl46
-rw-r--r--intern/cycles/kernel/shaders/node_light_path.osl (renamed from intern/cycles/kernel/osl/nodes/node_light_path.osl)5
-rw-r--r--intern/cycles/kernel/shaders/node_magic_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_magic_texture.osl)50
-rw-r--r--intern/cycles/kernel/shaders/node_mapping.osl (renamed from intern/cycles/kernel/osl/nodes/node_mapping.osl)6
-rw-r--r--intern/cycles/kernel/shaders/node_math.osl (renamed from intern/cycles/kernel/osl/nodes/node_math.osl)46
-rw-r--r--intern/cycles/kernel/shaders/node_mix.osl (renamed from intern/cycles/kernel/osl/nodes/node_mix.osl)148
-rw-r--r--intern/cycles/kernel/shaders/node_mix_closure.osl (renamed from intern/cycles/kernel/osl/nodes/node_mix_closure.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_musgrave_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl)50
-rw-r--r--intern/cycles/kernel/shaders/node_noise_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_noise_texture.osl)6
-rw-r--r--intern/cycles/kernel/shaders/node_normal.osl (renamed from intern/cycles/kernel/osl/nodes/node_normal.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_normal_map.osl52
-rw-r--r--intern/cycles/kernel/shaders/node_object_info.osl32
-rw-r--r--intern/cycles/kernel/shaders/node_output_displacement.osl (renamed from intern/cycles/kernel/osl/nodes/node_output_displacement.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_output_surface.osl (renamed from intern/cycles/kernel/osl/nodes/node_output_surface.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_output_volume.osl (renamed from intern/cycles/kernel/osl/nodes/node_output_volume.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_particle_info.osl (renamed from intern/cycles/kernel/osl/nodes/node_particle_info.osl)17
-rw-r--r--intern/cycles/kernel/shaders/node_refraction_bsdf.osl39
-rw-r--r--intern/cycles/kernel/shaders/node_rgb_ramp.osl (renamed from intern/cycles/kernel/osl/nodes/node_image_texture.osl)25
-rw-r--r--intern/cycles/kernel/shaders/node_separate_rgb.osl (renamed from intern/cycles/kernel/osl/nodes/node_separate_rgb.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_set_normal.osl28
-rw-r--r--intern/cycles/kernel/shaders/node_sky_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_sky_texture.osl)70
-rw-r--r--intern/cycles/kernel/shaders/node_tangent.osl50
-rw-r--r--intern/cycles/kernel/shaders/node_texture.h (renamed from intern/cycles/kernel/osl/nodes/node_texture.h)14
-rw-r--r--intern/cycles/kernel/shaders/node_texture_coordinate.osl (renamed from intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl)37
-rw-r--r--intern/cycles/kernel/shaders/node_translucent_bsdf.osl (renamed from intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_transparent_bsdf.osl (renamed from intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_value.osl (renamed from intern/cycles/kernel/osl/nodes/node_value.osl)0
-rw-r--r--intern/cycles/kernel/shaders/node_vector_math.osl (renamed from intern/cycles/kernel/osl/nodes/node_vector_math.osl)16
-rw-r--r--intern/cycles/kernel/shaders/node_velvet_bsdf.osl (renamed from intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl)2
-rw-r--r--intern/cycles/kernel/shaders/node_voronoi_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl)6
-rw-r--r--intern/cycles/kernel/shaders/node_ward_bsdf.osl (renamed from intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl)27
-rw-r--r--intern/cycles/kernel/shaders/node_wave_texture.osl (renamed from intern/cycles/kernel/osl/nodes/node_wave_texture.osl)14
-rw-r--r--intern/cycles/kernel/shaders/oslutil.h (renamed from intern/cycles/kernel/osl/nodes/oslutil.h)0
-rw-r--r--intern/cycles/kernel/shaders/stdosl.h (renamed from intern/cycles/kernel/osl/nodes/stdosl.h)73
-rw-r--r--intern/cycles/kernel/svm/svm.h43
-rw-r--r--intern/cycles/kernel/svm/svm_bsdf.h113
-rw-r--r--intern/cycles/kernel/svm/svm_closure.h176
-rw-r--r--intern/cycles/kernel/svm/svm_convert.h28
-rw-r--r--intern/cycles/kernel/svm/svm_displace.h26
-rw-r--r--intern/cycles/kernel/svm/svm_fresnel.h2
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h32
-rw-r--r--intern/cycles/kernel/svm/svm_image.h8
-rw-r--r--intern/cycles/kernel/svm/svm_tex_coord.h95
-rw-r--r--intern/cycles/kernel/svm/svm_types.h41
-rw-r--r--intern/cycles/render/CMakeLists.txt1
-rw-r--r--intern/cycles/render/attribute.cpp4
-rw-r--r--intern/cycles/render/buffers.cpp2
-rw-r--r--intern/cycles/render/camera.cpp52
-rw-r--r--intern/cycles/render/camera.h6
-rw-r--r--intern/cycles/render/graph.cpp85
-rw-r--r--intern/cycles/render/graph.h8
-rw-r--r--intern/cycles/render/image.h3
-rw-r--r--intern/cycles/render/light.cpp15
-rw-r--r--intern/cycles/render/mesh.cpp20
-rw-r--r--intern/cycles/render/nodes.cpp429
-rw-r--r--intern/cycles/render/nodes.h59
-rw-r--r--intern/cycles/render/object.cpp38
-rw-r--r--intern/cycles/render/object.h2
-rw-r--r--intern/cycles/render/osl.cpp345
-rw-r--r--intern/cycles/render/osl.h25
-rw-r--r--intern/cycles/render/particles.cpp3
-rw-r--r--intern/cycles/render/scene.cpp98
-rw-r--r--intern/cycles/render/scene.h12
-rw-r--r--intern/cycles/render/session.cpp135
-rw-r--r--intern/cycles/render/session.h20
-rw-r--r--intern/cycles/render/shader.cpp33
-rw-r--r--intern/cycles/render/shader.h17
-rw-r--r--intern/cycles/render/svm.cpp79
-rw-r--r--intern/cycles/render/tile.cpp105
-rw-r--r--intern/cycles/render/tile.h41
-rw-r--r--intern/cycles/subd/CMakeLists.txt2
-rw-r--r--intern/cycles/subd/subd_build.cpp2
-rw-r--r--intern/cycles/util/CMakeLists.txt1
-rw-r--r--intern/cycles/util/util_attribute.cpp4
-rw-r--r--intern/cycles/util/util_boundbox.h71
-rw-r--r--intern/cycles/util/util_cuda.cpp15
-rw-r--r--intern/cycles/util/util_math.h23
-rw-r--r--intern/cycles/util/util_md5.h2
-rw-r--r--intern/cycles/util/util_opencl.cpp4
-rw-r--r--intern/cycles/util/util_path.cpp10
-rw-r--r--intern/cycles/util/util_path.h3
-rw-r--r--intern/cycles/util/util_progress.h15
-rw-r--r--intern/cycles/util/util_stats.h44
-rw-r--r--intern/cycles/util/util_task.cpp10
-rw-r--r--intern/cycles/util/util_task.h6
-rw-r--r--intern/cycles/util/util_thread.h1
-rw-r--r--intern/cycles/util/util_transform.cpp3
-rw-r--r--intern/cycles/util/util_transform.h45
-rw-r--r--intern/cycles/util/util_types.h2
-rw-r--r--intern/decimation/CMakeLists.txt63
-rw-r--r--intern/decimation/SConscript8
-rw-r--r--intern/decimation/extern/LOD_decimation.h117
-rw-r--r--intern/decimation/intern/LOD_DecimationClass.h118
-rw-r--r--intern/decimation/intern/LOD_EdgeCollapser.cpp410
-rw-r--r--intern/decimation/intern/LOD_EdgeCollapser.h117
-rw-r--r--intern/decimation/intern/LOD_ExternBufferEditor.h164
-rw-r--r--intern/decimation/intern/LOD_ExternNormalEditor.cpp264
-rw-r--r--intern/decimation/intern/LOD_ExternNormalEditor.h135
-rw-r--r--intern/decimation/intern/LOD_FaceNormalEditor.cpp291
-rw-r--r--intern/decimation/intern/LOD_FaceNormalEditor.h144
-rw-r--r--intern/decimation/intern/LOD_ManMesh2.cpp618
-rw-r--r--intern/decimation/intern/LOD_ManMesh2.h265
-rw-r--r--intern/decimation/intern/LOD_MeshBounds.h133
-rw-r--r--intern/decimation/intern/LOD_MeshException.h55
-rw-r--r--intern/decimation/intern/LOD_MeshPrimitives.cpp404
-rw-r--r--intern/decimation/intern/LOD_MeshPrimitives.h221
-rw-r--r--intern/decimation/intern/LOD_QSDecimator.cpp327
-rw-r--r--intern/decimation/intern/LOD_QSDecimator.h129
-rw-r--r--intern/decimation/intern/LOD_Quadric.h167
-rw-r--r--intern/decimation/intern/LOD_QuadricEditor.cpp279
-rw-r--r--intern/decimation/intern/LOD_QuadricEditor.h120
-rw-r--r--intern/decimation/intern/LOD_decimation.cpp155
-rw-r--r--intern/dualcon/CMakeLists.txt5
-rw-r--r--intern/elbeem/intern/ntl_geometryshader.h2
-rw-r--r--intern/elbeem/intern/utilities.cpp2
-rw-r--r--intern/ffmpeg/ffmpeg_compat.h2
-rw-r--r--intern/ghost/CMakeLists.txt1
-rw-r--r--intern/ghost/GHOST_IEventConsumer.h13
-rw-r--r--intern/ghost/GHOST_ISystem.h108
-rw-r--r--intern/ghost/GHOST_IWindow.h94
-rw-r--r--intern/ghost/GHOST_Rect.h66
-rw-r--r--intern/ghost/GHOST_Types.h4
-rw-r--r--intern/ghost/intern/GHOST_Debug.h4
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerCocoa.mm2
-rw-r--r--intern/ghost/intern/GHOST_DisplayManagerX11.cpp10
-rw-r--r--intern/ghost/intern/GHOST_EventDragnDrop.h14
-rw-r--r--intern/ghost/intern/GHOST_Rect.cpp2
-rw-r--r--intern/ghost/intern/GHOST_System.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemCocoa.mm66
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp2
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp16
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowCocoa.mm46
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp2
-rw-r--r--intern/ghost/test/multitest/EventToBuf.c18
-rw-r--r--intern/ghost/test/multitest/MultiTest.c5
-rw-r--r--intern/guardedalloc/cpp/mallocn.cpp3
-rw-r--r--intern/itasc/CMakeLists.txt400
-rw-r--r--intern/itasc/Scene.cpp2
-rw-r--r--intern/itasc/kdl/chain.hpp9
-rw-r--r--intern/itasc/kdl/tree.hpp19
-rw-r--r--intern/memutil/MEM_CacheLimiterC-Api.h4
-rw-r--r--intern/memutil/intern/MEM_CacheLimiterC-Api.cpp12
-rw-r--r--intern/opencolorio/CMakeLists.txt1
-rw-r--r--intern/opennl/CMakeLists.txt3
-rw-r--r--intern/opennl/SConscript5
-rw-r--r--intern/raskter/raskter.c2
-rw-r--r--intern/smoke/CMakeLists.txt4
-rw-r--r--intern/smoke/extern/smoke_API.h51
-rw-r--r--intern/smoke/intern/FLUID_3D.cpp515
-rw-r--r--intern/smoke/intern/FLUID_3D.h46
-rw-r--r--intern/smoke/intern/FLUID_3D_SOLVERS.cpp1
-rw-r--r--intern/smoke/intern/FLUID_3D_STATIC.cpp28
-rw-r--r--intern/smoke/intern/WTURBULENCE.cpp151
-rw-r--r--intern/smoke/intern/WTURBULENCE.h19
-rw-r--r--intern/smoke/intern/smoke_API.cpp373
-rw-r--r--intern/smoke/intern/spectrum.cpp426
-rw-r--r--intern/smoke/intern/spectrum.h6
-rw-r--r--intern/utfconv/utfconv.h2
436 files changed, 9295 insertions, 12891 deletions
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt
index 46571831efc..576c048288e 100644
--- a/intern/CMakeLists.txt
+++ b/intern/CMakeLists.txt
@@ -49,11 +49,6 @@ if(WITH_MOD_SMOKE)
add_subdirectory(smoke)
endif()
-if(WITH_MOD_DECIMATE)
- add_subdirectory(container)
- add_subdirectory(decimation)
-endif()
-
if(WITH_MOD_BOOLEAN)
add_subdirectory(bsp)
endif()
diff --git a/intern/SConscript b/intern/SConscript
index 3e40ef38705..59e412333b0 100644
--- a/intern/SConscript
+++ b/intern/SConscript
@@ -6,9 +6,7 @@ SConscript(['audaspace/SConscript',
'ghost/SConscript',
'guardedalloc/SConscript',
'moto/SConscript',
- 'container/SConscript',
'memutil/SConscript/',
- 'decimation/SConscript',
'iksolver/SConscript',
'itasc/SConscript',
'opencolorio/SConscript',
@@ -17,6 +15,9 @@ SConscript(['audaspace/SConscript',
'smoke/SConscript',
'raskter/SConscript'])
+# currently only contains headers
+# SConscript('container/SConscript')
+
if env ['WITH_BF_REMESH']:
SConscript(['dualcon/SConscript'])
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index dc4ca7903cd..1617e520ac7 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -28,6 +28,7 @@ set(INC
set(INC_SYS
${PTHREADS_INCLUDE_DIRS}
+ ${BOOST_INCLUDE_DIR}
)
set(SRC
@@ -94,6 +95,7 @@ set(SRC
intern/AUD_IDevice.h
intern/AUD_IFactory.h
intern/AUD_IHandle.h
+ intern/AUD_ILockable.h
intern/AUD_IReader.h
intern/AUD_IWriter.h
intern/AUD_JOSResampleFactory.cpp
@@ -108,16 +110,17 @@ set(SRC
intern/AUD_Mixer.h
intern/AUD_MixerFactory.cpp
intern/AUD_MixerFactory.h
+ intern/AUD_MutexLock.h
intern/AUD_NULLDevice.cpp
intern/AUD_NULLDevice.h
intern/AUD_PyInit.h
intern/AUD_ReadDevice.cpp
intern/AUD_ReadDevice.h
- intern/AUD_Reference.h
- intern/AUD_ReferenceHandler.cpp
intern/AUD_ResampleFactory.h
intern/AUD_ResampleReader.cpp
intern/AUD_ResampleReader.h
+ intern/AUD_Sequencer.cpp
+ intern/AUD_Sequencer.h
intern/AUD_SequencerEntry.cpp
intern/AUD_SequencerEntry.h
intern/AUD_SequencerFactory.cpp
@@ -148,6 +151,7 @@ set(SRC
FX/AUD_DelayReader.h
FX/AUD_DoubleFactory.h
FX/AUD_DoubleReader.h
+ FX/AUD_IDynamicIIRFilterCalculator.h
FX/AUD_DynamicIIRFilterFactory.h
FX/AUD_DynamicIIRFilterReader.h
FX/AUD_EffectFactory.h
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
index 1862b9ab79d..00d3a9f2395 100644
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
+++ b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
@@ -50,15 +50,15 @@ sample_t AUD_AccumulatorFactory::accumulatorFilter(AUD_CallbackIIRFilterReader*
return out;
}
-AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_Reference<AUD_IFactory> factory,
+AUD_AccumulatorFactory::AUD_AccumulatorFactory(boost::shared_ptr<AUD_IFactory> factory,
bool additive) :
AUD_EffectFactory(factory),
m_additive(additive)
{
}
-AUD_Reference<AUD_IReader> AUD_AccumulatorFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_AccumulatorFactory::createReader()
{
- return new AUD_CallbackIIRFilterReader(getReader(), 2, 2,
- m_additive ? accumulatorFilterAdditive : accumulatorFilter);
+ return boost::shared_ptr<AUD_IReader>(new AUD_CallbackIIRFilterReader(getReader(), 2, 2,
+ m_additive ? accumulatorFilterAdditive : accumulatorFilter));
}
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.h b/intern/audaspace/FX/AUD_AccumulatorFactory.h
index ac73c5aa6ae..9087218a5f9 100644
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.h
+++ b/intern/audaspace/FX/AUD_AccumulatorFactory.h
@@ -58,9 +58,9 @@ public:
* \param factory The input factory.
* \param additive Whether the accumulator is additive.
*/
- AUD_AccumulatorFactory(AUD_Reference<AUD_IFactory> factory, bool additive = false);
+ AUD_AccumulatorFactory(boost::shared_ptr<AUD_IFactory> factory, bool additive = false);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
static sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless);
static sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
index fa9e8746b2b..eadfc525f96 100644
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
@@ -33,7 +33,7 @@
#define CC m_specs.channels + m_channel
-AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in,
+AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(boost::shared_ptr<AUD_IReader> reader, int in,
int out) :
AUD_EffectReader(reader),
m_specs(reader->getSpecs()),
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
index 43970c96a42..fe0a8efce64 100644
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
@@ -90,7 +90,7 @@ protected:
* \param in The count of past input samples needed.
* \param out The count of past output samples needed.
*/
- AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in, int out);
+ AUD_BaseIIRFilterReader(boost::shared_ptr<AUD_IReader> reader, int in, int out);
void setLengths(int in, int out);
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
index 5edca302ece..97d85c8122f 100644
--- a/intern/audaspace/FX/AUD_ButterworthFactory.cpp
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
@@ -39,7 +39,7 @@
#define BWPB41 0.76536686473
#define BWPB42 1.84775906502
-AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory,
+AUD_ButterworthFactory::AUD_ButterworthFactory(boost::shared_ptr<AUD_IFactory> factory,
float frequency) :
AUD_DynamicIIRFilterFactory(factory),
m_frequency(frequency)
@@ -53,11 +53,11 @@ void AUD_ButterworthFactory::recalculateCoefficients(AUD_SampleRate rate,
float omega = 2 * tan(m_frequency * M_PI / rate);
float o2 = omega * omega;
float o4 = o2 * o2;
- float x1 = o2 + 2 * BWPB41 * omega + 4;
- float x2 = o2 + 2 * BWPB42 * omega + 4;
- float y1 = o2 - 2 * BWPB41 * omega + 4;
- float y2 = o2 - 2 * BWPB42 * omega + 4;
- float o228 = 2 * o2 - 8;
+ float x1 = o2 + 2.0f * (float)BWPB41 * omega + 4.0f;
+ float x2 = o2 + 2.0f * (float)BWPB42 * omega + 4.0f;
+ float y1 = o2 - 2.0f * (float)BWPB41 * omega + 4.0f;
+ float y2 = o2 - 2.0f * (float)BWPB42 * omega + 4.0f;
+ float o228 = 2.0f * o2 - 8.0f;
float norm = x1 * x2;
a.push_back(1);
a.push_back((x1 + x2) * o228 / norm);
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h
index dc8b4d92775..e796f76aa29 100644
--- a/intern/audaspace/FX/AUD_ButterworthFactory.h
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.h
@@ -53,7 +53,7 @@ public:
* \param factory The input factory.
* \param frequency The cutoff frequency.
*/
- AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory, float frequency);
+ AUD_ButterworthFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency);
virtual void recalculateCoefficients(AUD_SampleRate rate,
std::vector<float>& b,
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
index 1a5c99adfb9..b5157d47666 100644
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
@@ -29,7 +29,7 @@
#include "AUD_CallbackIIRFilterReader.h"
-AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_Reference<AUD_IReader> reader,
+AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(boost::shared_ptr<AUD_IReader> reader,
int in, int out,
doFilterIIR doFilter,
endFilterIIR endFilter,
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
index 7ced73844c9..d9df65f03eb 100644
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
@@ -74,7 +74,7 @@ public:
* \param endFilter The finishing callback.
* \param data Data pointer for the callbacks.
*/
- AUD_CallbackIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in, int out,
+ AUD_CallbackIIRFilterReader(boost::shared_ptr<AUD_IReader> reader, int in, int out,
doFilterIIR doFilter,
endFilterIIR endFilter = 0,
void* data = 0);
diff --git a/intern/audaspace/FX/AUD_DelayFactory.cpp b/intern/audaspace/FX/AUD_DelayFactory.cpp
index a4606597933..3e5a7cfd2f8 100644
--- a/intern/audaspace/FX/AUD_DelayFactory.cpp
+++ b/intern/audaspace/FX/AUD_DelayFactory.cpp
@@ -31,7 +31,7 @@
#include "AUD_DelayReader.h"
#include "AUD_Space.h"
-AUD_DelayFactory::AUD_DelayFactory(AUD_Reference<AUD_IFactory> factory, float delay) :
+AUD_DelayFactory::AUD_DelayFactory(boost::shared_ptr<AUD_IFactory> factory, float delay) :
AUD_EffectFactory(factory),
m_delay(delay)
{
@@ -42,7 +42,7 @@ float AUD_DelayFactory::getDelay() const
return m_delay;
}
-AUD_Reference<AUD_IReader> AUD_DelayFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_DelayFactory::createReader()
{
- return new AUD_DelayReader(getReader(), m_delay);
+ return boost::shared_ptr<AUD_IReader>(new AUD_DelayReader(getReader(), m_delay));
}
diff --git a/intern/audaspace/FX/AUD_DelayFactory.h b/intern/audaspace/FX/AUD_DelayFactory.h
index 26855a05d70..8cfb2be9ac8 100644
--- a/intern/audaspace/FX/AUD_DelayFactory.h
+++ b/intern/audaspace/FX/AUD_DelayFactory.h
@@ -53,14 +53,14 @@ public:
* \param factory The input factory.
* \param delay The desired delay in seconds.
*/
- AUD_DelayFactory(AUD_Reference<AUD_IFactory> factory, float delay = 0);
+ AUD_DelayFactory(boost::shared_ptr<AUD_IFactory> factory, float delay = 0);
/**
* Returns the delay in seconds.
*/
float getDelay() const;
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_DELAYFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp
index 903e043af01..050508f28da 100644
--- a/intern/audaspace/FX/AUD_DelayReader.cpp
+++ b/intern/audaspace/FX/AUD_DelayReader.cpp
@@ -31,10 +31,10 @@
#include <cstring>
-AUD_DelayReader::AUD_DelayReader(AUD_Reference<AUD_IReader> reader, float delay) :
+AUD_DelayReader::AUD_DelayReader(boost::shared_ptr<AUD_IReader> reader, float delay) :
AUD_EffectReader(reader),
- m_delay(int(delay * reader->getSpecs().rate)),
- m_remdelay(int(delay * reader->getSpecs().rate))
+ m_delay(int((AUD_SampleRate)delay * reader->getSpecs().rate)),
+ m_remdelay(int((AUD_SampleRate)delay * reader->getSpecs().rate))
{
}
diff --git a/intern/audaspace/FX/AUD_DelayReader.h b/intern/audaspace/FX/AUD_DelayReader.h
index 9d9b6619470..d4388e3befc 100644
--- a/intern/audaspace/FX/AUD_DelayReader.h
+++ b/intern/audaspace/FX/AUD_DelayReader.h
@@ -59,7 +59,7 @@ public:
* \param reader The reader to read from.
* \param delay The delay in seconds.
*/
- AUD_DelayReader(AUD_Reference<AUD_IReader> reader, float delay);
+ AUD_DelayReader(boost::shared_ptr<AUD_IReader> reader, float delay);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.cpp b/intern/audaspace/FX/AUD_DoubleFactory.cpp
index ab0111f8955..21bcbc2f649 100644
--- a/intern/audaspace/FX/AUD_DoubleFactory.cpp
+++ b/intern/audaspace/FX/AUD_DoubleFactory.cpp
@@ -30,15 +30,15 @@
#include "AUD_DoubleFactory.h"
#include "AUD_DoubleReader.h"
-AUD_DoubleFactory::AUD_DoubleFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2) :
+AUD_DoubleFactory::AUD_DoubleFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2) :
m_factory1(factory1), m_factory2(factory2)
{
}
-AUD_Reference<AUD_IReader> AUD_DoubleFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_DoubleFactory::createReader()
{
- AUD_Reference<AUD_IReader> reader1 = m_factory1->createReader();
- AUD_Reference<AUD_IReader> reader2 = m_factory2->createReader();
+ boost::shared_ptr<AUD_IReader> reader1 = m_factory1->createReader();
+ boost::shared_ptr<AUD_IReader> reader2 = m_factory2->createReader();
- return new AUD_DoubleReader(reader1, reader2);
+ return boost::shared_ptr<AUD_IReader>(new AUD_DoubleReader(reader1, reader2));
}
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.h b/intern/audaspace/FX/AUD_DoubleFactory.h
index e4d8fbfde8f..4a02cc7bcdb 100644
--- a/intern/audaspace/FX/AUD_DoubleFactory.h
+++ b/intern/audaspace/FX/AUD_DoubleFactory.h
@@ -41,12 +41,12 @@ private:
/**
* First played factory.
*/
- AUD_Reference<AUD_IFactory> m_factory1;
+ boost::shared_ptr<AUD_IFactory> m_factory1;
/**
* Second played factory.
*/
- AUD_Reference<AUD_IFactory> m_factory2;
+ boost::shared_ptr<AUD_IFactory> m_factory2;
// hide copy constructor and operator=
AUD_DoubleFactory(const AUD_DoubleFactory&);
@@ -58,9 +58,9 @@ public:
* \param factory1 The first input factory.
* \param factory2 The second input factory.
*/
- AUD_DoubleFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2);
+ AUD_DoubleFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_DOUBLEFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp
index 2b28bc7d679..ee18914e93f 100644
--- a/intern/audaspace/FX/AUD_DoubleReader.cpp
+++ b/intern/audaspace/FX/AUD_DoubleReader.cpp
@@ -31,8 +31,8 @@
#include <cstring>
-AUD_DoubleReader::AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1,
- AUD_Reference<AUD_IReader> reader2) :
+AUD_DoubleReader::AUD_DoubleReader(boost::shared_ptr<AUD_IReader> reader1,
+ boost::shared_ptr<AUD_IReader> reader2) :
m_reader1(reader1), m_reader2(reader2), m_finished1(false)
{
AUD_Specs s1, s2;
diff --git a/intern/audaspace/FX/AUD_DoubleReader.h b/intern/audaspace/FX/AUD_DoubleReader.h
index 1489f4eb184..5d2f65f1a90 100644
--- a/intern/audaspace/FX/AUD_DoubleReader.h
+++ b/intern/audaspace/FX/AUD_DoubleReader.h
@@ -32,7 +32,8 @@
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
-#include "AUD_Reference.h"
+
+#include <boost/shared_ptr.hpp>
/**
* This reader plays two readers sequently.
@@ -43,12 +44,12 @@ private:
/**
* The first reader.
*/
- AUD_Reference<AUD_IReader> m_reader1;
+ boost::shared_ptr<AUD_IReader> m_reader1;
/**
* The second reader.
*/
- AUD_Reference<AUD_IReader> m_reader2;
+ boost::shared_ptr<AUD_IReader> m_reader2;
/**
* Whether we've reached the end of the first reader.
@@ -65,7 +66,7 @@ public:
* \param reader1 The first reader to read from.
* \param reader2 The second reader to read from.
*/
- AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2);
+ AUD_DoubleReader(boost::shared_ptr<AUD_IReader> reader1, boost::shared_ptr<AUD_IReader> reader2);
/**
* Destroys the reader.
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
index 3d6beb6c554..e8ea4323b2e 100644
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
@@ -29,12 +29,14 @@
#include "AUD_DynamicIIRFilterFactory.h"
#include "AUD_DynamicIIRFilterReader.h"
-AUD_DynamicIIRFilterFactory::AUD_DynamicIIRFilterFactory(AUD_Reference<AUD_IFactory> factory) :
+
+AUD_DynamicIIRFilterFactory::AUD_DynamicIIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_Reference<AUD_IReader> AUD_DynamicIIRFilterFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_DynamicIIRFilterFactory::createReader()
{
- return new AUD_DynamicIIRFilterReader(getReader(), this);
+ return boost::shared_ptr<AUD_IReader>(new AUD_DynamicIIRFilterReader(getReader(), m_calculator));
}
+
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
index 5b297db2d56..f36a37f44b4 100644
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
@@ -30,6 +30,7 @@
#define __AUD_DYNAMICIIRFILTERFACTORY_H__
#include "AUD_EffectFactory.h"
+#include "AUD_IDynamicIIRFilterCalculator.h"
#include <vector>
/**
@@ -40,24 +41,17 @@
*/
class AUD_DynamicIIRFilterFactory : public AUD_EffectFactory
{
+protected:
+ boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> m_calculator;
+
public:
/**
* Creates a new Dynmic IIR filter factory.
* \param factory The input factory.
*/
- AUD_DynamicIIRFilterFactory(AUD_Reference<AUD_IFactory> factory);
-
- virtual AUD_Reference<AUD_IReader> createReader();
+ AUD_DynamicIIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory);
- /**
- * Recalculates the filter coefficients.
- * \param rate The sample rate of the audio data.
- * \param[out] b The input filter coefficients.
- * \param[out] a The output filter coefficients.
- */
- virtual void recalculateCoefficients(AUD_SampleRate rate,
- std::vector<float>& b,
- std::vector<float>& a)=0;
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif // __AUD_DYNAMICIIRFILTERFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
index 24332ebfc1a..52aaf2311c0 100644
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
@@ -28,10 +28,10 @@
#include "AUD_DynamicIIRFilterReader.h"
-AUD_DynamicIIRFilterReader::AUD_DynamicIIRFilterReader(AUD_Reference<AUD_IReader> reader,
- AUD_Reference<AUD_DynamicIIRFilterFactory> factory) :
+AUD_DynamicIIRFilterReader::AUD_DynamicIIRFilterReader(boost::shared_ptr<AUD_IReader> reader,
+ boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator) :
AUD_IIRFilterReader(reader, std::vector<float>(), std::vector<float>()),
- m_factory(factory)
+ m_calculator(calculator)
{
sampleRateChanged(reader->getSpecs().rate);
}
@@ -39,6 +39,6 @@ AUD_DynamicIIRFilterReader::AUD_DynamicIIRFilterReader(AUD_Reference<AUD_IReader
void AUD_DynamicIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
{
std::vector<float> a, b;
- m_factory->recalculateCoefficients(rate, b, a);
+ m_calculator->recalculateCoefficients(rate, b, a);
setCoefficients(b, a);
}
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
index 8a53c15b18f..0b68578bc53 100644
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
@@ -30,7 +30,7 @@
#define __AUD_DYNAMICIIRFILTERREADER_H__
#include "AUD_IIRFilterReader.h"
-#include "AUD_DynamicIIRFilterFactory.h"
+#include "AUD_IDynamicIIRFilterCalculator.h"
/**
* This class is for dynamic infinite impulse response filters with simple
@@ -42,11 +42,11 @@ private:
/**
* The factory for dynamically recalculating filter coefficients.
*/
- AUD_Reference<AUD_DynamicIIRFilterFactory> m_factory;
+ boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> m_calculator;
public:
- AUD_DynamicIIRFilterReader(AUD_Reference<AUD_IReader> reader,
- AUD_Reference<AUD_DynamicIIRFilterFactory> factory);
+ AUD_DynamicIIRFilterReader(boost::shared_ptr<AUD_IReader> reader,
+ boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator);
virtual void sampleRateChanged(AUD_SampleRate rate);
};
diff --git a/intern/audaspace/FX/AUD_EffectFactory.cpp b/intern/audaspace/FX/AUD_EffectFactory.cpp
index d35f8affec8..6018ed561ca 100644
--- a/intern/audaspace/FX/AUD_EffectFactory.cpp
+++ b/intern/audaspace/FX/AUD_EffectFactory.cpp
@@ -30,7 +30,7 @@
#include "AUD_EffectFactory.h"
#include "AUD_IReader.h"
-AUD_EffectFactory::AUD_EffectFactory(AUD_Reference<AUD_IFactory> factory)
+AUD_EffectFactory::AUD_EffectFactory(boost::shared_ptr<AUD_IFactory> factory)
{
m_factory = factory;
}
@@ -39,7 +39,7 @@ AUD_EffectFactory::~AUD_EffectFactory()
{
}
-AUD_Reference<AUD_IFactory> AUD_EffectFactory::getFactory() const
+boost::shared_ptr<AUD_IFactory> AUD_EffectFactory::getFactory() const
{
return m_factory;
}
diff --git a/intern/audaspace/FX/AUD_EffectFactory.h b/intern/audaspace/FX/AUD_EffectFactory.h
index c8d26a1daa7..d09872638be 100644
--- a/intern/audaspace/FX/AUD_EffectFactory.h
+++ b/intern/audaspace/FX/AUD_EffectFactory.h
@@ -47,7 +47,7 @@ protected:
/**
* If there is no reader it is created out of this factory.
*/
- AUD_Reference<AUD_IFactory> m_factory;
+ boost::shared_ptr<AUD_IFactory> m_factory;
/**
* Returns the reader created out of the factory.
@@ -55,7 +55,7 @@ protected:
* classes.
* \return The reader created out of the factory.
*/
- inline AUD_Reference<AUD_IReader> getReader() const
+ inline boost::shared_ptr<AUD_IReader> getReader() const
{
return m_factory->createReader();
}
@@ -65,7 +65,7 @@ public:
* Creates a new factory.
* \param factory The input factory.
*/
- AUD_EffectFactory(AUD_Reference<AUD_IFactory> factory);
+ AUD_EffectFactory(boost::shared_ptr<AUD_IFactory> factory);
/**
* Destroys the factory.
@@ -76,7 +76,7 @@ public:
* Returns the saved factory.
* \return The factory or NULL if there has no factory been saved.
*/
- AUD_Reference<AUD_IFactory> getFactory() const;
+ boost::shared_ptr<AUD_IFactory> getFactory() const;
};
#endif //__AUD_EFFECTFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_EffectReader.cpp b/intern/audaspace/FX/AUD_EffectReader.cpp
index 6c08549e744..b3e80bef03b 100644
--- a/intern/audaspace/FX/AUD_EffectReader.cpp
+++ b/intern/audaspace/FX/AUD_EffectReader.cpp
@@ -29,7 +29,7 @@
#include "AUD_EffectReader.h"
-AUD_EffectReader::AUD_EffectReader(AUD_Reference<AUD_IReader> reader)
+AUD_EffectReader::AUD_EffectReader(boost::shared_ptr<AUD_IReader> reader)
{
m_reader = reader;
}
diff --git a/intern/audaspace/FX/AUD_EffectReader.h b/intern/audaspace/FX/AUD_EffectReader.h
index b089ec9a318..2745c12afaf 100644
--- a/intern/audaspace/FX/AUD_EffectReader.h
+++ b/intern/audaspace/FX/AUD_EffectReader.h
@@ -31,7 +31,8 @@
#define __AUD_EFFECTREADER_H__
#include "AUD_IReader.h"
-#include "AUD_Reference.h"
+
+#include <boost/shared_ptr.hpp>
/**
* This reader is a base class for all effect readers that take one other reader
@@ -48,14 +49,14 @@ protected:
/**
* The reader to read from.
*/
- AUD_Reference<AUD_IReader> m_reader;
+ boost::shared_ptr<AUD_IReader> m_reader;
public:
/**
* Creates a new effect reader.
* \param reader The reader to read from.
*/
- AUD_EffectReader(AUD_Reference<AUD_IReader> reader);
+ AUD_EffectReader(boost::shared_ptr<AUD_IReader> reader);
/**
* Destroys the reader.
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
index c7176662659..1e5737557c1 100644
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
+++ b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
@@ -54,7 +54,7 @@ void AUD_EnvelopeFactory::endEnvelopeFilter(EnvelopeParameters* param)
delete param;
}
-AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, float attack,
+AUD_EnvelopeFactory::AUD_EnvelopeFactory(boost::shared_ptr<AUD_IFactory> factory, float attack,
float release, float threshold,
float arthreshold) :
AUD_EffectFactory(factory),
@@ -65,9 +65,9 @@ AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, fl
{
}
-AUD_Reference<AUD_IReader> AUD_EnvelopeFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_EnvelopeFactory::createReader()
{
- AUD_Reference<AUD_IReader> reader = getReader();
+ boost::shared_ptr<AUD_IReader> reader = getReader();
EnvelopeParameters* param = new EnvelopeParameters();
param->arthreshold = m_arthreshold;
@@ -75,8 +75,8 @@ AUD_Reference<AUD_IReader> AUD_EnvelopeFactory::createReader()
param->release = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release));
param->threshold = m_threshold;
- return new AUD_CallbackIIRFilterReader(reader, 1, 2,
+ return boost::shared_ptr<AUD_IReader>(new AUD_CallbackIIRFilterReader(reader, 1, 2,
(doFilterIIR) envelopeFilter,
(endFilterIIR) endEnvelopeFilter,
- param);
+ param));
}
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.h b/intern/audaspace/FX/AUD_EnvelopeFactory.h
index c8f3dc37cd2..656212c8cac 100644
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.h
+++ b/intern/audaspace/FX/AUD_EnvelopeFactory.h
@@ -73,10 +73,10 @@ public:
* \param threshold The threshold value.
* \param arthreshold The attack/release threshold value.
*/
- AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, float attack, float release,
+ AUD_EnvelopeFactory(boost::shared_ptr<AUD_IFactory> factory, float attack, float release,
float threshold, float arthreshold);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
static sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param);
static void endEnvelopeFilter(EnvelopeParameters* param);
diff --git a/intern/audaspace/FX/AUD_FaderFactory.cpp b/intern/audaspace/FX/AUD_FaderFactory.cpp
index ec119ef9388..b34d2134385 100644
--- a/intern/audaspace/FX/AUD_FaderFactory.cpp
+++ b/intern/audaspace/FX/AUD_FaderFactory.cpp
@@ -30,7 +30,7 @@
#include "AUD_FaderFactory.h"
#include "AUD_FaderReader.h"
-AUD_FaderFactory::AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory, AUD_FadeType type,
+AUD_FaderFactory::AUD_FaderFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_FadeType type,
float start, float length) :
AUD_EffectFactory(factory),
m_type(type),
@@ -54,7 +54,7 @@ float AUD_FaderFactory::getLength() const
return m_length;
}
-AUD_Reference<AUD_IReader> AUD_FaderFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_FaderFactory::createReader()
{
- return new AUD_FaderReader(getReader(), m_type, m_start, m_length);
+ return boost::shared_ptr<AUD_IReader>(new AUD_FaderReader(getReader(), m_type, m_start, m_length));
}
diff --git a/intern/audaspace/FX/AUD_FaderFactory.h b/intern/audaspace/FX/AUD_FaderFactory.h
index 82eaf2fae9f..f9ad88a751d 100644
--- a/intern/audaspace/FX/AUD_FaderFactory.h
+++ b/intern/audaspace/FX/AUD_FaderFactory.h
@@ -67,7 +67,7 @@ public:
* \param start The time where fading should start in seconds.
* \param length How long fading should last in seconds.
*/
- AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory,
+ AUD_FaderFactory(boost::shared_ptr<AUD_IFactory> factory,
AUD_FadeType type = AUD_FADE_IN,
float start = 0.0f, float length = 1.0f);
@@ -86,7 +86,7 @@ public:
*/
float getLength() const;
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_FADERFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp
index 4ece91ca899..e09072054cb 100644
--- a/intern/audaspace/FX/AUD_FaderReader.cpp
+++ b/intern/audaspace/FX/AUD_FaderReader.cpp
@@ -31,7 +31,7 @@
#include <cstring>
-AUD_FaderReader::AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType type,
+AUD_FaderReader::AUD_FaderReader(boost::shared_ptr<AUD_IReader> reader, AUD_FadeType type,
float start,float length) :
AUD_EffectReader(reader),
m_type(type),
diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h
index 788e8539228..a49960b30fb 100644
--- a/intern/audaspace/FX/AUD_FaderReader.h
+++ b/intern/audaspace/FX/AUD_FaderReader.h
@@ -67,7 +67,7 @@ public:
* \param start The time where fading should start in seconds.
* \param length How long fading should last in seconds.
*/
- AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType type,
+ AUD_FaderReader(boost::shared_ptr<AUD_IReader> reader, AUD_FadeType type,
float start,float length);
virtual void read(int& length, bool& eos, sample_t* buffer);
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
index 41070842596..ba5297d21ed 100644
--- a/intern/audaspace/FX/AUD_HighpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_HighpassFactory.cpp
@@ -36,7 +36,7 @@
#define M_PI 3.14159265358979323846
#endif
-AUD_HighpassFactory::AUD_HighpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency,
+AUD_HighpassFactory::AUD_HighpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency,
float Q) :
AUD_DynamicIIRFilterFactory(factory),
m_frequency(frequency),
@@ -48,8 +48,8 @@ void AUD_HighpassFactory::recalculateCoefficients(AUD_SampleRate rate,
std::vector<float> &b,
std::vector<float> &a)
{
- float w0 = 2 * M_PI * m_frequency / rate;
- float alpha = sin(w0) / (2 * m_Q);
+ float w0 = 2.0 * M_PI * (AUD_SampleRate)m_frequency / rate;
+ float alpha = (float)(sin(w0) / (2.0 * (double)m_Q));
float norm = 1 + alpha;
float c = cos(w0);
a.push_back(1);
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h
index 66aa8091234..ed7e9db44a4 100644
--- a/intern/audaspace/FX/AUD_HighpassFactory.h
+++ b/intern/audaspace/FX/AUD_HighpassFactory.h
@@ -59,7 +59,7 @@ public:
* \param frequency The cutoff frequency.
* \param Q The Q factor.
*/
- AUD_HighpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency, float Q = 1.0f);
+ AUD_HighpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency, float Q = 1.0f);
virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
};
diff --git a/intern/audaspace/intern/AUD_ReferenceHandler.cpp b/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
index 6aa4f87ea96..77d83360255 100644
--- a/intern/audaspace/intern/AUD_ReferenceHandler.cpp
+++ b/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
@@ -22,31 +22,31 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file audaspace/intern/AUD_ReferenceHandler.cpp
- * \ingroup audaspaceintern
+/** \file audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
+ * \ingroup audfx
*/
-#include "AUD_Reference.h"
+#ifndef AUD_IDYNAMICIIRFILTERCALCULATOR_H
+#define AUD_IDYNAMICIIRFILTERCALCULATOR_H
-std::map<void*, unsigned int> AUD_ReferenceHandler::m_references;
-pthread_mutex_t AUD_ReferenceHandler::m_mutex;
-bool AUD_ReferenceHandler::m_mutex_initialised = false;
+#include <vector>
-pthread_mutex_t *AUD_ReferenceHandler::getMutex()
+/**
+ * This interface calculates dynamic filter coefficients which depend on the
+ * sampling rate for AUD_DynamicIIRFilterReaders.
+ */
+class AUD_IDynamicIIRFilterCalculator
{
- if(!m_mutex_initialised)
- {
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-
- pthread_mutex_init(&m_mutex, &attr);
-
- pthread_mutexattr_destroy(&attr);
-
- m_mutex_initialised = true;
- }
-
- return &m_mutex;
-}
-
+public:
+ /**
+ * Recalculates the filter coefficients.
+ * \param rate The sample rate of the audio data.
+ * \param[out] b The input filter coefficients.
+ * \param[out] a The output filter coefficients.
+ */
+ virtual void recalculateCoefficients(AUD_SampleRate rate,
+ std::vector<float>& b,
+ std::vector<float>& a)=0;
+};
+
+#endif // AUD_IDYNAMICIIRFILTERCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
index 807b0ef4899..c4f94a2dc27 100644
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
+++ b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
@@ -30,14 +30,14 @@
#include "AUD_IIRFilterFactory.h"
#include "AUD_IIRFilterReader.h"
-AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_Reference<AUD_IFactory> factory,
+AUD_IIRFilterFactory::AUD_IIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory,
std::vector<float> b,
std::vector<float> a) :
AUD_EffectFactory(factory), m_a(a), m_b(b)
{
}
-AUD_Reference<AUD_IReader> AUD_IIRFilterFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_IIRFilterFactory::createReader()
{
- return new AUD_IIRFilterReader(getReader(), m_b, m_a);
+ return boost::shared_ptr<AUD_IReader>(new AUD_IIRFilterReader(getReader(), m_b, m_a));
}
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.h b/intern/audaspace/FX/AUD_IIRFilterFactory.h
index 43256a166aa..0b55c120384 100644
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.h
+++ b/intern/audaspace/FX/AUD_IIRFilterFactory.h
@@ -31,6 +31,7 @@
#define __AUD_IIRFILTERFACTORY_H__
#include "AUD_EffectFactory.h"
+#include "AUD_IDynamicIIRFilterCalculator.h"
#include <vector>
@@ -61,10 +62,10 @@ public:
* \param b The input filter coefficients.
* \param a The output filter coefficients.
*/
- AUD_IIRFilterFactory(AUD_Reference<AUD_IFactory> factory, std::vector<float> b,
+ AUD_IIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory, std::vector<float> b,
std::vector<float> a);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_IIRFILTERFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.cpp b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
index 8f78c110d1f..6716e6b9ddc 100644
--- a/intern/audaspace/FX/AUD_IIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
@@ -29,7 +29,7 @@
#include "AUD_IIRFilterReader.h"
-AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_Reference<AUD_IReader> reader,
+AUD_IIRFilterReader::AUD_IIRFilterReader(boost::shared_ptr<AUD_IReader> reader,
const std::vector<float>& b,
const std::vector<float>& a) :
AUD_BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b)
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.h
index d9be52f2919..d663805b50f 100644
--- a/intern/audaspace/FX/AUD_IIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_IIRFilterReader.h
@@ -61,7 +61,7 @@ public:
* \param b The input filter coefficients.
* \param a The output filter coefficients.
*/
- AUD_IIRFilterReader(AUD_Reference<AUD_IReader> reader, const std::vector<float>& b,
+ AUD_IIRFilterReader(boost::shared_ptr<AUD_IReader> reader, const std::vector<float>& b,
const std::vector<float>& a);
virtual sample_t filter();
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.cpp b/intern/audaspace/FX/AUD_LimiterFactory.cpp
index e58657d8d70..679ed3a6b8b 100644
--- a/intern/audaspace/FX/AUD_LimiterFactory.cpp
+++ b/intern/audaspace/FX/AUD_LimiterFactory.cpp
@@ -31,7 +31,7 @@
#include "AUD_LimiterReader.h"
#include "AUD_Space.h"
-AUD_LimiterFactory::AUD_LimiterFactory(AUD_Reference<AUD_IFactory> factory,
+AUD_LimiterFactory::AUD_LimiterFactory(boost::shared_ptr<AUD_IFactory> factory,
float start, float end) :
AUD_EffectFactory(factory),
m_start(start),
@@ -49,7 +49,7 @@ float AUD_LimiterFactory::getEnd() const
return m_end;
}
-AUD_Reference<AUD_IReader> AUD_LimiterFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_LimiterFactory::createReader()
{
- return new AUD_LimiterReader(getReader(), m_start, m_end);
+ return boost::shared_ptr<AUD_IReader>(new AUD_LimiterReader(getReader(), m_start, m_end));
}
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.h b/intern/audaspace/FX/AUD_LimiterFactory.h
index ddc8183ce7a..0376952b4bd 100644
--- a/intern/audaspace/FX/AUD_LimiterFactory.h
+++ b/intern/audaspace/FX/AUD_LimiterFactory.h
@@ -60,7 +60,7 @@ public:
* \param end The desired end time, a negative value signals that it should
* play to the end.
*/
- AUD_LimiterFactory(AUD_Reference<AUD_IFactory> factory,
+ AUD_LimiterFactory(boost::shared_ptr<AUD_IFactory> factory,
float start = 0, float end = -1);
/**
@@ -73,7 +73,7 @@ public:
*/
float getEnd() const;
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_LIMITERFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp
index 0abf496c7f9..9c1d4443b06 100644
--- a/intern/audaspace/FX/AUD_LimiterReader.cpp
+++ b/intern/audaspace/FX/AUD_LimiterReader.cpp
@@ -30,7 +30,7 @@
#include "AUD_LimiterReader.h"
#include "AUD_Buffer.h"
-AUD_LimiterReader::AUD_LimiterReader(AUD_Reference<AUD_IReader> reader,
+AUD_LimiterReader::AUD_LimiterReader(boost::shared_ptr<AUD_IReader> reader,
float start, float end) :
AUD_EffectReader(reader),
m_start(start),
diff --git a/intern/audaspace/FX/AUD_LimiterReader.h b/intern/audaspace/FX/AUD_LimiterReader.h
index 34c4ea7c20e..607eb9e5bec 100644
--- a/intern/audaspace/FX/AUD_LimiterReader.h
+++ b/intern/audaspace/FX/AUD_LimiterReader.h
@@ -60,7 +60,7 @@ public:
* \param end The desired end time (sample exklusive), a negative value
* signals that it should play to the end.
*/
- AUD_LimiterReader(AUD_Reference<AUD_IReader> reader, float start = 0, float end = -1);
+ AUD_LimiterReader(boost::shared_ptr<AUD_IReader> reader, float start = 0, float end = -1);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/FX/AUD_LoopFactory.cpp b/intern/audaspace/FX/AUD_LoopFactory.cpp
index 32c9e6bad7f..a9e83e349a0 100644
--- a/intern/audaspace/FX/AUD_LoopFactory.cpp
+++ b/intern/audaspace/FX/AUD_LoopFactory.cpp
@@ -30,7 +30,7 @@
#include "AUD_LoopFactory.h"
#include "AUD_LoopReader.h"
-AUD_LoopFactory::AUD_LoopFactory(AUD_Reference<AUD_IFactory> factory, int loop) :
+AUD_LoopFactory::AUD_LoopFactory(boost::shared_ptr<AUD_IFactory> factory, int loop) :
AUD_EffectFactory(factory),
m_loop(loop)
{
@@ -41,7 +41,7 @@ int AUD_LoopFactory::getLoop() const
return m_loop;
}
-AUD_Reference<AUD_IReader> AUD_LoopFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_LoopFactory::createReader()
{
- return new AUD_LoopReader(getReader(), m_loop);
+ return boost::shared_ptr<AUD_IReader>(new AUD_LoopReader(getReader(), m_loop));
}
diff --git a/intern/audaspace/FX/AUD_LoopFactory.h b/intern/audaspace/FX/AUD_LoopFactory.h
index 754b780bd99..570536bee9a 100644
--- a/intern/audaspace/FX/AUD_LoopFactory.h
+++ b/intern/audaspace/FX/AUD_LoopFactory.h
@@ -55,14 +55,14 @@ public:
* \param loop The desired loop count, negative values result in endless
* looping.
*/
- AUD_LoopFactory(AUD_Reference<AUD_IFactory> factory, int loop = -1);
+ AUD_LoopFactory(boost::shared_ptr<AUD_IFactory> factory, int loop = -1);
/**
* Returns the loop count.
*/
int getLoop() const;
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_LOOPFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp
index 863f66f9f46..6fbcaa5af37 100644
--- a/intern/audaspace/FX/AUD_LoopReader.cpp
+++ b/intern/audaspace/FX/AUD_LoopReader.cpp
@@ -32,7 +32,7 @@
#include <cstring>
-AUD_LoopReader::AUD_LoopReader(AUD_Reference<AUD_IReader> reader, int loop) :
+AUD_LoopReader::AUD_LoopReader(boost::shared_ptr<AUD_IReader> reader, int loop) :
AUD_EffectReader(reader), m_count(loop), m_left(loop)
{
}
diff --git a/intern/audaspace/FX/AUD_LoopReader.h b/intern/audaspace/FX/AUD_LoopReader.h
index fd2dd71d78f..12b8078b12d 100644
--- a/intern/audaspace/FX/AUD_LoopReader.h
+++ b/intern/audaspace/FX/AUD_LoopReader.h
@@ -61,7 +61,7 @@ public:
* \param loop The desired loop count, negative values result in endless
* looping.
*/
- AUD_LoopReader(AUD_Reference<AUD_IReader> reader, int loop);
+ AUD_LoopReader(boost::shared_ptr<AUD_IReader> reader, int loop);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
index 14dbc951c7f..e2faa241ac9 100644
--- a/intern/audaspace/FX/AUD_LowpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_LowpassFactory.cpp
@@ -36,7 +36,7 @@
#define M_PI 3.14159265358979323846
#endif
-AUD_LowpassFactory::AUD_LowpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency,
+AUD_LowpassFactory::AUD_LowpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency,
float Q) :
AUD_DynamicIIRFilterFactory(factory),
m_frequency(frequency),
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h
index 7e98720a2db..fdbc6e5d91d 100644
--- a/intern/audaspace/FX/AUD_LowpassFactory.h
+++ b/intern/audaspace/FX/AUD_LowpassFactory.h
@@ -59,7 +59,7 @@ public:
* \param frequency The cutoff frequency.
* \param Q The Q factor.
*/
- AUD_LowpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency, float Q = 1.0f);
+ AUD_LowpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency, float Q = 1.0f);
virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
};
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.cpp b/intern/audaspace/FX/AUD_PingPongFactory.cpp
index 3d5011cf47b..84e4b29415e 100644
--- a/intern/audaspace/FX/AUD_PingPongFactory.cpp
+++ b/intern/audaspace/FX/AUD_PingPongFactory.cpp
@@ -31,16 +31,16 @@
#include "AUD_DoubleReader.h"
#include "AUD_ReverseFactory.h"
-AUD_PingPongFactory::AUD_PingPongFactory(AUD_Reference<AUD_IFactory> factory) :
+AUD_PingPongFactory::AUD_PingPongFactory(boost::shared_ptr<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_Reference<AUD_IReader> AUD_PingPongFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_PingPongFactory::createReader()
{
- AUD_Reference<AUD_IReader> reader = getReader();
+ boost::shared_ptr<AUD_IReader> reader = getReader();
AUD_ReverseFactory factory(m_factory);
- AUD_Reference<AUD_IReader> reader2 = factory.createReader();
+ boost::shared_ptr<AUD_IReader> reader2 = factory.createReader();
- return new AUD_DoubleReader(reader, reader2);
+ return boost::shared_ptr<AUD_IReader>(new AUD_DoubleReader(reader, reader2));
}
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.h b/intern/audaspace/FX/AUD_PingPongFactory.h
index f25624a7c5e..e8ee5c9e389 100644
--- a/intern/audaspace/FX/AUD_PingPongFactory.h
+++ b/intern/audaspace/FX/AUD_PingPongFactory.h
@@ -48,9 +48,9 @@ public:
* Creates a new ping pong factory.
* \param factory The input factory.
*/
- AUD_PingPongFactory(AUD_Reference<AUD_IFactory> factory);
+ AUD_PingPongFactory(boost::shared_ptr<AUD_IFactory> factory);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_PINGPONGFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_PitchFactory.cpp b/intern/audaspace/FX/AUD_PitchFactory.cpp
index c6e9ae0b457..9dc27a58162 100644
--- a/intern/audaspace/FX/AUD_PitchFactory.cpp
+++ b/intern/audaspace/FX/AUD_PitchFactory.cpp
@@ -31,13 +31,13 @@
#include "AUD_PitchReader.h"
#include "AUD_Space.h"
-AUD_PitchFactory::AUD_PitchFactory(AUD_Reference<AUD_IFactory> factory, float pitch) :
+AUD_PitchFactory::AUD_PitchFactory(boost::shared_ptr<AUD_IFactory> factory, float pitch) :
AUD_EffectFactory(factory),
m_pitch(pitch)
{
}
-AUD_Reference<AUD_IReader> AUD_PitchFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_PitchFactory::createReader()
{
- return new AUD_PitchReader(getReader(), m_pitch);
+ return boost::shared_ptr<AUD_IReader>(new AUD_PitchReader(getReader(), m_pitch));
}
diff --git a/intern/audaspace/FX/AUD_PitchFactory.h b/intern/audaspace/FX/AUD_PitchFactory.h
index 5ad37ad1a6c..159388b28dd 100644
--- a/intern/audaspace/FX/AUD_PitchFactory.h
+++ b/intern/audaspace/FX/AUD_PitchFactory.h
@@ -53,9 +53,9 @@ public:
* \param factory The input factory.
* \param pitch The desired pitch.
*/
- AUD_PitchFactory(AUD_Reference<AUD_IFactory> factory, float pitch);
+ AUD_PitchFactory(boost::shared_ptr<AUD_IFactory> factory, float pitch);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_PITCHFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_PitchReader.cpp b/intern/audaspace/FX/AUD_PitchReader.cpp
index 0d1ff012e73..218af4fc090 100644
--- a/intern/audaspace/FX/AUD_PitchReader.cpp
+++ b/intern/audaspace/FX/AUD_PitchReader.cpp
@@ -29,7 +29,7 @@
#include "AUD_PitchReader.h"
-AUD_PitchReader::AUD_PitchReader(AUD_Reference<AUD_IReader> reader, float pitch) :
+AUD_PitchReader::AUD_PitchReader(boost::shared_ptr<AUD_IReader> reader, float pitch) :
AUD_EffectReader(reader), m_pitch(pitch)
{
}
diff --git a/intern/audaspace/FX/AUD_PitchReader.h b/intern/audaspace/FX/AUD_PitchReader.h
index 3185bfdf30b..d22e589b05d 100644
--- a/intern/audaspace/FX/AUD_PitchReader.h
+++ b/intern/audaspace/FX/AUD_PitchReader.h
@@ -53,7 +53,7 @@ public:
* \param reader The reader to read from.
* \param pitch The pitch value.
*/
- AUD_PitchReader(AUD_Reference<AUD_IReader> reader, float pitch);
+ AUD_PitchReader(boost::shared_ptr<AUD_IReader> reader, float pitch);
virtual AUD_Specs getSpecs() const;
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.cpp b/intern/audaspace/FX/AUD_RectifyFactory.cpp
index ad01f404698..26bb5615dad 100644
--- a/intern/audaspace/FX/AUD_RectifyFactory.cpp
+++ b/intern/audaspace/FX/AUD_RectifyFactory.cpp
@@ -37,12 +37,12 @@ sample_t AUD_RectifyFactory::rectifyFilter(AUD_CallbackIIRFilterReader* reader,
return fabs(reader->x(0));
}
-AUD_RectifyFactory::AUD_RectifyFactory(AUD_Reference<AUD_IFactory> factory) :
+AUD_RectifyFactory::AUD_RectifyFactory(boost::shared_ptr<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_Reference<AUD_IReader> AUD_RectifyFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_RectifyFactory::createReader()
{
- return new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter);
+ return boost::shared_ptr<AUD_IReader>(new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter));
}
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.h b/intern/audaspace/FX/AUD_RectifyFactory.h
index 5ad41d424d9..eb595e43e4f 100644
--- a/intern/audaspace/FX/AUD_RectifyFactory.h
+++ b/intern/audaspace/FX/AUD_RectifyFactory.h
@@ -48,9 +48,9 @@ public:
* Creates a new rectify factory.
* \param factory The input factory.
*/
- AUD_RectifyFactory(AUD_Reference<AUD_IFactory> factory);
+ AUD_RectifyFactory(boost::shared_ptr<AUD_IFactory> factory);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
static sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
};
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.cpp b/intern/audaspace/FX/AUD_ReverseFactory.cpp
index 063cbc88180..afb4ad2bec9 100644
--- a/intern/audaspace/FX/AUD_ReverseFactory.cpp
+++ b/intern/audaspace/FX/AUD_ReverseFactory.cpp
@@ -31,12 +31,12 @@
#include "AUD_ReverseReader.h"
#include "AUD_Space.h"
-AUD_ReverseFactory::AUD_ReverseFactory(AUD_Reference<AUD_IFactory> factory) :
+AUD_ReverseFactory::AUD_ReverseFactory(boost::shared_ptr<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_Reference<AUD_IReader> AUD_ReverseFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_ReverseFactory::createReader()
{
- return new AUD_ReverseReader(getReader());
+ return boost::shared_ptr<AUD_IReader>(new AUD_ReverseReader(getReader()));
}
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.h b/intern/audaspace/FX/AUD_ReverseFactory.h
index e2d75dc560a..5b0c9e3c29a 100644
--- a/intern/audaspace/FX/AUD_ReverseFactory.h
+++ b/intern/audaspace/FX/AUD_ReverseFactory.h
@@ -48,9 +48,9 @@ public:
* Creates a new reverse factory.
* \param factory The input factory.
*/
- AUD_ReverseFactory(AUD_Reference<AUD_IFactory> factory);
+ AUD_ReverseFactory(boost::shared_ptr<AUD_IFactory> factory);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_REVERSEFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp
index 6b454c66d25..c0a5962a299 100644
--- a/intern/audaspace/FX/AUD_ReverseReader.cpp
+++ b/intern/audaspace/FX/AUD_ReverseReader.cpp
@@ -34,7 +34,7 @@
static const char* props_error = "AUD_ReverseReader: The reader has to be "
"seekable and a finite length.";
-AUD_ReverseReader::AUD_ReverseReader(AUD_Reference<AUD_IReader> reader) :
+AUD_ReverseReader::AUD_ReverseReader(boost::shared_ptr<AUD_IReader> reader) :
AUD_EffectReader(reader),
m_length(reader->getLength()),
m_position(0)
diff --git a/intern/audaspace/FX/AUD_ReverseReader.h b/intern/audaspace/FX/AUD_ReverseReader.h
index d1e5179b8ec..219047915bd 100644
--- a/intern/audaspace/FX/AUD_ReverseReader.h
+++ b/intern/audaspace/FX/AUD_ReverseReader.h
@@ -61,7 +61,7 @@ public:
* \exception AUD_Exception Thrown if the reader specified has an
* undeterminable/infinite length or is not seekable.
*/
- AUD_ReverseReader(AUD_Reference<AUD_IReader> reader);
+ AUD_ReverseReader(boost::shared_ptr<AUD_IReader> reader);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/FX/AUD_SquareFactory.cpp b/intern/audaspace/FX/AUD_SquareFactory.cpp
index 7aabdb775f6..4b4dccb6e6b 100644
--- a/intern/audaspace/FX/AUD_SquareFactory.cpp
+++ b/intern/audaspace/FX/AUD_SquareFactory.cpp
@@ -46,7 +46,7 @@ void AUD_SquareFactory::endSquareFilter(float* threshold)
delete threshold;
}
-AUD_SquareFactory::AUD_SquareFactory(AUD_Reference<AUD_IFactory> factory, float threshold) :
+AUD_SquareFactory::AUD_SquareFactory(boost::shared_ptr<AUD_IFactory> factory, float threshold) :
AUD_EffectFactory(factory),
m_threshold(threshold)
{
@@ -57,10 +57,10 @@ float AUD_SquareFactory::getThreshold() const
return m_threshold;
}
-AUD_Reference<AUD_IReader> AUD_SquareFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_SquareFactory::createReader()
{
- return new AUD_CallbackIIRFilterReader(getReader(), 1, 1,
+ return boost::shared_ptr<AUD_IReader>(new AUD_CallbackIIRFilterReader(getReader(), 1, 1,
(doFilterIIR) squareFilter,
(endFilterIIR) endSquareFilter,
- new float(m_threshold));
+ new float(m_threshold)));
}
diff --git a/intern/audaspace/FX/AUD_SquareFactory.h b/intern/audaspace/FX/AUD_SquareFactory.h
index 9c0dea25d2b..27e62b6f4cc 100644
--- a/intern/audaspace/FX/AUD_SquareFactory.h
+++ b/intern/audaspace/FX/AUD_SquareFactory.h
@@ -54,14 +54,14 @@ public:
* \param factory The input factory.
* \param threshold The threshold.
*/
- AUD_SquareFactory(AUD_Reference<AUD_IFactory> factory, float threshold = 0.0f);
+ AUD_SquareFactory(boost::shared_ptr<AUD_IFactory> factory, float threshold = 0.0f);
/**
* Returns the threshold.
*/
float getThreshold() const;
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
static sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold);
static void endSquareFilter(float* threshold);
diff --git a/intern/audaspace/FX/AUD_SumFactory.cpp b/intern/audaspace/FX/AUD_SumFactory.cpp
index b58c44b0171..7f82233a0b7 100644
--- a/intern/audaspace/FX/AUD_SumFactory.cpp
+++ b/intern/audaspace/FX/AUD_SumFactory.cpp
@@ -30,16 +30,16 @@
#include "AUD_SumFactory.h"
#include "AUD_IIRFilterReader.h"
-AUD_SumFactory::AUD_SumFactory(AUD_Reference<AUD_IFactory> factory) :
+AUD_SumFactory::AUD_SumFactory(boost::shared_ptr<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_Reference<AUD_IReader> AUD_SumFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_SumFactory::createReader()
{
std::vector<float> a, b;
a.push_back(1);
a.push_back(-1);
b.push_back(1);
- return new AUD_IIRFilterReader(getReader(), b, a);
+ return boost::shared_ptr<AUD_IReader>(new AUD_IIRFilterReader(getReader(), b, a));
}
diff --git a/intern/audaspace/FX/AUD_SumFactory.h b/intern/audaspace/FX/AUD_SumFactory.h
index ec17faf3fb2..a916f3509cb 100644
--- a/intern/audaspace/FX/AUD_SumFactory.h
+++ b/intern/audaspace/FX/AUD_SumFactory.h
@@ -47,9 +47,9 @@ public:
* Creates a new sum factory.
* \param factory The input factory.
*/
- AUD_SumFactory(AUD_Reference<AUD_IFactory> factory);
+ AUD_SumFactory(boost::shared_ptr<AUD_IFactory> factory);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_SUMFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.cpp b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
index 30c57198c73..3efad37a5b3 100644
--- a/intern/audaspace/FX/AUD_SuperposeFactory.cpp
+++ b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
@@ -30,15 +30,15 @@
#include "AUD_SuperposeFactory.h"
#include "AUD_SuperposeReader.h"
-AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2) :
+AUD_SuperposeFactory::AUD_SuperposeFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2) :
m_factory1(factory1), m_factory2(factory2)
{
}
-AUD_Reference<AUD_IReader> AUD_SuperposeFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_SuperposeFactory::createReader()
{
- AUD_Reference<AUD_IReader> reader1 = m_factory1->createReader();
- AUD_Reference<AUD_IReader> reader2 = m_factory2->createReader();
+ boost::shared_ptr<AUD_IReader> reader1 = m_factory1->createReader();
+ boost::shared_ptr<AUD_IReader> reader2 = m_factory2->createReader();
- return new AUD_SuperposeReader(reader1, reader2);
+ return boost::shared_ptr<AUD_IReader>(new AUD_SuperposeReader(reader1, reader2));
}
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.h b/intern/audaspace/FX/AUD_SuperposeFactory.h
index 2da8e34496d..caa0dfb752f 100644
--- a/intern/audaspace/FX/AUD_SuperposeFactory.h
+++ b/intern/audaspace/FX/AUD_SuperposeFactory.h
@@ -43,12 +43,12 @@ private:
/**
* First played factory.
*/
- AUD_Reference<AUD_IFactory> m_factory1;
+ boost::shared_ptr<AUD_IFactory> m_factory1;
/**
* Second played factory.
*/
- AUD_Reference<AUD_IFactory> m_factory2;
+ boost::shared_ptr<AUD_IFactory> m_factory2;
// hide copy constructor and operator=
AUD_SuperposeFactory(const AUD_SuperposeFactory&);
@@ -60,9 +60,9 @@ public:
* \param factory1 The first input factory.
* \param factory2 The second input factory.
*/
- AUD_SuperposeFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2);
+ AUD_SuperposeFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_SUPERPOSEFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp
index 535d3590a8f..294a48b3e7a 100644
--- a/intern/audaspace/FX/AUD_SuperposeReader.cpp
+++ b/intern/audaspace/FX/AUD_SuperposeReader.cpp
@@ -34,7 +34,7 @@
static const char* specs_error = "AUD_SuperposeReader: Both readers have to "
"have the same specs.";
-AUD_SuperposeReader::AUD_SuperposeReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2) :
+AUD_SuperposeReader::AUD_SuperposeReader(boost::shared_ptr<AUD_IReader> reader1, boost::shared_ptr<AUD_IReader> reader2) :
m_reader1(reader1), m_reader2(reader2)
{
}
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h
index d0fde13a267..a04ab90fe43 100644
--- a/intern/audaspace/FX/AUD_SuperposeReader.h
+++ b/intern/audaspace/FX/AUD_SuperposeReader.h
@@ -32,7 +32,8 @@
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
-#include "AUD_Reference.h"
+
+#include <boost/shared_ptr.hpp>
/**
* This reader plays two readers with the same specs in parallel.
@@ -43,12 +44,12 @@ private:
/**
* The first reader.
*/
- AUD_Reference<AUD_IReader> m_reader1;
+ boost::shared_ptr<AUD_IReader> m_reader1;
/**
* The second reader.
*/
- AUD_Reference<AUD_IReader> m_reader2;
+ boost::shared_ptr<AUD_IReader> m_reader2;
/**
* Buffer used for mixing.
@@ -66,7 +67,7 @@ public:
* \param reader2 The second reader to read from.
* \exception AUD_Exception Thrown if the specs from the readers differ.
*/
- AUD_SuperposeReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2);
+ AUD_SuperposeReader(boost::shared_ptr<AUD_IReader> reader1, boost::shared_ptr<AUD_IReader> reader2);
/**
* Destroys the reader.
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.cpp b/intern/audaspace/FX/AUD_VolumeFactory.cpp
index f5e635eec2d..4f0e1e425e6 100644
--- a/intern/audaspace/FX/AUD_VolumeFactory.cpp
+++ b/intern/audaspace/FX/AUD_VolumeFactory.cpp
@@ -30,7 +30,7 @@
#include "AUD_VolumeFactory.h"
#include "AUD_IIRFilterReader.h"
-AUD_VolumeFactory::AUD_VolumeFactory(AUD_Reference<AUD_IFactory> factory, float volume) :
+AUD_VolumeFactory::AUD_VolumeFactory(boost::shared_ptr<AUD_IFactory> factory, float volume) :
AUD_EffectFactory(factory),
m_volume(volume)
{
@@ -41,10 +41,10 @@ float AUD_VolumeFactory::getVolume() const
return m_volume;
}
-AUD_Reference<AUD_IReader> AUD_VolumeFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_VolumeFactory::createReader()
{
std::vector<float> a, b;
a.push_back(1);
b.push_back(m_volume);
- return new AUD_IIRFilterReader(getReader(), b, a);
+ return boost::shared_ptr<AUD_IReader>(new AUD_IIRFilterReader(getReader(), b, a));
}
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.h b/intern/audaspace/FX/AUD_VolumeFactory.h
index b12838373b3..6fe779ffb88 100644
--- a/intern/audaspace/FX/AUD_VolumeFactory.h
+++ b/intern/audaspace/FX/AUD_VolumeFactory.h
@@ -55,7 +55,7 @@ public:
* \param factory The input factory.
* \param volume The desired volume.
*/
- AUD_VolumeFactory(AUD_Reference<AUD_IFactory> factory, float volume);
+ AUD_VolumeFactory(boost::shared_ptr<AUD_IFactory> factory, float volume);
/**
* Returns the volume.
@@ -63,7 +63,7 @@ public:
*/
float getVolume() const;
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_VOLUMEFACTORY_H__
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index f68d41f6a1c..371e0007bd3 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -31,6 +31,7 @@
#include "AUD_IFactory.h"
#include "AUD_IReader.h"
#include "AUD_ConverterReader.h"
+#include "AUD_MutexLock.h"
#include <cstring>
#include <limits>
@@ -66,7 +67,7 @@ static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
"filled with data.";
-AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<AUD_IReader> reader, bool keep) :
+AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, boost::shared_ptr<AUD_IReader> reader, bool keep) :
m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0),
m_eos(false), m_loopcount(0), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING),
m_device(device)
@@ -125,22 +126,27 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
{
if(m_status)
{
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
if(m_status == AUD_STATUS_PLAYING)
{
- m_device->m_playingSounds.remove(this);
- m_device->m_pausedSounds.push_back(this);
+ for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ boost::shared_ptr<AUD_OpenALHandle> This = *it;
- alSourcePause(m_source);
+ m_device->m_playingSounds.erase(it);
+ m_device->m_pausedSounds.push_back(This);
- m_status = AUD_STATUS_PAUSED;
- m_device->unlock();
+ alSourcePause(m_source);
- return true;
- }
+ m_status = AUD_STATUS_PAUSED;
- m_device->unlock();
+ return true;
+ }
+ }
+ }
}
return false;
@@ -150,20 +156,26 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
{
if(m_status)
{
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
if(m_status == AUD_STATUS_PAUSED)
{
- m_device->m_pausedSounds.remove(this);
- m_device->m_playingSounds.push_back(this);
+ for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ boost::shared_ptr<AUD_OpenALHandle> This = *it;
- m_device->start();
- m_status = AUD_STATUS_PLAYING;
- m_device->unlock();
- return true;
- }
+ m_device->m_pausedSounds.erase(it);
+ m_device->m_playingSounds.push_back(This);
+
+ m_device->start();
+ m_status = AUD_STATUS_PLAYING;
- m_device->unlock();
+ return true;
+ }
+ }
+ }
}
return false;
@@ -174,25 +186,39 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::stop()
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- // AUD_XXX Create a reference of our own object so that it doesn't get
- // deleted before the end of this function
- AUD_Reference<AUD_OpenALHandle> This = this;
-
- if(m_status == AUD_STATUS_PLAYING)
- m_device->m_playingSounds.remove(This);
- else
- m_device->m_pausedSounds.remove(This);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ m_status = AUD_STATUS_INVALID;
alDeleteSources(1, &m_source);
if(!m_isBuffered)
alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
- m_status = AUD_STATUS_INVALID;
- return true;
+ for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ boost::shared_ptr<AUD_OpenALHandle> This = *it;
+
+ m_device->m_playingSounds.erase(it);
+
+ return true;
+ }
+ }
+
+ for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ m_device->m_pausedSounds.erase(it);
+ return true;
+ }
+ }
+
+ return false;
}
bool AUD_OpenALDevice::AUD_OpenALHandle::getKeep()
@@ -208,11 +234,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setKeep(bool keep)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- m_keep = keep;
+ if(!m_status)
+ return false;
- m_device->unlock();
+ m_keep = keep;
return true;
}
@@ -222,7 +249,10 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
+
+ if(!m_status)
+ return false;
if(m_isBuffered)
alSourcef(m_source, AL_SEC_OFFSET, position);
@@ -272,17 +302,18 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
}
}
- m_device->unlock();
-
return true;
}
float AUD_OpenALDevice::AUD_OpenALHandle::getPosition()
{
if(!m_status)
- return 0.0f;
+ return false;
+
+ AUD_MutexLock lock(*m_device);
- m_device->lock();
+ if(!m_status)
+ return 0.0f;
float position = 0.0f;
@@ -295,8 +326,6 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getPosition()
CYCLE_BUFFERS) / (float)specs.rate;
}
- m_device->unlock();
-
return position;
}
@@ -310,13 +339,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getVolume()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_GAIN, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_GAIN, &result);
return result;
}
@@ -326,11 +356,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setVolume(float volume)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_GAIN, volume);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_GAIN, volume);
return true;
}
@@ -340,13 +371,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getPitch()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_PITCH, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_PITCH, &result);
return result;
}
@@ -356,11 +388,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setPitch(float pitch)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_PITCH, pitch);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_PITCH, pitch);
return true;
}
@@ -385,13 +418,14 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setStopCallback(stopCallback callback,
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
+
+ if(!m_status)
+ return false;
m_stop = callback;
m_stop_data = data;
- m_device->unlock();
-
return true;
}
@@ -404,15 +438,16 @@ AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceLocation()
AUD_Vector3 result = AUD_Vector3(0, 0, 0);
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
+
+ if(!m_status)
+ return result;
ALfloat p[3];
alGetSourcefv(m_source, AL_POSITION, p);
- m_device->unlock();
-
result = AUD_Vector3(p[0], p[1], p[2]);
return result;
@@ -423,11 +458,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceLocation(const AUD_Vector3& lo
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
return true;
}
@@ -437,15 +473,16 @@ AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceVelocity()
AUD_Vector3 result = AUD_Vector3(0, 0, 0);
if(!m_status)
- return result;
+ return false;
+
+ AUD_MutexLock lock(*m_device);
- m_device->lock();
+ if(!m_status)
+ return result;
ALfloat v[3];
alGetSourcefv(m_source, AL_VELOCITY, v);
- m_device->unlock();
-
result = AUD_Vector3(v[0], v[1], v[2]);
return result;
@@ -456,11 +493,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceVelocity(const AUD_Vector3& ve
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
return true;
}
@@ -472,9 +510,6 @@ AUD_Quaternion AUD_OpenALDevice::AUD_OpenALHandle::getSourceOrientation()
bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaternion& orientation)
{
- if(!m_status)
- return false;
-
ALfloat direction[3];
direction[0] = -2 * (orientation.w() * orientation.y() +
orientation.x() * orientation.z());
@@ -482,11 +517,16 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaterni
orientation.z() * orientation.y());
direction[2] = 2 * (orientation.x() * orientation.x() +
orientation.y() * orientation.y()) - 1;
- m_device->lock();
- alSourcefv(m_source, AL_DIRECTION, direction);
+ if(!m_status)
+ return false;
+
+ AUD_MutexLock lock(*m_device);
+
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcefv(m_source, AL_DIRECTION, direction);
m_orientation = orientation;
@@ -500,11 +540,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::isRelative()
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
return result;
}
@@ -514,11 +555,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setRelative(bool relative)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
return true;
}
@@ -528,13 +570,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMaximum()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_MAX_GAIN, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_MAX_GAIN, &result);
return result;
}
@@ -544,11 +587,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMaximum(float volume)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_MAX_GAIN, volume);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_MAX_GAIN, volume);
return true;
}
@@ -558,13 +602,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMinimum()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_MIN_GAIN, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_MIN_GAIN, &result);
return result;
}
@@ -574,11 +619,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMinimum(float volume)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_MIN_GAIN, volume);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_MIN_GAIN, volume);
return true;
}
@@ -588,13 +634,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceMaximum()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
return result;
}
@@ -604,11 +651,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceMaximum(float distance)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_MAX_DISTANCE, distance);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_MAX_DISTANCE, distance);
return true;
}
@@ -618,13 +666,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceReference()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
return result;
}
@@ -634,11 +683,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceReference(float distance)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
return true;
}
@@ -648,13 +698,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getAttenuation()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
return result;
}
@@ -664,11 +715,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setAttenuation(float factor)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
return true;
}
@@ -678,13 +730,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleOuter()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
return result;
}
@@ -694,11 +747,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
return true;
}
@@ -708,13 +762,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
return result;
}
@@ -724,11 +779,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
return true;
}
@@ -738,13 +794,14 @@ float AUD_OpenALDevice::AUD_OpenALHandle::getConeVolumeOuter()
float result = std::numeric_limits<float>::quiet_NaN();
if(!m_status)
- return result;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
+ if(!m_status)
+ return result;
- m_device->unlock();
+ alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
return result;
}
@@ -754,11 +811,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setConeVolumeOuter(float volume)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
+ if(!m_status)
+ return false;
- m_device->unlock();
+ alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
return true;
}
@@ -776,7 +834,7 @@ static void *AUD_openalRunThread(void *device)
void AUD_OpenALDevice::start(bool join)
{
- lock();
+ AUD_MutexLock lock(*this);
if(!m_playing)
{
@@ -793,21 +851,19 @@ void AUD_OpenALDevice::start(bool join)
m_playing = true;
}
-
- unlock();
}
void AUD_OpenALDevice::updateStreams()
{
- AUD_Reference<AUD_OpenALHandle> sound;
+ boost::shared_ptr<AUD_OpenALHandle> sound;
int length;
ALint info;
AUD_DeviceSpecs specs = m_specs;
ALCenum cerr;
- std::list<AUD_Reference<AUD_OpenALHandle> > stopSounds;
- std::list<AUD_Reference<AUD_OpenALHandle> > pauseSounds;
+ std::list<boost::shared_ptr<AUD_OpenALHandle> > stopSounds;
+ std::list<boost::shared_ptr<AUD_OpenALHandle> > pauseSounds;
AUD_HandleIterator it;
while(1)
@@ -970,7 +1026,6 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
{
// cannot determine how many channels or which format OpenAL uses, but
// it at least is able to play 16 bit stereo audio
- specs.channels = AUD_CHANNELS_STEREO;
specs.format = AUD_FORMAT_S16;
#if 0
@@ -1009,6 +1064,11 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
+ if((!m_useMC && specs.channels > AUD_CHANNELS_STEREO) ||
+ specs.channels == AUD_CHANNELS_STEREO_LFE ||
+ specs.channels == AUD_CHANNELS_SURROUND5)
+ specs.channels = AUD_CHANNELS_STEREO;
+
alGetError();
alcGetError(m_device);
@@ -1161,36 +1221,36 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
return valid;
}
-AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
+boost::shared_ptr<AUD_IHandle> AUD_OpenALDevice::play(boost::shared_ptr<AUD_IReader> reader, bool keep)
{
AUD_Specs specs = reader->getSpecs();
// check format
if(specs.channels == AUD_CHANNELS_INVALID)
- return AUD_Reference<AUD_IHandle>();
+ return boost::shared_ptr<AUD_IHandle>();
if(m_specs.format != AUD_FORMAT_FLOAT32)
- reader = new AUD_ConverterReader(reader, m_specs);
+ reader = boost::shared_ptr<AUD_IReader>(new AUD_ConverterReader(reader, m_specs));
ALenum format;
if(!getFormat(format, specs))
- return AUD_Reference<AUD_IHandle>();
+ return boost::shared_ptr<AUD_IHandle>();
+
+ AUD_MutexLock lock(*this);
- lock();
alcSuspendContext(m_context);
- AUD_Reference<AUD_OpenALDevice::AUD_OpenALHandle> sound;
+ boost::shared_ptr<AUD_OpenALDevice::AUD_OpenALHandle> sound;
try
{
// create the handle
- sound = new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep);
+ sound = boost::shared_ptr<AUD_OpenALDevice::AUD_OpenALHandle>(new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep));
}
catch(AUD_Exception&)
{
alcProcessContext(m_context);
- unlock();
throw;
}
@@ -1201,12 +1261,10 @@ AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> rea
start();
- unlock();
-
- return AUD_Reference<AUD_IHandle>(sound);
+ return boost::shared_ptr<AUD_IHandle>(sound);
}
-AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
+boost::shared_ptr<AUD_IHandle> AUD_OpenALDevice::play(boost::shared_ptr<AUD_IFactory> factory, bool keep)
{
/* AUD_XXX disabled
AUD_OpenALHandle* sound = NULL;
@@ -1285,7 +1343,8 @@ AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> fa
void AUD_OpenALDevice::stopAll()
{
- lock();
+ AUD_MutexLock lock(*this);
+
alcSuspendContext(m_context);
while(!m_playingSounds.empty())
@@ -1295,7 +1354,6 @@ void AUD_OpenALDevice::stopAll()
m_pausedSounds.front()->stop();
alcProcessContext(m_context);
- unlock();
}
void AUD_OpenALDevice::lock()
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
index 0a409b42462..d2a4be227ba 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -58,7 +58,7 @@ private:
bool m_isBuffered;
/// The reader source.
- AUD_Reference<AUD_IReader> m_reader;
+ boost::shared_ptr<AUD_IReader> m_reader;
/// Whether to keep the source if end of it is reached.
bool m_keep;
@@ -105,7 +105,7 @@ private:
* \param reader The reader this handle plays.
* \param keep Whether to keep the handle alive when the reader ends.
*/
- AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<AUD_IReader> reader, bool keep);
+ AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, boost::shared_ptr<AUD_IReader> reader, bool keep);
virtual ~AUD_OpenALHandle() {}
virtual bool pause();
@@ -150,7 +150,7 @@ private:
virtual bool setConeVolumeOuter(float volume);
};
- typedef std::list<AUD_Reference<AUD_OpenALHandle> >::iterator AUD_HandleIterator;
+ typedef std::list<boost::shared_ptr<AUD_OpenALHandle> >::iterator AUD_HandleIterator;
/**
* The OpenAL device handle.
@@ -175,12 +175,12 @@ private:
/**
* The list of sounds that are currently playing.
*/
- std::list<AUD_Reference<AUD_OpenALHandle> > m_playingSounds;
+ std::list<boost::shared_ptr<AUD_OpenALHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<AUD_Reference<AUD_OpenALHandle> > m_pausedSounds;
+ std::list<boost::shared_ptr<AUD_OpenALHandle> > m_pausedSounds;
/**
* The list of buffered factories.
@@ -255,8 +255,8 @@ public:
virtual ~AUD_OpenALDevice();
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
- virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
+ virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false);
+ virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false);
virtual void stopAll();
virtual void lock();
virtual void unlock();
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
index dd58e5a7398..9beba2eb0a0 100644
--- a/intern/audaspace/Python/AUD_PyAPI.cpp
+++ b/intern/audaspace/Python/AUD_PyAPI.cpp
@@ -90,7 +90,7 @@ static void
Factory_dealloc(Factory* self)
{
if(self->factory)
- delete reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory);
+ delete reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory);
Py_XDECREF(self->child_list);
Py_TYPE(self)->tp_free((PyObject *)self);
}
@@ -114,7 +114,7 @@ Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
try
{
- self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
+ self->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename));
}
catch(AUD_Exception& e)
{
@@ -154,7 +154,7 @@ Factory_sine(PyTypeObject* type, PyObject *args)
{
try
{
- self->factory = new AUD_Reference<AUD_IFactory>(new AUD_SinusFactory(frequency, (AUD_SampleRate)rate));
+ self->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_SinusFactory(frequency, (AUD_SampleRate)rate));
}
catch(AUD_Exception& e)
{
@@ -193,7 +193,7 @@ Factory_file(PyTypeObject* type, PyObject *args)
{
try
{
- self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
+ self->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename));
}
catch(AUD_Exception& e)
{
@@ -236,7 +236,7 @@ Factory_lowpass(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LowpassFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), frequency, Q));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_LowpassFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), frequency, Q));
}
catch(AUD_Exception& e)
{
@@ -277,7 +277,7 @@ Factory_delay(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_DelayFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), delay));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_DelayFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), delay));
}
catch(AUD_Exception& e)
{
@@ -321,7 +321,7 @@ Factory_join(Factory* self, PyObject *object)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_DoubleFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), *reinterpret_cast<AUD_Reference<AUD_IFactory>*>(child->factory)));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_DoubleFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), *reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(child->factory)));
}
catch(AUD_Exception& e)
{
@@ -364,7 +364,7 @@ Factory_highpass(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_HighpassFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), frequency, Q));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_HighpassFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), frequency, Q));
}
catch(AUD_Exception& e)
{
@@ -405,7 +405,7 @@ Factory_limit(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LimiterFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), start, end));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_LimiterFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), start, end));
}
catch(AUD_Exception& e)
{
@@ -449,7 +449,7 @@ Factory_pitch(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_PitchFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), factor));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_PitchFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), factor));
}
catch(AUD_Exception& e)
{
@@ -491,7 +491,7 @@ Factory_volume(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_VolumeFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), volume));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_VolumeFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), volume));
}
catch(AUD_Exception& e)
{
@@ -534,7 +534,7 @@ Factory_fadein(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), AUD_FADE_IN, start, length));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), AUD_FADE_IN, start, length));
}
catch(AUD_Exception& e)
{
@@ -578,7 +578,7 @@ Factory_fadeout(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), AUD_FADE_OUT, start, length));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), AUD_FADE_OUT, start, length));
}
catch(AUD_Exception& e)
{
@@ -620,7 +620,7 @@ Factory_loop(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LoopFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), loop));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_LoopFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), loop));
}
catch(AUD_Exception& e)
{
@@ -663,7 +663,7 @@ Factory_mix(Factory* self, PyObject *object)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_SuperposeFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), *reinterpret_cast<AUD_Reference<AUD_IFactory>*>(child->factory)));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_SuperposeFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), *reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(child->factory)));
}
catch(AUD_Exception& e)
{
@@ -696,7 +696,7 @@ Factory_pingpong(Factory* self)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_PingPongFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory)));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_PingPongFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory)));
}
catch(AUD_Exception& e)
{
@@ -735,7 +735,7 @@ Factory_reverse(Factory* self)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_ReverseFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory)));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_ReverseFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory)));
}
catch(AUD_Exception& e)
{
@@ -770,7 +770,7 @@ Factory_buffer(Factory* self)
{
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_StreamBufferFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory)));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_StreamBufferFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory)));
}
catch(AUD_Exception& e)
{
@@ -812,7 +812,7 @@ Factory_square(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_SquareFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), threshold));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_SquareFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), threshold));
}
catch(AUD_Exception& e)
{
@@ -915,7 +915,7 @@ Factory_filter(Factory* self, PyObject *args)
try
{
- parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_IIRFilterFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), b, a));
+ parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_IIRFilterFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory), b, a));
}
catch(AUD_Exception& e)
{
@@ -1039,7 +1039,7 @@ static void
Handle_dealloc(Handle* self)
{
if(self->handle)
- delete reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle);
+ delete reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle);
Py_TYPE(self)->tp_free((PyObject *)self);
}
@@ -1054,7 +1054,7 @@ Handle_pause(Handle *self)
{
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->pause());
+ return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->pause());
}
catch(AUD_Exception& e)
{
@@ -1074,7 +1074,7 @@ Handle_resume(Handle *self)
{
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->resume());
+ return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->resume());
}
catch(AUD_Exception& e)
{
@@ -1095,7 +1095,7 @@ Handle_stop(Handle *self)
{
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->stop());
+ return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->stop());
}
catch(AUD_Exception& e)
{
@@ -1125,7 +1125,7 @@ Handle_get_position(Handle *self, void* nothing)
{
try
{
- return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getPosition());
+ return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getPosition());
}
catch(AUD_Exception& e)
{
@@ -1144,7 +1144,7 @@ Handle_set_position(Handle *self, PyObject *args, void* nothing)
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->seek(position))
+ if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->seek(position))
return 0;
PyErr_SetString(AUDError, "Couldn't seek the sound!");
}
@@ -1170,7 +1170,7 @@ Handle_get_keep(Handle *self, void* nothing)
{
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getKeep());
+ return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getKeep());
}
catch(AUD_Exception& e)
{
@@ -1192,7 +1192,7 @@ Handle_set_keep(Handle *self, PyObject *args, void* nothing)
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setKeep(keep))
+ if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setKeep(keep))
return 0;
PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
}
@@ -1212,7 +1212,7 @@ Handle_get_status(Handle *self, void* nothing)
{
try
{
- return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getStatus());
+ return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getStatus());
}
catch(AUD_Exception& e)
{
@@ -1229,7 +1229,7 @@ Handle_get_volume(Handle *self, void* nothing)
{
try
{
- return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getVolume());
+ return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getVolume());
}
catch(AUD_Exception& e)
{
@@ -1248,7 +1248,7 @@ Handle_set_volume(Handle *self, PyObject *args, void* nothing)
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setVolume(volume))
+ if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setVolume(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound volume!");
}
@@ -1268,7 +1268,7 @@ Handle_get_pitch(Handle *self, void* nothing)
{
try
{
- return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getPitch());
+ return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getPitch());
}
catch(AUD_Exception& e)
{
@@ -1287,7 +1287,7 @@ Handle_set_pitch(Handle *self, PyObject *args, void* nothing)
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setPitch(pitch))
+ if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setPitch(pitch))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
}
@@ -1307,7 +1307,7 @@ Handle_get_loop_count(Handle *self, void* nothing)
{
try
{
- return Py_BuildValue("i", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getLoopCount());
+ return Py_BuildValue("i", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getLoopCount());
}
catch(AUD_Exception& e)
{
@@ -1326,7 +1326,7 @@ Handle_set_loop_count(Handle *self, PyObject *args, void* nothing)
try
{
- if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setLoopCount(loops))
+ if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setLoopCount(loops))
return 0;
PyErr_SetString(AUDError, "Couldn't set the loop count!");
}
@@ -1346,7 +1346,7 @@ Handle_get_location(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Vector3 v = handle->getSourceLocation();
@@ -1375,7 +1375,7 @@ Handle_set_location(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Vector3 location(x, y, z);
@@ -1402,7 +1402,7 @@ Handle_get_velocity(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Vector3 v = handle->getSourceVelocity();
@@ -1431,7 +1431,7 @@ Handle_set_velocity(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Vector3 velocity(x, y, z);
@@ -1458,7 +1458,7 @@ Handle_get_orientation(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Quaternion o = handle->getSourceOrientation();
@@ -1487,7 +1487,7 @@ Handle_set_orientation(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Quaternion orientation(w, x, y, z);
@@ -1514,7 +1514,7 @@ Handle_get_relative(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return PyBool_FromLong((long)handle->isRelative());
@@ -1545,7 +1545,7 @@ Handle_set_relative(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(handle->setRelative(relative))
@@ -1572,7 +1572,7 @@ Handle_get_volume_minimum(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", handle->getVolumeMinimum());
@@ -1600,7 +1600,7 @@ Handle_set_volume_minimum(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(handle->setVolumeMinimum(volume))
@@ -1627,7 +1627,7 @@ Handle_get_volume_maximum(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", handle->getVolumeMaximum());
@@ -1655,7 +1655,7 @@ Handle_set_volume_maximum(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(handle->setVolumeMaximum(volume))
@@ -1683,7 +1683,7 @@ Handle_get_distance_reference(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", handle->getDistanceReference());
@@ -1711,7 +1711,7 @@ Handle_set_distance_reference(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(handle->setDistanceReference(distance))
@@ -1739,7 +1739,7 @@ Handle_get_distance_maximum(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", handle->getDistanceMaximum());
@@ -1767,7 +1767,7 @@ Handle_set_distance_maximum(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(handle->setDistanceMaximum(distance))
@@ -1795,7 +1795,7 @@ Handle_get_attenuation(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", handle->getAttenuation());
@@ -1823,7 +1823,7 @@ Handle_set_attenuation(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(handle->setAttenuation(factor))
@@ -1856,7 +1856,7 @@ Handle_get_cone_angle_inner(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", handle->getConeAngleInner());
@@ -1884,7 +1884,7 @@ Handle_set_cone_angle_inner(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(handle->setConeAngleInner(angle))
@@ -1911,7 +1911,7 @@ Handle_get_cone_angle_outer(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", handle->getConeAngleOuter());
@@ -1939,7 +1939,7 @@ Handle_set_cone_angle_outer(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(handle->setConeAngleOuter(angle))
@@ -1966,7 +1966,7 @@ Handle_get_cone_volume_outer(Handle *self, void* nothing)
{
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", handle->getConeVolumeOuter());
@@ -1994,7 +1994,7 @@ Handle_set_cone_volume_outer(Handle *self, PyObject *args, void* nothing)
try
{
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(handle->setConeVolumeOuter(volume))
@@ -2104,7 +2104,7 @@ static void
Device_dealloc(Device* self)
{
if(self->device)
- delete reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device);
+ delete reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device);
Py_TYPE(self)->tp_free((PyObject *)self);
}
@@ -2147,21 +2147,21 @@ Device_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
case AUD_DEVICE_NULL:
(void)specs; /* quiet warning when others disabled */
- self->device = new AUD_Reference<AUD_IDevice>(new AUD_NULLDevice());
+ self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_NULLDevice());
break;
case AUD_DEVICE_OPENAL:
#ifdef WITH_OPENAL
- self->device = new AUD_Reference<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
+ self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
#endif
break;
case AUD_DEVICE_SDL:
#ifdef WITH_SDL
- self->device = new AUD_Reference<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
+ self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
#endif
break;
case AUD_DEVICE_JACK:
#ifdef WITH_JACK
- self->device = new AUD_Reference<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
+ self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
#endif
break;
case AUD_DEVICE_READ:
@@ -2236,7 +2236,7 @@ Device_play(Device *self, PyObject *args, PyObject *kwds)
{
try
{
- handle->handle = new AUD_Reference<AUD_IHandle>((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(sound->factory), keep));
+ handle->handle = new boost::shared_ptr<AUD_IHandle>((*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(sound->factory), keep));
}
catch(AUD_Exception& e)
{
@@ -2258,7 +2258,7 @@ Device_stopAll(Device *self)
{
try
{
- (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->stopAll();
+ (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->stopAll();
Py_RETURN_NONE;
}
catch(AUD_Exception& e)
@@ -2284,7 +2284,7 @@ Device_lock(Device *self)
{
try
{
- (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->lock();
+ (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->lock();
Py_RETURN_NONE;
}
catch(AUD_Exception& e)
@@ -2304,7 +2304,7 @@ Device_unlock(Device *self)
{
try
{
- (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->unlock();
+ (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->unlock();
Py_RETURN_NONE;
}
catch(AUD_Exception& e)
@@ -2338,7 +2338,7 @@ Device_get_rate(Device *self, void* nothing)
{
try
{
- AUD_DeviceSpecs specs = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getSpecs();
+ AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs();
return Py_BuildValue("d", specs.rate);
}
catch(AUD_Exception& e)
@@ -2356,7 +2356,7 @@ Device_get_format(Device *self, void* nothing)
{
try
{
- AUD_DeviceSpecs specs = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getSpecs();
+ AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs();
return Py_BuildValue("i", specs.format);
}
catch(AUD_Exception& e)
@@ -2374,7 +2374,7 @@ Device_get_channels(Device *self, void* nothing)
{
try
{
- AUD_DeviceSpecs specs = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getSpecs();
+ AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs();
return Py_BuildValue("i", specs.channels);
}
catch(AUD_Exception& e)
@@ -2392,7 +2392,7 @@ Device_get_volume(Device *self, void* nothing)
{
try
{
- return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getVolume());
+ return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getVolume());
}
catch(AUD_Exception& e)
{
@@ -2411,7 +2411,7 @@ Device_set_volume(Device *self, PyObject *args, void* nothing)
try
{
- (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->setVolume(volume);
+ (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->setVolume(volume);
return 0;
}
catch(AUD_Exception& e)
@@ -2429,7 +2429,7 @@ Device_get_listener_location(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 v = device->getListenerLocation();
@@ -2458,7 +2458,7 @@ Device_set_listener_location(Device *self, PyObject *args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 location(x, y, z);
@@ -2484,7 +2484,7 @@ Device_get_listener_velocity(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 v = device->getListenerVelocity();
@@ -2513,7 +2513,7 @@ Device_set_listener_velocity(Device *self, PyObject *args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 velocity(x, y, z);
@@ -2539,7 +2539,7 @@ Device_get_listener_orientation(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Quaternion o = device->getListenerOrientation();
@@ -2568,7 +2568,7 @@ Device_set_listener_orientation(Device *self, PyObject *args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Quaternion orientation(w, x, y, z);
@@ -2595,7 +2595,7 @@ Device_get_speed_of_sound(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
return Py_BuildValue("f", device->getSpeedOfSound());
@@ -2623,7 +2623,7 @@ Device_set_speed_of_sound(Device *self, PyObject *args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
device->setSpeedOfSound(speed);
@@ -2651,7 +2651,7 @@ Device_get_doppler_factor(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
return Py_BuildValue("f", device->getDopplerFactor());
@@ -2679,7 +2679,7 @@ Device_set_doppler_factor(Device *self, PyObject *args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
device->setDopplerFactor(factor);
@@ -2705,7 +2705,7 @@ Device_get_distance_model(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
return Py_BuildValue("i", int(device->getDistanceModel()));
@@ -2733,7 +2733,7 @@ Device_set_distance_model(Device *self, PyObject *args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
if(device)
{
device->setDistanceModel(AUD_DistanceModel(model));
diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript
index 50c81db46dd..e2b6efacc96 100644
--- a/intern/audaspace/SConscript
+++ b/intern/audaspace/SConscript
@@ -3,7 +3,7 @@
Import ('env')
sources = env.Glob('intern/*.cpp') + env.Glob('FX/*.cpp')
-incs = '. intern FX ' + env['BF_PTHREADS_INC']
+incs = '. intern FX ' + env['BF_PTHREADS_INC'] + ' ' + env['BF_BOOST_INC']
defs = []
if env['WITH_BF_FFMPEG']:
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
index c4c384f054c..403c367fccc 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
@@ -46,10 +46,10 @@ AUD_FFMPEGFactory::AUD_FFMPEGFactory(const data_t* buffer, int size) :
memcpy(m_buffer->getBuffer(), buffer, size);
}
-AUD_Reference<AUD_IReader> AUD_FFMPEGFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_FFMPEGFactory::createReader()
{
- if(m_buffer.isNull())
- return new AUD_FFMPEGReader(m_filename);
+ if(m_buffer.get())
+ return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_buffer));
else
- return new AUD_FFMPEGReader(m_buffer);
+ return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_filename));
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
index 349f55dd7db..23d0f07ed0b 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
@@ -31,10 +31,10 @@
#define __AUD_FFMPEGFACTORY_H__
#include "AUD_IFactory.h"
-#include "AUD_Reference.h"
#include "AUD_Buffer.h"
#include <string>
+#include <boost/shared_ptr.hpp>
/**
* This factory reads a sound file via ffmpeg.
@@ -52,7 +52,7 @@ private:
/**
* The buffer to read from.
*/
- AUD_Reference<AUD_Buffer> m_buffer;
+ boost::shared_ptr<AUD_Buffer> m_buffer;
// hide copy constructor and operator=
AUD_FFMPEGFactory(const AUD_FFMPEGFactory&);
@@ -72,7 +72,7 @@ public:
*/
AUD_FFMPEGFactory(const data_t* buffer, int size);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_FFMPEGFACTORY_H__
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 28a14a9cfc7..0a3d0f8e85a 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -197,7 +197,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(std::string filename) :
static const char* streamopen_error = "AUD_FFMPEGReader: Stream couldn't be "
"opened.";
-AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer) :
+AUD_FFMPEGReader::AUD_FFMPEGReader(boost::shared_ptr<AUD_Buffer> buffer) :
m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1),
m_membuffer(buffer),
m_membufferpos(0)
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
index 2b354b0b2a1..d5d9fb300ff 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
@@ -32,10 +32,10 @@
#include "AUD_ConverterFunctions.h"
#include "AUD_IReader.h"
-#include "AUD_Reference.h"
#include "AUD_Buffer.h"
#include <string>
+#include <boost/shared_ptr.hpp>
struct AVCodecContext;
extern "C" {
@@ -99,7 +99,7 @@ private:
/**
* The memory file to read from.
*/
- AUD_Reference<AUD_Buffer> m_membuffer;
+ boost::shared_ptr<AUD_Buffer> m_membuffer;
/**
* The buffer to read with.
@@ -143,7 +143,7 @@ public:
* \exception AUD_Exception Thrown if the buffer specified cannot be read
* with ffmpeg.
*/
- AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer);
+ AUD_FFMPEGReader(boost::shared_ptr<AUD_Buffer> buffer);
/**
* Destroys the reader and closes the file.
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.cpp b/intern/audaspace/intern/AUD_AnimateableProperty.cpp
index 8a5c538c094..0b333e687ff 100644
--- a/intern/audaspace/intern/AUD_AnimateableProperty.cpp
+++ b/intern/audaspace/intern/AUD_AnimateableProperty.cpp
@@ -28,6 +28,7 @@
#include "AUD_AnimateableProperty.h"
+#include "AUD_MutexLock.h"
#include <cstring>
#include <cmath>
@@ -63,17 +64,15 @@ void AUD_AnimateableProperty::unlock()
void AUD_AnimateableProperty::write(const float* data)
{
- lock();
+ AUD_MutexLock lock(*this);
m_isAnimated = false;
memcpy(getBuffer(), data, m_count * sizeof(float));
-
- unlock();
}
void AUD_AnimateableProperty::write(const float* data, int position, int count)
{
- lock();
+ AUD_MutexLock lock(*this);
m_isAnimated = true;
@@ -87,18 +86,15 @@ void AUD_AnimateableProperty::write(const float* data, int position, int count)
for(int i = pos; i < position; i++)
memcpy(buf + i * m_count, buf + (pos - 1) * m_count, m_count * sizeof(float));
-
- unlock();
}
void AUD_AnimateableProperty::read(float position, float* out)
{
- lock();
+ AUD_MutexLock lock(*this);
if(!m_isAnimated)
{
memcpy(out, getBuffer(), m_count * sizeof(float));
- unlock();
return;
}
@@ -147,8 +143,6 @@ void AUD_AnimateableProperty::read(float position, float* out)
(t3 - 2 * t2 + t) * m0 + (t3 - t2) * m1;
}
}
-
- unlock();
}
bool AUD_AnimateableProperty::isAnimated() const
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.h b/intern/audaspace/intern/AUD_AnimateableProperty.h
index 2f25e330ebd..322748ad571 100644
--- a/intern/audaspace/intern/AUD_AnimateableProperty.h
+++ b/intern/audaspace/intern/AUD_AnimateableProperty.h
@@ -31,13 +31,14 @@
#define __AUD_ANIMATEABLEPROPERTY_H__
#include "AUD_Buffer.h"
+#include "AUD_ILockable.h"
#include <pthread.h>
/**
* This class saves animation data for float properties.
*/
-class AUD_AnimateableProperty : private AUD_Buffer
+class AUD_AnimateableProperty : private AUD_Buffer, public AUD_ILockable
{
private:
/// The count of floats for a single property.
@@ -68,12 +69,12 @@ public:
/**
* Locks the property.
*/
- void lock();
+ virtual void lock();
/**
* Unlocks the previously locked property.
*/
- void unlock();
+ virtual void unlock();
/**
* Writes the properties value and marks it non-animated.
diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp
index dbff70095ad..b9d819ff774 100644
--- a/intern/audaspace/intern/AUD_BufferReader.cpp
+++ b/intern/audaspace/intern/AUD_BufferReader.cpp
@@ -33,7 +33,7 @@
#include <cstring>
-AUD_BufferReader::AUD_BufferReader(AUD_Reference<AUD_Buffer> buffer,
+AUD_BufferReader::AUD_BufferReader(boost::shared_ptr<AUD_Buffer> buffer,
AUD_Specs specs) :
m_position(0), m_buffer(buffer), m_specs(specs)
{
diff --git a/intern/audaspace/intern/AUD_BufferReader.h b/intern/audaspace/intern/AUD_BufferReader.h
index 0e8c5de9a9d..d0c90ce7e61 100644
--- a/intern/audaspace/intern/AUD_BufferReader.h
+++ b/intern/audaspace/intern/AUD_BufferReader.h
@@ -31,9 +31,10 @@
#define __AUD_BUFFERREADER_H__
#include "AUD_IReader.h"
-#include "AUD_Reference.h"
class AUD_Buffer;
+#include <boost/shared_ptr.hpp>
+
/**
* This class represents a simple reader from a buffer that exists in memory.
* \warning Notice that the buffer used for creating the reader must exist as
@@ -50,7 +51,7 @@ private:
/**
* The buffer that is read.
*/
- AUD_Reference<AUD_Buffer> m_buffer;
+ boost::shared_ptr<AUD_Buffer> m_buffer;
/**
* The specification of the sample data in the buffer.
@@ -67,7 +68,7 @@ public:
* \param buffer The buffer to read from.
* \param specs The specification of the sample data in the buffer.
*/
- AUD_BufferReader(AUD_Reference<AUD_Buffer> buffer, AUD_Specs specs);
+ AUD_BufferReader(boost::shared_ptr<AUD_Buffer> buffer, AUD_Specs specs);
virtual bool isSeekable() const;
virtual void seek(int position);
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 46bba237cff..3150c1af011 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -68,6 +68,7 @@
#include "AUD_SequencerFactory.h"
#include "AUD_SequencerEntry.h"
#include "AUD_SilenceFactory.h"
+#include "AUD_MutexLock.h"
#ifdef WITH_SDL
#include "AUD_SDLDevice.h"
@@ -90,10 +91,10 @@ extern "C" {
#include <cassert>
-typedef AUD_Reference<AUD_IFactory> AUD_Sound;
-typedef AUD_Reference<AUD_ReadDevice> AUD_Device;
-typedef AUD_Reference<AUD_IHandle> AUD_Handle;
-typedef AUD_Reference<AUD_SequencerEntry> AUD_SEntry;
+typedef boost::shared_ptr<AUD_IFactory> AUD_Sound;
+typedef boost::shared_ptr<AUD_ReadDevice> AUD_Device;
+typedef boost::shared_ptr<AUD_IHandle> AUD_Handle;
+typedef boost::shared_ptr<AUD_SequencerEntry> AUD_SEntry;
#define AUD_CAPI_IMPLEMENTATION
#include "AUD_C-API.h"
@@ -102,7 +103,7 @@ typedef AUD_Reference<AUD_SequencerEntry> AUD_SEntry;
# define NULL (void *)0
#endif
-static AUD_Reference<AUD_IDevice> AUD_device;
+static boost::shared_ptr<AUD_IDevice> AUD_device;
static AUD_I3DDevice *AUD_3ddevice;
void AUD_initOnce()
@@ -114,25 +115,25 @@ void AUD_initOnce()
int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
{
- AUD_Reference<AUD_IDevice> dev;
+ boost::shared_ptr<AUD_IDevice> dev;
- if (!AUD_device.isNull()) {
+ if (AUD_device.get()) {
AUD_exit();
}
try {
switch(device) {
case AUD_NULL_DEVICE:
- dev = new AUD_NULLDevice();
+ dev = boost::shared_ptr<AUD_IDevice>(new AUD_NULLDevice());
break;
#ifdef WITH_SDL
case AUD_SDL_DEVICE:
- dev = new AUD_SDLDevice(specs, buffersize);
+ dev = boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
break;
#endif
#ifdef WITH_OPENAL
case AUD_OPENAL_DEVICE:
- dev = new AUD_OpenALDevice(specs, buffersize);
+ dev = boost::shared_ptr<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
break;
#endif
#ifdef WITH_JACK
@@ -146,7 +147,7 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
else
{
#endif
- dev = new AUD_JackDevice("Blender", specs, buffersize);
+ dev = boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice("Blender", specs, buffersize));
break;
#ifdef __APPLE__
}
@@ -169,17 +170,17 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
void AUD_exit()
{
- AUD_device = AUD_Reference<AUD_IDevice>();
+ AUD_device = boost::shared_ptr<AUD_IDevice>();
AUD_3ddevice = NULL;
}
#ifdef WITH_PYTHON
static PyObject *AUD_getCDevice(PyObject *self)
{
- if (!AUD_device.isNull()) {
+ if (AUD_device.get()) {
Device *device = (Device *)Device_empty();
if (device != NULL) {
- device->device = new AUD_Reference<AUD_IDevice>(AUD_device);
+ device->device = new boost::shared_ptr<AUD_IDevice>(AUD_device);
return (PyObject *)device;
}
}
@@ -205,12 +206,12 @@ static PyObject *AUD_getSoundFromPointer(PyObject *self, PyObject *args)
if (PyArg_Parse(args, "l:_sound_from_pointer", &lptr)) {
if (lptr) {
- AUD_Reference<AUD_IFactory>* factory = (AUD_Reference<AUD_IFactory>*) sound_get_factory((void *) lptr);
+ boost::shared_ptr<AUD_IFactory>* factory = (boost::shared_ptr<AUD_IFactory>*) sound_get_factory((void *) lptr);
if (factory) {
Factory *obj = (Factory *)Factory_empty();
if (obj) {
- obj->factory = new AUD_Reference<AUD_IFactory>(*factory);
+ obj->factory = new boost::shared_ptr<AUD_IFactory>(*factory);
return (PyObject *) obj;
}
}
@@ -245,7 +246,7 @@ void *AUD_getPythonFactory(AUD_Sound *sound)
if (sound) {
Factory *obj = (Factory *) Factory_empty();
if (obj) {
- obj->factory = new AUD_Reference<AUD_IFactory>(*sound);
+ obj->factory = new boost::shared_ptr<AUD_IFactory>(*sound);
return (PyObject *) obj;
}
}
@@ -260,7 +261,7 @@ AUD_Sound *AUD_getPythonSound(void *sound)
if (!factory)
return NULL;
- return new AUD_Reference<AUD_IFactory>(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(factory->factory));
+ return new boost::shared_ptr<AUD_IFactory>(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(factory->factory));
}
#endif
@@ -285,9 +286,9 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound *sound)
info.length = 0.0f;
try {
- AUD_Reference<AUD_IReader> reader = (*sound)->createReader();
+ boost::shared_ptr<AUD_IReader> reader = (*sound)->createReader();
- if (!reader.isNull()) {
+ if (reader.get()) {
info.specs = reader->getSpecs();
info.length = reader->getLength() / (float) info.specs.rate;
}
@@ -431,7 +432,7 @@ AUD_Handle *AUD_play(AUD_Sound *sound, int keep)
assert(sound);
try {
AUD_Handle handle = AUD_device->play(*sound, keep);
- if (!handle.isNull()) {
+ if (handle.get()) {
return new AUD_Handle(handle);
}
}
@@ -551,9 +552,9 @@ int AUD_setDistanceModel(AUD_DistanceModel model)
int AUD_setSourceLocation(AUD_Handle *handle, const float location[3])
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
AUD_Vector3 v(location[0], location[1], location[2]);
return h->setSourceLocation(v);
}
@@ -564,9 +565,9 @@ int AUD_setSourceLocation(AUD_Handle *handle, const float location[3])
int AUD_setSourceVelocity(AUD_Handle *handle, const float velocity[3])
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
return h->setSourceVelocity(v);
}
@@ -577,9 +578,9 @@ int AUD_setSourceVelocity(AUD_Handle *handle, const float velocity[3])
int AUD_setSourceOrientation(AUD_Handle *handle, const float orientation[4])
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
return h->setSourceOrientation(q);
}
@@ -590,9 +591,9 @@ int AUD_setSourceOrientation(AUD_Handle *handle, const float orientation[4])
int AUD_setRelative(AUD_Handle *handle, int relative)
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
return h->setRelative(relative);
}
@@ -602,9 +603,9 @@ int AUD_setRelative(AUD_Handle *handle, int relative)
int AUD_setVolumeMaximum(AUD_Handle *handle, float volume)
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
return h->setVolumeMaximum(volume);
}
@@ -614,9 +615,9 @@ int AUD_setVolumeMaximum(AUD_Handle *handle, float volume)
int AUD_setVolumeMinimum(AUD_Handle *handle, float volume)
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
return h->setVolumeMinimum(volume);
}
@@ -626,9 +627,9 @@ int AUD_setVolumeMinimum(AUD_Handle *handle, float volume)
int AUD_setDistanceMaximum(AUD_Handle *handle, float distance)
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
return h->setDistanceMaximum(distance);
}
@@ -638,9 +639,9 @@ int AUD_setDistanceMaximum(AUD_Handle *handle, float distance)
int AUD_setDistanceReference(AUD_Handle *handle, float distance)
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
return h->setDistanceReference(distance);
}
@@ -650,9 +651,9 @@ int AUD_setDistanceReference(AUD_Handle *handle, float distance)
int AUD_setAttenuation(AUD_Handle *handle, float factor)
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
return h->setAttenuation(factor);
}
@@ -662,9 +663,9 @@ int AUD_setAttenuation(AUD_Handle *handle, float factor)
int AUD_setConeAngleOuter(AUD_Handle *handle, float angle)
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
return h->setConeAngleOuter(angle);
}
@@ -674,9 +675,9 @@ int AUD_setConeAngleOuter(AUD_Handle *handle, float angle)
int AUD_setConeAngleInner(AUD_Handle *handle, float angle)
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
return h->setConeAngleInner(angle);
}
@@ -686,9 +687,9 @@ int AUD_setConeAngleInner(AUD_Handle *handle, float angle)
int AUD_setConeVolumeOuter(AUD_Handle *handle, float volume)
{
assert(handle);
- AUD_Reference<AUD_I3DHandle> h(*handle);
+ boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
- if (!h.isNull()) {
+ if (h.get()) {
return h->setConeVolumeOuter(volume);
}
@@ -733,7 +734,7 @@ AUD_Handle *AUD_playDevice(AUD_Device *device, AUD_Sound *sound, float seek)
try {
AUD_Handle handle = (*device)->play(*sound);
- if (!handle.isNull()) {
+ if (handle.get()) {
handle->seek(seek);
return new AUD_Handle(handle);
}
@@ -792,38 +793,38 @@ float *AUD_readSoundBuffer(const char *filename, float low, float high,
AUD_DeviceSpecs specs;
specs.channels = AUD_CHANNELS_MONO;
specs.rate = (AUD_SampleRate)samplerate;
- AUD_Reference<AUD_IFactory> sound;
+ boost::shared_ptr<AUD_IFactory> sound;
- AUD_Reference<AUD_IFactory> file = new AUD_FileFactory(filename);
+ boost::shared_ptr<AUD_IFactory> file = boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename));
int position = 0;
try {
- AUD_Reference<AUD_IReader> reader = file->createReader();
+ boost::shared_ptr<AUD_IReader> reader = file->createReader();
AUD_SampleRate rate = reader->getSpecs().rate;
- sound = new AUD_ChannelMapperFactory(file, specs);
+ sound = boost::shared_ptr<AUD_IFactory>(new AUD_ChannelMapperFactory(file, specs));
if (high < rate)
- sound = new AUD_LowpassFactory(sound, high);
+ sound = boost::shared_ptr<AUD_IFactory>(new AUD_LowpassFactory(sound, high));
if (low > 0)
- sound = new AUD_HighpassFactory(sound, low);
+ sound = boost::shared_ptr<AUD_IFactory>(new AUD_HighpassFactory(sound, low));
- sound = new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f);
- sound = new AUD_LinearResampleFactory(sound, specs);
+ sound = boost::shared_ptr<AUD_IFactory>(new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f));
+ sound = boost::shared_ptr<AUD_IFactory>(new AUD_LinearResampleFactory(sound, specs));
if (square)
- sound = new AUD_SquareFactory(sound, sthreshold);
+ sound = boost::shared_ptr<AUD_IFactory>(new AUD_SquareFactory(sound, sthreshold));
if (accumulate)
- sound = new AUD_AccumulatorFactory(sound, additive);
+ sound = boost::shared_ptr<AUD_IFactory>(new AUD_AccumulatorFactory(sound, additive));
else if (additive)
- sound = new AUD_SumFactory(sound);
+ sound = boost::shared_ptr<AUD_IFactory>(new AUD_SumFactory(sound));
reader = sound->createReader();
- if (reader.isNull())
+ if (!reader.get())
return NULL;
int len;
@@ -855,16 +856,15 @@ static void pauseSound(AUD_Handle *handle)
AUD_Handle *AUD_pauseAfter(AUD_Handle *handle, float seconds)
{
- AUD_Reference<AUD_IFactory> silence = new AUD_SilenceFactory;
- AUD_Reference<AUD_IFactory> limiter = new AUD_LimiterFactory(silence, 0, seconds);
+ boost::shared_ptr<AUD_IFactory> silence = boost::shared_ptr<AUD_IFactory>(new AUD_SilenceFactory);
+ boost::shared_ptr<AUD_IFactory> limiter = boost::shared_ptr<AUD_IFactory>(new AUD_LimiterFactory(silence, 0, seconds));
- AUD_device->lock();
+ AUD_MutexLock lock(*AUD_device);
try {
AUD_Handle handle2 = AUD_device->play(limiter);
- if (!handle2.isNull()) {
+ if (handle2.get()) {
handle2->setStopCallback((stopCallback)pauseSound, handle);
- AUD_device->unlock();
return new AUD_Handle(handle2);
}
}
@@ -872,8 +872,6 @@ AUD_Handle *AUD_pauseAfter(AUD_Handle *handle, float seconds)
{
}
- AUD_device->unlock();
-
return NULL;
}
@@ -883,7 +881,7 @@ AUD_Sound *AUD_createSequencer(float fps, int muted)
AUD_Specs specs;
specs.channels = AUD_CHANNELS_STEREO;
specs.rate = AUD_RATE_44100;
- AUD_Sound *sequencer = new AUD_Sound(AUD_Reference<AUD_SequencerFactory>(new AUD_SequencerFactory(specs, fps, muted)));
+ AUD_Sound *sequencer = new AUD_Sound(boost::shared_ptr<AUD_SequencerFactory>(new AUD_SequencerFactory(specs, fps, muted)));
return sequencer;
}
@@ -1072,7 +1070,7 @@ int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_pe
specs.channels = AUD_CHANNELS_MONO;
specs.format = AUD_FORMAT_INVALID;
- AUD_Reference<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();
+ boost::shared_ptr<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();
specs.specs = reader->getSpecs();
int len;
@@ -1126,7 +1124,7 @@ int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_pe
AUD_Sound *AUD_copy(AUD_Sound *sound)
{
- return new AUD_Reference<AUD_IFactory>(*sound);
+ return new boost::shared_ptr<AUD_IFactory>(*sound);
}
void AUD_freeHandle(AUD_Handle *handle)
@@ -1178,9 +1176,9 @@ const char *AUD_mixdown(AUD_Sound *sound, unsigned int start, unsigned int lengt
AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sound->get());
f->setSpecs(specs.specs);
- AUD_Reference<AUD_IReader> reader = f->createQualityReader();
+ boost::shared_ptr<AUD_IReader> reader = f->createQualityReader();
reader->seek(start);
- AUD_Reference<AUD_IWriter> writer = AUD_FileWriter::createWriter(filename, specs, format, codec, bitrate);
+ boost::shared_ptr<AUD_IWriter> writer = AUD_FileWriter::createWriter(filename, specs, format, codec, bitrate);
AUD_FileWriter::writeReader(reader, writer, length, buffersize);
return NULL;
@@ -1198,7 +1196,7 @@ const char *AUD_mixdown_per_channel(AUD_Sound *sound, unsigned int start, unsign
f->setSpecs(specs.specs);
- std::vector<AUD_Reference<AUD_IWriter> > writers;
+ std::vector<boost::shared_ptr<AUD_IWriter> > writers;
int channels = specs.channels;
specs.channels = AUD_CHANNELS_MONO;
@@ -1222,7 +1220,7 @@ const char *AUD_mixdown_per_channel(AUD_Sound *sound, unsigned int start, unsign
writers.push_back(AUD_FileWriter::createWriter(stream.str(), specs, format, codec, bitrate));
}
- AUD_Reference<AUD_IReader> reader = f->createQualityReader();
+ boost::shared_ptr<AUD_IReader> reader = f->createQualityReader();
reader->seek(start);
AUD_FileWriter::writeReader(reader, writers, length, buffersize);
@@ -1244,7 +1242,7 @@ AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, f
dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setSpecs(specs.specs);
AUD_Handle handle = device->play(*sequencer);
- if (!handle.isNull()) {
+ if (handle.get()) {
handle->seek(start);
}
@@ -1256,7 +1254,7 @@ AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, f
}
}
-AUD_Reference<AUD_IDevice> AUD_getDevice()
+boost::shared_ptr<AUD_IDevice> AUD_getDevice()
{
return AUD_device;
}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index 75e3456de9a..9c6611fe04a 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -755,7 +755,7 @@ extern AUD_Sound *AUD_getPythonSound(void *sound);
#ifdef __cplusplus
}
-#include "AUD_Reference.h"
+#include <boost/shared_ptr.hpp>
class AUD_IDevice;
class AUD_I3DDevice;
@@ -763,7 +763,7 @@ class AUD_I3DDevice;
* Returns the current playback device.
* \return The playback device.
*/
-AUD_Reference<AUD_IDevice> AUD_getDevice();
+boost::shared_ptr<AUD_IDevice> AUD_getDevice();
/**
* Returns the current playback 3D device.
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
index 7743ccf46da..f4ba5d05ff0 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
@@ -32,14 +32,14 @@
#include <cstring>
-AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Reference<AUD_IFactory> factory,
+AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(boost::shared_ptr<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
}
-AUD_Reference<AUD_IReader> AUD_ChannelMapperFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_ChannelMapperFactory::createReader()
{
- AUD_Reference<AUD_IReader> reader = getReader();
- return new AUD_ChannelMapperReader(reader, m_specs.channels);
+ boost::shared_ptr<AUD_IReader> reader = getReader();
+ return boost::shared_ptr<AUD_IReader>(new AUD_ChannelMapperReader(reader, m_specs.channels));
}
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.h b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
index b60a32d5510..611b5041c39 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.h
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
@@ -49,9 +49,9 @@ public:
* \param factory The input factory.
* \param specs The target specifications.
*/
- AUD_ChannelMapperFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
+ AUD_ChannelMapperFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_CHANNELMAPPERFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
index 61796098bf7..8b983d5c43d 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
@@ -38,7 +38,7 @@
#include "AUD_ChannelMapperReader.h"
-AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader,
+AUD_ChannelMapperReader::AUD_ChannelMapperReader(boost::shared_ptr<AUD_IReader> reader,
AUD_Channels channels) :
AUD_EffectReader(reader), m_target_channels(channels),
m_source_channels(AUD_CHANNELS_INVALID), m_mapping(0), m_map_size(0), m_mono_angle(0)
@@ -67,10 +67,12 @@ void AUD_ChannelMapperReader::setMonoAngle(float angle)
float AUD_ChannelMapperReader::angleDistance(float alpha, float beta)
{
- alpha = fabs(alpha - beta);
+ alpha = beta - alpha;
if(alpha > M_PI)
- alpha = fabs(alpha - 2 * M_PI);
+ alpha -= 2 * M_PI;
+ if(alpha < -M_PI)
+ alpha += 2 * M_PI;
return alpha;
}
@@ -107,8 +109,8 @@ void AUD_ChannelMapperReader::calculateMapping()
if(m_source_channels == AUD_CHANNELS_MONO)
source_angles = &m_mono_angle;
- int channel_min1, channel_min2;
- float angle_min1, angle_min2, angle;
+ int channel_left, channel_right;
+ float angle_left, angle_right, angle;
for(int i = 0; i < m_source_channels; i++)
{
@@ -120,38 +122,46 @@ void AUD_ChannelMapperReader::calculateMapping()
continue;
}
- channel_min1 = channel_min2 = -1;
- angle_min1 = angle_min2 = 2 * M_PI;
+ channel_left = channel_right = -1;
+ angle_left = -2 * M_PI;
+ angle_right = 2 * M_PI;
for(int j = 0; j < m_target_channels; j++)
{
if(j == lfe)
continue;
angle = angleDistance(source_angles[i], target_angles[j]);
- if(angle < angle_min1)
+ if(angle < 0)
{
- channel_min2 = channel_min1;
- angle_min2 = angle_min1;
-
- channel_min1 = j;
- angle_min1 = angle;
+ if(angle > angle_left)
+ {
+ angle_left = angle;
+ channel_left = j;
+ }
}
- else if(angle < angle_min2)
+ else
{
- channel_min2 = j;
- angle_min2 = angle;
+ if(angle < angle_right)
+ {
+ angle_right = angle;
+ channel_right = j;
+ }
}
}
- angle = angle_min1 + angle_min2;
- if(channel_min2 == -1 || angle == 0)
+ angle = angle_right - angle_left;
+ if(channel_right == -1 || angle == 0)
+ {
+ m_mapping[channel_left * m_source_channels + i] = 1;
+ }
+ else if(channel_left == -1)
{
- m_mapping[channel_min1 * m_source_channels + i] = 1;
+ m_mapping[channel_right * m_source_channels + i] = 1;
}
else
{
- m_mapping[channel_min1 * m_source_channels + i] = cos(M_PI_2 * angle_min1 / angle);
- m_mapping[channel_min2 * m_source_channels + i] = cos(M_PI_2 * angle_min2 / angle);
+ m_mapping[channel_left * m_source_channels + i] = cos(M_PI_2 * angle_left / angle);
+ m_mapping[channel_right * m_source_channels + i] = cos(M_PI_2 * angle_right / angle);
}
}
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.h b/intern/audaspace/intern/AUD_ChannelMapperReader.h
index 32adb058115..b122b070d29 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.h
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.h
@@ -110,7 +110,7 @@ public:
* \param reader The reader to map.
* \param mapping The mapping specification as two dimensional float array.
*/
- AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader, AUD_Channels channels);
+ AUD_ChannelMapperReader(boost::shared_ptr<AUD_IReader> reader, AUD_Channels channels);
/**
* Destroys the reader.
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.cpp b/intern/audaspace/intern/AUD_ConverterFactory.cpp
index b61f9bc194c..7cbf64f1697 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.cpp
+++ b/intern/audaspace/intern/AUD_ConverterFactory.cpp
@@ -30,18 +30,18 @@
#include "AUD_ConverterFactory.h"
#include "AUD_ConverterReader.h"
-AUD_ConverterFactory::AUD_ConverterFactory(AUD_Reference<AUD_IFactory> factory,
+AUD_ConverterFactory::AUD_ConverterFactory(boost::shared_ptr<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
}
-AUD_Reference<AUD_IReader> AUD_ConverterFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_ConverterFactory::createReader()
{
- AUD_Reference<AUD_IReader> reader = getReader();
+ boost::shared_ptr<AUD_IReader> reader = getReader();
if(m_specs.format != AUD_FORMAT_FLOAT32)
- reader = new AUD_ConverterReader(reader, m_specs);
+ reader = boost::shared_ptr<AUD_IReader>(new AUD_ConverterReader(reader, m_specs));
return reader;
}
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.h b/intern/audaspace/intern/AUD_ConverterFactory.h
index 3211b607517..2c9c82d235b 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.h
+++ b/intern/audaspace/intern/AUD_ConverterFactory.h
@@ -49,9 +49,9 @@ public:
* \param factory The input factory.
* \param specs The target specifications.
*/
- AUD_ConverterFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
+ AUD_ConverterFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_CONVERTERFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_ConverterReader.cpp b/intern/audaspace/intern/AUD_ConverterReader.cpp
index 63178f316b2..a90a54670e8 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.cpp
+++ b/intern/audaspace/intern/AUD_ConverterReader.cpp
@@ -29,7 +29,7 @@
#include "AUD_ConverterReader.h"
-AUD_ConverterReader::AUD_ConverterReader(AUD_Reference<AUD_IReader> reader,
+AUD_ConverterReader::AUD_ConverterReader(boost::shared_ptr<AUD_IReader> reader,
AUD_DeviceSpecs specs) :
AUD_EffectReader(reader),
m_format(specs.format)
diff --git a/intern/audaspace/intern/AUD_ConverterReader.h b/intern/audaspace/intern/AUD_ConverterReader.h
index 2dedbd89180..987b7c70279 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.h
+++ b/intern/audaspace/intern/AUD_ConverterReader.h
@@ -65,7 +65,7 @@ public:
* \param reader The reader to convert.
* \param specs The target specification.
*/
- AUD_ConverterReader(AUD_Reference<AUD_IReader> reader, AUD_DeviceSpecs specs);
+ AUD_ConverterReader(boost::shared_ptr<AUD_IReader> reader, AUD_DeviceSpecs specs);
virtual void read(int& length, bool& eos, sample_t* buffer);
};
diff --git a/intern/audaspace/intern/AUD_FileFactory.cpp b/intern/audaspace/intern/AUD_FileFactory.cpp
index a27acff19cf..f9353db6677 100644
--- a/intern/audaspace/intern/AUD_FileFactory.cpp
+++ b/intern/audaspace/intern/AUD_FileFactory.cpp
@@ -56,15 +56,15 @@ AUD_FileFactory::AUD_FileFactory(const data_t* buffer, int size) :
static const char* read_error = "AUD_FileFactory: File couldn't be read.";
-AUD_Reference<AUD_IReader> AUD_FileFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_FileFactory::createReader()
{
#ifdef WITH_SNDFILE
try
{
- if(m_buffer.isNull())
- return new AUD_SndFileReader(m_filename);
+ if(m_buffer.get())
+ return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_buffer));
else
- return new AUD_SndFileReader(m_buffer);
+ return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_filename));
}
catch(AUD_Exception&) {}
#endif
@@ -72,10 +72,10 @@ AUD_Reference<AUD_IReader> AUD_FileFactory::createReader()
#ifdef WITH_FFMPEG
try
{
- if(m_buffer.isNull())
- return new AUD_FFMPEGReader(m_filename);
+ if(m_buffer.get())
+ return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_buffer));
else
- return new AUD_FFMPEGReader(m_buffer);
+ return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_filename));
}
catch(AUD_Exception&) {}
#endif
diff --git a/intern/audaspace/intern/AUD_FileFactory.h b/intern/audaspace/intern/AUD_FileFactory.h
index 4ea4a9392e9..35c8db731b4 100644
--- a/intern/audaspace/intern/AUD_FileFactory.h
+++ b/intern/audaspace/intern/AUD_FileFactory.h
@@ -31,10 +31,10 @@
#define __AUD_FILEFACTORY_H__
#include "AUD_IFactory.h"
-#include "AUD_Reference.h"
#include "AUD_Buffer.h"
#include <string>
+#include <boost/shared_ptr.hpp>
/**
* This factory tries to read a sound file via all available file readers.
@@ -50,7 +50,7 @@ private:
/**
* The buffer to read from.
*/
- AUD_Reference<AUD_Buffer> m_buffer;
+ boost::shared_ptr<AUD_Buffer> m_buffer;
// hide copy constructor and operator=
AUD_FileFactory(const AUD_FileFactory&);
@@ -70,7 +70,7 @@ public:
*/
AUD_FileFactory(const data_t* buffer, int size);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_FILEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_FileWriter.cpp b/intern/audaspace/intern/AUD_FileWriter.cpp
index f74021acad1..e3072fa82e0 100644
--- a/intern/audaspace/intern/AUD_FileWriter.cpp
+++ b/intern/audaspace/intern/AUD_FileWriter.cpp
@@ -43,13 +43,13 @@
static const char* write_error = "AUD_FileWriter: File couldn't be written.";
-AUD_Reference<AUD_IWriter> AUD_FileWriter::createWriter(std::string filename,AUD_DeviceSpecs specs,
+boost::shared_ptr<AUD_IWriter> AUD_FileWriter::createWriter(std::string filename,AUD_DeviceSpecs specs,
AUD_Container format, AUD_Codec codec, unsigned int bitrate)
{
#ifdef WITH_SNDFILE
try
{
- return new AUD_SndFileWriter(filename, specs, format, codec, bitrate);
+ return boost::shared_ptr<AUD_IWriter>(new AUD_SndFileWriter(filename, specs, format, codec, bitrate));
}
catch(AUD_Exception&) {}
#endif
@@ -57,7 +57,7 @@ AUD_Reference<AUD_IWriter> AUD_FileWriter::createWriter(std::string filename,AUD
#ifdef WITH_FFMPEG
try
{
- return new AUD_FFMPEGWriter(filename, specs, format, codec, bitrate);
+ return boost::shared_ptr<AUD_IWriter>(new AUD_FFMPEGWriter(filename, specs, format, codec, bitrate));
}
catch(AUD_Exception&) {}
#endif
@@ -65,7 +65,7 @@ AUD_Reference<AUD_IWriter> AUD_FileWriter::createWriter(std::string filename,AUD
AUD_THROW(AUD_ERROR_SPECS, write_error);
}
-void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_IWriter> writer, unsigned int length, unsigned int buffersize)
+void AUD_FileWriter::writeReader(boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_IWriter> writer, unsigned int length, unsigned int buffersize)
{
AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(writer->getSpecs()));
sample_t* buf = buffer.getBuffer();
@@ -94,7 +94,7 @@ void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, AUD_Referenc
}
}
-void AUD_FileWriter::writeReader(AUD_Reference<AUD_IReader> reader, std::vector<AUD_Reference<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize)
+void AUD_FileWriter::writeReader(boost::shared_ptr<AUD_IReader> reader, std::vector<boost::shared_ptr<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize)
{
AUD_Buffer buffer(buffersize * AUD_SAMPLE_SIZE(reader->getSpecs()));
AUD_Buffer buffer2(buffersize * sizeof(sample_t));
diff --git a/intern/audaspace/intern/AUD_FileWriter.h b/intern/audaspace/intern/AUD_FileWriter.h
index 385aba5ef45..da52c7e0fb2 100644
--- a/intern/audaspace/intern/AUD_FileWriter.h
+++ b/intern/audaspace/intern/AUD_FileWriter.h
@@ -32,8 +32,7 @@
#include <string>
#include <vector>
-
-#include "AUD_Reference.h"
+#include <boost/shared_ptr.hpp>
#include "AUD_IWriter.h"
#include "AUD_IReader.h"
@@ -59,7 +58,7 @@ public:
* \param bitrate The bitrate for encoding.
* \return The writer to write data to.
*/
- static AUD_Reference<AUD_IWriter> createWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
+ static boost::shared_ptr<AUD_IWriter> createWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
/**
* Writes a reader to a writer.
@@ -68,7 +67,7 @@ public:
* \param length How many samples should be transfered.
* \param buffersize How many samples should be transfered at once.
*/
- static void writeReader(AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_IWriter> writer, unsigned int length, unsigned int buffersize);
+ static void writeReader(boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_IWriter> writer, unsigned int length, unsigned int buffersize);
/**
* Writes a reader to several writers.
@@ -77,7 +76,7 @@ public:
* \param length How many samples should be transfered.
* \param buffersize How many samples should be transfered at once.
*/
- static void writeReader(AUD_Reference<AUD_IReader> reader, std::vector<AUD_Reference<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize);
+ static void writeReader(boost::shared_ptr<AUD_IReader> reader, std::vector<boost::shared_ptr<AUD_IWriter> >& writers, unsigned int length, unsigned int buffersize);
};
#endif //__AUD_FILEWRITER_H__
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
index 1d6f8ca6efb..a7f9a985ce4 100644
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ b/intern/audaspace/intern/AUD_IDevice.h
@@ -31,10 +31,12 @@
#define __AUD_IDEVICE_H__
#include "AUD_Space.h"
-#include "AUD_Reference.h"
#include "AUD_IFactory.h"
#include "AUD_IReader.h"
#include "AUD_IHandle.h"
+#include "AUD_ILockable.h"
+
+#include <boost/shared_ptr.hpp>
/**
* This class represents an output device for sound sources.
@@ -44,7 +46,7 @@
* \warning Thread safety must be insured so that no reader is beeing called
* twice at the same time.
*/
-class AUD_IDevice
+class AUD_IDevice : public AUD_ILockable
{
public:
/**
@@ -67,7 +69,7 @@ public:
* \exception AUD_Exception Thrown if there's an unexpected (from the
* device side) error during creation of the reader.
*/
- virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false)=0;
+ virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false)=0;
/**
* Plays a sound source.
@@ -79,7 +81,7 @@ public:
* \exception AUD_Exception Thrown if there's an unexpected (from the
* device side) error during creation of the reader.
*/
- virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false)=0;
+ virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false)=0;
/**
* Stops all playing sounds.
diff --git a/intern/audaspace/intern/AUD_IFactory.h b/intern/audaspace/intern/AUD_IFactory.h
index 95b4643072e..75103963c68 100644
--- a/intern/audaspace/intern/AUD_IFactory.h
+++ b/intern/audaspace/intern/AUD_IFactory.h
@@ -31,9 +31,10 @@
#define __AUD_IFACTORY_H__
#include "AUD_Space.h"
-#include "AUD_Reference.h"
#include "AUD_IReader.h"
+#include <boost/shared_ptr.hpp>
+
/**
* This class represents a type of sound source and saves the necessary values
* for it. It is able to create a reader that is actually usable for playback
@@ -54,7 +55,7 @@ public:
* \exception AUD_Exception An exception may be thrown if there has been
* a more unexpected error during reader creation.
*/
- virtual AUD_Reference<AUD_IReader> createReader()=0;
+ virtual boost::shared_ptr<AUD_IReader> createReader()=0;
};
#endif //__AUD_IFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_ILockable.h b/intern/audaspace/intern/AUD_ILockable.h
new file mode 100644
index 00000000000..9bc417504fe
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ILockable.h
@@ -0,0 +1,21 @@
+#ifndef AUD_ILOCKABLE_H
+#define AUD_ILOCKABLE_H
+
+/**
+ * This class provides an interface for lockable objects.
+ * The main reason for this interface is to be used with AUD_MutexLock.
+ */
+class AUD_ILockable
+{
+public:
+ /**
+ * Locks the object.
+ */
+ virtual void lock()=0;
+ /**
+ * Unlocks the previously locked object.
+ */
+ virtual void unlock()=0;
+};
+
+#endif // AUD_ILOCKABLE_H
diff --git a/intern/audaspace/intern/AUD_JOSResampleFactory.cpp b/intern/audaspace/intern/AUD_JOSResampleFactory.cpp
index 21aae6b0547..188960f986f 100644
--- a/intern/audaspace/intern/AUD_JOSResampleFactory.cpp
+++ b/intern/audaspace/intern/AUD_JOSResampleFactory.cpp
@@ -30,13 +30,13 @@
#include "AUD_JOSResampleFactory.h"
#include "AUD_JOSResampleReader.h"
-AUD_JOSResampleFactory::AUD_JOSResampleFactory(AUD_Reference<AUD_IFactory> factory,
+AUD_JOSResampleFactory::AUD_JOSResampleFactory(boost::shared_ptr<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
}
-AUD_Reference<AUD_IReader> AUD_JOSResampleFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_JOSResampleFactory::createReader()
{
- return new AUD_JOSResampleReader(getReader(), m_specs.specs);
+ return boost::shared_ptr<AUD_IReader>(new AUD_JOSResampleReader(getReader(), m_specs.specs));
}
diff --git a/intern/audaspace/intern/AUD_JOSResampleFactory.h b/intern/audaspace/intern/AUD_JOSResampleFactory.h
index 6d18150d852..b6c2961c88a 100644
--- a/intern/audaspace/intern/AUD_JOSResampleFactory.h
+++ b/intern/audaspace/intern/AUD_JOSResampleFactory.h
@@ -48,9 +48,9 @@ public:
* \param factory The input factory.
* \param specs The target specifications.
*/
- AUD_JOSResampleFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
+ AUD_JOSResampleFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_JOSRESAMPLEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_JOSResampleReader.cpp b/intern/audaspace/intern/AUD_JOSResampleReader.cpp
index 0f7a038c88e..62fab48272b 100644
--- a/intern/audaspace/intern/AUD_JOSResampleReader.cpp
+++ b/intern/audaspace/intern/AUD_JOSResampleReader.cpp
@@ -68,7 +68,7 @@ static inline int lrint(double d)
#define fp_rest(x) (x & ((1 << SHIFT_BITS) - 1))
#define fp_rest_to_double(x) fp_to_double(fp_rest(x))
-AUD_JOSResampleReader::AUD_JOSResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs) :
+AUD_JOSResampleReader::AUD_JOSResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_Specs specs) :
AUD_ResampleReader(reader, specs.rate),
m_channels(AUD_CHANNELS_INVALID),
m_n(0),
diff --git a/intern/audaspace/intern/AUD_JOSResampleReader.h b/intern/audaspace/intern/AUD_JOSResampleReader.h
index 94524c1db3e..fb68e4dc9f5 100644
--- a/intern/audaspace/intern/AUD_JOSResampleReader.h
+++ b/intern/audaspace/intern/AUD_JOSResampleReader.h
@@ -123,7 +123,7 @@ public:
* \param reader The reader to mix.
* \param specs The target specification.
*/
- AUD_JOSResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs);
+ AUD_JOSResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_Specs specs);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
index 7f602599b7a..cd573f1047c 100644
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
@@ -30,13 +30,13 @@
#include "AUD_LinearResampleFactory.h"
#include "AUD_LinearResampleReader.h"
-AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_Reference<AUD_IFactory> factory,
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(boost::shared_ptr<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
}
-AUD_Reference<AUD_IReader> AUD_LinearResampleFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_LinearResampleFactory::createReader()
{
- return new AUD_LinearResampleReader(getReader(), m_specs.specs);
+ return boost::shared_ptr<AUD_IReader>(new AUD_LinearResampleReader(getReader(), m_specs.specs));
}
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.h b/intern/audaspace/intern/AUD_LinearResampleFactory.h
index 7d9efa01d2d..ceb29ef2edd 100644
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.h
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.h
@@ -48,9 +48,9 @@ public:
* \param factory The input factory.
* \param specs The target specifications.
*/
- AUD_LinearResampleFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
+ AUD_LinearResampleFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_LINEARRESAMPLEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
index aff62d7c3aa..6aa0faed863 100644
--- a/intern/audaspace/intern/AUD_LinearResampleReader.cpp
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
@@ -34,7 +34,7 @@
#define CC m_channels + channel
-AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_Reference<AUD_IReader> reader,
+AUD_LinearResampleReader::AUD_LinearResampleReader(boost::shared_ptr<AUD_IReader> reader,
AUD_Specs specs) :
AUD_ResampleReader(reader, specs.rate),
m_channels(reader->getSpecs().channels),
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.h b/intern/audaspace/intern/AUD_LinearResampleReader.h
index 4f6d422f772..9beea251c07 100644
--- a/intern/audaspace/intern/AUD_LinearResampleReader.h
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.h
@@ -74,7 +74,7 @@ public:
* \param reader The reader to mix.
* \param specs The target specification.
*/
- AUD_LinearResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs);
+ AUD_LinearResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_Specs specs);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/intern/AUD_Mixer.h b/intern/audaspace/intern/AUD_Mixer.h
index 0de9b7fc7dc..3dd03b0a3fe 100644
--- a/intern/audaspace/intern/AUD_Mixer.h
+++ b/intern/audaspace/intern/AUD_Mixer.h
@@ -32,9 +32,10 @@
#include "AUD_ConverterFunctions.h"
#include "AUD_Buffer.h"
-#include "AUD_Reference.h"
class AUD_IReader;
+#include <boost/shared_ptr.hpp>
+
/**
* This abstract class is able to mix audiosignals with same channel count
* and sample rate and convert it to a specific output format.
diff --git a/intern/audaspace/intern/AUD_MixerFactory.cpp b/intern/audaspace/intern/AUD_MixerFactory.cpp
index 95a7291d3eb..f3f00ea2cb6 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.cpp
+++ b/intern/audaspace/intern/AUD_MixerFactory.cpp
@@ -30,12 +30,12 @@
#include "AUD_MixerFactory.h"
#include "AUD_IReader.h"
-AUD_Reference<AUD_IReader> AUD_MixerFactory::getReader() const
+boost::shared_ptr<AUD_IReader> AUD_MixerFactory::getReader() const
{
return m_factory->createReader();
}
-AUD_MixerFactory::AUD_MixerFactory(AUD_Reference<AUD_IFactory> factory,
+AUD_MixerFactory::AUD_MixerFactory(boost::shared_ptr<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
m_specs(specs), m_factory(factory)
{
@@ -46,7 +46,7 @@ AUD_DeviceSpecs AUD_MixerFactory::getSpecs() const
return m_specs;
}
-AUD_Reference<AUD_IFactory> AUD_MixerFactory::getFactory() const
+boost::shared_ptr<AUD_IFactory> AUD_MixerFactory::getFactory() const
{
return m_factory;
}
diff --git a/intern/audaspace/intern/AUD_MixerFactory.h b/intern/audaspace/intern/AUD_MixerFactory.h
index d65eb8ef6ae..1d2b6a4cc91 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.h
+++ b/intern/audaspace/intern/AUD_MixerFactory.h
@@ -46,7 +46,7 @@ protected:
/**
* If there is no reader it is created out of this factory.
*/
- AUD_Reference<AUD_IFactory> m_factory;
+ boost::shared_ptr<AUD_IFactory> m_factory;
/**
* Returns the reader created out of the factory.
@@ -54,7 +54,7 @@ protected:
* classes.
* \return The reader to mix.
*/
- AUD_Reference<AUD_IReader> getReader() const;
+ boost::shared_ptr<AUD_IReader> getReader() const;
public:
/**
@@ -62,7 +62,7 @@ public:
* \param factory The factory to create the readers to mix out of.
* \param specs The target specification.
*/
- AUD_MixerFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
+ AUD_MixerFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
/**
* Returns the target specification for resampling.
@@ -73,7 +73,7 @@ public:
* Returns the saved factory.
* \return The factory.
*/
- AUD_Reference<AUD_IFactory> getFactory() const;
+ boost::shared_ptr<AUD_IFactory> getFactory() const;
};
#endif //__AUD_MIXERFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_MutexLock.h b/intern/audaspace/intern/AUD_MutexLock.h
new file mode 100644
index 00000000000..b6f6d2b4334
--- /dev/null
+++ b/intern/audaspace/intern/AUD_MutexLock.h
@@ -0,0 +1,24 @@
+#ifndef AUD_MUTEXLOCK_H
+#define AUD_MUTEXLOCK_H
+
+#include "AUD_ILockable.h"
+
+class AUD_MutexLock
+{
+public:
+ inline AUD_MutexLock(AUD_ILockable& lockable) :
+ lockable(lockable)
+ {
+ lockable.lock();
+ }
+
+ inline ~AUD_MutexLock()
+ {
+ lockable.unlock();
+ }
+
+private:
+ AUD_ILockable& lockable;
+};
+
+#endif // AUD_MUTEXLOCK_H
diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
index f390971c686..98a0d324c61 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ b/intern/audaspace/intern/AUD_NULLDevice.cpp
@@ -127,14 +127,14 @@ AUD_DeviceSpecs AUD_NULLDevice::getSpecs() const
return specs;
}
-AUD_Reference<AUD_IHandle> AUD_NULLDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
+boost::shared_ptr<AUD_IHandle> AUD_NULLDevice::play(boost::shared_ptr<AUD_IReader> reader, bool keep)
{
- return new AUD_NULLHandle();
+ return boost::shared_ptr<AUD_IHandle>(new AUD_NULLHandle());
}
-AUD_Reference<AUD_IHandle> AUD_NULLDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
+boost::shared_ptr<AUD_IHandle> AUD_NULLDevice::play(boost::shared_ptr<AUD_IFactory> factory, bool keep)
{
- return new AUD_NULLHandle();
+ return boost::shared_ptr<AUD_IHandle>(new AUD_NULLHandle());
}
void AUD_NULLDevice::stopAll()
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
index ee97b151ebe..ae1435bbeea 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ b/intern/audaspace/intern/AUD_NULLDevice.h
@@ -72,8 +72,8 @@ public:
virtual ~AUD_NULLDevice();
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
- virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
+ virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false);
+ virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false);
virtual void stopAll();
virtual void lock();
virtual void unlock();
diff --git a/intern/audaspace/intern/AUD_Reference.h b/intern/audaspace/intern/AUD_Reference.h
deleted file mode 100644
index 5a1aa947148..00000000000
--- a/intern/audaspace/intern/AUD_Reference.h
+++ /dev/null
@@ -1,275 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 Jörg Hermann Müller
- *
- * This file is part of AudaSpace.
- *
- * Audaspace is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * AudaSpace is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_Reference.h
- * \ingroup audaspaceintern
- */
-
-#ifndef __AUD_REFERENCE_H__
-#define __AUD_REFERENCE_H__
-
-#include <map>
-#include <cstddef>
-#include <pthread.h>
-
-// #define MEM_DEBUG
-
-#ifdef MEM_DEBUG
-#include <iostream>
-#include <typeinfo>
-#endif
-
-/**
- * This class handles the reference counting.
- */
-class AUD_ReferenceHandler
-{
-private:
- /**
- * Saves the reference counts.
- */
- static std::map<void*, unsigned int> m_references;
- static pthread_mutex_t m_mutex;
- static bool m_mutex_initialised;
-
-public:
-
- static pthread_mutex_t* getMutex();
-
- /**
- * Reference increment.
- * \param reference The reference.
- */
- static inline void incref(void* reference)
- {
- if(!reference)
- return;
-
- std::map<void*, unsigned int>::iterator result = m_references.find(reference);
- if(result != m_references.end())
- {
- m_references[reference]++;
- }
- else
- {
- m_references[reference] = 1;
- }
- }
-
- /**
- * Reference decrement.
- * \param reference The reference.
- * \return Whether the reference has to be deleted.
- */
- static inline bool decref(void* reference)
- {
- if(!reference)
- return false;
-
- if(!--m_references[reference])
- {
- m_references.erase(reference);
- return true;
- }
- return false;
- }
-};
-
-template <class T>
-/**
- * This class provides reference counting functionality.
- */
-class AUD_Reference
-{
-private:
- /// The reference.
- T* m_reference;
- void* m_original;
-public:
- /**
- * Creates a new reference counter.
- * \param reference The reference.
- */
- template <class U>
- AUD_Reference(U* reference)
- {
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
- m_original = reference;
- m_reference = dynamic_cast<T*>(reference);
- AUD_ReferenceHandler::incref(m_original);
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "+" << typeid(*m_reference).name() << std::endl;
-#endif
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
- }
-
- AUD_Reference()
- {
- m_original = NULL;
- m_reference = NULL;
- }
-
- /**
- * Copies an AUD_Reference object.
- * \param ref The AUD_Reference object to copy.
- */
- AUD_Reference(const AUD_Reference& ref)
- {
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
- m_original = ref.m_original;
- m_reference = ref.m_reference;
- AUD_ReferenceHandler::incref(m_original);
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "+" << typeid(*m_reference).name() << std::endl;
-#endif
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
- }
-
- template <class U>
- explicit AUD_Reference(const AUD_Reference<U>& ref)
- {
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
- m_original = ref.get();
- m_reference = dynamic_cast<T*>(ref.get());
- AUD_ReferenceHandler::incref(m_original);
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "+" << typeid(*m_reference).name() << std::endl;
-#endif
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
- }
-
- /**
- * Destroys a AUD_Reference object, if there's no furthere reference on the
- * reference, it is destroyed as well.
- */
- ~AUD_Reference()
- {
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "-" << typeid(*m_reference).name() << std::endl;
-#endif
- if(AUD_ReferenceHandler::decref(m_original))
- {
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
- delete m_reference;
- }
- else
- {
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
- }
- }
-
- /**
- * Assigns an AUD_Reference to this object.
- * \param ref The AUD_Reference object to assign.
- */
- AUD_Reference& operator=(const AUD_Reference& ref)
- {
- if(&ref == this)
- return *this;
-
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
-
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "-" << typeid(*m_reference).name() << std::endl;
-#endif
- if(AUD_ReferenceHandler::decref(m_original))
- {
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
- delete m_reference;
- pthread_mutex_lock(AUD_ReferenceHandler::getMutex());
- }
-
- m_original = ref.m_original;
- m_reference = ref.m_reference;
- AUD_ReferenceHandler::incref(m_original);
-#ifdef MEM_DEBUG
- if(m_reference != NULL)
- std::cerr << "+" << typeid(*m_reference).name() << std::endl;
-#endif
-
- pthread_mutex_unlock(AUD_ReferenceHandler::getMutex());
-
- return *this;
- }
-
- /**
- * Returns whether the reference is NULL.
- */
- inline bool isNull() const
- {
- return m_reference == NULL;
- }
-
- /**
- * Returns the reference.
- */
- inline T* get() const
- {
- return m_reference;
- }
-
- /**
- * Returns the original pointer.
- */
- inline void* getOriginal() const
- {
- return m_original;
- }
-
- /**
- * Returns the reference.
- */
- inline T& operator*() const
- {
- return *m_reference;
- }
-
- /**
- * Returns the reference.
- */
- inline T* operator->() const
- {
- return m_reference;
- }
-};
-
-template<class T, class U>
-inline bool operator==(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
-{
- return a.getOriginal() == b.getOriginal();
-}
-
-template<class T, class U>
-inline bool operator!=(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
-{
- return a.getOriginal() != b.getOriginal();
-}
-
-#endif // __AUD_REFERENCE_H__
diff --git a/intern/audaspace/intern/AUD_ResampleReader.cpp b/intern/audaspace/intern/AUD_ResampleReader.cpp
index 514d790be09..4b247ffd862 100644
--- a/intern/audaspace/intern/AUD_ResampleReader.cpp
+++ b/intern/audaspace/intern/AUD_ResampleReader.cpp
@@ -29,7 +29,7 @@
#include "AUD_ResampleReader.h"
-AUD_ResampleReader::AUD_ResampleReader(AUD_Reference<AUD_IReader> reader, AUD_SampleRate rate) :
+AUD_ResampleReader::AUD_ResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_SampleRate rate) :
AUD_EffectReader(reader), m_rate(rate)
{
}
diff --git a/intern/audaspace/intern/AUD_ResampleReader.h b/intern/audaspace/intern/AUD_ResampleReader.h
index c423326489d..7e21989bfa8 100644
--- a/intern/audaspace/intern/AUD_ResampleReader.h
+++ b/intern/audaspace/intern/AUD_ResampleReader.h
@@ -47,7 +47,7 @@ protected:
* \param reader The reader to mix.
* \param rate The target sampling rate.
*/
- AUD_ResampleReader(AUD_Reference<AUD_IReader> reader, AUD_SampleRate rate);
+ AUD_ResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_SampleRate rate);
public:
/**
diff --git a/intern/audaspace/intern/AUD_Sequencer.cpp b/intern/audaspace/intern/AUD_Sequencer.cpp
new file mode 100644
index 00000000000..58e8f682714
--- /dev/null
+++ b/intern/audaspace/intern/AUD_Sequencer.cpp
@@ -0,0 +1,176 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * Audaspace is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/intern/AUD_Sequencer.cpp
+ * \ingroup audaspaceintern
+ */
+
+
+#include "AUD_Sequencer.h"
+#include "AUD_SequencerReader.h"
+#include "AUD_3DMath.h"
+#include "AUD_MutexLock.h"
+
+AUD_Sequencer::AUD_Sequencer(AUD_Specs specs, float fps, bool muted) :
+ m_specs(specs),
+ m_status(0),
+ m_entry_status(0),
+ m_id(0),
+ m_muted(muted),
+ m_fps(fps),
+ m_speed_of_sound(434),
+ m_doppler_factor(1),
+ m_distance_model(AUD_DISTANCE_MODEL_INVERSE_CLAMPED),
+ m_location(3),
+ m_orientation(4)
+{
+ AUD_Quaternion q;
+ m_orientation.write(q.get());
+ float f = 1;
+ m_volume.write(&f);
+
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(&m_mutex, &attr);
+
+ pthread_mutexattr_destroy(&attr);
+}
+
+AUD_Sequencer::~AUD_Sequencer()
+{
+ pthread_mutex_destroy(&m_mutex);
+}
+
+void AUD_Sequencer::lock()
+{
+ pthread_mutex_lock(&m_mutex);
+}
+
+void AUD_Sequencer::unlock()
+{
+ pthread_mutex_unlock(&m_mutex);
+}
+
+void AUD_Sequencer::setSpecs(AUD_Specs specs)
+{
+ AUD_MutexLock lock(*this);
+
+ m_specs = specs;
+ m_status++;
+}
+
+void AUD_Sequencer::setFPS(float fps)
+{
+ AUD_MutexLock lock(*this);
+
+ m_fps = fps;
+}
+
+void AUD_Sequencer::mute(bool muted)
+{
+ AUD_MutexLock lock(*this);
+
+ m_muted = muted;
+}
+
+bool AUD_Sequencer::getMute() const
+{
+ return m_muted;
+}
+
+float AUD_Sequencer::getSpeedOfSound() const
+{
+ return m_speed_of_sound;
+}
+
+void AUD_Sequencer::setSpeedOfSound(float speed)
+{
+ AUD_MutexLock lock(*this);
+
+ m_speed_of_sound = speed;
+ m_status++;
+}
+
+float AUD_Sequencer::getDopplerFactor() const
+{
+ return m_doppler_factor;
+}
+
+void AUD_Sequencer::setDopplerFactor(float factor)
+{
+ AUD_MutexLock lock(*this);
+
+ m_doppler_factor = factor;
+ m_status++;
+}
+
+AUD_DistanceModel AUD_Sequencer::getDistanceModel() const
+{
+ return m_distance_model;
+}
+
+void AUD_Sequencer::setDistanceModel(AUD_DistanceModel model)
+{
+ AUD_MutexLock lock(*this);
+
+ m_distance_model = model;
+ m_status++;
+}
+
+AUD_AnimateableProperty* AUD_Sequencer::getAnimProperty(AUD_AnimateablePropertyType type)
+{
+ switch(type)
+ {
+ case AUD_AP_VOLUME:
+ return &m_volume;
+ case AUD_AP_LOCATION:
+ return &m_location;
+ case AUD_AP_ORIENTATION:
+ return &m_orientation;
+ default:
+ return NULL;
+ }
+}
+
+boost::shared_ptr<AUD_SequencerEntry> AUD_Sequencer::add(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip)
+{
+ AUD_MutexLock lock(*this);
+
+ boost::shared_ptr<AUD_SequencerEntry> entry = boost::shared_ptr<AUD_SequencerEntry>(new AUD_SequencerEntry(sound, begin, end, skip, m_id++));
+
+ m_entries.push_front(entry);
+ m_entry_status++;
+
+ return entry;
+}
+
+void AUD_Sequencer::remove(boost::shared_ptr<AUD_SequencerEntry> entry)
+{
+ AUD_MutexLock lock(*this);
+
+ m_entries.remove(entry);
+ m_entry_status++;
+}
diff --git a/intern/audaspace/intern/AUD_Sequencer.h b/intern/audaspace/intern/AUD_Sequencer.h
new file mode 100644
index 00000000000..9fdf537ff97
--- /dev/null
+++ b/intern/audaspace/intern/AUD_Sequencer.h
@@ -0,0 +1,206 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 Jörg Hermann Müller
+ *
+ * This file is part of AudaSpace.
+ *
+ * Audaspace is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * AudaSpace is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/intern/AUD_Sequencer.h
+ * \ingroup audaspaceintern
+ */
+
+
+#ifndef __AUD_SEQUENCER_H__
+#define __AUD_SEQUENCER_H__
+
+#include "AUD_AnimateableProperty.h"
+#include "AUD_IFactory.h"
+#include "AUD_ILockable.h"
+
+#include <list>
+#include <pthread.h>
+
+class AUD_SequencerEntry;
+
+/**
+ * This class represents sequenced entries to play a sound scene.
+ */
+class AUD_Sequencer : public AUD_ILockable
+{
+ friend class AUD_SequencerReader;
+private:
+ /// The target specification.
+ AUD_Specs m_specs;
+
+ /// The status of the sequence. Changes every time a non-animated parameter changes.
+ int m_status;
+
+ /// The entry status. Changes every time an entry is removed or added.
+ int m_entry_status;
+
+ /// The next unused ID for the entries.
+ int m_id;
+
+ /// The sequenced entries.
+ std::list<boost::shared_ptr<AUD_SequencerEntry> > m_entries;
+
+ /// Whether the whole scene is muted.
+ bool m_muted;
+
+ /// The FPS of the scene.
+ float m_fps;
+
+ /// Speed of Sound.
+ float m_speed_of_sound;
+
+ /// Doppler factor.
+ float m_doppler_factor;
+
+ /// Distance model.
+ AUD_DistanceModel m_distance_model;
+
+ /// The animated volume.
+ AUD_AnimateableProperty m_volume;
+
+ /// The animated listener location.
+ AUD_AnimateableProperty m_location;
+
+ /// The animated listener orientation.
+ AUD_AnimateableProperty m_orientation;
+
+ /// The mutex for locking.
+ pthread_mutex_t m_mutex;
+
+ // hide copy constructor and operator=
+ AUD_Sequencer(const AUD_Sequencer&);
+ AUD_Sequencer& operator=(const AUD_Sequencer&);
+
+public:
+ /**
+ * Creates a new sound scene.
+ * \param specs The output audio data specification.
+ * \param fps The FPS of the scene.
+ * \param muted Whether the whole scene is muted.
+ */
+ AUD_Sequencer(AUD_Specs specs, float fps, bool muted);
+ ~AUD_Sequencer();
+
+ /**
+ * Locks the sequence.
+ */
+ virtual void lock();
+
+ /**
+ * Unlocks the previously locked sequence.
+ */
+ virtual void unlock();
+
+ /**
+ * Sets the audio output specification.
+ * \param specs The new specification.
+ */
+ void setSpecs(AUD_Specs specs);
+
+ /**
+ * Sets the scene's FPS.
+ * \param fps The new FPS.
+ */
+ void setFPS(float fps);
+
+ /**
+ * Sets the muting state of the scene.
+ * \param muted Whether the scene is muted.
+ */
+ void mute(bool muted);
+
+ /**
+ * Retrieves the muting state of the scene.
+ * \return Whether the scene is muted.
+ */
+ bool getMute() const;
+
+ /**
+ * Retrieves the speed of sound.
+ * This value is needed for doppler effect calculation.
+ * \return The speed of sound.
+ */
+ float getSpeedOfSound() const;
+
+ /**
+ * Sets the speed of sound.
+ * This value is needed for doppler effect calculation.
+ * \param speed The new speed of sound.
+ */
+ void setSpeedOfSound(float speed);
+
+ /**
+ * Retrieves the doppler factor.
+ * This value is a scaling factor for the velocity vectors of sources and
+ * listener which is used while calculating the doppler effect.
+ * \return The doppler factor.
+ */
+ float getDopplerFactor() const;
+
+ /**
+ * Sets the doppler factor.
+ * This value is a scaling factor for the velocity vectors of sources and
+ * listener which is used while calculating the doppler effect.
+ * \param factor The new doppler factor.
+ */
+ void setDopplerFactor(float factor);
+
+ /**
+ * Retrieves the distance model.
+ * \return The distance model.
+ */
+ AUD_DistanceModel getDistanceModel() const;
+
+ /**
+ * Sets the distance model.
+ * \param model distance model.
+ */
+ void setDistanceModel(AUD_DistanceModel model);
+
+ /**
+ * Retrieves one of the animated properties of the sequence.
+ * \param type Which animated property to retrieve.
+ * \return A pointer to the animated property, valid as long as the
+ * sequence is.
+ */
+ AUD_AnimateableProperty* getAnimProperty(AUD_AnimateablePropertyType type);
+
+ /**
+ * Adds a new entry to the scene.
+ * \param sound The sound this entry should play.
+ * \param begin The start time.
+ * \param end The end time or a negative value if determined by the sound.
+ * \param skip How much seconds should be skipped at the beginning.
+ * \return The entry added.
+ */
+ boost::shared_ptr<AUD_SequencerEntry> add(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip);
+
+ /**
+ * Removes an entry from the scene.
+ * \param entry The entry to remove.
+ */
+ void remove(boost::shared_ptr<AUD_SequencerEntry> entry);
+};
+
+#endif //__AUD_SEQUENCER_H__
diff --git a/intern/audaspace/intern/AUD_SequencerEntry.cpp b/intern/audaspace/intern/AUD_SequencerEntry.cpp
index 6e6e2397626..005557bbed1 100644
--- a/intern/audaspace/intern/AUD_SequencerEntry.cpp
+++ b/intern/audaspace/intern/AUD_SequencerEntry.cpp
@@ -29,11 +29,12 @@
#include "AUD_SequencerEntry.h"
#include "AUD_SequencerReader.h"
+#include "AUD_MutexLock.h"
#include <cmath>
#include <limits>
-AUD_SequencerEntry::AUD_SequencerEntry(AUD_Reference<AUD_IFactory> sound, float begin, float end, float skip, int id) :
+AUD_SequencerEntry::AUD_SequencerEntry(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip, int id) :
m_status(0),
m_pos_status(1),
m_sound_status(0),
@@ -85,22 +86,20 @@ void AUD_SequencerEntry::unlock()
pthread_mutex_unlock(&m_mutex);
}
-void AUD_SequencerEntry::setSound(AUD_Reference<AUD_IFactory> sound)
+void AUD_SequencerEntry::setSound(boost::shared_ptr<AUD_IFactory> sound)
{
- lock();
+ AUD_MutexLock lock(*this);
if(m_sound.get() != sound.get())
{
m_sound = sound;
m_sound_status++;
}
-
- unlock();
}
void AUD_SequencerEntry::move(float begin, float end, float skip)
{
- lock();
+ AUD_MutexLock lock(*this);
if(m_begin != begin || m_skip != skip || m_end != end)
{
@@ -109,17 +108,13 @@ void AUD_SequencerEntry::move(float begin, float end, float skip)
m_end = end;
m_pos_status++;
}
-
- unlock();
}
void AUD_SequencerEntry::mute(bool mute)
{
- lock();
+ AUD_MutexLock lock(*this);
m_muted = mute;
-
- unlock();
}
int AUD_SequencerEntry::getID() const
@@ -150,7 +145,7 @@ void AUD_SequencerEntry::updateAll(float volume_max, float volume_min, float dis
float distance_reference, float attenuation, float cone_angle_outer,
float cone_angle_inner, float cone_volume_outer)
{
- lock();
+ AUD_MutexLock lock(*this);
if(volume_max != m_volume_max)
{
@@ -199,8 +194,6 @@ void AUD_SequencerEntry::updateAll(float volume_max, float volume_min, float dis
m_cone_volume_outer = cone_volume_outer;
m_status++;
}
-
- unlock();
}
bool AUD_SequencerEntry::isRelative()
@@ -210,15 +203,13 @@ bool AUD_SequencerEntry::isRelative()
void AUD_SequencerEntry::setRelative(bool relative)
{
- lock();
+ AUD_MutexLock lock(*this);
if(m_relative != relative)
{
m_relative = relative;
m_status++;
}
-
- unlock();
}
float AUD_SequencerEntry::getVolumeMaximum()
@@ -228,12 +219,10 @@ float AUD_SequencerEntry::getVolumeMaximum()
void AUD_SequencerEntry::setVolumeMaximum(float volume)
{
- lock();
+ AUD_MutexLock lock(*this);
m_volume_max = volume;
m_status++;
-
- unlock();
}
float AUD_SequencerEntry::getVolumeMinimum()
@@ -243,12 +232,10 @@ float AUD_SequencerEntry::getVolumeMinimum()
void AUD_SequencerEntry::setVolumeMinimum(float volume)
{
- lock();
+ AUD_MutexLock lock(*this);
m_volume_min = volume;
m_status++;
-
- unlock();
}
float AUD_SequencerEntry::getDistanceMaximum()
@@ -258,12 +245,10 @@ float AUD_SequencerEntry::getDistanceMaximum()
void AUD_SequencerEntry::setDistanceMaximum(float distance)
{
- lock();
+ AUD_MutexLock lock(*this);
m_distance_max = distance;
m_status++;
-
- unlock();
}
float AUD_SequencerEntry::getDistanceReference()
@@ -273,12 +258,10 @@ float AUD_SequencerEntry::getDistanceReference()
void AUD_SequencerEntry::setDistanceReference(float distance)
{
- lock();
+ AUD_MutexLock lock(*this);
m_distance_reference = distance;
m_status++;
-
- unlock();
}
float AUD_SequencerEntry::getAttenuation()
@@ -288,12 +271,10 @@ float AUD_SequencerEntry::getAttenuation()
void AUD_SequencerEntry::setAttenuation(float factor)
{
- lock();
+ AUD_MutexLock lock(*this);
m_attenuation = factor;
m_status++;
-
- unlock();
}
float AUD_SequencerEntry::getConeAngleOuter()
@@ -303,12 +284,10 @@ float AUD_SequencerEntry::getConeAngleOuter()
void AUD_SequencerEntry::setConeAngleOuter(float angle)
{
- lock();
+ AUD_MutexLock lock(*this);
m_cone_angle_outer = angle;
m_status++;
-
- unlock();
}
float AUD_SequencerEntry::getConeAngleInner()
@@ -318,12 +297,10 @@ float AUD_SequencerEntry::getConeAngleInner()
void AUD_SequencerEntry::setConeAngleInner(float angle)
{
- lock();
+ AUD_MutexLock lock(*this);
m_cone_angle_inner = angle;
m_status++;
-
- unlock();
}
float AUD_SequencerEntry::getConeVolumeOuter()
@@ -333,10 +310,8 @@ float AUD_SequencerEntry::getConeVolumeOuter()
void AUD_SequencerEntry::setConeVolumeOuter(float volume)
{
- lock();
+ AUD_MutexLock lock(*this);
m_cone_volume_outer = volume;
m_status++;
-
- unlock();
}
diff --git a/intern/audaspace/intern/AUD_SequencerEntry.h b/intern/audaspace/intern/AUD_SequencerEntry.h
index 7ff6fffea11..aa1edebfc2f 100644
--- a/intern/audaspace/intern/AUD_SequencerEntry.h
+++ b/intern/audaspace/intern/AUD_SequencerEntry.h
@@ -30,16 +30,17 @@
#ifndef __AUD_SEQUENCERENTRY_H__
#define __AUD_SEQUENCERENTRY_H__
-#include "AUD_Reference.h"
#include "AUD_AnimateableProperty.h"
#include "AUD_IFactory.h"
+#include "AUD_ILockable.h"
#include <pthread.h>
+#include <boost/shared_ptr.hpp>
/**
* This class represents a sequenced entry in a sequencer factory.
*/
-class AUD_SequencerEntry
+class AUD_SequencerEntry : public AUD_ILockable
{
friend class AUD_SequencerHandle;
private:
@@ -56,7 +57,7 @@ private:
int m_id;
/// The sound this entry plays.
- AUD_Reference<AUD_IFactory> m_sound;
+ boost::shared_ptr<AUD_IFactory> m_sound;
/// The begin time.
float m_begin;
@@ -124,24 +125,24 @@ public:
* \param skip How much seconds should be skipped at the beginning.
* \param id The ID of the entry.
*/
- AUD_SequencerEntry(AUD_Reference<AUD_IFactory> sound, float begin, float end, float skip, int id);
+ AUD_SequencerEntry(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip, int id);
virtual ~AUD_SequencerEntry();
/**
* Locks the entry.
*/
- void lock();
+ virtual void lock();
/**
* Unlocks the previously locked entry.
*/
- void unlock();
+ virtual void unlock();
/**
* Sets the sound of the entry.
* \param sound The new sound.
*/
- void setSound(AUD_Reference<AUD_IFactory> sound);
+ void setSound(boost::shared_ptr<AUD_IFactory> sound);
/**
* Moves the entry.
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.cpp b/intern/audaspace/intern/AUD_SequencerFactory.cpp
index fd495f467cf..f6076603c2b 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.cpp
+++ b/intern/audaspace/intern/AUD_SequencerFactory.cpp
@@ -30,40 +30,14 @@
#include "AUD_SequencerFactory.h"
#include "AUD_SequencerReader.h"
#include "AUD_3DMath.h"
+#include "AUD_MutexLock.h"
-AUD_SequencerFactory::AUD_SequencerFactory(AUD_Specs specs, float fps, bool muted) :
- m_specs(specs),
- m_status(0),
- m_entry_status(0),
- m_id(0),
- m_muted(muted),
- m_fps(fps),
- m_speed_of_sound(434),
- m_doppler_factor(1),
- m_distance_model(AUD_DISTANCE_MODEL_INVERSE_CLAMPED),
- m_location(3),
- m_orientation(4)
+AUD_SequencerFactory::AUD_SequencerFactory(AUD_Specs specs, float fps, bool muted)
{
- AUD_Quaternion q;
- m_orientation.write(q.get());
- float f = 1;
- m_volume.write(&f);
-
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-
- pthread_mutex_init(&m_mutex, &attr);
-
- pthread_mutexattr_destroy(&attr);
+ m_sequence = boost::shared_ptr<AUD_Sequencer>(new AUD_Sequencer(specs, fps, muted));
}
-AUD_SequencerFactory::~AUD_SequencerFactory()
-{
- pthread_mutex_destroy(&m_mutex);
-}
-
-void AUD_SequencerFactory::lock()
+/*void AUD_SequencerFactory::lock()
{
pthread_mutex_lock(&m_mutex);
}
@@ -71,131 +45,79 @@ void AUD_SequencerFactory::lock()
void AUD_SequencerFactory::unlock()
{
pthread_mutex_unlock(&m_mutex);
-}
+}*/
void AUD_SequencerFactory::setSpecs(AUD_Specs specs)
{
- lock();
-
- m_specs = specs;
- m_status++;
-
- unlock();
+ m_sequence->setSpecs(specs);
}
void AUD_SequencerFactory::setFPS(float fps)
{
- lock();
-
- m_fps = fps;
-
- unlock();
+ m_sequence->setFPS(fps);
}
void AUD_SequencerFactory::mute(bool muted)
{
- lock();
-
- m_muted = muted;
-
- unlock();
+ m_sequence->mute(muted);
}
bool AUD_SequencerFactory::getMute() const
{
- return m_muted;
+ return m_sequence->getMute();
}
float AUD_SequencerFactory::getSpeedOfSound() const
{
- return m_speed_of_sound;
+ return m_sequence->getSpeedOfSound();
}
void AUD_SequencerFactory::setSpeedOfSound(float speed)
{
- lock();
-
- m_speed_of_sound = speed;
- m_status++;
-
- unlock();
+ m_sequence->setSpeedOfSound(speed);
}
float AUD_SequencerFactory::getDopplerFactor() const
{
- return m_doppler_factor;
+ return m_sequence->getDopplerFactor();
}
void AUD_SequencerFactory::setDopplerFactor(float factor)
{
- lock();
-
- m_doppler_factor = factor;
- m_status++;
-
- unlock();
+ m_sequence->setDopplerFactor(factor);
}
AUD_DistanceModel AUD_SequencerFactory::getDistanceModel() const
{
- return m_distance_model;
+ return m_sequence->getDistanceModel();
}
void AUD_SequencerFactory::setDistanceModel(AUD_DistanceModel model)
{
- lock();
-
- m_distance_model = model;
- m_status++;
-
- unlock();
+ m_sequence->setDistanceModel(model);
}
AUD_AnimateableProperty* AUD_SequencerFactory::getAnimProperty(AUD_AnimateablePropertyType type)
{
- switch(type)
- {
- case AUD_AP_VOLUME:
- return &m_volume;
- case AUD_AP_LOCATION:
- return &m_location;
- case AUD_AP_ORIENTATION:
- return &m_orientation;
- default:
- return NULL;
- }
+ return m_sequence->getAnimProperty(type);
}
-AUD_Reference<AUD_SequencerEntry> AUD_SequencerFactory::add(AUD_Reference<AUD_IFactory> sound, float begin, float end, float skip)
+boost::shared_ptr<AUD_SequencerEntry> AUD_SequencerFactory::add(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip)
{
- lock();
-
- AUD_Reference<AUD_SequencerEntry> entry = new AUD_SequencerEntry(sound, begin, end, skip, m_id++);
-
- m_entries.push_front(entry);
- m_entry_status++;
-
- unlock();
-
- return entry;
+ return m_sequence->add(sound, begin, end, skip);
}
-void AUD_SequencerFactory::remove(AUD_Reference<AUD_SequencerEntry> entry)
+void AUD_SequencerFactory::remove(boost::shared_ptr<AUD_SequencerEntry> entry)
{
- lock();
-
- m_entries.remove(entry);
- m_entry_status++;
-
- unlock();
+ m_sequence->remove(entry);
}
-AUD_Reference<AUD_IReader> AUD_SequencerFactory::createQualityReader()
+boost::shared_ptr<AUD_IReader> AUD_SequencerFactory::createQualityReader()
{
- return new AUD_SequencerReader(this, true);
+ return boost::shared_ptr<AUD_IReader>(new AUD_SequencerReader(m_sequence, true));
}
-AUD_Reference<AUD_IReader> AUD_SequencerFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_SequencerFactory::createReader()
{
- return new AUD_SequencerReader(this);
+ return boost::shared_ptr<AUD_IReader>(new AUD_SequencerReader(m_sequence));
}
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.h b/intern/audaspace/intern/AUD_SequencerFactory.h
index 38241112020..3ef847d4b34 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.h
+++ b/intern/audaspace/intern/AUD_SequencerFactory.h
@@ -32,6 +32,8 @@
#include "AUD_IFactory.h"
#include "AUD_AnimateableProperty.h"
+//#include "AUD_ILockable.h"
+#include "AUD_Sequencer.h"
#include <list>
#include <pthread.h>
@@ -41,51 +43,12 @@ class AUD_SequencerEntry;
/**
* This factory represents sequenced entries to play a sound scene.
*/
-class AUD_SequencerFactory : public AUD_IFactory
+class AUD_SequencerFactory : public AUD_IFactory//, public AUD_ILockable
{
friend class AUD_SequencerReader;
private:
- /// The target specification.
- AUD_Specs m_specs;
-
- /// The status of the factory. Changes every time a non-animated parameter changes.
- int m_status;
-
- /// The entry status. Changes every time an entry is removed or added.
- int m_entry_status;
-
- /// The next unused ID for the entries.
- int m_id;
-
- /// The sequenced entries.
- std::list<AUD_Reference<AUD_SequencerEntry> > m_entries;
-
- /// Whether the whole scene is muted.
- bool m_muted;
-
- /// The FPS of the scene.
- float m_fps;
-
- /// Speed of Sound.
- float m_speed_of_sound;
-
- /// Doppler factor.
- float m_doppler_factor;
-
- /// Distance model.
- AUD_DistanceModel m_distance_model;
-
- /// The animated volume.
- AUD_AnimateableProperty m_volume;
-
- /// The animated listener location.
- AUD_AnimateableProperty m_location;
-
- /// The animated listener orientation.
- AUD_AnimateableProperty m_orientation;
-
- /// The mutex for locking.
- pthread_mutex_t m_mutex;
+ /// The sequence.
+ boost::shared_ptr<AUD_Sequencer> m_sequence;
// hide copy constructor and operator=
AUD_SequencerFactory(const AUD_SequencerFactory&);
@@ -99,17 +62,18 @@ public:
* \param muted Whether the whole scene is muted.
*/
AUD_SequencerFactory(AUD_Specs specs, float fps, bool muted);
- ~AUD_SequencerFactory();
+#if 0
/**
* Locks the factory.
*/
- void lock();
+ virtual void lock();
/**
* Unlocks the previously locked factory.
*/
- void unlock();
+ virtual void unlock();
+#endif
/**
* Sets the audio output specification.
@@ -193,21 +157,21 @@ public:
* \param skip How much seconds should be skipped at the beginning.
* \return The entry added.
*/
- AUD_Reference<AUD_SequencerEntry> add(AUD_Reference<AUD_IFactory> sound, float begin, float end, float skip);
+ boost::shared_ptr<AUD_SequencerEntry> add(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip);
/**
* Removes an entry from the scene.
* \param entry The entry to remove.
*/
- void remove(AUD_Reference<AUD_SequencerEntry> entry);
+ void remove(boost::shared_ptr<AUD_SequencerEntry> entry);
/**
* Creates a new reader with high quality resampling.
* \return The new reader.
*/
- AUD_Reference<AUD_IReader> createQualityReader();
+ boost::shared_ptr<AUD_IReader> createQualityReader();
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_SEQUENCERFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.cpp b/intern/audaspace/intern/AUD_SequencerHandle.cpp
index f4bfae6cee7..c9473cf274e 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.cpp
+++ b/intern/audaspace/intern/AUD_SequencerHandle.cpp
@@ -29,18 +29,19 @@
#include "AUD_SequencerHandle.h"
#include "AUD_ReadDevice.h"
+#include "AUD_MutexLock.h"
-AUD_SequencerHandle::AUD_SequencerHandle(AUD_Reference<AUD_SequencerEntry> entry, AUD_ReadDevice& device) :
+AUD_SequencerHandle::AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> entry, AUD_ReadDevice& device) :
m_entry(entry),
m_status(0),
m_pos_status(0),
m_sound_status(0),
m_device(device)
{
- if(!entry->m_sound.isNull())
+ if(entry->m_sound.get())
{
m_handle = device.play(entry->m_sound, true);
- m_3dhandle = AUD_Reference<AUD_I3DHandle>(m_handle);
+ m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
}
}
@@ -49,7 +50,7 @@ AUD_SequencerHandle::~AUD_SequencerHandle()
stop();
}
-int AUD_SequencerHandle::compare(AUD_Reference<AUD_SequencerEntry> entry) const
+int AUD_SequencerHandle::compare(boost::shared_ptr<AUD_SequencerEntry> entry) const
{
if(m_entry->getID() < entry->getID())
return -1;
@@ -60,15 +61,15 @@ int AUD_SequencerHandle::compare(AUD_Reference<AUD_SequencerEntry> entry) const
void AUD_SequencerHandle::stop()
{
- if(!m_handle.isNull())
+ if(m_handle.get())
m_handle->stop();
}
void AUD_SequencerHandle::update(float position, float frame, float fps)
{
- if(!m_handle.isNull())
+ if(m_handle.get())
{
- m_entry->lock();
+ AUD_MutexLock lock(*m_entry);
if(position >= m_entry->m_end && m_entry->m_end >= 0)
m_handle->pause();
else if(position >= m_entry->m_begin)
@@ -76,13 +77,13 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
if(m_sound_status != m_entry->m_sound_status)
{
- if(!m_handle.isNull())
+ if(m_handle.get())
m_handle->stop();
- if(!m_entry->m_sound.isNull())
+ if(m_entry->m_sound.get())
{
m_handle = m_device.play(m_entry->m_sound, true);
- m_3dhandle = AUD_Reference<AUD_I3DHandle>(m_handle);
+ m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
}
m_sound_status = m_entry->m_sound_status;
@@ -134,19 +135,17 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
if(m_entry->m_muted)
m_handle->setVolume(0);
- m_entry->unlock();
}
}
void AUD_SequencerHandle::seek(float position)
{
- if(!m_handle.isNull())
+ if(m_handle.get())
{
- m_entry->lock();
+ AUD_MutexLock lock(*m_entry);
if(position >= m_entry->m_end && m_entry->m_end >= 0)
{
m_handle->pause();
- m_entry->unlock();
return;
}
@@ -160,6 +159,5 @@ void AUD_SequencerHandle::seek(float position)
m_handle->pause();
else
m_handle->resume();
- m_entry->unlock();
}
}
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.h b/intern/audaspace/intern/AUD_SequencerHandle.h
index 72d3240a103..881bbdd43dc 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.h
+++ b/intern/audaspace/intern/AUD_SequencerHandle.h
@@ -43,13 +43,13 @@ class AUD_SequencerHandle
{
private:
/// The entry this handle belongs to.
- AUD_Reference<AUD_SequencerEntry> m_entry;
+ boost::shared_ptr<AUD_SequencerEntry> m_entry;
/// The handle in the read device.
- AUD_Reference<AUD_IHandle> m_handle;
+ boost::shared_ptr<AUD_IHandle> m_handle;
/// The 3D handle in the read device.
- AUD_Reference<AUD_I3DHandle> m_3dhandle;
+ boost::shared_ptr<AUD_I3DHandle> m_3dhandle;
/// The last read status from the entry.
int m_status;
@@ -69,7 +69,7 @@ public:
* \param entry The entry this handle plays.
* \param device The read device to play on.
*/
- AUD_SequencerHandle(AUD_Reference<AUD_SequencerEntry> entry, AUD_ReadDevice& device);
+ AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> entry, AUD_ReadDevice& device);
/**
* Destroys the handle.
@@ -81,7 +81,7 @@ public:
* \param entry The entry to compare to.
* \return Whether the entries ID is smaller, equal or bigger.
*/
- int compare(AUD_Reference<AUD_SequencerEntry> entry) const;
+ int compare(boost::shared_ptr<AUD_SequencerEntry> entry) const;
/**
* Stops playing back the handle.
diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp
index 2e41a99d3db..d5e14590df5 100644
--- a/intern/audaspace/intern/AUD_SequencerReader.cpp
+++ b/intern/audaspace/intern/AUD_SequencerReader.cpp
@@ -28,12 +28,13 @@
#include "AUD_SequencerReader.h"
+#include "AUD_MutexLock.h"
-typedef std::list<AUD_Reference<AUD_SequencerHandle> >::iterator AUD_HandleIterator;
-typedef std::list<AUD_Reference<AUD_SequencerEntry> >::iterator AUD_EntryIterator;
+typedef std::list<boost::shared_ptr<AUD_SequencerHandle> >::iterator AUD_HandleIterator;
+typedef std::list<boost::shared_ptr<AUD_SequencerEntry> >::iterator AUD_EntryIterator;
-AUD_SequencerReader::AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory, bool quality) :
- m_position(0), m_device(factory->m_specs), m_factory(factory), m_status(0), m_entry_status(0)
+AUD_SequencerReader::AUD_SequencerReader(boost::shared_ptr<AUD_Sequencer> sequence, bool quality) :
+ m_position(0), m_device(sequence->m_specs), m_sequence(sequence), m_status(0), m_entry_status(0)
{
m_device.setQuality(quality);
}
@@ -56,7 +57,7 @@ void AUD_SequencerReader::seek(int position)
for(AUD_HandleIterator it = m_handles.begin(); it != m_handles.end(); it++)
{
- (*it)->seek(position / m_factory->m_specs.rate);
+ (*it)->seek(position / m_sequence->m_specs.rate);
}
}
@@ -72,37 +73,37 @@ int AUD_SequencerReader::getPosition() const
AUD_Specs AUD_SequencerReader::getSpecs() const
{
- return m_factory->m_specs;
+ return m_sequence->m_specs;
}
void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
{
- m_factory->lock();
+ AUD_MutexLock lock(*m_sequence);
- if(m_factory->m_status != m_status)
+ if(m_sequence->m_status != m_status)
{
- m_device.changeSpecs(m_factory->m_specs);
- m_device.setSpeedOfSound(m_factory->m_speed_of_sound);
- m_device.setDistanceModel(m_factory->m_distance_model);
- m_device.setDopplerFactor(m_factory->m_doppler_factor);
+ m_device.changeSpecs(m_sequence->m_specs);
+ m_device.setSpeedOfSound(m_sequence->m_speed_of_sound);
+ m_device.setDistanceModel(m_sequence->m_distance_model);
+ m_device.setDopplerFactor(m_sequence->m_doppler_factor);
- m_status = m_factory->m_status;
+ m_status = m_sequence->m_status;
}
- if(m_factory->m_entry_status != m_entry_status)
+ if(m_sequence->m_entry_status != m_entry_status)
{
- std::list<AUD_Reference<AUD_SequencerHandle> > handles;
+ std::list<boost::shared_ptr<AUD_SequencerHandle> > handles;
AUD_HandleIterator hit = m_handles.begin();
- AUD_EntryIterator eit = m_factory->m_entries.begin();
+ AUD_EntryIterator eit = m_sequence->m_entries.begin();
int result;
- AUD_Reference<AUD_SequencerHandle> handle;
+ boost::shared_ptr<AUD_SequencerHandle> handle;
- while(hit != m_handles.end() && eit != m_factory->m_entries.end())
+ while(hit != m_handles.end() && eit != m_sequence->m_entries.end())
{
handle = *hit;
- AUD_Reference<AUD_SequencerEntry> entry = *eit;
+ boost::shared_ptr<AUD_SequencerEntry> entry = *eit;
result = handle->compare(entry);
@@ -110,7 +111,7 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
{
try
{
- handle = new AUD_SequencerHandle(entry, m_device);
+ handle = boost::shared_ptr<AUD_SequencerHandle>(new AUD_SequencerHandle(entry, m_device));
handles.push_front(handle);
}
catch(AUD_Exception&)
@@ -137,11 +138,11 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
hit++;
}
- while(eit != m_factory->m_entries.end())
+ while(eit != m_sequence->m_entries.end())
{
try
{
- handle = new AUD_SequencerHandle(*eit, m_device);
+ handle = boost::shared_ptr<AUD_SequencerHandle>(new AUD_SequencerHandle(*eit, m_device));
handles.push_front(handle);
}
catch(AUD_Exception&)
@@ -152,10 +153,10 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
m_handles = handles;
- m_entry_status = m_factory->m_entry_status;
+ m_entry_status = m_sequence->m_entry_status;
}
- AUD_Specs specs = m_factory->m_specs;
+ AUD_Specs specs = m_sequence->m_specs;
int pos = 0;
float time = float(m_position) / float(specs.rate);
float volume, frame;
@@ -166,30 +167,30 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
while(pos < length)
{
- frame = time * m_factory->m_fps;
+ frame = time * m_sequence->m_fps;
cfra = int(floor(frame));
- len = int(ceil((cfra + 1) / m_factory->m_fps * specs.rate)) - m_position;
+ len = int(ceil((cfra + 1) / m_sequence->m_fps * specs.rate)) - m_position;
len = AUD_MIN(length - pos, len);
len = AUD_MAX(len, 1);
for(AUD_HandleIterator it = m_handles.begin(); it != m_handles.end(); it++)
{
- (*it)->update(time, frame, m_factory->m_fps);
+ (*it)->update(time, frame, m_sequence->m_fps);
}
- m_factory->m_volume.read(frame, &volume);
- if(m_factory->m_muted)
+ m_sequence->m_volume.read(frame, &volume);
+ if(m_sequence->m_muted)
volume = 0.0f;
m_device.setVolume(volume);
- m_factory->m_orientation.read(frame, q.get());
+ m_sequence->m_orientation.read(frame, q.get());
m_device.setListenerOrientation(q);
- m_factory->m_location.read(frame, v.get());
+ m_sequence->m_location.read(frame, v.get());
m_device.setListenerLocation(v);
- m_factory->m_location.read(frame + 1, v2.get());
+ m_sequence->m_location.read(frame + 1, v2.get());
v2 -= v;
- m_device.setListenerVelocity(v2 * m_factory->m_fps);
+ m_device.setListenerVelocity(v2 * m_sequence->m_fps);
m_device.read(reinterpret_cast<data_t*>(buffer + specs.channels * pos), len);
@@ -197,8 +198,6 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
time += float(len) / float(specs.rate);
}
- m_factory->unlock();
-
m_position += length;
eos = false;
diff --git a/intern/audaspace/intern/AUD_SequencerReader.h b/intern/audaspace/intern/AUD_SequencerReader.h
index b3c3a3ea7a6..6b3dbc9313e 100644
--- a/intern/audaspace/intern/AUD_SequencerReader.h
+++ b/intern/audaspace/intern/AUD_SequencerReader.h
@@ -32,7 +32,7 @@
#include "AUD_IReader.h"
#include "AUD_ReadDevice.h"
-#include "AUD_SequencerFactory.h"
+#include "AUD_Sequencer.h"
#include "AUD_SequencerHandle.h"
/**
@@ -52,22 +52,22 @@ private:
AUD_ReadDevice m_device;
/**
- * Saves the SequencerFactory the reader belongs to.
+ * Saves the sequence the reader belongs to.
*/
- AUD_Reference<AUD_SequencerFactory> m_factory;
+ boost::shared_ptr<AUD_Sequencer> m_sequence;
/**
* The list of playback handles for the entries.
*/
- std::list<AUD_Reference<AUD_SequencerHandle> > m_handles;
+ std::list<boost::shared_ptr<AUD_SequencerHandle> > m_handles;
/**
- * Last status read from the factory.
+ * Last status read from the sequence.
*/
int m_status;
/**
- * Last entry status read from the factory.
+ * Last entry status read from the sequence.
*/
int m_entry_status;
@@ -81,7 +81,7 @@ public:
* \param reader The reader to mix.
* \param specs The target specification.
*/
- AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory, bool quality = false);
+ AUD_SequencerReader(boost::shared_ptr<AUD_Sequencer> sequence, bool quality = false);
/**
* Destroys the reader.
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.cpp b/intern/audaspace/intern/AUD_SilenceFactory.cpp
index 0ba553f1c02..85034b316ca 100644
--- a/intern/audaspace/intern/AUD_SilenceFactory.cpp
+++ b/intern/audaspace/intern/AUD_SilenceFactory.cpp
@@ -35,7 +35,7 @@ AUD_SilenceFactory::AUD_SilenceFactory()
{
}
-AUD_Reference<AUD_IReader> AUD_SilenceFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_SilenceFactory::createReader()
{
- return new AUD_SilenceReader();
+ return boost::shared_ptr<AUD_IReader>(new AUD_SilenceReader());
}
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.h b/intern/audaspace/intern/AUD_SilenceFactory.h
index 3bc7fc067ed..de62a2f94fc 100644
--- a/intern/audaspace/intern/AUD_SilenceFactory.h
+++ b/intern/audaspace/intern/AUD_SilenceFactory.h
@@ -48,7 +48,7 @@ public:
*/
AUD_SilenceFactory();
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_SILENCEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_SinusFactory.cpp b/intern/audaspace/intern/AUD_SinusFactory.cpp
index 3ef6a11de5b..2b9742cc90c 100644
--- a/intern/audaspace/intern/AUD_SinusFactory.cpp
+++ b/intern/audaspace/intern/AUD_SinusFactory.cpp
@@ -42,7 +42,7 @@ float AUD_SinusFactory::getFrequency() const
return m_frequency;
}
-AUD_Reference<AUD_IReader> AUD_SinusFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_SinusFactory::createReader()
{
- return new AUD_SinusReader(m_frequency, m_sampleRate);
+ return boost::shared_ptr<AUD_IReader>(new AUD_SinusReader(m_frequency, m_sampleRate));
}
diff --git a/intern/audaspace/intern/AUD_SinusFactory.h b/intern/audaspace/intern/AUD_SinusFactory.h
index d83323c6635..d1909dedb66 100644
--- a/intern/audaspace/intern/AUD_SinusFactory.h
+++ b/intern/audaspace/intern/AUD_SinusFactory.h
@@ -66,7 +66,7 @@ public:
*/
float getFrequency() const;
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_SINUSFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index 1d993abab73..a7e5b25664b 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -33,6 +33,7 @@
#include "AUD_IFactory.h"
#include "AUD_JOSResampleReader.h"
#include "AUD_LinearResampleReader.h"
+#include "AUD_MutexLock.h"
#include <cstring>
#include <cmath>
@@ -56,7 +57,7 @@ typedef enum
/********************** AUD_SoftwareHandle Handle Code ************************/
/******************************************************************************/
-AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_PitchReader> pitch, AUD_Reference<AUD_ResampleReader> resampler, AUD_Reference<AUD_ChannelMapperReader> mapper, bool keep) :
+AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_PitchReader> pitch, boost::shared_ptr<AUD_ResampleReader> resampler, boost::shared_ptr<AUD_ChannelMapperReader> mapper, bool keep) :
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(1.0f), m_loopcount(0),
m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
@@ -226,22 +227,28 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause()
{
if(m_status)
{
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
if(m_status == AUD_STATUS_PLAYING)
{
- m_device->m_playingSounds.remove(this);
- m_device->m_pausedSounds.push_back(this);
+ for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ boost::shared_ptr<AUD_SoftwareHandle> This = *it;
- if(m_device->m_playingSounds.empty())
- m_device->playing(m_device->m_playback = false);
- m_status = AUD_STATUS_PAUSED;
- m_device->unlock();
+ m_device->m_playingSounds.erase(it);
+ m_device->m_pausedSounds.push_back(This);
- return true;
- }
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
- m_device->unlock();
+ m_status = AUD_STATUS_PAUSED;
+
+ return true;
+ }
+ }
+ }
}
return false;
@@ -251,21 +258,29 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::resume()
{
if(m_status)
{
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
if(m_status == AUD_STATUS_PAUSED)
{
- m_device->m_pausedSounds.remove(this);
- m_device->m_playingSounds.push_back(this);
+ for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ boost::shared_ptr<AUD_SoftwareHandle> This = *it;
- if(!m_device->m_playback)
- m_device->playing(m_device->m_playback = true);
- m_status = AUD_STATUS_PLAYING;
- m_device->unlock();
- return true;
+ m_device->m_pausedSounds.erase(it);
+
+ m_device->m_playingSounds.push_back(This);
+
+ if(!m_device->m_playback)
+ m_device->playing(m_device->m_playback = true);
+ m_status = AUD_STATUS_PLAYING;
+
+ return true;
+ }
+ }
}
- m_device->unlock();
}
return false;
@@ -276,25 +291,38 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::stop()
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
+
+ if(!m_status)
+ return false;
- // AUD_XXX Create a reference of our own object so that it doesn't get
- // deleted before the end of this function
- AUD_Reference<AUD_SoftwareHandle> This = this;
+ m_status = AUD_STATUS_INVALID;
- if(m_status == AUD_STATUS_PLAYING)
+ for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
{
- m_device->m_playingSounds.remove(This);
+ if(it->get() == this)
+ {
+ boost::shared_ptr<AUD_SoftwareHandle> This = *it;
- if(m_device->m_playingSounds.empty())
- m_device->playing(m_device->m_playback = false);
+ m_device->m_playingSounds.erase(it);
+
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
+
+ return true;
+ }
}
- else
- m_device->m_pausedSounds.remove(This);
- m_device->unlock();
- m_status = AUD_STATUS_INVALID;
- return true;
+ for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ m_device->m_pausedSounds.erase(it);
+ return true;
+ }
+ }
+
+ return false;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::getKeep()
@@ -310,11 +338,12 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::setKeep(bool keep)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- m_keep = keep;
+ if(!m_status)
+ return false;
- m_device->unlock();
+ m_keep = keep;
return true;
}
@@ -324,11 +353,12 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- m_reader->seek((int)(position * m_reader->getSpecs().rate));
+ if(!m_status)
+ return false;
- m_device->unlock();
+ m_reader->seek((int)(position * m_reader->getSpecs().rate));
return true;
}
@@ -336,13 +366,14 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
float AUD_SoftwareDevice::AUD_SoftwareHandle::getPosition()
{
if(!m_status)
- return 0.0f;
+ return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
- float position = m_reader->getPosition() / (float)m_device->m_specs.rate;
+ if(!m_status)
+ return 0.0f;
- m_device->unlock();
+ float position = m_reader->getPosition() / (float)m_device->m_specs.rate;
return position;
}
@@ -407,13 +438,14 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::setStopCallback(stopCallback callba
if(!m_status)
return false;
- m_device->lock();
+ AUD_MutexLock lock(*m_device);
+
+ if(!m_status)
+ return false;
m_stop = callback;
m_stop_data = data;
- m_device->unlock();
-
return true;
}
@@ -657,7 +689,7 @@ void AUD_SoftwareDevice::create()
{
m_playback = false;
m_volume = 1.0f;
- m_mixer = new AUD_Mixer(m_specs);
+ m_mixer = boost::shared_ptr<AUD_Mixer>(new AUD_Mixer(m_specs));
m_speed_of_sound = 343.0f;
m_doppler_factor = 1.0f;
m_distance_model = AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
@@ -691,15 +723,15 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
{
m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_specs));
- lock();
+ AUD_MutexLock lock(*this);
{
- AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound;
+ boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle> sound;
int len;
int pos;
bool eos;
- std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> > stopSounds;
- std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> > pauseSounds;
+ std::list<boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle> > stopSounds;
+ std::list<boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle> > pauseSounds;
sample_t* buf = m_buffer.getBuffer();
m_mixer->clear(length);
@@ -775,8 +807,6 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
sound->pause();
}
}
-
- unlock();
}
void AUD_SoftwareDevice::setPanning(AUD_IHandle* handle, float pan)
@@ -806,59 +836,57 @@ AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const
return m_specs;
}
-AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
+boost::shared_ptr<AUD_IHandle> AUD_SoftwareDevice::play(boost::shared_ptr<AUD_IReader> reader, bool keep)
{
// prepare the reader
// pitch
- AUD_Reference<AUD_PitchReader> pitch = new AUD_PitchReader(reader, 1);
- reader = AUD_Reference<AUD_IReader>(pitch);
+ boost::shared_ptr<AUD_PitchReader> pitch = boost::shared_ptr<AUD_PitchReader>(new AUD_PitchReader(reader, 1));
+ reader = boost::shared_ptr<AUD_IReader>(pitch);
- AUD_Reference<AUD_ResampleReader> resampler;
+ boost::shared_ptr<AUD_ResampleReader> resampler;
// resample
if(m_quality)
- resampler = new AUD_JOSResampleReader(reader, m_specs.specs);
+ resampler = boost::shared_ptr<AUD_ResampleReader>(new AUD_JOSResampleReader(reader, m_specs.specs));
else
- resampler = new AUD_LinearResampleReader(reader, m_specs.specs);
- reader = AUD_Reference<AUD_IReader>(resampler);
+ resampler = boost::shared_ptr<AUD_ResampleReader>(new AUD_LinearResampleReader(reader, m_specs.specs));
+ reader = boost::shared_ptr<AUD_IReader>(resampler);
// rechannel
- AUD_Reference<AUD_ChannelMapperReader> mapper = new AUD_ChannelMapperReader(reader, m_specs.channels);
- reader = AUD_Reference<AUD_IReader>(mapper);
+ boost::shared_ptr<AUD_ChannelMapperReader> mapper = boost::shared_ptr<AUD_ChannelMapperReader>(new AUD_ChannelMapperReader(reader, m_specs.channels));
+ reader = boost::shared_ptr<AUD_IReader>(mapper);
- if(reader.isNull())
- return AUD_Reference<AUD_IHandle>();
+ if(!reader.get())
+ return boost::shared_ptr<AUD_IHandle>();
// play sound
- AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound = new AUD_SoftwareDevice::AUD_SoftwareHandle(this, reader, pitch, resampler, mapper, keep);
+ boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle> sound = boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle>(new AUD_SoftwareDevice::AUD_SoftwareHandle(this, reader, pitch, resampler, mapper, keep));
+
+ AUD_MutexLock lock(*this);
- lock();
m_playingSounds.push_back(sound);
if(!m_playback)
playing(m_playback = true);
- unlock();
- return AUD_Reference<AUD_IHandle>(sound);
+ return boost::shared_ptr<AUD_IHandle>(sound);
}
-AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
+boost::shared_ptr<AUD_IHandle> AUD_SoftwareDevice::play(boost::shared_ptr<AUD_IFactory> factory, bool keep)
{
return play(factory->createReader(), keep);
}
void AUD_SoftwareDevice::stopAll()
{
- lock();
+ AUD_MutexLock lock(*this);
while(!m_playingSounds.empty())
m_playingSounds.front()->stop();
while(!m_pausedSounds.empty())
m_pausedSounds.front()->stop();
-
- unlock();
}
void AUD_SoftwareDevice::lock()
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h
index c429508b622..8675a5ce2b8 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -59,16 +59,16 @@ protected:
{
public:
/// The reader source.
- AUD_Reference<AUD_IReader> m_reader;
+ boost::shared_ptr<AUD_IReader> m_reader;
/// The pitch reader in between.
- AUD_Reference<AUD_PitchReader> m_pitch;
+ boost::shared_ptr<AUD_PitchReader> m_pitch;
/// The resample reader in between.
- AUD_Reference<AUD_ResampleReader> m_resampler;
+ boost::shared_ptr<AUD_ResampleReader> m_resampler;
/// The channel mapper reader in between.
- AUD_Reference<AUD_ChannelMapperReader> m_mapper;
+ boost::shared_ptr<AUD_ChannelMapperReader> m_mapper;
/// Whether to keep the source if end of it is reached.
bool m_keep;
@@ -150,7 +150,7 @@ protected:
* \param mapper The channel mapping reader.
* \param keep Whether to keep the handle when the sound ends.
*/
- AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_PitchReader> pitch, AUD_Reference<AUD_ResampleReader> resampler, AUD_Reference<AUD_ChannelMapperReader> mapper, bool keep);
+ AUD_SoftwareHandle(AUD_SoftwareDevice* device, boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_PitchReader> pitch, boost::shared_ptr<AUD_ResampleReader> resampler, boost::shared_ptr<AUD_ChannelMapperReader> mapper, bool keep);
/**
* Updates the handle's playback parameters.
@@ -206,7 +206,7 @@ protected:
virtual bool setConeVolumeOuter(float volume);
};
- typedef std::list<AUD_Reference<AUD_SoftwareHandle> >::iterator AUD_HandleIterator;
+ typedef std::list<boost::shared_ptr<AUD_SoftwareHandle> >::iterator AUD_HandleIterator;
/**
* The specification of the device.
@@ -216,7 +216,7 @@ protected:
/**
* The mixer.
*/
- AUD_Reference<AUD_Mixer> m_mixer;
+ boost::shared_ptr<AUD_Mixer> m_mixer;
/**
* Whether to do high or low quality resampling.
@@ -261,12 +261,12 @@ private:
/**
* The list of sounds that are currently playing.
*/
- std::list<AUD_Reference<AUD_SoftwareHandle> > m_playingSounds;
+ std::list<boost::shared_ptr<AUD_SoftwareHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<AUD_Reference<AUD_SoftwareHandle> > m_pausedSounds;
+ std::list<boost::shared_ptr<AUD_SoftwareHandle> > m_pausedSounds;
/**
* Whether there is currently playback.
@@ -320,8 +320,8 @@ public:
void setQuality(bool quality);
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
- virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
+ virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false);
+ virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false);
virtual void stopAll();
virtual void lock();
virtual void unlock();
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
index 1c8d2a99351..daa714aeec3 100644
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
@@ -33,10 +33,10 @@
#include <cstring>
-AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_Reference<AUD_IFactory> factory) :
+AUD_StreamBufferFactory::AUD_StreamBufferFactory(boost::shared_ptr<AUD_IFactory> factory) :
m_buffer(new AUD_Buffer())
{
- AUD_Reference<AUD_IReader> reader = factory->createReader();
+ boost::shared_ptr<AUD_IReader> reader = factory->createReader();
m_specs = reader->getSpecs();
@@ -70,7 +70,7 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_Reference<AUD_IFactory> fac
m_buffer->resize(index * sample_size, true);
}
-AUD_Reference<AUD_IReader> AUD_StreamBufferFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_StreamBufferFactory::createReader()
{
- return new AUD_BufferReader(m_buffer, m_specs);
+ return boost::shared_ptr<AUD_IReader>(new AUD_BufferReader(m_buffer, m_specs));
}
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.h b/intern/audaspace/intern/AUD_StreamBufferFactory.h
index 99795d95d33..1bcd73d59b6 100644
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.h
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.h
@@ -31,9 +31,10 @@
#define __AUD_STREAMBUFFERFACTORY_H__
#include "AUD_IFactory.h"
-#include "AUD_Reference.h"
#include "AUD_Buffer.h"
+#include <boost/shared_ptr.hpp>
+
/**
* This factory creates a buffer out of a reader. This way normally streamed
* sound sources can be loaded into memory for buffered playback.
@@ -44,7 +45,7 @@ private:
/**
* The buffer that holds the audio data.
*/
- AUD_Reference<AUD_Buffer> m_buffer;
+ boost::shared_ptr<AUD_Buffer> m_buffer;
/**
* The specification of the samples.
@@ -62,9 +63,9 @@ public:
* \param factory The factory that creates the reader for buffering.
* \exception AUD_Exception Thrown if the reader cannot be created.
*/
- AUD_StreamBufferFactory(AUD_Reference<AUD_IFactory> factory);
+ AUD_StreamBufferFactory(boost::shared_ptr<AUD_IFactory> factory);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_STREAMBUFFERFACTORY_H__
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
index 1fc77fbde66..106b2937a06 100644
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
@@ -43,10 +43,10 @@ AUD_SndFileFactory::AUD_SndFileFactory(const data_t* buffer, int size) :
memcpy(m_buffer->getBuffer(), buffer, size);
}
-AUD_Reference<AUD_IReader> AUD_SndFileFactory::createReader()
+boost::shared_ptr<AUD_IReader> AUD_SndFileFactory::createReader()
{
- if(m_buffer.isNull())
- return new AUD_SndFileReader(m_filename);
+ if(m_buffer.get())
+ return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_buffer));
else
- return new AUD_SndFileReader(m_buffer);
+ return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_filename));
}
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.h b/intern/audaspace/sndfile/AUD_SndFileFactory.h
index 7039c7a2615..bc96325d6eb 100644
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.h
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.h
@@ -31,10 +31,10 @@
#define __AUD_SNDFILEFACTORY_H__
#include "AUD_IFactory.h"
-#include "AUD_Reference.h"
#include "AUD_Buffer.h"
#include <string>
+#include <boost/shared_ptr.hpp>
/**
* This factory reads a sound file via libsndfile.
@@ -50,7 +50,7 @@ private:
/**
* The buffer to read from.
*/
- AUD_Reference<AUD_Buffer> m_buffer;
+ boost::shared_ptr<AUD_Buffer> m_buffer;
// hide copy constructor and operator=
AUD_SndFileFactory(const AUD_SndFileFactory&);
@@ -70,7 +70,7 @@ public:
*/
AUD_SndFileFactory(const data_t* buffer, int size);
- virtual AUD_Reference<AUD_IReader> createReader();
+ virtual boost::shared_ptr<AUD_IReader> createReader();
};
#endif //__AUD_SNDFILEFACTORY_H__
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.cpp b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
index 8dbb43cb17e..aaee814f56b 100644
--- a/intern/audaspace/sndfile/AUD_SndFileReader.cpp
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
@@ -100,7 +100,7 @@ AUD_SndFileReader::AUD_SndFileReader(std::string filename) :
m_seekable = sfinfo.seekable;
}
-AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer) :
+AUD_SndFileReader::AUD_SndFileReader(boost::shared_ptr<AUD_Buffer> buffer) :
m_position(0),
m_membuffer(buffer),
m_memoffset(0)
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.h b/intern/audaspace/sndfile/AUD_SndFileReader.h
index 81d8b45120c..5cac5051ee2 100644
--- a/intern/audaspace/sndfile/AUD_SndFileReader.h
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.h
@@ -31,11 +31,11 @@
#define __AUD_SNDFILEREADER_H__
#include "AUD_IReader.h"
-#include "AUD_Reference.h"
#include "AUD_Buffer.h"
#include <string>
#include <sndfile.h>
+#include <boost/shared_ptr.hpp>
typedef sf_count_t (*sf_read_f)(SNDFILE *sndfile, void *ptr, sf_count_t frames);
@@ -78,7 +78,7 @@ private:
/**
* The pointer to the memory file.
*/
- AUD_Reference<AUD_Buffer> m_membuffer;
+ boost::shared_ptr<AUD_Buffer> m_membuffer;
/**
* The current reading pointer of the memory file.
@@ -110,7 +110,7 @@ public:
* \exception AUD_Exception Thrown if the buffer specified cannot be read
* with libsndfile.
*/
- AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer);
+ AUD_SndFileReader(boost::shared_ptr<AUD_Buffer> buffer);
/**
* Destroys the reader and closes the file.
diff --git a/intern/bsp/CMakeLists.txt b/intern/bsp/CMakeLists.txt
index 136c168bdb8..e3907c5273d 100644
--- a/intern/bsp/CMakeLists.txt
+++ b/intern/bsp/CMakeLists.txt
@@ -29,11 +29,10 @@ set(INC
../guardedalloc
../memutil
../moto/include
- ../../extern/carve/include
)
set(INC_SYS
-
+ ../../extern/carve/include
)
set(SRC
diff --git a/intern/bsp/extern/CSG_BooleanOps.h b/intern/bsp/extern/CSG_BooleanOps.h
index 94a74c30536..5ba6e0d76a1 100644
--- a/intern/bsp/extern/CSG_BooleanOps.h
+++ b/intern/bsp/extern/CSG_BooleanOps.h
@@ -61,9 +61,9 @@ extern "C" {
#endif
typedef struct {
- int vertex_index[4];
- int vertex_number;
- int orig_face;
+ int vertex_index[4];
+ int vertex_number;
+ int orig_face;
} CSG_IFace;
/**
@@ -72,7 +72,7 @@ typedef struct {
*/
typedef struct {
- float position[3];
+ float position[3];
} CSG_IVertex;
/**
diff --git a/intern/bsp/intern/BOP_CarveInterface.cpp b/intern/bsp/intern/BOP_CarveInterface.cpp
index 1f9c989cbc8..bb3a783548c 100644
--- a/intern/bsp/intern/BOP_CarveInterface.cpp
+++ b/intern/bsp/intern/BOP_CarveInterface.cpp
@@ -60,7 +60,7 @@ static bool isQuadPlanar(carve::geom3d::Vector &v1, carve::geom3d::Vector &v2,
float production = carve::geom::dot(cross, vec3);
float magnitude = 1e-5 * cross.length();
- return fabs(production) < magnitude;
+ return fabsf(production) < magnitude;
}
static bool isFacePlanar(CSG_IFace &face, std::vector<carve::geom3d::Vector> &vertices)
@@ -135,10 +135,10 @@ static bool Carve_checkEdgeFaceIntersections(carve::csg::Intersections &intersec
static inline bool Carve_facesAreCoplanar(const MeshSet<3>::face_t *a, const MeshSet<3>::face_t *b)
{
- carve::geom3d::Ray temp;
- // XXX: Find a better definition. This may be a source of problems
- // if floating point inaccuracies cause an incorrect answer.
- return !carve::geom3d::planeIntersection(a->plane, b->plane, temp);
+ carve::geom3d::Ray temp;
+ // XXX: Find a better definition. This may be a source of problems
+ // if floating point inaccuracies cause an incorrect answer.
+ return !carve::geom3d::planeIntersection(a->plane, b->plane, temp);
}
static bool Carve_checkMeshSetInterseciton_do(carve::csg::Intersections &intersections,
@@ -205,7 +205,7 @@ static void Carve_getIntersectedOperandMeshes(std::vector<MeshSet<3>::mesh_t*> &
std::vector<MeshSet<3>::mesh_t*>::iterator it = meshes.begin();
std::vector< RTreeNode<3, Face<3> *> *> meshRTree;
- while(it != meshes.end()) {
+ while (it != meshes.end()) {
MeshSet<3>::mesh_t *mesh = *it;
bool isAdded = false;
@@ -279,7 +279,7 @@ static MeshSet<3> *Carve_unionIntersectingMeshes(MeshSet<3> *poly,
return poly;
}
- while(orig_meshes.size()) {
+ while (orig_meshes.size()) {
MeshSet<3> *right = Carve_getIntersectedOperand(orig_meshes, otherAABB);
if (!right) {
@@ -559,8 +559,6 @@ static bool Carve_checkDegeneratedFace(std::map<MeshSet<3>::vertex_t*, uint> *ve
if (v1 == v2 || v2 == v3 || v1 == v3)
return true;
-
- return triangleArea(face->edge->prev->vert->v, face->edge->vert->v, face->edge->next->vert->v) < DBL_EPSILON;
}
else if (face->n_edges == 4) {
uint v1, v2, v3, v4;
@@ -572,9 +570,6 @@ static bool Carve_checkDegeneratedFace(std::map<MeshSet<3>::vertex_t*, uint> *ve
if (v1 == v2 || v1 == v3 || v1 == v4 || v2 == v3 || v2 == v4 || v3 == v4)
return true;
-
- return triangleArea(face->edge->vert->v, face->edge->next->vert->v, face->edge->next->next->vert->v) +
- triangleArea(face->edge->prev->vert->v, face->edge->vert->v, face->edge->next->next->vert->v) < DBL_EPSILON;
}
return false;
diff --git a/intern/container/CMakeLists.txt b/intern/container/CMakeLists.txt
index b29eea37bc7..8adc46a59de 100644
--- a/intern/container/CMakeLists.txt
+++ b/intern/container/CMakeLists.txt
@@ -33,14 +33,11 @@ set(INC_SYS
)
set(SRC
- intern/CTR_List.cpp
-
CTR_HashedPtr.h
- CTR_List.h
CTR_Map.h
CTR_TaggedIndex.h
CTR_TaggedSetOps.h
- CTR_UHeap.h
)
+# infact nothing to compile!
blender_add_lib(bf_intern_ctr "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/intern/container/CTR_HashedPtr.h b/intern/container/CTR_HashedPtr.h
index 11dc37b3625..ee832eee153 100644
--- a/intern/container/CTR_HashedPtr.h
+++ b/intern/container/CTR_HashedPtr.h
@@ -30,8 +30,8 @@
* \ingroup ctr
*/
-#ifndef CTR_HASHEDPTR_H
-#define CTR_HASHEDPTR_H
+#ifndef __CTR_HASHEDPTR_H__
+#define __CTR_HASHEDPTR_H__
#include <stdlib.h>
@@ -43,13 +43,20 @@ inline unsigned int CTR_Hash(void *inDWord)
class CTR_HashedPtr
{
- void* m_valptr;
+ void *m_valptr;
public:
- CTR_HashedPtr(void* val) : m_valptr(val) {};
- unsigned int hash() const { return CTR_Hash(m_valptr);};
- inline friend bool operator ==(const CTR_HashedPtr & rhs, const CTR_HashedPtr & lhs) { return rhs.m_valptr == lhs.m_valptr;};
- void *getValue() const { return m_valptr; }
+ CTR_HashedPtr(void *val) : m_valptr(val) {
+ }
+ unsigned int hash() const {
+ return CTR_Hash(m_valptr);
+ }
+ inline friend bool operator ==(const CTR_HashedPtr & rhs, const CTR_HashedPtr & lhs) {
+ return rhs.m_valptr == lhs.m_valptr;
+ }
+ void *getValue() const {
+ return m_valptr;
+ }
};
-#endif //CTR_HASHEDPTR_H
+#endif /* __CTR_HASHEDPTR_H__ */
diff --git a/intern/container/CTR_List.h b/intern/container/CTR_List.h
deleted file mode 100644
index 404a08fddf2..00000000000
--- a/intern/container/CTR_List.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file container/CTR_List.h
- * \ingroup ctr
- */
-
-
-
-#ifndef CTR_LIST_H
-#define CTR_LIST_H
-
-class CTR_Link {
-public:
- CTR_Link(
- );
-
- CTR_Link(
- CTR_Link *next,
- CTR_Link *prev
- );
-
- CTR_Link *
- getNext(
- ) const;
-
- CTR_Link *
- getPrev(
- ) const;
-
- bool
- isHead(
- ) const;
-
- bool
- isTail(
- ) const;
-
- void
- insertBefore(
- CTR_Link *link
- );
-
- void
- insertAfter(
- CTR_Link *link
- );
-
- void
- remove(
- );
-
-private:
- CTR_Link *m_next;
- CTR_Link *m_prev;
-};
-
-class CTR_List {
-public:
-
- CTR_List(
- );
-
- CTR_Link *
- getHead(
- ) const;
-
- CTR_Link *
- getTail(
- ) const;
-
- void
- addHead(
- CTR_Link *link
- );
-
- void
- addTail(
- CTR_Link *link
- );
-
-private:
- CTR_Link m_head;
- CTR_Link m_tail;
-};
-
-#endif
-
diff --git a/intern/container/CTR_Map.h b/intern/container/CTR_Map.h
index 9557821d642..c278fe5330c 100644
--- a/intern/container/CTR_Map.h
+++ b/intern/container/CTR_Map.h
@@ -29,22 +29,22 @@
* \ingroup ctr
*/
-
-#ifndef CTR_MAP_H
-#define CTR_MAP_H
+#ifndef __CTR_MAP_H__
+#define __CTR_MAP_H__
template <class Key, class Value>
class CTR_Map {
private:
struct Entry {
Entry (Entry *next, Key key, Value value) :
- m_next(next),
- m_key(key),
- m_value(value) {}
+ m_next(next),
+ m_key(key),
+ m_value(value) {
+ }
Entry *m_next;
- Key m_key;
- Value m_value;
+ Key m_key;
+ Value m_value;
};
public:
@@ -63,18 +63,18 @@ public:
for (int i = 0; i < m_num_buckets; ++i) {
m_buckets[i] = 0;
- for (Entry *entry = map.m_buckets[i]; entry; entry=entry->m_next)
+ for (Entry *entry = map.m_buckets[i]; entry; entry = entry->m_next) {
insert(entry->m_key, entry->m_value);
+ }
}
}
- int size() {
- int count=0;
- for (int i=0;i<m_num_buckets;i++)
- {
- Entry* bucket = m_buckets[i];
- while(bucket)
- {
+ int size()
+ {
+ int count = 0;
+ for (int i = 0; i < m_num_buckets; i++) {
+ Entry *bucket = m_buckets[i];
+ while (bucket) {
bucket = bucket->m_next;
count++;
}
@@ -82,15 +82,13 @@ public:
return count;
}
- Value* at(int index) {
- int count=0;
- for (int i=0;i<m_num_buckets;i++)
- {
- Entry* bucket = m_buckets[i];
- while(bucket)
- {
- if (count==index)
- {
+ Value *at(int index)
+ {
+ int count = 0;
+ for (int i = 0; i < m_num_buckets; i++) {
+ Entry *bucket = m_buckets[i];
+ while (bucket) {
+ if (count == index) {
return &bucket->m_value;
}
bucket = bucket->m_next;
@@ -100,15 +98,13 @@ public:
return 0;
}
- Key* getKey(int index) {
- int count=0;
- for (int i=0;i<m_num_buckets;i++)
- {
- Entry* bucket = m_buckets[i];
- while(bucket)
- {
- if (count==index)
- {
+ Key *getKey(int index)
+ {
+ int count = 0;
+ for (int i = 0; i < m_num_buckets; i++) {
+ Entry *bucket = m_buckets[i];
+ while (bucket) {
+ if (count == index) {
return &bucket->m_key;
}
bucket = bucket->m_next;
@@ -118,7 +114,8 @@ public:
return 0;
}
- void clear() {
+ void clear()
+ {
for (int i = 0; i < m_num_buckets; ++i) {
Entry *entry_ptr = m_buckets[i];
@@ -131,12 +128,14 @@ public:
}
}
- ~CTR_Map() {
+ ~CTR_Map()
+ {
clear();
- delete [] m_buckets;
+ delete[] m_buckets;
}
- void insert(const Key& key, const Value& value) {
+ void insert(const Key& key, const Value& value)
+ {
Entry *entry_ptr = m_buckets[key.hash() % m_num_buckets];
while ((entry_ptr != 0) && !(key == entry_ptr->m_key)) {
entry_ptr = entry_ptr->m_next;
@@ -151,7 +150,8 @@ public:
}
}
- void remove(const Key& key) {
+ void remove(const Key& key)
+ {
Entry **entry_ptr = &m_buckets[key.hash() % m_num_buckets];
while ((*entry_ptr != 0) && !(key == (*entry_ptr)->m_key)) {
entry_ptr = &(*entry_ptr)->m_next;
@@ -164,7 +164,8 @@ public:
}
}
- Value *operator[](Key key) {
+ Value *operator[](Key key)
+ {
Entry *bucket = m_buckets[key.hash() % m_num_buckets];
while ((bucket != 0) && !(key == bucket->m_key)) {
bucket = bucket->m_next;
@@ -177,5 +178,4 @@ private:
Entry **m_buckets;
};
-#endif
-
+#endif /* __CTR_MAP_H__ */
diff --git a/intern/container/CTR_TaggedIndex.h b/intern/container/CTR_TaggedIndex.h
index 8420414d6c7..0eb4e02e84f 100644
--- a/intern/container/CTR_TaggedIndex.h
+++ b/intern/container/CTR_TaggedIndex.h
@@ -29,13 +29,6 @@
* \ingroup ctr
*/
-
-/**
-
- * Copyright (C) 2001 NaN Technologies B.V.
- * Simple tagged index class.
- */
-
#ifndef __CTR_TAGGEDINDEX_H__
#define __CTR_TAGGEDINDEX_H__
@@ -53,7 +46,6 @@
#include "MEM_sys_types.h"
enum {
-
empty_tag = 0x0,
empty_index = 0xffffffff
};
@@ -191,7 +183,7 @@ public:
return (Tag() == Empty().Tag());
}
- // functionals
+ /* functionals */
struct greater : std::binary_function<CTR_TaggedIndex, CTR_TaggedIndex, bool>
{
@@ -213,7 +205,6 @@ private :
unsigned int m_val;
-};
-
-#endif
+};
+#endif /* __CTR_TAGGEDINDEX_H__ */
diff --git a/intern/container/CTR_TaggedSetOps.h b/intern/container/CTR_TaggedSetOps.h
index d30081d2d60..6ebf20b77bf 100644
--- a/intern/container/CTR_TaggedSetOps.h
+++ b/intern/container/CTR_TaggedSetOps.h
@@ -50,16 +50,16 @@
* type ObjectType must have the following public methods to be used by
* this template class:
*
- * int
+ * int
* OpenTag(void) --- return a persistent tag value for the primitive
*
- * void
+ * void
* SetOpenTag(int bla) --- set the persistent tag value for this primitive to bla.
*
- * bool
+ * bool
* SelectTag() --- return a persistent boolean tag for this primitive
*
- * void
+ * void
* SetSelectTag(bool bla) --- set the persistent boolean tag for this primitive to bla.
*
* Here persistent means that the tag should be associated with the object for the
@@ -86,16 +86,16 @@ public :
unsigned int shift
) {
- // iterate through vectors in index_list
- // iterate through individual members of each vector
- // mark each obejct that the index points to
+ /* iterate through vectors in index_list
+ * iterate through individual members of each vector
+ * mark each obejct that the index points to */
typename std::vector< std::vector<IndexType> >::const_iterator
last_vector = index_list.end();
typename std::vector< std::vector<IndexType> >::const_iterator
start_vector = index_list.begin();
- // FIXME some temporary space
+ /* FIXME some temporary space */
std::vector<IndexType> temp_union;
temp_union.reserve(64);
@@ -114,7 +114,7 @@ public :
ObjectType & prim = primitives[*start_index];
if (!prim.OpenTag()) {
- // compute the union
+ /* compute the union */
temp_union.push_back(*start_index);
}
int tag = prim.OpenTag();
@@ -126,7 +126,7 @@ public :
++tag_num;
}
- // now iterate through the union and pull out all those with the right tag
+ /* now iterate through the union and pull out all those with the right tag */
typename std::vector<IndexType>::const_iterator last_index =
temp_union.end();
@@ -138,20 +138,20 @@ public :
ObjectType & prim = primitives[*start_index];
if (prim.OpenTag() == tag_num) {
- //it's part of the intersection!
+ /* it's part of the intersection! */
output.push_back(*start_index);
- // because we're iterating through the union
- // it's safe to remove the tag at this point
+ /* because we're iterating through the union
+ * it's safe to remove the tag at this point */
prim.SetOpenTag(prim.OpenTag() & ~mask);
}
}
};
- // note not a strict set intersection!
- // if x appears twice in b and is part of the intersection
- // it will appear twice in the intersection
+ /* note not a strict set intersection!
+ * if x appears twice in b and is part of the intersection
+ * it will appear twice in the intersection */
static
void
@@ -180,7 +180,7 @@ public :
output.push_back(*start_index);
}
}
- // deselect
+ /* deselect */
last_index = a.end();
start_index = a.begin();
@@ -199,9 +199,9 @@ public :
std::vector<IndexType> &output
) {
- // iterate through vectors in index_list
- // iterate through individual members of each vector
- // mark each obejct that the index points to
+ /* iterate through vectors in index_list
+ * iterate through individual members of each vector
+ * mark each obejct that the index points to */
typename std::vector< std::vector<IndexType> >::const_iterator
last_vector = index_list.end();
@@ -220,15 +220,15 @@ public :
ObjectType & prim = primitives[*start_index];
if (!prim.SelectTag()) {
- // compute the union
+ /* compute the union */
output.push_back(*start_index);
prim.SetSelectTag(true);
}
}
}
- // now iterate through the union and reset the tags
-
+ /* now iterate through the union and reset the tags */
+
typename std::vector<IndexType>::const_iterator last_index =
output.end();
typename std::vector<IndexType>::iterator start_index =
@@ -238,7 +238,7 @@ public :
ObjectType & prim = primitives[*start_index];
prim.SetSelectTag(false);
- }
+ }
}
@@ -251,8 +251,8 @@ public :
std::vector< IndexType> &output
) {
- // iterate through b mark all
- // iterate through a and add to output all unmarked
+ /* iterate through b mark all
+ * iterate through a and add to output all unmarked */
typename std::vector<IndexType>::const_iterator last_index =
b.end();
@@ -276,7 +276,7 @@ public :
}
}
- // clean up the tags
+ /* clean up the tags */
last_index = b.end();
start_index = b.begin();
@@ -290,12 +290,11 @@ public :
private :
- // private constructor - this class is not meant for
- // instantiation
+ /* private constructor - this class is not meant for
+ * instantiation */
CTR_TaggedSetOps();
};
-#endif
-
+#endif /* __CTR_TAGGEDSETOPS_H__ */
diff --git a/intern/container/CTR_UHeap.h b/intern/container/CTR_UHeap.h
deleted file mode 100644
index 8330faa2f54..00000000000
--- a/intern/container/CTR_UHeap.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file container/CTR_UHeap.h
- * \ingroup ctr
- */
-
-
-/**
-
- * Copyright (C) 2001 NaN Technologies B.V.
- *
- * @author Laurence
- * @mainpage CTR_UHeap an updatable heap template class (also
- * known as an updatable priority queue)
- *
- * Todo: Make CTR_UHeapable a template class with m_key the
- * template parameter, so that arbitrary value types with
- * operators (=,>) defined can be used.
- *
- */
-
-#ifndef __CTR_UHEAP_H__
-#define __CTR_UHEAP_H__
-
-#include <vector>
-
-#include "MEM_NonCopyable.h"
-
-class CTR_UHeapable {
-
-public:
- int &
- HeapPos(
- ) {
- return m_ind;
- };
- float &
- HeapKey(
- ) {
- return m_key;
- };
-
- const
- float &
- HeapKey(
- ) const {
- return m_key;
- };
-
- const
- int &
- HeapPos(
- ) const {
- return m_ind;
- };
-
-private:
-
- float m_key;
- int m_ind;
-
-protected:
-
- CTR_UHeapable(
- ) : m_key(0),
- m_ind(0)
- {
- };
-
- ~CTR_UHeapable(
- ) {
- };
-};
-
-template <class HeapType>
-class CTR_UHeap : public MEM_NonCopyable
-{
-
-public:
-
- static
- CTR_UHeap *
- New(
- ) {
- return new CTR_UHeap();
- }
-
- void
- MakeHeap(
- HeapType *base
- ) {
- int i;
- int start = Parent(m_vector.size() - 1);
- for (i = start; i >= 0; --i) {
- DownHeap(base, i);
- }
- };
-
- void
- Insert(
- HeapType *base,
- int elem
- ) {
- // add element to vector
- m_vector.push_back(elem);
- base[elem].HeapPos() = m_vector.size() - 1;
-
- // push the element up the heap
- UpHeap(base, m_vector.size() - 1);
- }
-
- // access to the vector for initial loading of elements
-
- std::vector<int> &
- HeapVector(
- ) {
- return m_vector;
- };
-
-
- void
- Remove(
- HeapType *base,
- int i
- ) {
-
- // exchange with last element - pop last
- // element and move up or down the heap as appropriate
- if (m_vector.empty()) {
- assert(false);
- }
-
- if (i != int(m_vector.size()) - 1) {
-
- Swap(base, i, m_vector.size() - 1);
- m_vector.pop_back();
-
- if (!m_vector.empty()) {
- UpHeap(base, i);
- DownHeap(base, i);
- }
- }
- else {
- m_vector.pop_back();
- }
- }
-
- int
- Top(
- ) const {
- if (m_vector.empty()) return -1;
- return m_vector[0];
- }
-
-
- void
- SC_Heap(
- HeapType *base
- ) {
- int i;
- for (i = 1; i < int(m_vector.size()); i++) {
-
- CTR_UHeapable *elem = base + m_vector[i];
- CTR_UHeapable *p_elem = base + m_vector[Parent(i)];
-
- assert(p_elem->HeapKey() >= elem->HeapKey());
- assert(elem->HeapPos() == i);
- }
-
- };
-
-
- ~CTR_UHeap(
- ) {
- };
-
-
-private:
-
- CTR_UHeap(
- ) {
- };
-
-
- std::vector<int> m_vector;
-
-private:
- void
- Swap(
- HeapType *base,
- int i,
- int j
- ) {
- std::swap(m_vector[i], m_vector[j]);
-
- CTR_UHeapable *heap_i = base + m_vector[i];
- CTR_UHeapable *heap_j = base + m_vector[j];
-
- // Exchange heap positions
- heap_i->HeapPos() = i;
- heap_j->HeapPos() = j;
- }
-
- int
- Parent(
- unsigned int i
- ) {
- return (i - 1) >> 1;
- }
- int
- Left(
- int i
- ) {
- return (i << 1) + 1;
- }
-
- int
- Right(
- int i
- ) {
- return (i << 1) + 2;
- }
-
- float
- HeapVal(
- HeapType *base,
- int i
- ) {
- return base[m_vector[i]].HeapKey();
- }
-
- void
- DownHeap(
- HeapType *base,
- int i
- ) {
- int heap_size = m_vector.size();
-
- int l = Left(i);
- int r = Right(i);
-
- int largest;
- if (l < heap_size && HeapVal(base, l) > HeapVal(base, i)) {
- largest = l;
- }
- else {
- largest = i;
- }
-
- if (r < heap_size && HeapVal(base, r) > HeapVal(base, largest)) {
- largest = r;
- }
-
- if (largest != i) {
- // exchange i and largest
- Swap(base, i, largest);
- DownHeap(base, largest);
- }
- }
-
- void
- UpHeap(
- HeapType *base,
- int i
- ) {
-
- // swap parents untill it's found a place in the heap < it's parent or
- // top of heap
-
- while (i > 0) {
- int p = Parent(i);
- if (HeapVal(base, i) < HeapVal(base, p)) {
- break;
- }
- Swap(base, p, i);
- i = p;
- }
- }
-};
-
-#endif
-
diff --git a/intern/container/intern/CTR_List.cpp b/intern/container/intern/CTR_List.cpp
deleted file mode 100644
index c72d3ccf0d8..00000000000
--- a/intern/container/intern/CTR_List.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file container/intern/CTR_List.cpp
- * \ingroup ctr
- */
-
-
-#include "CTR_List.h"
-
-
-CTR_Link::CTR_Link() :
- m_next(0),
- m_prev(0)
-{
-}
-
-CTR_Link::CTR_Link(CTR_Link *next, CTR_Link *prev) :
- m_next(next),
- m_prev(prev)
-{
-}
-
-CTR_Link *
-CTR_Link::getNext() const
-{
- return m_next;
-}
-
-CTR_Link *
-CTR_Link::getPrev() const
-{
- return m_prev;
-}
-
-bool
-CTR_Link::isHead() const
-{
- return m_prev == 0;
-}
-
-bool
-CTR_Link::isTail() const
-{
- return m_next == 0;
-}
-
-void
-CTR_Link::insertBefore(CTR_Link *link)
-{
- m_next = link;
- m_prev = link->m_prev;
- m_next->m_prev = this;
- m_prev->m_next = this;
-}
-
-void
-CTR_Link::insertAfter(CTR_Link *link)
-{
- m_next = link->m_next;
- m_prev = link;
- m_next->m_prev = this;
- m_prev->m_next = this;
-}
-
-void
-CTR_Link::remove()
-{
- m_next->m_prev = m_prev;
- m_prev->m_next = m_next;
-}
-
-
-CTR_List::CTR_List() :
- m_head(&m_tail, 0),
- m_tail(0, &m_head)
-{
-}
-
-CTR_Link *
-CTR_List:: getHead() const
-{
- return m_head.getNext();
-}
-
-CTR_Link *
-CTR_List::getTail() const
-{
- return m_tail.getPrev();
-}
-
-void
-CTR_List::addHead(CTR_Link *link)
-{
- link->insertAfter(&m_head);
-}
-
-void
-CTR_List::addTail(CTR_Link *link)
-{
- link->insertBefore(&m_tail);
-}
-
diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt
index 38daf790955..7495a98aed1 100644
--- a/intern/cycles/CMakeLists.txt
+++ b/intern/cycles/CMakeLists.txt
@@ -41,10 +41,7 @@ endif()
if(WITH_CYCLES_OSL)
add_definitions(-DWITH_OSL)
-endif()
-
-if(WITH_CYCLES_PARTIO)
- add_definitions(-DWITH_PARTIO)
+ include_directories(${OSL_INCLUDES})
endif()
if(WITH_CYCLES_CUDA_BINARIES)
@@ -68,7 +65,10 @@ if(WITH_CYCLES_BLENDER)
add_subdirectory(blender)
endif()
-add_subdirectory(app)
+if(WITH_CYCLES_TEST)
+ add_subdirectory(app)
+endif()
+
add_subdirectory(bvh)
add_subdirectory(device)
add_subdirectory(doc)
diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript
index a7b8637e3ad..c0e0353d37d 100644
--- a/intern/cycles/SConscript
+++ b/intern/cycles/SConscript
@@ -29,7 +29,7 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']:
incs.extend('. bvh render device kernel kernel/osl kernel/svm util subd'.split())
incs.extend('#intern/guardedalloc #source/blender/makesrna #source/blender/makesdna'.split())
incs.extend('#source/blender/blenloader ../../source/blender/makesrna/intern'.split())
-incs.extend('#extern/glew/include'.split())
+incs.extend('#extern/glew/include #intern/mikktspace'.split())
incs.append(cycles['BF_OIIO_INC'])
incs.append(cycles['BF_BOOST_INC'])
incs.append(cycles['BF_PYTHON_INC'])
diff --git a/intern/cycles/app/CMakeLists.txt b/intern/cycles/app/CMakeLists.txt
index 83b3f731ffe..3fb8aaf934f 100644
--- a/intern/cycles/app/CMakeLists.txt
+++ b/intern/cycles/app/CMakeLists.txt
@@ -35,10 +35,6 @@ if(WITH_CYCLES_OSL)
list(APPEND LIBRARIES cycles_kernel_osl ${OSL_LIBRARIES})
endif()
-if(WITH_CYCLES_PARTIO)
- list(APPEND LIBRARIES ${PARTIO_LIBRARIES})
-endif()
-
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
diff --git a/intern/cycles/app/cycles_test.cpp b/intern/cycles/app/cycles_test.cpp
index e921cc46fe4..625e8cc1706 100644
--- a/intern/cycles/app/cycles_test.cpp
+++ b/intern/cycles/app/cycles_test.cpp
@@ -326,7 +326,7 @@ using namespace ccl;
int main(int argc, const char **argv)
{
- path_init("../build/bin/2.59/scripts/addons/cycles/");
+ path_init();
options_parse(argc, argv);
diff --git a/intern/cycles/app/cycles_xml.cpp b/intern/cycles/app/cycles_xml.cpp
index 87a238e508c..5de9d71b8cc 100644
--- a/intern/cycles/app/cycles_xml.cpp
+++ b/intern/cycles/app/cycles_xml.cpp
@@ -591,6 +591,7 @@ static void xml_read_shader_graph(const XMLReadState& state, Shader *shader, pug
if(string_iequals(in->name, attr.name())) {
switch(in->type) {
case SHADER_SOCKET_FLOAT:
+ case SHADER_SOCKET_INT:
xml_read_float(&in->value.x, node, attr.name());
break;
case SHADER_SOCKET_COLOR:
diff --git a/intern/cycles/blender/CCL_api.h b/intern/cycles/blender/CCL_api.h
index 469d63d1530..b8a30b71717 100644
--- a/intern/cycles/blender/CCL_api.h
+++ b/intern/cycles/blender/CCL_api.h
@@ -23,12 +23,12 @@
extern "C" {
#endif
-/* returns a list of devices for selection, array is name NULL pointer
+/* returns a list of devices for selection, array is empty identifier
* terminated and must not be freed */
typedef struct CCLDeviceInfo {
- const char *identifier;
- const char *name;
+ char identifier[128];
+ char name[512];
int value;
} CCLDeviceInfo;
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index a8c7eef89fa..292c37d6b61 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -7,6 +7,7 @@ set(INC
../util
../subd
../../guardedalloc
+ ../../mikktspace
../../../source/blender/makesdna
../../../source/blender/makesrna
../../../source/blender/blenloader
@@ -38,6 +39,7 @@ set(ADDON_FILES
addon/__init__.py
addon/engine.py
addon/enums.py
+ addon/osl.py
addon/presets.py
addon/properties.py
addon/ui.py
diff --git a/intern/cycles/blender/addon/__init__.py b/intern/cycles/blender/addon/__init__.py
index 6292c09fbb1..0fad2ac5618 100644
--- a/intern/cycles/blender/addon/__init__.py
+++ b/intern/cycles/blender/addon/__init__.py
@@ -48,7 +48,11 @@ class CyclesRender(bpy.types.RenderEngine):
# final render
def update(self, data, scene):
- engine.create(self, data, scene)
+ if not self.session:
+ engine.create(self, data, scene)
+ else:
+ engine.reset(self, data, scene)
+
engine.update(self, data, scene)
def render(self, scene):
@@ -71,6 +75,13 @@ class CyclesRender(bpy.types.RenderEngine):
def view_draw(self, context):
engine.draw(self, context.region, context.space_data, context.region_data)
+ def update_script_node(self, node):
+ if engine.with_osl():
+ from . import osl
+ osl.update_script_node(node, self.report)
+ else:
+ self.report({'ERROR'}, "OSL support disabled in this build.")
+
def register():
properties.register()
@@ -84,3 +95,4 @@ def unregister():
properties.unregister()
presets.unregister()
bpy.utils.unregister_module(__name__)
+
diff --git a/intern/cycles/blender/addon/engine.py b/intern/cycles/blender/addon/engine.py
index 05b1f883594..ca5cbee9325 100644
--- a/intern/cycles/blender/addon/engine.py
+++ b/intern/cycles/blender/addon/engine.py
@@ -61,6 +61,13 @@ def render(engine):
_cycles.render(engine.session)
+def reset(engine, data, scene):
+ import _cycles
+ data = data.as_pointer()
+ scene = scene.as_pointer()
+ _cycles.reset(engine.session, data, scene)
+
+
def update(engine, data, scene):
import _cycles
_cycles.sync(engine.session)
@@ -83,3 +90,4 @@ def available_devices():
def with_osl():
import _cycles
return _cycles.with_osl
+
diff --git a/intern/cycles/blender/addon/enums.py b/intern/cycles/blender/addon/enums.py
index 6cc3010eb0e..82b48973ca1 100644
--- a/intern/cycles/blender/addon/enums.py
+++ b/intern/cycles/blender/addon/enums.py
@@ -58,5 +58,6 @@ aperture_types = (
panorama_types = (
('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"),
('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"),
- ('FISHEYE_EQUISOLID', "Fisheye Equisolid", "Similar to most fisheye modern lens, take sensor dimensions into consideration"),
+ ('FISHEYE_EQUISOLID', "Fisheye Equisolid",
+ "Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
)
diff --git a/intern/cycles/blender/addon/osl.py b/intern/cycles/blender/addon/osl.py
new file mode 100644
index 00000000000..aac1e2422b9
--- /dev/null
+++ b/intern/cycles/blender/addon/osl.py
@@ -0,0 +1,127 @@
+#
+# Copyright 2011, Blender Foundation.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+
+# <pep8 compliant>
+
+import bpy, _cycles, os, tempfile
+
+# compile .osl file with given filepath to temporary .oso file
+def osl_compile(input_path, report):
+ output_file = tempfile.NamedTemporaryFile(mode='w', suffix=".oso", delete=False)
+ output_path = output_file.name
+ output_file.close()
+
+ ok = _cycles.osl_compile(input_path, output_path)
+
+ if ok:
+ report({'INFO'}, "OSL shader compilation succeeded")
+
+ return ok, output_path
+
+# compile and update shader script node
+def update_script_node(node, report):
+ import os, shutil
+
+ if node.mode == 'EXTERNAL':
+ # compile external script file
+ script_path = bpy.path.abspath(node.filepath, library=node.id_data.library)
+ script_path_noext, script_ext = os.path.splitext(script_path)
+
+ if script_ext == ".oso":
+ # it's a .oso file, no need to compile
+ ok, oso_path = True, script_path
+ oso_file_remove = False
+ elif script_ext == ".osl":
+ # compile .osl file
+ ok, oso_path = osl_compile(script_path, report)
+ oso_file_remove = True
+
+ if ok:
+ # copy .oso from temporary path to .osl directory
+ dst_path = script_path_noext + ".oso"
+ try:
+ shutil.copy2(oso_path, dst_path)
+ except:
+ report({'ERROR'}, "Failed to write .oso file next to external .osl file at " + dst_path)
+ elif os.path.dirname(node.filepath) == "":
+ # module in search path
+ oso_path = node.filepath
+ oso_file_remove = False
+ ok = True
+ else:
+ # unknown
+ report({'ERROR'}, "External shader script must have .osl or .oso extension, or be a module name")
+ ok = False
+
+ if ok:
+ node.bytecode = ""
+ node.bytecode_hash = ""
+
+ elif node.mode == 'INTERNAL' and node.script:
+ # internal script, we will store bytecode in the node
+ script = node.script
+ osl_path = bpy.path.abspath(script.filepath, library=script.library)
+
+ if script.is_in_memory or script.is_dirty or script.is_modified or not os.path.exists(osl_path):
+ # write text datablock contents to temporary file
+ osl_file = tempfile.NamedTemporaryFile(mode='w', suffix=".osl", delete=True)
+ osl_file.write(script.as_string())
+ osl_file.flush()
+ ok, oso_path = osl_compile(osl_file.name, report)
+ oso_file_remove = False
+ osl_file.close()
+ else:
+ # compile text datablock from disk directly
+ ok, oso_path = osl_compile(osl_path, report)
+ oso_file_remove = False
+
+ if ok:
+ # read bytecode
+ try:
+ oso = open(oso_path, 'r')
+ node.bytecode = oso.read()
+ oso.close()
+ except:
+ import traceback
+ traceback.print_exc()
+
+ report({'ERROR'}, "Can't read OSO bytecode to store in node at %r" % oso_path)
+ ok = False
+
+ else:
+ report({'WARNING'}, "No text or file specified in node, nothing to compile")
+ return
+
+ if ok:
+ # now update node with new sockets
+ ok = _cycles.osl_update_node(node.id_data.as_pointer(), node.as_pointer(), oso_path)
+
+ if not ok:
+ report({'ERROR'}, "OSL query failed to open " + oso_path)
+ else:
+ report({'ERROR'}, "OSL script compilation failed, see console for errors")
+
+ # remove temporary oso file
+ if oso_file_remove:
+ try:
+ os.remove(oso_path)
+ except:
+ pass
+
+ return ok
+
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 0fadfa0afc8..0b8ca6e0fbe 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -136,7 +136,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
)
cls.blur_glossy = FloatProperty(
name="Filter Glossy",
- description="Adaptively blur glossy shaders after blurry bounces, to reduce noise at the cost of accuracy",
+ description="Adaptively blur glossy shaders after blurry bounces, "
+ "to reduce noise at the cost of accuracy",
min=0.0, max=10.0,
default=0.0,
)
@@ -230,7 +231,9 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
cls.sample_clamp = FloatProperty(
name="Clamp",
- description="If non-zero, the maximum value for a sample, higher values will be scaled down to avoid too much noise and slow convergence at the cost of accuracy",
+ description="If non-zero, the maximum value for a sample, "
+ "higher values will be scaled down to avoid too "
+ "much noise and slow convergence at the cost of accuracy",
min=0.0, max=1e8,
default=0.0,
)
@@ -244,7 +247,8 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
cls.preview_start_resolution = IntProperty(
name="Start Resolution",
- description="Resolution to start rendering preview at, progressively increasing it to the full viewport size",
+ description="Resolution to start rendering preview at, "
+ "progressively increasing it to the full viewport size",
min=8, max=16384,
default=64,
)
@@ -284,6 +288,14 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Cache last built BVH to disk for faster re-render if no geometry changed",
default=False,
)
+ cls.use_progressive_refine = BoolProperty(
+ name="Progressive Refine",
+ description="Instead of rendering each tile until it is finished, "
+ "refine the whole image progressively "
+ "(this renders somewhat slower, "
+ "but time can be saved by manually stopping the render when the noise is low enough)",
+ default=False,
+ )
@classmethod
def unregister(cls):
@@ -369,12 +381,15 @@ class CyclesMaterialSettings(bpy.types.PropertyGroup):
)
cls.sample_as_light = BoolProperty(
name="Sample as Lamp",
- description="Use direct light sampling for this material, disabling may reduce overall noise for large objects that emit little light compared to other light sources",
+ description="Use direct light sampling for this material, "
+ "disabling may reduce overall noise for large "
+ "objects that emit little light compared to other light sources",
default=True,
)
cls.homogeneous_volume = BoolProperty(
name="Homogeneous Volume",
- description="When using volume rendering, assume volume has the same density everywhere, for faster rendering",
+ description="When using volume rendering, assume volume has the same density everywhere, "
+ "for faster rendering",
default=False,
)
@@ -418,12 +433,14 @@ class CyclesWorldSettings(bpy.types.PropertyGroup):
)
cls.sample_as_light = BoolProperty(
name="Sample as Lamp",
- description="Use direct light sampling for the environment, enabling for non-solid colors is recommended",
+ description="Use direct light sampling for the environment, "
+ "enabling for non-solid colors is recommended",
default=False,
)
cls.sample_map_resolution = IntProperty(
name="Map Resolution",
- description="Importance map size is resolution x resolution; higher values potentially produce less noise, at the cost of memory and speed",
+ description="Importance map size is resolution x resolution; "
+ "higher values potentially produce less noise, at the cost of memory and speed",
min=4, max=8096,
default=256,
)
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 4f4b0371839..4a651eb5aab 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -134,10 +134,6 @@ class CyclesRender_PT_motion_blur(CyclesButtonsPanel, Panel):
bl_label = "Motion Blur"
bl_options = {'DEFAULT_CLOSED'}
- @classmethod
- def poll(cls, context):
- return False
-
def draw_header(self, context):
rd = context.scene.render
@@ -197,10 +193,12 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
sub.prop(rd, "threads")
sub = col.column(align=True)
- sub.label(text="Tiles:")
+ sub.label(text="Tile Size:")
- sub.prop(rd, "parts_x", text="X")
- sub.prop(rd, "parts_y", text="Y")
+ sub.prop(rd, "tile_x", text="X")
+ sub.prop(rd, "tile_y", text="Y")
+
+ sub.prop(cscene, "use_progressive_refine")
subsub = sub.column()
subsub.enabled = not rd.use_border
@@ -218,6 +216,10 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
sub.label(text="Viewport:")
sub.prop(cscene, "preview_start_resolution")
+ sub = col.column(align=True)
+ sub.label(text="Final Render:")
+ sub.prop(rd, "use_persistent_data", text="Persistent Images")
+
class CyclesRender_PT_layers(CyclesButtonsPanel, Panel):
bl_label = "Layers"
@@ -955,7 +957,7 @@ def draw_device(self, context):
elif device_type == 'OPENCL' and cscene.feature_set == 'EXPERIMENTAL':
layout.prop(cscene, "device")
- if engine.with_osl() and (cscene.device == 'CPU' or device_type == 'None'):
+ if engine.with_osl() and (cscene.device == 'CPU' or device_type == 'NONE'):
layout.prop(cscene, "shading_system")
@@ -990,6 +992,7 @@ def get_panels():
bpy.types.DATA_PT_context_mesh,
bpy.types.DATA_PT_context_camera,
bpy.types.DATA_PT_context_lamp,
+ bpy.types.DATA_PT_context_speaker,
bpy.types.DATA_PT_texture_space,
bpy.types.DATA_PT_curve_texture_space,
bpy.types.DATA_PT_mball_texture_space,
@@ -1000,10 +1003,14 @@ def get_panels():
bpy.types.DATA_PT_camera,
bpy.types.DATA_PT_camera_display,
bpy.types.DATA_PT_lens,
+ bpy.types.DATA_PT_speaker,
+ bpy.types.DATA_PT_distance,
+ bpy.types.DATA_PT_cone,
bpy.types.DATA_PT_customdata,
bpy.types.DATA_PT_custom_props_mesh,
bpy.types.DATA_PT_custom_props_camera,
bpy.types.DATA_PT_custom_props_lamp,
+ bpy.types.DATA_PT_custom_props_speaker,
bpy.types.TEXTURE_PT_clouds,
bpy.types.TEXTURE_PT_wood,
bpy.types.TEXTURE_PT_marble,
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index e16677336d5..61fe7cf254d 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -56,10 +56,8 @@ struct BlenderCamera {
float sensor_width;
float sensor_height;
- float border_left;
- float border_right;
- float border_bottom;
- float border_top;
+ BoundBox2D border;
+ BoundBox2D pano_viewplane;
Transform matrix;
};
@@ -75,8 +73,10 @@ static void blender_camera_init(BlenderCamera *bcam)
bcam->sensor_height = 18.0f;
bcam->sensor_fit = BlenderCamera::AUTO;
bcam->shuttertime = 1.0f;
- bcam->border_right = 1.0f;
- bcam->border_top = 1.0f;
+ bcam->border.right = 1.0f;
+ bcam->border.top = 1.0f;
+ bcam->pano_viewplane.right = 1.0f;
+ bcam->pano_viewplane.top = 1.0f;
}
static float blender_camera_focal_distance(BL::Object b_ob, BL::Camera b_camera)
@@ -199,7 +199,7 @@ static Transform blender_camera_matrix(const Transform& tfm, CameraType type)
}
static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height,
- float *left, float *right, float *bottom, float *top, float *aspectratio, float *sensor_size)
+ BoundBox2D *viewplane, float *aspectratio, float *sensor_size)
{
/* dimensions */
float xratio = width*bcam->pixelaspect.x;
@@ -244,32 +244,26 @@ static void blender_camera_viewplane(BlenderCamera *bcam, int width, int height,
if(bcam->type == CAMERA_PANORAMA) {
/* set viewplane */
- *left = 0.0f;
- *right = 1.0f;
- *bottom = 0.0f;
- *top = 1.0f;
+ *viewplane = bcam->pano_viewplane;
}
else {
/* set viewplane */
- *left = -xaspect;
- *right = xaspect;
- *bottom = -yaspect;
- *top = yaspect;
+ viewplane->left = -xaspect;
+ viewplane->right = xaspect;
+ viewplane->bottom = -yaspect;
+ viewplane->top = yaspect;
/* zoom for 3d camera view */
- *left *= bcam->zoom;
- *right *= bcam->zoom;
- *bottom *= bcam->zoom;
- *top *= bcam->zoom;
+ *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);
- *left += dx;
- *right += dx;
- *bottom += dy;
- *top += dy;
+ viewplane->left += dx;
+ viewplane->right += dx;
+ viewplane->bottom += dy;
+ viewplane->top += dy;
}
}
@@ -281,7 +275,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
/* viewplane */
blender_camera_viewplane(bcam, width, height,
- &cam->left, &cam->right, &cam->bottom, &cam->top, &aspectratio, &sensor_size);
+ &cam->viewplane, &aspectratio, &sensor_size);
/* sensor */
cam->sensorwidth = bcam->sensor_width;
@@ -314,10 +308,7 @@ static void blender_camera_sync(Camera *cam, BlenderCamera *bcam, int width, int
cam->shuttertime = bcam->shuttertime;
/* border */
- cam->border_left = bcam->border_left;
- cam->border_right = bcam->border_right;
- cam->border_bottom = bcam->border_bottom;
- cam->border_top = bcam->border_top;
+ cam->border = bcam->border;
/* set update flag */
if(cam->modified(prevcam))
@@ -340,10 +331,10 @@ void BlenderSync::sync_camera(BL::Object b_override, int width, int height)
/* border */
if(r.use_border()) {
- bcam.border_left = r.border_min_x();
- bcam.border_right = r.border_max_x();
- bcam.border_bottom = r.border_min_y();
- bcam.border_top = r.border_max_y();
+ bcam.border.left = r.border_min_x();
+ bcam.border.right = r.border_max_x();
+ bcam.border.bottom = r.border_min_y();
+ bcam.border.top = r.border_max_y();
}
/* camera object */
@@ -381,6 +372,9 @@ void BlenderSync::sync_camera_motion(BL::Object b_ob, int motion)
/* Sync 3D View Camera */
+static void blender_camera_view_subset(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::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height, bool skip_panorama = false)
{
/* 3d view parameters */
@@ -396,14 +390,25 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
if(b_ob) {
blender_camera_from_object(bcam, b_ob, skip_panorama);
- /* 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());
+ if(!skip_panorama && bcam->type == CAMERA_PANORAMA) {
+ /* in panorama camera view, we map viewplane to camera border */
+ BoundBox2D view_box, cam_box;
+
+ blender_camera_view_subset(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) {
@@ -411,8 +416,14 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
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();
+ bcam->ortho_scale = b_rv3d.view_distance() * sensor_size / b_v3d.lens();
}
bcam->zoom *= 2.0f;
@@ -421,30 +432,11 @@ static void blender_camera_from_view(BlenderCamera *bcam, BL::Scene b_scene, BL:
bcam->matrix = transform_inverse(get_transform(b_rv3d.view_matrix()));
}
-static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d,
- BL::RegionView3D b_rv3d, int width, int height)
+static void blender_camera_view_subset(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)
{
BL::RenderSettings r = b_scene.render();
-
- if(!r.use_border())
- return;
-
- /* camera view? */
- if(!(b_rv3d && b_rv3d.view_perspective() == BL::RegionView3D::view_perspective_CAMERA))
- return;
-
- BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera();
-
- if(!b_ob)
- return;
-
- bcam->border_left = r.border_min_x();
- bcam->border_right = r.border_max_x();
- bcam->border_bottom = r.border_min_y();
- bcam->border_top = r.border_max_y();
-
- float cam_left, cam_right, cam_bottom, cam_top;
- float view_left, view_right, view_bottom, view_top;
+ BoundBox2D cam, view;
float view_aspect, cam_aspect, sensor_size;
/* get viewport viewplane */
@@ -453,12 +445,7 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
blender_camera_from_view(&view_bcam, b_scene, b_v3d, b_rv3d, width, height, true);
blender_camera_viewplane(&view_bcam, width, height,
- &view_left, &view_right, &view_bottom, &view_top, &view_aspect, &sensor_size);
-
- view_left /= view_aspect;
- view_right /= view_aspect;
- view_bottom /= view_aspect;
- view_top /= view_aspect;
+ &view, &view_aspect, &sensor_size);
/* get camera viewplane */
BlenderCamera cam_bcam;
@@ -469,29 +456,58 @@ static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::Sp
height = (int)(r.resolution_y()*r.resolution_percentage()/100);
blender_camera_viewplane(&cam_bcam, width, height,
- &cam_left, &cam_right, &cam_bottom, &cam_top, &cam_aspect, &sensor_size);
+ &cam, &cam_aspect, &sensor_size);
+
+ /* return */
+ *view_box = view * (1.0f/view_aspect);
+ *cam_box = cam * (1.0f/cam_aspect);
+}
+
+static void blender_camera_border(BlenderCamera *bcam, BL::Scene b_scene, BL::SpaceView3D b_v3d,
+ BL::RegionView3D b_rv3d, int width, int height)
+{
+ BL::RenderSettings r = b_scene.render();
+ bool is_camera_view;
- cam_left /= cam_aspect;
- cam_right /= cam_aspect;
- cam_bottom /= cam_aspect;
- cam_top /= cam_aspect;
+ /* 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;
+ }
+ }
+ else if(!r.use_border())
+ return;
+
+ BL::Object b_ob = (b_v3d.lock_camera_and_layers())? b_scene.camera(): b_v3d.camera();
+
+ if(!b_ob)
+ return;
+
+ bcam->border.left = r.border_min_x();
+ bcam->border.right = r.border_max_x();
+ bcam->border.bottom = r.border_min_y();
+ bcam->border.top = r.border_max_y();
+
+ /* determine camera viewport subset */
+ BoundBox2D view_box, cam_box;
+
+ blender_camera_view_subset(b_scene, b_ob, b_v3d, b_rv3d, width, height,
+ &view_box, &cam_box);
/* determine viewport subset matching camera border */
- float tmp_left = ((cam_left - view_left) / (view_right - view_left));
- float tmp_right = ((cam_right - view_left) / (view_right - view_left));
- float tmp_bottom = ((cam_bottom - view_bottom) / (view_top - view_bottom));
- float tmp_top = ((cam_top - view_bottom) / (view_top - view_bottom));
-
- bcam->border_left = tmp_left + bcam->border_left*(tmp_right - tmp_left);
- bcam->border_right = tmp_left + bcam->border_right*(tmp_right - tmp_left);
- bcam->border_bottom = tmp_bottom + bcam->border_bottom*(tmp_top - tmp_bottom);
- bcam->border_top = tmp_bottom + bcam->border_top*(tmp_top - tmp_bottom);
-
- /* clamp */
- bcam->border_left = clamp(bcam->border_left, 0.0f, 1.0f);
- bcam->border_right = clamp(bcam->border_right, 0.0f, 1.0f);
- bcam->border_bottom = clamp(bcam->border_bottom, 0.0f, 1.0f);
- bcam->border_top = clamp(bcam->border_top, 0.0f, 1.0f);
+ cam_box = cam_box.make_relative_to(view_box);
+ bcam->border = cam_box.subset(bcam->border).clamp();
}
void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int width, int height)
@@ -504,19 +520,25 @@ void BlenderSync::sync_view(BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, int
blender_camera_sync(scene->camera, &bcam, width, height);
}
-BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, Camera *cam, int width, int height)
+BufferParams BlenderSync::get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height)
{
BufferParams params;
+ bool use_border = false;
params.full_width = width;
params.full_height = height;
- if(b_scene.render().use_border()) {
+ 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_scene.render().use_border();
+
+ if(use_border) {
/* border render */
- params.full_x = cam->border_left*width;
- params.full_y = cam->border_bottom*height;
- params.width = (int)(cam->border_right*width) - params.full_x;
- params.height = (int)(cam->border_top*height) - params.full_y;
+ params.full_x = cam->border.left*width;
+ params.full_y = cam->border.bottom*height;
+ params.width = (int)(cam->border.right*width) - params.full_x;
+ params.height = (int)(cam->border.top*height) - params.full_y;
/* survive in case border goes out of view or becomes too small */
params.width = max(params.width, 1);
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 9764f24a893..c9748756d43 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -16,6 +16,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
+
#include "mesh.h"
#include "object.h"
#include "scene.h"
@@ -29,9 +30,172 @@
#include "util_foreach.h"
+#include "mikktspace.h"
+
CCL_NAMESPACE_BEGIN
-/* Find/Add */
+/* Tangent Space */
+
+struct MikkUserData {
+ MikkUserData(const BL::Mesh mesh_, const BL::MeshTextureFaceLayer layer_, int num_faces_)
+ : mesh(mesh_), layer(layer_), num_faces(num_faces_)
+ {
+ tangent.resize(num_faces*4);
+ }
+
+ BL::Mesh mesh;
+ BL::MeshTextureFaceLayer layer;
+ int num_faces;
+ vector<float4> tangent;
+};
+
+static int mikk_get_num_faces(const SMikkTSpaceContext *context)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ return userdata->num_faces;
+}
+
+static int mikk_get_num_verts_of_face(const SMikkTSpaceContext *context, const int face_num)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
+ int4 vi = get_int4(f.vertices_raw());
+
+ return (vi[3] == 0)? 3: 4;
+}
+
+static void mikk_get_position(const SMikkTSpaceContext *context, float P[3], const int face_num, const int vert_num)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
+ int4 vi = get_int4(f.vertices_raw());
+ BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]];
+ float3 vP = get_float3(v.co());
+
+ 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)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ BL::MeshTextureFace tf = userdata->layer.data[face_num];
+ float3 tfuv;
+
+ if(vert_num == 0)
+ tfuv = get_float3(tf.uv1());
+ else if(vert_num == 1)
+ tfuv = get_float3(tf.uv2());
+ else if(vert_num == 2)
+ tfuv = get_float3(tf.uv3());
+ else
+ tfuv = get_float3(tf.uv4());
+
+ uv[0] = tfuv.x;
+ uv[1] = tfuv.y;
+}
+
+static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3], const int face_num, const int vert_num)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+ BL::MeshTessFace f = userdata->mesh.tessfaces[face_num];
+ int4 vi = get_int4(f.vertices_raw());
+ BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]];
+ float3 vN = get_float3(v.normal());
+
+ 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, const int vert)
+{
+ MikkUserData *userdata = (MikkUserData*)context->m_pUserData;
+
+ userdata->tangent[face*4 + vert] = make_float4(T[0], T[1], T[2], sign);
+}
+
+static void mikk_compute_tangents(BL::Mesh b_mesh, BL::MeshTextureFaceLayer b_layer, Mesh *mesh, vector<int>& nverts, bool need_sign, bool active_render)
+{
+ /* setup userdata */
+ MikkUserData userdata(b_mesh, b_layer, nverts.size());
+
+ /* 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 */
+ Attribute *attr;
+ ustring name = ustring((string(b_layer.name().c_str()) + ".tangent").c_str());
+
+ if(active_render)
+ attr = mesh->attributes.add(ATTR_STD_UV_TANGENT, name);
+ else
+ attr = mesh->attributes.add(name, TypeDesc::TypeVector, Attribute::CORNER);
+
+ float3 *tangent = attr->data_float3();
+
+ /* create bitangent sign attribute */
+ float *tangent_sign = NULL;
+
+ if(need_sign) {
+ Attribute *attr_sign;
+ ustring name_sign = ustring((string(b_layer.name().c_str()) + ".tangent_sign").c_str());
+
+ if(active_render)
+ attr_sign = mesh->attributes.add(ATTR_STD_UV_TANGENT_SIGN, name_sign);
+ else
+ attr_sign = mesh->attributes.add(name_sign, TypeDesc::TypeFloat, Attribute::CORNER);
+
+ tangent_sign = attr_sign->data_float();
+ }
+
+ for(int i = 0; i < nverts.size(); i++) {
+ tangent[0] = float4_to_float3(userdata.tangent[i*4 + 0]);
+ tangent[1] = float4_to_float3(userdata.tangent[i*4 + 1]);
+ tangent[2] = float4_to_float3(userdata.tangent[i*4 + 2]);
+ tangent += 3;
+
+ if(tangent_sign) {
+ tangent_sign[0] = userdata.tangent[i*4 + 0].w;
+ tangent_sign[1] = userdata.tangent[i*4 + 1].w;
+ tangent_sign[2] = userdata.tangent[i*4 + 2].w;
+ tangent_sign += 3;
+ }
+
+ if(nverts[i] == 4) {
+ tangent[0] = float4_to_float3(userdata.tangent[i*4 + 0]);
+ tangent[1] = float4_to_float3(userdata.tangent[i*4 + 2]);
+ tangent[2] = float4_to_float3(userdata.tangent[i*4 + 3]);
+ tangent += 3;
+
+ if(tangent_sign) {
+ tangent_sign[0] = userdata.tangent[i*4 + 0].w;
+ tangent_sign[1] = userdata.tangent[i*4 + 2].w;
+ tangent_sign[2] = userdata.tangent[i*4 + 3].w;
+ tangent_sign += 3;
+ }
+ }
+ }
+}
+
+/* Create Mesh */
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders)
{
@@ -67,27 +231,6 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
nverts.push_back(n);
}
- /* create generated coordinates. todo: we should actually get the orco
- * coordinates from modifiers, for now we use texspace loc/size which
- * is available in the api. */
- if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
- Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
- float3 loc = get_float3(b_mesh.texspace_location());
- float3 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;
-
- loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
-
- float3 *fdata = attr->data_float3();
- size_t i = 0;
-
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v)
- fdata[i++] = get_float3(v->co())*size - loc;
- }
-
/* create vertex color attributes */
{
BL::Mesh::tessface_vertex_colors_iterator l;
@@ -125,38 +268,72 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
BL::Mesh::tessface_uv_textures_iterator l;
for(b_mesh.tessface_uv_textures.begin(l); l != b_mesh.tessface_uv_textures.end(); ++l) {
- AttributeStandard std = (l->active_render())? ATTR_STD_UV: ATTR_STD_NONE;
+ bool active_render = l->active_render();
+ AttributeStandard std = (active_render)? ATTR_STD_UV: ATTR_STD_NONE;
ustring name = ustring(l->name().c_str());
- if(!(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)))
- continue;
-
- Attribute *attr;
-
- if(l->active_render())
- attr = mesh->attributes.add(std, name);
- else
- attr = mesh->attributes.add(name, TypeDesc::TypePoint, Attribute::CORNER);
+ /* UV map */
+ if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
+ Attribute *attr;
- BL::MeshTextureFaceLayer::data_iterator t;
- float3 *fdata = attr->data_float3();
- size_t i = 0;
+ if(active_render)
+ attr = mesh->attributes.add(std, name);
+ else
+ attr = mesh->attributes.add(name, TypeDesc::TypePoint, Attribute::CORNER);
- for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
- fdata[0] = get_float3(t->uv1());
- fdata[1] = get_float3(t->uv2());
- fdata[2] = get_float3(t->uv3());
- fdata += 3;
+ BL::MeshTextureFaceLayer::data_iterator t;
+ float3 *fdata = attr->data_float3();
+ size_t i = 0;
- if(nverts[i] == 4) {
+ for(l->data.begin(t); t != l->data.end(); ++t, ++i) {
fdata[0] = get_float3(t->uv1());
- fdata[1] = get_float3(t->uv3());
- fdata[2] = get_float3(t->uv4());
+ fdata[1] = get_float3(t->uv2());
+ fdata[2] = get_float3(t->uv3());
fdata += 3;
+
+ if(nverts[i] == 4) {
+ fdata[0] = get_float3(t->uv1());
+ fdata[1] = get_float3(t->uv3());
+ fdata[2] = get_float3(t->uv4());
+ fdata += 3;
+ }
}
}
+
+ /* UV tangent */
+ std = (active_render)? ATTR_STD_UV_TANGENT: ATTR_STD_NONE;
+ name = ustring((string(l->name().c_str()) + ".tangent").c_str());
+
+ if(mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std)) {
+ std = (active_render)? ATTR_STD_UV_TANGENT_SIGN: ATTR_STD_NONE;
+ name = ustring((string(l->name().c_str()) + ".tangent_sign").c_str());
+ bool need_sign = (mesh->need_attribute(scene, name) || mesh->need_attribute(scene, std));
+
+ mikk_compute_tangents(b_mesh, *l, mesh, nverts, need_sign, active_render);
+ }
}
}
+
+ /* create generated coordinates. todo: we should actually get the orco
+ * coordinates from modifiers, for now we use texspace loc/size which
+ * is available in the api. */
+ if(mesh->need_attribute(scene, ATTR_STD_GENERATED)) {
+ Attribute *attr = mesh->attributes.add(ATTR_STD_GENERATED);
+ float3 loc = get_float3(b_mesh.texspace_location());
+ float3 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;
+
+ loc = loc*size - make_float3(0.5f, 0.5f, 0.5f);
+
+ 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->co())*size - loc;
+ }
}
static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA *cmesh, const vector<uint>& used_shaders)
@@ -270,7 +447,7 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated)
create_mesh(scene, mesh, b_mesh, used_shaders);
/* free derived mesh */
- object_remove_mesh(b_data, b_mesh);
+ b_data.meshes.remove(b_mesh);
}
/* displacement method */
@@ -328,7 +505,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion)
mesh->attributes.remove(std);
/* free derived mesh */
- object_remove_mesh(b_data, b_mesh);
+ b_data.meshes.remove(b_mesh);
}
}
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 27301026d35..e8fa5c0ff3d 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -17,12 +17,14 @@
*/
#include "camera.h"
+#include "integrator.h"
#include "graph.h"
#include "light.h"
#include "mesh.h"
#include "object.h"
#include "scene.h"
#include "nodes.h"
+#include "particles.h"
#include "shader.h"
#include "blender_sync.h"
@@ -84,11 +86,11 @@ static uint object_ray_visibility(BL::Object b_ob)
/* Light */
-void BlenderSync::sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm)
+void BlenderSync::sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm)
{
/* test if we need to sync */
Light *light;
- ObjectKey key(b_parent, b_index, b_ob);
+ ObjectKey key(b_parent, persistent_id, b_ob);
if(!light_map.sync(&light, b_ob, b_parent, key))
return;
@@ -194,23 +196,24 @@ void BlenderSync::sync_background_light()
/* Object */
-void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion, int particle_id)
+Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, Transform& tfm, uint layer_flag, int motion)
{
BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent);
/* light is handled separately */
if(object_is_light(b_ob)) {
if(!motion)
- sync_light(b_parent, b_index, b_ob, tfm);
- return;
+ sync_light(b_parent, persistent_id, b_ob, tfm);
+
+ return NULL;
}
/* only interested in object that we can create meshes from */
if(!object_is_mesh(b_ob))
- return;
+ return NULL;
/* key to lookup object */
- ObjectKey key(b_parent, b_index, b_ob);
+ ObjectKey key(b_parent, persistent_id, b_ob);
Object *object;
/* motion vector case */
@@ -227,10 +230,12 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject
object->use_motion = true;
}
- sync_mesh_motion(b_ob, object->mesh, motion);
+ /* mesh deformation blur not supported yet */
+ if(!scene->integrator->motion_blur)
+ sync_mesh_motion(b_ob, object->mesh, motion);
}
- return;
+ return object;
}
/* test if we need to sync */
@@ -244,13 +249,15 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject
/* mesh sync */
object->mesh = sync_mesh(b_ob, object_updated);
+ /* sspecial case not tracked by object update flags */
if(use_holdout != object->use_holdout) {
object->use_holdout = use_holdout;
scene->object_manager->tag_update(scene);
+ object_updated = true;
}
- /* object sync */
- /* transform comparison should not be needed, but duplis don't work perfect
+ /* 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();
@@ -260,7 +267,15 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject
object->motion.post = tfm;
object->use_motion = false;
- object->random_id = hash_int_2d(hash_string(object->name.c_str()), b_index);
+ /* random number */
+ object->random_id = hash_string(object->name.c_str());
+
+ if(persistent_id) {
+ for(int i = 0; i < OBJECT_PERSISTENT_ID_SIZE; i++)
+ object->random_id = hash_int_2d(object->random_id, persistent_id[i]);
+ }
+ else
+ object->random_id = hash_int_2d(object->random_id, 0);
/* visibility flags for both parent */
object->visibility = object_ray_visibility(b_ob) & PATH_RAY_ALL;
@@ -269,6 +284,10 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject
object->random_id ^= hash_int(hash_string(b_parent.name().c_str()));
}
+ /* make holdout objects on excluded layer invisible for non-camera rays */
+ if(use_holdout && (layer_flag & render_layer.exclude_layer))
+ object->visibility &= ~(PATH_RAY_ALL - PATH_RAY_CAMERA);
+
/* camera flag is not actually used, instead is tested
* against render layer flags */
if(object->visibility & PATH_RAY_CAMERA) {
@@ -285,10 +304,10 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::DupliObject
object->dupli_uv = make_float2(0.0f, 0.0f);
}
- object->particle_id = particle_id;
-
object->tag_update(scene);
}
+
+ return object;
}
/* Object Loop */
@@ -304,12 +323,15 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
mesh_map.pre_sync();
object_map.pre_sync();
mesh_synced.clear();
+ particle_system_map.pre_sync();
}
/* object loop */
BL::Scene::objects_iterator b_ob;
BL::Scene b_sce = b_scene;
- int particle_offset = 1; /* first particle is dummy for regular, non-instanced objects */
+
+ /* global particle index counter */
+ int particle_id = 1;
bool cancel = false;
@@ -322,45 +344,70 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
if(!hide) {
progress.set_sync_status("Synchronizing object", (*b_ob).name());
- int num_particles = object_count_particles(*b_ob);
-
if(b_ob->is_duplicator()) {
- hide = true; /* duplicators hidden by default */
+ /* duplicators hidden by default */
+ hide = true;
/* dupli objects */
- object_create_duplilist(*b_ob, b_scene);
+ b_ob->dupli_list_create(b_scene, 2);
BL::Object::dupli_list_iterator b_dup;
- int b_index = 0;
for(b_ob->dupli_list.begin(b_dup); b_dup != b_ob->dupli_list.end(); ++b_dup) {
Transform tfm = get_transform(b_dup->matrix());
BL::Object b_dup_ob = b_dup->object();
bool dup_hide = (b_v3d)? b_dup_ob.hide(): b_dup_ob.hide_render();
+ bool emitter_hide = false;
+
+ if(b_dup_ob.is_duplicator()) {
+ /* duplicators hidden by default */
+ emitter_hide = true;
+
+ /* check if we should render or hide particle emitter */
+ BL::Object::particle_systems_iterator b_psys;
+ for(b_dup_ob.particle_systems.begin(b_psys); b_psys != b_dup_ob.particle_systems.end(); ++b_psys)
+ if(b_psys->settings().use_render_emitter())
+ emitter_hide = false;
+ }
+
+ if(!(b_dup->hide() || dup_hide || emitter_hide)) {
+ /* the persistent_id allows us to match dupli objects
+ * between frames and updates */
+ BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id();
+
+ /* sync object and mesh or light data */
+ Object *object = sync_object(*b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion);
+
+ /* sync possible particle data, note particle_id
+ * starts counting at 1, first is dummy particle */
+ if(!motion && object && sync_dupli_particle(*b_ob, *b_dup, object)) {
+ if(particle_id != object->particle_id) {
+ object->particle_id = particle_id;
+ scene->object_manager->tag_update(scene);
+ }
+
+ particle_id++;
+ }
- if(!(b_dup->hide() || dup_hide)) {
- sync_object(*b_ob, b_index, *b_dup, tfm, ob_layer, motion, b_dup->particle_index() + particle_offset);
}
-
- ++b_index;
}
- object_free_duplilist(*b_ob);
+ b_ob->dupli_list_clear();
}
/* check if we should render or hide particle emitter */
BL::Object::particle_systems_iterator b_psys;
- for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
+
+ for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys) {
if(b_psys->settings().use_render_emitter())
hide = false;
+ }
if(!hide) {
/* object itself */
Transform tfm = get_transform(b_ob->matrix_world());
- sync_object(*b_ob, 0, PointerRNA_NULL, tfm, ob_layer, motion, 0);
+ sync_object(*b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion);
}
-
- particle_offset += num_particles;
}
cancel = progress.get_cancel();
@@ -379,6 +426,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, int motion)
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);
mesh_synced.clear();
}
}
@@ -393,11 +442,13 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override)
if(b_override)
b_cam = b_override;
+ Camera prevcam = *(scene->camera);
+
/* go back and forth one frame */
int frame = b_scene.frame_current();
for(int motion = -1; motion <= 1; motion += 2) {
- scene_frame_set(b_scene, frame + motion);
+ b_scene.frame_set(frame + motion, 0.0f);
/* camera object */
if(b_cam)
@@ -407,7 +458,11 @@ void BlenderSync::sync_motion(BL::SpaceView3D b_v3d, BL::Object b_override)
sync_objects(b_v3d, motion);
}
- scene_frame_set(b_scene, frame);
+ b_scene.frame_set(frame, 0.0f);
+
+ /* 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_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index f309960fc55..769cd9f532d 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -17,6 +17,7 @@
*/
#include "mesh.h"
+#include "object.h"
#include "particles.h"
#include "blender_sync.h"
@@ -28,191 +29,57 @@ CCL_NAMESPACE_BEGIN
/* Utilities */
+bool BlenderSync::sync_dupli_particle(BL::Object b_ob, BL::DupliObject b_dup, Object *object)
+{
+ /* test if this dupli was generated from a particle sytem */
+ BL::ParticleSystem b_psys = b_dup.particle_system();
+ if(!b_psys)
+ return false;
-/* Particles Sync */
+ /* test if we need particle data */
+ if(!object->mesh->need_attribute(scene, ATTR_STD_PARTICLE))
+ return false;
-bool BlenderSync::psys_need_update(BL::ParticleSystem b_psys)
-{
- /* Particle data is only needed for
- * a) Billboard render mode if object's own material uses particle info
- * b) object/group render mode if any dupli object's material uses particle info
- *
- * Note: Meshes have to be synced at this point!
- */
- bool need_update = false;
-
- switch (b_psys.settings().render_type()) {
- /* XXX not implemented yet!
- * billboards/strands would become part of the mesh data (?),
- * so the mesh attributes would store whether particle info is required.
- */
- #if 0
- case BL::ParticleSettings::render_type_BILLBOARD:
- case BL::ParticleSettings::render_type_PATH: { /* for strand rendering */
- BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob.data();
- Mesh *mesh = mesh_map.find(key);
- if (mesh) {
- need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update;
- }
- break;
- }
- #endif
-
- case BL::ParticleSettings::render_type_OBJECT: {
- BL::Object b_dupli_ob = b_psys.settings().dupli_object();
- if (b_dupli_ob) {
- BL::ID key = (BKE_object_is_modified(b_dupli_ob))? b_dupli_ob: b_dupli_ob.data();
- Mesh *mesh = mesh_map.find(key);
- if (mesh) {
- need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update;
- }
- }
- break;
- }
-
- case BL::ParticleSettings::render_type_GROUP: {
- BL::Group b_dupli_group = b_psys.settings().dupli_group();
- if (b_dupli_group) {
- BL::Group::objects_iterator b_gob;
- for (b_dupli_group.objects.begin(b_gob); b_gob != b_dupli_group.objects.end(); ++b_gob) {
- BL::ID key = (BKE_object_is_modified(*b_gob))? *b_gob: b_gob->data();
- Mesh *mesh = mesh_map.find(key);
- if (mesh) {
- need_update |= mesh->need_attribute(scene, ATTR_STD_PARTICLE) && mesh->need_update;
- }
- }
- }
- break;
- }
-
- default:
- /* avoid compiler warning */
- break;
- }
-
- return need_update;
-}
+ /* don't handle child particles yet */
+ BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup.persistent_id();
-static bool use_particle_system(BL::ParticleSystem b_psys)
-{
- /* only use duplicator particles? disabled particle info for
- * halo and billboard to reduce particle count.
- * Probably not necessary since particles don't contain a huge amount
- * of data compared to other textures.
- */
- #if 0
- int render_type = b_psys->settings().render_type();
- return (render_type == BL::ParticleSettings::render_type_OBJECT
- || render_type == BL::ParticleSettings::render_type_GROUP);
- #endif
-
- return true;
-}
+ if(persistent_id[0] >= b_psys.particles.length())
+ return false;
-static bool use_particle(BL::Particle b_pa)
-{
- return b_pa.is_exist() && b_pa.is_visible() &&
- (b_pa.alive_state()==BL::Particle::alive_state_ALIVE || b_pa.alive_state()==BL::Particle::alive_state_DYING);
-}
+ /* find particle system */
+ ParticleSystemKey key(b_ob, persistent_id);
+ ParticleSystem *psys;
-static int psys_count_particles(BL::ParticleSystem b_psys)
-{
- int tot = 0;
- BL::ParticleSystem::particles_iterator b_pa;
- for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) {
- if(use_particle(*b_pa))
- ++tot;
- }
- return tot;
-}
+ bool first_use = !particle_system_map.is_used(key);
+ bool need_update = particle_system_map.sync(&psys, b_ob, b_dup.object(), key);
-int BlenderSync::object_count_particles(BL::Object b_ob)
-{
- int tot = 0;
- 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 (use_particle_system(*b_psys))
- tot += psys_count_particles(*b_psys);
- }
- return tot;
-}
+ /* no update needed? */
+ if(!need_update && !object->mesh->need_update && !scene->object_manager->need_update)
+ return true;
-void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys)
-{
- /* depending on settings the psys may not even be rendered */
- if (!use_particle_system(b_psys))
- return;
-
- /* key to lookup particle system */
- ParticleSystemKey key(b_ob, b_psys);
- ParticleSystem *psys;
-
- /* test if we need to sync */
- bool object_updated = false;
-
- if(particle_system_map.sync(&psys, b_ob, b_ob, key))
- object_updated = true;
-
- bool need_update = psys_need_update(b_psys);
-
- if (object_updated || need_update) {
- int tot = psys_count_particles(b_psys);
+ /* first time used in this sync loop? clear and tag update */
+ if(first_use) {
psys->particles.clear();
- psys->particles.reserve(tot);
-
- int index = 0;
- BL::ParticleSystem::particles_iterator b_pa;
- for(b_psys.particles.begin(b_pa); b_pa != b_psys.particles.end(); ++b_pa) {
- if(use_particle(*b_pa)) {
- Particle pa;
-
- pa.index = index;
- 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(pa);
- }
-
- ++index;
- }
-
psys->tag_update(scene);
}
-}
-void BlenderSync::sync_particle_systems()
-{
- /* layer data */
- uint scene_layer = render_layer.scene_layer;
+ /* add particle */
+ BL::Particle b_pa = b_psys.particles[persistent_id[0]];
+ Particle pa;
- particle_system_map.pre_sync();
-
- /* object loop */
- BL::Scene::objects_iterator b_ob;
- BL::Scene b_sce = b_scene;
-
- for(; b_sce; b_sce = b_sce.background_set()) {
- for(b_sce.objects.begin(b_ob); b_ob != b_sce.objects.end(); ++b_ob) {
- bool hide = (render_layer.use_viewport_visibility)? b_ob->hide(): b_ob->hide_render();
- uint ob_layer = get_layer(b_ob->layers(), b_ob->layers_local_view(), render_layer.use_localview, object_is_light(*b_ob));
- hide = hide || !(ob_layer & scene_layer);
-
- if(!hide) {
- BL::Object::particle_systems_iterator b_psys;
- for(b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); ++b_psys)
- sync_particles(*b_ob, *b_psys);
- }
- }
- }
-
- /* handle removed data and modified pointers */
- if(particle_system_map.post_sync())
- scene->particle_system_manager->tag_update(scene);
+ 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(pa);
+
+ /* 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 d9220b76835..d164920ceff 100644
--- a/intern/cycles/blender/blender_python.cpp
+++ b/intern/cycles/blender/blender_python.cpp
@@ -24,9 +24,17 @@
#include "blender_session.h"
#include "util_foreach.h"
+#include "util_md5.h"
#include "util_opengl.h"
#include "util_path.h"
+#ifdef WITH_OSL
+#include "osl.h"
+
+#include <OSL/oslquery.h>
+#include <OSL/oslconfig.h>
+#endif
+
CCL_NAMESPACE_BEGIN
static PyObject *init_func(PyObject *self, PyObject *args)
@@ -138,6 +146,32 @@ static PyObject *draw_func(PyObject *self, PyObject *args)
Py_RETURN_NONE;
}
+static PyObject *reset_func(PyObject *self, PyObject *args)
+{
+ PyObject *pysession, *pydata, *pyscene;
+
+ if(!PyArg_ParseTuple(args, "OOO", &pysession, &pydata, &pyscene))
+ return NULL;
+
+ BlenderSession *session = (BlenderSession*)PyLong_AsVoidPtr(pysession);
+
+ PointerRNA dataptr;
+ RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pydata), &dataptr);
+ BL::BlendData b_data(dataptr);
+
+ PointerRNA sceneptr;
+ RNA_id_pointer_create((ID*)PyLong_AsVoidPtr(pyscene), &sceneptr);
+ BL::Scene b_scene(sceneptr);
+
+ Py_BEGIN_ALLOW_THREADS
+
+ session->reset_session(b_data, b_scene);
+
+ Py_END_ALLOW_THREADS
+
+ Py_RETURN_NONE;
+}
+
static PyObject *sync_func(PyObject *self, PyObject *value)
{
Py_BEGIN_ALLOW_THREADS
@@ -163,6 +197,182 @@ static PyObject *available_devices_func(PyObject *self, PyObject *args)
return ret;
}
+#ifdef WITH_OSL
+static PyObject *osl_update_node_func(PyObject *self, PyObject *args)
+{
+ PyObject *pynodegroup, *pynode;
+ const char *filepath = NULL;
+
+ if(!PyArg_ParseTuple(args, "OOs", &pynodegroup, &pynode, &filepath))
+ return NULL;
+
+ /* RNA */
+ 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 */
+ BL::NodeSocket::type_enum socket_type;
+ float default_float4[4] = {0.0f, 0.0f, 0.0f, 1.0f};
+ float default_float = 0.0f;
+ int default_int = 0;
+ std::string default_string = "";
+
+ if(param->isclosure) {
+ socket_type = BL::NodeSocket::type_SHADER;
+ }
+ else if(param->type.vecsemantics == TypeDesc::COLOR) {
+ socket_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 = 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 = BL::NodeSocket::type_INT;
+ if(param->validdefault)
+ default_int = param->idefault[0];
+ }
+ else if(param->type.basetype == TypeDesc::FLOAT) {
+ socket_type = BL::NodeSocket::type_VALUE;
+ if(param->validdefault)
+ default_float = param->fdefault[0];
+ }
+ else if(param->type.basetype == TypeDesc::STRING) {
+ socket_type = BL::NodeSocket::type_STRING;
+ if(param->validdefault)
+ default_string = param->sdefault[0];
+ }
+ else
+ continue;
+ }
+ else
+ continue;
+
+ /* find socket socket */
+ BL::NodeSocket b_sock = b_node.find_socket(param->name.c_str(), param->isoutput);
+
+ /* remove if type no longer matches */
+ if(b_sock && b_sock.type() != socket_type) {
+ b_node.remove_socket(b_sock);
+ b_sock = BL::NodeSocket(PointerRNA_NULL);
+ }
+
+ /* create new socket */
+ if(!b_sock) {
+ b_sock = b_node.add_socket(param->name.c_str(), socket_type, param->isoutput);
+
+ /* set default value */
+ if(socket_type == BL::NodeSocket::type_VALUE) {
+ BL::NodeSocketFloatNone b_float_sock(b_sock.ptr);
+ b_float_sock.default_value(default_float);
+ }
+ else if(socket_type == BL::NodeSocket::type_INT) {
+ BL::NodeSocketIntNone b_int_sock(b_sock.ptr);
+ b_int_sock.default_value(default_int);
+ }
+ else if(socket_type == BL::NodeSocket::type_RGBA) {
+ BL::NodeSocketRGBA b_rgba_sock(b_sock.ptr);
+ b_rgba_sock.default_value(default_float4);
+ }
+ else if(socket_type == BL::NodeSocket::type_VECTOR) {
+ BL::NodeSocketVectorNone b_vector_sock(b_sock.ptr);
+ b_vector_sock.default_value(default_float4);
+ }
+ else if(socket_type == BL::NodeSocket::type_STRING) {
+ BL::NodeSocketStringNone b_string_sock(b_sock.ptr);
+ b_string_sock.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.remove_socket(*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.remove_socket(*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;
+
+ if(!PyArg_ParseTuple(args, "ss", &inputfile, &outputfile))
+ return NULL;
+
+ /* return */
+ if(!OSLShaderManager::osl_compile(inputfile, outputfile))
+ Py_RETURN_FALSE;
+
+ Py_RETURN_TRUE;
+}
+#endif
+
static PyMethodDef methods[] = {
{"init", init_func, METH_VARARGS, ""},
{"create", create_func, METH_VARARGS, ""},
@@ -170,6 +380,11 @@ static PyMethodDef methods[] = {
{"render", render_func, METH_O, ""},
{"draw", draw_func, METH_VARARGS, ""},
{"sync", sync_func, METH_O, ""},
+ {"reset", reset_func, METH_VARARGS, ""},
+#ifdef WITH_OSL
+ {"osl_update_node", osl_update_node_func, METH_VARARGS, ""},
+ {"osl_compile", osl_compile_func, METH_VARARGS, ""},
+#endif
{"available_devices", available_devices_func, METH_NOARGS, ""},
{NULL, NULL, 0, NULL},
};
@@ -203,14 +418,23 @@ static CCLDeviceInfo *compute_device_list(DeviceType type)
if(info.type == type ||
(info.type == DEVICE_MULTI && info.multi_devices[0].type == type))
{
- CCLDeviceInfo cinfo = {info.id.c_str(), info.description.c_str(), i++};
+ CCLDeviceInfo cinfo;
+
+ strncpy(cinfo.identifier, info.id.c_str(), sizeof(cinfo.identifier));
+ cinfo.identifier[info.id.length()] = '\0';
+
+ strncpy(cinfo.name, info.description.c_str(), sizeof(cinfo.name));
+ cinfo.name[info.description.length()] = '\0';
+
+ cinfo.value = i++;
+
device_list.push_back(cinfo);
}
}
/* null terminate */
if(!device_list.empty()) {
- CCLDeviceInfo cinfo = {NULL, NULL, 0};
+ CCLDeviceInfo cinfo = {"", "", 0};
device_list.push_back(cinfo);
}
}
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index 7b80c520e72..ad43c39469c 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -105,13 +105,57 @@ void BlenderSession::create_session()
sync->sync_camera(b_engine.camera_override(), width, height);
/* set buffer parameters */
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
+ session->reset(buffer_params, session_params.samples);
+}
+
+void BlenderSession::reset_session(BL::BlendData b_data_, BL::Scene b_scene_)
+{
+ b_data = b_data_;
+ b_scene = b_scene_;
+
+ SceneParams scene_params = BlenderSync::get_scene_params(b_scene, background);
+ SessionParams session_params = BlenderSync::get_session_params(b_engine, b_userpref, b_scene, background);
+
+ width = b_engine.resolution_x();
+ height = b_engine.resolution_y();
+
+ if(scene->params.modified(scene_params) ||
+ session->params.modified(session_params))
+ {
+ /* 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
+ */
+
+ delete session;
+
+ create_session();
+
+ return;
+ }
+
+ session->progress.reset();
+ scene->reset();
+
+ /* 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;
+
+ /* sync object should be re-created */
+ sync = new BlenderSync(b_engine, b_data, b_scene, scene, !background, session->progress);
+ sync->sync_data(b_v3d, b_engine.camera_override());
+ sync->sync_camera(b_engine.camera_override(), width, height);
+
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, PointerRNA_NULL, PointerRNA_NULL, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
}
void BlenderSession::free_session()
{
- delete sync;
+ if(sync)
+ delete sync;
+
delete session;
}
@@ -178,15 +222,12 @@ static PassType get_pass_type(BL::RenderPass b_pass)
static BL::RenderResult begin_render_result(BL::RenderEngine b_engine, int x, int y, int w, int h, const char *layername)
{
- RenderResult *rrp = RE_engine_begin_result((RenderEngine*)b_engine.ptr.data, x, y, w, h, layername);
- PointerRNA rrptr;
- RNA_pointer_create(NULL, &RNA_RenderResult, rrp, &rrptr);
- return BL::RenderResult(rrptr);
+ return b_engine.begin_result(x, y, w, h, layername);
}
static void end_render_result(BL::RenderEngine b_engine, BL::RenderResult b_rr, bool cancel = false)
{
- RE_engine_end_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data, (int)cancel);
+ b_engine.end_result(b_rr, (int)cancel);
}
void BlenderSession::do_write_update_render_tile(RenderTile& rtile, bool do_update_only)
@@ -239,7 +280,7 @@ void BlenderSession::render()
/* 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_scene, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
/* render each layer */
BL::RenderSettings r = b_scene.render();
@@ -307,6 +348,15 @@ void BlenderSession::render()
/* clear callback */
session->write_render_tile_cb = NULL;
session->update_render_tile_cb = NULL;
+
+ /* 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, bool do_update_only)
@@ -335,16 +385,16 @@ void BlenderSession::do_write_update_render_result(BL::RenderResult b_rr, BL::Re
/* copy pixels */
if(buffers->get_pass_rect(pass_type, exposure, rtile.sample, components, &pixels[0]))
- rna_RenderPass_rect_set(&b_pass.ptr, &pixels[0]);
+ b_pass.rect(&pixels[0]);
}
}
/* copy combined pass */
if(buffers->get_pass_rect(PASS_COMBINED, exposure, rtile.sample, 4, &pixels[0]))
- rna_RenderLayer_rect_set(&b_rlay.ptr, &pixels[0]);
+ b_rlay.rect(&pixels[0]);
/* tag result as updated */
- RE_engine_update_result((RenderEngine*)b_engine.ptr.data, (RenderResult*)b_rr.ptr.data);
+ b_engine.update_result(b_rr);
}
void BlenderSession::write_render_result(BL::RenderResult b_rr, BL::RenderLayer b_rlay, RenderTile& rtile)
@@ -399,7 +449,7 @@ void BlenderSession::synchronize()
/* reset if needed */
if(scene->need_reset()) {
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
session->reset(buffer_params, session_params.samples);
}
}
@@ -437,7 +487,7 @@ bool BlenderSession::draw(int w, int h)
/* 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_scene, scene->camera, w, h);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, w, h);
session->reset(buffer_params, session_params.samples);
}
@@ -447,7 +497,7 @@ bool BlenderSession::draw(int w, int h)
update_status_progress();
/* draw */
- BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, scene->camera, width, height);
+ BufferParams buffer_params = BlenderSync::get_buffer_params(b_scene, b_v3d, b_rv3d, scene->camera, width, height);
return !session->draw(buffer_params);
}
@@ -466,9 +516,12 @@ void BlenderSession::get_progress(float& progress, double& total_time)
session->progress.get_tile(tile, total_time, tile_time);
sample = session->progress.get_sample();
- samples_per_tile = session->tile_manager.state.num_samples;
+ samples_per_tile = session->params.samples;
- progress = ((float)sample/(float)(tile_total * samples_per_tile));
+ if(samples_per_tile)
+ progress = ((float)sample/(float)(tile_total * samples_per_tile));
+ else
+ progress = 0.0;
}
void BlenderSession::update_status_progress()
@@ -477,11 +530,15 @@ void BlenderSession::update_status_progress()
float progress;
double total_time;
char time_str[128];
+ 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_progress(progress, total_time);
- timestatus = b_scene.name();
+ timestatus = string_printf("Mem: %.2fM, Peak: %.2fM | ", mem_used, mem_peak);
+
+ timestatus += b_scene.name();
if(b_rlay_name != "")
timestatus += ", " + b_rlay_name;
timestatus += " | ";
@@ -493,11 +550,12 @@ void BlenderSession::update_status_progress()
status += " | " + substatus;
if(status != last_status) {
- RE_engine_update_stats((RenderEngine*)b_engine.ptr.data, "", (timestatus + status).c_str());
+ b_engine.update_stats("", (timestatus + status).c_str());
+ b_engine.update_memory_stats(mem_used, mem_peak);
last_status = status;
}
if(progress != last_progress) {
- RE_engine_update_progress((RenderEngine*)b_engine.ptr.data, progress);
+ b_engine.update_progress(progress);
last_progress = progress;
}
}
@@ -505,7 +563,7 @@ void BlenderSession::update_status_progress()
void BlenderSession::tag_update()
{
/* tell blender that we want to get another update callback */
- engine_tag_update((RenderEngine*)b_engine.ptr.data);
+ b_engine.tag_update();
}
void BlenderSession::tag_redraw()
@@ -517,13 +575,13 @@ void BlenderSession::tag_redraw()
/* offline render, redraw if timeout passed */
if(time_dt() - last_redraw_time > 1.0) {
- engine_tag_redraw((RenderEngine*)b_engine.ptr.data);
+ b_engine.tag_redraw();
last_redraw_time = time_dt();
}
}
else {
/* tell blender that we want to redraw */
- engine_tag_redraw((RenderEngine*)b_engine.ptr.data);
+ b_engine.tag_redraw();
}
}
@@ -531,7 +589,7 @@ void BlenderSession::test_cancel()
{
/* test if we need to cancel rendering */
if(background)
- if(RE_engine_test_break((RenderEngine*)b_engine.ptr.data))
+ if(b_engine.test_break())
session->progress.set_cancel("Cancelled");
}
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index d52e0103bbf..7f3973ae873 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -46,6 +46,8 @@ public:
void create_session();
void free_session();
+ void reset_session(BL::BlendData b_data, BL::Scene b_scene);
+
/* offline render */
void render();
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index b6d5cc623bb..63cf719d010 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -20,6 +20,7 @@
#include "graph.h"
#include "light.h"
#include "nodes.h"
+#include "osl.h"
#include "scene.h"
#include "shader.h"
@@ -43,6 +44,7 @@ void BlenderSync::find_shader(BL::ID id, vector<uint>& used_shaders, int default
for(size_t i = 0; i < scene->shaders.size(); i++) {
if(scene->shaders[i] == shader) {
used_shaders.push_back(i);
+ scene->shaders[i]->tag_used(scene);
break;
}
}
@@ -80,22 +82,25 @@ static ShaderSocketType convert_socket_type(BL::NodeSocket::type_enum b_type)
switch (b_type) {
case BL::NodeSocket::type_VALUE:
return SHADER_SOCKET_FLOAT;
+ case BL::NodeSocket::type_INT:
+ return SHADER_SOCKET_INT;
case BL::NodeSocket::type_VECTOR:
return SHADER_SOCKET_VECTOR;
case BL::NodeSocket::type_RGBA:
return SHADER_SOCKET_COLOR;
case BL::NodeSocket::type_SHADER:
return SHADER_SOCKET_CLOSURE;
+ case BL::NodeSocket::type_STRING:
+ return SHADER_SOCKET_STRING;
case BL::NodeSocket::type_BOOLEAN:
case BL::NodeSocket::type_MESH:
- case BL::NodeSocket::type_INT:
default:
return SHADER_SOCKET_FLOAT;
}
}
-static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
+static void set_default_value(ShaderInput *input, BL::NodeSocket sock, BL::BlendData b_data, BL::ID b_id)
{
/* copy values for non linked inputs */
switch(input->type) {
@@ -104,6 +109,11 @@ static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
input->set(value_sock.default_value());
break;
}
+ case SHADER_SOCKET_INT: {
+ BL::NodeSocketIntNone value_sock(sock);
+ input->set((float)value_sock.default_value());
+ break;
+ }
case SHADER_SOCKET_COLOR: {
BL::NodeSocketRGBA rgba_sock(sock);
input->set(get_float3(rgba_sock.default_value()));
@@ -116,6 +126,11 @@ static void set_default_value(ShaderInput *input, BL::NodeSocket sock)
input->set(get_float3(vec_sock.default_value()));
break;
}
+ case SHADER_SOCKET_STRING: {
+ BL::NodeSocketStringNone string_sock(sock);
+ input->set((ustring)blender_absolute_path(b_data, b_id, string_sock.default_value()));
+ break;
+ }
case SHADER_SOCKET_CLOSURE:
break;
}
@@ -152,7 +167,7 @@ static void get_tex_mapping(TextureMapping *mapping, BL::ShaderNodeMapping b_map
mapping->max = get_float3(b_mapping.max());
}
-static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNode b_node)
+static ShaderNode *add_node(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, BL::ShaderNode b_node)
{
ShaderNode *node = NULL;
@@ -165,6 +180,7 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
case BL::ShaderNode::type_OUTPUT: break;
case BL::ShaderNode::type_SQUEEZE: break;
case BL::ShaderNode::type_TEXTURE: break;
+ case BL::ShaderNode::type_FRAME: break;
/* handled outside this function */
case BL::ShaderNode::type_GROUP: break;
/* existing blender nodes */
@@ -315,6 +331,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = new HoldoutNode();
break;
}
+ case BL::ShaderNode::type_BSDF_ANISOTROPIC: {
+ node = new WardBsdfNode();
+ break;
+ }
case BL::ShaderNode::type_BSDF_DIFFUSE: {
node = new DiffuseBsdfNode();
break;
@@ -354,6 +374,23 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = glass;
break;
}
+ case BL::ShaderNode::type_BSDF_REFRACTION: {
+ BL::ShaderNodeBsdfRefraction b_refraction_node(b_node);
+ RefractionBsdfNode *refraction = new RefractionBsdfNode();
+ switch(b_refraction_node.distribution()) {
+ case BL::ShaderNodeBsdfRefraction::distribution_SHARP:
+ refraction->distribution = ustring("Sharp");
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_BECKMANN:
+ refraction->distribution = ustring("Beckmann");
+ break;
+ case BL::ShaderNodeBsdfRefraction::distribution_GGX:
+ refraction->distribution = ustring("GGX");
+ break;
+ }
+ node = refraction;
+ break;
+ }
case BL::ShaderNode::type_BSDF_TRANSLUCENT: {
node = new TranslucentBsdfNode();
break;
@@ -370,6 +407,10 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = new EmissionNode();
break;
}
+ case BL::ShaderNode::type_AMBIENT_OCCLUSION: {
+ node = new AmbientOcclusionNode();
+ break;
+ }
case BL::ShaderNode::type_VOLUME_ISOTROPIC: {
node = new IsotropicVolumeNode();
break;
@@ -398,6 +439,62 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = new ParticleInfoNode();
break;
}
+ case BL::ShaderNode::type_BUMP: {
+ node = new BumpNode();
+ break;
+ }
+ case BL::ShaderNode::type_SCRIPT: {
+#ifdef WITH_OSL
+ if(scene->params.shadingsystem != SceneParams::OSL)
+ break;
+
+ /* create script node */
+ BL::ShaderNodeScript b_script_node(b_node);
+ OSLScriptNode *script_node = new OSLScriptNode();
+
+ /* Generate inputs/outputs from node sockets
+ *
+ * Note: the node sockets are generated from OSL parameters,
+ * so the names match those of the corresponding parameters exactly.
+ *
+ * Note 2: ShaderInput/ShaderOutput store shallow string copies only!
+ * Socket names must be stored in the extra lists instead. */
+ BL::Node::inputs_iterator b_input;
+
+ for (b_script_node.inputs.begin(b_input); b_input != b_script_node.inputs.end(); ++b_input) {
+ script_node->input_names.push_back(ustring(b_input->name()));
+ ShaderInput *input = script_node->add_input(script_node->input_names.back().c_str(), convert_socket_type(b_input->type()));
+ set_default_value(input, *b_input, b_data, b_ntree);
+ }
+
+ BL::Node::outputs_iterator b_output;
+
+ for (b_script_node.outputs.begin(b_output); b_output != b_script_node.outputs.end(); ++b_output) {
+ script_node->output_names.push_back(ustring(b_output->name()));
+ script_node->add_output(script_node->output_names.back().c_str(), convert_socket_type(b_output->type()));
+ }
+
+ /* load bytecode or filepath */
+ OSLShaderManager *manager = (OSLShaderManager*)scene->shader_manager;
+ string bytecode_hash = b_script_node.bytecode_hash();
+
+ if(!bytecode_hash.empty()) {
+ /* loaded bytecode if not already done */
+ if(!manager->shader_test_loaded(bytecode_hash))
+ manager->shader_load_bytecode(bytecode_hash, b_script_node.bytecode());
+
+ script_node->bytecode_hash = bytecode_hash;
+ }
+ else {
+ /* set filepath */
+ script_node->filepath = blender_absolute_path(b_data, b_ntree, b_script_node.filepath());
+ }
+
+ node = script_node;
+#endif
+
+ break;
+ }
case BL::ShaderNode::type_TEX_IMAGE: {
BL::ShaderNodeTexImage b_image_node(b_node);
BL::Image b_image(b_image_node.image());
@@ -505,6 +602,23 @@ static ShaderNode *add_node(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph
node = sky;
break;
}
+ case BL::ShaderNode::type_NORMAL_MAP: {
+ BL::ShaderNodeNormalMap b_normal_map_node(b_node);
+ NormalMapNode *nmap = new NormalMapNode();
+ nmap->space = NormalMapNode::space_enum[(int)b_normal_map_node.space()];
+ nmap->attribute = b_normal_map_node.uv_map();
+ node = nmap;
+ break;
+ }
+ case BL::ShaderNode::type_TANGENT: {
+ BL::ShaderNodeTangent b_tangent_node(b_node);
+ TangentNode *tangent = new TangentNode();
+ tangent->direction_type = TangentNode::direction_type_enum[(int)b_tangent_node.direction_type()];
+ tangent->axis = TangentNode::axis_enum[(int)b_tangent_node.axis()];
+ tangent->attribute = b_tangent_node.uv_map();
+ node = tangent;
+ break;
+ }
}
if(node && node != graph->output())
@@ -561,7 +675,7 @@ static SocketPair node_socket_map_pair(PtrNodeMap& node_map, BL::Node b_node, BL
return SocketPair(node_map[b_node.ptr.data], name);
}
-static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
+static void add_nodes(Scene *scene, BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *graph, BL::ShaderNodeTree b_ntree, PtrSockMap& sockets_map)
{
/* add nodes */
BL::ShaderNodeTree::nodes_iterator b_node;
@@ -569,7 +683,34 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
PtrSockMap proxy_map;
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
- if(b_node->is_a(&RNA_NodeGroup)) {
+ if(b_node->mute()) {
+ BL::Node::inputs_iterator b_input;
+ BL::Node::outputs_iterator b_output;
+ bool found_match = false;
+
+ /* this is slightly different than blender logic, we just connect a
+ * single pair for of input/output, but works ok for the node we have */
+ for(b_node->inputs.begin(b_input); b_input != b_node->inputs.end(); ++b_input) {
+ if(b_input->is_linked()) {
+ for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
+ if(b_output->is_linked() && b_input->type() == b_output->type()) {
+ ProxyNode *proxy = new ProxyNode(convert_socket_type(b_input->type()), convert_socket_type(b_output->type()));
+ graph->add(proxy);
+
+ proxy_map[b_input->ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
+ proxy_map[b_output->ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
+ found_match = true;
+
+ break;
+ }
+ }
+ }
+
+ if(found_match)
+ break;
+ }
+ }
+ else if(b_node->is_a(&RNA_NodeGroup)) {
/* add proxy converter nodes for inputs and outputs */
BL::NodeGroup b_gnode(*b_node);
BL::ShaderNodeTree b_group_ntree(b_gnode.node_tree());
@@ -592,7 +733,7 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
group_sockmap[b_input->group_socket().ptr.data] = SocketPair(proxy, proxy->outputs[0]->name);
/* default input values of the group node */
- set_default_value(proxy->inputs[0], *b_input);
+ set_default_value(proxy->inputs[0], *b_input, b_data, b_group_ntree);
}
for(b_node->outputs.begin(b_output); b_output != b_node->outputs.end(); ++b_output) {
@@ -606,13 +747,13 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
group_sockmap[b_output->group_socket().ptr.data] = SocketPair(proxy, proxy->inputs[0]->name);
/* default input values of internal, unlinked group outputs */
- set_default_value(proxy->inputs[0], b_output->group_socket());
+ set_default_value(proxy->inputs[0], b_output->group_socket(), b_data, b_group_ntree);
}
- add_nodes(b_data, b_scene, graph, b_group_ntree, group_sockmap);
+ add_nodes(scene, b_data, b_scene, graph, b_group_ntree, group_sockmap);
}
else {
- ShaderNode *node = add_node(b_data, b_scene, graph, BL::ShaderNode(*b_node));
+ ShaderNode *node = add_node(scene, b_data, b_scene, graph, b_ntree, BL::ShaderNode(*b_node));
if(node) {
BL::Node::inputs_iterator b_input;
@@ -626,7 +767,7 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
assert(input);
/* copy values for non linked inputs */
- set_default_value(input, *b_input);
+ set_default_value(input, *b_input, b_data, b_ntree);
}
}
}
@@ -649,7 +790,7 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
/* from sock */
if(b_from_node) {
- if (b_from_node.is_a(&RNA_NodeGroup))
+ if (b_from_node.mute() || b_from_node.is_a(&RNA_NodeGroup))
from_pair = proxy_map[b_from_sock.ptr.data];
else
from_pair = node_socket_map_pair(node_map, b_from_node, b_from_sock);
@@ -659,7 +800,7 @@ static void add_nodes(BL::BlendData b_data, BL::Scene b_scene, ShaderGraph *grap
/* to sock */
if(b_to_node) {
- if (b_to_node.is_a(&RNA_NodeGroup))
+ if (b_to_node.mute() || b_to_node.is_a(&RNA_NodeGroup))
to_pair = proxy_map[b_to_sock.ptr.data];
else
to_pair = node_socket_map_pair(node_map, b_to_node, b_to_sock);
@@ -702,7 +843,7 @@ void BlenderSync::sync_materials()
PtrSockMap sock_to_node;
BL::ShaderNodeTree b_ntree(b_mat->node_tree());
- add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node);
+ add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node);
}
else {
ShaderNode *closure, *out;
@@ -743,7 +884,7 @@ void BlenderSync::sync_world()
PtrSockMap sock_to_node;
BL::ShaderNodeTree b_ntree(b_world.node_tree());
- add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node);
+ add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node);
}
else if(b_world) {
ShaderNode *closure, *out;
@@ -802,7 +943,7 @@ void BlenderSync::sync_lamps()
PtrSockMap sock_to_node;
BL::ShaderNodeTree b_ntree(b_lamp->node_tree());
- add_nodes(b_data, b_scene, graph, b_ntree, sock_to_node);
+ add_nodes(scene, b_data, b_scene, graph, b_ntree, sock_to_node);
}
else {
ShaderNode *closure, *out;
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index b4990eb815a..9ebdcfd04bd 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -17,6 +17,7 @@
*/
#include "background.h"
+#include "camera.h"
#include "film.h"
#include "../render/filter.h"
#include "graph.h"
@@ -141,7 +142,6 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const
sync_film();
sync_shaders();
sync_objects(b_v3d);
- sync_particle_systems();
sync_motion(b_v3d, b_override);
}
@@ -149,6 +149,9 @@ void BlenderSync::sync_data(BL::SpaceView3D b_v3d, BL::Object b_override, const
void BlenderSync::sync_integrator()
{
+#ifdef __CAMERA_MOTION__
+ BL::RenderSettings r = b_scene.render();
+#endif
PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
experimental = (RNA_enum_get(&cscene, "feature_set") != 0);
@@ -175,7 +178,12 @@ void BlenderSync::sync_integrator()
integrator->layer_flag = render_layer.layer;
integrator->sample_clamp = get_float(cscene, "sample_clamp");
-#ifdef __MOTION__
+#ifdef __CAMERA_MOTION__
+ if(integrator->motion_blur != r.use_motion_blur()) {
+ scene->object_manager->tag_update(scene);
+ scene->camera->tag_update();
+ }
+
integrator->motion_blur = (!preview && r.use_motion_blur());
#endif
@@ -233,6 +241,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer)
render_layer.use_localview = (b_v3d.local_view() ? true : false);
render_layer.scene_layer = get_layer(b_v3d.layers(), b_v3d.layers_local_view(), render_layer.use_localview);
render_layer.layer = render_layer.scene_layer;
+ render_layer.exclude_layer = 0;
render_layer.holdout_layer = 0;
render_layer.material_override = PointerRNA_NULL;
render_layer.use_background = true;
@@ -250,10 +259,16 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer)
for(r.layers.begin(b_rlay); b_rlay != r.layers.end(); ++b_rlay) {
if((!layer && first_layer) || (layer && b_rlay->name() == layer)) {
render_layer.name = b_rlay->name();
- render_layer.scene_layer = get_layer(b_scene.layers()) & ~get_layer(b_rlay->layers_exclude());
- render_layer.layer = get_layer(b_rlay->layers());
+
render_layer.holdout_layer = get_layer(b_rlay->layers_zmask());
+ render_layer.exclude_layer = get_layer(b_rlay->layers_exclude());
+
+ render_layer.scene_layer = get_layer(b_scene.layers()) & ~render_layer.exclude_layer;
+ render_layer.scene_layer |= render_layer.exclude_layer & render_layer.holdout_layer;
+
+ render_layer.layer = get_layer(b_rlay->layers());
render_layer.layer |= render_layer.holdout_layer;
+
render_layer.material_override = b_rlay->material_override();
render_layer.use_background = b_rlay->use_sky();
render_layer.use_viewport_visibility = false;
@@ -269,6 +284,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D b_v3d, const char *layer)
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");
int shadingsystem = RNA_enum_get(&cscene, "shading_system");
@@ -286,6 +302,8 @@ SceneParams BlenderSync::get_scene_params(BL::Scene b_scene, bool background)
params.use_bvh_spatial_split = RNA_boolean_get(&cscene, "debug_use_spatial_splits");
params.use_bvh_cache = (background)? RNA_boolean_get(&cscene, "use_cache"): false;
+ params.persistent_images = (background)? r.use_persistent_data(): false;
+
return params;
}
@@ -371,19 +389,36 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine b_engine, BL::Use
params.start_resolution = get_int(cscene, "preview_start_resolution");
/* other parameters */
- params.threads = b_scene.render().threads();
+ if(b_scene.render().threads_mode() == BL::RenderSettings::threads_mode_FIXED)
+ params.threads = b_scene.render().threads();
+ else
+ params.threads = 0;
params.cancel_timeout = get_float(cscene, "debug_cancel_timeout");
params.reset_timeout = get_float(cscene, "debug_reset_timeout");
params.text_timeout = get_float(cscene, "debug_text_timeout");
+ params.progressive_refine = get_boolean(cscene, "use_progressive_refine");
+
if(background) {
- params.progressive = false;
+ if(params.progressive_refine)
+ params.progressive = true;
+ else
+ params.progressive = false;
+
params.start_resolution = INT_MAX;
}
else
params.progressive = true;
-
+
+ /* shading system - scene level needs full refresh */
+ int shadingsystem = RNA_enum_get(&cscene, "shading_system");
+
+ if(shadingsystem == 0)
+ params.shadingsystem = SessionParams::SVM;
+ else if(shadingsystem == 1)
+ params.shadingsystem = SessionParams::OSL;
+
return params;
}
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index ce563087b4a..71781bc5459 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -42,6 +42,7 @@ class Film;
class Light;
class Mesh;
class Object;
+class ParticleSystem;
class Scene;
class Shader;
class ShaderGraph;
@@ -63,7 +64,7 @@ public:
static SceneParams get_scene_params(BL::Scene b_scene, bool background);
static SessionParams get_session_params(BL::RenderEngine b_engine, BL::UserPreferences 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::Scene b_scene, Camera *cam, int width, int height);
+ static BufferParams get_buffer_params(BL::Scene b_scene, BL::SpaceView3D b_v3d, BL::RegionView3D b_rv3d, Camera *cam, int width, int height);
private:
/* sync */
@@ -77,24 +78,23 @@ private:
void sync_world();
void sync_render_layers(BL::SpaceView3D b_v3d, const char *layer);
void sync_shaders();
- void sync_particle_systems();
void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree);
Mesh *sync_mesh(BL::Object b_ob, bool object_updated);
- void sync_object(BL::Object b_parent, int b_index, BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion, int particle_id);
- void sync_light(BL::Object b_parent, int b_index, BL::Object b_ob, Transform& tfm);
+ Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_object, Transform& tfm, uint layer_flag, int motion);
+ void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm);
void sync_background_light();
void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
void sync_camera_motion(BL::Object b_ob, int motion);
- void sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys);
+
+ /* particles */
+ bool sync_dupli_particle(BL::Object b_ob, BL::DupliObject b_dup, Object *object);
/* util */
void find_shader(BL::ID id, vector<uint>& used_shaders, int 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);
- bool psys_need_update(BL::ParticleSystem b_psys);
- int object_count_particles(BL::Object b_ob);
/* variables */
BL::RenderEngine b_engine;
@@ -116,7 +116,8 @@ private:
struct RenderLayerInfo {
RenderLayerInfo()
- : scene_layer(0), layer(0), holdout_layer(0),
+ : scene_layer(0), layer(0),
+ holdout_layer(0), exclude_layer(0),
material_override(PointerRNA_NULL),
use_background(true),
use_viewport_visibility(false),
@@ -127,6 +128,7 @@ private:
uint scene_layer;
uint layer;
uint holdout_layer;
+ uint exclude_layer;
BL::Material material_override;
bool use_background;
bool use_viewport_visibility;
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index da8f30ea169..4feb8b556d5 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -30,29 +30,7 @@
* todo: clean this up ... */
extern "C" {
-
-struct RenderEngine;
-struct RenderResult;
-
-ID *rna_Object_to_mesh(void *_self, void *reports, void *scene, int apply_modifiers, int settings);
-void rna_Main_meshes_remove(void *bmain, void *reports, void *mesh);
-void rna_Object_create_duplilist(void *ob, void *reports, void *sce, int settings);
-void rna_Object_free_duplilist(void *ob);
-void rna_RenderLayer_rect_set(PointerRNA *ptr, const float *values);
-void rna_RenderPass_rect_set(PointerRNA *ptr, const float *values);
-struct RenderResult *RE_engine_begin_result(struct RenderEngine *engine, int x, int y, int w, int h, const char *layername);
-void RE_engine_update_result(struct RenderEngine *engine, struct RenderResult *result);
-void RE_engine_end_result(struct RenderEngine *engine, struct RenderResult *result, int cancel);
-int RE_engine_test_break(struct RenderEngine *engine);
-void RE_engine_update_stats(struct RenderEngine *engine, const char *stats, const char *info);
-void RE_engine_update_progress(struct RenderEngine *engine, float progress);
-void engine_tag_redraw(void *engine);
-void engine_tag_update(void *engine);
-int rna_Object_is_modified(void *ob, void *scene, int settings);
-int rna_Object_is_deform_modified(void *ob, void *scene, int settings);
void BLI_timestr(double _time, char *str);
-void rna_ColorRamp_eval(void *coba, float position, float color[4]);
-void rna_Scene_frame_set(void *scene, int frame, float subframe);
void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
}
@@ -61,10 +39,7 @@ CCL_NAMESPACE_BEGIN
static inline BL::Mesh object_to_mesh(BL::Object self, BL::Scene scene, bool apply_modifiers, bool render)
{
- ID *data = rna_Object_to_mesh(self.ptr.data, NULL, scene.ptr.data, apply_modifiers, (render)? 2: 1);
- PointerRNA ptr;
- RNA_id_pointer_create(data, &ptr);
- return BL::Mesh(ptr);
+ return self.to_mesh(scene, apply_modifiers, (render)? 2: 1);
}
static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size)
@@ -72,34 +47,19 @@ static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size
for(int i = 0; i < size; i++) {
float color[4];
- rna_ColorRamp_eval(ramp.ptr.data, i/(float)(size-1), color);
+ ramp.evaluate(i/(float)(size-1), color);
data[i] = make_float4(color[0], color[1], color[2], color[3]);
}
}
-static inline void object_remove_mesh(BL::BlendData data, BL::Mesh mesh)
-{
- rna_Main_meshes_remove(data.ptr.data, NULL, mesh.ptr.data);
-}
-
-static inline void object_create_duplilist(BL::Object self, BL::Scene scene)
-{
- rna_Object_create_duplilist(self.ptr.data, NULL, scene.ptr.data, 2);
-}
-
-static inline void object_free_duplilist(BL::Object self)
-{
- rna_Object_free_duplilist(self.ptr.data);
-}
-
static inline bool BKE_object_is_modified(BL::Object self, BL::Scene scene, bool preview)
{
- return rna_Object_is_modified(self.ptr.data, scene.ptr.data, (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)
{
- return rna_Object_is_deform_modified(self.ptr.data, scene.ptr.data, (preview)? (1<<0): (1<<1))? true: false;
+ return self.is_deform_modified(scene, (preview)? (1<<0): (1<<1))? true: false;
}
static inline string image_user_file_path(BL::ImageUser iuser, BL::Image ima, int cfra)
@@ -110,11 +70,6 @@ static inline string image_user_file_path(BL::ImageUser iuser, BL::Image ima, in
return string(filepath);
}
-static inline void scene_frame_set(BL::Scene scene, int frame)
-{
- rna_Scene_frame_set(scene.ptr.data, frame, 0.0f);
-}
-
/* Utilities */
static inline Transform get_transform(BL::Array<float, 16> array)
@@ -329,6 +284,12 @@ public:
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 */
@@ -388,27 +349,49 @@ protected:
/* Object Key */
+enum { OBJECT_PERSISTENT_ID_SIZE = 8 };
+
struct ObjectKey {
void *parent;
- int index;
+ int id[OBJECT_PERSISTENT_ID_SIZE];
void *ob;
- ObjectKey(void *parent_, int index_, void *ob_)
- : parent(parent_), index(index_), ob(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
- { return (parent < k.parent || (parent == k.parent && (index < k.index || (index == k.index && ob < k.ob)))); }
+ {
+ return (parent < k.parent) ||
+ (parent == k.parent && (memcmp(id, k.id, sizeof(id)) < 0)) ||
+ (memcmp(id, k.id, sizeof(id)) == 0 && ob < k.ob);
+ }
};
struct ParticleSystemKey {
void *ob;
- void *psys;
+ int id[OBJECT_PERSISTENT_ID_SIZE];
- ParticleSystemKey(void *ob_, void *psys_)
- : ob(ob_), psys(psys_) {}
+ 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
- { return (ob < k.ob && psys < k.psys); }
+ {
+ /* first id is particle index, we don't compare that */
+ return (ob < k.ob) ||
+ (ob == k.ob && (memcmp(id+1, k.id+1, sizeof(int)*(OBJECT_PERSISTENT_ID_SIZE-1)) < 0));
+ }
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/bvh/CMakeLists.txt b/intern/cycles/bvh/CMakeLists.txt
index ba5c3785eac..cbbd23fcff8 100644
--- a/intern/cycles/bvh/CMakeLists.txt
+++ b/intern/cycles/bvh/CMakeLists.txt
@@ -7,6 +7,7 @@ set(INC
../util
../device
)
+
set(INC_SYS
)
diff --git a/intern/cycles/bvh/bvh_node.h b/intern/cycles/bvh/bvh_node.h
index 5c00f7b7a38..a0d10a46bfc 100644
--- a/intern/cycles/bvh/bvh_node.h
+++ b/intern/cycles/bvh/bvh_node.h
@@ -54,7 +54,7 @@ public:
// Subtree functions
int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const;
- float computeSubtreeSAHCost(const BVHParams& p, float probability = 1.0f) const;
+ float computeSubtreeSAHCost(const BVHParams& p, float probability = 1.0f) const;
void deleteSubtree();
uint update_visibility();
diff --git a/intern/cycles/cmake/external_libs.cmake b/intern/cycles/cmake/external_libs.cmake
index 332d3d74715..790049898ff 100644
--- a/intern/cycles/cmake/external_libs.cmake
+++ b/intern/cycles/cmake/external_libs.cmake
@@ -18,33 +18,6 @@ else()
endif()
###########################################################################
-# Partio
-
-if(WITH_CYCLES_PARTIO)
-
- set(CYCLES_PARTIO "" CACHE PATH "Path to Partio installation")
-
- message(STATUS "CYCLES_PARTIO = ${CYCLES_PARTIO}")
-
- find_library(PARTIO_LIBRARIES NAMES partio PATHS ${CYCLES_PARTIO}/lib)
- find_path(PARTIO_INCLUDES Partio.h ${CYCLES_PARTIO}/include)
-
- find_package(ZLIB)
-
- if(PARTIO_INCLUDES AND PARTIO_LIBRARIES AND ZLIB_LIBRARIES)
- list(APPEND PARTIO_LIBRARIES ${ZLIB_LIBRARIES})
- set(PARTIO_FOUND TRUE)
- message(STATUS "PARTIO includes = ${PARTIO_INCLUDES}")
- message(STATUS "PARTIO library = ${PARTIO_LIBRARIES}")
- else()
- message(STATUS "PARTIO not found")
- endif()
-
- include_directories(${PARTIO_INCLUDES})
-
-endif()
-
-###########################################################################
# CUDA
if(WITH_CYCLES_CUDA_BINARIES)
diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt
index 0f692aa3051..fe2368b7ea8 100644
--- a/intern/cycles/device/CMakeLists.txt
+++ b/intern/cycles/device/CMakeLists.txt
@@ -7,6 +7,7 @@ set(INC
../util
../render
)
+
set(INC_SYS
${OPENGL_INCLUDE_DIR}
${GLEW_INCLUDE_PATH}
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 2db2b11c1cb..721c262f094 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -28,6 +28,7 @@
#include "util_math.h"
#include "util_opencl.h"
#include "util_opengl.h"
+#include "util_time.h"
#include "util_types.h"
#include "util_vector.h"
@@ -79,36 +80,36 @@ void Device::draw_pixels(device_memory& rgba, int y, int w, int h, int dy, int w
}
}
-Device *Device::create(DeviceInfo& info, bool background, int threads)
+Device *Device::create(DeviceInfo& info, Stats &stats, bool background)
{
Device *device;
switch(info.type) {
case DEVICE_CPU:
- device = device_cpu_create(info, threads);
+ device = device_cpu_create(info, stats);
break;
#ifdef WITH_CUDA
case DEVICE_CUDA:
if(cuLibraryInit())
- device = device_cuda_create(info, background);
+ device = device_cuda_create(info, stats, background);
else
device = NULL;
break;
#endif
#ifdef WITH_MULTI
case DEVICE_MULTI:
- device = device_multi_create(info, background);
+ device = device_multi_create(info, stats, background);
break;
#endif
#ifdef WITH_NETWORK
case DEVICE_NETWORK:
- device = device_network_create(info, "127.0.0.1");
+ device = device_network_create(info, stats, "127.0.0.1");
break;
#endif
#ifdef WITH_OPENCL
case DEVICE_OPENCL:
if(clLibraryInit())
- device = device_opencl_create(info, background);
+ device = device_opencl_create(info, stats, background);
else
device = NULL;
break;
@@ -190,6 +191,18 @@ vector<DeviceInfo>& Device::available_devices()
{
static vector<DeviceInfo> devices;
static bool devices_init = false;
+ static double device_update_time = 0.0;
+
+ /* only update device list if we're not actively rendering already, things
+ * could go very wrong if a device suddenly becomes (un)available. also do
+ * it only every 5 seconds. it not super cpu intensive but don't want to do
+ * it on every redraw. */
+ if(devices_init) {
+ if(!TaskScheduler::active() && (time_dt() > device_update_time + 5.0)) {
+ devices.clear();
+ devices_init = false;
+ }
+ }
if(!devices_init) {
#ifdef WITH_CUDA
@@ -213,6 +226,7 @@ vector<DeviceInfo>& Device::available_devices()
#endif
devices_init = true;
+ device_update_time = time_dt();
}
return devices;
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 2ee2e044618..9840687b76a 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -25,6 +25,7 @@
#include "device_task.h"
#include "util_list.h"
+#include "util_stats.h"
#include "util_string.h"
#include "util_thread.h"
#include "util_types.h"
@@ -72,7 +73,7 @@ public:
class Device {
protected:
- Device() {}
+ Device(Stats &stats_) : stats(stats_) {}
bool background;
string error_msg;
@@ -84,6 +85,9 @@ public:
DeviceInfo info;
virtual const string& error_message() { return error_msg; }
+ /* statistics */
+ Stats &stats;
+
/* regular memory */
virtual void mem_alloc(device_memory& mem, MemoryType type) = 0;
virtual void mem_copy_to(device_memory& mem) = 0;
@@ -130,7 +134,7 @@ public:
virtual int device_number(Device *sub_device) { return 0; }
/* static */
- static Device *create(DeviceInfo& info, bool background = true, int threads = 0);
+ static Device *create(DeviceInfo& info, Stats &stats, bool background = true);
static DeviceType type_from_string(const char *name);
static string string_from_type(DeviceType type);
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 4c54671b0d0..bc280616615 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -45,7 +45,7 @@ public:
TaskPool task_pool;
KernelGlobals *kg;
- CPUDevice(int threads_num)
+ CPUDevice(Stats &stats) : Device(stats)
{
kg = kernel_globals_create();
@@ -67,6 +67,8 @@ public:
void mem_alloc(device_memory& mem, MemoryType type)
{
mem.device_pointer = mem.data_pointer;
+
+ stats.mem_alloc(mem.memory_size());
}
void mem_copy_to(device_memory& mem)
@@ -87,6 +89,8 @@ public:
void mem_free(device_memory& mem)
{
mem.device_pointer = 0;
+
+ stats.mem_free(mem.memory_size());
}
void const_copy_to(const char *name, void *host, size_t size)
@@ -98,11 +102,15 @@ public:
{
kernel_tex_copy(kg, name, mem.data_pointer, mem.data_width, mem.data_height);
mem.device_pointer = mem.data_pointer;
+
+ stats.mem_alloc(mem.memory_size());
}
void tex_free(device_memory& mem)
{
mem.device_pointer = 0;
+
+ stats.mem_free(mem.memory_size());
}
void *osl_memory()
@@ -135,8 +143,10 @@ public:
void thread_path_trace(DeviceTask& task)
{
- if(task_pool.cancelled())
- return;
+ if(task_pool.cancelled()) {
+ if(task.need_finish_queue == false)
+ return;
+ }
#ifdef WITH_OSL
if(kernel_osl_use(kg))
@@ -154,8 +164,10 @@ public:
#ifdef WITH_OPTIMIZED_KERNEL
if(system_cpu_support_optimized()) {
for(int sample = start_sample; sample < end_sample; sample++) {
- if (task.get_cancel() || task_pool.cancelled())
- break;
+ if (task.get_cancel() || task_pool.cancelled()) {
+ 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++) {
@@ -173,8 +185,10 @@ public:
#endif
{
for(int sample = start_sample; sample < end_sample; sample++) {
- if (task.get_cancel() || task_pool.cancelled())
- break;
+ if (task.get_cancel() || task_pool.cancelled()) {
+ 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++) {
@@ -191,8 +205,10 @@ public:
task.release_tile(tile);
- if(task_pool.cancelled())
- break;
+ if(task_pool.cancelled()) {
+ if(task.need_finish_queue == false)
+ break;
+ }
}
#ifdef WITH_OSL
@@ -258,7 +274,7 @@ public:
/* split task into smaller ones, more than number of threads for uneven
* workloads where some parts of the image render slower than others */
list<DeviceTask> tasks;
- task.split(tasks, TaskScheduler::num_threads()+1);
+ task.split(tasks, TaskScheduler::num_threads());
foreach(DeviceTask& task, tasks)
task_pool.push(new CPUDeviceTask(this, task));
@@ -275,9 +291,9 @@ public:
}
};
-Device *device_cpu_create(DeviceInfo& info, int threads)
+Device *device_cpu_create(DeviceInfo& info, Stats &stats)
{
- return new CPUDevice(threads);
+ return new CPUDevice(stats);
}
void device_cpu_info(vector<DeviceInfo>& devices)
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index 18a29b2551c..440971e2663 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -157,7 +157,7 @@ public:
cuda_assert(cuCtxSetCurrent(NULL));
}
- CUDADevice(DeviceInfo& info, bool background_)
+ CUDADevice(DeviceInfo& info, Stats &stats, bool background_) : Device(stats)
{
background = background_;
@@ -316,8 +316,10 @@ public:
{
cuda_push_context();
CUdeviceptr device_pointer;
- cuda_assert(cuMemAlloc(&device_pointer, mem.memory_size()))
+ size_t size = mem.memory_size();
+ cuda_assert(cuMemAlloc(&device_pointer, size))
mem.device_pointer = (device_ptr)device_pointer;
+ stats.mem_alloc(size);
cuda_pop_context();
}
@@ -356,6 +358,8 @@ public:
cuda_pop_context();
mem.device_pointer = 0;
+
+ stats.mem_free(mem.memory_size());
}
}
@@ -424,6 +428,8 @@ public:
cuda_assert(cuTexRefSetFlags(texref, CU_TRSF_NORMALIZED_COORDINATES))
mem.device_pointer = (device_ptr)handle;
+
+ stats.mem_alloc(size);
}
else {
cuda_pop_context();
@@ -463,6 +469,8 @@ public:
tex_interp_map.erase(tex_interp_map.find(mem.device_pointer));
mem.device_pointer = 0;
+
+ stats.mem_free(mem.memory_size());
}
else {
tex_interp_map.erase(tex_interp_map.find(mem.device_pointer));
@@ -707,6 +715,8 @@ public:
mem.device_pointer = pmem.cuTexId;
pixel_mem_map[mem.device_pointer] = pmem;
+ stats.mem_alloc(mem.memory_size());
+
return;
}
else {
@@ -762,6 +772,8 @@ public:
pixel_mem_map.erase(pixel_mem_map.find(mem.device_pointer));
mem.device_pointer = 0;
+ stats.mem_free(mem.memory_size());
+
return;
}
@@ -839,8 +851,10 @@ public:
int end_sample = tile.start_sample + tile.num_samples;
for(int sample = start_sample; sample < end_sample; sample++) {
- if (task->get_cancel())
- break;
+ if (task->get_cancel()) {
+ if(task->need_finish_queue == false)
+ break;
+ }
path_trace(tile, sample);
@@ -896,9 +910,9 @@ public:
}
};
-Device *device_cuda_create(DeviceInfo& info, bool background)
+Device *device_cuda_create(DeviceInfo& info, Stats &stats, bool background)
{
- return new CUDADevice(info, background);
+ return new CUDADevice(info, stats, background);
}
void device_cuda_info(vector<DeviceInfo>& devices)
diff --git a/intern/cycles/device/device_intern.h b/intern/cycles/device/device_intern.h
index e3601aa8ad4..b49ebba3e8b 100644
--- a/intern/cycles/device/device_intern.h
+++ b/intern/cycles/device/device_intern.h
@@ -23,11 +23,11 @@ CCL_NAMESPACE_BEGIN
class Device;
-Device *device_cpu_create(DeviceInfo& info, int threads);
-Device *device_opencl_create(DeviceInfo& info, bool background);
-Device *device_cuda_create(DeviceInfo& info, bool background);
-Device *device_network_create(DeviceInfo& info, const char *address);
-Device *device_multi_create(DeviceInfo& info, bool background);
+Device *device_cpu_create(DeviceInfo& info, Stats &stats);
+Device *device_opencl_create(DeviceInfo& info, Stats &stats, bool background);
+Device *device_cuda_create(DeviceInfo& info, Stats &stats, bool background);
+Device *device_network_create(DeviceInfo& info, Stats &stats, const char *address);
+Device *device_multi_create(DeviceInfo& info, Stats &stats, bool background);
void device_cpu_info(vector<DeviceInfo>& devices);
void device_opencl_info(vector<DeviceInfo>& devices);
diff --git a/intern/cycles/device/device_multi.cpp b/intern/cycles/device/device_multi.cpp
index 546ffe5e4b9..807bfe578f3 100644
--- a/intern/cycles/device/device_multi.cpp
+++ b/intern/cycles/device/device_multi.cpp
@@ -46,14 +46,14 @@ public:
list<SubDevice> devices;
device_ptr unique_ptr;
- MultiDevice(DeviceInfo& info, bool background_)
- : unique_ptr(1)
+ MultiDevice(DeviceInfo& info, Stats &stats, bool background_)
+ : Device(stats), unique_ptr(1)
{
Device *device;
background = background_;
foreach(DeviceInfo& subinfo, info.multi_devices) {
- device = Device::create(subinfo, background);
+ device = Device::create(subinfo, stats, background);
devices.push_back(SubDevice(device));
}
@@ -314,9 +314,9 @@ public:
}
};
-Device *device_multi_create(DeviceInfo& info, bool background)
+Device *device_multi_create(DeviceInfo& info, Stats &stats, bool background)
{
- return new MultiDevice(info, background);
+ return new MultiDevice(info, stats, background);
}
static bool device_multi_add(vector<DeviceInfo>& devices, DeviceType type, bool with_display, bool with_advanced_shading, const char *id_fmt, int num)
diff --git a/intern/cycles/device/device_network.cpp b/intern/cycles/device/device_network.cpp
index 931890b5859..a5e0d39df73 100644
--- a/intern/cycles/device/device_network.cpp
+++ b/intern/cycles/device/device_network.cpp
@@ -32,8 +32,8 @@ public:
boost::asio::io_service io_service;
tcp::socket socket;
- NetworkDevice(const char *address)
- : socket(io_service)
+ NetworkDevice(Stats &stats, const char *address)
+ : Device(stats), socket(io_service)
{
stringstream portstr;
portstr << SERVER_PORT;
@@ -202,9 +202,9 @@ public:
}
};
-Device *device_network_create(DeviceInfo& info, const char *address)
+Device *device_network_create(DeviceInfo& info, Stats &stats, const char *address)
{
- return new NetworkDevice(address);
+ return new NetworkDevice(stats, address);
}
void device_network_info(vector<DeviceInfo>& devices)
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 673ffdf79fd..69287f1a8bd 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -144,7 +144,8 @@ public:
}
}
- OpenCLDevice(DeviceInfo& info, bool background_)
+ OpenCLDevice(DeviceInfo& info, Stats &stats, bool background_)
+ : Device(stats)
{
background = background_;
cpPlatform = NULL;
@@ -473,6 +474,8 @@ public:
mem.device_pointer = (device_ptr)clCreateBuffer(cxContext, CL_MEM_READ_WRITE, size, NULL, &ciErr);
opencl_assert(ciErr);
+
+ stats.mem_alloc(size);
}
void mem_copy_to(device_memory& mem)
@@ -506,6 +509,8 @@ public:
ciErr = clReleaseMemObject(CL_MEM_PTR(mem.device_pointer));
mem.device_pointer = 0;
opencl_assert(ciErr);
+
+ stats.mem_free(mem.memory_size());
}
}
@@ -686,8 +691,10 @@ public:
int end_sample = tile.start_sample + tile.num_samples;
for(int sample = start_sample; sample < end_sample; sample++) {
- if (task->get_cancel())
- break;
+ if (task->get_cancel()) {
+ if(task->need_finish_queue == false)
+ break;
+ }
path_trace(tile, sample);
@@ -726,9 +733,9 @@ public:
}
};
-Device *device_opencl_create(DeviceInfo& info, bool background)
+Device *device_opencl_create(DeviceInfo& info, Stats &stats, bool background)
{
- return new OpenCLDevice(info, background);
+ return new OpenCLDevice(info, stats, background);
}
void device_opencl_info(vector<DeviceInfo>& devices)
diff --git a/intern/cycles/device/device_task.cpp b/intern/cycles/device/device_task.cpp
index c85e182d629..b3f02deaf6f 100644
--- a/intern/cycles/device/device_task.cpp
+++ b/intern/cycles/device/device_task.cpp
@@ -101,7 +101,7 @@ void DeviceTask::update_progress(RenderTile &rtile)
if(update_tile_sample) {
double current_time = time_dt();
- if (current_time - last_update_time >= 1.0f) {
+ if (current_time - last_update_time >= 1.0) {
update_tile_sample(rtile);
last_update_time = current_time;
diff --git a/intern/cycles/device/device_task.h b/intern/cycles/device/device_task.h
index cfb3d8d988e..8ca8b88ea49 100644
--- a/intern/cycles/device/device_task.h
+++ b/intern/cycles/device/device_task.h
@@ -65,6 +65,7 @@ public:
boost::function<void(RenderTile&)> release_tile;
boost::function<bool(void)> get_cancel;
+ bool need_finish_queue;
protected:
double last_update_time;
};
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index df8a9b1d5b4..5a570328948 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -5,7 +5,9 @@ set(INC
osl
svm
)
+
set(INC_SYS
+
)
set(SRC
@@ -31,13 +33,11 @@ set(SRC_HEADERS
kernel_globals.h
kernel_light.h
kernel_math.h
- kernel_mbvh.h
kernel_montecarlo.h
kernel_object.h
kernel_passes.h
kernel_path.h
kernel_projection.h
- kernel_qbvh.h
kernel_random.h
kernel_shader.h
kernel_textures.h
@@ -45,18 +45,22 @@ set(SRC_HEADERS
kernel_types.h
)
+set(SRC_CLOSURE_HEADERS
+ closure/bsdf.h
+ closure/bsdf_ashikhmin_velvet.h
+ closure/bsdf_diffuse.h
+ closure/bsdf_microfacet.h
+ closure/bsdf_oren_nayar.h
+ closure/bsdf_phong_ramp.h
+ closure/bsdf_reflection.h
+ closure/bsdf_refraction.h
+ closure/bsdf_transparent.h
+ closure/bsdf_ward.h
+ closure/bsdf_westin.h
+ closure/emissive.h
+ closure/volume.h
+)
set(SRC_SVM_HEADERS
- svm/bsdf.h
- svm/bsdf_ashikhmin_velvet.h
- svm/bsdf_diffuse.h
- svm/bsdf_oren_nayar.h
- svm/bsdf_microfacet.h
- svm/bsdf_reflection.h
- svm/bsdf_refraction.h
- svm/bsdf_transparent.h
- svm/bsdf_ward.h
- svm/bsdf_westin.h
- svm/emissive.h
svm/svm.h
svm/svm_attribute.h
svm/svm_bsdf.h
@@ -92,7 +96,6 @@ set(SRC_SVM_HEADERS
svm/svm_value.h
svm/svm_voronoi.h
svm/svm_wave.h
- svm/volume.h
)
set(SRC_UTIL_HEADERS
@@ -110,7 +113,7 @@ if(WITH_CYCLES_CUDA_BINARIES)
set(CUDA_BITS 32)
endif()
- set(cuda_sources kernel.cu ${SRC_HEADERS} ${SRC_SVM_HEADERS} ${SRC_UTIL_HEADERS})
+ set(cuda_sources kernel.cu ${SRC_HEADERS} ${SRC_SVM_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_UTIL_HEADERS})
set(cuda_cubins)
foreach(arch ${CYCLES_CUDA_BINARIES_ARCH})
@@ -132,6 +135,7 @@ endif()
if(WITH_CYCLES_OSL)
add_subdirectory(osl)
+ add_subdirectory(shaders)
endif()
# CPU module
@@ -139,7 +143,7 @@ endif()
include_directories(${INC})
include_directories(SYSTEM ${INC_SYS})
-add_library(cycles_kernel ${SRC} ${SRC_HEADERS} ${SRC_SVM_HEADERS})
+add_library(cycles_kernel ${SRC} ${SRC_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_SVM_HEADERS})
if(WITH_CYCLES_OPTIMIZED_KERNEL)
set_source_files_properties(kernel_optimized.cpp PROPERTIES COMPILE_FLAGS "${CYCLES_OPTIMIZED_KERNEL_FLAGS}")
@@ -162,6 +166,7 @@ endif()
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernel.cl" ${CYCLES_INSTALL_PATH}/kernel)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "kernel.cu" ${CYCLES_INSTALL_PATH}/kernel)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_HEADERS}" ${CYCLES_INSTALL_PATH}/kernel)
+delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_CLOSURE_HEADERS}" ${CYCLES_INSTALL_PATH}/kernel/closure)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_SVM_HEADERS}" ${CYCLES_INSTALL_PATH}/kernel/svm)
delayed_install(${CMAKE_CURRENT_SOURCE_DIR} "${SRC_UTIL_HEADERS}" ${CYCLES_INSTALL_PATH}/kernel)
diff --git a/intern/cycles/kernel/svm/bsdf.h b/intern/cycles/kernel/closure/bsdf.h
index cfb6321a918..cfb6321a918 100644
--- a/intern/cycles/kernel/svm/bsdf.h
+++ b/intern/cycles/kernel/closure/bsdf.h
diff --git a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
index 40249dbe9c6..016fd73204e 100644
--- a/intern/cycles/kernel/svm/bsdf_ashikhmin_velvet.h
+++ b/intern/cycles/kernel/closure/bsdf_ashikhmin_velvet.h
@@ -35,37 +35,34 @@
CCL_NAMESPACE_BEGIN
-typedef struct BsdfAshikhminVelvetClosure {
- //float3 m_N;
- float m_invsigma2;
-} BsdfAshikhminVelvetClosure;
-
-__device void bsdf_ashikhmin_velvet_setup(ShaderData *sd, ShaderClosure *sc, float sigma)
+__device int bsdf_ashikhmin_velvet_setup(ShaderClosure *sc)
{
+ float sigma = sc->data0;
sigma = fmaxf(sigma, 0.01f);
float m_invsigma2 = 1.0f/(sigma * sigma);
sc->type = CLOSURE_BSDF_ASHIKHMIN_VELVET_ID;
- sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL;
sc->data0 = m_invsigma2;
+
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
__device void bsdf_ashikhmin_velvet_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_invsigma2 = sc->data0;
- float3 m_N = sd->N;
+ float3 N = sc->N;
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ 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(m_N, H);
+ float cosNH = dot(N, H);
float cosHO = fabsf(dot(I, H));
if(!(fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f))
@@ -93,32 +90,27 @@ __device float3 bsdf_ashikhmin_velvet_eval_reflect(const ShaderData *sd, const S
return make_float3(0, 0, 0);
}
-__device float3 bsdf_ashikhmin_velvet_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float bsdf_ashikhmin_velvet_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__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)
{
float m_invsigma2 = sc->data0;
- float3 m_N = sd->N;
+ float3 N = sc->N;
// we are viewing the surface from above - send a ray out with uniform
// distribution over the hemisphere
- sample_uniform_hemisphere(m_N, randu, randv, omega_in, pdf);
+ sample_uniform_hemisphere(N, randu, randv, omega_in, pdf);
- if(dot(sd->Ng, *omega_in) > 0) {
- float3 H = normalize(*omega_in + sd->I);
+ if(dot(Ng, *omega_in) > 0) {
+ float3 H = normalize(*omega_in + I);
- float cosNI = dot(m_N, *omega_in);
- float cosNO = dot(m_N, sd->I);
- float cosNH = dot(m_N, H);
- float cosHO = fabsf(dot(sd->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;
@@ -140,8 +132,8 @@ __device int bsdf_ashikhmin_velvet_sample(const ShaderData *sd, const ShaderClos
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the retroreflective bounce
- *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
*domega_in_dx *= 125.0f;
*domega_in_dy *= 125.0f;
#endif
diff --git a/intern/cycles/kernel/svm/bsdf_diffuse.h b/intern/cycles/kernel/closure/bsdf_diffuse.h
index edf8dd93341..88b40e3d479 100644
--- a/intern/cycles/kernel/svm/bsdf_diffuse.h
+++ b/intern/cycles/kernel/closure/bsdf_diffuse.h
@@ -37,52 +37,43 @@ CCL_NAMESPACE_BEGIN
/* DIFFUSE */
-typedef struct BsdfDiffuseClosure {
- //float3 m_N;
-} BsdfDiffuseClosure;
-
-__device void bsdf_diffuse_setup(ShaderData *sd, ShaderClosure *sc)
+__device int bsdf_diffuse_setup(ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_DIFFUSE_ID;
- sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
__device void bsdf_diffuse_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_diffuse_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_diffuse_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float3 m_N = sd->N;
+ float3 N = sc->N;
- float cos_pi = fmaxf(dot(m_N, omega_in), 0.0f) * M_1_PI_F;
+ 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);
}
-__device float3 bsdf_diffuse_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float bsdf_diffuse_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_diffuse_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__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)
{
- float3 m_N = sd->N;
+ float3 N = sc->N;
// distribution over the hemisphere
- sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf);
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
- if(dot(sd->Ng, *omega_in) > 0.0f) {
+ 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(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
*domega_in_dx *= 125.0f;
*domega_in_dy *= 125.0f;
#endif
@@ -95,52 +86,48 @@ __device int bsdf_diffuse_sample(const ShaderData *sd, const ShaderClosure *sc,
/* TRANSLUCENT */
-typedef struct BsdfTranslucentClosure {
- //float3 m_N;
-} BsdfTranslucentClosure;
-
-__device void bsdf_translucent_setup(ShaderData *sd, ShaderClosure *sc)
+__device int bsdf_translucent_setup(ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_TRANSLUCENT_ID;
- sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL;
+ return SD_BSDF|SD_BSDF_HAS_EVAL;
}
__device void bsdf_translucent_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_translucent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float3 bsdf_translucent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_translucent_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- float3 m_N = sd->N;
+ float3 N = sc->N;
- float cos_pi = fmaxf(-dot(m_N, omega_in), 0.0f) * M_1_PI_F;
+ 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);
}
-__device float bsdf_translucent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
+__device float bsdf_translucent_albedo(const ShaderClosure *sc, const float3 I)
{
return 1.0f;
}
-__device int bsdf_translucent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__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)
{
- float3 m_N = sd->N;
+ float3 N = sc->N;
// we are viewing the surface from the right side - send a ray out with cosine
// distribution over the hemisphere
- sample_cos_hemisphere (-m_N, randu, randv, omega_in, pdf);
- if(dot(sd->Ng, *omega_in) < 0) {
+ 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(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
*domega_in_dx *= -125.0f;
*domega_in_dy *= -125.0f;
#endif
diff --git a/intern/cycles/kernel/svm/bsdf_microfacet.h b/intern/cycles/kernel/closure/bsdf_microfacet.h
index d8f0310bd02..a564b99e759 100644
--- a/intern/cycles/kernel/svm/bsdf_microfacet.h
+++ b/intern/cycles/kernel/closure/bsdf_microfacet.h
@@ -37,31 +37,36 @@ CCL_NAMESPACE_BEGIN
/* GGX */
-typedef struct BsdfMicrofacetGGXClosure {
- //float3 m_N;
- float m_ag;
- float m_eta;
-} BsdfMicrofacetGGXClosure;
-
__device_inline float safe_sqrtf(float f)
{
return sqrtf(max(f, 0.0f));
}
-__device void bsdf_microfacet_ggx_setup(ShaderData *sd, ShaderClosure *sc, float ag, float eta, bool refractive)
+__device int bsdf_microfacet_ggx_setup(ShaderClosure *sc)
{
+ float ag = sc->data0;
+
+ float m_ag = clamp(ag, 1e-4f, 1.0f);
+
+ sc->data0 = m_ag;
+ sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
+
+ return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+}
+
+__device int bsdf_microfacet_ggx_refraction_setup(ShaderClosure *sc)
+{
+ float ag = sc->data0;
+ float eta = sc->data1;
+
float m_ag = clamp(ag, 1e-4f, 1.0f);
float m_eta = eta;
sc->data0 = m_ag;
sc->data1 = m_eta;
+ sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- if(refractive)
- sc->type = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- else
- sc->type = CLOSURE_BSDF_MICROFACET_GGX_ID;
-
- sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
__device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness)
@@ -71,23 +76,22 @@ __device void bsdf_microfacet_ggx_blur(ShaderClosure *sc, float roughness)
sc->data0 = m_ag;
}
-__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ag = sc->data0;
- //float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 m_N = sd->N;
+ float3 N = sc->N;
if(m_refractive) return make_float3 (0, 0, 0);
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNI > 0 && cosNO > 0) {
// get half vector
float3 Hr = normalize(omega_in + I);
// eq. 20: (F*G*D)/(4*in*on)
// eq. 33: first we calculate D(m) with m=Hr:
float alpha2 = m_ag * m_ag;
- float cosThetaM = dot(m_N, Hr);
+ float cosThetaM = dot(N, Hr);
float cosThetaM2 = cosThetaM * cosThetaM;
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
float cosThetaM4 = cosThetaM2 * cosThetaM2;
@@ -108,16 +112,16 @@ __device float3 bsdf_microfacet_ggx_eval_reflect(const ShaderData *sd, const Sha
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ag = sc->data0;
float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 m_N = sd->N;
+ float3 N = sc->N;
if(!m_refractive) return make_float3 (0, 0, 0);
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO <= 0 || cosNI >= 0)
return make_float3 (0, 0, 0); // vectors on same side -- not possible
// compute half-vector of the refraction (eq. 16)
@@ -128,7 +132,7 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const Sh
float cosHI = dot(Ht, omega_in);
// eq. 33: first we calculate D(m) with m=Ht:
float alpha2 = m_ag * m_ag;
- float cosThetaM = dot(m_N, Ht);
+ float cosThetaM = dot(N, Ht);
float cosThetaM2 = cosThetaM * cosThetaM;
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
float cosThetaM4 = cosThetaM2 * cosThetaM2;
@@ -144,21 +148,15 @@ __device float3 bsdf_microfacet_ggx_eval_transmit(const ShaderData *sd, const Sh
return make_float3 (out, out, out);
}
-__device float bsdf_microfacet_ggx_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_microfacet_ggx_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)
{
float m_ag = sc->data0;
- float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
- float3 m_N = sd->N;
+ float3 N = sc->N;
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
if(cosNO > 0) {
- float3 X, Y, Z = m_N;
+ float3 X, Y, Z = N;
make_orthonormals(Z, &X, &Y);
// generate a random microfacet normal m
// eq. 35,36:
@@ -173,11 +171,11 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur
(sinf(phiM) * sinThetaM) * Y +
cosThetaM * Z;
if(!m_refractive) {
- float cosMO = dot(m, sd->I);
+ float cosMO = dot(m, I);
if(cosMO > 0) {
// eq. 39 - compute actual reflected direction
- *omega_in = 2 * cosMO * m - sd->I;
- if(dot(sd->Ng, *omega_in) > 0) {
+ *omega_in = 2 * cosMO * m - I;
+ if(dot(Ng, *omega_in) > 0) {
// microfacet normal is visible to this ray
// eq. 33
float cosThetaM2 = cosThetaM * cosThetaM;
@@ -190,7 +188,7 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
*pdf = pm * 0.25f / cosMO;
// eval BRDF*cosNI
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// eq. 34: now calculate G1(i,m) and G1(o,m)
float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
@@ -199,8 +197,8 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur
float out = (G * D) * 0.25f / cosNO;
*eval = make_float3(out, out, out);
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(m, sd->dI.dx)) * m - sd->dI.dx;
- *domega_in_dy = (2 * dot(m, sd->dI.dy)) * m - sd->dI.dy;
+ *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
+ *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
// Since there is some blur to this reflection, make the
// derivatives a bit bigger. In theory this varies with the
// roughness but the exact relationship is complex and
@@ -218,10 +216,11 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur
#ifdef __RAY_DIFFERENTIALS__
float3 dRdx, dRdy, dTdx, dTdy;
#endif
+ float m_eta = sc->data1;
bool inside;
- fresnel_dielectric(m_eta, m, sd->I, &R, &T,
+ fresnel_dielectric(m_eta, m, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
- sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
#endif
&inside);
@@ -238,14 +237,14 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur
// eq. 24
float pm = D * cosThetaM;
// eval BRDF*cosNI
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// eq. 34: now calculate G1(i,m) and G1(o,m)
float G1o = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
float G1i = 2 / (1 + safe_sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
float G = G1o * G1i;
// eq. 21
float cosHI = dot(m, *omega_in);
- float cosHO = dot(m, sd->I);
+ float cosHO = dot(m, I);
float Ht2 = m_eta * cosHI + cosHO;
Ht2 *= Ht2;
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
@@ -268,26 +267,29 @@ __device int bsdf_microfacet_ggx_sample(const ShaderData *sd, const ShaderClosur
/* BECKMANN */
-typedef struct BsdfMicrofacetBeckmannClosure {
- //float3 m_N;
- float m_ab;
- float m_eta;
-} BsdfMicrofacetBeckmannClosure;
+__device int bsdf_microfacet_beckmann_setup(ShaderClosure *sc)
+{
+ float ab = sc->data0;
+ float m_ab = clamp(ab, 1e-4f, 1.0f);
-__device void bsdf_microfacet_beckmann_setup(ShaderData *sd, ShaderClosure *sc, float ab, float eta, bool refractive)
+ sc->data0 = m_ab;
+
+ sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
+ return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+}
+
+__device int bsdf_microfacet_beckmann_refraction_setup(ShaderClosure *sc)
{
+ float ab = sc->data0;
+ float eta = sc->data1;
float m_ab = clamp(ab, 1e-4f, 1.0f);
float m_eta = eta;
sc->data0 = m_ab;
sc->data1 = m_eta;
- if(refractive)
- sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- else
- sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_ID;
-
- sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ sc->type = CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
+ return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
__device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness)
@@ -297,23 +299,22 @@ __device void bsdf_microfacet_beckmann_blur(ShaderClosure *sc, float roughness)
sc->data0 = m_ab;
}
-__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ab = sc->data0;
- //float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 m_N = sd->N;
+ float3 N = sc->N;
if(m_refractive) return make_float3 (0, 0, 0);
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO > 0 && cosNI > 0) {
// get half vector
float3 Hr = normalize(omega_in + I);
// eq. 20: (F*G*D)/(4*in*on)
// eq. 25: first we calculate D(m) with m=Hr:
float alpha2 = m_ab * m_ab;
- float cosThetaM = dot(m_N, Hr);
+ float cosThetaM = dot(N, Hr);
float cosThetaM2 = cosThetaM * cosThetaM;
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
float cosThetaM4 = cosThetaM2 * cosThetaM2;
@@ -336,16 +337,16 @@ __device float3 bsdf_microfacet_beckmann_eval_reflect(const ShaderData *sd, cons
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ab = sc->data0;
float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 m_N = sd->N;
+ float3 N = sc->N;
if(!m_refractive) return make_float3 (0, 0, 0);
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO <= 0 || cosNI >= 0)
return make_float3 (0, 0, 0);
// compute half-vector of the refraction (eq. 16)
@@ -356,7 +357,7 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, con
float cosHI = dot(Ht, omega_in);
// eq. 33: first we calculate D(m) with m=Ht:
float alpha2 = m_ab * m_ab;
- float cosThetaM = dot(m_N, Ht);
+ float cosThetaM = dot(N, Ht);
float cosThetaM2 = cosThetaM * cosThetaM;
float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
float cosThetaM4 = cosThetaM2 * cosThetaM2;
@@ -374,21 +375,15 @@ __device float3 bsdf_microfacet_beckmann_eval_transmit(const ShaderData *sd, con
return make_float3 (out, out, out);
}
-__device float bsdf_microfacet_beckmann_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_microfacet_beckmann_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)
{
float m_ab = sc->data0;
- float m_eta = sc->data1;
int m_refractive = sc->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
- float3 m_N = sd->N;
+ float3 N = sc->N;
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
if(cosNO > 0) {
- float3 X, Y, Z = m_N;
+ float3 X, Y, Z = N;
make_orthonormals(Z, &X, &Y);
// generate a random microfacet normal m
// eq. 35,36:
@@ -404,11 +399,11 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC
cosThetaM * Z;
if(!m_refractive) {
- float cosMO = dot(m, sd->I);
+ float cosMO = dot(m, I);
if(cosMO > 0) {
// eq. 39 - compute actual reflected direction
- *omega_in = 2 * cosMO * m - sd->I;
- if(dot(sd->Ng, *omega_in) > 0) {
+ *omega_in = 2 * cosMO * m - I;
+ if(dot(Ng, *omega_in) > 0) {
// microfacet normal is visible to this ray
// eq. 25
float cosThetaM2 = cosThetaM * cosThetaM;
@@ -422,7 +417,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC
// eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
*pdf = pm * 0.25f / cosMO;
// Eval BRDF*cosNI
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
@@ -433,8 +428,8 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC
float out = (G * D) * 0.25f / cosNO;
*eval = make_float3(out, out, out);
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(m, sd->dI.dx)) * m - sd->dI.dx;
- *domega_in_dy = (2 * dot(m, sd->dI.dy)) * m - sd->dI.dy;
+ *domega_in_dx = (2 * dot(m, dIdx)) * m - dIdx;
+ *domega_in_dy = (2 * dot(m, dIdy)) * m - dIdy;
// Since there is some blur to this reflection, make the
// derivatives a bit bigger. In theory this varies with the
// roughness but the exact relationship is complex and
@@ -452,10 +447,11 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC
#ifdef __RAY_DIFFERENTIALS__
float3 dRdx, dRdy, dTdx, dTdy;
#endif
+ float m_eta = sc->data1;
bool inside;
- fresnel_dielectric(m_eta, m, sd->I, &R, &T,
+ fresnel_dielectric(m_eta, m, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
- sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
#endif
&inside);
@@ -474,7 +470,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC
// eq. 24
float pm = D * cosThetaM;
// eval BRDF*cosNI
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// eq. 26, 27: now calculate G1(i,m) and G1(o,m)
float ao = 1 / (m_ab * safe_sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
float ai = 1 / (m_ab * safe_sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
@@ -483,7 +479,7 @@ __device int bsdf_microfacet_beckmann_sample(const ShaderData *sd, const ShaderC
float G = G1o * G1i;
// eq. 21
float cosHI = dot(m, *omega_in);
- float cosHO = dot(m, sd->I);
+ float cosHO = dot(m, I);
float Ht2 = m_eta * cosHI + cosHO;
Ht2 *= Ht2;
float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
diff --git a/intern/cycles/kernel/svm/bsdf_oren_nayar.h b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
index a7edccdc423..066937da6eb 100644
--- a/intern/cycles/kernel/svm/bsdf_oren_nayar.h
+++ b/intern/cycles/kernel/closure/bsdf_oren_nayar.h
@@ -21,11 +21,6 @@
CCL_NAMESPACE_BEGIN
-typedef struct BsdfOrenNayarClosure {
- float m_a;
- float m_b;
-} BsdfOrenNayarClosure;
-
__device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n, float3 v, float3 l)
{
float nl = max(dot(n, l), 0.0f);
@@ -38,10 +33,11 @@ __device float3 bsdf_oren_nayar_get_intensity(const ShaderClosure *sc, float3 n,
return make_float3(is, is, is);
}
-__device void bsdf_oren_nayar_setup(ShaderData *sd, ShaderClosure *sc, float sigma)
+__device int bsdf_oren_nayar_setup(ShaderClosure *sc)
{
+ float sigma = sc->data0;
+
sc->type = CLOSURE_BSDF_OREN_NAYAR_ID;
- sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL;
sigma = clamp(sigma, 0.0f, 1.0f);
@@ -49,17 +45,19 @@ __device void bsdf_oren_nayar_setup(ShaderData *sd, ShaderClosure *sc, float sig
sc->data0 = 1.0f * div;
sc->data1 = sigma * div;
+
+ return SD_BSDF | SD_BSDF_HAS_EVAL;
}
__device void bsdf_oren_nayar_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_oren_nayar_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_oren_nayar_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
- if (dot(sd->N, omega_in) > 0.0f) {
+ if (dot(sc->N, omega_in) > 0.0f) {
*pdf = 0.5f * M_1_PI_F;
- return bsdf_oren_nayar_get_intensity(sc, sd->N, I, omega_in);
+ return bsdf_oren_nayar_get_intensity(sc, sc->N, I, omega_in);
}
else {
*pdf = 0.0f;
@@ -67,27 +65,22 @@ __device float3 bsdf_oren_nayar_eval_reflect(const ShaderData *sd, const ShaderC
}
}
-__device float3 bsdf_oren_nayar_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float bsdf_oren_nayar_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_oren_nayar_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__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)
{
- sample_uniform_hemisphere(sd->N, randu, randv, omega_in, pdf);
+ sample_uniform_hemisphere(sc->N, randu, randv, omega_in, pdf);
- if (dot(sd->Ng, *omega_in) > 0.0f) {
- *eval = bsdf_oren_nayar_get_intensity(sc, sd->N, sd->I, *omega_in);
+ if (dot(Ng, *omega_in) > 0.0f) {
+ *eval = bsdf_oren_nayar_get_intensity(sc, sc->N, I, *omega_in);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the bounce
- *domega_in_dx = (2.0f * dot(sd->N, sd->dI.dx)) * sd->N - sd->dI.dx;
- *domega_in_dy = (2.0f * dot(sd->N, sd->dI.dy)) * sd->N - sd->dI.dy;
+ *domega_in_dx = (2.0f * dot(sc->N, dIdx)) * sc->N - dIdx;
+ *domega_in_dy = (2.0f * dot(sc->N, dIdy)) * sc->N - dIdy;
*domega_in_dx *= 125.0f;
*domega_in_dy *= 125.0f;
#endif
diff --git a/intern/cycles/kernel/closure/bsdf_phong_ramp.h b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
new file mode 100644
index 00000000000..a2df77c2d2b
--- /dev/null
+++ b/intern/cycles/kernel/closure/bsdf_phong_ramp.h
@@ -0,0 +1,140 @@
+/*
+ * Adapted from Open Shading Language with this license:
+ *
+ * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
+ * All Rights Reserved.
+ *
+ * Modifications Copyright 2012, Blender Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * 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.
+ * * 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.
+ * * 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.
+ * 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
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BSDF_PHONG_RAMP_H__
+#define __BSDF_PHONG_RAMP_H__
+
+CCL_NAMESPACE_BEGIN
+
+__device float3 bsdf_phong_ramp_get_color(const ShaderClosure *sc, const float3 colors[8], float pos)
+{
+ int MAXCOLORS = 8;
+
+ float npos = pos * (float)(MAXCOLORS - 1);
+ int ipos = (int)npos;
+ if (ipos >= (MAXCOLORS - 1))
+ return colors[MAXCOLORS - 1];
+ float offset = npos - (float)ipos;
+ return colors[ipos] * (1.0f - offset) + colors[ipos+1] * offset;
+}
+
+__device int bsdf_phong_ramp_setup(ShaderClosure *sc)
+{
+ sc->type = CLOSURE_BSDF_PHONG_RAMP_ID;
+ return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
+}
+
+__device void bsdf_phong_ramp_blur(ShaderClosure *sc, float roughness)
+{
+}
+
+__device float3 bsdf_phong_ramp_eval_reflect(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf)
+{
+ float m_exponent = sc->data0;
+ float cosNI = dot(sc->N, omega_in);
+ float cosNO = dot(sc->N, I);
+
+ if (cosNI > 0 && cosNO > 0) {
+ // reflect the view vector
+ float3 R = (2 * cosNO) * sc->N - I;
+ float cosRI = dot(R, omega_in);
+ if (cosRI > 0) {
+ float cosp = powf(cosRI, m_exponent);
+ float common = 0.5f * (float) M_1_PI_F * cosp;
+ float out = cosNI * (m_exponent + 2) * common;
+ *pdf = (m_exponent + 1) * common;
+ return bsdf_phong_ramp_get_color(sc, colors, cosp) * out;
+ }
+ }
+
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device float3 bsdf_phong_ramp_eval_transmit(const ShaderClosure *sc, const float3 colors[8], const float3 I, const float3 omega_in, float *pdf)
+{
+ return make_float3(0.0f, 0.0f, 0.0f);
+}
+
+__device int bsdf_phong_ramp_sample(const ShaderClosure *sc, const float3 colors[8], 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)
+{
+ float cosNO = dot(sc->N, I);
+ float m_exponent = sc->data0;
+
+ if (cosNO > 0) {
+ // reflect the view vector
+ float3 R = (2 * cosNO) * sc->N - I;
+
+#ifdef __RAY_DIFFERENTIALS__
+ *domega_in_dx = (2 * dot(sc->N, dIdx)) * sc->N - dIdx;
+ *domega_in_dy = (2 * dot(sc->N, dIdy)) * sc->N - dIdy;
+#endif
+
+ float3 T, B;
+ make_orthonormals (R, &T, &B);
+ float phi = 2 * M_PI_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(sc->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(sc, colors, cosp) * out;
+
+#ifdef __RAY_DIFFERENTIALS__
+ // Since there is some blur to this reflection, make the
+ // derivatives a bit bigger. In theory this varies with the
+ // exponent but the exact relationship is complex and
+ // requires more ops than are practical.
+ *domega_in_dx *= 10;
+ *domega_in_dy *= 10;
+#endif
+ }
+ }
+ }
+ return LABEL_REFLECT;
+}
+
+
+CCL_NAMESPACE_END
+
+#endif /* __BSDF_PHONG_RAMP_H__ */
diff --git a/intern/cycles/kernel/svm/bsdf_reflection.h b/intern/cycles/kernel/closure/bsdf_reflection.h
index 09b4e0e48f0..9356f950d98 100644
--- a/intern/cycles/kernel/svm/bsdf_reflection.h
+++ b/intern/cycles/kernel/closure/bsdf_reflection.h
@@ -37,48 +37,39 @@ CCL_NAMESPACE_BEGIN
/* REFLECTION */
-typedef struct BsdfReflectionClosure {
- //float3 m_N;
-} BsdfReflectionClosure;
-
-__device void bsdf_reflection_setup(ShaderData *sd, ShaderClosure *sc)
+__device int bsdf_reflection_setup(ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_REFLECTION_ID;
- sd->flag |= SD_BSDF;
+ return SD_BSDF;
}
__device void bsdf_reflection_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_reflection_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float3 bsdf_reflection_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float bsdf_reflection_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_reflection_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__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 BsdfReflectionClosure *self = (const BsdfReflectionClosure*)sc->data;
- float3 m_N = sd->N;
+ float3 N = sc->N;
// only one direction is possible
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
if(cosNO > 0) {
- *omega_in = (2 * cosNO) * m_N - sd->I;
- if(dot(sd->Ng, *omega_in) > 0) {
+ *omega_in = (2 * cosNO) * N - I;
+ if(dot(Ng, *omega_in) > 0) {
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = 2 * dot(m_N, sd->dI.dx) * m_N - sd->dI.dx;
- *domega_in_dy = 2 * dot(m_N, sd->dI.dy) * m_N - sd->dI.dy;
+ *domega_in_dx = 2 * dot(N, dIdx) * N - dIdx;
+ *domega_in_dy = 2 * dot(N, dIdy) * N - dIdy;
#endif
*pdf = 1;
*eval = make_float3(1, 1, 1);
diff --git a/intern/cycles/kernel/svm/bsdf_refraction.h b/intern/cycles/kernel/closure/bsdf_refraction.h
index c9c268999c0..ef79d6cc259 100644
--- a/intern/cycles/kernel/svm/bsdf_refraction.h
+++ b/intern/cycles/kernel/closure/bsdf_refraction.h
@@ -37,50 +37,39 @@ CCL_NAMESPACE_BEGIN
/* REFRACTION */
-typedef struct BsdfRefractionClosure {
- float m_eta;
-} BsdfRefractionClosure;
-
-__device void bsdf_refraction_setup(ShaderData *sd, ShaderClosure *sc, float eta)
+__device int bsdf_refraction_setup(ShaderClosure *sc)
{
- sc->data0 = eta;
-
sc->type = CLOSURE_BSDF_REFRACTION_ID;
- sd->flag |= SD_BSDF;
+ return SD_BSDF;
}
__device void bsdf_refraction_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_refraction_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float3 bsdf_refraction_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float bsdf_refraction_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_refraction_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__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)
{
float m_eta = sc->data0;
- float3 m_N = sd->N;
+ float3 N = sc->N;
float3 R, T;
#ifdef __RAY_DIFFERENTIALS__
float3 dRdx, dRdy, dTdx, dTdy;
#endif
bool inside;
- fresnel_dielectric(m_eta, m_N, sd->I, &R, &T,
+ fresnel_dielectric(m_eta, N, I, &R, &T,
#ifdef __RAY_DIFFERENTIALS__
- sd->dI.dx, sd->dI.dy, &dRdx, &dRdy, &dTdx, &dTdy,
+ dIdx, dIdy, &dRdx, &dRdy, &dTdx, &dTdy,
#endif
&inside);
diff --git a/intern/cycles/kernel/svm/bsdf_transparent.h b/intern/cycles/kernel/closure/bsdf_transparent.h
index 511836cdfa2..81bc7690b50 100644
--- a/intern/cycles/kernel/svm/bsdf_transparent.h
+++ b/intern/cycles/kernel/closure/bsdf_transparent.h
@@ -35,38 +35,33 @@
CCL_NAMESPACE_BEGIN
-__device void bsdf_transparent_setup(ShaderData *sd, ShaderClosure *sc)
+__device int bsdf_transparent_setup(ShaderClosure *sc)
{
sc->type = CLOSURE_BSDF_TRANSPARENT_ID;
- sd->flag |= SD_BSDF;
+ return SD_BSDF;
}
__device void bsdf_transparent_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_transparent_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float3 bsdf_transparent_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__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);
}
-__device float bsdf_transparent_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_transparent_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__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 = -sd->I;
+ *omega_in = -I;
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = -sd->dI.dx;
- *domega_in_dy = -sd->dI.dy;
+ *domega_in_dx = -dIdx;
+ *domega_in_dy = -dIdy;
#endif
*pdf = 1;
*eval = make_float3(1, 1, 1);
diff --git a/intern/cycles/kernel/svm/bsdf_ward.h b/intern/cycles/kernel/closure/bsdf_ward.h
index 6ae45948a73..dbddcf20dba 100644
--- a/intern/cycles/kernel/svm/bsdf_ward.h
+++ b/intern/cycles/kernel/closure/bsdf_ward.h
@@ -37,23 +37,19 @@ CCL_NAMESPACE_BEGIN
/* WARD */
-typedef struct BsdfWardClosure {
- //float3 m_N;
- //float3 m_T;
- float m_ax;
- float m_ay;
-} BsdfWardClosure;
-
-__device void bsdf_ward_setup(ShaderData *sd, ShaderClosure *sc, float3 T, float ax, float ay)
+__device int bsdf_ward_setup(ShaderClosure *sc)
{
- float m_ax = clamp(ax, 1e-5f, 1.0f);
- float m_ay = clamp(ay, 1e-5f, 1.0f);
+ float ax = sc->data0;
+ float ay = sc->data1;
+
+ float m_ax = clamp(ax, 1e-4f, 1.0f);
+ float m_ay = clamp(ay, 1e-4f, 1.0f);
sc->data0 = m_ax;
sc->data1 = m_ay;
sc->type = CLOSURE_BSDF_WARD_ID;
- sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
+ return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
__device void bsdf_ward_blur(ShaderClosure *sc, float roughness)
@@ -62,25 +58,28 @@ __device void bsdf_ward_blur(ShaderClosure *sc, float roughness)
sc->data1 = fmaxf(roughness, sc->data1);
}
-__device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ward_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_ax = sc->data0;
float m_ay = sc->data1;
- float3 m_N = sd->N;
- float3 m_T = normalize(sd->dPdu);
+ float3 N = sc->N;
+ float3 T = sc->T;
+
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ if(cosNI > 0.0f && cosNO > 0.0f) {
+ cosNO = max(cosNO, 1e-4f);
+ cosNI = max(cosNI, 1e-4f);
- if(cosNI > 0 && cosNO > 0) {
// get half vector and get x,y basis on the surface for anisotropy
float3 H = normalize(omega_in + I); // normalize needed for pdf
float3 X, Y;
- make_orthonormals_tangent(m_N, m_T, &X, &Y);
+ make_orthonormals_tangent(N, T, &X, &Y);
// eq. 4
float dotx = dot(H, X) / m_ax;
float doty = dot(H, Y) / m_ay;
- float dotn = dot(H, m_N);
+ float dotn = dot(H, N);
float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
float denom = (4 * M_PI_F * m_ax * m_ay * sqrtf(cosNO * cosNI));
float exp_val = expf(-exp_arg);
@@ -90,31 +89,27 @@ __device float3 bsdf_ward_eval_reflect(const ShaderData *sd, const ShaderClosure
*pdf = exp_val / denom;
return make_float3 (out, out, out);
}
+
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_ward_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_ward_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_ward_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_ward_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)
{
float m_ax = sc->data0;
float m_ay = sc->data1;
- float3 m_N = sd->N;
- float3 m_T = normalize(sd->dPdu);
+ float3 N = sc->N;
+ float3 T = sc->T;
- float cosNO = dot(m_N, sd->I);
- if(cosNO > 0) {
+ float cosNO = dot(N, I);
+ if(cosNO > 0.0f) {
// get x,y basis on the surface for anisotropy
float3 X, Y;
- make_orthonormals_tangent(m_N, m_T, &X, &Y);
+ make_orthonormals_tangent(N, T, &X, &Y);
// generate random angles for the half vector
// eq. 7 (taking care around discontinuities to keep
//ttoutput angle in the right quadrant)
@@ -166,13 +161,16 @@ __device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, flo
float doty = h.y / m_ay;
float dotn = h.z;
// transform to world space
- h = h.x * X + h.y * Y + h.z * m_N;
+ h = h.x * X + h.y * Y + h.z * N;
// generate the final sample
- float oh = dot(h, sd->I);
- *omega_in = 2.0f * oh * h - sd->I;
- if(dot(sd->Ng, *omega_in) > 0) {
- float cosNI = dot(m_N, *omega_in);
+ float oh = dot(h, I);
+ *omega_in = 2.0f * oh * h - I;
+ if(dot(Ng, *omega_in) > 0) {
+ float cosNI = dot(N, *omega_in);
if(cosNI > 0) {
+ cosNO = max(cosNO, 1e-4f);
+ cosNI = max(cosNI, 1e-4f);
+
// eq. 9
float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
float denom = 4 * M_PI_F * m_ax * m_ay * oh * dotn * dotn * dotn;
@@ -182,8 +180,8 @@ __device int bsdf_ward_sample(const ShaderData *sd, const ShaderClosure *sc, flo
float power = cosNI * expf(-exp_arg) / denom;
*eval = make_float3(power, power, power);
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
// Since there is some blur to this reflection, make the
// derivatives a bit bigger. In theory this varies with the
// roughness but the exact relationship is complex and
diff --git a/intern/cycles/kernel/svm/bsdf_westin.h b/intern/cycles/kernel/closure/bsdf_westin.h
index 3e7c27f44a4..968173208b4 100644
--- a/intern/cycles/kernel/svm/bsdf_westin.h
+++ b/intern/cycles/kernel/closure/bsdf_westin.h
@@ -37,19 +37,16 @@ CCL_NAMESPACE_BEGIN
/* WESTIN BACKSCATTER */
-typedef struct BsdfWestinBackscatterClosure {
- //float3 m_N;
- float m_invroughness;
-} BsdfWestinBackscatterClosure;
-
-__device void bsdf_westin_backscatter_setup(ShaderData *sd, ShaderClosure *sc, float roughness)
+__device int bsdf_westin_backscatter_setup(ShaderClosure *sc)
{
+ float roughness = sc->data0;
roughness = clamp(roughness, 1e-5f, 1.0f);
float m_invroughness = 1.0f/roughness;
sc->type = CLOSURE_BSDF_WESTIN_BACKSCATTER_ID;
- sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
sc->data0 = m_invroughness;
+
+ return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
__device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness)
@@ -59,14 +56,14 @@ __device void bsdf_westin_backscatter_blur(ShaderClosure *sc, float roughness)
sc->data0 = m_invroughness;
}
-__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_backscatter_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_invroughness = sc->data0;
- float3 m_N = sd->N;
+ float3 N = sc->N;
// pdf is implicitly 0 (no indirect sampling)
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO > 0 && cosNI > 0) {
float cosine = dot(I, omega_in);
*pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0;
@@ -76,40 +73,35 @@ __device float3 bsdf_westin_backscatter_eval_reflect(const ShaderData *sd, const
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_backscatter_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_westin_backscatter_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_westin_backscatter_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)
{
float m_invroughness = sc->data0;
- float3 m_N = sd->N;
+ float3 N = sc->N;
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
if(cosNO > 0) {
#ifdef __RAY_DIFFERENTIALS__
- *domega_in_dx = sd->dI.dx;
- *domega_in_dy = sd->dI.dy;
+ *domega_in_dx = dIdx;
+ *domega_in_dy = dIdy;
#endif
float3 T, B;
- make_orthonormals (sd->I, &T, &B);
+ make_orthonormals (I, &T, &B);
float phi = 2 * M_PI_F * randu;
float cosTheta = powf(randv, 1 / (m_invroughness + 1));
float sinTheta2 = 1 - cosTheta * cosTheta;
float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
*omega_in = (cosf(phi) * sinTheta) * T +
(sinf(phi) * sinTheta) * B +
- (cosTheta) * sd->I;
- if(dot(sd->Ng, *omega_in) > 0)
+ (cosTheta) * I;
+ if(dot(Ng, *omega_in) > 0)
{
// common terms for pdf and eval
- float cosNI = dot(m_N, *omega_in);
+ float cosNI = dot(N, *omega_in);
// make sure the direction we chose is still in the right hemisphere
if(cosNI > 0)
{
@@ -132,30 +124,26 @@ __device int bsdf_westin_backscatter_sample(const ShaderData *sd, const ShaderCl
/* WESTIN SHEEN */
-typedef struct BsdfWestinSheenClosure {
- //float3 m_N;
- float m_edginess;
-} BsdfWestinSheenClosure;
-
-__device void bsdf_westin_sheen_setup(ShaderData *sd, ShaderClosure *sc, float edginess)
+__device int bsdf_westin_sheen_setup(ShaderClosure *sc)
{
+ float edginess = sc->data0;
sc->type = CLOSURE_BSDF_WESTIN_SHEEN_ID;
- sd->flag |= SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
sc->data0 = edginess;
+ return SD_BSDF|SD_BSDF_HAS_EVAL|SD_BSDF_GLOSSY;
}
__device void bsdf_westin_sheen_blur(ShaderClosure *sc, float roughness)
{
}
-__device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_sheen_eval_reflect(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
float m_edginess = sc->data0;
- float3 m_N = sd->N;
+ float3 N = sc->N;
// pdf is implicitly 0 (no indirect sampling)
- float cosNO = dot(m_N, I);
- float cosNI = dot(m_N, omega_in);
+ float cosNO = dot(N, I);
+ float cosNI = dot(N, omega_in);
if(cosNO > 0 && cosNI > 0) {
float sinNO2 = 1 - cosNO * cosNO;
*pdf = cosNI * M_1_PI_F;
@@ -165,34 +153,29 @@ __device float3 bsdf_westin_sheen_eval_reflect(const ShaderData *sd, const Shade
return make_float3 (0, 0, 0);
}
-__device float3 bsdf_westin_sheen_eval_transmit(const ShaderData *sd, const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
+__device float3 bsdf_westin_sheen_eval_transmit(const ShaderClosure *sc, const float3 I, const float3 omega_in, float *pdf)
{
return make_float3(0.0f, 0.0f, 0.0f);
}
-__device float bsdf_westin_sheen_albedo(const ShaderData *sd, const ShaderClosure *sc, const float3 I)
-{
- return 1.0f;
-}
-
-__device int bsdf_westin_sheen_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3 *eval, float3 *omega_in, float3 *domega_in_dx, float3 *domega_in_dy, float *pdf)
+__device int bsdf_westin_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)
{
float m_edginess = sc->data0;
- float3 m_N = sd->N;
+ float3 N = sc->N;
// we are viewing the surface from the right side - send a ray out with cosine
// distribution over the hemisphere
- sample_cos_hemisphere(m_N, randu, randv, omega_in, pdf);
- if(dot(sd->Ng, *omega_in) > 0) {
+ sample_cos_hemisphere(N, randu, randv, omega_in, pdf);
+ if(dot(Ng, *omega_in) > 0) {
// TODO: account for sheen when sampling
- float cosNO = dot(m_N, sd->I);
+ float cosNO = dot(N, I);
float sinNO2 = 1 - cosNO * cosNO;
float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * (*pdf) : 0;
*eval = make_float3(westin, westin, westin);
#ifdef __RAY_DIFFERENTIALS__
// TODO: find a better approximation for the diffuse bounce
- *domega_in_dx = (2 * dot(m_N, sd->dI.dx)) * m_N - sd->dI.dx;
- *domega_in_dy = (2 * dot(m_N, sd->dI.dy)) * m_N - sd->dI.dy;
+ *domega_in_dx = (2 * dot(N, dIdx)) * N - dIdx;
+ *domega_in_dy = (2 * dot(N, dIdy)) * N - dIdy;
*domega_in_dx *= 125.0f;
*domega_in_dy *= 125.0f;
#endif
diff --git a/intern/cycles/kernel/svm/emissive.h b/intern/cycles/kernel/closure/emissive.h
index 9a906f82963..cbf9d9a4efb 100644
--- a/intern/cycles/kernel/svm/emissive.h
+++ b/intern/cycles/kernel/closure/emissive.h
@@ -34,15 +34,21 @@ CCL_NAMESPACE_BEGIN
/* EMISSION CLOSURE */
-/// Return the probability distribution function in the direction I,
-/// given the parameters and the light's surface normal. This MUST match
-/// the PDF computed by sample().
+/* return the probability distribution function in the direction I,
+ * given the parameters and the light's surface normal. This MUST match
+ * the PDF computed by sample(). */
__device float emissive_pdf(const float3 Ng, const float3 I)
{
float cosNO = fabsf(dot(Ng, I));
return (cosNO > 0.0f)? 1.0f: 0.0f;
}
+__device void emissive_sample(const float3 Ng, float randu, float randv,
+ float3 *omega_out, float *pdf)
+{
+ /* todo: not implemented and used yet */
+}
+
__device float3 emissive_eval(const float3 Ng, const float3 I)
{
float res = emissive_pdf(Ng, I);
diff --git a/intern/cycles/kernel/svm/volume.h b/intern/cycles/kernel/closure/volume.h
index 10e9c5de352..734f9111ab6 100644
--- a/intern/cycles/kernel/svm/volume.h
+++ b/intern/cycles/kernel/closure/volume.h
@@ -23,44 +23,46 @@ CCL_NAMESPACE_BEGIN
/* ISOTROPIC VOLUME CLOSURE */
-__device void volume_isotropic_setup(ShaderData *sd, ShaderClosure *sc, float density)
+__device int volume_isotropic_setup(ShaderClosure *sc, float density)
{
sc->type = CLOSURE_VOLUME_ISOTROPIC_ID;
- sd->flag |= SD_VOLUME;
sc->data0 = density;
+
+ return SD_VOLUME;
}
-__device float3 volume_isotropic_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+__device float3 volume_isotropic_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
{
return make_float3(1.0f, 1.0f, 1.0f);
}
/* TRANSPARENT VOLUME CLOSURE */
-__device void volume_transparent_setup(ShaderData *sd, ShaderClosure *sc, float density)
+__device int volume_transparent_setup(ShaderClosure *sc, float density)
{
sc->type = CLOSURE_VOLUME_TRANSPARENT_ID;
- sd->flag |= SD_VOLUME;
sc->data0 = density;
+
+ return SD_VOLUME;
}
-__device float3 volume_transparent_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+__device float3 volume_transparent_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
{
return make_float3(1.0f, 1.0f, 1.0f);
}
/* VOLUME CLOSURE */
-__device float3 volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+__device float3 volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
{
float3 eval;
switch(sc->type) {
case CLOSURE_VOLUME_ISOTROPIC_ID:
- eval = volume_isotropic_eval_phase(sd, sc, omega_in, omega_out);
+ eval = volume_isotropic_eval_phase(sc, omega_in, omega_out);
break;
case CLOSURE_VOLUME_TRANSPARENT_ID:
- eval = volume_transparent_eval_phase(sd, sc, omega_in, omega_out);
+ eval = volume_transparent_eval_phase(sc, omega_in, omega_out);
break;
default:
eval = make_float3(0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/kernel/kernel_attribute.h b/intern/cycles/kernel/kernel_attribute.h
index 115de2fdbdb..2774f5e924b 100644
--- a/intern/cycles/kernel/kernel_attribute.h
+++ b/intern/cycles/kernel/kernel_attribute.h
@@ -59,7 +59,7 @@ __device_inline int find_attribute(KernelGlobals *kg, ShaderData *sd, uint id)
attr_map = kernel_tex_fetch(__attributes_map, ++attr_offset);
/* return result */
- return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : attr_map.z;
+ return (attr_map.y == ATTR_ELEMENT_NONE) ? (int)ATTR_STD_NOT_FOUND : (int)attr_map.z;
}
}
diff --git a/intern/cycles/kernel/kernel_bvh.h b/intern/cycles/kernel/kernel_bvh.h
index 34a44af8b8d..d70485fd6cf 100644
--- a/intern/cycles/kernel/kernel_bvh.h
+++ b/intern/cycles/kernel/kernel_bvh.h
@@ -57,7 +57,7 @@ __device_inline float3 bvh_inverse_direction(float3 dir)
__device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
{
- Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
*P = transform_point(&tfm, ray->P);
@@ -75,7 +75,7 @@ __device_inline void bvh_instance_push(KernelGlobals *kg, int object, const Ray
__device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
{
if(*t != FLT_MAX) {
- Transform tfm = object_fetch_transform(kg, object, ray->time, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
*t *= len(transform_direction(&tfm, 1.0f/(*idir)));
}
@@ -83,6 +83,35 @@ __device_inline void bvh_instance_pop(KernelGlobals *kg, int object, const Ray *
*idir = bvh_inverse_direction(ray->D);
}
+#ifdef __OBJECT_MOTION__
+__device_inline void bvh_instance_motion_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax)
+{
+ Transform itfm;
+ *tfm = object_fetch_transform_motion_test(kg, object, ray->time, &itfm);
+
+ *P = transform_point(&itfm, ray->P);
+
+ float3 dir = transform_direction(&itfm, ray->D);
+
+ float len;
+ dir = normalize_len(dir, &len);
+
+ *idir = bvh_inverse_direction(dir);
+
+ if(*t != FLT_MAX)
+ *t *= len;
+}
+
+__device_inline void bvh_instance_motion_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, Transform *tfm, const float tmax)
+{
+ if(*t != FLT_MAX)
+ *t *= len(transform_direction(tfm, 1.0f/(*idir)));
+
+ *P = ray->P;
+ *idir = bvh_inverse_direction(ray->D);
+}
+#endif
+
/* intersect two bounding boxes */
__device_inline void bvh_node_intersect(KernelGlobals *kg,
bool *traverseChild0, bool *traverseChild1,
@@ -176,7 +205,7 @@ __device_inline void bvh_triangle_intersect(KernelGlobals *kg, Intersection *ise
}
}
-__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
+__device_inline bool bvh_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
{
/* traversal stack in CUDA thread-local memory */
int traversalStack[BVH_STACK_SIZE];
@@ -268,7 +297,6 @@ __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const ui
else {
/* instance push */
object = kernel_tex_fetch(__prim_object, -primAddr-1);
-
bvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax);
++stackPtr;
@@ -296,6 +324,135 @@ __device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const ui
return (isect->prim != ~0);
}
+#ifdef __OBJECT_MOTION__
+__device_inline bool bvh_intersect_motion(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
+{
+ /* traversal stack in CUDA thread-local memory */
+ int traversalStack[BVH_STACK_SIZE];
+ traversalStack[0] = ENTRYPOINT_SENTINEL;
+
+ /* traversal variables in registers */
+ int stackPtr = 0;
+ int nodeAddr = kernel_data.bvh.root;
+
+ /* ray parameters in registers */
+ const float tmax = ray->t;
+ float3 P = ray->P;
+ float3 idir = bvh_inverse_direction(ray->D);
+ int object = ~0;
+
+ Transform ob_tfm;
+
+ isect->t = tmax;
+ isect->object = ~0;
+ isect->prim = ~0;
+ isect->u = 0.0f;
+ isect->v = 0.0f;
+
+ /* traversal loop */
+ do {
+ do
+ {
+ /* traverse internal nodes */
+ while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL)
+ {
+ bool traverseChild0, traverseChild1, closestChild1;
+ int nodeAddrChild1;
+
+ bvh_node_intersect(kg, &traverseChild0, &traverseChild1,
+ &closestChild1, &nodeAddr, &nodeAddrChild1,
+ P, idir, isect->t, visibility, nodeAddr);
+
+ if(traverseChild0 != traverseChild1) {
+ /* one child was intersected */
+ if(traverseChild1) {
+ nodeAddr = nodeAddrChild1;
+ }
+ }
+ else {
+ if(!traverseChild0) {
+ /* neither child was intersected */
+ nodeAddr = traversalStack[stackPtr];
+ --stackPtr;
+ }
+ else {
+ /* both children were intersected, push the farther one */
+ if(closestChild1) {
+ int tmp = nodeAddr;
+ nodeAddr = nodeAddrChild1;
+ nodeAddrChild1 = tmp;
+ }
+
+ ++stackPtr;
+ traversalStack[stackPtr] = nodeAddrChild1;
+ }
+ }
+ }
+
+ /* if node is leaf, fetch triangle list */
+ if(nodeAddr < 0) {
+ float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*BVH_NODE_SIZE+(BVH_NODE_SIZE-1));
+ int primAddr = __float_as_int(leaf.x);
+
+ if(primAddr >= 0) {
+ int primAddr2 = __float_as_int(leaf.y);
+
+ /* pop */
+ nodeAddr = traversalStack[stackPtr];
+ --stackPtr;
+
+ /* triangle intersection */
+ while(primAddr < primAddr2) {
+ /* intersect ray against triangle */
+ bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr);
+
+ /* shadow ray early termination */
+ if(visibility == PATH_RAY_SHADOW_OPAQUE && isect->prim != ~0)
+ return true;
+
+ primAddr++;
+ }
+ }
+ else {
+ /* instance push */
+ object = kernel_tex_fetch(__prim_object, -primAddr-1);
+ bvh_instance_motion_push(kg, object, ray, &P, &idir, &isect->t, &ob_tfm, tmax);
+
+ ++stackPtr;
+ traversalStack[stackPtr] = ENTRYPOINT_SENTINEL;
+
+ nodeAddr = kernel_tex_fetch(__object_node, object);
+ }
+ }
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+ if(stackPtr >= 0) {
+ kernel_assert(object != ~0);
+
+ /* instance pop */
+ bvh_instance_motion_pop(kg, object, ray, &P, &idir, &isect->t, &ob_tfm, tmax);
+ object = ~0;
+ nodeAddr = traversalStack[stackPtr];
+ --stackPtr;
+ }
+ } while(nodeAddr != ENTRYPOINT_SENTINEL);
+
+ return (isect->prim != ~0);
+}
+#endif
+
+__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const uint visibility, Intersection *isect)
+{
+#ifdef __OBJECT_MOTION__
+ if(kernel_data.bvh.have_motion)
+ return bvh_intersect_motion(kg, ray, visibility, isect);
+ else
+ return bvh_intersect(kg, ray, visibility, isect);
+#else
+ return bvh_intersect(kg, ray, visibility, isect);
+#endif
+}
+
__device_inline float3 ray_offset(float3 P, float3 Ng)
{
#ifdef __INTERSECTION_REFINE__
@@ -349,10 +506,10 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co
#ifdef __INTERSECTION_REFINE__
if(isect->object != ~0) {
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_itfm;
#else
- Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
#endif
P = transform_point(&tfm, P);
@@ -370,10 +527,10 @@ __device_inline float3 bvh_triangle_refine(KernelGlobals *kg, ShaderData *sd, co
P = P + D*rt;
if(isect->object != ~0) {
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
Transform tfm = sd->ob_tfm;
#else
- Transform tfm = object_fetch_transform(kg, isect->object, ray->time, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
#endif
P = transform_point(&tfm, P);
diff --git a/intern/cycles/kernel/kernel_camera.h b/intern/cycles/kernel/kernel_camera.h
index 7fa987197c9..1b2fe8c56ee 100644
--- a/intern/cycles/kernel/kernel_camera.h
+++ b/intern/cycles/kernel/kernel_camera.h
@@ -63,7 +63,7 @@ __device void camera_sample_perspective(KernelGlobals *kg, float raster_x, float
/* transform ray from camera to world */
Transform cameratoworld = kernel_data.cam.cameratoworld;
-#ifdef __MOTION__
+#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
#endif
@@ -106,7 +106,7 @@ __device void camera_sample_orthographic(KernelGlobals *kg, float raster_x, floa
/* transform ray from camera to world */
Transform cameratoworld = kernel_data.cam.cameratoworld;
-#ifdef __MOTION__
+#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
#endif
@@ -180,7 +180,7 @@ __device void camera_sample_panorama(KernelGlobals *kg, float raster_x, float ra
/* transform ray from camera to world */
Transform cameratoworld = kernel_data.cam.cameratoworld;
-#ifdef __MOTION__
+#ifdef __CAMERA_MOTION__
if(kernel_data.cam.have_motion)
transform_motion_interpolate(&cameratoworld, &kernel_data.cam.motion, ray->time);
#endif
@@ -212,12 +212,12 @@ __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, flo
float raster_x = x + kernel_tex_interp(__filter_table, filter_u, FILTER_TABLE_SIZE);
float raster_y = y + kernel_tex_interp(__filter_table, filter_v, FILTER_TABLE_SIZE);
-#ifdef __MOTION__
+#ifdef __CAMERA_MOTION__
/* motion blur */
if(kernel_data.cam.shuttertime == 0.0f)
ray->time = TIME_INVALID;
else
- ray->time = 0.5f + (time - 0.5f)*kernel_data.cam.shuttertime;
+ ray->time = 0.5f + 0.5f*(time - 0.5f)*kernel_data.cam.shuttertime;
#endif
/* sample */
diff --git a/intern/cycles/kernel/kernel_displace.h b/intern/cycles/kernel/kernel_displace.h
index 6461a1eea38..a55f7a7fd75 100644
--- a/intern/cycles/kernel/kernel_displace.h
+++ b/intern/cycles/kernel/kernel_displace.h
@@ -47,6 +47,9 @@ __device void kernel_shader_evaluate(KernelGlobals *kg, uint4 *input, float4 *ou
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;
+#endif
#ifdef __RAY_DIFFERENTIALS__
ray.dD.dx = make_float3(0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/kernel/kernel_emission.h b/intern/cycles/kernel/kernel_emission.h
index 53d53b4bedd..6d650a0158d 100644
--- a/intern/cycles/kernel/kernel_emission.h
+++ b/intern/cycles/kernel/kernel_emission.h
@@ -32,8 +32,15 @@ __device float3 direct_emissive_eval(KernelGlobals *kg, float rando,
Ray ray;
ray.D = ls->D;
ray.P = ls->P;
+ ray.t = 1.0f;
+#ifdef __OBJECT_MOTION__
+ ray.time = time;
+#endif
ray.dP.dx = make_float3(0.0f, 0.0f, 0.0f);
ray.dP.dy = make_float3(0.0f, 0.0f, 0.0f);
+#ifdef __CAMERA_MOTION__
+ ray.time = time;
+#endif
shader_setup_from_background(kg, &sd, &ray);
eval = shader_eval_background(kg, &sd, 0);
}
diff --git a/intern/cycles/kernel/kernel_light.h b/intern/cycles/kernel/kernel_light.h
index 1084415d0cf..2791b3abbb6 100644
--- a/intern/cycles/kernel/kernel_light.h
+++ b/intern/cycles/kernel/kernel_light.h
@@ -301,8 +301,13 @@ __device void triangle_light_sample(KernelGlobals *kg, int prim, int object,
#ifdef __INSTANCING__
/* instance transform */
if(ls->object >= 0) {
- Transform tfm = object_fetch_transform(kg, ls->object, time, OBJECT_TRANSFORM);
- Transform itfm = object_fetch_transform(kg, ls->object, time, OBJECT_INVERSE_TRANSFORM);
+#ifdef __OBJECT_MOTION__
+ Transform itfm;
+ Transform tfm = object_fetch_transform_motion_test(kg, object, time, &itfm);
+#else
+ Transform tfm = object_fetch_transform(kg, ls->object, OBJECT_TRANSFORM);
+ Transform itfm = object_fetch_transform(kg, ls->object, OBJECT_INVERSE_TRANSFORM);
+#endif
ls->P = transform_point(&tfm, ls->P);
ls->Ng = normalize(transform_direction_transposed(&itfm, ls->Ng));
diff --git a/intern/cycles/kernel/kernel_mbvh.h b/intern/cycles/kernel/kernel_mbvh.h
deleted file mode 100644
index ccbd3d069b4..00000000000
--- a/intern/cycles/kernel/kernel_mbvh.h
+++ /dev/null
@@ -1,394 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-CCL_NAMESPACE_BEGIN
-
-#define MBVH_OBJECT_SENTINEL 0x76543210
-#define MBVH_NODE_SIZE 8
-#define MBVH_STACK_SIZE 1024
-#define MBVH_RAY_STACK_SIZE 10000
-
-typedef struct MBVHTask {
- int node;
- int index;
- int num;
- int object;
-} MBVHTask;
-
-typedef struct MVBHRay {
- float3 P;
- float u;
- float3 idir;
- float v;
- float t;
- int index;
- int object;
-
- float3 origP;
- float3 origD;
- float tmax;
-} MBVHRay;
-
-__device float3 mbvh_inverse_direction(float3 dir)
-{
- // Avoid divide by zero (ooeps = exp2f(-80.0f))
- float ooeps = 0.00000000000000000000000082718061255302767487140869206996285356581211090087890625f;
- float3 idir;
-
- idir.x = 1.0f / (fabsf(dir.x) > ooeps ? dir.x : copysignf(ooeps, dir.x));
- idir.y = 1.0f / (fabsf(dir.y) > ooeps ? dir.y : copysignf(ooeps, dir.y));
- idir.z = 1.0f / (fabsf(dir.z) > ooeps ? dir.z : copysignf(ooeps, dir.z));
-
- return idir;
-}
-
-__device void mbvh_instance_push(KernelGlobals *kg, int object, MBVHRay *ray)
-{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
-
- ray->P = transform_point(&tfm, ray->origP);
-
- float3 dir = ray->origD;
-
- if(ray->t != ray->tmax) dir *= ray->t;
-
- dir = transform_direction(&tfm, dir);
- ray->idir = mbvh_inverse_direction(normalize(dir));
-
- if(ray->t != ray->tmax) ray->t = len(dir);
-}
-
-__device void mbvh_instance_pop(KernelGlobals *kg, int object, MBVHRay *ray)
-{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
-
- if(ray->t != ray->tmax)
- ray->t = len(transform_direction(&tfm, (1.0f/(ray->idir)) * (ray->t)));
-
- ray->P = ray->origP;
- ray->idir = mbvh_inverse_direction(ray->origD);
-}
-
-/* Sven Woop's algorithm */
-__device void mbvh_triangle_intersect(KernelGlobals *kg, MBVHRay *ray, int object, int triAddr)
-{
- float3 P = ray->P;
- float3 idir = ray->idir;
-
- /* compute and check intersection t-value */
- float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*MBVH_NODE_SIZE+0);
- float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*MBVH_NODE_SIZE+1);
- float3 dir = 1.0f/idir;
-
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z);
- float t = Oz * invDz;
-
- if(t > 0.0f && t < ray->t) {
- /* compute and check barycentric u */
- float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z;
- float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z;
- float u = Ox + t*Dx;
-
- if(u >= 0.0f) {
- /* compute and check barycentric v */
- float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*MBVH_NODE_SIZE+2);
- float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z;
- float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z;
- float v = Oy + t*Dy;
-
- if(v >= 0.0f && u + v <= 1.0f) {
- /* record intersection */
- ray->index = triAddr;
- ray->object = object;
- ray->u = u;
- ray->v = v;
- ray->t = t;
- }
- }
- }
-}
-
-__device void mbvh_node_intersect(KernelGlobals *kg, __m128 *traverseChild,
- __m128 *tHit, float3 P, float3 idir, float t, int nodeAddr)
-{
- /* X axis */
- const __m128 bminx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+0);
- const __m128 t0x = _mm_mul_ps(_mm_sub_ps(bminx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x));
- const __m128 bmaxx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+1);
- const __m128 t1x = _mm_mul_ps(_mm_sub_ps(bmaxx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x));
-
- __m128 tmin = _mm_max_ps(_mm_min_ps(t0x, t1x), _mm_setzero_ps());
- __m128 tmax = _mm_min_ps(_mm_max_ps(t0x, t1x), _mm_set_ps1(t));
-
- /* Y axis */
- const __m128 bminy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+2);
- const __m128 t0y = _mm_mul_ps(_mm_sub_ps(bminy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y));
- const __m128 bmaxy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+3);
- const __m128 t1y = _mm_mul_ps(_mm_sub_ps(bmaxy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y));
-
- tmin = _mm_max_ps(_mm_min_ps(t0y, t1y), tmin);
- tmax = _mm_min_ps(_mm_max_ps(t0y, t1y), tmax);
-
- /* Z axis */
- const __m128 bminz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+4);
- const __m128 t0z = _mm_mul_ps(_mm_sub_ps(bminz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z));
- const __m128 bmaxz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*MBVH_NODE_SIZE+5);
- const __m128 t1z = _mm_mul_ps(_mm_sub_ps(bmaxz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z));
-
- tmin = _mm_max_ps(_mm_min_ps(t0z, t1z), tmin);
- tmax = _mm_min_ps(_mm_max_ps(t0z, t1z), tmax);
-
- /* compare and get mask */
- *traverseChild = _mm_cmple_ps(tmin, tmax);
-
- /* get distance XXX probably wrong */
- *tHit = tmin;
-}
-
-static void mbvh_sort_by_length(int id[4], float len[4])
-{
- for(int i = 1; i < 4; i++) {
- int j = i - 1;
-
- while(j >= 0 && len[j] > len[j+1]) {
- swap(len[j], len[j+1]);
- swap(id[j], id[j+1]);
- j--;
- }
- }
-}
-
-__device void scene_intersect(KernelGlobals *kg, MBVHRay *rays, int numrays)
-{
- /* traversal stacks */
- MBVHTask task_stack[MBVH_STACK_SIZE];
- int active_ray_stacks[4][MBVH_RAY_STACK_SIZE];
- int num_task, num_active[4] = {0, 0, 0, 0};
- __m128i one_mm = _mm_set1_epi32(1);
-
- /* push root node task on stack */
- task_stack[0].node = kernel_data.bvh.root;
- task_stack[0].index = 0;
- task_stack[0].num = numrays;
- task_stack[0].object = ~0;
- num_task = 1;
-
- /* push all rays in first SIMD lane */
- for(int i = 0; i < numrays; i++)
- active_ray_stacks[0][i] = i;
- num_active[0] = numrays;
-
- while(num_task >= 1) {
- /* pop task */
- MBVHTask task = task_stack[--num_task];
-
- if(task.node == MBVH_OBJECT_SENTINEL) {
- /* instance pop */
-
- /* pop rays from stack */
- num_active[task.index] -= task.num;
- int ray_offset = num_active[task.index];
-
- /* transform rays */
- for(int i = 0; i < task.num; i++) {
- MBVHRay *ray = &rays[active_ray_stacks[task.index][ray_offset + i]];
- mbvh_instance_pop(kg, task.object, ray);
- }
- }
- else if(task.node >= 0) {
- /* inner node? */
-
- /* pop rays from stack*/
- num_active[task.index] -= task.num;
- int ray_offset = num_active[task.index];
-
- /* initialze simd values */
- __m128i num_active_mm = _mm_load_si128((__m128i*)num_active);
- __m128 len_mm = _mm_set_ps1(0.0f);
-
- for(int i = 0; i < task.num; i++) {
- int rayid = active_ray_stacks[task.index][ray_offset + i];
- MVBHRay *ray = rays + rayid;
-
- /* intersect 4 QBVH node children */
- __m128 result;
- __m128 thit;
-
- mbvh_node_intersect(kg, &result, &thit, ray->P, ray->idir, ray->t, task.node);
-
- /* update length for sorting */
- len_mm = _mm_add_ps(len_mm, _mm_and_ps(thit, result));
-
- /* push rays on stack */
- for(int j = 0; j < 4; j++)
- active_ray_stacks[j][num_active[j]] = rayid;
-
- /* update num active */
- __m128i resulti = _mm_and_si128(*((__m128i*)&result), one_mm);
- num_active_mm = _mm_add_epi32(resulti, num_active_mm);
- _mm_store_si128((__m128i*)num_active, num_active_mm);
- }
-
- if(num_active[0] || num_active[1] || num_active[2] || num_active[3]) {
- /* load child node addresses */
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, task.node);
- int child[4] = {
- __float_as_int(cnodes.x),
- __float_as_int(cnodes.y),
- __float_as_int(cnodes.z),
- __float_as_int(cnodes.w)};
-
- /* sort nodes by average intersection distance */
- int ids[4] = {0, 1, 2, 3};
- float len[4];
-
- _mm_store_ps(len, len_mm);
- mbvh_sort_by_length(ids, len);
-
- /* push new tasks on stack */
- for(int j = 0; j < 4; j++) {
- if(num_active[j]) {
- int id = ids[j];
-
- task_stack[num_task].node = child[id];
- task_stack[num_task].index = id;
- task_stack[num_task].num = num_active[id];
- task_stack[num_task].object = task.object;
- num_task++;
- }
- }
- }
- }
- else {
- /* fetch leaf node data */
- float4 leaf = kernel_tex_fetch(__bvh_nodes, (-task.node-1)*MBVH_NODE_SIZE+(MBVH_NODE_SIZE-2));
- int triAddr = __float_as_int(leaf.x);
- int triAddr2 = __float_as_int(leaf.y);
-
- /* pop rays from stack*/
- num_active[task.index] -= task.num;
- int ray_offset = num_active[task.index];
-
- /* triangles */
- if(triAddr >= 0) {
- int i, numq = (task.num >> 2) << 2;
-
- /* SIMD ray leaf intersection */
- for(i = 0; i < numq; i += 4) {
- MBVHRay *ray4[4] = {
- &rays[active_ray_stacks[task.index][ray_offset + i + 0]],
- &rays[active_ray_stacks[task.index][ray_offset + i + 1]],
- &rays[active_ray_stacks[task.index][ray_offset + i + 2]],
- &rays[active_ray_stacks[task.index][ray_offset + i + 3]]};
-
- /* load SoA */
-
- while(triAddr < triAddr2) {
- mbvh_triangle_intersect(ray4[0], task.object, task.node);
- mbvh_triangle_intersect(ray4[1], task.object, task.node);
- mbvh_triangle_intersect(ray4[2], task.object, task.node);
- mbvh_triangle_intersect(ray4[3], task.object, task.node);
- triAddr++;
-
- /* some shadow ray optim could be done by setting t=0 */
- }
-
- /* store AoS */
- }
-
- /* mono ray leaf intersection */
- for(; i < task.num; i++) {
- MBVHRay *ray = &rays[active_ray_stacks[task.index][ray_offset + i]];
-
- while(triAddr < triAddr2) {
- mbvh_triangle_intersect(kg, ray, task.object, task.node);
- triAddr++;
- }
- }
- }
- else {
- /* instance push */
- int object = -triAddr-1;
- int node = triAddr;
-
- /* push instance pop task */
- task_stack[num_task].node = MBVH_OBJECT_SENTINEL;
- task_stack[num_task].index = task.index;
- task_stack[num_task].num = task.num;
- task_stack[num_task].object = object;
- num_task++;
-
- num_active[task.index] += task.num;
-
- /* push node task */
- task_stack[num_task].node = node;
- task_stack[num_task].index = task.index;
- task_stack[num_task].num = task.num;
- task_stack[num_task].object = object;
- num_task++;
-
- for(int i = 0; i < task.num; i++) {
- int rayid = active_ray_stacks[task.index][ray_offset + i];
-
- /* push on stack for last task */
- active_ray_stacks[task.index][num_active[task.index]] = rayid;
- num_active[task.index]++;
-
- /* transform ray */
- MBVHRay *ray = &rays[rayid];
- mbvh_instance_push(kg, object, ray);
- }
- }
- }
- }
-}
-
-__device void mbvh_set_ray(MBVHRay *rays, int i, Ray *ray, float tmax)
-{
- MBVHRay *mray = &rays[i];
-
- /* ray parameters in registers */
- mray->P = ray->P;
- mray->idir = mbvh_inverse_direction(ray->D);
- mray->t = tmax;
-}
-
-__device bool mbvh_get_intersection(MVBHRay *rays, int i, Intersection *isect, float tmax)
-{
- MBVHRay *mray = &rays[i];
-
- if(mray->t == tmax)
- return false;
-
- isect->t = mray->t;
- isect->u = mray->u;
- isect->v = mray->v;
- isect->index = mray->index;
- isect->object = mray->object;
-
- return true;
-}
-
-__device bool mbvh_get_shadow(MBVHRay *rays, int i, float tmax)
-{
- return (rays[i].t == tmax);
-}
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/kernel_montecarlo.h b/intern/cycles/kernel/kernel_montecarlo.h
index d0b588a88d4..48d1aa64c9f 100644
--- a/intern/cycles/kernel/kernel_montecarlo.h
+++ b/intern/cycles/kernel/kernel_montecarlo.h
@@ -72,7 +72,7 @@ __device void to_unit_disk(float *x, float *y)
__device void make_orthonormals_tangent(const float3 N, const float3 T, float3 *a, float3 *b)
{
- *b = cross(N, T);
+ *b = normalize(cross(N, T));
*a = cross(*b, N);
}
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h
index 01da5050c8d..112bfbb86b5 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/kernel_object.h
@@ -23,107 +23,134 @@ enum ObjectTransform {
OBJECT_INVERSE_TRANSFORM = 3,
OBJECT_PROPERTIES = 6,
OBJECT_TRANSFORM_MOTION_PRE = 8,
- OBJECT_TRANSFORM_MOTION_POST = 12,
- OBJECT_DUPLI = 16
+ OBJECT_TRANSFORM_MOTION_MID = 12,
+ OBJECT_TRANSFORM_MOTION_POST = 16,
+ OBJECT_DUPLI = 20
};
-__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, float time, enum ObjectTransform type)
+__device_inline Transform object_fetch_transform(KernelGlobals *kg, int object, enum ObjectTransform type)
{
- Transform tfm;
+ int offset = object*OBJECT_SIZE + (int)type;
-#ifdef __MOTION__
- /* if we do motion blur */
- if(sd->flag & SD_OBJECT_MOTION) {
- /* fetch motion transforms */
- MotionTransform motion;
+ Transform tfm;
+ tfm.x = kernel_tex_fetch(__objects, offset + 0);
+ tfm.y = kernel_tex_fetch(__objects, offset + 1);
+ tfm.z = kernel_tex_fetch(__objects, offset + 2);
+ tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
- motion.pre.x = have_motion;
- motion.pre.y = kernel_tex_fetch(__objects, offset + 1);
- motion.pre.z = kernel_tex_fetch(__objects, offset + 2);
- motion.pre.w = kernel_tex_fetch(__objects, offset + 3);
+ return tfm;
+}
- motion.post.x = kernel_tex_fetch(__objects, offset + 4);
- motion.post.y = kernel_tex_fetch(__objects, offset + 5);
- motion.post.z = kernel_tex_fetch(__objects, offset + 6);
- motion.post.w = kernel_tex_fetch(__objects, offset + 7);
+#ifdef __OBJECT_MOTION__
+__device_inline Transform object_fetch_transform_motion(KernelGlobals *kg, int object, float time)
+{
+ MotionTransform motion;
- /* interpolate (todo: do only once per object) */
- transform_motion_interpolate(&tfm, &motion, time);
+ int offset = object*OBJECT_SIZE + (int)OBJECT_TRANSFORM_MOTION_PRE;
- /* invert */
- if(type == OBJECT_INVERSE_TRANSFORM)
- tfm = transform_quick_inverse(tfm);
+ motion.pre.x = kernel_tex_fetch(__objects, offset + 0);
+ motion.pre.y = kernel_tex_fetch(__objects, offset + 1);
+ motion.pre.z = kernel_tex_fetch(__objects, offset + 2);
+ motion.pre.w = kernel_tex_fetch(__objects, offset + 3);
- return tfm;
- }
-#endif
+ motion.mid.x = kernel_tex_fetch(__objects, offset + 4);
+ motion.mid.y = kernel_tex_fetch(__objects, offset + 5);
+ motion.mid.z = kernel_tex_fetch(__objects, offset + 6);
+ motion.mid.w = kernel_tex_fetch(__objects, offset + 7);
- int offset = object*OBJECT_SIZE + (int)type;
+ motion.post.x = kernel_tex_fetch(__objects, offset + 8);
+ motion.post.y = kernel_tex_fetch(__objects, offset + 9);
+ motion.post.z = kernel_tex_fetch(__objects, offset + 10);
+ motion.post.w = kernel_tex_fetch(__objects, offset + 11);
- tfm.x = kernel_tex_fetch(__objects, offset + 0);
- tfm.y = kernel_tex_fetch(__objects, offset + 1);
- tfm.z = kernel_tex_fetch(__objects, offset + 2);
- tfm.w = make_float4(0.0f, 0.0f, 0.0f, 1.0f);
+ Transform tfm;
+ transform_motion_interpolate(&tfm, &motion, time);
return tfm;
}
+__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);
+
+ 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;
+ }
+}
+#endif
+
__device_inline void object_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
{
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
*P = transform_point(&sd->ob_tfm, *P);
#else
- Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
*P = transform_point(&tfm, *P);
#endif
}
__device_inline void object_inverse_position_transform(KernelGlobals *kg, ShaderData *sd, float3 *P)
{
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
*P = transform_point(&sd->ob_itfm, *P);
#else
- Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
*P = transform_point(&tfm, *P);
#endif
}
__device_inline void object_inverse_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
{
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
*N = normalize(transform_direction_transposed(&sd->ob_tfm, *N));
#else
- Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
*N = normalize(transform_direction_transposed(&tfm, *N));
#endif
}
__device_inline void object_normal_transform(KernelGlobals *kg, ShaderData *sd, float3 *N)
{
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
*N = normalize(transform_direction_transposed(&sd->ob_itfm, *N));
#else
- Transform tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_INVERSE_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_INVERSE_TRANSFORM);
*N = normalize(transform_direction_transposed(&tfm, *N));
#endif
}
__device_inline void object_dir_transform(KernelGlobals *kg, ShaderData *sd, float3 *D)
{
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
*D = transform_direction(&sd->ob_tfm, *D);
#else
- Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
*D = transform_direction(&tfm, *D);
#endif
}
__device_inline float3 object_location(KernelGlobals *kg, ShaderData *sd)
{
-#ifdef __MOTION__
+ if(sd->object == ~0)
+ 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);
#else
- Transform tfm = object_fetch_transform(kg, sd->object, 0.0f, OBJECT_TRANSFORM);
+ Transform tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM);
return make_float3(tfm.x.w, tfm.y.w, tfm.z.w);
#endif
}
@@ -249,6 +276,5 @@ __device float3 particle_angular_velocity(KernelGlobals *kg, int particle)
return make_float3(f3.z, f3.w, f4.x);
}
-
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index d606c3d634a..585068ce8e2 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -326,7 +326,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
#ifdef __AO__
/* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion) {
+ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
/* todo: solve correlation */
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
@@ -343,12 +343,13 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
light_ray.P = ray_offset(sd.P, sd.Ng);
light_ray.D = ao_D;
light_ray.t = kernel_data.background.ao_distance;
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
+ ao_bsdf += shader_bsdf_ao(kg, &sd);
path_radiance_accum_ao(&L, throughput, ao_bsdf, ao_shadow, state.bounce);
}
}
@@ -368,7 +369,7 @@ __device float4 kernel_path_progressive(KernelGlobals *kg, RNG *rng, int sample,
BsdfEval L_light;
bool is_lamp;
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
@@ -503,7 +504,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
#ifdef __AO__
/* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion) {
+ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
/* todo: solve correlation */
float bsdf_u = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_U);
float bsdf_v = path_rng(kg, rng, sample, rng_offset + PRNG_BSDF_V);
@@ -520,12 +521,13 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
light_ray.P = ray_offset(sd.P, sd.Ng);
light_ray.D = ao_D;
light_ray.t = kernel_data.background.ao_distance;
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*kernel_data.background.ao_factor;
+ ao_bsdf += shader_bsdf_ao(kg, &sd);
path_radiance_accum_ao(L, throughput, ao_bsdf, ao_shadow, state.bounce);
}
}
@@ -545,7 +547,7 @@ __device void kernel_path_indirect(KernelGlobals *kg, RNG *rng, int sample, Ray
BsdfEval L_light;
bool is_lamp;
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
@@ -706,7 +708,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
#ifdef __AO__
/* ambient occlusion */
- if(kernel_data.integrator.use_ambient_occlusion) {
+ if(kernel_data.integrator.use_ambient_occlusion || (sd.flag & SD_AO)) {
int num_samples = kernel_data.integrator.ao_samples;
float num_samples_inv = 1.0f/num_samples;
float ao_factor = kernel_data.background.ao_factor;
@@ -728,12 +730,13 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
light_ray.P = ray_offset(sd.P, sd.Ng);
light_ray.D = ao_D;
light_ray.t = kernel_data.background.ao_distance;
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
if(!shadow_blocked(kg, &state, &light_ray, &ao_shadow)) {
float3 ao_bsdf = shader_bsdf_diffuse(kg, &sd)*ao_factor;
+ ao_bsdf += shader_bsdf_ao(kg, &sd);
path_radiance_accum_ao(&L, throughput*num_samples_inv, ao_bsdf, ao_shadow, state.bounce);
}
}
@@ -748,7 +751,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
BsdfEval L_light;
bool is_lamp;
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
light_ray.time = sd.time;
#endif
@@ -867,7 +870,7 @@ __device float4 kernel_path_non_progressive(KernelGlobals *kg, RNG *rng, int sam
bsdf_ray.dP = sd.dP;
bsdf_ray.dD = bsdf_domega_in;
#endif
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
bsdf_ray.time = sd.time;
#endif
@@ -925,7 +928,7 @@ __device void kernel_path_trace(KernelGlobals *kg,
float lens_u = path_rng(kg, &rng, sample, PRNG_LENS_U);
float lens_v = path_rng(kg, &rng, sample, PRNG_LENS_V);
-#ifdef __MOTION__
+#ifdef __CAMERA_MOTION__
float time = path_rng(kg, &rng, sample, PRNG_TIME);
#else
float time = 0.0f;
diff --git a/intern/cycles/kernel/kernel_projection.h b/intern/cycles/kernel/kernel_projection.h
index 64747bcb42e..6516b9e4d82 100644
--- a/intern/cycles/kernel/kernel_projection.h
+++ b/intern/cycles/kernel/kernel_projection.h
@@ -98,7 +98,7 @@ __device float3 fisheye_to_direction(float u, float v, float fov)
return make_float3(0.0f, 0.0f, 0.0f);
float phi = acosf((r != 0.0f)? u/r: 0.0f);
- float theta = asinf(r) * (fov / M_PI_F);
+ float theta = r * fov * 0.5f;
if(v < 0.0f) phi = -phi;
diff --git a/intern/cycles/kernel/kernel_qbvh.h b/intern/cycles/kernel/kernel_qbvh.h
deleted file mode 100644
index 525b616921d..00000000000
--- a/intern/cycles/kernel/kernel_qbvh.h
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- * Adapted from code Copyright 2009-2010 NVIDIA Corporation
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-CCL_NAMESPACE_BEGIN
-
-/*
- * "Persistent while-while kernel" used in:
- *
- * "Understanding the Efficiency of Ray Traversal on GPUs",
- * Timo Aila and Samuli Laine,
- * Proc. High-Performance Graphics 2009
- */
-
-/* bottom-most stack entry, indicating the end of traversal */
-
-#define ENTRYPOINT_SENTINEL 0x76543210
-/* 64 object BVH + 64 mesh BVH + 64 object node splitting */
-#define QBVH_STACK_SIZE 192
-#define QBVH_NODE_SIZE 8
-#define TRI_NODE_SIZE 3
-
-__device_inline float3 qbvh_inverse_direction(float3 dir)
-{
- // Avoid divide by zero (ooeps = exp2f(-80.0f))
- float ooeps = 0.00000000000000000000000082718061255302767487140869206996285356581211090087890625f;
- float3 idir;
-
- idir.x = 1.0f/((fabsf(dir.x) > ooeps)? dir.x: copysignf(ooeps, dir.x));
- idir.y = 1.0f/((fabsf(dir.y) > ooeps)? dir.y: copysignf(ooeps, dir.y));
- idir.z = 1.0f/((fabsf(dir.z) > ooeps)? dir.z: copysignf(ooeps, dir.z));
-
- return idir;
-}
-
-__device_inline void qbvh_instance_push(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
-{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
-
- *P = transform_point(&tfm, ray->P);
-
- float3 dir = transform_direction(&tfm, ray->D);
-
- float len;
- dir = normalize_len(dir, &len);
-
- *idir = qbvh_inverse_direction(dir);
-
- if(*t != FLT_MAX)
- *t *= len;
-}
-
-__device_inline void qbvh_instance_pop(KernelGlobals *kg, int object, const Ray *ray, float3 *P, float3 *idir, float *t, const float tmax)
-{
- Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
-
- if(*t != FLT_MAX)
- *t *= len(transform_direction(&tfm, 1.0f/(*idir)));
-
- *P = ray->P;
- *idir = qbvh_inverse_direction(ray->D);
-}
-
-#ifdef __KERNEL_CPU__
-
-__device_inline void qbvh_node_intersect(KernelGlobals *kg, int *traverseChild,
- int nodeAddrChild[4], float3 P, float3 idir, float t, int nodeAddr)
-{
- /* X axis */
- const __m128 bminx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+0);
- const __m128 t0x = _mm_mul_ps(_mm_sub_ps(bminx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x));
- const __m128 bmaxx = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+1);
- const __m128 t1x = _mm_mul_ps(_mm_sub_ps(bmaxx, _mm_set_ps1(P.x)), _mm_set_ps1(idir.x));
-
- __m128 tmin = _mm_max_ps(_mm_min_ps(t0x, t1x), _mm_setzero_ps());
- __m128 tmax = _mm_min_ps(_mm_max_ps(t0x, t1x), _mm_set_ps1(t));
-
- /* Y axis */
- const __m128 bminy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+2);
- const __m128 t0y = _mm_mul_ps(_mm_sub_ps(bminy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y));
- const __m128 bmaxy = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+3);
- const __m128 t1y = _mm_mul_ps(_mm_sub_ps(bmaxy, _mm_set_ps1(P.y)), _mm_set_ps1(idir.y));
-
- tmin = _mm_max_ps(_mm_min_ps(t0y, t1y), tmin);
- tmax = _mm_min_ps(_mm_max_ps(t0y, t1y), tmax);
-
- /* Z axis */
- const __m128 bminz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+4);
- const __m128 t0z = _mm_mul_ps(_mm_sub_ps(bminz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z));
- const __m128 bmaxz = kernel_tex_fetch_m128(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+5);
- const __m128 t1z = _mm_mul_ps(_mm_sub_ps(bmaxz, _mm_set_ps1(P.z)), _mm_set_ps1(idir.z));
-
- tmin = _mm_max_ps(_mm_min_ps(t0z, t1z), tmin);
- tmax = _mm_min_ps(_mm_max_ps(t0z, t1z), tmax);
-
- /* compare and get mask */
- *traverseChild = _mm_movemask_ps(_mm_cmple_ps(tmin, tmax));
-
- /* get node addresses */
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+6);
-
- nodeAddrChild[0] = __float_as_int(cnodes.x);
- nodeAddrChild[1] = __float_as_int(cnodes.y);
- nodeAddrChild[2] = __float_as_int(cnodes.z);
- nodeAddrChild[3] = __float_as_int(cnodes.w);
-}
-
-#else
-
-__device_inline bool qbvh_bb_intersect(float3 bmin, float3 bmax, float3 P, float3 idir, float t)
-{
- float t0x = (bmin.x - P.x)*idir.x;
- float t1x = (bmax.x - P.x)*idir.x;
- float t0y = (bmin.y - P.y)*idir.y;
- float t1y = (bmax.y - P.y)*idir.y;
- float t0z = (bmin.z - P.z)*idir.z;
- float t1z = (bmax.z - P.z)*idir.z;
-
- float minx = min(t0x, t1x);
- float maxx = max(t0x, t1x);
- float miny = min(t0y, t1y);
- float maxy = max(t0y, t1y);
- float minz = min(t0z, t1z);
- float maxz = max(t0z, t1z);
-
- float tmin = max4(0.0f, minx, miny, minz);
- float tmax = min4(t, maxx, maxy, maxz);
-
- return (tmin <= tmax);
-}
-
-/* intersect four bounding boxes */
-__device_inline void qbvh_node_intersect(KernelGlobals *kg, int *traverseChild,
- int nodeAddrChild[4], float3 P, float3 idir, float t, int nodeAddr)
-{
- /* fetch node data */
- float4 minx = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+0);
- float4 miny = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+2);
- float4 minz = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+4);
- float4 maxx = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+1);
- float4 maxy = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+3);
- float4 maxz = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+5);
-
- /* intersect bounding boxes */
- bool traverseChild0 = qbvh_bb_intersect(make_float3(minx.x, miny.x, minz.x), make_float3(maxx.x, maxy.x, maxz.x), P, idir, t);
- bool traverseChild1 = qbvh_bb_intersect(make_float3(minx.y, miny.y, minz.y), make_float3(maxx.y, maxy.y, maxz.y), P, idir, t);
- bool traverseChild2 = qbvh_bb_intersect(make_float3(minx.z, miny.z, minz.z), make_float3(maxx.z, maxy.z, maxz.z), P, idir, t);
- bool traverseChild3 = qbvh_bb_intersect(make_float3(minx.w, miny.w, minz.w), make_float3(maxx.w, maxy.w, maxz.w), P, idir, t);
-
- *traverseChild = 0;
- if(traverseChild0) *traverseChild |= 1;
- if(traverseChild1) *traverseChild |= 2;
- if(traverseChild2) *traverseChild |= 4;
- if(traverseChild3) *traverseChild |= 8;
-
- /* get node addresses */
- float4 cnodes = kernel_tex_fetch(__bvh_nodes, nodeAddr*QBVH_NODE_SIZE+6);
-
- nodeAddrChild[0] = __float_as_int(cnodes.x);
- nodeAddrChild[1] = __float_as_int(cnodes.y);
- nodeAddrChild[2] = __float_as_int(cnodes.z);
- nodeAddrChild[3] = __float_as_int(cnodes.w);
-}
-
-#endif
-
-/* Sven Woop's algorithm */
-__device_inline void qbvh_triangle_intersect(KernelGlobals *kg, Intersection *isect, float3 P, float3 idir, int object, int triAddr)
-{
- /* compute and check intersection t-value */
- float4 v00 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+0);
- float4 v11 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+1);
- float3 dir = 1.0f/idir;
-
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(dir.x*v00.x + dir.y*v00.y + dir.z*v00.z);
- float t = Oz * invDz;
-
- if(t > 0.0f && t < isect->t) {
- /* compute and check barycentric u */
- float Ox = v11.w + P.x*v11.x + P.y*v11.y + P.z*v11.z;
- float Dx = dir.x*v11.x + dir.y*v11.y + dir.z*v11.z;
- float u = Ox + t*Dx;
-
- if(u >= 0.0f) {
- /* compute and check barycentric v */
- float4 v22 = kernel_tex_fetch(__tri_woop, triAddr*TRI_NODE_SIZE+2);
- float Oy = v22.w + P.x*v22.x + P.y*v22.y + P.z*v22.z;
- float Dy = dir.x*v22.x + dir.y*v22.y + dir.z*v22.z;
- float v = Oy + t*Dy;
-
- if(v >= 0.0f && u + v <= 1.0f) {
- /* record intersection */
- isect->prim = triAddr;
- isect->object = object;
- isect->u = u;
- isect->v = v;
- isect->t = t;
- }
- }
- }
-}
-
-__device_inline bool scene_intersect(KernelGlobals *kg, const Ray *ray, const bool isshadowray, Intersection *isect)
-{
- /* traversal stack in CUDA thread-local memory */
- int traversalStack[QBVH_STACK_SIZE];
- traversalStack[0] = ENTRYPOINT_SENTINEL;
-
- /* traversal variables in registers */
- int stackPtr = 0;
- int nodeAddr = kernel_data.bvh.root;
-
- /* ray parameters in registers */
- const float tmax = ray->t;
- float3 P = ray->P;
- float3 idir = qbvh_inverse_direction(ray->D);
- int object = ~0;
-
- isect->t = tmax;
- isect->object = ~0;
- isect->prim = ~0;
- isect->u = 0.0f;
- isect->v = 0.0f;
-
- /* traversal loop */
- do {
- do
- {
- /* traverse internal nodes */
- while(nodeAddr >= 0 && nodeAddr != ENTRYPOINT_SENTINEL)
- {
- int traverseChild, nodeAddrChild[4];
-
- qbvh_node_intersect(kg, &traverseChild, nodeAddrChild,
- P, idir, isect->t, nodeAddr);
-
- if(traverseChild & 1) {
- ++stackPtr;
- traversalStack[stackPtr] = nodeAddrChild[0];
- }
-
- if(traverseChild & 2) {
- ++stackPtr;
- traversalStack[stackPtr] = nodeAddrChild[1];
- }
- if(traverseChild & 4) {
- ++stackPtr;
- traversalStack[stackPtr] = nodeAddrChild[2];
- }
-
- if(traverseChild & 8) {
- ++stackPtr;
- traversalStack[stackPtr] = nodeAddrChild[3];
- }
-
- nodeAddr = traversalStack[stackPtr];
- --stackPtr;
- }
-
- /* if node is leaf, fetch triangle list */
- if(nodeAddr < 0) {
- float4 leaf = kernel_tex_fetch(__bvh_nodes, (-nodeAddr-1)*QBVH_NODE_SIZE+(QBVH_NODE_SIZE-2));
- int primAddr = __float_as_int(leaf.x);
-
-#ifdef __INSTANCING__
- if(primAddr >= 0) {
-#endif
- int primAddr2 = __float_as_int(leaf.y);
-
- /* pop */
- nodeAddr = traversalStack[stackPtr];
- --stackPtr;
-
- /* triangle intersection */
- while(primAddr < primAddr2) {
- /* intersect ray against triangle */
- qbvh_triangle_intersect(kg, isect, P, idir, object, primAddr);
-
- /* shadow ray early termination */
- if(isshadowray && isect->prim != ~0)
- return true;
-
- primAddr++;
- }
-#ifdef __INSTANCING__
- }
- else {
- /* instance push */
- object = kernel_tex_fetch(__prim_object, -primAddr-1);
-
- qbvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax);
-
- ++stackPtr;
- traversalStack[stackPtr] = ENTRYPOINT_SENTINEL;
-
- nodeAddr = kernel_tex_fetch(__object_node, object);
- }
-#endif
- }
- } while(nodeAddr != ENTRYPOINT_SENTINEL);
-
-#ifdef __INSTANCING__
- if(stackPtr >= 0) {
- kernel_assert(object != ~0);
-
- /* instance pop */
- qbvh_instance_pop(kg, object, ray, &P, &idir, &isect->t, tmax);
- object = ~0;
- nodeAddr = traversalStack[stackPtr];
- --stackPtr;
- }
-#endif
- } while(nodeAddr != ENTRYPOINT_SENTINEL);
-
- return (isect->prim != ~0);
-}
-
-__device_inline float3 ray_offset(float3 P, float3 Ng)
-{
-#ifdef __INTERSECTION_REFINE__
- const float epsilon_f = 1e-5f;
- const int epsilon_i = 32;
-
- float3 res;
-
- /* x component */
- if(fabsf(P.x) < epsilon_f) {
- 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_f) {
- 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_f) {
- 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;
-#endif
-}
-
-__device_inline float3 bvh_triangle_refine(KernelGlobals *kg, const Intersection *isect, const Ray *ray)
-{
- float3 P = ray->P;
- float3 D = ray->D;
- float t = isect->t;
-
-#ifdef __INTERSECTION_REFINE__
- if(isect->object != ~0) {
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D*t);
- D = normalize_len(D, &t);
- }
-
- P = P + D*t;
-
- float4 v00 = kernel_tex_fetch(__tri_woop, isect->prim*TRI_NODE_SIZE+0);
- float Oz = v00.w - P.x*v00.x - P.y*v00.y - P.z*v00.z;
- float invDz = 1.0f/(D.x*v00.x + D.y*v00.y + D.z*v00.z);
- float rt = Oz * invDz;
-
- P = P + D*rt;
-
- if(isect->object != ~0) {
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
- P = transform_point(&tfm, P);
- }
-
- return P;
-#else
- return P + D*t;
-#endif
-}
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index b57e27bc8ed..1af5e048ad9 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -27,22 +27,36 @@
*/
#ifdef __OSL__
-
#include "osl_shader.h"
-
#endif
-#include "svm/bsdf.h"
-#include "svm/emissive.h"
-#include "svm/volume.h"
+#include "closure/bsdf.h"
+#include "closure/emissive.h"
+#include "closure/volume.h"
+
#include "svm/svm_bsdf.h"
#include "svm/svm.h"
-
CCL_NAMESPACE_BEGIN
/* ShaderData setup from incoming ray */
+#ifdef __OBJECT_MOTION__
+__device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time)
+{
+ /* note that this is a separate non-inlined function to work around crash
+ * on CUDA sm 2.0, otherwise kernel execution crashes (compiler bug?) */
+ if(sd->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
+
__device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
const Intersection *isect, const Ray *ray)
{
@@ -67,11 +81,12 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
sd->v = isect->v;
#endif
- /* matrices and time */
-#ifdef __MOTION__
- sd->ob_tfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_TRANSFORM);
- sd->ob_itfm = object_fetch_transform(kg, sd->object, ray->time, OBJECT_INVERSE_TRANSFORM);
+ sd->flag = kernel_tex_fetch(__shader_flag, (shader & SHADER_MASK)*2);
+ sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
+ /* matrices and time */
+#ifdef __OBJECT_MOTION__
+ shader_setup_object_transforms(kg, sd, ray->time);
sd->time = ray->time;
#endif
@@ -87,9 +102,6 @@ __device_inline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
if(sd->shader & SHADER_SMOOTH_NORMAL)
sd->N = triangle_smooth_normal(kg, sd->prim, sd->u, sd->v);
- sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
- sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
-
#ifdef __DPDU__
/* dPdu/dPdv */
triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim);
@@ -171,11 +183,17 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
}
#endif
-#ifdef __MOTION__
- sd->time = time;
+ sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
+ if(sd->object != -1) {
+ sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
- sd->ob_tfm = object_fetch_transform(kg, sd->object, time, OBJECT_TRANSFORM);
- sd->ob_itfm = object_fetch_transform(kg, sd->object, time, OBJECT_INVERSE_TRANSFORM);
+#ifdef __OBJECT_MOTION__
+ shader_setup_object_transforms(kg, sd, time);
+ }
+
+ sd->time = time;
+#else
+ }
#endif
/* smooth normal */
@@ -188,10 +206,6 @@ __device void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd,
#endif
}
- sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
- if(sd->object != -1)
- sd->flag |= kernel_tex_fetch(__object_flag, sd->object);
-
#ifdef __DPDU__
/* dPdu/dPdv */
if(sd->prim == ~0) {
@@ -275,7 +289,7 @@ __device_inline void shader_setup_from_background(KernelGlobals *kg, ShaderData
sd->I = -sd->P;
sd->shader = kernel_data.background.shader;
sd->flag = kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2);
-#ifdef __MOTION__
+#ifdef __OBJECT_MOTION__
sd->time = ray->time;
#endif
sd->ray_length = 0.0f;
@@ -483,18 +497,22 @@ __device int shader_bsdf_sample_closure(KernelGlobals *kg, const ShaderData *sd,
__device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughness)
{
-#ifndef __OSL__
#ifdef __MULTI_CLOSURE__
for(int i = 0; i< sd->num_closure; i++) {
ShaderClosure *sc = &sd->closure[i];
- if(CLOSURE_IS_BSDF(sc->type))
- svm_bsdf_blur(sc, roughness);
+ if(CLOSURE_IS_BSDF(sc->type)) {
+#ifdef __OSL__
+ if (kernel_osl_use(kg))
+ OSLShader::bsdf_blur(sc, roughness);
+ else
+#endif
+ svm_bsdf_blur(sc, roughness);
+ }
}
#else
svm_bsdf_blur(&sd->closure, roughness);
#endif
-#endif
}
__device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
@@ -581,6 +599,27 @@ __device float3 shader_bsdf_transmission(KernelGlobals *kg, ShaderData *sd)
#endif
}
+__device float3 shader_bsdf_ao(KernelGlobals *kg, ShaderData *sd)
+{
+#ifdef __MULTI_CLOSURE__
+ float3 eval = 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_AMBIENT_OCCLUSION(sc->type))
+ eval += sc->weight;
+ }
+
+ return eval;
+#else
+ if(CLOSURE_IS_AMBIENT_OCCLUSION(sd->closure.type))
+ return sd->closure.weight;
+ else
+ return make_float3(0.0f, 0.0f, 0.0f);
+#endif
+}
+
/* Emission */
__device float3 shader_emissive_eval(KernelGlobals *kg, ShaderData *sd)
@@ -704,16 +743,16 @@ __device float3 shader_volume_eval_phase(KernelGlobals *kg, ShaderData *sd,
if(CLOSURE_IS_VOLUME(sc->type)) {
#ifdef __OSL__
if (kernel_osl_use(kg))
- eval += OSLShader::volume_eval_phase(sd, sc, omega_in, omega_out);
+ eval += OSLShader::volume_eval_phase(sc, omega_in, omega_out);
else
#endif
- eval += volume_eval_phase(sd, sc, omega_in, omega_out);
+ eval += volume_eval_phase(sc, omega_in, omega_out);
}
}
return eval;
#else
- return volume_eval_phase(sd, &sd->closure, omega_in, omega_out);
+ return volume_eval_phase(&sd->closure, omega_in, omega_out);
#endif
}
diff --git a/intern/cycles/kernel/kernel_triangle.h b/intern/cycles/kernel/kernel_triangle.h
index f57c59a45eb..e39ae1d4fbc 100644
--- a/intern/cycles/kernel/kernel_triangle.h
+++ b/intern/cycles/kernel/kernel_triangle.h
@@ -68,6 +68,17 @@ __device_inline float3 triangle_normal_MT(KernelGlobals *kg, int tri_index, int
#endif
}
+/* Return 3 triangle vertex locations */
+__device_inline void triangle_vertices(KernelGlobals *kg, int tri_index, float3 P[3])
+{
+ /* load triangle vertices */
+ float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, tri_index));
+
+ P[0] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
+ P[1] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
+ P[2] = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
+}
+
__device_inline float3 triangle_smooth_normal(KernelGlobals *kg, int tri_index, float u, float v)
{
/* load triangle vertices */
@@ -201,10 +212,10 @@ __device float4 triangle_motion_vector(KernelGlobals *kg, ShaderData *sd)
* transformation was set match the world/object space of motion_pre/post */
Transform tfm;
- tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_PRE);
+ tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_PRE);
motion_pre = transform_point(&tfm, motion_pre);
- tfm = object_fetch_transform(kg, sd->object, TIME_INVALID, OBJECT_TRANSFORM_MOTION_POST);
+ tfm = object_fetch_transform(kg, sd->object, OBJECT_TRANSFORM_MOTION_POST);
motion_post = transform_point(&tfm, motion_post);
float3 P;
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 48e271a9f3f..d4d88466688 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -29,13 +29,15 @@
CCL_NAMESPACE_BEGIN
/* constants */
-#define OBJECT_SIZE 18
+#define OBJECT_SIZE 22
#define LIGHT_SIZE 4
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
#define PARTICLE_SIZE 5
#define TIME_INVALID FLT_MAX
+#define TEX_NUM_FLOAT_IMAGES 5
+
/* device capabilities */
#ifdef __KERNEL_CPU__
#define __KERNEL_SHADING__
@@ -108,11 +110,15 @@ CCL_NAMESPACE_BEGIN
#define __PASSES__
#define __BACKGROUND_MIS__
#define __AO__
-//#define __MOTION__
+#define __CAMERA_MOTION__
+
+#ifndef __KERNEL_CUDA__
+#define __OBJECT_MOTION__
+#endif
+
#endif
//#define __SOBOL_FULL_SCREEN__
-//#define __QBVH__
/* Shader Evaluation */
@@ -129,7 +135,7 @@ enum PathTraceDimension {
PRNG_FILTER_V = 1,
PRNG_LENS_U = 2,
PRNG_LENS_V = 3,
-#ifdef __MOTION__
+#ifdef __CAMERA_MOTION__
PRNG_TIME = 4,
PRNG_UNUSED = 5,
PRNG_BASE_NUM = 6,
@@ -148,9 +154,7 @@ enum PathTraceDimension {
PRNG_BOUNCE_NUM = 8
};
-/* these flag values correspond exactly to OSL defaults, so be careful not to
- * change this, or if you do, set the "raytypes" shading system attribute with
- * your own new ray types and bitflag values.
+/* these flags values correspond to raytypes in osl.cpp, so keep them in sync!
*
* for ray visibility tests in BVH traversal, the upper 20 bits are used for
* layer visibility tests. */
@@ -370,6 +374,9 @@ typedef struct ShaderClosure {
float data0;
float data1;
+ float3 N;
+ float3 T;
+
} ShaderClosure;
/* Shader Data
@@ -386,16 +393,17 @@ enum ShaderDataFlag {
SD_BSDF_GLOSSY = 16, /* have glossy bsdf */
SD_HOLDOUT = 32, /* have holdout closure? */
SD_VOLUME = 64, /* have volume closure? */
+ SD_AO = 128, /* have ao closure? */
/* shader flags */
- SD_SAMPLE_AS_LIGHT = 128, /* direct light sample */
- SD_HAS_SURFACE_TRANSPARENT = 256, /* has surface transparency */
- SD_HAS_VOLUME = 512, /* has volume shader */
- SD_HOMOGENEOUS_VOLUME = 1024, /* has homogeneous volume */
+ SD_SAMPLE_AS_LIGHT = 256, /* direct light sample */
+ SD_HAS_SURFACE_TRANSPARENT = 512, /* has surface transparency */
+ SD_HAS_VOLUME = 1024, /* has volume shader */
+ SD_HOMOGENEOUS_VOLUME = 2048, /* has homogeneous volume */
/* object flags */
- SD_HOLDOUT_MASK = 2048, /* holdout for camera rays */
- SD_OBJECT_MOTION = 4096 /* has object motion blur */
+ SD_HOLDOUT_MASK = 4096, /* holdout for camera rays */
+ SD_OBJECT_MOTION = 8192 /* has object motion blur */
};
typedef struct ShaderData {
@@ -408,7 +416,7 @@ typedef struct ShaderData {
/* view/incoming direction */
float3 I;
/* shader id */
- int shader;
+ int shader;
/* booleans describing shader, see ShaderDataFlag */
int flag;
@@ -426,13 +434,6 @@ typedef struct ShaderData {
/* length of the ray being shaded */
float ray_length;
-#ifdef __MOTION__
- /* object <-> world space transformations, cached to avoid
- * re-interpolating them constantly for shading */
- Transform ob_tfm;
- Transform ob_itfm;
-#endif
-
#ifdef __RAY_DIFFERENTIALS__
/* differential of P. these are orthogonal to Ng, not N */
differential3 dP;
@@ -448,6 +449,13 @@ typedef struct ShaderData {
float3 dPdu, dPdv;
#endif
+#ifdef __OBJECT_MOTION__
+ /* object <-> world space transformations, cached to avoid
+ * re-interpolating them constantly for shading */
+ Transform ob_tfm;
+ Transform ob_itfm;
+#endif
+
#ifdef __MULTI_CLOSURE__
/* Closure data, we store a fixed array of closures */
ShaderClosure closure[MAX_CLOSURE];
@@ -511,7 +519,9 @@ typedef struct KernelCamera {
/* more matrices */
Transform screentoworld;
Transform rastertoworld;
- Transform ndctoworld;
+ /* work around cuda sm 2.0 crash, this seems to
+ * cross some limit in combination with motion
+ * Transform ndctoworld; */
Transform worldtoscreen;
Transform worldtoraster;
Transform worldtondc;
@@ -627,7 +637,8 @@ typedef struct KernelBVH {
/* root node */
int root;
int attributes_map_stride;
- int pad1, pad2;
+ int have_motion;
+ int pad2;
} KernelBVH;
typedef struct KernelData {
diff --git a/intern/cycles/kernel/osl/CMakeLists.txt b/intern/cycles/kernel/osl/CMakeLists.txt
index 65d7a7ad53b..1b1bb558bc9 100644
--- a/intern/cycles/kernel/osl/CMakeLists.txt
+++ b/intern/cycles/kernel/osl/CMakeLists.txt
@@ -7,28 +7,18 @@ set(INC
../../util
../../device
)
+
set(INC_SYS
+
)
set(SRC
background.cpp
- bsdf_ashikhmin_velvet.cpp
- bsdf_diffuse.cpp
- bsdf_oren_nayar.cpp
- bsdf_phong.cpp
- bsdf_microfacet.cpp
- bsdf_reflection.cpp
- bsdf_refraction.cpp
- bsdf_transparent.cpp
- bsdf_ward.cpp
- bsdf_westin.cpp
- bssrdf.cpp
- debug.cpp
+ bsdf_phong_ramp.cpp
emissive.cpp
osl_closures.cpp
osl_services.cpp
osl_shader.cpp
- vol_subsurface.cpp
)
set(HEADER_SRC
@@ -45,4 +35,3 @@ include_directories(SYSTEM ${INC_SYS})
add_library(cycles_kernel_osl ${SRC} ${HEADER_SRC})
-add_subdirectory(nodes)
diff --git a/intern/cycles/kernel/osl/background.cpp b/intern/cycles/kernel/osl/background.cpp
index 6290eed0af8..eed4446cddc 100644
--- a/intern/cycles/kernel/osl/background.cpp
+++ b/intern/cycles/kernel/osl/background.cpp
@@ -46,23 +46,16 @@ using namespace OSL;
/// to return a color in background shaders. No methods,
/// only the weight is taking into account
///
-class GenericBackgroundClosure : public BackgroundClosure {
+class GenericBackgroundClosure : public OSL::BackgroundClosure {
public:
GenericBackgroundClosure() {}
void setup() {};
-
size_t memsize() const { return sizeof(*this); }
-
const char *name() const { return "background"; }
-
- void print_on(std::ostream &out) const {
- out << name() << " ()";
- }
-
+ void print_on(std::ostream &out) const { out << name() << " ()"; }
};
-
/// Holdout closure
///
/// This will be used by the shader to mark the
@@ -75,16 +68,26 @@ public:
HoldoutClosure () : ClosurePrimitive(Holdout) {}
void setup() {};
-
size_t memsize() const { return sizeof(*this); }
-
const char *name() const { return "holdout"; }
-
- void print_on(std::ostream &out) const {
- out << name() << " ()";
- }
+ void print_on(std::ostream &out) const { out << name() << " ()"; }
};
+/// ambient occlusion closure
+///
+/// We only have a ambient occlusion closure for the shaders
+/// to return a color in ambient occlusion shaders. No methods,
+/// only the weight is taking into account
+///
+class AmbientOcclusionClosure : public ClosurePrimitive {
+public:
+ AmbientOcclusionClosure () : ClosurePrimitive((ClosurePrimitive::Category)AmbientOcclusion) {}
+
+ void setup() {};
+ size_t memsize() const { return sizeof(*this); }
+ const char *name() const { return "ambient_occlusion"; }
+ void print_on(std::ostream &out) const { out << name() << " ()"; }
+};
ClosureParam *closure_background_params()
{
@@ -107,5 +110,16 @@ ClosureParam *closure_holdout_params()
CLOSURE_PREPARE(closure_holdout_prepare, HoldoutClosure)
+ClosureParam *closure_ambient_occlusion_params()
+{
+ static ClosureParam params[] = {
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(AmbientOcclusionClosure)
+ };
+ return params;
+}
+
+CLOSURE_PREPARE(closure_ambient_occlusion_prepare, AmbientOcclusionClosure)
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp b/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp
deleted file mode 100644
index a1904d7f5d7..00000000000
--- a/intern/cycles/kernel/osl/bsdf_ashikhmin_velvet.cpp
+++ /dev/null
@@ -1,190 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-#include "util_math.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-class AshikhminVelvetClosure : public BSDFClosure {
-public:
- Vec3 m_N;
- float m_sigma;
- float m_invsigma2;
-
- AshikhminVelvetClosure() : BSDFClosure(Labels::DIFFUSE) {}
-
- void setup()
- {
- m_sigma = max(m_sigma, 0.01f);
- m_invsigma2 = 1.0f / (m_sigma * m_sigma);
- }
-
- bool mergeable(const ClosurePrimitive *other) const {
- const AshikhminVelvetClosure *comp = (const AshikhminVelvetClosure *)other;
- return m_N == comp->m_N && m_sigma == comp->m_sigma &&
- BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "ashikhmin_velvet"; }
-
- void print_on(std::ostream &out) const
- {
- out << name() << " (";
- out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
- out << m_sigma;
- out << ")";
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- float cosNO = m_N.dot(omega_out);
- float cosNI = m_N.dot(omega_in);
- if (cosNO > 0 && cosNI > 0) {
- Vec3 H = omega_in + omega_out;
- H.normalize();
-
- float cosNH = m_N.dot(H);
- float cosHO = fabsf(omega_out.dot(H));
-
- if(!(fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f))
- return Color3(0, 0, 0);
-
- float cosNHdivHO = cosNH / cosHO;
- cosNHdivHO = max(cosNHdivHO, 1e-5f);
-
- 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 D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4;
- float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically
-
- float out = 0.25f * (D * G) / cosNO;
-
- pdf = 0.5f * (float) M_1_PI;
- return Color3(out, out, out);
- }
- return Color3(0, 0, 0);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- // we are viewing the surface from above - send a ray out with uniform
- // distribution over the hemisphere
- sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf);
- if (Ng.dot(omega_in) > 0) {
- Vec3 H = omega_in + omega_out;
- H.normalize();
-
- float cosNI = m_N.dot(omega_in);
- float cosNO = m_N.dot(omega_out);
- float cosNH = m_N.dot(H);
- float cosHO = fabsf(omega_out.dot(H));
-
- if(fabsf(cosNO) > 1e-5f && fabsf(cosNH) < 1.0f-1e-5f && cosHO > 1e-5f) {
- float cosNHdivHO = cosNH / cosHO;
- cosNHdivHO = max(cosNHdivHO, 1e-5f);
-
- 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 D = expf(-cotangent2 * m_invsigma2) * m_invsigma2 * float(M_1_PI) / sinNH4;
- float G = min(1.0f, min(fac1, fac2)); // TODO: derive G from D analytically
-
- float power = 0.25f * (D * G) / cosNO;
-
- eval.setValue(power, power, power);
-
- // TODO: find a better approximation for the retroreflective bounce
- domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx;
- domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
- domega_in_dx *= 125;
- domega_in_dy *= 125;
- }
- else
- pdf = 0;
- }
- else
- pdf = 0;
- return Labels::REFLECT;
- }
-
-};
-
-
-
-ClosureParam *bsdf_ashikhmin_velvet_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, m_N),
- CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, m_sigma),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(AshikhminVelvetClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_ashikhmin_velvet_prepare, AshikhminVelvetClosure)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/bsdf_diffuse.cpp b/intern/cycles/kernel/osl/bsdf_diffuse.cpp
deleted file mode 100644
index 1e06d3b583f..00000000000
--- a/intern/cycles/kernel/osl/bsdf_diffuse.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-#include "util_math.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-class DiffuseClosure : public BSDFClosure {
-public:
- Vec3 m_N;
-
- DiffuseClosure() : BSDFClosure(Labels::DIFFUSE) {}
-
- void setup() {};
-
- bool mergeable(const ClosurePrimitive *other) const {
- const DiffuseClosure *comp = (const DiffuseClosure *)other;
- return m_N == comp->m_N && BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "diffuse"; }
-
- void print_on(std::ostream &out) const
- {
- out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))";
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- float cos_pi = max(m_N.dot(omega_in), 0.0f) * (float) M_1_PI;
- pdf = cos_pi;
- return Color3(cos_pi, cos_pi, cos_pi);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- // we are viewing the surface from the right side - send a ray out with cosine
- // distribution over the hemisphere
- sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf);
- if (Ng.dot(omega_in) > 0) {
- eval.setValue(pdf, pdf, pdf);
- // TODO: find a better approximation for the diffuse bounce
- domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx;
- domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
- domega_in_dx *= 125;
- domega_in_dy *= 125;
- }
- else
- pdf = 0;
- return Labels::REFLECT;
- }
-};
-
-
-
-class TranslucentClosure : public BSDFClosure {
-public:
- Vec3 m_N;
-
- TranslucentClosure() : BSDFClosure(Labels::DIFFUSE, Back) {}
-
- void setup() {};
-
- bool mergeable(const ClosurePrimitive *other) const {
- const TranslucentClosure *comp = (const TranslucentClosure *)other;
- return m_N == comp->m_N && BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "translucent"; }
-
- void print_on(std::ostream &out) const
- {
- out << name() << " ((" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))";
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- float cos_pi = max(-m_N.dot(omega_in), 0.0f) * (float) M_1_PI;
- pdf = cos_pi;
- return Color3(cos_pi, cos_pi, cos_pi);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- // we are viewing the surface from the right side - send a ray out with cosine
- // distribution over the hemisphere
- sample_cos_hemisphere(-m_N, omega_out, randu, randv, omega_in, pdf);
- if (Ng.dot(omega_in) < 0) {
- eval.setValue(pdf, pdf, pdf);
- // TODO: find a better approximation for the diffuse bounce
- domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx;
- domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
- domega_in_dx *= -125;
- domega_in_dy *= -125;
- }
- else
- pdf = 0;
- return Labels::TRANSMIT;
- }
-};
-
-ClosureParam *bsdf_diffuse_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(DiffuseClosure, m_N),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(DiffuseClosure)
- };
- return params;
-}
-
-ClosureParam *bsdf_translucent_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(TranslucentClosure, m_N),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(TranslucentClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_diffuse_prepare, DiffuseClosure)
-CLOSURE_PREPARE(bsdf_translucent_prepare, TranslucentClosure)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/bsdf_microfacet.cpp b/intern/cycles/kernel/osl/bsdf_microfacet.cpp
deleted file mode 100644
index 8446dbbe982..00000000000
--- a/intern/cycles/kernel/osl/bsdf_microfacet.cpp
+++ /dev/null
@@ -1,558 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-#include "util_math.h"
-
-using namespace OSL;
-
-CCL_NAMESPACE_BEGIN
-
-// TODO: fresnel_dielectric is only used for derivatives, could be optimized
-
-// TODO: refactor these two classes so they share everything by the microfacet
-// distribution terms
-
-// microfacet model with GGX facet distribution
-// see http://www.graphics.cornell.edu/~bjw/microfacetbsdf.pdf
-template <int Refractive = 0>
-class MicrofacetGGXClosure : public BSDFClosure {
-public:
- Vec3 m_N;
- float m_ag; // width parameter (roughness)
- float m_eta; // index of refraction (for fresnel term)
- MicrofacetGGXClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) { m_eta = 1.0f; }
-
- void setup()
- {
- m_ag = clamp(m_ag, 1e-5f, 1.0f);
- }
-
- bool mergeable(const ClosurePrimitive *other) const {
- const MicrofacetGGXClosure *comp = (const MicrofacetGGXClosure *)other;
- return m_N == comp->m_N && m_ag == comp->m_ag &&
- m_eta == comp->m_eta && BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const {
- return Refractive ? "microfacet_ggx_refraction" : "microfacet_ggx";
- }
-
- void print_on(std::ostream &out) const {
- out << name() << " (";
- out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
- out << m_ag << ", ";
- out << m_eta;
- out << ")";
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- if (Refractive == 1) return Color3(0, 0, 0);
- float cosNO = m_N.dot(omega_out);
- float cosNI = m_N.dot(omega_in);
- if (cosNI > 0 && cosNO > 0) {
- // get half vector
- Vec3 Hr = omega_in + omega_out;
- Hr.normalize();
- // eq. 20: (F*G*D)/(4*in*on)
- // eq. 33: first we calculate D(m) with m=Hr:
- float alpha2 = m_ag * m_ag;
- float cosThetaM = m_N.dot(Hr);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- // eq. 34: now calculate G1(i,m) and G1(o,m)
- float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G = G1o * G1i;
- float out = (G * D) * 0.25f / cosNO;
- // eq. 24
- float pm = D * cosThetaM;
- // convert into pdf of the sampled direction
- // eq. 38 - but see also:
- // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- pdf = pm * 0.25f / Hr.dot(omega_out);
- return Color3(out, out, out);
- }
- return Color3(0, 0, 0);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- if (Refractive == 0) return Color3(0, 0, 0);
- float cosNO = m_N.dot(omega_out);
- float cosNI = m_N.dot(omega_in);
- if (cosNO <= 0 || cosNI >= 0)
- return Color3(0, 0, 0); // vectors on same side -- not possible
- // compute half-vector of the refraction (eq. 16)
- Vec3 ht = -(m_eta * omega_in + omega_out);
- Vec3 Ht = ht; Ht.normalize();
- float cosHO = Ht.dot(omega_out);
-
- float cosHI = Ht.dot(omega_in);
- // eq. 33: first we calculate D(m) with m=Ht:
- float alpha2 = m_ag * m_ag;
- float cosThetaM = m_N.dot(Ht);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = alpha2 / ((float) M_PI * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- // eq. 34: now calculate G1(i,m) and G1(o,m)
- float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G = G1o * G1i;
- // probability
- float invHt2 = 1 / ht.dot(ht);
- pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2;
- float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO;
- return Color3(out, out, out);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- float cosNO = m_N.dot(omega_out);
- if (cosNO > 0) {
- Vec3 X, Y, Z = m_N;
- make_orthonormals(Z, X, Y);
- // generate a random microfacet normal m
- // eq. 35,36:
- // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
- // and sin(atan(x)) == x/sqrt(1+x^2)
- float alpha2 = m_ag * m_ag;
- float tanThetaM2 = alpha2 * randu / (1 - randu);
- float cosThetaM = 1 / sqrtf(1 + tanThetaM2);
- float sinThetaM = cosThetaM * sqrtf(tanThetaM2);
- float phiM = 2 * float(M_PI) * randv;
- Vec3 m = (cosf(phiM) * sinThetaM) * X +
- (sinf(phiM) * sinThetaM) * Y +
- cosThetaM * Z;
- if (Refractive == 0) {
- float cosMO = m.dot(omega_out);
- if (cosMO > 0) {
- // eq. 39 - compute actual reflected direction
- omega_in = 2 * cosMO * m - omega_out;
- if (Ng.dot(omega_in) > 0) {
- // microfacet normal is visible to this ray
- // eq. 33
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- // eq. 24
- float pm = D * cosThetaM;
- // convert into pdf of the sampled direction
- // eq. 38 - but see also:
- // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- pdf = pm * 0.25f / cosMO;
- // eval BRDF*cosNI
- float cosNI = m_N.dot(omega_in);
- // eq. 34: now calculate G1(i,m) and G1(o,m)
- float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G = G1o * G1i;
- // eq. 20: (F*G*D)/(4*in*on)
- float out = (G * D) * 0.25f / cosNO;
- eval.setValue(out, out, out);
- domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx;
- domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy;
-
- /* disabled for now - gives texture filtering problems */
-#if 0
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- domega_in_dx *= 10;
- domega_in_dy *= 10;
-#endif
- }
- }
- }
- else {
- // CAUTION: the i and o variables are inverted relative to the paper
- // eq. 39 - compute actual refractive direction
- Vec3 R, dRdx, dRdy;
- Vec3 T, dTdx, dTdy;
- bool inside;
- fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy,
- R, dRdx, dRdy,
- T, dTdx, dTdy,
- inside);
-
- if (!inside) {
- omega_in = T;
- domega_in_dx = dTdx;
- domega_in_dy = dTdy;
- // eq. 33
- float cosThetaM2 = cosThetaM * cosThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = alpha2 / (float(M_PI) * cosThetaM4 * (alpha2 + tanThetaM2) * (alpha2 + tanThetaM2));
- // eq. 24
- float pm = D * cosThetaM;
- // eval BRDF*cosNI
- float cosNI = m_N.dot(omega_in);
- // eq. 34: now calculate G1(i,m) and G1(o,m)
- float G1o = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNO * cosNO) / (cosNO * cosNO)));
- float G1i = 2 / (1 + sqrtf(1 + alpha2 * (1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G = G1o * G1i;
- // eq. 21
- float cosHI = m.dot(omega_in);
- float cosHO = m.dot(omega_out);
- float Ht2 = m_eta * cosHI + cosHO;
- Ht2 *= Ht2;
- float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
- // eq. 38 and eq. 17
- pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
- eval.setValue(out, out, out);
-
- /* disabled for now - gives texture filtering problems */
-#if 0
- // Since there is some blur to this refraction, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- domega_in_dx *= 10;
- domega_in_dy *= 10;
-#endif
- }
- }
- }
- return Refractive ? Labels::TRANSMIT : Labels::REFLECT;
- }
-};
-
-// microfacet model with Beckmann facet distribution
-// see http://www.graphics.cornell.edu/~bjw/microfacetbsdf.pdf
-template <int Refractive = 0>
-class MicrofacetBeckmannClosure : public BSDFClosure {
-public:
- Vec3 m_N;
- float m_ab; // width parameter (roughness)
- float m_eta; // index of refraction (for fresnel term)
- MicrofacetBeckmannClosure() : BSDFClosure(Labels::GLOSSY, Refractive ? Back : Front) {
- }
-
- void setup()
- {
- m_ab = clamp(m_ab, 1e-5f, 1.0f);
- }
-
- bool mergeable(const ClosurePrimitive *other) const {
- const MicrofacetBeckmannClosure *comp = (const MicrofacetBeckmannClosure *)other;
- return m_N == comp->m_N && m_ab == comp->m_ab &&
- m_eta == comp->m_eta && BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const {
- return sizeof(*this);
- }
-
- const char *name() const {
- return Refractive ? "microfacet_beckmann_refraction"
- : "microfacet_beckmann";
- }
-
- void print_on(std::ostream &out) const
- {
- out << name() << " (";
- out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
- out << m_ab << ", ";
- out << m_eta;
- out << ")";
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- if (Refractive == 1) return Color3(0, 0, 0);
- float cosNO = m_N.dot(omega_out);
- float cosNI = m_N.dot(omega_in);
- if (cosNO > 0 && cosNI > 0) {
- // get half vector
- Vec3 Hr = omega_in + omega_out;
- Hr.normalize();
- // eq. 20: (F*G*D)/(4*in*on)
- // eq. 25: first we calculate D(m) with m=Hr:
- float alpha2 = m_ab * m_ab;
- float cosThetaM = m_N.dot(Hr);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4);
- // eq. 26, 27: now calculate G1(i,m) and G1(o,m)
- float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
- float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
- float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
- float G = G1o * G1i;
- float out = (G * D) * 0.25f / cosNO;
- // eq. 24
- float pm = D * cosThetaM;
- // convert into pdf of the sampled direction
- // eq. 38 - but see also:
- // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- pdf = pm * 0.25f / Hr.dot(omega_out);
- return Color3(out, out, out);
- }
- return Color3(0, 0, 0);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- if (Refractive == 0) return Color3(0, 0, 0);
- float cosNO = m_N.dot(omega_out);
- float cosNI = m_N.dot(omega_in);
- if (cosNO <= 0 || cosNI >= 0)
- return Color3(0, 0, 0);
- // compute half-vector of the refraction (eq. 16)
- Vec3 ht = -(m_eta * omega_in + omega_out);
- Vec3 Ht = ht; Ht.normalize();
- float cosHO = Ht.dot(omega_out);
-
- float cosHI = Ht.dot(omega_in);
- // eq. 33: first we calculate D(m) with m=Ht:
- float alpha2 = m_ab * m_ab;
- float cosThetaM = m_N.dot(Ht);
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = (1 - cosThetaM2) / cosThetaM2;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4);
- // eq. 26, 27: now calculate G1(i,m) and G1(o,m)
- float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
- float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
- float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
- float G = G1o * G1i;
- // probability
- float invHt2 = 1 / ht.dot(ht);
- pdf = D * fabsf(cosThetaM) * (fabsf(cosHI) * (m_eta * m_eta)) * invHt2;
- float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D) * invHt2) / cosNO;
- return Color3(out, out, out);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- float cosNO = m_N.dot(omega_out);
- if (cosNO > 0) {
- Vec3 X, Y, Z = m_N;
- make_orthonormals(Z, X, Y);
- // generate a random microfacet normal m
- // eq. 35,36:
- // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
- // and sin(atan(x)) == x/sqrt(1+x^2)
- float alpha2 = m_ab * m_ab;
- float tanThetaM = sqrtf(-alpha2 * logf(1 - randu));
- float cosThetaM = 1 / sqrtf(1 + tanThetaM * tanThetaM);
- float sinThetaM = cosThetaM * tanThetaM;
- float phiM = 2 * float(M_PI) * randv;
- Vec3 m = (cosf(phiM) * sinThetaM) * X +
- (sinf(phiM) * sinThetaM) * Y +
- cosThetaM * Z;
- if (Refractive == 0) {
- float cosMO = m.dot(omega_out);
- if (cosMO > 0) {
- // eq. 39 - compute actual reflected direction
- omega_in = 2 * cosMO * m - omega_out;
- if (Ng.dot(omega_in) > 0) {
- // microfacet normal is visible to this ray
- // eq. 25
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = tanThetaM * tanThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4);
- // eq. 24
- float pm = D * cosThetaM;
- // convert into pdf of the sampled direction
- // eq. 38 - but see also:
- // eq. 17 in http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
- pdf = pm * 0.25f / cosMO;
- // Eval BRDF*cosNI
- float cosNI = m_N.dot(omega_in);
- // eq. 26, 27: now calculate G1(i,m) and G1(o,m)
- float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
- float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
- float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
- float G = G1o * G1i;
- // eq. 20: (F*G*D)/(4*in*on)
- float out = (G * D) * 0.25f / cosNO;
- eval.setValue(out, out, out);
- domega_in_dx = (2 * m.dot(domega_out_dx)) * m - domega_out_dx;
- domega_in_dy = (2 * m.dot(domega_out_dy)) * m - domega_out_dy;
-
- /* disabled for now - gives texture filtering problems */
-#if 0
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- domega_in_dx *= 10;
- domega_in_dy *= 10;
-#endif
- }
- }
- }
- else {
- // CAUTION: the i and o variables are inverted relative to the paper
- // eq. 39 - compute actual refractive direction
- Vec3 R, dRdx, dRdy;
- Vec3 T, dTdx, dTdy;
- bool inside;
- fresnel_dielectric(m_eta, m, omega_out, domega_out_dx, domega_out_dy,
- R, dRdx, dRdy,
- T, dTdx, dTdy,
- inside);
- if (!inside) {
- omega_in = T;
- domega_in_dx = dTdx;
- domega_in_dy = dTdy;
- // eq. 33
- float cosThetaM2 = cosThetaM * cosThetaM;
- float tanThetaM2 = tanThetaM * tanThetaM;
- float cosThetaM4 = cosThetaM2 * cosThetaM2;
- float D = expf(-tanThetaM2 / alpha2) / (float(M_PI) * alpha2 * cosThetaM4);
- // eq. 24
- float pm = D * cosThetaM;
- // eval BRDF*cosNI
- float cosNI = m_N.dot(omega_in);
- // eq. 26, 27: now calculate G1(i,m) and G1(o,m)
- float ao = 1 / (m_ab * sqrtf((1 - cosNO * cosNO) / (cosNO * cosNO)));
- float ai = 1 / (m_ab * sqrtf((1 - cosNI * cosNI) / (cosNI * cosNI)));
- float G1o = ao < 1.6f ? (3.535f * ao + 2.181f * ao * ao) / (1 + 2.276f * ao + 2.577f * ao * ao) : 1.0f;
- float G1i = ai < 1.6f ? (3.535f * ai + 2.181f * ai * ai) / (1 + 2.276f * ai + 2.577f * ai * ai) : 1.0f;
- float G = G1o * G1i;
- // eq. 21
- float cosHI = m.dot(omega_in);
- float cosHO = m.dot(omega_out);
- float Ht2 = m_eta * cosHI + cosHO;
- Ht2 *= Ht2;
- float out = (fabsf(cosHI * cosHO) * (m_eta * m_eta) * (G * D)) / (cosNO * Ht2);
- // eq. 38 and eq. 17
- pdf = pm * (m_eta * m_eta) * fabsf(cosHI) / Ht2;
- eval.setValue(out, out, out);
-
- /* disabled for now - gives texture filtering problems */
-#if 0
- // Since there is some blur to this refraction, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- domega_in_dx *= 10;
- domega_in_dy *= 10;
-#endif
- }
- }
- }
- return Refractive ? Labels::TRANSMIT : Labels::REFLECT;
- }
-};
-
-
-
-ClosureParam *bsdf_microfacet_ggx_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<0>, m_N),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<0>, m_ag),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<0>)
- };
- return params;
-}
-
-ClosureParam *bsdf_microfacet_ggx_refraction_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure<1>, m_N),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_ag),
- CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure<1>, m_eta),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(MicrofacetGGXClosure<1>)
- };
- return params;
-}
-
-ClosureParam *bsdf_microfacet_beckmann_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<0>, m_N),
- CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<0>, m_ab),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<0>)
- };
- return params;
-}
-
-ClosureParam *bsdf_microfacet_beckmann_refraction_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure<1>, m_N),
- CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_ab),
- CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure<1>, m_eta),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(MicrofacetBeckmannClosure<1>)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_microfacet_ggx_prepare, MicrofacetGGXClosure<0>)
-CLOSURE_PREPARE(bsdf_microfacet_ggx_refraction_prepare, MicrofacetGGXClosure<1>)
-CLOSURE_PREPARE(bsdf_microfacet_beckmann_prepare, MicrofacetBeckmannClosure<0>)
-CLOSURE_PREPARE(bsdf_microfacet_beckmann_refraction_prepare, MicrofacetBeckmannClosure<1>)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp b/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp
deleted file mode 100644
index 2a00100c256..00000000000
--- a/intern/cycles/kernel/osl/bsdf_oren_nayar.cpp
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include <OpenImageIO/fmath.h>
-#include <OSL/genclosure.h>
-#include "osl_closures.h"
-#include "util_math.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-
-class OrenNayarClosure : public BSDFClosure {
-public:
- Vec3 m_N;
- float m_sigma;
- float m_a, m_b;
-
- OrenNayarClosure() : BSDFClosure(Labels::DIFFUSE) {}
-
- void setup() {
- m_sigma = clamp(m_sigma, 0.0f, 1.0f);
-
- float div = 1.0f / (M_PI + ((3.0f * M_PI - 4.0f) / 6.0f) * m_sigma);
-
- m_a = 1.0f * div;
- m_b = m_sigma * div;
- }
-
- bool mergeable(const ClosurePrimitive *other) const {
- const OrenNayarClosure *comp = static_cast<const OrenNayarClosure *>(other);
- return
- m_N == comp->m_N &&
- m_sigma == comp->m_sigma &&
- BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const {
- return sizeof(*this);
- }
-
- const char *name() const {
- return "oren_nayar";
- }
-
- void print_on(std::ostream& out) const {
- out << name() << " (";
- out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
- out << m_sigma;
- out << ")";
- }
-
- float albedo(const Vec3& omega_out) const {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3& omega_out, const Vec3& omega_in, float& pdf) const {
- if (m_N.dot(omega_in) > 0.0f) {
- pdf = float(0.5 * M_1_PI);
- float is = get_intensity(m_N, omega_out, omega_in);
- return Color3(is, is, is);
- }
- else {
- pdf = 0.0f;
- return Color3(0.0f, 0.0f, 0.0f);
- }
- }
-
- Color3 eval_transmit(const Vec3& omega_out, const Vec3& omega_in, float& pdf) const {
- return Color3(0.0f, 0.0f, 0.0f);
- }
-
- ustring sample(
- const Vec3& Ng,
- const Vec3& omega_out, const Vec3& domega_out_dx, const Vec3& domega_out_dy,
- float randu, float randv,
- Vec3& omega_in, Vec3& domega_in_dx, Vec3& domega_in_dy,
- float& pdf, Color3& eval
- ) const {
- sample_uniform_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf);
-
- if (Ng.dot(omega_in) > 0.0f) {
- float is = get_intensity(m_N, omega_out, omega_in);
- eval.setValue(is, is, is);
-
- // TODO: find a better approximation for the bounce
- domega_in_dx = (2.0f * m_N.dot(domega_out_dx)) * m_N - domega_out_dx;
- domega_in_dy = (2.0f * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
- domega_in_dx *= 125.0f;
- domega_in_dy *= 125.0f;
- }
- else {
- pdf = 0.0f;
- }
-
- return Labels::REFLECT;
- }
-
-private:
- float get_intensity(Vec3 const& n, Vec3 const& v, Vec3 const& l) const {
- float nl = max(n.dot(l), 0.0f);
- float nv = max(n.dot(v), 0.0f);
- float t = l.dot(v) - nl * nv;
-
- if (t > 0.0f) {
- t /= max(nl, nv) + 1e-8f;
- }
- return nl * (m_a + m_b * t);
- }
-};
-
-ClosureParam *bsdf_oren_nayar_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(OrenNayarClosure, m_N),
- CLOSURE_FLOAT_PARAM(OrenNayarClosure, m_sigma),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(OrenNayarClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_oren_nayar_prepare, OrenNayarClosure)
-
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/bsdf_phong.cpp b/intern/cycles/kernel/osl/bsdf_phong.cpp
deleted file mode 100644
index 1f430cc6f5d..00000000000
--- a/intern/cycles/kernel/osl/bsdf_phong.cpp
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2012, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-#include "osl_closures.h"
-#include "util_math.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-// vanilla phong - leaks energy at grazing angles
-// see Global Illumination Compendium entry (66)
-class PhongClosure : public BSDFClosure {
-public:
- Vec3 m_N;
- float m_exponent;
- PhongClosure() : BSDFClosure(Labels::GLOSSY) { }
-
- void setup() {};
-
- bool mergeable (const ClosurePrimitive *other) const {
- const PhongClosure *comp = (const PhongClosure *)other;
- return m_N == comp->m_N && m_exponent == comp->m_exponent &&
- BSDFClosure::mergeable(other);
- }
-
- size_t memsize () const { return sizeof(*this); }
-
- const char *name () const { return "phong"; }
-
- void print_on (std::ostream &out) const {
- out << name() << " ((";
- out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
- out << m_exponent << ")";
- }
-
- float albedo (const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- float cosNI = m_N.dot(omega_in);
- float cosNO = m_N.dot(omega_out);
- if (cosNI > 0 && cosNO > 0) {
- // reflect the view vector
- Vec3 R = (2 * cosNO) * m_N - omega_out;
- float cosRI = R.dot(omega_in);
- if (cosRI > 0) {
- float common = 0.5f * (float) M_1_PI * powf(cosRI, m_exponent);
- float out = cosNI * (m_exponent + 2) * common;
- pdf = (m_exponent + 1) * common;
- return Color3 (out, out, out);
- }
- }
- return Color3 (0, 0, 0);
- }
-
- Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3 (0, 0, 0);
- }
-
- ustring sample (const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- float cosNO = m_N.dot(omega_out);
- if (cosNO > 0) {
- // reflect the view vector
- Vec3 R = (2 * cosNO) * m_N - omega_out;
- domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx;
- domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
- Vec3 T, B;
- make_orthonormals (R, T, B);
- float phi = 2 * (float) M_PI * 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 (Ng.dot(omega_in) > 0)
- {
- // common terms for pdf and eval
- float cosNI = m_N.dot(omega_in);
- // make sure the direction we chose is still in the right hemisphere
- if (cosNI > 0)
- {
- float common = 0.5f * (float) M_1_PI * powf(cosTheta, m_exponent);
- pdf = (m_exponent + 1) * common;
- float out = cosNI * (m_exponent + 2) * common;
- eval.setValue(out, out, out);
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // exponent but the exact relationship is complex and
- // requires more ops than are practical.
- domega_in_dx *= 10;
- domega_in_dy *= 10;
- }
- }
- }
- return Labels::REFLECT;
- }
-};
-
-
-class PhongRampClosure : public BSDFClosure {
-public:
- static const int MAXCOLORS = 8;
- Vec3 m_N;
- float m_exponent;
- Color3 m_colors[MAXCOLORS];
- PhongRampClosure() : BSDFClosure(Labels::GLOSSY) { }
-
- void setup() {};
-
- bool mergeable (const ClosurePrimitive *other) const {
- const PhongRampClosure *comp = (const PhongRampClosure *)other;
- if (! (m_N == comp->m_N && m_exponent == comp->m_exponent &&
- BSDFClosure::mergeable(other)))
- return false;
- for (int i = 0; i < MAXCOLORS; ++i)
- if (m_colors[i] != comp->m_colors[i])
- return false;
- return true;
- }
-
- size_t memsize () const { return sizeof(*this); }
-
- const char *name () const { return "phong_ramp"; }
-
- void print_on (std::ostream &out) const {
- out << name() << " ((";
- out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
- out << m_exponent << ")";
- }
-
- Color3 get_color (float pos) const
- {
- float npos = pos * (float)(MAXCOLORS - 1);
- int ipos = (int)npos;
- if (ipos >= (MAXCOLORS - 1))
- return m_colors[MAXCOLORS - 1];
- float offset = npos - (float)ipos;
- return m_colors[ipos] * (1.0f - offset) + m_colors[ipos+1] * offset;
- }
-
- float albedo (const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- float cosNI = m_N.dot(omega_in);
- float cosNO = m_N.dot(omega_out);
- if (cosNI > 0 && cosNO > 0) {
- // reflect the view vector
- Vec3 R = (2 * cosNO) * m_N - omega_out;
- float cosRI = R.dot(omega_in);
- if (cosRI > 0) {
- float cosp = powf(cosRI, m_exponent);
- float common = 0.5f * (float) M_1_PI * cosp;
- float out = cosNI * (m_exponent + 2) * common;
- pdf = (m_exponent + 1) * common;
- return get_color(cosp) * out;
- }
- }
- return Color3 (0, 0, 0);
- }
-
- Color3 eval_transmit (const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3 (0, 0, 0);
- }
-
- ustring sample (const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- float cosNO = m_N.dot(omega_out);
- if (cosNO > 0) {
- // reflect the view vector
- Vec3 R = (2 * cosNO) * m_N - omega_out;
- domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx;
- domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
- Vec3 T, B;
- make_orthonormals (R, T, B);
- float phi = 2 * (float) M_PI * 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 (Ng.dot(omega_in) > 0)
- {
- // common terms for pdf and eval
- float cosNI = m_N.dot(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 * (float) M_1_PI * cosp;
- pdf = (m_exponent + 1) * common;
- float out = cosNI * (m_exponent + 2) * common;
- eval = get_color(cosp) * out;
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // exponent but the exact relationship is complex and
- // requires more ops than are practical.
- domega_in_dx *= 10;
- domega_in_dy *= 10;
- }
- }
- }
- return Labels::REFLECT;
- }
-};
-
-
-
-ClosureParam *bsdf_phong_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(PhongClosure, m_N),
- CLOSURE_FLOAT_PARAM (PhongClosure, m_exponent),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(PhongClosure)
- };
- return params;
-}
-
-ClosureParam *bsdf_phong_ramp_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM (PhongRampClosure, m_N),
- CLOSURE_FLOAT_PARAM (PhongRampClosure, m_exponent),
- CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, m_colors, PhongRampClosure::MAXCOLORS),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM (PhongRampClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_phong_prepare, PhongClosure)
-CLOSURE_PREPARE(bsdf_phong_ramp_prepare, PhongRampClosure)
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/bssrdf.cpp b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
index 889e8a54796..fb144be7e50 100644
--- a/intern/cycles/kernel/osl/bssrdf.cpp
+++ b/intern/cycles/kernel/osl/bsdf_phong_ramp.cpp
@@ -36,75 +36,80 @@
#include "osl_closures.h"
+#include "kernel_types.h"
+#include "closure/bsdf_phong_ramp.h"
+
CCL_NAMESPACE_BEGIN
using namespace OSL;
-class BSSRDFCubicClosure : public BSSRDFClosure {
+class PhongRampClosure : public CBSDFClosure {
public:
- Color3 m_radius;
- Color3 m_scale;
- float m_max_radius;
-
- template <typename T>
- static inline T pow3(const T &x) { return x * x * x; }
+ PhongRampClosure() : CBSDFClosure(LABEL_GLOSSY) {}
+ Color3 colors[8];
+ float3 fcolors[8];
- template <typename T>
- static inline T pow5(const T &x) { T x2 = x * x; return x2 * x2 * x; }
-
- BSSRDFCubicClosure() {}
+ size_t memsize() const { return sizeof(*this); }
+ const char *name() const { return "phong_ramp"; }
void setup()
{
- // pre-compute some terms
- m_max_radius = 0;
- for (int i = 0; i < 3; i++) {
- m_scale[i] = m_radius[i] > 0 ? 4 / pow5(m_radius[i]) : 0;
- m_max_radius = std::max(m_max_radius, m_radius[i]);
- }
- }
+ sc.N = TO_FLOAT3(N);
+ m_shaderdata_flag = bsdf_phong_ramp_setup(&sc);
- bool mergeable(const ClosurePrimitive *other) const {
- const BSSRDFCubicClosure *comp = (const BSSRDFCubicClosure *)other;
- return m_radius == comp->m_radius && BSSRDFClosure::mergeable(other);
+ for(int i = 0; i < 8; i++)
+ fcolors[i] = TO_FLOAT3(colors[i]);
}
- size_t memsize() const { return sizeof(*this); }
+ bool mergeable(const ClosurePrimitive *other) const
+ {
+ return false;
+ }
- const char *name() const { return "bssrdf_cubic"; }
+ void blur(float roughness)
+ {
+ bsdf_phong_ramp_blur(&sc, roughness);
+ }
void print_on(std::ostream &out) const
{
- out << name() << " ((" << m_radius[0] << ", " << m_radius[1] << ", " << m_radius[2] << "), ("
- << m_scale[0] << ", " << m_scale[1] << ", " << m_scale[2] << "))";
+ out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))";
}
- Color3 eval(float r) const
+ float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const
{
- return Color3((r < m_radius.x) ? pow3(m_radius.x - r) * m_scale.x : 0,
- (r < m_radius.y) ? pow3(m_radius.y - r) * m_scale.y : 0,
- (r < m_radius.z) ? pow3(m_radius.z - r) * m_scale.z : 0);
+ return bsdf_phong_ramp_eval_reflect(&sc, fcolors, omega_out, omega_in, &pdf);
}
- float max_radius() const
+ float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const
{
- return m_max_radius;
+ return bsdf_phong_ramp_eval_transmit(&sc, fcolors, omega_out, omega_in, &pdf);
}
-};
-
+ int sample(const float3 &Ng,
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ float randu, float randv,
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
+ float &pdf, float3 &eval) const
+ {
+ return bsdf_phong_ramp_sample(&sc, fcolors, Ng, omega_out, domega_out_dx, domega_out_dy,
+ randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf);
+ }
+};
-ClosureParam *closure_bssrdf_cubic_params()
+ClosureParam *closure_bsdf_phong_ramp_params()
{
static ClosureParam params[] = {
- CLOSURE_COLOR_PARAM(BSSRDFCubicClosure, m_radius),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(BSSRDFCubicClosure)
+ CLOSURE_VECTOR_PARAM(PhongRampClosure, N),
+ CLOSURE_FLOAT_PARAM(PhongRampClosure, sc.data0),
+ CLOSURE_COLOR_ARRAY_PARAM(PhongRampClosure, colors, 8),
+ CLOSURE_STRING_KEYPARAM("label"),
+ CLOSURE_FINISH_PARAM(PhongRampClosure)
};
return params;
}
-CLOSURE_PREPARE(closure_bssrdf_cubic_prepare, BSSRDFCubicClosure)
+CLOSURE_PREPARE(closure_bsdf_phong_ramp_prepare, PhongRampClosure)
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/bsdf_reflection.cpp b/intern/cycles/kernel/osl/bsdf_reflection.cpp
deleted file mode 100644
index 1b85ec146d3..00000000000
--- a/intern/cycles/kernel/osl/bsdf_reflection.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-class ReflectionClosure : public BSDFClosure {
-public:
- Vec3 m_N; // shading normal
- ReflectionClosure() : BSDFClosure(Labels::SINGULAR) {}
-
- void setup() {};
-
- bool mergeable(const ClosurePrimitive *other) const {
- const ReflectionClosure *comp = (const ReflectionClosure *)other;
- return m_N == comp->m_N && BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "reflection"; }
-
- void print_on(std::ostream &out) const {
- out << name() << " (";
- out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "))";
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- // only one direction is possible
- float cosNO = m_N.dot(omega_out);
- if (cosNO > 0) {
- omega_in = (2 * cosNO) * m_N - omega_out;
- if (Ng.dot(omega_in) > 0) {
- domega_in_dx = 2 * m_N.dot(domega_out_dx) * m_N - domega_out_dx;
- domega_in_dy = 2 * m_N.dot(domega_out_dy) * m_N - domega_out_dy;
- pdf = 1;
- eval.setValue(1, 1, 1);
- }
- }
- return Labels::REFLECT;
- }
-};
-
-ClosureParam *bsdf_reflection_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(ReflectionClosure, m_N),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(ReflectionClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_reflection_prepare, ReflectionClosure)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/bsdf_refraction.cpp b/intern/cycles/kernel/osl/bsdf_refraction.cpp
deleted file mode 100644
index 76ee53f7929..00000000000
--- a/intern/cycles/kernel/osl/bsdf_refraction.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-class RefractionClosure : public BSDFClosure {
-public:
- Vec3 m_N; // shading normal
- float m_eta; // ratio of indices of refraction (inside / outside)
- RefractionClosure() : BSDFClosure(Labels::SINGULAR, Back) {}
-
- void setup() {}
-
- bool mergeable(const ClosurePrimitive *other) const {
- const RefractionClosure *comp = (const RefractionClosure *)other;
- return m_N == comp->m_N && m_eta == comp->m_eta &&
- BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "refraction"; }
-
- void print_on(std::ostream &out) const {
- out << name() << " (";
- out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
- out << m_eta;
- out << ")";
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- Vec3 R, dRdx, dRdy;
- Vec3 T, dTdx, dTdy;
- bool inside;
-
- fresnel_dielectric(m_eta, m_N,
- omega_out, domega_out_dx, domega_out_dy,
- R, dRdx, dRdy,
- T, dTdx, dTdy,
- inside);
-
- if (!inside) {
- pdf = 1;
- eval.setValue(1.0f, 1.0f, 1.0f);
- omega_in = T;
- domega_in_dx = dTdx;
- domega_in_dy = dTdy;
- }
-
- return Labels::TRANSMIT;
- }
-};
-
-ClosureParam *bsdf_refraction_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(RefractionClosure, m_N),
- CLOSURE_FLOAT_PARAM(RefractionClosure, m_eta),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(RefractionClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_refraction_prepare, RefractionClosure)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/bsdf_transparent.cpp b/intern/cycles/kernel/osl/bsdf_transparent.cpp
deleted file mode 100644
index 29cef8e192f..00000000000
--- a/intern/cycles/kernel/osl/bsdf_transparent.cpp
+++ /dev/null
@@ -1,102 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-class TransparentClosure : public BSDFClosure {
-public:
- TransparentClosure() : BSDFClosure(Labels::STRAIGHT, Back) {}
-
- void setup() {}
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "transparent"; }
-
- void print_on(std::ostream &out) const {
- out << name() << " ()";
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- // only one direction is possible
- omega_in = -omega_out;
- domega_in_dx = -domega_out_dx;
- domega_in_dy = -domega_out_dy;
- pdf = 1;
- eval.setValue(1, 1, 1);
- return Labels::TRANSMIT;
- }
-};
-
-
-
-ClosureParam *bsdf_transparent_params()
-{
- static ClosureParam params[] = {
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(TransparentClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_transparent_prepare, TransparentClosure)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/bsdf_ward.cpp b/intern/cycles/kernel/osl/bsdf_ward.cpp
deleted file mode 100644
index 9d8d2fc4b76..00000000000
--- a/intern/cycles/kernel/osl/bsdf_ward.cpp
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-#include "util_math.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-// anisotropic ward - leaks energy at grazing angles
-// see http://www.graphics.cornell.edu/~bjw/wardnotes.pdf
-class WardClosure : public BSDFClosure {
-public:
- Vec3 m_N;
- Vec3 m_T;
- float m_ax, m_ay;
- WardClosure() : BSDFClosure(Labels::GLOSSY) {}
-
- void setup()
- {
- m_ax = clamp(m_ax, 1e-5f, 1.0f);
- m_ay = clamp(m_ay, 1e-5f, 1.0f);
- }
-
- bool mergeable(const ClosurePrimitive *other) const {
- const WardClosure *comp = (const WardClosure *)other;
- return m_N == comp->m_N && m_T == comp->m_T &&
- m_ax == comp->m_ax && m_ay == comp->m_ay &&
- BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "ward"; }
-
- void print_on(std::ostream &out) const {
- out << name() << " ((";
- out << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), (";
- out << m_T[0] << ", " << m_T[1] << ", " << m_T[2] << "), ";
- out << m_ax << ", " << m_ay << ")";
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- float cosNO = m_N.dot(omega_out);
- float cosNI = m_N.dot(omega_in);
- if (cosNI > 0 && cosNO > 0) {
- // get half vector and get x,y basis on the surface for anisotropy
- Vec3 H = omega_in + omega_out;
- H.normalize(); // normalize needed for pdf
- Vec3 X, Y;
- make_orthonormals(m_N, m_T, X, Y);
- // eq. 4
- float dotx = H.dot(X) / m_ax;
- float doty = H.dot(Y) / m_ay;
- float dotn = H.dot(m_N);
- float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
- float denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI));
- float exp_val = expf(-exp_arg);
- float out = cosNI * exp_val / denom;
- float oh = H.dot(omega_out);
- denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn;
- pdf = exp_val / denom;
- return Color3(out, out, out);
- }
- return Color3(0, 0, 0);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float& pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- float cosNO = m_N.dot(omega_out);
- if (cosNO > 0) {
- // get x,y basis on the surface for anisotropy
- Vec3 X, Y;
- make_orthonormals(m_N, m_T, X, Y);
- // generate random angles for the half vector
- // eq. 7 (taking care around discontinuities to keep
- // output angle in the right quadrant)
- // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
- // and sin(atan(x)) == x/sqrt(1+x^2)
- float alphaRatio = m_ay / m_ax;
- float cosPhi, sinPhi;
- if (randu < 0.25f) {
- float val = 4 * randu;
- float tanPhi = alphaRatio * tanf((float) M_PI_2 * val);
- cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi);
- sinPhi = tanPhi * cosPhi;
- }
- else if (randu < 0.5) {
- float val = 1 - 4 * (0.5f - randu);
- float tanPhi = alphaRatio * tanf((float) M_PI_2 * val);
- // phi = (float) M_PI - phi;
- cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi);
- sinPhi = -tanPhi * cosPhi;
- }
- else if (randu < 0.75f) {
- float val = 4 * (randu - 0.5f);
- float tanPhi = alphaRatio * tanf((float) M_PI_2 * val);
- //phi = (float) M_PI + phi;
- cosPhi = -1 / sqrtf(1 + tanPhi * tanPhi);
- sinPhi = tanPhi * cosPhi;
- }
- else {
- float val = 1 - 4 * (1 - randu);
- float tanPhi = alphaRatio * tanf((float) M_PI_2 * val);
- // phi = 2 * (float) M_PI - phi;
- cosPhi = 1 / sqrtf(1 + tanPhi * tanPhi);
- sinPhi = -tanPhi * cosPhi;
- }
- // eq. 6
- // we take advantage of cos(atan(x)) == 1/sqrt(1+x^2)
- // and sin(atan(x)) == x/sqrt(1+x^2)
- float thetaDenom = (cosPhi * cosPhi) / (m_ax * m_ax) + (sinPhi * sinPhi) / (m_ay * m_ay);
- float tanTheta2 = -logf(1 - randv) / thetaDenom;
- float cosTheta = 1 / sqrtf(1 + tanTheta2);
- float sinTheta = cosTheta * sqrtf(tanTheta2);
-
- Vec3 h; // already normalized becaused expressed from spherical coordinates
- h.x = sinTheta * cosPhi;
- h.y = sinTheta * sinPhi;
- h.z = cosTheta;
- // compute terms that are easier in local space
- float dotx = h.x / m_ax;
- float doty = h.y / m_ay;
- float dotn = h.z;
- // transform to world space
- h = h.x * X + h.y * Y + h.z * m_N;
- // generate the final sample
- float oh = h.dot(omega_out);
- omega_in.x = 2 * oh * h.x - omega_out.x;
- omega_in.y = 2 * oh * h.y - omega_out.y;
- omega_in.z = 2 * oh * h.z - omega_out.z;
- if (Ng.dot(omega_in) > 0) {
- float cosNI = m_N.dot(omega_in);
- if (cosNI > 0) {
- // eq. 9
- float exp_arg = (dotx * dotx + doty * doty) / (dotn * dotn);
- float denom = 4 * (float) M_PI * m_ax * m_ay * oh * dotn * dotn * dotn;
- pdf = expf(-exp_arg) / denom;
- // compiler will reuse expressions already computed
- denom = (4 * (float) M_PI * m_ax * m_ay * sqrtf(cosNO * cosNI));
- float power = cosNI * expf(-exp_arg) / denom;
- eval.setValue(power, power, power);
- domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx;
- domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
-
- /* disabled for now - gives texture filtering problems */
-#if 0
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // roughness but the exact relationship is complex and
- // requires more ops than are practical.
- domega_in_dx *= 10;
- domega_in_dy *= 10;
-#endif
- }
- }
- }
- return Labels::REFLECT;
- }
-};
-
-
-
-ClosureParam *bsdf_ward_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(WardClosure, m_N),
- CLOSURE_VECTOR_PARAM(WardClosure, m_T),
- CLOSURE_FLOAT_PARAM(WardClosure, m_ax),
- CLOSURE_FLOAT_PARAM(WardClosure, m_ay),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(WardClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_ward_prepare, WardClosure)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/bsdf_westin.cpp b/intern/cycles/kernel/osl/bsdf_westin.cpp
deleted file mode 100644
index 6716376ad3e..00000000000
--- a/intern/cycles/kernel/osl/bsdf_westin.cpp
+++ /dev/null
@@ -1,251 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-#include "util_math.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-class WestinBackscatterClosure : public BSDFClosure {
-public:
- Vec3 m_N;
- float m_roughness;
- float m_invroughness;
- WestinBackscatterClosure() : BSDFClosure(Labels::GLOSSY) {}
-
- void setup()
- {
- m_roughness = clamp(m_roughness, 1e-5f, 1.0f);
- m_invroughness = m_roughness > 0 ? 1 / m_roughness : 0;
- }
-
- bool mergeable(const ClosurePrimitive *other) const {
- const WestinBackscatterClosure *comp = (const WestinBackscatterClosure *)other;
- return m_N == comp->m_N && m_roughness == comp->m_roughness &&
- BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "westin_backscatter"; }
-
- void print_on(std::ostream &out) const
- {
- out << name() << " (";
- out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
- out << m_roughness;
- out << ")";
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const
- {
- // pdf is implicitly 0 (no indirect sampling)
- float cosNO = m_N.dot(omega_out);
- float cosNI = m_N.dot(omega_in);
- if (cosNO > 0 && cosNI > 0) {
- float cosine = omega_out.dot(omega_in);
- pdf = cosine > 0 ? (m_invroughness + 1) * powf(cosine, m_invroughness) : 0;
- pdf *= 0.5f * float(M_1_PI);
- return Color3(pdf, pdf, pdf);
- }
- return Color3(0, 0, 0);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- float cosNO = m_N.dot(omega_out);
- if (cosNO > 0) {
- domega_in_dx = domega_out_dx;
- domega_in_dy = domega_out_dy;
- Vec3 T, B;
- make_orthonormals(omega_out, T, B);
- float phi = 2 * (float) M_PI * randu;
- float cosTheta = powf(randv, 1 / (m_invroughness + 1));
- float sinTheta2 = 1 - cosTheta * cosTheta;
- float sinTheta = sinTheta2 > 0 ? sqrtf(sinTheta2) : 0;
- omega_in = (cosf(phi) * sinTheta) * T +
- (sinf(phi) * sinTheta) * B +
- (cosTheta) * omega_out;
- if (Ng.dot(omega_in) > 0)
- {
- // common terms for pdf and eval
- float cosNI = m_N.dot(omega_in);
- // make sure the direction we chose is still in the right hemisphere
- if (cosNI > 0)
- {
- pdf = 0.5f * (float) M_1_PI * powf(cosTheta, m_invroughness);
- pdf = (m_invroughness + 1) * pdf;
- eval.setValue(pdf, pdf, pdf);
- // Since there is some blur to this reflection, make the
- // derivatives a bit bigger. In theory this varies with the
- // exponent but the exact relationship is complex and
- // requires more ops than are practical.
- domega_in_dx *= 10;
- domega_in_dy *= 10;
- }
- }
- }
- return Labels::REFLECT;
- }
-
-};
-
-
-class WestinSheenClosure : public BSDFClosure {
-public:
- Vec3 m_N;
- float m_edginess;
-// float m_normalization;
- WestinSheenClosure() : BSDFClosure(Labels::DIFFUSE) {}
-
- void setup() {};
-
- bool mergeable(const ClosurePrimitive *other) const {
- const WestinSheenClosure *comp = (const WestinSheenClosure *)other;
- return m_N == comp->m_N && m_edginess == comp->m_edginess &&
- BSDFClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "westin_sheen"; }
-
- void print_on(std::ostream &out) const
- {
- out << name() << " (";
- out << "(" << m_N[0] << ", " << m_N[1] << ", " << m_N[2] << "), ";
- out << m_edginess;
- out << ")";
- }
-
- float albedo(const Vec3 &omega_out) const
- {
- return 1.0f;
- }
-
- Color3 eval_reflect(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const
- {
- // pdf is implicitly 0 (no indirect sampling)
- float cosNO = m_N.dot(omega_out);
- float cosNI = m_N.dot(omega_in);
- if (cosNO > 0 && cosNI > 0) {
- float sinNO2 = 1 - cosNO * cosNO;
- pdf = cosNI * float(M_1_PI);
- float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0;
- return Color3(westin, westin, westin);
- }
- return Color3(0, 0, 0);
- }
-
- Color3 eval_transmit(const Vec3 &omega_out, const Vec3 &omega_in, float &pdf) const
- {
- return Color3(0, 0, 0);
- }
-
- ustring sample(const Vec3 &Ng,
- const Vec3 &omega_out, const Vec3 &domega_out_dx, const Vec3 &domega_out_dy,
- float randu, float randv,
- Vec3 &omega_in, Vec3 &domega_in_dx, Vec3 &domega_in_dy,
- float &pdf, Color3 &eval) const
- {
- // we are viewing the surface from the right side - send a ray out with cosine
- // distribution over the hemisphere
- sample_cos_hemisphere(m_N, omega_out, randu, randv, omega_in, pdf);
- if (Ng.dot(omega_in) > 0) {
- // TODO: account for sheen when sampling
- float cosNO = m_N.dot(omega_out);
- float sinNO2 = 1 - cosNO * cosNO;
- float westin = sinNO2 > 0 ? powf(sinNO2, 0.5f * m_edginess) * pdf : 0;
- eval.setValue(westin, westin, westin);
- // TODO: find a better approximation for the diffuse bounce
- domega_in_dx = (2 * m_N.dot(domega_out_dx)) * m_N - domega_out_dx;
- domega_in_dy = (2 * m_N.dot(domega_out_dy)) * m_N - domega_out_dy;
- domega_in_dx *= 125;
- domega_in_dy *= 125;
- }
- else {
- pdf = 0;
- }
- return Labels::REFLECT;
- }
-};
-
-
-
-ClosureParam *bsdf_westin_backscatter_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, m_N),
- CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, m_roughness),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(WestinBackscatterClosure)
- };
- return params;
-}
-
-ClosureParam *bsdf_westin_sheen_params()
-{
- static ClosureParam params[] = {
- CLOSURE_VECTOR_PARAM(WestinSheenClosure, m_N),
- CLOSURE_FLOAT_PARAM(WestinSheenClosure, m_edginess),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(WestinSheenClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(bsdf_westin_backscatter_prepare, WestinBackscatterClosure)
-CLOSURE_PREPARE(bsdf_westin_sheen_prepare, WestinSheenClosure)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/debug.cpp b/intern/cycles/kernel/osl/debug.cpp
deleted file mode 100644
index ee5fb30371a..00000000000
--- a/intern/cycles/kernel/osl/debug.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-/// Debug closure
-///
-/// This is going to be used for mask AOV's and similar
-/// purposes. A tag (string) is always associated with
-/// this closure, that "selects: the channel where the
-/// weight should be sent.
-
-class DebugClosure : public ClosurePrimitive {
-public:
- ustring m_tag;
-
- DebugClosure () : ClosurePrimitive(Debug) {}
-
- bool mergeable(const ClosurePrimitive *other) const {
- const DebugClosure *comp = (const DebugClosure *)other;
- return m_tag == comp->m_tag &&
- ClosurePrimitive::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "debug"; }
-
- void print_on(std::ostream &out) const {
- out << name() << " (\"" << m_tag.c_str() << "\")";
- }
-
-};
-
-ClosureParam *closure_debug_params()
-{
- static ClosureParam params[] = {
- CLOSURE_STRING_PARAM(DebugClosure, m_tag),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(DebugClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(closure_debug_prepare, DebugClosure)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/emissive.cpp b/intern/cycles/kernel/osl/emissive.cpp
index 3ee57cbe6b6..37e3e37c00a 100644
--- a/intern/cycles/kernel/osl/emissive.cpp
+++ b/intern/cycles/kernel/osl/emissive.cpp
@@ -36,6 +36,9 @@
#include "osl_closures.h"
+#include "kernel_types.h"
+#include "closure/emissive.h"
+
CCL_NAMESPACE_BEGIN
using namespace OSL;
@@ -52,51 +55,34 @@ public:
GenericEmissiveClosure() { }
void setup() {}
-
size_t memsize() const { return sizeof(*this); }
-
const char *name() const { return "emission"; }
- void print_on(std::ostream &out) const {
+ void print_on(std::ostream &out) const
+ {
out << name() << "()";
}
Color3 eval(const Vec3 &Ng, const Vec3 &omega_out) const
{
- float cosNO = fabsf(Ng.dot(omega_out));
- float res = cosNO > 0 ? 1.0f : 0.0f;
- return Color3(res, res, res);
+ float3 result = emissive_eval(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
+ return TO_COLOR3(result);
}
void sample(const Vec3 &Ng, float randu, float randv,
Vec3 &omega_out, float &pdf) const
{
- // We don't do anything sophisticated here for the step
- // We just sample the whole cone uniformly to the cosine
- Vec3 T, B;
- make_orthonormals(Ng, T, B);
- float phi = 2 * (float) M_PI * randu;
- float cosTheta = sqrtf(1.0f - 1.0f * randv);
- float sinTheta = sqrtf(1.0f - cosTheta * cosTheta);
- omega_out = (cosf(phi) * sinTheta) * T +
- (sinf(phi) * sinTheta) * B +
- cosTheta * Ng;
- pdf = 1.0f / float(M_PI);
+ float3 omega_out_;
+ emissive_sample(TO_FLOAT3(Ng), randu, randv, &omega_out_, &pdf);
+ omega_out = TO_VEC3(omega_out_);
}
- /// Return the probability distribution function in the direction omega_out,
- /// given the parameters and the light's surface normal. This MUST match
- /// the PDF computed by sample().
- float pdf(const Vec3 &Ng,
- const Vec3 &omega_out) const
+ float pdf(const Vec3 &Ng, const Vec3 &omega_out) const
{
- float cosNO = Ng.dot(omega_out);
- return cosNO > 0 ? 1.0f : 0.0f;
+ return emissive_pdf(TO_FLOAT3(Ng), TO_FLOAT3(omega_out));
}
};
-
-
ClosureParam *closure_emission_params()
{
static ClosureParam params[] = {
diff --git a/intern/cycles/kernel/osl/nodes/node_object_info.osl b/intern/cycles/kernel/osl/nodes/node_object_info.osl
deleted file mode 100644
index 21e50d8a43e..00000000000
--- a/intern/cycles/kernel/osl/nodes/node_object_info.osl
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#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
- )
-{
- getattribute("std::object_location", Location);
- getattribute("std::object_index", ObjectIndex);
- getattribute("std::material_index", MaterialIndex);
- getattribute("std::object_random", Random);
-}
-
diff --git a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl b/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl
deleted file mode 100644
index 2bc10f31cb3..00000000000
--- a/intern/cycles/kernel/osl/nodes/node_rgb_ramp.osl
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2011, Blender Foundation.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
-
-#include "stdosl.h"
-#include "oslutil.h"
-
-shader node_rgb_ramp(
- color ramp_color[RAMP_TABLE_SIZE] = {0.0},
- float ramp_alpha[RAMP_TABLE_SIZE] = {0.0},
-
- float Fac = 0.0,
- output color Color = color(0.0, 0.0, 0.0),
- output float Alpha = 1.0
- )
-{
- float f = clamp(Fac, 0.0, 1.0)*(RAMP_TABLE_SIZE-1);
-
- int i = (int)f;
- float t = f - (float)i;
-
- Color = ramp_color[i];
- Alpha = ramp_alpha[i];
-
- if (t > 0.0) {
- Color = (1.0 - t)*Color + t*ramp_color[i+1];
- Alpha = (1.0 - t)*Alpha + t*ramp_alpha[i+1];
- }
-}
-
diff --git a/intern/cycles/kernel/osl/osl_closures.cpp b/intern/cycles/kernel/osl/osl_closures.cpp
index 9e99d4d2480..d42d65608c8 100644
--- a/intern/cycles/kernel/osl/osl_closures.cpp
+++ b/intern/cycles/kernel/osl/osl_closures.cpp
@@ -37,10 +37,101 @@
#include "osl_shader.h"
#include "util_debug.h"
+#include "util_math.h"
#include "util_param.h"
+#include "kernel_types.h"
+#include "kernel_montecarlo.h"
+
+#include "closure/bsdf.h"
+#include "closure/bsdf_ashikhmin_velvet.h"
+#include "closure/bsdf_diffuse.h"
+#include "closure/bsdf_microfacet.h"
+#include "closure/bsdf_oren_nayar.h"
+#include "closure/bsdf_phong_ramp.h"
+#include "closure/bsdf_reflection.h"
+#include "closure/bsdf_refraction.h"
+#include "closure/bsdf_transparent.h"
+#include "closure/bsdf_ward.h"
+#include "closure/bsdf_westin.h"
+
CCL_NAMESPACE_BEGIN
+using namespace OSL;
+
+/* BSDF class definitions */
+
+BSDF_CLOSURE_CLASS_BEGIN(Diffuse, diffuse, diffuse, LABEL_DIFFUSE)
+ CLOSURE_VECTOR_PARAM(DiffuseClosure, N),
+BSDF_CLOSURE_CLASS_END(Diffuse, diffuse)
+
+BSDF_CLOSURE_CLASS_BEGIN(Translucent, translucent, translucent, LABEL_DIFFUSE)
+ CLOSURE_VECTOR_PARAM(TranslucentClosure, N),
+BSDF_CLOSURE_CLASS_END(Translucent, translucent)
+
+BSDF_CLOSURE_CLASS_BEGIN(OrenNayar, oren_nayar, oren_nayar, LABEL_DIFFUSE)
+ CLOSURE_VECTOR_PARAM(OrenNayarClosure, N),
+ CLOSURE_FLOAT_PARAM(OrenNayarClosure, sc.data0),
+BSDF_CLOSURE_CLASS_END(OrenNayar, oren_nayar)
+
+BSDF_CLOSURE_CLASS_BEGIN(Reflection, reflection, reflection, LABEL_SINGULAR)
+ CLOSURE_VECTOR_PARAM(ReflectionClosure, N),
+BSDF_CLOSURE_CLASS_END(Reflection, reflection)
+
+BSDF_CLOSURE_CLASS_BEGIN(Refraction, refraction, refraction, LABEL_SINGULAR)
+ CLOSURE_VECTOR_PARAM(RefractionClosure, N),
+ CLOSURE_FLOAT_PARAM(RefractionClosure, sc.data0),
+BSDF_CLOSURE_CLASS_END(Refraction, refraction)
+
+BSDF_CLOSURE_CLASS_BEGIN(WestinBackscatter, westin_backscatter, westin_backscatter, LABEL_GLOSSY)
+ CLOSURE_VECTOR_PARAM(WestinBackscatterClosure, N),
+ CLOSURE_FLOAT_PARAM(WestinBackscatterClosure, sc.data0),
+BSDF_CLOSURE_CLASS_END(WestinBackscatter, westin_backscatter)
+
+BSDF_CLOSURE_CLASS_BEGIN(WestinSheen, westin_sheen, westin_sheen, LABEL_DIFFUSE)
+ CLOSURE_VECTOR_PARAM(WestinSheenClosure, N),
+ CLOSURE_FLOAT_PARAM(WestinSheenClosure, sc.data0),
+BSDF_CLOSURE_CLASS_END(WestinSheen, westin_sheen)
+
+BSDF_CLOSURE_CLASS_BEGIN(Transparent, transparent, transparent, LABEL_SINGULAR)
+BSDF_CLOSURE_CLASS_END(Transparent, transparent)
+
+BSDF_CLOSURE_CLASS_BEGIN(AshikhminVelvet, ashikhmin_velvet, ashikhmin_velvet, LABEL_DIFFUSE)
+ CLOSURE_VECTOR_PARAM(AshikhminVelvetClosure, N),
+ CLOSURE_FLOAT_PARAM(AshikhminVelvetClosure, sc.data0),
+BSDF_CLOSURE_CLASS_END(AshikhminVelvet, ashikhmin_velvet)
+
+BSDF_CLOSURE_CLASS_BEGIN(Ward, ward, ward, LABEL_GLOSSY)
+ CLOSURE_VECTOR_PARAM(WardClosure, N),
+ CLOSURE_VECTOR_PARAM(WardClosure, T),
+ CLOSURE_FLOAT_PARAM(WardClosure, sc.data0),
+ CLOSURE_FLOAT_PARAM(WardClosure, sc.data1),
+BSDF_CLOSURE_CLASS_END(Ward, ward)
+
+BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGX, microfacet_ggx, microfacet_ggx, LABEL_GLOSSY)
+ CLOSURE_VECTOR_PARAM(MicrofacetGGXClosure, N),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXClosure, sc.data0),
+BSDF_CLOSURE_CLASS_END(MicrofacetGGX, microfacet_ggx)
+
+BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmann, microfacet_beckmann, microfacet_beckmann, LABEL_GLOSSY)
+ CLOSURE_VECTOR_PARAM(MicrofacetBeckmannClosure, N),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannClosure, sc.data0),
+BSDF_CLOSURE_CLASS_END(MicrofacetBeckmann, microfacet_beckmann)
+
+BSDF_CLOSURE_CLASS_BEGIN(MicrofacetGGXRefraction, microfacet_ggx_refraction, microfacet_ggx, LABEL_GLOSSY)
+ CLOSURE_VECTOR_PARAM(MicrofacetGGXRefractionClosure, N),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data0),
+ CLOSURE_FLOAT_PARAM(MicrofacetGGXRefractionClosure, sc.data1),
+BSDF_CLOSURE_CLASS_END(MicrofacetGGXRefraction, microfacet_ggx_refraction)
+
+BSDF_CLOSURE_CLASS_BEGIN(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction, microfacet_beckmann, LABEL_GLOSSY)
+ CLOSURE_VECTOR_PARAM(MicrofacetBeckmannRefractionClosure, N),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data0),
+ CLOSURE_FLOAT_PARAM(MicrofacetBeckmannRefractionClosure, sc.data1),
+BSDF_CLOSURE_CLASS_END(MicrofacetBeckmannRefraction, microfacet_beckmann_refraction)
+
+/* Registration */
+
static void generic_closure_setup(OSL::RendererServices *, int id, void *data)
{
assert(data);
@@ -64,28 +155,46 @@ static void register_closure(OSL::ShadingSystem *ss, const char *name, int id, O
void OSLShader::register_closures(OSL::ShadingSystem *ss)
{
- register_closure(ss, "diffuse", OSL_CLOSURE_BSDF_DIFFUSE_ID, bsdf_diffuse_params(), bsdf_diffuse_prepare);
- register_closure(ss, "oren_nayar", OSL_CLOSURE_BSDF_OREN_NAYAR_ID, bsdf_oren_nayar_params(), bsdf_oren_nayar_prepare);
- register_closure(ss, "translucent", OSL_CLOSURE_BSDF_TRANSLUCENT_ID, bsdf_translucent_params(), bsdf_translucent_prepare);
- register_closure(ss, "reflection", OSL_CLOSURE_BSDF_REFLECTION_ID, bsdf_reflection_params(), bsdf_reflection_prepare);
- register_closure(ss, "refraction", OSL_CLOSURE_BSDF_REFRACTION_ID, bsdf_refraction_params(), bsdf_refraction_prepare);
- register_closure(ss, "transparent", OSL_CLOSURE_BSDF_TRANSPARENT_ID, bsdf_transparent_params(), bsdf_transparent_prepare);
- register_closure(ss, "microfacet_ggx", OSL_CLOSURE_BSDF_MICROFACET_GGX_ID, bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
- register_closure(ss, "microfacet_ggx_refraction", OSL_CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID, bsdf_microfacet_ggx_refraction_params(), bsdf_microfacet_ggx_refraction_prepare);
- register_closure(ss, "microfacet_beckmann", OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_ID, bsdf_microfacet_beckmann_params(), bsdf_microfacet_beckmann_prepare);
- register_closure(ss, "microfacet_beckmann_refraction", OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID, bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare);
- register_closure(ss, "ward", OSL_CLOSURE_BSDF_WARD_ID, bsdf_ward_params(), bsdf_ward_prepare);
- register_closure(ss, "phong", OSL_CLOSURE_BSDF_PHONG_ID, bsdf_phong_params(), bsdf_phong_prepare);
- register_closure(ss, "phong_ramp", OSL_CLOSURE_BSDF_PHONG_RAMP_ID, bsdf_phong_ramp_params(), bsdf_phong_ramp_prepare);
- register_closure(ss, "ashikhmin_velvet", OSL_CLOSURE_BSDF_ASHIKHMIN_VELVET_ID, bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
- register_closure(ss, "westin_backscatter", OSL_CLOSURE_BSDF_WESTIN_BACKSCATTER_ID, bsdf_westin_backscatter_params(), bsdf_westin_backscatter_prepare);
- register_closure(ss, "westin_sheen", OSL_CLOSURE_BSDF_WESTIN_SHEEN_ID, bsdf_westin_sheen_params(), bsdf_westin_sheen_prepare);
- register_closure(ss, "bssrdf_cubic", OSL_CLOSURE_BSSRDF_CUBIC_ID, closure_bssrdf_cubic_params(), closure_bssrdf_cubic_prepare);
- register_closure(ss, "emission", OSL_CLOSURE_EMISSION_ID, closure_emission_params(), closure_emission_prepare);
- register_closure(ss, "debug", OSL_CLOSURE_DEBUG_ID, closure_debug_params(), closure_debug_prepare);
- register_closure(ss, "background", OSL_CLOSURE_BACKGROUND_ID, closure_background_params(), closure_background_prepare);
- register_closure(ss, "holdout", OSL_CLOSURE_HOLDOUT_ID, closure_holdout_params(), closure_holdout_prepare);
- register_closure(ss, "subsurface", OSL_CLOSURE_SUBSURFACE_ID, closure_subsurface_params(), closure_subsurface_prepare);
+ 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++,
+ bsdf_transparent_params(), bsdf_transparent_prepare);
+ register_closure(ss, "microfacet_ggx", id++,
+ bsdf_microfacet_ggx_params(), bsdf_microfacet_ggx_prepare);
+ register_closure(ss, "microfacet_ggx_refraction", id++,
+ bsdf_microfacet_ggx_refraction_params(), bsdf_microfacet_ggx_refraction_prepare);
+ register_closure(ss, "microfacet_beckmann", id++,
+ bsdf_microfacet_beckmann_params(), bsdf_microfacet_beckmann_prepare);
+ register_closure(ss, "microfacet_beckmann_refraction", id++,
+ bsdf_microfacet_beckmann_refraction_params(), bsdf_microfacet_beckmann_refraction_prepare);
+ register_closure(ss, "ward", id++,
+ bsdf_ward_params(), bsdf_ward_prepare);
+ register_closure(ss, "ashikhmin_velvet", id++,
+ bsdf_ashikhmin_velvet_params(), bsdf_ashikhmin_velvet_prepare);
+ register_closure(ss, "westin_backscatter", id++,
+ bsdf_westin_backscatter_params(), bsdf_westin_backscatter_prepare);
+ register_closure(ss, "westin_sheen", id++,
+ bsdf_westin_sheen_params(), bsdf_westin_sheen_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, "ambient_occlusion", id++,
+ closure_ambient_occlusion_params(), closure_ambient_occlusion_prepare);
+ register_closure(ss, "phong_ramp", id++,
+ closure_bsdf_phong_ramp_params(), closure_bsdf_phong_ramp_prepare);
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_closures.h b/intern/cycles/kernel/osl/osl_closures.h
index a69af45672d..71e9e5ae4fd 100644
--- a/intern/cycles/kernel/osl/osl_closures.h
+++ b/intern/cycles/kernel/osl/osl_closures.h
@@ -37,78 +37,27 @@
#include <OSL/oslexec.h>
#include <OSL/genclosure.h>
-CCL_NAMESPACE_BEGIN
+#include "kernel_types.h"
-enum {
- OSL_CLOSURE_BSDF_DIFFUSE_ID,
- OSL_CLOSURE_BSDF_OREN_NAYAR_ID,
- OSL_CLOSURE_BSDF_TRANSLUCENT_ID,
- OSL_CLOSURE_BSDF_REFLECTION_ID,
- OSL_CLOSURE_BSDF_REFRACTION_ID,
- OSL_CLOSURE_BSDF_TRANSPARENT_ID,
- OSL_CLOSURE_BSDF_MICROFACET_GGX_ID,
- OSL_CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID,
- OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_ID,
- OSL_CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID,
- OSL_CLOSURE_BSDF_WARD_ID,
- OSL_CLOSURE_BSDF_PHONG_ID,
- OSL_CLOSURE_BSDF_PHONG_RAMP_ID,
- OSL_CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
- OSL_CLOSURE_BSDF_WESTIN_BACKSCATTER_ID,
- OSL_CLOSURE_BSDF_WESTIN_SHEEN_ID,
- OSL_CLOSURE_BSSRDF_CUBIC_ID,
- OSL_CLOSURE_EMISSION_ID,
- OSL_CLOSURE_DEBUG_ID,
- OSL_CLOSURE_BACKGROUND_ID,
- OSL_CLOSURE_HOLDOUT_ID,
- OSL_CLOSURE_SUBSURFACE_ID
-};
+#include "util_types.h"
+
+CCL_NAMESPACE_BEGIN
-OSL::ClosureParam *bsdf_diffuse_params();
-OSL::ClosureParam *bsdf_oren_nayar_params();
-OSL::ClosureParam *bsdf_translucent_params();
-OSL::ClosureParam *bsdf_reflection_params();
-OSL::ClosureParam *bsdf_refraction_params();
-OSL::ClosureParam *bsdf_transparent_params();
-OSL::ClosureParam *bsdf_microfacet_ggx_params();
-OSL::ClosureParam *bsdf_microfacet_ggx_refraction_params();
-OSL::ClosureParam *bsdf_microfacet_beckmann_params();
-OSL::ClosureParam *bsdf_microfacet_beckmann_refraction_params();
-OSL::ClosureParam *bsdf_ward_params();
-OSL::ClosureParam *bsdf_phong_params();
-OSL::ClosureParam *bsdf_phong_ramp_params();
-OSL::ClosureParam *bsdf_ashikhmin_velvet_params();
-OSL::ClosureParam *bsdf_westin_backscatter_params();
-OSL::ClosureParam *bsdf_westin_sheen_params();
-OSL::ClosureParam *closure_bssrdf_cubic_params();
OSL::ClosureParam *closure_emission_params();
-OSL::ClosureParam *closure_debug_params();
OSL::ClosureParam *closure_background_params();
OSL::ClosureParam *closure_holdout_params();
-OSL::ClosureParam *closure_subsurface_params();
-
-void bsdf_diffuse_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_oren_nayar_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_translucent_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_reflection_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_refraction_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_transparent_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_microfacet_ggx_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_microfacet_ggx_refraction_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_microfacet_beckmann_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_microfacet_beckmann_refraction_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_ward_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_phong_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_ashikhmin_velvet_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_westin_backscatter_prepare(OSL::RendererServices *, int id, void *data);
-void bsdf_westin_sheen_prepare(OSL::RendererServices *, int id, void *data);
-void closure_bssrdf_cubic_prepare(OSL::RendererServices *, int id, void *data);
+OSL::ClosureParam *closure_ambient_occlusion_params();
+OSL::ClosureParam *closure_bsdf_phong_ramp_params();
+
void closure_emission_prepare(OSL::RendererServices *, int id, void *data);
-void closure_debug_prepare(OSL::RendererServices *, int id, void *data);
void closure_background_prepare(OSL::RendererServices *, int id, void *data);
void closure_holdout_prepare(OSL::RendererServices *, int id, void *data);
-void closure_subsurface_prepare(OSL::RendererServices *, int id, void *data);
+void closure_ambient_occlusion_prepare(OSL::RendererServices *, int id, void *data);
+void closure_bsdf_phong_ramp_prepare(OSL::RendererServices *, int id, void *data);
+
+enum {
+ AmbientOcclusion = 100
+};
#define CLOSURE_PREPARE(name, classname) \
void name(RendererServices *, int id, void *data) \
@@ -117,6 +66,106 @@ void name(RendererServices *, int id, void *data) \
new (data) classname(); \
}
+#define TO_VEC3(v) (*(OSL::Vec3 *)&(v))
+#define TO_COLOR3(v) (*(OSL::Color3 *)&(v))
+#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
+
+/* BSDF */
+
+class CBSDFClosure : public OSL::ClosurePrimitive {
+public:
+ ShaderClosure sc;
+ OSL::Vec3 N, T;
+
+ CBSDFClosure(int scattering) : OSL::ClosurePrimitive(BSDF),
+ m_scattering_label(scattering), m_shaderdata_flag(0) { }
+ ~CBSDFClosure() { }
+
+ int scattering() const { return m_scattering_label; }
+ int shaderdata_flag() const { return m_shaderdata_flag; }
+ ClosureType shaderclosure_type() const { return sc.type; }
+
+ virtual void blur(float roughness) = 0;
+ virtual float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
+ virtual float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float &pdf) const = 0;
+
+ virtual int sample(const float3 &Ng,
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy,
+ float randu, float randv,
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy,
+ float &pdf, float3 &eval) const = 0;
+
+protected:
+ int m_scattering_label;
+ int m_shaderdata_flag;
+};
+
+#define BSDF_CLOSURE_CLASS_BEGIN(Upper, lower, svmlower, TYPE) \
+\
+class Upper##Closure : public CBSDFClosure { \
+public: \
+ Upper##Closure() : CBSDFClosure(TYPE) {} \
+ size_t memsize() const { return sizeof(*this); } \
+ const char *name() const { return #lower; } \
+\
+ void setup() \
+ { \
+ sc.N = TO_FLOAT3(N); \
+ sc.T = TO_FLOAT3(T); \
+ m_shaderdata_flag = bsdf_##lower##_setup(&sc); \
+ } \
+\
+ bool mergeable(const ClosurePrimitive *other) const \
+ { \
+ return false; \
+ } \
+ \
+ void blur(float roughness) \
+ { \
+ bsdf_##svmlower##_blur(&sc, roughness); \
+ } \
+\
+ void print_on(std::ostream &out) const \
+ { \
+ out << name() << " ((" << sc.N[0] << ", " << sc.N[1] << ", " << sc.N[2] << "))"; \
+ } \
+\
+ float3 eval_reflect(const float3 &omega_out, const float3 &omega_in, float& pdf) const \
+ { \
+ return bsdf_##svmlower##_eval_reflect(&sc, omega_out, omega_in, &pdf); \
+ } \
+\
+ float3 eval_transmit(const float3 &omega_out, const float3 &omega_in, float& pdf) const \
+ { \
+ return bsdf_##svmlower##_eval_transmit(&sc, omega_out, omega_in, &pdf); \
+ } \
+\
+ int sample(const float3 &Ng, \
+ const float3 &omega_out, const float3 &domega_out_dx, const float3 &domega_out_dy, \
+ float randu, float randv, \
+ float3 &omega_in, float3 &domega_in_dx, float3 &domega_in_dy, \
+ float &pdf, float3 &eval) const \
+ { \
+ return bsdf_##svmlower##_sample(&sc, Ng, omega_out, domega_out_dx, domega_out_dy, \
+ randu, randv, &eval, &omega_in, &domega_in_dx, &domega_in_dy, &pdf); \
+ } \
+}; \
+\
+ClosureParam *bsdf_##lower##_params() \
+{ \
+ static ClosureParam params[] = {
+
+/* parameters */
+
+#define BSDF_CLOSURE_CLASS_END(Upper, lower) \
+ CLOSURE_STRING_KEYPARAM("label"), \
+ CLOSURE_FINISH_PARAM(Upper##Closure) \
+ }; \
+ return params; \
+} \
+\
+CLOSURE_PREPARE(bsdf_##lower##_prepare, Upper##Closure)
+
CCL_NAMESPACE_END
#endif /* __OSL_CLOSURES_H__ */
diff --git a/intern/cycles/kernel/osl/osl_globals.h b/intern/cycles/kernel/osl/osl_globals.h
index 8cbbfc8dbb1..80ced9dfd62 100644
--- a/intern/cycles/kernel/osl/osl_globals.h
+++ b/intern/cycles/kernel/osl/osl_globals.h
@@ -59,6 +59,7 @@ struct OSLGlobals {
vector<AttributeMap> attribute_map;
ObjectNameMap object_name_map;
+ vector<ustring> object_names;
/* thread key for thread specific data lookup */
struct ThreadData {
@@ -67,6 +68,11 @@ struct OSLGlobals {
};
static tls_ptr(ThreadData, thread_data);
+ static thread_mutex thread_data_mutex;
+ static volatile int thread_data_users;
+
+ void thread_data_init();
+ void thread_data_free();
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp
index f1deaa9db9d..54cbf49704f 100644
--- a/intern/cycles/kernel/osl/osl_services.cpp
+++ b/intern/cycles/kernel/osl/osl_services.cpp
@@ -22,6 +22,7 @@
#include "object.h"
#include "scene.h"
+#include "osl_closures.h"
#include "osl_services.h"
#include "osl_shader.h"
@@ -30,8 +31,14 @@
#include "kernel_compat_cpu.h"
#include "kernel_globals.h"
+#include "kernel_montecarlo.h"
+#include "kernel_projection.h"
+#include "kernel_differential.h"
#include "kernel_object.h"
+#include "kernel_bvh.h"
#include "kernel_triangle.h"
+#include "kernel_accumulate.h"
+#include "kernel_shader.h"
CCL_NAMESPACE_BEGIN
@@ -72,7 +79,11 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr
int object = sd->object;
if (object != ~0) {
- Transform tfm = object_fetch_transform(kg, object, time, OBJECT_TRANSFORM);
+#ifdef __OBJECT_MOTION__
+ Transform tfm = object_fetch_transform_motion_test(kg, object, time, NULL);
+#else
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+#endif
tfm = transform_transpose(tfm);
result = TO_MATRIX44(tfm);
@@ -93,9 +104,14 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, OSL::Transform
int object = sd->object;
if (object != ~0) {
- Transform tfm = object_fetch_transform(kg, object, time, OBJECT_INVERSE_TRANSFORM);
- tfm = transform_transpose(tfm);
- result = TO_MATRIX44(tfm);
+#ifdef __OBJECT_MOTION__
+ Transform itfm;
+ object_fetch_transform_motion_test(kg, object, time, &itfm);
+#else
+ Transform itfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+#endif
+ itfm = transform_transpose(itfm);
+ result = TO_MATRIX44(itfm);
return true;
}
@@ -109,7 +125,7 @@ bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from, float ti
KernelGlobals *kg = kernel_globals;
if (from == u_ndc) {
- Transform tfm = transform_transpose(kernel_data.cam.ndctoworld);
+ Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
result = TO_MATRIX44(tfm);
return true;
}
@@ -162,14 +178,108 @@ bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to, fl
bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform)
{
- // XXX implementation
- return true;
+ /* 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 != ~0) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ KernelGlobals *kg = kernel_globals;
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_TRANSFORM);
+#endif
+ tfm = transform_transpose(tfm);
+ result = TO_MATRIX44(tfm);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool OSLRenderServices::get_inverse_matrix(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;
+
+ if (object != ~0) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ KernelGlobals *kg = kernel_globals;
+ Transform tfm = object_fetch_transform(kg, object, OBJECT_INVERSE_TRANSFORM);
+#endif
+ tfm = transform_transpose(tfm);
+ result = TO_MATRIX44(tfm);
+
+ return true;
+ }
+ }
+
+ return false;
}
bool OSLRenderServices::get_matrix(OSL::Matrix44 &result, ustring from)
{
- // XXX implementation
- return true;
+ KernelGlobals *kg = kernel_globals;
+
+ if (from == u_ndc) {
+ Transform tfm = transform_transpose(transform_quick_inverse(kernel_data.cam.worldtondc));
+ result = TO_MATRIX44(tfm);
+ return true;
+ }
+ else if (from == u_raster) {
+ Transform tfm = transform_transpose(kernel_data.cam.rastertoworld);
+ result = TO_MATRIX44(tfm);
+ return true;
+ }
+ else if (from == u_screen) {
+ Transform tfm = transform_transpose(kernel_data.cam.screentoworld);
+ result = TO_MATRIX44(tfm);
+ return true;
+ }
+ else if (from == u_camera) {
+ Transform tfm = transform_transpose(kernel_data.cam.cameratoworld);
+ result = TO_MATRIX44(tfm);
+ return true;
+ }
+
+ return false;
+}
+
+bool OSLRenderServices::get_inverse_matrix(OSL::Matrix44 &result, ustring to)
+{
+ KernelGlobals *kg = kernel_globals;
+
+ if (to == u_ndc) {
+ Transform tfm = transform_transpose(kernel_data.cam.worldtondc);
+ result = TO_MATRIX44(tfm);
+ return true;
+ }
+ else if (to == u_raster) {
+ Transform tfm = transform_transpose(kernel_data.cam.worldtoraster);
+ result = TO_MATRIX44(tfm);
+ return true;
+ }
+ else if (to == u_screen) {
+ Transform tfm = transform_transpose(kernel_data.cam.worldtoscreen);
+ result = TO_MATRIX44(tfm);
+ return true;
+ }
+ else if (to == u_camera) {
+ Transform tfm = transform_transpose(kernel_data.cam.worldtocamera);
+ result = TO_MATRIX44(tfm);
+ return true;
+ }
+
+ return false;
}
bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives,
@@ -179,72 +289,185 @@ bool OSLRenderServices::get_array_attribute(void *renderstate, bool derivatives,
return false;
}
-static void set_attribute_float3(float3 f[3], TypeDesc type, bool derivatives, void *val)
+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)
{
- float3 *fval = (float3 *)val;
- fval[0] = f[0];
+ float *fval = (float *)val;
+
+ fval[0] = f[0].x;
+ fval[1] = f[0].y;
+ fval[2] = f[0].z;
+
if (derivatives) {
- fval[1] = f[1];
- fval[2] = f[2];
+ 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 {
+ 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 void set_attribute_float(float f[3], TypeDesc type, bool derivatives, void *val)
+static bool set_attribute_float3(float3 f, TypeDesc type, bool derivatives, void *val)
+{
+ 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);
+
+ 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)
{
- float3 *fval = (float3 *)val;
- fval[0] = make_float3(f[0], f[0], f[0]);
+ float *fval = (float *)val;
+ fval[0] = f[0];
+ fval[1] = f[1];
+ fval[2] = f[2];
+
if (derivatives) {
- fval[1] = make_float3(f[1], f[2], f[1]);
- fval[2] = make_float3(f[2], f[2], f[2]);
+ 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 {
+ 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 get_mesh_attribute(KernelGlobals *kg, const ShaderData *sd, const OSLGlobals::Attribute& attr,
- const TypeDesc& type, bool derivatives, void *val)
+static bool set_attribute_float(float f, TypeDesc type, bool derivatives, void *val)
{
- if (attr.type == TypeDesc::TypeFloat) {
- float fval[3];
- fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
- (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
- set_attribute_float(fval, type, derivatives, val);
+ float fv[3];
+
+ fv[0] = f;
+ fv[1] = 0.0f;
+ fv[2] = 0.0f;
+
+ 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 (derivatives) {
+ ival[1] = 0;
+ ival[2] = 0;
+ }
+
return true;
}
- else if (attr.type == TypeDesc::TypePoint || attr.type == TypeDesc::TypeVector ||
- attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
+
+ return false;
+}
+
+static bool set_attribute_string(ustring str, TypeDesc type, bool derivatives, void *val)
+{
+ if(type.basetype == TypeDesc::INT && 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;
+ }
+
+ return true;
+ }
+
+ 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;
+
+ 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[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);
+
+ return true;
+ }
+
+ return false;
+}
+
+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::TypePoint || attr.type == TypeDesc::TypeVector ||
+ attr.type == TypeDesc::TypeNormal || attr.type == TypeDesc::TypeColor)
{
- /* todo: this won't work when float3 has w component */
float3 fval[3];
fval[0] = triangle_attribute_float3(kg, sd, attr.elem, attr.offset,
(derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
- set_attribute_float3(fval, type, derivatives, val);
- return true;
+ return set_attribute_float3(fval, type, derivatives, val);
}
- else
+ else if (attr.type == TypeDesc::TypeFloat) {
+ float fval[3];
+ fval[0] = triangle_attribute_float(kg, sd, attr.elem, attr.offset,
+ (derivatives) ? &fval[1] : NULL, (derivatives) ? &fval[2] : NULL);
+ return set_attribute_float(fval, type, derivatives, val);
+ }
+ else {
return false;
+ }
}
static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivatives, void *val)
@@ -259,102 +482,103 @@ static void get_object_attribute(const OSLGlobals::Attribute& attr, bool derivat
static bool get_object_standard_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
TypeDesc type, bool derivatives, void *val)
{
+ /* todo: turn this into hash table returning int, which can be used in switch */
+
/* Object Attributes */
- if (name == "std::object_location") {
- float3 fval[3];
- fval[0] = object_location(kg, sd);
- fval[1] = fval[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */
- set_attribute_float3(fval, type, derivatives, val);
- return true;
+ if (name == "object:location") {
+ float3 f = object_location(kg, sd);
+ return set_attribute_float3(f, type, derivatives, val);
}
- else if (name == "std::object_index") {
- float fval[3];
- fval[0] = object_pass_id(kg, sd->object);
- fval[1] = fval[2] = 0.0; /* derivates set to 0 */
- set_attribute_float(fval, type, derivatives, val);
- return true;
+ else if (name == "object:index") {
+ float f = object_pass_id(kg, sd->object);
+ return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "std::material_index") {
- float fval[3];
- fval[0] = shader_pass_id(kg, sd);
- fval[1] = fval[2] = 0.0; /* derivates set to 0 */
- set_attribute_float(fval, type, derivatives, val);
- return true;
+ else if (name == "geom:dupli_generated") {
+ float3 f = object_dupli_generated(kg, sd->object);
+ return set_attribute_float3(f, type, derivatives, val);
}
- else if (name == "std::object_random") {
- float fval[3];
- fval[0] = object_random_number(kg, sd->object);
- fval[1] = fval[2] = 0.0; /* derivates set to 0 */
- set_attribute_float(fval, type, derivatives, val);
- return true;
+ else if (name == "geom:dupli_uv") {
+ float3 f = object_dupli_uv(kg, sd->object);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == "material:index") {
+ float f = shader_pass_id(kg, sd);
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if (name == "object:random") {
+ float f = object_random_number(kg, sd->object);
+ return set_attribute_float(f, type, derivatives, val);
}
/* Particle Attributes */
- else if (name == "std::particle_index") {
- float fval[3];
+ else if (name == "particle:index") {
uint particle_id = object_particle_id(kg, sd->object);
- fval[0] = particle_index(kg, particle_id);
- fval[1] = fval[2] = 0.0; /* derivates set to 0 */
- set_attribute_float(fval, type, derivatives, val);
- return true;
+ float f = particle_index(kg, particle_id);
+ return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "std::particle_age") {
- float fval[3];
+ else if (name == "particle:age") {
uint particle_id = object_particle_id(kg, sd->object);
- fval[0] = particle_age(kg, particle_id);
- fval[1] = fval[2] = 0.0; /* derivates set to 0 */
- set_attribute_float(fval, type, derivatives, val);
- return true;
+ float f = particle_age(kg, particle_id);
+ return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "std::particle_lifetime") {
- float fval[3];
+ else if (name == "particle:lifetime") {
uint particle_id = object_particle_id(kg, sd->object);
- fval[0] = particle_lifetime(kg, particle_id);
- fval[1] = fval[2] = 0.0; /* derivates set to 0 */
- set_attribute_float(fval, type, derivatives, val);
- return true;
+ float f= particle_lifetime(kg, particle_id);
+ return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "std::particle_location") {
- float3 fval[3];
+ else if (name == "particle:location") {
uint particle_id = object_particle_id(kg, sd->object);
- fval[0] = particle_location(kg, particle_id);
- fval[1] = fval[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */
- set_attribute_float3(fval, type, derivatives, val);
- return true;
+ float3 f = particle_location(kg, particle_id);
+ return set_attribute_float3(f, type, derivatives, val);
}
#if 0 /* unsupported */
- else if (name == "std::particle_rotation") {
- float4 fval[3];
+ else if (name == "particle:rotation") {
uint particle_id = object_particle_id(kg, sd->object);
- fval[0] = particle_rotation(kg, particle_id);
- fval[1] = fval[2] = make_float4(0.0, 0.0, 0.0, 0.0); /* derivates set to 0 */
- set_attribute_float4(fval, type, derivatives, val);
- return true;
+ float4 f = particle_rotation(kg, particle_id);
+ return set_attribute_float4(f, type, derivatives, val);
}
#endif
- else if (name == "std::particle_size") {
- float fval[3];
+ else if (name == "particle:size") {
uint particle_id = object_particle_id(kg, sd->object);
- fval[0] = particle_size(kg, particle_id);
- fval[1] = fval[2] = 0.0; /* derivates set to 0 */
- set_attribute_float(fval, type, derivatives, val);
- return true;
+ float f = particle_size(kg, particle_id);
+ return set_attribute_float(f, type, derivatives, val);
}
- else if (name == "std::particle_velocity") {
- float3 fval[3];
+ else if (name == "particle:velocity") {
uint particle_id = object_particle_id(kg, sd->object);
- fval[0] = particle_velocity(kg, particle_id);
- fval[1] = fval[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */
- set_attribute_float3(fval, type, derivatives, val);
- return true;
+ float3 f = particle_velocity(kg, particle_id);
+ return set_attribute_float3(f, type, derivatives, val);
}
- else if (name == "std::particle_angular_velocity") {
- float3 fval[3];
+ else if (name == "particle:angular_velocity") {
uint particle_id = object_particle_id(kg, sd->object);
- fval[0] = particle_angular_velocity(kg, particle_id);
- fval[1] = fval[2] = make_float3(0.0, 0.0, 0.0); /* derivates set to 0 */
- set_attribute_float3(fval, type, derivatives, val);
- return true;
+ float3 f = particle_angular_velocity(kg, particle_id);
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if (name == "geom:numpolyvertices") {
+ return set_attribute_int(3, type, derivatives, val);
+ }
+ else if (name == "geom:trianglevertices" || name == "geom:polyvertices") {
+ float3 P[3];
+ triangle_vertices(kg, sd->prim, P);
+ 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 == "geom:name") {
+ ustring object_name = kg->osl.object_names[sd->object];
+ return set_attribute_string(object_name, type, derivatives, val);
+ }
+ else
+ return false;
+}
+
+static bool get_background_attribute(KernelGlobals *kg, ShaderData *sd, ustring name,
+ TypeDesc type, bool derivatives, void *val)
+{
+ /* Ray Length */
+ if (name == "path:ray_length") {
+ float f = sd->ray_length;
+ return set_attribute_float(f, type, derivatives, val);
}
else
@@ -380,8 +604,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
tri = ~0;
}
else if (object == ~0) {
- /* no background attributes supported */
- return false;
+ return get_background_attribute(kg, sd, name, type, derivatives, val);
}
/* find attribute on object */
@@ -390,7 +613,7 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
if (it != attribute_map.end()) {
const OSLGlobals::Attribute& attr = it->second;
-
+
if (attr.elem != ATTR_ELEMENT_VALUE) {
/* triangle and vertex attributes */
if (tri != ~0)
@@ -404,7 +627,12 @@ bool OSLRenderServices::get_attribute(void *renderstate, bool derivatives, ustri
}
else {
/* not found in attribute, check standard object info */
- return get_object_standard_attribute(kg, sd, name, type, derivatives, val);
+ 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;
@@ -434,4 +662,107 @@ int OSLRenderServices::pointcloud_get(ustring filename, size_t *indices, int cou
return 0;
}
+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.0e30)? 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 */
+ TraceData *tracedata = new TraceData();
+ tracedata->ray = ray;
+ tracedata->setup = false;
+
+ if(sg->tracedata)
+ delete (TraceData*)sg->tracedata;
+ sg->tracedata = tracedata;
+
+ /* raytrace */
+ return scene_intersect(kernel_globals, &ray, ~0, &tracedata->isect);
+}
+
+
+bool OSLRenderServices::getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
+ TypeDesc type, void *val, bool derivatives)
+{
+ TraceData *tracedata = (TraceData*)sg->tracedata;
+
+ if(source == "trace" && tracedata) {
+ if(name == "hit") {
+ return set_attribute_int((tracedata->isect.prim != ~0), type, derivatives, val);
+ }
+ else if(tracedata->isect.prim != ~0) {
+ if(name == "hitdist") {
+ float f[3] = {tracedata->isect.t, 0.0f, 0.0f};
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else {
+ KernelGlobals *kg = kernel_globals;
+ ShaderData *sd = &tracedata->sd;
+
+ if(!tracedata->setup) {
+ /* lazy shader data setup */
+ shader_setup_from_ray(kg, sd, &tracedata->isect, &tracedata->ray);
+ tracedata->setup = true;
+ }
+
+ if(name == "N") {
+ return set_attribute_float3(sd->N, type, derivatives, val);
+ }
+ else if(name == "Ng") {
+ return set_attribute_float3(sd->Ng, type, derivatives, val);
+ }
+ else if(name == "P") {
+ float3 f[3] = {sd->P, sd->dP.dx, sd->dP.dy};
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if(name == "I") {
+ float3 f[3] = {sd->I, sd->dI.dx, sd->dI.dy};
+ return set_attribute_float3(f, type, derivatives, val);
+ }
+ else if(name == "u") {
+ float f[3] = {sd->u, sd->du.dx, sd->du.dy};
+ return set_attribute_float(f, type, derivatives, val);
+ }
+ else if(name == "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 790b02a8abc..ce62eaf8994 100644
--- a/intern/cycles/kernel/osl/osl_services.h
+++ b/intern/cycles/kernel/osl/osl_services.h
@@ -54,7 +54,10 @@ public:
bool get_inverse_matrix(OSL::Matrix44 &result, ustring to, float time);
bool get_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform);
+ bool get_inverse_matrix(OSL::Matrix44 &result, OSL::TransformationPtr xform);
+
bool get_matrix(OSL::Matrix44 &result, ustring from);
+ bool get_inverse_matrix(OSL::Matrix44 &result, ustring from);
bool get_array_attribute(void *renderstate, bool derivatives,
ustring object, TypeDesc type, ustring name,
@@ -73,8 +76,20 @@ public:
int pointcloud_get(ustring filename, size_t *indices, int count, ustring attr_name,
TypeDesc attr_type, void *out_data);
-private:
- KernelGlobals *kernel_globals;
+ 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);
+
+ bool getmessage(OSL::ShaderGlobals *sg, ustring source, ustring name,
+ TypeDesc type, void *val, bool derivatives);
+
+ struct TraceData {
+ Ray ray;
+ Intersection isect;
+ ShaderData sd;
+ bool setup;
+ };
static ustring u_distance;
static ustring u_index;
@@ -83,6 +98,9 @@ private:
static ustring u_raster;
static ustring u_ndc;
static ustring u_empty;
+
+private:
+ KernelGlobals *kernel_globals;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/osl/osl_shader.cpp b/intern/cycles/kernel/osl/osl_shader.cpp
index ea508dcb660..abf7c041cb3 100644
--- a/intern/cycles/kernel/osl/osl_shader.cpp
+++ b/intern/cycles/kernel/osl/osl_shader.cpp
@@ -21,6 +21,7 @@
#include "kernel_globals.h"
#include "kernel_object.h"
+#include "osl_closures.h"
#include "osl_services.h"
#include "osl_shader.h"
@@ -31,9 +32,32 @@
CCL_NAMESPACE_BEGIN
tls_ptr(OSLGlobals::ThreadData, OSLGlobals::thread_data);
+volatile int OSLGlobals::thread_data_users = 0;
+thread_mutex OSLGlobals::thread_data_mutex;
/* Threads */
+void OSLGlobals::thread_data_init()
+{
+ thread_scoped_lock thread_data_lock(thread_data_mutex);
+
+ if(thread_data_users == 0)
+ tls_create(OSLGlobals::ThreadData, thread_data);
+
+ thread_data_users++;
+}
+
+void OSLGlobals::thread_data_free()
+{
+ /* thread local storage delete */
+ thread_scoped_lock thread_data_lock(thread_data_mutex);
+
+ thread_data_users--;
+
+ if(thread_data_users == 0)
+ tls_delete(OSLGlobals::ThreadData, thread_data);
+}
+
void OSLShader::thread_init(KernelGlobals *kg)
{
OSL::ShadingSystem *ss = kg->osl.ss;
@@ -61,10 +85,6 @@ void OSLShader::thread_free(KernelGlobals *kg)
/* Globals */
-#define TO_VEC3(v) (*(OSL::Vec3 *)&(v))
-#define TO_COLOR3(v) (*(OSL::Color3 *)&(v))
-#define TO_FLOAT3(v) make_float3(v[0], v[1], v[2])
-
static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
int path_flag, OSL::ShaderGlobals *globals)
{
@@ -96,6 +116,7 @@ static void shaderdata_to_shaderglobals(KernelGlobals *kg, ShaderData *sd,
/* shader data to be used in services callbacks */
globals->renderstate = sd;
+ globals->tracedata = NULL;
/* hacky, we leave it to services to fetch actual object matrix */
globals->shader2common = sd;
@@ -127,39 +148,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
if (sd->num_closure == MAX_CLOSURE)
return;
- OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)prim;
- ustring scattering = bsdf->scattering();
+ CBSDFClosure *bsdf = (CBSDFClosure *)prim;
+ int scattering = bsdf->scattering();
/* no caustics option */
- if (no_glossy && scattering == OSL::Labels::GLOSSY)
+ if (no_glossy && scattering == LABEL_GLOSSY)
return;
/* sample weight */
- float albedo = bsdf->albedo(TO_VEC3(sd->I));
- float sample_weight = fabsf(average(weight)) * albedo;
+ float sample_weight = fabsf(average(weight));
- sc.sample_weight = sample_weight;
+ sd->flag |= bsdf->shaderdata_flag();
- /* scattering flags */
- if (scattering == OSL::Labels::DIFFUSE) {
- sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL;
- sc.type = CLOSURE_BSDF_DIFFUSE_ID;
- }
- else if (scattering == OSL::Labels::GLOSSY) {
- sd->flag |= SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_GLOSSY;
- sc.type = CLOSURE_BSDF_GLOSSY_ID;
- }
- else if (scattering == OSL::Labels::STRAIGHT) {
- sd->flag |= SD_BSDF;
- sc.type = CLOSURE_BSDF_TRANSPARENT_ID;
- }
- else {
- /* todo: we don't actually have a way to determine if
- * this closure will reflect/transmit. could add our own
- * own scattering flag that do give this info */
- sd->flag |= SD_BSDF;
- sc.type = CLOSURE_BSDF_GLOSSY_ID;
- }
+ sc.sample_weight = sample_weight;
+ sc.type = bsdf->shaderclosure_type();
/* add */
sd->closure[sd->num_closure++] = sc;
@@ -181,6 +183,20 @@ static void flatten_surface_closure_tree(ShaderData *sd, bool no_glossy,
sd->closure[sd->num_closure++] = sc;
break;
}
+ case AmbientOcclusion: {
+ if (sd->num_closure == MAX_CLOSURE)
+ return;
+
+ /* sample weight */
+ float sample_weight = fabsf(average(weight));
+
+ sc.sample_weight = sample_weight;
+ sc.type = CLOSURE_AMBIENT_OCCLUSION_ID;
+
+ sd->closure[sd->num_closure++] = sc;
+ sd->flag |= SD_AO;
+ break;
+ }
case OSL::ClosurePrimitive::Holdout:
if (sd->num_closure == MAX_CLOSURE)
return;
@@ -227,6 +243,10 @@ void OSLShader::eval_surface(KernelGlobals *kg, ShaderData *sd, float randb, int
if (kg->osl.surface_state[shader])
ss->execute(*ctx, *(kg->osl.surface_state[shader]), *globals);
+ /* free trace data */
+ if(globals->tracedata)
+ delete (OSLRenderServices::TraceData*)globals->tracedata;
+
/* flatten closure tree */
sd->num_closure = 0;
sd->randb_closure = randb;
@@ -282,6 +302,10 @@ float3 OSLShader::eval_background(KernelGlobals *kg, ShaderData *sd, int path_fl
if (kg->osl.background_state)
ss->execute(*ctx, *(kg->osl.background_state), *globals);
+ /* free trace data */
+ if(globals->tracedata)
+ delete (OSLRenderServices::TraceData*)globals->tracedata;
+
/* return background color immediately */
if (globals->Ci)
return flatten_background_closure_tree(globals->Ci);
@@ -360,6 +384,10 @@ void OSLShader::eval_volume(KernelGlobals *kg, ShaderData *sd, float randb, int
if (kg->osl.volume_state[shader])
ss->execute(*ctx, *(kg->osl.volume_state[shader]), *globals);
+ /* free trace data */
+ if(globals->tracedata)
+ delete (OSLRenderServices::TraceData*)globals->tracedata;
+
if (globals->Ci)
flatten_volume_closure_tree(sd, globals->Ci);
}
@@ -383,6 +411,10 @@ void OSLShader::eval_displacement(KernelGlobals *kg, ShaderData *sd)
if (kg->osl.displacement_state[shader])
ss->execute(*ctx, *(kg->osl.displacement_state[shader]), *globals);
+ /* free trace data */
+ if(globals->tracedata)
+ delete (OSLRenderServices::TraceData*)globals->tracedata;
+
/* get back position */
sd->P = TO_FLOAT3(globals->P);
}
@@ -406,54 +438,34 @@ void OSLShader::release(KernelGlobals *kg, ShaderData *sd)
int OSLShader::bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, float randu, float randv, float3& eval, float3& omega_in, differential3& domega_in, float& pdf)
{
- OSL::BSDFClosure *sample_bsdf = (OSL::BSDFClosure *)sc->prim;
- int label = LABEL_NONE;
+ CBSDFClosure *sample_bsdf = (CBSDFClosure *)sc->prim;
pdf = 0.0f;
- /* sample BSDF closure */
- ustring ulabel;
-
- ulabel = sample_bsdf->sample(TO_VEC3(sd->Ng),
- TO_VEC3(sd->I), TO_VEC3(sd->dI.dx), TO_VEC3(sd->dI.dy),
- randu, randv,
- TO_VEC3(omega_in), TO_VEC3(domega_in.dx), TO_VEC3(domega_in.dy),
- pdf, TO_COLOR3(eval));
-
- /* convert OSL label */
- if (ulabel == OSL::Labels::REFLECT)
- label = LABEL_REFLECT;
- else if (ulabel == OSL::Labels::TRANSMIT)
- label = LABEL_TRANSMIT;
- else
- return LABEL_NONE; /* sampling failed */
-
- /* convert scattering to our bitflag label */
- ustring uscattering = sample_bsdf->scattering();
-
- if (uscattering == OSL::Labels::DIFFUSE)
- label |= LABEL_DIFFUSE;
- else if (uscattering == OSL::Labels::GLOSSY)
- label |= LABEL_GLOSSY;
- else if (uscattering == OSL::Labels::SINGULAR)
- label |= LABEL_SINGULAR;
- else
- label |= LABEL_TRANSPARENT;
-
- return label;
+ return sample_bsdf->sample(sd->Ng,
+ sd->I, sd->dI.dx, sd->dI.dy,
+ randu, randv,
+ omega_in, domega_in.dx, domega_in.dy,
+ pdf, eval);
}
float3 OSLShader::bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, const float3& omega_in, float& pdf)
{
- OSL::BSDFClosure *bsdf = (OSL::BSDFClosure *)sc->prim;
- OSL::Color3 bsdf_eval;
+ CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim;
+ float3 bsdf_eval;
if (dot(sd->Ng, omega_in) >= 0.0f)
- bsdf_eval = bsdf->eval_reflect(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf);
+ bsdf_eval = bsdf->eval_reflect(sd->I, omega_in, pdf);
else
- bsdf_eval = bsdf->eval_transmit(TO_VEC3(sd->I), TO_VEC3(omega_in), pdf);
+ bsdf_eval = bsdf->eval_transmit(sd->I, omega_in, pdf);
- return TO_FLOAT3(bsdf_eval);
+ return bsdf_eval;
+}
+
+void OSLShader::bsdf_blur(ShaderClosure *sc, float roughness)
+{
+ CBSDFClosure *bsdf = (CBSDFClosure *)sc->prim;
+ bsdf->blur(roughness);
}
/* Emissive Closure */
@@ -468,7 +480,7 @@ float3 OSLShader::emissive_eval(const ShaderData *sd, const ShaderClosure *sc)
/* Volume Closure */
-float3 OSLShader::volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
+float3 OSLShader::volume_eval_phase(const ShaderClosure *sc, const float3 omega_in, const float3 omega_out)
{
OSL::VolumeClosure *volume = (OSL::VolumeClosure *)sc->prim;
OSL::Color3 volume_eval = volume->eval_phase(TO_VEC3(omega_in), TO_VEC3(omega_out));
diff --git a/intern/cycles/kernel/osl/osl_shader.h b/intern/cycles/kernel/osl/osl_shader.h
index e2f4d1e94b8..9ff31e9160b 100644
--- a/intern/cycles/kernel/osl/osl_shader.h
+++ b/intern/cycles/kernel/osl/osl_shader.h
@@ -72,10 +72,11 @@ public:
float3& eval, float3& omega_in, differential3& domega_in, float& pdf);
static float3 bsdf_eval(const ShaderData *sd, const ShaderClosure *sc,
const float3& omega_in, float& pdf);
+ static void bsdf_blur(ShaderClosure *sc, float roughness);
static float3 emissive_eval(const ShaderData *sd, const ShaderClosure *sc);
- static float3 volume_eval_phase(const ShaderData *sd, const ShaderClosure *sc,
+ static float3 volume_eval_phase(const ShaderClosure *sc,
const float3 omega_in, const float3 omega_out);
/* release */
diff --git a/intern/cycles/kernel/osl/vol_subsurface.cpp b/intern/cycles/kernel/osl/vol_subsurface.cpp
deleted file mode 100644
index 5845428ed43..00000000000
--- a/intern/cycles/kernel/osl/vol_subsurface.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Adapted from Open Shading Language with this license:
- *
- * Copyright (c) 2009-2010 Sony Pictures Imageworks Inc., et al.
- * All Rights Reserved.
- *
- * Modifications Copyright 2011, Blender Foundation.
- *
- * Redistribution and use in source and binary forms, with or without
- * 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.
- * * 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.
- * * 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.
- * 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
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <OpenImageIO/fmath.h>
-
-#include <OSL/genclosure.h>
-
-#include "osl_closures.h"
-
-CCL_NAMESPACE_BEGIN
-
-using namespace OSL;
-
-// Computes scattering properties based on Jensen's reparameterization
-// described in:
-// http://graphics.ucsd.edu/~henrik/papers/fast_bssrdf/
-
-class SubsurfaceClosure : public VolumeClosure {
-public:
- float m_g;
- float m_eta;
- Color3 m_mfp, m_albedo;
- static float root_find_Rd(const float Rd0, const float A) {
- // quick exit for trivial cases
- if (Rd0 <= 0) return 0;
- const float A43 = A * 4.0f / 3.0f;
- // Find alpha such that f(alpha) = Rd (see eq.15). A simple bisection
- // method can be used because this function is monotonicaly increasing.
- float lo = 0, hi = 1;
- for (int i = 0; i < 20; i++) { // 2^20 divisions should be sufficient
- // eval function at midpoint
- float alpha = 0.5f * (lo + hi);
- float a1 = sqrtf(3 * (1 - alpha));
- float e1 = expf(-a1);
- float e2 = expf(-A43 * a1);
- float Rd = 0.5f * alpha * (1 + e2) * e1 - Rd0;
- if (fabsf(Rd) < 1e-6f)
- return alpha; // close enough
- else if (Rd > 0)
- hi = alpha; // root is on left side
- else
- lo = alpha; // root is on right side
- }
- // didn't quite converge, pick result in the middle of remaining interval
- return 0.5f * (lo + hi);
- }
- SubsurfaceClosure() {
- }
-
- void setup()
- {
- ior(m_eta);
-
- if (m_g >= 0.99f) m_g = 0.99f;
- if (m_g <= -0.99f) m_g = -0.99f;
-
- // eq.10
- float inv_eta = 1 / m_eta;
- float Fdr = -1.440f * inv_eta * inv_eta + 0.710 * inv_eta + 0.668f + 0.0636 * m_eta;
- float A = (1 + Fdr) / (1 - Fdr);
- // compute sigma_s, sigma_a (eq.16)
- Color3 alpha_prime = Color3(root_find_Rd(m_albedo[0], A),
- root_find_Rd(m_albedo[1], A),
- root_find_Rd(m_albedo[2], A));
- Color3 sigma_t_prime = Color3(m_mfp.x > 0 ? 1.0f / (m_mfp[0] * sqrtf(3 * (1 - alpha_prime[0]))) : 0.0f,
- m_mfp.y > 0 ? 1.0f / (m_mfp[1] * sqrtf(3 * (1 - alpha_prime[1]))) : 0.0f,
- m_mfp.z > 0 ? 1.0f / (m_mfp[2] * sqrtf(3 * (1 - alpha_prime[2]))) : 0.0f);
- Color3 sigma_s_prime = alpha_prime * sigma_t_prime;
-
- sigma_s((1.0f / (1 - m_g)) * sigma_s_prime);
- sigma_a(sigma_t_prime - sigma_s_prime);
- }
-
- bool mergeable(const ClosurePrimitive *other) const {
- const SubsurfaceClosure *comp = (const SubsurfaceClosure *)other;
- return m_g == comp->m_g && VolumeClosure::mergeable(other);
- }
-
- size_t memsize() const { return sizeof(*this); }
-
- const char *name() const { return "subsurface"; }
-
- void print_on(std::ostream &out) const {
- out << name() << " ()";
- }
-
- virtual Color3 eval_phase(const Vec3 &omega_in, const Vec3 &omega_out) const {
- float costheta = omega_in.dot(omega_out);
- float ph = 0.25f * float(M_1_PI) * ((1 - m_g * m_g) / powf(1 + m_g * m_g - 2.0f * m_g * costheta, 1.5f));
- return Color3(ph, ph, ph);
- }
-};
-
-
-
-ClosureParam *closure_subsurface_params()
-{
- static ClosureParam params[] = {
- CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_eta),
- CLOSURE_FLOAT_PARAM(SubsurfaceClosure, m_g),
- CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_mfp),
- CLOSURE_COLOR_PARAM(SubsurfaceClosure, m_albedo),
- CLOSURE_STRING_KEYPARAM("label"),
- CLOSURE_FINISH_PARAM(SubsurfaceClosure)
- };
- return params;
-}
-
-CLOSURE_PREPARE(closure_subsurface_prepare, SubsurfaceClosure)
-
-CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/osl/nodes/CMakeLists.txt b/intern/cycles/kernel/shaders/CMakeLists.txt
index 541076f84c9..4f5a97c1bb6 100644
--- a/intern/cycles/kernel/osl/nodes/CMakeLists.txt
+++ b/intern/cycles/kernel/shaders/CMakeLists.txt
@@ -3,15 +3,18 @@
set(SRC_OSL
node_add_closure.osl
+ node_ambient_occlusion.osl
node_attribute.osl
node_background.osl
node_brick_texture.osl
+ node_brightness.osl
node_bump.osl
node_camera.osl
node_checker_texture.osl
node_combine_rgb.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
@@ -20,15 +23,16 @@ set(SRC_OSL
node_environment_texture.osl
node_fresnel.osl
node_gamma.osl
- node_gradient_texture.osl
- node_brightness.osl
node_geometry.osl
node_glass_bsdf.osl
node_glossy_bsdf.osl
+ node_gradient_texture.osl
node_holdout.osl
node_hsv.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
@@ -36,16 +40,20 @@ set(SRC_OSL
node_mix.osl
node_mix_closure.osl
node_musgrave_texture.osl
- node_normal.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_ramp.osl
node_separate_rgb.osl
+ node_set_normal.osl
node_sky_texture.osl
+ node_tangent.osl
node_texture_coordinate.osl
node_translucent_bsdf.osl
node_transparent_bsdf.osl
@@ -72,11 +80,11 @@ set(SRC_OSO
# TODO, add a module to compile OSL
foreach(_file ${SRC_OSL})
set(_OSL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${_file})
- string(REPLACE ".osl" ".oso" _OSO_FILE ${_OSL_FILE}) # TODO, replace extension only
+ 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} -O2 ${_OSL_FILE}
+ COMMAND ${OSL_COMPILER} -O2 -I"${CMAKE_CURRENT_SOURCE_DIR}" ${_OSL_FILE}
DEPENDS ${_OSL_FILE} ${SRC_OSL_HEADERS})
list(APPEND SRC_OSO
${_OSO_FILE}
@@ -86,7 +94,9 @@ foreach(_file ${SRC_OSL})
unset(_OSO_FILE)
endforeach()
-add_custom_target(shader ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS})
+add_custom_target(cycles_osl_shaders ALL DEPENDS ${SRC_OSO} ${SRC_OSL_HEADERS})
# CMAKE_CURRENT_SOURCE_DIR is already included in OSO paths
delayed_install("" "${SRC_OSO}" ${CYCLES_INSTALL_PATH}/shader)
+delayed_install("${CMAKE_CURRENT_SOURCE_DIR}" "${SRC_OSL_HEADERS}" ${CYCLES_INSTALL_PATH}/shader)
+
diff --git a/intern/cycles/kernel/osl/nodes/node_add_closure.osl b/intern/cycles/kernel/shaders/node_add_closure.osl
index ecf6bf5912e..ecf6bf5912e 100644
--- a/intern/cycles/kernel/osl/nodes/node_add_closure.osl
+++ b/intern/cycles/kernel/shaders/node_add_closure.osl
diff --git a/intern/cycles/kernel/shaders/node_ambient_occlusion.osl b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
new file mode 100644
index 00000000000..57a06f35461
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_ambient_occlusion.osl
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+shader node_ambient_occlusion(
+ color Color = color(0.8, 0.8, 0.8),
+ output closure color AO = ambient_occlusion())
+{
+ AO = Color * ambient_occlusion();
+}
+
diff --git a/intern/cycles/kernel/osl/nodes/node_attribute.osl b/intern/cycles/kernel/shaders/node_attribute.osl
index d273d0c68d7..8e7c846d1a3 100644
--- a/intern/cycles/kernel/osl/nodes/node_attribute.osl
+++ b/intern/cycles/kernel/shaders/node_attribute.osl
@@ -29,12 +29,12 @@ shader node_attribute(
Vector = point(Color);
getattribute(name, Fac);
- if(bump_offset == "dx") {
+ if (bump_offset == "dx") {
Color += Dx(Color);
Vector += Dx(Vector);
Fac += Dx(Fac);
}
- else if(bump_offset == "dy") {
+ else if (bump_offset == "dy") {
Color += Dy(Color);
Vector += Dy(Vector);
Fac += Dy(Fac);
diff --git a/intern/cycles/kernel/osl/nodes/node_background.osl b/intern/cycles/kernel/shaders/node_background.osl
index 69f8d85a82e..b51a1685294 100644
--- a/intern/cycles/kernel/osl/nodes/node_background.osl
+++ b/intern/cycles/kernel/shaders/node_background.osl
@@ -23,6 +23,6 @@ shader node_background(
float Strength = 1.0,
output closure color Background = background())
{
- Background = Color*Strength*background();
+ Background = Color * Strength * background();
}
diff --git a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl b/intern/cycles/kernel/shaders/node_brick_texture.osl
index 4daceb4018e..478d9457001 100644
--- a/intern/cycles/kernel/osl/nodes/node_brick_texture.osl
+++ b/intern/cycles/kernel/shaders/node_brick_texture.osl
@@ -40,21 +40,21 @@ float brick(point p, float mortar_size, float bias,
rownum = (int)floor(p[1] / row_height);
- if(offset_frequency && squash_frequency) {
- brick_width *= ((int)(rownum) % squash_frequency ) ? 1.0 : squash_amount; /* squash */
- offset = ((int)(rownum) % offset_frequency ) ? 0 : (brick_width*offset_amount); /* offset */
+ if (offset_frequency && squash_frequency) {
+ brick_width *= ((int)(rownum) % squash_frequency) ? 1.0 : squash_amount; /* squash */
+ offset = ((int)(rownum) % offset_frequency) ? 0 : (brick_width * offset_amount); /* offset */
}
- bricknum = (int)floor((p[0]+offset) / brick_width);
+ bricknum = (int)floor((p[0] + offset) / brick_width);
- x = (p[0]+offset) - brick_width*bricknum;
- y = p[1] - row_height*rownum;
+ 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);
return (x < mortar_size || y < mortar_size ||
- x > (brick_width - mortar_size) ||
- y > (row_height - mortar_size)) ? 1.0 : 0.0;
+ x > (brick_width - mortar_size) ||
+ y > (row_height - mortar_size)) ? 1.0 : 0.0;
}
shader node_brick_texture(
@@ -77,10 +77,10 @@ shader node_brick_texture(
float tint = 0.0;
color Col = Color1;
- Fac = brick(Vector*Scale, MortarSize, Bias, BrickWidth, RowHeight,
+ Fac = brick(Vector * Scale, MortarSize, Bias, BrickWidth, RowHeight,
Offset, OffsetFrequency, Squash, SquashFrequency, tint);
- if(Fac != 1.0) {
+ if (Fac != 1.0) {
float facm = 1.0 - tint;
Col[0] = facm * (Color1[0]) + tint * Color2[0];
@@ -89,6 +89,5 @@ shader node_brick_texture(
}
Color = (Fac == 1.0) ? Mortar: Col;
-
}
diff --git a/intern/cycles/kernel/osl/nodes/node_brightness.osl b/intern/cycles/kernel/shaders/node_brightness.osl
index 4f19a20f736..8e9f5c9c796 100644
--- a/intern/cycles/kernel/osl/nodes/node_brightness.osl
+++ b/intern/cycles/kernel/shaders/node_brightness.osl
@@ -24,7 +24,7 @@ shader node_brightness(
float Contrast = 0.0,
output color ColorOut = color(0.8, 0.8, 0.8))
{
- float delta = Contrast * (1.0/200.0);
+ float delta = Contrast * (1.0 / 200.0);
float a = 1.0 - delta * 2.0;
float b;
@@ -32,13 +32,13 @@ shader node_brightness(
float bright_factor = Brightness / 100.0;
/*
- * The algorithm is by Werner D. Streidt
- * (http://visca.com/ffactory/archives/5-99/msg00021.html)
- * Extracted of OpenCV demhist.c
- */
+ * The algorithm is by Werner D. Streidt
+ * (http://visca.com/ffactory/archives/5-99/msg00021.html)
+ * Extracted of OpenCV demhist.c
+ */
if (Contrast > 0.0) {
- a = (a < 0.0 ? 1.0/a : 0.0);
+ a = (a < 0.0 ? 1.0 / a : 0.0);
b = a * (bright_factor - delta);
}
else {
diff --git a/intern/cycles/kernel/osl/nodes/node_bump.osl b/intern/cycles/kernel/shaders/node_bump.osl
index a3849e70f98..24db1b24458 100644
--- a/intern/cycles/kernel/osl/nodes/node_bump.osl
+++ b/intern/cycles/kernel/shaders/node_bump.osl
@@ -18,29 +18,32 @@
#include "stdosl.h"
-/* "Bump Mapping Unparametrized Surfaces on the GPU"
+/* "Bump Mapping Unparameterized Surfaces on the GPU"
* Morten S. Mikkelsen, 2010 */
surface node_bump(
+ normal NormalIn = N,
+ float Strength = 0.0,
float SampleCenter = 0.0,
float SampleX = 0.0,
float SampleY = 0.0,
output normal Normal = N)
{
- float dx = SampleX - SampleCenter;
- float dy = SampleY - SampleCenter;
-
+ /* get surface tangents from normal */
vector dPdx = Dx(P);
vector dPdy = Dy(P);
- vector Rx = cross(dPdy, N);
- vector Ry = cross(N, dPdx);
+ vector Rx = cross(dPdy, NormalIn);
+ vector Ry = cross(NormalIn, dPdx);
+ /* compute surface gradient and determinant */
float det = dot(dPdx, Rx);
- vector surfgrad = dx*Rx + dy*Ry;
+ vector surfgrad = (SampleX - SampleCenter) * Rx + (SampleY - SampleCenter) * Ry;
- surfgrad *= 0.1; /* todo: remove this factor */
+ surfgrad *= Strength;
+ float absdet = fabs(det);
- Normal = normalize(abs(det)*N - sign(det)*surfgrad);
+ /* compute and output perturbed normal */
+ Normal = normalize(absdet * NormalIn - sign(det) * surfgrad);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_camera.osl b/intern/cycles/kernel/shaders/node_camera.osl
index 898ebd2bbb2..898ebd2bbb2 100644
--- a/intern/cycles/kernel/osl/nodes/node_camera.osl
+++ b/intern/cycles/kernel/shaders/node_camera.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl b/intern/cycles/kernel/shaders/node_checker_texture.osl
index e92d7be34fc..577caf308ff 100644
--- a/intern/cycles/kernel/osl/nodes/node_checker_texture.osl
+++ b/intern/cycles/kernel/shaders/node_checker_texture.osl
@@ -23,15 +23,15 @@
float checker(point p)
{
- p[0] = (p[0] + 0.00001)*0.9999;
- p[1] = (p[1] + 0.00001)*0.9999;
- p[2] = (p[2] + 0.00001)*0.9999;
+ p[0] = (p[0] + 0.00001) * 0.9999;
+ p[1] = (p[1] + 0.00001) * 0.9999;
+ p[2] = (p[2] + 0.00001) * 0.9999;
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)) {
+ if ((xi % 2 == yi % 2) == (zi % 2)) {
return 1.0;
}
else {
@@ -47,8 +47,8 @@ shader node_checker_texture(
output float Fac = 0.0,
output color Color = color(0.0, 0.0, 0.0))
{
- Fac = checker(Vector*Scale);
- if(Fac == 1.0) {
+ Fac = checker(Vector * Scale);
+ if (Fac == 1.0) {
Color = Color1;
}
else {
diff --git a/intern/cycles/kernel/osl/nodes/node_color.h b/intern/cycles/kernel/shaders/node_color.h
index 80786e4e369..80786e4e369 100644
--- a/intern/cycles/kernel/osl/nodes/node_color.h
+++ b/intern/cycles/kernel/shaders/node_color.h
diff --git a/intern/cycles/kernel/osl/nodes/node_combine_rgb.osl b/intern/cycles/kernel/shaders/node_combine_rgb.osl
index 546369f660e..546369f660e 100644
--- a/intern/cycles/kernel/osl/nodes/node_combine_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_combine_rgb.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl b/intern/cycles/kernel/shaders/node_convert_from_color.osl
index 97356139c48..2884c772414 100644
--- a/intern/cycles/kernel/osl/nodes/node_convert_from_color.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_color.osl
@@ -21,11 +21,13 @@
shader node_convert_from_color(
color Color = color(0.0, 0.0, 0.0),
output float Val = 0.0,
+ output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
output point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 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;
+ ValInt = (int)(Color[0]*0.2126 + Color[1]*0.7152 + Color[2]*0.0722);
Vector = vector(Color[0], Color[1], Color[2]);
Point = point(Color[0], Color[1], Color[2]);
Normal = normal(Color[0], Color[1], Color[2]);
diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl b/intern/cycles/kernel/shaders/node_convert_from_float.osl
index 00e78f3bab4..4466fbae3a6 100644
--- a/intern/cycles/kernel/osl/nodes/node_convert_from_float.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_float.osl
@@ -20,11 +20,13 @@
shader node_convert_from_float(
float Val = 0.0,
+ output int ValInt = 0,
output color Color = color(0.0, 0.0, 0.0),
output vector Vector = vector(0.0, 0.0, 0.0),
output point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 0.0))
{
+ ValInt = (int)Val;
Color = color(Val, Val, Val);
Vector = vector(Val, Val, Val);
Point = point(Val, Val, Val);
diff --git a/intern/cycles/kernel/shaders/node_convert_from_int.osl b/intern/cycles/kernel/shaders/node_convert_from_int.osl
new file mode 100644
index 00000000000..060d4184fa6
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_convert_from_int.osl
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+shader node_convert_from_int(
+ int ValInt = 0,
+ output float Val = 0.0,
+ output color Color = color(0.0, 0.0, 0.0),
+ output vector Vector = vector(0.0, 0.0, 0.0),
+ output point Point = point(0.0, 0.0, 0.0),
+ output normal Normal = normal(0.0, 0.0, 0.0))
+{
+ float f = (float)ValInt;
+ Val = f;
+ Color = color(f, f, f);
+ Vector = vector(f, f, f);
+ Point = point(f, f, f);
+ Normal = normal(f, f, f);
+}
+
diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
index 0bb9092591d..32ef430d93b 100644
--- a/intern/cycles/kernel/osl/nodes/node_convert_from_normal.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_normal.osl
@@ -21,11 +21,13 @@
shader node_convert_from_normal(
normal Normal = normal(0.0, 0.0, 0.0),
output float Val = 0.0,
+ output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
output color Color = color(0.0, 0.0, 0.0),
output point Point = point(0.0, 0.0, 0.0))
{
- Val = (Normal[0] + Normal[1] + Normal[2])*(1.0/3.0);
+ Val = (Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0);
+ ValInt = (int)((Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0));
Vector = vector(Normal[0], Normal[1], Normal[2]);
Color = color(Normal[0], Normal[1], Normal[2]);
Point = point(Normal[0], Normal[1], Normal[2]);
diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl b/intern/cycles/kernel/shaders/node_convert_from_point.osl
index e66d6a864d6..a9435c8abf4 100644
--- a/intern/cycles/kernel/osl/nodes/node_convert_from_point.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_point.osl
@@ -21,11 +21,13 @@
shader node_convert_from_point(
point Point = point(0.0, 0.0, 0.0),
output float Val = 0.0,
+ output int ValInt = 0,
output vector Vector = vector(0.0, 0.0, 0.0),
output color Color = color(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 0.0))
{
- Val = (Point[0] + Point[1] + Point[2])*(1.0/3.0);
+ Val = (Point[0] + Point[1] + Point[2]) * (1.0 / 3.0);
+ ValInt = (int)((Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0));
Vector = vector(Point[0], Point[1], Point[2]);
Color = color(Point[0], Point[1], Point[2]);
Normal = normal(Point[0], Point[1], Point[2]);
diff --git a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl b/intern/cycles/kernel/shaders/node_convert_from_vector.osl
index 37ba9582cad..4516f92c753 100644
--- a/intern/cycles/kernel/osl/nodes/node_convert_from_vector.osl
+++ b/intern/cycles/kernel/shaders/node_convert_from_vector.osl
@@ -21,11 +21,13 @@
shader node_convert_from_vector(
vector Vector = vector(0.0, 0.0, 0.0),
output float Val = 0.0,
+ output int ValInt = 0,
output color Color = color(0.0, 0.0, 0.0),
output point Point = point(0.0, 0.0, 0.0),
output normal Normal = normal(0.0, 0.0, 0.0))
{
- Val = (Vector[0] + Vector[1] + Vector[2])*(1.0/3.0);
+ Val = (Vector[0] + Vector[1] + Vector[2]) * (1.0 / 3.0);
+ ValInt = (int)((Normal[0] + Normal[1] + Normal[2]) * (1.0 / 3.0));
Color = color(Vector[0], Vector[1], Vector[2]);
Point = point(Vector[0], Vector[1], Vector[2]);
Normal = normal(Vector[0], Vector[1], Vector[2]);
diff --git a/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
index 6075b7c93f3..d6dc17316e8 100644
--- a/intern/cycles/kernel/osl/nodes/node_diffuse_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_diffuse_bsdf.osl
@@ -24,7 +24,7 @@ shader node_diffuse_bsdf(
normal Normal = N,
output closure color BSDF = diffuse(Normal))
{
- if(Roughness == 0.0)
+ if (Roughness == 0.0)
BSDF = Color * diffuse(Normal);
else
BSDF = Color * oren_nayar(Normal, Roughness);
diff --git a/intern/cycles/kernel/osl/nodes/node_emission.osl b/intern/cycles/kernel/shaders/node_emission.osl
index 8bfd1af173a..7ad0f9f7760 100644
--- a/intern/cycles/kernel/osl/nodes/node_emission.osl
+++ b/intern/cycles/kernel/shaders/node_emission.osl
@@ -24,9 +24,9 @@ shader node_emission(
float Strength = 1.0,
output closure color Emission = emission())
{
- if(TotalPower)
- Emission = ((Strength/surfacearea())*Color)*emission();
+ if (TotalPower)
+ Emission = ((Strength / surfacearea()) * Color) * emission();
else
- Emission = (Strength*Color)*emission();
+ Emission = (Strength * Color) * emission();
}
diff --git a/intern/cycles/kernel/osl/nodes/node_environment_texture.osl b/intern/cycles/kernel/shaders/node_environment_texture.osl
index 3ad806781eb..bad62e56ab4 100644
--- a/intern/cycles/kernel/osl/nodes/node_environment_texture.osl
+++ b/intern/cycles/kernel/shaders/node_environment_texture.osl
@@ -28,7 +28,7 @@ shader node_environment_texture(
{
Color = (color)environment(filename, Vector, "alpha", Alpha);
- if(color_space == "sRGB")
+ if (color_space == "sRGB")
Color = color_srgb_to_scene_linear(Color);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_fresnel.h b/intern/cycles/kernel/shaders/node_fresnel.h
index dfd0a23fe1e..dfd0a23fe1e 100644
--- a/intern/cycles/kernel/osl/nodes/node_fresnel.h
+++ b/intern/cycles/kernel/shaders/node_fresnel.h
diff --git a/intern/cycles/kernel/osl/nodes/node_fresnel.osl b/intern/cycles/kernel/shaders/node_fresnel.osl
index 3af4448b43f..e8d8e945f98 100644
--- a/intern/cycles/kernel/osl/nodes/node_fresnel.osl
+++ b/intern/cycles/kernel/shaders/node_fresnel.osl
@@ -25,7 +25,7 @@ shader node_fresnel(
output float Fac = 0.0)
{
float f = max(IOR, 1.0 + 1e-5);
- float eta = backfacing()? 1.0/f: f;
+ float eta = backfacing() ? 1.0 / f: f;
Fac = fresnel_dielectric(I, Normal, eta);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_gamma.osl b/intern/cycles/kernel/shaders/node_gamma.osl
index d55e908b0b7..d55e908b0b7 100644
--- a/intern/cycles/kernel/osl/nodes/node_gamma.osl
+++ b/intern/cycles/kernel/shaders/node_gamma.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_geometry.osl b/intern/cycles/kernel/shaders/node_geometry.osl
index 9efc2a75c64..3940b98eec1 100644
--- a/intern/cycles/kernel/osl/nodes/node_geometry.osl
+++ b/intern/cycles/kernel/shaders/node_geometry.osl
@@ -32,19 +32,32 @@ shader node_geometry(
{
Position = P;
Normal = NormalIn;
- Tangent = normalize(dPdu);
TrueNormal = Ng;
Incoming = I;
Parametric = point(u, v, 0.0);
Backfacing = backfacing();
- if(bump_offset == "dx") {
+ if (bump_offset == "dx") {
Position += Dx(Position);
Parametric += Dx(Parametric);
}
- else if(bump_offset == "dy") {
+ else if (bump_offset == "dy") {
Position += Dy(Position);
Parametric += Dy(Parametric);
}
+
+ /* first try to get tangent attribute */
+ point generated;
+
+ /* try to create spherical tangent from generated coordinates */
+ if (getattribute("geom:generated", generated)) {
+ vector T = vector(-(generated[1] - 0.5), (generated[0] - 0.5), 0.0);
+ T = transform("object", "world", T);
+ Tangent = cross(Normal, normalize(cross(T, Normal)));
+ }
+ else {
+ /* otherwise use surface derivatives */
+ Tangent = normalize(dPdu);
+ }
}
diff --git a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
index 52743669c99..30b9d301f32 100644
--- a/intern/cycles/kernel/osl/nodes/node_glass_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glass_bsdf.osl
@@ -28,14 +28,16 @@ shader node_glass_bsdf(
output closure color BSDF = diffuse(Normal))
{
float f = max(IOR, 1.0 + 1e-5);
- float eta = backfacing()? 1.0/f: f;
+ float eta = backfacing() ? 1.0 / f: f;
float Fr = fresnel_dielectric(I, Normal, 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, eta) + (1.0-Fr)*microfacet_beckmann_refraction(Normal, Roughness, eta));
- else if(distribution == "GGX")
- BSDF = Color*(Fr*microfacet_ggx(Normal, Roughness, eta) + (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 == "GGX")
+ BSDF = Color * (Fr * microfacet_ggx(Normal, Roughness) +
+ (1.0 - Fr) * microfacet_ggx_refraction(Normal, Roughness, eta));
}
diff --git a/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
index 3890630e8a2..03340c74af5 100644
--- a/intern/cycles/kernel/osl/nodes/node_glossy_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_glossy_bsdf.osl
@@ -26,12 +26,12 @@ shader node_glossy_bsdf(
normal Normal = N,
output closure color BSDF = diffuse(Normal))
{
- if(distribution == "Sharp")
- BSDF = Color*reflection(Normal);
- else if(distribution == "Beckmann")
- BSDF = Color*microfacet_beckmann(Normal, Roughness, 1.0);
- else if(distribution == "GGX")
- BSDF = Color*microfacet_ggx(Normal, Roughness, 1.0);
+ 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);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl b/intern/cycles/kernel/shaders/node_gradient_texture.osl
index e0cbc2cc569..ae7cfa51f59 100644
--- a/intern/cycles/kernel/osl/nodes/node_gradient_texture.osl
+++ b/intern/cycles/kernel/shaders/node_gradient_texture.osl
@@ -31,31 +31,31 @@ float gradient(point p, string type)
float result = 0.0;
- if(type == "Linear") {
+ if (type == "Linear") {
result = x;
}
- else if(type == "Quadratic") {
+ else if (type == "Quadratic") {
float r = max(x, 0.0);
- result = r*r;
+ result = r * r;
}
- else if(type == "Easing") {
+ else if (type == "Easing") {
float r = min(max(x, 0.0), 1.0);
- float t = r*r;
+ float t = r * r;
- result = (3.0*t - 2.0*t*r);
+ result = (3.0 * t - 2.0 * t * r);
}
- else if(type == "Diagonal") {
- result = (x + y)/2.0;
+ else if (type == "Diagonal") {
+ result = (x + y) / 2.0;
}
- else if(type == "Radial") {
- result = atan2(y, x)/(2.0*M_PI) + 0.5;
+ else if (type == "Radial") {
+ result = atan2(y, x) / (2.0 * M_PI) + 0.5;
}
else {
- float r = max(1.0 - sqrt(x*x + y*y + z*z), 0.0);
+ 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")
+ if (type == "Quadratic Sphere")
+ result = r * r;
+ else if (type == "Spherical")
result = r;
}
diff --git a/intern/cycles/kernel/osl/nodes/node_holdout.osl b/intern/cycles/kernel/shaders/node_holdout.osl
index aede50c7ca0..aede50c7ca0 100644
--- a/intern/cycles/kernel/osl/nodes/node_holdout.osl
+++ b/intern/cycles/kernel/shaders/node_holdout.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_hsv.osl b/intern/cycles/kernel/shaders/node_hsv.osl
index 8fd7a1612e8..8fd7a1612e8 100644
--- a/intern/cycles/kernel/osl/nodes/node_hsv.osl
+++ b/intern/cycles/kernel/shaders/node_hsv.osl
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl
new file mode 100644
index 00000000000..6393605e6b5
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_image_texture.osl
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+#include "node_color.h"
+
+color image_texture_lookup(string filename, string color_space, float u, float v, output float Alpha)
+{
+ color rgb = (color)texture(filename, u, 1.0 - v, "wrap", "periodic", "alpha", Alpha);
+
+ if (color_space == "sRGB")
+ rgb = color_srgb_to_scene_linear(rgb);
+
+ return rgb;
+}
+
+shader node_image_texture(
+ point Vector = P,
+ string filename = "",
+ string color_space = "sRGB",
+ string projection = "Flat",
+ float projection_blend = 0.0,
+ output color Color = color(0.0, 0.0, 0.0),
+ output float Alpha = 1.0)
+{
+ if (projection == "Flat") {
+ Color = image_texture_lookup(filename, color_space, Vector[0], Vector[1], Alpha);
+ }
+ 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);
+ }
+ }
+
+ 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, Vector[1], Vector[2], tmp_alpha);
+ Alpha += weight[0]*tmp_alpha;
+ }
+ if (weight[1] > 0.0) {
+ Color += weight[1]*image_texture_lookup(filename, color_space, Vector[0], Vector[2], tmp_alpha);
+ Alpha += weight[1]*tmp_alpha;
+ }
+ if (weight[2] > 0.0) {
+ Color += weight[2]*image_texture_lookup(filename, color_space, Vector[1], Vector[0], tmp_alpha);
+ Alpha += weight[2]*tmp_alpha;
+ }
+ }
+}
+
diff --git a/intern/cycles/kernel/osl/nodes/node_invert.osl b/intern/cycles/kernel/shaders/node_invert.osl
index 27021942558..27021942558 100644
--- a/intern/cycles/kernel/osl/nodes/node_invert.osl
+++ b/intern/cycles/kernel/shaders/node_invert.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_blend_weight.osl b/intern/cycles/kernel/shaders/node_layer_weight.osl
index d834819ef3a..3ea57f71786 100644
--- a/intern/cycles/kernel/osl/nodes/node_blend_weight.osl
+++ b/intern/cycles/kernel/shaders/node_layer_weight.osl
@@ -19,24 +19,28 @@
#include "stdosl.h"
#include "node_fresnel.h"
-shader node_blend_weight(
- float Blend = 0.3,
+shader node_layer_weight(
+ float Blend = 0.5,
normal Normal = N,
output float Fresnel = 0.0,
output float Facing = 0.0)
{
- float f = max(1.0 - Blend, 1e-5);
- Fresnel = fresnel_dielectric(I, Normal, backfacing()? f: 1.0/f);
+ float blend = Blend;
+ /* Fresnel */
+ float eta = max(1.0 - Blend, 1e-5);
+ eta = backfacing() ? eta : 1.0 / eta;
+ Fresnel = fresnel_dielectric(I, Normal, eta);
+
+ /* Facing */
Facing = abs(dot(I, Normal));
- if(Blend != 0.5) {
- Blend = clamp(Blend, 0.0, 1.0);
- 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 = powf(Facing, Blend);
+ Facing = pow(Facing, blend);
}
Facing = 1.0 - Facing;
}
-
diff --git a/intern/cycles/kernel/shaders/node_light_falloff.osl b/intern/cycles/kernel/shaders/node_light_falloff.osl
new file mode 100644
index 00000000000..7ffa6fe0ffb
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_light_falloff.osl
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#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)
+{
+ 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);
+ }
+
+ /* Quadratic */
+ Quadratic = strength;
+
+ /* Linear */
+ Linear = (strength*ray_length);
+
+ /* Constant */
+ Constant = (strength*ray_length*ray_length);
+}
+
diff --git a/intern/cycles/kernel/osl/nodes/node_light_path.osl b/intern/cycles/kernel/shaders/node_light_path.osl
index 0ead20bf2bb..9e3f6c7b4a9 100644
--- a/intern/cycles/kernel/osl/nodes/node_light_path.osl
+++ b/intern/cycles/kernel/shaders/node_light_path.osl
@@ -25,7 +25,8 @@ shader node_light_path(
output float IsGlossyRay = 0.0,
output float IsSingularRay = 0.0,
output float IsReflectionRay = 0.0,
- output float IsTransmissionRay = 0.0)
+ output float IsTransmissionRay = 0.0,
+ output float RayLength = 0.0)
{
IsCameraRay = raytype("camera");
IsShadowRay = raytype("shadow");
@@ -34,5 +35,7 @@ shader node_light_path(
IsSingularRay = raytype("singular");
IsReflectionRay = raytype("reflection");
IsTransmissionRay = raytype("refraction");
+
+ getattribute("path:ray_length", RayLength);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_magic_texture.osl b/intern/cycles/kernel/shaders/node_magic_texture.osl
index c013ebfe658..e464b83bc9e 100644
--- a/intern/cycles/kernel/osl/nodes/node_magic_texture.osl
+++ b/intern/cycles/kernel/shaders/node_magic_texture.osl
@@ -25,51 +25,51 @@ 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);
+ 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) {
+ if (n > 0) {
x *= dist;
y *= dist;
z *= dist;
- y = -cos(x-y+z);
+ y = -cos(x - y + z);
y *= dist;
- if(n > 1) {
- x = cos(x-y-z);
+ if (n > 1) {
+ x = cos(x - y - z);
x *= dist;
- if(n > 2) {
- z = sin(-x-y-z);
+ if (n > 2) {
+ z = sin(-x - y - z);
z *= dist;
- if(n > 3) {
- x = -cos(-x+y-z);
+ if (n > 3) {
+ x = -cos(-x + y - z);
x *= dist;
- if(n > 4) {
- y = -sin(-x+y+z);
+ if (n > 4) {
+ y = -sin(-x + y + z);
y *= dist;
- if(n > 5) {
- y = -cos(-x+y+z);
+ if (n > 5) {
+ y = -cos(-x + y + z);
y *= dist;
- if(n > 6) {
- x = cos(x+y+z);
+ if (n > 6) {
+ x = cos(x + y + z);
x *= dist;
- if(n > 7) {
- z = sin(x+y-z);
+ if (n > 7) {
+ z = sin(x + y - z);
z *= dist;
- if(n > 8) {
- x = -cos(-x-y+z);
+ if (n > 8) {
+ x = -cos(-x - y + z);
x *= dist;
- if(n > 9) {
- y = -sin(x-y+z);
+ if (n > 9) {
+ y = -sin(x - y + z);
y *= dist;
}
}
@@ -82,7 +82,7 @@ color magic(point p, int n, float distortion)
}
}
- if(dist != 0.0) {
+ if (dist != 0.0) {
dist *= 2.0;
x /= dist;
y /= dist;
@@ -99,6 +99,6 @@ shader node_magic_texture(
point Vector = P,
output color Color = color(0.0, 0.0, 0.0))
{
- Color = magic(Vector*Scale, Depth, Distortion);
+ Color = magic(Vector * Scale, Depth, Distortion);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_mapping.osl b/intern/cycles/kernel/shaders/node_mapping.osl
index f342837d3c9..2e720edfc7e 100644
--- a/intern/cycles/kernel/osl/nodes/node_mapping.osl
+++ b/intern/cycles/kernel/shaders/node_mapping.osl
@@ -20,9 +20,9 @@
shader node_mapping(
matrix Matrix = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
- point Vector = point(0.0, 0.0, 0.0),
- output point Vector_ = point(0.0, 0.0, 0.0))
+ point VectorIn = point(0.0, 0.0, 0.0),
+ output point VectorOut = point(0.0, 0.0, 0.0))
{
- Vector_ = transform(Matrix, Vector);
+ VectorOut = transform(Matrix, VectorIn);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_math.osl b/intern/cycles/kernel/shaders/node_math.osl
index 3327795286a..24dce898fd2 100644
--- a/intern/cycles/kernel/osl/nodes/node_math.osl
+++ b/intern/cycles/kernel/shaders/node_math.osl
@@ -22,20 +22,20 @@ float safe_divide(float a, float b)
{
float result;
- if(b == 0.0)
+ if (b == 0.0)
result = 0.0;
else
- result = a/b;
+ result = a / b;
return result;
}
float safe_log(float a, float b)
{
- if(a < 0.0 || b < 0.0)
+ if (a < 0.0 || b < 0.0)
return 0.0;
- return log(a)/log(b);
+ return log(a) / log(b);
}
shader node_math(
@@ -47,42 +47,42 @@ shader node_math(
{
/* OSL asin, acos, pow check for values that could give rise to nan */
- if(type == "Add")
+ if (type == "Add")
Value = Value1 + Value2;
- if(type == "Subtract")
+ if (type == "Subtract")
Value = Value1 - Value2;
- if(type == "Multiply")
- Value = Value1*Value2;
- if(type == "Divide")
+ if (type == "Multiply")
+ Value = Value1 * Value2;
+ if (type == "Divide")
Value = safe_divide(Value1, Value2);
- if(type == "Sine")
+ if (type == "Sine")
Value = sin(Value1);
- if(type == "Cosine")
+ if (type == "Cosine")
Value = cos(Value1);
- if(type == "Tangent")
+ if (type == "Tangent")
Value = tan(Value1);
- if(type == "Arcsine")
+ if (type == "Arcsine")
Value = asin(Value1);
- if(type == "Arccosine")
+ if (type == "Arccosine")
Value = acos(Value1);
- if(type == "Arctangent")
+ if (type == "Arctangent")
Value = atan(Value1);
- if(type == "Power")
+ if (type == "Power")
Value = pow(Value1, Value2);
- if(type == "Logarithm")
+ if (type == "Logarithm")
Value = safe_log(Value1, Value2);
- if(type == "Minimum")
+ if (type == "Minimum")
Value = min(Value1, Value2);
- if(type == "Maximum")
+ if (type == "Maximum")
Value = max(Value1, Value2);
- if(type == "Round")
+ if (type == "Round")
Value = floor(Value1 + 0.5);
- if(type == "Less Than")
+ if (type == "Less Than")
Value = Value1 < Value2;
- if(type == "Greater Than")
+ if (type == "Greater Than")
Value = Value1 > Value2;
- if(Clamp)
+ if (Clamp)
Value = clamp(Value1, 0.0, 1.0);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_mix.osl b/intern/cycles/kernel/shaders/node_mix.osl
index 2ce342c49cd..69e68e5ed15 100644
--- a/intern/cycles/kernel/osl/nodes/node_mix.osl
+++ b/intern/cycles/kernel/shaders/node_mix.osl
@@ -38,7 +38,7 @@ color node_mix_screen(float t, color col1, color col2)
{
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)
@@ -47,20 +47,20 @@ color node_mix_overlay(float t, color col1, color col2)
color outcol = col1;
- if(outcol[0] < 0.5)
- outcol[0] *= tm + 2.0*t*col2[0];
+ 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]);
+ 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];
+ 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]);
+ 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];
+ 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]);
+ outcol[2] = 1.0 - (tm + 2.0 * t * (1.0 - col2[2])) * (1.0 - outcol[2]);
return outcol;
}
@@ -76,9 +76,9 @@ color node_mix_div(float t, color col1, color col2)
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;
}
@@ -90,41 +90,41 @@ color node_mix_diff(float t, color col1, color col2)
color node_mix_dark(float t, color col1, color col2)
{
- return min(col1, col2*t);
+ return min(col1, col2 * 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ 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)
+ else if ((tmp = outcol[2] / tmp) > 1.0)
outcol[2] = 1.0;
else
outcol[2] = tmp;
@@ -139,32 +139,32 @@ color node_mix_burn(float t, color col1, color col2)
color outcol = col1;
- tmp = tm + t*col2[0];
- if(tmp <= 0.0)
+ 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)
+ else if ((tmp = (1.0 - (1.0 - outcol[0]) / tmp)) < 0.0)
outcol[0] = 0.0;
- else if(tmp > 1.0)
+ else if (tmp > 1.0)
outcol[0] = 1.0;
else
outcol[0] = tmp;
- tmp = tm + t*col2[1];
- if(tmp <= 0.0)
+ 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)
+ else if ((tmp = (1.0 - (1.0 - outcol[1]) / tmp)) < 0.0)
outcol[1] = 0.0;
- else if(tmp > 1.0)
+ else if (tmp > 1.0)
outcol[1] = 1.0;
else
outcol[1] = tmp;
- tmp = tm + t*col2[2];
- if(tmp <= 0.0)
+ 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)
+ else if ((tmp = (1.0 - (1.0 - outcol[2]) / tmp)) < 0.0)
outcol[2] = 0.0;
- else if(tmp > 1.0)
+ else if (tmp > 1.0)
outcol[2] = 1.0;
else
outcol[2] = tmp;
@@ -177,7 +177,7 @@ color node_mix_hue(float t, color col1, color col2)
color outcol = col1;
color hsv2 = rgb_to_hsv(col2);
- if(hsv2[1] != 0.0) {
+ if (hsv2[1] != 0.0) {
color hsv = rgb_to_hsv(outcol);
hsv[0] = hsv2[0];
color tmp = hsv_to_rgb(hsv);
@@ -196,10 +196,10 @@ color node_mix_sat(float t, color col1, color col2)
color hsv = rgb_to_hsv(outcol);
- if(hsv[1] != 0.0) {
+ if (hsv[1] != 0.0) {
color hsv2 = rgb_to_hsv(col2);
- hsv[1] = tm*hsv[1] + t*hsv2[1];
+ hsv[1] = tm * hsv[1] + t * hsv2[1];
outcol = hsv_to_rgb(hsv);
}
@@ -213,7 +213,7 @@ color node_mix_val(float t, color col1, color 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);
}
@@ -223,7 +223,7 @@ color node_mix_color(float t, color col1, color col2)
color outcol = col1;
color hsv2 = rgb_to_hsv(col2);
- if(hsv2[1] != 0.0) {
+ if (hsv2[1] != 0.0) {
color hsv = rgb_to_hsv(outcol);
hsv[0] = hsv2[0];
hsv[1] = hsv2[1];
@@ -240,29 +240,29 @@ color node_mix_soft(float t, color col1, color col2)
float tm = 1.0 - t;
color one = color(1.0);
- color scr = one - (one - col2)*(one - col1);
+ 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));
+ 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);
+ 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));
+ 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);
+ 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));
+ 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);
+ outcol[2] = col1[2] + t * (2.0 * (col2[2]) - 1.0);
return outcol;
}
@@ -288,44 +288,44 @@ shader node_mix(
{
float t = clamp(Fac, 0.0, 1.0);
- if(type == "Mix")
+ if (type == "Mix")
Color = node_mix_blend(t, Color1, Color2);
- if(type == "Add")
+ if (type == "Add")
Color = node_mix_add(t, Color1, Color2);
- if(type == "Multiply")
+ if (type == "Multiply")
Color = node_mix_mul(t, Color1, Color2);
- if(type == "Screen")
+ if (type == "Screen")
Color = node_mix_screen(t, Color1, Color2);
- if(type == "Overlay")
+ if (type == "Overlay")
Color = node_mix_overlay(t, Color1, Color2);
- if(type == "Subtract")
+ if (type == "Subtract")
Color = node_mix_sub(t, Color1, Color2);
- if(type == "Divide")
+ if (type == "Divide")
Color = node_mix_div(t, Color1, Color2);
- if(type == "Difference")
+ if (type == "Difference")
Color = node_mix_diff(t, Color1, Color2);
- if(type == "Darken")
+ if (type == "Darken")
Color = node_mix_dark(t, Color1, Color2);
- if(type == "Lighten")
+ if (type == "Lighten")
Color = node_mix_light(t, Color1, Color2);
- if(type == "Dodge")
+ if (type == "Dodge")
Color = node_mix_dodge(t, Color1, Color2);
- if(type == "Burn")
+ if (type == "Burn")
Color = node_mix_burn(t, Color1, Color2);
- if(type == "Hue")
+ if (type == "Hue")
Color = node_mix_hue(t, Color1, Color2);
- if(type == "Saturation")
+ if (type == "Saturation")
Color = node_mix_sat(t, Color1, Color2);
- if(type == "Value")
+ if (type == "Value")
Color = node_mix_val (t, Color1, Color2);
- if(type == "Color")
+ if (type == "Color")
Color = node_mix_color(t, Color1, Color2);
- if(type == "Soft Light")
+ if (type == "Soft Light")
Color = node_mix_soft(t, Color1, Color2);
- if(type == "Linear Light")
+ if (type == "Linear Light")
Color = node_mix_linear(t, Color1, Color2);
- if(Clamp)
+ if (Clamp)
Color = node_mix_clamp(Color);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_mix_closure.osl b/intern/cycles/kernel/shaders/node_mix_closure.osl
index 1a377abd381..e28dd1fc436 100644
--- a/intern/cycles/kernel/osl/nodes/node_mix_closure.osl
+++ b/intern/cycles/kernel/shaders/node_mix_closure.osl
@@ -25,6 +25,6 @@ shader node_mix_closure(
output closure color Closure = background())
{
float t = clamp(Fac, 0.0, 1.0);
- Closure = (1.0 - t)*Closure1 + t*Closure2;
+ Closure = (1.0 - t) * Closure1 + t * Closure2;
}
diff --git a/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
index 7d125d50fd6..71461b8fd79 100644
--- a/intern/cycles/kernel/osl/nodes/node_musgrave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_musgrave_texture.osl
@@ -36,14 +36,14 @@ float noise_musgrave_fBm(point p, string basis, float H, float lacunarity, float
float pwHL = pow(lacunarity, -H);
int i;
- for(i = 0; i < (int)octaves; i++) {
+ for (i = 0; i < (int)octaves; i++) {
value += noise("perlin", p) * pwr;
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
- if(rmd != 0.0)
+ if (rmd != 0.0)
value += rmd * noise("perlin", p) * pwr;
return value;
@@ -64,14 +64,14 @@ float noise_musgrave_multi_fractal(point p, string basis, float H, float lacunar
float pwHL = pow(lacunarity, -H);
int i;
- for(i = 0; i < (int)octaves; i++) {
+ for (i = 0; i < (int)octaves; i++) {
value *= (pwr * noise("perlin", p) + 1.0);
pwr *= pwHL;
p *= lacunarity;
}
rmd = octaves - floor(octaves);
- if(rmd != 0.0)
+ if (rmd != 0.0)
value *= (rmd * pwr * noise("perlin", p) + 1.0); /* correct? */
return value;
@@ -96,7 +96,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
value = offset + noise("perlin", p);
p *= lacunarity;
- for(i = 1; i < (int)octaves; i++) {
+ for (i = 1; i < (int)octaves; i++) {
increment = (noise("perlin", p) + offset) * pwr * value;
value += increment;
pwr *= pwHL;
@@ -104,7 +104,7 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
}
rmd = octaves - floor(octaves);
- if(rmd != 0.0) {
+ if (rmd != 0.0) {
increment = (noise("perlin", p) + offset) * pwr * value;
value += rmd * increment;
}
@@ -120,7 +120,8 @@ float noise_musgrave_hetero_terrain(point p, string basis, float H, float lacuna
* offset: raises the terrain from `sea level'
*/
-float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float lacunarity, float octaves, float offset, float gain)
+float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H,
+ float lacunarity, float octaves, float offset, float gain)
{
float result, signal, weight, rmd;
float pwHL = pow(lacunarity, -H);
@@ -131,8 +132,8 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float
weight = gain * result;
p *= lacunarity;
- for(i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
- if(weight > 1.0)
+ for (i = 1; (weight > 0.001) && (i < (int)octaves); i++) {
+ if (weight > 1.0)
weight = 1.0;
signal = (noise("perlin", p) + offset) * pwr;
@@ -143,7 +144,7 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float
}
rmd = octaves - floor(octaves);
- if(rmd != 0.0)
+ if (rmd != 0.0)
result += rmd * ((noise("perlin", p) + offset) * pwr);
return result;
@@ -157,7 +158,8 @@ float noise_musgrave_hybrid_multi_fractal(point p, string basis, float H, float
* offset: raises the terrain from `sea level'
*/
-float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, float lacunarity, float octaves, float offset, float gain)
+float noise_musgrave_ridged_multi_fractal(point p, string basis, float H,
+ float lacunarity, float octaves, float offset, float gain)
{
float result, signal, weight;
float pwHL = pow(lacunarity, -H);
@@ -169,7 +171,7 @@ float noise_musgrave_ridged_multi_fractal(point p, string basis, float H, float
result = signal;
weight = 1.0;
- for(i = 1; i < (int)octaves; i++) {
+ for (i = 1; i < (int)octaves; i++) {
p *= lacunarity;
weight = clamp(signal * gain, 0.0, 1.0);
signal = offset - fabs(noise("perlin", p));
@@ -202,18 +204,18 @@ shader node_musgrave_texture(
string Basis = "Perlin";
float intensity = 1.0;
- point p = Vector*Scale;
-
- if(Type == "Multifractal")
- Fac = intensity*noise_musgrave_multi_fractal(p, Basis, dimension, lacunarity, octaves);
- else if(Type == "fBM")
- Fac = intensity*noise_musgrave_fBm(p, Basis, dimension, lacunarity, octaves);
- else if(Type == "Hybrid Multifractal")
- Fac = intensity*noise_musgrave_hybrid_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain);
- else if(Type == "Ridged Multifractal")
- Fac = intensity*noise_musgrave_ridged_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain);
- else if(Type == "Hetero Terrain")
- Fac = intensity*noise_musgrave_hetero_terrain(p, Basis, dimension, lacunarity, octaves, Offset);
+ point p = Vector * Scale;
+
+ if (Type == "Multifractal")
+ Fac = intensity * noise_musgrave_multi_fractal(p, Basis, dimension, lacunarity, octaves);
+ else if (Type == "fBM")
+ Fac = intensity * noise_musgrave_fBm(p, Basis, dimension, lacunarity, octaves);
+ else if (Type == "Hybrid Multifractal")
+ Fac = intensity * noise_musgrave_hybrid_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain);
+ else if (Type == "Ridged Multifractal")
+ Fac = intensity * noise_musgrave_ridged_multi_fractal(p, Basis, dimension, lacunarity, octaves, Offset, Gain);
+ else if (Type == "Hetero Terrain")
+ Fac = intensity * noise_musgrave_hetero_terrain(p, Basis, dimension, lacunarity, octaves, Offset);
Color = color(Fac, Fac, Fac);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_noise_texture.osl b/intern/cycles/kernel/shaders/node_noise_texture.osl
index 1ddb4d8a08b..227b2bf8cea 100644
--- a/intern/cycles/kernel/osl/nodes/node_noise_texture.osl
+++ b/intern/cycles/kernel/shaders/node_noise_texture.osl
@@ -25,8 +25,8 @@ float noise(point p, string basis, float distortion, float detail, float fac, co
{
point r;
int hard = 0;
-
- if(distortion != 0.0) {
+
+ if (distortion != 0.0) {
r[0] = noise_basis(p + point(13.5), basis) * distortion;
r[1] = noise_basis(p, basis) * distortion;
r[2] = noise_basis(p - point(13.5), basis) * distortion;
@@ -51,6 +51,6 @@ shader node_noise_texture(
output color Color = color(0.2, 0.2, 0.2))
{
string Basis = "Perlin";
- Fac = noise(Vector*Scale, Basis, Distortion, Detail, Fac, Color);
+ Fac = noise(Vector * Scale, Basis, Distortion, Detail, Fac, Color);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_normal.osl b/intern/cycles/kernel/shaders/node_normal.osl
index d5f16acb88c..d5f16acb88c 100644
--- a/intern/cycles/kernel/osl/nodes/node_normal.osl
+++ b/intern/cycles/kernel/shaders/node_normal.osl
diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl
new file mode 100644
index 00000000000..d101ee870b7
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_normal_map.osl
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#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)
+{
+ color mcolor = 2.0*color(Color[0] - 0.5, Color[1] - 0.5, Color[2] - 0.5);
+
+ if (space == "Tangent") {
+ vector tangent;
+ float tangent_sign;
+
+ getattribute(attr_name, tangent);
+ getattribute(attr_sign_name, tangent_sign);
+
+ tangent = transform("object", "world", tangent);
+
+ vector B = tangent_sign * cross(NormalIn, tangent);
+ Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * NormalIn);
+ }
+ else if (space == "Object")
+ Normal = normalize(transform("object", "world", vector(mcolor)));
+ else if (space == "World")
+ Normal = normalize(vector(mcolor));
+
+ if (Strength != 1.0)
+ Normal = normalize(NormalIn + (Normal - NormalIn)*max(Strength, 0.0));
+}
+
diff --git a/intern/cycles/kernel/shaders/node_object_info.osl b/intern/cycles/kernel/shaders/node_object_info.osl
new file mode 100644
index 00000000000..c3b1ff29f09
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_object_info.osl
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#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)
+{
+ getattribute("object:location", Location);
+ getattribute("object:index", ObjectIndex);
+ getattribute("material:index", MaterialIndex);
+ getattribute("object:random", Random);
+}
+
diff --git a/intern/cycles/kernel/osl/nodes/node_output_displacement.osl b/intern/cycles/kernel/shaders/node_output_displacement.osl
index a6b452c532a..5649b879c5b 100644
--- a/intern/cycles/kernel/osl/nodes/node_output_displacement.osl
+++ b/intern/cycles/kernel/shaders/node_output_displacement.osl
@@ -20,6 +20,6 @@
displacement node_output_displacement(float Displacement = 0.0)
{
- P += N*Displacement*0.1; /* todo: get rid of this factor */
+ P += N * Displacement * 0.1; /* todo: get rid of this factor */
}
diff --git a/intern/cycles/kernel/osl/nodes/node_output_surface.osl b/intern/cycles/kernel/shaders/node_output_surface.osl
index 6efaf91121b..6efaf91121b 100644
--- a/intern/cycles/kernel/osl/nodes/node_output_surface.osl
+++ b/intern/cycles/kernel/shaders/node_output_surface.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_output_volume.osl b/intern/cycles/kernel/shaders/node_output_volume.osl
index 18094242dc7..18094242dc7 100644
--- a/intern/cycles/kernel/osl/nodes/node_output_volume.osl
+++ b/intern/cycles/kernel/shaders/node_output_volume.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_particle_info.osl b/intern/cycles/kernel/shaders/node_particle_info.osl
index aadc2812865..5e59ad1a990 100644
--- a/intern/cycles/kernel/osl/nodes/node_particle_info.osl
+++ b/intern/cycles/kernel/shaders/node_particle_info.osl
@@ -25,15 +25,14 @@ shader node_particle_info(
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)
- )
+ output vector AngularVelocity = point(0.0, 0.0, 0.0))
{
- getattribute("std::particle_index", Index);
- getattribute("std::particle_age", Age);
- getattribute("std::particle_lifetime", Lifetime);
- getattribute("std::particle_location", Location);
- getattribute("std::particle_size", Size);
- getattribute("std::particle_velocity", Velocity);
- getattribute("std::particle_angular_velocity", AngularVelocity);
+ getattribute("particle:index", Index);
+ 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_refraction_bsdf.osl b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
new file mode 100644
index 00000000000..0cf9d460c6e
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_refraction_bsdf.osl
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+shader node_refraction_bsdf(
+ color Color = color(0.8, 0.8, 0.8),
+ string distribution = "Sharp",
+ float Roughness = 0.2,
+ float IOR = 1.45,
+ normal Normal = N,
+ output closure color BSDF = diffuse(Normal))
+{
+ float f = max(IOR, 1.0 + 1e-5);
+ float eta = backfacing() ? 1.0 / f: f;
+
+ 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/osl/nodes/node_image_texture.osl b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
index 38126401d76..a128ebbd1cf 100644
--- a/intern/cycles/kernel/osl/nodes/node_image_texture.osl
+++ b/intern/cycles/kernel/shaders/node_rgb_ramp.osl
@@ -17,18 +17,27 @@
*/
#include "stdosl.h"
-#include "node_color.h"
+#include "oslutil.h"
-shader node_image_texture(
- point Vector = P,
- string filename = "",
- string color_space = "sRGB",
+shader node_rgb_ramp(
+ color ramp_color[RAMP_TABLE_SIZE] = {0.0},
+ float ramp_alpha[RAMP_TABLE_SIZE] = {0.0},
+
+ float Fac = 0.0,
output color Color = color(0.0, 0.0, 0.0),
output float Alpha = 1.0)
{
- Color = (color)texture(filename, Vector[0], 1.0-Vector[1], "wrap", "periodic", "alpha", Alpha);
+ float f = clamp(Fac, 0.0, 1.0) * (RAMP_TABLE_SIZE - 1);
+
+ int i = (int)f;
+ float t = f - (float)i;
+
+ Color = ramp_color[i];
+ Alpha = ramp_alpha[i];
- if(color_space == "sRGB")
- Color = color_srgb_to_scene_linear(Color);
+ if (t > 0.0) {
+ Color = (1.0 - t) * Color + t * ramp_color[i + 1];
+ Alpha = (1.0 - t) * Alpha + t * ramp_alpha[i + 1];
+ }
}
diff --git a/intern/cycles/kernel/osl/nodes/node_separate_rgb.osl b/intern/cycles/kernel/shaders/node_separate_rgb.osl
index b48bd7e59d6..b48bd7e59d6 100644
--- a/intern/cycles/kernel/osl/nodes/node_separate_rgb.osl
+++ b/intern/cycles/kernel/shaders/node_separate_rgb.osl
diff --git a/intern/cycles/kernel/shaders/node_set_normal.osl b/intern/cycles/kernel/shaders/node_set_normal.osl
new file mode 100644
index 00000000000..27a4b2f5b8b
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_set_normal.osl
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#include "stdosl.h"
+
+surface node_set_normal(
+ normal Direction = N,
+ output normal Normal = N)
+{
+ N = Direction;
+ Normal = Direction;
+}
+
diff --git a/intern/cycles/kernel/osl/nodes/node_sky_texture.osl b/intern/cycles/kernel/shaders/node_sky_texture.osl
index fdb9b1d9708..932fb1e2f17 100644
--- a/intern/cycles/kernel/osl/nodes/node_sky_texture.osl
+++ b/intern/cycles/kernel/shaders/node_sky_texture.osl
@@ -32,10 +32,10 @@ color xyY_to_xyz(float x, float y, float Y)
{
float X, Z;
- if(y != 0.0) X = (x / y) * Y;
+ 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;
+ if (y != 0.0 && Y != 0.0) Z = ((1.0 - x - y) / y) * Y;
else Z = 0.0;
return color(X, Y, Z);
@@ -50,11 +50,11 @@ color xyz_to_rgb(float x, float y, float z)
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)
+ if (cospsi > 1.0)
return 0.0;
- if(cospsi < -1.0)
+ if (cospsi < -1.0)
return M_PI;
return acos(cospsi);
@@ -70,7 +70,7 @@ float sky_perez_function(float lam[5], float theta, float 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_xyz_radiance(KernelSunSky sunsky, vector dir)
@@ -106,42 +106,42 @@ void precompute_sunsky(vector dir, float turbidity, output KernelSunSky sunsky)
sunsky.phi = phi;
sunsky.dir = dir;
- float theta2 = theta*theta;
- float theta3 = theta*theta*theta;
+ float theta2 = theta * theta;
+ float theta3 = theta * theta * theta;
float T = turbidity;
- float T2 = T*T;
+ float T2 = T * T;
- float chi = (4.0/ 9.0- T / 120.0) * (M_PI - 2.0* theta);
- sunsky.zenith_Y = (4.0453*T - 4.9710) * tan(chi) - 0.2155*T + 2.4192;
+ float chi = (4.0 / 9.0 - T / 120.0) * (M_PI - 2.0 * theta);
+ sunsky.zenith_Y = (4.0453 * T - 4.9710) * tan(chi) - 0.2155 * T + 2.4192;
sunsky.zenith_Y *= 0.06;
sunsky.zenith_x =
- (0.00166* theta3 - 0.00375* theta2 + 0.00209* theta)*T2 +
- (-0.02903* theta3 + 0.06377* theta2 - 0.03202* theta + 0.00394)*T +
- (0.11693* theta3 - 0.21196* theta2 + 0.06052* theta + 0.25886);
+ ( 0.00166 * theta3 - 0.00375 * theta2 + 0.00209 * theta) * T2 +
+ (-0.02903 * theta3 + 0.06377 * theta2 - 0.03202 * theta + 0.00394) * T +
+ ( 0.11693 * theta3 - 0.21196 * theta2 + 0.06052 * theta + 0.25886);
sunsky.zenith_y =
- (0.00275* theta3 - 0.00610* theta2 + 0.00317* theta)*T2 +
- (-0.04214* theta3 + 0.08970* theta2 - 0.04153* theta + 0.00516)*T +
- (0.15346* theta3 - 0.26756* theta2 + 0.06670* theta + 0.26688);
-
- sunsky.perez_Y[0] = (0.1787*T - 1.4630);
- sunsky.perez_Y[1] = (-0.3554*T + 0.4275);
- sunsky.perez_Y[2] = (-0.0227*T + 5.3251);
- sunsky.perez_Y[3] = (0.1206*T - 2.5771);
- sunsky.perez_Y[4] = (-0.0670*T + 0.3703);
-
- sunsky.perez_x[0] = (-0.0193*T - 0.2592);
- sunsky.perez_x[1] = (-0.0665*T + 0.0008);
- sunsky.perez_x[2] = (-0.0004*T + 0.2125);
- sunsky.perez_x[3] = (-0.0641*T - 0.8989);
- sunsky.perez_x[4] = (-0.0033*T + 0.0452);
-
- sunsky.perez_y[0] = (-0.0167*T - 0.2608);
- sunsky.perez_y[1] = (-0.0950*T + 0.0092);
- sunsky.perez_y[2] = (-0.0079*T + 0.2102);
- sunsky.perez_y[3] = (-0.0441*T - 1.6537);
- sunsky.perez_y[4] = (-0.0109*T + 0.0529);
+ ( 0.00275 * theta3 - 0.00610 * theta2 + 0.00317 * theta) * T2 +
+ (-0.04214 * theta3 + 0.08970 * theta2 - 0.04153 * theta + 0.00516) * T +
+ ( 0.15346 * theta3 - 0.26756 * theta2 + 0.06670 * theta + 0.26688);
+
+ sunsky.perez_Y[0] = ( 0.1787 * T - 1.4630);
+ sunsky.perez_Y[1] = (-0.3554 * T + 0.4275);
+ sunsky.perez_Y[2] = (-0.0227 * T + 5.3251);
+ sunsky.perez_Y[3] = ( 0.1206 * T - 2.5771);
+ sunsky.perez_Y[4] = (-0.0670 * T + 0.3703);
+
+ sunsky.perez_x[0] = (-0.0193 * T - 0.2592);
+ sunsky.perez_x[1] = (-0.0665 * T + 0.0008);
+ sunsky.perez_x[2] = (-0.0004 * T + 0.2125);
+ sunsky.perez_x[3] = (-0.0641 * T - 0.8989);
+ sunsky.perez_x[4] = (-0.0033 * T + 0.0452);
+
+ sunsky.perez_y[0] = (-0.0167 * T - 0.2608);
+ sunsky.perez_y[1] = (-0.0950 * T + 0.0092);
+ sunsky.perez_y[2] = (-0.0079 * T + 0.2102);
+ sunsky.perez_y[3] = (-0.0441 * T - 1.6537);
+ sunsky.perez_y[4] = (-0.0109 * T + 0.0529);
sunsky.zenith_Y /= sky_perez_function(sunsky.perez_Y, 0, theta);
sunsky.zenith_x /= sky_perez_function(sunsky.perez_x, 0, theta);
diff --git a/intern/cycles/kernel/shaders/node_tangent.osl b/intern/cycles/kernel/shaders/node_tangent.osl
new file mode 100644
index 00000000000..731af89231a
--- /dev/null
+++ b/intern/cycles/kernel/shaders/node_tangent.osl
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#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))
+{
+ vector T;
+
+ if (direction_type == "UV Map") {
+ getattribute(attr_name, T);
+ }
+ else if (direction_type == "Radial") {
+ point generated;
+
+ 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);
+ }
+
+ T = transform("object", "world", T);
+ Tangent = cross(NormalIn, normalize(cross(T, NormalIn)));
+}
+
diff --git a/intern/cycles/kernel/osl/nodes/node_texture.h b/intern/cycles/kernel/shaders/node_texture.h
index 7cd0742ffe8..1b3ba8207ab 100644
--- a/intern/cycles/kernel/osl/nodes/node_texture.h
+++ b/intern/cycles/kernel/shaders/node_texture.h
@@ -235,21 +235,21 @@ float noise_turbulence(point p, string basis, float details, int hard)
float rmd = octaves - floor(octaves);
- if(rmd != 0.0) {
- float t = noise_basis(fscale*p, basis);
+ if (rmd != 0.0) {
+ float t = noise_basis(fscale * p, basis);
- if(hard)
- t = fabs(2.0*t - 1.0);
+ if (hard)
+ t = fabs(2.0 * t - 1.0);
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));
+ sum *= ((float)(1 << n) / (float)((1 << (n + 1)) - 1));
return sum;
}
}
diff --git a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
index 2acf72aef54..791838dfffe 100644
--- a/intern/cycles/kernel/osl/nodes/node_texture_coordinate.osl
+++ b/intern/cycles/kernel/shaders/node_texture_coordinate.osl
@@ -19,8 +19,9 @@
#include "stdosl.h"
shader node_texture_coordinate(
- normal Normal = N,
+ normal NormalIn = N,
int is_background = 0,
+ int from_dupli = 0,
string bump_offset = "center",
output point Generated = point(0.0, 0.0, 0.0),
@@ -28,36 +29,50 @@ shader node_texture_coordinate(
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) {
+ 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);
Window = transform("NDC", P + Pcam);
+ Normal = NormalIn;
Reflection = I;
}
else {
- getattribute("std::generated", Generated);
- getattribute("std::uv", UV);
+ if (from_dupli) {
+ getattribute("geom:dupli_generated", Generated);
+ getattribute("geom:dupli_uv", UV);
+ }
+ else {
+ getattribute("geom:generated", Generated);
+ getattribute("geom:uv", UV);
+ }
+
Object = transform("object", P);
Camera = transform("camera", P);
Window = transform("NDC", P);
- Reflection = reflect(I, Normal);
+ Normal = transform("world", "object", NormalIn);
+ Reflection = reflect(I, NormalIn);
}
- if(bump_offset == "dx") {
- Generated += Dx(Generated);
- UV += Dx(UV);
+ 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") {
- Generated += Dy(Generated);
- UV += Dy(UV);
+ else if (bump_offset == "dy") {
+ if (!from_dupli) {
+ Generated += Dy(Generated);
+ UV += Dy(UV);
+ }
Object += Dy(Object);
Camera += Dy(Camera);
Window += Dy(Window);
diff --git a/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
index 9acd46756d2..e7efe73700c 100644
--- a/intern/cycles/kernel/osl/nodes/node_translucent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_translucent_bsdf.osl
@@ -23,6 +23,6 @@ shader node_translucent_bsdf(
normal Normal = N,
output closure color BSDF = diffuse(Normal))
{
- BSDF = Color*translucent(Normal);
+ BSDF = Color * translucent(Normal);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
index b347bfb116b..875bce3f16c 100644
--- a/intern/cycles/kernel/osl/nodes/node_transparent_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_transparent_bsdf.osl
@@ -23,6 +23,6 @@ shader node_transparent_bsdf(
normal Normal = N,
output closure color BSDF = diffuse(Normal))
{
- BSDF = Color*transparent();
+ BSDF = Color * transparent();
}
diff --git a/intern/cycles/kernel/osl/nodes/node_value.osl b/intern/cycles/kernel/shaders/node_value.osl
index bee6f39f2bc..bee6f39f2bc 100644
--- a/intern/cycles/kernel/osl/nodes/node_value.osl
+++ b/intern/cycles/kernel/shaders/node_value.osl
diff --git a/intern/cycles/kernel/osl/nodes/node_vector_math.osl b/intern/cycles/kernel/shaders/node_vector_math.osl
index 9e0f0b60522..f22a6e8441a 100644
--- a/intern/cycles/kernel/osl/nodes/node_vector_math.osl
+++ b/intern/cycles/kernel/shaders/node_vector_math.osl
@@ -25,27 +25,27 @@ shader node_vector_math(
output float Value = 0.0,
output vector Vector = vector(0.0, 0.0, 0.0))
{
- if(type == "Add") {
+ if (type == "Add") {
Vector = Vector1 + Vector2;
- Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2]))/3.0;
+ Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0;
}
- if(type == "Subtract") {
+ if (type == "Subtract") {
Vector = Vector1 - Vector2;
- Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2]))/3.0;
+ Value = (abs(Vector[0]) + abs(Vector[1]) + abs(Vector[2])) / 3.0;
}
- if(type == "Average") {
+ if (type == "Average") {
Value = length(Vector1 + Vector2);
Vector = normalize(Vector1 + Vector2);
}
- if(type == "Dot Product") {
+ if (type == "Dot Product") {
Value = dot(Vector1, Vector2);
}
- if(type == "Cross Product") {
+ if (type == "Cross Product") {
vector c = cross(Vector1, Vector2);
Value = length(c);
Vector = normalize(c);
}
- if(type == "Normalize") {
+ if (type == "Normalize") {
Value = length(Vector1);
Vector = normalize(Vector1);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
index 5e0cae8cbd1..3aa662bdd08 100644
--- a/intern/cycles/kernel/osl/nodes/node_velvet_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_velvet_bsdf.osl
@@ -27,6 +27,6 @@ shader node_velvet_bsdf(
{
float sigma = clamp(Sigma, 0.0, 1.0);
- BSDF = Color*ashikhmin_velvet(Normal, sigma, 1.0);
+ BSDF = Color * ashikhmin_velvet(Normal, sigma);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
index db08b64de1c..a44df00a267 100644
--- a/intern/cycles/kernel/osl/nodes/node_voronoi_texture.osl
+++ b/intern/cycles/kernel/shaders/node_voronoi_texture.osl
@@ -32,16 +32,16 @@ shader node_voronoi_texture(
float da[4];
point pa[4];
- voronoi(Vector*Scale, "Distance Squared", 1.0, da, pa);
+ voronoi(Vector * Scale, "Distance Squared", 1.0, da, pa);
/* Colored output */
- if(Coloring == "Intensity") {
+ if (Coloring == "Intensity") {
Fac = fabs(da[0]);
Color = color(Fac);
}
else {
Color = cellnoise_color(pa[0]);
- Fac = (Color[0]+Color[1]+Color[2])*(1.0/3.0);
+ Fac = (Color[0] + Color[1] + Color[2]) * (1.0 / 3.0);
}
}
diff --git a/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
index 68db07109ed..e5c6f0ad705 100644
--- a/intern/cycles/kernel/osl/nodes/node_ward_bsdf.osl
+++ b/intern/cycles/kernel/shaders/node_ward_bsdf.osl
@@ -20,11 +20,32 @@
shader node_ward_bsdf(
color Color = color(0.8, 0.8, 0.8),
- float RoughnessU = 0.0,
- float RoughnessV = 0.0,
+ float Roughness = 0.0,
+ float Anisotropy = 0.0,
+ float Rotation = 0.0,
normal Normal = N,
+ normal Tangent = normalize(dPdu),
output closure color BSDF = diffuse(Normal))
{
- BSDF = Color*ward(Normal, normalize(dPdu), RoughnessU, RoughnessV);
+ /* rotate tangent around normal */
+ vector T = Tangent;
+
+ if(Rotation != 0.0)
+ T = rotate(T, Rotation*2.0*M_PI, point(0.0, 0.0, 0.0), Normal);
+
+ /* compute roughness */
+ float RoughnessU, RoughnessV;
+ float aniso = clamp(Anisotropy, -0.99, 0.99);
+
+ if(aniso < 0.0) {
+ RoughnessU = Roughness/(1.0 + aniso);
+ RoughnessV = Roughness*(1.0 + aniso);
+ }
+ else {
+ RoughnessU = Roughness*(1.0 - aniso);
+ RoughnessV = Roughness/(1.0 - aniso);
+ }
+
+ BSDF = Color * ward(Normal, T, RoughnessU, RoughnessV);
}
diff --git a/intern/cycles/kernel/osl/nodes/node_wave_texture.osl b/intern/cycles/kernel/shaders/node_wave_texture.osl
index db53faaf94b..79b8a8885d1 100644
--- a/intern/cycles/kernel/osl/nodes/node_wave_texture.osl
+++ b/intern/cycles/kernel/shaders/node_wave_texture.osl
@@ -30,15 +30,15 @@ float wave(point p, float scale, string type, float detail, float distortion, fl
float result = 0.0;
float n = 0.0;
- if(type == "Bands") {
- n = (x + y + z)*10.0;
+ if (type == "Bands") {
+ n = (x + y + z) * 10.0;
}
- else if(type == "Rings") {
- n = (sqrt(x*x + y*y + z*z)*20.0);
+ else if (type == "Rings") {
+ n = (sqrt(x * x + y * y + z * z) * 20.0);
}
-
- if(distortion != 0.0) {
- n = n +(distortion * noise_turbulence(p*dscale, "Perlin", detail, 0));
+
+ if (distortion != 0.0) {
+ n = n + (distortion * noise_turbulence(p * dscale, "Perlin", detail, 0));
}
result = noise_wave("Sine", n);
diff --git a/intern/cycles/kernel/osl/nodes/oslutil.h b/intern/cycles/kernel/shaders/oslutil.h
index 6c91684d9a6..6c91684d9a6 100644
--- a/intern/cycles/kernel/osl/nodes/oslutil.h
+++ b/intern/cycles/kernel/shaders/oslutil.h
diff --git a/intern/cycles/kernel/osl/nodes/stdosl.h b/intern/cycles/kernel/shaders/stdosl.h
index e5accf4eb54..24c3a50e6f6 100644
--- a/intern/cycles/kernel/osl/nodes/stdosl.h
+++ b/intern/cycles/kernel/shaders/stdosl.h
@@ -433,82 +433,21 @@ string concat (string a, string b, string c, string d, string e, string f) {
closure color diffuse(normal N) BUILTIN;
closure color oren_nayar(normal N, float sigma) BUILTIN;
+closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
closure color translucent(normal N) BUILTIN;
-closure color reflection(normal N, float eta) BUILTIN;
-closure color reflection(normal N) { return reflection (N, 0.0); }
+closure color reflection(normal N) BUILTIN;
closure color refraction(normal N, float eta) BUILTIN;
-closure color dielectric(normal N, float eta) BUILTIN;
closure color transparent() BUILTIN;
-closure color microfacet_ggx(normal N, float ag, float eta) BUILTIN;
+closure color microfacet_ggx(normal N, float ag) BUILTIN;
closure color microfacet_ggx_refraction(normal N, float ag, float eta) BUILTIN;
-closure color microfacet_beckmann(normal N, float ab, float eta) BUILTIN;
+closure color microfacet_beckmann(normal N, float ab) BUILTIN;
closure color microfacet_beckmann_refraction(normal N, float ab, float eta) BUILTIN;
closure color ward(normal N, vector T,float ax, float ay) BUILTIN;
-closure color phong(normal N, float exponent) BUILTIN;
-closure color phong_ramp(normal N, float exponent, color colors[8]) BUILTIN;
-closure color hair_diffuse(vector T) BUILTIN;
-closure color hair_specular(vector T, float offset, float exponent) BUILTIN;
-closure color ashikhmin_velvet(normal N, float sigma, float eta) BUILTIN;
-closure color westin_backscatter(normal N, float roughness) BUILTIN;
-closure color westin_sheen(normal N, float edginess) BUILTIN;
-closure color bssrdf_cubic(color radius) BUILTIN;
-closure color emission(float inner_angle, float outer_angle) BUILTIN;
-closure color emission(float outer_angle) BUILTIN;
+closure color ashikhmin_velvet(normal N, float sigma) BUILTIN;
closure color emission() BUILTIN;
-closure color debug(string tag) BUILTIN;
closure color background() BUILTIN;
closure color holdout() BUILTIN;
-closure color subsurface(float eta, float g, color mfp, color albedo) BUILTIN;
-
-closure color cloth(normal N, float s, float t, float dsdx, float dtdx, float dsdy, float dtdy,
- float area_scaled, vector dPdu, color diff_warp_col, color diff_weft_col,
- color spec_warp_col, color spec_weft_col, float fresnel_warp, float fresnel_weft,
- float spread_x_mult, float spread_y_mult, int pattern, float pattern_angle,
- float warp_width_scale, float weft_width_scale, float thread_count_mult_u,
- float thread_count_mult_v) BUILTIN;
-closure color cloth_specular(normal N, color spec_col[4], float eta[4], int thread_pattern[4],
- float pattern_weight[4], int current_thread, float brdf_interp,
- float btf_interp, float uux, float vvx, float area_scaled, vector dPdu,
- float eccentricity[4], float angle[4], float Kx[4], float Ky[4],
- float Sx[4], float Sy[4]) BUILTIN;
-closure color fakefur_diffuse(normal N, vector T, float fur_reflectivity, float fur_transmission,
- float shadow_start, float shadow_end, float fur_attenuation, float fur_density,
- float fur_avg_radius, float fur_length, float fur_shadow_fraction) BUILTIN;
-closure color fakefur_specular(normal N, vector T, float offset, float exp, float fur_reflectivity,
- float fur_transmission, float shadow_start, float shadow_end,
- float fur_attenuation, float fur_density, float fur_avg_radius,
- float fur_length, float fur_shadow_fraction) BUILTIN;
-
-closure color fakefur_skin(vector N, vector T, float fur_reflectivity, float fur_transmission,
- float shadow_start, float shadow_end, float fur_attenuation, float fur_density,
- float fur_avg_radius, float fur_length) BUILTIN;
-
-
-closure color cloth(normal N, float s, float t, color diff_warp, color diff_weft,
- color spec_warp, color spec_weft, float fresnel_warp, float fresnel_weft,
- float spread_x_mult, float spread_y_mult, int pattern, float pattern_angle,
- float warp_width_scale, float weft_width_scale, float thread_count_mult_u,
- float thread_count_mult_v)
-{
-
- return cloth(N, s, t, Dx(s), Dx(t), Dy(s), Dy(t), area(P), dPdu, diff_warp, diff_weft, spec_warp, spec_weft,
- fresnel_warp, fresnel_weft, spread_x_mult, spread_y_mult, pattern, pattern_angle,
- warp_width_scale, weft_width_scale, thread_count_mult_u, thread_count_mult_v);
-}
-
-closure color cloth(normal N, float s, float t, color diff_warp, color diff_weft,
- color spec_warp, color spec_weft, float fresnel_warp, float fresnel_weft,
- float spread_x_mult, float spread_y_mult, int pattern, float pattern_angle,
- float warp_width_scale, float weft_width_scale, float thread_count_mult_u,
- float thread_count_mult_v, string tok, string val)
-{
-
- return cloth(N, s, t, Dx(s), Dx(t), Dy(s), Dy(t), area(P), dPdu, diff_warp, diff_weft, spec_warp, spec_weft,
- fresnel_warp, fresnel_weft, spread_x_mult, spread_y_mult, pattern, pattern_angle,
- warp_width_scale, weft_width_scale, thread_count_mult_u, thread_count_mult_v, tok, val);
-}
-
-
+closure color ambient_occlusion() BUILTIN;
// Renderer state
int raytype (string typename) BUILTIN;
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 5b0f192ea47..886fce63fd4 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -82,6 +82,25 @@ __device_inline void stack_store_float(float *stack, uint a, float f)
stack[a] = f;
}
+__device_inline int stack_load_int(float *stack, uint a)
+{
+ kernel_assert(a < SVM_STACK_SIZE);
+
+ return __float_as_int(stack[a]);
+}
+
+__device_inline float stack_load_int_default(float *stack, uint a, uint value)
+{
+ return (a == (uint)SVM_STACK_INVALID)? (int)value: stack_load_int(stack, a);
+}
+
+__device_inline void stack_store_int(float *stack, uint a, int i)
+{
+ kernel_assert(a < SVM_STACK_SIZE);
+
+ stack[a] = __int_as_float(i);
+}
+
__device_inline bool stack_valid(uint a)
{
return a != (uint)SVM_STACK_INVALID;
@@ -185,7 +204,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
break;
}
case NODE_CLOSURE_BSDF:
- svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag);
+ svm_node_closure_bsdf(kg, sd, stack, node, randb, path_flag, &offset);
break;
case NODE_CLOSURE_EMISSION:
svm_node_closure_emission(sd, stack, node);
@@ -196,6 +215,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_CLOSURE_HOLDOUT:
svm_node_closure_holdout(sd, stack, node);
break;
+ case NODE_CLOSURE_AMBIENT_OCCLUSION:
+ svm_node_closure_ambient_occlusion(sd, stack, node);
+ break;
case NODE_CLOSURE_VOLUME:
svm_node_closure_volume(kg, sd, stack, node, path_flag);
break;
@@ -261,14 +283,14 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
svm_node_camera(kg, sd, stack, node.y, node.z, node.w);
break;
case NODE_GEOMETRY:
- svm_node_geometry(sd, stack, node.y, node.z);
+ svm_node_geometry(kg, sd, stack, node.y, node.z);
break;
#ifdef __EXTRA_NODES__
case NODE_GEOMETRY_BUMP_DX:
- svm_node_geometry_bump_dx(sd, stack, node.y, node.z);
+ svm_node_geometry_bump_dx(kg, sd, stack, node.y, node.z);
break;
case NODE_GEOMETRY_BUMP_DY:
- svm_node_geometry_bump_dy(sd, stack, node.y, node.z);
+ svm_node_geometry_bump_dy(kg, sd, stack, node.y, node.z);
break;
case NODE_LIGHT_PATH:
svm_node_light_path(sd, stack, node.y, node.z, path_flag);
@@ -334,7 +356,7 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
svm_node_set_displacement(sd, stack, node.y);
break;
case NODE_SET_BUMP:
- svm_node_set_bump(sd, stack, node.y, node.z, node.w);
+ svm_node_set_bump(kg, sd, stack, node);
break;
case NODE_MATH:
svm_node_math(kg, sd, stack, node.y, node.z, node.w, &offset);
@@ -362,6 +384,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_TEX_COORD_BUMP_DY:
svm_node_tex_coord_bump_dy(kg, sd, stack, node.y, node.z);
break;
+ case NODE_CLOSURE_SET_NORMAL:
+ svm_node_set_normal(kg, sd, stack, node.y, node.z );
+ break;
#endif
case NODE_EMISSION_SET_WEIGHT_TOTAL:
svm_node_emission_set_weight_total(kg, sd, node.y, node.z, node.w);
@@ -376,7 +401,13 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_LIGHT_FALLOFF:
svm_node_light_falloff(sd, stack, node);
break;
-#endif
+ case NODE_TANGENT:
+ svm_node_tangent(kg, sd, stack, node);
+ break;
+ case NODE_NORMAL_MAP:
+ svm_node_normal_map(kg, sd, stack, node);
+ break;
+#endif
case NODE_END:
default:
#ifndef __MULTI_CLOSURE__
diff --git a/intern/cycles/kernel/svm/svm_bsdf.h b/intern/cycles/kernel/svm/svm_bsdf.h
index 411916f8aa0..373710446e5 100644
--- a/intern/cycles/kernel/svm/svm_bsdf.h
+++ b/intern/cycles/kernel/svm/svm_bsdf.h
@@ -16,17 +16,18 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
-#include "bsdf_ashikhmin_velvet.h"
-#include "bsdf_diffuse.h"
-#include "bsdf_oren_nayar.h"
-#include "bsdf_microfacet.h"
-#include "bsdf_reflection.h"
-#include "bsdf_refraction.h"
-#include "bsdf_transparent.h"
+#include "../closure/bsdf_ashikhmin_velvet.h"
+#include "../closure/bsdf_diffuse.h"
+#include "../closure/bsdf_oren_nayar.h"
+#include "../closure/bsdf_phong_ramp.h"
+#include "../closure/bsdf_microfacet.h"
+#include "../closure/bsdf_reflection.h"
+#include "../closure/bsdf_refraction.h"
+#include "../closure/bsdf_transparent.h"
#ifdef __DPDU__
-#include "bsdf_ward.h"
+#include "../closure/bsdf_ward.h"
#endif
-#include "bsdf_westin.h"
+#include "../closure/bsdf_westin.h"
CCL_NAMESPACE_BEGIN
@@ -36,45 +37,61 @@ __device int svm_bsdf_sample(const ShaderData *sd, const ShaderClosure *sc, floa
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- label = bsdf_diffuse_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ 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(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ 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;
+ /*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_TRANSLUCENT_ID:
- label = bsdf_translucent_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ 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(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ 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(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ 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(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ 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_REFRACTION_ID:
- label = bsdf_microfacet_ggx_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_microfacet_ggx_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_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- label = bsdf_microfacet_beckmann_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_microfacet_beckmann_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 __DPDU__
case CLOSURE_BSDF_WARD_ID:
- label = bsdf_ward_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_ward_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_ASHIKHMIN_VELVET_ID:
- label = bsdf_ashikhmin_velvet_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ 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_WESTIN_BACKSCATTER_ID:
- label = bsdf_westin_backscatter_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_westin_backscatter_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_WESTIN_SHEEN_ID:
- label = bsdf_westin_sheen_sample(sd, sc, randu, randv, eval, omega_in, &domega_in->dx, &domega_in->dy, pdf);
+ label = bsdf_westin_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
default:
@@ -92,45 +109,48 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con
if(dot(sd->Ng, omega_in) >= 0.0f) {
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ 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(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_oren_nayar_eval_reflect(sc, sd->I, omega_in, pdf);
break;
+ /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+ eval = bsdf_phong_ramp_eval_reflect(sc, sd->I, omega_in, pdf);
+ break;*/
case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_translucent_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_reflection_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_refraction_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_transparent_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_ggx_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_beckmann_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_ward_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_ashikhmin_velvet_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_westin_backscatter_eval_reflect(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_reflect(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_westin_sheen_eval_reflect(sc, sd->I, omega_in, pdf);
break;
#endif
default:
@@ -141,45 +161,45 @@ __device float3 svm_bsdf_eval(const ShaderData *sd, const ShaderClosure *sc, con
else {
switch(sc->type) {
case CLOSURE_BSDF_DIFFUSE_ID:
- eval = bsdf_diffuse_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ 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(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_oren_nayar_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSLUCENT_ID:
- eval = bsdf_translucent_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_translucent_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFLECTION_ID:
- eval = bsdf_reflection_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_reflection_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_REFRACTION_ID:
- eval = bsdf_refraction_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_refraction_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_TRANSPARENT_ID:
- eval = bsdf_transparent_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_transparent_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_GGX_ID:
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID:
- eval = bsdf_microfacet_ggx_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_ggx_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_MICROFACET_BECKMANN_ID:
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID:
- eval = bsdf_microfacet_beckmann_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_microfacet_beckmann_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#ifdef __DPDU__
case CLOSURE_BSDF_WARD_ID:
- eval = bsdf_ward_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_ward_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID:
- eval = bsdf_ashikhmin_velvet_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_ashikhmin_velvet_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_BACKSCATTER_ID:
- eval = bsdf_westin_backscatter_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_westin_backscatter_eval_transmit(sc, sd->I, omega_in, pdf);
break;
case CLOSURE_BSDF_WESTIN_SHEEN_ID:
- eval = bsdf_westin_sheen_eval_transmit(sd, sc, sd->I, omega_in, pdf);
+ eval = bsdf_westin_sheen_eval_transmit(sc, sd->I, omega_in, pdf);
break;
#endif
default:
@@ -201,6 +221,9 @@ __device void svm_bsdf_blur(ShaderClosure *sc, float roughness)
case CLOSURE_BSDF_OREN_NAYAR_ID:
bsdf_oren_nayar_blur(sc, roughness);
break;
+ /*case CLOSURE_BSDF_PHONG_RAMP_ID:
+ bsdf_phong_ramp_blur(sc, roughness);
+ break;*/
case CLOSURE_BSDF_TRANSLUCENT_ID:
bsdf_translucent_blur(sc, roughness);
break;
diff --git a/intern/cycles/kernel/svm/svm_closure.h b/intern/cycles/kernel/svm/svm_closure.h
index 935504026ef..f378d24463d 100644
--- a/intern/cycles/kernel/svm/svm_closure.h
+++ b/intern/cycles/kernel/svm/svm_closure.h
@@ -20,19 +20,34 @@ CCL_NAMESPACE_BEGIN
/* Closure Nodes */
-__device void svm_node_glossy_setup(ShaderData *sd, ShaderClosure *sc, int type, float eta, float roughness, bool refract)
+__device void svm_node_glass_setup(ShaderData *sd, ShaderClosure *sc, int type, float eta, float roughness, bool refract)
{
- if(type == CLOSURE_BSDF_REFRACTION_ID) {
+ if(type == CLOSURE_BSDF_SHARP_GLASS_ID) {
+ if(refract) {
+ sc->data0 = eta;
+ sd->flag |= bsdf_refraction_setup(sc);
+ }
+ else
+ sd->flag |= bsdf_reflection_setup(sc);
+ }
+ else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID) {
+ sc->data0 = roughness;
+ sc->data1 = eta;
+
if(refract)
- bsdf_refraction_setup(sd, sc, eta);
+ sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
else
- bsdf_reflection_setup(sd, sc);
+ sd->flag |= bsdf_microfacet_beckmann_setup(sc);
}
- else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID) {
- bsdf_microfacet_beckmann_setup(sd, sc, roughness, eta, refract);
+ else {
+ sc->data0 = roughness;
+ sc->data1 = eta;
+
+ if(refract)
+ sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
+ else
+ sd->flag |= bsdf_microfacet_ggx_setup(sc);
}
- else
- bsdf_microfacet_ggx_setup(sd, sc, roughness, eta, refract);
}
__device_inline ShaderClosure *svm_node_closure_get(ShaderData *sd)
@@ -57,7 +72,7 @@ __device_inline void svm_node_closure_set_mix_weight(ShaderClosure *sc, float mi
#endif
}
-__device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag)
+__device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node, float randb, int path_flag, int *offset)
{
uint type, param1_offset, param2_offset;
@@ -66,11 +81,19 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
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);
+
if(mix_weight == 0.0f)
return;
+
+ float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N;
#else
decode_node_uchar4(node.y, &type, &param1_offset, &param2_offset, NULL);
float mix_weight = 1.0f;
+
+ uint4 data_node = read_node(kg, offset);
+ float3 N = stack_valid(data_node.y)? stack_load_float3(stack, data_node.y): sd->N;
#endif
float param1 = (stack_valid(param1_offset))? stack_load_float(stack, param1_offset): __int_as_float(node.z);
@@ -79,25 +102,32 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
switch(type) {
case CLOSURE_BSDF_DIFFUSE_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
float roughness = param1;
- if(roughness == 0.0f)
- bsdf_diffuse_setup(sd, sc);
- else
- bsdf_oren_nayar_setup(sd, sc, roughness);
+
+ if(roughness == 0.0f) {
+ sd->flag |= bsdf_diffuse_setup(sc);
+ }
+ else {
+ sc->data0 = roughness;
+ sd->flag |= bsdf_oren_nayar_setup(sc);
+ }
break;
}
case CLOSURE_BSDF_TRANSLUCENT_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
- bsdf_translucent_setup(sd, sc);
+ sd->flag |= bsdf_translucent_setup(sc);
break;
}
case CLOSURE_BSDF_TRANSPARENT_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
- bsdf_transparent_setup(sd, sc);
+ sd->flag |= bsdf_transparent_setup(sc);
break;
}
case CLOSURE_BSDF_REFLECTION_ID:
@@ -108,17 +138,17 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
break;
#endif
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
+ sc->data0 = param1;
svm_node_closure_set_mix_weight(sc, mix_weight);
- float roughness = param1;
-
/* setup bsdf */
if(type == CLOSURE_BSDF_REFLECTION_ID)
- bsdf_reflection_setup(sd, sc);
+ sd->flag |= bsdf_reflection_setup(sc);
else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_ID)
- bsdf_microfacet_beckmann_setup(sd, sc, roughness, 1.0f, false);
+ sd->flag |= bsdf_microfacet_beckmann_setup(sc);
else
- bsdf_microfacet_ggx_setup(sd, sc, roughness, 1.0f, false);
+ sd->flag |= bsdf_microfacet_ggx_setup(sc);
break;
}
@@ -129,40 +159,68 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
if(kernel_data.integrator.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
break;
#endif
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
+ sc->data0 = param1;
+ svm_node_closure_set_mix_weight(sc, mix_weight);
+
+ float eta = fmaxf(param2, 1.0f + 1e-5f);
+ sc->data1 = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
+
+ /* setup bsdf */
+ if(type == CLOSURE_BSDF_REFRACTION_ID)
+ sd->flag |= bsdf_refraction_setup(sc);
+ else if(type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID)
+ sd->flag |= bsdf_microfacet_beckmann_refraction_setup(sc);
+ else
+ sd->flag |= bsdf_microfacet_ggx_refraction_setup(sc);
+
+ 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.no_caustics && (path_flag & PATH_RAY_DIFFUSE))
+ break;
+#endif
/* index of refraction */
float eta = fmaxf(param2, 1.0f + 1e-5f);
eta = (sd->flag & SD_BACKFACING)? 1.0f/eta: eta;
/* fresnel */
- float cosNO = dot(sd->N, sd->I);
+ float cosNO = dot(N, sd->I);
float fresnel = fresnel_dielectric_cos(cosNO, eta);
float roughness = param1;
#ifdef __MULTI_CLOSURE__
/* reflection */
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
float3 weight = sc->weight;
float sample_weight = sc->sample_weight;
svm_node_closure_set_mix_weight(sc, mix_weight*fresnel);
- svm_node_glossy_setup(sd, sc, type, eta, roughness, false);
+ svm_node_glass_setup(sd, sc, type, eta, roughness, false);
/* refraction */
sc = svm_node_closure_get(sd);
+ sc->N = N;
sc->weight = weight;
sc->sample_weight = sample_weight;
svm_node_closure_set_mix_weight(sc, mix_weight*(1.0f - fresnel));
- svm_node_glossy_setup(sd, sc, type, eta, roughness, true);
+ svm_node_glass_setup(sd, sc, type, eta, roughness, true);
#else
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
bool refract = (randb > fresnel);
svm_node_closure_set_mix_weight(sc, mix_weight);
- svm_node_glossy_setup(sd, sc, type, eta, roughness, refract);
+ svm_node_glass_setup(sd, sc, type, eta, roughness, refract);
#endif
break;
@@ -174,22 +232,41 @@ __device void svm_node_closure_bsdf(KernelGlobals *kg, ShaderData *sd, float *st
break;
#endif
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
+ sc->T = stack_load_float3(stack, data_node.z);
svm_node_closure_set_mix_weight(sc, mix_weight);
- float roughness_u = param1;
- float roughness_v = param2;
+ /* rotate tangent */
+ float rotation = stack_load_float(stack, data_node.w);
- bsdf_ward_setup(sd, sc, normalize(sd->dPdu), roughness_u, roughness_v);
+ if(rotation != 0.0f)
+ sc->T = rotate_around_axis(sc->T, sc->N, rotation * 2.0f * M_PI_F);
+
+ /* compute roughness */
+ float roughness = param1;
+ float anisotropy = clamp(param2, -0.99f, 0.99f);
+
+ if(anisotropy < 0.0f) {
+ sc->data0 = roughness/(1.0f + anisotropy);
+ sc->data1 = roughness*(1.0f + anisotropy);
+ }
+ else {
+ sc->data0 = roughness*(1.0f - anisotropy);
+ sc->data1 = roughness/(1.0f - anisotropy);
+ }
+
+ sd->flag |= bsdf_ward_setup(sc);
break;
}
#endif
case CLOSURE_BSDF_ASHIKHMIN_VELVET_ID: {
ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->N = N;
svm_node_closure_set_mix_weight(sc, mix_weight);
/* sigma */
- float sigma = clamp(param1, 0.0f, 1.0f);
- bsdf_ashikhmin_velvet_setup(sd, sc, sigma);
+ sc->data0 = clamp(param1, 0.0f, 1.0f);
+ sd->flag |= bsdf_ashikhmin_velvet_setup(sc);
break;
}
default:
@@ -222,7 +299,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *
svm_node_closure_set_mix_weight(sc, mix_weight);
float density = param1;
- volume_transparent_setup(sd, sc, density);
+ sd->flag |= volume_transparent_setup(sc, density);
break;
}
case CLOSURE_VOLUME_ISOTROPIC_ID: {
@@ -230,7 +307,7 @@ __device void svm_node_closure_volume(KernelGlobals *kg, ShaderData *sd, float *
svm_node_closure_set_mix_weight(sc, mix_weight);
float density = param1;
- volume_isotropic_setup(sd, sc, density);
+ sd->flag |= volume_isotropic_setup(sc, density);
break;
}
default:
@@ -320,6 +397,34 @@ __device void svm_node_closure_holdout(ShaderData *sd, float *stack, uint4 node)
sd->flag |= SD_HOLDOUT;
}
+__device void svm_node_closure_ambient_occlusion(ShaderData *sd, float *stack, uint4 node)
+{
+#ifdef __MULTI_CLOSURE__
+ uint mix_weight_offset = node.y;
+
+ if(stack_valid(mix_weight_offset)) {
+ float mix_weight = stack_load_float(stack, mix_weight_offset);
+
+ if(mix_weight == 0.0f)
+ return;
+
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->weight *= mix_weight;
+ sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
+ }
+ else {
+ ShaderClosure *sc = svm_node_closure_get(sd);
+ sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
+ }
+
+#else
+ ShaderClosure *sc = &sd->closure;
+ sc->type = CLOSURE_AMBIENT_OCCLUSION_ID;
+#endif
+
+ sd->flag |= SD_AO;
+}
+
/* Closure Nodes */
__device_inline void svm_node_closure_store_weight(ShaderData *sd, float3 weight)
@@ -425,5 +530,14 @@ __device void svm_node_add_closure(ShaderData *sd, float *stack, uint unused,
#endif
}
+/* (Bump) normal */
+
+__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);
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_convert.h b/intern/cycles/kernel/svm/svm_convert.h
index 188b0489d9e..f74915a4bc9 100644
--- a/intern/cycles/kernel/svm/svm_convert.h
+++ b/intern/cycles/kernel/svm/svm_convert.h
@@ -23,6 +23,11 @@ CCL_NAMESPACE_BEGIN
__device void svm_node_convert(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, (int)f);
+ break;
+ }
case NODE_CONVERT_FV: {
float f = stack_load_float(stack, from);
stack_store_float3(stack, to, make_float3(f, f, f));
@@ -34,13 +39,34 @@ __device void svm_node_convert(ShaderData *sd, float *stack, uint type, uint fro
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(f);
+ stack_store_int(stack, to, i);
+ break;
+ }
case NODE_CONVERT_VF: {
float3 f = stack_load_float3(stack, from);
float g = (f.x + f.y + f.z)*(1.0f/3.0f);
stack_store_float(stack, to, g);
break;
}
-
+ case NODE_CONVERT_VI: {
+ float3 f = stack_load_float3(stack, from);
+ int i = (f.x + f.y + f.z)*(1.0f/3.0f);
+ 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;
+ }
}
}
diff --git a/intern/cycles/kernel/svm/svm_displace.h b/intern/cycles/kernel/svm/svm_displace.h
index b1677f67eca..92f23990ad1 100644
--- a/intern/cycles/kernel/svm/svm_displace.h
+++ b/intern/cycles/kernel/svm/svm_displace.h
@@ -20,23 +20,35 @@ CCL_NAMESPACE_BEGIN
/* Bump Node */
-__device void svm_node_set_bump(ShaderData *sd, float *stack, uint c_offset, uint x_offset, uint y_offset)
+__device void svm_node_set_bump(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
{
#ifdef __RAY_DIFFERENTIALS__
+ /* get normal input */
+ float3 normal_in = stack_valid(node.y)? stack_load_float3(stack, node.y): sd->N;
+
+ /* get surface tangents from normal */
+ float3 Rx = cross(sd->dP.dy, normal_in);
+ float3 Ry = cross(normal_in, sd->dP.dx);
+
+ /* get bump values */
+ uint c_offset, x_offset, y_offset, intensity_offset;
+ decode_node_uchar4(node.z, &c_offset, &x_offset, &y_offset, &intensity_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);
- float3 Rx = cross(sd->dP.dy, sd->N);
- float3 Ry = cross(sd->N, sd->dP.dx);
-
+ /* compute surface gradient and determinant */
float det = dot(sd->dP.dx, Rx);
float3 surfgrad = (h_x - h_c)*Rx + (h_y - h_c)*Ry;
+ float intensity = stack_load_float(stack, intensity_offset);
- surfgrad *= 0.1f; /* todo: remove this factor */
-
+ surfgrad *= intensity;
float absdet = fabsf(det);
- sd->N = normalize(absdet*sd->N - signf(det)*surfgrad);
+
+ /* compute and output perturbed normal */
+ float3 outN = normalize(absdet*normal_in - signf(det)*surfgrad);
+ stack_store_float3(stack, node.w, outN);
#endif
}
diff --git a/intern/cycles/kernel/svm/svm_fresnel.h b/intern/cycles/kernel/svm/svm_fresnel.h
index 7684eabeecb..d5b415a87ce 100644
--- a/intern/cycles/kernel/svm/svm_fresnel.h
+++ b/intern/cycles/kernel/svm/svm_fresnel.h
@@ -54,7 +54,7 @@ __device void svm_node_layer_weight(ShaderData *sd, float *stack, uint4 node)
f = fabsf(dot(sd->I, sd->N));
if(blend != 0.5f) {
- blend = clamp(blend, 0.0f, 1.0f);
+ 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);
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index 22741bdb067..c4d03c1f948 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -20,7 +20,7 @@ CCL_NAMESPACE_BEGIN
/* Geometry Node */
-__device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint out_offset)
+__device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
float3 data;
@@ -28,7 +28,23 @@ __device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint ou
case NODE_GEOM_P: data = sd->P; break;
case NODE_GEOM_N: data = sd->N; break;
#ifdef __DPDU__
- case NODE_GEOM_T: data = normalize(sd->dPdu); break;
+ case NODE_GEOM_T: {
+ /* try to create spherical tangent from generated coordinates */
+ int attr_offset = (sd->object != ~0)? find_attribute(kg, sd, ATTR_STD_GENERATED): ATTR_STD_NOT_FOUND;
+
+ if(attr_offset != ATTR_STD_NOT_FOUND) {
+ data = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
+ data = make_float3(-(data.y - 0.5f), (data.x - 0.5f), 0.0f);
+ object_normal_transform(kg, sd, &data);
+ data = cross(sd->N, normalize(cross(data, sd->N)));;
+ }
+ else {
+ /* otherwise use surface derivatives */
+ data = normalize(sd->dPdu);
+ }
+
+ break;
+ }
#endif
case NODE_GEOM_I: data = sd->I; break;
case NODE_GEOM_Ng: data = sd->Ng; break;
@@ -40,7 +56,7 @@ __device void svm_node_geometry(ShaderData *sd, float *stack, uint type, uint ou
stack_store_float3(stack, out_offset, data);
}
-__device void svm_node_geometry_bump_dx(ShaderData *sd, float *stack, uint type, uint out_offset)
+__device void svm_node_geometry_bump_dx(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
#ifdef __RAY_DIFFERENTIALS__
float3 data;
@@ -48,16 +64,16 @@ __device void svm_node_geometry_bump_dx(ShaderData *sd, float *stack, uint type,
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(sd, stack, type, out_offset); return;
+ default: svm_node_geometry(kg, sd, stack, type, out_offset); return;
}
stack_store_float3(stack, out_offset, data);
#else
- svm_node_geometry(sd, stack, type, out_offset);
+ svm_node_geometry(kg, sd, stack, type, out_offset);
#endif
}
-__device void svm_node_geometry_bump_dy(ShaderData *sd, float *stack, uint type, uint out_offset)
+__device void svm_node_geometry_bump_dy(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
#ifdef __RAY_DIFFERENTIALS__
float3 data;
@@ -65,12 +81,12 @@ __device void svm_node_geometry_bump_dy(ShaderData *sd, float *stack, uint type,
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(sd, stack, type, out_offset); return;
+ default: svm_node_geometry(kg, sd, stack, type, out_offset); return;
}
stack_store_float3(stack, out_offset, data);
#else
- svm_node_geometry(sd, stack, type, out_offset);
+ svm_node_geometry(kg, sd, stack, type, out_offset);
#endif
}
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 662419418e3..0894c9c8290 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -52,6 +52,12 @@ __device_inline float svm_image_texture_frac(float x, int *ix)
__device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y, uint srgb)
{
+ /* first slots are used by float textures, which are not supported here */
+ if(id < TEX_NUM_FLOAT_IMAGES)
+ return make_float4(1.0f, 0.0f, 1.0f, 1.0f);
+
+ id -= TEX_NUM_FLOAT_IMAGES;
+
uint4 info = kernel_tex_fetch(__tex_image_packed_info, id);
uint width = info.x;
uint height = info.y;
@@ -265,7 +271,7 @@ __device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float *s
* 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
+ * 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 */
diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h
index 6bd8f2ac69c..8ca7dff3970 100644
--- a/intern/cycles/kernel/svm/svm_tex_coord.h
+++ b/intern/cycles/kernel/svm/svm_tex_coord.h
@@ -225,5 +225,100 @@ __device void svm_node_tex_coord_bump_dy(KernelGlobals *kg, ShaderData *sd, floa
#endif
}
+__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);
+
+ float3 N;
+
+ if(space == NODE_NORMAL_MAP_TANGENT) {
+ /* tangent space */
+ if(sd->object == ~0) {
+ stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
+ return;
+ }
+
+ /* first try to get tangent attribute */
+ int attr_offset = find_attribute(kg, sd, node.z);
+ int attr_sign_offset = find_attribute(kg, sd, node.w);
+
+ if(attr_offset == ATTR_STD_NOT_FOUND || attr_sign_offset == ATTR_STD_NOT_FOUND) {
+ stack_store_float3(stack, normal_offset, make_float3(0.0f, 0.0f, 0.0f));
+ return;
+ }
+
+ /* ensure orthogonal and normalized (interpolation breaks it) */
+ float3 tangent = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
+ float sign = triangle_attribute_float(kg, sd, ATTR_ELEMENT_CORNER, attr_sign_offset, NULL, NULL);
+
+ object_normal_transform(kg, sd, &tangent);
+ tangent = cross(sd->N, normalize(cross(tangent, sd->N)));;
+
+ float3 B = sign * cross(sd->N, tangent);
+ N = normalize(color.x * tangent + color.y * B + color.z * sd->N);
+ }
+ else {
+ /* object, world space */
+ N = color;
+
+ if(space == NODE_NORMAL_MAP_OBJECT)
+ object_normal_transform(kg, sd, &N);
+
+ N = normalize(N);
+ }
+
+ float strength = stack_load_float(stack, strength_offset);
+
+ if(strength != 1.0f) {
+ strength = max(strength, 0.0f);
+ N = normalize(sd->N + (N - sd->N)*strength);
+ }
+
+ stack_store_float3(stack, normal_offset, normalize(N));
+}
+
+__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;
+
+ if(direction_type == NODE_TANGENT_UVMAP) {
+ /* UV map */
+ int attr_offset = find_attribute(kg, sd, node.z);
+
+ if(attr_offset == ATTR_STD_NOT_FOUND)
+ tangent = make_float3(0.0f, 0.0f, 0.0f);
+ else
+ tangent = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_CORNER, attr_offset, NULL, NULL);
+ }
+ else {
+ /* radial */
+ int attr_offset = find_attribute(kg, sd, node.z);
+ float3 generated;
+
+ if(attr_offset == ATTR_STD_NOT_FOUND)
+ generated = sd->P;
+ else
+ generated = triangle_attribute_float3(kg, sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL);
+
+ 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_types.h b/intern/cycles/kernel/svm/svm_types.h
index ee423573cdf..b41e34ab407 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -92,7 +92,11 @@ typedef enum NodeType {
NODE_LIGHT_FALLOFF,
NODE_OBJECT_INFO,
NODE_PARTICLE_INFO,
- NODE_TEX_BRICK
+ NODE_TEX_BRICK,
+ NODE_CLOSURE_SET_NORMAL,
+ NODE_CLOSURE_AMBIENT_OCCLUSION,
+ NODE_TANGENT,
+ NODE_NORMAL_MAP
} NodeType;
typedef enum NodeAttributeType {
@@ -209,8 +213,13 @@ typedef enum NodeVectorMath {
typedef enum NodeConvert {
NODE_CONVERT_FV,
+ NODE_CONVERT_FI,
NODE_CONVERT_CF,
- NODE_CONVERT_VF
+ NODE_CONVERT_CI,
+ NODE_CONVERT_VF,
+ NODE_CONVERT_VI,
+ NODE_CONVERT_IF,
+ NODE_CONVERT_IV
} NodeConvert;
typedef enum NodeDistanceMetric {
@@ -273,6 +282,23 @@ typedef enum NodeBlendWeightType {
NODE_LAYER_WEIGHT_FACING
} NodeBlendWeightType;
+typedef enum NodeTangentDirectionType {
+ NODE_TANGENT_RADIAL,
+ NODE_TANGENT_UVMAP
+} NodeTangentDirectionType;
+
+typedef enum NodeTangentAxis {
+ 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
+} NodeNormalMapSpace;
+
typedef enum ShaderType {
SHADER_TYPE_SURFACE,
SHADER_TYPE_VOLUME,
@@ -294,6 +320,7 @@ typedef enum ClosureType {
CLOSURE_BSDF_WARD_ID,
CLOSURE_BSDF_ASHIKHMIN_VELVET_ID,
CLOSURE_BSDF_WESTIN_SHEEN_ID,
+ CLOSURE_BSDF_PHONG_RAMP_ID,
CLOSURE_BSDF_TRANSMISSION_ID,
CLOSURE_BSDF_TRANSLUCENT_ID,
@@ -301,7 +328,9 @@ typedef enum ClosureType {
CLOSURE_BSDF_WESTIN_BACKSCATTER_ID,
CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID,
CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID,
- CLOSURE_BSDF_GLASS_ID,
+ CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID,
+ CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID,
+ CLOSURE_BSDF_SHARP_GLASS_ID,
CLOSURE_BSDF_TRANSPARENT_ID,
@@ -311,6 +340,7 @@ typedef enum ClosureType {
CLOSURE_BACKGROUND_ID,
CLOSURE_HOLDOUT_ID,
CLOSURE_SUBSURFACE_ID,
+ CLOSURE_AMBIENT_OCCLUSION_ID,
CLOSURE_VOLUME_ID,
CLOSURE_VOLUME_TRANSPARENT_ID,
@@ -322,12 +352,13 @@ typedef enum 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_OREN_NAYAR_ID)
-#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_WESTIN_SHEEN_ID)
-#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_GLASS_ID)
+#define CLOSURE_IS_BSDF_GLOSSY(type) (type >= CLOSURE_BSDF_GLOSSY_ID && type <= CLOSURE_BSDF_PHONG_RAMP_ID)
+#define CLOSURE_IS_BSDF_TRANSMISSION(type) (type >= CLOSURE_BSDF_TRANSMISSION_ID && type <= CLOSURE_BSDF_SHARP_GLASS_ID)
#define CLOSURE_IS_VOLUME(type) (type >= CLOSURE_VOLUME_ID && type <= CLOSURE_VOLUME_ISOTROPIC_ID)
#define CLOSURE_IS_EMISSION(type) (type == CLOSURE_EMISSION_ID)
#define CLOSURE_IS_HOLDOUT(type) (type == CLOSURE_HOLDOUT_ID)
#define CLOSURE_IS_BACKGROUND(type) (type == CLOSURE_BACKGROUND_ID)
+#define CLOSURE_IS_AMBIENT_OCCLUSION(type) (type == CLOSURE_AMBIENT_OCCLUSION_ID)
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/CMakeLists.txt b/intern/cycles/render/CMakeLists.txt
index e75a3b37f3b..7907061c19c 100644
--- a/intern/cycles/render/CMakeLists.txt
+++ b/intern/cycles/render/CMakeLists.txt
@@ -8,6 +8,7 @@ set(INC
../bvh
../util
)
+
set(INC_SYS
${GLEW_INCLUDE_PATH}
)
diff --git a/intern/cycles/render/attribute.cpp b/intern/cycles/render/attribute.cpp
index 5122c1af410..95941c14b6c 100644
--- a/intern/cycles/render/attribute.cpp
+++ b/intern/cycles/render/attribute.cpp
@@ -162,6 +162,10 @@ Attribute *AttributeSet::add(AttributeStandard std, ustring name)
attr = add(name, TypeDesc::TypeNormal, Attribute::FACE);
else if(std == ATTR_STD_UV)
attr = add(name, TypeDesc::TypePoint, Attribute::CORNER);
+ else if(std == ATTR_STD_UV_TANGENT)
+ attr = add(name, TypeDesc::TypeVector, Attribute::CORNER);
+ else if(std == ATTR_STD_UV_TANGENT_SIGN)
+ attr = add(name, TypeDesc::TypeFloat, Attribute::CORNER);
else if(std == ATTR_STD_GENERATED)
attr = add(name, TypeDesc::TypePoint, Attribute::VERTEX);
else if(std == ATTR_STD_POSITION_UNDEFORMED)
diff --git a/intern/cycles/render/buffers.cpp b/intern/cycles/render/buffers.cpp
index 6f8740b8a51..3b61ccd176d 100644
--- a/intern/cycles/render/buffers.cpp
+++ b/intern/cycles/render/buffers.cpp
@@ -101,7 +101,7 @@ RenderTile::RenderTile()
RenderBuffers::RenderBuffers(Device *device_)
{
- device = device_;
+ device = device_;
}
RenderBuffers::~RenderBuffers()
diff --git a/intern/cycles/render/camera.cpp b/intern/cycles/render/camera.cpp
index 3fd7a1b28e3..308ebd0794a 100644
--- a/intern/cycles/render/camera.cpp
+++ b/intern/cycles/render/camera.cpp
@@ -19,6 +19,8 @@
#include "camera.h"
#include "scene.h"
+#include "device.h"
+
#include "util_vector.h"
CCL_NAMESPACE_BEGIN
@@ -53,15 +55,10 @@ Camera::Camera()
width = 1024;
height = 512;
- left = -((float)width/(float)height);
- right = (float)width/(float)height;
- bottom = -1.0f;
- top = 1.0f;
-
- border_left = 0.0f;
- border_right = 1.0f;
- border_bottom = 0.0f;
- border_top = 1.0f;
+ viewplane.left = -((float)width/(float)height);
+ viewplane.right = (float)width/(float)height;
+ viewplane.bottom = -1.0f;
+ viewplane.top = 1.0f;
screentoworld = transform_identity();
rastertoworld = transform_identity();
@@ -93,10 +90,11 @@ void Camera::update()
/* raster to screen */
Transform screentoraster = ndctoraster;
-
+
screentoraster = ndctoraster *
- transform_scale(1.0f/(right - left), 1.0f/(top - bottom), 1.0f) *
- transform_translate(-left, -bottom, 0.0f);
+ transform_scale(1.0f/(viewplane.right - viewplane.left),
+ 1.0f/(viewplane.top - viewplane.bottom), 1.0f) *
+ transform_translate(-viewplane.left, -viewplane.bottom, 0.0f);
Transform rastertoscreen = transform_inverse(screentoraster);
@@ -141,7 +139,7 @@ void Camera::update()
void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
{
- Scene::MotionType need_motion = scene->need_motion();
+ Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
update();
@@ -160,7 +158,6 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
/* store matrices */
kcam->screentoworld = screentoworld;
kcam->rastertoworld = rastertoworld;
- kcam->ndctoworld = ndctoworld;
kcam->rastertocamera = rastertocamera;
kcam->cameratoworld = cameratoworld;
kcam->worldtoscreen = transform_inverse(screentoworld);
@@ -193,13 +190,14 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
}
}
}
+#ifdef __CAMERA_MOTION__
else if(need_motion == Scene::MOTION_BLUR) {
- /* todo: exact camera position will not be hit this way */
if(use_motion) {
- transform_motion_decompose(&kcam->motion, &motion);
+ transform_motion_decompose(&kcam->motion, &motion, &matrix);
kcam->have_motion = 1;
}
}
+#endif
/* depth of field */
kcam->aperturesize = aperturesize;
@@ -208,7 +206,11 @@ void Camera::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kcam->bladesrotation = bladesrotation;
/* motion blur */
+#ifdef __CAMERA_MOTION__
kcam->shuttertime = (need_motion == Scene::MOTION_BLUR) ? shuttertime: 0.0f;
+#else
+ kcam->shuttertime = 0.0f;
+#endif
/* type */
kcam->type = type;
@@ -259,22 +261,20 @@ bool Camera::modified(const Camera& cam)
// modified for progressive render
// (width == cam.width) &&
// (height == cam.height) &&
- (left == cam.left) &&
- (right == cam.right) &&
- (bottom == cam.bottom) &&
- (top == cam.top) &&
- (border_left == cam.border_left) &&
- (border_right == cam.border_right) &&
- (border_bottom == cam.border_bottom) &&
- (border_top == cam.border_top) &&
+ (viewplane == cam.viewplane) &&
+ (border == cam.border) &&
(matrix == cam.matrix) &&
- (motion == cam.motion) &&
- (use_motion == cam.use_motion) &&
(panorama_type == cam.panorama_type) &&
(fisheye_fov == cam.fisheye_fov) &&
(fisheye_lens == cam.fisheye_lens));
}
+bool Camera::motion_modified(const Camera& cam)
+{
+ return !((motion == cam.motion) &&
+ (use_motion == cam.use_motion));
+}
+
void Camera::tag_update()
{
need_update = true;
diff --git a/intern/cycles/render/camera.h b/intern/cycles/render/camera.h
index 82852bde5e0..4c2de7b50b8 100644
--- a/intern/cycles/render/camera.h
+++ b/intern/cycles/render/camera.h
@@ -21,6 +21,7 @@
#include "kernel_types.h"
+#include "util_boundbox.h"
#include "util_transform.h"
#include "util_types.h"
@@ -65,10 +66,10 @@ public:
/* screen */
int width, height;
- float left, right, bottom, top;
+ BoundBox2D viewplane;
/* border */
- float border_left, border_right, border_bottom, border_top;
+ BoundBox2D border;
/* transformation */
Transform matrix;
@@ -103,6 +104,7 @@ public:
void device_free(Device *device, DeviceScene *dscene);
bool modified(const Camera& cam);
+ bool motion_modified(const Camera& cam);
void tag_update();
};
diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp
index 62758128a73..f71675dbda3 100644
--- a/intern/cycles/render/graph.cpp
+++ b/intern/cycles/render/graph.cpp
@@ -229,6 +229,8 @@ void ShaderGraph::finalize(bool do_bump, bool do_osl)
if(!finalized) {
clean();
default_inputs(do_osl);
+ refine_bump_nodes();
+
if(do_bump)
bump_from_displacement();
@@ -324,6 +326,7 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed)
/* transfer the default input value to the target socket */
to->set(input->value);
+ to->set(input->value_string);
}
}
@@ -468,6 +471,12 @@ void ShaderGraph::default_inputs(bool do_osl)
connect(geom->output("Position"), input);
}
+ else if(input->default_value == ShaderInput::TANGENT) {
+ if(!geom)
+ geom = new GeometryNode();
+
+ connect(geom->output("Tangent"), input);
+ }
}
}
}
@@ -478,6 +487,61 @@ void ShaderGraph::default_inputs(bool do_osl)
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->name == ustring("bump") && node->input("Height")->link) {
+ ShaderInput *bump_input = node->input("Height");
+ set<ShaderNode*> nodes_bump;
+
+ /* make 2 extra copies of the subgraph defined in Bump input */
+ map<ShaderNode*, ShaderNode*> nodes_dx;
+ map<ShaderNode*, ShaderNode*> 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 conected is bump to samplecenter input*/
+ connect(out , node->input("SampleCenter"));
+
+ /* bump input is just for connectivity purpose for the graph input,
+ * we reconected this input to samplecenter, so lets disconnect it
+ * from bump input */
+ disconnect(bump_input);
+ }
+ }
+}
+
void ShaderGraph::bump_from_displacement()
{
/* generate bump mapping automatically from displacement. bump mapping is
@@ -491,7 +555,7 @@ void ShaderGraph::bump_from_displacement()
* different shifted coordinates.
*
* these 3 displacement values are then fed into the bump node, which will
- * modify the normal. */
+ * output the the perturbed normal. */
ShaderInput *displacement_in = output()->input("Displacement");
@@ -520,6 +584,12 @@ void ShaderGraph::bump_from_displacement()
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 */
ShaderNode *bump = add(new BumpNode());
@@ -531,6 +601,9 @@ void ShaderGraph::bump_from_displacement()
connect(out_center, bump->input("SampleCenter"));
connect(out_dx, bump->input("SampleX"));
connect(out_dy, bump->input("SampleY"));
+
+ /* connect the bump out to the set normal in: */
+ connect(bump->output("Normal"), set_normal->input("Direction"));
/* connect bump output to normal input nodes that aren't set yet. actually
* this will only set the normal input to the geometry node that we created
@@ -538,8 +611,14 @@ void ShaderGraph::bump_from_displacement()
foreach(ShaderNode *node, nodes)
foreach(ShaderInput *input, node->inputs)
if(!input->link && input->default_value == ShaderInput::NORMAL)
- connect(bump->output("Normal"), input);
-
+ connect(set_normal->output("Normal"), input);
+
+ /* for displacement bump, clear the normal input in case the above loop
+ * connected the setnormal out to the bump normalin */
+ ShaderInput *bump_normal_in = bump->input("NormalIn");
+ if(bump_normal_in)
+ bump_normal_in->link = NULL;
+
/* 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)
diff --git a/intern/cycles/render/graph.h b/intern/cycles/render/graph.h
index c3b674d0f23..373c7e0eaab 100644
--- a/intern/cycles/render/graph.h
+++ b/intern/cycles/render/graph.h
@@ -44,11 +44,13 @@ class OSLCompiler;
enum ShaderSocketType {
SHADER_SOCKET_FLOAT,
+ SHADER_SOCKET_INT,
SHADER_SOCKET_COLOR,
SHADER_SOCKET_VECTOR,
SHADER_SOCKET_POINT,
SHADER_SOCKET_NORMAL,
- SHADER_SOCKET_CLOSURE
+ SHADER_SOCKET_CLOSURE,
+ SHADER_SOCKET_STRING
};
/* Bump
@@ -112,12 +114,14 @@ public:
INCOMING,
NORMAL,
POSITION,
+ TANGENT,
NONE
};
ShaderInput(ShaderNode *parent, const char *name, ShaderSocketType type);
void set(const float3& v) { value = v; }
void set(float f) { value = make_float3(f, 0, 0); }
+ void set(const ustring v) { value_string = v; }
const char *name;
ShaderSocketType type;
@@ -127,6 +131,7 @@ public:
DefaultValue default_value;
float3 value;
+ ustring value_string;
int stack_offset; /* for SVM compiler */
bool osl_only;
@@ -234,6 +239,7 @@ protected:
void break_cycles(ShaderNode *node, vector<bool>& visited, vector<bool>& on_stack);
void clean();
void bump_from_displacement();
+ void refine_bump_nodes();
void default_inputs(bool do_osl);
};
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 8fb229282dc..485bfc5cbf5 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -25,9 +25,10 @@
#include "util_thread.h"
#include "util_vector.h"
+#include "kernel_types.h" /* for TEX_NUM_FLOAT_IMAGES */
+
CCL_NAMESPACE_BEGIN
-#define TEX_NUM_FLOAT_IMAGES 5
#define TEX_NUM_IMAGES 95
#define TEX_IMAGE_BYTE_START TEX_NUM_FLOAT_IMAGES
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 5c1737bd60a..4173da453fd 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -68,20 +68,15 @@ static void dump_background_pixels(Device *device, DeviceScene *dscene, int res,
main_task.shader_w = width*height;
/* disabled splitting for now, there's an issue with multi-GPU mem_copy_from */
-#if 0
list<DeviceTask> split_tasks;
main_task.split_max_size(split_tasks, 128*128);
foreach(DeviceTask& task, split_tasks) {
device->task_add(task);
device->task_wait();
+ device->mem_copy_from(d_output, task.shader_x, 1, task.shader_w, sizeof(float4));
}
-#else
- device->task_add(main_task);
- device->task_wait();
-#endif
- device->mem_copy_from(d_output, 0, 1, d_output.size(), sizeof(float4));
device->mem_free(d_input);
device->mem_free(d_output);
@@ -152,6 +147,10 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
Mesh *mesh = object->mesh;
bool have_emission = false;
+ /* skip if we are not visible for BSDFs */
+ if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT)))
+ continue;
+
/* skip if we have no emission shaders */
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
@@ -188,6 +187,10 @@ void LightManager::device_update_distribution(Device *device, DeviceScene *dscen
Mesh *mesh = object->mesh;
bool have_emission = false;
+ /* skip if we are not visible for BSDFs */
+ if(!(object->visibility & (PATH_RAY_DIFFUSE|PATH_RAY_GLOSSY|PATH_RAY_TRANSMIT)))
+ continue;
+
/* skip if we have no emission shaders */
foreach(uint sindex, mesh->used_shaders) {
Shader *shader = scene->shaders[sindex];
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 7037e36f313..1958cfc10f7 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -19,6 +19,7 @@
#include "bvh.h"
#include "bvh_build.h"
+#include "camera.h"
#include "device.h"
#include "shader.h"
#include "light.h"
@@ -324,6 +325,7 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
og->object_name_map.clear();
og->attribute_map.clear();
+ og->object_names.clear();
og->attribute_map.resize(scene->objects.size());
@@ -331,6 +333,7 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
/* 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) {
@@ -354,6 +357,9 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
/* set object attributes */
foreach(AttributeRequest& req, attributes.requests) {
+ if(req.element == ATTR_ELEMENT_NONE)
+ continue;
+
OSLGlobals::Attribute osl_attr;
osl_attr.elem = req.element;
@@ -365,8 +371,8 @@ void MeshManager::update_osl_attributes(Device *device, Scene *scene, vector<Att
osl_attr.type = TypeDesc::TypeColor;
if(req.std != ATTR_STD_NONE) {
- /* if standard attribute, add lookup by std:: name convention */
- ustring stdname(std::string("std::") + std::string(attribute_standard_name(req.std)));
+ /* if standard attribute, add lookup by geom: name convention */
+ ustring stdname(string("geom:") + string(attribute_standard_name(req.std)));
og->attribute_map[i][stdname] = osl_attr;
}
else if(req.name != ustring()) {
@@ -722,10 +728,16 @@ void MeshManager::device_update(Device *device, DeviceScene *dscene, Scene *scen
foreach(Shader *shader, scene->shaders)
shader->need_update_attributes = false;
- bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR;
+ float shuttertime = scene->camera->shuttertime;
+#ifdef __OBJECT_MOTION__
+ Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
+ bool motion_blur = need_motion == Scene::MOTION_BLUR;
+#else
+ bool motion_blur = false;
+#endif
foreach(Object *object, scene->objects)
- object->compute_bounds(motion_blur);
+ object->compute_bounds(motion_blur, shuttertime);
if(progress.get_cancel()) return;
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 4e16eea2774..82afab4dc1a 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -225,6 +225,8 @@ void ImageTextureNode::compile(OSLCompiler& compiler)
compiler.parameter("color_space", "Linear");
else
compiler.parameter("color_space", "sRGB");
+ compiler.parameter("projection", projection);
+ compiler.parameter("projection_blend", projection_blend);
compiler.add(this, "node_image_texture");
}
@@ -1065,6 +1067,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
if(from == SHADER_SOCKET_FLOAT)
add_input("Val", SHADER_SOCKET_FLOAT);
+ else if(from == SHADER_SOCKET_INT)
+ add_input("ValInt", SHADER_SOCKET_INT);
else if(from == SHADER_SOCKET_COLOR)
add_input("Color", SHADER_SOCKET_COLOR);
else if(from == SHADER_SOCKET_VECTOR)
@@ -1078,6 +1082,8 @@ ConvertNode::ConvertNode(ShaderSocketType from_, ShaderSocketType to_)
if(to == SHADER_SOCKET_FLOAT)
add_output("Val", SHADER_SOCKET_FLOAT);
+ else if(to == SHADER_SOCKET_INT)
+ add_output("ValInt", SHADER_SOCKET_INT);
else if(to == SHADER_SOCKET_COLOR)
add_output("Color", SHADER_SOCKET_COLOR);
else if(to == SHADER_SOCKET_VECTOR)
@@ -1095,7 +1101,29 @@ void ConvertNode::compile(SVMCompiler& compiler)
ShaderInput *in = inputs[0];
ShaderOutput *out = outputs[0];
- if(to == SHADER_SOCKET_FLOAT) {
+ if(from == SHADER_SOCKET_FLOAT) {
+ compiler.stack_assign(in);
+ compiler.stack_assign(out);
+
+ if(to == SHADER_SOCKET_INT)
+ /* float to int */
+ compiler.add_node(NODE_CONVERT, NODE_CONVERT_FI, in->stack_offset, out->stack_offset);
+ else
+ /* float to float3 */
+ compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset);
+ }
+ else if(from == SHADER_SOCKET_INT) {
+ compiler.stack_assign(in);
+ compiler.stack_assign(out);
+
+ if(to == SHADER_SOCKET_FLOAT)
+ /* int to float */
+ compiler.add_node(NODE_CONVERT, NODE_CONVERT_IF, in->stack_offset, out->stack_offset);
+ else
+ /* int to vector/point/normal */
+ compiler.add_node(NODE_CONVERT, NODE_CONVERT_IV, in->stack_offset, out->stack_offset);
+ }
+ else if(to == SHADER_SOCKET_FLOAT) {
compiler.stack_assign(in);
compiler.stack_assign(out);
@@ -1106,12 +1134,16 @@ void ConvertNode::compile(SVMCompiler& compiler)
/* vector/point/normal to float */
compiler.add_node(NODE_CONVERT, NODE_CONVERT_VF, in->stack_offset, out->stack_offset);
}
- else if(from == SHADER_SOCKET_FLOAT) {
+ else if(to == SHADER_SOCKET_INT) {
compiler.stack_assign(in);
compiler.stack_assign(out);
- /* float to float3 */
- compiler.add_node(NODE_CONVERT, NODE_CONVERT_FV, in->stack_offset, out->stack_offset);
+ if(from == SHADER_SOCKET_COLOR)
+ /* color to int */
+ compiler.add_node(NODE_CONVERT, NODE_CONVERT_CI, in->stack_offset, out->stack_offset);
+ else
+ /* vector/point/normal to int */
+ compiler.add_node(NODE_CONVERT, NODE_CONVERT_VI, in->stack_offset, out->stack_offset);
}
else {
/* float3 to float3 */
@@ -1134,6 +1166,8 @@ void ConvertNode::compile(OSLCompiler& compiler)
{
if(from == SHADER_SOCKET_FLOAT)
compiler.add(this, "node_convert_from_float");
+ else if(from == SHADER_SOCKET_INT)
+ compiler.add(this, "node_convert_from_int");
else if(from == SHADER_SOCKET_COLOR)
compiler.add(this, "node_convert_from_color");
else if(from == SHADER_SOCKET_VECTOR)
@@ -1175,14 +1209,16 @@ BsdfNode::BsdfNode()
closure = ccl::CLOSURE_BSDF_DIFFUSE_ID;
add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
- add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL);
add_output("BSDF", SHADER_SOCKET_CLOSURE);
}
-void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2)
+void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3)
{
ShaderInput *color_in = input("Color");
+ ShaderInput *normal_in = input("Normal");
+ ShaderInput *tangent_in = input("Tangent");
if(color_in->link) {
compiler.stack_assign(color_in);
@@ -1195,6 +1231,14 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *
compiler.stack_assign(param1);
if(param2)
compiler.stack_assign(param2);
+ if(param3)
+ compiler.stack_assign(param3);
+
+ if(normal_in->link)
+ compiler.stack_assign(normal_in);
+
+ if(tangent_in && tangent_in->link)
+ compiler.stack_assign(tangent_in);
compiler.add_node(NODE_CLOSURE_BSDF,
compiler.encode_uchar4(closure,
@@ -1203,6 +1247,14 @@ void BsdfNode::compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *
compiler.closure_mix_weight_offset()),
__float_as_int((param1)? param1->value.x: 0.0f),
__float_as_int((param2)? param2->value.x: 0.0f));
+
+ if(tangent_in) {
+ compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset, tangent_in->stack_offset,
+ (param3)? param3->stack_offset: SVM_STACK_INVALID);
+ }
+ else {
+ compiler.add_node(NODE_CLOSURE_BSDF, normal_in->stack_offset);
+ }
}
void BsdfNode::compile(SVMCompiler& compiler)
@@ -1221,13 +1273,26 @@ WardBsdfNode::WardBsdfNode()
{
closure = CLOSURE_BSDF_WARD_ID;
- add_input("Roughness U", SHADER_SOCKET_FLOAT, 0.2f);
- add_input("Roughness V", SHADER_SOCKET_FLOAT, 0.2f);
+ add_input("Tangent", SHADER_SOCKET_VECTOR, ShaderInput::TANGENT);
+
+ add_input("Roughness", SHADER_SOCKET_FLOAT, 0.2f);
+ add_input("Anisotropy", SHADER_SOCKET_FLOAT, 0.5f);
+ add_input("Rotation", SHADER_SOCKET_FLOAT, 0.0f);
+}
+
+void WardBsdfNode::attributes(AttributeRequestSet *attributes)
+{
+ ShaderInput *tangent_in = input("Tangent");
+
+ if(!tangent_in->link)
+ attributes->add(ATTR_STD_GENERATED);
+
+ ShaderNode::attributes(attributes);
}
void WardBsdfNode::compile(SVMCompiler& compiler)
{
- BsdfNode::compile(compiler, input("Roughness U"), input("Roughness V"));
+ BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
}
void WardBsdfNode::compile(OSLCompiler& compiler)
@@ -1279,9 +1344,9 @@ static ShaderEnum glass_distribution_init()
{
ShaderEnum enm;
- enm.insert("Sharp", CLOSURE_BSDF_REFRACTION_ID);
- enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
- enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
+ enm.insert("Sharp", CLOSURE_BSDF_SHARP_GLASS_ID);
+ enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_GLASS_ID);
+ enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID);
return enm;
}
@@ -1300,7 +1365,7 @@ void GlassBsdfNode::compile(SVMCompiler& compiler)
{
closure = (ClosureType)distribution_enum[distribution];
- if(closure == CLOSURE_BSDF_REFRACTION_ID)
+ if(closure == CLOSURE_BSDF_SHARP_GLASS_ID)
BsdfNode::compile(compiler, NULL, input("IOR"));
else
BsdfNode::compile(compiler, input("Roughness"), input("IOR"));
@@ -1312,6 +1377,45 @@ void GlassBsdfNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_glass_bsdf");
}
+/* Refraction BSDF Closure */
+
+static ShaderEnum refraction_distribution_init()
+{
+ ShaderEnum enm;
+
+ enm.insert("Sharp", CLOSURE_BSDF_REFRACTION_ID);
+ enm.insert("Beckmann", CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID);
+ enm.insert("GGX", CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID);
+
+ return enm;
+}
+
+ShaderEnum RefractionBsdfNode::distribution_enum = refraction_distribution_init();
+
+RefractionBsdfNode::RefractionBsdfNode()
+{
+ distribution = ustring("Sharp");
+
+ add_input("Roughness", SHADER_SOCKET_FLOAT, 0.0f);
+ add_input("IOR", SHADER_SOCKET_FLOAT, 0.3f);
+}
+
+void RefractionBsdfNode::compile(SVMCompiler& compiler)
+{
+ closure = (ClosureType)distribution_enum[distribution];
+
+ 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)
+{
+ compiler.parameter("distribution", distribution);
+ compiler.add(this, "node_refraction_bsdf");
+}
+
/* Velvet BSDF Closure */
VelvetBsdfNode::VelvetBsdfNode()
@@ -1469,6 +1573,34 @@ void HoldoutNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_holdout");
}
+/* Ambient Occlusion */
+
+AmbientOcclusionNode::AmbientOcclusionNode()
+: ShaderNode("ambient_occlusion")
+{
+ add_input("Color", SHADER_SOCKET_COLOR, make_float3(0.8f, 0.8f, 0.8f));
+ add_output("AO", SHADER_SOCKET_CLOSURE);
+}
+
+void AmbientOcclusionNode::compile(SVMCompiler& compiler)
+{
+ ShaderInput *color_in = input("Color");
+
+ if(color_in->link) {
+ compiler.stack_assign(color_in);
+ compiler.add_node(NODE_CLOSURE_WEIGHT, color_in->stack_offset);
+ }
+ else
+ compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color_in->value);
+
+ compiler.add_node(NODE_CLOSURE_AMBIENT_OCCLUSION, compiler.closure_mix_weight_offset());
+}
+
+void AmbientOcclusionNode::compile(OSLCompiler& compiler)
+{
+ compiler.add(this, "node_ambient_occlusion");
+}
+
/* Volume Closure */
VolumeNode::VolumeNode()
@@ -1566,6 +1698,14 @@ GeometryNode::GeometryNode()
add_output("Backfacing", SHADER_SOCKET_FLOAT);
}
+void GeometryNode::attributes(AttributeRequestSet *attributes)
+{
+ if(!output("Tangent")->links.empty())
+ attributes->add(ATTR_STD_GENERATED);
+
+ ShaderNode::attributes(attributes);
+}
+
void GeometryNode::compile(SVMCompiler& compiler)
{
ShaderOutput *out;
@@ -1636,7 +1776,7 @@ void GeometryNode::compile(OSLCompiler& compiler)
TextureCoordinateNode::TextureCoordinateNode()
: ShaderNode("texture_coordinate")
{
- add_input("Normal", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
add_output("Generated", SHADER_SOCKET_POINT);
add_output("Normal", SHADER_SOCKET_NORMAL);
add_output("UV", SHADER_SOCKET_POINT);
@@ -1758,6 +1898,8 @@ void TextureCoordinateNode::compile(OSLCompiler& compiler)
if(compiler.background)
compiler.parameter("is_background", true);
+
+ compiler.parameter("from_dupli", from_dupli);
compiler.add(this, "node_texture_coordinate");
}
@@ -1996,13 +2138,14 @@ void ParticleInfoNode::compile(SVMCompiler& compiler)
compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, out->stack_offset);
}
- #if 0 /* XXX 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.stack_assign(out);
compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, out->stack_offset);
}
- #endif
+#endif
out = output("Size");
if(!out->links.empty()) {
@@ -2184,7 +2327,7 @@ static ShaderEnum mix_type_init()
enm.insert("Burn", NODE_MIX_BURN);
enm.insert("Hue", NODE_MIX_HUE);
enm.insert("Saturation", NODE_MIX_SAT);
- enm.insert("Value", NODE_MIX_VAL );
+ enm.insert("Value", NODE_MIX_VAL);
enm.insert("Color", NODE_MIX_COLOR);
enm.insert("Soft Light", NODE_MIX_SOFT);
enm.insert("Linear Light", NODE_MIX_LINEAR);
@@ -2544,7 +2687,7 @@ void LayerWeightNode::compile(SVMCompiler& compiler)
void LayerWeightNode::compile(OSLCompiler& compiler)
{
- compiler.add(this, "node_blend_weight");
+ compiler.add(this, "node_layer_weight");
}
/* Output */
@@ -2555,6 +2698,7 @@ OutputNode::OutputNode()
add_input("Surface", SHADER_SOCKET_CLOSURE);
add_input("Volume", SHADER_SOCKET_CLOSURE);
add_input("Displacement", SHADER_SOCKET_FLOAT);
+ add_input("Normal", SHADER_SOCKET_NORMAL);
}
void OutputNode::compile(SVMCompiler& compiler)
@@ -2702,9 +2846,15 @@ void VectorMathNode::compile(OSLCompiler& compiler)
BumpNode::BumpNode()
: ShaderNode("bump")
{
+ /* this input is used by the user, but after graph transform it is no longer
+ * used and moved to sampler center/x/y instead */
+ add_input("Height", SHADER_SOCKET_FLOAT);
+
add_input("SampleCenter", SHADER_SOCKET_FLOAT);
add_input("SampleX", SHADER_SOCKET_FLOAT);
add_input("SampleY", SHADER_SOCKET_FLOAT);
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL);
+ add_input("Strength", SHADER_SOCKET_FLOAT, 0.1f);
add_output("Normal", SHADER_SOCKET_NORMAL);
}
@@ -2714,12 +2864,25 @@ void BumpNode::compile(SVMCompiler& compiler)
ShaderInput *center_in = input("SampleCenter");
ShaderInput *dx_in = input("SampleX");
ShaderInput *dy_in = input("SampleY");
+ ShaderInput *normal_in = input("NormalIn");
+ ShaderInput *intensity_in = input("Strength");
+ ShaderOutput *normal_out = output("Normal");
compiler.stack_assign(center_in);
compiler.stack_assign(dx_in);
compiler.stack_assign(dy_in);
+ compiler.stack_assign(intensity_in);
+ compiler.stack_assign(normal_out);
- compiler.add_node(NODE_SET_BUMP, center_in->stack_offset, dx_in->stack_offset, dy_in->stack_offset);
+ if(normal_in->link)
+ compiler.stack_assign(normal_in);
+
+ /* pack all parameters in the node */
+ compiler.add_node(NODE_SET_BUMP,
+ normal_in->stack_offset,
+ compiler.encode_uchar4(center_in->stack_offset, dx_in->stack_offset,
+ dy_in->stack_offset, intensity_in->stack_offset),
+ normal_out->stack_offset);
}
void BumpNode::compile(OSLCompiler& compiler)
@@ -2788,17 +2951,245 @@ void RGBRampNode::compile(OSLCompiler& compiler)
/* NB: cycles float3 type is actually 4 floats! need to use an explicit array */
float ramp_color[RAMP_TABLE_SIZE][3];
float ramp_alpha[RAMP_TABLE_SIZE];
+
for (int i = 0; i < RAMP_TABLE_SIZE; ++i) {
ramp_color[i][0] = ramp[i].x;
ramp_color[i][1] = ramp[i].y;
ramp_color[i][2] = ramp[i].z;
ramp_alpha[i] = ramp[i].w;
}
+
compiler.parameter_color_array("ramp_color", ramp_color, RAMP_TABLE_SIZE);
compiler.parameter_array("ramp_alpha", ramp_alpha, RAMP_TABLE_SIZE);
compiler.add(this, "node_rgb_ramp");
}
+/* Set Normal Node */
+
+SetNormalNode::SetNormalNode()
+: ShaderNode("set_normal")
+{
+ add_input("Direction", SHADER_SOCKET_VECTOR);
+ add_output("Normal", SHADER_SOCKET_NORMAL);
+}
+
+void SetNormalNode::compile(SVMCompiler& compiler)
+{
+ ShaderInput *direction_in = input("Direction");
+ ShaderOutput *normal_out = output("Normal");
+
+ compiler.stack_assign(direction_in);
+ compiler.stack_assign(normal_out);
+
+ compiler.add_node(NODE_CLOSURE_SET_NORMAL, direction_in->stack_offset, normal_out->stack_offset);
+}
+
+void SetNormalNode::compile(OSLCompiler& compiler)
+{
+ compiler.add(this, "node_set_normal");
+}
+
+/* OSLScriptNode */
+
+OSLScriptNode::OSLScriptNode()
+: ShaderNode("osl_script")
+{
+}
+
+void OSLScriptNode::compile(SVMCompiler& compiler)
+{
+ /* doesn't work for SVM, obviously ... */
+}
+
+void OSLScriptNode::compile(OSLCompiler& compiler)
+{
+ if(!filepath.empty())
+ compiler.add(this, filepath.c_str(), true);
+ else
+ compiler.add(this, bytecode_hash.c_str(), false);
+}
+
+/* Normal Map */
+
+static ShaderEnum normal_map_space_init()
+{
+ ShaderEnum enm;
+
+ enm.insert("Tangent", NODE_NORMAL_MAP_TANGENT);
+ enm.insert("Object", NODE_NORMAL_MAP_OBJECT);
+ enm.insert("World", NODE_NORMAL_MAP_WORLD);
+
+ return enm;
+}
+
+ShaderEnum NormalMapNode::space_enum = normal_map_space_init();
+
+NormalMapNode::NormalMapNode()
+: ShaderNode("normal_map")
+{
+ space = ustring("Tangent");
+ attribute = ustring("");
+
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_input("Strength", SHADER_SOCKET_FLOAT, 1.0f);
+ add_input("Color", SHADER_SOCKET_COLOR);
+
+ add_output("Normal", SHADER_SOCKET_NORMAL);
+}
+
+void NormalMapNode::attributes(AttributeRequestSet *attributes)
+{
+ if(space == ustring("Tangent")) {
+ if(attribute == ustring("")) {
+ 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()));
+ }
+ }
+
+ ShaderNode::attributes(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 == ustring("Tangent")) {
+ if(attribute == ustring("")) {
+ 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.stack_assign(color_in);
+ compiler.stack_assign(strength_in);
+ compiler.stack_assign(normal_out);
+
+ compiler.add_node(NODE_NORMAL_MAP,
+ compiler.encode_uchar4(
+ color_in->stack_offset,
+ strength_in->stack_offset,
+ normal_out->stack_offset,
+ space_enum[space]),
+ attr, attr_sign);
+}
+
+void NormalMapNode::compile(OSLCompiler& compiler)
+{
+ if(space == ustring("Tangent")) {
+ if(attribute == ustring("")) {
+ 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("space", space);
+
+ compiler.add(this, "node_normal_map");
+}
+
+/* Tangent */
+
+static ShaderEnum tangent_direction_type_init()
+{
+ ShaderEnum enm;
+
+ enm.insert("Radial", NODE_TANGENT_RADIAL);
+ enm.insert("UV Map", NODE_TANGENT_UVMAP);
+
+ return enm;
+}
+
+static ShaderEnum tangent_axis_init()
+{
+ ShaderEnum enm;
+
+ enm.insert("X", NODE_TANGENT_AXIS_X);
+ enm.insert("Y", NODE_TANGENT_AXIS_Y);
+ enm.insert("Z", NODE_TANGENT_AXIS_Z);
+
+ return enm;
+}
+
+ShaderEnum TangentNode::direction_type_enum = tangent_direction_type_init();
+ShaderEnum TangentNode::axis_enum = tangent_axis_init();
+
+TangentNode::TangentNode()
+: ShaderNode("normal_map")
+{
+ direction_type = ustring("Radial");
+ axis = ustring("X");
+ attribute = ustring("");
+
+ add_input("NormalIn", SHADER_SOCKET_NORMAL, ShaderInput::NORMAL, true);
+ add_output("Tangent", SHADER_SOCKET_NORMAL);
+}
+
+void TangentNode::attributes(AttributeRequestSet *attributes)
+{
+ if(direction_type == ustring("UV Map")) {
+ if(attribute == ustring(""))
+ 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(attributes);
+}
+
+void TangentNode::compile(SVMCompiler& compiler)
+{
+ ShaderOutput *tangent_out = output("Tangent");
+ int attr;
+
+ if(direction_type == ustring("UV Map")) {
+ if(attribute == ustring(""))
+ 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.stack_assign(tangent_out);
+
+ compiler.add_node(NODE_TANGENT,
+ compiler.encode_uchar4(
+ tangent_out->stack_offset,
+ direction_type_enum[direction_type],
+ axis_enum[axis]), attr);
+}
+
+void TangentNode::compile(OSLCompiler& compiler)
+{
+ if(direction_type == ustring("UV Map")) {
+ if(attribute == ustring(""))
+ compiler.parameter("attr_name", ustring("geom:tangent"));
+ else
+ compiler.parameter("attr_name", ustring((string(attribute.c_str()) + ".tangent").c_str()));
+ }
+
+ compiler.parameter("direction_type", direction_type);
+ compiler.parameter("axis", axis);
+ compiler.add(this, "node_tangent");
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index e8e584dd8ef..27b07769e28 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -193,7 +193,7 @@ class BsdfNode : public ShaderNode {
public:
SHADER_NODE_CLASS(BsdfNode)
- void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2);
+ void compile(SVMCompiler& compiler, ShaderInput *param1, ShaderInput *param2, ShaderInput *param3 = NULL);
ClosureType closure;
};
@@ -201,6 +201,7 @@ public:
class WardBsdfNode : public BsdfNode {
public:
SHADER_NODE_CLASS(WardBsdfNode)
+ void attributes(AttributeRequestSet *attributes);
};
class DiffuseBsdfNode : public BsdfNode {
@@ -239,6 +240,14 @@ public:
static ShaderEnum distribution_enum;
};
+class RefractionBsdfNode : public BsdfNode {
+public:
+ SHADER_NODE_CLASS(RefractionBsdfNode)
+
+ ustring distribution;
+ static ShaderEnum distribution_enum;
+};
+
class EmissionNode : public ShaderNode {
public:
SHADER_NODE_CLASS(EmissionNode)
@@ -256,6 +265,11 @@ public:
SHADER_NODE_CLASS(HoldoutNode)
};
+class AmbientOcclusionNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(AmbientOcclusionNode)
+};
+
class VolumeNode : public ShaderNode {
public:
SHADER_NODE_CLASS(VolumeNode)
@@ -278,6 +292,7 @@ public:
class GeometryNode : public ShaderNode {
public:
SHADER_NODE_CLASS(GeometryNode)
+ void attributes(AttributeRequestSet *attributes);
};
class TextureCoordinateNode : public ShaderNode {
@@ -438,6 +453,48 @@ public:
float4 ramp[RAMP_TABLE_SIZE];
};
+class SetNormalNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(SetNormalNode)
+};
+
+class OSLScriptNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(OSLScriptNode)
+ string filepath;
+ string bytecode_hash;
+
+ /* ShaderInput/ShaderOutput only stores a shallow string copy (const char *)!
+ * The actual socket names have to be stored externally to avoid memory errors. */
+ vector<ustring> input_names;
+ vector<ustring> output_names;
+};
+
+class NormalMapNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(NormalMapNode)
+ void attributes(AttributeRequestSet *attributes);
+
+ ustring space;
+ static ShaderEnum space_enum;
+
+ ustring attribute;
+};
+
+class TangentNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(TangentNode)
+ void attributes(AttributeRequestSet *attributes);
+
+ ustring direction_type;
+ static ShaderEnum direction_type_enum;
+
+ ustring axis;
+ static ShaderEnum axis_enum;
+
+ ustring attribute;
+};
+
CCL_NAMESPACE_END
#endif /* __NODES_H__ */
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index d78a82d589a..25b4d1f08cc 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -51,20 +51,23 @@ Object::~Object()
{
}
-void Object::compute_bounds(bool motion_blur)
+void Object::compute_bounds(bool motion_blur, float shuttertime)
{
BoundBox mbounds = mesh->bounds;
if(motion_blur && use_motion) {
MotionTransform decomp;
- transform_motion_decompose(&decomp, &motion);
+ transform_motion_decompose(&decomp, &motion, &tfm);
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) {
+ float start_t = 0.5f - shuttertime*0.25f;
+ float end_t = 0.5f + shuttertime*0.25f;
+
+ for(float t = start_t; t < end_t; t += (1.0f/128.0f)*shuttertime) {
Transform ttfm;
transform_motion_interpolate(&ttfm, &decomp, t);
@@ -109,7 +112,7 @@ void Object::apply_transform()
if(bounds.valid()) {
mesh->compute_bounds();
- compute_bounds(false);
+ compute_bounds(false, 0.0f);
}
/* tfm is not reset to identity, all code that uses it needs to check the
@@ -151,7 +154,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
uint *object_flag = dscene->object_flag.resize(scene->objects.size());
int i = 0;
map<Mesh*, float> surface_area_map;
- Scene::MotionType need_motion = scene->need_motion();
+ Scene::MotionType need_motion = scene->need_motion(device->info.advanced_shading);
+ bool have_motion = false;
foreach(Object *ob, scene->objects) {
Mesh *mesh = ob->mesh;
@@ -218,26 +222,29 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
mtfm_post = mtfm_post * itfm;
memcpy(&objects[offset+8], &mtfm_pre, sizeof(float4)*4);
- memcpy(&objects[offset+12], &mtfm_post, sizeof(float4)*4);
+ memcpy(&objects[offset+16], &mtfm_post, sizeof(float4)*4);
}
+#ifdef __OBJECT_MOTION__
else if(need_motion == Scene::MOTION_BLUR) {
if(ob->use_motion) {
/* decompose transformations for interpolation */
MotionTransform decomp;
- transform_motion_decompose(&decomp, &ob->motion);
- memcpy(&objects[offset+8], &decomp, sizeof(float4)*8);
+ transform_motion_decompose(&decomp, &ob->motion, &ob->tfm);
+ memcpy(&objects[offset+8], &decomp, sizeof(float4)*12);
flag |= SD_OBJECT_MOTION;
+ have_motion = true;
}
else {
float4 no_motion = make_float4(FLT_MAX);
- memcpy(&objects[offset+8], &no_motion, sizeof(float4));
+ memcpy(&objects[offset+8], &no_motion, sizeof(float4)*12);
}
}
+#endif
/* dupli object coords */
- objects[offset+16] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
- objects[offset+17] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
+ objects[offset+20] = make_float4(ob->dupli_generated[0], ob->dupli_generated[1], ob->dupli_generated[2], 0.0f);
+ objects[offset+21] = make_float4(ob->dupli_uv[0], ob->dupli_uv[1], 0.0f, 0.0f);
/* object flag */
if(ob->use_holdout)
@@ -251,6 +258,8 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
device->tex_alloc("__objects", dscene->objects);
device->tex_alloc("__object_flag", dscene->object_flag);
+
+ dscene->data.bvh.have_motion = have_motion;
}
void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
@@ -297,7 +306,12 @@ void ObjectManager::apply_static_transforms(Scene *scene, Progress& progress)
/* counter mesh users */
map<Mesh*, int> mesh_users;
- bool motion_blur = scene->need_motion() == Scene::MOTION_BLUR;
+#ifdef __OBJECT_MOTION__
+ Scene::MotionType need_motion = scene->need_motion();
+ bool motion_blur = need_motion == Scene::MOTION_BLUR;
+#else
+ bool motion_blur = false;
+#endif
foreach(Object *object, scene->objects) {
map<Mesh*, int>::iterator it = mesh_users.find(object->mesh);
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index e2c3ad4e071..922c886d961 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -59,7 +59,7 @@ public:
void tag_update(Scene *scene);
- void compute_bounds(bool motion_blur);
+ void compute_bounds(bool motion_blur, float shuttertime);
void apply_transform();
};
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index 6d23097d7a8..5fbc7932849 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -31,6 +31,7 @@
#include "osl_shader.h"
#include "util_foreach.h"
+#include "util_md5.h"
#include "util_path.h"
#include "util_progress.h"
@@ -44,22 +45,12 @@ CCL_NAMESPACE_BEGIN
OSLShaderManager::OSLShaderManager()
{
- services = new OSLRenderServices();
-
- /* if we let OSL create it, it leaks */
- ts = TextureSystem::create(true);
- ts->attribute("automip", 1);
- ts->attribute("autotile", 64);
+ thread_data_initialized = false;
- ss = OSL::ShadingSystem::create(services, ts, &errhandler);
- ss->attribute("lockgeom", 1);
- ss->attribute("commonspace", "world");
- ss->attribute("optimize", 2);
- //ss->attribute("debug", 1);
- //ss->attribute("statistics:level", 1);
- ss->attribute("searchpath:shader", path_get("shader").c_str());
+ services = new OSLRenderServices();
- OSLShader::register_closures(ss);
+ shading_system_init();
+ texture_system_init();
}
OSLShaderManager::~OSLShaderManager()
@@ -71,18 +62,14 @@ OSLShaderManager::~OSLShaderManager()
void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
- /* test if we need to update */
- bool need_update = false;
-
- foreach(Shader *shader, scene->shaders)
- if(shader->need_update)
- need_update = true;
-
if(!need_update)
return;
device_free(device, dscene);
+ /* determine which shaders are in use */
+ device_update_shaders_used(scene);
+
/* create shaders */
OSLGlobals *og = (OSLGlobals*)device->osl_memory();
@@ -94,7 +81,7 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
if(shader->sample_as_light && shader->has_surface_emission)
scene->light_manager->need_update = true;
- OSLCompiler compiler((void*)ss);
+ OSLCompiler compiler((void*)this, (void*)ss);
compiler.background = (shader == scene->shaders[scene->default_background]);
compiler.compile(og, shader);
}
@@ -106,15 +93,20 @@ void OSLShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
og->background_state = og->surface_state[background_id & SHADER_MASK];
og->use = true;
- tls_create(OSLGlobals::ThreadData, og->thread_data);
-
foreach(Shader *shader, scene->shaders)
shader->need_update = false;
+
+ need_update = false;
/* set texture system */
scene->image_manager->set_osl_texture_system((void*)ts);
device_update_common(device, dscene, scene, progress);
+
+ if(!thread_data_initialized) {
+ og->thread_data_init();
+ thread_data_initialized = true;
+ }
}
void OSLShaderManager::device_free(Device *device, DeviceScene *dscene)
@@ -127,18 +119,176 @@ void OSLShaderManager::device_free(Device *device, DeviceScene *dscene)
og->use = false;
og->ss = NULL;
- tls_delete(OSLGlobals::ThreadData, og->thread_data);
-
og->surface_state.clear();
og->volume_state.clear();
og->displacement_state.clear();
og->background_state.reset();
+
+ if(thread_data_initialized) {
+ og->thread_data_free();
+ thread_data_initialized = false;
+ }
+}
+
+void OSLShaderManager::texture_system_init()
+{
+ /* if we let OSL create it, it leaks */
+ ts = TextureSystem::create(true);
+ ts->attribute("automip", 1);
+ ts->attribute("autotile", 64);
+
+ /* effectively unlimited for now, until we support proper mipmap lookups */
+ ts->attribute("max_memory_MB", 16384);
+}
+
+void OSLShaderManager::shading_system_init()
+{
+ ss = OSL::ShadingSystem::create(services, ts, &errhandler);
+ ss->attribute("lockgeom", 1);
+ ss->attribute("commonspace", "world");
+ ss->attribute("optimize", 2);
+ //ss->attribute("debug", 1);
+ //ss->attribute("statistics:level", 1);
+ ss->attribute("searchpath:shader", path_get("shader"));
+
+ /* 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 */
+ "shadow", /* PATH_RAY_SHADOW_TRANSPARENT */
+ };
+
+ const int nraytypes = sizeof(raytypes)/sizeof(raytypes[0]);
+ ss->attribute("raytypes", TypeDesc(TypeDesc::STRING, nraytypes), raytypes);
+
+ OSLShader::register_closures(ss);
+
+ loaded_shaders.clear();
+}
+
+bool OSLShaderManager::osl_compile(const string& inputfile, const string& outputfile)
+{
+ vector<string> options;
+ string stdosl_path;
+
+ /* specify output file name */
+ options.push_back("-o");
+ options.push_back(outputfile);
+
+ /* specify standard include path */
+ options.push_back("-I" + path_get("shader"));
+ stdosl_path = path_get("shader/stdosl.h");
+
+ /* compile */
+ OSL::OSLCompiler *compiler = OSL::OSLCompiler::create();
+ bool ok = compiler->compile(inputfile, options, stdosl_path);
+ delete compiler;
+
+ return ok;
+}
+
+bool OSLShaderManager::osl_query(OSL::OSLQuery& query, const string& filepath)
+{
+ string searchpath = path_user_get("shaders");
+ return query.open(filepath, searchpath);
+}
+
+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));
+
+ return md5.get_hex();
+}
+
+const char *OSLShaderManager::shader_test_loaded(const string& hash)
+{
+ set<string>::iterator it = loaded_shaders.find(hash);
+ return (it == loaded_shaders.end())? NULL: it->c_str();
+}
+
+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());
+ loaded_shaders.insert(bytecode_hash); /* 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)
+{
+ ss->LoadMemoryShader(hash.c_str(), bytecode.c_str());
+
+ return loaded_shaders.insert(hash).first->c_str();
}
/* Graph Compiler */
-OSLCompiler::OSLCompiler(void *shadingsys_)
+OSLCompiler::OSLCompiler(void *manager_, void *shadingsys_)
{
+ manager = manager_;
shadingsys = shadingsys_;
current_type = SHADER_TYPE_SURFACE;
current_shader = NULL;
@@ -206,6 +356,12 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
return true;
if(strcmp(input->name, "Displacement") == 0 && current_type != SHADER_TYPE_DISPLACEMENT)
return true;
+ if(strcmp(input->name, "Normal") == 0)
+ return true;
+ }
+ else if(node->name == ustring("bump")) {
+ if(strcmp(input->name, "Height") == 0)
+ return true;
}
else if(current_type == SHADER_TYPE_DISPLACEMENT && input->link && input->link->parent->name == ustring("bump"))
return true;
@@ -213,10 +369,18 @@ bool OSLCompiler::node_skip_input(ShaderNode *node, ShaderInput *input)
return false;
}
-void OSLCompiler::add(ShaderNode *node, const char *name)
+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) {
@@ -244,6 +408,12 @@ void OSLCompiler::add(ShaderNode *node, const char *name)
case SHADER_SOCKET_FLOAT:
parameter(param_name.c_str(), input->value.x);
break;
+ case SHADER_SOCKET_INT:
+ parameter(param_name.c_str(), (int)input->value.x);
+ break;
+ case SHADER_SOCKET_STRING:
+ parameter(param_name.c_str(), input->value_string);
+ break;
case SHADER_SOCKET_CLOSURE:
break;
}
@@ -482,82 +652,85 @@ void OSLCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
void OSLCompiler::compile(OSLGlobals *og, Shader *shader)
{
- OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
- ShaderGraph *graph = shader->graph;
- ShaderNode *output = (graph)? graph->output(): NULL;
+ if(shader->need_update) {
+ OSL::ShadingSystem *ss = (OSL::ShadingSystem*)shadingsys;
+ ShaderGraph *graph = shader->graph;
+ ShaderNode *output = (graph)? graph->output(): NULL;
- /* copy graph for shader with bump mapping */
- if(output->input("Surface")->link && output->input("Displacement")->link)
- if(!shader->graph_bump)
- shader->graph_bump = shader->graph->copy();
+ /* copy graph for shader with bump mapping */
+ if(output->input("Surface")->link && output->input("Displacement")->link)
+ if(!shader->graph_bump)
+ shader->graph_bump = shader->graph->copy();
- /* finalize */
- shader->graph->finalize(false, true);
- if(shader->graph_bump)
- shader->graph_bump->finalize(true, true);
+ /* finalize */
+ shader->graph->finalize(false, true);
+ if(shader->graph_bump)
+ shader->graph_bump->finalize(true, true);
- current_shader = shader;
+ current_shader = shader;
- shader->has_surface = false;
- shader->has_surface_emission = false;
- shader->has_surface_transparent = false;
- shader->has_volume = false;
- shader->has_displacement = false;
+ shader->has_surface = false;
+ shader->has_surface_emission = false;
+ shader->has_surface_transparent = false;
+ shader->has_volume = false;
+ shader->has_displacement = false;
- /* generate surface shader */
- if(graph && output->input("Surface")->link) {
- compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
- og->surface_state.push_back(ss->state());
+ /* generate surface shader */
+ if(shader->used && graph && output->input("Surface")->link) {
+ compile_type(shader, shader->graph, SHADER_TYPE_SURFACE);
+ shader->osl_surface_ref = ss->state();
- if(shader->graph_bump) {
+ if(shader->graph_bump) {
+ ss->clear_state();
+ compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE);
+ }
+
+ shader->osl_surface_bump_ref = ss->state();
ss->clear_state();
- compile_type(shader, shader->graph_bump, SHADER_TYPE_SURFACE);
- og->surface_state.push_back(ss->state());
- }
- else
- og->surface_state.push_back(ss->state());
- ss->clear_state();
+ shader->has_surface = true;
+ }
+ else {
+ shader->osl_surface_ref = OSL::ShadingAttribStateRef();
+ shader->osl_surface_bump_ref = OSL::ShadingAttribStateRef();
+ }
- shader->has_surface = true;
- }
- else {
- og->surface_state.push_back(OSL::ShadingAttribStateRef());
- og->surface_state.push_back(OSL::ShadingAttribStateRef());
- }
+ /* generate volume shader */
+ if(shader->used && graph && output->input("Volume")->link) {
+ compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
+ shader->has_volume = true;
- /* generate volume shader */
- if(graph && output->input("Volume")->link) {
- compile_type(shader, shader->graph, SHADER_TYPE_VOLUME);
- shader->has_volume = true;
+ shader->osl_volume_ref = ss->state();
+ ss->clear_state();
+ }
+ else
+ shader->osl_volume_ref = OSL::ShadingAttribStateRef();
- og->volume_state.push_back(ss->state());
- og->volume_state.push_back(ss->state());
- ss->clear_state();
- }
- else {
- og->volume_state.push_back(OSL::ShadingAttribStateRef());
- og->volume_state.push_back(OSL::ShadingAttribStateRef());
+ /* generate displacement shader */
+ if(shader->used && graph && output->input("Displacement")->link) {
+ compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
+ shader->has_displacement = true;
+ shader->osl_displacement_ref = ss->state();
+ ss->clear_state();
+ }
+ else
+ shader->osl_displacement_ref = OSL::ShadingAttribStateRef();
}
- /* generate displacement shader */
- if(graph && output->input("Displacement")->link) {
- compile_type(shader, shader->graph, SHADER_TYPE_DISPLACEMENT);
- shader->has_displacement = true;
+ /* push state to array for lookup */
+ og->surface_state.push_back(shader->osl_surface_ref);
+ og->surface_state.push_back(shader->osl_surface_bump_ref);
- og->displacement_state.push_back(ss->state());
- og->displacement_state.push_back(ss->state());
- ss->clear_state();
- }
- else {
- og->displacement_state.push_back(OSL::ShadingAttribStateRef());
- og->displacement_state.push_back(OSL::ShadingAttribStateRef());
- }
+ og->volume_state.push_back(shader->osl_volume_ref);
+ og->volume_state.push_back(shader->osl_volume_ref);
+
+ og->displacement_state.push_back(shader->osl_displacement_ref);
+ og->displacement_state.push_back(shader->osl_displacement_ref);
}
#else
-void OSLCompiler::add(ShaderNode *node, const char *name)
+void OSLCompiler::add(ShaderNode *node, const char *name, bool isfilepath)
{
}
diff --git a/intern/cycles/render/osl.h b/intern/cycles/render/osl.h
index 90107a34a98..b4b3f59e02a 100644
--- a/intern/cycles/render/osl.h
+++ b/intern/cycles/render/osl.h
@@ -20,11 +20,14 @@
#define __OSL_H__
#include "util_set.h"
+#include "util_string.h"
#include "shader.h"
#ifdef WITH_OSL
+#include <OSL/oslcomp.h>
#include <OSL/oslexec.h>
+#include <OSL/oslquery.h>
#endif
CCL_NAMESPACE_BEGIN
@@ -52,11 +55,26 @@ public:
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
-private:
+ /* 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);
+
+protected:
+ void texture_system_init();
+ void shading_system_init();
+
OSL::ShadingSystem *ss;
OSL::TextureSystem *ts;
OSLRenderServices *services;
OSL::ErrorHandler errhandler;
+ set<string> loaded_shaders;
+
+ bool thread_data_initialized;
};
#endif
@@ -65,10 +83,10 @@ private:
class OSLCompiler {
public:
- OSLCompiler(void *shadingsys);
+ OSLCompiler(void *manager, void *shadingsys);
void compile(OSLGlobals *og, Shader *shader);
- void add(ShaderNode *node, const char *name);
+ void add(ShaderNode *node, const char *name, bool isfilepath = false);
void parameter(const char *name, float f);
void parameter_color(const char *name, float3 f);
@@ -104,6 +122,7 @@ private:
void generate_nodes(const set<ShaderNode*>& nodes);
void *shadingsys;
+ void *manager;
ShaderType current_type;
Shader *current_shader;
};
diff --git a/intern/cycles/render/particles.cpp b/intern/cycles/render/particles.cpp
index 9f951d9673f..2a1570f7a0d 100644
--- a/intern/cycles/render/particles.cpp
+++ b/intern/cycles/render/particles.cpp
@@ -57,8 +57,7 @@ void ParticleSystemManager::device_update_particles(Device *device, DeviceScene
{
/* count particles.
* adds one dummy particle at the beginning to avoid invalid lookups,
- * in case a shader uses particle info without actual particle data.
- */
+ * in case a shader uses particle info without actual particle data. */
int num_particles = 1;
foreach(ParticleSystem *psys, scene->particle_systems)
num_particles += psys->particles.size();
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 071338d49c2..7834aa701ea 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -44,6 +44,10 @@ Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
device = NULL;
memset(&dscene.data, 0, sizeof(dscene.data));
+ /* OSL only works on the CPU */
+ if(device_info_.type != DEVICE_CPU)
+ params.shadingsystem = SceneParams::SVM;
+
camera = new Camera();
filter = new Filter();
film = new Film();
@@ -62,33 +66,11 @@ Scene::Scene(const SceneParams& params_, const DeviceInfo& device_info_)
Scene::~Scene()
{
- if(device) camera->device_free(device, &dscene);
- delete camera;
-
- if(device) filter->device_free(device, &dscene);
- delete filter;
-
- if(device) film->device_free(device, &dscene);
- delete film;
-
- if(device) background->device_free(device, &dscene);
- delete background;
-
- if(device) mesh_manager->device_free(device, &dscene);
- delete mesh_manager;
-
- if(device) object_manager->device_free(device, &dscene);
- delete object_manager;
-
- if(device) integrator->device_free(device, &dscene);
- delete integrator;
-
- if(device) shader_manager->device_free(device, &dscene);
- delete shader_manager;
-
- if(device) light_manager->device_free(device, &dscene);
- delete light_manager;
+ free_memory(true);
+}
+void Scene::free_memory(bool final)
+{
foreach(Shader *s, shaders)
delete s;
foreach(Mesh *m, meshes)
@@ -100,11 +82,44 @@ Scene::~Scene()
foreach(ParticleSystem *p, particle_systems)
delete p;
- if(device) image_manager->device_free(device, &dscene);
- delete image_manager;
-
- if(device) particle_system_manager->device_free(device, &dscene);
- delete particle_system_manager;
+ if(device) {
+ camera->device_free(device, &dscene);
+ filter->device_free(device, &dscene);
+ film->device_free(device, &dscene);
+ 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);
+ light_manager->device_free(device, &dscene);
+
+ particle_system_manager->device_free(device, &dscene);
+
+ if(!params.persistent_images || final)
+ image_manager->device_free(device, &dscene);
+ }
+
+ if(final) {
+ delete filter;
+ delete camera;
+ delete film;
+ delete background;
+ delete integrator;
+ delete object_manager;
+ delete mesh_manager;
+ delete shader_manager;
+ delete light_manager;
+ delete particle_system_manager;
+ delete image_manager;
+ }
+ else {
+ shaders.clear();
+ meshes.clear();
+ objects.clear();
+ lights.clear();
+ particle_systems.clear();
+ }
}
void Scene::device_update(Device *device_, Progress& progress)
@@ -183,10 +198,10 @@ void Scene::device_update(Device *device_, Progress& progress)
device->const_copy_to("__data", &dscene.data, sizeof(dscene.data));
}
-Scene::MotionType Scene::need_motion()
+Scene::MotionType Scene::need_motion(bool advanced_shading)
{
if(integrator->motion_blur)
- return MOTION_BLUR;
+ return (advanced_shading)? MOTION_BLUR: MOTION_NONE;
else if(Pass::contains(film->passes, PASS_MOTION))
return MOTION_PASS;
else
@@ -229,5 +244,22 @@ bool Scene::need_reset()
|| particle_system_manager->need_update);
}
+void Scene::reset()
+{
+ shader_manager->add_default(this);
+
+ /* ensure all objects are updated */
+ camera->tag_update();
+ filter->tag_update(this);
+ film->tag_update(this);
+ background->tag_update(this);
+ integrator->tag_update(this);
+}
+
+void Scene::device_free()
+{
+ free_memory(false);
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 09087fb2970..92ef692b4b9 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -120,6 +120,7 @@ public:
bool use_bvh_cache;
bool use_bvh_spatial_split;
bool use_qbvh;
+ bool persistent_images;
SceneParams()
{
@@ -139,7 +140,8 @@ public:
&& bvh_type == params.bvh_type
&& use_bvh_cache == params.use_bvh_cache
&& use_bvh_spatial_split == params.use_bvh_spatial_split
- && use_qbvh == params.use_qbvh); }
+ && use_qbvh == params.use_qbvh
+ && persistent_images == params.persistent_images); }
};
/* Scene */
@@ -194,10 +196,16 @@ public:
void need_global_attributes(AttributeRequestSet& attributes);
enum MotionType { MOTION_NONE = 0, MOTION_PASS, MOTION_BLUR };
- MotionType need_motion();
+ MotionType need_motion(bool advanced_shading = true);
bool need_update();
bool need_reset();
+
+ void reset();
+ void device_free();
+
+protected:
+ void free_memory(bool final);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index cd410e4e011..41212c2db84 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -34,16 +34,22 @@
CCL_NAMESPACE_BEGIN
+/* Note about preserve_tile_device option for tile manager:
+ * 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)? 1: max(params.device.multi_devices.size(), 1))
+ params.background == false || params.progressive_refine, params.background,
+ max(params.device.multi_devices.size(), 1)),
+ stats()
{
device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
TaskScheduler::init(params.threads);
- device = Device::create(params.device, params.background, params.threads);
+ device = Device::create(params.device, stats, params.background);
if(params.background) {
buffers = NULL;
@@ -96,6 +102,9 @@ Session::~Session()
display->write(device, params.output_path);
}
+ foreach(RenderBuffers *buffers, tile_buffers)
+ delete buffers;
+
delete buffers;
delete display;
delete scene;
@@ -173,9 +182,12 @@ bool Session::draw_gpu(BufferParams& buffer_params)
void Session::run_gpu()
{
+ bool tiles_written = false;
+
start_time = time_dt();
reset_time = time_dt();
paused_time = 0.0;
+ last_update_time = time_dt();
if(!params.background)
progress.set_start_time(start_time + paused_time);
@@ -267,10 +279,15 @@ void Session::run_gpu()
if(device->error_message() != "")
progress.set_cancel(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 */
@@ -313,14 +330,18 @@ bool Session::draw_cpu(BufferParams& buffer_params)
bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
{
- if(progress.get_cancel())
- return false;
+ 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 = (params.background)? 0: device->device_number(tile_device);
+ int device_num = device->device_number(tile_device);
if(!tile_manager.next_tile(tile, device_num))
return false;
@@ -338,7 +359,7 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
/* in case of a permant buffer, return it, otherwise we will allocate
* a new temporary buffer */
- if(!write_render_tile_cb) {
+ if(!params.background) {
tile_manager.state.buffer.get_offset_stride(rtile.offset, rtile.stride);
rtile.buffer = buffers->buffer.device_pointer;
@@ -360,9 +381,30 @@ bool Session::acquire_tile(Device *tile_device, RenderTile& rtile)
buffer_params.get_offset_stride(rtile.offset, rtile.stride);
- /* allocate buffers */
RenderBuffers *tilebuffers = new RenderBuffers(tile_device);
- tilebuffers->reset(tile_device, buffer_params);
+
+ /* allocate buffers */
+ if(params.progressive_refine) {
+ tile_lock.lock();
+
+ if(tile_buffers.size() == 0)
+ tile_buffers.resize(tile_manager.state.num_tiles, NULL);
+
+ tilebuffers = tile_buffers[tile.index];
+ if(tilebuffers == NULL) {
+ tilebuffers = new RenderBuffers(tile_device);
+ tile_buffers[tile.index] = tilebuffers;
+
+ tilebuffers->reset(tile_device, buffer_params);
+ }
+
+ tile_lock.unlock();
+ }
+ else {
+ tilebuffers = new RenderBuffers(tile_device);
+
+ tilebuffers->reset(tile_device, buffer_params);
+ }
rtile.buffer = tilebuffers->buffer.device_pointer;
rtile.rng_state = tilebuffers->rng_state.device_pointer;
@@ -377,9 +419,11 @@ void Session::update_tile_sample(RenderTile& rtile)
thread_scoped_lock tile_lock(tile_mutex);
if(update_render_tile_cb) {
- /* todo: optimize this by making it thread safe and removing lock */
+ if(params.progressive_refine == false) {
+ /* todo: optimize this by making it thread safe and removing lock */
- update_render_tile_cb(rtile);
+ update_render_tile_cb(rtile);
+ }
}
update_status_time();
@@ -390,10 +434,12 @@ void Session::release_tile(RenderTile& rtile)
thread_scoped_lock tile_lock(tile_mutex);
if(write_render_tile_cb) {
- /* todo: optimize this by making it thread safe and removing lock */
- write_render_tile_cb(rtile);
+ if(params.progressive_refine == false) {
+ /* todo: optimize this by making it thread safe and removing lock */
+ write_render_tile_cb(rtile);
- delete rtile.buffers;
+ delete rtile.buffers;
+ }
}
update_status_time();
@@ -401,6 +447,10 @@ void Session::release_tile(RenderTile& rtile)
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);
@@ -502,10 +552,15 @@ void Session::run_cpu()
if(device->error_message() != "")
progress.set_cancel(device->error_message());
+
+ tiles_written = update_progressive_refine(progress.get_cancel());
}
progress.set_update();
}
+
+ if(!tiles_written)
+ update_progressive_refine(true);
}
void Session::run()
@@ -657,10 +712,13 @@ void Session::update_status_time(bool show_pause, bool show_done)
string status, substatus;
if(!params.progressive) {
+ bool is_gpu = params.device.type == DEVICE_CUDA || params.device.type == DEVICE_OPENCL;
+ bool is_multidevice = params.device.multi_devices.size() > 1;
+ bool is_cpu = params.device.type == DEVICE_CPU;
+
substatus = string_printf("Path Tracing Tile %d/%d", tile, num_tiles);
- if(params.device.type == DEVICE_CUDA || params.device.type == DEVICE_OPENCL ||
- (params.device.type == DEVICE_CPU && num_tiles == 1)) {
+ if((is_gpu && !is_multidevice) || (is_cpu && num_tiles == 1)) {
/* when rendering on GPU multithreading happens within single tile, as in
* tiles are handling sequentially and in this case we could display
* currently rendering sample number
@@ -722,6 +780,7 @@ void Session::path_trace()
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(&Session::update_progress_sample, this);
+ task.need_finish_queue = params.progressive_refine;
device->task_add(task);
}
@@ -752,5 +811,49 @@ void Session::tonemap()
display_outdated = false;
}
-CCL_NAMESPACE_END
+bool Session::update_progressive_refine(bool cancel)
+{
+ int sample = tile_manager.state.sample + 1;
+ bool write = sample == params.samples || cancel;
+ double current_time = time_dt();
+
+ if (current_time - last_update_time < 1.0) {
+ /* if last sample was processed, we need to write buffers anyway */
+ if (!write)
+ return false;
+ }
+
+ if(params.progressive_refine) {
+ foreach(RenderBuffers *buffers, tile_buffers) {
+ RenderTile rtile;
+ rtile.buffers = buffers;
+ rtile.sample = sample;
+
+ if(write)
+ write_render_tile_cb(rtile);
+ else
+ update_render_tile_cb(rtile);
+ }
+ }
+
+ last_update_time = current_time;
+
+ return write;
+}
+
+void Session::device_free()
+{
+ scene->device_free();
+
+ foreach(RenderBuffers *buffers, tile_buffers)
+ delete buffers;
+
+ tile_buffers.clear();
+
+ /* used from background render only, so no need to
+ * re-create render/display buffers here
+ */
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index eda8b3da60e..cfc1502287d 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -24,7 +24,9 @@
#include "tile.h"
#include "util_progress.h"
+#include "util_stats.h"
#include "util_thread.h"
+#include "util_vector.h"
CCL_NAMESPACE_BEGIN
@@ -42,6 +44,7 @@ class SessionParams {
public:
DeviceInfo device;
bool background;
+ bool progressive_refine;
string output_path;
bool progressive;
@@ -55,9 +58,12 @@ public:
double reset_timeout;
double text_timeout;
+ enum { OSL, SVM } shadingsystem;
+
SessionParams()
{
background = false;
+ progressive_refine = false;
output_path = "";
progressive = false;
@@ -70,12 +76,15 @@ public:
cancel_timeout = 0.1;
reset_timeout = 0.1;
text_timeout = 1.0;
+
+ shadingsystem = SVM;
}
bool modified(const SessionParams& params)
{ return !(device.type == params.device.type
&& device.id == params.device.id
&& background == params.background
+ && progressive_refine == params.progressive_refine
&& output_path == params.output_path
/* && samples == params.samples */
&& progressive == params.progressive
@@ -85,7 +94,8 @@ public:
&& threads == params.threads
&& cancel_timeout == params.cancel_timeout
&& reset_timeout == params.reset_timeout
- && text_timeout == params.text_timeout); }
+ && text_timeout == params.text_timeout
+ && shadingsystem == params.shadingsystem); }
};
@@ -103,6 +113,7 @@ public:
Progress progress;
SessionParams params;
TileManager tile_manager;
+ Stats stats;
boost::function<void(RenderTile&)> write_render_tile_cb;
boost::function<void(RenderTile&)> update_render_tile_cb;
@@ -119,6 +130,7 @@ public:
void set_samples(int samples);
void set_pause(bool pause);
+ void device_free();
protected:
struct DelayedReset {
thread_mutex mutex;
@@ -173,6 +185,12 @@ protected:
double reset_time;
double preview_time;
double paused_time;
+
+ /* progressive refine */
+ double last_update_time;
+ bool update_progressive_refine(bool cancel);
+
+ vector<RenderBuffers *> tile_buffers;
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index fae1d6bd81c..17f7fbd43d6 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -49,6 +49,8 @@ Shader::Shader()
has_volume = false;
has_displacement = false;
+ used = false;
+
need_update = true;
need_update_attributes = true;
}
@@ -98,6 +100,16 @@ void Shader::tag_update(Scene *scene)
}
}
+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;
+ }
+}
+
/* Shader Manager */
ShaderManager::ShaderManager()
@@ -161,6 +173,27 @@ int ShaderManager::get_shader_id(uint shader, Mesh *mesh, bool smooth)
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 */
+ foreach(Shader *shader, scene->shaders)
+ shader->used = false;
+
+ scene->shaders[scene->default_surface]->used = true;
+ scene->shaders[scene->default_light]->used = true;
+ scene->shaders[scene->default_background]->used = true;
+ scene->shaders[scene->default_holdout]->used = true;
+ scene->shaders[scene->default_empty]->used = true;
+
+ foreach(Mesh *mesh, scene->meshes)
+ foreach(uint shader, mesh->used_shaders)
+ scene->shaders[shader]->used = true;
+
+ foreach(Light *light, scene->lights)
+ scene->shaders[light->shader]->used = true;
+}
+
void ShaderManager::device_update_common(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
device_free_common(device, dscene);
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index 02788008060..373b3356f51 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -27,6 +27,10 @@
#include "util_string.h"
#include "util_types.h"
+#ifdef WITH_OSL
+#include <OSL/oslexec.h>
+#endif
+
CCL_NAMESPACE_BEGIN
class Device;
@@ -75,11 +79,23 @@ public:
/* requested mesh attributes */
AttributeRequestSet attributes;
+ /* determined before compiling */
+ bool used;
+
+#ifdef WITH_OSL
+ /* osl shading state references */
+ OSL::ShadingAttribStateRef osl_surface_ref;
+ OSL::ShadingAttribStateRef osl_surface_bump_ref;
+ OSL::ShadingAttribStateRef osl_volume_ref;
+ OSL::ShadingAttribStateRef osl_displacement_ref;
+#endif
+
Shader();
~Shader();
void set_graph(ShaderGraph *graph);
void tag_update(Scene *scene);
+ void tag_used(Scene *scene);
};
/* Shader Manager virtual base class
@@ -98,6 +114,7 @@ public:
virtual void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress) = 0;
virtual void device_free(Device *device, DeviceScene *dscene) = 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);
diff --git a/intern/cycles/render/svm.cpp b/intern/cycles/render/svm.cpp
index da287a10199..dc249984499 100644
--- a/intern/cycles/render/svm.cpp
+++ b/intern/cycles/render/svm.cpp
@@ -48,6 +48,9 @@ void SVMShaderManager::device_update(Device *device, DeviceScene *dscene, Scene
/* test if we need to update */
device_free(device, dscene);
+ /* determine which shaders are in use */
+ device_update_shaders_used(scene);
+
/* svm_nodes */
vector<int4> svm_nodes;
size_t i;
@@ -119,6 +122,8 @@ int SVMCompiler::stack_size(ShaderSocketType type)
{
if(type == SHADER_SOCKET_FLOAT)
return 1;
+ else if(type == SHADER_SOCKET_INT)
+ return 1;
else if(type == SHADER_SOCKET_COLOR)
return 3;
else if(type == SHADER_SOCKET_VECTOR)
@@ -212,10 +217,13 @@ void SVMCompiler::stack_assign(ShaderInput *input)
if(input->type == SHADER_SOCKET_FLOAT) {
add_node(NODE_VALUE_F, __float_as_int(input->value.x), input->stack_offset);
}
+ else if(input->type == SHADER_SOCKET_INT) {
+ add_node(NODE_VALUE_F, (int)input->value.x, input->stack_offset);
+ }
else if(input->type == SHADER_SOCKET_VECTOR ||
- input->type == SHADER_SOCKET_NORMAL ||
- input->type == SHADER_SOCKET_POINT ||
- input->type == SHADER_SOCKET_COLOR) {
+ input->type == SHADER_SOCKET_NORMAL ||
+ input->type == SHADER_SOCKET_POINT ||
+ input->type == SHADER_SOCKET_COLOR) {
add_node(NODE_VALUE_V, input->stack_offset);
add_node(NODE_VALUE_V, input->value);
@@ -274,17 +282,6 @@ void SVMCompiler::stack_clear_users(ShaderNode *node, set<ShaderNode*>& done)
foreach(ShaderInput *in, output->links)
in->stack_offset = SVM_STACK_INVALID;
-
- /* unmark any nodes that have no more valid outputs, see [#31806] */
- if(done.find(output->parent) != done.end()) {
- all_done = true;
- foreach(ShaderOutput *pout, output->parent->outputs)
- if(pout->stack_offset != SVM_STACK_INVALID)
- all_done = false;
-
- if(all_done)
- done.erase(output->parent);
- }
}
}
}
@@ -615,36 +612,38 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
output->stack_offset = SVM_STACK_INVALID;
}
- if(clin->link) {
- bool generate = false;
- if(type == SHADER_TYPE_SURFACE) {
- /* generate surface shader */
- generate = true;
- shader->has_surface = true;
- }
- else if(type == SHADER_TYPE_VOLUME) {
- /* generate volume shader */
- generate = true;
- shader->has_volume = true;
- }
- else if(type == SHADER_TYPE_DISPLACEMENT) {
- /* generate displacement shader */
- generate = true;
- shader->has_displacement = true;
- }
+ if(shader->used) {
+ if(clin->link) {
+ bool generate = false;
+ if(type == SHADER_TYPE_SURFACE) {
+ /* generate surface shader */
+ generate = true;
+ shader->has_surface = true;
+ }
+ else if(type == SHADER_TYPE_VOLUME) {
+ /* generate volume shader */
+ generate = true;
+ shader->has_volume = true;
+ }
+ else if(type == SHADER_TYPE_DISPLACEMENT) {
+ /* generate displacement shader */
+ generate = true;
+ shader->has_displacement = true;
+ }
- if(generate) {
- set<ShaderNode*> done;
+ if(generate) {
+ set<ShaderNode*> done;
- if(use_multi_closure)
- generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID);
- else
- generate_closure(clin->link->parent, done);
+ if(use_multi_closure)
+ generate_multi_closure(clin->link->parent, done, SVM_STACK_INVALID);
+ else
+ generate_closure(clin->link->parent, done);
+ }
}
- }
- /* compile output node */
- node->compile(*this);
+ /* compile output node */
+ node->compile(*this);
+ }
add_node(NODE_END, 0, 0, 0);
}
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 874f1a6b3aa..bbcdb47260e 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -23,12 +23,15 @@
CCL_NAMESPACE_BEGIN
-TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_, int num_devices_)
+TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_,
+ bool preserve_tile_device_, bool background_, int num_devices_)
{
progressive = progressive_;
tile_size = tile_size_;
start_resolution = start_resolution_;
num_devices = num_devices_;
+ preserve_tile_device = preserve_tile_device_;
+ background = background_;
BufferParams buffer_params;
reset(buffer_params, 0);
@@ -70,7 +73,45 @@ void TileManager::set_samples(int num_samples_)
num_samples = num_samples_;
}
-void TileManager::set_tiles()
+/* splits image into tiles and assigns equal amount of tiles to every render device */
+void TileManager::gen_tiles_global()
+{
+ int resolution = state.resolution_divider;
+ int image_w = max(1, params.width/resolution);
+ int image_h = max(1, params.height/resolution);
+
+ state.tiles.clear();
+
+ int tile_w = (tile_size.x >= image_w)? 1: (image_w + tile_size.x - 1)/tile_size.x;
+ int tile_h = (tile_size.y >= image_h)? 1: (image_h + tile_size.y - 1)/tile_size.y;
+
+ int num_logical_devices = preserve_tile_device? num_devices: 1;
+ int num = min(image_h, num_logical_devices);
+ int tile_index = 0;
+
+ int tiles_per_device = (tile_w * tile_h + num - 1) / 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++, tile_index++) {
+ 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)? image_h - y: tile_size.y;
+
+ state.tiles.push_back(Tile(tile_index, x, y, w, h, cur_device));
+ cur_tiles++;
+
+ if(cur_tiles == tiles_per_device) {
+ cur_tiles = 0;
+ cur_device++;
+ }
+ }
+ }
+}
+
+/* slices image into as much pieces as how many devices are rendering this image */
+void TileManager::gen_tiles_sliced()
{
int resolution = state.resolution_divider;
int image_w = max(1, params.width/resolution);
@@ -78,7 +119,9 @@ void TileManager::set_tiles()
state.tiles.clear();
- int num = min(image_h, num_devices);
+ int num_logical_devices = preserve_tile_device? num_devices: 1;
+ int num = min(image_h, num_logical_devices);
+ int tile_index = 0;
for(int device = 0; device < num; device++) {
int device_y = (image_h/num)*device;
@@ -86,20 +129,30 @@ void TileManager::set_tiles()
int tile_w = (tile_size.x >= image_w)? 1: (image_w + tile_size.x - 1)/tile_size.x;
int tile_h = (tile_size.y >= device_h)? 1: (device_h + tile_size.y - 1)/tile_size.y;
- int sub_w = (image_w + tile_w - 1)/tile_w;
- int sub_h = (device_h + tile_h - 1)/tile_h;
for(int tile_y = 0; tile_y < tile_h; tile_y++) {
- for(int tile_x = 0; tile_x < tile_w; tile_x++) {
- int x = tile_x * sub_w;
- int y = tile_y * sub_h;
- int w = (tile_x == tile_w-1)? image_w - x: sub_w;
- int h = (tile_y == tile_h-1)? device_h - y: sub_h;
+ for(int tile_x = 0; tile_x < tile_w; tile_x++, tile_index++) {
+ 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)? device_h - y: tile_size.y;
- state.tiles.push_back(Tile(x, y + device_y, w, h, device));
+ state.tiles.push_back(Tile(tile_index, x, y + device_y, w, h, device));
}
}
}
+}
+
+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);
+
+ if(background)
+ gen_tiles_global();
+ else
+ gen_tiles_sliced();
state.num_tiles = state.tiles.size();
@@ -120,13 +173,10 @@ list<Tile>::iterator TileManager::next_center_tile(int device)
int image_w = max(1, params.width/resolution);
int image_h = max(1, params.height/resolution);
- int num = min(image_h, num_devices);
-
- int device_y = (image_h / num) * device;
- int device_h = (device == num - 1) ? image_h - device * (image_h / num) : image_h / num;
+ int logical_device = preserve_tile_device? device: 0;
- int64_t centx = image_w / 2, centy = device_y + device_h / 2, tot = 1;
- int64_t mindist = (int64_t) image_w * (int64_t) device_h;
+ int64_t centx = image_w / 2, centy = image_h / 2, tot = 1;
+ int64_t mindist = (int64_t) image_w * (int64_t) image_h;
/* find center of rendering tiles, image center counts for 1 too */
for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
@@ -143,7 +193,7 @@ list<Tile>::iterator TileManager::next_center_tile(int device)
/* closest of the non-rendering tiles */
for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
- if(iter->device == device && iter->rendering == false) {
+ if(iter->device == logical_device && iter->rendering == false) {
Tile &cur_tile = *iter;
int64_t distx = centx - (cur_tile.x + cur_tile.w / 2);
@@ -160,11 +210,28 @@ list<Tile>::iterator TileManager::next_center_tile(int device)
return best;
}
+list<Tile>::iterator TileManager::next_simple_tile(int device)
+{
+ list<Tile>::iterator iter;
+
+ int logical_device = preserve_tile_device? device: 0;
+
+ for(iter = state.tiles.begin(); iter != state.tiles.end(); iter++) {
+ if(iter->device == logical_device && iter->rendering == false)
+ return iter;
+ }
+
+ return state.tiles.end();
+}
+
bool TileManager::next_tile(Tile& tile, int device)
{
list<Tile>::iterator tile_it;
- tile_it = next_center_tile(device);
+ if(background)
+ tile_it = next_center_tile(device);
+ else
+ tile_it = next_simple_tile(device);
if(tile_it != state.tiles.end()) {
tile_it->rendering = true;
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index d820f74e3bd..6f7a8f20734 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -30,6 +30,7 @@ CCL_NAMESPACE_BEGIN
class Tile {
public:
+ int index;
int x, y, w, h;
int device;
bool rendering;
@@ -37,8 +38,8 @@ public:
Tile()
{}
- Tile(int x_, int y_, int w_, int h_, int device_)
- : x(x_), y(y_), w(w_), h(h_), device(device_), rendering(false) {}
+ Tile(int index_, int x_, int y_, int w_, int h_, int device_)
+ : index(index_), x(x_), y(y_), w(w_), h(h_), device(device_), rendering(false) {}
};
/* Tile Manager */
@@ -57,7 +58,8 @@ public:
list<Tile> tiles;
} state;
- TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution, int num_devices = 1);
+ TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution,
+ bool preserve_tile_device, bool background, int num_devices = 1);
~TileManager();
void reset(BufferParams& params, int num_samples);
@@ -75,7 +77,38 @@ protected:
int start_resolution;
int num_devices;
- list<Tile>::iterator next_center_tile(int device = 0);
+ /* 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;
+
+ /* splits image into tiles and assigns equal amount of tiles to every render device */
+ void gen_tiles_global();
+
+ /* slices image into as much pieces as how many devices are rendering this image */
+ void gen_tiles_sliced();
+
+ /* returns closest tile to center of rendered tiles
+ * mimics behavior of blender internal's tile order
+ */
+ list<Tile>::iterator next_center_tile(int device);
+
+ /* returns first unhandled tile starting from left bottom corner of the image */
+ list<Tile>::iterator next_simple_tile(int device);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/subd/CMakeLists.txt b/intern/cycles/subd/CMakeLists.txt
index c0986e9c173..838776d60bf 100644
--- a/intern/cycles/subd/CMakeLists.txt
+++ b/intern/cycles/subd/CMakeLists.txt
@@ -6,7 +6,9 @@ set(INC
../kernel/svm
../render
)
+
set(INC_SYS
+
)
set(SRC
diff --git a/intern/cycles/subd/subd_build.cpp b/intern/cycles/subd/subd_build.cpp
index 312980f1fa2..8e84da7f019 100644
--- a/intern/cycles/subd/subd_build.cpp
+++ b/intern/cycles/subd/subd_build.cpp
@@ -333,7 +333,7 @@ void SubdAccBuilder::computeEdgeStencil(SubdFaceRing *ring, GregoryAccStencil *s
/* @@ this probably does not provide watertight results!! (1/3 + 1/3 + 1/3 != 1) */
/* distribute weight to all verts */
- stencil->get(eid1, vert) += beta * costerm1_b / 3.0f;
+ stencil->get(eid1, vert) += beta * costerm1_b / 3.0f;
stencil->get(eid1, edge->to()) += beta * costerm1_b / 3.0f;
stencil->get(eid1, edge->next->to()) += beta * costerm1_b / 3.0f;
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index 6349870f4a2..4e6ecdeb5d6 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -2,6 +2,7 @@
set(INC
.
)
+
set(INC_SYS
${GLEW_INCLUDE_PATH}
${OPENGL_INCLUDE_DIR}
diff --git a/intern/cycles/util/util_attribute.cpp b/intern/cycles/util/util_attribute.cpp
index 3a1c2b6f332..057fb6213e9 100644
--- a/intern/cycles/util/util_attribute.cpp
+++ b/intern/cycles/util/util_attribute.cpp
@@ -30,6 +30,10 @@ const char *attribute_standard_name(AttributeStandard std)
return "uv";
else if(std == ATTR_STD_GENERATED)
return "generated";
+ else if(std == ATTR_STD_UV_TANGENT)
+ return "tangent";
+ else if(std == ATTR_STD_UV_TANGENT_SIGN)
+ return "tangent_sign";
else if(std == ATTR_STD_POSITION_UNDEFORMED)
return "undeformed";
else if(std == ATTR_STD_POSITION_UNDISPLACED)
diff --git a/intern/cycles/util/util_boundbox.h b/intern/cycles/util/util_boundbox.h
index b35c4c12bb8..a0cdf1761ad 100644
--- a/intern/cycles/util/util_boundbox.h
+++ b/intern/cycles/util/util_boundbox.h
@@ -31,6 +31,8 @@ using namespace std;
CCL_NAMESPACE_BEGIN
+/* 3D BoundBox */
+
class BoundBox
{
public:
@@ -160,6 +162,75 @@ __forceinline BoundBox intersect(const BoundBox& a, const BoundBox& b, const Bou
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);
+ }
+
+ 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__ */
diff --git a/intern/cycles/util/util_cuda.cpp b/intern/cycles/util/util_cuda.cpp
index 2960022fd8d..2716f00e173 100644
--- a/intern/cycles/util/util_cuda.cpp
+++ b/intern/cycles/util/util_cuda.cpp
@@ -17,6 +17,7 @@
*/
#include <stdlib.h>
+#include <stdio.h>
#include "util_cuda.h"
#include "util_debug.h"
@@ -413,8 +414,18 @@ string cuCompilerPath()
return nvcc;
#ifndef _WIN32
- if(system("which nvcc") == 0)
- return "nvcc";
+ {
+ FILE *handle = popen("which nvcc", "r");
+ if(handle) {
+ char buffer[4096] = {0};
+ int len = fread(buffer, 1, sizeof(buffer) - 1, handle);
+ buffer[len] = '\0';
+ pclose(handle);
+
+ if(buffer[0])
+ return "nvcc";
+ }
+ }
#endif
return "";
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 0b6f020ade5..70adee4385b 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -1069,6 +1069,29 @@ __device_inline float3 safe_divide_color(float3 a, float3 b)
return make_float3(x, y, z);
}
+/* Rotation of point around axis and angle */
+
+__device_inline float3 rotate_around_axis(float3 p, float3 axis, float angle)
+{
+ 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.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);
+
+ return r;
+}
+
CCL_NAMESPACE_END
#endif /* __UTIL_MATH_H__ */
diff --git a/intern/cycles/util/util_md5.h b/intern/cycles/util/util_md5.h
index 43e08e64f39..aab177d9fe6 100644
--- a/intern/cycles/util/util_md5.h
+++ b/intern/cycles/util/util_md5.h
@@ -44,7 +44,7 @@ public:
bool append_file(const string& filepath);
string get_hex();
- protected:
+protected:
void process(const uint8_t *data);
void finish(uint8_t digest[16]);
diff --git a/intern/cycles/util/util_opencl.cpp b/intern/cycles/util/util_opencl.cpp
index 40b637f5cb7..c146c14b10c 100644
--- a/intern/cycles/util/util_opencl.cpp
+++ b/intern/cycles/util/util_opencl.cpp
@@ -140,6 +140,10 @@ int clLibraryInit()
#endif
int error = 0;
+ // OpenCL disabled for now, only works with this environment variable set
+ if(!getenv("CYCLES_OPENCL_TEST"))
+ return 0;
+
// Check if already initialized
if (module != NULL)
{
diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp
index a571fe81118..8cf23bc6a76 100644
--- a/intern/cycles/util/util_path.cpp
+++ b/intern/cycles/util/util_path.cpp
@@ -170,7 +170,7 @@ bool path_read_binary(const string& path, vector<uint8_t>& binary)
return true;
}
-static bool path_read_text(const string& path, string& text)
+bool path_read_text(const string& path, string& text)
{
vector<uint8_t> binary;
@@ -184,6 +184,14 @@ static bool path_read_text(const string& path, string& text)
return true;
}
+uint64_t path_modified_time(const string& path)
+{
+ if(boost::filesystem::exists(path))
+ return (uint64_t)boost::filesystem::last_write_time(path);
+
+ return 0;
+}
+
string path_source_replace_includes(const string& source_, const string& path)
{
/* our own little c preprocessor that replaces #includes with the file
diff --git a/intern/cycles/util/util_path.h b/intern/cycles/util/util_path.h
index 6cba6a3158f..89e4452ecd9 100644
--- a/intern/cycles/util/util_path.h
+++ b/intern/cycles/util/util_path.h
@@ -45,6 +45,9 @@ string path_files_md5_hash(const string& dir);
void path_create_directories(const string& path);
bool path_write_binary(const string& path, const vector<uint8_t>& binary);
bool path_read_binary(const string& path, vector<uint8_t>& binary);
+bool path_read_text(const string& path, string& text);
+
+uint64_t path_modified_time(const string& path);
string path_source_replace_includes(const string& source, const string& path);
diff --git a/intern/cycles/util/util_progress.h b/intern/cycles/util/util_progress.h
index c97379d8776..03e25d4d132 100644
--- a/intern/cycles/util/util_progress.h
+++ b/intern/cycles/util/util_progress.h
@@ -68,6 +68,21 @@ public:
return *this;
}
+ void reset()
+ {
+ tile = 0;
+ sample = 0;
+ start_time = time_dt();
+ total_time = 0.0f;
+ tile_time = 0.0f;
+ status = "Initializing";
+ substatus = "";
+ sync_status = "";
+ sync_substatus = "";
+ cancel = false;
+ cancel_message = "";
+ }
+
/* cancel */
void set_cancel(const string& cancel_message_)
{
diff --git a/intern/cycles/util/util_stats.h b/intern/cycles/util/util_stats.h
new file mode 100644
index 00000000000..27638015f40
--- /dev/null
+++ b/intern/cycles/util/util_stats.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2012, Blender Foundation.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+#ifndef __UTIL_STATS_H__
+#define __UTIL_STATS_H__
+
+CCL_NAMESPACE_BEGIN
+
+class Stats {
+public:
+ Stats() : mem_used(0), mem_peak(0) {}
+
+ void mem_alloc(size_t size) {
+ mem_used += size;
+ if(mem_used > mem_peak)
+ mem_peak = mem_used;
+ }
+
+ void mem_free(size_t size) {
+ mem_used -= size;
+ }
+
+ size_t mem_used;
+ size_t mem_peak;
+};
+
+CCL_NAMESPACE_END
+
+#endif /* __UTIL_STATS_H__ */
diff --git a/intern/cycles/util/util_task.cpp b/intern/cycles/util/util_task.cpp
index ea0abd6f54f..8c4ec312256 100644
--- a/intern/cycles/util/util_task.cpp
+++ b/intern/cycles/util/util_task.cpp
@@ -168,10 +168,16 @@ void TaskScheduler::init(int num_threads)
if(users == 0) {
do_exit = false;
- /* launch threads that will be waiting for work */
- if(num_threads == 0)
+ if(num_threads == 0) {
+ /* automatic number of threads will be main thread + num cores */
num_threads = system_cpu_thread_count();
+ }
+ else {
+ /* main thread will also work, for fixed threads we count it too */
+ num_threads -= 1;
+ }
+ /* launch threads that will be waiting for work */
threads.resize(num_threads);
thread_level.resize(num_threads);
diff --git a/intern/cycles/util/util_task.h b/intern/cycles/util/util_task.h
index 401a503f540..b795ca7524b 100644
--- a/intern/cycles/util/util_task.h
+++ b/intern/cycles/util/util_task.h
@@ -94,7 +94,11 @@ public:
static void init(int num_threads = 0);
static void exit();
- static int num_threads() { return threads.size(); }
+ /* number of threads that can work on tasks, main thread counts too */
+ static int num_threads() { return threads.size() + 1; }
+
+ /* test if any session is using the scheduler */
+ static bool active() { return users != 0; }
protected:
friend class TaskPool;
diff --git a/intern/cycles/util/util_thread.h b/intern/cycles/util/util_thread.h
index 9bea4e7808a..843764ca9d6 100644
--- a/intern/cycles/util/util_thread.h
+++ b/intern/cycles/util/util_thread.h
@@ -60,6 +60,7 @@ public:
bool join()
{
+ joined = true;
return pthread_join(pthread_id, NULL) == 0;
}
diff --git a/intern/cycles/util/util_transform.cpp b/intern/cycles/util/util_transform.cpp
index b3c6506dfa0..70ee13d96d7 100644
--- a/intern/cycles/util/util_transform.cpp
+++ b/intern/cycles/util/util_transform.cpp
@@ -246,9 +246,10 @@ static void transform_decompose(Transform *decomp, const Transform *tfm)
decomp->w = make_float4(scale.y.z, scale.z.x, scale.z.y, scale.z.z);
}
-void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion)
+void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid)
{
transform_decompose(&decomp->pre, &motion->pre);
+ transform_decompose(&decomp->mid, mid);
transform_decompose(&decomp->post, &motion->post);
}
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index d93bbff5415..df525542207 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -41,6 +41,7 @@ typedef struct Transform {
typedef struct MotionTransform {
Transform pre;
+ Transform mid;
Transform post;
} MotionTransform;
@@ -304,10 +305,18 @@ __device_inline float4 quat_interpolate(float4 q1, float4 q2, float t)
{
float costheta = dot(q1, q2);
+ /* rotate around shortest angle */
+ if(costheta < 0.0f) {
+ costheta = -costheta;
+ q1 = -q1;
+ }
+
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));
float thetap = theta * t;
float4 qperp = normalize(q2 - q1 * costheta);
@@ -375,11 +384,37 @@ __device void transform_motion_interpolate(Transform *tfm, const MotionTransform
{
Transform decomp;
- decomp.x = quat_interpolate(motion->pre.x, motion->post.x, t);
- decomp.y = (1.0f - t)*motion->pre.y + t*motion->post.y;
- decomp.z = (1.0f - t)*motion->pre.z + t*motion->post.z;
- decomp.w = (1.0f - t)*motion->pre.w + t*motion->post.w;
+ /* 3 point bezier curve interpolation for position */
+ float3 Ppre = float4_to_float3(motion->pre.y);
+ float3 Pmid = float4_to_float3(motion->mid.y);
+ float3 Ppost = float4_to_float3(motion->post.y);
+
+ float3 Pcontrol = 2.0f*Pmid - 0.5f*(Ppre + Ppost);
+ float3 P = Ppre*t*t + Pcontrol*2.0f*t*(1.0f - t) + Ppost*(1.0f - t)*(1.0f - t);
+
+ decomp.y.x = P.x;
+ decomp.y.y = P.y;
+ decomp.y.z = P.z;
+
+ /* linear interpolation for rotation and scale */
+ if(t < 0.5f) {
+ t *= 2.0f;
+
+ decomp.x = quat_interpolate(motion->pre.x, motion->mid.x, t);
+ decomp.y.w = (1.0f - t)*motion->pre.y.w + t*motion->mid.y.w;
+ decomp.z = (1.0f - t)*motion->pre.z + t*motion->mid.z;
+ decomp.w = (1.0f - t)*motion->pre.w + t*motion->mid.w;
+ }
+ else {
+ t = (t - 0.5f)*2.0f;
+
+ decomp.x = quat_interpolate(motion->mid.x, motion->post.x, t);
+ decomp.y.w = (1.0f - t)*motion->mid.y.w + t*motion->post.y.w;
+ decomp.z = (1.0f - t)*motion->mid.z + t*motion->post.z;
+ decomp.w = (1.0f - t)*motion->mid.w + t*motion->post.w;
+ }
+ /* compose rotation, translation, scale into matrix */
transform_compose(tfm, &decomp);
}
@@ -390,7 +425,7 @@ __device_inline bool operator==(const MotionTransform& A, const MotionTransform&
return (A.pre == B.pre && A.post == B.post);
}
-void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion);
+void transform_motion_decompose(MotionTransform *decomp, const MotionTransform *motion, const Transform *mid);
#endif
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index 5c6b9d5bb78..fe530d727ad 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -449,6 +449,8 @@ typedef enum AttributeStandard {
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_POSITION_UNDEFORMED,
ATTR_STD_POSITION_UNDISPLACED,
diff --git a/intern/decimation/CMakeLists.txt b/intern/decimation/CMakeLists.txt
deleted file mode 100644
index 73b67d7f3b1..00000000000
--- a/intern/decimation/CMakeLists.txt
+++ /dev/null
@@ -1,63 +0,0 @@
-# ***** BEGIN GPL LICENSE BLOCK *****
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License
-# as published by the Free Software Foundation; either version 2
-# of the License, or (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-#
-# The Original Code is Copyright (C) 2006, Blender Foundation
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): Jacques Beaurain.
-#
-# ***** END GPL LICENSE BLOCK *****
-
-set(INC
- .
- ../container
- ../guardedalloc
- ../memutil
- ../moto/include
-)
-
-set(INC_SYS
-
-)
-
-set(SRC
- intern/LOD_EdgeCollapser.cpp
- intern/LOD_ExternNormalEditor.cpp
- intern/LOD_FaceNormalEditor.cpp
- intern/LOD_ManMesh2.cpp
- intern/LOD_MeshPrimitives.cpp
- intern/LOD_QSDecimator.cpp
- intern/LOD_QuadricEditor.cpp
- intern/LOD_decimation.cpp
-
- extern/LOD_decimation.h
- intern/LOD_DecimationClass.h
- intern/LOD_EdgeCollapser.h
- intern/LOD_ExternBufferEditor.h
- intern/LOD_ExternNormalEditor.h
- intern/LOD_FaceNormalEditor.h
- intern/LOD_ManMesh2.h
- intern/LOD_MeshBounds.h
- intern/LOD_MeshException.h
- intern/LOD_MeshPrimitives.h
- intern/LOD_QSDecimator.h
- intern/LOD_Quadric.h
- intern/LOD_QuadricEditor.h
-)
-
-blender_add_lib(bf_intern_decimate "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/intern/decimation/SConscript b/intern/decimation/SConscript
deleted file mode 100644
index 6f4befb3ffa..00000000000
--- a/intern/decimation/SConscript
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/usr/bin/python
-Import ('env')
-
-sources = env.Glob('intern/*.cpp')
-
-incs = '. ../moto/include ../container ../memutil ../guardedalloc'
-
-env.BlenderLib ('bf_intern_decimate', sources, Split(incs) , [], libtype=['core', 'player'], priority = [200, 100] )
diff --git a/intern/decimation/extern/LOD_decimation.h b/intern/decimation/extern/LOD_decimation.h
deleted file mode 100644
index 4c52cb18577..00000000000
--- a/intern/decimation/extern/LOD_decimation.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/extern/LOD_decimation.h
- * \ingroup decimation
- */
-
-
-/**
-
- * @author Laurence Bourn
- * @date 6/7/2001
- *
- * This is the external interface for the decimation module.
- */
-
-#ifndef __LOD_DECIMATION_H__
-#define __LOD_DECIMATION_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * External decimation structure
- */
-
-typedef struct LOD_Decimation_Info {
- float * vertex_buffer;
- float * vertex_normal_buffer;
- int * triangle_index_buffer;
- int vertex_num;
- int face_num;
- void * intern;
-} LOD_Decimation_Info;
-
-typedef LOD_Decimation_Info* LOD_Decimation_InfoPtr;
-
-/**
- * Create internal mesh representation from
- * LOD_Decimation_Info structure.
- * @return 1 on successful loading
- * @return 0 on failure
- * @warning This should be changed to return an enumeration
- * detailing the error encountered
- */
-
-extern int LOD_LoadMesh(LOD_Decimation_InfoPtr info);
-
-/**
- * Allocate and Compute internal data strucures required for
- * decimation.
- * @return 1 on successful computation of data
- * @return 0 on failure
- * @warning This should be changed to return an enumeration
- * detailing the error encountered
- */
-
-extern int LOD_PreprocessMesh(LOD_Decimation_InfoPtr info);
-
-/**
- * Once both the stages above have been completed
- * this function collapses a single edge in the mesh.
- * The LOD_Decimation_Info structure is updated
- * to represent the new mesh.
- * @return 1 if an edge was collapsed.
- * @return 0 if no suitable edge was found to be collapsable
- * You should stop calling this method in this case
- * @warning Do not expect that the order of polygons, vertices or
- * vertex normals will be preserved by this operation. This function
- * returns a packed array of polygons and vertices and so necessarily
- * the order will be different. This means you should not expect to
- * find the same polygon in the same place in the polygon array after
- * this function has been called.
- */
-
-extern int LOD_CollapseEdge(LOD_Decimation_InfoPtr info);
-
-/**
- * Free any memory the decimation process used
- * during the decimation process
- * @return 1 if internal data successfully freed
- * @return 0 if no data was freed
- */
-
-extern int LOD_FreeDecimationData(LOD_Decimation_InfoPtr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif // __LOD_DECIMATION_H__
-
diff --git a/intern/decimation/intern/LOD_DecimationClass.h b/intern/decimation/intern/LOD_DecimationClass.h
deleted file mode 100644
index ecf2e4e6790..00000000000
--- a/intern/decimation/intern/LOD_DecimationClass.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_DecimationClass.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_DECIMATIONCLASS_H__
-#define __LOD_DECIMATIONCLASS_H__
-
-#include "MEM_SmartPtr.h"
-#include "MEM_NonCopyable.h"
-
-#include "LOD_ManMesh2.h"
-#include "LOD_QSDecimator.h"
-#include "LOD_ExternNormalEditor.h"
-#include "../extern/LOD_decimation.h"
-#include "LOD_ExternBufferEditor.h"
-
-
-class LOD_DecimationClass : public MEM_NonCopyable
-{
-public :
-
- enum {
- e_not_loaded,
- e_loaded,
- e_preprocessed
- } m_e_decimation_state;
-
-
- static
- LOD_DecimationClass *
- New(
- LOD_Decimation_InfoPtr extern_info
- ) {
- // create everything
-
- MEM_SmartPtr<LOD_DecimationClass> output(new LOD_DecimationClass());
- MEM_SmartPtr<LOD_ManMesh2> mesh(LOD_ManMesh2::New());
- MEM_SmartPtr<LOD_ExternBufferEditor> extern_editor(LOD_ExternBufferEditor::New(extern_info));
-
- if (mesh == NULL || extern_editor == NULL) return NULL;
- MEM_SmartPtr<LOD_ExternNormalEditor> normals(LOD_ExternNormalEditor::New(extern_info,mesh.Ref()));
-
- if (normals == NULL) return NULL;
- MEM_SmartPtr<LOD_QSDecimator> decimator(LOD_QSDecimator::New(
- mesh.Ref(),
- normals.Ref(),
- extern_editor.Ref()
- ));
- if (decimator == NULL || output == NULL) return NULL;
-
- output->m_mesh = mesh.Release();
- output->m_decimator = decimator.Release();
- output->m_normals = normals.Release();
- output->m_extern_editor = extern_editor.Release();
-
- return output.Release();
- }
-
- LOD_ManMesh2 &
- Mesh(
- ){
- return m_mesh.Ref();
- }
-
- LOD_QSDecimator &
- Decimator(
- ) {
- return m_decimator.Ref();
- }
-
- LOD_ExternNormalEditor &
- FaceEditor(
- ){
- return m_normals.Ref();
- }
-
-private :
-
- LOD_DecimationClass(
- ) : m_e_decimation_state(e_not_loaded) {
- };
-
- MEM_SmartPtr<LOD_ManMesh2> m_mesh;
- MEM_SmartPtr<LOD_QSDecimator> m_decimator;
- MEM_SmartPtr<LOD_ExternNormalEditor> m_normals;
- MEM_SmartPtr<LOD_ExternBufferEditor> m_extern_editor;
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_EdgeCollapser.cpp b/intern/decimation/intern/LOD_EdgeCollapser.cpp
deleted file mode 100644
index 1405d6f53fa..00000000000
--- a/intern/decimation/intern/LOD_EdgeCollapser.cpp
+++ /dev/null
@@ -1,410 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_EdgeCollapser.cpp
- * \ingroup decimation
- */
-
-
-#include "LOD_EdgeCollapser.h"
-
-#include "LOD_ManMesh2.h"
-#include "CTR_TaggedSetOps.h"
-#include <algorithm>
-#include <functional>
-
-
-using namespace std;
-
-
- LOD_EdgeCollapser *
-LOD_EdgeCollapser::
-New(
-){
- return new LOD_EdgeCollapser();
-}
-
-
- bool
-LOD_EdgeCollapser::
-TJunctionTest(
- LOD_ManMesh2 &mesh,
- vector<LOD_EdgeInd> &e_v0v1,
- LOD_EdgeInd collapse_edge
-){
-
- // we need to copy the edges in e_v0v1 from the mesh
- // into a new buffer -> we are going to modify them
-
- int original_size = e_v0v1.size();
- if (original_size == 0) return true;
-
- vector<LOD_Edge> &edge_set = mesh.EdgeSet();
-
- LOD_VertexInd c_v0 = edge_set[collapse_edge].m_verts[0];
- LOD_VertexInd c_v1 = edge_set[collapse_edge].m_verts[1];
-
- vector<LOD_Edge> temp_edges;
- temp_edges.reserve(e_v0v1.size());
-
- vector<LOD_EdgeInd>::iterator edge_it = e_v0v1.begin();
- vector<LOD_EdgeInd>::const_iterator edge_end = e_v0v1.end();
-
- for (;edge_it != edge_end; ++edge_it) {
- temp_edges.push_back(edge_set[*edge_it]);
- }
-
- // in the copied edges replace all instances of c_v0 with c_v1
-
- vector<LOD_Edge>::iterator e_it = temp_edges.begin();
- vector<LOD_Edge>::const_iterator e_it_end = temp_edges.end();
-
- for (; e_it != e_it_end; ++e_it) {
-
- if (e_it->m_verts[0] == c_v0) {
- e_it->m_verts[0] = c_v1;
- }
- if (e_it->m_verts[1] == c_v0) {
- e_it->m_verts[1] = c_v1;
- }
-
- // normalize the edge
- if (int(e_it->m_verts[0]) > int(e_it->m_verts[1])) {
- LOD_EdgeInd temp = e_it->m_verts[0];
- e_it->m_verts[0] = e_it->m_verts[1];
- e_it->m_verts[1] = temp;
- }
- }
-
- // sort the edges using the edge less functional
-
- sort(temp_edges.begin(),temp_edges.end(),LOD_EdgeCollapser::less());
- // count the unique edges.
-
- e_it = temp_edges.begin();
- e_it_end = temp_edges.end();
-
- int coincedent_edges = 0;
-
- vector<LOD_Edge>::const_iterator last_edge = e_it;
- ++e_it;
-
- for (; e_it != e_it_end; ++e_it) {
-
- if ((e_it->m_verts[0] == last_edge->m_verts[0]) &&
- (e_it->m_verts[1] == last_edge->m_verts[1])
- ) {
- ++coincedent_edges;
- }
- last_edge = e_it;
- }
-
- // now if the collapse edge is a boundary edges
- // then we are alloved at most one coincedent edge
-
- // otherwise at most 2 coincedent edges
-
- if (edge_set[collapse_edge].BoundaryEdge()) {
- return (coincedent_edges > 1);
- } else {
- return (coincedent_edges > 2);
- }
-
-
-}
-
-
-
- bool
-LOD_EdgeCollapser::
-CollapseEdge(
- LOD_EdgeInd ei,
- LOD_ManMesh2 &mesh,
- vector<LOD_EdgeInd> & degenerate_edges,
- vector<LOD_FaceInd> & degenerate_faces,
- vector<LOD_VertexInd> & degenerate_vertices,
- vector<LOD_EdgeInd> & new_edges,
- vector<LOD_FaceInd> & update_faces,
- vector<LOD_VertexInd> & update_vertices
-){
-
- vector<LOD_Vertex> &verts = mesh.VertexSet();
- vector<LOD_Edge> &edges = mesh.EdgeSet();
- vector<LOD_TriFace> &faces = mesh.FaceSet();
-
- // shouldn't do this (use mesh interface instead!)
- LOD_VertexInd v0_ind = edges[ei].m_verts[0];
- LOD_VertexInd v1_ind = edges[ei].m_verts[1];
-#if 0
- LOD_Vertex &v0 = verts[v0_ind];
- LOD_Vertex &v1 = verts[v1_ind];
-#endif
- vector<vector<LOD_EdgeInd> > e_v01(2);
- e_v01[0].reserve(32);
- e_v01[1].reserve(32);
-
- mesh.VertexEdges(v0_ind,e_v01[0]);
- mesh.VertexEdges(v1_ind,e_v01[1]);
-
-
- // compute the union of e_v0 and e_v1 -> this is the degenerate edges of the collapse
- // we remove old edges and replace edges inside the collapse zone with new ones
-
- CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::Union(e_v01,edges,degenerate_edges);
-
- vector< vector<LOD_FaceInd> > p_v01(2);
- p_v01[0].reserve(32);
- p_v01[1].reserve(32);
-
- mesh.VertexFaces(v0_ind,p_v01[0]);
- mesh.VertexFaces(v1_ind,p_v01[1]);
-
- // compute the union of p_v0 anf p_v1
- vector<LOD_FaceInd> p_v0v1;
- p_v0v1.reserve(32);
-
- CTR_TaggedSetOps<LOD_FaceInd,LOD_TriFace>::Union(p_v01,faces,p_v0v1);
-
- // compute the union of all the edges in p_v0v1 this is the collapse zone
-
- vector<vector<LOD_EdgeInd> > e_input_vectors(p_v0v1.size());
-
- vector<LOD_FaceInd>::iterator p_v0v1_end = p_v0v1.end();
- vector<LOD_FaceInd>::iterator p_v0v1_start = p_v0v1.begin();
-
- vector<vector<LOD_FaceInd> >::iterator vector_insert_it = e_input_vectors.begin();
-
- for (;p_v0v1_start != p_v0v1_end; ++p_v0v1_start , ++vector_insert_it) {
- mesh.FaceEdges(*p_v0v1_start,*vector_insert_it);
- }
-
- vector<LOD_EdgeInd> collapse_zone;
- collapse_zone.reserve(32);
-
- CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::Union(e_input_vectors,edges,collapse_zone);
-
- // compute the ring edges = collpase_zone - e_v0v1
-
- vector<LOD_EdgeInd> edge_ring;
- edge_ring.reserve(32);
-
- CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::Difference(collapse_zone,degenerate_edges,edges,edge_ring);
-
- // T Junction test
- //////////////////
- // At this point we check to see if any of the polygons
- // in p_v0v1 are coninceddent - this leads
- // to errors later on if we try and insert a polygon
- // into the mesh to an edge which already has 2 polygons.
-
- // not that t junctions occur naturally from edge collapses
- // and are not just the result of coincedent polygons
- // for example consider collapsing an edge that forms part
- // of a triangular bottle neck.
-
- // Really we need to make sure that we don't create t-junctions.
-
- // I think that a sufficient test is to check the number of
- // coincedent edge pairs after a collapse. If it is more than 2
- // then collapsing the edge may result in an undeleted edge
- // sharing more than 2 polygons. This test probably is too
- // restictive though.
-
- // To perform this test we need to make a copy of the edges
- // in e_v0v1. We then apply the contraction to these edge
- // copies. Sort them using a function that places coincedent
- // edges next to each other. And then count the number
- // of coincedent pairs.
-
- // Of course we have to do this test before we change any of the
- // mesh -> so we can back out safely.
-
- if (TJunctionTest(mesh,degenerate_edges,ei)) return false;
-
- // Compute the set of possibly degenerate vertices
- // this is the union of all the vertices of polygons
- // of v0 and v1
-
- vector<LOD_FaceInd>::iterator face_it = p_v0v1.begin();
- vector<LOD_FaceInd>::const_iterator face_end = p_v0v1.end();
-
-
- vector<vector<LOD_VertexInd> > p_v0v1_vertices(p_v0v1.size());
-
- for (int i = 0; face_it != face_end; ++face_it, ++i) {
- mesh.FaceVertices(*face_it,p_v0v1_vertices[i]);
- }
-
- vector<LOD_VertexInd> vertex_ring;
- vertex_ring.reserve(32);
-
- CTR_TaggedSetOps<LOD_VertexInd,LOD_Vertex>::Union(p_v0v1_vertices,verts,vertex_ring);
-
- // remove all the internal edges e_v0v1 from the mesh.
- // for each edge remove the egde from it's vertices edge lists.
-
- vector<LOD_EdgeInd>::iterator edge_it = degenerate_edges.begin();
- vector<LOD_EdgeInd>::const_iterator edge_end = degenerate_edges.end();
-
- for (; !(edge_it == edge_end); ++edge_it) {
-
- LOD_EdgeInd ed = (*edge_it);
- LOD_Edge & edge = edges[ed];//*edge_it];
-
- verts[edge.m_verts[0]].RemoveEdge(ed);
- verts[edge.m_verts[1]].RemoveEdge(ed);
- }
-
- // we postpone deletion of the internal edges untill the end
- // this is because deleting edges invalidates all of the
- // EdgeInd vectors above.
-
-
- // now untie all the polygons in p_v0v1 from the edge ring
-
- // select all polygons in p_v0v1
-
- face_it = p_v0v1.begin();
- face_end = p_v0v1.end();
-
- for (;face_it != face_end; ++face_it) {
- faces[*face_it].SetSelectTag(true);
- }
-
- edge_it = edge_ring.begin();
- edge_end = edge_ring.end();
-
- for (;edge_it != edge_end; ++edge_it) {
- LOD_Edge & edge = edges[*edge_it];
-
- // presumably all edges in edge_ring point to at least
- // one polygon from p_v0v1
-
- if (!edge.m_faces[0].IsEmpty() && faces[edge.m_faces[0]].SelectTag()) {
- edge.m_faces[0].Invalidate();
- }
-
- if (!edge.m_faces[1].IsEmpty() && faces[edge.m_faces[1]].SelectTag()) {
- edge.m_faces[1].Invalidate();
- }
- }
-
- // deselect the faces
-
- face_it = p_v0v1.begin();
- face_end = p_v0v1.end();
-
- for (;face_it != face_end; ++face_it) {
- faces[*face_it].SetSelectTag(false);
- }
-
- // perform the edge collapse
- ////////////////////////////
-
- // iterate through the polygons of p_v0 and replace the vertex
- // index v0 with v1
-
- face_it = p_v01[0].begin();
- face_end = p_v01[0].end();
-
- for (;face_it != face_end; ++face_it) {
- faces[*face_it].SwapVertex(v0_ind,v1_ind);
- }
-
- face_it = p_v0v1.begin();
- face_end = p_v0v1.end();
-
- for (;face_it != face_end; ++face_it) {
- if (faces[*face_it].Degenerate()) {
- degenerate_faces.push_back(*face_it);
- } else {
- update_faces.push_back(*face_it);
- }
- }
-
- // Add all the non-degenerate faces back into the
- // mesh. Get a record of the new edges created in
- // this process.
-
- face_it = update_faces.begin();
- face_end = update_faces.end();
-
- for (;face_it != face_end; ++face_it) {
- mesh.ConnectTriangle(*face_it,new_edges);
- }
-
- // degenerate ring primitives
- /////////////////////////////
-
- // we now need to examine each of the edges on the ring
- // and work out if they are degenerate - if so we attempt
- // to delete them -> add them to the other edges to delete
- // in e_v0v1
-
- edge_it = edge_ring.begin();
- edge_end = edge_ring.end();
-
- for (;edge_it != edge_end; ++edge_it) {
- if (edges[*edge_it].Degenerate()) {
- degenerate_edges.push_back(*edge_it);
- }
- }
-
- // do the same for the ring vertices.
-
- vector<LOD_VertexInd>::iterator vertex_it = vertex_ring.begin();
- vector<LOD_VertexInd>::const_iterator vertex_end = vertex_ring.end();
-
- for (;vertex_it != vertex_end; ++vertex_it) {
- if (verts[*vertex_it].Degenerate()) {
- degenerate_vertices.push_back(*vertex_it);
- } else {
- update_vertices.push_back(*vertex_it);
- }
- }
-
- // we now know all the degenerate primitives
- // and the new primitives we have inserted into the mesh
-
- // We now delete the mesh primitives, mesh.DeleteXXXXXX() methods
- // assume that the index vectors are sorted into descending order.
- // we do that now.
-
- sort(degenerate_edges.begin(),degenerate_edges.end(),LOD_EdgeInd::greater());
- sort(degenerate_faces.begin(),degenerate_faces.end(),LOD_FaceInd::greater());
- sort(degenerate_vertices.begin(),degenerate_vertices.end(),LOD_VertexInd::greater());
-
-
- return true;
-
-}
-
-LOD_EdgeCollapser::
-LOD_EdgeCollapser(
-){
- // nothing to do
-}
diff --git a/intern/decimation/intern/LOD_EdgeCollapser.h b/intern/decimation/intern/LOD_EdgeCollapser.h
deleted file mode 100644
index 75a8b70f672..00000000000
--- a/intern/decimation/intern/LOD_EdgeCollapser.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_EdgeCollapser.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_EDGECOLLAPSER_H__
-#define __LOD_EDGECOLLAPSER_H__
-
-// This is a helper class that collapses edges of a 2 - manifold mesh.
-
-#include "LOD_MeshPrimitives.h"
-#include "MEM_NonCopyable.h"
-#include <vector>
-#include <functional>
-
-class LOD_ManMesh2;
-
-class LOD_EdgeCollapser
-: public MEM_NonCopyable
-{
-
-public :
-
- static
- LOD_EdgeCollapser *
- New(
- );
-
- // returns via arguments the set of modified
- // verts,edges and faces.
-
- bool
- CollapseEdge(
- LOD_EdgeInd ei,
- LOD_ManMesh2 &mesh,
- std::vector<LOD_EdgeInd> & degenerate_edges,
- std::vector<LOD_FaceInd> & degenerate_faces,
- std::vector<LOD_VertexInd> & degenerate_vertices,
- std::vector<LOD_EdgeInd> & new_edges,
- std::vector<LOD_FaceInd> & update_faces,
- std::vector<LOD_VertexInd> & update_vertices
- );
-
-private :
-
- LOD_EdgeCollapser(
- );
-
- // Test to see if the result of collapsing the
- // edge produces 2 junctions in the mesh i.e. where
- // an edge is shared by more than 2 polygons
-
- // We count the number of coincedent edge pairs that
- // result from the collapse of collapse_edge.
-
- // If collapse edge is a boundary edge then the number of
- // coincedent pairs should be 1
- // else it should be 2.
-
- bool
- TJunctionTest(
- LOD_ManMesh2 &mesh,
- std::vector<LOD_EdgeInd> &e_v0v1,
- LOD_EdgeInd collapse_edge
- );
-
- // here's the definition of the sort function
- // we use to determine coincedent edges
-
- // assumes the edges are normalized i.e. m_verts[0] <= m_verts[1]
-
- struct less : std::binary_function<LOD_Edge, LOD_Edge, bool> {
- bool
- operator()(
- const LOD_Edge& a,
- const LOD_Edge& b
- ) const {
-
- if (int(a.m_verts[0]) == int(b.m_verts[0])) {
- return (int(a.m_verts[1]) < int(b.m_verts[1]));
- } else {
- return (int(a.m_verts[0]) < int(b.m_verts[0]));
- }
- }
- };
-
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_ExternBufferEditor.h b/intern/decimation/intern/LOD_ExternBufferEditor.h
deleted file mode 100644
index c903b255812..00000000000
--- a/intern/decimation/intern/LOD_ExternBufferEditor.h
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_ExternBufferEditor.h
- * \ingroup decimation
- */
-
-
-/**
-
- * Copyright (C) 2001 NaN Technologies B.V.
- */
-
-#ifndef __LOD_EXTERNBUFFEREDITOR_H__
-#define __LOD_EXTERNBUFFEREDITOR_H__
-
-#include "LOD_MeshPrimitives.h"
-#include <vector>
-#include "LOD_ManMesh2.h"
-#include "../extern/LOD_decimation.h"
-
-
-// This class syncs external vertex/face buffers
-// with the internal mesh representation during
-// decimation.
-
-class LOD_ExternBufferEditor
-{
-
-public :
-
- static
- LOD_ExternBufferEditor *
- New(
- LOD_Decimation_InfoPtr extern_info
- ){
- if (extern_info == NULL) return NULL;
- return new LOD_ExternBufferEditor(extern_info);
- }
-
- // update the external vertex buffer with vertices
- // from the mesh
-
- void
- CopyModifiedVerts(
- LOD_ManMesh2 & mesh,
- const std::vector<LOD_VertexInd> & mod_vertices
- ){
-
- std::vector<LOD_VertexInd>::const_iterator v_start = mod_vertices.begin();
- std::vector<LOD_VertexInd>::const_iterator v_end = mod_vertices.end();
-
- std::vector<LOD_Vertex> & mesh_verts = mesh.VertexSet();
-
- float * const extern_vertex_ptr = m_extern_info->vertex_buffer;
-
- for (; v_start != v_end; ++v_start) {
- float * mod_vert = extern_vertex_ptr + int(*v_start)*3;
- mesh_verts[*v_start].CopyPosition(mod_vert);
- }
- }
-
- // update the external face buffer with faces from the mesh
-
- void
- CopyModifiedFaces(
- LOD_ManMesh2 & mesh,
- const std::vector<LOD_FaceInd> & mod_faces
- ){
-
- std::vector<LOD_FaceInd>::const_iterator f_start = mod_faces.begin();
- std::vector<LOD_FaceInd>::const_iterator f_end = mod_faces.end();
-
- std::vector<LOD_TriFace> &mesh_faces = mesh.FaceSet();
-
- int * const extern_face_ptr = m_extern_info->triangle_index_buffer;
-
- for (; f_start != f_end; ++f_start) {
- int *mod_face = extern_face_ptr + 3*int(*f_start);
- mesh_faces[*f_start].CopyVerts(mod_face);
- }
- }
-
-
- // Copy the last vertex over the vertex specified by
- // vi. Decrement the size of the vertex array
-
- void
- CopyBackVertex(
- LOD_VertexInd vi
- ){
-
- float * const extern_vertex_ptr = m_extern_info->vertex_buffer;
- int * extern_vertex_num = &(m_extern_info->vertex_num);
-
- float * last_external_vert = extern_vertex_ptr + 3*((*extern_vertex_num) - 1);
- float * external_vert = extern_vertex_ptr + 3*int(vi);
-
- external_vert[0] = last_external_vert[0];
- external_vert[1] = last_external_vert[1];
- external_vert[2] = last_external_vert[2];
-
- *extern_vertex_num -=1;
- }
-
- // Copy the last face over the face specified by fi
- // Decrement the size of the face array
-
- void
- CopyBackFace(
- LOD_FaceInd fi
- ) {
- int * const extern_face_ptr = m_extern_info->triangle_index_buffer;
- int * extern_face_num = &(m_extern_info->face_num);
-
- int * last_external_face = extern_face_ptr + 3*((*extern_face_num) -1);
- int * external_face = extern_face_ptr + 3*int(fi);
- external_face[0] = last_external_face[0];
- external_face[1] = last_external_face[1];
- external_face[2] = last_external_face[2];
-
- *extern_face_num -=1;
- }
-
-
-private :
-
- LOD_ExternBufferEditor(
- LOD_Decimation_InfoPtr extern_info
- ) :
- m_extern_info (extern_info)
- {
- }
-
- LOD_Decimation_InfoPtr const m_extern_info;
-
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_ExternNormalEditor.cpp b/intern/decimation/intern/LOD_ExternNormalEditor.cpp
deleted file mode 100644
index 90033fe672b..00000000000
--- a/intern/decimation/intern/LOD_ExternNormalEditor.cpp
+++ /dev/null
@@ -1,264 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_ExternNormalEditor.cpp
- * \ingroup decimation
- */
-
-
-#include "LOD_ExternNormalEditor.h"
-#include <vector>
-
-using namespace std;
-
-
-LOD_ExternNormalEditor::
-LOD_ExternNormalEditor(
- LOD_Decimation_InfoPtr extern_info,
- LOD_ManMesh2 &mesh
-) :
- m_mesh(mesh),
- m_extern_info (extern_info)
-{
-}
-
- LOD_ExternNormalEditor *
-LOD_ExternNormalEditor::
-New(
- LOD_Decimation_InfoPtr extern_info,
- LOD_ManMesh2 &mesh
-){
- if (extern_info == NULL) return NULL;
-
- MEM_SmartPtr<LOD_ExternNormalEditor> output(new LOD_ExternNormalEditor(extern_info,mesh));
-
- int face_num = mesh.FaceSet().size();
-
- MEM_SmartPtr<vector<MT_Vector3> > normals(new vector<MT_Vector3>);
-
- if (output == NULL ||
- normals == NULL
- ) {
- return NULL;
- }
-
- normals->reserve(face_num);
- output->m_normals = normals.Release();
-
- return output.Release();
-};
-
-
- void
-LOD_ExternNormalEditor::
-Remove(
- std::vector<LOD_FaceInd> &sorted_faces
-){
- // assumes a collection of faces sorted in descending order .
-
- vector<MT_Vector3> & normals = m_normals.Ref();
-
- vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
- vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
-
- for (; it_start != it_end; ++it_start) {
-
- if (normals.size() > 0) {
- MT_Vector3 temp = normals[*it_start];
-
- normals[*it_start] = normals.back();
- normals.back() = temp;
-
- normals.pop_back();
- }
-
- // FIXME - throw exception
- }
-}
-
-
- void
-LOD_ExternNormalEditor::
-Add(
-){
- MT_Vector3 zero(0.0f,0.0f,0.0f);
- m_normals->push_back(zero);
-};
-
- void
-LOD_ExternNormalEditor::
-Update(
- std::vector<LOD_FaceInd> &sorted_faces
-){
- vector<MT_Vector3> & normals = m_normals.Ref();
-
- vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
- vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
-
- const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
-
- for (; it_start != it_end; ++it_start) {
- normals[*it_start] = ComputeNormal(faces[*it_start]);
- }
-};
-
-
-
-
-// vertex normals
-/////////////////
-
- void
-LOD_ExternNormalEditor::
-RemoveVertexNormals(
- std::vector<LOD_VertexInd> &sorted_verts
-){
-
- float * vertex_normals = m_extern_info->vertex_normal_buffer;
-
- // assumption here that the vertexs normal number corresponds with
- // the number of vertices !
-
- int vertex_normal_num = m_extern_info->vertex_num;
-
- vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
- vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
-
- for (; it_start != it_end; ++it_start) {
-
- if (vertex_normal_num > 0) {
- float * vertex_normal = vertex_normals + int(*it_start)*3;
- float * last_vertex = vertex_normals + ((vertex_normal_num-1)*3);
-
- MT_Vector3 last_v(last_vertex);
- last_v.getValue(vertex_normal);
- vertex_normal_num--;
- }
-
- // FIXME - through exception
- }
-};
-
-
-
- void
-LOD_ExternNormalEditor::
-UpdateVertexNormals(
- std::vector<LOD_VertexInd> &sorted_verts
-){
- float * vertex_normals = m_extern_info->vertex_normal_buffer;
-
- vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
- vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
-
- for (; it_start != it_end; ++it_start) {
- MT_Vector3 temp = ComputeVertexNormal(*it_start);
- float * vertex_normal = vertex_normals + int(*it_start)*3;
- temp.getValue(vertex_normal);
- }
-}
-
-// Editor specific methods
-//////////////////////////
-
- void
-LOD_ExternNormalEditor::
-BuildNormals(
-) {
- const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
- vector<MT_Vector3> & normals = m_normals.Ref();
-
- int face_num = faces.size();
- int cur_face = 0;
-
- for (; cur_face < face_num; ++cur_face) {
-
- MT_Vector3 new_normal = ComputeNormal(faces[cur_face]);
- normals.push_back(new_normal);
- }
-}
-
-const
- MT_Vector3
-LOD_ExternNormalEditor::
-ComputeNormal(
- const LOD_TriFace &face
-) const {
-
- const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
-
- MT_Vector3 vec1 =
- verts[face.m_verts[1]].pos -
- verts[face.m_verts[0]].pos;
-
- MT_Vector3 vec2 =
- verts[face.m_verts[2]].pos -
- verts[face.m_verts[1]].pos;
-
- vec1 = vec1.cross(vec2);
-
- if (!vec1.fuzzyZero()) {
- vec1.normalize();
- return (vec1);
- } else {
- return (MT_Vector3(1.0,0,0));
- }
-}
-
-const
- MT_Vector3
-LOD_ExternNormalEditor::
-ComputeVertexNormal(
- const LOD_VertexInd v
-) const {
-
- // average the face normals surrounding this
- // vertex and normalize
- // vector<LOD_Vertex> &verts = m_mesh.VertexSet(); /*unused*/
- const vector<MT_Vector3> & face_normals = m_normals.Ref();
-
- vector<LOD_FaceInd> vertex_faces;
- vertex_faces.reserve(32);
-
- m_mesh.VertexFaces(v,vertex_faces);
-
- MT_Vector3 normal(0,0,0);
-
- vector<LOD_FaceInd>::const_iterator face_it = vertex_faces.begin();
- vector<LOD_FaceInd>::const_iterator face_end = vertex_faces.end();
-
- for (; face_it != face_end; ++face_it) {
- normal += face_normals[*face_it];
- }
-
- if (!normal.fuzzyZero()) {
- normal.normalize();
- return (normal);
- } else {
- return (MT_Vector3(1.0,0,0));
- }
-}
diff --git a/intern/decimation/intern/LOD_ExternNormalEditor.h b/intern/decimation/intern/LOD_ExternNormalEditor.h
deleted file mode 100644
index 52135196dc5..00000000000
--- a/intern/decimation/intern/LOD_ExternNormalEditor.h
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_ExternNormalEditor.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_EXTERNNORMALEDITOR_H__
-#define __LOD_EXTERNNORMALEDITOR_H__
-
-#include "MEM_NonCopyable.h"
-#include "LOD_ManMesh2.h"
-#include "MT_Vector3.h"
-#include "../extern/LOD_decimation.h"
-
-class LOD_ExternNormalEditor : public MEM_NonCopyable
-{
-
-public :
-
- // Creation
- ///////////
-
- static
- LOD_ExternNormalEditor *
- New(
- LOD_Decimation_InfoPtr,
- LOD_ManMesh2 &mesh
- );
-
- // Property editor interface
- ////////////////////////////
-
-
- // Faces
- ////////
- void
- Remove(
- std::vector<LOD_FaceInd> &sorted_faces
- );
-
- void
- Add(
- );
-
- void
- Update(
- std::vector<LOD_FaceInd> &sorted_faces
- );
-
- const
- std::vector<MT_Vector3> &
- Normals(
- ) const {
- return m_normals.Ref();
- };
-
-
- // vertex normals
- /////////////////
-
- void
- RemoveVertexNormals(
- std::vector<LOD_VertexInd> &sorted_verts
- );
-
-
- void
- UpdateVertexNormals(
- std::vector<LOD_VertexInd> &sorted_verts
- );
-
- // Editor specific methods
- //////////////////////////
-
- void
- BuildNormals(
- );
-
-
-private :
-
- MEM_SmartPtr<std::vector<MT_Vector3> > m_normals;
-
- LOD_ManMesh2 &m_mesh;
- LOD_Decimation_InfoPtr m_extern_info;
-
-private :
-
-
- LOD_ExternNormalEditor(
- LOD_Decimation_InfoPtr extern_info,
- LOD_ManMesh2 &mesh
- );
-
- const
- MT_Vector3
- ComputeNormal(
- const LOD_TriFace &face
- ) const;
-
- const
- MT_Vector3
- ComputeVertexNormal (
- const LOD_VertexInd vi
- ) const;
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_FaceNormalEditor.cpp b/intern/decimation/intern/LOD_FaceNormalEditor.cpp
deleted file mode 100644
index 430406a6d63..00000000000
--- a/intern/decimation/intern/LOD_FaceNormalEditor.cpp
+++ /dev/null
@@ -1,291 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_FaceNormalEditor.cpp
- * \ingroup decimation
- */
-
-
-// implementation of LOD_FaceNormalEditor.h
-
-///////////////////////////////////////
-#include "LOD_FaceNormalEditor.h"
-
-using namespace std;
-
-LOD_FaceNormalEditor::
-LOD_FaceNormalEditor(
- LOD_ManMesh2 & mesh
-) : m_mesh(mesh) {
-};
-
- LOD_FaceNormalEditor *
-LOD_FaceNormalEditor::
-New(
- LOD_ManMesh2 &mesh
-){
- // build a set of normals of the same size
- // as the number of polys in the mesh
-
- MEM_SmartPtr<LOD_FaceNormalEditor> output(new LOD_FaceNormalEditor(mesh));
-
- int face_num = mesh.FaceSet().size();
-
- MEM_SmartPtr<vector<MT_Vector3> > normals(new vector<MT_Vector3>);
- MEM_SmartPtr<vector<MT_Vector3> > vertex_normals(new vector<MT_Vector3>);
-
- if (output == NULL ||
- normals == NULL
- ) {
- return NULL;
- }
-
- normals->reserve(face_num);
- vertex_normals->reserve(mesh.VertexSet().size());
- output->m_normals = normals.Release();
- output->m_vertex_normals = vertex_normals.Release();
-
- return output.Release();
-};
-
-
-// Property editor interface
-////////////////////////////
-
- void
-LOD_FaceNormalEditor::
-Remove(
- std::vector<LOD_FaceInd> &sorted_faces
-){
-
- // assumes a collection of faces sorted in descending order .
-
- vector<MT_Vector3> & normals = m_normals.Ref();
-
- vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
- vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
-
- for (; it_start != it_end; ++it_start) {
-
- if (normals.size() > 0) {
- MT_Vector3 temp = normals[*it_start];
-
- normals[*it_start] = normals.back();
- normals.back() = temp;
-
- normals.pop_back();
- }
-
- // FIXME - through exception
- }
-}
-
-
- void
-LOD_FaceNormalEditor::
-Add(
-){
- MT_Vector3 zero(0.0f,0.0f,0.0f);
- m_normals->push_back(zero);
-}
-
- void
-LOD_FaceNormalEditor::
-Update(
- std::vector<LOD_FaceInd> &sorted_faces
-){
-
- vector<MT_Vector3> & normals = m_normals.Ref();
-
- vector<LOD_FaceInd>::const_iterator it_start = sorted_faces.begin();
- vector<LOD_FaceInd>::const_iterator it_end = sorted_faces.end();
-
- const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
-
- for (; it_start != it_end; ++it_start) {
- normals[*it_start] = ComputeNormal(faces[*it_start]);
- }
-};
-
-// vertex normals
-/////////////////
-
-
- void
-LOD_FaceNormalEditor::
-RemoveVertexNormals(
- vector<LOD_VertexInd> &sorted_verts
-){
- vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
-
- vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
- vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
-
- for (; it_start != it_end; ++it_start) {
-
- if (vertex_normals.size() > 0) {
- MT_Vector3 temp = vertex_normals[*it_start];
-
- vertex_normals[*it_start] = vertex_normals.back();
- vertex_normals.back() = temp;
-
- vertex_normals.pop_back();
- }
-
- // FIXME - through exception
- }
-};
-
- void
-LOD_FaceNormalEditor::
-UpdateVertexNormals(
- vector<LOD_VertexInd> &sorted_verts
-){
- vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
-
- vector<LOD_VertexInd>::const_iterator it_start = sorted_verts.begin();
- vector<LOD_VertexInd>::const_iterator it_end = sorted_verts.end();
-
- for (; it_start != it_end; ++it_start) {
- vertex_normals[*it_start] = ComputeVertexNormal(*it_start);
- }
-}
-
-
-
-// Editor specific methods
-//////////////////////////
-
- void
-LOD_FaceNormalEditor::
-BuildNormals(
-){
-
- const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
- vector<MT_Vector3> & normals = m_normals.Ref();
-
- int face_num = faces.size();
- int cur_face = 0;
-
- for (; cur_face < face_num; ++cur_face) {
-
- MT_Vector3 new_normal = ComputeNormal(faces[cur_face]);
- normals.push_back(new_normal);
- }
- // now build the vertex normals
-
- vector<MT_Vector3> & vertex_normals = m_vertex_normals.Ref();
- const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
-
- int vertex_num = verts.size();
- int cur_vertex = 0;
-
- for (; cur_vertex < vertex_num; ++cur_vertex) {
- MT_Vector3 new_normal = ComputeVertexNormal(cur_vertex);
- vertex_normals.push_back(new_normal);
- }
-}
-
-const
- MT_Vector3
-LOD_FaceNormalEditor::
-ComputeNormal(
- const LOD_TriFace &face
-) const {
-
- const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
-
- MT_Vector3 vec1 =
- verts[face.m_verts[1]].pos -
- verts[face.m_verts[0]].pos;
-
- MT_Vector3 vec2 =
- verts[face.m_verts[2]].pos -
- verts[face.m_verts[1]].pos;
-
- vec1 = vec1.cross(vec2);
-
- if (!vec1.fuzzyZero()) {
- vec1.normalize();
- return (vec1);
- } else {
- return (MT_Vector3(1.0,0,0));
- }
-}
-
-const
- MT_Vector3
-LOD_FaceNormalEditor::
-ComputeVertexNormal(
- const LOD_VertexInd v
-) const {
-
- // average the face normals surrounding this
- // vertex and normalize
- const vector<MT_Vector3> & face_normals = m_normals.Ref();
-
- vector<LOD_FaceInd> vertex_faces;
- vertex_faces.reserve(32);
-
- m_mesh.VertexFaces(v,vertex_faces);
-
- MT_Vector3 normal(0,0,0);
-
- vector<LOD_FaceInd>::const_iterator face_it = vertex_faces.begin();
- vector<LOD_FaceInd>::const_iterator face_end = vertex_faces.end();
-
- for (; face_it != face_end; ++face_it) {
- normal += face_normals[*face_it];
- }
-
- if (!normal.fuzzyZero()) {
- normal.normalize();
- return (normal);
- } else {
- return (MT_Vector3(1.0,0,0));
- }
-}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intern/decimation/intern/LOD_FaceNormalEditor.h b/intern/decimation/intern/LOD_FaceNormalEditor.h
deleted file mode 100644
index a221ab0bd7a..00000000000
--- a/intern/decimation/intern/LOD_FaceNormalEditor.h
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_FaceNormalEditor.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_FACENORMALEDITOR_H__
-#define __LOD_FACENORMALEDITOR_H__
-
-#include "MEM_NonCopyable.h"
-#include "LOD_ManMesh2.h"
-#include "MT_Vector3.h"
-
-
-class LOD_FaceNormalEditor : public MEM_NonCopyable
-{
-
-public :
-
- // Creation
- ///////////
-
- static
- LOD_FaceNormalEditor *
- New(
- LOD_ManMesh2 &mesh
- );
-
- // Property editor interface
- ////////////////////////////
-
-
- // Faces
- ////////
- void
- Remove(
- std::vector<LOD_FaceInd> &sorted_faces
- );
-
- void
- Add(
- );
-
- void
- Update(
- std::vector<LOD_FaceInd> &sorted_faces
- );
-
-
- // vertex normals
- /////////////////
-
- void
- RemoveVertexNormals(
- std::vector<LOD_VertexInd> &sorted_verts
- );
-
-
- void
- UpdateVertexNormals(
- std::vector<LOD_VertexInd> &sorted_verts
- );
-
-
-
- const
- std::vector<MT_Vector3> &
- Normals(
- ) const {
- return m_normals.Ref();
- };
-
-
- const
- std::vector<MT_Vector3> &
- VertexNormals(
- ) const {
- return m_vertex_normals.Ref();
- };
-
- // Editor specific methods
- //////////////////////////
-
- void
- BuildNormals(
- );
-
-
-private :
-
- MEM_SmartPtr<std::vector<MT_Vector3> > m_normals;
- MEM_SmartPtr<std::vector<MT_Vector3> > m_vertex_normals;
-
- LOD_ManMesh2 &m_mesh;
-
-private :
-
-
- LOD_FaceNormalEditor(LOD_ManMesh2 &mesh);
-
- const
- MT_Vector3
- ComputeNormal(
- const LOD_TriFace &face
- ) const;
-
- const
- MT_Vector3
- ComputeVertexNormal (
- const LOD_VertexInd vi
- ) const;
-
-
-
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_ManMesh2.cpp b/intern/decimation/intern/LOD_ManMesh2.cpp
deleted file mode 100644
index c618944162f..00000000000
--- a/intern/decimation/intern/LOD_ManMesh2.cpp
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_ManMesh2.cpp
- * \ingroup decimation
- */
-
-
-#include "LOD_ManMesh2.h"
-
-#include "MT_assert.h"
-#include <algorithm>
-#include "LOD_MeshException.h"
-#include "CTR_TaggedSetOps.h"
-#include "CTR_UHeap.h"
-#include "LOD_ExternBufferEditor.h"
-
-
-using namespace std;
-
-LOD_ManMesh2::
-LOD_ManMesh2(
-) :
- m_bbox_min(0,0,0),
- m_bbox_max(0,0,0)
-{
-}
-
-
- LOD_ManMesh2 *
-LOD_ManMesh2::
-New(
-){
- MEM_SmartPtr<LOD_ManMesh2> output(new LOD_ManMesh2());
- if (output == NULL) return NULL;
-
- // build the vertex, edge and face sets.
-
- MEM_SmartPtr<vector<LOD_Vertex> > verts(new vector<LOD_Vertex>);
- MEM_SmartPtr<vector<LOD_TriFace> > faces(new vector<LOD_TriFace>);
- MEM_SmartPtr<vector<LOD_Edge> > edges(new vector<LOD_Edge>);
-
- if ((faces == NULL) || (edges == NULL) || (verts == NULL)) {
- return NULL;
- }
-
- output->m_verts = verts.Release();
- output->m_faces = faces.Release();
- output->m_edges = edges.Release();
-
- return output.Release();
-}
-
-// take ownership of the vertices.
-
- bool
-LOD_ManMesh2::
-SetVertices(
- MEM_SmartPtr<vector<LOD_Vertex> > verts
-){
-
-
- // take ownership of vertices
- m_verts = verts;
-
- // create a polygon and edge buffer of half the size
- // and just use the automatic resizing feature of vector<>
- // to worry about the dynamic array resizing
-
- m_faces->clear();
- m_edges->clear();
-
- m_faces->reserve(m_verts->size()/2);
- m_edges->reserve(m_verts->size()/2);
-
- return true;
-
-}
-
-
-// add a triangle to the mesh
-
- void
-LOD_ManMesh2::
-AddTriangle(
- int verts[3]
-) {
-
- MT_assert(verts[0] < int(m_verts->size()));
- MT_assert(verts[1] < int(m_verts->size()));
- MT_assert(verts[2] < int(m_verts->size()));
-
- LOD_TriFace face;
- face.m_verts[0] = verts[0];
- face.m_verts[1] = verts[1];
- face.m_verts[2] = verts[2];
-
- LOD_FaceInd face_index = m_faces->size();
-
- m_faces->push_back(face);
-
- // now work out if any of the directed edges or their
- // companion edges exist already.
- // We go through the edges associated with each of the given vertices
-
- // the safest thing to do is iterate through each of the edge sets
- // check against each of the 2 other triangle edges to see if they are there
-
- vector<LOD_EdgeInd> new_edges;
- new_edges.reserve(3);
-
- InsertEdge(verts[0],verts[1],face_index,new_edges);
- InsertEdge(verts[1],verts[2],face_index,new_edges);
- InsertEdge(verts[2],verts[0],face_index,new_edges);
-
-}
-
-// Adds the index of any created edges to new_edges
-
- bool
-LOD_ManMesh2::
-InsertEdge(
- const LOD_VertexInd v1,
- const LOD_VertexInd v2,
- const LOD_FaceInd f,
- vector<LOD_EdgeInd> &new_edges
-){
-
- MT_assert(!v1.IsEmpty());
- MT_assert(!v2.IsEmpty());
- MT_assert(!f.IsEmpty());
-
- vector<LOD_Vertex> &verts = VertexSet();
- vector<LOD_Edge> &edges = EdgeSet();
-
- LOD_EdgeInd e;
-
- e = FindEdge(v1,v2);
-
- if (e.IsEmpty()) {
- // This edge does not exist -- make a new one
-
- LOD_Edge temp_e;
- temp_e.m_verts[0] = v1;
- temp_e.m_verts[1] = v2;
-
- e = m_edges->size();
-
- // set the face ptr for this half-edge
- temp_e.m_faces[0] = f;
-
- m_edges->push_back(temp_e);
-
- // add the edge index to it's vertices
-
- verts[v1].AddEdge(e);
- verts[v2].AddEdge(e);
-
- new_edges.push_back(e);
-
- } else {
-
- // edge already exists
- // insure that there is no polygon already
- // attached to the other side of this edge
-
- // swap the empty face pointer in edge with f
-
- LOD_Edge &edge = edges[e];
-
- edge.SwapFace(LOD_FaceInd::Empty(),f);
- }
-
-
- return true;
-
-}
-
- void
-LOD_ManMesh2::
-ConnectTriangle(
- LOD_FaceInd fi,
- std::vector<LOD_EdgeInd> & new_edges
-){
-
- vector<LOD_TriFace> &faces = FaceSet();
-
- MT_assert(!faces[fi].Degenerate());
-
- LOD_TriFace & face = faces[fi];
-
- InsertEdge(face.m_verts[0],face.m_verts[1],fi,new_edges);
- InsertEdge(face.m_verts[1],face.m_verts[2],fi,new_edges);
- InsertEdge(face.m_verts[2],face.m_verts[0],fi,new_edges);
-};
-
-
-
-
-// geometry access
-//////////////////
-
- vector<LOD_Vertex> &
-LOD_ManMesh2::
-VertexSet(
-) const {
- return m_verts.Ref();
-}
-
- vector<LOD_TriFace> &
-LOD_ManMesh2::
-FaceSet(
-) const {
- return m_faces.Ref();
-}
-
- vector<LOD_Edge> &
-LOD_ManMesh2::
-EdgeSet(
-) const {
- return m_edges.Ref();
-};
-
-LOD_ManMesh2::
-~LOD_ManMesh2(
-){
- //auto ptr takes care of vertex arrays etc.
-}
-
- LOD_EdgeInd
-LOD_ManMesh2::
-FindEdge(
- const LOD_VertexInd v1,
- const LOD_VertexInd v2
-) {
-
- vector<LOD_Vertex> &verts = VertexSet();
- vector<LOD_Edge> &edges = EdgeSet();
-
- LOD_Edge e;
- e.m_verts[0] = v1;
- e.m_verts[1] = v2;
-
- vector<LOD_EdgeInd> &v1_edges = verts[v1].m_edges;
- vector<LOD_EdgeInd>::const_iterator v1_end = v1_edges.end();
- vector<LOD_EdgeInd>::iterator v1_begin = v1_edges.begin();
-
- for (; v1_begin != v1_end; ++v1_begin) {
- if (edges[*v1_begin] == e) return *v1_begin;
- }
-
- return LOD_EdgeInd::Empty();
-}
-
-// face queries
-///////////////
-
- void
-LOD_ManMesh2::
-FaceVertices(
- LOD_FaceInd fi,
- vector<LOD_VertexInd> &output
-){
- const vector<LOD_TriFace> &faces = FaceSet();
- const LOD_TriFace & f = faces[fi];
-
- output.push_back(f.m_verts[0]);
- output.push_back(f.m_verts[1]);
- output.push_back(f.m_verts[2]);
-}
-
- void
-LOD_ManMesh2::
-FaceEdges(
- LOD_FaceInd fi,
- vector<LOD_EdgeInd> &output
-){
- const vector<LOD_TriFace> &faces = FaceSet();
- vector<LOD_Edge> &edges = EdgeSet();
- vector<LOD_Vertex> &verts = VertexSet();
-
- const LOD_TriFace & f = faces[fi];
- // intersect vertex edges
-
- vector<LOD_EdgeInd> & v0_edges = verts[f.m_verts[0]].m_edges;
- vector<LOD_EdgeInd> & v1_edges = verts[f.m_verts[1]].m_edges;
- vector<LOD_EdgeInd> & v2_edges = verts[f.m_verts[2]].m_edges;
-
- CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v0_edges,v1_edges,edges,output);
- CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v1_edges,v2_edges,edges,output);
- CTR_TaggedSetOps<LOD_EdgeInd,LOD_Edge>::IntersectPair(v2_edges,v0_edges,edges,output);
-
- MT_assert(output.size() == 3);
- if (output.size() != 3) {
- LOD_MeshException e(LOD_MeshException::e_non_manifold);
- throw(e);
- }
-}
-
-
-// edge queries
-///////////////
-
- void
-LOD_ManMesh2::
-EdgeVertices(
- LOD_EdgeInd ei,
- vector<LOD_VertexInd> &output
-){
- const vector<LOD_Edge> &edges = EdgeSet();
- const LOD_Edge & e = edges[ei];
-
- output.push_back(e.m_verts[0]);
- output.push_back(e.m_verts[1]);
-}
-
- void
-LOD_ManMesh2::
-EdgeFaces(
- LOD_EdgeInd ei,
- vector<LOD_FaceInd> &output
-){
- const vector<LOD_Edge> &edges = EdgeSet();
- const LOD_Edge & e = edges[ei];
-
- if (!e.m_faces[0].IsEmpty()) {
- output.push_back(e.m_faces[0]);
- }
- if (!e.m_faces[1].IsEmpty()) {
- output.push_back(e.m_faces[1]);
- }
-}
-
-// vertex queries
-/////////////////
-
- void
-LOD_ManMesh2::
-VertexEdges(
- LOD_VertexInd vi,
- vector<LOD_EdgeInd> &output
-){
- // iterate through the edges of v and push them onto the
- // output
-
- vector<LOD_Vertex> &verts = VertexSet();
-
- vector<LOD_EdgeInd> & v_edges = verts[vi].m_edges;
- vector<LOD_EdgeInd>::iterator v_it = v_edges.begin();
-
- for (; v_it != v_edges.end(); ++v_it) {
- output.push_back(*v_it);
- }
-}
-
- void
-LOD_ManMesh2::
-VertexFaces(
- LOD_VertexInd vi,
- vector<LOD_FaceInd> &output
-){
- const vector<LOD_Vertex> &verts = VertexSet();
- vector<LOD_Edge> &edges = EdgeSet();
- vector<LOD_TriFace> &faces = FaceSet();
-
- const vector<LOD_EdgeInd> &v_edges = verts[vi].m_edges;
- vector<LOD_EdgeInd>::const_iterator e_it = v_edges.begin();
-
- for (; e_it != v_edges.end(); ++e_it) {
-
- LOD_Edge &e = edges[*e_it];
-
- if ((!e.m_faces[0].IsEmpty()) && (!faces[e.m_faces[0]].SelectTag())) {
- output.push_back(e.m_faces[0]);
- faces[e.m_faces[0]].SetSelectTag(true);
- }
-
- if ((!e.m_faces[1].IsEmpty()) && (!faces[e.m_faces[1]].SelectTag())) {
- output.push_back(e.m_faces[1]);
- faces[e.m_faces[1]].SetSelectTag(true);
- }
- }
-
- vector<LOD_FaceInd>::iterator f_it = output.begin();
-
- for (; f_it != output.end(); ++f_it) {
- faces[*f_it].SetSelectTag(false);
- }
-};
-
- void
-LOD_ManMesh2::
-SetBBox(
- MT_Vector3 bbox_min,
- MT_Vector3 bbox_max
-){
- m_bbox_min = bbox_min;
- m_bbox_max = bbox_max;
-};
-
- void
-LOD_ManMesh2::
-SC_TriFace(
- LOD_FaceInd f
-){
- LOD_TriFace face = (*m_faces)[f];
-
- // check for unique vertices
-
- if (
- (face.m_verts[0] == face.m_verts[1]) ||
- (face.m_verts[1] == face.m_verts[2]) ||
- (face.m_verts[2] == face.m_verts[0])
- ) {
- MT_assert(false);
- }
-
-}
-
-
- void
-LOD_ManMesh2::
-SC_EdgeList(
- LOD_VertexInd v
-){
- vector<LOD_Edge> &edges = EdgeSet();
- vector<LOD_Vertex> &verts = VertexSet();
-
- vector<LOD_EdgeInd>::iterator e_it = verts[v].m_edges.begin();
-
- for (;e_it != verts[v].m_edges.end(); ++e_it) {
- MT_assert( (edges[*e_it].m_verts[0] == v) || (edges[*e_it].m_verts[1] == v));
- }
-
-};
-
- void
-LOD_ManMesh2::
-DeleteVertex(
- LOD_ExternBufferEditor & extern_editor,
- LOD_VertexInd v
-){
-
- vector<LOD_Edge> &edges = EdgeSet();
- vector<LOD_Vertex> &verts = VertexSet();
- vector<LOD_TriFace> &faces = FaceSet();
-
- // need to update all the edge and polygons pointing to
- // the last vertex in m_verts
-
- if (verts.size() == 1) {
- verts.clear();
- return;
- }
-
- LOD_VertexInd last = LOD_VertexInd(size_t(verts.end() - verts.begin() - 1));
-
- if (!(last == v)) {
-
- // we asume that v is already disconnected
-
- vector<LOD_FaceInd> v_faces;
- vector<LOD_EdgeInd> v_edges;
-
- v_faces.reserve(64);
- v_edges.reserve(64);
-
- VertexFaces(last,v_faces);
- VertexEdges(last,v_edges);
-
- // map the faces and edges to look at v
-
- vector<LOD_FaceInd>::iterator face_it = v_faces.begin();
-
- for(; face_it != v_faces.end(); ++face_it) {
- faces[*face_it].SwapVertex(last,v);
- }
- vector<LOD_EdgeInd>::iterator edge_it = v_edges.begin();
-
- for (; edge_it != v_edges.end(); ++edge_it) {
- edges[*edge_it].SwapVertex(last,v);
- }
-
- // copy the last vertex onto v and pop off the back.
-
- verts[v] = verts[last];
-
- // tidy external buffer
- extern_editor.CopyModifiedFaces(*this,v_faces);
- }
-
- verts.pop_back();
- extern_editor.CopyBackVertex(v);
-
-
-};
-
- void
-LOD_ManMesh2::
-DeleteEdge(
- LOD_EdgeInd e,
- CTR_UHeap<LOD_Edge> * heap
-){
- vector<LOD_Edge> &edges = EdgeSet();
- vector<LOD_Vertex> &verts = VertexSet();
-
- if (edges.size() == 1) {
- edges.clear();
- return;
- }
-
- LOD_EdgeInd last = LOD_EdgeInd(size_t(edges.end() - edges.begin() - 1));
-
- if (!(last == e)) {
- vector<LOD_EdgeInd> e_verts;
- e_verts.reserve(2);
- EdgeVertices(last,e_verts);
- // something is wrong if there arent two!
-
- verts[e_verts[0]].SwapEdge(last,e);
- verts[e_verts[1]].SwapEdge(last,e);
-
- // edges[e] should already have been removed from the heap
-
- MT_assert(edges[e].HeapPos() == -1);
-
- edges[e] = edges[last];
- // also have to swap there heap positions.!!!!!
-
- heap->HeapVector()[edges[e].HeapPos()] = e;
-
-
- }
- edges.pop_back();
-};
-
- void
-LOD_ManMesh2::
-DeleteFace(
- LOD_ExternBufferEditor & extern_editor,
- LOD_FaceInd f
-){
-
- vector<LOD_Edge> &edges = EdgeSet();
- vector<LOD_TriFace> &faces = FaceSet();
-
- if (faces.size() == 1) {
- faces.clear();
- return;
- }
-
- LOD_FaceInd last = LOD_FaceInd(size_t (faces.end() - faces.begin() - 1));
-
- if (!(last == f)) {
-
- // we have to update the edges which point to the last
- // face
-
- vector<LOD_EdgeInd> f_edges;
- f_edges.reserve(3);
-
- FaceEdges(last,f_edges);
-
- vector<LOD_EdgeInd>::iterator edge_it = f_edges.begin();
- vector<LOD_EdgeInd>::const_iterator edge_end = f_edges.end();
-
- for (; edge_it != edge_end; ++edge_it) {
- edges[*edge_it].SwapFace(last,f);
- }
-
- faces[f] = faces[last];
-
- }
- faces.pop_back();
-
- // tidy external buffers
- extern_editor.CopyBackFace(f);
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intern/decimation/intern/LOD_ManMesh2.h b/intern/decimation/intern/LOD_ManMesh2.h
deleted file mode 100644
index 5d4e1aff4e6..00000000000
--- a/intern/decimation/intern/LOD_ManMesh2.h
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_ManMesh2.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_MANMESH2_H__
-#define __LOD_MANMESH2_H__
-
-#include "LOD_MeshPrimitives.h"
-#include "MEM_SmartPtr.h"
-#include <vector>
-
-template <class HeapType> class CTR_UHeap;
-
-class LOD_ExternBufferEditor;
-
-class LOD_ManMesh2 // Manifold 2 dimensional mesh
-{
-
-public:
-
- static
- LOD_ManMesh2 *
- New(
- );
-
- // take ownership of the vertices.
-
- bool
- SetVertices(
- MEM_SmartPtr<std::vector<LOD_Vertex> > verts
- );
-
- // Add a triangle to the mesh
-
- void
- AddTriangle(
- int verts[3]
- );
-
- void
- ConnectTriangle(
- LOD_FaceInd fi,
- std::vector<LOD_EdgeInd> & new_edges
- );
-
- // geometry access
- //////////////////
-
- std::vector<LOD_Vertex> &
- VertexSet(
- ) const;
-
- std::vector<LOD_TriFace> &
- FaceSet(
- ) const;
-
- std::vector<LOD_Edge> &
- EdgeSet(
- ) const;
-
- ~LOD_ManMesh2(
- );
-
- // local geometry queries
- /////////////////////////
-
- // face queries
- ///////////////
-
- void
- FaceVertices(
- LOD_FaceInd f,
- std::vector<LOD_VertexInd> &output
- );
-
- void
- FaceEdges(
- LOD_FaceInd f,
- std::vector<LOD_EdgeInd> &output
- );
-
- // edge queries
- ///////////////
-
- void
- EdgeVertices(
- LOD_EdgeInd e,
- std::vector<LOD_VertexInd> &output
- );
-
- void
- EdgeFaces(
- LOD_EdgeInd e,
- std::vector<LOD_FaceInd> &output
- );
-
- // vertex queries
- /////////////////
-
- void
- VertexEdges(
- LOD_VertexInd v,
- std::vector<LOD_EdgeInd> &output
- );
-
- void
- VertexFaces(
- LOD_VertexInd v,
- std::vector<LOD_FaceInd> &output
- );
-
- void
- SetBBox(
- MT_Vector3 bbox_min,
- MT_Vector3 bbox_max
- );
-
- MT_Vector3
- BBoxMin(
- ) const {
- return m_bbox_min;
- };
-
- MT_Vector3
- BBoxMax(
- ) const {
- return m_bbox_max;
- };
-
- // Remove a primitive from the mesh
- ///////////////////////////////////
-
- // These methods assume you have correctly
- // tidied up the index pointers in other primitives,
- // so that nothing refers to this object any more
-
- // These methods exchange the primitive with the
- // last primitive in the vector. It modifies everything
- // pointing to the last primitive correctly.
-
- // FIXME refactor extern editor out of primitive deletion
- // insead return a vector of primitives that need to be
- // modified and do this externally
-
- void
- DeleteVertex(
- LOD_ExternBufferEditor & extern_editor,
- LOD_VertexInd v
- );
-
- void
- DeleteEdge(
- LOD_EdgeInd e,
- CTR_UHeap<LOD_Edge> *heap
- );
-
- void
- DeleteFace(
- LOD_ExternBufferEditor & extern_editor,
- LOD_FaceInd f
- );
-
- // Sanity Check routines
- ////////////////////////
-
- // Make sure the edge sets and the vertex sets are
- // consistent
-
- void
- SC_TriFace(
- LOD_FaceInd f
- );
-
- // basic sanity checking of an edge list bails out if there are more than 1024
- // edges
-
- void
- SC_EdgeList(
- LOD_EdgeInd e
- );
-
-
- // Check to see that the edges of v1 and v2 are unique.
-
- bool
- SC_UniqueEdge(
- LOD_EdgeInd e
- );
-
-
-private :
-
-
- // Returns the edge index of the edge from v1 to v2.
- // Does this by searching the edge sets of v1 - but not v2.
- // If you are paranoid you should check both and make sure the
- // indices are the same. If the edge doe not exist edgeInd is empty.
-
- LOD_EdgeInd
- FindEdge(
- const LOD_VertexInd v1,
- const LOD_VertexInd v2
- );
-
- // Insert an edge into the mesh
- // Tie up the ptrs and create space for the edge
- // returns manifold errors - need to sort out memory edges
-
- bool
- InsertEdge(
- const LOD_VertexInd v1,
- const LOD_VertexInd v2,
- const LOD_FaceInd f,
- std::vector<LOD_EdgeInd> &new_edges
- );
-
-
-private :
-
- LOD_ManMesh2(
- );
-
- MEM_SmartPtr< std::vector<LOD_Vertex> > m_verts;
- MEM_SmartPtr< std::vector<LOD_TriFace> > m_faces;
- MEM_SmartPtr< std::vector<LOD_Edge> > m_edges;
-
- // not sure of these descrtiptions of the mesh should
- // reside in this class coz may lead to very bloated interface.
-
- MT_Vector3 m_bbox_min;
- MT_Vector3 m_bbox_max;
-
-
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_MeshBounds.h b/intern/decimation/intern/LOD_MeshBounds.h
deleted file mode 100644
index c95e6c7b61f..00000000000
--- a/intern/decimation/intern/LOD_MeshBounds.h
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_MeshBounds.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_MESHBOUNDS_H__
-#define __LOD_MESHBOUNDS_H__
-
-#include "MEM_SmartPtr.h"
-#include "LOD_MeshPrimitives.h"
-#include "LOD_ManMesh2.h"
-#include "MT_assert.h"
-
-// simple class to compute the mesh bounds of a manifold mesh,
-
-class LOD_MeshBounds {
-
-public :
- static
- LOD_MeshBounds *
- New(
- ){
-
- MEM_SmartPtr<LOD_MeshBounds> output(new LOD_MeshBounds());
- return output.Release();
- }
-
- void
- ComputeBounds(
- const LOD_ManMesh2 * mesh
- ){
- MT_assert(mesh!=NULL);
- MT_assert(mesh->VertexSet().size() > 0);
-
- const std::vector<LOD_Vertex> &verts = mesh->VertexSet();
-
- m_min = verts[0].pos;
- m_max = verts[0].pos;
-
- // iterate through the verts
-
- int t;
- const int size = verts.size();
-
- for (t=1; t< size ; ++t) {
-
- UpdateBounds(verts[t].pos,m_min,m_max);
- }
- }
-
- MT_Vector3
- Min(
- ) const {
- return m_min;
- }
-
- MT_Vector3
- Max(
- ) const {
- return m_max;
- }
-
-private :
-
- void
- UpdateBounds(
- MT_Vector3 vertex,
- MT_Vector3& min,
- MT_Vector3& max
- ) {
- if (vertex.x() < min.x()) {
- min.x() = vertex.x();
- } else
- if (vertex.x() > max.x()) {
- max.x()= vertex.x();
- }
-
- if (vertex.y() < min.y()) {
- min.y() = vertex.y();
- } else
- if (vertex.y() > max.y()) {
- max.y()= vertex.y();
- }
-
- if (vertex.z() < min.z()) {
- min.z() = vertex.z();
- } else
- if (vertex.z() > max.z()) {
- max.z()= vertex.z();
- }
- }
-
- LOD_MeshBounds(
- ) :
- m_min(0,0,0),
- m_max(0,0,0)
- {
- };
-
- MT_Vector3 m_min;
- MT_Vector3 m_max;
-
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_MeshException.h b/intern/decimation/intern/LOD_MeshException.h
deleted file mode 100644
index 67bd8188c41..00000000000
--- a/intern/decimation/intern/LOD_MeshException.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_MeshException.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_MESHEXCEPTION_H__
-#define __LOD_MESHEXCEPTION_H__
-
-class LOD_MeshException {
-
-public :
-
- // stick in more error types as you think of them
-
- enum ExceptionType{
- e_non_manifold,
- e_search_error
- } m_e_type;
-
- LOD_MeshException (
- ExceptionType type
- ) : m_e_type (type)
- {
- }
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_MeshPrimitives.cpp b/intern/decimation/intern/LOD_MeshPrimitives.cpp
deleted file mode 100644
index ee4e4c120fc..00000000000
--- a/intern/decimation/intern/LOD_MeshPrimitives.cpp
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_MeshPrimitives.cpp
- * \ingroup decimation
- */
-
-
-#include "LOD_MeshPrimitives.h"
-
-#include "MT_assert.h"
-#include "LOD_MeshException.h"
-#include <algorithm>
-
-using namespace std;
-
-// Vertex Methods
-/////////////////
-
-LOD_Vertex::
-LOD_Vertex(
-) :
- pos (MT_Vector3()),
- m_select_tag(false)
-{
-};
-
- bool
-LOD_Vertex::
-RemoveEdge(
- LOD_EdgeInd e
-){
-
- vector<LOD_EdgeInd>::iterator result = find(m_edges.begin(),m_edges.end(),e);
- if (result == m_edges.end()) {
- return false;
- }
-
- std::swap(*result, m_edges.back());
- m_edges.pop_back();
- return true;
-};
-
- void
-LOD_Vertex::
-AddEdge(
- LOD_EdgeInd e
-){
- m_edges.push_back(e);
-};
-
- void
-LOD_Vertex::
-SwapEdge(
- LOD_EdgeInd e_old,
- LOD_EdgeInd e_new
-){
-
- vector<LOD_EdgeInd>::iterator result =
- find(m_edges.begin(),m_edges.end(),e_old);
- if (result == m_edges.end()) {
- MT_assert(false);
- LOD_MeshException e(LOD_MeshException::e_search_error);
- throw(e);
- }
-
- *result = e_new;
-};
-
- bool
-LOD_Vertex::
-SelectTag(
-) const {
- return m_select_tag;
-};
-
- void
-LOD_Vertex::
-SetSelectTag(
- bool tag
-){
- m_select_tag = tag;
-};
-
- bool
-LOD_Vertex::
-Degenerate(
-){
- return m_edges.empty();
-}
-
- void
-LOD_Vertex::
-CopyPosition(
- float *float_ptr
-){
- pos.getValue(float_ptr);
-}
-
-
-
-// Edge Methods
-///////////////
-
-LOD_Edge::
-LOD_Edge (
-) {
- m_verts[0] = m_verts[1] = LOD_VertexInd::Empty();
- m_faces[0] = m_faces[1] = LOD_FaceInd::Empty();
-}
-
- bool
-LOD_Edge::
-operator == (
- LOD_Edge & rhs
-) {
- // edges are the same if their vertex indices are the
- // same!!! Other properties are not checked
-
- int matches = 0;
-
- if (this->m_verts[0] == rhs.m_verts[0]) {
- ++matches;
- }
- if (this->m_verts[1] == rhs.m_verts[0]) {
- ++matches;
- }
- if (this->m_verts[0] == rhs.m_verts[1]) {
- ++matches;
- }
- if (this->m_verts[1] == rhs.m_verts[1]) {
- ++matches;
- }
-
- if (matches >= 2) {
- return true;
- }
- return false;
-}
-
-// Elementary helper methods
-////////////////////////////
-
- LOD_FaceInd
-LOD_Edge::
-OpFace(
- LOD_FaceInd f
-) const {
- if (f == m_faces[0]) {
- return m_faces[1];
- } else
- if (f == m_faces[1]) {
- return m_faces[0];
- } else {
- MT_assert(false);
- LOD_MeshException e(LOD_MeshException::e_search_error);
- throw(e);
-
- return LOD_FaceInd::Empty();
- }
-}
-
- void
-LOD_Edge::
-SwapFace(
- LOD_FaceInd old_f,
- LOD_FaceInd new_f
-) {
- if (old_f == m_faces[0]) {
- m_faces[0] = new_f;
- } else
- if (old_f == m_faces[1]) {
- m_faces[1] = new_f;
- } else {
- LOD_MeshException e(LOD_MeshException::e_search_error);
- throw(e);
- }
-}
-
-
-// return the half edge face - the half edge is defined
-// by the {vertex,edge} tuple.
-
- LOD_FaceInd
-LOD_Edge::
-HalfEdgeFace(
- LOD_VertexInd vi
-){
- if (vi == m_verts[0]) return m_faces[0];
- if (vi == m_verts[1]) return m_faces[1];
- MT_assert(false);
-
- LOD_MeshException e(LOD_MeshException::e_search_error);
- throw(e);
-
- return LOD_FaceInd::Empty();
-}
-
-
- LOD_VertexInd
-LOD_Edge::
-OpVertex(
- LOD_VertexInd vi
-) {
- if (vi == m_verts[0]) return m_verts[1];
- if (vi == m_verts[1]) return m_verts[0];
- MT_assert(false);
-
- LOD_MeshException e(LOD_MeshException::e_search_error);
- throw(e);
-
- return LOD_VertexInd::Empty();
-}
-
-// replace the vertex v_old with vertex v_new
-// error if v_old is not one of the original vertices
-
- void
-LOD_Edge::
-SwapVertex(
- LOD_VertexInd v_old,
- LOD_VertexInd v_new
-) {
- if (v_old == m_verts[0]) {
- m_verts[0] = v_new;
- } else
- if (v_old == m_verts[1]) {
- m_verts[1] = v_new;
- } else {
-
- MT_assert(false);
-
- LOD_MeshException e(LOD_MeshException::e_search_error);
- throw(e);
- }
- if(m_verts[0] == m_verts[1]) {
- MT_assert(false);
-
- LOD_MeshException e(LOD_MeshException::e_non_manifold);
- throw(e);
- }
-
-}
-
- bool
-LOD_Edge::
-SelectTag(
-) const {
- return bool(m_verts[1].Tag() & 0x1);
-};
-
- void
-LOD_Edge::
-SetSelectTag(
- bool tag
-) {
- m_verts[1].SetTag(int(tag));
-};
-
- int
-LOD_Edge::
-OpenTag(
-) const {
- return m_faces[0].Tag();
-}
-
- void
-LOD_Edge::
-SetOpenTag(
- int tag
-) {
- m_faces[0].SetTag(tag);
-}
-
- bool
-LOD_Edge::
-Degenerate(
-) const {
- return (
- (m_faces[0].IsEmpty() && m_faces[1].IsEmpty()) ||
- (m_verts[0] == m_verts[1])
- );
-};
-
-// TriFace Methods
-//////////////////
-
-LOD_TriFace::
-LOD_TriFace(
-) {
- m_verts[0] = m_verts[1] = m_verts[2] = LOD_VertexInd::Empty();
-}
-
-// Elementary helper methods
-////////////////////////////
-
- void
-LOD_TriFace::
-SwapVertex(
- LOD_VertexInd old_v,
- LOD_VertexInd new_v
-) {
- // could save branching here...
-
- if (m_verts[0] == old_v) {
- m_verts[0] = new_v;
- } else
- if (m_verts[1] == old_v) {
- m_verts[1] = new_v;
- } else
- if (m_verts[2] == old_v) {
- m_verts[2] = new_v;
- } else {
- MT_assert(false);
-
- LOD_MeshException excep(LOD_MeshException::e_search_error);
- throw(excep);
- }
-}
-
- bool
-LOD_TriFace::
-SelectTag(
-) const {
- return bool(m_verts[1].Tag() & 0x1);
-};
-
- void
-LOD_TriFace::
-SetSelectTag(
- bool tag
-) {
- m_verts[1].SetTag(int(tag));
-};
-
- int
-LOD_TriFace::
-OpenTag(
-) {
- return m_verts[2].Tag();
-}
-
- void
-LOD_TriFace::
-SetOpenTag(
- int tag
-) {
- m_verts[2].SetTag(tag);
-}
-
- bool
-LOD_TriFace::
-Degenerate(
-) {
-
- return (
- (m_verts[0] == m_verts[1]) ||
- (m_verts[1] == m_verts[2]) ||
- (m_verts[2] == m_verts[0])
- );
-}
-
- void
-LOD_TriFace::
-CopyVerts(
- int * index_ptr
-){
- index_ptr[0] = m_verts[0];
- index_ptr[1] = m_verts[1];
- index_ptr[2] = m_verts[2];
-};
-
-
-
-
-
-
-
-
-
diff --git a/intern/decimation/intern/LOD_MeshPrimitives.h b/intern/decimation/intern/LOD_MeshPrimitives.h
deleted file mode 100644
index ea2d157308b..00000000000
--- a/intern/decimation/intern/LOD_MeshPrimitives.h
+++ /dev/null
@@ -1,221 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_MeshPrimitives.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_MESHPRIMITIVES_H__
-#define __LOD_MESHPRIMITIVES_H__
-
-#include "MT_Vector3.h"
-#include "CTR_TaggedIndex.h"
-#include "CTR_UHeap.h"
-#include <vector>
-
-typedef CTR_TaggedIndex<24,0x00ffffff> LOD_VertexInd;
-typedef CTR_TaggedIndex<24,0x00ffffff> LOD_EdgeInd;
-typedef CTR_TaggedIndex<24,0x00ffffff> LOD_FaceInd;
-typedef CTR_TaggedIndex<24,0x00ffffff> LOD_HeapInd;
-
-class LOD_Vertex {
-public :
- MT_Vector3 pos;
- std::vector<LOD_EdgeInd> m_edges;
- bool m_select_tag;
-
- LOD_Vertex(
- );
-
- bool
- RemoveEdge(
- LOD_EdgeInd e
- );
-
- void
- AddEdge(
- LOD_EdgeInd e
- );
-
- void
- SwapEdge(
- LOD_EdgeInd e_old,
- LOD_EdgeInd e_new
- );
-
- bool
- SelectTag(
- ) const;
-
- void
- SetSelectTag(
- bool tag
- );
-
- bool
- Degenerate(
- );
-
- void
- CopyPosition(
- float *float_ptr
- );
-
-private :
-
-
-};
-
-class LOD_Edge : public CTR_UHeapable {
-public :
- LOD_VertexInd m_verts[2];
- LOD_FaceInd m_faces[2];
-
- LOD_Edge (
- );
-
- bool operator == (
- LOD_Edge & rhs
- );
-
- // Elementary helper methods
- ////////////////////////////
-
- LOD_FaceInd
- OpFace(
- LOD_FaceInd f
- ) const;
-
- void
- SwapFace(
- LOD_FaceInd old_f,
- LOD_FaceInd new_f
- );
-
-
- // return the half edge face - the half edge is defined
- // by the {vertex,edge} tuple.
-
- LOD_FaceInd
- HalfEdgeFace(
- LOD_VertexInd vi
- );
-
-
- LOD_VertexInd
- OpVertex(
- LOD_VertexInd vi
- );
-
- // replace the vertex v_old with vertex v_new
- // error if v_old is not one of the original vertices
-
- void
- SwapVertex(
- LOD_VertexInd v_old,
- LOD_VertexInd v_new
- );
-
- bool
- SelectTag(
- ) const;
-
- void
- SetSelectTag(
- bool tag
- );
-
- int
- OpenTag(
- ) const;
-
- void
- SetOpenTag(
- int tag
- );
-
- bool
- Degenerate(
- ) const;
-
- bool
- BoundaryEdge(
- ) const {
- return (m_faces[0].IsEmpty() || m_faces[1].IsEmpty());
- };
-
-
-};
-
-class LOD_TriFace {
-public:
-
- LOD_VertexInd m_verts[3];
-
- LOD_TriFace(
- );
-
- // Elementary helper methods
- ////////////////////////////
-
- void
- SwapVertex(
- LOD_VertexInd old_v,
- LOD_VertexInd new_v
- );
-
- bool
- SelectTag(
- ) const;
-
- void
- SetSelectTag(
- bool tag
- );
-
- int
- OpenTag(
- );
- void
- SetOpenTag(
- int tag
- );
-
- bool
- Degenerate(
- );
-
- void
- CopyVerts(
- int * index_ptr
- );
-
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_QSDecimator.cpp b/intern/decimation/intern/LOD_QSDecimator.cpp
deleted file mode 100644
index bdcf7950447..00000000000
--- a/intern/decimation/intern/LOD_QSDecimator.cpp
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_QSDecimator.cpp
- * \ingroup decimation
- */
-
-
-#include "LOD_QSDecimator.h"
-
-#include "LOD_ExternBufferEditor.h"
-
-using namespace std;
-
- LOD_QSDecimator *
-LOD_QSDecimator::
-New(
- LOD_ManMesh2 &mesh,
- LOD_ExternNormalEditor &face_editor,
- LOD_ExternBufferEditor &extern_editor
-){
-
- MEM_SmartPtr<LOD_QSDecimator> output
- = new LOD_QSDecimator(mesh,face_editor,extern_editor);
-
- MEM_SmartPtr<LOD_EdgeCollapser > collapser(LOD_EdgeCollapser::New());
- MEM_SmartPtr<LOD_QuadricEditor> q_editor(LOD_QuadricEditor::New(mesh));
-
- if (
- output == NULL ||
- collapser == NULL ||
- q_editor == NULL
- ) {
- return NULL;
- }
- output->m_collapser = collapser.Release();
- output->m_quadric_editor = q_editor.Release();
- return output.Release();
-}
-
-
-
- bool
-LOD_QSDecimator::
-Arm(
-){
- MT_assert(!m_is_armed);
- bool heap_result = BuildHeap();
- if (!heap_result) {
- return false;
- }
- m_is_armed = true;
- return true;
-}
-
- bool
-LOD_QSDecimator::
-Step(
-){
- return CollapseEdge();
-}
-
-
-LOD_QSDecimator::
-LOD_QSDecimator(
- LOD_ManMesh2 &mesh,
- LOD_ExternNormalEditor &face_editor,
- LOD_ExternBufferEditor &extern_editor
-) :
- m_is_armed (false),
- m_mesh(mesh),
- m_face_editor(face_editor),
- m_extern_editor(extern_editor)
-{
- m_deg_edges.reserve(32);
- m_deg_faces.reserve(32);
- m_deg_vertices.reserve(32);
- m_update_faces.reserve(32);
- m_new_edges.reserve(32);
- m_update_vertices.reserve(32);
-};
-
- bool
-LOD_QSDecimator::
-CollapseEdge(
-){
-
- // find an edge to collapse
-
- // FIXME force an edge collapse
- // or return false
-
- std::vector<LOD_Edge> & edges = m_mesh.EdgeSet();
- std::vector<LOD_Vertex> & verts = m_mesh.VertexSet();
- std::vector<LOD_Quadric> & quadrics = m_quadric_editor->Quadrics();
- int size = edges.size();
-
- if (size == 0) return false;
-
- const int heap_top = m_heap->Top();
-
- if (heap_top == -1 || edges[heap_top].HeapKey() <= -MT_INFINITY) {
- return false;
- }
-
- // compute the target position
- MT_Vector3 new_vertex = m_quadric_editor->TargetVertex(edges[heap_top]);
- LOD_Quadric & q0 = quadrics[edges[heap_top].m_verts[0]];
- LOD_Quadric & q1 = quadrics[edges[heap_top].m_verts[1]];
-
- LOD_Vertex &v0 = verts[edges[heap_top].m_verts[0]];
- LOD_Vertex &v1 = verts[edges[heap_top].m_verts[1]];
-
- LOD_Quadric sum = q0;
- sum += q1;
-
-
- if (m_collapser->CollapseEdge(
- heap_top,
- m_mesh,
- m_deg_edges,
- m_deg_faces,
- m_deg_vertices,
- m_new_edges,
- m_update_faces,
- m_update_vertices
- )) {
-
- // assign new vertex position
-
- v0.pos = new_vertex;
- v1.pos = new_vertex;
-
- // sum the quadrics of v0 and v1
- q0 = sum;
- q1 = sum;
-
- // ok update the primitive properties
-
- m_face_editor.Update(m_update_faces);
- m_face_editor.UpdateVertexNormals(m_update_vertices);
-
- // update the external vertex buffer
- m_extern_editor.CopyModifiedVerts(m_mesh,m_update_vertices);
-
- // update the external face buffer
- m_extern_editor.CopyModifiedFaces(m_mesh,m_update_faces);
-
- // update the edge heap
- UpdateHeap(m_deg_edges,m_new_edges);
-
- m_quadric_editor->Remove(m_deg_vertices);
- m_face_editor.Remove(m_deg_faces);
- m_face_editor.RemoveVertexNormals(m_deg_vertices);
-
- // delete the primitives
-
- DeletePrimitives(m_deg_edges,m_deg_faces,m_deg_vertices);
-
- } else {
- // the edge could not be collapsed at the moment - so
- // we adjust it's priority and add it back to the heap.
- m_heap->Remove(&edges[0],0);
- edges[heap_top].HeapKey() = - MT_INFINITY;
- m_heap->Insert(&edges[0],heap_top);
- }
-
- //clear all the temporary buffers
-
- m_deg_faces.clear();
- m_deg_edges.clear();
- m_deg_vertices.clear();
-
- m_update_faces.clear();
- m_update_vertices.clear();
- m_new_edges.clear();
-
- return true;
-
-}
-
- void
-LOD_QSDecimator::
-DeletePrimitives(
- const vector<LOD_EdgeInd> & degenerate_edges,
- const vector<LOD_FaceInd> & degenerate_faces,
- const vector<LOD_VertexInd> & degenerate_vertices
-) {
-
- // assumes that the 3 vectors are sorted in descending order.
-
- // Delete Degnerate primitives
- //////////////////////////////
-
-
- // delete the old edges - we have to be very careful here
- // mesh.delete() swaps edges to be deleted with the last edge in
- // the edge buffer. However the next edge to be deleted may have
- // been the last edge in the buffer!
-
- // One way to solve this is to sort degenerate_edges in descending order.
- // And then delete them in that order.
-
- // it is also vital that degenerate_edges contains no duplicates
-
- vector<LOD_EdgeInd>::const_iterator edge_it = degenerate_edges.begin();
- vector<LOD_EdgeInd>::const_iterator edge_end = degenerate_edges.end();
-
- for (; edge_it != edge_end; ++edge_it) {
- m_mesh.DeleteEdge(*edge_it,m_heap);
- }
-
-
-
- vector<LOD_FaceInd>::const_iterator face_it = degenerate_faces.begin();
- vector<LOD_FaceInd>::const_iterator face_end = degenerate_faces.end();
-
- for (;face_it != face_end; ++face_it) {
- m_mesh.DeleteFace(m_extern_editor,*face_it);
- }
-
- vector<LOD_VertexInd>::const_iterator vertex_it = degenerate_vertices.begin();
- vector<LOD_VertexInd>::const_iterator vertex_end = degenerate_vertices.end();
-
- for (;vertex_it != vertex_end; ++vertex_it) {
- m_mesh.DeleteVertex(m_extern_editor,*vertex_it);
- }
-}
-
-
- bool
-LOD_QSDecimator::
-BuildHeap(
-){
- // build the quadrics
-
- if (m_quadric_editor->BuildQuadrics(m_face_editor,true) == false) return false;
-
-
- m_heap = CTR_UHeap<LOD_Edge>::New();
- // load in edge pointers to the heap
-
- std::vector<LOD_Edge> & edge_set= m_mesh.EdgeSet();
-
- // UNUSED
- // std::vector<LOD_Edge>::const_iterator edge_end = edge_set.end();
- // std::vector<LOD_Edge>::iterator edge_start = edge_set.begin();
-
- std::vector<int> & heap_vector = m_heap->HeapVector();
-
- for (unsigned int i = 0; i < edge_set.size(); ++i) {
- edge_set[i].HeapPos() = i;
- heap_vector.push_back(i);
- }
-
- m_heap->MakeHeap(&edge_set[0]);
-
- return true;
-}
-
- void
-LOD_QSDecimator::
-UpdateHeap(
- std::vector<LOD_EdgeInd> &deg_edges,
- std::vector<LOD_EdgeInd> &new_edges
-){
- // first of all compute values for the new edges
- // and bung them on the heap.
-
- std::vector<LOD_Edge> & edge_set= m_mesh.EdgeSet();
-
- std::vector<LOD_EdgeInd>::const_iterator edge_it = new_edges.begin();
- std::vector<LOD_EdgeInd>::const_iterator end_it = new_edges.end();
-
-
- // insert all the new edges
- ///////////////////////////
-
- // compute edge costs ffor the new edges
-
- m_quadric_editor->ComputeEdgeCosts(new_edges);
-
- // inser the new elements into the heap
-
- for (; edge_it != end_it; ++edge_it) {
- m_heap->Insert(&edge_set[0],*edge_it);
- }
-
-
- // remove all the old values from the heap
-
- edge_it = deg_edges.begin();
- end_it = deg_edges.end();
-
- for (; edge_it != end_it; ++edge_it) {
- LOD_Edge &e = edge_set[*edge_it];
- m_heap->Remove(&edge_set[0],e.HeapPos());
-
- e.HeapPos() = -1;
-
- }
-}
-
diff --git a/intern/decimation/intern/LOD_QSDecimator.h b/intern/decimation/intern/LOD_QSDecimator.h
deleted file mode 100644
index 2ac223996f2..00000000000
--- a/intern/decimation/intern/LOD_QSDecimator.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_QSDecimator.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_QSDECIMATOR_H__
-#define __LOD_QSDECIMATOR_H__
-
-#include "MEM_NonCopyable.h"
-#include "LOD_ManMesh2.h"
-#include "LOD_ExternNormalEditor.h"
-#include "LOD_EdgeCollapser.h"
-#include "LOD_QuadricEditor.h"
-
-class LOD_ExternBufferEditor;
-
-class LOD_QSDecimator : public MEM_NonCopyable {
-
-public :
-
- static
- LOD_QSDecimator *
- New(
- LOD_ManMesh2 &mesh,
- LOD_ExternNormalEditor &face_editor,
- LOD_ExternBufferEditor &extern_editor
- );
-
-
- bool
- Arm(
- );
-
-
- bool
- Step(
- );
-
-private :
-
- LOD_QSDecimator(
- LOD_ManMesh2 &mesh,
- LOD_ExternNormalEditor &face_editor,
- LOD_ExternBufferEditor &extern_editor
- );
-
- bool
- CollapseEdge(
- );
-
- bool
- BuildHeap(
- );
-
- void
- UpdateHeap(
- std::vector<LOD_EdgeInd> &deg_edges,
- std::vector<LOD_EdgeInd> &new_edges
- );
-
- void
- DeletePrimitives(
- const std::vector<LOD_EdgeInd> & degenerate_edges,
- const std::vector<LOD_FaceInd> & degenerate_faces,
- const std::vector<LOD_VertexInd> & degenerate_vertices
- );
-
-
-private :
-
- // owned by this class
- //////////////////////
-
- MEM_SmartPtr<LOD_EdgeCollapser> m_collapser;
- MEM_SmartPtr<CTR_UHeap<LOD_Edge> > m_heap;
- MEM_SmartPtr<LOD_QuadricEditor> m_quadric_editor;
-
- bool m_is_armed;
-
- // arguments to New(...)
- ////////////////////////
-
- LOD_ManMesh2 & m_mesh;
- LOD_ExternNormalEditor &m_face_editor;
- LOD_ExternBufferEditor & m_extern_editor;
-
- // temporary buffers
- ////////////////////
-
- std::vector<LOD_FaceInd> m_deg_faces;
- std::vector<LOD_EdgeInd> m_deg_edges;
- std::vector<LOD_VertexInd> m_deg_vertices;
-
- std::vector<LOD_FaceInd> m_update_faces;
- std::vector<LOD_EdgeInd> m_new_edges;
- std::vector<LOD_VertexInd> m_update_vertices;
-
-
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_Quadric.h b/intern/decimation/intern/LOD_Quadric.h
deleted file mode 100644
index 9dde0502aa3..00000000000
--- a/intern/decimation/intern/LOD_Quadric.h
+++ /dev/null
@@ -1,167 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_Quadric.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_QUADRIC_H__
-#define __LOD_QUADRIC_H__
-
-#include "MT_Vector3.h"
-#include "MT_Matrix3x3.h"
-
-
-class LOD_Quadric {
-
-private:
- MT_Scalar a2, ab, ac, ad;
- MT_Scalar b2, bc, bd;
- MT_Scalar c2, cd;
- MT_Scalar d2;
-
- void init(MT_Scalar a, MT_Scalar b, MT_Scalar c, MT_Scalar d);
-
-public:
-
- LOD_Quadric(
- ) {
- Clear();
- };
-
- LOD_Quadric(
- const MT_Vector3 & vec,
- const MT_Scalar & offset
- ) {
- a2 = vec[0] *vec[0];
- b2 = vec[1] *vec[1];
- c2 = vec[2] *vec[2];
-
- ab = vec[0]*vec[1];
- ac = vec[0]*vec[2];
- bc = vec[1]*vec[2];
-
- MT_Vector3 temp = vec*offset;
- ad = temp[0];
- bd = temp[1];
- cd = temp[2];
-
- d2 = offset*offset;
- };
-
- MT_Matrix3x3
- Tensor(
- ) const {
- // return a symmetric matrix
-
- return MT_Matrix3x3(
- a2,ab,ac,
- ab,b2,bc,
- ac,bc,c2
- );
- };
-
-
- MT_Vector3
- Vector(
- ) const {
- return MT_Vector3(ad, bd, cd);
- };
-
- void
- Clear(
- MT_Scalar val=0.0
- ) {
- a2=ab=ac=ad=b2=bc=bd=c2=cd=d2=val;
- };
-
- LOD_Quadric &
- operator=(
- const LOD_Quadric& Q
- ) {
-
- a2 = Q.a2; ab = Q.ab; ac = Q.ac; ad = Q.ad;
- b2 = Q.b2; bc = Q.bc; bd = Q.bd;
- c2 = Q.c2; cd = Q.cd;
- d2 = Q.d2;
- return *this;
- };
-
- LOD_Quadric&
- operator+=(
- const LOD_Quadric& Q
- ) {
- a2 += Q.a2; ab += Q.ab; ac += Q.ac; ad += Q.ad;
- b2 += Q.b2; bc += Q.bc; bd += Q.bd;
- c2 += Q.c2; cd += Q.cd;
- d2 += Q.d2;
- return *this;
- };
-
- LOD_Quadric&
- operator*=(
- const MT_Scalar & s
- ) {
- a2 *= s; ab *= s; ac *= s; ad *= s;
- b2 *= s; bc *= s; bd *= s;
- c2 *= s; cd *= s;
- d2 *= s;
- return *this;
- };
-
-
- MT_Scalar
- Evaluate(
- const MT_Vector3 &v
- ) const {
- // compute the LOD_Quadric error
-
- return v[0]*v[0]*a2 + 2*v[0]*v[1]*ab + 2*v[0]*v[2]*ac + 2*v[0]*ad
- +v[1]*v[1]*b2 + 2*v[1]*v[2]*bc + 2*v[1]*bd
- +v[2]*v[2]*c2 + 2*v[2]*cd
- + d2;
- };
-
- bool
- Optimize(
- MT_Vector3& v
- ) const {
-
- MT_Scalar det = Tensor().determinant();
- if (MT_fuzzyZero(det)) {
- return false;
- }
-
- v = -((Tensor().inverse()) * Vector());
- return true;
- };
-
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_QuadricEditor.cpp b/intern/decimation/intern/LOD_QuadricEditor.cpp
deleted file mode 100644
index fbaf0c1180f..00000000000
--- a/intern/decimation/intern/LOD_QuadricEditor.cpp
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_QuadricEditor.cpp
- * \ingroup decimation
- */
-
-
-#include "LOD_QuadricEditor.h"
-#include "LOD_ExternNormalEditor.h"
-
-// Creation
-///////////
-
-using namespace std;
-
-
-LOD_QuadricEditor::
-LOD_QuadricEditor(
- LOD_ManMesh2 &mesh
-) :
- m_quadrics(NULL),
- m_mesh(mesh)
-{
-};
-
- LOD_QuadricEditor *
-LOD_QuadricEditor::
-New(
- LOD_ManMesh2 &mesh
-){
- //same number of quadrics as vertices in the mesh
-
- MEM_SmartPtr<LOD_QuadricEditor> output(new LOD_QuadricEditor(mesh));
-
- if (output == NULL) {
- return NULL;
- }
- return output.Release();
-}
-
-
-// Property editor interface
-////////////////////////////
-
- void
-LOD_QuadricEditor::
-Remove(
- std::vector<LOD_VertexInd> &sorted_vertices
-){
- vector<LOD_Quadric> & quadrics = *m_quadrics;
-
- vector<LOD_VertexInd>::const_iterator it_start = sorted_vertices.begin();
- vector<LOD_VertexInd>::const_iterator it_end = sorted_vertices.end();
-
- for (; it_start != it_end; ++it_start) {
-
- if (quadrics.size() > 0) {
- LOD_Quadric temp = quadrics[*it_start];
-
- quadrics[*it_start] = quadrics.back();
- quadrics.back() = temp;
-
- quadrics.pop_back();
- }
- }
-};
-
-
-// Editor specific methods
-//////////////////////////
-
- bool
-LOD_QuadricEditor::
-BuildQuadrics(
- LOD_ExternNormalEditor& normal_editor,
- bool preserve_boundaries
-){
- if (m_quadrics != NULL) delete(m_quadrics);
-
- m_quadrics =new vector<LOD_Quadric> (m_mesh.VertexSet().size());
- if (m_quadrics == NULL) return false;
-
- // iterate through the face set of the mesh
- // compute a quadric based upon that face and
- // add it to each of it's vertices quadrics.
-
- const vector<LOD_TriFace> &faces = m_mesh.FaceSet();
- const vector<LOD_Vertex> &verts = m_mesh.VertexSet();
- vector<LOD_Edge> &edges = m_mesh.EdgeSet();
-
- const vector<MT_Vector3> &normals = normal_editor.Normals();
- vector<MT_Vector3>::const_iterator normal_it = normals.begin();
-
- vector<LOD_TriFace>::const_iterator face_it = faces.begin();
- vector<LOD_TriFace>::const_iterator face_end = faces.end();
-
- vector<LOD_Quadric> & quadrics = *m_quadrics;
-
-
- for (; face_it != face_end; ++face_it, ++normal_it) {
-
- MT_Vector3 normal = *normal_it;
- MT_Scalar offset = -normal.dot(verts[face_it->m_verts[0]].pos);
-
- LOD_Quadric q(normal,offset);
-
- quadrics[face_it->m_verts[0]] += q;
- quadrics[face_it->m_verts[1]] += q;
- quadrics[face_it->m_verts[2]] += q;
- }
-
- if (preserve_boundaries) {
-
- // iterate through the edge set and add a boundary quadric to
- // each of the boundary edges vertices.
-
- vector<LOD_Edge>::const_iterator edge_it = edges.begin();
- vector<LOD_Edge>::const_iterator edge_end = edges.end();
-
- for (; edge_it != edge_end; ++edge_it) {
- if (edge_it->BoundaryEdge()) {
-
- // compute a plane perpendicular to the edge and the normal
- // of the edges single polygon.
- const MT_Vector3 & v0 = verts[edge_it->m_verts[0]].pos;
- const MT_Vector3 & v1 = verts[edge_it->m_verts[1]].pos;
-
- MT_Vector3 edge_vector = v1 - v0;
-
- LOD_FaceInd edge_face = edge_it->OpFace(LOD_EdgeInd::Empty());
- edge_vector = edge_vector.cross(normals[edge_face]);
-
- if (!edge_vector.fuzzyZero()) {
- edge_vector.normalize();
-
- LOD_Quadric boundary_q(edge_vector, - edge_vector.dot(v0));
- boundary_q *= 100;
-
- quadrics[edge_it->m_verts[0]] += boundary_q;
- quadrics[edge_it->m_verts[1]] += boundary_q;
- }
- }
- }
- }
-
-
- // initiate the heap keys of the edges by computing the edge costs.
-
- vector<LOD_Edge>::iterator edge_it = edges.begin();
- vector<LOD_Edge>::const_iterator edge_end = edges.end();
-
- for (; edge_it != edge_end; ++edge_it) {
-
- MT_Vector3 target = TargetVertex(*edge_it);
-
- LOD_Edge &e = *edge_it;
- LOD_Quadric q0 = quadrics[e.m_verts[0]];
- const LOD_Quadric &q1 = quadrics[e.m_verts[1]];
-
- e.HeapKey() = -float(q0.Evaluate(target) + q1.Evaluate(target));
- }
-
- return true;
-
-};
-
- MT_Vector3
-LOD_QuadricEditor::
-TargetVertex(
- LOD_Edge & e
-){
-
- // compute an edge contration target for edge ei
- // this is computed by summing it's vertices quadrics and
- // optimizing the result.
- vector<LOD_Vertex> &verts = m_mesh.VertexSet();
-
- vector<LOD_Quadric> &quadrics = *m_quadrics;
-
- LOD_VertexInd v0 = e.m_verts[0];
- LOD_VertexInd v1 = e.m_verts[1];
-
- LOD_Quadric q0 = quadrics[v0];
- q0 += quadrics[v1];
-
- MT_Vector3 result;
-
- if (q0.Optimize(result)) {
- return result;
- } else {
- // the quadric was degenerate -> just take the average of
- // v0 and v1
-
- return ((verts[v0].pos + verts[v1].pos) * 0.5);
- }
-};
-
- void
-LOD_QuadricEditor::
-ComputeEdgeCosts(
- vector<LOD_EdgeInd> &edges
-){
-
- // for each we compute the target vertex and then compute
- // the quadric error e = Q1(v') + Q2(v')
- vector<LOD_Edge> &edge_set = m_mesh.EdgeSet();
-
- vector<LOD_Quadric> &quadrics = *m_quadrics;
-
- vector<LOD_EdgeInd>::const_iterator edge_it = edges.begin();
- vector<LOD_EdgeInd>::const_iterator edge_end = edges.end();
-
- for (; edge_it != edge_end; ++edge_it) {
-
- MT_Vector3 target = TargetVertex(edge_set[*edge_it]);
-
- LOD_Edge &e = edge_set[*edge_it];
- LOD_Quadric q0 = quadrics[e.m_verts[0]];
- const LOD_Quadric &q1 = quadrics[e.m_verts[1]];
-
- e.HeapKey() = -float(q0.Evaluate(target) + q1.Evaluate(target));
- }
-};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/intern/decimation/intern/LOD_QuadricEditor.h b/intern/decimation/intern/LOD_QuadricEditor.h
deleted file mode 100644
index 0a66d299e15..00000000000
--- a/intern/decimation/intern/LOD_QuadricEditor.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_QuadricEditor.h
- * \ingroup decimation
- */
-
-
-#ifndef __LOD_QUADRICEDITOR_H__
-#define __LOD_QUADRICEDITOR_H__
-
-#include "MEM_NonCopyable.h"
-#include "LOD_ManMesh2.h"
-#include "MT_Vector3.h"
-#include "LOD_Quadric.h"
-
-class LOD_ExternNormalEditor;
-
-
-class LOD_QuadricEditor : public MEM_NonCopyable
-{
-
-public :
-
- // Creation
- ///////////
-
- static
- LOD_QuadricEditor *
- New(
- LOD_ManMesh2 &mesh
- );
-
- // Property editor interface
- ////////////////////////////
-
- void
- Remove(
- std::vector<LOD_VertexInd> &sorted_vertices
- );
-
- void
- Update(
- std::vector<LOD_FaceInd> &sorted_vertices
- );
-
-
- std::vector<LOD_Quadric> &
- Quadrics(
- ) const {
- return *m_quadrics;
- };
-
-
- // Editor specific methods
- //////////////////////////
-
- bool
- BuildQuadrics(
- LOD_ExternNormalEditor& normal_editor,
- bool preserve_boundaries
- );
-
-
- void
- ComputeEdgeCosts(
- std::vector<LOD_EdgeInd> &edges
- );
-
- MT_Vector3
- TargetVertex(
- LOD_Edge &e
- );
-
- ~LOD_QuadricEditor(
- ){
- delete(m_quadrics);
- };
-
-
-private :
-
- std::vector<LOD_Quadric> * m_quadrics;
-
- LOD_ManMesh2 &m_mesh;
-
-private :
-
- LOD_QuadricEditor(LOD_ManMesh2 &mesh);
-
-
-
-};
-
-#endif
-
diff --git a/intern/decimation/intern/LOD_decimation.cpp b/intern/decimation/intern/LOD_decimation.cpp
deleted file mode 100644
index 49033933cd6..00000000000
--- a/intern/decimation/intern/LOD_decimation.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file decimation/intern/LOD_decimation.cpp
- * \ingroup decimation
- */
-
-
-// implementation of external c api
-#include "../extern/LOD_decimation.h"
-#include "LOD_DecimationClass.h"
-
-using namespace std;
-
- int
-LOD_LoadMesh(
- LOD_Decimation_InfoPtr info
-) {
- if (info == NULL) return 0;
- if (
- info->vertex_buffer == NULL ||
- info->vertex_normal_buffer == NULL ||
- info->triangle_index_buffer == NULL
- ) {
- return 0;
- }
-
-
- // create the intern object to hold all
- // the decimation classes
-
- MEM_SmartPtr<LOD_DecimationClass> intern(LOD_DecimationClass::New(info));
-
- if (intern == NULL) return 0;
-
- MEM_SmartPtr<vector<LOD_Vertex> > intern_vertex_buffer(new vector<LOD_Vertex>(info->vertex_num));
- if (intern_vertex_buffer == NULL) return 0;
-
- vector<LOD_Vertex>::iterator intern_vertex_it(intern_vertex_buffer->begin());
-
- // now load in the vertices to the mesh
-
- const int vertex_stride = 3;
-
- float * vertex_ptr = info->vertex_buffer;
- const float * vertex_end = vertex_ptr + info->vertex_num*vertex_stride;
-
- LOD_ManMesh2 &mesh = intern->Mesh();
-
- for (;vertex_ptr < vertex_end; vertex_ptr += vertex_stride,++intern_vertex_it) {
- intern_vertex_it->pos = MT_Vector3(vertex_ptr);
- }
-
- mesh.SetVertices(intern_vertex_buffer);
-
- // load in the triangles
-
- const int triangle_stride = 3;
-
- int * triangle_ptr = info->triangle_index_buffer;
- const int * triangle_end = triangle_ptr + info->face_num*triangle_stride;
-
- try {
-
- for (;triangle_ptr < triangle_end; triangle_ptr += triangle_stride) {
- mesh.AddTriangle(triangle_ptr);
- }
- }
-
- catch (...) {
- return 0;
- }
-
- // ok we have built the mesh
-
- intern->m_e_decimation_state = LOD_DecimationClass::e_loaded;
-
- info->intern = (void *) (intern.Release());
-
- return 1;
-}
-
- int
-LOD_PreprocessMesh(
- LOD_Decimation_InfoPtr info
-) {
- if (info == NULL) return 0;
- if (info->intern == NULL) return 0;
-
- LOD_DecimationClass *intern = (LOD_DecimationClass *) info->intern;
- if (intern->m_e_decimation_state != LOD_DecimationClass::e_loaded) return 0;
-
- // arm the various internal classes so that we are ready to step
- // through decimation
-
- intern->FaceEditor().BuildNormals();
- if (intern->Decimator().Arm() == false) return 0;
-
- // ok preprocessing done
- intern->m_e_decimation_state = LOD_DecimationClass::e_preprocessed;
-
- return 1;
-}
-
- int
-LOD_CollapseEdge(
- LOD_Decimation_InfoPtr info
-){
- if (info == NULL) return 0;
- if (info->intern == NULL) return 0;
- LOD_DecimationClass *intern = (LOD_DecimationClass *) info->intern;
- if (intern->m_e_decimation_state != LOD_DecimationClass::e_preprocessed) return 0;
-
- bool step_result = intern->Decimator().Step();
-
- return step_result == true ? 1 : 0;
-}
-
-
- int
-LOD_FreeDecimationData(
- LOD_Decimation_InfoPtr info
-){
- if (info == NULL) return 0;
- if (info->intern == NULL) return 0;
- LOD_DecimationClass *intern = (LOD_DecimationClass *) info->intern;
- delete(intern);
- info->intern = NULL;
- return 1;
-}
-
diff --git a/intern/dualcon/CMakeLists.txt b/intern/dualcon/CMakeLists.txt
index caa1ea09b04..da5e10fe6a7 100644
--- a/intern/dualcon/CMakeLists.txt
+++ b/intern/dualcon/CMakeLists.txt
@@ -19,6 +19,9 @@
set(INC
.
intern
+)
+
+set(INC_SYS
../../extern/Eigen3
)
@@ -42,5 +45,5 @@ set(SRC
dualcon.h
)
-blender_add_lib(bf_intern_dualcon "${SRC}" "${INC}" "")
+blender_add_lib(bf_intern_dualcon "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/intern/elbeem/intern/ntl_geometryshader.h b/intern/elbeem/intern/ntl_geometryshader.h
index 61598556b7e..f43df6539e6 100644
--- a/intern/elbeem/intern/ntl_geometryshader.h
+++ b/intern/elbeem/intern/ntl_geometryshader.h
@@ -46,7 +46,7 @@ class ntlGeometryShader :
/*! notify object that dump is in progress (e.g. for field dump) */
virtual void notifyShaderOfDump(int dumptype, int frameNr,char *frameNrStr,string outfilename) = 0;
- /*! get ouput filename, returns global render outfile if empty */
+ /*! get output filename, returns global render outfile if empty */
string getOutFilename( void ) { return mOutFilename; }
protected:
diff --git a/intern/elbeem/intern/utilities.cpp b/intern/elbeem/intern/utilities.cpp
index c912e70b281..2b9b8d5b8a5 100644
--- a/intern/elbeem/intern/utilities.cpp
+++ b/intern/elbeem/intern/utilities.cpp
@@ -51,7 +51,7 @@ int getElbeemState(void) {
return gElbeemState;
}
int isSimworldOk(void) {
- return (getElbeemState>=0);
+ return (getElbeemState() >=0);
}
// last error as string, acces with get/setElbeemErrorString
diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h
index 2fd61570011..37cde2c2837 100644
--- a/intern/ffmpeg/ffmpeg_compat.h
+++ b/intern/ffmpeg/ffmpeg_compat.h
@@ -110,7 +110,7 @@ void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp)
#endif
/* there are some version inbetween, which have avio_... functions but no
- AVIO_FLAG_... */
+ * AVIO_FLAG_... */
#ifndef AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE URL_WRONLY
#endif
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index be79aad2e90..8771929c14d 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -223,7 +223,6 @@ elseif(APPLE)
if(WITH_INPUT_NDOF)
list(APPEND SRC
intern/GHOST_NDOFManagerCocoa.mm
-
intern/GHOST_NDOFManagerCocoa.h
)
endif()
diff --git a/intern/ghost/GHOST_IEventConsumer.h b/intern/ghost/GHOST_IEventConsumer.h
index 5682d04d434..5b6fa7ba046 100644
--- a/intern/ghost/GHOST_IEventConsumer.h
+++ b/intern/ghost/GHOST_IEventConsumer.h
@@ -42,8 +42,8 @@
* they want to receive events. The system will call the processEvent() method
* for every installed event consumer to pass events.
* \see GHOST_ISystem#addEventConsumer
- * \author Maarten Gribnau
- * \date May 14, 2001
+ * \author Maarten Gribnau
+ * \date May 14, 2001
*/
class GHOST_IEventConsumer
{
@@ -58,15 +58,14 @@ public:
/**
* 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.
+ * \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")
#endif
};
-#endif // _GHOST_EVENT_CONSUMER_H_
-
+#endif /* __GHOST_IEVENTCONSUMER_H__ */
diff --git a/intern/ghost/GHOST_ISystem.h b/intern/ghost/GHOST_ISystem.h
index 7bf86925875..69f44ee6bcb 100644
--- a/intern/ghost/GHOST_ISystem.h
+++ b/intern/ghost/GHOST_ISystem.h
@@ -47,14 +47,14 @@ class GHOST_IEventConsumer;
* \section intro Introduction
*
* GHOST is yet another acronym. It stands for "Generic Handy Operating System
- * Toolkit". It has been created to replace the OpenGL utility tool kit
+ * Toolkit". It has been created to replace the OpenGL utility tool kit
* <a href="http://www.opengl.org/developers/documentation/glut.html">GLUT</a>.
* GLUT was used in <a href="http://www.blender3d.com">Blender</a> until the
* point that Blender needed to be ported to Apple's Mac OSX. Blender needed a
* number of modifications in GLUT to work but the GLUT sources for OSX were
* unavailable at the time. The decision was made to build our own replacement
- * for GLUT. In those days, NaN Technologies BV was the company that developed
- * Blender.
+ * for GLUT. In those days, NaN Technologies BV was the company that developed
+ * Blender.
* <br><br>
* Enough history. What does GHOST have to offer?<br>
* In short: everything that Blender needed from GLUT to run on all it's supported
@@ -96,7 +96,7 @@ class GHOST_IEventConsumer;
* <li>The C-API. For programs written in C.</li>
* <li>The C++-API. For programs written in C++.</li>
* </ul>
- * GHOST itself is writtem in C++ and the C-API is a wrapper around the C++
+ * GHOST itself is writtem in C++ and the C-API is a wrapper around the C++
* API.
*
* \subsection cplusplus_api The C++ API consists of the following files:
@@ -113,7 +113,7 @@ class GHOST_IEventConsumer;
* program in the ?/ghost/test/gears/ directory.
*
* \subsection c_api The C-API
- * To use GHOST in programs written in C, include the file GHOST_C-API.h in
+ * To use GHOST in programs written in C, include the file GHOST_C-API.h in
* your program. This file includes the GHOST_Types.h file for all GHOST types
* and defines functions that give you access to the same functionality present
* in the C++ API.<br>
@@ -123,7 +123,7 @@ class GHOST_IEventConsumer;
* \section work Work in progress
* \todo write WIP section
*/
-
+
/** \interface GHOST_ISystem
* Interface for classes that provide access to the operating system.
* There should be only one system class in an application.
@@ -136,8 +136,8 @@ class GHOST_IEventConsumer;
* -# Access to the state of the mouse buttons and the keyboard.
* -# Menus for windows with events generated when they are accessed (this is
* work in progress).
- * \author Maarten Gribnau
- * \date May 30, 2001
+ * \author Maarten Gribnau
+ * \date May 30, 2001
*/
class GHOST_ISystem
{
@@ -190,12 +190,12 @@ public:
/**
* Installs a timer.
- * Note that, on most operating systems, messages need to be processed in order
+ * 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.
+ * \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,
@@ -225,22 +225,22 @@ public:
* \return The dimension of the main display.
*/
virtual void getMainDisplayDimensions(GHOST_TUns32& width, GHOST_TUns32& height) const = 0;
-
+
/**
* Create a new window.
- * The new window is added to the list of windows managed.
+ * 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 numOfAASamples Number of samples used for AA (zero if no AA)
- * \param parentWindow Parent (embedder) window
- * \return The new window (or 0 if creation failed).
+ * \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 numOfAASamples Number of samples used for AA (zero if no AA)
+ * \param parentWindow Parent (embedder) window
+ * \return The new window (or 0 if creation failed).
*/
virtual GHOST_IWindow *createWindow(
const STR_String& title,
@@ -252,40 +252,40 @@ public:
/**
* Dispose a window.
- * \param window Pointer to the window to be disposed.
- * \return Indication of success.
+ * \param window Pointer to the window to be disposed.
+ * \return Indication of success.
*/
virtual GHOST_TSuccess disposeWindow(GHOST_IWindow *window) = 0;
/**
* Returns whether a window is valid.
- * \param window Pointer to the window to be checked.
- * \return Indication of validity.
+ * \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.
+ * \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 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.
+ * \param setting The new setting of the display.
+ * \param window Window displayed in full screen.
*
- * \return Indication of success.
+ * \return Indication of success.
*/
virtual GHOST_TSuccess updateFullScreen(const GHOST_DisplaySetting& setting, GHOST_IWindow **window) = 0;
/**
* Ends full screen mode.
- * \return Indication of success.
+ * \return Indication of success.
*/
virtual GHOST_TSuccess endFullScreen(void) = 0;
@@ -305,7 +305,7 @@ public:
* \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.
* \return Indication of the presence of events.
@@ -332,18 +332,18 @@ public:
/**
* 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.
+ * \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.
+ * \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;
@@ -353,17 +353,17 @@ public:
/**
* 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.
+ * \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.
+ * \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;
@@ -398,11 +398,11 @@ public:
* \return current status (1 -visible, 0 - hidden)
*/
virtual int toggleConsole(int action) = 0;
-
+
/***************************************************************************************
* Access to clipboard.
***************************************************************************************/
-
+
/**
* Returns the selection buffer
* \return Returns "unsinged char" from X11 XA_CUT_BUFFER0 buffer
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 7ec6417ca4f..88f130aabe8 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -41,20 +41,20 @@
/**
* Interface for GHOST windows.
*
- * You can create a window with the system's GHOST_ISystem::createWindow
+ * You can create a window with the system's GHOST_ISystem::createWindow
* method.
* \see GHOST_ISystem#createWindow
*
* There are two coordinate systems:
* <ul>
* <li>The screen coordinate system. The origin of the screen is located in the
- * upper left corner of the screen.</li>
+ * upper left corner of the screen.</li>
* <li>The client rectangle coordinate system. The client rectangle of a window
* is the area that is drawable by the application (excluding title bars etc.).
- * </li>
+ * </li>
* </ul>
- * \author Maarten Gribnau
- * \date May 31, 2001
+ * \author Maarten Gribnau
+ * \date May 31, 2001
*/
class GHOST_IWindow
{
@@ -86,20 +86,20 @@ public:
/**
* Tries to install a rendering context in this window.
- * \param type The type of rendering context installed.
+ * \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.
+ * \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.
+ * \param title The title displayed in the title bar.
*/
virtual void getTitle(STR_String& title) const = 0;
@@ -109,7 +109,7 @@ public:
* \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.
@@ -131,26 +131,26 @@ public:
/**
* 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.
+ * \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.
+ * \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.
+ * \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;
@@ -158,13 +158,13 @@ public:
* 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.
@@ -184,13 +184,13 @@ public:
* \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.
@@ -200,13 +200,13 @@ public:
/**
* Swaps front and back buffers of a window.
- * \return A boolean success indicator.
+ * \return A boolean success indicator.
*/
virtual GHOST_TSuccess swapBuffers() = 0;
/**
* Activates the drawing context of this window.
- * \return A boolean success indicator.
+ * \return A boolean success indicator.
*/
virtual GHOST_TSuccess activateDrawingContext() = 0;
@@ -215,71 +215,71 @@ public:
* \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 data 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.
+ * \return The current cursor shape.
*/
virtual GHOST_TStandardCursor getCursorShape() const = 0;
/**
* Set the shape of the cursor.
- * \param cursor The new cursor shape type id.
- * \return Indication of success.
+ * \param cursor 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.
+ * \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],
+ 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,
+ virtual GHOST_TSuccess setCustomCursorShape(GHOST_TUns8 *bitmap,
GHOST_TUns8 *mask,
int sizex, int sizey,
int hotX, int hotY,
@@ -287,21 +287,21 @@ public:
/**
* Returns the visibility state of the cursor.
- * \return 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.
+ * \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.
+ * \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; }
diff --git a/intern/ghost/GHOST_Rect.h b/intern/ghost/GHOST_Rect.h
index aa7969d68ad..a055b6f7f0d 100644
--- a/intern/ghost/GHOST_Rect.h
+++ b/intern/ghost/GHOST_Rect.h
@@ -41,8 +41,8 @@
* The four extreme coordinates are stored as left, top, right and bottom.
* To be valid, a rectangle should have a left coordinate smaller than or equal to right.
* To be valid, a rectangle should have a top coordinate smaller than or equal to bottom.
- * \author Maarten Gribnau
- * \date May 10, 2001
+ * \author Maarten Gribnau
+ * \date May 10, 2001
*/
class GHOST_Rect {
@@ -50,10 +50,10 @@ 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
+ * \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)
@@ -61,12 +61,12 @@ public:
/**
* Copy constructor.
- * \param r rectangle to copy
+ * \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.
*/
@@ -74,71 +74,71 @@ public:
/**
* Access to rectangle width.
- * \return width of the rectangle
+ * \return width of the rectangle
*/
virtual inline GHOST_TInt32 getWidth() const;
/**
* Access to rectangle height.
- * \return height of the rectangle
+ * \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
+ * \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)
+ * \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, emapty rectangles are valid.
- * \return boolean value (true==valid rectangle)
+ * \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).
+ * \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.
+ * \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.
+ * \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.
+ * \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 x x-coordinate of point to test.
* \param y y-coordinate of point to test.
* \return boolean value (true if point is inside).
*/
@@ -146,16 +146,16 @@ public:
/**
* Returns whether the rectangle is inside this rectangle.
- * \param r rectangle to test.
- * \return visibility (not, partially or fully visible).
+ * \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
+ * \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);
@@ -163,10 +163,10 @@ public:
* 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
+ * \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);
@@ -174,8 +174,8 @@ public:
* 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
+ * \param r the rectangle to clip
+ * \return whether clipping has occurred
*/
virtual bool clip(GHOST_Rect& r) const;
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index d5cf6e0a8fc..4fe3f10d23e 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -50,7 +50,7 @@ typedef unsigned short GHOST_TUns16;
typedef int GHOST_TInt32;
typedef unsigned int GHOST_TUns32;
-#if defined(WIN32) && !defined(FREE_WINDOWS)
+#ifdef _MSC_VER
typedef __int64 GHOST_TInt64;
typedef unsigned __int64 GHOST_TUns64;
#else
@@ -392,7 +392,7 @@ typedef struct {
typedef struct {
/** Displacement of a mouse wheel. */
- GHOST_TInt32 z;
+ GHOST_TInt32 z;
} GHOST_TEventWheelData;
typedef enum {
diff --git a/intern/ghost/intern/GHOST_Debug.h b/intern/ghost/intern/GHOST_Debug.h
index c364f1d26a4..f0db1b3de8d 100644
--- a/intern/ghost/intern/GHOST_Debug.h
+++ b/intern/ghost/intern/GHOST_Debug.h
@@ -33,12 +33,12 @@
#ifndef __GHOST_DEBUG_H__
#define __GHOST_DEBUG_H__
-#if defined(WIN32) && !defined(FREE_WINDOWS)
+#ifdef _MSC_VER
# ifdef DEBUG
# pragma warning (disable:4786) // suppress stl-MSVC debug info warning
// #define GHOST_DEBUG
# endif // DEBUG
-#endif // WIN32
+#endif // _MSC_VER
#ifdef WITH_GHOST_DEBUG
# define GHOST_DEBUG // spit ghost events to stdout
diff --git a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
index c5a2fecd3b8..555f883cbf2 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
+++ b/intern/ghost/intern/GHOST_DisplayManagerCocoa.mm
@@ -102,7 +102,7 @@ GHOST_TSuccess GHOST_DisplayManagerCocoa::getCurrentDisplaySetting(GHOST_TUns8 d
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];
diff --git a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
index 0bd90854a31..754218191a5 100644
--- a/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
+++ b/intern/ghost/intern/GHOST_DisplayManagerX11.cpp
@@ -88,8 +88,8 @@ getNumDisplaySettings(
#else
/* We only have one X11 setting at the moment. */
- GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
- numSettings = GHOST_TInt32(1);
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ numSettings = 1;
#endif
return GHOST_kSuccess;
@@ -130,8 +130,8 @@ getDisplaySetting(
setting.bpp = DefaultDepth(dpy, DefaultScreen(dpy));
#else
- GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
- GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
+ GHOST_ASSERT(display < 1, "Only single display systems are currently supported.\n");
+ GHOST_ASSERT(index < 1, "Requested setting outside of valid range.\n");
Display *x_display = m_system->getXDisplay();
@@ -160,7 +160,7 @@ getCurrentDisplaySetting(
/* According to the xf86vidmodegetallmodelines man page,
* "The first element of the array corresponds to the current video mode."
*/
- return getDisplaySetting(display, GHOST_TInt32(0), setting);
+ return getDisplaySetting(display, 0, setting);
}
diff --git a/intern/ghost/intern/GHOST_EventDragnDrop.h b/intern/ghost/intern/GHOST_EventDragnDrop.h
index cef9bb0a34a..c51f9568087 100644
--- a/intern/ghost/intern/GHOST_EventDragnDrop.h
+++ b/intern/ghost/intern/GHOST_EventDragnDrop.h
@@ -72,13 +72,13 @@ 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
+ * \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,
diff --git a/intern/ghost/intern/GHOST_Rect.cpp b/intern/ghost/intern/GHOST_Rect.cpp
index dc30b3eb220..9af4f30ebc1 100644
--- a/intern/ghost/intern/GHOST_Rect.cpp
+++ b/intern/ghost/intern/GHOST_Rect.cpp
@@ -75,7 +75,7 @@ GHOST_TVisibility GHOST_Rect::getVisibility(GHOST_Rect& r) const
GHOST_TVisibility v;
if (lt && rt && lb && rb) {
// All points inside, rectangle is inside this
- v = GHOST_kFullyVisible;
+ v = GHOST_kFullyVisible;
}
else if (!(lt || rt || lb || rb)) {
// None of the points inside
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 5f9928c47c7..f8c930a4824 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -207,7 +207,7 @@ public:
***************************************************************************************/
/** Inherited from GHOST_ISystem but left pure virtual
- * GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0;
+ * GHOST_TSuccess getCursorPosition(GHOST_TInt32& x, GHOST_TInt32& y) const = 0;
* GHOST_TSuccess setCursorPosition(GHOST_TInt32 x, GHOST_TInt32 y)
*/
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp
index bb68ce8889c..f5784c7d451 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.cpp
+++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp
@@ -126,7 +126,7 @@ static GHOST_TKey convertKey(int rawCode)
*/
static UInt32 dummy = 0;
Handle transData = (Handle) GetScriptManagerVariable(smKCHRCache);
- unsigned char vk = KeyTranslate(transData, rawCode, &dummy);
+ unsigned char vk = KeyTranslate(transData, rawCode, &dummy);
/* Map numpad based on rawcodes first, otherwise they
* look like non-numpad events.
* Added too: mapping the number keys, for french keyboards etc (ton)
diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm
index fed3bdbc8f0..475ad2bdcb3 100644
--- a/intern/ghost/intern/GHOST_SystemCocoa.mm
+++ b/intern/ghost/intern/GHOST_SystemCocoa.mm
@@ -423,7 +423,7 @@ static GHOST_TKey convertKey(int rawCode, unichar recvChar, UInt16 keyAction)
#pragma mark defines for 10.6 api not documented in 10.5
-#ifndef MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
enum {
/* The following event types are available on some hardware on 10.5.2 and later */
NSEventTypeGesture = 29,
@@ -435,12 +435,10 @@ enum {
};
@interface NSEvent(GestureEvents)
-/* This message is valid for events of type NSEventTypeMagnify, on 10.5.2 or later */
-#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_4
- (float)magnification; // change in magnification.
#else
-- (CGFloat)magnification; // change in magnification.
-#endif
+@interface NSEvent(GestureEvents)
+- (CGFloat)magnification; // change in magnification on 10.5.2 or later.
@end
#endif
@@ -966,7 +964,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent)
//Resend event to NSApp to ensure Mac wide events are handled
[NSApp sendEvent:event];
[pool drain];
- } while (event!= nil);
+ } while (event != nil);
#if 0
} while (waitForEvent && !anyProcessed); // Needed only for timer implementation
#endif
@@ -1000,16 +998,16 @@ GHOST_TSuccess GHOST_SystemCocoa::handleApplicationBecomeActiveEvent()
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) );
+ 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) );
+ 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) );
+ 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) );
+ pushEvent( new GHOST_EventKey(getMilliSeconds(), (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyOS));
}
m_modifierMask = modifiers;
@@ -1052,7 +1050,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleWindowEvent(GHOST_TEventType eventType,
case GHOST_kEventWindowSize:
if (!m_ignoreWindowSizedMessages)
{
- //Enforce only one resize message per event loop (coalescing all the live resize messages)
+ //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
@@ -1089,7 +1087,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
GHOST_TUns8 * temp_buff;
GHOST_TStringArray *strArray;
NSArray *droppedArray;
- size_t pastedTextSize;
+ size_t pastedTextSize;
NSString *droppedStr;
GHOST_TEventDataPtr eventData;
int i;
@@ -1126,7 +1124,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
strArray->strings[i] = temp_buff;
}
- eventData = (GHOST_TEventDataPtr) strArray;
+ eventData = (GHOST_TEventDataPtr) strArray;
break;
case GHOST_kDragnDropTypeString:
@@ -1159,7 +1157,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleDraggingEvent(GHOST_TEventType eventType
NSEnumerator *enumerator;
NSImageRep *representation;
- ibuf = IMB_allocImBuf (imgSize.width , imgSize.height, 32, IB_rect);
+ ibuf = IMB_allocImBuf (imgSize.width, imgSize.height, 32, IB_rect);
if (!ibuf) {
[droppedImg release];
return GHOST_kFailure;
@@ -1326,7 +1324,7 @@ bool GHOST_SystemCocoa::handleOpenDocumentRequest(void *filepathStr)
int confirmOpen = NSAlertAlternateReturn;
NSArray *windowsList;
char * temp_buff;
- size_t filenameTextSize;
+ size_t filenameTextSize;
GHOST_Window* window= (GHOST_Window*)m_windowManager->getActiveWindow();
if (!window) {
@@ -1460,7 +1458,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
case NSLeftMouseDown:
case NSRightMouseDown:
case NSOtherMouseDown:
- pushEvent(new GHOST_EventButton([event timestamp]*1000, GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
+ pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonDown, window, convertButton([event buttonNumber])));
//Handle tablet events combined with mouse events
handleTabletEvent(event);
break;
@@ -1468,14 +1466,14 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
case NSLeftMouseUp:
case NSRightMouseUp:
case NSOtherMouseUp:
- pushEvent(new GHOST_EventButton([event timestamp]*1000, GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
+ pushEvent(new GHOST_EventButton([event timestamp] * 1000, GHOST_kEventButtonUp, window, convertButton([event buttonNumber])));
//Handle tablet events combined with mouse events
handleTabletEvent(event);
break;
case NSLeftMouseDragged:
case NSRightMouseDragged:
- case NSOtherMouseDragged:
+ case NSOtherMouseDragged:
//Handle tablet events combined with mouse events
handleTabletEvent(event);
@@ -1503,7 +1501,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
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));
+ pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
}
break;
case GHOST_kGrabWrap: //Wrap cursor at area/window boundaries
@@ -1548,7 +1546,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
//Post event
window->getCursorGrabInitPos(x_cur, y_cur);
window->clientToScreenIntern(x_cur + x_accum, y_cur + y_accum, x, y);
- pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x, y));
+ pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
}
break;
default:
@@ -1558,7 +1556,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
GHOST_TInt32 x, y;
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
- pushEvent(new GHOST_EventCursor([event timestamp]*1000, GHOST_kEventCursorMove, window, x, y));
+ pushEvent(new GHOST_EventCursor([event timestamp] * 1000, GHOST_kEventCursorMove, window, x, y));
m_cursorDelta_x=0;
m_cursorDelta_y=0; //Mouse motion occurred between two cursor warps, so we can reset the delta counter
@@ -1580,7 +1578,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
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));
+ pushEvent(new GHOST_EventWheel([event timestamp] * 1000, window, delta));
}
else {
NSPoint mousePos = [event locationInWindow];
@@ -1604,7 +1602,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
window->clientToScreenIntern(mousePos.x, mousePos.y, x, y);
dy = -dy;
- pushEvent(new GHOST_EventTrackpad([event timestamp]*1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy));
+ pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventScroll, x, y, dx, dy));
}
}
break;
@@ -1614,8 +1612,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
NSPoint mousePos = [event locationInWindow];
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));
+ pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventMagnify, x, y,
+ [event magnification] * 125.0 + 0.1, 0));
}
break;
@@ -1624,8 +1622,8 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
NSPoint mousePos = [event locationInWindow];
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));
+ pushEvent(new GHOST_EventTrackpad([event timestamp] * 1000, window, GHOST_kTrackpadEventRotate, x, y,
+ -[event rotation] * 5.0, 0));
}
case NSEventTypeBeginGesture:
m_isGestureInProgress = true;
@@ -1700,11 +1698,11 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
break; //Cmd-Q is directly handled by Cocoa
if ([event type] == NSKeyDown) {
- pushEvent( new GHOST_EventKey([event timestamp]*1000, GHOST_kEventKeyDown, window, keyCode, ascii, utf8_buf) );
+ 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, '\0') );
+ pushEvent( new GHOST_EventKey([event timestamp] * 1000, GHOST_kEventKeyUp, window, keyCode, 0, '\0') );
//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);
}
break;
@@ -1713,16 +1711,16 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
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) );
+ 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) );
+ 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) );
+ 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) );
+ pushEvent(new GHOST_EventKey([event timestamp] * 1000, (modifiers & NSCommandKeyMask) ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, GHOST_kKeyOS));
}
m_modifierMask = modifiers;
@@ -1743,7 +1741,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
GHOST_TUns8* GHOST_SystemCocoa::getClipboard(bool selection) const
{
GHOST_TUns8 * temp_buff;
- size_t pastedTextSize;
+ size_t pastedTextSize;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 271935639fd..430569823ab 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -758,8 +758,6 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_IWindow *window, RAWINP
ascii = utf8_char[0] & 0x80 ? '?' : utf8_char[0];
}
- if (0x80 & state[VK_MENU]) utf8_char[0] = '\0';
-
event = new GHOST_EventKey(system->getMilliSeconds(), keyDown ? GHOST_kEventKeyDown : GHOST_kEventKeyUp, window, key, ascii, utf8_char);
#ifdef GHOST_DEBUG
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index 232bea6749b..c9953c80a52 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -858,7 +858,7 @@ GHOST_SystemX11::processEvent(XEvent *xe)
}
case DestroyNotify:
- ::exit(-1);
+ ::exit(-1);
/* We're not interested in the following things.(yet...) */
case NoExpose:
case GraphicsExpose:
@@ -1171,7 +1171,7 @@ generateWindowExposeEvents()
*w_start
);
- (*w_start)->validate();
+ (*w_start)->validate();
if (g_event) {
pushEvent(g_event);
@@ -1456,7 +1456,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
/* check size and format of the property */
XGetWindowProperty(m_display, win, m_xclip_out, 0, 0, False,
AnyPropertyType, &pty_type, &pty_format,
- &pty_items, &pty_size, (unsigned char **) &buffer);
+ &pty_items, &pty_size, &buffer);
if (pty_format != 8) {
/* property does not contain text, delete it
@@ -1484,7 +1484,7 @@ void GHOST_SystemX11::getClipboard_xcout(XEvent evt,
* text, we know the size. */
XGetWindowProperty(m_display, win, m_xclip_out, 0, (long) pty_size,
False, AnyPropertyType, &pty_type, &pty_format,
- &pty_items, &pty_size, (unsigned char **) &buffer);
+ &pty_items, &pty_size, &buffer);
/* allocate memory to accommodate data in *txt */
if (*len == 0) {
@@ -1538,12 +1538,12 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
if (sseln == m_clipboard) {
sel_buf = (unsigned char *)malloc(strlen(txt_cut_buffer) + 1);
strcpy((char *)sel_buf, txt_cut_buffer);
- return((GHOST_TUns8 *)sel_buf);
+ return sel_buf;
}
else {
sel_buf = (unsigned char *)malloc(strlen(txt_select_buffer) + 1);
strcpy((char *)sel_buf, txt_select_buffer);
- return((GHOST_TUns8 *)sel_buf);
+ return sel_buf;
}
}
else if (owner == None)
@@ -1594,7 +1594,7 @@ GHOST_TUns8 *GHOST_SystemX11::getClipboard(bool selection) const
else
free(sel_buf);
- return (GHOST_TUns8 *)tmp_data;
+ return tmp_data;
}
return(NULL);
}
@@ -1603,7 +1603,7 @@ 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 *> & 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();
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index bc556490d12..02c0109085a 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -230,7 +230,7 @@ public:
/**
* Puts buffer to system clipboard
- * \param buffer The buffer to copy to the 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;
diff --git a/intern/ghost/intern/GHOST_WindowCocoa.mm b/intern/ghost/intern/GHOST_WindowCocoa.mm
index dc05fe42a70..01705fe8f7b 100644
--- a/intern/ghost/intern/GHOST_WindowCocoa.mm
+++ b/intern/ghost/intern/GHOST_WindowCocoa.mm
@@ -28,7 +28,7 @@
#include <Cocoa/Cocoa.h>
-#ifndef MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
//Use of the SetSystemUIMode function (64bit compatible)
#include <Carbon/Carbon.h>
#endif
@@ -58,7 +58,7 @@ extern "C" {
extern void wm_draw_update(bContext *C);
};*/
@interface CocoaWindowDelegate : NSObject
-#ifdef MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
<NSWindowDelegate>
#endif
{
@@ -115,12 +115,12 @@ extern "C" {
- (void)windowDidResize:(NSNotification *)notification
{
-#ifdef MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
//if (![[notification object] inLiveResize]) {
//Send event only once, at end of resize operation (when user has released mouse button)
#endif
systemCocoa->handleWindowEvent(GHOST_kEventWindowSize, associatedWindow);
-#ifdef MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
//}
#endif
/* Live resize ugly patch. Needed because live resize runs in a modal loop, not letting main loop run
@@ -187,7 +187,7 @@ extern "C" {
NSPoint mouseLocation = [sender draggingLocation];
systemCocoa->handleDraggingEvent(GHOST_kEventDraggingUpdated, m_draggedObjectType, associatedWindow, mouseLocation.x, mouseLocation.y, nil);
- return associatedWindow->canAcceptDragOperation()?NSDragOperationCopy:NSDragOperationNone;
+ return associatedWindow->canAcceptDragOperation() ? NSDragOperationCopy : NSDragOperationNone;
}
- (void)draggingExited:(id < NSDraggingInfo >)sender
@@ -368,7 +368,7 @@ extern "C" {
- (BOOL)hasMarkedText
{
- return (composing)? YES: NO;
+ return (composing) ? YES : NO;
}
- (void)doCommandBySelector:(SEL)selector
@@ -392,7 +392,7 @@ extern "C" {
- (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);
@@ -402,7 +402,7 @@ extern "C" {
- (NSRange)selectedRange
{
- unsigned int length = (composing_text)? [composing_text length]: 0;
+ unsigned int length = (composing_text) ? [composing_text length] : 0;
return NSMakeRange(0, length);
}
@@ -637,7 +637,7 @@ void* GHOST_WindowCocoa::getOSWindow() const
void GHOST_WindowCocoa::setTitle(const STR_String& title)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setTitle(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSString *windowTitle = [[NSString alloc] initWithCString:title encoding:NSUTF8StringEncoding];
@@ -684,7 +684,7 @@ void GHOST_WindowCocoa::setTitle(const STR_String& title)
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];
@@ -701,7 +701,7 @@ void GHOST_WindowCocoa::getTitle(STR_String& title) const
void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const
{
NSRect rect;
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getWindowBounds(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -721,7 +721,7 @@ void GHOST_WindowCocoa::getWindowBounds(GHOST_Rect& bounds) const
void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
{
NSRect rect;
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getClientBounds(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@@ -753,7 +753,7 @@ void GHOST_WindowCocoa::getClientBounds(GHOST_Rect& bounds) const
GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientWidth(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
@@ -770,7 +770,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientWidth(GHOST_TUns32 width)
GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientHeight(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
@@ -787,7 +787,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientHeight(GHOST_TUns32 height)
GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32 height)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setClientSize(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
@@ -806,7 +806,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setClientSize(GHOST_TUns32 width, GHOST_TUns32
GHOST_TWindowState GHOST_WindowCocoa::getState() const
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::getState(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
GHOST_TWindowState state;
if (m_fullScreen) {
@@ -828,7 +828,7 @@ GHOST_TWindowState GHOST_WindowCocoa::getState() 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);
@@ -841,7 +841,7 @@ void GHOST_WindowCocoa::screenToClient(GHOST_TInt32 inX, GHOST_TInt32 inY, GHOST
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;
@@ -895,7 +895,7 @@ NSScreen* GHOST_WindowCocoa::getScreen()
*/
GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setState(): window invalid");
switch (state) {
case GHOST_kWindowStateMinimized:
[m_window miniaturize:nil];
@@ -913,7 +913,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
* doesn't know view/window difference. */
m_fullScreen = true;
-#ifdef MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
//10.6 provides Cocoa functions to autoshow menu bar, and to change a window style
//Hide menu & dock if needed
if ([[m_window screen] isEqual:[[NSScreen screens] objectAtIndex:0]]) {
@@ -972,7 +972,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setState(GHOST_TWindowState state)
m_fullScreen = false;
//Exit fullscreen
-#ifdef MAC_OS_X_VERSION_10_6
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6
//Show again menu & dock if needed
if ([[m_window screen] isEqual:[NSScreen mainScreen]]) {
[NSApp setPresentationOptions:NSApplicationPresentationDefault];
@@ -1049,7 +1049,7 @@ GHOST_TSuccess GHOST_WindowCocoa::setOrder(GHOST_TWindowOrder order)
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::setOrder(): window invalid");
if (order == GHOST_kWindowOrderTop) {
[m_window makeKeyAndOrderFront:nil];
}
@@ -1199,7 +1199,7 @@ GHOST_TSuccess GHOST_WindowCocoa::removeDrawingContext()
GHOST_TSuccess GHOST_WindowCocoa::invalidate()
{
- GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid")
+ GHOST_ASSERT(getValid(), "GHOST_WindowCocoa::invalidate(): window invalid");
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[m_openGLView setNeedsDisplay:YES];
[pool drain];
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 903e02e33d5..61bee046103 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -726,7 +726,7 @@ GHOST_TSuccess GHOST_WindowWin32::initMultisample(PIXELFORMATDESCRIPTOR pfd)
};
// Get the function
- PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
+ PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC)wglGetProcAddress("wglChoosePixelFormatARB");
if (!wglChoosePixelFormatARB)
{
diff --git a/intern/ghost/test/multitest/EventToBuf.c b/intern/ghost/test/multitest/EventToBuf.c
index aba80784a72..49255de5e64 100644
--- a/intern/ghost/test/multitest/EventToBuf.c
+++ b/intern/ghost/test/multitest/EventToBuf.c
@@ -197,15 +197,15 @@ static char *keytype_to_string(GHOST_TKey key)
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;
+ 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);
+ char *s = GHOST_GetTitle(win);
pos += sprintf(pos, " - win: %s", s);
free(s);
}
@@ -215,14 +215,14 @@ void event_to_buf(GHOST_EventHandle evt, char buf[128])
switch (type) {
case GHOST_kEventCursorMove:
{
- GHOST_TEventCursorData *cd= data;
+ 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;
+ GHOST_TEventButtonData *bd = data;
pos += sprintf(pos, " - but: %d", bd->button);
break;
}
@@ -230,7 +230,7 @@ void event_to_buf(GHOST_EventHandle evt, char buf[128])
case GHOST_kEventKeyDown:
case GHOST_kEventKeyUp:
{
- GHOST_TEventKeyData *kd= data;
+ 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/MultiTest.c b/intern/ghost/test/multitest/MultiTest.c
index 5d207dafaaf..2d0afcf671c 100644
--- a/intern/ghost/test/multitest/MultiTest.c
+++ b/intern/ghost/test/multitest/MultiTest.c
@@ -26,9 +26,8 @@
*/
#define FALSE 0
-#ifdef WIN32
-
-#pragma warning(disable: 4244 4305)
+#ifdef _MSC_VER
+# pragma warning(disable: 4244 4305)
#endif
#include <stdlib.h>
diff --git a/intern/guardedalloc/cpp/mallocn.cpp b/intern/guardedalloc/cpp/mallocn.cpp
index da77f0e1c83..8b05d25018f 100644
--- a/intern/guardedalloc/cpp/mallocn.cpp
+++ b/intern/guardedalloc/cpp/mallocn.cpp
@@ -28,6 +28,9 @@
#include <new>
#include "../MEM_guardedalloc.h"
+void *operator new(size_t size, const char *str) throw(std::bad_alloc);
+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)
{
diff --git a/intern/itasc/CMakeLists.txt b/intern/itasc/CMakeLists.txt
index f4bc0326ea1..bc3ea0cf24c 100644
--- a/intern/itasc/CMakeLists.txt
+++ b/intern/itasc/CMakeLists.txt
@@ -22,13 +22,13 @@
# Contributor(s): Jacques Beaurain.
#
# ***** END GPL LICENSE BLOCK *****
-
+remove_strict_flags()
set(INC
- ../../extern/Eigen3
+
)
set(INC_SYS
-
+ ../../extern/Eigen3
)
set(SRC
@@ -121,201 +121,235 @@ set(SRC
kdl/framevel.inl
# until we have another user...
- ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h
- ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h
- ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h
- ../../extern/Eigen3/Eigen/src/plugins/BlockMethods.h
- ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h
- ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h
- ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h
- ../../extern/Eigen3/Eigen/src/misc/Kernel.h
- ../../extern/Eigen3/Eigen/src/misc/Image.h
- ../../extern/Eigen3/Eigen/src/misc/Solve.h
- ../../extern/Eigen3/Eigen/src/QR/HouseholderQR.h
- ../../extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h
- ../../extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h
- ../../extern/Eigen3/Eigen/src/StlSupport/details.h
- ../../extern/Eigen3/Eigen/src/StlSupport/StdList.h
- ../../extern/Eigen3/Eigen/src/StlSupport/StdDeque.h
- ../../extern/Eigen3/Eigen/src/StlSupport/StdVector.h
- ../../extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h
- ../../extern/Eigen3/Eigen/src/SVD/JacobiSVD.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/EigenvaluesCommon.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
- ../../extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h
- ../../extern/Eigen3/Eigen/src/Jacobi/Jacobi.h
- ../../extern/Eigen3/Eigen/src/Householder/Householder.h
- ../../extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h
- ../../extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h
- ../../extern/Eigen3/Eigen/src/Geometry/RotationBase.h
- ../../extern/Eigen3/Eigen/src/Geometry/Rotation2D.h
- ../../extern/Eigen3/Eigen/src/Geometry/Homogeneous.h
- ../../extern/Eigen3/Eigen/src/Geometry/Hyperplane.h
- ../../extern/Eigen3/Eigen/src/Geometry/EulerAngles.h
- ../../extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h
- ../../extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h
- ../../extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h
- ../../extern/Eigen3/Eigen/src/Geometry/AngleAxis.h
- ../../extern/Eigen3/Eigen/src/Geometry/Umeyama.h
- ../../extern/Eigen3/Eigen/src/Geometry/Scaling.h
- ../../extern/Eigen3/Eigen/src/Geometry/Translation.h
- ../../extern/Eigen3/Eigen/src/Geometry/AlignedBox.h
- ../../extern/Eigen3/Eigen/src/Geometry/Transform.h
- ../../extern/Eigen3/Eigen/src/Geometry/Quaternion.h
- ../../extern/Eigen3/Eigen/src/LU/PartialPivLU.h
- ../../extern/Eigen3/Eigen/src/LU/Determinant.h
- ../../extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h
- ../../extern/Eigen3/Eigen/src/LU/FullPivLU.h
- ../../extern/Eigen3/Eigen/src/LU/Inverse.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseMatrixBase.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseSelfAdjointView.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseVector.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseDiagonalProduct.h
- ../../extern/Eigen3/Eigen/src/Sparse/TriangularSolver.h
- ../../extern/Eigen3/Eigen/src/Sparse/AmbiVector.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseDenseProduct.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseBlock.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseTriangularView.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseCwiseBinaryOp.h
- ../../extern/Eigen3/Eigen/src/Sparse/CoreIterators.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseMatrix.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseAssign.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseSparseProduct.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseDot.h
- ../../extern/Eigen3/Eigen/src/Sparse/DynamicSparseMatrix.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseRedux.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseFuzzy.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseCwiseUnaryOp.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseView.h
- ../../extern/Eigen3/Eigen/src/Sparse/MappedSparseMatrix.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseUtil.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseTranspose.h
- ../../extern/Eigen3/Eigen/src/Sparse/SparseProduct.h
- ../../extern/Eigen3/Eigen/src/Sparse/CompressedStorage.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/QR.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Memory.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/SVD.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Meta.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Macros.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/LU.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Block.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/Minor.h
- ../../extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h
- ../../extern/Eigen3/Eigen/src/Core/SelfAdjointView.h
- ../../extern/Eigen3/Eigen/src/Core/MatrixBase.h
- ../../extern/Eigen3/Eigen/src/Core/Swap.h
- ../../extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h
- ../../extern/Eigen3/Eigen/src/Core/DenseBase.h
- ../../extern/Eigen3/Eigen/src/Core/GlobalFunctions.h
- ../../extern/Eigen3/Eigen/src/Core/ProductBase.h
- ../../extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h
- ../../extern/Eigen3/Eigen/src/Core/Stride.h
- ../../extern/Eigen3/Eigen/src/Core/Matrix.h
- ../../extern/Eigen3/Eigen/src/Core/Visitor.h
+ ../../extern/Eigen3/Eigen/src/Cholesky/LDLT.h
+ ../../extern/Eigen3/Eigen/src/Cholesky/LLT.h
+ ../../extern/Eigen3/Eigen/src/Cholesky/LLT_MKL.h
+ ../../extern/Eigen3/Eigen/src/CholmodSupport/CholmodSupport.h
../../extern/Eigen3/Eigen/src/Core/Array.h
- ../../extern/Eigen3/Eigen/src/Core/ReturnByValue.h
- ../../extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h
- ../../extern/Eigen3/Eigen/src/Core/EigenBase.h
- ../../extern/Eigen3/Eigen/src/Core/Random.h
- ../../extern/Eigen3/Eigen/src/Core/Redux.h
- ../../extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h
- ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h
- ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h
- ../../extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h
- ../../extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h
- ../../extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h
- ../../extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h
- ../../extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h
- ../../extern/Eigen3/Eigen/src/Core/BooleanRedux.h
- ../../extern/Eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h
- ../../extern/Eigen3/Eigen/src/Core/util/BlasUtil.h
- ../../extern/Eigen3/Eigen/src/Core/util/Memory.h
- ../../extern/Eigen3/Eigen/src/Core/util/Meta.h
- ../../extern/Eigen3/Eigen/src/Core/util/Constants.h
- ../../extern/Eigen3/Eigen/src/Core/util/Macros.h
- ../../extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h
- ../../extern/Eigen3/Eigen/src/Core/util/StaticAssert.h
- ../../extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h
- ../../extern/Eigen3/Eigen/src/Core/util/XprHelper.h
- ../../extern/Eigen3/Eigen/src/Core/VectorBlock.h
- ../../extern/Eigen3/Eigen/src/Core/Transpositions.h
- ../../extern/Eigen3/Eigen/src/Core/Select.h
+ ../../extern/Eigen3/Eigen/src/Core/ArrayBase.h
+ ../../extern/Eigen3/Eigen/src/Core/ArrayWrapper.h
+ ../../extern/Eigen3/Eigen/src/Core/Assign.h
+ ../../extern/Eigen3/Eigen/src/Core/Assign_MKL.h
../../extern/Eigen3/Eigen/src/Core/BandMatrix.h
+ ../../extern/Eigen3/Eigen/src/Core/Block.h
+ ../../extern/Eigen3/Eigen/src/Core/BooleanRedux.h
+ ../../extern/Eigen3/Eigen/src/Core/CommaInitializer.h
+ ../../extern/Eigen3/Eigen/src/Core/CwiseBinaryOp.h
+ ../../extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h
+ ../../extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h
../../extern/Eigen3/Eigen/src/Core/CwiseUnaryView.h
+ ../../extern/Eigen3/Eigen/src/Core/DenseBase.h
+ ../../extern/Eigen3/Eigen/src/Core/DenseCoeffsBase.h
+ ../../extern/Eigen3/Eigen/src/Core/DenseStorage.h
+ ../../extern/Eigen3/Eigen/src/Core/Diagonal.h
+ ../../extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h
+ ../../extern/Eigen3/Eigen/src/Core/DiagonalProduct.h
../../extern/Eigen3/Eigen/src/Core/Dot.h
+ ../../extern/Eigen3/Eigen/src/Core/EigenBase.h
+ ../../extern/Eigen3/Eigen/src/Core/Flagged.h
+ ../../extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h
+ ../../extern/Eigen3/Eigen/src/Core/Functors.h
+ ../../extern/Eigen3/Eigen/src/Core/Fuzzy.h
+ ../../extern/Eigen3/Eigen/src/Core/GeneralProduct.h
../../extern/Eigen3/Eigen/src/Core/GenericPacketMath.h
- ../../extern/Eigen3/Eigen/src/Core/Product.h
- ../../extern/Eigen3/Eigen/src/Core/Transpose.h
- ../../extern/Eigen3/Eigen/src/Core/Block.h
- ../../extern/Eigen3/Eigen/src/Core/ArrayWrapper.h
+ ../../extern/Eigen3/Eigen/src/Core/GlobalFunctions.h
+ ../../extern/Eigen3/Eigen/src/Core/IO.h
+ ../../extern/Eigen3/Eigen/src/Core/Map.h
../../extern/Eigen3/Eigen/src/Core/MapBase.h
+ ../../extern/Eigen3/Eigen/src/Core/MathFunctions.h
+ ../../extern/Eigen3/Eigen/src/Core/Matrix.h
+ ../../extern/Eigen3/Eigen/src/Core/MatrixBase.h
+ ../../extern/Eigen3/Eigen/src/Core/NestByValue.h
../../extern/Eigen3/Eigen/src/Core/NoAlias.h
- ../../extern/Eigen3/Eigen/src/Core/ForceAlignedAccess.h
- ../../extern/Eigen3/Eigen/src/Core/PlainObjectBase.h
- ../../extern/Eigen3/Eigen/src/Core/IO.h
- ../../extern/Eigen3/Eigen/src/Core/DiagonalMatrix.h
- ../../extern/Eigen3/Eigen/src/Core/CwiseUnaryOp.h
- ../../extern/Eigen3/Eigen/src/Core/Reverse.h
- ../../extern/Eigen3/Eigen/src/Core/Fuzzy.h
- ../../extern/Eigen3/Eigen/src/Core/DenseStorage.h
- ../../extern/Eigen3/Eigen/src/Core/StableNorm.h
../../extern/Eigen3/Eigen/src/Core/NumTraits.h
- ../../extern/Eigen3/Eigen/src/Core/Map.h
- ../../extern/Eigen3/Eigen/src/Core/Functors.h
../../extern/Eigen3/Eigen/src/Core/PermutationMatrix.h
- ../../extern/Eigen3/Eigen/src/Core/ArrayBase.h
- ../../extern/Eigen3/Eigen/src/Core/CwiseNullaryOp.h
- ../../extern/Eigen3/Eigen/src/Core/SolveTriangular.h
- ../../extern/Eigen3/Eigen/src/Core/NestByValue.h
- ../../extern/Eigen3/Eigen/src/Core/DiagonalProduct.h
- ../../extern/Eigen3/Eigen/src/Core/CommaInitializer.h
- ../../extern/Eigen3/Eigen/src/Core/MathFunctions.h
- ../../extern/Eigen3/Eigen/src/Core/Diagonal.h
+ ../../extern/Eigen3/Eigen/src/Core/PlainObjectBase.h
+ ../../extern/Eigen3/Eigen/src/Core/Product.h
+ ../../extern/Eigen3/Eigen/src/Core/ProductBase.h
+ ../../extern/Eigen3/Eigen/src/Core/Random.h
+ ../../extern/Eigen3/Eigen/src/Core/Redux.h
../../extern/Eigen3/Eigen/src/Core/Replicate.h
- ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h
- ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h
- ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h
+ ../../extern/Eigen3/Eigen/src/Core/ReturnByValue.h
+ ../../extern/Eigen3/Eigen/src/Core/Reverse.h
+ ../../extern/Eigen3/Eigen/src/Core/Select.h
+ ../../extern/Eigen3/Eigen/src/Core/SelfAdjointView.h
+ ../../extern/Eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h
+ ../../extern/Eigen3/Eigen/src/Core/SolveTriangular.h
+ ../../extern/Eigen3/Eigen/src/Core/StableNorm.h
+ ../../extern/Eigen3/Eigen/src/Core/Stride.h
+ ../../extern/Eigen3/Eigen/src/Core/Swap.h
+ ../../extern/Eigen3/Eigen/src/Core/Transpose.h
+ ../../extern/Eigen3/Eigen/src/Core/Transpositions.h
+ ../../extern/Eigen3/Eigen/src/Core/TriangularMatrix.h
+ ../../extern/Eigen3/Eigen/src/Core/VectorBlock.h
+ ../../extern/Eigen3/Eigen/src/Core/VectorwiseOp.h
+ ../../extern/Eigen3/Eigen/src/Core/Visitor.h
+ ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/Complex.h
+ ../../extern/Eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h
+ ../../extern/Eigen3/Eigen/src/Core/arch/Default/Settings.h
+ ../../extern/Eigen3/Eigen/src/Core/arch/NEON/Complex.h
+ ../../extern/Eigen3/Eigen/src/Core/arch/NEON/PacketMath.h
+ ../../extern/Eigen3/Eigen/src/Core/arch/SSE/Complex.h
+ ../../extern/Eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h
+ ../../extern/Eigen3/Eigen/src/Core/arch/SSE/PacketMath.h
../../extern/Eigen3/Eigen/src/Core/products/CoeffBasedProduct.h
- ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h
- ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h
- ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
+ ../../extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h
../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h
- ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
+ ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h
+ ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_MKL.h
+ ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_MKL.h
+ ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector.h
+ ../../extern/Eigen3/Eigen/src/Core/products/GeneralMatrixVector_MKL.h
../../extern/Eigen3/Eigen/src/Core/products/Parallelizer.h
+ ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h
+ ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_MKL.h
+ ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h
+ ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_MKL.h
+ ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointProduct.h
+ ../../extern/Eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h
+ ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h
+ ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_MKL.h
+ ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h
+ ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector_MKL.h
../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h
+ ../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverMatrix_MKL.h
../../extern/Eigen3/Eigen/src/Core/products/TriangularSolverVector.h
- ../../extern/Eigen3/Eigen/src/Core/products/TriangularMatrixVector.h
- ../../extern/Eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h
- ../../extern/Eigen3/Eigen/src/Core/TriangularMatrix.h
- ../../extern/Eigen3/Eigen/src/Core/VectorwiseOp.h
- ../../extern/Eigen3/Eigen/src/Core/Assign.h
- ../../extern/Eigen3/Eigen/src/Core/Flagged.h
- ../../extern/Eigen3/Eigen/src/Cholesky/LDLT.h
- ../../extern/Eigen3/Eigen/src/Cholesky/LLT.h
+ ../../extern/Eigen3/Eigen/src/Core/util/BlasUtil.h
+ ../../extern/Eigen3/Eigen/src/Core/util/Constants.h
+ ../../extern/Eigen3/Eigen/src/Core/util/DisableStupidWarnings.h
+ ../../extern/Eigen3/Eigen/src/Core/util/ForwardDeclarations.h
+ ../../extern/Eigen3/Eigen/src/Core/util/Macros.h
+ ../../extern/Eigen3/Eigen/src/Core/util/Memory.h
+ ../../extern/Eigen3/Eigen/src/Core/util/Meta.h
+ ../../extern/Eigen3/Eigen/src/Core/util/MKL_support.h
+ ../../extern/Eigen3/Eigen/src/Core/util/NonMPL2.h
+ ../../extern/Eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h
+ ../../extern/Eigen3/Eigen/src/Core/util/StaticAssert.h
+ ../../extern/Eigen3/Eigen/src/Core/util/XprHelper.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Block.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Cwise.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/CwiseOperators.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Lazy.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/LeastSquares.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/LU.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Macros.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/MathFunctions.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Memory.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Meta.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Minor.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/QR.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/SVD.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/TriangularSolver.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/VectorBlock.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AlignedBox.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/All.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/AngleAxis.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Hyperplane.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/ParametrizedLine.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Quaternion.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Rotation2D.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/RotationBase.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Scaling.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Transform.h
+ ../../extern/Eigen3/Eigen/src/Eigen2Support/Geometry/Translation.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/ComplexSchur_MKL.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/EigenSolver.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/RealSchur.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/RealSchur_MKL.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_MKL.h
+ ../../extern/Eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h
+ ../../extern/Eigen3/Eigen/src/Geometry/AlignedBox.h
+ ../../extern/Eigen3/Eigen/src/Geometry/AngleAxis.h
+ ../../extern/Eigen3/Eigen/src/Geometry/EulerAngles.h
+ ../../extern/Eigen3/Eigen/src/Geometry/Homogeneous.h
+ ../../extern/Eigen3/Eigen/src/Geometry/Hyperplane.h
+ ../../extern/Eigen3/Eigen/src/Geometry/OrthoMethods.h
+ ../../extern/Eigen3/Eigen/src/Geometry/ParametrizedLine.h
+ ../../extern/Eigen3/Eigen/src/Geometry/Quaternion.h
+ ../../extern/Eigen3/Eigen/src/Geometry/Rotation2D.h
+ ../../extern/Eigen3/Eigen/src/Geometry/RotationBase.h
+ ../../extern/Eigen3/Eigen/src/Geometry/Scaling.h
+ ../../extern/Eigen3/Eigen/src/Geometry/Transform.h
+ ../../extern/Eigen3/Eigen/src/Geometry/Translation.h
+ ../../extern/Eigen3/Eigen/src/Geometry/Umeyama.h
+ ../../extern/Eigen3/Eigen/src/Geometry/arch/Geometry_SSE.h
+ ../../extern/Eigen3/Eigen/src/Householder/BlockHouseholder.h
+ ../../extern/Eigen3/Eigen/src/Householder/Householder.h
+ ../../extern/Eigen3/Eigen/src/Householder/HouseholderSequence.h
+ ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h
+ ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h
+ ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h
+ ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h
+ ../../extern/Eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h
+ ../../extern/Eigen3/Eigen/src/Jacobi/Jacobi.h
+ ../../extern/Eigen3/Eigen/src/LU/Determinant.h
+ ../../extern/Eigen3/Eigen/src/LU/FullPivLU.h
+ ../../extern/Eigen3/Eigen/src/LU/Inverse.h
+ ../../extern/Eigen3/Eigen/src/LU/PartialPivLU.h
+ ../../extern/Eigen3/Eigen/src/LU/PartialPivLU_MKL.h
+ ../../extern/Eigen3/Eigen/src/LU/arch/Inverse_SSE.h
+ ../../extern/Eigen3/Eigen/src/misc/blas.h
+ ../../extern/Eigen3/Eigen/src/misc/Image.h
+ ../../extern/Eigen3/Eigen/src/misc/Kernel.h
+ ../../extern/Eigen3/Eigen/src/misc/Solve.h
+ ../../extern/Eigen3/Eigen/src/misc/SparseSolve.h
+ ../../extern/Eigen3/Eigen/src/OrderingMethods/Amd.h
+ ../../extern/Eigen3/Eigen/src/PardisoSupport/PardisoSupport.h
+ ../../extern/Eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h
+ ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h
+ ../../extern/Eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h
+ ../../extern/Eigen3/Eigen/src/plugins/BlockMethods.h
+ ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h
+ ../../extern/Eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h
+ ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h
+ ../../extern/Eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h
+ ../../extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR.h
+ ../../extern/Eigen3/Eigen/src/QR/ColPivHouseholderQR_MKL.h
+ ../../extern/Eigen3/Eigen/src/QR/FullPivHouseholderQR.h
+ ../../extern/Eigen3/Eigen/src/QR/HouseholderQR.h
+ ../../extern/Eigen3/Eigen/src/QR/HouseholderQR_MKL.h
+ ../../extern/Eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/AmbiVector.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/CompressedStorage.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/CoreIterators.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseAssign.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseBlock.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseDenseProduct.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseDot.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseFuzzy.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseMatrix.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseMatrixBase.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparsePermutation.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseProduct.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseRedux.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseTranspose.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseTriangularView.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseUtil.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseVector.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/SparseView.h
+ ../../extern/Eigen3/Eigen/src/SparseCore/TriangularSolver.h
+ ../../extern/Eigen3/Eigen/src/StlSupport/details.h
+ ../../extern/Eigen3/Eigen/src/StlSupport/StdDeque.h
+ ../../extern/Eigen3/Eigen/src/StlSupport/StdList.h
+ ../../extern/Eigen3/Eigen/src/StlSupport/StdVector.h
+ ../../extern/Eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h
+ ../../extern/Eigen3/Eigen/src/SVD/JacobiSVD.h
+ ../../extern/Eigen3/Eigen/src/SVD/JacobiSVD_MKL.h
+ ../../extern/Eigen3/Eigen/src/SVD/UpperBidiagonalization.h
+ ../../extern/Eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h
)
diff --git a/intern/itasc/Scene.cpp b/intern/itasc/Scene.cpp
index 7a83f821bf0..7ed8fc4e63c 100644
--- a/intern/itasc/Scene.cpp
+++ b/intern/itasc/Scene.cpp
@@ -40,7 +40,7 @@ public:
{
q_nr += m_qrange.start;
project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
- // update the ouput vector so that the movement of this joint will be
+ // update the output vector so that the movement of this joint will be
// taken into account and we can put the joint back in its initial position
// which means that the jacobian doesn't need to be changed
for (unsigned int i=0 ;i<ndof ; ++i, ++q_nr) {
diff --git a/intern/itasc/kdl/chain.hpp b/intern/itasc/kdl/chain.hpp
index 773f472cc5c..fde9d4ed23e 100644
--- a/intern/itasc/kdl/chain.hpp
+++ b/intern/itasc/kdl/chain.hpp
@@ -35,11 +35,16 @@ namespace KDL {
*/
class Chain {
private:
-#if !defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_5)
+#if defined(__APPLE__)
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+ std::vector<Segment> segments;
+# else
// Eigen allocator is needed for alignment of Eigen data types
std::vector<Segment, Eigen::aligned_allocator<Segment> > segments;
+# endif /* MAC_OS_X_VERSION_MIN_REQUIRED */
#else
- std::vector<Segment> segments;
+ // Eigen allocator is needed for alignment of Eigen data types
+ std::vector<Segment, Eigen::aligned_allocator<Segment> > segments;
#endif
unsigned int nrOfJoints;
unsigned int nrOfSegments;
diff --git a/intern/itasc/kdl/tree.hpp b/intern/itasc/kdl/tree.hpp
index 08c1aadc6de..a020c6cf2cf 100644
--- a/intern/itasc/kdl/tree.hpp
+++ b/intern/itasc/kdl/tree.hpp
@@ -27,19 +27,30 @@
#include <string>
#include <map>
-#if !defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_5)
-#include <Eigen/Core>
+#if defined(__APPLE__)
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+ //no include
+# else
+# include <Eigen/Core>
+# endif /* MAC_OS_X_VERSION_MIN_REQUIRED */
+#else
+# include <Eigen/Core>
#endif
namespace KDL
{
//Forward declaration
class TreeElement;
-#if !defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_5)
+#if defined(__APPLE__)
+# if MAC_OS_X_VERSION_MIN_REQUIRED <= MAC_OS_X_VERSION_10_5
+ typedef std::map<std::string,TreeElement> SegmentMap;
+# else
// Eigen allocator is needed for alignment of Eigen data types
typedef std::map<std::string,TreeElement, std::less<std::string>, Eigen::aligned_allocator<std::pair<std::string, TreeElement> > > SegmentMap;
+# endif /* MAC_OS_X_VERSION_MIN_REQUIRED */
#else
- typedef std::map<std::string,TreeElement> SegmentMap;
+ // Eigen allocator is needed for alignment of Eigen data types
+ typedef std::map<std::string,TreeElement, std::less<std::string>, Eigen::aligned_allocator<std::pair<std::string, TreeElement> > > SegmentMap;
#endif
class TreeElement
{
diff --git a/intern/memutil/MEM_CacheLimiterC-Api.h b/intern/memutil/MEM_CacheLimiterC-Api.h
index 1ae5e9df1c6..c05c9d61ea2 100644
--- a/intern/memutil/MEM_CacheLimiterC-Api.h
+++ b/intern/memutil/MEM_CacheLimiterC-Api.h
@@ -80,7 +80,7 @@ void delete_MEM_CacheLimiter(MEM_CacheLimiterC *This);
* @return CacheLimiterHandle to ref, unref, touch the managed object
*/
-MEM_CacheLimiterHandleC *MEM_CacheLimiter_insert(MEM_CacheLimiterC * This, void * data);
+MEM_CacheLimiterHandleC *MEM_CacheLimiter_insert(MEM_CacheLimiterC *This, void *data);
/**
* Free objects until memory constraints are satisfied
@@ -140,7 +140,7 @@ int MEM_CacheLimiter_get_refcount(MEM_CacheLimiterHandleC *handle);
* @param handle of object
*/
-void * MEM_CacheLimiter_get(MEM_CacheLimiterHandleC *handle);
+void *MEM_CacheLimiter_get(MEM_CacheLimiterHandleC *handle);
void MEM_CacheLimiter_ItemPriority_Func_set(MEM_CacheLimiterC *This,
MEM_CacheLimiter_ItemPriority_Func item_priority_func);
diff --git a/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp b/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
index 81a1ce670ae..7a19543b2db 100644
--- a/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
+++ b/intern/memutil/intern/MEM_CacheLimiterC-Api.cpp
@@ -59,9 +59,9 @@ public:
}
~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;
@@ -76,7 +76,7 @@ private:
class MEM_CacheLimiterHandleCClass {
public:
- MEM_CacheLimiterHandleCClass(void * data_, MEM_CacheLimiterCClass * parent_) :
+ MEM_CacheLimiterHandleCClass(void *data_, MEM_CacheLimiterCClass *parent_) :
data(data_),
parent(parent_)
{ }
@@ -87,7 +87,7 @@ public:
it = it_;
}
- void set_data(void * data_) {
+ void set_data(void *data_) {
data = data_;
}
@@ -101,7 +101,7 @@ private:
list_t::iterator it;
};
-handle_t *MEM_CacheLimiterCClass::insert(void * data)
+handle_t *MEM_CacheLimiterCClass::insert(void *data)
{
cclass_list.push_back(new MEM_CacheLimiterHandleCClass(data, this));
list_t::iterator it = cclass_list.end();
@@ -111,7 +111,7 @@ handle_t *MEM_CacheLimiterCClass::insert(void * data)
return cache.insert(cclass_list.back());
}
-void MEM_CacheLimiterCClass::destruct(void * data, list_t::iterator it)
+void MEM_CacheLimiterCClass::destruct(void *data, list_t::iterator it)
{
data_destructor(data);
cclass_list.erase(it);
diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt
index d46b09cf76a..c281a6e7bbb 100644
--- a/intern/opencolorio/CMakeLists.txt
+++ b/intern/opencolorio/CMakeLists.txt
@@ -30,6 +30,7 @@ set(INC
)
set(INC_SYS
+
)
set(SRC
diff --git a/intern/opennl/CMakeLists.txt b/intern/opennl/CMakeLists.txt
index 4f96587953f..2f15bbb907c 100644
--- a/intern/opennl/CMakeLists.txt
+++ b/intern/opennl/CMakeLists.txt
@@ -40,11 +40,10 @@ add_definitions(
set(INC
extern
superlu
- ../../extern/colamd/Include
)
set(INC_SYS
-
+ ../../extern/colamd/Include
)
set(SRC
diff --git a/intern/opennl/SConscript b/intern/opennl/SConscript
index 711955cbfeb..a0f02735748 100644
--- a/intern/opennl/SConscript
+++ b/intern/opennl/SConscript
@@ -5,8 +5,5 @@ sources = env.Glob('intern/*.c') + env.Glob('superlu/*.c')
incs = 'extern superlu ../../extern/colamd/Include'
-if (env['OURPLATFORM'] in ('win32-mingw', 'win64-mingw')):
- env.BlenderLib ('bf_intern_opennl', sources, Split(incs), [], libtype=['core','intern'], priority=[1,80] )
-else:
- env.BlenderLib ('bf_intern_opennl', sources, Split(incs), [], libtype=['core'], priority=[55] )
+env.BlenderLib ('bf_intern_opennl', sources, Split(incs), [], libtype=['intern','player'], priority=[100,90] )
diff --git a/intern/raskter/raskter.c b/intern/raskter/raskter.c
index c79bcc4a76d..21153082324 100644
--- a/intern/raskter/raskter.c
+++ b/intern/raskter/raskter.c
@@ -113,7 +113,7 @@ static void preprocess_all_edges(struct r_FillContext *ctx,
ctx->rb.xmin = xbeg;
}
if (ybeg >= ctx->rb.ymax) {
- ctx->rb.ymax= ybeg;
+ ctx->rb.ymax = ybeg;
}
else if (ybeg <= ctx->rb.ymin) {
ctx->rb.ymin=ybeg;
diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt
index 9524f7b2935..3b8a4c06e69 100644
--- a/intern/smoke/CMakeLists.txt
+++ b/intern/smoke/CMakeLists.txt
@@ -26,10 +26,10 @@
set(INC
intern
../memutil
- ../../extern/bullet2/src
)
set(INC_SYS
+ ../../extern/bullet2/src
${PNG_INCLUDE_DIR}
${ZLIB_INCLUDE_DIRS}
)
@@ -40,6 +40,7 @@ set(SRC
intern/FLUID_3D_SOLVERS.cpp
intern/FLUID_3D_STATIC.cpp
intern/LU_HELPER.cpp
+ intern/spectrum.cpp
intern/SPHERE.cpp
intern/WTURBULENCE.cpp
intern/smoke_API.cpp
@@ -53,6 +54,7 @@ set(SRC
intern/LU_HELPER.h
intern/MERSENNETWISTER.h
intern/OBSTACLE.h
+ intern/spectrum.h
intern/SPHERE.h
intern/VEC3.h
intern/WAVELET_NOISE.h
diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h
index a0eb1bf38e0..98c63f08fbd 100644
--- a/intern/smoke/extern/smoke_API.h
+++ b/intern/smoke/extern/smoke_API.h
@@ -37,17 +37,23 @@ extern "C" {
struct FLUID_3D;
-// export
-void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles);
-
// low res
-struct FLUID_3D *smoke_init(int *res, float *p0, float dtdef);
+struct FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors);
void smoke_free(struct FLUID_3D *fluid);
-void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli);
-void smoke_step(struct FLUID_3D *fluid, float dtSubdiv);
+void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate,
+ float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp);
+void smoke_step(struct FLUID_3D *fluid, float gravity[3], float dtSubdiv);
float *smoke_get_density(struct FLUID_3D *fluid);
+float *smoke_get_flame(struct FLUID_3D *fluid);
+float *smoke_get_fuel(struct FLUID_3D *fluid);
+float *smoke_get_react(struct FLUID_3D *fluid);
+float *smoke_get_color_r(struct FLUID_3D *fluid);
+float *smoke_get_color_g(struct FLUID_3D *fluid);
+float *smoke_get_color_b(struct FLUID_3D *fluid);
+void smoke_get_rgba(struct FLUID_3D *fluid, float *data, int sequential);
+void smoke_get_rgba_from_density(struct FLUID_3D *fluid, float color[3], float *data, int sequential);
float *smoke_get_heat(struct FLUID_3D *fluid);
float *smoke_get_velocity_x(struct FLUID_3D *fluid);
float *smoke_get_velocity_y(struct FLUID_3D *fluid);
@@ -68,19 +74,44 @@ size_t smoke_get_index2d(int x, int max_x, int y);
void smoke_dissolve(struct FLUID_3D *fluid, int speed, int log);
// wavelet turbulence functions
-struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype);
+struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, int use_fire, int use_colors);
void smoke_turbulence_free(struct WTURBULENCE *wt);
void smoke_turbulence_step(struct WTURBULENCE *wt, struct FLUID_3D *fluid);
float *smoke_turbulence_get_density(struct WTURBULENCE *wt);
+float *smoke_turbulence_get_color_r(struct WTURBULENCE *wt);
+float *smoke_turbulence_get_color_g(struct WTURBULENCE *wt);
+float *smoke_turbulence_get_color_b(struct WTURBULENCE *wt);
+void smoke_turbulence_get_rgba(struct WTURBULENCE *wt, float *data, int sequential);
+void smoke_turbulence_get_rgba_from_density(struct WTURBULENCE *wt, float color[3], float *data, int sequential);
+float *smoke_turbulence_get_flame(struct WTURBULENCE *wt);
+float *smoke_turbulence_get_fuel(struct WTURBULENCE *wt);
+float *smoke_turbulence_get_react(struct WTURBULENCE *wt);
void smoke_turbulence_get_res(struct WTURBULENCE *wt, int *res);
+int smoke_turbulence_get_cells(struct WTURBULENCE *wt);
void smoke_turbulence_set_noise(struct WTURBULENCE *wt, int type);
void smoke_initWaveletBlenderRNA(struct WTURBULENCE *wt, float *strength);
-
void smoke_dissolve_wavelet(struct WTURBULENCE *wt, int speed, int log);
-// export
-void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw);
+/* export */
+void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat, float **heatold,
+ float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles);
+void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel,
+ float **r, float **g, float **b, float **tcu, float **tcv, float **tcw);
+
+/* flame spectrum */
+void flame_get_spectrum(unsigned char *spec, int width, float t1, float t2);
+
+/* data fields */
+int smoke_has_heat(struct FLUID_3D *fluid);
+int smoke_has_fuel(struct FLUID_3D *fluid);
+int smoke_has_colors(struct FLUID_3D *fluid);
+int smoke_turbulence_has_fuel(struct WTURBULENCE *wt);
+int smoke_turbulence_has_colors(struct WTURBULENCE *wt);
+
+void smoke_ensure_heat(struct FLUID_3D *fluid);
+void smoke_ensure_fire(struct FLUID_3D *fluid, struct WTURBULENCE *wt);
+void smoke_ensure_colors(struct FLUID_3D *fluid, struct WTURBULENCE *wt, float init_r, float init_g, float init_b);
#ifdef __cplusplus
}
diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp
index e006132ea8f..4eb11a46f5b 100644
--- a/intern/smoke/intern/FLUID_3D.cpp
+++ b/intern/smoke/intern/FLUID_3D.cpp
@@ -44,16 +44,11 @@
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
-FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) :
+FLUID_3D::FLUID_3D(int *res, float dx, float dtdef, int init_heat, int init_fire, int init_colors) :
_xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f)
{
// set simulation consts
_dt = dtdef; // just in case. set in step from a RNA factor
-
- // start point of array
- _p0[0] = p0[0];
- _p0[1] = p0[1];
- _p0[2] = p0[2];
_iterations = 100;
_tempAmb = 0;
@@ -72,7 +67,10 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) :
*/
// scale the constants according to the refinement of the grid
- _dx = 1.0f / (float)_maxRes;
+ if (!dx)
+ _dx = 1.0f / (float)_maxRes;
+ else
+ _dx = dx;
_constantScaling = 64.0f / _maxRes;
_constantScaling = (_constantScaling < 1.0f) ? 1.0f : _constantScaling;
_vorticityEps = 2.0f / _constantScaling; // Just in case set a default value
@@ -94,8 +92,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) :
_zForce = new float[_totalCells];
_density = new float[_totalCells];
_densityOld = new float[_totalCells];
- _heat = new float[_totalCells];
- _heatOld = new float[_totalCells];
_obstacles = new unsigned char[_totalCells]; // set 0 at end of step
// For threaded version:
@@ -103,7 +99,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) :
_yVelocityTemp = new float[_totalCells];
_zVelocityTemp = new float[_totalCells];
_densityTemp = new float[_totalCells];
- _heatTemp = new float[_totalCells];
// DG TODO: check if alloc went fine
@@ -111,8 +106,6 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) :
{
_density[x] = 0.0f;
_densityOld[x] = 0.0f;
- _heat[x] = 0.0f;
- _heatOld[x] = 0.0f;
_xVelocity[x] = 0.0f;
_yVelocity[x] = 0.0f;
_zVelocity[x] = 0.0f;
@@ -128,6 +121,25 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) :
_obstacles[x] = false;
}
+ /* heat */
+ _heat = _heatOld = _heatTemp = NULL;
+ if (init_heat) {
+ initHeat();
+ }
+ // Fire simulation
+ _flame = _fuel = _fuelTemp = _fuelOld = NULL;
+ _react = _reactTemp = _reactOld = NULL;
+ if (init_fire) {
+ initFire();
+ }
+ // Smoke color
+ _color_r = _color_rOld = _color_rTemp = NULL;
+ _color_g = _color_gOld = _color_gTemp = NULL;
+ _color_b = _color_bOld = _color_bTemp = NULL;
+ if (init_colors) {
+ initColors(0.0f, 0.0f, 0.0f);
+ }
+
// boundary conditions of the fluid domain
// set default values -> vertically non-colliding
_domainBcFront = true;
@@ -138,9 +150,70 @@ FLUID_3D::FLUID_3D(int *res, float *p0, float dtdef) :
_domainBcRight = _domainBcLeft;
_colloPrev = 1; // default value
+}
- setBorderObstacles(); // walls
+void FLUID_3D::initHeat()
+{
+ if (!_heat) {
+ _heat = new float[_totalCells];
+ _heatOld = new float[_totalCells];
+ _heatTemp = new float[_totalCells];
+ for (int x = 0; x < _totalCells; x++)
+ {
+ _heat[x] = 0.0f;
+ _heatOld[x] = 0.0f;
+ }
+ }
+}
+
+void FLUID_3D::initFire()
+{
+ if (!_flame) {
+ _flame = new float[_totalCells];
+ _fuel = new float[_totalCells];
+ _fuelTemp = new float[_totalCells];
+ _fuelOld = new float[_totalCells];
+ _react = new float[_totalCells];
+ _reactTemp = new float[_totalCells];
+ _reactOld = new float[_totalCells];
+
+ for (int x = 0; x < _totalCells; x++)
+ {
+ _flame[x] = 0.0f;
+ _fuel[x] = 0.0f;
+ _fuelTemp[x] = 0.0f;
+ _fuelOld[x] = 0.0f;
+ _react[x] = 0.0f;
+ _reactTemp[x] = 0.0f;
+ _reactOld[x] = 0.0f;
+ }
+ }
+}
+
+void FLUID_3D::initColors(float init_r, float init_g, float init_b)
+{
+ if (!_color_r) {
+ _color_r = new float[_totalCells];
+ _color_rOld = new float[_totalCells];
+ _color_rTemp = new float[_totalCells];
+ _color_g = new float[_totalCells];
+ _color_gOld = new float[_totalCells];
+ _color_gTemp = new float[_totalCells];
+ _color_b = new float[_totalCells];
+ _color_bOld = new float[_totalCells];
+ _color_bTemp = new float[_totalCells];
+
+ for (int x = 0; x < _totalCells; x++)
+ {
+ _color_r[x] = _density[x] * init_r;
+ _color_rOld[x] = 0.0f;
+ _color_g[x] = _density[x] * init_g;
+ _color_gOld[x] = 0.0f;
+ _color_b[x] = _density[x] * init_b;
+ _color_bOld[x] = 0.0f;
+ }
+ }
}
void FLUID_3D::setBorderObstacles()
@@ -204,7 +277,6 @@ FLUID_3D::~FLUID_3D()
if (_heat) delete[] _heat;
if (_heatOld) delete[] _heatOld;
if (_obstacles) delete[] _obstacles;
- // if (_wTurbulence) delete _wTurbulence;
if (_xVelocityTemp) delete[] _xVelocityTemp;
if (_yVelocityTemp) delete[] _yVelocityTemp;
@@ -212,23 +284,48 @@ FLUID_3D::~FLUID_3D()
if (_densityTemp) delete[] _densityTemp;
if (_heatTemp) delete[] _heatTemp;
+ if (_flame) delete[] _flame;
+ if (_fuel) delete[] _fuel;
+ if (_fuelTemp) delete[] _fuelTemp;
+ if (_fuelOld) delete[] _fuelOld;
+ if (_react) delete[] _react;
+ if (_reactTemp) delete[] _reactTemp;
+ if (_reactOld) delete[] _reactOld;
+
+ if (_color_r) delete[] _color_r;
+ if (_color_rOld) delete[] _color_rOld;
+ if (_color_rTemp) delete[] _color_rTemp;
+ if (_color_g) delete[] _color_g;
+ if (_color_gOld) delete[] _color_gOld;
+ if (_color_gTemp) delete[] _color_gTemp;
+ if (_color_b) delete[] _color_b;
+ if (_color_bOld) delete[] _color_bOld;
+ if (_color_bTemp) delete[] _color_bTemp;
+
// printf("deleted fluid\n");
}
// init direct access functions from blender
-void FLUID_3D::initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *borderCollision)
+void FLUID_3D::initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *borderCollision, float *burning_rate,
+ float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp)
{
_alpha = alpha;
_beta = beta;
_dtFactor = dt_factor;
_vorticityRNA = vorticity;
_borderColli = borderCollision;
+ _burning_rate = burning_rate;
+ _flame_smoke = flame_smoke;
+ _flame_smoke_color = flame_smoke_color;
+ _flame_vorticity = flame_vorticity;
+ _ignition_temp = flame_ignition_temp;
+ _max_temp = flame_max_temp;
}
//////////////////////////////////////////////////////////////////////
// step simulation once
//////////////////////////////////////////////////////////////////////
-void FLUID_3D::step(float dt)
+void FLUID_3D::step(float dt, float gravity[3])
{
#if 0
// If border rules have been changed
@@ -281,7 +378,7 @@ void FLUID_3D::step(float dt)
wipeBoundariesSL(zBegin, zEnd);
addVorticity(zBegin, zEnd);
- addBuoyancy(_heat, _density, zBegin, zEnd);
+ addBuoyancy(_heat, _density, gravity, zBegin, zEnd);
addForce(zBegin, zEnd);
#if PARALLEL==1
@@ -312,13 +409,15 @@ void FLUID_3D::step(float dt)
if (i==0)
{
#endif
- project();
+ project();
#if PARALLEL==1
}
- else
+ else if (i==1)
{
#endif
- diffuseHeat();
+ if (_heat) {
+ diffuseHeat();
+ }
#if PARALLEL==1
}
}
@@ -338,6 +437,13 @@ void FLUID_3D::step(float dt)
SWAP_POINTERS(_density, _densityOld);
SWAP_POINTERS(_heat, _heatOld);
+ SWAP_POINTERS(_fuel, _fuelOld);
+ SWAP_POINTERS(_react, _reactOld);
+
+ SWAP_POINTERS(_color_r, _color_rOld);
+ SWAP_POINTERS(_color_g, _color_gOld);
+ SWAP_POINTERS(_color_b, _color_bOld);
+
advectMacCormackBegin(0, _zRes);
#if PARALLEL==1
@@ -398,11 +504,8 @@ void FLUID_3D::step(float dt)
SWAP_POINTERS(_yVelocity, _yForce);
SWAP_POINTERS(_zVelocity, _zForce);
-
-
-
_totalTime += _dt;
- _totalSteps++;
+ _totalSteps++;
for (int i = 0; i < _totalCells; i++)
{
@@ -643,6 +746,15 @@ void FLUID_3D::wipeBoundaries(int zBegin, int zEnd)
setZeroBorder(_yVelocity, _res, zBegin, zEnd);
setZeroBorder(_zVelocity, _res, zBegin, zEnd);
setZeroBorder(_density, _res, zBegin, zEnd);
+ if (_fuel) {
+ setZeroBorder(_fuel, _res, zBegin, zEnd);
+ setZeroBorder(_react, _res, zBegin, zEnd);
+ }
+ if (_color_r) {
+ setZeroBorder(_color_r, _res, zBegin, zEnd);
+ setZeroBorder(_color_g, _res, zBegin, zEnd);
+ setZeroBorder(_color_b, _res, zBegin, zEnd);
+ }
}
void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd)
@@ -668,6 +780,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd)
_yVelocity[index] = 0.0f;
_zVelocity[index] = 0.0f;
_density[index] = 0.0f;
+ if (_fuel) {
+ _fuel[index] = 0.0f;
+ _react[index] = 0.0f;
+ }
+ if (_color_r) {
+ _color_r[index] = 0.0f;
+ _color_g[index] = 0.0f;
+ _color_b[index] = 0.0f;
+ }
// right slab
index += _xRes - 1;
@@ -675,6 +796,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd)
_yVelocity[index] = 0.0f;
_zVelocity[index] = 0.0f;
_density[index] = 0.0f;
+ if (_fuel) {
+ _fuel[index] = 0.0f;
+ _react[index] = 0.0f;
+ }
+ if (_color_r) {
+ _color_r[index] = 0.0f;
+ _color_g[index] = 0.0f;
+ _color_b[index] = 0.0f;
+ }
}
/////////////////////////////////////
@@ -690,6 +820,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd)
_yVelocity[index] = 0.0f;
_zVelocity[index] = 0.0f;
_density[index] = 0.0f;
+ if (_fuel) {
+ _fuel[index] = 0.0f;
+ _react[index] = 0.0f;
+ }
+ if (_color_r) {
+ _color_r[index] = 0.0f;
+ _color_g[index] = 0.0f;
+ _color_b[index] = 0.0f;
+ }
// top slab
index += slabSize - _xRes;
@@ -697,6 +836,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd)
_yVelocity[index] = 0.0f;
_zVelocity[index] = 0.0f;
_density[index] = 0.0f;
+ if (_fuel) {
+ _fuel[index] = 0.0f;
+ _react[index] = 0.0f;
+ }
+ if (_color_r) {
+ _color_r[index] = 0.0f;
+ _color_g[index] = 0.0f;
+ _color_b[index] = 0.0f;
+ }
}
@@ -717,6 +865,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd)
_yVelocity[index] = 0.0f;
_zVelocity[index] = 0.0f;
_density[index] = 0.0f;
+ if (_fuel) {
+ _fuel[index] = 0.0f;
+ _react[index] = 0.0f;
+ }
+ if (_color_r) {
+ _color_r[index] = 0.0f;
+ _color_g[index] = 0.0f;
+ _color_b[index] = 0.0f;
+ }
}
if (zEnd == _zRes)
@@ -735,6 +892,15 @@ void FLUID_3D::wipeBoundariesSL(int zBegin, int zEnd)
_yVelocity[indexx] = 0.0f;
_zVelocity[indexx] = 0.0f;
_density[indexx] = 0.0f;
+ if (_fuel) {
+ _fuel[index] = 0.0f;
+ _react[index] = 0.0f;
+ }
+ if (_color_r) {
+ _color_r[index] = 0.0f;
+ _color_g[index] = 0.0f;
+ _color_b[index] = 0.0f;
+ }
}
}
@@ -781,35 +947,6 @@ void FLUID_3D::project()
if(!_domainBcTop) setNeumannZ(_zVelocity, _res, 0, _zRes);
else setZeroZ(_zVelocity, _res, 0, _zRes);
- /*
- {
- float maxx = 0, maxy = 0, maxz = 0;
- for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++)
- {
- if(_xVelocity[i] > maxx)
- maxx = _xVelocity[i];
- if(_yVelocity[i] > maxy)
- maxy = _yVelocity[i];
- if(_zVelocity[i] > maxz)
- maxz = _zVelocity[i];
- }
- printf("Max velx: %f, vely: %f, velz: %f\n", maxx, maxy, maxz);
- }
- */
-
- /*
- {
- float maxvalue = 0;
- for(unsigned int i = 0; i < _xRes * _yRes * _zRes; i++)
- {
- if(_heat[i] > maxvalue)
- maxvalue = _heat[i];
-
- }
- printf("Max heat: %f\n", maxvalue);
- }
- */
-
// calculate divergence
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
@@ -910,21 +1047,52 @@ void FLUID_3D::project()
setObstaclePressure(_pressure, 0, _zRes);
// project out solution
+ // New idea for code from NVIDIA graphic gems 3 - DG
float invDx = 1.0f / _dx;
index = _slabSize + _xRes + 1;
for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
for (y = 1; y < _yRes - 1; y++, index += 2)
for (x = 1; x < _xRes - 1; x++, index++)
{
+ float vMask[3] = {1.0f, 1.0f, 1.0f}, vObst[3] = {0, 0, 0};
+ float vR = 0.0f, vL = 0.0f, vT = 0.0f, vB = 0.0f, vD = 0.0f, vU = 0.0f;
+
+ float pC = _pressure[index]; // center
+ float pR = _pressure[index + 1]; // right
+ float pL = _pressure[index - 1]; // left
+ float pU = _pressure[index + _xRes]; // Up
+ float pD = _pressure[index - _xRes]; // Down
+ float pT = _pressure[index + _slabSize]; // top
+ float pB = _pressure[index - _slabSize]; // bottom
+
if(!_obstacles[index])
{
- _xVelocity[index] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx;
- _yVelocity[index] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx;
- _zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx;
+ // DG TODO: What if obstacle is left + right and one of them is moving?
+ if(_obstacles[index+1]) { pR = pC; vObst[0] = _xVelocityOb[index + 1]; vMask[0] = 0; }
+ if(_obstacles[index-1]) { pL = pC; vObst[0] = _xVelocityOb[index - 1]; vMask[0] = 0; }
+ if(_obstacles[index+_xRes]) { pU = pC; vObst[1] = _yVelocityOb[index + _xRes]; vMask[1] = 0; }
+ if(_obstacles[index-_xRes]) { pD = pC; vObst[1] = _yVelocityOb[index - _xRes]; vMask[1] = 0; }
+ if(_obstacles[index+_slabSize]) { pT = pC; vObst[2] = _zVelocityOb[index + _slabSize]; vMask[2] = 0; }
+ if(_obstacles[index-_slabSize]) { pB = pC; vObst[2] = _zVelocityOb[index - _slabSize]; vMask[2] = 0; }
+
+ _xVelocity[index] -= 0.5f * (pR - pL) * invDx;
+ _yVelocity[index] -= 0.5f * (pU - pD) * invDx;
+ _zVelocity[index] -= 0.5f * (pT - pB) * invDx;
+
+ _xVelocity[index] = (vMask[0] * _xVelocity[index]) + vObst[0];
+ _yVelocity[index] = (vMask[1] * _yVelocity[index]) + vObst[1];
+ _zVelocity[index] = (vMask[2] * _zVelocity[index]) + vObst[2];
+ }
+ else
+ {
+ _xVelocity[index] = _xVelocityOb[index];
+ _yVelocity[index] = _yVelocityOb[index];
+ _zVelocity[index] = _zVelocityOb[index];
}
}
- setObstacleVelocity(0, _zRes);
+ // DG: was enabled in original code but now we do this later
+ // setObstacleVelocity(0, _zRes);
if (_pressure) delete[] _pressure;
if (_divergence) delete[] _divergence;
@@ -1007,7 +1175,6 @@ void FLUID_3D::diffuseHeat()
for (int x = 0; x < _totalCells; x++)
if (_obstacles[x])
_heat[x] = 0.0f;
-
}
//////////////////////////////////////////////////////////////////////
@@ -1175,7 +1342,7 @@ void FLUID_3D::setObstacleBoundaries(float *_pressure, int zBegin, int zEnd)
//////////////////////////////////////////////////////////////////////
// add buoyancy forces
//////////////////////////////////////////////////////////////////////
-void FLUID_3D::addBuoyancy(float *heat, float *density, int zBegin, int zEnd)
+void FLUID_3D::addBuoyancy(float *heat, float *density, float gravity[3], int zBegin, int zEnd)
{
int index = zBegin*_slabSize;
@@ -1183,17 +1350,26 @@ void FLUID_3D::addBuoyancy(float *heat, float *density, int zBegin, int zEnd)
for (int y = 0; y < _yRes; y++)
for (int x = 0; x < _xRes; x++, index++)
{
- _zForce[index] += *_alpha * density[index] + (*_beta * (heat[index] - _tempAmb)); // DG: was _yForce, changed for Blender
+ float buoyancy = *_alpha * density[index] + (*_beta * (((heat) ? heat[index] : 0.0f) - _tempAmb));
+ _xForce[index] -= gravity[0] * buoyancy;
+ _yForce[index] -= gravity[1] * buoyancy;
+ _zForce[index] -= gravity[2] * buoyancy;
}
}
+
//////////////////////////////////////////////////////////////////////
// add vorticity to the force field
//////////////////////////////////////////////////////////////////////
+#define VORT_VEL(i, j) \
+ ((_obstacles[obpos[(i)]] & 8) ? ((abs(objvelocity[(j)][obpos[(i)]]) > FLT_EPSILON) ? objvelocity[(j)][obpos[(i)]] : velocity[(j)][index]) : velocity[(j)][obpos[(i)]])
+
void FLUID_3D::addVorticity(int zBegin, int zEnd)
{
+ // set flame vorticity from RNA value
+ float flame_vorticity = (*_flame_vorticity)/_constantScaling;
//int x,y,z,index;
- if(_vorticityEps<=0.) return;
+ if(_vorticityEps+flame_vorticity<=0.) return;
int _blockSize=zEnd-zBegin;
int _blockTotalCells = _slabSize * (_blockSize+2);
@@ -1225,9 +1401,18 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd)
float gridSize = 0.5f / _dx;
//index = _slabSize + _xRes + 1;
+ float *velocity[3];
+ float *objvelocity[3];
- size_t vIndex=_xRes + 1;
+ velocity[0] = _xVelocity;
+ velocity[1] = _yVelocity;
+ velocity[2] = _zVelocity;
+
+ objvelocity[0] = _xVelocityOb;
+ objvelocity[1] = _yVelocityOb;
+ objvelocity[2] = _zVelocityOb;
+ size_t vIndex=_xRes + 1;
for (int z = zBegin + bb1; z < (zEnd - bt1); z++)
{
size_t index = index_ +(z-1)*_slabSize;
@@ -1237,25 +1422,47 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd)
{
for (int x = 1; x < _xRes - 1; x++, index++)
{
+ if (!_obstacles[index])
+ {
+ int obpos[6];
+
+ obpos[0] = (_obstacles[index + _xRes] == 1) ? index : index + _xRes; // up
+ obpos[1] = (_obstacles[index - _xRes] == 1) ? index : index - _xRes; // down
+ float dy = (obpos[0] == index || obpos[1] == index) ? 1.0f / _dx : gridSize;
+
+ obpos[2] = (_obstacles[index + _slabSize] == 1) ? index : index + _slabSize; // out
+ obpos[3] = (_obstacles[index - _slabSize] == 1) ? index : index - _slabSize; // in
+ float dz = (obpos[2] == index || obpos[3] == index) ? 1.0f / _dx : gridSize;
+
+ obpos[4] = (_obstacles[index + 1] == 1) ? index : index + 1; // right
+ obpos[5] = (_obstacles[index - 1] == 1) ? index : index - 1; // left
+ float dx = (obpos[4] == index || obpos[5] == index) ? 1.0f / _dx : gridSize;
+
+ float xV[2], yV[2], zV[2];
+
+ zV[1] = VORT_VEL(0, 2);
+ zV[0] = VORT_VEL(1, 2);
+ yV[1] = VORT_VEL(2, 1);
+ yV[0] = VORT_VEL(3, 1);
+ _xVorticity[vIndex] = (zV[1] - zV[0]) * dy + (-yV[1] + yV[0]) * dz;
+
+ xV[1] = VORT_VEL(2, 0);
+ xV[0] = VORT_VEL(3, 0);
+ zV[1] = VORT_VEL(4, 2);
+ zV[0] = VORT_VEL(5, 2);
+ _yVorticity[vIndex] = (xV[1] - xV[0]) * dz + (-zV[1] + zV[0]) * dx;
+
+ yV[1] = VORT_VEL(4, 1);
+ yV[0] = VORT_VEL(5, 1);
+ xV[1] = VORT_VEL(0, 0);
+ xV[0] = VORT_VEL(1, 0);
+ _zVorticity[vIndex] = (yV[1] - yV[0]) * dx + (-xV[1] + xV[0])* dy;
- int up = _obstacles[index + _xRes] ? index : index + _xRes;
- int down = _obstacles[index - _xRes] ? index : index - _xRes;
- float dy = (up == index || down == index) ? 1.0f / _dx : gridSize;
- int out = _obstacles[index + _slabSize] ? index : index + _slabSize;
- int in = _obstacles[index - _slabSize] ? index : index - _slabSize;
- float dz = (out == index || in == index) ? 1.0f / _dx : gridSize;
- int right = _obstacles[index + 1] ? index : index + 1;
- int left = _obstacles[index - 1] ? index : index - 1;
- float dx = (right == index || left == index) ? 1.0f / _dx : gridSize;
-
- _xVorticity[vIndex] = (_zVelocity[up] - _zVelocity[down]) * dy + (-_yVelocity[out] + _yVelocity[in]) * dz;
- _yVorticity[vIndex] = (_xVelocity[out] - _xVelocity[in]) * dz + (-_zVelocity[right] + _zVelocity[left]) * dx;
- _zVorticity[vIndex] = (_yVelocity[right] - _yVelocity[left]) * dx + (-_xVelocity[up] + _xVelocity[down])* dy;
-
- _vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] +
+ _vorticity[vIndex] = sqrtf(_xVorticity[vIndex] * _xVorticity[vIndex] +
_yVorticity[vIndex] * _yVorticity[vIndex] +
_zVorticity[vIndex] * _zVorticity[vIndex]);
+ }
vIndex++;
}
vIndex+=2;
@@ -1284,15 +1491,18 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd)
{
float N[3];
- int up = _obstacles[index + _xRes] ? vIndex : vIndex + _xRes;
- int down = _obstacles[index - _xRes] ? vIndex : vIndex - _xRes;
+ int up = (_obstacles[index + _xRes] == 1) ? vIndex : vIndex + _xRes;
+ int down = (_obstacles[index - _xRes] == 1) ? vIndex : vIndex - _xRes;
float dy = (up == vIndex || down == vIndex) ? 1.0f / _dx : gridSize;
- int out = _obstacles[index + _slabSize] ? vIndex : vIndex + _slabSize;
- int in = _obstacles[index - _slabSize] ? vIndex : vIndex - _slabSize;
+
+ int out = (_obstacles[index + _slabSize] == 1) ? vIndex : vIndex + _slabSize;
+ int in = (_obstacles[index - _slabSize] == 1) ? vIndex : vIndex - _slabSize;
float dz = (out == vIndex || in == vIndex) ? 1.0f / _dx : gridSize;
- int right = _obstacles[index + 1] ? vIndex : vIndex + 1;
- int left = _obstacles[index - 1] ? vIndex : vIndex - 1;
+
+ int right = (_obstacles[index + 1] == 1) ? vIndex : vIndex + 1;
+ int left = (_obstacles[index - 1] == 1) ? vIndex : vIndex - 1;
float dx = (right == vIndex || left == vIndex) ? 1.0f / _dx : gridSize;
+
N[0] = (_vorticity[right] - _vorticity[left]) * dx;
N[1] = (_vorticity[up] - _vorticity[down]) * dy;
N[2] = (_vorticity[out] - _vorticity[in]) * dz;
@@ -1300,14 +1510,15 @@ void FLUID_3D::addVorticity(int zBegin, int zEnd)
float magnitude = sqrtf(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]);
if (magnitude > FLT_EPSILON)
{
+ float flame_vort = (_fuel) ? _fuel[index]*flame_vorticity : 0.0f;
magnitude = 1.0f / magnitude;
N[0] *= magnitude;
N[1] *= magnitude;
N[2] *= magnitude;
- _xForce[index] += (N[1] * _zVorticity[vIndex] - N[2] * _yVorticity[vIndex]) * _dx * eps;
- _yForce[index] += (N[2] * _xVorticity[vIndex] - N[0] * _zVorticity[vIndex]) * _dx * eps;
- _zForce[index] += (N[0] * _yVorticity[vIndex] - N[1] * _xVorticity[vIndex]) * _dx * eps;
+ _xForce[index] += (N[1] * _zVorticity[vIndex] - N[2] * _yVorticity[vIndex]) * _dx * (eps + flame_vort);
+ _yForce[index] += (N[2] * _xVorticity[vIndex] - N[0] * _zVorticity[vIndex]) * _dx * (eps + flame_vort);
+ _zForce[index] += (N[0] * _yVorticity[vIndex] - N[1] * _xVorticity[vIndex]) * _dx * (eps + flame_vort);
}
} // if
vIndex++;
@@ -1328,14 +1539,9 @@ void FLUID_3D::advectMacCormackBegin(int zBegin, int zEnd)
{
Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);
- if(!_domainBcLeft) copyBorderX(_xVelocityOld, res, zBegin, zEnd);
- else setZeroX(_xVelocityOld, res, zBegin, zEnd);
-
- if(!_domainBcFront) copyBorderY(_yVelocityOld, res, zBegin, zEnd);
- else setZeroY(_yVelocityOld, res, zBegin, zEnd);
-
- if(!_domainBcTop) copyBorderZ(_zVelocityOld, res, zBegin, zEnd);
- else setZeroZ(_zVelocityOld, res, zBegin, zEnd);
+ setZeroX(_xVelocityOld, res, zBegin, zEnd);
+ setZeroY(_yVelocityOld, res, zBegin, zEnd);
+ setZeroZ(_zVelocityOld, res, zBegin, zEnd);
}
//////////////////////////////////////////////////////////////////////
@@ -1355,7 +1561,18 @@ void FLUID_3D::advectMacCormackEnd1(int zBegin, int zEnd)
// advectFieldMacCormack1(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res)
advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _densityTemp, res, zBegin, zEnd);
- advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heatTemp, res, zBegin, zEnd);
+ if (_heat) {
+ advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heatTemp, res, zBegin, zEnd);
+ }
+ if (_fuel) {
+ advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuelTemp, res, zBegin, zEnd);
+ advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _reactTemp, res, zBegin, zEnd);
+ }
+ if (_color_r) {
+ advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_rTemp, res, zBegin, zEnd);
+ advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_gOld, _color_gTemp, res, zBegin, zEnd);
+ advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_bOld, _color_bTemp, res, zBegin, zEnd);
+ }
advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, res, zBegin, zEnd);
advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, res, zBegin, zEnd);
advectFieldMacCormack1(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, res, zBegin, zEnd);
@@ -1371,17 +1588,30 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd)
const float dt0 = _dt / _dx;
Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);
- // use force array as temp arrays
+ // use force array as temp array
float* t1 = _xForce;
// advectFieldMacCormack2(dt, xVelocity, yVelocity, zVelocity, oldField, newField, tempfield, temp, res, obstacles)
+ /* finish advection */
advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, _densityTemp, t1, res, _obstacles, zBegin, zEnd);
- advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, _heatTemp, t1, res, _obstacles, zBegin, zEnd);
+ if (_heat) {
+ advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, _heatTemp, t1, res, _obstacles, zBegin, zEnd);
+ }
+ if (_fuel) {
+ advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _fuelOld, _fuel, _fuelTemp, t1, res, _obstacles, zBegin, zEnd);
+ advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _reactOld, _react, _reactTemp, t1, res, _obstacles, zBegin, zEnd);
+ }
+ if (_color_r) {
+ advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_rOld, _color_r, _color_rTemp, t1, res, _obstacles, zBegin, zEnd);
+ advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_gOld, _color_g, _color_gTemp, t1, res, _obstacles, zBegin, zEnd);
+ advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _color_bOld, _color_b, _color_bTemp, t1, res, _obstacles, zBegin, zEnd);
+ }
advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocityTemp, _xVelocity, t1, res, _obstacles, zBegin, zEnd);
advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocityTemp, _yVelocity, t1, res, _obstacles, zBegin, zEnd);
advectFieldMacCormack2(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocityTemp, _zVelocity, t1, res, _obstacles, zBegin, zEnd);
+ /* set boundary conditions for velocity */
if(!_domainBcLeft) copyBorderX(_xVelocityTemp, res, zBegin, zEnd);
else setZeroX(_xVelocityTemp, res, zBegin, zEnd);
@@ -1391,40 +1621,71 @@ void FLUID_3D::advectMacCormackEnd2(int zBegin, int zEnd)
if(!_domainBcTop) copyBorderZ(_zVelocityTemp, res, zBegin, zEnd);
else setZeroZ(_zVelocityTemp, res, zBegin, zEnd);
+ /* clear data boundaries */
setZeroBorder(_density, res, zBegin, zEnd);
- setZeroBorder(_heat, res, zBegin, zEnd);
-#if 0
- {
- const size_t index_ = _slabSize + _xRes + 1;
- int bb=0;
- int bt=0;
+ if (_fuel) {
+ setZeroBorder(_fuel, res, zBegin, zEnd);
+ setZeroBorder(_react, res, zBegin, zEnd);
+ }
+ if (_color_r) {
+ setZeroBorder(_color_r, res, zBegin, zEnd);
+ setZeroBorder(_color_g, res, zBegin, zEnd);
+ setZeroBorder(_color_b, res, zBegin, zEnd);
+ }
+}
- if (zBegin == 0) {bb = 1;}
- if (zEnd == _zRes) {bt = 1;}
-
- for (int z = zBegin + bb; z < zEnd - bt; z++)
+
+void FLUID_3D::processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat,
+ float *r, float *g, float *b, int total_cells, float dt)
+{
+ float burning_rate = *_burning_rate;
+ float flame_smoke = *_flame_smoke;
+ float ignition_point = *_ignition_temp;
+ float temp_max = *_max_temp;
+
+ for (int index = 0; index < total_cells; index++)
{
- size_t index = index_ +(z-1)*_slabSize;
+ float orig_fuel = fuel[index];
+ float orig_smoke = smoke[index];
+ float smoke_emit = 0.0f;
+ float react_coord = 0.0f;
+
+ /* process fuel */
+ fuel[index] -= burning_rate * dt;
+ if (fuel[index] < 0.0f) fuel[index] = 0.0f;
+ /* process reaction coordinate */
+ if (orig_fuel) {
+ react[index] *= fuel[index]/orig_fuel;
+ react_coord = react[index];
+ }
+ else {
+ react[index] = 0.0f;
+ }
- for (int y = 1; y < _yRes - 1; y++, index += 2)
- {
- for (int x = 1; x < _xRes - 1; x++, index++)
- {
- // clean custom velocities from moving obstacles again
- if (_obstacles[index])
- {
- _xVelocity[index] =
- _yVelocity[index] =
- _zVelocity[index] = 0.0f;
- }
- }
+ /* emit smoke based on fuel burn rate and "flame_smoke" factor */
+ smoke_emit = (orig_fuel < 1.0f) ? (1.0f - orig_fuel)*0.5f : 0.0f;
+ smoke_emit = (smoke_emit + 0.5f) * (orig_fuel-fuel[index]) * 0.1f * flame_smoke;
+ smoke[index] += smoke_emit;
+ CLAMP(smoke[index], 0.0f, 1.0f);
+
+ /* model flame temperature curve from the reaction coordinate (fuel) */
+ if (react_coord>0.0f) {
+ /* do a smooth falloff for rest of the values */
+ flame[index] = pow(react_coord, 0.5f);
+ }
+ else
+ flame[index] = 0.0f;
+
+ /* set fluid temperature from the flame temperature profile */
+ if (heat && flame[index])
+ heat[index] = (1.0f-flame[index])*ignition_point + flame[index]*temp_max;
+
+ /* mix new color */
+ if (r && smoke_emit) {
+ float smoke_factor = smoke[index]/(orig_smoke+smoke_emit);
+ r[index] = (r[index] + _flame_smoke_color[0] * smoke_emit) * smoke_factor;
+ g[index] = (g[index] + _flame_smoke_color[1] * smoke_emit) * smoke_factor;
+ b[index] = (b[index] + _flame_smoke_color[2] * smoke_emit) * smoke_factor;
}
}
- }
-#endif
-
- /*int begin=zBegin * _slabSize;
- int end=begin + (zEnd - zBegin) * _slabSize;
- for (int x = begin; x < end; x++)
- _xForce[x] = _yForce[x] = 0.0f;*/
}
diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h
index ac77148ce84..8cadf3bc989 100644
--- a/intern/smoke/intern/FLUID_3D.h
+++ b/intern/smoke/intern/FLUID_3D.h
@@ -46,11 +46,16 @@ class WTURBULENCE;
class FLUID_3D
{
public:
- FLUID_3D(int *res, /* int amplify, */ float *p0, float dtdef);
+ FLUID_3D(int *res, float dx, float dtdef, int init_heat, int init_fire, int init_colors);
FLUID_3D() {};
virtual ~FLUID_3D();
- void initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli);
+ void initHeat();
+ void initFire();
+ void initColors(float init_r, float init_g, float init_b);
+
+ void initBlenderRNA(float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate,
+ float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *ignition_temp, float *max_temp);
// create & allocate vector noise advection
void initVectorNoise(int amplify);
@@ -58,7 +63,7 @@ class FLUID_3D
void addSmokeColumn();
static void addSmokeTestCase(float* field, Vec3Int res);
- void step(float dt);
+ void step(float dt, float gravity[3]);
void addObstacle(OBSTACLE* obstacle);
const float* xVelocity() { return _xVelocity; };
@@ -115,6 +120,27 @@ class FLUID_3D
float* _heatTemp;
float* _densityTemp;
+ // fire simulation
+ float *_flame;
+ float *_fuel;
+ float *_fuelTemp;
+ float *_fuelOld;
+ float *_react;
+ float *_reactTemp;
+ float *_reactOld;
+
+ // smoke color
+ float *_color_r;
+ float *_color_rOld;
+ float *_color_rTemp;
+ float *_color_g;
+ float *_color_gOld;
+ float *_color_gTemp;
+ float *_color_b;
+ float *_color_bOld;
+ float *_color_bTemp;
+
+
// CG fields
int _iterations;
@@ -153,14 +179,16 @@ class FLUID_3D
void wipeBoundariesSL(int zBegin, int zEnd);
void addForce(int zBegin, int zEnd);
void addVorticity(int zBegin, int zEnd);
- void addBuoyancy(float *heat, float *density, int zBegin, int zEnd);
+ void addBuoyancy(float *heat, float *density, float gravity[3], int zBegin, int zEnd);
// solver stuff
void project();
void diffuseHeat();
+ void diffuseColor();
void solvePressure(float* field, float* b, unsigned char* skip);
void solvePressurePre(float* field, float* b, unsigned char* skip);
void solveHeat(float* field, float* b, unsigned char* skip);
+ void solveDiffusion(float* field, float* b, float* factor);
// handle obstacle boundaries
@@ -174,6 +202,16 @@ class FLUID_3D
void advectMacCormackEnd1(int zBegin, int zEnd);
void advectMacCormackEnd2(int zBegin, int zEnd);
+ /* burning */
+ float *_burning_rate; // RNA pointer
+ float *_flame_smoke; // RNA pointer
+ float *_flame_smoke_color; // RNA pointer
+ float *_flame_vorticity; // RNA pointer
+ float *_ignition_temp; // RNA pointer
+ float *_max_temp; // RNA pointer
+ void processBurn(float *fuel, float *smoke, float *react, float *flame, float *heat,
+ float *r, float *g, float *b, int total_cells, float dt);
+
// boundary setting functions
static void copyBorderX(float* field, Vec3Int res, int zBegin, int zEnd);
static void copyBorderY(float* field, Vec3Int res, int zBegin, int zEnd);
diff --git a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp
index 3cf94eb00a9..42a8b2d6923 100644
--- a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp
+++ b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp
@@ -165,7 +165,6 @@ void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip)
if (_Acenter) delete[] _Acenter;
}
-
void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
{
int x, y, z;
diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp
index c7a0ddcd04c..ac485ad983a 100644
--- a/intern/smoke/intern/FLUID_3D_STATIC.cpp
+++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp
@@ -92,18 +92,10 @@ void FLUID_3D::setNeumannX(float* field, Vec3Int res, int zBegin, int zEnd)
// left slab
index = y * res[0] + z * slabSize;
field[index] = field[index + 2];
- /* only allow outwards flux */
- if(field[index]>0.) field[index] = 0.;
- index += 1;
- if(field[index]>0.) field[index] = 0.;
// right slab
index = y * res[0] + z * slabSize + res[0] - 1;
field[index] = field[index - 2];
- /* only allow outwards flux */
- if(field[index]<0.) field[index] = 0.;
- index -= 1;
- if(field[index]<0.) field[index] = 0.;
}
}
@@ -120,18 +112,10 @@ void FLUID_3D::setNeumannY(float* field, Vec3Int res, int zBegin, int zEnd)
// front slab
index = x + z * slabSize;
field[index] = field[index + 2 * res[0]];
- /* only allow outwards flux */
- if(field[index]>0.) field[index] = 0.;
- index += res[0];
- if(field[index]>0.) field[index] = 0.;
// back slab
index = x + z * slabSize + slabSize - res[0];
field[index] = field[index - 2 * res[0]];
- /* only allow outwards flux */
- if(field[index]<0.) field[index] = 0.;
- index -= res[0];
- if(field[index]<0.) field[index] = 0.;
}
}
@@ -152,14 +136,6 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd)
// front slab
index = x + y * res[0];
field[index] = field[index + 2 * slabSize];
- /* only allow outwards flux */
-
- // DG: Disable this for z-axis.
- // The problem is that smoke somehow gets sucked in again
- // from the TOP slab when this is enabled
- // if(field[index]>0.) field[index] = 0.;
- // index += slabSize;
- // if(field[index]>0.) field[index] = 0.;
}
}
@@ -170,10 +146,6 @@ void FLUID_3D::setNeumannZ(float* field, Vec3Int res, int zBegin, int zEnd)
// back slab
index = x + y * res[0] + cellsslab;
field[index] = field[index - 2 * slabSize];
- /* only allow outwards flux */
- if(field[index]<0.) field[index] = 0.;
- index -= slabSize;
- if(field[index]<0.) field[index] = 0.;
}
}
diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp
index 671198065e8..1c89f5d681b 100644
--- a/intern/smoke/intern/WTURBULENCE.cpp
+++ b/intern/smoke/intern/WTURBULENCE.cpp
@@ -51,7 +51,7 @@ static const float persistence = 0.56123f;
//////////////////////////////////////////////////////////////////////
// constructor
//////////////////////////////////////////////////////////////////////
-WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype)
+WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, int init_fire, int init_colors)
{
// if noise magnitude is below this threshold, its contribution
// is negilgible, so stop evaluating new octaves
@@ -87,12 +87,26 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no
// allocate high resolution density field
_totalStepsBig = 0;
_densityBig = new float[_totalCellsBig];
- _densityBigOld = new float[_totalCellsBig];
+ _densityBigOld = new float[_totalCellsBig];
for(int i = 0; i < _totalCellsBig; i++) {
_densityBig[i] =
_densityBigOld[i] = 0.;
}
+
+ /* fire */
+ _flameBig = _fuelBig = _fuelBigOld = NULL;
+ _reactBig = _reactBigOld = NULL;
+ if (init_fire) {
+ initFire();
+ }
+ /* colors */
+ _color_rBig = _color_rBigOld = NULL;
+ _color_gBig = _color_gBigOld = NULL;
+ _color_bBig = _color_bBigOld = NULL;
+ if (init_colors) {
+ initColors(0.0f, 0.0f, 0.0f);
+ }
// allocate & init texture coordinates
_tcU = new float[_totalCellsSm];
@@ -128,12 +142,64 @@ WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int no
*/
}
+void WTURBULENCE::initFire()
+{
+ if (!_fuelBig) {
+ _flameBig = new float[_totalCellsBig];
+ _fuelBig = new float[_totalCellsBig];
+ _fuelBigOld = new float[_totalCellsBig];
+ _reactBig = new float[_totalCellsBig];
+ _reactBigOld = new float[_totalCellsBig];
+
+ for(int i = 0; i < _totalCellsBig; i++) {
+ _flameBig[i] =
+ _fuelBig[i] =
+ _fuelBigOld[i] = 0.;
+ _reactBig[i] =
+ _reactBigOld[i] = 0.;
+ }
+ }
+}
+
+void WTURBULENCE::initColors(float init_r, float init_g, float init_b)
+{
+ if (!_color_rBig) {
+ _color_rBig = new float[_totalCellsBig];
+ _color_rBigOld = new float[_totalCellsBig];
+ _color_gBig = new float[_totalCellsBig];
+ _color_gBigOld = new float[_totalCellsBig];
+ _color_bBig = new float[_totalCellsBig];
+ _color_bBigOld = new float[_totalCellsBig];
+
+ for(int i = 0; i < _totalCellsBig; i++) {
+ _color_rBig[i] = _densityBig[i] * init_r;
+ _color_rBigOld[i] = 0.0f;
+ _color_gBig[i] = _densityBig[i] * init_g;
+ _color_gBigOld[i] = 0.0f;
+ _color_bBig[i] = _densityBig[i] * init_b;
+ _color_bBigOld[i] = 0.0f;
+ }
+ }
+}
+
//////////////////////////////////////////////////////////////////////
// destructor
//////////////////////////////////////////////////////////////////////
WTURBULENCE::~WTURBULENCE() {
delete[] _densityBig;
delete[] _densityBigOld;
+ if (_flameBig) delete[] _flameBig;
+ if (_fuelBig) delete[] _fuelBig;
+ if (_fuelBigOld) delete[] _fuelBigOld;
+ if (_reactBig) delete[] _reactBig;
+ if (_reactBigOld) delete[] _reactBigOld;
+
+ if (_color_rBig) delete[] _color_rBig;
+ if (_color_rBigOld) delete[] _color_rBigOld;
+ if (_color_gBig) delete[] _color_gBig;
+ if (_color_gBigOld) delete[] _color_gBigOld;
+ if (_color_bBig) delete[] _color_bBig;
+ if (_color_bBigOld) delete[] _color_bBigOld;
delete[] _tcU;
delete[] _tcV;
@@ -757,8 +823,10 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
// enlarge timestep to match grid
const float dt = dtOrg * _amplify;
const float invAmp = 1.0f / _amplify;
- float *tempBig1 = (float *)calloc(_totalCellsBig, sizeof(float));
- float *tempBig2 = (float *)calloc(_totalCellsBig, sizeof(float));
+ float *tempFuelBig = NULL, *tempReactBig = NULL;
+ float *tempColor_rBig = NULL, *tempColor_gBig = NULL, *tempColor_bBig = NULL;
+ float *tempDensityBig = (float *)calloc(_totalCellsBig, sizeof(float));
+ float *tempBig = (float *)calloc(_totalCellsBig, sizeof(float));
float *bigUx = (float *)calloc(_totalCellsBig, sizeof(float));
float *bigUy = (float *)calloc(_totalCellsBig, sizeof(float));
float *bigUz = (float *)calloc(_totalCellsBig, sizeof(float));
@@ -767,11 +835,21 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
float *eigMin = (float *)calloc(_totalCellsSm, sizeof(float));
float *eigMax = (float *)calloc(_totalCellsSm, sizeof(float));
+ if (_fuelBig) {
+ tempFuelBig = (float *)calloc(_totalCellsBig, sizeof(float));
+ tempReactBig = (float *)calloc(_totalCellsBig, sizeof(float));
+ }
+ if (_color_rBig) {
+ tempColor_rBig = (float *)calloc(_totalCellsBig, sizeof(float));
+ tempColor_gBig = (float *)calloc(_totalCellsBig, sizeof(float));
+ tempColor_bBig = (float *)calloc(_totalCellsBig, sizeof(float));
+ }
+
memset(_tcTemp, 0, sizeof(float)*_totalCellsSm);
// prepare textures
- advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2);
+ advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempDensityBig, tempBig);
// do wavelet decomposition of energy
computeEnergy(_energy, xvel, yvel, zvel, obstacles);
@@ -972,6 +1050,11 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
// prepare density for an advection
SWAP_POINTERS(_densityBig, _densityBigOld);
+ SWAP_POINTERS(_fuelBig, _fuelBigOld);
+ SWAP_POINTERS(_reactBig, _reactBigOld);
+ SWAP_POINTERS(_color_rBig, _color_rBigOld);
+ SWAP_POINTERS(_color_gBig, _color_gBigOld);
+ SWAP_POINTERS(_color_bBig, _color_bBigOld);
// based on the maximum velocity present, see if we need to substep,
// but cap the maximum number of substeps to 5
@@ -1017,7 +1100,21 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
int zEnd = (int)((float)(i+1)*partSize + 0.5f);
#endif
FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz,
- _densityBigOld, tempBig1, _resBig, zBegin, zEnd);
+ _densityBigOld, tempDensityBig, _resBig, zBegin, zEnd);
+ if (_fuelBig) {
+ FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz,
+ _fuelBigOld, tempFuelBig, _resBig, zBegin, zEnd);
+ FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz,
+ _reactBigOld, tempReactBig, _resBig, zBegin, zEnd);
+ }
+ if (_color_rBig) {
+ FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz,
+ _color_rBigOld, tempColor_rBig, _resBig, zBegin, zEnd);
+ FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz,
+ _color_gBigOld, tempColor_gBig, _resBig, zBegin, zEnd);
+ FLUID_3D::advectFieldMacCormack1(dtSubdiv, bigUx, bigUy, bigUz,
+ _color_bBigOld, tempColor_bBig, _resBig, zBegin, zEnd);
+ }
#if PARALLEL==1
}
@@ -1030,18 +1127,43 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
int zEnd = (int)((float)(i+1)*partSize + 0.5f);
#endif
FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz,
- _densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL, zBegin, zEnd);
+ _densityBigOld, _densityBig, tempDensityBig, tempBig, _resBig, NULL, zBegin, zEnd);
+ if (_fuelBig) {
+ FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz,
+ _fuelBigOld, _fuelBig, tempFuelBig, tempBig, _resBig, NULL, zBegin, zEnd);
+ FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz,
+ _reactBigOld, _reactBig, tempReactBig, tempBig, _resBig, NULL, zBegin, zEnd);
+ }
+ if (_color_rBig) {
+ FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz,
+ _color_rBigOld, _color_rBig, tempColor_rBig, tempBig, _resBig, NULL, zBegin, zEnd);
+ FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz,
+ _color_gBigOld, _color_gBig, tempColor_gBig, tempBig, _resBig, NULL, zBegin, zEnd);
+ FLUID_3D::advectFieldMacCormack2(dtSubdiv, bigUx, bigUy, bigUz,
+ _color_bBigOld, _color_bBig, tempColor_bBig, tempBig, _resBig, NULL, zBegin, zEnd);
+ }
#if PARALLEL==1
}
}
#endif
- if (substep < totalSubsteps - 1)
+ if (substep < totalSubsteps - 1) {
SWAP_POINTERS(_densityBig, _densityBigOld);
+ SWAP_POINTERS(_fuelBig, _fuelBigOld);
+ SWAP_POINTERS(_reactBig, _reactBigOld);
+ SWAP_POINTERS(_color_rBig, _color_rBigOld);
+ SWAP_POINTERS(_color_gBig, _color_gBigOld);
+ SWAP_POINTERS(_color_bBig, _color_bBigOld);
+ }
} // substep
- free(tempBig1);
- free(tempBig2);
+ free(tempDensityBig);
+ if (tempFuelBig) free(tempFuelBig);
+ if (tempReactBig) free(tempReactBig);
+ if (tempColor_rBig) free(tempColor_rBig);
+ if (tempColor_gBig) free(tempColor_gBig);
+ if (tempColor_bBig) free(tempColor_bBig);
+ free(tempBig);
free(bigUx);
free(bigUy);
free(bigUz);
@@ -1050,6 +1172,15 @@ void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, floa
// wipe the density borders
FLUID_3D::setZeroBorder(_densityBig, _resBig, 0 , _resBig[2]);
+ if (_fuelBig) {
+ FLUID_3D::setZeroBorder(_fuelBig, _resBig, 0 , _resBig[2]);
+ FLUID_3D::setZeroBorder(_reactBig, _resBig, 0 , _resBig[2]);
+ }
+ if (_color_rBig) {
+ FLUID_3D::setZeroBorder(_color_rBig, _resBig, 0 , _resBig[2]);
+ FLUID_3D::setZeroBorder(_color_gBig, _resBig, 0 , _resBig[2]);
+ FLUID_3D::setZeroBorder(_color_bBig, _resBig, 0 , _resBig[2]);
+ }
// reset texture coordinates now in preparation for next timestep
// Shouldn't do this before generating the noise because then the
diff --git a/intern/smoke/intern/WTURBULENCE.h b/intern/smoke/intern/WTURBULENCE.h
index f31ca100fdf..1655bd95d32 100644
--- a/intern/smoke/intern/WTURBULENCE.h
+++ b/intern/smoke/intern/WTURBULENCE.h
@@ -36,10 +36,13 @@ class WTURBULENCE
{
public:
// both config files can be NULL, altCfg might override values from noiseCfg
- WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype);
+ WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, int init_fire, int init_colors);
/// destructor
virtual ~WTURBULENCE();
+
+ void initFire();
+ void initColors(float init_r, float init_g, float init_b);
void setNoise(int type);
void initBlenderRNA(float *strength);
@@ -63,6 +66,8 @@ class WTURBULENCE
// access functions
inline float* getDensityBig() { return _densityBig; }
+ inline float* getFlameBig() { return _flameBig; }
+ inline float* getFuelBig() { return _fuelBig; }
inline float* getArrayTcU() { return _tcU; }
inline float* getArrayTcV() { return _tcV; }
inline float* getArrayTcW() { return _tcW; }
@@ -111,6 +116,18 @@ class WTURBULENCE
float* _densityBig;
float* _densityBigOld;
+ float* _flameBig;
+ float* _fuelBig;
+ float* _fuelBigOld;
+ float* _reactBig;
+ float* _reactBigOld;
+
+ float* _color_rBig;
+ float* _color_rBigOld;
+ float* _color_gBig;
+ float* _color_gBigOld;
+ float* _color_bBig;
+ float* _color_bBigOld;
// texture coordinates for noise
float* _tcU;
diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp
index 4bbf8e0a82b..6011de0bddb 100644
--- a/intern/smoke/intern/smoke_API.cpp
+++ b/intern/smoke/intern/smoke_API.cpp
@@ -30,6 +30,7 @@
#include "FLUID_3D.h"
#include "WTURBULENCE.h"
+#include "spectrum.h"
#include <stdio.h>
#include <stdlib.h>
@@ -37,22 +38,16 @@
#include "../extern/smoke_API.h" /* to ensure valid prototypes */
-// y in smoke is z in blender
-extern "C" FLUID_3D *smoke_init(int *res, float *p0, float dtdef)
+extern "C" FLUID_3D *smoke_init(int *res, float dx, float dtdef, int use_heat, int use_fire, int use_colors)
{
- // smoke lib uses y as top-bottom/vertical axis where blender uses z
- FLUID_3D *fluid = new FLUID_3D(res, p0, dtdef);
-
- // printf("xres: %d, yres: %d, zres: %d\n", res[0], res[1], res[2]);
-
+ FLUID_3D *fluid = new FLUID_3D(res, dx, dtdef, use_heat, use_fire, use_colors);
return fluid;
}
-extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype)
+extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype, int use_fire, int use_colors)
{
- // initialize wavelet turbulence
- if(amplify)
- return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype);
+ if (amplify)
+ return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype, use_fire, use_colors);
else
return NULL;
}
@@ -71,7 +66,6 @@ extern "C" void smoke_turbulence_free(WTURBULENCE *wt)
extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */)
{
- // // const int index = x + y * smd->res[0] + z * smd->res[0]*smd->res[1];
return x + y * max_x + z * max_x*max_y;
}
@@ -80,137 +74,133 @@ extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z
return x + y * max_x;
}
-extern "C" void smoke_step(FLUID_3D *fluid, float dtSubdiv)
+extern "C" void smoke_step(FLUID_3D *fluid, float gravity[3], float dtSubdiv)
{
- fluid->step(dtSubdiv);
+ if (fluid->_fuel) {
+ fluid->processBurn(fluid->_fuel, fluid->_density, fluid->_react, fluid->_flame, fluid->_heat,
+ fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, (*fluid->_dtFactor)*dtSubdiv);
+ }
+ fluid->step(dtSubdiv, gravity);
}
extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
{
+ if (wt->_fuelBig) {
+ fluid->processBurn(wt->_fuelBig, wt->_densityBig, wt->_reactBig, wt->_flameBig, 0,
+ wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, fluid->_dt);
+ }
wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles);
}
-extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli)
+extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta, float *dt_factor, float *vorticity, int *border_colli, float *burning_rate,
+ float *flame_smoke, float *flame_smoke_color, float *flame_vorticity, float *flame_ignition_temp, float *flame_max_temp)
{
- fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli);
+ fluid->initBlenderRNA(alpha, beta, dt_factor, vorticity, border_colli, burning_rate, flame_smoke, flame_smoke_color, flame_vorticity, flame_ignition_temp, flame_max_temp);
}
-extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
+extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
{
- float *density = fluid->_density;
- //float *densityOld = fluid->_densityOld;
- float *heat = fluid->_heat;
-
- if(log)
- {
- /* max density/speed = dydx */
- float dydx = 1.0 / (float)speed;
- size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
-
- for(size_t i = 0; i < size; i++)
- {
- density[i] *= (1.0 - dydx);
-
- if(density[i] < 0.0f)
- density[i] = 0.0f;
-
- heat[i] *= (1.0 - dydx);
-
- /*if(heat[i] < 0.0f)
- heat[i] = 0.0f;*/
- }
- }
- else // linear falloff
- {
- /* max density/speed = dydx */
- float dydx = 1.0 / (float)speed;
- size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
-
- for(size_t i = 0; i < size; i++)
- {
- density[i] -= dydx;
-
- if(density[i] < 0.0f)
- density[i] = 0.0f;
-
- if(abs(heat[i]) < dydx) heat[i] = 0.0f;
- else if (heat[i]>0.0f) heat[i] -= dydx;
- else if (heat[i]<0.0f) heat[i] += dydx;
-
- }
- }
+ wt->initBlenderRNA(strength);
}
-extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log)
+static void data_dissolve(float *density, float *heat, float *r, float *g, float *b, int total_cells, int speed, int log)
{
- float *density = wt->getDensityBig();
- Vec3Int r = wt->getResBig();
-
- if(log)
- {
+ if (log) {
/* max density/speed = dydx */
- float dydx = 1.0 / (float)speed;
- size_t size= r[0] * r[1] * r[2];
+ float fac = 1.0f - (1.0f / (float)speed);
- for(size_t i = 0; i < size; i++)
+ for(size_t i = 0; i < total_cells; i++)
{
- density[i] *= (1.0 - dydx);
-
- if(density[i] < 0.0f)
- density[i] = 0.0f;
+ /* density */
+ density[i] *= fac;
+
+ /* heat */
+ if (heat) {
+ heat[i] *= fac;
+ }
+
+ /* color */
+ if (r) {
+ r[i] *= fac;
+ g[i] *= fac;
+ b[i] *= fac;
+ }
}
}
else // linear falloff
{
/* max density/speed = dydx */
- float dydx = 1.0 / (float)speed;
- size_t size= r[0] * r[1] * r[2];
+ float dydx = 1.0f / (float)speed;
- for(size_t i = 0; i < size; i++)
+ for(size_t i = 0; i < total_cells; i++)
{
+ float d = density[i];
+ /* density */
density[i] -= dydx;
+ if (density[i] < 0.0f)
+ density[i] = 0.0f;
- if(density[i] < 0.0f)
- density[i] = 0.0f;
+ /* heat */
+ if (heat) {
+ if (abs(heat[i]) < dydx) heat[i] = 0.0f;
+ else if (heat[i] > 0.0f) heat[i] -= dydx;
+ else if (heat[i] < 0.0f) heat[i] += dydx;
+ }
+
+ /* color */
+ if (r && d) {
+ r[i] *= (density[i]/d);
+ g[i] *= (density[i]/d);
+ b[i] *= (density[i]/d);
+ }
+
}
}
}
-extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
+extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
{
- wt->initBlenderRNA(strength);
+ data_dissolve(fluid->_density, fluid->_heat, fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_totalCells, speed, log);
}
-template < class T > inline T ABS( T a )
+extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log)
{
- return (0 < a) ? a : -a ;
+ data_dissolve(wt->_densityBig, 0, wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_totalCellsBig, speed, log);
}
-extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles)
+extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **react, float **flame, float **fuel, float **heat,
+ float **heatold, float **vx, float **vy, float **vz, float **r, float **g, float **b, unsigned char **obstacles)
{
*dens = fluid->_density;
- *densold = fluid->_densityOld;
+ *fuel = fluid->_fuel;
+ *react = fluid->_react;
+ *flame = fluid->_flame;
*heat = fluid->_heat;
*heatold = fluid->_heatOld;
*vx = fluid->_xVelocity;
*vy = fluid->_yVelocity;
*vz = fluid->_zVelocity;
- *vxold = fluid->_xVelocityOld;
- *vyold = fluid->_yVelocityOld;
- *vzold = fluid->_zVelocityOld;
+ *r = fluid->_color_r;
+ *g = fluid->_color_g;
+ *b = fluid->_color_b;
*obstacles = fluid->_obstacles;
*dt = fluid->_dt;
*dx = fluid->_dx;
-
}
-extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw)
+extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **react, float **flame, float **fuel,
+ float **r, float **g, float **b , float **tcu, float **tcv, float **tcw)
{
- if(!wt)
+ if (!wt)
return;
*dens = wt->_densityBig;
- *densold = wt->_densityBigOld;
+ *fuel = wt->_fuelBig;
+ *react = wt->_reactBig;
+ *flame = wt->_flameBig;
+ *r = wt->_color_rBig;
+ *g = wt->_color_gBig;
+ *b = wt->_color_bBig;
*tcu = wt->_tcU;
*tcv = wt->_tcV;
*tcw = wt->_tcW;
@@ -221,6 +211,16 @@ extern "C" float *smoke_get_density(FLUID_3D *fluid)
return fluid->_density;
}
+extern "C" float *smoke_get_fuel(FLUID_3D *fluid)
+{
+ return fluid->_fuel;
+}
+
+extern "C" float *smoke_get_react(FLUID_3D *fluid)
+{
+ return fluid->_react;
+}
+
extern "C" float *smoke_get_heat(FLUID_3D *fluid)
{
return fluid->_heat;
@@ -256,15 +256,137 @@ extern "C" float *smoke_get_force_z(FLUID_3D *fluid)
return fluid->_zForce;
}
+extern "C" float *smoke_get_flame(FLUID_3D *fluid)
+{
+ return fluid->_flame;
+}
+
+extern "C" float *smoke_get_color_r(FLUID_3D *fluid)
+{
+ return fluid->_color_r;
+}
+
+extern "C" float *smoke_get_color_g(FLUID_3D *fluid)
+{
+ return fluid->_color_g;
+}
+
+extern "C" float *smoke_get_color_b(FLUID_3D *fluid)
+{
+ return fluid->_color_b;
+}
+
+static void get_rgba(float *r, float *g, float *b, float *a, int total_cells, float *data, int sequential)
+{
+ int i;
+ int m = 4, i_g = 1, i_b = 2, i_a = 3;
+ /* sequential data */
+ if (sequential) {
+ m = 1;
+ i_g *= total_cells;
+ i_b *= total_cells;
+ i_a *= total_cells;
+ }
+
+ for (i=0; i<total_cells; i++) {
+ float alpha = a[i];
+ if (alpha) {
+ data[i*m ] = r[i];
+ data[i*m+i_g] = g[i];
+ data[i*m+i_b] = b[i];
+ }
+ else {
+ data[i*m ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f;
+ }
+ data[i*m+i_a] = alpha;
+ }
+}
+
+extern "C" void smoke_get_rgba(FLUID_3D *fluid, float *data, int sequential)
+{
+ get_rgba(fluid->_color_r, fluid->_color_g, fluid->_color_b, fluid->_density, fluid->_totalCells, data, sequential);
+}
+
+extern "C" void smoke_turbulence_get_rgba(WTURBULENCE *wt, float *data, int sequential)
+{
+ get_rgba(wt->_color_rBig, wt->_color_gBig, wt->_color_bBig, wt->_densityBig, wt->_totalCellsBig, data, sequential);
+}
+
+/* get a single color premultiplied voxel grid */
+static void get_rgba_from_density(float color[3], float *a, int total_cells, float *data, int sequential)
+{
+ int i;
+ int m = 4, i_g = 1, i_b = 2, i_a = 3;
+ /* sequential data */
+ if (sequential) {
+ m = 1;
+ i_g *= total_cells;
+ i_b *= total_cells;
+ i_a *= total_cells;
+ }
+
+ for (i=0; i<total_cells; i++) {
+ float alpha = a[i];
+ if (alpha) {
+ data[i*m ] = color[0] * alpha;
+ data[i*m+i_g] = color[1] * alpha;
+ data[i*m+i_b] = color[2] * alpha;
+ }
+ else {
+ data[i*m ] = data[i*m+i_g] = data[i*m+i_b] = 0.0f;
+ }
+ data[i*m+i_a] = alpha;
+ }
+}
+
+extern "C" void smoke_get_rgba_from_density(FLUID_3D *fluid, float color[3], float *data, int sequential)
+{
+ get_rgba_from_density(color, fluid->_density, fluid->_totalCells, data, sequential);
+}
+
+extern "C" void smoke_turbulence_get_rgba_from_density(WTURBULENCE *wt, float color[3], float *data, int sequential)
+{
+ get_rgba_from_density(color, wt->_densityBig, wt->_totalCellsBig, data, sequential);
+}
+
extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt)
{
return wt ? wt->getDensityBig() : NULL;
}
+extern "C" float *smoke_turbulence_get_fuel(WTURBULENCE *wt)
+{
+ return wt ? wt->getFuelBig() : NULL;
+}
+
+extern "C" float *smoke_turbulence_get_react(WTURBULENCE *wt)
+{
+ return wt ? wt->_reactBig : NULL;
+}
+
+extern "C" float *smoke_turbulence_get_color_r(WTURBULENCE *wt)
+{
+ return wt ? wt->_color_rBig : NULL;
+}
+
+extern "C" float *smoke_turbulence_get_color_g(WTURBULENCE *wt)
+{
+ return wt ? wt->_color_gBig : NULL;
+}
+
+extern "C" float *smoke_turbulence_get_color_b(WTURBULENCE *wt)
+{
+ return wt ? wt->_color_bBig : NULL;
+}
+
+extern "C" float *smoke_turbulence_get_flame(WTURBULENCE *wt)
+{
+ return wt ? wt->getFlameBig() : NULL;
+}
+
extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res)
{
- if(wt)
- {
+ if (wt) {
Vec3Int r = wt->getResBig();
res[0] = r[0];
res[1] = r[1];
@@ -272,6 +394,15 @@ extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res)
}
}
+extern "C" int smoke_turbulence_get_cells(WTURBULENCE *wt)
+{
+ if (wt) {
+ Vec3Int r = wt->getResBig();
+ return r[0] * r[1] * r[2];
+ }
+ return 0;
+}
+
extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid)
{
return fluid->_obstacles;
@@ -295,3 +426,61 @@ extern "C" void smoke_turbulence_set_noise(WTURBULENCE *wt, int type)
{
wt->setNoise(type);
}
+
+extern "C" void flame_get_spectrum(unsigned char *spec, int width, float t1, float t2)
+{
+ spectrum(t1, t2, width, spec);
+}
+
+extern "C" int smoke_has_heat(FLUID_3D *fluid)
+{
+ return (fluid->_heat) ? 1 : 0;
+}
+
+extern "C" int smoke_has_fuel(FLUID_3D *fluid)
+{
+ return (fluid->_fuel) ? 1 : 0;
+}
+
+extern "C" int smoke_has_colors(FLUID_3D *fluid)
+{
+ return (fluid->_color_r && fluid->_color_g && fluid->_color_b) ? 1 : 0;
+}
+
+extern "C" int smoke_turbulence_has_fuel(WTURBULENCE *wt)
+{
+ return (wt->_fuelBig) ? 1 : 0;
+}
+
+extern "C" int smoke_turbulence_has_colors(WTURBULENCE *wt)
+{
+ return (wt->_color_rBig && wt->_color_gBig && wt->_color_bBig) ? 1 : 0;
+}
+
+/* additional field initialization */
+extern "C" void smoke_ensure_heat(FLUID_3D *fluid)
+{
+ if (fluid) {
+ fluid->initHeat();
+ }
+}
+
+extern "C" void smoke_ensure_fire(FLUID_3D *fluid, WTURBULENCE *wt)
+{
+ if (fluid) {
+ fluid->initFire();
+ }
+ if (wt) {
+ wt->initFire();
+ }
+}
+
+extern "C" void smoke_ensure_colors(FLUID_3D *fluid, WTURBULENCE *wt, float init_r, float init_g, float init_b)
+{
+ if (fluid) {
+ fluid->initColors(init_r, init_g, init_b);
+ }
+ if (wt) {
+ wt->initColors(init_r, init_g, init_b);
+ }
+}
diff --git a/intern/smoke/intern/spectrum.cpp b/intern/smoke/intern/spectrum.cpp
new file mode 100644
index 00000000000..30433451ac2
--- /dev/null
+++ b/intern/smoke/intern/spectrum.cpp
@@ -0,0 +1,426 @@
+/*
+ Colour Rendering of Spectra
+
+ by John Walker
+ http://www.fourmilab.ch/
+
+ Last updated: March 9, 2003
+
+ This program is in the public domain.
+
+ For complete information about the techniques employed in
+ this program, see the World-Wide Web document:
+
+ http://www.fourmilab.ch/documents/specrend/
+
+ The xyz_to_rgb() function, which was wrong in the original
+ version of this program, was corrected by:
+
+ Andrew J. S. Hamilton 21 May 1999
+ Andrew.Hamilton@Colorado.EDU
+ http://casa.colorado.edu/~ajsh/
+
+ who also added the gamma correction facilities and
+ modified constrain_rgb() to work by desaturating the
+ colour by adding white.
+
+ A program which uses these functions to plot CIE
+ "tongue" diagrams called "ppmcie" is included in
+ the Netpbm graphics toolkit:
+ http://netpbm.sourceforge.net/
+ (The program was called cietoppm in earlier
+ versions of Netpbm.)
+
+*/
+
+#include <stdio.h>
+#include <math.h>
+#include "spectrum.h"
+
+/* A colour system is defined by the CIE x and y coordinates of
+ its three primary illuminants and the x and y coordinates of
+ the white point. */
+
+struct colourSystem {
+ const char *name; /* Colour system name */
+ double xRed, yRed, /* Red x, y */
+ xGreen, yGreen, /* Green x, y */
+ xBlue, yBlue, /* Blue x, y */
+ xWhite, yWhite, /* White point x, y */
+ gamma; /* Gamma correction for system */
+};
+
+/* White point chromaticities. */
+
+#define IlluminantC 0.3101, 0.3162 /* For NTSC television */
+#define IlluminantD65 0.3127, 0.3291 /* For EBU and SMPTE */
+#define IlluminantE 0.33333333, 0.33333333 /* CIE equal-energy illuminant */
+
+/* Gamma of nonlinear correction.
+
+ See Charles Poynton's ColorFAQ Item 45 and GammaFAQ Item 6 at:
+
+ http://www.poynton.com/ColorFAQ.html
+ http://www.poynton.com/GammaFAQ.html
+
+*/
+
+#define GAMMA_REC709 0 /* Rec. 709 */
+
+static struct colourSystem
+ /* Name xRed yRed xGreen yGreen xBlue yBlue White point Gamma */
+#if 0 /* UNUSED */
+ NTSCsystem = { "NTSC", 0.67, 0.33, 0.21, 0.71, 0.14, 0.08, IlluminantC, GAMMA_REC709 },
+ EBUsystem = { "EBU (PAL/SECAM)", 0.64, 0.33, 0.29, 0.60, 0.15, 0.06, IlluminantD65, GAMMA_REC709 },
+ SMPTEsystem = { "SMPTE", 0.630, 0.340, 0.310, 0.595, 0.155, 0.070, IlluminantD65, GAMMA_REC709 },
+ HDTVsystem = { "HDTV", 0.670, 0.330, 0.210, 0.710, 0.150, 0.060, IlluminantD65, GAMMA_REC709 },
+#endif
+
+ CIEsystem = { "CIE", 0.7355, 0.2645, 0.2658, 0.7243, 0.1669, 0.0085, IlluminantE, GAMMA_REC709 };
+
+#if 0 /* UNUSED */
+ Rec709system = { "CIE REC 709", 0.64, 0.33, 0.30, 0.60, 0.15, 0.06, IlluminantD65, GAMMA_REC709 };
+#endif
+
+/* UPVP_TO_XY
+
+ Given 1976 coordinates u', v', determine 1931 chromaticities x, y
+
+*/
+
+#if 0 /* UNUSED */
+static void upvp_to_xy(double up, double vp, double *xc, double *yc)
+{
+ *xc = (9 * up) / ((6 * up) - (16 * vp) + 12);
+ *yc = (4 * vp) / ((6 * up) - (16 * vp) + 12);
+}
+#endif
+
+/* XY_TO_UPVP
+
+ Given 1931 chromaticities x, y, determine 1976 coordinates u', v'
+
+*/
+
+#if 0 /* UNUSED */
+static void xy_to_upvp(double xc, double yc, double *up, double *vp)
+{
+ *up = (4 * xc) / ((-2 * xc) + (12 * yc) + 3);
+ *vp = (9 * yc) / ((-2 * xc) + (12 * yc) + 3);
+}
+#endif
+
+/* XYZ_TO_RGB
+
+ Given an additive tricolour system CS, defined by the CIE x
+ and y chromaticities of its three primaries (z is derived
+ trivially as 1-(x+y)), and a desired chromaticity (XC, YC,
+ ZC) in CIE space, determine the contribution of each
+ primary in a linear combination which sums to the desired
+ chromaticity. If the requested chromaticity falls outside
+ the Maxwell triangle (colour gamut) formed by the three
+ primaries, one of the r, g, or b weights will be negative.
+
+ Caller can use constrain_rgb() to desaturate an
+ outside-gamut colour to the closest representation within
+ the available gamut and/or norm_rgb to normalise the RGB
+ components so the largest nonzero component has value 1.
+
+*/
+
+static void xyz_to_rgb(struct colourSystem *cs,
+ double xc, double yc, double zc,
+ double *r, double *g, double *b)
+{
+ double xr, yr, zr, xg, yg, zg, xb, yb, zb;
+ double xw, yw, zw;
+ double rx, ry, rz, gx, gy, gz, bx, by, bz;
+ double rw, gw, bw;
+
+ xr = cs->xRed; yr = cs->yRed; zr = 1 - (xr + yr);
+ xg = cs->xGreen; yg = cs->yGreen; zg = 1 - (xg + yg);
+ xb = cs->xBlue; yb = cs->yBlue; zb = 1 - (xb + yb);
+
+ xw = cs->xWhite; yw = cs->yWhite; zw = 1 - (xw + yw);
+
+ /* xyz -> rgb matrix, before scaling to white. */
+
+ rx = (yg * zb) - (yb * zg); ry = (xb * zg) - (xg * zb); rz = (xg * yb) - (xb * yg);
+ gx = (yb * zr) - (yr * zb); gy = (xr * zb) - (xb * zr); gz = (xb * yr) - (xr * yb);
+ bx = (yr * zg) - (yg * zr); by = (xg * zr) - (xr * zg); bz = (xr * yg) - (xg * yr);
+
+ /* White scaling factors.
+ Dividing by yw scales the white luminance to unity, as conventional. */
+
+ rw = ((rx * xw) + (ry * yw) + (rz * zw)) / yw;
+ gw = ((gx * xw) + (gy * yw) + (gz * zw)) / yw;
+ bw = ((bx * xw) + (by * yw) + (bz * zw)) / yw;
+
+ /* xyz -> rgb matrix, correctly scaled to white. */
+
+ rx = rx / rw; ry = ry / rw; rz = rz / rw;
+ gx = gx / gw; gy = gy / gw; gz = gz / gw;
+ bx = bx / bw; by = by / bw; bz = bz / bw;
+
+ /* rgb of the desired point */
+
+ *r = (rx * xc) + (ry * yc) + (rz * zc);
+ *g = (gx * xc) + (gy * yc) + (gz * zc);
+ *b = (bx * xc) + (by * yc) + (bz * zc);
+}
+
+/* INSIDE_GAMUT
+
+ Test whether a requested colour is within the gamut
+ achievable with the primaries of the current colour
+ system. This amounts simply to testing whether all the
+ primary weights are non-negative. */
+
+#if 0 /* UNUSED */
+static int inside_gamut(double r, double g, double b)
+{
+ return (r >= 0) && (g >= 0) && (b >= 0);
+}
+#endif
+
+/* CONSTRAIN_RGB
+
+ If the requested RGB shade contains a negative weight for
+ one of the primaries, it lies outside the colour gamut
+ accessible from the given triple of primaries. Desaturate
+ it by adding white, equal quantities of R, G, and B, enough
+ to make RGB all positive. The function returns 1 if the
+ components were modified, zero otherwise.
+
+*/
+
+static int constrain_rgb(double *r, double *g, double *b)
+{
+ double w;
+
+ /* Amount of white needed is w = - min(0, *r, *g, *b) */
+
+ w = (0 < *r) ? 0 : *r;
+ w = (w < *g) ? w : *g;
+ w = (w < *b) ? w : *b;
+ w = -w;
+
+ /* Add just enough white to make r, g, b all positive. */
+
+ if (w > 0) {
+ *r += w; *g += w; *b += w;
+ return 1; /* Colour modified to fit RGB gamut */
+ }
+
+ return 0; /* Colour within RGB gamut */
+}
+
+/* GAMMA_CORRECT_RGB
+
+ Transform linear RGB values to nonlinear RGB values. Rec.
+ 709 is ITU-R Recommendation BT. 709 (1990) ``Basic
+ Parameter Values for the HDTV Standard for the Studio and
+ for International Programme Exchange'', formerly CCIR Rec.
+ 709. For details see
+
+ http://www.poynton.com/ColorFAQ.html
+ http://www.poynton.com/GammaFAQ.html
+*/
+
+#if 0 /* UNUSED */
+static void gamma_correct(const struct colourSystem *cs, double *c)
+{
+ double gamma;
+
+ gamma = cs->gamma;
+
+ if (gamma == GAMMA_REC709) {
+ /* Rec. 709 gamma correction. */
+ double cc = 0.018;
+
+ if (*c < cc) {
+ *c *= ((1.099 * pow(cc, 0.45)) - 0.099) / cc;
+ } else {
+ *c = (1.099 * pow(*c, 0.45)) - 0.099;
+ }
+ } else {
+ /* Nonlinear colour = (Linear colour)^(1/gamma) */
+ *c = pow(*c, 1.0 / gamma);
+ }
+}
+
+static void gamma_correct_rgb(const struct colourSystem *cs, double *r, double *g, double *b)
+{
+ gamma_correct(cs, r);
+ gamma_correct(cs, g);
+ gamma_correct(cs, b);
+}
+#endif
+
+/* NORM_RGB
+
+ Normalise RGB components so the most intense (unless all
+ are zero) has a value of 1.
+
+*/
+
+static void norm_rgb(double *r, double *g, double *b)
+{
+#define Max(a, b) (((a) > (b)) ? (a) : (b))
+ double greatest = Max(*r, Max(*g, *b));
+
+ if (greatest > 0) {
+ *r /= greatest;
+ *g /= greatest;
+ *b /= greatest;
+ }
+#undef Max
+}
+
+/* SPECTRUM_TO_XYZ
+
+ Calculate the CIE X, Y, and Z coordinates corresponding to
+ a light source with spectral distribution given by the
+ function SPEC_INTENS, which is called with a series of
+ wavelengths between 380 and 780 nm (the argument is
+ expressed in meters), which returns emittance at that
+ wavelength in arbitrary units. The chromaticity
+ coordinates of the spectrum are returned in the x, y, and z
+ arguments which respect the identity:
+
+ x + y + z = 1.
+*/
+
+static void spectrum_to_xyz(double (*spec_intens)(double wavelength),
+ double *x, double *y, double *z)
+{
+ int i;
+ double lambda, X = 0, Y = 0, Z = 0, XYZ;
+
+ /* 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
+
+ To save memory, this table can be declared as floats
+ rather than doubles; (IEEE) float has enough
+ significant bits to represent the values. It's declared
+ as a double here to avoid warnings about "conversion
+ between floating-point types" from certain persnickety
+ compilers. */
+
+ static double cie_colour_match[81][3] = {
+ {0.0014,0.0000,0.0065}, {0.0022,0.0001,0.0105}, {0.0042,0.0001,0.0201},
+ {0.0076,0.0002,0.0362}, {0.0143,0.0004,0.0679}, {0.0232,0.0006,0.1102},
+ {0.0435,0.0012,0.2074}, {0.0776,0.0022,0.3713}, {0.1344,0.0040,0.6456},
+ {0.2148,0.0073,1.0391}, {0.2839,0.0116,1.3856}, {0.3285,0.0168,1.6230},
+ {0.3483,0.0230,1.7471}, {0.3481,0.0298,1.7826}, {0.3362,0.0380,1.7721},
+ {0.3187,0.0480,1.7441}, {0.2908,0.0600,1.6692}, {0.2511,0.0739,1.5281},
+ {0.1954,0.0910,1.2876}, {0.1421,0.1126,1.0419}, {0.0956,0.1390,0.8130},
+ {0.0580,0.1693,0.6162}, {0.0320,0.2080,0.4652}, {0.0147,0.2586,0.3533},
+ {0.0049,0.3230,0.2720}, {0.0024,0.4073,0.2123}, {0.0093,0.5030,0.1582},
+ {0.0291,0.6082,0.1117}, {0.0633,0.7100,0.0782}, {0.1096,0.7932,0.0573},
+ {0.1655,0.8620,0.0422}, {0.2257,0.9149,0.0298}, {0.2904,0.9540,0.0203},
+ {0.3597,0.9803,0.0134}, {0.4334,0.9950,0.0087}, {0.5121,1.0000,0.0057},
+ {0.5945,0.9950,0.0039}, {0.6784,0.9786,0.0027}, {0.7621,0.9520,0.0021},
+ {0.8425,0.9154,0.0018}, {0.9163,0.8700,0.0017}, {0.9786,0.8163,0.0014},
+ {1.0263,0.7570,0.0011}, {1.0567,0.6949,0.0010}, {1.0622,0.6310,0.0008},
+ {1.0456,0.5668,0.0006}, {1.0026,0.5030,0.0003}, {0.9384,0.4412,0.0002},
+ {0.8544,0.3810,0.0002}, {0.7514,0.3210,0.0001}, {0.6424,0.2650,0.0000},
+ {0.5419,0.2170,0.0000}, {0.4479,0.1750,0.0000}, {0.3608,0.1382,0.0000},
+ {0.2835,0.1070,0.0000}, {0.2187,0.0816,0.0000}, {0.1649,0.0610,0.0000},
+ {0.1212,0.0446,0.0000}, {0.0874,0.0320,0.0000}, {0.0636,0.0232,0.0000},
+ {0.0468,0.0170,0.0000}, {0.0329,0.0119,0.0000}, {0.0227,0.0082,0.0000},
+ {0.0158,0.0057,0.0000}, {0.0114,0.0041,0.0000}, {0.0081,0.0029,0.0000},
+ {0.0058,0.0021,0.0000}, {0.0041,0.0015,0.0000}, {0.0029,0.0010,0.0000},
+ {0.0020,0.0007,0.0000}, {0.0014,0.0005,0.0000}, {0.0010,0.0004,0.0000},
+ {0.0007,0.0002,0.0000}, {0.0005,0.0002,0.0000}, {0.0003,0.0001,0.0000},
+ {0.0002,0.0001,0.0000}, {0.0002,0.0001,0.0000}, {0.0001,0.0000,0.0000},
+ {0.0001,0.0000,0.0000}, {0.0001,0.0000,0.0000}, {0.0000,0.0000,0.0000}
+ };
+
+ for (i = 0, lambda = 380; lambda < 780.1; i++, lambda += 5) {
+ double Me;
+
+ Me = (*spec_intens)(lambda);
+ X += Me * cie_colour_match[i][0];
+ Y += Me * cie_colour_match[i][1];
+ Z += Me * cie_colour_match[i][2];
+ }
+ XYZ = (X + Y + Z);
+ *x = X / XYZ;
+ *y = Y / XYZ;
+ *z = Z / XYZ;
+}
+
+/* BB_SPECTRUM
+
+ Calculate, by Planck's radiation law, the emittance of a black body
+ of temperature bbTemp at the given wavelength (in metres). */
+
+double bbTemp = 5000; /* Hidden temperature argument
+ to BB_SPECTRUM. */
+static double bb_spectrum(double wavelength)
+{
+ double wlm = wavelength * 1e-9; /* Wavelength in meters */
+
+ return (3.74183e-16 * pow(wlm, -5.0)) /
+ (exp(1.4388e-2 / (wlm * bbTemp)) - 1.0);
+}
+
+static void xyz_to_lms(double x, double y, double z, double* l, double* m, double* s)
+{
+ *l = 0.3897*x + 0.6890*y - 0.0787*z;
+ *m = -0.2298*x + 1.1834*y + 0.0464*z;
+ *s = z;
+}
+
+static void lms_to_xyz(double l, double m, double s, double* x, double *y, double* z)
+{
+ *x = 1.9102*l - 1.1121*m + 0.2019*s;
+ *y = 0.3709*l + 0.6290*m + 0.0000*s;
+ *z = s;
+}
+
+void spectrum(double t1, double t2, int N, unsigned char *d)
+{
+ int i,j,dj;
+ double X,Y,Z,R,G,B,L,M,S, Lw, Mw, Sw;
+ struct colourSystem *cs = &CIEsystem;
+
+ j = 0; dj = 1;
+ if (t1<t2) {
+ double t = t1;
+ t1 = t2;
+ t2 = t;
+ j = N-1; dj=-1;
+ }
+
+ for (i=0; i<N; i++) {
+ bbTemp = t1 + (t2-t1)/N*i;
+
+ // integrate blackbody radiation spectrum to XYZ
+ spectrum_to_xyz(bb_spectrum, &X, &Y, &Z);
+
+ // normalize highest temperature to white (in LMS system)
+ xyz_to_lms(X,Y,Z,&L,&M,&S);
+ if (i==0) {
+ Lw=1/L; Mw=1/M; Sw=1/S;
+ }
+ L *= Lw; M *= Mw; S *= Sw;
+ lms_to_xyz(L,M,S,&X,&Y,&Z);
+
+ // convert to RGB
+ xyz_to_rgb(cs, X, Y, Z, &R, &G, &B);
+ constrain_rgb(&R, &G, &B);
+ norm_rgb(&R, &G, &B);
+ d[(j<<2)] = (unsigned char) ((double)R*255);
+ d[(j<<2)+1] = (unsigned char) ((double)G*255);
+ d[(j<<2)+2] = (unsigned char) ((double)B*255);
+ d[(j<<2)+3] = (B>0.1)? B*255 : 0;
+ j += dj;
+ }
+}
diff --git a/intern/smoke/intern/spectrum.h b/intern/smoke/intern/spectrum.h
new file mode 100644
index 00000000000..3ffd41f9517
--- /dev/null
+++ b/intern/smoke/intern/spectrum.h
@@ -0,0 +1,6 @@
+#ifndef __SPECTRUM_H
+#define __SPECTRUM_H
+
+void spectrum(double t1, double t2, int n, unsigned char *d);
+
+#endif
diff --git a/intern/utfconv/utfconv.h b/intern/utfconv/utfconv.h
index 3bfd2772991..cf0e69170a2 100644
--- a/intern/utfconv/utfconv.h
+++ b/intern/utfconv/utfconv.h
@@ -95,7 +95,7 @@ wchar_t *alloc_utf16_from_8(const char *in8, size_t add);
wchar_t *in8str ## _16 = alloc_utf16_from_8((char *)in8str, 0)
#define UTF16_UN_ENCODE(in8str) \
- free(in8str ## _16); } (void)0
+ free(in8str ## _16); } (void)0
#ifdef __cplusplus
}