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
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2017-08-19 14:02:03 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2017-08-19 14:02:03 +0300
commit45f0f3dc0457a53a25103784f0e0d100c7a17cbe (patch)
tree94767d8e4fa6ea23f2bbd2274f239ecbbdc5931a
parent0d67f8d5c46fcc97cbb0544ef7d8c3c0056025c4 (diff)
parent9a262ed47ecb1c9f43053b0653364c59d9595fdf (diff)
Merge branch 'blender2.8' into strand_editmode
-rw-r--r--.gitignore3
-rw-r--r--CMakeLists.txt53
-rw-r--r--GNUmakefile35
-rw-r--r--build_files/build_environment/CMakeLists.txt130
-rw-r--r--build_files/build_environment/cmake/alembic.cmake75
-rw-r--r--build_files/build_environment/cmake/blendthumb.cmake61
-rw-r--r--build_files/build_environment/cmake/blosc.cmake43
-rw-r--r--build_files/build_environment/cmake/boost.cmake99
-rw-r--r--build_files/build_environment/cmake/clang.cmake35
-rw-r--r--build_files/build_environment/cmake/clew.cmake28
-rw-r--r--build_files/build_environment/cmake/cuew.cmake29
-rw-r--r--build_files/build_environment/cmake/faad.cmake35
-rw-r--r--build_files/build_environment/cmake/ffmpeg.cmake119
-rw-r--r--build_files/build_environment/cmake/fftw.cmake40
-rw-r--r--build_files/build_environment/cmake/flac.cmake32
-rw-r--r--build_files/build_environment/cmake/flexbison.cmake31
-rw-r--r--build_files/build_environment/cmake/freeglut.cmake35
-rw-r--r--build_files/build_environment/cmake/freetype.cmake28
-rw-r--r--build_files/build_environment/cmake/glew.cmake32
-rw-r--r--build_files/build_environment/cmake/glfw.cmake28
-rw-r--r--build_files/build_environment/cmake/harvest.cmake292
-rw-r--r--build_files/build_environment/cmake/hdf5.cmake42
-rw-r--r--build_files/build_environment/cmake/hidapi.cmake29
-rw-r--r--build_files/build_environment/cmake/iconv.cmake34
-rw-r--r--build_files/build_environment/cmake/ilmbase.cmake35
-rw-r--r--build_files/build_environment/cmake/jemalloc.cmake28
-rw-r--r--build_files/build_environment/cmake/jpeg.cmake65
-rw-r--r--build_files/build_environment/cmake/lame.cmake47
-rw-r--r--build_files/build_environment/cmake/lapack.cmake43
-rw-r--r--build_files/build_environment/cmake/llvm.cmake44
-rw-r--r--build_files/build_environment/cmake/mingw.cmake40
-rw-r--r--build_files/build_environment/cmake/numpy.cmake55
-rw-r--r--build_files/build_environment/cmake/ogg.cmake32
-rw-r--r--build_files/build_environment/cmake/openal.cmake42
-rw-r--r--build_files/build_environment/cmake/opencollada.cmake37
-rw-r--r--build_files/build_environment/cmake/opencolorio.cmake70
-rw-r--r--build_files/build_environment/cmake/openexr.cmake41
-rw-r--r--build_files/build_environment/cmake/openimageio.cmake113
-rw-r--r--build_files/build_environment/cmake/openjpeg.cmake43
-rw-r--r--build_files/build_environment/cmake/opensubdiv.cmake71
-rw-r--r--build_files/build_environment/cmake/openvdb.cmake71
-rw-r--r--build_files/build_environment/cmake/options.cmake205
-rw-r--r--build_files/build_environment/cmake/orc.cmake32
-rw-r--r--build_files/build_environment/cmake/osl.cmake87
-rw-r--r--build_files/build_environment/cmake/png.cmake41
-rw-r--r--build_files/build_environment/cmake/pthreads.cmake45
-rw-r--r--build_files/build_environment/cmake/python.cmake138
-rw-r--r--build_files/build_environment/cmake/requests.cmake37
-rw-r--r--build_files/build_environment/cmake/schroedinger.cmake45
-rw-r--r--build_files/build_environment/cmake/sdl.cmake39
-rw-r--r--build_files/build_environment/cmake/setup_mingw32.cmake219
-rw-r--r--build_files/build_environment/cmake/setup_mingw64.cmake219
-rw-r--r--build_files/build_environment/cmake/sndfile.cmake44
-rw-r--r--build_files/build_environment/cmake/spnav.cmake28
-rw-r--r--build_files/build_environment/cmake/tbb.cmake36
-rw-r--r--build_files/build_environment/cmake/theora.cmake40
-rw-r--r--build_files/build_environment/cmake/tiff.cmake44
-rw-r--r--build_files/build_environment/cmake/versions.cmake245
-rw-r--r--build_files/build_environment/cmake/vorbis.cmake38
-rw-r--r--build_files/build_environment/cmake/vpx.cmake60
-rw-r--r--build_files/build_environment/cmake/webp.cmake50
-rw-r--r--build_files/build_environment/cmake/x264.cmake40
-rw-r--r--build_files/build_environment/cmake/xml2.cmake36
-rw-r--r--build_files/build_environment/cmake/xvidcore.cmake44
-rw-r--r--build_files/build_environment/cmake/zlib.cmake33
-rw-r--r--build_files/build_environment/cmake/zlib_mingw.cmake40
-rwxr-xr-xbuild_files/build_environment/install_deps.sh27
-rw-r--r--build_files/build_environment/patches/alembic.diff35
-rw-r--r--build_files/build_environment/patches/blosc.diff33
-rw-r--r--build_files/build_environment/patches/clang.diff127
-rw-r--r--build_files/build_environment/patches/cmake/modules/FindBlosc.cmake73
-rw-r--r--build_files/build_environment/patches/cmake/modules/FindCppUnit.cmake73
-rw-r--r--build_files/build_environment/patches/cmake/modules/FindIlmBase.cmake260
-rw-r--r--build_files/build_environment/patches/cmake/modules/FindLogC4Plus.cmake73
-rw-r--r--build_files/build_environment/patches/cmake/modules/FindOpenEXR.cmake244
-rw-r--r--build_files/build_environment/patches/cmake/modules/FindTBB.cmake73
-rw-r--r--build_files/build_environment/patches/cmake/modules/SelectLibraryConfigurations.cmake82
-rw-r--r--build_files/build_environment/patches/cmakelists_glew.txt2
-rw-r--r--build_files/build_environment/patches/cmakelists_hidapi.txt20
-rw-r--r--build_files/build_environment/patches/cmakelists_openvdb.txt398
-rw-r--r--build_files/build_environment/patches/cmakelists_tbb.txt196
-rw-r--r--build_files/build_environment/patches/cuew.diff26
-rw-r--r--build_files/build_environment/patches/distutildebugflags.diff11
-rw-r--r--build_files/build_environment/patches/ffmpeg.diff32
-rw-r--r--build_files/build_environment/patches/fftw3.diff25
-rw-r--r--build_files/build_environment/patches/hdf5.diff11
-rw-r--r--build_files/build_environment/patches/hidapi.diff15
-rw-r--r--build_files/build_environment/patches/install_deps_llvm.diff (renamed from build_files/build_environment/install_deps_patches/llvm.patch)0
-rw-r--r--build_files/build_environment/patches/install_deps_osl.diff (renamed from build_files/build_environment/install_deps_patches/osl.patch)0
-rw-r--r--build_files/build_environment/patches/libfaad.diff10
-rw-r--r--build_files/build_environment/patches/llvm-alloca-fix.diff111
-rw-r--r--build_files/build_environment/patches/ming32sh.cmd7
-rw-r--r--build_files/build_environment/patches/ming64sh.cmd7
-rw-r--r--build_files/build_environment/patches/numpy.diff23
-rw-r--r--build_files/build_environment/patches/opencollada.diff32
-rw-r--r--build_files/build_environment/patches/opencolorio.diff21
-rw-r--r--build_files/build_environment/patches/openexr.diff33
-rw-r--r--build_files/build_environment/patches/openimageio_gdi.diff26
-rw-r--r--build_files/build_environment/patches/openimageio_idiff.diff13
-rw-r--r--build_files/build_environment/patches/openimageio_staticexr.diff10
-rw-r--r--build_files/build_environment/patches/opensubdiv.diff16
-rw-r--r--build_files/build_environment/patches/openvdb.diff11
-rw-r--r--build_files/build_environment/patches/openvdb_vc2013.diff35
-rw-r--r--build_files/build_environment/patches/osl.diff12
-rw-r--r--build_files/build_environment/patches/osl_simd_oiio.diff14
-rw-r--r--build_files/build_environment/patches/pthreads.diff13
-rw-r--r--build_files/build_environment/patches/pyshell.diff12
-rw-r--r--build_files/build_environment/patches/python.diff40
-rw-r--r--build_files/build_environment/patches/python_apple.diff48
-rw-r--r--build_files/build_environment/patches/python_runtime_vc2013.diff29
-rw-r--r--build_files/build_environment/patches/schroedinger.diff54
-rw-r--r--build_files/build_environment/patches/sdl.diff50
-rw-r--r--build_files/build_environment/patches/semi.txt1
-rw-r--r--build_files/build_environment/windows/build_deps.cmd122
-rw-r--r--build_files/build_environment/windows/buildall.cmd10
-rw-r--r--build_files/build_environment/windows/nuke.cmd52
-rw-r--r--build_files/buildbot/config/blender_linux.cmake4
-rw-r--r--build_files/cmake/Modules/FindSndFile.cmake40
-rw-r--r--build_files/cmake/macros.cmake14
-rw-r--r--build_files/cmake/platform/platform_apple.cmake19
-rw-r--r--build_files/cmake/platform/platform_unix.cmake2
-rw-r--r--build_files/cmake/platform/platform_win32.cmake10
-rw-r--r--build_files/cmake/platform/platform_win32_msvc.cmake5
-rw-r--r--extern/CMakeLists.txt5
-rw-r--r--extern/audaspace/AUTHORS16
-rw-r--r--extern/audaspace/CHANGES115
-rw-r--r--extern/audaspace/CMakeLists.txt983
-rw-r--r--extern/audaspace/INSTALL107
-rw-r--r--extern/audaspace/LICENSE202
-rw-r--r--extern/audaspace/README.md47
-rw-r--r--extern/audaspace/bindings/C/AUD_Device.cpp336
-rw-r--r--extern/audaspace/bindings/C/AUD_Device.h258
-rw-r--r--extern/audaspace/bindings/C/AUD_DynamicMusic.cpp144
-rw-r--r--extern/audaspace/bindings/C/AUD_DynamicMusic.h145
-rw-r--r--extern/audaspace/bindings/C/AUD_HRTF.cpp50
-rw-r--r--extern/audaspace/bindings/C/AUD_HRTF.h48
-rw-r--r--extern/audaspace/bindings/C/AUD_Handle.cpp384
-rw-r--r--extern/audaspace/bindings/C/AUD_Handle.h308
-rw-r--r--extern/audaspace/bindings/C/AUD_ImpulseResponse.cpp44
-rw-r--r--extern/audaspace/bindings/C/AUD_ImpulseResponse.h40
-rw-r--r--extern/audaspace/bindings/C/AUD_PlaybackManager.cpp94
-rw-r--r--extern/audaspace/bindings/C/AUD_PlaybackManager.h103
-rw-r--r--extern/audaspace/bindings/C/AUD_Sequence.cpp315
-rw-r--r--extern/audaspace/bindings/C/AUD_Sequence.h338
-rw-r--r--extern/audaspace/bindings/C/AUD_Sound.cpp709
-rw-r--r--extern/audaspace/bindings/C/AUD_Sound.h370
-rw-r--r--extern/audaspace/bindings/C/AUD_Source.cpp84
-rw-r--r--extern/audaspace/bindings/C/AUD_Source.h84
-rw-r--r--extern/audaspace/bindings/C/AUD_Special.cpp420
-rw-r--r--extern/audaspace/bindings/C/AUD_Special.h138
-rw-r--r--extern/audaspace/bindings/C/AUD_ThreadPool.cpp42
-rw-r--r--extern/audaspace/bindings/C/AUD_ThreadPool.h40
-rw-r--r--extern/audaspace/bindings/C/AUD_Types.h179
-rw-r--r--extern/audaspace/bindings/doc/conf.py.in261
-rw-r--r--extern/audaspace/bindings/doc/device.rst7
-rw-r--r--extern/audaspace/bindings/doc/handle.rst7
-rw-r--r--extern/audaspace/bindings/doc/index.rst35
-rw-r--r--extern/audaspace/bindings/doc/sequence.rst7
-rw-r--r--extern/audaspace/bindings/doc/sequence_entry.rst7
-rw-r--r--extern/audaspace/bindings/doc/sound.rst7
-rw-r--r--extern/audaspace/bindings/doc/tutorials.rst166
-rw-r--r--extern/audaspace/bindings/python/PyAPI.cpp231
-rw-r--r--extern/audaspace/bindings/python/PyAPI.h45
-rw-r--r--extern/audaspace/bindings/python/PyDevice.cpp785
-rw-r--r--extern/audaspace/bindings/python/PyDevice.h33
-rw-r--r--extern/audaspace/bindings/python/PyDynamicMusic.cpp467
-rw-r--r--extern/audaspace/bindings/python/PyDynamicMusic.h33
-rw-r--r--extern/audaspace/bindings/python/PyHRTF.cpp247
-rw-r--r--extern/audaspace/bindings/python/PyHRTF.h33
-rw-r--r--extern/audaspace/bindings/python/PyHandle.cpp1126
-rw-r--r--extern/audaspace/bindings/python/PyHandle.h33
-rw-r--r--extern/audaspace/bindings/python/PyImpulseResponse.cpp137
-rw-r--r--extern/audaspace/bindings/python/PyImpulseResponse.h33
-rw-r--r--extern/audaspace/bindings/python/PyPlaybackManager.cpp389
-rw-r--r--extern/audaspace/bindings/python/PyPlaybackManager.h33
-rw-r--r--extern/audaspace/bindings/python/PySequence.cpp655
-rw-r--r--extern/audaspace/bindings/python/PySequence.h33
-rw-r--r--extern/audaspace/bindings/python/PySequenceEntry.cpp740
-rw-r--r--extern/audaspace/bindings/python/PySequenceEntry.h33
-rw-r--r--extern/audaspace/bindings/python/PySound.cpp1966
-rw-r--r--extern/audaspace/bindings/python/PySound.h33
-rw-r--r--extern/audaspace/bindings/python/PySource.cpp260
-rw-r--r--extern/audaspace/bindings/python/PySource.h33
-rw-r--r--extern/audaspace/bindings/python/PyThreadPool.cpp134
-rw-r--r--extern/audaspace/bindings/python/PyThreadPool.h33
-rw-r--r--extern/audaspace/bindings/python/examples/binaural.py13
-rw-r--r--extern/audaspace/bindings/python/examples/convolution.py10
-rw-r--r--extern/audaspace/bindings/python/examples/dynamicmusic.py20
-rw-r--r--extern/audaspace/bindings/python/examples/playbackmanager.py27
-rw-r--r--extern/audaspace/bindings/python/examples/player.py7
-rw-r--r--extern/audaspace/bindings/python/examples/randomSounds.py21
-rw-r--r--extern/audaspace/bindings/python/examples/simple.py7
-rw-r--r--extern/audaspace/bindings/python/examples/siren.py19
-rw-r--r--extern/audaspace/bindings/python/examples/siren2.py23
-rw-r--r--extern/audaspace/bindings/python/examples/tetris.py66
-rw-r--r--extern/audaspace/bindings/python/examples/tetris2.py64
-rw-r--r--extern/audaspace/bindings/python/examples/tetris3.py63
-rw-r--r--extern/audaspace/bindings/python/setup.py.in61
-rw-r--r--extern/audaspace/blender_config.cmake26
-rw-r--r--extern/audaspace/config/Audaspace.h.in131
-rw-r--r--extern/audaspace/include/Exception.h185
-rw-r--r--extern/audaspace/include/IReader.h (renamed from intern/audaspace/intern/AUD_IReader.h)57
-rw-r--r--extern/audaspace/include/ISound.h57
-rw-r--r--extern/audaspace/include/devices/DefaultSynchronizer.h44
-rw-r--r--extern/audaspace/include/devices/DeviceManager.h129
-rw-r--r--extern/audaspace/include/devices/I3DDevice.h142
-rw-r--r--extern/audaspace/include/devices/I3DHandle.h (renamed from intern/audaspace/intern/AUD_I3DHandle.h)110
-rw-r--r--extern/audaspace/include/devices/IDevice.h123
-rw-r--r--extern/audaspace/include/devices/IDeviceFactory.h72
-rw-r--r--extern/audaspace/include/devices/IHandle.h (renamed from intern/audaspace/intern/AUD_IHandle.h)80
-rw-r--r--extern/audaspace/include/devices/ISynchronizer.h92
-rw-r--r--extern/audaspace/include/devices/NULLDevice.h96
-rw-r--r--extern/audaspace/include/devices/ReadDevice.h82
-rw-r--r--extern/audaspace/include/devices/SoftwareDevice.h (renamed from intern/audaspace/intern/AUD_SoftwareDevice.h)194
-rw-r--r--extern/audaspace/include/file/File.h74
-rw-r--r--extern/audaspace/include/file/FileManager.h95
-rw-r--r--extern/audaspace/include/file/FileWriter.h78
-rw-r--r--extern/audaspace/include/file/IFileInput.h60
-rw-r--r--extern/audaspace/include/file/IFileOutput.h52
-rw-r--r--extern/audaspace/include/file/IWriter.h89
-rw-r--r--extern/audaspace/include/fx/ADSR.h121
-rw-r--r--extern/audaspace/include/fx/ADSRReader.h101
-rw-r--r--extern/audaspace/include/fx/Accumulator.h79
-rw-r--r--extern/audaspace/include/fx/BaseIIRFilterReader.h (renamed from intern/audaspace/FX/AUD_BaseIIRFilterReader.h)70
-rw-r--r--extern/audaspace/include/fx/BinauralReader.h223
-rw-r--r--extern/audaspace/include/fx/BinauralSound.h119
-rw-r--r--extern/audaspace/include/fx/Butterworth.h48
-rw-r--r--extern/audaspace/include/fx/ButterworthCalculator.h55
-rw-r--r--extern/audaspace/include/fx/CallbackIIRFilterReader.h88
-rw-r--r--extern/audaspace/include/fx/Convolver.h177
-rw-r--r--extern/audaspace/include/fx/ConvolverReader.h198
-rw-r--r--extern/audaspace/include/fx/ConvolverSound.h100
-rw-r--r--extern/audaspace/include/fx/Delay.h60
-rw-r--r--extern/audaspace/include/fx/DelayReader.h63
-rw-r--r--extern/audaspace/include/fx/DynamicIIRFilter.h54
-rw-r--r--extern/audaspace/include/fx/DynamicIIRFilterReader.h60
-rw-r--r--extern/audaspace/include/fx/DynamicMusic.h235
-rw-r--r--extern/audaspace/include/fx/Effect.h76
-rw-r--r--extern/audaspace/include/fx/EffectReader.h68
-rw-r--r--extern/audaspace/include/fx/Envelope.h93
-rw-r--r--extern/audaspace/include/fx/FFTConvolver.h196
-rw-r--r--extern/audaspace/include/fx/Fader.h87
-rw-r--r--extern/audaspace/include/fx/FaderReader.h77
-rw-r--r--extern/audaspace/include/fx/HRTF.h108
-rw-r--r--extern/audaspace/include/fx/HRTFLoader.h99
-rw-r--r--extern/audaspace/include/fx/Highpass.h49
-rw-r--r--extern/audaspace/include/fx/HighpassCalculator.h61
-rw-r--r--extern/audaspace/include/fx/IDynamicIIRFilterCalculator.h50
-rw-r--r--extern/audaspace/include/fx/IIRFilter.h63
-rw-r--r--extern/audaspace/include/fx/IIRFilterReader.h70
-rw-r--r--extern/audaspace/include/fx/ImpulseResponse.h108
-rw-r--r--extern/audaspace/include/fx/Limiter.h73
-rw-r--r--extern/audaspace/include/fx/LimiterReader.h65
-rw-r--r--extern/audaspace/include/fx/Loop.h62
-rw-r--r--extern/audaspace/include/fx/LoopReader.h65
-rw-r--r--extern/audaspace/include/fx/Lowpass.h49
-rw-r--r--extern/audaspace/include/fx/LowpassCalculator.h61
-rw-r--r--extern/audaspace/include/fx/MutableReader.h71
-rw-r--r--extern/audaspace/include/fx/MutableSound.h58
-rw-r--r--extern/audaspace/include/fx/Pitch.h55
-rw-r--r--extern/audaspace/include/fx/PitchReader.h67
-rw-r--r--extern/audaspace/include/fx/PlaybackCategory.h127
-rw-r--r--extern/audaspace/include/fx/PlaybackManager.h156
-rw-r--r--extern/audaspace/include/fx/Reverse.h50
-rw-r--r--extern/audaspace/include/fx/ReverseReader.h65
-rw-r--r--extern/audaspace/include/fx/SoundList.h110
-rw-r--r--extern/audaspace/include/fx/Source.h109
-rw-r--r--extern/audaspace/include/fx/Sum.h49
-rw-r--r--extern/audaspace/include/fx/Threshold.h78
-rw-r--r--extern/audaspace/include/fx/Volume.h63
-rw-r--r--extern/audaspace/include/fx/VolumeReader.h70
-rw-r--r--extern/audaspace/include/fx/VolumeSound.h74
-rw-r--r--extern/audaspace/include/fx/VolumeStorage.h71
-rw-r--r--extern/audaspace/include/generator/Sawtooth.h66
-rw-r--r--extern/audaspace/include/generator/SawtoothReader.h86
-rw-r--r--extern/audaspace/include/generator/Silence.h48
-rw-r--r--extern/audaspace/include/generator/SilenceReader.h59
-rw-r--r--extern/audaspace/include/generator/Sine.h67
-rw-r--r--extern/audaspace/include/generator/SineReader.h77
-rw-r--r--extern/audaspace/include/generator/Square.h67
-rw-r--r--extern/audaspace/include/generator/SquareReader.h86
-rw-r--r--extern/audaspace/include/generator/Triangle.h67
-rw-r--r--extern/audaspace/include/generator/TriangleReader.h86
-rw-r--r--extern/audaspace/include/plugin/PluginManager.h81
-rw-r--r--extern/audaspace/include/respec/ChannelMapper.h51
-rw-r--r--extern/audaspace/include/respec/ChannelMapperReader.h151
-rw-r--r--extern/audaspace/include/respec/Converter.h51
-rw-r--r--extern/audaspace/include/respec/ConverterFunctions.h377
-rw-r--r--extern/audaspace/include/respec/ConverterReader.h67
-rw-r--r--extern/audaspace/include/respec/JOSResample.h50
-rw-r--r--extern/audaspace/include/respec/JOSResampleReader.h129
-rw-r--r--extern/audaspace/include/respec/LinearResample.h50
-rw-r--r--extern/audaspace/include/respec/LinearResampleReader.h80
-rw-r--r--extern/audaspace/include/respec/Mixer.h123
-rw-r--r--extern/audaspace/include/respec/ResampleReader.h61
-rw-r--r--extern/audaspace/include/respec/Specification.h138
-rw-r--r--extern/audaspace/include/respec/SpecsChanger.h74
-rw-r--r--extern/audaspace/include/sequence/AnimateableProperty.h129
-rw-r--r--extern/audaspace/include/sequence/Double.h60
-rw-r--r--extern/audaspace/include/sequence/DoubleReader.h77
-rw-r--r--extern/audaspace/include/sequence/PingPong.h50
-rw-r--r--extern/audaspace/include/sequence/Sequence.h (renamed from intern/audaspace/intern/AUD_SequencerFactory.h)114
-rw-r--r--extern/audaspace/include/sequence/SequenceData.h (renamed from intern/audaspace/intern/AUD_Sequencer.h)115
-rw-r--r--extern/audaspace/include/sequence/SequenceEntry.h (renamed from intern/audaspace/intern/AUD_SequencerEntry.h)116
-rw-r--r--extern/audaspace/include/sequence/SequenceReader.h94
-rw-r--r--extern/audaspace/include/sequence/Superpose.h62
-rw-r--r--extern/audaspace/include/sequence/SuperposeReader.h79
-rw-r--r--extern/audaspace/include/util/Barrier.h78
-rw-r--r--extern/audaspace/include/util/Buffer.h87
-rw-r--r--extern/audaspace/include/util/BufferReader.h76
-rw-r--r--extern/audaspace/include/util/FFTPlan.h120
-rw-r--r--extern/audaspace/include/util/ILockable.h46
-rw-r--r--extern/audaspace/include/util/Math3D.h (renamed from intern/audaspace/intern/AUD_3DMath.h)102
-rw-r--r--extern/audaspace/include/util/StreamBuffer.h85
-rw-r--r--extern/audaspace/include/util/ThreadPool.h119
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEG.cpp63
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEG.h60
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp397
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGReader.h184
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp427
-rw-r--r--extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h145
-rw-r--r--extern/audaspace/plugins/jack/JackDevice.cpp385
-rw-r--r--extern/audaspace/plugins/jack/JackDevice.h (renamed from intern/audaspace/jack/AUD_JackDevice.h)115
-rw-r--r--extern/audaspace/plugins/jack/JackLibrary.cpp59
-rw-r--r--extern/audaspace/plugins/jack/JackLibrary.h48
-rw-r--r--extern/audaspace/plugins/jack/JackSymbols.h45
-rw-r--r--extern/audaspace/plugins/jack/JackSynchronizer.cpp58
-rw-r--r--extern/audaspace/plugins/jack/JackSynchronizer.h59
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFile.cpp62
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFile.h60
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFileReader.cpp161
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFileReader.h125
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFileWriter.cpp128
-rw-r--r--extern/audaspace/plugins/libsndfile/SndFileWriter.h84
-rw-r--r--extern/audaspace/plugins/openal/OpenALDevice.cpp1490
-rw-r--r--extern/audaspace/plugins/openal/OpenALDevice.h (renamed from intern/audaspace/OpenAL/AUD_OpenALDevice.h)198
-rw-r--r--extern/audaspace/plugins/openal/OpenALReader.cpp96
-rw-r--r--extern/audaspace/plugins/openal/OpenALReader.h83
-rw-r--r--extern/audaspace/plugins/sdl/SDLDevice.cpp156
-rw-r--r--extern/audaspace/plugins/sdl/SDLDevice.h82
-rw-r--r--extern/audaspace/src/Exception.cpp110
-rw-r--r--extern/audaspace/src/devices/DefaultSynchronizer.cpp49
-rw-r--r--extern/audaspace/src/devices/DeviceManager.cpp117
-rw-r--r--extern/audaspace/src/devices/NULLDevice.cpp193
-rw-r--r--extern/audaspace/src/devices/ReadDevice.cpp69
-rw-r--r--extern/audaspace/src/devices/SoftwareDevice.cpp989
-rw-r--r--extern/audaspace/src/file/File.cpp45
-rw-r--r--extern/audaspace/src/file/FileManager.cpp88
-rw-r--r--extern/audaspace/src/file/FileWriter.cpp95
-rw-r--r--extern/audaspace/src/fx/ADSR.cpp73
-rw-r--r--extern/audaspace/src/fx/ADSRReader.cpp115
-rw-r--r--extern/audaspace/src/fx/Accumulator.cpp54
-rw-r--r--extern/audaspace/src/fx/BaseIIRFilterReader.cpp125
-rw-r--r--extern/audaspace/src/fx/BinauralReader.cpp255
-rw-r--r--extern/audaspace/src/fx/BinauralSound.cpp60
-rw-r--r--extern/audaspace/src/fx/Butterworth.cpp28
-rw-r--r--extern/audaspace/src/fx/ButterworthCalculator.cpp54
-rw-r--r--extern/audaspace/src/fx/CallbackIIRFilterReader.cpp38
-rw-r--r--extern/audaspace/src/fx/Convolver.cpp156
-rw-r--r--extern/audaspace/src/fx/ConvolverReader.cpp203
-rw-r--r--extern/audaspace/src/fx/ConvolverSound.cpp50
-rw-r--r--extern/audaspace/src/fx/Delay.cpp38
-rw-r--r--extern/audaspace/src/fx/DelayReader.cpp87
-rw-r--r--extern/audaspace/src/fx/DynamicIIRFilter.cpp35
-rw-r--r--extern/audaspace/src/fx/DynamicIIRFilterReader.cpp36
-rw-r--r--extern/audaspace/src/fx/DynamicMusic.cpp346
-rw-r--r--extern/audaspace/src/fx/Effect.cpp35
-rw-r--r--extern/audaspace/src/fx/EffectReader.cpp60
-rw-r--r--extern/audaspace/src/fx/Envelope.cpp71
-rw-r--r--extern/audaspace/src/fx/FFTConvolver.cpp214
-rw-r--r--extern/audaspace/src/fx/Fader.cpp49
-rw-r--r--extern/audaspace/src/fx/FaderReader.cpp76
-rw-r--r--extern/audaspace/src/fx/HRTF.cpp122
-rw-r--r--extern/audaspace/src/fx/HRTFLoaderUnix.cpp89
-rw-r--r--extern/audaspace/src/fx/HRTFLoaderWindows.cpp93
-rw-r--r--extern/audaspace/src/fx/Highpass.cpp28
-rw-r--r--extern/audaspace/src/fx/HighpassCalculator.cpp43
-rw-r--r--extern/audaspace/src/fx/IIRFilter.cpp32
-rw-r--r--extern/audaspace/src/fx/IIRFilterReader.cpp53
-rw-r--r--extern/audaspace/src/fx/ImpulseResponse.cpp97
-rw-r--r--extern/audaspace/src/fx/Limiter.cpp45
-rw-r--r--extern/audaspace/src/fx/LimiterReader.cpp (renamed from intern/audaspace/FX/AUD_LimiterReader.cpp)70
-rw-r--r--extern/audaspace/src/fx/Loop.cpp38
-rw-r--r--extern/audaspace/src/fx/LoopReader.cpp91
-rw-r--r--extern/audaspace/src/fx/Lowpass.cpp27
-rw-r--r--extern/audaspace/src/fx/LowpassCalculator.cpp43
-rw-r--r--extern/audaspace/src/fx/MutableReader.cpp64
-rw-r--r--extern/audaspace/src/fx/MutableSound.cpp35
-rw-r--r--extern/audaspace/src/fx/Pitch.cpp33
-rw-r--r--extern/audaspace/src/fx/PitchReader.cpp44
-rw-r--r--extern/audaspace/src/fx/PlaybackCategory.cpp144
-rw-r--r--extern/audaspace/src/fx/PlaybackManager.cpp186
-rw-r--r--extern/audaspace/src/fx/Reverse.cpp32
-rw-r--r--extern/audaspace/src/fx/ReverseReader.cpp88
-rw-r--r--extern/audaspace/src/fx/SoundList.cpp84
-rw-r--r--extern/audaspace/src/fx/Source.cpp71
-rw-r--r--extern/audaspace/src/fx/Sum.cpp36
-rw-r--r--extern/audaspace/src/fx/Threshold.cpp54
-rw-r--r--extern/audaspace/src/fx/Volume.cpp41
-rw-r--r--extern/audaspace/src/fx/VolumeReader.cpp60
-rw-r--r--extern/audaspace/src/fx/VolumeSound.cpp45
-rw-r--r--extern/audaspace/src/fx/VolumeStorage.cpp39
-rw-r--r--extern/audaspace/src/generator/Sawtooth.cpp38
-rw-r--r--extern/audaspace/src/generator/SawtoothReader.cpp83
-rw-r--r--extern/audaspace/src/generator/Silence.cpp31
-rw-r--r--extern/audaspace/src/generator/SilenceReader.cpp63
-rw-r--r--extern/audaspace/src/generator/Sine.cpp38
-rw-r--r--extern/audaspace/src/generator/SineReader.cpp75
-rw-r--r--extern/audaspace/src/generator/Square.cpp38
-rw-r--r--extern/audaspace/src/generator/SquareReader.cpp83
-rw-r--r--extern/audaspace/src/generator/Triangle.cpp38
-rw-r--r--extern/audaspace/src/generator/TriangleReader.cpp83
-rw-r--r--extern/audaspace/src/plugin/PluginManagerUnix.cpp.in98
-rw-r--r--extern/audaspace/src/plugin/PluginManagerWindows.cpp.in101
-rw-r--r--extern/audaspace/src/respec/ChannelMapper.cpp35
-rw-r--r--extern/audaspace/src/respec/ChannelMapperReader.cpp379
-rw-r--r--extern/audaspace/src/respec/Converter.cpp38
-rw-r--r--extern/audaspace/src/respec/ConverterFunctions.cpp464
-rw-r--r--extern/audaspace/src/respec/ConverterReader.cpp68
-rw-r--r--extern/audaspace/src/respec/JOSResample.cpp33
-rw-r--r--extern/audaspace/src/respec/JOSResampleReader.cpp (renamed from intern/audaspace/intern/AUD_JOSResampleReader.cpp)159
-rw-r--r--extern/audaspace/src/respec/JOSResampleReaderCoeff.cpp (renamed from intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp)48
-rw-r--r--extern/audaspace/src/respec/LinearResample.cpp32
-rw-r--r--extern/audaspace/src/respec/LinearResampleReader.cpp174
-rw-r--r--extern/audaspace/src/respec/Mixer.cpp112
-rw-r--r--extern/audaspace/src/respec/ResampleReader.cpp36
-rw-r--r--extern/audaspace/src/respec/SpecsChanger.cpp42
-rw-r--r--extern/audaspace/src/sequence/AnimateableProperty.cpp217
-rw-r--r--extern/audaspace/src/sequence/Double.cpp35
-rw-r--r--extern/audaspace/src/sequence/DoubleReader.cpp102
-rw-r--r--extern/audaspace/src/sequence/PingPong.cpp36
-rw-r--r--extern/audaspace/src/sequence/Sequence.cpp113
-rw-r--r--extern/audaspace/src/sequence/SequenceData.cpp172
-rw-r--r--extern/audaspace/src/sequence/SequenceEntry.cpp256
-rw-r--r--extern/audaspace/src/sequence/SequenceHandle.cpp (renamed from intern/audaspace/intern/AUD_SequencerHandle.cpp)96
-rw-r--r--extern/audaspace/src/sequence/SequenceHandle.h (renamed from intern/audaspace/intern/AUD_SequencerHandle.h)71
-rw-r--r--extern/audaspace/src/sequence/SequenceReader.cpp198
-rw-r--r--extern/audaspace/src/sequence/Superpose.cpp35
-rw-r--r--extern/audaspace/src/sequence/SuperposeReader.cpp95
-rw-r--r--extern/audaspace/src/util/Barrier.cpp42
-rw-r--r--extern/audaspace/src/util/Buffer.cpp72
-rw-r--r--extern/audaspace/src/util/BufferReader.cpp80
-rw-r--r--extern/audaspace/src/util/FFTPlan.cpp66
-rw-r--r--extern/audaspace/src/util/StreamBuffer.cpp83
-rw-r--r--extern/audaspace/src/util/ThreadPool.cpp60
-rw-r--r--extern/cuew/README.blender2
-rw-r--r--extern/cuew/include/cuew.h177
-rw-r--r--extern/cuew/src/cuew.c25
-rw-r--r--intern/audaspace/CMakeLists.txt304
-rw-r--r--intern/audaspace/COPYING339
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.cpp64
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.h69
-rw-r--r--intern/audaspace/FX/AUD_BandpassCalculator.cpp5
-rw-r--r--intern/audaspace/FX/AUD_BandpassCalculator.h10
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp137
-rw-r--r--intern/audaspace/FX/AUD_ButterworthCalculator.cpp38
-rw-r--r--intern/audaspace/FX/AUD_ButterworthCalculator.h20
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.cpp39
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.h54
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp51
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.h87
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.cpp48
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.h66
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.cpp96
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.h70
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.cpp44
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.h66
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.cpp112
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.h84
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp44
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h58
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp44
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterReader.h54
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.cpp45
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.h82
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.cpp69
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.h74
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.cpp82
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.h85
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.cpp60
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.h92
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.cpp86
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.h76
-rw-r--r--intern/audaspace/FX/AUD_HighpassCalculator.cpp27
-rw-r--r--intern/audaspace/FX/AUD_HighpassCalculator.h25
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.cpp39
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.h55
-rw-r--r--intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h56
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.cpp43
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.h71
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.cpp65
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.h73
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.cpp55
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.h79
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.h71
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.cpp47
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.h68
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.cpp101
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.h72
-rw-r--r--intern/audaspace/FX/AUD_LowpassCalculator.cpp27
-rw-r--r--intern/audaspace/FX/AUD_LowpassCalculator.h25
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.cpp38
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.h55
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.cpp46
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.h56
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.cpp43
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.h61
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.cpp54
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.h73
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.cpp48
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.h58
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.cpp42
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.h56
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.cpp105
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.h72
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.cpp66
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.h70
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.cpp45
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.h55
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.cpp44
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.h68
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.cpp105
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.h85
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.cpp50
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.h69
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp1647
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp2922
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.h74
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.cpp97
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.h86
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.cpp42
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.h57
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.cpp150
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.h103
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp55
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h78
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp483
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h169
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp395
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h160
-rw-r--r--intern/audaspace/fftw/AUD_BandPassFactory.cpp75
-rw-r--r--intern/audaspace/fftw/AUD_BandPassFactory.h92
-rw-r--r--intern/audaspace/fftw/AUD_BandPassReader.cpp127
-rw-r--r--intern/audaspace/fftw/AUD_BandPassReader.h102
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.cpp247
-rw-r--r--intern/audaspace/intern/AUD_AnimateableProperty.h128
-rw-r--r--intern/audaspace/intern/AUD_Buffer.cpp80
-rw-r--r--intern/audaspace/intern/AUD_Buffer.h93
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.cpp90
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.h81
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp1323
-rw-r--r--intern/audaspace/intern/AUD_C-API.h822
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.cpp45
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.h57
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.cpp378
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.h136
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.cpp47
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.h57
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.cpp472
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.h128
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.cpp77
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.h73
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.cpp84
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.h76
-rw-r--r--intern/audaspace/intern/AUD_FileWriter.cpp131
-rw-r--r--intern/audaspace/intern/AUD_FileWriter.h82
-rw-r--r--intern/audaspace/intern/AUD_I3DDevice.h122
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h120
-rw-r--r--intern/audaspace/intern/AUD_IFactory.h61
-rw-r--r--intern/audaspace/intern/AUD_ILockable.h21
-rw-r--r--intern/audaspace/intern/AUD_IWriter.h67
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleFactory.cpp42
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleFactory.h56
-rw-r--r--intern/audaspace/intern/AUD_JOSResampleReader.h135
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.cpp42
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.h56
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.cpp186
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.h86
-rw-r--r--intern/audaspace/intern/AUD_Mixer.cpp121
-rw-r--r--intern/audaspace/intern/AUD_Mixer.h114
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.cpp52
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.h79
-rw-r--r--intern/audaspace/intern/AUD_MutexLock.h24
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp159
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h84
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.cpp78
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.h88
-rw-r--r--intern/audaspace/intern/AUD_ResampleFactory.h37
-rw-r--r--intern/audaspace/intern/AUD_ResampleReader.cpp45
-rw-r--r--intern/audaspace/intern/AUD_ResampleReader.h66
-rw-r--r--intern/audaspace/intern/AUD_Sequencer.cpp177
-rw-r--r--intern/audaspace/intern/AUD_SequencerEntry.cpp319
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.cpp123
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.cpp204
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.h99
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.cpp41
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.h54
-rw-r--r--intern/audaspace/intern/AUD_SilenceReader.cpp72
-rw-r--r--intern/audaspace/intern/AUD_SilenceReader.h66
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.cpp48
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.h72
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.cpp83
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.h78
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp995
-rw-r--r--intern/audaspace/intern/AUD_Space.h257
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.cpp76
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.h71
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.cpp348
-rw-r--r--intern/audaspace/jack/AUD_JackLibrary.cpp128
-rw-r--r--intern/audaspace/jack/AUD_JackLibrary.h104
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.cpp52
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.h76
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.cpp171
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.h128
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileWriter.cpp139
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileWriter.h86
-rw-r--r--intern/cycles/blender/addon/presets.py2
-rw-r--r--intern/cycles/blender/addon/properties.py19
-rw-r--r--intern/cycles/blender/addon/ui.py18
-rw-r--r--intern/cycles/blender/addon/version_update.py33
-rw-r--r--intern/cycles/blender/blender_camera.cpp11
-rw-r--r--intern/cycles/blender/blender_object.cpp14
-rw-r--r--intern/cycles/blender/blender_shader.cpp13
-rw-r--r--intern/cycles/blender/blender_sync.cpp50
-rw-r--r--intern/cycles/bvh/bvh.cpp8
-rw-r--r--intern/cycles/bvh/bvh2.cpp4
-rw-r--r--intern/cycles/bvh/bvh4.cpp4
-rw-r--r--intern/cycles/bvh/bvh_build.cpp8
-rw-r--r--intern/cycles/device/CMakeLists.txt2
-rw-r--r--intern/cycles/device/device.cpp2
-rw-r--r--intern/cycles/device/device.h2
-rw-r--r--intern/cycles/device/device_cpu.cpp2
-rw-r--r--intern/cycles/device/device_cuda.cpp11
-rw-r--r--intern/cycles/device/device_opencl.cpp1
-rw-r--r--intern/cycles/device/opencl/memory_manager.cpp253
-rw-r--r--intern/cycles/device/opencl/memory_manager.h105
-rw-r--r--intern/cycles/device/opencl/opencl.h51
-rw-r--r--intern/cycles/device/opencl/opencl_base.cpp150
-rw-r--r--intern/cycles/device/opencl/opencl_mega.cpp5
-rw-r--r--intern/cycles/device/opencl/opencl_split.cpp25
-rw-r--r--intern/cycles/device/opencl/opencl_util.cpp2
-rw-r--r--intern/cycles/kernel/CMakeLists.txt3
-rw-r--r--intern/cycles/kernel/bvh/bvh.h12
-rw-r--r--intern/cycles/kernel/bvh/bvh_shadow_all.h71
-rw-r--r--intern/cycles/kernel/bvh/bvh_traversal.h60
-rw-r--r--intern/cycles/kernel/bvh/qbvh_shadow_all.h65
-rw-r--r--intern/cycles/kernel/bvh/qbvh_traversal.h54
-rw-r--r--intern/cycles/kernel/filter/filter_features_sse.h80
-rw-r--r--intern/cycles/kernel/filter/filter_nlm_cpu.h18
-rw-r--r--intern/cycles/kernel/filter/filter_prefilter.h2
-rw-r--r--intern/cycles/kernel/filter/filter_transform_sse.h16
-rw-r--r--intern/cycles/kernel/geom/geom.h1
-rw-r--r--intern/cycles/kernel/geom/geom_curve.h904
-rw-r--r--intern/cycles/kernel/geom/geom_curve_intersect.h934
-rw-r--r--intern/cycles/kernel/geom/geom_object.h5
-rw-r--r--intern/cycles/kernel/kernel_accumulate.h30
-rw-r--r--intern/cycles/kernel/kernel_compat_cuda.h4
-rw-r--r--intern/cycles/kernel/kernel_compat_opencl.h5
-rw-r--r--intern/cycles/kernel/kernel_debug.h56
-rw-r--r--intern/cycles/kernel/kernel_globals.h68
-rw-r--r--intern/cycles/kernel/kernel_image_opencl.h66
-rw-r--r--intern/cycles/kernel/kernel_passes.h39
-rw-r--r--intern/cycles/kernel/kernel_path.h75
-rw-r--r--intern/cycles/kernel/kernel_path_branched.h65
-rw-r--r--intern/cycles/kernel/kernel_path_state.h10
-rw-r--r--intern/cycles/kernel/kernel_random.h202
-rw-r--r--intern/cycles/kernel/kernel_shader.h6
-rw-r--r--intern/cycles/kernel/kernel_shadow.h84
-rw-r--r--intern/cycles/kernel/kernel_textures.h11
-rw-r--r--intern/cycles/kernel/kernel_types.h68
-rw-r--r--intern/cycles/kernel/kernels/cpu/filter_sse41.cpp1
-rw-r--r--intern/cycles/kernel/kernels/cuda/kernel_config.h9
-rw-r--r--intern/cycles/kernel/kernels/cuda/kernel_split.cu4
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel.cl47
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel_data_init.cl11
-rw-r--r--intern/cycles/kernel/kernels/opencl/kernel_split_function.h9
-rw-r--r--intern/cycles/kernel/split/kernel_buffer_update.h19
-rw-r--r--intern/cycles/kernel/split/kernel_data_init.h29
-rw-r--r--intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h19
-rw-r--r--intern/cycles/kernel/split/kernel_indirect_background.h3
-rw-r--r--intern/cycles/kernel/split/kernel_path_init.h8
-rw-r--r--intern/cycles/kernel/split/kernel_scene_intersect.h13
-rw-r--r--intern/cycles/kernel/split/kernel_shader_sort.h10
-rw-r--r--intern/cycles/kernel/split/kernel_split_data_types.h12
-rw-r--r--intern/cycles/render/image.cpp170
-rw-r--r--intern/cycles/render/image.h15
-rw-r--r--intern/cycles/render/integrator.cpp18
-rw-r--r--intern/cycles/render/integrator.h1
-rw-r--r--intern/cycles/render/light.cpp2
-rw-r--r--intern/cycles/render/mesh.cpp11
-rw-r--r--intern/cycles/render/object.cpp11
-rw-r--r--intern/cycles/render/object.h7
-rw-r--r--intern/cycles/render/osl.cpp6
-rw-r--r--intern/cycles/render/scene.cpp2
-rw-r--r--intern/cycles/render/scene.h7
-rw-r--r--intern/cycles/render/session.cpp3
-rw-r--r--intern/cycles/render/session.h3
-rw-r--r--intern/cycles/render/shader.cpp4
-rw-r--r--intern/cycles/render/tile.cpp12
-rw-r--r--intern/cycles/render/tile.h3
-rw-r--r--intern/cycles/util/CMakeLists.txt1
-rw-r--r--intern/cycles/util/util_defines.h135
-rw-r--r--intern/cycles/util/util_math.h1
-rw-r--r--intern/cycles/util/util_math_float3.h20
-rw-r--r--intern/cycles/util/util_math_float4.h109
-rw-r--r--intern/cycles/util/util_math_matrix.h56
-rw-r--r--intern/cycles/util/util_optimization.h52
-rw-r--r--intern/cycles/util/util_simd.h174
-rw-r--r--intern/cycles/util/util_sseb.h3
-rw-r--r--intern/cycles/util/util_ssef.h3
-rw-r--r--intern/cycles/util/util_ssei.h9
-rw-r--r--intern/cycles/util/util_types.h131
-rw-r--r--intern/gawain/CMakeLists.txt48
-rw-r--r--intern/gawain/gawain/gwn_attr_binding.h (renamed from intern/gawain/gawain/attrib_binding.h)4
-rw-r--r--intern/gawain/gawain/gwn_attr_binding_private.h (renamed from intern/gawain/gawain/attrib_binding_private.h)4
-rw-r--r--intern/gawain/gawain/gwn_batch.h (renamed from intern/gawain/gawain/batch.h)41
-rw-r--r--intern/gawain/gawain/gwn_buffer_id.h (renamed from intern/gawain/gawain/buffer_id.h)2
-rw-r--r--intern/gawain/gawain/gwn_common.h (renamed from intern/gawain/gawain/common.h)0
-rw-r--r--intern/gawain/gawain/gwn_element.h (renamed from intern/gawain/gawain/element.h)6
-rw-r--r--intern/gawain/gawain/gwn_imm_util.h (renamed from intern/gawain/gawain/imm_util.h)0
-rw-r--r--intern/gawain/gawain/gwn_immediate.h (renamed from intern/gawain/gawain/immediate.h)8
-rw-r--r--intern/gawain/gawain/gwn_primitive.h (renamed from intern/gawain/gawain/primitive.h)2
-rw-r--r--intern/gawain/gawain/gwn_primitive_private.h (renamed from intern/gawain/gawain/primitive_private.h)0
-rw-r--r--intern/gawain/gawain/gwn_shader_interface.h (renamed from intern/gawain/gawain/shader_interface.h)6
-rw-r--r--intern/gawain/gawain/gwn_vertex_buffer.h (renamed from intern/gawain/gawain/vertex_buffer.h)6
-rw-r--r--intern/gawain/gawain/gwn_vertex_format.h (renamed from intern/gawain/gawain/vertex_format.h)8
-rw-r--r--intern/gawain/gawain/gwn_vertex_format_private.h (renamed from intern/gawain/gawain/vertex_format_private.h)0
-rw-r--r--intern/gawain/src/gwn_attr_binding.c (renamed from intern/gawain/src/attrib_binding.c)4
-rw-r--r--intern/gawain/src/gwn_batch.c (renamed from intern/gawain/src/batch.c)58
-rw-r--r--intern/gawain/src/gwn_buffer_id.cpp (renamed from intern/gawain/src/buffer_id.cpp)2
-rw-r--r--intern/gawain/src/gwn_element.c (renamed from intern/gawain/src/element.c)4
-rw-r--r--intern/gawain/src/gwn_imm_util.c (renamed from intern/gawain/src/imm_util.c)4
-rw-r--r--intern/gawain/src/gwn_immediate.c (renamed from intern/gawain/src/immediate.c)12
-rw-r--r--intern/gawain/src/gwn_primitive.c (renamed from intern/gawain/src/primitive.c)4
-rw-r--r--intern/gawain/src/gwn_shader_interface.c (renamed from intern/gawain/src/shader_interface.c)2
-rw-r--r--intern/gawain/src/gwn_vertex_buffer.c (renamed from intern/gawain/src/vertex_buffer.c)6
-rw-r--r--intern/gawain/src/gwn_vertex_format.c (renamed from intern/gawain/src/vertex_format.c)4
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.cpp2
-rw-r--r--intern/ghost/intern/GHOST_ContextGLX.h2
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp2
-rw-r--r--intern/itasc/FixedObject.hpp2
-rw-r--r--intern/itasc/MovingFrame.cpp2
-rw-r--r--intern/itasc/MovingFrame.hpp9
-rw-r--r--intern/itasc/Scene.cpp2
-rw-r--r--intern/itasc/Scene.hpp2
-rw-r--r--intern/itasc/UncontrolledObject.hpp2
-rw-r--r--intern/itasc/WorldObject.hpp2
-rw-r--r--intern/opencolorio/ocio_impl_glsl.cc2
-rw-r--r--intern/opensubdiv/opensubdiv_gpu_capi.cc2
-rw-r--r--release/scripts/presets/cycles/integrator/direct_light.py2
-rw-r--r--release/scripts/presets/cycles/integrator/full_global_illumination.py2
-rw-r--r--release/scripts/presets/cycles/integrator/limited_global_illumination.py2
-rw-r--r--release/scripts/presets/cycles/sampling/final.py22
-rw-r--r--release/scripts/presets/cycles/sampling/preview.py22
-rw-r--r--release/scripts/startup/bl_operators/clip.py7
-rw-r--r--release/scripts/startup/bl_ui/properties_material.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_common.py2
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_softbody.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_render.py7
-rw-r--r--release/scripts/startup/bl_ui/properties_render_layer.py6
-rw-r--r--release/scripts/startup/bl_ui/space_sequencer.py3
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py11
-rw-r--r--release/scripts/startup/nodeitems_builtins.py10
-rw-r--r--release/windows/blendthumb/CMakeLists.txt42
-rw-r--r--release/windows/blendthumb/src/BlendThumb.def5
-rw-r--r--release/windows/blendthumb/src/BlendThumb.rc26
-rw-r--r--release/windows/blendthumb/src/BlenderThumb.cpp324
-rw-r--r--release/windows/blendthumb/src/Dll.cpp277
-rw-r--r--source/blender/alembic/intern/abc_customdata.cc48
-rw-r--r--source/blender/alembic/intern/abc_customdata.h3
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc70
-rw-r--r--source/blender/alembic/intern/abc_mesh.h5
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h35
-rw-r--r--source/blender/blenkernel/BKE_action.h6
-rw-r--r--source/blender/blenkernel/BKE_anim.h6
-rw-r--r--source/blender/blenkernel/BKE_animsys.h10
-rw-r--r--source/blender/blenkernel/BKE_armature.h27
-rw-r--r--source/blender/blenkernel/BKE_brush.h1
-rw-r--r--source/blender/blenkernel/BKE_cachefile.h2
-rw-r--r--source/blender/blenkernel/BKE_camera.h1
-rw-r--r--source/blender/blenkernel/BKE_cloth.h2
-rw-r--r--source/blender/blenkernel/BKE_constraint.h9
-rw-r--r--source/blender/blenkernel/BKE_crazyspace.h8
-rw-r--r--source/blender/blenkernel/BKE_curve.h22
-rw-r--r--source/blender/blenkernel/BKE_data_transfer.h6
-rw-r--r--source/blender/blenkernel/BKE_displist.h29
-rw-r--r--source/blender/blenkernel/BKE_dynamicpaint.h4
-rw-r--r--source/blender/blenkernel/BKE_editmesh.h3
-rw-r--r--source/blender/blenkernel/BKE_effect.h9
-rw-r--r--source/blender/blenkernel/BKE_fluidsim.h2
-rw-r--r--source/blender/blenkernel/BKE_font.h1
-rw-r--r--source/blender/blenkernel/BKE_freestyle.h2
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h1
-rw-r--r--source/blender/blenkernel/BKE_group.h3
-rw-r--r--source/blender/blenkernel/BKE_idprop.h4
-rw-r--r--source/blender/blenkernel/BKE_image.h1
-rw-r--r--source/blender/blenkernel/BKE_key.h1
-rw-r--r--source/blender/blenkernel/BKE_lamp.h1
-rw-r--r--source/blender/blenkernel/BKE_lattice.h13
-rw-r--r--source/blender/blenkernel/BKE_layer.h6
-rw-r--r--source/blender/blenkernel/BKE_library.h70
-rw-r--r--source/blender/blenkernel/BKE_lightprobe.h3
-rw-r--r--source/blender/blenkernel/BKE_linestyle.h15
-rw-r--r--source/blender/blenkernel/BKE_mask.h1
-rw-r--r--source/blender/blenkernel/BKE_material.h3
-rw-r--r--source/blender/blenkernel/BKE_mball.h5
-rw-r--r--source/blender/blenkernel/BKE_mball_tessellate.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h7
-rw-r--r--source/blender/blenkernel/BKE_modifier.h21
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h1
-rw-r--r--source/blender/blenkernel/BKE_multires.h12
-rw-r--r--source/blender/blenkernel/BKE_node.h4
-rw-r--r--source/blender/blenkernel/BKE_object.h58
-rw-r--r--source/blender/blenkernel/BKE_paint.h11
-rw-r--r--source/blender/blenkernel/BKE_particle.h17
-rw-r--r--source/blender/blenkernel/BKE_pointcache.h2
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h16
-rw-r--r--source/blender/blenkernel/BKE_sca.h14
-rw-r--r--source/blender/blenkernel/BKE_scene.h8
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h9
-rw-r--r--source/blender/blenkernel/BKE_smoke.h2
-rw-r--r--source/blender/blenkernel/BKE_softbody.h2
-rw-r--r--source/blender/blenkernel/BKE_sound.h10
-rw-r--r--source/blender/blenkernel/BKE_speaker.h1
-rw-r--r--source/blender/blenkernel/BKE_text.h1
-rw-r--r--source/blender/blenkernel/BKE_texture.h7
-rw-r--r--source/blender/blenkernel/BKE_tracking.h2
-rw-r--r--source/blender/blenkernel/BKE_world.h3
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c108
-rw-r--r--source/blender/blenkernel/intern/action.c88
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c17
-rw-r--r--source/blender/blenkernel/intern/appdir.c12
-rw-r--r--source/blender/blenkernel/intern/armature.c86
-rw-r--r--source/blender/blenkernel/intern/armature_update.c27
-rw-r--r--source/blender/blenkernel/intern/blender_copybuffer.c5
-rw-r--r--source/blender/blenkernel/intern/blendfile.c7
-rw-r--r--source/blender/blenkernel/intern/brush.c50
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c13
-rw-r--r--source/blender/blenkernel/intern/cachefile.c28
-rw-r--r--source/blender/blenkernel/intern/camera.c25
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c17
-rw-r--r--source/blender/blenkernel/intern/cloth.c5
-rw-r--r--source/blender/blenkernel/intern/constraint.c46
-rw-r--r--source/blender/blenkernel/intern/crazyspace.c14
-rw-r--r--source/blender/blenkernel/intern/curve.c88
-rw-r--r--source/blender/blenkernel/intern/data_transfer.c7
-rw-r--r--source/blender/blenkernel/intern/displist.c60
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c35
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c16
-rw-r--r--source/blender/blenkernel/intern/effect.c17
-rw-r--r--source/blender/blenkernel/intern/fluidsim.c4
-rw-r--r--source/blender/blenkernel/intern/font.c19
-rw-r--r--source/blender/blenkernel/intern/freestyle.c18
-rw-r--r--source/blender/blenkernel/intern/gpencil.c81
-rw-r--r--source/blender/blenkernel/intern/group.c35
-rw-r--r--source/blender/blenkernel/intern/idprop.c70
-rw-r--r--source/blender/blenkernel/intern/image.c66
-rw-r--r--source/blender/blenkernel/intern/key.c51
-rw-r--r--source/blender/blenkernel/intern/lamp.c56
-rw-r--r--source/blender/blenkernel/intern/lattice.c56
-rw-r--r--source/blender/blenkernel/intern/layer.c6
-rw-r--r--source/blender/blenkernel/intern/library.c522
-rw-r--r--source/blender/blenkernel/intern/library_remap.c110
-rw-r--r--source/blender/blenkernel/intern/lightprobe.c26
-rw-r--r--source/blender/blenkernel/intern/linestyle.c127
-rw-r--r--source/blender/blenkernel/intern/mask.c32
-rw-r--r--source/blender/blenkernel/intern/material.c73
-rw-r--r--source/blender/blenkernel/intern/mball.c60
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c4
-rw-r--r--source/blender/blenkernel/intern/mesh.c73
-rw-r--r--source/blender/blenkernel/intern/mesh_remap.c17
-rw-r--r--source/blender/blenkernel/intern/mesh_sample.c2
-rw-r--r--source/blender/blenkernel/intern/modifier.c37
-rw-r--r--source/blender/blenkernel/intern/movieclip.c38
-rw-r--r--source/blender/blenkernel/intern/multires.c14
-rw-r--r--source/blender/blenkernel/intern/nla.c2
-rw-r--r--source/blender/blenkernel/intern/node.c290
-rw-r--r--source/blender/blenkernel/intern/object.c204
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c10
-rw-r--r--source/blender/blenkernel/intern/object_update.c23
-rw-r--r--source/blender/blenkernel/intern/paint.c72
-rw-r--r--source/blender/blenkernel/intern/particle.c63
-rw-r--r--source/blender/blenkernel/intern/particle_system.c8
-rw-r--r--source/blender/blenkernel/intern/pointcache.c9
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c62
-rw-r--r--source/blender/blenkernel/intern/sca.c32
-rw-r--r--source/blender/blenkernel/intern/scene.c573
-rw-r--r--source/blender/blenkernel/intern/screen.c1
-rw-r--r--source/blender/blenkernel/intern/sequencer.c49
-rw-r--r--source/blender/blenkernel/intern/smoke.c18
-rw-r--r--source/blender/blenkernel/intern/softbody.c18
-rw-r--r--source/blender/blenkernel/intern/sound.c63
-rw-r--r--source/blender/blenkernel/intern/speaker.c28
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c19
-rw-r--r--source/blender/blenkernel/intern/text.c72
-rw-r--r--source/blender/blenkernel/intern/texture.c102
-rw-r--r--source/blender/blenkernel/intern/tracking.c44
-rw-r--r--source/blender/blenkernel/intern/tracking_auto.c109
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c146
-rw-r--r--source/blender/blenkernel/intern/workspace.c2
-rw-r--r--source/blender/blenkernel/intern/world.c56
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c4
-rw-r--r--source/blender/blenkernel/tracking_private.h1
-rw-r--r--source/blender/blenlib/BLI_ghash.h2
-rw-r--r--source/blender/blenlib/BLI_math_geom.h10
-rw-r--r--source/blender/blenlib/BLI_vfontdata.h2
-rw-r--r--source/blender/blenlib/intern/BLI_memiter.c4
-rw-r--r--source/blender/blenlib/intern/freetypefont.c30
-rw-r--r--source/blender/blenlib/intern/math_geom.c40
-rw-r--r--source/blender/blenloader/intern/readfile.c2
-rw-r--r--source/blender/blenloader/intern/versioning_280.c71
-rw-r--r--source/blender/blenloader/intern/writefile.c3
-rw-r--r--source/blender/blentranslation/CMakeLists.txt4
-rw-r--r--source/blender/blentranslation/msgfmt/msgfmt.c9
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.c69
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c231
-rw-r--r--source/blender/collada/AnimationExporter.cpp2
-rw-r--r--source/blender/collada/AnimationExporter.h4
-rw-r--r--source/blender/collada/ArmatureExporter.cpp4
-rw-r--r--source/blender/collada/ArmatureExporter.h4
-rw-r--r--source/blender/collada/ControllerExporter.cpp2
-rw-r--r--source/blender/collada/ControllerExporter.h4
-rw-r--r--source/blender/collada/DocumentExporter.cpp2
-rw-r--r--source/blender/collada/DocumentExporter.h2
-rw-r--r--source/blender/collada/GeometryExporter.cpp2
-rw-r--r--source/blender/collada/GeometryExporter.h4
-rw-r--r--source/blender/collada/SceneExporter.cpp6
-rw-r--r--source/blender/collada/SceneExporter.h6
-rw-r--r--source/blender/collada/collada.cpp2
-rw-r--r--source/blender/collada/collada.h2
-rw-r--r--source/blender/collada/collada_utils.cpp2
-rw-r--r--source/blender/collada/collada_utils.h2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc1
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc101
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc2
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc29
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.cc1
-rw-r--r--source/blender/draw/CMakeLists.txt4
-rw-r--r--source/blender/draw/engines/clay/clay_engine.c2
-rw-r--r--source/blender/draw/engines/eevee/eevee_effects.c279
-rw-r--r--source/blender/draw/engines/eevee/eevee_engine.c47
-rw-r--r--source/blender/draw/engines/eevee/eevee_lightprobes.c47
-rw-r--r--source/blender/draw/engines/eevee/eevee_lut.h11011
-rw-r--r--source/blender/draw/engines/eevee/eevee_materials.c269
-rw-r--r--source/blender/draw/engines/eevee/eevee_private.h58
-rw-r--r--source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl413
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl145
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl6
-rw-r--r--source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl10
-rw-r--r--source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl59
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl11
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl30
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl22
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl69
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl43
-rw-r--r--source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl168
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl7
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl3
-rw-r--r--source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl41
-rw-r--r--source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl325
-rw-r--r--source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl148
-rw-r--r--source/blender/draw/engines/eevee/shaders/ssr_lib.glsl72
-rw-r--r--source/blender/draw/intern/draw_cache.c153
-rw-r--r--source/blender/draw/intern/draw_cache_impl.h7
-rw-r--r--source/blender/draw/intern/draw_cache_impl_curve.c61
-rw-r--r--source/blender/draw/intern/draw_cache_impl_displist.c4
-rw-r--r--source/blender/draw/intern/draw_cache_impl_lattice.c6
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c612
-rw-r--r--source/blender/draw/intern/draw_manager.c59
-rw-r--r--source/blender/draw/intern/draw_manager_profiling.c8
-rw-r--r--source/blender/draw/intern/draw_view.c2
-rw-r--r--source/blender/draw/modes/object_mode.c6
-rw-r--r--source/blender/draw/modes/shaders/object_outline_detect_frag.glsl42
-rw-r--r--source/blender/draw/modes/shaders/object_outline_expand_frag.glsl43
-rw-r--r--source/blender/draw/modes/shaders/object_particle_prim_vert.glsl14
-rw-r--r--source/blender/editors/animation/anim_filter.c2
-rw-r--r--source/blender/editors/animation/keyframing.c46
-rw-r--r--source/blender/editors/armature/armature_edit.c28
-rw-r--r--source/blender/editors/armature/armature_relations.c4
-rw-r--r--source/blender/editors/armature/armature_select.c20
-rw-r--r--source/blender/editors/armature/editarmature_sketch.c14
-rw-r--r--source/blender/editors/armature/pose_select.c2
-rw-r--r--source/blender/editors/curve/editcurve.c2
-rw-r--r--source/blender/editors/curve/editcurve_paint.c9
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c7
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c81
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c7
-rw-r--r--source/blender/editors/include/ED_armature.h6
-rw-r--r--source/blender/editors/include/ED_manipulator_library.h5
-rw-r--r--source/blender/editors/include/ED_mesh.h24
-rw-r--r--source/blender/editors/include/ED_particle.h9
-rw-r--r--source/blender/editors/include/ED_transform.h14
-rw-r--r--source/blender/editors/include/ED_transform_snap_object_context.h20
-rw-r--r--source/blender/editors/include/ED_view3d.h39
-rw-r--r--source/blender/editors/include/UI_resources.h7
-rw-r--r--source/blender/editors/interface/interface_draw.c10
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c5
-rw-r--r--source/blender/editors/interface/interface_handlers.c9
-rw-r--r--source/blender/editors/interface/interface_layout.c13
-rw-r--r--source/blender/editors/interface/resources.c69
-rw-r--r--source/blender/editors/io/io_cache.c2
-rw-r--r--source/blender/editors/manipulator_library/manipulator_draw_utils.c6
-rw-r--r--source/blender/editors/manipulator_library/manipulator_library_intern.h4
-rw-r--r--source/blender/editors/manipulator_library/manipulator_library_presets.c6
-rw-r--r--source/blender/editors/manipulator_library/manipulator_library_utils.c22
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c23
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/arrow3d_manipulator.c62
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c119
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/dial3d_manipulator.c34
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c194
-rw-r--r--source/blender/editors/manipulator_library/manipulator_types/primitive3d_manipulator.c37
-rw-r--r--source/blender/editors/mesh/editface.c4
-rw-r--r--source/blender/editors/mesh/editmesh_bisect.c10
-rw-r--r--source/blender/editors/mesh/editmesh_extrude.c14
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c70
-rw-r--r--source/blender/editors/mesh/editmesh_loopcut.c15
-rw-r--r--source/blender/editors/mesh/editmesh_path.c16
-rw-r--r--source/blender/editors/mesh/editmesh_select.c84
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c4
-rw-r--r--source/blender/editors/mesh/editmesh_utils.c2
-rw-r--r--source/blender/editors/mesh/meshtools.c12
-rw-r--r--source/blender/editors/metaball/mball_edit.c4
-rw-r--r--source/blender/editors/object/object_add.c151
-rw-r--r--source/blender/editors/object/object_bake.c4
-rw-r--r--source/blender/editors/object/object_constraint.c6
-rw-r--r--source/blender/editors/object/object_edit.c38
-rw-r--r--source/blender/editors/object/object_group.c2
-rw-r--r--source/blender/editors/object/object_relations.c14
-rw-r--r--source/blender/editors/object/object_select.c4
-rw-r--r--source/blender/editors/object/object_transform.c26
-rw-r--r--source/blender/editors/physics/particle_edit.c97
-rw-r--r--source/blender/editors/physics/particle_object.c54
-rw-r--r--source/blender/editors/physics/physics_fluid.c4
-rw-r--r--source/blender/editors/physics/rigidbody_constraint.c4
-rw-r--r--source/blender/editors/render/render_internal.c9
-rw-r--r--source/blender/editors/render/render_shading.c8
-rw-r--r--source/blender/editors/render/render_update.c2
-rw-r--r--source/blender/editors/screen/screen_edit.c12
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c2
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c7
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c10
-rw-r--r--source/blender/editors/sculpt_paint/paint_vertex.c16
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c2
-rw-r--r--source/blender/editors/sound/CMakeLists.txt2
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_clip/space_clip.c3
-rw-r--r--source/blender/editors/space_clip/tracking_ops_orient.c4
-rw-r--r--source/blender/editors/space_graph/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_graph/graph_draw.c6
-rw-r--r--source/blender/editors/space_graph/graph_edit.c2
-rw-r--r--source/blender/editors/space_image/image_edit.c2
-rw-r--r--source/blender/editors/space_image/space_image.c2
-rw-r--r--source/blender/editors/space_logic/logic_window.c2
-rw-r--r--source/blender/editors/space_nla/nla_draw.c107
-rw-r--r--source/blender/editors/space_node/node_edit.c4
-rw-r--r--source/blender/editors/space_node/node_intern.h2
-rw-r--r--source/blender/editors/space_node/node_manipulators.c258
-rw-r--r--source/blender/editors/space_node/space_node.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_draw.c12
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c2
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c22
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c6
-rw-r--r--source/blender/editors/space_sequencer/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_add.c2
-rw-r--r--source/blender/editors/space_sequencer/sequencer_draw.c13
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c10
-rw-r--r--source/blender/editors/space_sequencer/space_sequencer.c3
-rw-r--r--source/blender/editors/space_text/text_format_pov.c912
-rw-r--r--source/blender/editors/space_text/text_format_pov_ini.c129
-rw-r--r--source/blender/editors/space_view3d/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c100
-rw-r--r--source/blender/editors/space_view3d/drawobject.c364
-rw-r--r--source/blender/editors/space_view3d/space_view3d.c3
-rw-r--r--source/blender/editors/space_view3d/view3d_buttons.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c69
-rw-r--r--source/blender/editors/space_view3d/view3d_draw_legacy.c164
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c43
-rw-r--r--source/blender/editors/space_view3d/view3d_header.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h56
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c28
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_armature.c220
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_camera.c31
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_empty.c211
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_forcefield.c10
-rw-r--r--source/blender/editors/space_view3d/view3d_manipulator_lamp.c33
-rw-r--r--source/blender/editors/space_view3d/view3d_ruler.c15
-rw-r--r--source/blender/editors/space_view3d/view3d_select.c172
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c8
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c15
-rw-r--r--source/blender/editors/transform/transform.c2
-rw-r--r--source/blender/editors/transform/transform_conversions.c18
-rw-r--r--source/blender/editors/transform/transform_generics.c10
-rw-r--r--source/blender/editors/transform/transform_manipulator.c18
-rw-r--r--source/blender/editors/transform/transform_manipulator2d.c8
-rw-r--r--source/blender/editors/transform/transform_orientations.c6
-rw-r--r--source/blender/editors/transform/transform_snap.c25
-rw-r--r--source/blender/editors/transform/transform_snap_object.c132
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c8
-rw-r--r--source/blender/gpu/GPU_batch.h8
-rw-r--r--source/blender/gpu/GPU_immediate.h8
-rw-r--r--source/blender/gpu/GPU_lamp.h2
-rw-r--r--source/blender/gpu/GPU_matrix.h3
-rw-r--r--source/blender/gpu/GPU_shader.h1
-rw-r--r--source/blender/gpu/GPU_texture.h2
-rw-r--r--source/blender/gpu/GPU_uniformbuffer.h1
-rw-r--r--source/blender/gpu/intern/gpu_batch.c20
-rw-r--r--source/blender/gpu/intern/gpu_compositing.c8
-rw-r--r--source/blender/gpu/intern/gpu_draw.c2
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c9
-rw-r--r--source/blender/gpu/intern/gpu_lamp.c6
-rw-r--r--source/blender/gpu/intern/gpu_material.c4
-rw-r--r--source/blender/gpu/intern/gpu_shader.c2
-rw-r--r--source/blender/gpu/intern/gpu_shader_private.h2
-rw-r--r--source/blender/gpu/intern/gpu_texture.c5
-rw-r--r--source/blender/gpu/intern/gpu_uniformbuffer.c91
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl52
-rw-r--r--source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl12
-rw-r--r--source/blender/ikplugin/BIK_api.h4
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.c4
-rw-r--r--source/blender/ikplugin/intern/ikplugin_api.h4
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c6
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.h8
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.cpp16
-rw-r--r--source/blender/ikplugin/intern/itasc_plugin.h4
-rw-r--r--source/blender/imbuf/intern/colormanagement.c8
-rw-r--r--source/blender/imbuf/intern/jp2.c2
-rw-r--r--source/blender/imbuf/intern/png.c2
-rw-r--r--source/blender/imbuf/intern/tiff.c2
-rw-r--r--source/blender/makesdna/DNA_ID.h12
-rw-r--r--source/blender/makesdna/DNA_material_types.h6
-rw-r--r--source/blender/makesdna/DNA_scene_types.h19
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h10
-rw-r--r--source/blender/makesrna/RNA_access.h2
-rw-r--r--source/blender/makesrna/RNA_define.h3
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt2
-rw-r--r--source/blender/makesrna/intern/makesrna.c20
-rw-r--r--source/blender/makesrna/intern/rna_access.c13
-rw-r--r--source/blender/makesrna/intern/rna_armature.c2
-rw-r--r--source/blender/makesrna/intern/rna_curve_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_define.c77
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_material.c12
-rw-r--r--source/blender/makesrna/intern/rna_meta_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c7
-rw-r--r--source/blender/makesrna/intern/rna_render.c16
-rw-r--r--source/blender/makesrna/intern/rna_rna.c24
-rw-r--r--source/blender/makesrna/intern/rna_scene.c97
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c5
-rw-r--r--source/blender/makesrna/intern/rna_sculpt_paint.c16
-rw-r--r--source/blender/makesrna/intern/rna_space.c4
-rw-r--r--source/blender/makesrna/intern/rna_ui.c10
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c76
-rw-r--r--source/blender/makesrna/intern/rna_wm.c3
-rw-r--r--source/blender/makesrna/intern/rna_wm_manipulator.c7
-rw-r--r--source/blender/makesrna/intern/rna_wm_manipulator_api.c6
-rw-r--r--source/blender/modifiers/intern/MOD_armature.c16
-rw-r--r--source/blender/modifiers/intern/MOD_array.c4
-rw-r--r--source/blender/modifiers/intern/MOD_bevel.c16
-rw-r--r--source/blender/modifiers/intern/MOD_boolean.c2
-rw-r--r--source/blender/modifiers/intern/MOD_build.c2
-rw-r--r--source/blender/modifiers/intern/MOD_cast.c4
-rw-r--r--source/blender/modifiers/intern/MOD_cloth.c2
-rw-r--r--source/blender/modifiers/intern/MOD_collision.c4
-rw-r--r--source/blender/modifiers/intern/MOD_correctivesmooth.c4
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c4
-rw-r--r--source/blender/modifiers/intern/MOD_datatransfer.c2
-rw-r--r--source/blender/modifiers/intern/MOD_decimate.c2
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c10
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c2
-rw-r--r--source/blender/modifiers/intern/MOD_edgesplit.c2
-rw-r--r--source/blender/modifiers/intern/MOD_explode.c9
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim.c2
-rw-r--r--source/blender/modifiers/intern/MOD_hair.c2
-rw-r--r--source/blender/modifiers/intern/MOD_hook.c4
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciandeform.c6
-rw-r--r--source/blender/modifiers/intern/MOD_laplaciansmooth.c4
-rw-r--r--source/blender/modifiers/intern/MOD_lattice.c4
-rw-r--r--source/blender/modifiers/intern/MOD_mask.c2
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache.c4
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c2
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c6
-rw-r--r--source/blender/modifiers/intern/MOD_meshsequencecache.c28
-rw-r--r--source/blender/modifiers/intern/MOD_mirror.c2
-rw-r--r--source/blender/modifiers/intern/MOD_multires.c2
-rw-r--r--source/blender/modifiers/intern/MOD_normal_edit.c2
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c2
-rw-r--r--source/blender/modifiers/intern/MOD_particleinstance.c2
-rw-r--r--source/blender/modifiers/intern/MOD_particlesystem.c2
-rw-r--r--source/blender/modifiers/intern/MOD_remesh.c4
-rw-r--r--source/blender/modifiers/intern/MOD_screw.c2
-rw-r--r--source/blender/modifiers/intern/MOD_shapekey.c8
-rw-r--r--source/blender/modifiers/intern/MOD_shrinkwrap.c4
-rw-r--r--source/blender/modifiers/intern/MOD_simpledeform.c4
-rw-r--r--source/blender/modifiers/intern/MOD_skin.c2
-rw-r--r--source/blender/modifiers/intern/MOD_smoke.c2
-rw-r--r--source/blender/modifiers/intern/MOD_smooth.c4
-rw-r--r--source/blender/modifiers/intern/MOD_softbody.c2
-rw-r--r--source/blender/modifiers/intern/MOD_solidify.c2
-rw-r--r--source/blender/modifiers/intern/MOD_subsurf.c11
-rw-r--r--source/blender/modifiers/intern/MOD_surface.c2
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c4
-rw-r--r--source/blender/modifiers/intern/MOD_triangulate.c2
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c2
-rw-r--r--source/blender/modifiers/intern/MOD_uvwarp.c2
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c4
-rw-r--r--source/blender/modifiers/intern/MOD_wave.c10
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c6
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c8
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgproximity.c8
-rw-r--r--source/blender/modifiers/intern/MOD_wireframe.c2
-rw-r--r--source/blender/nodes/CMakeLists.txt2
-rw-r--r--source/blender/nodes/NOD_static_types.h2
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c3
-rw-r--r--source/blender/nodes/shader/node_shader_tree.c4
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c2
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_eevee_metallic.c88
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_output_eevee_material.c66
-rw-r--r--source/blender/nodes/texture/node_texture_tree.c2
-rw-r--r--source/blender/python/CMakeLists.txt1
-rw-r--r--source/blender/python/gawain/CMakeLists.txt47
-rw-r--r--source/blender/python/gawain/gwn_py_api.c63
-rw-r--r--source/blender/python/gawain/gwn_py_api.h30
-rw-r--r--source/blender/python/gawain/gwn_py_types.c848
-rw-r--r--source/blender/python/gawain/gwn_py_types.h67
-rw-r--r--source/blender/python/intern/bpy_interface.c2
-rw-r--r--source/blender/python/intern/bpy_manipulator_wrap.c2
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c10
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.c1
-rw-r--r--source/blender/quicktime/CMakeLists.txt2
-rw-r--r--source/blender/quicktime/apple/qtkit_export.m2
-rw-r--r--source/blender/windowmanager/CMakeLists.txt2
-rw-r--r--source/blender/windowmanager/intern/wm.c2
-rw-r--r--source/blender/windowmanager/intern/wm_files.c126
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c5
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c6
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c8
-rw-r--r--source/blender/windowmanager/intern/wm_window.c11
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_api.h24
-rw-r--r--source/blender/windowmanager/manipulators/WM_manipulator_types.h9
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator.c61
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c17
-rw-r--r--source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c2
-rw-r--r--source/blender/windowmanager/manipulators/wm_manipulator_fn.h2
-rw-r--r--source/blender/windowmanager/wm_files.h2
-rw-r--r--source/blenderplayer/CMakeLists.txt8
-rw-r--r--source/blenderplayer/bad_level_call_stubs/stubs.c9
-rw-r--r--source/creator/CMakeLists.txt119
-rw-r--r--source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp2
-rw-r--r--source/gameengine/BlenderRoutines/CMakeLists.txt2
-rw-r--r--source/gameengine/Converter/CMakeLists.txt2
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp2
-rw-r--r--source/gameengine/GamePlayer/ghost/CMakeLists.txt2
-rw-r--r--source/gameengine/GamePlayer/ghost/GPG_Application.cpp2
-rw-r--r--source/gameengine/Ketsji/CMakeLists.txt2
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.cpp12
-rw-r--r--source/gameengine/Ketsji/KX_SoundActuator.h4
-rw-r--r--tests/CMakeLists.txt5
-rw-r--r--tests/python/CMakeLists.txt10
-rw-r--r--tests/python/bl_alembic_import_test.py22
-rw-r--r--tests/python/bl_load_py_modules.py27
-rwxr-xr-xtests/python/cycles_render_tests.py248
-rw-r--r--tests/python/render_layer/CMakeLists.txt1
-rw-r--r--tests/python/render_layer/test_scene_copy_d.py2
-rw-r--r--tests/python/render_layer/test_scene_copy_f.py94
1265 files changed, 72033 insertions, 32125 deletions
diff --git a/.gitignore b/.gitignore
index 3418afebb58..814b7661bc6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -33,3 +33,6 @@ Desktop.ini
/doc/python_api/sphinx-in/
/doc/python_api/sphinx-out/
/doc/python_api/rst/bmesh.ops.rst
+
+# in-source lib downloads
+/build_files/build_environment/downloads
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 3adf5825fa4..9ea7581ec34 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -392,10 +392,14 @@ if(UNIX AND NOT APPLE)
endif()
option(WITH_PYTHON_INSTALL "Copy system python into the blender install folder" ON)
-if(WITH_PYTHON_INSTALL)
- option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install folder" ON)
+if(WITH_PYTHON_INSTALL OR (WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE))
set(PYTHON_NUMPY_PATH "" CACHE PATH "Path to python site-packages or dist-packages containing 'numpy' module")
mark_as_advanced(PYTHON_NUMPY_PATH)
+ set(PYTHON_NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_PATH}/numpy/core/include CACHE PATH "Path to the include directory of the numpy module")
+ mark_as_advanced(PYTHON_NUMPY_INCLUDE_DIRS)
+endif()
+if(WITH_PYTHON_INSTALL)
+ option(WITH_PYTHON_INSTALL_NUMPY "Copy system numpy into the blender install folder" ON)
if(UNIX AND NOT APPLE)
option(WITH_PYTHON_INSTALL_REQUESTS "Copy system requests into the blender install folder" ON)
@@ -623,16 +627,11 @@ if(NOT WITH_BOOST)
endmacro()
set_and_warn(WITH_CYCLES OFF)
- set_and_warn(WITH_AUDASPACE OFF)
set_and_warn(WITH_INTERNATIONAL OFF)
set_and_warn(WITH_OPENVDB OFF)
set_and_warn(WITH_OPENCOLORIO OFF)
set_and_warn(WITH_MOD_BOOLEAN OFF)
-
- set_and_warn(WITH_OPENAL OFF) # depends on AUDASPACE
- set_and_warn(WITH_GAMEENGINE OFF) # depends on AUDASPACE
- set_and_warn(WITH_PLAYER OFF) # depends on GAMEENGINE
-elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_AUDASPACE OR WITH_INTERNATIONAL OR
+elseif(WITH_CYCLES OR WITH_OPENIMAGEIO OR WITH_INTERNATIONAL OR
WITH_OPENVDB OR WITH_OPENCOLORIO OR WITH_MOD_BOOLEAN)
# Keep enabled
else()
@@ -700,30 +699,9 @@ TEST_SHARED_PTR_SUPPORT()
TEST_UNORDERED_MAP_SUPPORT()
if(WITH_AUDASPACE)
- if(WITH_SYSTEM_AUDASPACE)
- set(AUDASPACE_DEFINITIONS
- -DWITH_AUDASPACE
- -DWITH_SYSTEM_AUDASPACE
- "-DAUD_DEVICE_H=<AUD_Device.h>"
- "-DAUD_SPECIAL_H=<AUD_Special.h>"
- "-DAUD_SOUND_H=<AUD_Sound.h>"
- "-DAUD_HANDLE_H=<AUD_Handle.h>"
- "-DAUD_SEQUENCE_H=<AUD_Sequence.h>"
- "-DAUD_TYPES_H=<AUD_Types.h>"
- "-DAUD_PYTHON_H=<python/PyAPI.h>"
- )
- else()
- set(AUDASPACE_C_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/intern/audaspace/intern")
- set(AUDASPACE_PY_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/intern/audaspace/intern")
- set(AUDASPACE_DEFINITIONS
- -DWITH_AUDASPACE
- "-DAUD_DEVICE_H=<AUD_C-API.h>"
- "-DAUD_SPECIAL_H=<AUD_C-API.h>"
- "-DAUD_SOUND_H=<AUD_C-API.h>"
- "-DAUD_HANDLE_H=<AUD_C-API.h>"
- "-DAUD_SEQUENCE_H=<AUD_C-API.h>"
- "-DAUD_TYPES_H=<AUD_Space.h>"
- )
+ if(NOT WITH_SYSTEM_AUDASPACE)
+ set(AUDASPACE_C_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/audaspace/bindings/C" "${CMAKE_BINARY_DIR}/extern/audaspace")
+ set(AUDASPACE_PY_INCLUDE_DIRS "${CMAKE_SOURCE_DIR}/extern/audaspace/bindings")
endif()
endif()
@@ -1469,10 +1447,15 @@ if(WITH_PYTHON)
)
endif()
- if(WIN32 OR APPLE)
+ if(WIN32)
# pass, we have this in an archive to extract
- elseif(WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY)
- find_python_package(numpy)
+ elseif((WITH_PYTHON_INSTALL AND WITH_PYTHON_INSTALL_NUMPY) OR (WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE))
+ if(("${PYTHON_NUMPY_PATH}" STREQUAL "") OR (${PYTHON_NUMPY_PATH} MATCHES NOTFOUND))
+ find_python_package(numpy)
+ unset(PYTHON_NUMPY_INCLUDE_DIRS CACHE)
+ set(PYTHON_NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_PATH}/numpy/core/include CACHE PATH "Path to the include directory of the numpy module")
+ mark_as_advanced(PYTHON_NUMPY_INCLUDE_DIRS)
+ endif()
endif()
if(WIN32 OR APPLE)
diff --git a/GNUmakefile b/GNUmakefile
index dbba6ffab8e..c6c7eac1653 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -43,6 +43,11 @@ ifndef BUILD_DIR
BUILD_DIR:=$(shell dirname "$(BLENDER_DIR)")/build_$(OS_NCASE)
endif
+# Dependencies DIR's
+DEPS_SOURCE_DIR:=$(BLENDER_DIR)/build_files/build_environment
+DEPS_BUILD_DIR:=$(BUILD_DIR)/deps
+DEPS_INSTALL_DIR:=$(shell dirname "$(BLENDER_DIR)")/lib/$(OS_NCASE)
+
# Allow to use alternative binary (pypy3, etc)
ifndef PYTHON
PYTHON:=python3
@@ -86,13 +91,7 @@ ifndef NPROCS
ifeq ($(OS), Linux)
NPROCS:=$(shell nproc)
endif
- ifeq ($(OS), Darwin)
- NPROCS:=$(shell sysctl -n hw.ncpu)
- endif
- ifeq ($(OS), FreeBSD)
- NPROCS:=$(shell sysctl -n hw.ncpu)
- endif
- ifeq ($(OS), NetBSD)
+ ifneq (,$(filter $(OS),Darwin FreeBSD NetBSD))
NPROCS:=$(shell sysctl -n hw.ncpu)
endif
endif
@@ -146,6 +145,27 @@ cycles: all
headless: all
bpy: all
+# -----------------------------------------------------------------------------
+# Build dependencies
+DEPS_TARGET = install
+ifneq "$(findstring clean, $(MAKECMDGOALS))" ""
+ DEPS_TARGET = clean
+endif
+
+deps: .FORCE
+ @echo
+ @echo Configuring dependencies in \"$(DEPS_BUILD_DIR)\"
+
+ @cmake -H"$(DEPS_SOURCE_DIR)" \
+ -B"$(DEPS_BUILD_DIR)" \
+ -DHARVEST_TARGET=$(DEPS_INSTALL_DIR)
+
+ @echo
+ @echo Building dependencies ...
+ $(MAKE) -C "$(DEPS_BUILD_DIR)" -s -j $(NPROCS) $(DEPS_TARGET)
+ @echo
+ @echo Dependencies successfully built and installed to $(DEPS_INSTALL_DIR).
+ @echo
# -----------------------------------------------------------------------------
# Configuration (save some cd'ing around)
@@ -164,6 +184,7 @@ help: .FORCE
@echo " * headless - build without an interface (renderfarm or server automation)"
@echo " * cycles - build Cycles standalone only, without Blender"
@echo " * bpy - build as a python module which can be loaded from python directly"
+ @echo " * deps - build library dependencies (intended only for platform maintainers)"
@echo ""
@echo " * config - run cmake configuration tool to set build options"
@echo ""
diff --git a/build_files/build_environment/CMakeLists.txt b/build_files/build_environment/CMakeLists.txt
new file mode 100644
index 00000000000..5bcfd477d71
--- /dev/null
+++ b/build_files/build_environment/CMakeLists.txt
@@ -0,0 +1,130 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+####################################################################################################
+#
+# This is a build system used by platform maintainers to build library dependencies on
+# Windows and macOS. There is some support for Linux as well, but not ready for releases.
+#
+# Windows and macOS users should download the precompiled libraries in lib/, Linux users
+# should run install_deps.sh for building dependencies.
+#
+# WINDOWS USAGE:
+# Don't call this cmake file your self, use build_deps.cmd
+# build_deps 2013 x64 / build_deps 2013 x86
+# build_deps 2015 x64 / build_deps 2015 x86
+#
+# MAC OS X USAGE:
+# Install with homebrew: brew install autoconf automake libtool yasm openssl xz
+# Run "make deps" from main Blender directory
+#
+# LINUX USAGE:
+# Install compiler, cmake, autoconf, automake, libtool, yasm
+# Run "make deps" from main Blender directory
+#
+####################################################################################################
+
+project("BlenderDependencies")
+cmake_minimum_required(VERSION 3.5)
+
+include(ExternalProject)
+include(cmake/options.cmake)
+include(cmake/versions.cmake)
+include(cmake/zlib.cmake)
+include(cmake/blendthumb.cmake)
+include(cmake/openal.cmake)
+include(cmake/png.cmake)
+include(cmake/jpeg.cmake)
+include(cmake/boost.cmake)
+include(cmake/blosc.cmake)
+include(cmake/pthreads.cmake)
+include(cmake/ilmbase.cmake)
+include(cmake/openexr.cmake)
+include(cmake/freetype.cmake)
+include(cmake/freeglut.cmake)
+include(cmake/glew.cmake)
+include(cmake/hdf5.cmake)
+include(cmake/alembic.cmake)
+include(cmake/glfw.cmake)
+include(cmake/clew.cmake)
+include(cmake/cuew.cmake)
+include(cmake/opensubdiv.cmake)
+include(cmake/sdl.cmake)
+include(cmake/opencollada.cmake)
+include(cmake/opencolorio.cmake)
+include(cmake/llvm.cmake)
+include(cmake/clang.cmake)
+include(cmake/openimageio.cmake)
+include(cmake/tiff.cmake)
+include(cmake/flexbison.cmake)
+include(cmake/osl.cmake)
+include(cmake/tbb.cmake)
+include(cmake/openvdb.cmake)
+include(cmake/python.cmake)
+include(cmake/requests.cmake)
+include(cmake/numpy.cmake)
+include(cmake/webp.cmake)
+if(WIN32)
+ include(cmake/hidapi.cmake)
+endif()
+
+if(ENABLE_MINGW64)
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ include(cmake/setup_mingw64.cmake)
+ else()
+ include(cmake/setup_mingw32.cmake)
+ endif()
+else()
+ set(mingw_LIBDIR ${LIBDIR})
+endif()
+
+if(NOT WIN32 OR ENABLE_MINGW64)
+ if(BUILD_MODE STREQUAL Release)
+ if(WIN32)
+ include(cmake/zlib_mingw.cmake)
+ endif()
+ include(cmake/lame.cmake)
+ include(cmake/ogg.cmake)
+ include(cmake/vorbis.cmake)
+ include(cmake/theora.cmake)
+ include(cmake/vpx.cmake)
+ include(cmake/orc.cmake)
+ include(cmake/schroedinger.cmake)
+ include(cmake/x264.cmake)
+ include(cmake/xvidcore.cmake)
+ include(cmake/openjpeg.cmake)
+ include(cmake/faad.cmake)
+ include(cmake/ffmpeg.cmake)
+ include(cmake/fftw.cmake)
+ include(cmake/sndfile.cmake)
+ if(WIN32)
+ include(cmake/iconv.cmake)
+ include(cmake/lapack.cmake)
+ endif()
+ if(UNIX)
+ include(cmake/flac.cmake)
+ if(NOT APPLE)
+ include(cmake/spnav.cmake)
+ include(cmake/jemalloc.cmake)
+ include(cmake/xml2.cmake)
+ endif()
+ endif()
+ endif()
+endif()
+
+include(cmake/harvest.cmake)
diff --git a/build_files/build_environment/cmake/alembic.cmake b/build_files/build_environment/cmake/alembic.cmake
new file mode 100644
index 00000000000..a49047ec102
--- /dev/null
+++ b/build_files/build_environment/cmake/alembic.cmake
@@ -0,0 +1,75 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(ALEMBIC_HDF5)
+ set(ALEMBIC_HDF5_HL)
+ # in debug mode we do not build HDF5_hdf5_hl_LIBRARY which makes cmake really
+ # unhappy, stub it with the debug mode lib. it's not linking it in at this
+ # point in time anyhow
+ if(BUILD_MODE STREQUAL Debug)
+ set(ALEMBIC_HDF5_HL -DHDF5_hdf5_hl_LIBRARY=${LIBDIR}/hdf5/lib/libhdf5_hl_D.${LIBEXT})
+ endif()
+endif()
+
+set(ALEMBIC_EXTRA_ARGS
+ -DBUILDSTATIC=ON
+ -DLINKSTATIC=ON
+ -DALEMBIC_LIB_USES_BOOST=ON
+ -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING}
+ -DBoost_USE_MULTITHREADED=ON
+ -DUSE_STATIC_BOOST=On
+ -DBoost_USE_STATIC_LIBS=ON
+ -DBoost_USE_STATIC_RUNTIME=ON
+ -DBoost_DEBUG=ON
+ -DBOOST_ROOT=${LIBDIR}/boost
+ -DBoost_NO_SYSTEM_PATHS=ON
+ -DILMBASE_ROOT=${LIBDIR}/ilmbase
+ -DALEMBIC_ILMBASE_INCLUDE_DIRECTORY=${LIBDIR}/ilmbase/include/OpenEXR
+ -DALEMBIC_ILMBASE_HALF_LIB=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Half${LIBEXT}
+ -DALEMBIC_ILMBASE_IMATH_LIB=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Imath-2_2${LIBEXT}
+ -DALEMBIC_ILMBASE_ILMTHREAD_LIB=${LIBDIR}/ilmbase/lib/${LIBPREFIX}IlmThread-2_2${LIBEXT}
+ -DALEMBIC_ILMBASE_IEX_LIB=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Iex-2_2${LIBEXT}
+ -DUSE_PYILMBASE=0
+ -DUSE_PYALEMBIC=0
+ -DUSE_ARNOLD=0
+ -DUSE_MAYA=0
+ -DUSE_PRMAN=0
+ -DUSE_HDF5=Off
+ -DUSE_STATIC_HDF5=Off
+ -DHDF5_ROOT=${LIBDIR}/hdf5
+ -DUSE_TESTS=Off
+ -DALEMBIC_NO_OPENGL=1
+ -DUSE_BINARIES=ON
+ -DALEMBIC_ILMBASE_LINK_STATIC=On
+ -DALEMBIC_SHARED_LIBS=OFF
+ -DGLUT_INCLUDE_DIR=""
+ -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/
+ ${ALEMBIC_HDF5_HL}
+)
+
+ExternalProject_Add(external_alembic
+ URL ${ALEMBIC_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${ALEMBIC_MD5}
+ PREFIX ${BUILD_DIR}/alembic
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/alembic -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${ALEMBIC_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/alembic
+)
+
+add_dependencies(external_alembic external_boost external_zlib external_ilmbase)
diff --git a/build_files/build_environment/cmake/blendthumb.cmake b/build_files/build_environment/cmake/blendthumb.cmake
new file mode 100644
index 00000000000..624869971c6
--- /dev/null
+++ b/build_files/build_environment/cmake/blendthumb.cmake
@@ -0,0 +1,61 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(BUILD_MODE STREQUAL Release)
+ if(WIN32)
+ set(THUMB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../release/windows/blendthumb)
+
+ ExternalProject_Add(external_zlib_32
+ URL ${ZLIB_URI}
+ CMAKE_GENERATOR ${GENERATOR_32}
+ URL_HASH MD5=${ZLIB_HASH}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ PREFIX ${BUILD_DIR}/zlib32
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/zlib32 ${DEFAULT_CMAKE_FLAGS}
+ INSTALL_DIR ${LIBDIR}/zlib32
+ )
+
+ ExternalProject_Add(external_zlib_64
+ URL ${ZLIB_URI}
+ CMAKE_GENERATOR ${GENERATOR_64}
+ URL_HASH MD5=${ZLIB_HASH}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ PREFIX ${BUILD_DIR}/zlib64
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/zlib64 ${DEFAULT_CMAKE_FLAGS}
+ INSTALL_DIR ${LIBDIR}/zlib64
+ )
+
+ ExternalProject_Add(external_blendthumb_32
+ CMAKE_GENERATOR ${GENERATOR_32}
+ SOURCE_DIR ${THUMB_DIR}
+ PREFIX ${BUILD_DIR}/blendthumb32
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/blendThumb32 ${DEFAULT_CMAKE_FLAGS} -DZLIB_INCLUDE=${LIBDIR}/zlib32/include -DZLIB_LIBS=${LIBDIR}/zlib32/lib/zlibstatic.lib
+ INSTALL_DIR ${LIBDIR}/blendthumb32
+ )
+ add_dependencies(external_blendthumb_32 external_zlib_32)
+
+ ExternalProject_Add(external_blendthumb_64
+ CMAKE_GENERATOR ${GENERATOR_64}
+ SOURCE_DIR ${THUMB_DIR}
+ PREFIX ${BUILD_DIR}/blendthumb64
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/blendThumb64 ${DEFAULT_CMAKE_FLAGS} -DZLIB_INCLUDE=${LIBDIR}/zlib64/include -DZLIB_LIBS=${LIBDIR}/zlib64/lib/zlibstatic.lib
+ INSTALL_DIR ${LIBDIR}/blendthumb64
+ )
+ add_dependencies(external_blendthumb_64 external_zlib_64)
+ endif()
+endif()
diff --git a/build_files/build_environment/cmake/blosc.cmake b/build_files/build_environment/cmake/blosc.cmake
new file mode 100644
index 00000000000..68df525b802
--- /dev/null
+++ b/build_files/build_environment/cmake/blosc.cmake
@@ -0,0 +1,43 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(BLOSC_EXTRA_ARGS
+ -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/
+ -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ -DBUILD_TESTS=OFF
+ -DBUILD_BENCHMARKS=OFF
+ -DCMAKE_DEBUG_POSTFIX=_d
+ -DThreads_FOUND=1
+ -DPTHREAD_LIBS=${LIBDIR}/pthreads/lib/pthreadVC2.lib
+ -DPTHREAD_INCLUDE_DIR=${LIBDIR}/pthreads/inc
+)
+
+ExternalProject_Add(external_blosc
+ URL ${BLOSC_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${BLOSC_HASH}
+ PREFIX ${BUILD_DIR}/blosc
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/blosc/src/external_blosc < ${PATCH_DIR}/blosc.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/blosc ${DEFAULT_CMAKE_FLAGS} ${BLOSC_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/blosc
+)
+
+add_dependencies(external_blosc external_zlib)
+if(WIN32)
+ add_dependencies(external_blosc external_pthreads)
+endif()
diff --git a/build_files/build_environment/cmake/boost.cmake b/build_files/build_environment/cmake/boost.cmake
new file mode 100644
index 00000000000..554db6583b7
--- /dev/null
+++ b/build_files/build_environment/cmake/boost.cmake
@@ -0,0 +1,99 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(PYTHON_ARCH x64)
+ set(PYTHON_ARCH2 win-AMD64)
+ set(PYTHON_OUTPUTDIR ${BUILD_DIR}/python/src/external_python/pcbuild/amd64/)
+ else()
+ set(PYTHON_ARCH x86)
+ set(PYTHON_ARCH2 win32)
+ set(PYTHON_OUTPUTDIR ${BUILD_DIR}/python/src/external_python/pcbuild/win32/)
+ endif()
+ if(MSVC12)
+ set(BOOST_TOOLSET toolset=msvc-12.0)
+ set(BOOST_COMPILER_STRING -vc120)
+ set(PYTHON_COMPILER_STRING v120)
+ endif()
+ if(MSVC14)
+ set(BOOST_TOOLSET toolset=msvc-14.0)
+ set(BOOST_COMPILER_STRING -vc140)
+ set(PYTHON_COMPILER_STRING v140)
+ endif()
+ set(JAM_FILE ${BUILD_DIR}/boost/src/external_boost/user-config.jam)
+ set(semi_path "${PATCH_DIR}/semi.txt")
+ FILE(TO_NATIVE_PATH ${semi_path} semi_path)
+ set(BOOST_CONFIGURE_COMMAND bootstrap.bat &&
+ echo using python : 3.5 : ${PYTHON_OUTPUTDIR}\\python.exe > "${JAM_FILE}" &&
+ echo. : ${BUILD_DIR}/python/src/external_python/include ${BUILD_DIR}/python/src/external_python/pc >> "${JAM_FILE}" &&
+ echo. : ${BUILD_DIR}/python/src/external_python/pcbuild >> "${JAM_FILE}" &&
+ type ${semi_path} >> "${JAM_FILE}"
+ )
+ set(BOOST_BUILD_COMMAND bjam)
+ set(BOOST_BUILD_OPTIONS runtime-link=static --user-config=user-config.jam)
+ set(BOOST_WITH_PYTHON --with-python)
+elseif(APPLE)
+ set(BOOST_CONFIGURE_COMMAND ./bootstrap.sh)
+ set(BOOST_BUILD_COMMAND ./bjam)
+ set(BOOST_BUILD_OPTIONS toolset=clang cxxflags=${PLATFORM_CXXFLAGS} linkflags=${PLATFORM_LDFLAGS} --disable-icu boost.locale.icu=off)
+else()
+ set(BOOST_CONFIGURE_COMMAND ./bootstrap.sh)
+ set(BOOST_BUILD_COMMAND ./bjam)
+ set(BOOST_BUILD_OPTIONS cxxflags=${PLATFORM_CXXFLAGS} --disable-icu boost.locale.icu=off)
+endif()
+
+set(BOOST_OPTIONS
+ --with-filesystem
+ --with-locale
+ --with-thread
+ --with-regex
+ --with-system
+ --with-date_time
+ --with-wave
+ --with-atomic
+ --with-serialization
+ --with-program_options
+ --with-iostreams
+ ${BOOST_WITH_PYTHON}
+ ${BOOST_TOOLSET}
+)
+
+if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(BOOST_ADDRESS_MODEL 64)
+else()
+ set(BOOST_ADDRESS_MODEL 32)
+endif()
+
+string(TOLOWER ${BUILD_MODE} BOOST_BUILD_TYPE)
+
+ExternalProject_Add(external_boost
+ URL ${BOOST_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${BOOST_MD5}
+ PREFIX ${BUILD_DIR}/boost
+ UPDATE_COMMAND ""
+ CONFIGURE_COMMAND ${BOOST_CONFIGURE_COMMAND}
+ BUILD_COMMAND ${BOOST_BUILD_COMMAND} ${BOOST_BUILD_OPTIONS} -j${MAKE_THREADS} architecture=x86 address-model=${BOOST_ADDRESS_MODEL} variant=${BOOST_BUILD_TYPE} link=static threading=multi ${BOOST_OPTIONS} --prefix=${LIBDIR}/boost install
+ BUILD_IN_SOURCE 1
+ INSTALL_COMMAND ""
+)
+
+if(WIN32)
+ add_dependencies(external_boost Make_Python_Environment)
+endif()
diff --git a/build_files/build_environment/cmake/clang.cmake b/build_files/build_environment/cmake/clang.cmake
new file mode 100644
index 00000000000..8d57c4dfc6f
--- /dev/null
+++ b/build_files/build_environment/cmake/clang.cmake
@@ -0,0 +1,35 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(CLANG_EXTRA_ARGS
+ -DCLANG_PATH_TO_LLVM_SOURCE=${BUILD_DIR}/ll/src/ll
+ -DCLANG_PATH_TO_LLVM_BUILD=${LIBDIR}/llvm
+ -DLLVM_USE_CRT_RELEASE=MT
+ -DLLVM_USE_CRT_DEBUG=MTd
+)
+ExternalProject_Add(external_clang
+ URL ${CLANG_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${CLANG_HASH}
+ PATCH_COMMAND ${PATCH_CMD} -p 2 -N -R -d ${BUILD_DIR}/clang/src/external_clang < ${PATCH_DIR}/clang.diff
+ PREFIX ${BUILD_DIR}/clang
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/llvm ${DEFAULT_CMAKE_FLAGS} ${CLANG_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/llvm
+)
+
+add_dependencies(external_clang ll)
diff --git a/build_files/build_environment/cmake/clew.cmake b/build_files/build_environment/cmake/clew.cmake
new file mode 100644
index 00000000000..0dcc1f24db7
--- /dev/null
+++ b/build_files/build_environment/cmake/clew.cmake
@@ -0,0 +1,28 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(CLEW_EXTRA_ARGS)
+
+ExternalProject_Add(external_clew
+ URL ${CLEW_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${CLEW_HASH}
+ PREFIX ${BUILD_DIR}/clew
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/clew -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${CLEW_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/clew
+)
diff --git a/build_files/build_environment/cmake/cuew.cmake b/build_files/build_environment/cmake/cuew.cmake
new file mode 100644
index 00000000000..99b7bb5c06d
--- /dev/null
+++ b/build_files/build_environment/cmake/cuew.cmake
@@ -0,0 +1,29 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(CUEW_EXTRA_ARGS)
+
+ExternalProject_Add(external_cuew
+ URL ${CUEW_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${CUEW_HASH}
+ PREFIX ${BUILD_DIR}/cuew
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/cuew/src/external_cuew < ${PATCH_DIR}/cuew.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/cuew -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${CUEW_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/cuew
+)
diff --git a/build_files/build_environment/cmake/faad.cmake b/build_files/build_environment/cmake/faad.cmake
new file mode 100644
index 00000000000..3dd90971b84
--- /dev/null
+++ b/build_files/build_environment/cmake/faad.cmake
@@ -0,0 +1,35 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(FAAD_EXTRA_ARGS)
+
+ExternalProject_Add(external_faad
+ URL ${FAAD_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${FAAD_HASH}
+ PREFIX ${BUILD_DIR}/faad
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/faad/src/external_faad < ${PATCH_DIR}/libfaad.diff
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/faad/src/external_faad/ && ${CONFIGURE_COMMAND} --disable-shared --enable-static --prefix=${LIBDIR}/faad
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/faad/src/external_faad/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/faad/src/external_faad/ && make install
+ INSTALL_DIR ${LIBDIR}/faad
+)
+
+if(MSVC)
+ set_target_properties(external_faad PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/ffmpeg.cmake b/build_files/build_environment/cmake/ffmpeg.cmake
new file mode 100644
index 00000000000..2a45849acf5
--- /dev/null
+++ b/build_files/build_environment/cmake/ffmpeg.cmake
@@ -0,0 +1,119 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(FFMPEG_CFLAGS "-I${mingw_LIBDIR}/lame/include -I${mingw_LIBDIR}/openjpeg/include/ -I${mingw_LIBDIR}/ogg/include -I${mingw_LIBDIR}/vorbis/include -I${mingw_LIBDIR}/theora/include -I${mingw_LIBDIR}/vpx/include -I${mingw_LIBDIR}/x264/include -I${mingw_LIBDIR}/xvidcore/include -I${mingw_LIBDIR}/dirac/include/dirac -I${mingw_LIBDIR}/schroedinger/include/schroedinger-1.0 -I${mingw_LIBDIR}/zlib/include")
+set(FFMPEG_LDFLAGS "-L${mingw_LIBDIR}/lame/lib -L${mingw_LIBDIR}/openjpeg/lib -L${mingw_LIBDIR}/ogg/lib -L${mingw_LIBDIR}/vorbis/lib -L${mingw_LIBDIR}/theora/lib -L${mingw_LIBDIR}/vpx/lib -L${mingw_LIBDIR}/x264/lib -L${mingw_LIBDIR}/xvidcore/lib -L${mingw_LIBDIR}/dirac/lib -L${mingw_LIBDIR}/schroedinger/lib -L${mingw_LIBDIR}/orc/lib -L${mingw_LIBDIR}/zlib/lib")
+set(FFMPEG_EXTRA_FLAGS --extra-cflags=${FFMPEG_CFLAGS} --extra-ldflags=${FFMPEG_LDFLAGS})
+set(FFMPEG_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/schroedinger/lib/pkgconfig:${mingw_LIBDIR}/orc/lib/pkgconfig:${mingw_LIBDIR}/x264/lib/pkgconfig:${mingw_LIBDIR})
+
+if(WIN32)
+ set(FFMPEG_ENV set ${FFMPEG_ENV} &&)
+ set(FFMPEG_EXTRA_FLAGS
+ ${FFMPEG_EXTRA_FLAGS}
+ --disable-static
+ --enable-shared
+ --enable-w32threads
+ --disable-pthreads
+ --enable-libopenjpeg
+ )
+else()
+ set(FFMPEG_EXTRA_FLAGS
+ ${FFMPEG_EXTRA_FLAGS}
+ --enable-static
+ --disable-shared
+ --enable-libopenjpeg)
+endif()
+
+if(APPLE)
+ set(FFMPEG_EXTRA_FLAGS
+ ${FFMPEG_EXTRA_FLAGS}
+ --target-os=darwin
+ )
+endif()
+
+ExternalProject_Add(external_ffmpeg
+ URL ${FFMPEG_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${FFMPEG_HASH}
+ PREFIX ${BUILD_DIR}/ffmpeg
+ CONFIGURE_COMMAND ${CONFIGURE_ENV_NO_PERL} &&
+ cd ${BUILD_DIR}/ffmpeg/src/external_ffmpeg/ &&
+ ${FFMPEG_ENV} ${CONFIGURE_COMMAND_NO_TARGET} ${FFMPEG_EXTRA_FLAGS}
+ --disable-lzma
+ --disable-avfilter
+ --disable-vdpau
+ --disable-bzlib
+ --disable-libgsm
+ --disable-libspeex
+ --enable-libvpx
+ --prefix=${LIBDIR}/ffmpeg
+ --enable-libschroedinger
+ --enable-libtheora
+ --enable-libvorbis
+ --enable-zlib
+ --enable-stripping
+ --enable-runtime-cpudetect
+ --disable-vaapi
+ --disable-nonfree
+ --enable-gpl
+ --disable-postproc
+ --disable-x11grab
+ --enable-libmp3lame
+ --disable-librtmp
+ --enable-libx264
+ --enable-libxvid
+ --disable-libopencore-amrnb
+ --disable-libopencore-amrwb
+ --disable-libdc1394
+ --disable-version3
+ --disable-debug
+ --enable-optimizations
+ --disable-sse
+ --disable-ssse3
+ --enable-ffplay
+ --disable-openssl
+ --disable-securetransport
+ --disable-indev=avfoundation
+ --disable-indev=qtkit
+ --disable-sdl
+ --disable-gnutls
+ --disable-vda
+ --disable-videotoolbox
+ --disable-libxcb
+ --disable-xlib
+ --disable-audiotoolbox
+ --disable-cuvid
+ --disable-nvenc
+ --disable-indev=jack
+ --disable-indev=alsa
+ --disable-outdev=alsa
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/ffmpeg/src/external_ffmpeg < ${PATCH_DIR}/ffmpeg.diff
+ BUILD_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/ffmpeg/src/external_ffmpeg/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV_NO_PERL} && cd ${BUILD_DIR}/ffmpeg/src/external_ffmpeg/ && make install
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/ffmpeg ${DEFAULT_CMAKE_FLAGS}
+ INSTALL_DIR ${LIBDIR}/ffmpeg
+)
+
+if(MSVC)
+ set_target_properties(external_ffmpeg PROPERTIES FOLDER Mingw)
+endif(MSVC)
+
+add_dependencies(external_ffmpeg external_zlib external_faad external_openjpeg external_xvidcore external_x264 external_schroedinger external_vpx external_theora external_vorbis external_ogg external_lame)
+if(WIN32)
+ add_dependencies(external_ffmpeg external_zlib_mingw)
+endif()
diff --git a/build_files/build_environment/cmake/fftw.cmake b/build_files/build_environment/cmake/fftw.cmake
new file mode 100644
index 00000000000..e6e6165199c
--- /dev/null
+++ b/build_files/build_environment/cmake/fftw.cmake
@@ -0,0 +1,40 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(FFTW_EXTRA_ARGS)
+
+if(WIN32)
+ set(FFTW3_ENV set CFLAGS=-fno-stack-check -fno-stack-protector -mno-stack-arg-probe -fno-lto &&)
+ set(FFTW3_PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/fftw3/src/external_fftw3 < ${PATCH_DIR}/fftw3.diff)
+endif()
+
+ExternalProject_Add(external_fftw3
+ URL ${FFTW_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${FFTW_HASH}
+ PREFIX ${BUILD_DIR}/fftw3
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && ${FFTW3_ENV} cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && ${CONFIGURE_COMMAND} --enable-static --prefix=${mingw_LIBDIR}/fftw3
+ PATCH_COMMAND ${FFTW3_PATCH_COMMAND}
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/fftw3/src/external_fftw3/ && make install
+ INSTALL_DIR ${LIBDIR}/fftw3
+)
+
+if(MSVC)
+ set_target_properties(external_fftw3 PROPERTIES FOLDER Mingw)
+endif(MSVC)
diff --git a/build_files/build_environment/cmake/flac.cmake b/build_files/build_environment/cmake/flac.cmake
new file mode 100644
index 00000000000..74d222632d0
--- /dev/null
+++ b/build_files/build_environment/cmake/flac.cmake
@@ -0,0 +1,32 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_flac
+ URL ${FLAC_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${FLAC_HASH}
+ PREFIX ${BUILD_DIR}/flac
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/flac/src/external_flac/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/flac --disable-shared --enable-static
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/flac/src/external_flac/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/flac/src/external_flac/ && make install
+ INSTALL_DIR ${LIBDIR}/flac
+)
+
+if(MSVC)
+ set_target_properties(external_flac PROPERTIES FOLDER Mingw)
+endif(MSVC)
diff --git a/build_files/build_environment/cmake/flexbison.cmake b/build_files/build_environment/cmake/flexbison.cmake
new file mode 100644
index 00000000000..f2908e1ce2c
--- /dev/null
+++ b/build_files/build_environment/cmake/flexbison.cmake
@@ -0,0 +1,31 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(FLEXBISON_EXTRA_ARGS)
+
+ExternalProject_Add(external_flexbison
+ URL ${FLEXBISON_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${FLEXBISON_HASH}
+ PREFIX ${BUILD_DIR}/flexbison
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/flexbison ${DEFAULT_CMAKE_FLAGS} ${FLEXBISON_EXTRA_ARGS}
+ CONFIGURE_COMMAND echo .
+ BUILD_COMMAND echo .
+ INSTALL_COMMAND COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/flexbison/src/external_flexbison/ ${LIBDIR}/flexbison/
+ INSTALL_DIR ${LIBDIR}/flexbison
+)
diff --git a/build_files/build_environment/cmake/freeglut.cmake b/build_files/build_environment/cmake/freeglut.cmake
new file mode 100644
index 00000000000..043b382e8fd
--- /dev/null
+++ b/build_files/build_environment/cmake/freeglut.cmake
@@ -0,0 +1,35 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ if(BUILD_MODE STREQUAL Release)
+ set(FREEGLUT_EXTRA_ARGS
+ -DFREEGLUT_BUILD_SHARED_LIBS=Off
+ -DFREEGLUT_BUILD_STATIC_LIBS=On
+ )
+
+ ExternalProject_Add(external_freeglut
+ URL ${FREEGLUT_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${FREEGLUT_HASH}
+ PREFIX ${BUILD_DIR}/freeglut
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/freeglut ${DEFAULT_C_FLAGS} ${DEFAULT_CXX_FLAGS} ${FREEGLUT_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/freeglut
+ )
+ endif()
+endif()
diff --git a/build_files/build_environment/cmake/freetype.cmake b/build_files/build_environment/cmake/freetype.cmake
new file mode 100644
index 00000000000..751b2b1f383
--- /dev/null
+++ b/build_files/build_environment/cmake/freetype.cmake
@@ -0,0 +1,28 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(FREETYPE_EXTRA_ARGS -DCMAKE_RELEASE_POSTFIX:STRING=2ST -DCMAKE_DEBUG_POSTFIX:STRING=2ST_d -DWITH_BZip2=OFF -DWITH_HarfBuzz=OFF)
+
+ExternalProject_Add(external_freetype
+ URL ${FREETYPE_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${FREETYPE_HASH}
+ PREFIX ${BUILD_DIR}/freetype
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/freetype ${DEFAULT_CMAKE_FLAGS} ${FREETYPE_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/freetype
+)
diff --git a/build_files/build_environment/cmake/glew.cmake b/build_files/build_environment/cmake/glew.cmake
new file mode 100644
index 00000000000..b5d9e4d3310
--- /dev/null
+++ b/build_files/build_environment/cmake/glew.cmake
@@ -0,0 +1,32 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(GLEW_EXTRA_ARGS
+ -DBUILD_UTILS=Off
+ -DBUILD_SHARED_LIBS=Off
+)
+
+ExternalProject_Add(external_glew
+ URL ${GLEW_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${GLEW_HASH}
+ PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_glew.txt ${BUILD_DIR}/glew/src/external_glew/CMakeLists.txt
+ PREFIX ${BUILD_DIR}/glew
+ CMAKE_ARGS -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_PREFIX=${LIBDIR}/glew ${DEFAULT_CMAKE_FLAGS} ${GLEW_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/glew
+)
diff --git a/build_files/build_environment/cmake/glfw.cmake b/build_files/build_environment/cmake/glfw.cmake
new file mode 100644
index 00000000000..ae80080525c
--- /dev/null
+++ b/build_files/build_environment/cmake/glfw.cmake
@@ -0,0 +1,28 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(GLFW_EXTRA_ARGS)
+
+ExternalProject_Add(external_glfw
+ URL ${GLFW_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${GLFW_HASH}
+ PREFIX ${BUILD_DIR}/glfw
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/glfw -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${GLFW_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/glfw
+)
diff --git a/build_files/build_environment/cmake/harvest.cmake b/build_files/build_environment/cmake/harvest.cmake
new file mode 100644
index 00000000000..fbc9f8687f9
--- /dev/null
+++ b/build_files/build_environment/cmake/harvest.cmake
@@ -0,0 +1,292 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+########################################################################
+# Copy all generated files to the proper strucure as blender prefers
+########################################################################
+
+if(NOT DEFINED HARVEST_TARGET)
+ set(HARVEST_TARGET ${CMAKE_CURRENT_SOURCE_DIR}/Harvest)
+endif()
+message("HARVEST_TARGET = ${HARVEST_TARGET}")
+
+if(WIN32)
+
+if(BUILD_MODE STREQUAL Release)
+ add_custom_target(Harvest_Release_Results
+ # Zlib Rename the lib file and copy the include/bin folders
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/zlib/lib/zlibstatic.lib ${HARVEST_TARGET}/zlib/lib/libz_st.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/zlib/include/ ${HARVEST_TARGET}/zlib/include/ &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/zlib/bin/ ${HARVEST_TARGET}/zlib/bin/ &&
+ # Boost copy lib + rename boost_1_60 to boost
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/boost/lib/ ${HARVEST_TARGET}/boost/lib/ &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/boost/include/boost-1_60/ ${HARVEST_TARGET}/boost/include/ &&
+ # jpeg rename libfile + copy include
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpg/lib/jpeg-static.lib ${HARVEST_TARGET}/jpeg/lib/libjpeg.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/jpg/include/ ${HARVEST_TARGET}/jpeg/include/ &&
+ # FreeType, straight up copy
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freetype ${HARVEST_TARGET}/freetype &&
+ # pthreads, rename include dir
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/inc/ ${HARVEST_TARGET}/pthreads/include/ &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/pthreads/lib/ ${HARVEST_TARGET}/pthreads/lib &&
+ # ffmpeg copy include+bin
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/ffmpeg/include ${HARVEST_TARGET}/ffmpeg/include &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/ffmpeg/bin ${HARVEST_TARGET}/ffmpeg/lib &&
+ # sdl merge bin/lib folder, copy include
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/sdl/include/sdl2 ${HARVEST_TARGET}/sdl/include &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/sdl/lib ${HARVEST_TARGET}/sdl/lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/sdl/bin ${HARVEST_TARGET}/sdl/lib &&
+ # openal
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/openal/lib/openal32.lib ${HARVEST_TARGET}/openal/lib/openal32.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/openal/bin/openal32.dll ${HARVEST_TARGET}/openal/lib/openal32.dll &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openal/include/ ${HARVEST_TARGET}/openal/include/ &&
+ # OpenImageIO
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/OpenImageIO/include ${HARVEST_TARGET}/OpenImageIO/include &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/OpenImageIO/lib ${HARVEST_TARGET}/OpenImageIO/lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/OpenImageIO/bin/idiff.exe ${HARVEST_TARGET}/OpenImageIO/bin/idiff.exe &&
+ # openEXR
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/ilmbase ${HARVEST_TARGET}/openexr &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openexr/lib ${HARVEST_TARGET}/openexr/lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openexr/include ${HARVEST_TARGET}/openexr/include &&
+ # png
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_static.lib ${HARVEST_TARGET}/png/lib/libpng.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/png/include/ ${HARVEST_TARGET}/png/include/ &&
+ # fftw3
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/lib/libfftw3.a ${HARVEST_TARGET}/fftw3/lib/libfftw.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/fftw3/include/fftw3.h ${HARVEST_TARGET}/fftw3/include/fftw3.h &&
+ # freeglut-> opengl
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/freeglut/lib/freeglut_static.lib ${HARVEST_TARGET}/opengl/lib/freeglut_static.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/freeglut/include/ ${HARVEST_TARGET}/opengl/include/ &&
+ # glew-> opengl
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/glew/lib/libglew32.lib ${HARVEST_TARGET}/opengl/lib/glew.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/glew/include/ ${HARVEST_TARGET}/opengl/include/ &&
+ # sndfile
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/lib/libsndfile.dll.a ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/bin/libsndfile-1.dll ${HARVEST_TARGET}/sndfile/lib/libsndfile-1.dll &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/sndfile/include/sndfile.h ${HARVEST_TARGET}/sndfile/include/sndfile.h &&
+ # tiff
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/tiff/lib/tiff.lib ${HARVEST_TARGET}/tiff/lib/libtiff.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/tiff/include/ ${HARVEST_TARGET}/tiff/include/ &&
+ # iconv
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/iconv/lib/libiconv.a ${HARVEST_TARGET}/iconv/lib/iconv.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/iconv/include/iconv.h ${HARVEST_TARGET}/iconv/include/iconv.h &&
+ # opencolorIO
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/OpenColorIO/ ${HARVEST_TARGET}/opencolorio &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/OpenColorIO/lib/OpenColorIO.dll ${HARVEST_TARGET}/opencolorio/bin/OpenColorIO.dll &&
+ # Osl
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/osl/ ${HARVEST_TARGET}/osl &&
+ # OpenVDB
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/openVDB/ ${HARVEST_TARGET}/openVDB &&
+ # blosc
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/blosc/lib/libblosc.lib ${HARVEST_TARGET}/blosc/lib/libblosc.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/blosc/include/ ${HARVEST_TARGET}/blosc/include/ &&
+ # tbb
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb_static.lib ${HARVEST_TARGET}/tbb/lib/tbb.lib &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/tbb/include/ ${HARVEST_TARGET}/tbb/include/ &&
+ # llvm
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/ ${HARVEST_TARGET}/llvm/ &&
+ # opencollada
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opencollada/ ${HARVEST_TARGET}/opencollada/ &&
+ # opensubdiv
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/opensubdiv ${HARVEST_TARGET}/opensubdiv &&
+ # python
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/python/ ${HARVEST_TARGET}/python/ &&
+ # alembic
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/alembic ${HARVEST_TARGET}/alembic &&
+ # hdf5
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hdf5 ${HARVEST_TARGET}/hdf5 &&
+ # BlendThumb
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/BlendThumb64/bin/blendthumb.dll ${HARVEST_TARGET}/ThumbHandler/lib/BlendThumb64.dll &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/BlendThumb32/bin/blendthumb.dll ${HARVEST_TARGET}/ThumbHandler/lib/BlendThumb.dll &&
+ # python
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/python35.tar.gz ${HARVEST_TARGET}/Release/python35.tar.gz &&
+ # requests
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/requests ${HARVEST_TARGET}/Release/site-packages/requests &&
+ # numpy
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/python35_numpy${PYTHON_POSTFIX}_1.10.tar.gz ${HARVEST_TARGET}/Release/python35_numpy_1.10.tar.gz &&
+ # hidapi
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hidapi/ ${HARVEST_TARGET}/hidapi/ &&
+ # webp, straight up copy
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/webp ${HARVEST_TARGET}/webp
+ DEPENDS
+)
+endif(BUILD_MODE STREQUAL Release)
+
+if(BUILD_MODE STREQUAL Debug)
+ add_custom_target(Harvest_Debug_Results
+ # OpenImageIO
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimageio/lib/OpenImageIO.lib ${HARVEST_TARGET}/openimageio/lib/OpenImageIO_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/openimageio/lib/OpenImageIO_Util.lib ${HARVEST_TARGET}/openimageio/lib/OpenImageIO_Util_d.lib &&
+ # ilmbase+openexr
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/ilmbase/lib/Half.lib ${HARVEST_TARGET}/openexr/lib/Half_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/ilmbase/lib/Iex-2_2.lib ${HARVEST_TARGET}/openexr/lib/Iex-2_2_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/ilmbase/lib/IexMath-2_2.lib ${HARVEST_TARGET}/openexr/lib/IexMath-2_2_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/ilmbase/lib/IlmThread-2_2.lib ${HARVEST_TARGET}/openexr/lib/IlmThread-2_2_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/ilmbase/lib/Imath-2_2.lib ${HARVEST_TARGET}/openexr/lib/Imath-2_2_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/openexr/lib/IlmImf-2_2.lib ${HARVEST_TARGET}/openexr/lib/IlmImf-2_2_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/openexr/lib/IlmImfUtil-2_2.lib ${HARVEST_TARGET}/openexr/lib/IlmImfUtil-2_2_d.lib &&
+ # opencollada
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/buffer.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/buffer_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/ftoa.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/ftoa_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/GeneratedSaxParser.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/GeneratedSaxParser_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/MathMLSolver.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/MathMLSolver_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/OpenCOLLADABaseUtils.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/OpenCOLLADABaseUtils_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/OpenCOLLADAFramework.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/OpenCOLLADAFramework_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/OpenCOLLADASaxFrameworkLoader.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/OpenCOLLADASaxFrameworkLoader_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/OpenCOLLADAStreamWriter.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/OpenCOLLADAStreamWriter_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/pcre.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/pcre_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/UTF.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/UTF_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opencollada/lib/opencollada/xml.lib ${HARVEST_TARGET}/opencollada/lib/opencollada/xml_d.lib &&
+ # blosc
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/blosc/lib/libblosc_d.lib ${HARVEST_TARGET}/blosc/lib/libblosc_d.lib &&
+ # boost
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/boost/lib/ ${HARVEST_TARGET}/boost/lib/ &&
+ # llvm
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/lib/ ${HARVEST_TARGET}/llvm/debug/lib/ &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/bin/ ${HARVEST_TARGET}/llvm/debug/bin/ &&
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/llvm/include/ ${HARVEST_TARGET}/llvm/debug/include/ &&
+ # osl
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/osl/lib/oslcomp.lib ${HARVEST_TARGET}/osl/lib/oslcomp_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/osl/lib/oslexec.lib ${HARVEST_TARGET}/osl/lib/oslexec_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/osl/lib/oslquery.lib ${HARVEST_TARGET}/osl/lib/oslquery_d.lib &&
+ # opensubdiv
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opensubdiv/lib/osdCPU.lib ${HARVEST_TARGET}/opensubdiv/lib/osdCPU_d.lib &&
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/opensubdiv/lib/osdGPU.lib ${HARVEST_TARGET}/opensubdiv/lib/osdGPU_d.lib &&
+ # tbb
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/tbb/lib/tbb_static.lib ${HARVEST_TARGET}/tbb/lib/tbb_debug.lib &&
+ # openvdb
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/openvdb/lib/openvdb.lib ${HARVEST_TARGET}/openvdb/lib/openvdb_d.lib &&
+ # python
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/python/ ${HARVEST_TARGET}/python/ &&
+ # alembic
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/alembic/lib/alembic.lib ${HARVEST_TARGET}/alembic/lib/alembic_d.lib &&
+ # hdf5
+ ${CMAKE_COMMAND} -E copy_directory ${LIBDIR}/hdf5/lib ${HARVEST_TARGET}/hdf5/lib &&
+ # numpy
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/python35_numpy_1.10d.tar.gz ${HARVEST_TARGET}/Release/python35_numpy_1.10d.tar.gz &&
+ # python
+ ${CMAKE_COMMAND} -E copy ${LIBDIR}/python35_d.tar.gz ${HARVEST_TARGET}/Release/python35_d.tar.gz
+ DEPENDS Package_Python
+)
+endif(BUILD_MODE STREQUAL Debug)
+
+else(WIN32)
+
+function(harvest from to)
+ set(pattern "")
+ foreach(f ${ARGN})
+ set(pattern ${f})
+ endforeach()
+
+ if(pattern STREQUAL "")
+ get_filename_component(dirpath ${to} DIRECTORY)
+ get_filename_component(filename ${to} NAME)
+ install(
+ FILES ${LIBDIR}/${from}
+ DESTINATION ${HARVEST_TARGET}/${dirpath}
+ RENAME ${filename})
+ else()
+ install(
+ DIRECTORY ${LIBDIR}/${from}/
+ DESTINATION ${HARVEST_TARGET}/${to}
+ USE_SOURCE_PERMISSIONS
+ FILES_MATCHING PATTERN ${pattern}
+ PATTERN "pkgconfig" EXCLUDE
+ PATTERN "cmake" EXCLUDE
+ PATTERN "clang" EXCLUDE
+ PATTERN "__pycache__" EXCLUDE
+ PATTERN "tests" EXCLUDE)
+ endif()
+endfunction()
+
+harvest(alembic/include alembic/include "*.h")
+harvest(alembic/lib/libAlembic.a alembic/lib/libAlembic.a)
+harvest(alembic/bin alembic/bin "*")
+harvest(blosc/lib openvdb/lib "*.a")
+harvest(boost/include boost/include "*")
+harvest(boost/lib boost/lib "*.a")
+harvest(ffmpeg/include ffmpeg/include "*.h")
+harvest(ffmpeg/lib ffmpeg/lib "*.a")
+harvest(fftw3/include fftw3/include "*.h")
+harvest(fftw3/lib fftw3/lib "*.a")
+harvest(flac/lib sndfile/lib "libFLAC.a")
+harvest(freetype/include freetype/include "*.h")
+harvest(freetype/lib/libfreetype2ST.a freetype/lib/libfreetype.a)
+harvest(glew/include glew/include "*.h")
+harvest(glew/lib glew/lib "*.a")
+harvest(ilmbase openexr "*")
+harvest(ilmbase/include openexr/include "*.h")
+harvest(jemalloc/include jemalloc/include "*.h")
+harvest(jemalloc/lib jemalloc/lib "*.a")
+harvest(jpg/include jpeg/include "*.h")
+harvest(jpg/lib jpeg/lib "libjpeg.a")
+harvest(lame/lib ffmpeg/lib "*.a")
+harvest(llvm/bin llvm/bin "llvm-config")
+harvest(llvm/lib llvm/lib "libLLVM*.a")
+harvest(ogg/lib ffmpeg/lib "*.a")
+harvest(openal/include openal/include "*.h")
+if(UNIX AND NOT APPLE)
+ harvest(openal/lib openal/lib "*.a")
+endif()
+harvest(opencollada/include/opencollada opencollada/include "*.h")
+harvest(opencollada/lib/opencollada opencollada/lib "*.a")
+harvest(opencolorio/include opencolorio/include "*.h")
+harvest(opencolorio/lib opencolorio/lib "*.a")
+harvest(openexr/include openexr/include "*.h")
+harvest(openexr/lib openexr/lib "*.a")
+harvest(openimageio/bin openimageio/bin "idiff")
+harvest(openimageio/bin openimageio/bin "maketx")
+harvest(openimageio/bin openimageio/bin "oiiotool")
+harvest(openimageio/include openimageio/include "*")
+harvest(openimageio/lib openimageio/lib "*.a")
+harvest(openjpeg/include/openjpeg-1.5 openjpeg/include "*.h")
+harvest(openjpeg/lib openjpeg/lib "*.a")
+harvest(opensubdiv/include opensubdiv/include "*.h")
+harvest(opensubdiv/lib opensubdiv/lib "*.a")
+harvest(openvdb/include/openvdb/openvdb openvdb/include/openvdb "*.h")
+harvest(openvdb/lib openvdb/lib "*.a")
+harvest(orc/lib/liborc-0.4.a ffmpeg/lib/liborc.a)
+harvest(osl/bin osl/bin "oslc")
+harvest(osl/include osl/include "*.h")
+harvest(osl/lib osl/lib "*.a")
+harvest(osl/shaders osl/shaders "*.h")
+harvest(png/include png/include "*.h")
+harvest(png/lib png/lib "*.a")
+harvest(python/bin python/bin "python${PYTHON_SHORT_VERSION}m")
+harvest(python/include python/include "*h")
+harvest(python/lib python/lib "*")
+harvest(schroedinger/lib/libschroedinger-1.0.a ffmpeg/lib/libschroedinger.a)
+harvest(sdl/include/SDL2 sdl/include "*.h")
+harvest(sdl/lib sdl/lib "libSDL2.a")
+harvest(sndfile/include sndfile/include "*.h")
+harvest(sndfile/lib sndfile/lib "*.a")
+harvest(spnav/include spnav/include "*.h")
+harvest(spnav/lib spnav/lib "*.a")
+harvest(tbb/include tbb/include "*.h")
+harvest(tbb/lib/libtbb_static.a tbb/lib/libtbb.a)
+harvest(theora/lib ffmpeg/lib "*.a")
+harvest(tiff/include tiff/include "*.h")
+harvest(tiff/lib tiff/lib "*.a")
+harvest(vorbis/lib ffmpeg/lib "*.a")
+harvest(vpx/lib ffmpeg/lib "*.a")
+harvest(webp/lib ffmpeg/lib "*.a")
+harvest(x264/lib ffmpeg/lib "*.a")
+harvest(xml2/lib opencollada/lib "*.a")
+harvest(xvidcore/lib ffmpeg/lib "*.a")
+
+endif(WIN32)
diff --git a/build_files/build_environment/cmake/hdf5.cmake b/build_files/build_environment/cmake/hdf5.cmake
new file mode 100644
index 00000000000..09d40d0605f
--- /dev/null
+++ b/build_files/build_environment/cmake/hdf5.cmake
@@ -0,0 +1,42 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(HDF5_EXTRA_ARGS
+ -DHDF5_ENABLE_THREADSAFE=Off
+ -DHDF5_BUILD_CPP_LIB=Off
+ -DBUILD_TESTING=Off
+ -DHDF5_BUILD_TOOLS=Off
+ -DHDF5_BUILD_EXAMPLES=Off
+ -DHDF5_BUILD_HL_LIB=On
+ -DBUILD_STATIC_CRT_LIBS=On
+ -DBUILD_SHARED_LIBS=On
+)
+
+if(WIN32)
+ set(HDF5_PATCH ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/hdf5/src/external_hdf5 < ${PATCH_DIR}/hdf5.diff)
+endif()
+
+ExternalProject_Add(external_hdf5
+ URL ${HDF5_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${HDF5_HASH}
+ PREFIX ${BUILD_DIR}/hdf5
+ PATCH_COMMAND ${HDF5_PATCH}
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/hdf5 ${HDF5_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/hdf5
+)
diff --git a/build_files/build_environment/cmake/hidapi.cmake b/build_files/build_environment/cmake/hidapi.cmake
new file mode 100644
index 00000000000..cfa4cc53d2d
--- /dev/null
+++ b/build_files/build_environment/cmake/hidapi.cmake
@@ -0,0 +1,29 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(HIDAPI_EXTRA_ARGS)
+
+ExternalProject_Add(external_hidapi
+ URL ${HIDAPI_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${HIDAPI_HASH}
+ PREFIX ${BUILD_DIR}/hidapi
+ PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_hidapi.txt ${BUILD_DIR}/hidapi/src/external_hidapi/cmakelists.txt && ${PATCH_CMD} -p 0 -d ${BUILD_DIR}/hidapi/src/external_hidapi < ${PATCH_DIR}/hidapi.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/hidapi -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${HIDAPI_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/hidapi
+)
diff --git a/build_files/build_environment/cmake/iconv.cmake b/build_files/build_environment/cmake/iconv.cmake
new file mode 100644
index 00000000000..cd6cf9547df
--- /dev/null
+++ b/build_files/build_environment/cmake/iconv.cmake
@@ -0,0 +1,34 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(ICONV_EXTRA_ARGS)
+
+ExternalProject_Add(external_iconv
+ URL ${ICONV_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${ICONV_HASH}
+ PREFIX ${BUILD_DIR}/iconv
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/iconv/src/external_iconv/ && ${CONFIGURE_COMMAND} --enable-static --prefix=${mingw_LIBDIR}/iconv
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/iconv/src/external_iconv/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/iconv/src/external_iconv/ && make install
+ INSTALL_DIR ${LIBDIR}/iconv
+)
+
+if(MSVC)
+ set_target_properties(external_iconv PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/ilmbase.cmake b/build_files/build_environment/cmake/ilmbase.cmake
new file mode 100644
index 00000000000..0639848346f
--- /dev/null
+++ b/build_files/build_environment/cmake/ilmbase.cmake
@@ -0,0 +1,35 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ set(ILMBASE_CMAKE_CXX_STANDARD_LIBRARIES "kernel32${LIBEXT} user32${LIBEXT} gdi32${LIBEXT} winspool${LIBEXT} shell32${LIBEXT} ole32${LIBEXT} oleaut32${LIBEXT} uuid${LIBEXT} comdlg32${LIBEXT} advapi32${LIBEXT} psapi${LIBEXT}")
+endif()
+
+set(ILMBASE_EXTRA_ARGS
+ -DBUILD_SHARED_LIBS=OFF
+ -DCMAKE_CXX_STANDARD_LIBRARIES=${ILMBASE_CMAKE_CXX_STANDARD_LIBRARIES}
+)
+
+ExternalProject_Add(external_ilmbase
+ URL ${ILMBASE_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${ILMBASE_HASH}
+ PREFIX ${BUILD_DIR}/ilmbase
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/ilmbase ${DEFAULT_CMAKE_FLAGS} ${ILMBASE_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/openexr
+)
diff --git a/build_files/build_environment/cmake/jemalloc.cmake b/build_files/build_environment/cmake/jemalloc.cmake
new file mode 100644
index 00000000000..c39ba448917
--- /dev/null
+++ b/build_files/build_environment/cmake/jemalloc.cmake
@@ -0,0 +1,28 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_jemalloc
+ URL ${JEMALLOC_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${JEMALLOC_HASH}
+ PREFIX ${BUILD_DIR}/jemalloc
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/jemalloc/src/external_jemalloc/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/jemalloc --disable-shared --enable-static --with-pic
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/jemalloc/src/external_jemalloc/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/jemalloc/src/external_jemalloc/ && make install
+ INSTALL_DIR ${LIBDIR}/jemalloc
+)
diff --git a/build_files/build_environment/cmake/jpeg.cmake b/build_files/build_environment/cmake/jpeg.cmake
new file mode 100644
index 00000000000..1f2b04387f0
--- /dev/null
+++ b/build_files/build_environment/cmake/jpeg.cmake
@@ -0,0 +1,65 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ # cmake for windows
+ set(JPEG_EXTRA_ARGS -DWITH_JPEG8=ON -DCMAKE_DEBUG_POSTFIX=d)
+
+ ExternalProject_Add(external_jpeg
+ URL ${JPEG_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${JPEG_HASH}
+ PREFIX ${BUILD_DIR}/jpg
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/jpg ${DEFAULT_CMAKE_FLAGS} ${JPEG_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/jpg
+ )
+
+ if(BUILD_MODE STREQUAL Debug)
+ ExternalProject_Add_Step(external_jpeg after_install
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/jpg/lib/jpegd${LIBEXT} ${LIBDIR}/jpg/lib/jpeg${LIBEXT}
+ DEPENDEES install
+ )
+ endif()
+
+ if(BUILD_MODE STREQUAL Release)
+ set(JPEG_LIBRARY jpeg-static${LIBEXT})
+ else()
+ set(JPEG_LIBRARY jpeg-staticd${LIBEXT})
+ endif()
+else(WIN32)
+ # autoconf for unix
+ if(APPLE)
+ set(JPEG_EXTRA_ARGS --host x86_64-apple-darwin --with-jpeg8)
+ else()
+ set(JPEG_EXTRA_ARGS --with-jpeg8)
+ endif()
+
+ ExternalProject_Add(external_jpeg
+ URL ${JPEG_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${JPEG_HASH}
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && autoreconf -fiv && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/jpg NASM=yasm ${JPEG_EXTRA_ARGS}
+ BUILD_IN_SOURCE 1
+ BUILD_COMMAND ${CONFIGURE_ENV} && make install
+ PREFIX ${BUILD_DIR}/jpg
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/jpg ${DEFAULT_CMAKE_FLAGS} ${JPEG_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/jpg
+ )
+
+ set(JPEG_LIBRARY libjpeg${LIBEXT})
+endif(WIN32)
diff --git a/build_files/build_environment/cmake/lame.cmake b/build_files/build_environment/cmake/lame.cmake
new file mode 100644
index 00000000000..a489b2302ce
--- /dev/null
+++ b/build_files/build_environment/cmake/lame.cmake
@@ -0,0 +1,47 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(LAME_EXTRA_ARGS)
+if(MSVC)
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
+ set(LAME_EXTRA_ARGS CFLAGS=-msse)
+ endif()
+endif()
+
+ExternalProject_Add(external_lame
+ URL ${LAME_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${LAME_HASH}
+ PREFIX ${BUILD_DIR}/lame
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/lame/src/external_lame/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/lame --disable-shared --enable-static ${LAME_EXTRA_ARGS}
+ --enable-export=full
+ --with-fileio=sndfile
+ --without-vorbis
+ --with-pic
+ --disable-mp3x
+ --disable-mp3rtp
+ --disable-gtktest
+ --enable-export=full
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/lame/src/external_lame/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/lame/src/external_lame/ && make install
+ INSTALL_DIR ${LIBDIR}/lame
+)
+
+if(MSVC)
+ set_target_properties(external_lame PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/lapack.cmake b/build_files/build_environment/cmake/lapack.cmake
new file mode 100644
index 00000000000..3110503db52
--- /dev/null
+++ b/build_files/build_environment/cmake/lapack.cmake
@@ -0,0 +1,43 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(LAPACK_EXTRA_ARGS)
+
+if(WIN32)
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(LAPACK_EXTRA_ARGS -G "MSYS Makefiles" -DCMAKE_Fortran_COMPILER=${DOWNLOAD_DIR}/mingw/mingw64/bin/gfortran.exe)
+ else()
+ set(LAPACK_EXTRA_ARGS -G "MSYS Makefiles" -DCMAKE_Fortran_COMPILER=${DOWNLOAD_DIR}/mingw/mingw32/bin/gfortran.exe)
+ endif()
+endif()
+
+ExternalProject_Add(external_lapack
+ URL ${LAPACK_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${LAPACK_HASH}
+ PREFIX ${BUILD_DIR}/lapack
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/lapack/src/external_lapack/ && ${CMAKE_COMMAND} ${LAPACK_EXTRA_ARGS} -DBUILD_TESTING=Off -DCMAKE_INSTALL_PREFIX=${LIBDIR}/lapack .
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/lapack/src/external_lapack/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/lapack/src/external_lapack/ && make install
+
+ INSTALL_DIR ${LIBDIR}/lapack
+)
+
+if(MSVC)
+ set_target_properties(external_lapack PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/llvm.cmake b/build_files/build_environment/cmake/llvm.cmake
new file mode 100644
index 00000000000..b9afa4d1b7b
--- /dev/null
+++ b/build_files/build_environment/cmake/llvm.cmake
@@ -0,0 +1,44 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(LLVM_EXTRA_ARGS
+ -DLLVM_USE_CRT_RELEASE=MT
+ -DLLVM_USE_CRT_DEBUG=MTd
+ -DLLVM_INCLUDE_TESTS=OFF
+ -DLLVM_TARGETS_TO_BUILD=X86
+ -DLLVM_INCLUDE_EXAMPLES=OFF
+ -DLLVM_ENABLE_TERMINFO=OFF
+)
+
+if(WIN32)
+ set(LLVM_GENERATOR "NMake Makefiles")
+else()
+ set(LLVM_GENERATOR "Unix Makefiles")
+endif()
+
+# short project name due to long filename issues on windows
+ExternalProject_Add(ll
+ URL ${LLVM_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${LLVM_HASH}
+ CMAKE_GENERATOR ${LLVM_GENERATOR}
+ PREFIX ${BUILD_DIR}/ll
+ PATCH_COMMAND ${PATCH_CMD} -p 0 -d ${BUILD_DIR}/ll/src/ll < ${PATCH_DIR}/llvm-alloca-fix.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/llvm ${DEFAULT_CMAKE_FLAGS} ${LLVM_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/llvm
+)
diff --git a/build_files/build_environment/cmake/mingw.cmake b/build_files/build_environment/cmake/mingw.cmake
new file mode 100644
index 00000000000..d8b87d8bd4e
--- /dev/null
+++ b/build_files/build_environment/cmake/mingw.cmake
@@ -0,0 +1,40 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(MSVC)
+ if(BUILD_MODE STREQUAL Release)
+ set(NUMPY_POSTFIX)
+ message("Python_binary = ${PYTHON_BINARY}")
+ message("Python_post = ${PYTHON_POSTFIX}")
+
+ ExternalProject_Add(external_numpy
+ URL ${NUMPY_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${NUMPY_HASH}
+ PREFIX ${BUILD_DIR}/numpy
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/numpy/src/external_numpy < ${PATCH_DIR}/numpy.diff
+ CONFIGURE_COMMAND ""
+ LOG_BUILD 1
+ BUILD_COMMAND ${PYTHON_BINARY} ${BUILD_DIR}/numpy/src/external_numpy/setup.py build
+ INSTALL_COMMAND ${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/numpy/src/external_numpy/build/lib.${PYTHON_ARCH2}-3.5"
+ ${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python35_numpy${PYTHON_POSTFIX}_1.11.tar.gz" "."
+ )
+
+ add_dependencies(external_numpy Make_Python_Environment)
+ endif()
+endif()
diff --git a/build_files/build_environment/cmake/numpy.cmake b/build_files/build_environment/cmake/numpy.cmake
new file mode 100644
index 00000000000..b1bf1691a28
--- /dev/null
+++ b/build_files/build_environment/cmake/numpy.cmake
@@ -0,0 +1,55 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(MSVC)
+ if(BUILD_MODE STREQUAL Debug)
+ set(NUMPY_DIR_POSTFIX -pydebug)
+ set(NUMPY_ARCHIVE_POSTFIX d)
+ set(NUMPY_BUILD_OPTION --debug)
+ else()
+ set(NUMPY_DIR_POSTFIX)
+ set(NUMPY_ARCHIVE_POSTFIX)
+ set(NUMPY_BUILD_OPTION)
+ endif(BUILD_MODE STREQUAL Debug)
+endif()
+
+set(NUMPY_POSTFIX)
+
+if(WIN32)
+ set(NUMPY_INSTALL
+ ${CMAKE_COMMAND} -E copy_directory "${BUILD_DIR}/python/src/external_python/run/lib/site-packages/numpy/core/include/numpy" "${LIBDIR}/python/include/python3.5/numpy" &&
+ ${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/numpy/src/external_numpy/build/lib.${PYTHON_ARCH2}-3.5${NUMPY_DIR_POSTFIX}"
+ ${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python35_numpy_${NUMPY_SHORT_VERSION}${NUMPY_ARCHIVE_POSTFIX}.tar.gz" "."
+ )
+else()
+ set(NUMPY_INSTALL echo .)
+endif()
+
+ExternalProject_Add(external_numpy
+ URL ${NUMPY_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${NUMPY_HASH}
+ PREFIX ${BUILD_DIR}/numpy
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/numpy/src/external_numpy < ${PATCH_DIR}/numpy.diff
+ CONFIGURE_COMMAND ""
+ LOG_BUILD 1
+ BUILD_COMMAND ${PYTHON_BINARY} ${BUILD_DIR}/numpy/src/external_numpy/setup.py build ${NUMPY_BUILD_OPTION} install
+ INSTALL_COMMAND ${NUMPY_INSTALL}
+)
+
+add_dependencies(external_numpy Make_Python_Environment)
diff --git a/build_files/build_environment/cmake/ogg.cmake b/build_files/build_environment/cmake/ogg.cmake
new file mode 100644
index 00000000000..1f69cee0996
--- /dev/null
+++ b/build_files/build_environment/cmake/ogg.cmake
@@ -0,0 +1,32 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_ogg
+ URL ${OGG_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${OGG_HASH}
+ PREFIX ${BUILD_DIR}/ogg
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/ogg/src/external_ogg/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/ogg --disable-shared --enable-static
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/ogg/src/external_ogg/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/ogg/src/external_ogg/ && make install
+ INSTALL_DIR ${LIBDIR}/ogg
+)
+
+if(MSVC)
+ set_target_properties(external_ogg PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/openal.cmake b/build_files/build_environment/cmake/openal.cmake
new file mode 100644
index 00000000000..d63c4443ca0
--- /dev/null
+++ b/build_files/build_environment/cmake/openal.cmake
@@ -0,0 +1,42 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(BUILD_MODE STREQUAL Release)
+ set(OPENAL_EXTRA_ARGS
+ -DALSOFT_UTILS=Off
+ -DALSOFT_NO_CONFIG_UTIL=On
+ -DALSOFT_EXAMPLES=Off
+ -DALSOFT_TESTS=Off
+ -DALSOFT_CONFIG=Off
+ -DALSOFT_HRTF_DEFS=Off
+ -DALSOFT_INSTALL=On
+ )
+
+ if(UNIX)
+ set(OPENAL_EXTRA_ARGS ${OPENAL_EXTRA_ARGS} -DLIBTYPE=STATIC)
+ endif()
+
+ ExternalProject_Add(external_openal
+ URL ${OPENAL_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${OPENAL_HASH}
+ PREFIX ${BUILD_DIR}/openal
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openal ${DEFAULT_CMAKE_FLAGS} ${OPENAL_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/openal
+ )
+endif()
diff --git a/build_files/build_environment/cmake/opencollada.cmake b/build_files/build_environment/cmake/opencollada.cmake
new file mode 100644
index 00000000000..9b2a2d9dc4d
--- /dev/null
+++ b/build_files/build_environment/cmake/opencollada.cmake
@@ -0,0 +1,37 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(UNIX AND NOT APPLE)
+ set(OPENCOLLADA_EXTRA_ARGS
+ -DLIBXML2_INCLUDE_DIR=${LIBDIR}/xml2/include/libxml2
+ -DLIBXML2_LIBRARIES=${LIBDIR}/xml2/lib/libxml2.a)
+endif()
+
+ExternalProject_Add(external_opencollada
+ URL ${OPENCOLLADA_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${OPENCOLLADA_HASH}
+ PREFIX ${BUILD_DIR}/opencollada
+ PATCH_COMMAND ${PATCH_CMD} -p 1 -N -d ${BUILD_DIR}/opencollada/src/external_opencollada < ${PATCH_DIR}/opencollada.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/opencollada ${DEFAULT_CMAKE_FLAGS} ${OPENCOLLADA_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/opencollada
+)
+
+if(UNIX AND NOT APPLE)
+ add_dependencies(external_opencollada external_xml2)
+endif()
diff --git a/build_files/build_environment/cmake/opencolorio.cmake b/build_files/build_environment/cmake/opencolorio.cmake
new file mode 100644
index 00000000000..14fb62af672
--- /dev/null
+++ b/build_files/build_environment/cmake/opencolorio.cmake
@@ -0,0 +1,70 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(OPENCOLORIO_EXTRA_ARGS
+ -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING}
+ -DBoost_USE_MULTITHREADED=ON
+ -DBoost_USE_STATIC_LIBS=ON
+ -DBoost_USE_STATIC_RUNTIME=ON
+ -DBOOST_ROOT=${LIBDIR}/boost
+ -DBOOST_INCLUDEDIR=${LIBDIR}/boost/include/boost_1_60/boost
+ -DBoost_NO_SYSTEM_PATHS=ON
+ -DBoost_DEBUG=ON
+ -DBoost_MAJOR_VERSION=1
+ -DBoost_MINOR_VERSION=60
+ -DOCIO_BUILD_APPS=OFF
+ -DOCIO_BUILD_PYGLUE=OFF
+ -DOCIO_BUILD_NUKE=OFF
+)
+
+if(WIN32)
+ set(OPENCOLORIO_EXTRA_ARGS
+ ${OPENCOLORIO_EXTRA_ARGS}
+ -DOCIO_USE_BOOST_PTR=ON
+ -DOCIO_BUILD_STATIC=OFF
+ -DOCIO_BUILD_SHARED=ON
+ )
+else()
+ set(OPENCOLORIO_EXTRA_ARGS
+ ${OPENCOLORIO_EXTRA_ARGS}
+ -DOCIO_USE_BOOST_PTR=OFF
+ -DOCIO_BUILD_STATIC=ON
+ -DOCIO_BUILD_SHARED=OFF
+ )
+endif()
+
+ExternalProject_Add(external_opencolorio
+ URL ${OPENCOLORIO_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${OPENCOLORIO_HASH}
+ PREFIX ${BUILD_DIR}/opencolorio
+ PATCH_COMMAND ${PATCH_CMD} -p 0 -N -d ${BUILD_DIR}/opencolorio/src/external_opencolorio < ${PATCH_DIR}/opencolorio.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/opencolorio ${DEFAULT_CMAKE_FLAGS} ${OPENCOLORIO_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/opencolorio
+)
+
+if(NOT WIN32)
+ add_custom_command(
+ OUTPUT ${LIBDIR}/opencolorio/lib/libtinyxml.a
+ COMMAND cp ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/libtinyxml.a ${LIBDIR}/opencolorio/lib/libtinyxml.a
+ COMMAND cp ${BUILD_DIR}/opencolorio/src/external_opencolorio-build/ext/dist/lib/libyaml-cpp.a ${LIBDIR}/opencolorio/lib/libyaml-cpp.a
+ )
+ add_custom_target(external_opencolorio_extra ALL DEPENDS external_opencolorio ${LIBDIR}/opencolorio/lib/libtinyxml.a)
+endif()
+
+add_dependencies(external_opencolorio external_boost)
diff --git a/build_files/build_environment/cmake/openexr.cmake b/build_files/build_environment/cmake/openexr.cmake
new file mode 100644
index 00000000000..53a1bc4c146
--- /dev/null
+++ b/build_files/build_environment/cmake/openexr.cmake
@@ -0,0 +1,41 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ set(OPENEXR_CMAKE_CXX_STANDARD_LIBRARIES "kernel32${LIBEXT} user32${LIBEXT} gdi32${LIBEXT} winspool${LIBEXT} shell32${LIBEXT} ole32${LIBEXT} oleaut32${LIBEXT} uuid${LIBEXT} comdlg32${LIBEXT} advapi32${LIBEXT} psapi${LIBEXT}")
+endif()
+
+set(OPENEXR_EXTRA_ARGS
+ -DBUILD_SHARED_LIBS=OFF
+ -DCMAKE_CXX_STANDARD_LIBRARIES=${OPENEXR_CMAKE_CXX_STANDARD_LIBRARIES}
+ -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/
+ -DILMBASE_PACKAGE_PREFIX=${LIBDIR}/ilmbase
+)
+
+ExternalProject_Add(external_openexr
+ URL ${OPENEXR_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${OPENEXR_HASH}
+ PREFIX ${BUILD_DIR}/openexr
+ PATCH_COMMAND ${PATCH_CMD} -p 0 -d ${BUILD_DIR}/openexr/src/external_openexr < ${PATCH_DIR}/openexr.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openexr ${DEFAULT_CMAKE_FLAGS} ${OPENEXR_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/openexr
+)
+
+add_dependencies(external_openexr external_zlib external_ilmbase)
diff --git a/build_files/build_environment/cmake/openimageio.cmake b/build_files/build_environment/cmake/openimageio.cmake
new file mode 100644
index 00000000000..f323161d5f2
--- /dev/null
+++ b/build_files/build_environment/cmake/openimageio.cmake
@@ -0,0 +1,113 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(BUILD_MODE STREQUAL Release)
+ set(OIIO_TOOLS ON)
+else()
+ set(OIIO_TOOLS OFF)
+endif()
+
+if(UNIX AND NOT APPLE)
+ # This causes linking to static pthread libraries which gives link errors.
+ # Since we manually specify library paths it should static link other libs.
+ set(OPENIMAGEIO_LINKSTATIC -DLINKSTATIC=OFF)
+else()
+ set(OPENIMAGEIO_LINKSTATIC -DLINKSTATIC=ON)
+endif()
+
+if(WIN32)
+ set(PNG_LIBNAME libpng16_static${LIBEXT})
+ set(OIIO_SIMD_FLAGS -DUSE_SIMD=sse2)
+else()
+ set(PNG_LIBNAME libpng${LIBEXT})
+ set(OIIO_SIMD_FLAGS)
+endif()
+
+set(OPENIMAGEIO_EXTRA_ARGS
+ -DBUILDSTATIC=ON
+ ${OPENIMAGEIO_LINKSTATIC}
+ -DOPENEXR_INCLUDE_DIR=${LIBDIR}/openexr/include/openexr/
+ -DOPENEXR_ILMIMF_LIBRARIES=${LIBDIR}/openexr/lib/IlmImf-2_2${LIBEXT}
+ -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING}
+ -DBoost_USE_MULTITHREADED=ON
+ -DBoost_USE_STATIC_LIBS=ON
+ -DBoost_USE_STATIC_RUNTIME=ON
+ -DBOOST_ROOT=${LIBDIR}/boost
+ -DBOOST_LIBRARYDIR=${LIBDIR}/boost/lib/
+ -DBoost_NO_SYSTEM_PATHS=ON
+ -OIIO_BUILD_CPP11=ON
+ -DUSE_OPENGL=OFF
+ -DUSE_TBB=OFF
+ -DUSE_FIELD3D=OFF
+ -DUSE_QT=OFF
+ -DUSE_PYTHON=OFF
+ -DUSE_GIF=OFF
+ -DUSE_OPENCV=OFF
+ -DUSE_OPENSSL=OFF
+ -DUSE_OPENJPEG=OFF
+ -DUSE_FFMPEG=OFF
+ -DUSE_PTEX=OFF
+ -DUSE_FREETYPE=OFF
+ -DUSE_LIBRAW=OFF
+ -DUSE_PYTHON=OFF
+ -DUSE_PYTHON3=OFF
+ -DUSE_OCIO=OFF
+ -DOIIO_BUILD_TOOLS=${OIIO_TOOLS}
+ -DOIIO_BUILD_TESTS=OFF
+ -DBUILD_TESTING=OFF
+ -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include
+ -DPNG_LIBRARY=${LIBDIR}/png/lib/${PNG_LIBNAME}
+ -DPNG_PNG_INCLUDE_DIR=${LIBDIR}/png/include
+ -DTIFF_LIBRARY=${LIBDIR}/tiff/lib/${LIBPREFIX}tiff${LIBEXT}
+ -DTIFF_INCLUDE_DIR=${LIBDIR}/tiff/include
+ -DJPEG_LIBRARY=${LIBDIR}/jpg/lib/${JPEG_LIBRARY}
+ -DJPEG_INCLUDE_DIR=${LIBDIR}/jpg/include
+ -DOCIO_PATH=${LIBDIR}/opencolorio/
+ -DOpenEXR_USE_STATIC_LIBS=On
+ -DOPENEXR_HOME=${LIBDIR}/openexr/
+ -DILMBASE_INCLUDE_PATH=${LIBDIR}/ilmbase/
+ -DILMBASE_PACKAGE_PREFIX=${LIBDIR}/ilmbase/
+ -DILMBASE_INCLUDE_DIR=${LIBDIR}/ilmbase/include/
+ -DOPENEXR_HALF_LIBRARY=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Half${LIBEXT}
+ -DOPENEXR_IMATH_LIBRARY=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Imath-2_2${LIBEXT}
+ -DOPENEXR_ILMTHREAD_LIBRARY=${LIBDIR}/ilmbase/lib/${LIBPREFIX}IlmThread-2_2${LIBEXT}
+ -DOPENEXR_IEX_LIBRARY=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Iex-2_2${LIBEXT}
+ -DOPENEXR_INCLUDE_DIR=${LIBDIR}/openexr/include/
+ -DOPENEXR_ILMIMF_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf-2_2${LIBEXT}
+ -DSTOP_ON_WARNING=OFF
+ -DWEBP_INCLUDE_DIR=${LIBDIR}/webp/include
+ -DWEBP_LIBRARY=${LIBDIR}/webp/lib/${LIBPREFIX}webp${LIBEXT}
+ ${OIIO_SIMD_FLAGS}
+)
+
+ExternalProject_Add(external_openimageio
+ URL ${OPENIMAGEIO_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${OPENIMAGEIO_HASH}
+ PREFIX ${BUILD_DIR}/openimageio
+ PATCH_COMMAND ${PATCH_CMD} -p 0 -N -d ${BUILD_DIR}/openimageio/src/external_openimageio/src/include < ${PATCH_DIR}/openimageio_gdi.diff &&
+ ${PATCH_CMD} -p 0 -N -d ${BUILD_DIR}/openimageio/src/external_openimageio/ < ${PATCH_DIR}/openimageio_staticexr.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openimageio ${DEFAULT_CMAKE_FLAGS} ${OPENIMAGEIO_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/openimageio
+)
+
+add_dependencies(external_openimageio external_png external_zlib external_ilmbase external_openexr external_jpeg external_boost external_tiff external_webp external_opencolorio)
+if(NOT WIN32)
+ add_dependencies(external_openimageio external_opencolorio_extra)
+endif()
diff --git a/build_files/build_environment/cmake/openjpeg.cmake b/build_files/build_environment/cmake/openjpeg.cmake
new file mode 100644
index 00000000000..66f815034eb
--- /dev/null
+++ b/build_files/build_environment/cmake/openjpeg.cmake
@@ -0,0 +1,43 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# Note the encoder/decoder may use png/tiff/lcms system libraries, but the
+# library itself does not depend on them, so should give no problems.
+
+set(OPENJPEG_EXTRA_ARGS -DBUILD_SHARED_LIBS=OFF)
+
+if(WIN32)
+ set(OPENJPEG_EXTRA_ARGS -G "MSYS Makefiles")
+else()
+ set(OPENJPEG_EXTRA_ARGS ${DEFAULT_CMAKE_FLAGS})
+endif()
+
+ExternalProject_Add(external_openjpeg
+ URL ${OPENJPEG_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${OPENJPEG_HASH}
+ PREFIX ${BUILD_DIR}/openjpeg
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/openjpeg/src/external_openjpeg-build && ${CMAKE_COMMAND} ${OPENJPEG_EXTRA_ARGS} -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openjpeg -DBUILD_SHARED_LIBS=Off -DBUILD_THIRDPARTY=OFF ${BUILD_DIR}/openjpeg/src/external_openjpeg
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/openjpeg/src/external_openjpeg-build/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/openjpeg/src/external_openjpeg-build/ && make install
+ INSTALL_DIR ${LIBDIR}/openjpeg
+)
+
+if(MSVC)
+ set_target_properties(external_openjpeg PROPERTIES FOLDER Mingw)
+endif(MSVC)
diff --git a/build_files/build_environment/cmake/opensubdiv.cmake b/build_files/build_environment/cmake/opensubdiv.cmake
new file mode 100644
index 00000000000..5a3a4d142fa
--- /dev/null
+++ b/build_files/build_environment/cmake/opensubdiv.cmake
@@ -0,0 +1,71 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(OPENSUBDIV_EXTRA_ARGS
+ -DNO_EXAMPLES=ON
+ -DNO_REGRESSION=ON
+ -DNO_PYTHON=ON
+ -DNO_MAYA=ON
+ -DNO_PTEX=ON
+ -DNO_DOC=ON
+ -DNO_CLEW=OFF
+ -DNO_OPENCL=OFF
+ -DNO_TUTORIALS=ON
+ -DGLEW_INCLUDE_DIR=${LIBDIR}/glew/include
+ -DGLEW_LIBRARY=${LIBDIR}/glew/lib/libGLEW${LIBEXT}
+ -DGLFW_INCLUDE_DIR=${LIBDIR}/glfw/include
+ -DGLFW_LIBRARIES=${LIBDIR}/glfw/lib/glfw3${LIBEXT}
+)
+
+if(WIN32)
+ #no cuda support for vc15 yet
+ if(msvc15)
+ set(OPENSUBDIV_CUDA ON)
+ else()
+ set(OPENSUBDIV_CUDA ON)
+ endif()
+
+ set(OPENSUBDIV_EXTRA_ARGS
+ ${OPENSUBDIV_EXTRA_ARGS}
+ -DNO_CUDA=${OPENSUBDIV_CUDA}
+ -DCLEW_INCLUDE_DIR=${LIBDIR}/clew/include/cl
+ -DCLEW_LIBRARY=${LIBDIR}/clew/lib/clew${LIBEXT}
+ -DCUEW_INCLUDE_DIR=${LIBDIR}/cuew/include
+ -DCUEW_LIBRARY=${LIBDIR}/cuew/lib/cuew${LIBEXT}
+ -DCMAKE_EXE_LINKER_FLAGS_RELEASE=libcmt.lib
+ )
+else()
+ set(OPENSUBDIV_EXTRA_ARGS
+ ${OPENSUBDIV_EXTRA_ARGS}
+ -DNO_CUDA=ON
+ -DCUEW_INCLUDE_DIR=${LIBDIR}/cuew/include
+ -DCLEW_LIBRARY=${LIBDIR}/clew/lib/static/${LIBPREFIX}clew${LIBEXT}
+ )
+endif()
+
+ExternalProject_Add(external_opensubdiv
+ URL ${OPENSUBDIV_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${OPENSUBDIV_Hash}
+ PREFIX ${BUILD_DIR}/opensubdiv
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 1 -N -d ${BUILD_DIR}/opensubdiv/src/external_opensubdiv < ${PATCH_DIR}/opensubdiv.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/opensubdiv -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${OPENSUBDIV_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/opensubdiv
+)
+
+add_dependencies(external_opensubdiv external_glew external_glfw external_clew external_cuew)
diff --git a/build_files/build_environment/cmake/openvdb.cmake b/build_files/build_environment/cmake/openvdb.cmake
new file mode 100644
index 00000000000..a71598c1a3b
--- /dev/null
+++ b/build_files/build_environment/cmake/openvdb.cmake
@@ -0,0 +1,71 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(BUILD_MODE STREQUAL Debug)
+ set(BLOSC_POST _d)
+endif()
+
+set(OPENVDB_EXTRA_ARGS
+ -DILMBASE_HOME=${LIBDIR}/ilmbase/
+ -DILMBASE_CUSTOM=ON
+ -DILMBASE_CUSTOM_LIBRARIES=Half;Imath-2_2;IlmThread-2_2;Iex-2_2
+ -DILMBASE_INCLUDE_DIR=${LIBDIR}/ilmbase/include/
+ -DILMBASE_HALF_LIBRARIES=${LIBDIR}/ilmbase/lib/Half${LIBEXT}
+ -DILMBASE_IMATH_LIBRARIES=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Imath-2_2${LIBEXT}
+ -DILMBASE_ILMTHREAD_LIBRARIES=${LIBDIR}/ilmbase/lib/${LIBPREFIX}IlmThread-2_2${LIBEXT}
+ -DILMBASE_IEX_LIBRARIES=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Iex-2_2${LIBEXT}
+ -DOPENEXR_HOME=${LIBDIR}/openexr/
+ -DOPENEXR_USE_STATIC_LIBS=ON
+ -DOPENEXR_CUSTOM=ON
+ -DOPENEXR_CUSTOM_LIBRARY=IlmImf-2_2
+ -DOPENEXR_INCLUDE_DIR=${LIBDIR}/openexr/include/
+ -DOPENEXR_ILMIMF_LIBRARIES=${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf-2_2${LIBEXT}
+ -DTBB_ROOT_DIR=${LIBDIR}/tbb/
+ -DTBB_INCLUDE_DIRS=${LIBDIR}/tbb/include
+ -DTBB_LIBRARY=${LIBDIR}/tbb/lib/tbb_static${LIBEXT}
+ -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING}
+ -DBoost_USE_MULTITHREADED=ON
+ -DBoost_USE_STATIC_LIBS=ON
+ -DBoost_USE_STATIC_RUNTIME=ON
+ -DBOOST_ROOT=${LIBDIR}/boost
+ -DBoost_NO_SYSTEM_PATHS=ON
+ -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/
+ -DWITH_BLOSC=ON
+ -DBLOSC_INCLUDE_DIR=${LIBDIR}/blosc/include/
+ -DBLOSC_LIBRARY=${LIBDIR}/blosc/lib/libblosc${BLOSC_POST}${LIBEXT}
+)
+
+set(OPENVDB_EXTRA_ARGS ${OPENVDB_EXTRA_ARGS})
+
+# CMake script for OpenVDB based on https://raw.githubusercontent.com/diekev/openvdb-cmake/master/CMakeLists.txt
+# can't be in external_openvdb because of how the includes are setup.
+
+ExternalProject_Add(openvdb
+ URL ${OPENVDB_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${OPENVDB_HASH}
+ PREFIX ${BUILD_DIR}/openvdb
+ PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_openvdb.txt ${BUILD_DIR}/openvdb/src/openvdb/CMakeLists.txt &&
+ ${CMAKE_COMMAND} -E copy_directory ${PATCH_DIR}/cmake/ ${BUILD_DIR}/openvdb/src/openvdb/cmake/ &&
+ ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/openvdb/src/openvdb < ${PATCH_DIR}/openvdb_vc2013.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/openvdb ${DEFAULT_CMAKE_FLAGS} ${OPENVDB_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/openvdb
+)
+
+add_dependencies(openvdb external_tbb external_boost external_ilmbase external_openexr external_zlib external_blosc)
diff --git a/build_files/build_environment/cmake/options.cmake b/build_files/build_environment/cmake/options.cmake
new file mode 100644
index 00000000000..465ca3c034c
--- /dev/null
+++ b/build_files/build_environment/cmake/options.cmake
@@ -0,0 +1,205 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ option(ENABLE_MINGW64 "Enable building of ffmpeg/iconv/libsndfile/lapack/fftw3 by installing mingw64" ON)
+endif()
+set(MAKE_THREADS 1 CACHE STRING "Number of threads to run make with")
+
+if(NOT BUILD_MODE)
+ set(BUILD_MODE "Release")
+ message(STATUS "Build type not specified: defaulting to a release build.")
+endif()
+Message("BuildMode = ${BUILD_MODE}")
+
+if(BUILD_MODE STREQUAL "Debug")
+ set(LIBDIR ${CMAKE_CURRENT_BINARY_DIR}/Debug)
+ELSE(BUILD_MODE STREQUAL "Debug")
+ set(LIBDIR ${CMAKE_CURRENT_BINARY_DIR}/Release)
+ENDIF(BUILD_MODE STREQUAL "Debug")
+
+option(DOWNLOAD_DIR "Path for downloaded files" ${CMAKE_CURRENT_SOURCE_DIR}/downloads)
+file(TO_CMAKE_PATH ${DOWNLOAD_DIR} DOWNLOAD_DIR)
+set(PATCH_DIR ${CMAKE_CURRENT_SOURCE_DIR}/patches)
+set(BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/build)
+
+message("LIBDIR = ${LIBDIR}")
+message("DOWNLOAD_DIR = ${DOWNLOAD_DIR}")
+message("PATCH_DIR = ${PATCH_DIR}")
+message("BUILD_DIR = ${BUILD_DIR}")
+
+if(WIN32)
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(PATCH_CMD ${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/patch.exe)
+ else()
+ set(PATCH_CMD ${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/patch.exe)
+ endif()
+ set(LIBEXT ".lib")
+ set(LIBPREFIX "")
+
+ # For OIIO and OSL
+ set(COMMON_DEFINES /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS)
+
+ # TODO FIXME highly MSVC specific
+ if(WITH_OPTIMIZED_DEBUG)
+ set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MTd /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ else()
+ set(BLENDER_CMAKE_C_FLAGS_DEBUG "/MTd /Zi /Ob0 /Od /RTC1 /D_DEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ endif()
+ set(BLENDER_CMAKE_C_FLAGS_MINSIZEREL "/MT /O1 /Ob1 /D NDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_C_FLAGS_RELEASE "/MT /O2 /Ob2 /DNDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_C_FLAGS_RELWITHDEBINFO "/MT /Zi /O2 /Ob1 /D NDEBUG /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+
+ if(WITH_OPTIMIZED_DEBUG)
+ set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/D_DEBUG /D PLATFORM_WINDOWS /MTd /Zi /Ob0 /Od /RTC1 /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ else()
+ set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "/MTd /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ endif()
+ set(BLENDER_CMAKE_CXX_FLAGS_MINSIZEREL "/MT /O1 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_CXX_FLAGS_RELEASE "/MT /O2 /Ob2 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+ set(BLENDER_CMAKE_CXX_FLAGS_RELWITHDEBINFO "/MT /Zi /O2 /Ob1 /D NDEBUG /D PLATFORM_WINDOWS /DPSAPI_VERSION=1 /DOIIO_STATIC_BUILD /DTINYFORMAT_ALLOW_WCHAR_STRINGS")
+
+ set(PLATFORM_FLAGS)
+ set(PLATFORM_CXX_FLAGS)
+ set(PLATFORM_CMAKE_FLAGS)
+
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(MINGW_PATH ${DOWNLOAD_DIR}/mingw/mingw64)
+ set(MINGW_SHELL ming64sh.cmd)
+ set(PERL_SHELL ${DOWNLOAD_DIR}/perl/portableshell.bat)
+ set(MINGW_HOST x86_64-w64-mingw32)
+ else()
+ set(MINGW_PATH ${DOWNLOAD_DIR}/mingw/mingw32)
+ set(MINGW_SHELL ming32sh.cmd)
+ set(PERL_SHELL ${DOWNLOAD_DIR}/perl32/portableshell.bat)
+ set(MINGW_HOST i686-w64-mingw32)
+ endif()
+
+ set(CONFIGURE_ENV
+ cd ${MINGW_PATH} &&
+ call ${MINGW_SHELL} &&
+ call ${PERL_SHELL} &&
+ set path &&
+ set CFLAGS=-g &&
+ set LDFLAGS=-Wl,--as-needed -static-libgcc
+ )
+
+ set(CONFIGURE_ENV_NO_PERL
+ cd ${MINGW_PATH} &&
+ call ${MINGW_SHELL} &&
+ set path &&
+ set CFLAGS=-g &&
+ set LDFLAGS=-Wl,--as-needed -static-libgcc
+ )
+
+ set(CONFIGURE_COMMAND sh ./configure)
+ set(CONFIGURE_COMMAND_NO_TARGET ${CONFIGURE_COMMAND})
+else()
+ set(PATCH_CMD patch)
+ set(LIBEXT ".a")
+ set(LIBPREFIX "lib")
+
+ if(APPLE)
+ set(OSX_ARCHITECTURES x86_64)
+ set(OSX_DEPLOYMENT_TARGET 10.9)
+ set(OSX_SDK_VERSION 10.12)
+ set(OSX_SYSROOT /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX${OSX_SDK_VERSION}.sdk)
+
+ set(PLATFORM_CFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET}")
+ set(PLATFORM_CXXFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET} -std=c++11 -stdlib=libc++")
+ set(PLATFORM_LDFLAGS "-isysroot ${OSX_SYSROOT} -mmacosx-version-min=${OSX_DEPLOYMENT_TARGET}")
+ set(PLATFORM_BUILD_TARGET --build=x86_64-apple-darwin13.0.0) # OS X 10.9
+ set(PLATFORM_CMAKE_FLAGS
+ -DCMAKE_OSX_ARCHITECTURES:STRING=${OSX_ARCHITECTURES}
+ -DCMAKE_OSX_DEPLOYMENT_TARGET:STRING=${OSX_DEPLOYMENT_TARGET}
+ -DCMAKE_OSX_SYSROOT:PATH=${OSX_SYSROOT}
+ )
+ else()
+ set(PLATFORM_CFLAGS "-fPIC")
+ set(PLATFORM_CXXFLAGS "-std=c++11 -fPIC")
+ set(PLATFORM_LDFLAGS)
+ set(PLATFORM_BUILD_TARGET)
+ set(PLATFORM_CMAKE_FLAGS)
+ endif()
+
+ if(WITH_OPTIMIZED_DEBUG)
+ set(BLENDER_CMAKE_C_FLAGS_DEBUG "-O2 -DNDEBUG")
+ else()
+ set(BLENDER_CMAKE_C_FLAGS_DEBUG "-g")
+ endif()
+ set(BLENDER_CMAKE_C_FLAGS_MINSIZEREL "-Os -DNDEBUG")
+ set(BLENDER_CMAKE_C_FLAGS_RELEASE "-O2 -DNDEBUG")
+ set(BLENDER_CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG")
+
+ if(WITH_OPTIMIZED_DEBUG)
+ set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "-O2 -DNDEBUG ${PLATFORM_CXXFLAGS}")
+ else()
+ set(BLENDER_CMAKE_CXX_FLAGS_DEBUG "-g ${PLATFORM_CXXFLAGS}")
+ endif()
+
+ set(BLENDER_CMAKE_CXX_FLAGS_MINSIZEREL "-Os -DNDEBUG ${PLATFORM_CXXFLAGS}")
+ set(BLENDER_CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG ${PLATFORM_CXXFLAGS}")
+ set(BLENDER_CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g -DNDEBUG ${PLATFORM_CXXFLAGS}")
+
+ set(CONFIGURE_ENV
+ export MACOSX_DEPLOYMENT_TARGET=${OSX_DEPLOYMENT_TARGET} &&
+ export CFLAGS=${PLATFORM_CFLAGS} &&
+ export CXXFLAGS=${PLATFORM_CXXFLAGS} &&
+ export LDFLAGS=${PLATFORM_LDFLAGS}
+ )
+ set(CONFIGURE_ENV_NO_PERL ${CONFIGURE_ENV})
+ set(CONFIGURE_COMMAND ./configure ${PLATFORM_BUILD_TARGET})
+ set(CONFIGURE_COMMAND_NO_TARGET ./configure)
+endif()
+
+set(DEFAULT_CMAKE_FLAGS
+ -DCMAKE_BUILD_TYPE=${BUILD_MODE}
+ -DCMAKE_C_FLAGS_DEBUG=${BLENDER_CMAKE_C_FLAGS_DEBUG}
+ -DCMAKE_C_FLAGS_MINSIZEREL=${BLENDER_CMAKE_C_FLAGS_MINSIZEREL}
+ -DCMAKE_C_FLAGS_RELEASE=${BLENDER_CMAKE_C_FLAGS_RELEASE}
+ -DCMAKE_C_FLAGS_RELWITHDEBINFO=${BLENDER_CMAKE_C_FLAGS_RELWITHDEBINFO}
+ -DCMAKE_CXX_FLAGS_DEBUG=${BLENDER_CMAKE_CXX_FLAGS_DEBUG}
+ -DCMAKE_CXX_FLAGS_MINSIZEREL=${BLENDER_CMAKE_CXX_FLAGS_MINSIZEREL}
+ -DCMAKE_CXX_FLAGS_RELEASE=${BLENDER_CMAKE_CXX_FLAGS_RELEASE}
+ -DCMAKE_CXX_FLAGS_RELWITHDEBINFO=${CMAKE_CXX_FLAGS_RELWITHDEBINFO}
+ ${PLATFORM_CMAKE_FLAGS}
+)
+
+if(WIN32)
+ #we need both flavors to build the thumbnail dlls
+ if(MSVC12)
+ set(GENERATOR_32 "Visual Studio 12 2013")
+ set(GENERATOR_64 "Visual Studio 12 2013 Win64")
+ elseif(MSVC14)
+ set(GENERATOR_32 "Visual Studio 14 2015")
+ set(GENERATOR_64 "Visual Studio 14 2015 Win64")
+ endif()
+endif()
+
+
+if(WIN32)
+ set(ZLIB_LIBRARY zlibstatic${LIBEXT})
+else()
+ set(ZLIB_LIBRARY libz${LIBEXT})
+endif()
+
+if(MSVC)
+ set_property(GLOBAL PROPERTY USE_FOLDERS ON)
+endif()
+
+set(CMAKE_INSTALL_MESSAGE LAZY)
diff --git a/build_files/build_environment/cmake/orc.cmake b/build_files/build_environment/cmake/orc.cmake
new file mode 100644
index 00000000000..aac7884f49e
--- /dev/null
+++ b/build_files/build_environment/cmake/orc.cmake
@@ -0,0 +1,32 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_orc
+ URL ${ORC_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${ORC_HASH}
+ PREFIX ${BUILD_DIR}/orc
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/orc/src/external_orc/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/orc --disable-shared --enable-static
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/orc/src/external_orc/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/orc/src/external_orc/ && make install
+ INSTALL_DIR ${LIBDIR}/orc
+)
+
+if(MSVC)
+ set_target_properties(external_orc PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/osl.cmake b/build_files/build_environment/cmake/osl.cmake
new file mode 100644
index 00000000000..5ddb981c604
--- /dev/null
+++ b/build_files/build_environment/cmake/osl.cmake
@@ -0,0 +1,87 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ set(OSL_CMAKE_CXX_STANDARD_LIBRARIES "kernel32${LIBEXT} user32${LIBEXT} gdi32${LIBEXT} winspool${LIBEXT} shell32${LIBEXT} ole32${LIBEXT} oleaut32${LIBEXT} uuid${LIBEXT} comdlg32${LIBEXT} advapi32${LIBEXT} psapi${LIBEXT}")
+ set(OSL_FLEX_BISON -DFLEX_EXECUTABLE=${LIBDIR}/flexbison/win_flex.exe -DFLEX_EXTRA_OPTIONS="--wincompat" -DBISON_EXECUTABLE=${LIBDIR}/flexbison/win_bison.exe)
+ set(OSL_OPENIMAGEIO_LIBRARY "${LIBDIR}/openimageio/lib/${LIBPREFIX}OpenImageIO${LIBEXT};${LIBDIR}/openimageio/lib/${LIBPREFIX}OpenImageIO_Util${LIBEXT};${LIBDIR}/png/lib/libpng16${LIBEXT};${LIBDIR}/jpg/lib/${LIBPREFIX}jpeg${LIBEXT};${LIBDIR}/tiff/lib/${LIBPREFIX}tiff${LIBEXT};${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf-2_2${LIBEXT}")
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "4")
+ set(OSL_SIMD_FLAGS -DOIIO_NOSIMD=1 -DOIIO_SIMD=0)
+ else()
+ set(OSL_SIMD_FLAGS -DOIIO_NOSIMD=1 -DOIIO_SIMD=sse2)
+ endif()
+else()
+ set(OSL_CMAKE_CXX_STANDARD_LIBRARIES)
+ set(OSL_FLEX_BISON)
+ set(OSL_OPENIMAGEIO_LIBRARY "${LIBDIR}/openimageio/lib/${LIBPREFIX}OpenImageIO${LIBEXT};${LIBDIR}/openimageio/lib/${LIBPREFIX}OpenImageIO_Util${LIBEXT};${LIBDIR}/png/lib/${LIBPREFIX}png16${LIBEXT};${LIBDIR}/jpg/lib/${LIBPREFIX}jpeg${LIBEXT};${LIBDIR}/tiff/lib/${LIBPREFIX}tiff${LIBEXT};${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf-2_2${LIBEXT}")
+endif()
+
+set(OSL_ILMBASE_CUSTOM_LIBRARIES "${LIBDIR}/ilmbase/lib/Imath-2_2.lib^^${LIBDIR}/ilmbase/lib/Half.lib^^${LIBDIR}/ilmbase/lib/IlmThread-2_2.lib^^${LIBDIR}/ilmbase/lib/Iex-2_2.lib")
+set(OSL_LLVM_LIBRARY "${LIBDIR}/llvm/lib/LLVMAnalysis${LIBEXT};${LIBDIR}/llvm/lib/LLVMAsmParser${LIBEXT};${LIBDIR}/llvm/lib/LLVMAsmPrinter${LIBEXT};${LIBDIR}/llvm/lib/LLVMBitReader${LIBEXT};${LIBDIR}/llvm/lib/LLVMBitWriter${LIBEXT};${LIBDIR}/llvm/lib/LLVMCodeGen${LIBEXT};${LIBDIR}/llvm/lib/LLVMCore${LIBEXT};${LIBDIR}/llvm/lib/LLVMDebugInfo${LIBEXT};${LIBDIR}/llvm/lib/LLVMExecutionEngine${LIBEXT};${LIBDIR}/llvm/lib/LLVMInstCombine${LIBEXT};${LIBDIR}/llvm/lib/LLVMInstrumentation${LIBEXT};${LIBDIR}/llvm/lib/LLVMInterpreter${LIBEXT};${LIBDIR}/llvm/lib/LLVMJIT${LIBEXT};${LIBDIR}/llvm/lib/LLVMLinker${LIBEXT};${LIBDIR}/llvm/lib/LLVMMC${LIBEXT};${LIBDIR}/llvm/lib/LLVMMCDisassembler${LIBEXT};${LIBDIR}/llvm/lib/LLVMMCJIT${LIBEXT};${LIBDIR}/llvm/lib/LLVMMCParser${LIBEXT};${LIBDIR}/llvm/lib/LLVMObject${LIBEXT};${LIBDIR}/llvm/lib/LLVMRuntimeDyld${LIBEXT};${LIBDIR}/llvm/lib/LLVMScalarOpts${LIBEXT};${LIBDIR}/llvm/lib/LLVMSelectionDAG${LIBEXT};${LIBDIR}/llvm/lib/LLVMSupport${LIBEXT};${LIBDIR}/llvm/lib/LLVMTableGen${LIBEXT};${LIBDIR}/llvm/lib/LLVMTarget${LIBEXT};${LIBDIR}/llvm/lib/LLVMTransformUtils${LIBEXT};${LIBDIR}/llvm/lib/LLVMVectorize${LIBEXT};${LIBDIR}/llvm/lib/LLVMX86AsmParser${LIBEXT};${LIBDIR}/llvm/lib/LLVMX86AsmPrinter${LIBEXT};${LIBDIR}/llvm/lib/LLVMX86CodeGen${LIBEXT};${LIBDIR}/llvm/lib/LLVMX86Desc${LIBEXT};${LIBDIR}/llvm/lib/LLVMX86Disassembler${LIBEXT};${LIBDIR}/llvm/lib/LLVMX86Info${LIBEXT};${LIBDIR}/llvm/lib/LLVMX86Utils${LIBEXT};${LIBDIR}/llvm/lib/LLVMipa${LIBEXT};${LIBDIR}/llvm/lib/LLVMipo${LIBEXT}")
+
+set(OSL_EXTRA_ARGS
+ -DBoost_COMPILER:STRING=${BOOST_COMPILER_STRING}
+ -DBoost_USE_MULTITHREADED=ON
+ -DBoost_USE_STATIC_LIBS=ON
+ -DBoost_USE_STATIC_RUNTIME=ON
+ -DBOOST_ROOT=${LIBDIR}/boost
+ -DBOOST_LIBRARYDIR=${LIBDIR}/boost/lib/
+ -DBoost_NO_SYSTEM_PATHS=ON
+ -DLLVM_DIRECTORY=${LIBDIR}/llvm
+ -DLLVM_INCLUDES=${LIBDIR}/llvm/include
+ -DLLVM_LIB_DIR=${LIBDIR}/llvm/lib
+ -DLLVM_VERSION=3.4
+ -DLLVM_LIBRARY=${OSL_LLVM_LIBRARY}
+ -DOPENEXR_HOME=${LIBDIR}/openexr/
+ -DILMBASE_HOME=${LIBDIR}/ilmbase/
+ -DILMBASE_INCLUDE_DIR=${LIBDIR}/ilmbase/include/
+ -DOPENEXR_IMATH_LIBRARY=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Imath-2_2${LIBEXT}
+ -DOPENEXR_ILMTHREAD_LIBRARY=${LIBDIR}/ilmbase/lib/${LIBPREFIX}IlmThread-2_2${LIBEXT}
+ -DOPENEXR_IEX_LIBRARY=${LIBDIR}/ilmbase/lib/${LIBPREFIX}Iex-2_2${LIBEXT}
+ -DOPENEXR_INCLUDE_DIR=${LIBDIR}/openexr/include/
+ -DOPENEXR_ILMIMF_LIBRARY=${LIBDIR}/openexr/lib/${LIBPREFIX}IlmImf-2_2${LIBEXT}
+ -DOSL_BUILD_TESTS=OFF
+ -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/
+ -DOPENIMAGEIOHOME=${LIBDIR}/openimageio/
+ -DOPENIMAGEIO_LIBRARY=${OSL_OPENIMAGEIO_LIBRARY}
+ -DOPENIMAGEIO_INCLUDES=${LIBDIR}/openimageio/include
+ ${OSL_FLEX_BISON}
+ -DCMAKE_CXX_STANDARD_LIBRARIES=${OSL_CMAKE_CXX_STANDARD_LIBRARIES}
+ -DBUILDSTATIC=ON
+ -DLINKSTATIC=ON
+ -DOSL_BUILD_PLUGINS=Off
+ -DSTOP_ON_WARNING=OFF
+ -DOSL_BUILD_CPP11=ON
+ -DUSE_LLVM_BITCODE=OFF
+ ${OSL_SIMD_FLAGS}
+)
+
+ExternalProject_Add(external_osl
+ URL ${OSL_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ LIST_SEPARATOR ^^
+ URL_HASH MD5=${OSL_HASH}
+ PREFIX ${BUILD_DIR}/osl
+ PATCH_COMMAND ${PATCH_CMD} -p 3 -d ${BUILD_DIR}/osl/src/external_osl < ${PATCH_DIR}/osl.diff &&
+ ${PATCH_CMD} -p 0 -d ${BUILD_DIR}/osl/src/external_osl < ${PATCH_DIR}/osl_simd_oiio.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/osl -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} ${DEFAULT_CMAKE_FLAGS} ${OSL_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/osl
+)
+
+add_dependencies(external_osl external_boost ll external_clang external_ilmbase external_openexr external_zlib external_flexbison external_openimageio)
diff --git a/build_files/build_environment/cmake/png.cmake b/build_files/build_environment/cmake/png.cmake
new file mode 100644
index 00000000000..8d6fee871f9
--- /dev/null
+++ b/build_files/build_environment/cmake/png.cmake
@@ -0,0 +1,41 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(PNG_EXTRA_ARGS
+ -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include/
+ -DPNG_STATIC=ON
+)
+
+ExternalProject_Add(external_png
+ URL ${PNG_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${PNG_HASH}
+ PREFIX ${BUILD_DIR}/png
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/png ${DEFAULT_CMAKE_FLAGS} ${PNG_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/png
+)
+
+add_dependencies(external_png external_zlib)
+
+if(BUILD_MODE STREQUAL Debug)
+ ExternalProject_Add_Step(external_png after_install
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/png/lib/libpng16_staticd${LIBEXT} ${LIBDIR}/png/lib/libpng16${LIBEXT}
+ DEPENDEES install
+ )
+endif()
diff --git a/build_files/build_environment/cmake/pthreads.cmake b/build_files/build_environment/cmake/pthreads.cmake
new file mode 100644
index 00000000000..f4301b95f3a
--- /dev/null
+++ b/build_files/build_environment/cmake/pthreads.cmake
@@ -0,0 +1,45 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ set(PTHREAD_XCFLAGS /MD)
+
+ if(MSVC14) # vs2015 has timespec
+ set(PTHREAD_CPPFLAGS "/I. /DHAVE_PTW32_CONFIG_H /D_TIMESPEC_DEFINED ")
+ else() # everything before doesn't
+ set(PTHREAD_CPPFLAGS "/I. /DHAVE_PTW32_CONFIG_H ")
+ endif()
+
+ set(PTHREADS_BUILD cd ${BUILD_DIR}/pthreads/src/external_pthreads/ && cd && nmake VC /e CPPFLAGS=${PTHREAD_CPPFLAGS} /e XCFLAGS=${PTHREAD_XCFLAGS} /e XLIBS=/NODEFAULTLIB:msvcr)
+
+ ExternalProject_Add(external_pthreads
+ URL ${PTHREADS_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA512=${PTHREADS_SHA512}
+ PREFIX ${BUILD_DIR}/pthreads
+ CONFIGURE_COMMAND echo .
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/pthreads/src/external_pthreads < ${PATCH_DIR}/pthreads.diff
+ BUILD_COMMAND ${PTHREADS_BUILD}
+ INSTALL_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/pthreadVC2.dll ${LIBDIR}/pthreads/lib/pthreadVC2.dll &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/pthreadVC2${LIBEXT} ${LIBDIR}/pthreads/lib/pthreadVC2${LIBEXT} &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/pthread.h ${LIBDIR}/pthreads/inc/pthread.h &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/sched.h ${LIBDIR}/pthreads/inc/sched.h &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/pthreads/src/external_pthreads/semaphore.h ${LIBDIR}/pthreads/inc/semaphore.h
+ INSTALL_DIR ${LIBDIR}/pthreads
+ )
+endif()
diff --git a/build_files/build_environment/cmake/python.cmake b/build_files/build_environment/cmake/python.cmake
new file mode 100644
index 00000000000..c1c7bf7001c
--- /dev/null
+++ b/build_files/build_environment/cmake/python.cmake
@@ -0,0 +1,138 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(PYTHON_POSTFIX)
+if(BUILD_MODE STREQUAL Debug)
+ set(PYTHON_POSTFIX _d)
+endif()
+
+if(WIN32)
+ set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe)
+
+ macro(cmake_to_dos_path MsysPath ResultingPath)
+ string(REPLACE "/" "\\" ${ResultingPath} "${MsysPath}")
+ endmacro()
+
+ set(PYTHON_EXTERNALS_FOLDER ${BUILD_DIR}/python/src/external_python/externals)
+ set(DOWNLOADS_EXTERNALS_FOLDER ${DOWNLOAD_DIR}/externals)
+
+ cmake_to_dos_path(${PYTHON_EXTERNALS_FOLDER} PYTHON_EXTERNALS_FOLDER_DOS)
+ cmake_to_dos_path(${DOWNLOADS_EXTERNALS_FOLDER} DOWNLOADS_EXTERNALS_FOLDER_DOS)
+
+ message("Python externals = ${PYTHON_EXTERNALS_FOLDER}")
+ message("Python externals_dos = ${PYTHON_EXTERNALS_FOLDER_DOS}")
+ message("Python DOWNLOADS_EXTERNALS_FOLDER = ${DOWNLOADS_EXTERNALS_FOLDER}")
+ message("Python DOWNLOADS_EXTERNALS_FOLDER_DOS = ${DOWNLOADS_EXTERNALS_FOLDER_DOS}")
+
+ ExternalProject_Add(external_python
+ URL ${PYTHON_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${PYTHON_HASH}
+ PREFIX ${BUILD_DIR}/python
+ PATCH_COMMAND echo mklink /D "${PYTHON_EXTERNALS_FOLDER_DOS}" "${DOWNLOADS_EXTERNALS_FOLDER_DOS}" &&
+ mklink /D "${PYTHON_EXTERNALS_FOLDER_DOS}" "${DOWNLOADS_EXTERNALS_FOLDER_DOS}" &&
+ ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python.diff &&
+ ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python/pc < ${PATCH_DIR}/pyshell.diff
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND cd ${BUILD_DIR}/python/src/external_python/pcbuild/ && set IncludeTkinter=false && call build.bat -e -p ${PYTHON_ARCH} -c ${BUILD_MODE} -k ${PYTHON_COMPILER_STRING}
+ INSTALL_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.dll ${LIBDIR}/python/lib/python35${PYTHON_POSTFIX}.dll &&
+ ${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.lib ${LIBDIR}/python/lib/python35${PYTHON_POSTFIX}.lib &&
+ ${CMAKE_COMMAND} -E copy ${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.exp ${LIBDIR}/python/lib/python35${PYTHON_POSTFIX}.exp &&
+ ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/include ${LIBDIR}/python/include/Python3.5 &&
+ ${CMAKE_COMMAND} -E copy "${BUILD_DIR}/python/src/external_python/PC/pyconfig.h" ${LIBDIR}/python/include/Python3.5/pyconfig.h
+ )
+ Message("PythinRedist = ${BUILD_DIR}/python/src/external_python/redist")
+ Message("POutput = ${PYTHON_OUTPUTDIR}")
+else()
+ if(APPLE)
+ # we need to manually add homebrew headers to get ssl module building
+ set(PYTHON_CFLAGS "-I/usr/local/opt/openssl/include -I${OSX_SYSROOT}/usr/include ${PLATFORM_CFLAGS}")
+ set(PYTHON_LDFLAGS "-L/usr/local/opt/openssl/lib ${PLATFORM_LDFLAGS}")
+ set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV} && export CFLAGS=${PYTHON_CFLAGS} && export LDFLAGS=${PYTHON_LDFLAGS})
+ set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/python.exe)
+ set(PYTHON_PATCH ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python < ${PATCH_DIR}/python_apple.diff)
+ else()
+ set(PYTHON_CONFIGURE_ENV ${CONFIGURE_ENV})
+ set(PYTHON_BINARY ${BUILD_DIR}/python/src/external_python/python)
+ endif()
+
+ ExternalProject_Add(external_python
+ URL ${PYTHON_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${PYTHON_HASH}
+ PREFIX ${BUILD_DIR}/python
+ PATCH_COMMAND ${PYTHON_PATCH}
+ CONFIGURE_COMMAND ${PYTHON_CONFIGURE_ENV} && cd ${BUILD_DIR}/python/src/external_python/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/python
+ BUILD_COMMAND ${PYTHON_CONFIGURE_ENV} && cd ${BUILD_DIR}/python/src/external_python/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${PYTHON_CONFIGURE_ENV} && cd ${BUILD_DIR}/python/src/external_python/ && make install
+ INSTALL_DIR ${LIBDIR}/python)
+
+ add_custom_target(Make_Python_Environment ALL DEPENDS external_python)
+endif()
+
+if(MSVC)
+ add_custom_command(
+ OUTPUT ${LIBDIR}/python35${PYTHON_POSTFIX}.tar.gz
+ OUTPUT ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/lib ${BUILD_DIR}/python/src/external_python/redist/lib
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_POSTFIX}.exe" ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_bz2${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_bz2${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_hashlib${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_hashlib${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_lzma${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_lzma${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_sqlite3${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_sqlite3${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_ssl${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_ssl${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/pyexpat${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/pyexpat${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/select${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/select${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/unicodedata${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/unicodedata${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/winsound${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/winsound${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_ctypes${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_ctypes${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_ctypes_test${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_ctypes_test${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_decimal${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_decimal${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_elementtree${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_elementtree${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_msi${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_msi${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_multiprocessing${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_multiprocessing${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_overlapped${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_overlapped${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_socket${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_socket${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testbuffer${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testbuffer${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testcapi${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testcapi${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testimportmultiple${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testimportmultiple${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/_testmultiphase${PYTHON_POSTFIX}.pyd" ${BUILD_DIR}/python/src/external_python/redist/lib/_testmultiphase${PYTHON_POSTFIX}.pyd
+ COMMAND ${CMAKE_COMMAND} -E chdir "${BUILD_DIR}/python/src/external_python/redist" ${CMAKE_COMMAND} -E tar "cfvz" "${LIBDIR}/python35${PYTHON_POSTFIX}.tar.gz" "."
+ )
+
+ add_custom_target(Package_Python ALL DEPENDS external_python ${LIBDIR}/python35${PYTHON_POSTFIX}.tar.gz ${BUILD_DIR}/python/src/external_python/redist/bin/python${PYTHON_POSTFIX}.exe)
+
+ if(MSVC12)
+ set(PYTHON_DISTUTIL_PATCH ${PATCH_CMD} --verbose -p 0 -d ${BUILD_DIR}/python/src/external_python/run/lib/distutils < ${PATCH_DIR}/python_runtime_vc2013.diff)
+ else()
+ set(PYTHON_DISTUTIL_PATCH echo "No patch needed")
+ endif()
+
+ add_custom_command(OUTPUT ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/redist ${BUILD_DIR}/python/src/external_python/run
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/python/src/external_python/include ${BUILD_DIR}/python/src/external_python/run/include
+ COMMAND ${CMAKE_COMMAND} -E copy "${BUILD_DIR}/python/src/external_python/PC/pyconfig.h" ${BUILD_DIR}/python/src/external_python/run/include/pyconfig.h
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.dll" ${BUILD_DIR}/python/src/external_python/run/python35${PYTHON_POSTFIX}.dll
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.lib" ${BUILD_DIR}/python/src/external_python/run/libs/python35.lib #missing postfix on purpose, distutils is not expecting it
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python35${PYTHON_POSTFIX}.lib" ${BUILD_DIR}/python/src/external_python/run/libs/python35${PYTHON_POSTFIX}.lib #other things like numpy still want it though.
+ COMMAND ${CMAKE_COMMAND} -E copy "${PYTHON_OUTPUTDIR}/python${PYTHON_POSTFIX}.exe" ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe
+ COMMAND ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe -m ensurepip --upgrade
+ COMMAND ${PYTHON_DISTUTIL_PATCH}
+ )
+ add_custom_target(Make_Python_Environment ALL DEPENDS ${BUILD_DIR}/python/src/external_python/run/python${PYTHON_POSTFIX}.exe Package_Python)
+endif(MSVC)
diff --git a/build_files/build_environment/cmake/requests.cmake b/build_files/build_environment/cmake/requests.cmake
new file mode 100644
index 00000000000..f5aa26b0615
--- /dev/null
+++ b/build_files/build_environment/cmake/requests.cmake
@@ -0,0 +1,37 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(BUILD_MODE STREQUAL Release)
+ if(WIN32)
+ set(REQUESTS_INSTALL_DIR ${LIBDIR}/requests)
+ else()
+ set(REQUESTS_INSTALL_DIR ${LIBDIR}/python/lib/python${PYTHON_SHORT_VERSION}/site-packages/requests)
+ endif()
+
+ ExternalProject_Add(external_requests
+ URL ${REQUESTS_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${REQUESTS_HASH}
+ PREFIX ${BUILD_DIR}/requests
+ CONFIGURE_COMMAND ""
+ BUILD_COMMAND ""
+ INSTALL_COMMAND ${CMAKE_COMMAND} -E copy_directory ${BUILD_DIR}/requests/src/external_requests/requests ${REQUESTS_INSTALL_DIR}
+ )
+
+ add_dependencies(external_requests Make_Python_Environment)
+endif(BUILD_MODE STREQUAL Release)
diff --git a/build_files/build_environment/cmake/schroedinger.cmake b/build_files/build_environment/cmake/schroedinger.cmake
new file mode 100644
index 00000000000..54a20db5b5e
--- /dev/null
+++ b/build_files/build_environment/cmake/schroedinger.cmake
@@ -0,0 +1,45 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ set(SCHROEDINGER_EXTRA_FLAGS "CFLAGS=-g -I./ -I${LIBDIR}/orc/include/orc-0.4" "LDFLAGS=-Wl,--as-needed -static-libgcc -L${LIBDIR}/orc/lib" ORC_CFLAGS=-I${LIBDIR}/orc/include/orc-0.4 ORC_LDFLAGS=-L${LIBDIR}/orc/lib ORC_LIBS=${LIBDIR}/orc/lib/liborc-0.4.a ORCC=${LIBDIR}/orc/bin/orcc.exe)
+else()
+ set(SCHROEDINGER_CFLAGS "${PLATFORM_CFLAGS} -I./ -I${LIBDIR}/orc/include/orc-0.4")
+ set(SCHROEDINGER_LDFLAGS "${PLATFORM_LDFLAGS} -L${LIBDIR}/orc/lib")
+ set(SCHROEDINGER_EXTRA_FLAGS CFLAGS=${SCHROEDINGER_CFLAGS} LDFLAGS=${SCHROEDINGER_LDFLAGS} ORC_CFLAGS=-I${LIBDIR}/orc/include/orc-0.4 ORC_LDFLAGS=-L${LIBDIR}/orc/lib ORCC=${LIBDIR}/orc/bin/orcc) # ORC_LIBS=${LIBDIR}/orc/lib/liborc-0.4.a
+endif()
+
+ExternalProject_Add(external_schroedinger
+ URL ${SCHROEDINGER_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${SCHROEDINGER_HASH}
+ PREFIX ${BUILD_DIR}/schroedinger
+ PATCH_COMMAND ${PATCH_CMD} --verbose -p 0 -N -d ${BUILD_DIR}/schroedinger/src/external_schroedinger < ${PATCH_DIR}/schroedinger.diff
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} &&
+ cd ${BUILD_DIR}/schroedinger/src/external_schroedinger/ &&
+ ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/schroedinger --disable-shared --enable-static ${SCHROEDINGER_EXTRA_FLAGS}
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/schroedinger/src/external_schroedinger/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/schroedinger/src/external_schroedinger/ && make install
+ INSTALL_DIR ${LIBDIR}/schroedinger
+)
+
+add_dependencies(external_schroedinger external_orc)
+
+if(MSVC)
+ set_target_properties(external_schroedinger PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/sdl.cmake b/build_files/build_environment/cmake/sdl.cmake
new file mode 100644
index 00000000000..0fbfa078eb1
--- /dev/null
+++ b/build_files/build_environment/cmake/sdl.cmake
@@ -0,0 +1,39 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ set(SDL_EXTRA_ARGS
+ -DSDL_STATIC=Off
+ )
+else()
+ set(SDL_EXTRA_ARGS
+ -DSDL_STATIC=ON
+ -DSDL_SHARED=OFF
+ -DSDL_VIDEO=OFF
+ )
+endif()
+
+ExternalProject_Add(external_sdl
+ URL ${SDL_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${SDL_HASH}
+ PREFIX ${BUILD_DIR}/sdl
+ PATCH_COMMAND ${PATCH_CMD} -p 0 -N -d ${BUILD_DIR}/sdl/src/external_sdl < ${PATCH_DIR}/sdl.diff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/sdl ${DEFAULT_CMAKE_FLAGS} ${SDL_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/sdl
+)
diff --git a/build_files/build_environment/cmake/setup_mingw32.cmake b/build_files/build_environment/cmake/setup_mingw32.cmake
new file mode 100644
index 00000000000..f0d99356da0
--- /dev/null
+++ b/build_files/build_environment/cmake/setup_mingw32.cmake
@@ -0,0 +1,219 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+####################################################################################################################
+# Mingw32 Builds
+####################################################################################################################
+# This installs mingw32+msys to compile ffmpeg/iconv/libsndfile/lapack/fftw3
+####################################################################################################################
+
+message("LIBDIR = ${LIBDIR}")
+macro(cmake_to_msys_path MsysPath ResultingPath)
+ string(REPLACE ":" "" TmpPath "${MsysPath}")
+ string(SUBSTRING ${TmpPath} 0 1 Drive)
+ string(SUBSTRING ${TmpPath} 1 255 PathPart)
+ string(TOLOWER ${Drive} LowerDrive)
+ string(CONCAT ${ResultingPath} "/" ${LowerDrive} ${PathPart})
+endmacro()
+cmake_to_msys_path(${LIBDIR} mingw_LIBDIR)
+message("mingw_LIBDIR = ${mingw_LIBDIR}")
+
+message("Checking for mingw32")
+# download mingw32
+if(NOT EXISTS "${DOWNLOAD_DIR}/i686-w64-mingw32-gcc-4.8.0-win32_rubenvb.7z")
+ message("Downloading mingw32")
+ file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw-w64/Toolchains%20targetting%20Win32/Personal%20Builds/rubenvb/gcc-4.8-release/i686-w64-mingw32-gcc-4.8.0-win32_rubenvb.7z" "${DOWNLOAD_DIR}/i686-w64-mingw32-gcc-4.8.0-win32_rubenvb.7z")
+endif()
+
+# make mingw root directory
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/mingw
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}
+ )
+endif()
+
+# extract mingw32
+if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/mingw32env.cmd") AND (EXISTS "${DOWNLOAD_DIR}/i686-w64-mingw32-gcc-4.8.0-win32_rubenvb.7z"))
+ message("Extracting mingw32")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/i686-w64-mingw32-gcc-4.8.0-win32_rubenvb.7z
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw
+ )
+endif()
+
+message("Checking for pkg-config")
+if(NOT EXISTS "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip")
+ message("Downloading pkg-config")
+ file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/pkgconfiglite/0.28-1/pkg-config-lite-0.28-1_bin-win32.zip" "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip")
+endif()
+
+# extract pkgconfig
+if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/pkg-config.exe") AND (EXISTS "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip"))
+ message("Extracting pkg-config")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip"
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/
+ )
+
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1/bin/pkg-config.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/pkg-config.exe"
+ )
+
+endif()
+
+message("Checking for nasm")
+if(NOT EXISTS "${DOWNLOAD_DIR}/nasm-2.12.01-win32.zip")
+ message("Downloading nasm")
+ file(DOWNLOAD "http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win32/nasm-2.12.01-win32.zip" "${DOWNLOAD_DIR}/nasm-2.12.01-win32.zip")
+endif()
+
+# extract nasm
+if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe") AND (EXISTS "${DOWNLOAD_DIR}/nasm-2.12.01-win32.zip"))
+ message("Extracting nasm")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/nasm-2.12.01-win32.zip"
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/
+ )
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/nasm-2.12.01/nasm.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/nasm.exe"
+ )
+
+endif()
+
+message("Checking for mingwGet")
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip")
+ message("Downloading mingw-get")
+ file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw/Installer/mingw-get/mingw-get-0.6.2-beta-20131004-1/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip" "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip")
+endif()
+
+# extract mingw_get
+if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get.exe") AND (EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip"))
+ message("Extracting mingw-get")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip"
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw32/
+ )
+endif()
+
+if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get.exe") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/make.exe"))
+ message("Installing MSYS")
+ execute_process(
+ COMMAND ${DOWNLOAD_DIR}/mingw/mingw32/bin/mingw-get install msys msys-patch
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw32/bin/
+ )
+endif()
+
+message("Checking for CoreUtils")
+# download old core_utils for pr.exe (ffmpeg needs it to build)
+if(NOT EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")
+ message("Downloading CoreUtils 5.97")
+ file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw/MSYS/Base/msys-core/_obsolete/coreutils-5.97-MSYS-1.0.11-2/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2" "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")
+endif()
+
+if((EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/pr.exe"))
+ message("Installing pr from CoreUtils 5.97")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/tmp_coreutils
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}
+ )
+
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/tmp_coreutils/
+ )
+
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy ${DOWNLOAD_DIR}/tmp_coreutils/coreutils-5.97/bin/pr.exe "${DOWNLOAD_DIR}/mingw/mingw32/msys/1.0/bin/pr.exe"
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/tmp_coreutils/
+ )
+endif()
+
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/ming32sh.cmd")
+ message("Installing ming32sh.cmd")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/ming32sh.cmd ${DOWNLOAD_DIR}/mingw/mingw32/ming32sh.cmd
+ )
+endif()
+
+message("Checking for perl")
+# download perl for libvpx
+if(NOT EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip")
+ message("Downloading perl")
+ file(DOWNLOAD "http://strawberryperl.com/download/5.22.1.3/strawberry-perl-5.22.1.3-32bit-portable.zip" "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip")
+endif()
+
+# make perl root directory
+if(NOT EXISTS "${DOWNLOAD_DIR}/perl32")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/perl32
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}
+ )
+endif()
+
+# extract perl
+if((NOT EXISTS "${DOWNLOAD_DIR}/perl32/portable.perl") AND (EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip"))
+ message("Extracting perl")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-32bit-portable.zip
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/perl32
+ )
+endif()
+
+# get yasm for vpx
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/yasm.exe")
+ message("Downloading yasm")
+ file(DOWNLOAD "http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win32.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/yasm.exe")
+endif()
+
+message("checking i686-w64-mingw32-strings")
+# copy strings.exe to i686-w64-mingw32-strings for x264
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strings.exe")
+ message("fixing i686-w64-mingw32-strings.exe")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/strings.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strings.exe"
+ )
+endif()
+
+message("checking i686-w64-mingw32-ar.exe")
+# copy ar.exe to i686-w64-mingw32-ar.exe for x264
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ar.exe")
+ message("fixing i686-w64-mingw32-ar.exe")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/ar.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ar.exe"
+ )
+endif()
+
+message("checking i686-w64-mingw32-strip.exe")
+# copy strip.exe to i686-w64-mingw32-strip.exe for x264
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strip.exe")
+ message("fixing i686-w64-mingw32-strip.exe")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/strip.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-strip.exe"
+ )
+endif()
+
+message("checking i686-w64-mingw32-ranlib.exe")
+# copy ranlib.exe to i686-w64-mingw32-ranlib.exe for x264
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ranlib.exe")
+ message("fixing i686-w64-mingw32-ranlib.exe")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw32/bin/ranlib.exe" "${DOWNLOAD_DIR}/mingw/mingw32/bin/i686-w64-mingw32-ranlib.exe"
+ )
+endif()
+
diff --git a/build_files/build_environment/cmake/setup_mingw64.cmake b/build_files/build_environment/cmake/setup_mingw64.cmake
new file mode 100644
index 00000000000..14f75d410b4
--- /dev/null
+++ b/build_files/build_environment/cmake/setup_mingw64.cmake
@@ -0,0 +1,219 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+####################################################################################################################
+# Mingw64 Builds
+####################################################################################################################
+# This installs mingw64+msys to compile ffmpeg/iconv/libsndfile/lapack/fftw3
+####################################################################################################################
+
+message("LIBDIR = ${LIBDIR}")
+macro(cmake_to_msys_path MsysPath ResultingPath)
+ string(REPLACE ":" "" TmpPath "${MsysPath}")
+ string(SUBSTRING ${TmpPath} 0 1 Drive)
+ string(SUBSTRING ${TmpPath} 1 255 PathPart)
+ string(TOLOWER ${Drive} LowerDrive)
+ string(CONCAT ${ResultingPath} "/" ${LowerDrive} ${PathPart})
+endmacro()
+cmake_to_msys_path(${LIBDIR} mingw_LIBDIR)
+message("mingw_LIBDIR = ${mingw_LIBDIR}")
+
+message("Checking for mingw64")
+# download ming64
+if(NOT EXISTS "${DOWNLOAD_DIR}/x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb.7z")
+ message("Downloading mingw64")
+ file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw-w64/Toolchains%20targetting%20Win64/Personal%20Builds/rubenvb/gcc-4.8-release/x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb.7z" "${DOWNLOAD_DIR}/x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb.7z")
+endif()
+
+# make mingw root directory
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/mingw
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}
+ )
+endif()
+
+# extract mingw64
+if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/mingw64env.cmd") AND (EXISTS "${DOWNLOAD_DIR}/x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb.7z"))
+ message("Extracting mingw64")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/x86_64-w64-mingw32-gcc-4.8.0-win64_rubenvb.7z
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw
+ )
+endif()
+
+message("Checking for pkg-config")
+if(NOT EXISTS "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip")
+ message("Downloading pkg-config")
+ file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/pkgconfiglite/0.28-1/pkg-config-lite-0.28-1_bin-win32.zip" "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip")
+endif()
+
+# extract pkgconfig
+if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/pkg-config.exe") AND (EXISTS "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip"))
+ message("Extracting pkg-config")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1_bin-win32.zip"
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/
+ )
+
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/pkg-config-lite-0.28-1/bin/pkg-config.exe" "${DOWNLOAD_DIR}/mingw/mingw64/bin/pkg-config.exe"
+ )
+
+endif()
+
+message("Checking for nasm")
+if(NOT EXISTS "${DOWNLOAD_DIR}/nasm-2.12.01-win64.zip")
+ message("Downloading nasm")
+ file(DOWNLOAD "http://www.nasm.us/pub/nasm/releasebuilds/2.12.01/win64/nasm-2.12.01-win64.zip" "${DOWNLOAD_DIR}/nasm-2.12.01-win64.zip")
+endif()
+
+# extract nasm
+if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/nasm.exe") AND (EXISTS "${DOWNLOAD_DIR}/nasm-2.12.01-win64.zip"))
+ message("Extracting nasm")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/nasm-2.12.01-win64.zip"
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/
+ )
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/nasm-2.12.01/nasm.exe" "${DOWNLOAD_DIR}/mingw/mingw64/bin/nasm.exe"
+ )
+
+endif()
+
+message("Checking for mingwGet")
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip")
+ message("Downloading mingw-get")
+ file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw/Installer/mingw-get/mingw-get-0.6.2-beta-20131004-1/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip" "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip")
+endif()
+
+# extract mingw_get
+if((NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/mingw-get.exe") AND (EXISTS "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip"))
+ message("Extracting mingw-get")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf "${DOWNLOAD_DIR}/mingw-get-0.6.2-mingw32-beta-20131004-1-bin.zip"
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw64/
+ )
+endif()
+
+if((EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/mingw-get.exe") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/make.exe"))
+ message("Installing MSYS")
+ execute_process(
+ COMMAND ${DOWNLOAD_DIR}/mingw/mingw64/bin/mingw-get install msys msys-patch
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/mingw/mingw64/bin/
+ )
+endif()
+
+message("Checking for CoreUtils")
+# download old core_utils for pr.exe (ffmpeg needs it to build)
+if(NOT EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")
+ message("Downloading CoreUtils 5.97")
+ file(DOWNLOAD "https://nchc.dl.sourceforge.net/project/mingw/MSYS/Base/msys-core/_obsolete/coreutils-5.97-MSYS-1.0.11-2/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2" "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2")
+endif()
+
+if((EXISTS "${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2") AND (NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/pr.exe"))
+ message("Installing pr from CoreUtils 5.97")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/tmp_coreutils
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}
+ )
+
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/coreutils-5.97-MSYS-1.0.11-snapshot.tar.bz2
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/tmp_coreutils/
+ )
+
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy ${DOWNLOAD_DIR}/tmp_coreutils/coreutils-5.97/bin/pr.exe "${DOWNLOAD_DIR}/mingw/mingw64/msys/1.0/bin/pr.exe"
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/tmp_coreutils/
+ )
+endif()
+
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/ming64sh.cmd")
+ message("Installing ming64sh.cmd")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/ming64sh.cmd ${DOWNLOAD_DIR}/mingw/mingw64/ming64sh.cmd
+ )
+endif()
+
+message("Checking for perl")
+# download perl for libvpx
+if(NOT EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-64bit-portable.zip")
+ message("Downloading perl")
+ file(DOWNLOAD "http://strawberryperl.com/download/5.22.1.3/strawberry-perl-5.22.1.3-64bit-portable.zip" "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-64bit-portable.zip")
+endif()
+
+# make perl root directory
+if(NOT EXISTS "${DOWNLOAD_DIR}/perl")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${DOWNLOAD_DIR}/perl
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}
+ )
+endif()
+
+# extract perl
+if((NOT EXISTS "${DOWNLOAD_DIR}/perl/portable.perl") AND (EXISTS "${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-64bit-portable.zip"))
+ message("Extracting perl")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E tar jxf ${DOWNLOAD_DIR}/strawberry-perl-5.22.1.3-64bit-portable.zip
+ WORKING_DIRECTORY ${DOWNLOAD_DIR}/perl
+ )
+endif()
+
+# get yasm for vpx
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/yasm.exe")
+ message("Downloading yasm")
+ file(DOWNLOAD "http://www.tortall.net/projects/yasm/releases/yasm-1.3.0-win64.exe" "${DOWNLOAD_DIR}/mingw/mingw64/bin/yasm.exe")
+endif()
+
+message("checking x86_64-w64-mingw32-strings.exe")
+# copy strings.exe to x86_64-w64-mingw32-strings.exe for x264
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/x86_64-w64-mingw32-strings.exe")
+ message("fixing x86_64-w64-mingw32-strings.exe")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw64/bin/strings.exe" "${DOWNLOAD_DIR}/mingw/mingw64/bin/x86_64-w64-mingw32-strings.exe"
+ )
+endif()
+
+message("checking x86_64-w64-mingw32-ar.exe")
+# copy ar.exe to x86_64-w64-mingw32-ar.exe for x264
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/x86_64-w64-mingw32-ar.exe")
+ message("fixing x86_64-w64-mingw32-ar.exe")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw64/bin/ar.exe" "${DOWNLOAD_DIR}/mingw/mingw64/bin/x86_64-w64-mingw32-ar.exe"
+ )
+endif()
+
+message("checking x86_64-w64-mingw32-strip.exe")
+# copy strip.exe to x86_64-w64-mingw32-strip.exe for x264
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/x86_64-w64-mingw32-strip.exe")
+ message("fixing x86_64-w64-mingw32-strip.exe")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw64/bin/strip.exe" "${DOWNLOAD_DIR}/mingw/mingw64/bin/x86_64-w64-mingw32-strip.exe"
+ )
+endif()
+
+message("checking x86_64-w64-mingw32-ranlib.exe")
+# copy ranlib.exe to x86_64-w64-mingw32-ranlib.exe for x264
+if(NOT EXISTS "${DOWNLOAD_DIR}/mingw/mingw64/bin/x86_64-w64-mingw32-ranlib.exe")
+ message("fixing x86_64-w64-mingw32-ranlib.exe")
+ execute_process(
+ COMMAND ${CMAKE_COMMAND} -E copy "${DOWNLOAD_DIR}/mingw/mingw64/bin/ranlib.exe" "${DOWNLOAD_DIR}/mingw/mingw64/bin/x86_64-w64-mingw32-ranlib.exe"
+ )
+endif()
+
diff --git a/build_files/build_environment/cmake/sndfile.cmake b/build_files/build_environment/cmake/sndfile.cmake
new file mode 100644
index 00000000000..fb8d0d98e0e
--- /dev/null
+++ b/build_files/build_environment/cmake/sndfile.cmake
@@ -0,0 +1,44 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(LIBSNDFILE_EXTRA_ARGS)
+set(LIBSNDFILE_ENV PKG_CONFIG_PATH=${mingw_LIBDIR}/ogg/lib/pkgconfig:${mingw_LIBDIR}/vorbis/lib/pkgconfig:${mingw_LIBDIR}/flac/lib/pkgconfig:${mingw_LIBDIR})
+
+if(WIN32)
+ set(LIBSNDFILE_ENV set ${LIBSNDFILE_ENV} &&)
+endif()
+
+ExternalProject_Add(external_sndfile
+ URL ${LIBSNDFILE_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${LIBSNDFILE_HASH}
+ PREFIX ${BUILD_DIR}/sndfile
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && ${LIBSNDFILE_ENV} ${CONFIGURE_COMMAND} --enable-static --disable-shared --prefix=${mingw_LIBDIR}/sndfile
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/sndfile/src/external_sndfile/ && make install
+ INSTALL_DIR ${LIBDIR}/sndfile
+)
+
+if(MSVC)
+ set_target_properties(external_sndfile PROPERTIES FOLDER Mingw)
+endif()
+
+add_dependencies(external_sndfile external_ogg external_vorbis)
+if(UNIX)
+ add_dependencies(external_sndfile external_flac)
+endif()
diff --git a/build_files/build_environment/cmake/spnav.cmake b/build_files/build_environment/cmake/spnav.cmake
new file mode 100644
index 00000000000..0dec9799715
--- /dev/null
+++ b/build_files/build_environment/cmake/spnav.cmake
@@ -0,0 +1,28 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_spnav
+ URL ${SPNAV_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${SPNAV_HASH}
+ PREFIX ${BUILD_DIR}/spnav
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/spnav/src/external_spnav/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/spnav --disable-shared --enable-static --with-pic
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/spnav/src/external_spnav/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/spnav/src/external_spnav/ && make install
+ INSTALL_DIR ${LIBDIR}/spnav
+)
diff --git a/build_files/build_environment/cmake/tbb.cmake b/build_files/build_environment/cmake/tbb.cmake
new file mode 100644
index 00000000000..c4055d55648
--- /dev/null
+++ b/build_files/build_environment/cmake/tbb.cmake
@@ -0,0 +1,36 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(TBB_EXTRA_ARGS
+ -DTBB_BUILD_SHARED=Off
+ -DTBB_BUILD_TBBMALLOC=Off
+ -DTBB_BUILD_TBBMALLOC_PROXY=Off
+ -DTBB_BUILD_STATIC=On
+)
+
+# CMake script for TBB from https://github.com/wjakob/tbb/blob/master/CMakeLists.txt
+ExternalProject_Add(external_tbb
+ URL ${TBB_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${TBB_HASH}
+ PREFIX ${BUILD_DIR}/tbb
+ PATCH_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${PATCH_DIR}/cmakelists_tbb.txt ${BUILD_DIR}/tbb/src/external_tbb/CMakeLists.txt &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/tbb/src/external_tbb/build/vs2010/version_string.ver ${BUILD_DIR}/tbb/src/external_tbb/src/tbb/version_string.ver
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/tbb ${DEFAULT_CMAKE_FLAGS} ${TBB_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/tbb
+)
diff --git a/build_files/build_environment/cmake/theora.cmake b/build_files/build_environment/cmake/theora.cmake
new file mode 100644
index 00000000000..03aad42f2db
--- /dev/null
+++ b/build_files/build_environment/cmake/theora.cmake
@@ -0,0 +1,40 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_theora
+ URL ${THEORA_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${THEORA_HASH}
+ PREFIX ${BUILD_DIR}/theora
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/theora/src/external_theora/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/theora
+ --disable-shared
+ --enable-static
+ --with-pic
+ --with-ogg=${LIBDIR}/ogg
+ --with-vorbis=${LIBDIR}/vorbis
+ --disable-examples
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/theora/src/external_theora/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/theora/src/external_theora/ && make install
+ INSTALL_DIR ${LIBDIR}/theora
+)
+
+add_dependencies(external_theora external_vorbis external_ogg)
+
+if(MSVC)
+ set_target_properties(external_theora PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/tiff.cmake b/build_files/build_environment/cmake/tiff.cmake
new file mode 100644
index 00000000000..2c01341eb21
--- /dev/null
+++ b/build_files/build_environment/cmake/tiff.cmake
@@ -0,0 +1,44 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(TIFF_EXTRA_ARGS
+ -DZLIB_LIBRARY=${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ -DZLIB_INCLUDE_DIR=${LIBDIR}/zlib/include
+ -DPNG_STATIC=ON
+ -DBUILD_SHARED_LIBS=OFF
+ -Dlzma=OFF
+ -Djbig=OFF
+)
+
+ExternalProject_Add(external_tiff
+ URL ${TIFF_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${TIFF_HASH}
+ PREFIX ${BUILD_DIR}/tiff
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/tiff ${DEFAULT_CMAKE_FLAGS} ${TIFF_EXTRA_ARGS}
+ INSTALL_DIR ${LIBDIR}/tiff
+)
+
+add_dependencies(external_tiff external_zlib)
+
+if(BUILD_MODE STREQUAL Debug)
+ ExternalProject_Add_Step(external_tiff after_install
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/tiff/lib/tiffd${LIBEXT} ${LIBDIR}/tiff/lib/tiff${LIBEXT}
+ DEPENDEES install
+ )
+endif()
diff --git a/build_files/build_environment/cmake/versions.cmake b/build_files/build_environment/cmake/versions.cmake
new file mode 100644
index 00000000000..fe60e04ee43
--- /dev/null
+++ b/build_files/build_environment/cmake/versions.cmake
@@ -0,0 +1,245 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(ZLIB_VERSION 1.2.8)
+set(ZLIB_URI https://netcologne.dl.sourceforge.net/project/libpng/zlib/${ZLIB_VERSION}/zlib-${ZLIB_VERSION}.tar.gz)
+set(ZLIB_HASH 44d667c142d7cda120332623eab69f40)
+
+set(OPENAL_VERSION 1.17.2)
+set(OPENAL_URI http://kcat.strangesoft.net/openal-releases/openal-soft-${OPENAL_VERSION}.tar.bz2)
+set(OPENAL_HASH 1764e0d8fec499589b47ebc724e0913d)
+
+set(PNG_VERSION 1.6.21)
+set(PNG_URI http://prdownloads.sourceforge.net/libpng/libpng-${PNG_VERSION}.tar.gz)
+set(PNG_HASH aca36ec8e0a3b406a5912243bc243717)
+
+set(JPEG_VERSION 1.4.2)
+set(JPEG_URI https://github.com/libjpeg-turbo/libjpeg-turbo/archive/${JPEG_VERSION}.tar.gz)
+set(JPEG_HASH f9804884c1c41eb7f4febb9353a2cb27)
+
+set(BOOST_VERSION 1.60.0)
+set(BOOST_VERSION_NODOTS 1_60_0)
+set(BOOST_URI http://sourceforge.net/projects/boost/files/boost/${BOOST_VERSION}/boost_${BOOST_VERSION_NODOTS}.tar.bz2/download)
+set(BOOST_MD5 65a840e1a0b13a558ff19eeb2c4f0cbe)
+
+set(BLOSC_VERSION 1.7.1)
+set(BLOSC_URI https://github.com/Blosc/c-blosc/archive/v${BLOSC_VERSION}.zip)
+set(BLOSC_HASH ff5cc729a5a25934ef714217218eed26)
+
+set(PTHREADS_VERSION 2-9-1)
+set(PTHREADS_URI ftp://sourceware.org/pub/pthreads-win32/pthreads-w32-${PTHREADS_VERSION}-release.tar.gz)
+set(PTHREADS_SHA512 9c06e85310766834370c3dceb83faafd397da18a32411ca7645c8eb6b9495fea54ca2872f4a3e8d83cb5fdc5dea7f3f0464be5bb9af3222a6534574a184bd551)
+
+set(ILMBASE_VERSION 2.2.0)
+set(ILMBASE_URI http://download.savannah.nongnu.org/releases/openexr/ilmbase-${ILMBASE_VERSION}.tar.gz)
+set(ILMBASE_HASH b540db502c5fa42078249f43d18a4652)
+
+set(OPENEXR_VERSION 2.2.0)
+set(OPENEXR_URI http://download.savannah.nongnu.org/releases/openexr/openexr-2.2.0.tar.gz)
+set(OPENEXR_HASH b64e931c82aa3790329c21418373db4e)
+
+set(FREETYPE_VERSION 263)
+set(FREETYPE_URI http://download.savannah.gnu.org/releases/freetype/ft${FREETYPE_VERSION}.zip)
+set(FREETYPE_HASH 0db2a43301572e5c2b4a0864f237aeeb)
+
+set(GLEW_VERSION 1.13.0)
+set(GLEW_URI http://prdownloads.sourceforge.net/glew/glew/${GLEW_VERSION}/glew-${GLEW_VERSION}.tgz)
+set(GLEW_HASH 7cbada3166d2aadfc4169c4283701066)
+
+set(FREEGLUT_VERSION 3.0.0)
+set(FREEGLUT_URI http://pilotfiber.dl.sourceforge.net/project/freeglut/freeglut/${FREEGLUT_VERSION}/freeglut-${FREEGLUT_VERSION}.tar.gz)
+set(FREEGLUT_HASH 90c3ca4dd9d51cf32276bc5344ec9754)
+
+set(HDF5_VERSION 1.8.17)
+set(HDF5_URI https://support.hdfgroup.org/ftp/HDF5/releases/hdf5-1.8/hdf5-${HDF5_VERSION}/src/hdf5-${HDF5_VERSION}.tar.gz)
+set(HDF5_HASH 7d572f8f3b798a628b8245af0391a0ca)
+
+set(ALEMBIC_VERSION 1.7.1)
+set(ALEMBIC_URI https://github.com/alembic/alembic/archive/${ALEMBIC_VERSION}.zip)
+set(ALEMBIC_MD5 cf7705055501d5ea0cb8256866496f79)
+
+## hash is for 3.1.2
+set(GLFW_GIT_UID 30306e54705c3adae9fe082c816a3be71963485c)
+set(GLFW_URI https://github.com/glfw/glfw/archive/${GLFW_GIT_UID}.zip)
+set(GLFW_HASH 20cacb1613da7eeb092f3ac4f6b2b3d0)
+
+#latest uid in git as of 2016-04-01
+set(CLEW_GIT_UID 277db43f6cafe8b27c6f1055f69dc67da4aeb299)
+set(CLEW_URI https://github.com/OpenCLWrangler/clew/archive/${CLEW_GIT_UID}.zip)
+set(CLEW_HASH 2c699d10ed78362e71f56fae2a4c5f98)
+
+#latest uid in git as of 2016-04-01
+set(CUEW_GIT_UID 1744972026de9cf27c8a7dc39cf39cd83d5f922f)
+set(CUEW_URI https://github.com/CudaWrangler/cuew/archive/${CUEW_GIT_UID}.zip)
+set(CUEW_HASH 86760d62978ebfd96cd93f5aa1abaf4a)
+
+set(OPENSUBDIV_VERSION v3_1_1)
+set(OPENSUBDIV_Hash 25a9a6a94136b0eb85ce69e9c8cb6ab3)
+set(OPENSUBDIV_URI https://github.com/PixarAnimationStudios/OpenSubdiv/archive/${OPENSUBDIV_VERSION}.zip)
+
+set(SDL_VERSION 2.0.4)
+set(SDL_URI https://www.libsdl.org/release/SDL2-${SDL_VERSION}.tar.gz)
+set(SDL_HASH 44fc4a023349933e7f5d7a582f7b886e)
+
+set(OPENCOLLADA_VERSION v1.6.51)
+set(OPENCOLLADA_URI https://github.com/KhronosGroup/OpenCOLLADA/archive/${OPENCOLLADA_VERSION}.tar.gz)
+set(OPENCOLLADA_HASH 23db5087faed4bc4cc1dfe456c0d4701)
+
+set(OPENCOLORIO_URI https://github.com/imageworks/OpenColorIO/archive/6de971097c7f552300f669ed69ca0b6cf5a70843.zip)
+set(OPENCOLORIO_HASH c9de0fd98f26ce6f2e08d617ca68b8e4)
+
+set(LLVM_VERSION 3.4.2)
+set(LLVM_URI http://llvm.org/releases/${LLVM_VERSION}/llvm-${LLVM_VERSION}.src.tar.gz)
+set(LLVM_HASH a20669f75967440de949ac3b1bad439c)
+
+set(CLANG_URI http://llvm.org/releases/${LLVM_VERSION}/cfe-${LLVM_VERSION}.src.tar.gz)
+set(CLANG_HASH 87945973b7c73038871c5f849a818588)
+
+set(OPENIMAGEIO_VERSION 1.7.15)
+set(OPENIMAGEIO_URI https://github.com/OpenImageIO/oiio/archive/Release-${OPENIMAGEIO_VERSION}.zip)
+set(OPENIMAGEIO_HASH_178 e156e3669af0e1373142ab5e8f13de66)
+set(OPENIMAGEIO_HASH_179 4121cb0e0433bda6a7ef32c8628a149f)
+set(OPENIMAGEIO_HASH_1713 42a662775b834161ba88c6abdb299360)
+set(OPENIMAGEIO_HASH_1715 e2ece0f62c013d64c478f82265988b0b)
+set(OPENIMAGEIO_HASH ${OPENIMAGEIO_HASH_1715})
+
+
+set(TIFF_VERSION 4.0.6)
+set(TIFF_URI http://download.osgeo.org/libtiff/tiff-${TIFF_VERSION}.tar.gz)
+set(TIFF_HASH d1d2e940dea0b5ad435f21f03d96dd72)
+
+set(FLEXBISON_VERSION 2.5.5)
+set(FLEXBISON_URI http://prdownloads.sourceforge.net/winflexbison//win_flex_bison-2.5.5.zip)
+set(FLEXBISON_HASH d87a3938194520d904013abef3df10ce)
+
+set(OSL_VERSION 1.7.5)
+set(OSL_URI https://github.com/imageworks/OpenShadingLanguage/archive/Release-${OSL_VERSION}.zip)
+set(OSL_HASH 6924dd5d453159e7b6eb106a08c358cf)
+
+set(PYTHON_VERSION 3.5.3)
+set(PYTHON_SHORT_VERSION 3.5)
+set(PYTHON_URI https://www.python.org/ftp/python/${PYTHON_VERSION}/Python-${PYTHON_VERSION}.tar.xz)
+set(PYTHON_HASH 57d1f8bfbabf4f2500273fb0706e6f21)
+
+set(TBB_VERSION 44_20160128)
+set(TBB_URI https://www.threadingbuildingblocks.org/sites/default/files/software_releases/source/tbb${TBB_VERSION}oss_src_0.tgz)
+set(TBB_HASH 9d8a4cdf43496f1b3f7c473a5248e5cc)
+
+set(OPENVDB_VERSION 3.1.0)
+set(OPENVDB_URI https://github.com/dreamworksanimation/openvdb/archive/v${OPENVDB_VERSION}.tar.gz)
+set(OPENVDB_HASH 30a7e9571a03ab7bcf1a39fb62aa436f)
+
+set(REQUESTS_VERSION v2.10.0)
+set(REQUESTS_URI https://github.com/kennethreitz/requests/archive/${REQUESTS_VERSION}.zip)
+set(REQUESTS_HASH 6ebefdf0210c7f0933f61501334e46c3)
+
+set(NUMPY_VERSION v1.10.1)
+set(NUMPY_SHORT_VERSION 1.10)
+set(NUMPY_URI https://pypi.python.org/packages/a5/2e/5412784108f5dc0f827fb460ccdeaa9d76286979fe5ddd070d526d168a59/numpy-1.10.1.zip)
+set(NUMPY_HASH 6f57c58bc5b28440fbeccd505da63d58)
+
+set(LAME_VERSION 3.99.5)
+set(LAME_URI http://downloads.sourceforge.net/project/lame/lame/3.99/lame-${LAME_VERSION}.tar.gz)
+set(LAME_HASH 84835b313d4a8b68f5349816d33e07ce)
+
+set(OGG_VERSION 1.3.2)
+set(OGG_URI http://downloads.xiph.org/releases/ogg/libogg-${OGG_VERSION}.tar.gz)
+set(OGG_HASH e19ee34711d7af328cb26287f4137e70630e7261b17cbe3cd41011d73a654692)
+
+set(VORBIS_VERSION 1.3.5)
+set(VORBIS_URI http://downloads.xiph.org/releases/vorbis/libvorbis-${VORBIS_VERSION}.tar.gz)
+set(VORBIS_HASH 6efbcecdd3e5dfbf090341b485da9d176eb250d893e3eb378c428a2db38301ce)
+
+set(THEORA_VERSION 1.1.1)
+set(THEORA_URI http://downloads.xiph.org/releases/theora/libtheora-${THEORA_VERSION}.tar.bz2)
+set(THEORA_HASH b6ae1ee2fa3d42ac489287d3ec34c5885730b1296f0801ae577a35193d3affbc)
+
+set(FLAC_VERSION 1.3.1)
+set(FLAC_URI http://downloads.xiph.org/releases/flac/flac-${FLAC_VERSION}.tar.xz)
+set(FLAC_HASH 4773c0099dba767d963fd92143263be338c48702172e8754b9bc5103efe1c56c)
+
+set(VPX_VERSION 1.5.0)
+set(VPX_URI http://storage.googleapis.com/downloads.webmproject.org/releases/webm/libvpx-${VPX_VERSION}.tar.bz2)
+set(VPX_HASH 306d67908625675f8e188d37a81fbfafdf5068b09d9aa52702b6fbe601c76797)
+
+set(ORC_VERSION 0.4.25)
+set(ORC_URI https://gstreamer.freedesktop.org/src/orc/orc-${ORC_VERSION}.tar.xz)
+set(ORC_HASH c1b1d54a58f26d483f0b3881538984789fe5d5460ab8fab74a1cacbd3d1c53d1)
+
+set(SCHROEDINGER_VERSION 1.0.11)
+set(SCHROEDINGER_URI https://download.videolan.org/contrib/schroedinger/schroedinger-${SCHROEDINGER_VERSION}.tar.gz)
+set(SCHROEDINGER_HASH 1e572a0735b92aca5746c4528f9bebd35aa0ccf8619b22fa2756137a8cc9f912)
+
+set(X264_URI http://download.videolan.org/pub/videolan/x264/snapshots/x264-snapshot-20160401-2245-stable.tar.bz2)
+set(X264_HASH 1e9a7b835e80313aade53a9b6ff353e099de3856bf5f30a4d8dfc91281f786f5)
+
+set(XVIDCORE_VERSION 1.3.4)
+set(XVIDCORE_URI http://downloads.xvid.org/downloads/xvidcore-${XVIDCORE_VERSION}.tar.gz)
+set(XVIDCORE_HASH 4e9fd62728885855bc5007fe1be58df42e5e274497591fec37249e1052ae316f)
+
+set(OPENJPEG_VERSION 1.5)
+set(OPENJPEG_URI https://github.com/uclouvain/openjpeg/archive/version.${OPENJPEG_VERSION}.tar.gz)
+set(OPENJPEG_HASH 60662566595e02104c0f6d1052f8b1669624c646e62b6280d5fd5a66d4e92f8d)
+
+set(FAAD_VERSION 2-2.7)
+set(FAAD_URI http://downloads.sourceforge.net/faac/faad${FAAD_VERSION}.tar.bz2)
+set(FAAD_HASH 4c332fa23febc0e4648064685a3d4332)
+
+set(FFMPEG_VERSION 3.2.1)
+set(FFMPEG_URI http://ffmpeg.org/releases/ffmpeg-${FFMPEG_VERSION}.tar.bz2)
+set(FFMPEG_HASH cede174178e61f882844f5870c35ce72)
+
+set(FFTW_VERSION 3.3.4)
+set(FFTW_URI http://www.fftw.org/fftw-${FFTW_VERSION}.tar.gz)
+set(FFTW_HASH 2edab8c06b24feeb3b82bbb3ebf3e7b3)
+
+set(ICONV_VERSION 1.14)
+set(ICONV_URI http://ftp.gnu.org/pub/gnu/libiconv/libiconv-${ICONV_VERSION}.tar.gz)
+set(ICONV_HASH e34509b1623cec449dfeb73d7ce9c6c6)
+
+set(LAPACK_VERSION 3.6.0)
+set(LAPACK_URI http://www.netlib.org/lapack/lapack-${LAPACK_VERSION}.tgz)
+set(LAPACK_HASH f2f6c67134e851fe189bb3ca1fbb5101)
+
+set(LIBSNDFILE_VERSION 1.0.26)
+set(LIBSNDFILE_URI http://www.mega-nerd.com/libsndfile/files/libsndfile-${LIBSNDFILE_VERSION}.tar.gz)
+set(LIBSNDFILE_HASH ec810a0c60c08772a8a5552704b63393)
+
+#set(HIDAPI_VERSION 0.8.0-rc1)
+#set(HIDAPI_URI https://github.com/signal11/hidapi/archive/hidapi-${HIDAPI_VERSION}.tar.gz)
+#set(HIDAPI_HASH 069f9dd746edc37b6b6d0e3656f47199)
+
+set(HIDAPI_UID 89a6c75dc6f45ecabd4ddfbd2bf5ba6ad8ba38b5)
+set(HIDAPI_URI https://github.com/TheOnlyJoey/hidapi/archive/${HIDAPI_UID}.zip)
+set(HIDAPI_HASH b6e22f6b514f8bcf594989f20ffc46fb)
+
+set(WEBP_VERSION 0.5.1)
+set(WEBP_URI https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-${WEBP_VERSION}.tar.gz)
+set(WEBP_HASH 3d7db92ebba5b4f679413d25c6040881)
+
+set(SPNAV_VERSION 0.2.3)
+set(SPNAV_URI http://downloads.sourceforge.net/project/spacenav/spacenav%20library%20%28SDK%29/libspnav%20${SPNAV_VERSION}/libspnav-${SPNAV_VERSION}.tar.gz)
+set(SPNAV_HASH 44d840540d53326d4a119c0f1aa7bf0a)
+
+set(JEMALLOC_VERSION 5.0.1)
+set(JEMALLOC_URI https://github.com/jemalloc/jemalloc/releases/download/${JEMALLOC_VERSION}/jemalloc-${JEMALLOC_VERSION}.tar.bz2)
+set(JEMALLOC_HASH 507f7b6b882d868730d644510491d18f)
+
+set(XML2_VERSION 2.9.4)
+set(XML2_URI ftp://xmlsoft.org/libxml2/libxml2-${XML2_VERSION}.tar.gz)
+set(XML2_HASH ae249165c173b1ff386ee8ad676815f5)
diff --git a/build_files/build_environment/cmake/vorbis.cmake b/build_files/build_environment/cmake/vorbis.cmake
new file mode 100644
index 00000000000..d16c7c6a1bc
--- /dev/null
+++ b/build_files/build_environment/cmake/vorbis.cmake
@@ -0,0 +1,38 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_vorbis
+ URL ${VORBIS_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${VORBIS_HASH}
+ PREFIX ${BUILD_DIR}/vorbis
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/vorbis/src/external_vorbis/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/vorbis
+ --disable-shared
+ --enable-static
+ --with-pic
+ --with-ogg=${LIBDIR}/ogg
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/vorbis/src/external_vorbis/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/vorbis/src/external_vorbis/ && make install
+ INSTALL_DIR ${LIBDIR}/vorbis
+)
+
+add_dependencies(external_vorbis external_ogg)
+
+if(MSVC)
+ set_target_properties(external_vorbis PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/vpx.cmake b/build_files/build_environment/cmake/vpx.cmake
new file mode 100644
index 00000000000..9d155be1c6c
--- /dev/null
+++ b/build_files/build_environment/cmake/vpx.cmake
@@ -0,0 +1,60 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8")
+ set(VPX_EXTRA_FLAGS --target=x86_64-win64-gcc)
+ else()
+ set(VPX_EXTRA_FLAGS --target=x86-win32-gcc)
+ endif()
+else()
+ if(APPLE)
+ set(VPX_EXTRA_FLAGS --target=x86_64-darwin13-gcc)
+ else()
+ set(VPX_EXTRA_FLAGS --target=generic-gnu)
+ endif()
+endif()
+
+ExternalProject_Add(external_vpx
+ URL ${VPX_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${VPX_HASH}
+ PREFIX ${BUILD_DIR}/vpx
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} &&
+ cd ${BUILD_DIR}/vpx/src/external_vpx/ &&
+ ${CONFIGURE_COMMAND_NO_TARGET} --prefix=${LIBDIR}/vpx
+ --disable-shared
+ --enable-static
+ --disable-install-bins
+ --disable-install-srcs
+ --disable-sse4_1
+ --disable-sse3
+ --disable-ssse3
+ --disable-avx
+ --disable-avx2
+ --disable-unit-tests
+ --disable-examples
+ ${VPX_EXTRA_FLAGS}
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/vpx/src/external_vpx/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/vpx/src/external_vpx/ && make install
+ INSTALL_DIR ${LIBDIR}/vpx
+)
+
+if(MSVC)
+ set_target_properties(external_vpx PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/webp.cmake b/build_files/build_environment/cmake/webp.cmake
new file mode 100644
index 00000000000..0504988a088
--- /dev/null
+++ b/build_files/build_environment/cmake/webp.cmake
@@ -0,0 +1,50 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# Note the utility apps may use png/tiff/gif system libraries, but the
+# library itself does not depend on them, so should give no problems.
+
+set(WEBP_EXTRA_ARGS
+ -DWEBP_HAVE_SSE2=ON
+ -DWEBP_HAVE_SSE41=OFF
+ -DWEBP_HAVE_AVX2=OFF
+)
+
+if(WIN32)
+ set(WEBP_BUILD_DIR ${BUILD_MODE}/)
+else()
+ set(WEBP_BUILD_DIR)
+endif()
+
+ExternalProject_Add(external_webp
+ URL ${WEBP_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${WEBP_HASH}
+ PREFIX ${BUILD_DIR}/webp
+ CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${LIBDIR}/webp -Wno-dev ${DEFAULT_CMAKE_FLAGS} ${WEBP_EXTRA_ARGS}
+ INSTALL_COMMAND COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp-build/${WEBP_BUILD_DIR}${LIBPREFIX}webp${LIBEXT} ${LIBDIR}/webp/lib/${LIBPREFIX}webp${LIBEXT} &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/decode.h ${LIBDIR}/webp/include/webp/decode.h &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/encode.h ${LIBDIR}/webp/include/webp/encode.h &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/demux.h ${LIBDIR}/webp/include/webp/demux.h &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/extras.h ${LIBDIR}/webp/include/webp/extras.h &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/format_constants.h ${LIBDIR}/webp/include/webp/format_constants.h &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/mux.h ${LIBDIR}/webp/include/webp/mux.h &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/mux_types.h ${LIBDIR}/webp/include/webp/mux_types.h &&
+ ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/webp/src/external_webp/src/webp/types.h ${LIBDIR}/webp/include/webp/types.h
+ INSTALL_DIR ${LIBDIR}/webp
+)
diff --git a/build_files/build_environment/cmake/x264.cmake b/build_files/build_environment/cmake/x264.cmake
new file mode 100644
index 00000000000..64029ca1b5e
--- /dev/null
+++ b/build_files/build_environment/cmake/x264.cmake
@@ -0,0 +1,40 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ set(X264_EXTRA_ARGS --enable-win32thread --cross-prefix=${MINGW_HOST}- --host=${MINGW_HOST})
+endif()
+
+ExternalProject_Add(external_x264
+ URL ${X264_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${X264_HASH}
+ PREFIX ${BUILD_DIR}/x264
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/x264/src/external_x264/ && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/x264
+ --enable-static
+ --enable-pic
+ --disable-lavf
+ ${X264_EXTRA_ARGS}
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/x264/src/external_x264/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/x264/src/external_x264/ && make install
+ INSTALL_DIR ${LIBDIR}/x264
+)
+
+if(MSVC)
+ set_target_properties(external_x264 PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/xml2.cmake b/build_files/build_environment/cmake/xml2.cmake
new file mode 100644
index 00000000000..a8f87a67ad4
--- /dev/null
+++ b/build_files/build_environment/cmake/xml2.cmake
@@ -0,0 +1,36 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_xml2
+ URL ${XML2_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH MD5=${XML2_HASH}
+ PREFIX ${BUILD_DIR}/xml2
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xml2/src/external_xml2/ && ${CONFIGURE_COMMAND}
+ --prefix=${LIBDIR}/xml2
+ --disable-shared
+ --enable-static
+ --with-pic
+ --with-python=no
+ --with-lzma=no
+ --with-zlib=no
+ --with-iconv=no
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xml2/src/external_xml2/ && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xml2/src/external_xml2/ && make install
+ INSTALL_DIR ${LIBDIR}/xml2
+)
diff --git a/build_files/build_environment/cmake/xvidcore.cmake b/build_files/build_environment/cmake/xvidcore.cmake
new file mode 100644
index 00000000000..a341275ea47
--- /dev/null
+++ b/build_files/build_environment/cmake/xvidcore.cmake
@@ -0,0 +1,44 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+if(WIN32)
+ set(XVIDCORE_EXTRA_ARGS --host=${MINGW_HOST})
+endif()
+
+ExternalProject_Add(external_xvidcore
+ URL ${XVIDCORE_URI}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ URL_HASH SHA256=${XVIDCORE_HASH}
+ PREFIX ${BUILD_DIR}/xvidcore
+ CONFIGURE_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xvidcore/src/external_xvidcore/build/generic && ${CONFIGURE_COMMAND} --prefix=${LIBDIR}/xvidcore ${XVIDCORE_EXTRA_ARGS}
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/xvidcore/src/external_xvidcore/build/generic && make -j${MAKE_THREADS}
+ INSTALL_COMMAND ${CONFIGURE_ENV} &&
+ ${CMAKE_COMMAND} -E remove ${LIBDIR}/xvidcore/lib/* && # clean because re-installing fails otherwise
+ cd ${BUILD_DIR}/xvidcore/src/external_xvidcore/build/generic && make install
+ INSTALL_DIR ${LIBDIR}/xvidcore
+)
+
+ExternalProject_Add_Step(external_xvidcore after_install
+ COMMAND ${CMAKE_COMMAND} -E rename ${LIBDIR}/xvidcore/lib/xvidcore.a ${LIBDIR}/xvidcore/lib/libxvidcore.a || true
+ COMMAND ${CMAKE_COMMAND} -E remove ${LIBDIR}/xvidcore/lib/xvidcore.dll.a
+ DEPENDEES install
+)
+
+if(MSVC)
+ set_target_properties(external_xvidcore PROPERTIES FOLDER Mingw)
+endif()
diff --git a/build_files/build_environment/cmake/zlib.cmake b/build_files/build_environment/cmake/zlib.cmake
new file mode 100644
index 00000000000..3307cb1f167
--- /dev/null
+++ b/build_files/build_environment/cmake/zlib.cmake
@@ -0,0 +1,33 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_zlib
+ URL ${ZLIB_URI}
+ URL_HASH MD5=${ZLIB_HASH}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ PREFIX ${BUILD_DIR}/zlib
+ CMAKE_ARGS -DCMAKE_POSITION_INDEPENDENT_CODE=ON -DCMAKE_INSTALL_PREFIX=${LIBDIR}/zlib ${DEFAULT_CMAKE_FLAGS}
+ INSTALL_DIR ${LIBDIR}/zlib
+)
+
+if(BUILD_MODE STREQUAL Debug)
+ ExternalProject_Add_Step(external_zlib after_install
+ COMMAND ${CMAKE_COMMAND} -E copy ${LIBDIR}/zlib/lib/zlibstaticd${LIBEXT} ${LIBDIR}/zlib/lib/${ZLIB_LIBRARY}
+ DEPENDEES install
+ )
+endif()
diff --git a/build_files/build_environment/cmake/zlib_mingw.cmake b/build_files/build_environment/cmake/zlib_mingw.cmake
new file mode 100644
index 00000000000..13345f29ffa
--- /dev/null
+++ b/build_files/build_environment/cmake/zlib_mingw.cmake
@@ -0,0 +1,40 @@
+# ***** 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.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+ExternalProject_Add(external_zlib_mingw
+ URL ${ZLIB_URI}
+ URL_HASH MD5=${ZLIB_HASH}
+ DOWNLOAD_DIR ${DOWNLOAD_DIR}
+ PREFIX ${BUILD_DIR}/zlib_mingw
+ CONFIGURE_COMMAND echo .
+ BUILD_COMMAND ${CONFIGURE_ENV} && cd ${BUILD_DIR}/zlib_mingw/src/external_zlib_mingw/ && make -f win32/makefile.gcc -j${MAKE_THREADS}
+ INSTALL_COMMAND echo .
+ INSTALL_DIR ${LIBDIR}/zlib_mingw
+)
+
+if(BUILD_MODE STREQUAL Release)
+ ExternalProject_Add_Step(external_zlib_mingw after_install
+ COMMAND ${CMAKE_COMMAND} -E copy ${BUILD_DIR}/zlib_mingw/src/external_zlib_mingw/libz.a ${LIBDIR}/zlib/lib/z.lib
+ DEPENDEES install
+ )
+endif()
+
+if(MSVC)
+ set_target_properties(external_zlib_mingw PROPERTIES FOLDER Mingw)
+endif()
+
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index ad9ef3f8594..28eaa70711c 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -1591,7 +1591,7 @@ compile_OIIO() {
fi
# To be changed each time we make edits that would modify the compiled result!
- oiio_magic=16
+ oiio_magic=17
_init_oiio
# Clean install if needed!
@@ -1655,6 +1655,9 @@ compile_OIIO() {
INFO "ILMBASE_HOME=$INST/openexr"
fi
+ # ptex is only needed when nicholas bishop is ready
+ cmake_d="$cmake_d -D USE_PTEX=OFF"
+
# Optional tests and cmd tools
cmake_d="$cmake_d -D USE_QT=OFF"
cmake_d="$cmake_d -D USE_PYTHON=OFF"
@@ -1766,7 +1769,7 @@ compile_LLVM() {
cd $_src
# XXX Ugly patching hack!
- patch -p1 -i "$SCRIPT_DIR/install_deps_patches/llvm.patch"
+ patch -p1 -i "$SCRIPT_DIR/patches/install_deps_llvm.diff"
cd $CWD
@@ -1872,7 +1875,7 @@ compile_OSL() {
git reset --hard
# XXX Ugly patching hack!
- patch -p1 -i "$SCRIPT_DIR/install_deps_patches/osl.patch"
+ patch -p1 -i "$SCRIPT_DIR/patches/install_deps_osl.diff"
fi
# Always refresh the whole build!
@@ -2670,10 +2673,10 @@ install_DEB() {
install_packages_DEB $_packages
PRINT""
- SNDFILE_DEV="libsndfile1-dev"
- check_package_DEB $SNDFILE_DEV
+ LIBSNDFILE_DEV="libsndfile1-dev"
+ check_package_DEB $LIBSNDFILE_DEV
if [ $? -eq 0 ]; then
- install_packages_DEB $SNDFILE_DEV
+ install_packages_DEB $LIBSNDFILE_DEV
fi
PRINT ""
@@ -3268,10 +3271,10 @@ install_RPM() {
fi
PRINT""
- SNDFILE_DEV="libsndfile-devel"
- check_package_RPM $SNDFILE_DEV
+ LIBSNDFILE_DEV="libsndfile-devel"
+ check_package_RPM $LIBSNDFILE_DEV
if [ $? -eq 0 ]; then
- install_packages_RPM $SNDFILE_DEV
+ install_packages_RPM $LIBSNDFILE_DEV
fi
if [ "$WITH_ALL" = true ]; then
@@ -3675,10 +3678,10 @@ install_ARCH() {
install_packages_ARCH $_packages
PRINT""
- SNDFILE_DEV="libsndfile"
- check_package_ARCH $SNDFILE_DEV
+ LIBSNDFILE_DEV="libsndfile"
+ check_package_ARCH $LIBSNDFILE_DEV
if [ $? -eq 0 ]; then
- install_packages_ARCH $SNDFILE_DEV
+ install_packages_ARCH $LIBSNDFILE_DEV
fi
PRINT ""
diff --git a/build_files/build_environment/patches/alembic.diff b/build_files/build_environment/patches/alembic.diff
new file mode 100644
index 00000000000..f869858efb2
--- /dev/null
+++ b/build_files/build_environment/patches/alembic.diff
@@ -0,0 +1,35 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 3e09c57..26565ae 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -116,7 +116,7 @@ IF (NOT ${ALEMBIC_LIB_USES_TR1} AND NOT ${ALEMBIC_LIB_USES_BOOST})
+ INCLUDE(CheckCXXCompilerFlag)
+ CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
+ CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
+- IF (COMPILER_SUPPORTS_CXX1X)
++ IF (COMPILER_SUPPORTS_CXX11)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+ ELSEIF (COMPILER_SUPPORTS_CXX0X)
+ SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
+--- a/lib/Alembic/AbcCoreOgawa/StreamManager.cpp
++++ b/lib/Alembic/AbcCoreOgawa/StreamManager.cpp
+@@ -47,7 +47,18 @@
+ #define COMPARE_EXCHANGE( V, COMP, EXCH ) V.compare_exchange_weak( COMP, EXCH, std::memory_order_seq_cst, std::memory_order_seq_cst )
+ // Windows
+ #elif defined( _MSC_VER )
+-#define COMPARE_EXCHANGE( V, COMP, EXCH ) InterlockedCompareExhange64( &V, EXCH, COMP ) == COMP
++#define COMPARE_EXCHANGE( V, COMP, EXCH ) InterlockedCompareExchange64( &V, EXCH, COMP ) == COMP
++int ffsll(long long value)
++{
++ if (!value)
++ return 0;
++
++ for (int bit = 0; bit < 63; bit++)
++ {
++ if (value & (1 << bit))
++ return bit + 1;
++ }
++}
+ // gcc 4.8 and above not using C++11
+ #elif defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 8
+ #define COMPARE_EXCHANGE( V, COMP, EXCH ) __atomic_compare_exchange_n( &V, &COMP, EXCH, false, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST )
diff --git a/build_files/build_environment/patches/blosc.diff b/build_files/build_environment/patches/blosc.diff
new file mode 100644
index 00000000000..3bd6ef28144
--- /dev/null
+++ b/build_files/build_environment/patches/blosc.diff
@@ -0,0 +1,33 @@
+diff -Naur src/blosc/CMakeLists.txt external_blosc/blosc/CMakeLists.txt
+--- src/blosc/CMakeLists.txt 2016-02-03 10:26:28 -0700
++++ external_blosc/blosc/CMakeLists.txt 2017-03-03 09:03:31 -0700
+@@ -61,6 +61,8 @@
+ set(SOURCES ${SOURCES} win32/pthread.c)
+ else(NOT Threads_FOUND)
+ set(LIBS ${LIBS} ${CMAKE_THREAD_LIBS_INIT})
++ set(LIBS ${LIBS} ${PTHREAD_LIBS})
++ include_directories( ${PTHREAD_INCLUDE_DIR} )
+ endif(NOT Threads_FOUND)
+ else(WIN32)
+ find_package(Threads REQUIRED)
+diff -Naur src/blosc/blosc.c external_blosc/blosc/blosc.c
+--- src/blosc/blosc.c 2016-02-03 10:26:28 -0700
++++ external_blosc/blosc/blosc.c 2017-03-03 09:01:50 -0700
+@@ -49,12 +49,12 @@
+ #include <inttypes.h>
+ #endif /* _WIN32 */
+
+-#if defined(_WIN32) && !defined(__GNUC__)
+- #include "win32/pthread.h"
+- #include "win32/pthread.c"
+-#else
++//#if defined(_WIN32) && !defined(__GNUC__)
++// #include "win32/pthread.h"
++ //#include "win32/pthread.c"
++//#else
+ #include <pthread.h>
+-#endif
++//#endif
+
+ /* If C11 is supported, use it's built-in aligned allocation. */
+ #if __STDC_VERSION__ >= 201112L
diff --git a/build_files/build_environment/patches/clang.diff b/build_files/build_environment/patches/clang.diff
new file mode 100644
index 00000000000..724e92f8163
--- /dev/null
+++ b/build_files/build_environment/patches/clang.diff
@@ -0,0 +1,127 @@
+--- cfe/trunk/lib/Serialization/ASTWriter.cpp
++++ cfe/trunk/lib/Serialization/ASTWriter.cpp
+@@ -56,14 +56,14 @@
+ using namespace clang::serialization;
+
+ template <typename T, typename Allocator>
+-static StringRef bytes(const std::vector<T, Allocator> &v) {
++static StringRef data(const std::vector<T, Allocator> &v) {
+ if (v.empty()) return StringRef();
+ return StringRef(reinterpret_cast<const char*>(&v[0]),
+ sizeof(T) * v.size());
+ }
+
+ template <typename T>
+-static StringRef bytes(const SmallVectorImpl<T> &v) {
++static StringRef data(const SmallVectorImpl<T> &v) {
+ return StringRef(reinterpret_cast<const char*>(v.data()),
+ sizeof(T) * v.size());
+ }
+@@ -1385,7 +1385,7 @@
+ Record.push_back(INPUT_FILE_OFFSETS);
+ Record.push_back(InputFileOffsets.size());
+ Record.push_back(UserFilesNum);
+- Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record, bytes(InputFileOffsets));
++ Stream.EmitRecordWithBlob(OffsetsAbbrevCode, Record, data(InputFileOffsets));
+ }
+
+ //===----------------------------------------------------------------------===//
+@@ -1771,7 +1771,7 @@
+ Record.push_back(SOURCE_LOCATION_OFFSETS);
+ Record.push_back(SLocEntryOffsets.size());
+ Record.push_back(SourceMgr.getNextLocalOffset() - 1); // skip dummy
+- Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, bytes(SLocEntryOffsets));
++ Stream.EmitRecordWithBlob(SLocOffsetsAbbrev, Record, data(SLocEntryOffsets));
+
+ // Write the source location entry preloads array, telling the AST
+ // reader which source locations entries it should load eagerly.
+@@ -2087,7 +2087,7 @@
+ Record.push_back(MacroOffsets.size());
+ Record.push_back(FirstMacroID - NUM_PREDEF_MACRO_IDS);
+ Stream.EmitRecordWithBlob(MacroOffsetAbbrev, Record,
+- bytes(MacroOffsets));
++ data(MacroOffsets));
+ }
+
+ void ASTWriter::WritePreprocessorDetail(PreprocessingRecord &PPRec) {
+@@ -2185,7 +2185,7 @@
+ Record.push_back(PPD_ENTITIES_OFFSETS);
+ Record.push_back(FirstPreprocessorEntityID - NUM_PREDEF_PP_ENTITY_IDS);
+ Stream.EmitRecordWithBlob(PPEOffsetAbbrev, Record,
+- bytes(PreprocessedEntityOffsets));
++ data(PreprocessedEntityOffsets));
+ }
+ }
+
+@@ -2548,7 +2548,7 @@
+ Record.push_back(CXX_BASE_SPECIFIER_OFFSETS);
+ Record.push_back(CXXBaseSpecifiersOffsets.size());
+ Stream.EmitRecordWithBlob(BaseSpecifierOffsetAbbrev, Record,
+- bytes(CXXBaseSpecifiersOffsets));
++ data(CXXBaseSpecifiersOffsets));
+ }
+
+ //===----------------------------------------------------------------------===//
+@@ -2623,7 +2623,7 @@
+ Decls.push_back(std::make_pair((*D)->getKind(), GetDeclRef(*D)));
+
+ ++NumLexicalDeclContexts;
+- Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, bytes(Decls));
++ Stream.EmitRecordWithBlob(DeclContextLexicalAbbrev, Record, data(Decls));
+ return Offset;
+ }
+
+@@ -2642,7 +2642,7 @@
+ Record.push_back(TYPE_OFFSET);
+ Record.push_back(TypeOffsets.size());
+ Record.push_back(FirstTypeID - NUM_PREDEF_TYPE_IDS);
+- Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, bytes(TypeOffsets));
++ Stream.EmitRecordWithBlob(TypeOffsetAbbrev, Record, data(TypeOffsets));
+
+ // Write the declaration offsets array
+ Abbrev = new BitCodeAbbrev();
+@@ -2655,7 +2655,7 @@
+ Record.push_back(DECL_OFFSET);
+ Record.push_back(DeclOffsets.size());
+ Record.push_back(FirstDeclID - NUM_PREDEF_DECL_IDS);
+- Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, bytes(DeclOffsets));
++ Stream.EmitRecordWithBlob(DeclOffsetAbbrev, Record, data(DeclOffsets));
+ }
+
+ void ASTWriter::WriteFileDeclIDsMap() {
+@@ -2680,7 +2680,7 @@
+ unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
+ Record.push_back(FILE_SORTED_DECLS);
+ Record.push_back(FileSortedIDs.size());
+- Stream.EmitRecordWithBlob(AbbrevCode, Record, bytes(FileSortedIDs));
++ Stream.EmitRecordWithBlob(AbbrevCode, Record, data(FileSortedIDs));
+ }
+
+ void ASTWriter::WriteComments() {
+@@ -2893,7 +2893,7 @@
+ Record.push_back(SelectorOffsets.size());
+ Record.push_back(FirstSelectorID - NUM_PREDEF_SELECTOR_IDS);
+ Stream.EmitRecordWithBlob(SelectorOffsetAbbrev, Record,
+- bytes(SelectorOffsets));
++ data(SelectorOffsets));
+ }
+ }
+
+@@ -3253,7 +3253,7 @@
+ Record.push_back(IdentifierOffsets.size());
+ Record.push_back(FirstIdentID - NUM_PREDEF_IDENT_IDS);
+ Stream.EmitRecordWithBlob(IdentifierOffsetAbbrev, Record,
+- bytes(IdentifierOffsets));
++ data(IdentifierOffsets));
+ }
+
+ //===----------------------------------------------------------------------===//
+@@ -4046,7 +4046,7 @@
+ Record.clear();
+ Record.push_back(TU_UPDATE_LEXICAL);
+ Stream.EmitRecordWithBlob(TuUpdateLexicalAbbrev, Record,
+- bytes(NewGlobalDecls));
++ data(NewGlobalDecls));
+
+ // And a visible updates block for the translation unit.
+ Abv = new llvm::BitCodeAbbrev();
diff --git a/build_files/build_environment/patches/cmake/modules/FindBlosc.cmake b/build_files/build_environment/patches/cmake/modules/FindBlosc.cmake
new file mode 100644
index 00000000000..d490b7a2ff3
--- /dev/null
+++ b/build_files/build_environment/patches/cmake/modules/FindBlosc.cmake
@@ -0,0 +1,73 @@
+# - Find BLOSC library
+# Find the native BLOSC includes and library
+# This module defines
+# BLOSC_INCLUDE_DIRS, where to find blosc.h, Set when
+# BLOSC is found.
+# BLOSC_LIBRARIES, libraries to link against to use BLOSC.
+# BLOSC_ROOT_DIR, The base directory to search for BLOSC.
+# This can also be an environment variable.
+# BLOSC_FOUND, If false, do not try to use BLOSC.
+#
+# also defined, but not for general use are
+# BLOSC_LIBRARY, where to find the BLOSC library.
+
+#=============================================================================
+# Copyright 2016 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If BLOSC_ROOT_DIR was defined in the environment, use it.
+IF(NOT BLOSC_ROOT_DIR AND NOT $ENV{BLOSC_ROOT_DIR} STREQUAL "")
+ SET(BLOSC_ROOT_DIR $ENV{BLOSC_ROOT_DIR})
+ENDIF()
+
+SET(_blosc_SEARCH_DIRS
+ ${BLOSC_ROOT_DIR}
+ /usr/local
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt/lib/blosc
+)
+
+FIND_PATH(BLOSC_INCLUDE_DIR
+ NAMES
+ blosc.h
+ HINTS
+ ${_blosc_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include
+)
+
+FIND_LIBRARY(BLOSC_LIBRARY
+ NAMES
+ blosc
+ HINTS
+ ${_blosc_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+)
+
+# handle the QUIETLY and REQUIRED arguments and set BLOSC_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(BLOSC DEFAULT_MSG
+ BLOSC_LIBRARY BLOSC_INCLUDE_DIR)
+
+IF(BLOSC_FOUND)
+ SET(BLOSC_LIBRARIES ${BLOSC_LIBRARY})
+ SET(BLOSC_INCLUDE_DIRS ${BLOSC_INCLUDE_DIR})
+ELSE()
+ SET(BLOSC_FOUND FALSE)
+ENDIF()
+
+MARK_AS_ADVANCED(
+ BLOSC_INCLUDE_DIR
+ BLOSC_LIBRARY
+)
diff --git a/build_files/build_environment/patches/cmake/modules/FindCppUnit.cmake b/build_files/build_environment/patches/cmake/modules/FindCppUnit.cmake
new file mode 100644
index 00000000000..3dd480356af
--- /dev/null
+++ b/build_files/build_environment/patches/cmake/modules/FindCppUnit.cmake
@@ -0,0 +1,73 @@
+# - Find CPPUNIT library
+# Find the native CPPUNIT includes and library
+# This module defines
+# CPPUNIT_INCLUDE_DIRS, where to find cppunit.h, Set when
+# CPPUNIT is found.
+# CPPUNIT_LIBRARIES, libraries to link against to use CPPUNIT.
+# CPPUNIT_ROOT_DIR, The base directory to search for CPPUNIT.
+# This can also be an environment variable.
+# CPPUNIT_FOUND, If false, do not try to use CPPUNIT.
+#
+# also defined, but not for general use are
+# CPPUNIT_LIBRARY, where to find the CPPUNIT library.
+
+#=============================================================================
+# Copyright 2016 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If CPPUNIT_ROOT_DIR was defined in the environment, use it.
+IF(NOT CPPUNIT_ROOT_DIR AND NOT $ENV{CPPUNIT_ROOT_DIR} STREQUAL "")
+ SET(CPPUNIT_ROOT_DIR $ENV{CPPUNIT_ROOT_DIR})
+ENDIF()
+
+SET(_cppunit_SEARCH_DIRS
+ ${CPPUNIT_ROOT_DIR}
+ /usr/local
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt/lib/cppunit
+)
+
+FIND_PATH(CPPUNIT_INCLUDE_DIR
+ NAMES
+ cppunit/Test.h
+ HINTS
+ ${_cppunit_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include
+)
+
+FIND_LIBRARY(CPPUNIT_LIBRARY
+ NAMES
+ cppunit
+ HINTS
+ ${_cppunit_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+)
+
+# handle the QUIETLY and REQUIRED arguments and set CPPUNIT_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(CPPUNIT DEFAULT_MSG
+ CPPUNIT_LIBRARY CPPUNIT_INCLUDE_DIR)
+
+IF(CPPUNIT_FOUND)
+ SET(CPPUNIT_LIBRARIES ${CPPUNIT_LIBRARY})
+ SET(CPPUNIT_INCLUDE_DIRS ${CPPUNIT_INCLUDE_DIR})
+ELSE()
+ SET(CPPUNIT_FOUND FALSE)
+ENDIF()
+
+MARK_AS_ADVANCED(
+ CPPUNIT_INCLUDE_DIR
+ CPPUNIT_LIBRARY
+)
diff --git a/build_files/build_environment/patches/cmake/modules/FindIlmBase.cmake b/build_files/build_environment/patches/cmake/modules/FindIlmBase.cmake
new file mode 100644
index 00000000000..f1a45228128
--- /dev/null
+++ b/build_files/build_environment/patches/cmake/modules/FindIlmBase.cmake
@@ -0,0 +1,260 @@
+# Module to find IlmBase
+#
+# This module will first look into the directories defined by the variables:
+# - ILMBASE_HOME, ILMBASE_VERSION, ILMBASE_LIB_AREA
+#
+# It also supports non-standard names for the library components.
+#
+# To use a custom IlmBase:
+# - Set the variable ILMBASE_CUSTOM to True
+# - Set the variable ILMBASE_CUSTOM_LIBRARIES to a list of the libraries to
+# use, e.g. "SpiImath SpiHalf SpiIlmThread SpiIex"
+# - Optionally set the variable ILMBASE_CUSTOM_INCLUDE_DIR to any
+# particularly weird place that the OpenEXR/*.h files may be found
+# - Optionally set the variable ILMBASE_CUSTOM_LIB_DIR to any
+# particularly weird place that the libraries files may be found
+#
+# This module defines the following variables:
+#
+# ILMBASE_INCLUDE_DIR - where to find half.h, IlmBaseConfig.h, etc.
+# ILMBASE_LIBRARIES - list of libraries to link against when using IlmBase.
+# ILMBASE_FOUND - True if IlmBase was found.
+
+# Other standarnd issue macros
+include (FindPackageHandleStandardArgs)
+include (FindPackageMessage)
+include (SelectLibraryConfigurations)
+
+
+if( ILMBASE_USE_STATIC_LIBS )
+ set( _ilmbase_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ if(WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ else()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
+ endif()
+endif()
+
+# Macro to assemble a helper state variable
+macro (SET_STATE_VAR varname)
+ set (tmp_ilmbaselibs ${ILMBASE_CUSTOM_LIBRARIES})
+ separate_arguments (tmp_ilmbaselibs)
+ set (tmp_lst
+ ${ILMBASE_CUSTOM} | ${tmp_ilmbaselibs} |
+ ${ILMBASE_HOME} | ${ILMBASE_VERSION} | ${ILMBASE_LIB_AREA}
+ )
+ set (${varname} "${tmp_lst}")
+ unset (tmp_ilmbaselibs)
+ unset (tmp_lst)
+endmacro ()
+
+# To enforce that find_* functions do not use inadvertently existing versions
+if (ILMBASE_CUSTOM)
+ set (ILMBASE_FIND_OPTIONS "NO_DEFAULT_PATH")
+endif ()
+
+# Macro to search for an include directory
+macro (PREFIX_FIND_INCLUDE_DIR prefix includefile libpath_var)
+ string (TOUPPER ${prefix}_INCLUDE_DIR tmp_varname)
+ find_path(${tmp_varname} ${includefile}
+ HINTS ${${libpath_var}}
+ PATH_SUFFIXES include
+ ${ILMBASE_FIND_OPTIONS}
+ )
+ if (${tmp_varname})
+ mark_as_advanced (${tmp_varname})
+ endif ()
+ unset (tmp_varname)
+endmacro ()
+
+
+# Macro to search for the given library and adds the cached
+# variable names to the specified list
+macro (PREFIX_FIND_LIB prefix libname libpath_var liblist_var cachelist_var)
+ string (TOUPPER ${prefix}_${libname} tmp_prefix)
+ # Handle new library names for OpenEXR 2.1 build via cmake
+ string(REPLACE "." "_" _ILMBASE_VERSION ${ILMBASE_VERSION})
+ string(SUBSTRING ${_ILMBASE_VERSION} 0 3 _ILMBASE_VERSION )
+
+ find_library(${tmp_prefix}_LIBRARY_RELEASE
+ NAMES ${libname} ${libname}-${_ILMBASE_VERSION}
+ HINTS ${${libpath_var}}
+ PATH_SUFFIXES lib
+ ${ILMBASE_FIND_OPTIONS}
+ )
+ find_library(${tmp_prefix}_LIBRARY_DEBUG
+ NAMES ${libname}d ${libname}_d ${libname}debug ${libname}_debug
+ HINTS ${${libpath_var}}
+ PATH_SUFFIXES lib
+ ${ILMBASE_FIND_OPTIONS}
+ )
+ # Properly define ${tmp_prefix}_LIBRARY (cached) and ${tmp_prefix}_LIBRARIES
+ select_library_configurations (${tmp_prefix})
+ list (APPEND ${liblist_var} ${tmp_prefix}_LIBRARIES)
+
+ # Add to the list of variables which should be reset
+ list (APPEND ${cachelist_var}
+ ${tmp_prefix}_LIBRARY
+ ${tmp_prefix}_LIBRARY_RELEASE
+ ${tmp_prefix}_LIBRARY_DEBUG)
+ mark_as_advanced (
+ ${tmp_prefix}_LIBRARY
+ ${tmp_prefix}_LIBRARY_RELEASE
+ ${tmp_prefix}_LIBRARY_DEBUG)
+ unset (tmp_prefix)
+endmacro ()
+
+
+# Encode the current state of the external variables into a string
+SET_STATE_VAR (ILMBASE_CURRENT_STATE)
+
+# If the state has changed, clear the cached variables
+if (ILMBASE_CACHED_STATE AND
+ NOT ILMBASE_CACHED_STATE STREQUAL ILMBASE_CURRENT_STATE)
+
+ foreach (libvar ${ILMBASE_CACHED_VARS})
+ unset (${libvar} CACHE)
+ endforeach ()
+endif ()
+
+
+# Generic search paths
+set (IlmBase_generic_include_paths
+ ${ILMBASE_CUSTOM_INCLUDE_DIR}
+ /usr/include
+ /usr/include/${CMAKE_LIBRARY_ARCHITECTURE}
+ /usr/local/include
+ /sw/include
+ /opt/local/include)
+set (IlmBase_generic_library_paths
+ ${ILMBASE_CUSTOM_LIB_DIR}
+ /usr/lib
+ /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
+ /usr/local/lib
+ /usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
+ /sw/lib
+ /opt/local/lib)
+
+# Search paths for the IlmBase files
+if (ILMBASE_HOME)
+ if (ILMBASE_VERSION)
+ set (IlmBase_include_paths
+ ${ILMBASE_HOME}/ilmbase-${ILMBASE_VERSION}/include
+ ${ILMBASE_HOME}/include/ilmbase-${ILMBASE_VERSION})
+ set (IlmBase_library_paths
+ ${ILMBASE_HOME}/ilmbase-${ILMBASE_VERSION}/lib
+ ${ILMBASE_HOME}/lib/ilmbase-${ILMBASE_VERSION})
+ endif()
+ list (APPEND IlmBase_include_paths ${ILMBASE_HOME}/include)
+ set (IlmBase_library_paths
+ ${ILMBASE_HOME}/lib
+ ${ILMBASE_HOME}/lib64
+ ${ILMBASE_LIB_AREA}
+ ${IlmBase_library_paths})
+endif ()
+list (APPEND IlmBase_include_paths ${IlmBase_generic_include_paths})
+list (APPEND IlmBase_library_paths ${IlmBase_generic_library_paths})
+
+# Locate the header files
+PREFIX_FIND_INCLUDE_DIR (IlmBase
+ OpenEXR/IlmBaseConfig.h IlmBase_include_paths)
+
+if (ILMBASE_INCLUDE_DIR)
+ # Get the version from config file, if not already set.
+ if (NOT ILMBASE_VERSION)
+ FILE(STRINGS "${ILMBASE_INCLUDE_DIR}/OpenEXR/IlmBaseConfig.h" ILMBASE_BUILD_SPECIFICATION
+ REGEX "^[ \t]*#define[ \t]+ILMBASE_VERSION_STRING[ \t]+\"[.0-9]+\".*$")
+
+ if(ILMBASE_BUILD_SPECIFICATION)
+ if (NOT IlmBase_FIND_QUIETLY)
+ message(STATUS "${ILMBASE_BUILD_SPECIFICATION}")
+ endif ()
+ string(REGEX REPLACE ".*#define[ \t]+ILMBASE_VERSION_STRING[ \t]+\"([.0-9]+)\".*"
+ "\\1" XYZ ${ILMBASE_BUILD_SPECIFICATION})
+ set("ILMBASE_VERSION" ${XYZ} CACHE STRING "Version of ILMBase lib")
+ else()
+ # Old versions (before 2.0?) do not have any version string, just assuming 2.0 should be fine though.
+ message(WARNING "Could not determine ILMBase library version, assuming 2.0.")
+ set("ILMBASE_VERSION" "2.0" CACHE STRING "Version of ILMBase lib")
+ endif()
+ endif()
+endif ()
+
+
+if (ILMBASE_CUSTOM)
+ if (NOT ILMBASE_CUSTOM_LIBRARIES)
+ message (FATAL_ERROR "Custom IlmBase libraries requested but ILMBASE_CUSTOM_LIBRARIES is not set.")
+ endif()
+ set (IlmBase_Libraries ${ILMBASE_CUSTOM_LIBRARIES})
+ separate_arguments(IlmBase_Libraries)
+else ()
+#elseif (${ILMBASE_VERSION} VERSION_LESS "2.1")
+ set (IlmBase_Libraries Half Iex Imath IlmThread)
+#else ()
+# string(REGEX REPLACE "([0-9]+)[.]([0-9]+).*" "\\1_\\2" _ilmbase_libs_ver ${ILMBASE_VERSION})
+# set (IlmBase_Libraries Half Iex-${_ilmbase_libs_ver} Imath-${_ilmbase_libs_ver} IlmThread-${_ilmbase_libs_ver})
+endif ()
+
+
+# Locate the IlmBase libraries
+set (IlmBase_libvars "")
+set (IlmBase_cachevars "")
+foreach (ilmbase_lib ${IlmBase_Libraries})
+ PREFIX_FIND_LIB (IlmBase ${ilmbase_lib}
+ IlmBase_library_paths IlmBase_libvars IlmBase_cachevars)
+endforeach ()
+# Create the list of variables that might need to be cleared
+set (ILMBASE_CACHED_VARS
+ ILMBASE_INCLUDE_DIR ${IlmBase_cachevars}
+ CACHE INTERNAL "Variables set by FindIlmBase.cmake" FORCE)
+
+# Store the current state so that variables might be cleared if required
+set (ILMBASE_CACHED_STATE ${ILMBASE_CURRENT_STATE}
+ CACHE INTERNAL "State last seen by FindIlmBase.cmake" FORCE)
+
+# Link with pthreads if required
+if (NOT WIN32 AND EXISTS ${ILMBASE_INCLUDE_DIR}/OpenEXR/IlmBaseConfig.h)
+ file (STRINGS ${ILMBASE_INCLUDE_DIR}/OpenEXR/IlmBaseConfig.h
+ ILMBASE_HAVE_PTHREAD
+ REGEX "^[ \\t]*#define[ \\t]+HAVE_PTHREAD[ \\t]1[ \\t]*\$"
+ )
+ if (ILMBASE_HAVE_PTHREAD)
+ find_package (Threads)
+ if (CMAKE_USE_PTHREADS_INIT)
+ set (ILMBASE_PTHREADS ${CMAKE_THREAD_LIBS_INIT})
+ endif ()
+ endif ()
+endif ()
+
+# Use the standard function to handle ILMBASE_FOUND
+FIND_PACKAGE_HANDLE_STANDARD_ARGS (IlmBase DEFAULT_MSG
+ ILMBASE_INCLUDE_DIR ${IlmBase_libvars})
+
+if (ILMBASE_FOUND)
+ set (ILMBASE_LIBRARIES "")
+ foreach (tmplib ${IlmBase_libvars})
+ list (APPEND ILMBASE_LIBRARIES ${${tmplib}})
+ endforeach ()
+ list (APPEND ILMBASE_LIBRARIES ${ILMBASE_PTHREADS})
+ if (NOT IlmBase_FIND_QUIETLY)
+ FIND_PACKAGE_MESSAGE (ILMBASE
+ "Found IlmBase: ${ILMBASE_LIBRARIES}"
+ "[${ILMBASE_INCLUDE_DIR}][${ILMBASE_LIBRARIES}][${ILMBASE_CURRENT_STATE}]"
+ )
+ endif ()
+endif ()
+
+# Restore the original find library ordering
+if( ILMBASE_USE_STATIC_LIBS )
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${_ilmbase_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+endif()
+
+# Unset the helper variables to avoid pollution
+unset (ILMBASE_CURRENT_STATE)
+unset (IlmBase_include_paths)
+unset (IlmBase_library_paths)
+unset (IlmBase_generic_include_paths)
+unset (IlmBase_generic_library_paths)
+unset (IlmBase_libvars)
+unset (IlmBase_cachevars)
+unset (ILMBASE_PTHREADS)
diff --git a/build_files/build_environment/patches/cmake/modules/FindLogC4Plus.cmake b/build_files/build_environment/patches/cmake/modules/FindLogC4Plus.cmake
new file mode 100644
index 00000000000..2002419cc75
--- /dev/null
+++ b/build_files/build_environment/patches/cmake/modules/FindLogC4Plus.cmake
@@ -0,0 +1,73 @@
+# - Find LOGC4PLUS library
+# Find the native LOGC4PLUS includes and library
+# This module defines
+# LOGC4PLUS_INCLUDE_DIRS, where to find logc4plus.h, Set when
+# LOGC4PLUS is found.
+# LOGC4PLUS_LIBRARIES, libraries to link against to use LOGC4PLUS.
+# LOGC4PLUS_ROOT_DIR, The base directory to search for LOGC4PLUS.
+# This can also be an environment variable.
+# LOGC4PLUS_FOUND, If false, do not try to use LOGC4PLUS.
+#
+# also defined, but not for general use are
+# LOGC4PLUS_LIBRARY, where to find the LOGC4PLUS library.
+
+#=============================================================================
+# Copyright 2016 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If LOGC4PLUS_ROOT_DIR was defined in the environment, use it.
+IF(NOT LOGC4PLUS_ROOT_DIR AND NOT $ENV{LOGC4PLUS_ROOT_DIR} STREQUAL "")
+ SET(LOGC4PLUS_ROOT_DIR $ENV{LOGC4PLUS_ROOT_DIR})
+ENDIF()
+
+SET(_logc4plus_SEARCH_DIRS
+ ${LOGC4PLUS_ROOT_DIR}
+ /usr/local
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt/lib/logc4plus
+)
+
+FIND_PATH(LOGC4PLUS_INCLUDE_DIR
+ NAMES
+ logc4plus.h
+ HINTS
+ ${_logc4plus_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include
+)
+
+FIND_LIBRARY(LOGC4PLUS_LIBRARY
+ NAMES
+ logc4plus
+ HINTS
+ ${_logc4plus_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+# handle the QUIETLY and REQUIRED arguments and set LOGC4PLUS_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(LOGC4PLUS DEFAULT_MSG
+ LOGC4PLUS_LIBRARY LOGC4PLUS_INCLUDE_DIR)
+
+IF(LOGC4PLUS_FOUND)
+ SET(LOGC4PLUS_LIBRARIES ${LOGC4PLUS_LIBRARY})
+ SET(LOGC4PLUS_INCLUDE_DIRS ${LOGC4PLUS_INCLUDE_DIR})
+ELSE()
+ SET(LOGC4PLUS_LOGC4PLUS_FOUND FALSE)
+ENDIF()
+
+MARK_AS_ADVANCED(
+ LOGC4PLUS_INCLUDE_DIR
+ LOGC4PLUS_LIBRARY
+)
diff --git a/build_files/build_environment/patches/cmake/modules/FindOpenEXR.cmake b/build_files/build_environment/patches/cmake/modules/FindOpenEXR.cmake
new file mode 100644
index 00000000000..08d872445d7
--- /dev/null
+++ b/build_files/build_environment/patches/cmake/modules/FindOpenEXR.cmake
@@ -0,0 +1,244 @@
+# Module to find OpenEXR.
+#
+# This module will first look into the directories defined by the variables:
+# - OPENEXR_HOME, OPENEXR_VERSION, OPENEXR_LIB_AREA
+#
+# It also supports non-standard names for the library components.
+#
+# To use a custom OpenEXR
+# - Set the variable OPENEXR_CUSTOM to True
+# - Set the variable OPENEXR_CUSTOM_LIBRARY to the name of the library to
+# use, e.g. "SpiIlmImf"
+# - Optionally set the variable OPENEXR_CUSTOM_INCLUDE_DIR to any
+# particularly weird place that the OpenEXR/*.h files may be found
+# - Optionally set the variable OPENEXR_CUSTOM_LIB_DIR to any
+# particularly weird place that the libraries files may be found
+#
+# This module defines the following variables:
+#
+# OPENEXR_INCLUDE_DIR - where to find ImfRgbaFile.h, OpenEXRConfig, etc.
+# OPENEXR_LIBRARIES - list of libraries to link against when using OpenEXR.
+# This list does NOT include the IlmBase libraries.
+# These are defined by the FindIlmBase module.
+# OPENEXR_FOUND - True if OpenEXR was found.
+
+# Other standarnd issue macros
+include (SelectLibraryConfigurations)
+include (FindPackageHandleStandardArgs)
+include (FindPackageMessage)
+
+if( OPENEXR_USE_STATIC_LIBS )
+ set( _openexr_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ if(WIN32)
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
+ else()
+ set(CMAKE_FIND_LIBRARY_SUFFIXES .a )
+ endif()
+endif()
+
+# Macro to assemble a helper state variable
+macro (SET_STATE_VAR varname)
+ set (tmp_lst
+ ${OPENEXR_CUSTOM} | ${OPENEXR_CUSTOM_LIBRARY} |
+ ${OPENEXR_HOME} | ${OPENEXR_VERSION} | ${OPENEXR_LIB_AREA}
+ )
+ set (${varname} "${tmp_lst}")
+ unset (tmp_lst)
+endmacro ()
+
+# To enforce that find_* functions do not use inadvertently existing versions
+if (OPENEXR_CUSTOM)
+ set (OPENEXR_FIND_OPTIONS "NO_DEFAULT_PATH")
+endif ()
+
+# Macro to search for an include directory
+macro (PREFIX_FIND_INCLUDE_DIR prefix includefile libpath_var)
+ string (TOUPPER ${prefix}_INCLUDE_DIR tmp_varname)
+ find_path(${tmp_varname} ${includefile}
+ HINTS ${${libpath_var}}
+ PATH_SUFFIXES include
+ ${OPENEXR_FIND_OPTIONS}
+ )
+ if (${tmp_varname})
+ mark_as_advanced (${tmp_varname})
+ endif ()
+ unset (tmp_varname)
+endmacro ()
+
+
+# Macro to search for the given library and adds the cached
+# variable names to the specified list
+macro (PREFIX_FIND_LIB prefix libname libpath_var liblist_var cachelist_var)
+ string (TOUPPER ${prefix}_${libname} tmp_prefix)
+ # Handle new library names for OpenEXR 2.1 build via cmake
+ string(REPLACE "." "_" _ILMBASE_VERSION ${ILMBASE_VERSION})
+ string(SUBSTRING ${_ILMBASE_VERSION} 0 3 _ILMBASE_VERSION )
+ find_library(${tmp_prefix}_LIBRARY_RELEASE
+ NAMES ${libname} ${libname}-${_ILMBASE_VERSION}
+ HINTS ${${libpath_var}}
+ PATH_SUFFIXES lib
+ ${OPENEXR_FIND_OPTIONS}
+ )
+ find_library(${tmp_prefix}_LIBRARY_DEBUG
+ NAMES ${libname}d ${libname}_d ${libname}debug ${libname}_debug
+ HINTS ${${libpath_var}}
+ PATH_SUFFIXES lib
+ ${OPENEXR_FIND_OPTIONS}
+ )
+ # Properly define ${tmp_prefix}_LIBRARY (cached) and ${tmp_prefix}_LIBRARIES
+ select_library_configurations (${tmp_prefix})
+ list (APPEND ${liblist_var} ${tmp_prefix}_LIBRARIES)
+
+ # Add to the list of variables which should be reset
+ list (APPEND ${cachelist_var}
+ ${tmp_prefix}_LIBRARY
+ ${tmp_prefix}_LIBRARY_RELEASE
+ ${tmp_prefix}_LIBRARY_DEBUG)
+ mark_as_advanced (
+ ${tmp_prefix}_LIBRARY
+ ${tmp_prefix}_LIBRARY_RELEASE
+ ${tmp_prefix}_LIBRARY_DEBUG)
+ unset (tmp_prefix)
+endmacro ()
+
+
+# Encode the current state of the external variables into a string
+SET_STATE_VAR (OPENEXR_CURRENT_STATE)
+
+# If the state has changed, clear the cached variables
+if (OPENEXR_CACHED_STATE AND
+ NOT OPENEXR_CACHED_STATE STREQUAL OPENEXR_CURRENT_STATE)
+ foreach (libvar ${OPENEXR_CACHED_VARS})
+ unset (${libvar} CACHE)
+ endforeach ()
+endif ()
+
+# Generic search paths
+set (OpenEXR_generic_include_paths
+ ${OPENEXR_CUSTOM_INCLUDE_DIR}
+ /usr/include
+ /usr/include/${CMAKE_LIBRARY_ARCHITECTURE}
+ /usr/local/include
+ /sw/include
+ /opt/local/include)
+set (OpenEXR_generic_library_paths
+ ${OPENEXR_CUSTOM_LIB_DIR}
+ /usr/lib
+ /usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
+ /usr/local/lib
+ /usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
+ /sw/lib
+ /opt/local/lib)
+
+# Search paths for the OpenEXR files
+if (OPENEXR_HOME)
+ set (OpenEXR_library_paths
+ ${OPENEXR_HOME}/lib
+ ${OPENEXR_HOME}/lib64)
+ if (OPENEXR_VERSION)
+ set (OpenEXR_include_paths
+ ${OPENEXR_HOME}/openexr-${OPENEXR_VERSION}/include
+ ${OPENEXR_HOME}/include/openexr-${OPENEXR_VERSION})
+ list (APPEND OpenEXR_library_paths
+ ${OPENEXR_HOME}/openexr-${OPENEXR_VERSION}/lib
+ ${OPENEXR_HOME}/lib/openexr-${OPENEXR_VERSION})
+ endif()
+ list (APPEND OpenEXR_include_paths ${OPENEXR_HOME}/include)
+ if (OPENEXR_LIB_AREA)
+ list (INSERT OpenEXR_library_paths 2 ${OPENEXR_LIB_AREA})
+ endif ()
+endif ()
+if (ILMBASE_HOME AND OPENEXR_VERSION)
+ list (APPEND OpenEXR_include_paths
+ ${ILMBASE_HOME}/include/openexr-${OPENEXR_VERSION})
+endif()
+list (APPEND OpenEXR_include_paths ${OpenEXR_generic_include_paths})
+list (APPEND OpenEXR_library_paths ${OpenEXR_generic_library_paths})
+
+# Locate the header files
+PREFIX_FIND_INCLUDE_DIR (OpenEXR
+ OpenEXR/ImfArray.h OpenEXR_include_paths)
+
+if (OPENEXR_INCLUDE_DIR)
+ # Get the version from config file, if not already set.
+ if (NOT OPENEXR_VERSION)
+ FILE(STRINGS "${OPENEXR_INCLUDE_DIR}/OpenEXR/OpenEXRConfig.h" OPENEXR_BUILD_SPECIFICATION
+ REGEX "^[ \t]*#define[ \t]+OPENEXR_VERSION_STRING[ \t]+\"[.0-9]+\".*$")
+
+ if(OPENEXR_BUILD_SPECIFICATION)
+ if (NOT OpenEXR_FIND_QUIETLY)
+ message(STATUS "${OPENEXR_BUILD_SPECIFICATION}")
+ endif ()
+ string(REGEX REPLACE ".*#define[ \t]+OPENEXR_VERSION_STRING[ \t]+\"([.0-9]+)\".*"
+ "\\1" XYZ ${OPENEXR_BUILD_SPECIFICATION})
+ set("OPENEXR_VERSION" ${XYZ} CACHE STRING "Version of OpenEXR lib")
+ else()
+ # Old versions (before 2.0?) do not have any version string, just assuming 2.0 should be fine though.
+ message(WARNING "Could not determine ILMBase library version, assuming 2.0.")
+ set("OPENEXR_VERSION" "2.0" CACHE STRING "Version of OpenEXR lib")
+ endif()
+ endif()
+endif ()
+
+if (OPENEXR_CUSTOM)
+ if (NOT OPENEXR_CUSTOM_LIBRARY)
+ message (FATAL_ERROR "Custom OpenEXR library requested but OPENEXR_CUSTOM_LIBRARY is not set.")
+ endif()
+ set (OpenEXR_Library ${OPENEXR_CUSTOM_LIBRARY})
+else ()
+#elseif (${OPENEXR_VERSION} VERSION_LESS "2.1")
+ set (OpenEXR_Library IlmImf)
+#else ()
+# string(REGEX REPLACE "([0-9]+)[.]([0-9]+).*" "\\1_\\2" _openexr_libs_ver ${OPENEXR_VERSION})
+# set (OpenEXR_Library IlmImf-${_openexr_libs_ver})
+endif ()
+
+# Locate the OpenEXR library
+set (OpenEXR_libvars "")
+set (OpenEXR_cachevars "")
+PREFIX_FIND_LIB (OpenEXR ${OpenEXR_Library}
+ OpenEXR_library_paths OpenEXR_libvars OpenEXR_cachevars)
+
+# Create the list of variables that might need to be cleared
+set (OPENEXR_CACHED_VARS
+ OPENEXR_INCLUDE_DIR ${OpenEXR_cachevars}
+ CACHE INTERNAL "Variables set by FindOpenEXR.cmake" FORCE)
+
+# Store the current state so that variables might be cleared if required
+set (OPENEXR_CACHED_STATE ${OPENEXR_CURRENT_STATE}
+ CACHE INTERNAL "State last seen by FindOpenEXR.cmake" FORCE)
+
+# Always link explicitly with zlib
+set (OPENEXR_ZLIB ${ZLIB_LIBRARIES})
+
+# Use the standard function to handle OPENEXR_FOUND
+FIND_PACKAGE_HANDLE_STANDARD_ARGS (OpenEXR DEFAULT_MSG
+ OPENEXR_INCLUDE_DIR ${OpenEXR_libvars})
+
+if (OPENEXR_FOUND)
+ set (OPENEXR_LIBRARIES "")
+ foreach (tmplib ${OpenEXR_libvars})
+ list (APPEND OPENEXR_LIBRARIES ${${tmplib}})
+ endforeach ()
+ list (APPEND OPENEXR_LIBRARIES ${ZLIB_LIBRARIES})
+ if (NOT OpenEXR_FIND_QUIETLY)
+ FIND_PACKAGE_MESSAGE (OPENEXR
+ "Found OpenEXR: ${OPENEXR_LIBRARIES}"
+ "[${OPENEXR_INCLUDE_DIR}][${OPENEXR_LIBRARIES}][${OPENEXR_CURRENT_STATE}]"
+ )
+ endif ()
+endif ()
+
+# Restore the original find library ordering
+if( OPENEXR_USE_STATIC_LIBS )
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ${_openexr_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES})
+endif()
+
+# Unset the helper variables to avoid pollution
+unset (OPENEXR_CURRENT_STATE)
+unset (OpenEXR_include_paths)
+unset (OpenEXR_library_paths)
+unset (OpenEXR_generic_include_paths)
+unset (OpenEXR_generic_library_paths)
+unset (OpenEXR_libvars)
+unset (OpenEXR_cachevars)
diff --git a/build_files/build_environment/patches/cmake/modules/FindTBB.cmake b/build_files/build_environment/patches/cmake/modules/FindTBB.cmake
new file mode 100644
index 00000000000..8a821f8092e
--- /dev/null
+++ b/build_files/build_environment/patches/cmake/modules/FindTBB.cmake
@@ -0,0 +1,73 @@
+# - Find TBB library
+# Find the native TBB includes and library
+# This module defines
+# TBB_INCLUDE_DIRS, where to find tbb.h, Set when
+# TBB is found.
+# TBB_LIBRARIES, libraries to link against to use TBB.
+# TBB_ROOT_DIR, The base directory to search for TBB.
+# This can also be an environment variable.
+# TBB_FOUND, If false, do not try to use TBB.
+#
+# also defined, but not for general use are
+# TBB_LIBRARY, where to find the TBB library.
+
+#=============================================================================
+# Copyright 2016 Blender Foundation.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+
+# If TBB_ROOT_DIR was defined in the environment, use it.
+IF(NOT TBB_ROOT_DIR AND NOT $ENV{TBB_ROOT_DIR} STREQUAL "")
+ SET(TBB_ROOT_DIR $ENV{TBB_ROOT_DIR})
+ENDIF()
+
+SET(_tbb_SEARCH_DIRS
+ ${TBB_ROOT_DIR}
+ /usr/local
+ /sw # Fink
+ /opt/local # DarwinPorts
+ /opt/csw # Blastwave
+ /opt/lib/tbb
+)
+
+FIND_PATH(TBB_INCLUDE_DIR
+ NAMES
+ tbb/tbb.h
+ HINTS
+ ${_tbb_SEARCH_DIRS}
+ PATH_SUFFIXES
+ include
+)
+
+FIND_LIBRARY(TBB_LIBRARY
+ NAMES
+ tbb
+ HINTS
+ ${_tbb_SEARCH_DIRS}
+ PATH_SUFFIXES
+ lib64 lib
+ )
+
+# handle the QUIETLY and REQUIRED arguments and set TBB_FOUND to TRUE if
+# all listed variables are TRUE
+INCLUDE(FindPackageHandleStandardArgs)
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(TBB DEFAULT_MSG
+ TBB_LIBRARY TBB_INCLUDE_DIR)
+
+IF(TBB_FOUND)
+ SET(TBB_LIBRARIES ${TBB_LIBRARY})
+ SET(TBB_INCLUDE_DIRS ${TBB_INCLUDE_DIR})
+ELSE()
+ SET(TBB_TBB_FOUND FALSE)
+ENDIF()
+
+MARK_AS_ADVANCED(
+ TBB_INCLUDE_DIR
+ TBB_LIBRARY
+)
diff --git a/build_files/build_environment/patches/cmake/modules/SelectLibraryConfigurations.cmake b/build_files/build_environment/patches/cmake/modules/SelectLibraryConfigurations.cmake
new file mode 100644
index 00000000000..51b4dda0653
--- /dev/null
+++ b/build_files/build_environment/patches/cmake/modules/SelectLibraryConfigurations.cmake
@@ -0,0 +1,82 @@
+# select_library_configurations( basename )
+#
+# This macro takes a library base name as an argument, and will choose good
+# values for basename_LIBRARY, basename_LIBRARIES, basename_LIBRARY_DEBUG, and
+# basename_LIBRARY_RELEASE depending on what has been found and set. If only
+# basename_LIBRARY_RELEASE is defined, basename_LIBRARY, basename_LIBRARY_DEBUG,
+# and basename_LIBRARY_RELEASE will be set to the release value. If only
+# basename_LIBRARY_DEBUG is defined, then basename_LIBRARY,
+# basename_LIBRARY_DEBUG and basename_LIBRARY_RELEASE will take the debug value.
+#
+# If the generator supports configuration types, then basename_LIBRARY and
+# basename_LIBRARIES will be set with debug and optimized flags specifying the
+# library to be used for the given configuration. If no build type has been set
+# or the generator in use does not support configuration types, then
+# basename_LIBRARY and basename_LIBRARIES will take only the release values.
+
+#=============================================================================
+# Copyright 2009 Kitware, Inc.
+# Copyright 2009 Will Dicharry <wdicharry@stellarscience.com>
+# Copyright 2005-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# This macro was adapted from the FindQt4 CMake module and is maintained by Will
+# Dicharry <wdicharry@stellarscience.com>.
+
+# Utility macro to check if one variable exists while another doesn't, and set
+# one that doesn't exist to the one that exists.
+macro( _set_library_name basename GOOD BAD )
+ if( ${basename}_LIBRARY_${GOOD} AND NOT ${basename}_LIBRARY_${BAD} )
+ set( ${basename}_LIBRARY_${BAD} ${${basename}_LIBRARY_${GOOD}} )
+ set( ${basename}_LIBRARY ${${basename}_LIBRARY_${GOOD}} )
+ set( ${basename}_LIBRARIES ${${basename}_LIBRARY_${GOOD}} )
+ endif( ${basename}_LIBRARY_${GOOD} AND NOT ${basename}_LIBRARY_${BAD} )
+endmacro( _set_library_name )
+
+macro( select_library_configurations basename )
+ # if only the release version was found, set the debug to be the release
+ # version.
+ _set_library_name( ${basename} RELEASE DEBUG )
+ # if only the debug version was found, set the release value to be the
+ # debug value.
+ _set_library_name( ${basename} DEBUG RELEASE )
+ if (${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE )
+ # if the generator supports configuration types or CMAKE_BUILD_TYPE
+ # is set, then set optimized and debug options.
+ if( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
+ set( ${basename}_LIBRARY
+ optimized ${${basename}_LIBRARY_RELEASE}
+ debug ${${basename}_LIBRARY_DEBUG} )
+ set( ${basename}_LIBRARIES
+ optimized ${${basename}_LIBRARY_RELEASE}
+ debug ${${basename}_LIBRARY_DEBUG} )
+ else( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
+ # If there are no configuration types or build type, just use
+ # the release version
+ set( ${basename}_LIBRARY ${${basename}_LIBRARY_RELEASE} )
+ set( ${basename}_LIBRARIES ${${basename}_LIBRARY_RELEASE} )
+ endif( CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE )
+ endif( ${basename}_LIBRARY_DEBUG AND ${basename}_LIBRARY_RELEASE )
+
+ set( ${basename}_LIBRARY ${${basename}_LIBRARY} CACHE FILEPATH
+ "The ${basename} library" )
+
+ if( ${basename}_LIBRARY )
+ set( ${basename}_FOUND TRUE )
+ endif( ${basename}_LIBRARY )
+
+ mark_as_advanced( ${basename}_LIBRARY
+ ${basename}_LIBRARY_RELEASE
+ ${basename}_LIBRARY_DEBUG
+ )
+endmacro( select_library_configurations )
+
diff --git a/build_files/build_environment/patches/cmakelists_glew.txt b/build_files/build_environment/patches/cmakelists_glew.txt
new file mode 100644
index 00000000000..ec36d4bde63
--- /dev/null
+++ b/build_files/build_environment/patches/cmakelists_glew.txt
@@ -0,0 +1,2 @@
+cmake_minimum_required (VERSION 2.4)
+add_subdirectory(build/cmake) \ No newline at end of file
diff --git a/build_files/build_environment/patches/cmakelists_hidapi.txt b/build_files/build_environment/patches/cmakelists_hidapi.txt
new file mode 100644
index 00000000000..239b9d88b16
--- /dev/null
+++ b/build_files/build_environment/patches/cmakelists_hidapi.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 2.8)
+project(hidapi)
+
+set(SRC_FILES
+ windows/hid.c
+)
+
+set(HEADER_FILES
+ hidapi/hidapi.h
+)
+include_directories(hidapi)
+add_definitions(-DHID_API_STATIC)
+add_library(hidapi STATIC ${SRC_FILES} ${HEADER_FILES})
+
+install(TARGETS hidapi DESTINATION lib)
+
+INSTALL(FILES hidapi/hidapi.h
+ DESTINATION "include"
+ )
+
diff --git a/build_files/build_environment/patches/cmakelists_openvdb.txt b/build_files/build_environment/patches/cmakelists_openvdb.txt
new file mode 100644
index 00000000000..dd3e9c1a887
--- /dev/null
+++ b/build_files/build_environment/patches/cmakelists_openvdb.txt
@@ -0,0 +1,398 @@
+# --------------------------------------------------------------------------------
+
+cmake_minimum_required(VERSION 2.8)
+
+# --------------------------------------------------------------------------------
+
+project(OpenVDB)
+
+# --------------------------------------------------------------------------------
+
+set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules")
+
+# --------------------------------------------------------------------------------
+
+set(CMAKE_BUILD_TYPE_INIT "Release")
+
+# --------------------------------------------------------------------------------
+# Options
+
+option(WITH_BLOSC "Enable Blosc support for compression" OFF)
+option(WITH_LOGC4PLUS "Enable logging" OFF)
+option(WITH_OPENVDB_2_ABI "Enable building the library to be compability with the OpenVDB 2 ABI" OFF)
+option(WITH_PRINTER "Enable building the OpenVDB print executable" OFF)
+option(WITH_PYTHON "Enable building the OpenVDB python API" OFF)
+option(WITH_RENDERER "Enable building the OpenVDB render executable" OFF)
+option(WITH_UNITTEST "Enable building the unit tests" OFF)
+option(WITH_VIEWER "Enable building the OpenVDB viewer executable" OFF)
+
+# --------------------------------------------------------------------------------
+# Find packages
+#set(BOOST_LIBRARIES boost_iostreams boost_system boost_thread)
+
+find_package(IlmBase)
+find_package(OpenEXR)
+find_package(TBB)
+find_package(Boost)
+
+if(WITH_BLOSC)
+ find_package(Blosc)
+
+ if(NOT BLOSC_FOUND)
+ set(WITH_BLOSC OFF)
+ endif()
+endif()
+
+# todo
+if(WITH_VIEWER)
+ set(GLFW_INCLUDE_DIRS ${GLFW_INCLUDE_PATH})
+ set(GLFW_LIBRARY_DIRS ${GLFW_LIBRARY_PATH})
+endif()
+
+if(WITH_LOGC4PLUS)
+ find_package(LogC4Plus)
+
+ if(NOT LOGC4PLUS_FOUND)
+ set(WITH_LOGC4PLUS OFF)
+ endif()
+endif()
+
+# todo
+if(WITH_PYTHON)
+ set(PYTHON_INCLUDE_DIRS ${PYTHON_INCLUDE_PATH})
+ set(PYTHON_LIBRARY_DIRS ${PYTHON_LIBRARY_PATH})
+endif()
+
+if(WITH_UNITTEST)
+ find_package(CppUnit)
+
+ if(NOT CPPUNIT_FOUND)
+ set(WITH_UNITTEST OFF)
+ endif()
+endif()
+
+# --------------------------------------------------------------------------------
+
+message (STATUS "BOOST_ROOT ${BOOST_ROOT}")
+message (STATUS "Boost found ${Boost_FOUND} ")
+message (STATUS "Boost version ${Boost_VERSION}")
+message (STATUS "Boost include dirs ${Boost_INCLUDE_DIRS}")
+message (STATUS "Boost library dirs ${Boost_LIBRARY_DIRS}")
+message (STATUS "Boost libraries ${Boost_LIBRARIES}")
+
+message (STATUS "ILMBase found ${ILMBASE_FOUND} ")
+message (STATUS "ILMBase include dir ${ILMBASE_INCLUDE_DIR}")
+message (STATUS "ILMBase libraries ${ILMBASE_LIBRARIES}")
+
+message (STATUS "TBB found ${TBB_FOUND} ")
+message (STATUS "TBB include dir ${TBB_INCLUDE_DIR}")
+message (STATUS "TBB libraries ${TBB_LIBRARIES}")
+
+if(MSVC)
+ set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj" )
+ set ( CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /bigobj" )
+endif()
+
+set(OPENVDB_LIBRARIES ${BLOSC_LIBRARIES} ${BOOST_LIBRARIES} ${OPENEXR_LIBRARIES} ${ILMBASE_LIBRARIES} ${TBB_LIBRARIES} ${ZLIB_LIBRARY} )
+
+include_directories(. ${CMAKE_CURRENT_SOURCE_DIR}/../ ${Boost_INCLUDE_DIRS} ${ILMBASE_INCLUDE_DIR} ${OPENEXR_INCLUDE_DIR} ${TBB_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR})
+link_directories(${Boost_LIBRARY_DIRS} ${OPENEXR_LIBRARY_DIRS} ${TBB_INCLUDE_DIRS})
+add_definitions(-DNOMINMAX -D__TBB_NO_IMPLICIT_LINKAGE -DOPENVDB_STATICLIB -DOPENVDB_OPENEXR_STATICLIB)
+
+if(WITH_BLOSC)
+ add_definitions(-DOPENVDB_USE_BLOSC)
+ include_directories(${BLOSC_INCLUDE_DIRS})
+ link_directories(${BLOSC_LIBRARY_DIRS})
+endif()
+
+if(WITH_LOGC4PLUS)
+ add_definitions(-DOPENVDB_USE_LOG4CPLUS)
+ include_directories(${LOG4CPLUS_INCLUDE_DIRS})
+ link_directories(${LOG4CPLUS_LIBRARY_DIRS})
+endif()
+
+if(WITH_OPENVDB_2_ABI)
+ add_definitions(-DOPENVDB_2_ABI_COMPATIBLE)
+endif()
+
+# todo
+if(WITH_OPENVDB_USE_GLFW_3)
+ add_definitions(-DOPENVDB_USE_GLFW_3)
+endif()
+
+if(WITH_UNITTEST)
+ include_directories(${CPPUNIT_INCLUDE_DIRS})
+ link_directories(${CPPUNIT_LIBRARY_DIRS})
+endif()
+
+# --------------------------------------------------------------------------------
+
+set(SRC_FILES
+ openvdb/openvdb.cc
+ openvdb/io/Compression.cc
+ openvdb/io/File.cc
+ openvdb/io/Queue.cc
+ openvdb/io/Stream.cc
+ openvdb/io/TempFile.cc
+ openvdb/io/GridDescriptor.cc
+ openvdb/io/Archive.cc
+ openvdb/metadata/MetaMap.cc
+ openvdb/metadata/Metadata.cc
+ openvdb/math/Maps.cc
+ openvdb/math/Transform.cc
+ openvdb/math/QuantizedUnitVec.cc
+ openvdb/math/Proximity.cc
+ openvdb/Grid.cc
+ openvdb/util/Formats.cc
+ openvdb/util/Util.cc
+)
+
+set(HEADER_FILES
+ openvdb/openvdb.h
+ openvdb/version.h
+ openvdb/PlatformConfig.h
+ openvdb/Metadata.h
+ openvdb/Exceptions.h
+ openvdb/Grid.h
+ openvdb/Types.h
+ openvdb/Platform.h
+ openvdb/tree/ValueAccessor.h
+ openvdb/tree/NodeUnion.h
+ openvdb/tree/Tree.h
+ openvdb/tree/Iterator.h
+ openvdb/tree/LeafNodeBool.h
+ openvdb/tree/TreeIterator.h
+ openvdb/tree/LeafNode.h
+ openvdb/tree/NodeManager.h
+ openvdb/tree/LeafManager.h
+ openvdb/tree/InternalNode.h
+ openvdb/tree/RootNode.h
+ openvdb/tools/PointScatter.h
+ openvdb/tools/VolumeAdvect.h
+ openvdb/tools/LevelSetTracker.h
+ openvdb/tools/Composite.h
+ openvdb/tools/Morphology.h
+ openvdb/tools/ValueTransformer.h
+ openvdb/tools/ChangeBackground.h
+ openvdb/tools/GridTransformer.h
+ openvdb/tools/Prune.h
+ openvdb/tools/LevelSetUtil.h
+ openvdb/tools/VolumeToSpheres.h
+ openvdb/tools/LevelSetAdvect.h
+ openvdb/tools/Statistics.h
+ openvdb/tools/LevelSetMeasure.h
+ openvdb/tools/VectorTransformer.h
+ openvdb/tools/RayIntersector.h
+ openvdb/tools/PointPartitioner.h
+ openvdb/tools/Interpolation.h
+ openvdb/tools/VelocityFields.h
+ openvdb/tools/PointIndexGrid.h
+ openvdb/tools/LevelSetRebuild.h
+ openvdb/tools/Clip.h
+ openvdb/tools/SignedFloodFill.h
+ openvdb/tools/MeshToVolume.h
+ openvdb/tools/Dense.h
+ openvdb/tools/Filter.h
+ openvdb/tools/RayTracer.h
+ openvdb/tools/Diagnostics.h
+ openvdb/tools/VolumeToMesh.h
+ openvdb/tools/PoissonSolver.h
+ openvdb/tools/LevelSetFracture.h
+ openvdb/tools/GridOperators.h
+ openvdb/tools/DenseSparseTools.h
+ openvdb/tools/ParticlesToLevelSet.h
+ openvdb/tools/LevelSetSphere.h
+ openvdb/tools/LevelSetMorph.h
+ openvdb/tools/LevelSetFilter.h
+ openvdb/tools/PointAdvect.h
+ openvdb/io/Queue.h
+ openvdb/io/TempFile.h
+ openvdb/io/Stream.h
+ openvdb/io/GridDescriptor.h
+ openvdb/io/Archive.h
+ openvdb/io/io.h
+ openvdb/io/Compression.h
+ openvdb/io/File.h
+ openvdb/metadata/StringMetadata.h
+ openvdb/metadata/MetaMap.h
+ openvdb/metadata/Metadata.h
+ openvdb/math/DDA.h
+ openvdb/math/Vec2.h
+ openvdb/math/FiniteDifference.h
+ openvdb/math/Stencils.h
+ openvdb/math/BBox.h
+ openvdb/math/Mat3.h
+ openvdb/math/Mat.h
+ openvdb/math/Proximity.h
+ openvdb/math/Ray.h
+ openvdb/math/ConjGradient.h
+ openvdb/math/Quat.h
+ openvdb/math/Vec3.h
+ openvdb/math/Vec4.h
+ openvdb/math/QuantizedUnitVec.h
+ openvdb/math/Coord.h
+ openvdb/math/Operators.h
+ openvdb/math/Stats.h
+ openvdb/math/Math.h
+ openvdb/math/Tuple.h
+ openvdb/math/LegacyFrustum.h
+ openvdb/math/Mat4.h
+ openvdb/math/Maps.h
+ openvdb/math/Transform.h
+ openvdb/util/PagedArray.h
+ openvdb/util/CpuTimer.h
+ openvdb/util/Formats.h
+ openvdb/util/NullInterrupter.h
+ openvdb/util/Util.h
+ openvdb/util/Name.h
+ openvdb/util/MapsUtil.h
+ openvdb/util/NodeMasks.h
+ openvdb/util/logging.h
+)
+
+add_library(openvdb STATIC ${SRC_FILES} ${HEADER_FILES})
+
+# --------------------------------------------------------------------------------
+
+target_link_libraries(openvdb ${OPENVDB_LIBRARIES})
+
+set(OPENVDB_VERSION_MAJOR 3)
+set(OPENVDB_VERSION_MINOR 1)
+set(OPENVDB_VERSION_PATCH 0)
+set(OPENVDB_VERSION_STRING ${OPENVDB_VERSION_MAJOR}.${OPENVDB_VERSION_MINOR}.${OPENVDB_VERSION_PATCH})
+
+set_target_properties(openvdb PROPERTIES VERSION ${OPENVDB_VERSION_STRING} SOVERSION ${OPENVDB_VERSION_MAJOR})
+
+install(TARGETS openvdb DESTINATION lib)
+
+install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION include COMPONENT Development FILES_MATCHING PATTERN "*.h"
+ PATTERN ".git" EXCLUDE PATTERN "build" EXCLUDE PATTERN "cmake" EXCLUDE)
+
+# --------------------------------------------------------------------------------
+
+if(WITH_PRINTER)
+ set(PRINT_SRC
+ openvdb/cmd/openvdb_print/main.cc
+ )
+
+ add_executable(vdb_print ${PRINT_SRC})
+ target_link_libraries(vdb_print openvdb)
+ install(TARGETS vdb_print RUNTIME DESTINATION bin)
+endif()
+
+if(WITH_RENDER)
+ set(RENDER_SRC
+ openvdb/cmd/openvdb_render/main.cc
+ )
+
+ add_executable(vdb_render ${RENDER_SRC})
+ target_link_libraries(vdb_render openvdb)
+ install(TARGETS vdb_render RUNTIME DESTINATION bin)
+endif()
+
+# todo
+if(WITH_VIEWER)
+ set(VIEWER_SRC
+ openvdb/viewer/Camera.cc
+ openvdb/viewer/ClipBox.cc
+ openvdb/viewer/Font.cc
+ openvdb/viewer/RenderModules.cc
+ openvdb/viewer/Viewer.cc
+
+ openvdb/viewer/Camera.h
+ openvdb/viewer/ClipBox.h
+ openvdb/viewer/Font.h
+ openvdb/viewer/RenderModules.h
+ openvdb/viewer/Viewer.h
+ openvdb/cmd/openvdb_viewer/main.cc
+ )
+
+ include_directories(${GLFW_INCLUDE_DIRS})
+ link_directories(${GLFW_LIBRARY_DIRS})
+
+ add_executable(vdb_viewer ${VIEWER_SRC})
+ target_link_libraries(vdb_viewer openvdb)
+ install(TARGETS vdb_viewer RUNTIME DESTINATION bin)
+endif()
+
+# todo
+if(WITH_PYTHON)
+# add_library(pyopenvdb SHARED )
+endif()
+
+set(UNITTEST_SRC
+ openvdb/unittest/main.cc
+ openvdb/unittest/TestBBox.cc
+ openvdb/unittest/TestConjGradient.cc
+ openvdb/unittest/TestCoord.cc
+ openvdb/unittest/TestCpt.cc
+ openvdb/unittest/TestCurl.cc
+ openvdb/unittest/TestDense.cc
+ openvdb/unittest/TestDenseSparseTools.cc
+ openvdb/unittest/TestDiagnostics.cc
+ openvdb/unittest/TestDivergence.cc
+ openvdb/unittest/TestDoubleMetadata.cc
+ openvdb/unittest/TestExceptions.cc
+ openvdb/unittest/TestFile.cc
+ openvdb/unittest/TestFloatMetadata.cc
+ openvdb/unittest/TestGradient.cc
+ openvdb/unittest/TestGrid.cc
+ openvdb/unittest/TestGridBbox.cc
+ openvdb/unittest/TestGridDescriptor.cc
+ openvdb/unittest/TestGridIO.cc
+ openvdb/unittest/TestGridTransformer.cc
+ openvdb/unittest/TestInit.cc
+ openvdb/unittest/TestInt32Metadata.cc
+ openvdb/unittest/TestInt64Metadata.cc
+ openvdb/unittest/TestInternalOrigin.cc
+ openvdb/unittest/TestLaplacian.cc
+ openvdb/unittest/TestLeaf.cc
+ openvdb/unittest/TestLeafBool.cc
+ openvdb/unittest/TestLeafIO.cc
+ openvdb/unittest/TestLeafOrigin.cc
+ openvdb/unittest/TestLevelSetRayIntersector.cc
+ openvdb/unittest/TestLevelSetUtil.cc
+ openvdb/unittest/TestLinearInterp.cc
+ openvdb/unittest/TestMaps.cc
+ openvdb/unittest/TestMat4Metadata.cc
+ openvdb/unittest/TestMath.cc
+ openvdb/unittest/TestMeanCurvature.cc
+ openvdb/unittest/TestMeshToVolume.cc
+ openvdb/unittest/TestMetadata.cc
+ openvdb/unittest/TestMetadataIO.cc
+ openvdb/unittest/TestMetaMap.cc
+ openvdb/unittest/TestName.cc
+ openvdb/unittest/TestNodeIterator.cc
+ openvdb/unittest/TestNodeMask.cc
+ openvdb/unittest/TestParticlesToLevelSet.cc
+ openvdb/unittest/TestPointIndexGrid.cc
+ openvdb/unittest/TestPointPartitioner.cc
+ openvdb/unittest/TestPoissonSolver.cc
+ openvdb/unittest/TestPrePostAPI.cc
+ openvdb/unittest/TestQuadraticInterp.cc
+ openvdb/unittest/TestQuantizedUnitVec.cc
+ openvdb/unittest/TestQuat.cc
+ openvdb/unittest/TestRay.cc
+ openvdb/unittest/TestStats.cc
+ openvdb/unittest/TestStream.cc
+ openvdb/unittest/TestStringMetadata.cc
+ openvdb/unittest/TestTools.cc
+ openvdb/unittest/TestTransform.cc
+ openvdb/unittest/TestTree.cc
+ openvdb/unittest/TestTreeCombine.cc
+ openvdb/unittest/TestTreeGetSetValues.cc
+ openvdb/unittest/TestTreeIterators.cc
+ openvdb/unittest/TestTreeVisitor.cc
+ openvdb/unittest/TestUtil.cc
+ openvdb/unittest/TestValueAccessor.cc
+ openvdb/unittest/TestVec2Metadata.cc
+ openvdb/unittest/TestVec3Metadata.cc
+ openvdb/unittest/TestVolumeRayIntersector.cc
+ openvdb/unittest/TestVolumeToMesh.cc
+)
+
+# todo
+if(WITH_UNITTEST)
+ add_executable(test ${UNITTEST_SRC} ${HEADER_FILES})
+ target_link_libraries(test openvdb ${CPPUNIT_LIBRARIES})
+endif()
diff --git a/build_files/build_environment/patches/cmakelists_tbb.txt b/build_files/build_environment/patches/cmakelists_tbb.txt
new file mode 100644
index 00000000000..1be9ca25f6a
--- /dev/null
+++ b/build_files/build_environment/patches/cmakelists_tbb.txt
@@ -0,0 +1,196 @@
+cmake_minimum_required (VERSION 2.8)
+project(tbb CXX)
+
+if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
+ message(STATUS "Setting build type to 'Release' as none was specified.")
+ set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
+ set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release"
+ "MinSizeRel" "RelWithDebInfo")
+endif()
+
+include_directories(include src src/rml/include )
+
+option(TBB_BUILD_SHARED "Build TBB shared library" ON)
+option(TBB_BUILD_STATIC "Build TBB static library" ON)
+option(TBB_BUILD_TBBMALLOC "Build TBB malloc library" ON)
+option(TBB_BUILD_TBBMALLOC_PROXY "Build TBB malloc proxy library" ON)
+
+if(APPLE)
+ set(CMAKE_MACOSX_RPATH ON)
+endif()
+
+file(GLOB tbb_src "${CMAKE_CURRENT_SOURCE_DIR}/src/tbb/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/old/*.cpp")
+list(APPEND tbb_src ${CMAKE_CURRENT_SOURCE_DIR}/src/rml/client/rml_tbb.cpp)
+file(GLOB to_remove "${CMAKE_CURRENT_SOURCE_DIR}/src/old/test*.cpp")
+list(REMOVE_ITEM tbb_src ${to_remove})
+
+set(tbbmalloc_static_src
+ src/tbbmalloc/backend.cpp
+ src/tbbmalloc/large_objects.cpp
+ src/tbbmalloc/backref.cpp
+ src/tbbmalloc/tbbmalloc.cpp
+ src/tbbmalloc/frontend.cpp
+ src/tbb/itt_notify.cpp)
+
+set(tbbmalloc_src ${tbbmalloc_static_src})
+
+set(tbbmalloc_proxy_src
+ src/tbbmalloc/proxy.cpp
+ src/tbbmalloc/tbb_function_replacement.cpp)
+
+if (NOT APPLE)
+ add_definitions(-DDO_ITT_NOTIFY)
+else()
+ # Disable annoying "has no symbols" warnings
+ set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
+ set(CMAKE_C_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
+ set(CMAKE_CXX_ARCHIVE_FINISH "<CMAKE_RANLIB> -no_warning_for_no_symbols -c <TARGET>")
+endif()
+
+if (UNIX)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -DUSE_PTHREAD")
+ if(NOT CMAKE_CXX_FLAGS MATCHES "-mno-rtm")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mrtm")
+ endif()
+ if (APPLE)
+ set(ARCH_PREFIX "mac")
+ else()
+ set(ARCH_PREFIX "lin")
+ endif()
+ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+ set(ARCH_PREFIX "${ARCH_PREFIX}64")
+ else()
+ set(ARCH_PREFIX "${ARCH_PREFIX}32")
+ endif()
+ set(ENABLE_RTTI "-frtti -fexceptions ")
+ set(DISABLE_RTTI "-fno-rtti -fno-exceptions ")
+elseif(WIN32)
+ cmake_minimum_required (VERSION 3.1)
+ enable_language(ASM_MASM)
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GS- /Zc:wchar_t /Zc:forScope /DUSE_WINTHREAD")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D_CRT_SECURE_NO_DEPRECATE /D_WIN32_WINNT=0x0600 /volatile:iso")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4267 /wd4800 /wd4146 /wd4244 /wd4018")
+
+ if (CMAKE_SIZEOF_VOID_P EQUAL 8)
+ list(APPEND tbb_src src/tbb/intel64-masm/atomic_support.asm
+ src/tbb/intel64-masm/itsx.asm src/tbb/intel64-masm/intel64_misc.asm)
+ list(APPEND tbbmalloc_src src/tbb/intel64-masm/atomic_support.asm)
+ set(CMAKE_ASM_MASM_FLAGS "/DEM64T=1")
+ set(ARCH_PREFIX "win64")
+ else()
+ list(APPEND tbb_src src/tbb/ia32-masm/atomic_support.asm
+ src/tbb/ia32-masm/itsx.asm src/tbb/ia32-masm/lock_byte.asm)
+ list(APPEND tbbmalloc_src src/tbb/ia32-masm/atomic_support.asm)
+ set(ARCH_PREFIX "win32")
+ endif()
+ set(ENABLE_RTTI "/EHsc /GR ")
+ set(DISABLE_RTTI "/EHs- /GR- ")
+endif()
+
+# Linker export definitions
+if (WIN32)
+ add_custom_command(OUTPUT tbb.def
+ COMMAND ${CMAKE_CXX_COMPILER} /TC /EP ${CMAKE_CURRENT_SOURCE_DIR}/src/tbb/${ARCH_PREFIX}-tbb-export.def -I ${CMAKE_CURRENT_SOURCE_DIR}/include > tbb.def
+ MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/src/tbb/${ARCH_PREFIX}-tbb-export.def
+ COMMENT "Preprocessing tbb.def"
+ )
+
+ add_custom_command(OUTPUT tbbmalloc.def
+ COMMAND ${CMAKE_CXX_COMPILER} /TC /EP ${CMAKE_CURRENT_SOURCE_DIR}/src/tbbmalloc/${ARCH_PREFIX}-tbbmalloc-export.def -I ${CMAKE_CURRENT_SOURCE_DIR}/include > tbbmalloc.def
+ MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/src/tbbmalloc/${ARCH_PREFIX}-tbbmalloc-export.def
+ COMMENT "Preprocessing tbbmalloc.def"
+ )
+else()
+ add_custom_command(OUTPUT tbb.def
+ COMMAND ${CMAKE_CXX_COMPILER} -xc++ -E ${CMAKE_CURRENT_SOURCE_DIR}/src/tbb/${ARCH_PREFIX}-tbb-export.def -I ${CMAKE_CURRENT_SOURCE_DIR}/include -o tbb.def
+ MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/src/tbb/${ARCH_PREFIX}-tbb-export.def
+ COMMENT "Preprocessing tbb.def"
+ )
+
+ add_custom_command(OUTPUT tbbmalloc.def
+ COMMAND ${CMAKE_CXX_COMPILER} -xc++ -E ${CMAKE_CURRENT_SOURCE_DIR}/src/tbbmalloc/${ARCH_PREFIX}-tbbmalloc-export.def -I ${CMAKE_CURRENT_SOURCE_DIR}/include -o tbbmalloc.def
+ MAIN_DEPENDENCY ${CMAKE_CURRENT_SOURCE_DIR}/src/tbbmalloc/${ARCH_PREFIX}-tbbmalloc-export.def
+ COMMENT "Preprocessing tbbmalloc.def"
+ )
+endif()
+
+add_custom_target(tbb_def_files DEPENDS tbb.def tbbmalloc.def)
+
+# TBB library
+if (TBB_BUILD_STATIC)
+ add_library(tbb_static STATIC ${tbb_src})
+ set_property(TARGET tbb_static APPEND PROPERTY COMPILE_DEFINITIONS "__TBB_BUILD=1")
+ set_property(TARGET tbb_static APPEND PROPERTY COMPILE_DEFINITIONS "__TBB_SOURCE_DIRECTLY_INCLUDED=1")
+ set_property(TARGET tbb_static APPEND_STRING PROPERTY COMPILE_FLAGS ${ENABLE_RTTI})
+ install(TARGETS tbb_static ARCHIVE DESTINATION lib)
+endif()
+
+if (TBB_BUILD_SHARED)
+ add_library(tbb SHARED ${tbb_src})
+ set_property(TARGET tbb APPEND PROPERTY COMPILE_DEFINITIONS "__TBB_BUILD=1")
+ set_property(TARGET tbb APPEND_STRING PROPERTY COMPILE_FLAGS ${ENABLE_RTTI})
+ add_dependencies(tbb tbb_def_files)
+ if (APPLE)
+ set_property(TARGET tbb APPEND PROPERTY LINK_FLAGS "-Wl,-exported_symbols_list,${CMAKE_CURRENT_BINARY_DIR}/tbb.def")
+ elseif(UNIX)
+ set_property(TARGET tbb APPEND PROPERTY LINK_FLAGS "-Wl,-version-script,${CMAKE_CURRENT_BINARY_DIR}/tbb.def")
+ elseif(WIN32)
+ set_property(TARGET tbb APPEND PROPERTY LINK_FLAGS "/DEF:${CMAKE_CURRENT_BINARY_DIR}/tbb.def")
+ endif()
+ install(TARGETS tbb DESTINATION lib)
+endif()
+
+if(CMAKE_COMPILER_IS_GNUCC)
+ # Quench a warning on GCC
+ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/tbb/governor.cpp COMPILE_FLAGS "-Wno-missing-field-initializers ")
+elseif(MSVC)
+ # Quench a warning on MSVC
+ set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/tbb/scheduler.cpp COMPILE_FLAGS "/wd4458 ")
+endif()
+
+if(TBB_BUILD_TBBMALLOC)
+ # TBB malloc library
+ if (TBB_BUILD_STATIC)
+ add_library(tbbmalloc_static STATIC ${tbbmalloc_static_src})
+ set_property(TARGET tbbmalloc_static APPEND PROPERTY COMPILE_DEFINITIONS "__TBBMALLOC_BUILD=1")
+ set_property(TARGET tbbmalloc_static APPEND_STRING PROPERTY COMPILE_FLAGS ${DISABLE_RTTI})
+ install(TARGETS tbbmalloc_static ARCHIVE DESTINATION lib)
+ endif()
+
+ if (TBB_BUILD_SHARED)
+ add_library(tbbmalloc SHARED ${tbbmalloc_src})
+ set_property(TARGET tbbmalloc APPEND PROPERTY COMPILE_DEFINITIONS "__TBBMALLOC_BUILD=1")
+ set_property(TARGET tbbmalloc APPEND_STRING PROPERTY COMPILE_FLAGS ${DISABLE_RTTI})
+ add_dependencies(tbbmalloc tbb_def_files)
+ if (APPLE)
+ set_property(TARGET tbbmalloc APPEND PROPERTY LINK_FLAGS "-Wl,-exported_symbols_list,${CMAKE_CURRENT_BINARY_DIR}/tbbmalloc.def")
+ elseif(UNIX)
+ set_property(TARGET tbbmalloc APPEND PROPERTY LINK_FLAGS "-Wl,-version-script,${CMAKE_CURRENT_BINARY_DIR}/tbbmalloc.def")
+ elseif(WIN32)
+ set_property(TARGET tbbmalloc APPEND PROPERTY LINK_FLAGS "/DEF:${CMAKE_CURRENT_BINARY_DIR}/tbbmalloc.def")
+ endif()
+ install(TARGETS tbbmalloc DESTINATION lib)
+ endif()
+endif()
+
+if(TBB_BUILD_TBBMALLOC_PROXY)
+ # TBB malloc proxy library
+ if (TBB_BUILD_STATIC)
+ add_library(tbbmalloc_proxy_static STATIC ${tbbmalloc_proxy_src})
+ set_property(TARGET tbbmalloc_proxy_static APPEND PROPERTY COMPILE_DEFINITIONS "__TBBMALLOC_BUILD=1")
+ set_property(TARGET tbbmalloc_proxy_static APPEND_STRING PROPERTY COMPILE_FLAGS ${DISABLE_RTTI})
+ link_libraries(tbbmalloc_proxy_static tbbmalloc)
+ install(TARGETS tbbmalloc_proxy_static ARCHIVE DESTINATION lib)
+ endif()
+
+ if (TBB_BUILD_SHARED)
+ add_library(tbbmalloc_proxy SHARED ${tbbmalloc_proxy_src})
+ set_property(TARGET tbbmalloc_proxy APPEND PROPERTY COMPILE_DEFINITIONS "__TBBMALLOC_BUILD=1")
+ set_property(TARGET tbbmalloc_proxy APPEND_STRING PROPERTY COMPILE_FLAGS ${DISABLE_RTTI})
+ link_libraries(tbbmalloc_proxy tbbmalloc)
+ install(TARGETS tbbmalloc_proxy DESTINATION lib)
+ endif()
+endif()
+
+install(DIRECTORY include/tbb DESTINATION include)
diff --git a/build_files/build_environment/patches/cuew.diff b/build_files/build_environment/patches/cuew.diff
new file mode 100644
index 00000000000..0363034cd93
--- /dev/null
+++ b/build_files/build_environment/patches/cuew.diff
@@ -0,0 +1,26 @@
+--- CmakeLists.txt.orig 2015-12-31 03:46:41 -0700
++++ CMakeLists.txt 2016-04-01 13:28:33 -0600
+@@ -22,3 +22,10 @@
+
+ add_executable(testcuew cuewTest/cuewTest.c include/cuew.h)
+ target_link_libraries(testcuew cuew ${CMAKE_DL_LIBS})
++
++install(TARGETS cuew
++ LIBRARY DESTINATION lib COMPONENT libraries
++ ARCHIVE DESTINATION lib/static COMPONENT libraries)
++
++INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/include/cuew.h
++ DESTINATION include/)
+\ No newline at end of file
+--- src/cuew.c 2016-04-01 13:41:43 -0600
++++ src/cuew.c 2016-04-01 13:41:11 -0600
+@@ -15,7 +15,9 @@
+ */
+
+ #ifdef _MSC_VER
++#if _MSC_VER < 1900
+ # define snprintf _snprintf
++#endif
+ # define popen _popen
+ # define pclose _pclose
+ # define _CRT_SECURE_NO_WARNINGS
diff --git a/build_files/build_environment/patches/distutildebugflags.diff b/build_files/build_environment/patches/distutildebugflags.diff
new file mode 100644
index 00000000000..3d6b688bc53
--- /dev/null
+++ b/build_files/build_environment/patches/distutildebugflags.diff
@@ -0,0 +1,11 @@
+--- _msvccompiler.py.orig 2017-01-17 00:57:48 -0700
++++ _msvccompiler.py 2017-05-20 09:47:26 -0600
+@@ -237,7 +237,7 @@
+ ldflags.extend(('/nodefaultlib:libucrt.lib', 'ucrt.lib'))
+
+ ldflags_debug = [
+- '/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL'
++ '/nologo', '/INCREMENTAL:NO', '/LTCG'
+ ]
+
+ self.ldflags_exe = [*ldflags, '/MANIFEST:EMBED,ID=1']
diff --git a/build_files/build_environment/patches/ffmpeg.diff b/build_files/build_environment/patches/ffmpeg.diff
new file mode 100644
index 00000000000..75fc6490031
--- /dev/null
+++ b/build_files/build_environment/patches/ffmpeg.diff
@@ -0,0 +1,32 @@
+--- libavutil/common.h 2016-02-14 19:29:42 -0700
++++ libavutil/common.h 2016-03-30 09:50:29 -0600
+@@ -99,6 +99,11 @@
+ #define FFSWAP(type,a,b) do{type SWAP_tmp= b; b= a; a= SWAP_tmp;}while(0)
+ #define FF_ARRAY_ELEMS(a) (sizeof(a) / sizeof((a)[0]))
+
++//msvc helper
++#ifdef _MSC_VER
++#define inline __inline
++#endif
++
+ /* misc math functions */
+
+ #ifdef HAVE_AV_CONFIG_H
+--- configure 2016-11-26 03:12:05.000000000 +0100
++++ configure 2017-04-05 03:24:35.000000000 +0200
+@@ -1899,7 +1899,6 @@
+ access
+ aligned_malloc
+ arc4random
+- clock_gettime
+ closesocket
+ CommandLineToArgvW
+ CoTaskMemFree
+@@ -5494,7 +5493,6 @@
+
+ check_func access
+ check_func_headers stdlib.h arc4random
+-check_func_headers time.h clock_gettime || { check_func_headers time.h clock_gettime -lrt && add_extralibs -lrt && LIBRT="-lrt"; }
+ check_func fcntl
+ check_func fork
+ check_func gethrtime
diff --git a/build_files/build_environment/patches/fftw3.diff b/build_files/build_environment/patches/fftw3.diff
new file mode 100644
index 00000000000..48d88414045
--- /dev/null
+++ b/build_files/build_environment/patches/fftw3.diff
@@ -0,0 +1,25 @@
+--- config.h.in 2014-03-04 11:44:58 -0700
++++ config.h.in 2016-03-30 11:42:49 -0600
+@@ -142,9 +142,6 @@
+ /* Define to 1 if you have the `gethrtime' function. */
+ #undef HAVE_GETHRTIME
+
+-/* Define to 1 if you have the `gettimeofday' function. */
+-#undef HAVE_GETTIMEOFDAY
+-
+ /* Define to 1 if hrtime_t is defined in <sys/time.h> */
+ #undef HAVE_HRTIME_T
+
+--- kernel/assert.c 2014-03-04 11:41:03 -0700
++++ kernel/assert.c 2016-04-01 09:41:05 -0600
+@@ -24,8 +24,10 @@
+
+ void X(assertion_failed)(const char *s, int line, const char *file)
+ {
++#if 0
+ fflush(stdout);
+ fprintf(stderr, "fftw: %s:%d: assertion failed: %s\n", file, line, s);
++#endif
+ #ifdef HAVE_ABORT
+ abort();
+ #else
diff --git a/build_files/build_environment/patches/hdf5.diff b/build_files/build_environment/patches/hdf5.diff
new file mode 100644
index 00000000000..cb84625810d
--- /dev/null
+++ b/build_files/build_environment/patches/hdf5.diff
@@ -0,0 +1,11 @@
+--- UserMacros.cmake
++++ UserMacros.cmake
+@@ -16,6 +16,8 @@
+ if (BUILD_USER_DEFINED_LIBS)
+ MACRO_USER_DEFINED_LIBS ()
+ endif (BUILD_USER_DEFINED_LIBS)
++
++include(Config/cmake/usermacros/windows_mt.cmake)
+ #-----------------------------------------------------------------------------
+ #------------------- E X A M P L E E N D -----------------------------------
+ #-----------------------------------------------------------------------------
diff --git a/build_files/build_environment/patches/hidapi.diff b/build_files/build_environment/patches/hidapi.diff
new file mode 100644
index 00000000000..720a8ae5ae9
--- /dev/null
+++ b/build_files/build_environment/patches/hidapi.diff
@@ -0,0 +1,15 @@
+--- hidapi/hidapi.h 2011-10-25 20:58:16 -0600
++++ hidapi/hidapi.h 2016-11-01 12:05:58 -0600
+@@ -30,7 +30,11 @@
+ #include <wchar.h>
+
+ #ifdef _WIN32
+- #define HID_API_EXPORT __declspec(dllexport)
++ #ifdef HID_API_STATIC
++ #define HID_API_EXPORT
++ #else
++ #define HID_API_EXPORT __declspec(dllexport)
++ #endif
+ #define HID_API_CALL
+ #else
+ #define HID_API_EXPORT /**< API export macro */
diff --git a/build_files/build_environment/install_deps_patches/llvm.patch b/build_files/build_environment/patches/install_deps_llvm.diff
index 968f011e57c..968f011e57c 100644
--- a/build_files/build_environment/install_deps_patches/llvm.patch
+++ b/build_files/build_environment/patches/install_deps_llvm.diff
diff --git a/build_files/build_environment/install_deps_patches/osl.patch b/build_files/build_environment/patches/install_deps_osl.diff
index 3b52403f740..3b52403f740 100644
--- a/build_files/build_environment/install_deps_patches/osl.patch
+++ b/build_files/build_environment/patches/install_deps_osl.diff
diff --git a/build_files/build_environment/patches/libfaad.diff b/build_files/build_environment/patches/libfaad.diff
new file mode 100644
index 00000000000..37605b29cd9
--- /dev/null
+++ b/build_files/build_environment/patches/libfaad.diff
@@ -0,0 +1,10 @@
+--- frontend/main.c 2008-09-22 11:55:09 -0600
++++ frontend/main.c 2016-04-06 15:20:36 -0600
+@@ -31,7 +31,6 @@
+ #ifdef _WIN32
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
+-#define off_t __int64
+ #else
+ #include <time.h>
+ #endif
diff --git a/build_files/build_environment/patches/llvm-alloca-fix.diff b/build_files/build_environment/patches/llvm-alloca-fix.diff
new file mode 100644
index 00000000000..5394a472167
--- /dev/null
+++ b/build_files/build_environment/patches/llvm-alloca-fix.diff
@@ -0,0 +1,111 @@
+Index: lib/Target/X86/X86ISelLowering.cpp
+===================================================================
+--- lib/Target/X86/X86ISelLowering.cpp 2014-04-11 23:04:44.000000000 +0200
++++ lib/Target/X86/X86ISelLowering.cpp (working copy)
+@@ -15493,12 +15493,36 @@
+ // non-trivial part is impdef of ESP.
+
+ if (Subtarget->isTargetWin64()) {
++ const char *StackProbeSymbol =
++ Subtarget->isTargetCygMing() ? "___chkstk" : "__chkstk";
++
++ MachineInstrBuilder MIB;
++
++ if (getTargetMachine().getCodeModel() == CodeModel::Large) {
++ // For large code model we need to do indirect call to __chkstk.
++
++ // R11 will be used to contain the address of __chkstk.
++ // R11 is a volotiale register and assumed to be destoyed by the callee,
++ // so there is no need to save and restore it.
++ BuildMI(*BB, MI, DL, TII->get(X86::MOV64ri), X86::R11)
++ .addExternalSymbol(StackProbeSymbol);
++ // Create a call to __chkstk function which address contained in R11.
++ MIB = BuildMI(*BB, MI, DL, TII->get(X86::CALL64r))
++ .addReg(X86::R11, RegState::Kill);
++
++ } else {
++
++ // For non-large code model we can do direct call to __chkstk.
++
++ MIB = BuildMI(*BB, MI, DL, TII->get(X86::W64ALLOCA))
++ .addExternalSymbol(StackProbeSymbol);
++ }
++
+ if (Subtarget->isTargetCygMing()) {
+ // ___chkstk(Mingw64):
+ // Clobbers R10, R11, RAX and EFLAGS.
+ // Updates RSP.
+- BuildMI(*BB, MI, DL, TII->get(X86::W64ALLOCA))
+- .addExternalSymbol("___chkstk")
++ MIB
+ .addReg(X86::RAX, RegState::Implicit)
+ .addReg(X86::RSP, RegState::Implicit)
+ .addReg(X86::RAX, RegState::Define | RegState::Implicit)
+@@ -15507,8 +15531,7 @@
+ } else {
+ // __chkstk(MSVCRT): does not update stack pointer.
+ // Clobbers R10, R11 and EFLAGS.
+- BuildMI(*BB, MI, DL, TII->get(X86::W64ALLOCA))
+- .addExternalSymbol("__chkstk")
++ MIB
+ .addReg(X86::RAX, RegState::Implicit)
+ .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit);
+ // RAX has the offset to be subtracted from RSP.
+Index: lib/Target/X86/X86FrameLowering.cpp
+===================================================================
+--- lib/Target/X86/X86FrameLowering.cpp 2013-10-24 01:37:01.000000000 +0200
++++ lib/Target/X86/X86FrameLowering.cpp (working copy)
+@@ -635,25 +635,49 @@
+ .addReg(X86::EAX, RegState::Kill)
+ .setMIFlag(MachineInstr::FrameSetup);
+ }
++
++ MachineInstrBuilder MIB;
+
+ if (Is64Bit) {
++
+ // Handle the 64-bit Windows ABI case where we need to call __chkstk.
+ // Function prologue is responsible for adjusting the stack pointer.
+ BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::RAX)
+ .addImm(NumBytes)
+ .setMIFlag(MachineInstr::FrameSetup);
++
++ if (TM.getCodeModel() == CodeModel::Large) {
++ // For large code model we need to do indirect call to __chkstk.
++
++
++ // R11 will be used to contain the address of __chkstk.
++ // R11 is a volotiale register and assumed to be destoyed by the callee,
++ // so there is no need to save and restore it.
++ BuildMI(MBB, MBBI, DL, TII.get(X86::MOV64ri), X86::R11)
++ .addExternalSymbol(StackProbeSymbol);
++ // Create a call to __chkstk function which address contained in R11.
++ MIB = BuildMI(MBB, MBBI, DL, TII.get(X86::CALL64r))
++ .addReg(X86::R11, RegState::Kill);
++ } else {
++
++ // For non-large code model we can do direct call to __chkstk.
++
++ MIB = BuildMI(MBB, MBBI, DL, TII.get(X86::W64ALLOCA))
++ .addExternalSymbol(StackProbeSymbol);
++ }
+ } else {
+ // Allocate NumBytes-4 bytes on stack in case of isEAXAlive.
+ // We'll also use 4 already allocated bytes for EAX.
+ BuildMI(MBB, MBBI, DL, TII.get(X86::MOV32ri), X86::EAX)
+ .addImm(isEAXAlive ? NumBytes - 4 : NumBytes)
+ .setMIFlag(MachineInstr::FrameSetup);
++
++ MIB = BuildMI(MBB, MBBI, DL, TII.get(X86::CALLpcrel32))
++ .addExternalSymbol(StackProbeSymbol);
+ }
+
+- BuildMI(MBB, MBBI, DL,
+- TII.get(Is64Bit ? X86::W64ALLOCA : X86::CALLpcrel32))
+- .addExternalSymbol(StackProbeSymbol)
+- .addReg(StackPtr, RegState::Define | RegState::Implicit)
++
++ MIB.addReg(StackPtr, RegState::Define | RegState::Implicit)
+ .addReg(X86::EFLAGS, RegState::Define | RegState::Implicit)
+ .setMIFlag(MachineInstr::FrameSetup);
+
diff --git a/build_files/build_environment/patches/ming32sh.cmd b/build_files/build_environment/patches/ming32sh.cmd
new file mode 100644
index 00000000000..3259d9d3714
--- /dev/null
+++ b/build_files/build_environment/patches/ming32sh.cmd
@@ -0,0 +1,7 @@
+@title MinGW-w64 32-bit GCC build environment
+
+@echo Setting up environment for MinGW-w64 GCC 32-bit...
+
+@set PATH=%CD%\bin;%CD%\msys\1.0\bin;%cd%\..\..\perl32\site\bin;%cd%\..\..\perl32\bin;%cd%\..\..\c\bin;%PATH%
+
+
diff --git a/build_files/build_environment/patches/ming64sh.cmd b/build_files/build_environment/patches/ming64sh.cmd
new file mode 100644
index 00000000000..18fea3829f3
--- /dev/null
+++ b/build_files/build_environment/patches/ming64sh.cmd
@@ -0,0 +1,7 @@
+@title MinGW-w64 64-bit GCC build environment
+
+@echo Setting up environment for MinGW-w64 GCC 64-bit...
+
+@set PATH=%CD%\bin;%CD%\msys\1.0\bin;%cd%\..\..\perl\site\bin;%cd%\..\..\perl\bin;%cd%\..\..\c\bin;%PATH%
+
+
diff --git a/build_files/build_environment/patches/numpy.diff b/build_files/build_environment/patches/numpy.diff
new file mode 100644
index 00000000000..c4c57222838
--- /dev/null
+++ b/build_files/build_environment/patches/numpy.diff
@@ -0,0 +1,23 @@
+diff -Naur numpy-1.11.1/numpy/distutils/ccompiler.py numpy-1.11.1/numpy/distutils/ccompiler.py
+--- numpy-1.11.1/numpy/distutils/ccompiler.py 2016-06-25 08:38:34 -0600
++++ numpy-1.11.1/numpy/distutils/ccompiler.py 2016-08-04 12:33:43 -0600
+@@ -29,6 +29,7 @@
+
+ # Using customized CCompiler.spawn.
+ def CCompiler_spawn(self, cmd, display=None):
++ cmd = quote_args(cmd)
+ """
+ Execute a command in a sub-process.
+
+diff -Naur numpy-1.11.1/numpy/distutils/misc_util.py numpy-1.11.1/numpy/distutils/misc_util.py
+--- numpy-1.11.1/numpy/distutils/misc_util.py 2016-06-25 08:38:34 -0600
++++ numpy-1.11.1/numpy/distutils/misc_util.py 2016-08-04 12:34:56 -0600
+@@ -116,7 +116,7 @@
+ args = list(args)
+ for i in range(len(args)):
+ a = args[i]
+- if ' ' in a and a[0] not in '"\'':
++ if ' ' in a and a[0] not in '"\'' and a[len(a)-1] not in '"\'':
+ args[i] = '"%s"' % (a)
+ return args
+
diff --git a/build_files/build_environment/patches/opencollada.diff b/build_files/build_environment/patches/opencollada.diff
new file mode 100644
index 00000000000..0c91b4151fe
--- /dev/null
+++ b/build_files/build_environment/patches/opencollada.diff
@@ -0,0 +1,32 @@
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 3fc9be5..5112ce6 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -254,11 +254,11 @@
+ endif()
+
+ #adding PCRE
+-find_package(PCRE)
++#find_package(PCRE)
+ if (PCRE_FOUND)
+ message(STATUS "SUCCESSFUL: PCRE found")
+ else () # if pcre not found building its local copy from ./Externals
+- if (WIN32 OR APPLE)
++ if (1)
+ message("WARNING: Native PCRE not found, taking PCRE from ./Externals")
+ add_definitions(-DPCRE_STATIC)
+ add_subdirectory(${EXTERNAL_LIBRARIES}/pcre)
+diff --git a/DAEValidator/library/include/no_warning_begin.orig b/DAEValidator/library/include/no_warning_begin
+index 3fc9be5..5112ce6 100644
+--- a/DAEValidator/library/include/no_warning_begin.orig 2017-05-31 16:56:39 -0600
++++ b/DAEValidator/library/include/no_warning_begin 2017-06-07 10:18:45 -0600
+@@ -2,6 +2,9 @@
+ #if defined(_WIN32)
+ # pragma warning(push)
+ # pragma warning(disable:4668)
++# if _MSC_VER >=1900
++# pragma warning(disable:5031)
++# endif
+ # if defined(_MSC_VER) && defined(_DEBUG)
+ # pragma warning(disable:4548)
+ # endif
diff --git a/build_files/build_environment/patches/opencolorio.diff b/build_files/build_environment/patches/opencolorio.diff
new file mode 100644
index 00000000000..4e947d89097
--- /dev/null
+++ b/build_files/build_environment/patches/opencolorio.diff
@@ -0,0 +1,21 @@
+diff -ru ./CMakeLists.txt ./CMakeLists.txt
+--- ./CMakeLists.txt 2014-09-11 21:08:18.000000000 +0200
++++ ./CMakeLists.txt 2016-05-15 17:17:01.000000000 +0200
+@@ -186,7 +186,7 @@
+ PATCH_COMMAND patch -f -p1 < ${CMAKE_SOURCE_DIR}/ext/tinyxml_${TINYXML_VERSION}.patch
+ BINARY_DIR ext/build/tinyxml
+ INSTALL_DIR ext/dist
+- CMAKE_ARGS ${TINYXML_CMAKE_ARGS}
++ CMAKE_ARGS ${TINYXML_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} -DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT} -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} -DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG} -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
+ )
+ if(WIN32)
+ set(TINYXML_STATIC_LIBRARIES ${PROJECT_BINARY_DIR}/ext/dist/lib/tinyxml.lib)
+@@ -254,7 +254,7 @@
+ BINARY_DIR ext/build/yaml-cpp
+ PATCH_COMMAND patch -p1 < ${CMAKE_SOURCE_DIR}/ext/yaml-cpp-${YAML_CPP_VERSION}.patch
+ INSTALL_DIR ext/dist
+- CMAKE_ARGS ${YAML_CPP_CMAKE_ARGS}
++ CMAKE_ARGS ${YAML_CPP_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES} -DCMAKE_OSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} -DCMAKE_OSX_SYSROOT=${CMAKE_OSX_SYSROOT} -DCMAKE_C_FLAGS_DEBUG=${CMAKE_C_FLAGS_DEBUG} -DCMAKE_C_FLAGS_RELEASE=${CMAKE_C_FLAGS_RELEASE} -DCMAKE_CXX_FLAGS_DEBUG=${CMAKE_CXX_FLAGS_DEBUG} -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS}
+ )
+ set(YAML_CPP_INCLUDE_DIRS ${PROJECT_BINARY_DIR}/ext/dist/include)
+ set(YAML_CPP_LIBRARY_DIRS ${PROJECT_BINARY_DIR}/ext/dist/lib)
diff --git a/build_files/build_environment/patches/openexr.diff b/build_files/build_environment/patches/openexr.diff
new file mode 100644
index 00000000000..ec18751fe74
--- /dev/null
+++ b/build_files/build_environment/patches/openexr.diff
@@ -0,0 +1,33 @@
+--- IlmImf/CMakeLists.txt 2014-08-10 06:23:56.000000000 +0200
++++ IlmImf/CMakeLists.txt 2017-01-08 04:06:04.931723800 +0100
+@@ -8,8 +8,8 @@
+
+ TARGET_LINK_LIBRARIES ( b44ExpLogTable
+ Half
+- Iex${ILMBASE_LIBSUFFIX}
+ IlmThread${ILMBASE_LIBSUFFIX}
++ Iex${ILMBASE_LIBSUFFIX}
+ ${PTHREAD_LIB}
+ )
+
+@@ -25,8 +25,8 @@
+
+ TARGET_LINK_LIBRARIES ( dwaLookups
+ Half
+- Iex${ILMBASE_LIBSUFFIX}
+ IlmThread${ILMBASE_LIBSUFFIX}
++ Iex${ILMBASE_LIBSUFFIX}
+ ${PTHREAD_LIB}
+ )
+
+@@ -138,9 +138,9 @@
+
+ TARGET_LINK_LIBRARIES ( IlmImf
+ Half
+- Iex${ILMBASE_LIBSUFFIX}
+ Imath${ILMBASE_LIBSUFFIX}
+ IlmThread${ILMBASE_LIBSUFFIX}
++ Iex${ILMBASE_LIBSUFFIX}
+ ${PTHREAD_LIB} ${ZLIB_LIBRARIES}
+ )
+
diff --git a/build_files/build_environment/patches/openimageio_gdi.diff b/build_files/build_environment/patches/openimageio_gdi.diff
new file mode 100644
index 00000000000..af0c90638de
--- /dev/null
+++ b/build_files/build_environment/patches/openimageio_gdi.diff
@@ -0,0 +1,26 @@
+Index: OpenImageIO/osdep.h
+===================================================================
+--- OpenImageIO/osdep.h (revision 61595)
++++ OpenImageIO/osdep.h (working copy)
+@@ -34,6 +34,7 @@
+ # define WIN32_LEAN_AND_MEAN
+ # define VC_EXTRALEAN
+ # define NOMINMAX
++# define NOGDI
+ # include <windows.h>
+ #endif
+
+Index: OpenImageIO/platform.h
+===================================================================
+--- OpenImageIO/platform.h (revision 61595)
++++ OpenImageIO/platform.h (working copy)
+@@ -77,6 +77,9 @@
+ # ifndef NOMINMAX
+ # define NOMINMAX
+ # endif
++# ifndef NOGDI
++# define NOGDI
++# endif
+ # include <windows.h>
+ #endif
+
diff --git a/build_files/build_environment/patches/openimageio_idiff.diff b/build_files/build_environment/patches/openimageio_idiff.diff
new file mode 100644
index 00000000000..ae1884f76b5
--- /dev/null
+++ b/build_files/build_environment/patches/openimageio_idiff.diff
@@ -0,0 +1,13 @@
+--- idiff.cpp 2016-11-18 11:42:01 -0700
++++ idiff.cpp 2016-11-18 11:41:25 -0700
+@@ -308,8 +308,10 @@
+ // printed with three digit exponent. We change this behaviour to fit
+ // Linux way
+ #ifdef _MSC_VER
++#if _MSC_VER < 1900
+ _set_output_format(_TWO_DIGIT_EXPONENT);
+ #endif
++#endif
+ std::streamsize precis = std::cout.precision();
+ std::cout << " " << cr.nwarn << " pixels ("
+ << std::setprecision(3) << (100.0*cr.nwarn / npels)
diff --git a/build_files/build_environment/patches/openimageio_staticexr.diff b/build_files/build_environment/patches/openimageio_staticexr.diff
new file mode 100644
index 00000000000..7e4eee04548
--- /dev/null
+++ b/build_files/build_environment/patches/openimageio_staticexr.diff
@@ -0,0 +1,10 @@
+--- CMakeLists.txt 2016-11-01 01:03:44 -0600
++++ CMakeLists.txt 2016-12-01 09:20:12 -0700
+@@ -454,7 +454,6 @@
+ add_definitions (-D_CRT_NONSTDC_NO_WARNINGS)
+ add_definitions (-D_SCL_SECURE_NO_WARNINGS)
+ add_definitions (-DJAS_WIN_MSVC_BUILD)
+- add_definitions (-DOPENEXR_DLL)
+ if (LINKSTATIC)
+ add_definitions (-DBoost_USE_STATIC_LIBS=1)
+ else ()
diff --git a/build_files/build_environment/patches/opensubdiv.diff b/build_files/build_environment/patches/opensubdiv.diff
new file mode 100644
index 00000000000..9e9cf7ad554
--- /dev/null
+++ b/build_files/build_environment/patches/opensubdiv.diff
@@ -0,0 +1,16 @@
+ opensubdiv/osd/d3d11VertexBuffer.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/opensubdiv/osd/d3d11VertexBuffer.cpp b/opensubdiv/osd/d3d11VertexBuffer.cpp
+index 603cbf4..07e7e0a 100644
+--- a/opensubdiv/osd/d3d11VertexBuffer.cpp
++++ b/opensubdiv/osd/d3d11VertexBuffer.cpp
+@@ -81,7 +81,7 @@ D3D11VertexBuffer::UpdateData(const float *src, int startVertex, int numVertices
+
+ deviceContext->Unmap(_uploadBuffer, 0);
+
+- D3D11_BOX srcBox = { 0, 0, 0, size, 1, 1 };
++ D3D11_BOX srcBox = { 0, 0, 0, (UINT) size, 1, 1 };
+ deviceContext->CopySubresourceRegion(_buffer, 0, 0, 0, 0,
+ _uploadBuffer, 0, &srcBox);
+ }
diff --git a/build_files/build_environment/patches/openvdb.diff b/build_files/build_environment/patches/openvdb.diff
new file mode 100644
index 00000000000..f3afa13ea17
--- /dev/null
+++ b/build_files/build_environment/patches/openvdb.diff
@@ -0,0 +1,11 @@
+diff -Naur k:\BlenderDev\lib\win64_vc12_Harvest\openVDB\/include/openvdb/math/Coord.h .\openVDB/include/openvdb/math/Coord.h
+--- k:\BlenderDev\lib\win64_vc12_Harvest\openVDB\/include/openvdb/math/Coord.h 2016-03-30 15:09:49 -0600
++++ .\openVDB/include/openvdb/math/Coord.h 2016-04-01 06:53:47 -0600
+@@ -34,6 +34,7 @@
+ #include <openvdb/Platform.h>
+ #include "Math.h"
+ #include "Vec3.h"
++#define NOMINMAX
+
+ namespace tbb { class split; } // forward declaration
+
diff --git a/build_files/build_environment/patches/openvdb_vc2013.diff b/build_files/build_environment/patches/openvdb_vc2013.diff
new file mode 100644
index 00000000000..7dc3e476297
--- /dev/null
+++ b/build_files/build_environment/patches/openvdb_vc2013.diff
@@ -0,0 +1,35 @@
+--- openvdb/tree/LeafNode.h 2015-10-01 15:55:33 -0600
++++ openvdb/tree/LeafNode.h 2016-03-26 13:12:22 -0600
+@@ -70,13 +70,14 @@
+ typedef boost::shared_ptr<LeafNode> Ptr;
+ typedef util::NodeMask<Log2Dim> NodeMaskType;
+
+- static const Index
+- LOG2DIM = Log2Dim, // needed by parent nodes
+- TOTAL = Log2Dim, // needed by parent nodes
+- DIM = 1 << TOTAL, // dimension along one coordinate direction
+- NUM_VALUES = 1 << 3 * Log2Dim,
+- NUM_VOXELS = NUM_VALUES, // total number of voxels represented by this node
+- SIZE = NUM_VALUES,
++ static const Index
++ LOG2DIM = Log2Dim, // needed by parent nodes
++ TOTAL = Log2Dim, // needed by parent nodes
++ DIM = 1 << TOTAL, // dimension along one coordinate direction
++ NUM_VALUES = 1 << 3 * Log2Dim,
++ NUM_VOXELS = NUM_VALUES; // total number of voxels represented by this node
++ static const Index
++ SIZE = NUM_VALUES,
+ LEVEL = 0; // level 0 = leaf
+
+ /// @brief ValueConverter<T>::Type is the type of a LeafNode having the same
+--- openvdb/PlatformConfig.h 2016-03-30 15:09:49 -0600
++++ openvdb/PlatformConfig.h 2016-04-01 07:00:38 -0600
+@@ -47,7 +47,7 @@
+ #if !defined(OPENVDB_OPENEXR_STATICLIB) && !defined(OPENEXR_DLL)
+ #define OPENEXR_DLL
+ #endif
+-
++ #define NOMINMAX
+ #endif // _WIN32
+
+ #endif // OPENVDB_PLATFORMCONFIG_HAS_BEEN_INCLUDED
diff --git a/build_files/build_environment/patches/osl.diff b/build_files/build_environment/patches/osl.diff
new file mode 100644
index 00000000000..fcb5ec4165f
--- /dev/null
+++ b/build_files/build_environment/patches/osl.diff
@@ -0,0 +1,12 @@
+diff -Naur osl/src/external_osl/src/cmake/flexbison.cmake osl_bak/src/external_osl/src/cmake/flexbison.cmake
+--- osl/src/external_osl//src/cmake/flexbison.cmake 2016-01-29 11:15:22 -0700
++++ osl_bak/src/external_osl/src/cmake/flexbison.cmake 2016-02-29 21:26:26 -0700
+@@ -77,7 +77,7 @@
+ DEPENDS ${${compiler_headers}}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
+ ADD_CUSTOM_COMMAND ( OUTPUT ${flexoutputcxx}
+- COMMAND ${FLEX_EXECUTABLE} -o ${flexoutputcxx} "${CMAKE_CURRENT_SOURCE_DIR}/${flexsrc}"
++ COMMAND ${FLEX_EXECUTABLE} ${FLEX_EXTRA_OPTIONS} -o ${flexoutputcxx} "${CMAKE_CURRENT_SOURCE_DIR}/${flexsrc}"
+ MAIN_DEPENDENCY ${flexsrc}
+ DEPENDS ${${compiler_headers}}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
diff --git a/build_files/build_environment/patches/osl_simd_oiio.diff b/build_files/build_environment/patches/osl_simd_oiio.diff
new file mode 100644
index 00000000000..5062a597167
--- /dev/null
+++ b/build_files/build_environment/patches/osl_simd_oiio.diff
@@ -0,0 +1,14 @@
+--- CMakeLists.txt 2016-10-31 16:48:19 -0600
++++ CMakeLists.txt 2017-04-10 10:38:48 -0600
+@@ -269,6 +269,11 @@
+ add_definitions ("-DOIIO_STATIC_BUILD=1")
+ endif ()
+
++set (OIIO_NOSIMD OFF CACHE BOOL "Disable simd support in oiio")
++if (OIIO_NOSIMD)
++ add_definitions ("-DOIIO_NO_SSE=1")
++endif ()
++
+ if (OSL_NO_DEFAULT_TEXTURESYSTEM)
+ add_definitions ("-DOSL_NO_DEFAULT_TEXTURESYSTEM=1")
+ endif ()
diff --git a/build_files/build_environment/patches/pthreads.diff b/build_files/build_environment/patches/pthreads.diff
new file mode 100644
index 00000000000..bbabfdc8925
--- /dev/null
+++ b/build_files/build_environment/patches/pthreads.diff
@@ -0,0 +1,13 @@
+--- pthread.h.orig 2012-05-26 22:16:45 -0600
++++ pthread.h 2016-04-01 09:20:36 -0600
+@@ -109,6 +109,10 @@
+ /* Include everything */
+ #endif
+
++#if _MSC_VER >= 1900
++# define HAVE_STRUCT_TIMESPEC 1
++#endif
++
+ #if defined(_UWIN)
+ # define HAVE_STRUCT_TIMESPEC 1
+ # define HAVE_SIGNAL_H 1
diff --git a/build_files/build_environment/patches/pyshell.diff b/build_files/build_environment/patches/pyshell.diff
new file mode 100644
index 00000000000..7ccffe4c040
--- /dev/null
+++ b/build_files/build_environment/patches/pyshell.diff
@@ -0,0 +1,12 @@
+--- pyshellext.cpp.orig 2017-01-17 00:57:53 -0700
++++ pyshellext.cpp 2017-05-20 15:21:51 -0600
+@@ -13,6 +13,9 @@
+ #include <strsafe.h>
+
+ #include "pyshellext_h.h"
++#if _MSC_VER < 1900
++#include "pyshellext_i.c"
++#endif
+
+ #define DDWM_UPDATEWINDOW (WM_USER+3)
+
diff --git a/build_files/build_environment/patches/python.diff b/build_files/build_environment/patches/python.diff
new file mode 100644
index 00000000000..749a51d6972
--- /dev/null
+++ b/build_files/build_environment/patches/python.diff
@@ -0,0 +1,40 @@
+--- pcbuild/build.bat 2016-05-21 09:53:55 -0600
++++ pcbuild/build.bat 2016-05-21 09:56:16 -0600
+@@ -59,6 +59,7 @@
+ if "%~1"=="-h" goto Usage
+ if "%~1"=="-c" (set conf=%2) & shift & shift & goto CheckOpts
+ if "%~1"=="-p" (set platf=%2) & shift & shift & goto CheckOpts
++if "%~1"=="-k" (set vs_toolset=%2) & shift & shift & goto CheckOpts
+ if "%~1"=="-r" (set target=Rebuild) & shift & goto CheckOpts
+ if "%~1"=="-t" (set target=%2) & shift & shift & goto CheckOpts
+ if "%~1"=="-d" (set conf=Debug) & shift & goto CheckOpts
+@@ -126,7 +126,7 @@
+
+ :Kill
+ echo on
+-msbuild "%dir%\pythoncore.vcxproj" /t:KillPython %verbose%^
++msbuild "%dir%\pythoncore.vcxproj" /t:KillPython %verbose% /p:PlatformToolset=%vs_toolset%^
+ /p:Configuration=%conf% /p:Platform=%platf%^
+ /p:KillPython=true
+
+@@ -95,7 +96,7 @@
+ rem batch is, shall we say, "lackluster"
+ echo on
+ msbuild "%dir%pcbuild.proj" /t:%target% %parallel% %verbose%^
+- /p:Configuration=%conf% /p:Platform=%platf%^
++ /p:Configuration=%conf% /p:Platform=%platf% /p:PlatformToolset=%vs_toolset%^
+ /p:IncludeExternals=%IncludeExternals%^
+ /p:IncludeSSL=%IncludeSSL% /p:IncludeTkinter=%IncludeTkinter%^
+ /p:UseTestMarker=%UseTestMarker%^
+
+--- pcbuild/sqlite3.vcxproj 2015-12-06 18:39:10 -0700
++++ pcbuild/sqlite3.vcxproj 2016-11-02 09:25:56 -0600
+@@ -43,7 +43,7 @@
+ <Import Project="python.props" />
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+ <PropertyGroup Label="Configuration">
+- <ConfigurationType>DynamicLibrary</ConfigurationType>
++ <ConfigurationType>StaticLibrary</ConfigurationType>
+ <CharacterSet>NotSet</CharacterSet>
+ </PropertyGroup>
+ <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
diff --git a/build_files/build_environment/patches/python_apple.diff b/build_files/build_environment/patches/python_apple.diff
new file mode 100644
index 00000000000..0ca7a8d8f04
--- /dev/null
+++ b/build_files/build_environment/patches/python_apple.diff
@@ -0,0 +1,48 @@
+--- Modules/expat/expat_external.h 2016-12-17 06:51:30 -0500
++++ Modules/expat/expat_external.h 2016-12-17 06:55:29 -0500
+@@ -7,9 +7,17 @@
+
+ /* External API definitions */
+
+-/* Namespace external symbols to allow multiple libexpat version to
+- co-exist. */
+-#include "pyexpatns.h"
++/*
++
++ HACK: Fix build breakage on MacOS:
++ *** WARNING: renaming "pyexpat" since importing it failed: dlopen(build/lib.macosx-10.6-i386-3.3/pyexpat.so, 2): Symbol not found: _XML_ErrorString
++ This reverts c242a8f30806 from the python hg repo:
++ restore namespacing of pyexpat symbols (closes #19186)
++ See http://bugs.python.org/issue19186#msg214069
++ The recommendation to include Modules/inc at first broke the Linux build...
++ So do it this way, as it was before. Needs some realignment later.
++
++*/
+
+ #if defined(_MSC_EXTENSIONS) && !defined(__BEOS__) && !defined(__CYGWIN__)
+ #define XML_USE_MSC_EXTENSIONS 1
+--- pyconfig.h.in 2017-04-05 02:47:52.000000000 +0200
++++ pyconfig.h.in 2017-04-05 02:51:33.000000000 +0200
+@@ -119,12 +119,6 @@
+ /* Define to 1 if you have the `clock' function. */
+ #undef HAVE_CLOCK
+
+-/* Define to 1 if you have the `clock_getres' function. */
+-#undef HAVE_CLOCK_GETRES
+-
+-/* Define to 1 if you have the `clock_gettime' function. */
+-#undef HAVE_CLOCK_GETTIME
+-
+ /* Define if the C compiler supports computed gotos. */
+ #undef HAVE_COMPUTED_GOTOS
+
+@@ -338,9 +332,6 @@
+ /* Define this if you have flockfile(), getc_unlocked(), and funlockfile() */
+ #undef HAVE_GETC_UNLOCKED
+
+-/* Define to 1 if you have the `getentropy' function. */
+-#undef HAVE_GETENTROPY
+-
+ /* Define to 1 if you have the `getgrouplist' function. */
+ #undef HAVE_GETGROUPLIST
+
diff --git a/build_files/build_environment/patches/python_runtime_vc2013.diff b/build_files/build_environment/patches/python_runtime_vc2013.diff
new file mode 100644
index 00000000000..186d2b36c07
--- /dev/null
+++ b/build_files/build_environment/patches/python_runtime_vc2013.diff
@@ -0,0 +1,29 @@
+--- _msvccompiler.py.orig 2017-05-20 19:31:45 -0600
++++ _msvccompiler.py 2017-06-10 10:05:38 -0600
+@@ -222,9 +222,9 @@
+ # use /MT[d] to build statically, then switch from libucrt[d].lib to ucrt[d].lib
+ # later to dynamically link to ucrtbase but not vcruntime.
+ self.compile_options = [
+- '/nologo', '/Ox', '/W3', '/GL', '/DNDEBUG'
++ '/nologo', '/Ox', '/W3', '/GL', '/DNDEBUG' , '/MD'
+ ]
+- self.compile_options.append('/MD' if self._vcruntime_redist else '/MT')
++ #self.compile_options.append('/MD' if self._vcruntime_redist else '/MT')
+
+ self.compile_options_debug = [
+ '/nologo', '/Od', '/MDd', '/Zi', '/W3', '/D_DEBUG'
+@@ -233,11 +233,11 @@
+ ldflags = [
+ '/nologo', '/INCREMENTAL:NO', '/LTCG'
+ ]
+- if not self._vcruntime_redist:
+- ldflags.extend(('/nodefaultlib:libucrt.lib', 'ucrt.lib'))
++ #if not self._vcruntime_redist:
++ # ldflags.extend(('/nodefaultlib:libucrt.lib', 'ucrt.lib'))
+
+ ldflags_debug = [
+- '/nologo', '/INCREMENTAL:NO', '/LTCG', '/DEBUG:FULL'
++ '/nologo', '/INCREMENTAL:NO', '/LTCG'
+ ]
+
+ self.ldflags_exe = [*ldflags, '/MANIFEST:EMBED,ID=1']
diff --git a/build_files/build_environment/patches/schroedinger.diff b/build_files/build_environment/patches/schroedinger.diff
new file mode 100644
index 00000000000..6acb35f2a7b
--- /dev/null
+++ b/build_files/build_environment/patches/schroedinger.diff
@@ -0,0 +1,54 @@
+--- configure.orig 2012-01-22 19:06:43 -0700
++++ configure 2016-04-06 20:00:50 -0600
+@@ -16492,10 +16492,10 @@
+ HAVE_ORC=yes
+ fi
+ if test "x${HAVE_ORC}" != xyes ; then
+- as_fn_error $? "orc-0.4 >= $ORC_VER is required" "$LINENO" 5
++ $as_echo "orc-0.4 >= $ORC_VER is required"
+ fi
+ SCHRO_PKG_DEPS="$SCHRO_PKG_DEPS orc-0.4 >= $ORC_VER"
+-ORCC=`$PKG_CONFIG --variable=orcc orc-0.4`
++#ORCC=`$PKG_CONFIG --variable=orcc orc-0.4`
+
+ if test "x$cross_compiling" != xyes; then
+ HAVE_ORCC_TRUE=
+--- Makefile.in 2012-01-22 18:06:42 -0700
++++ Makefile.in 2016-04-06 20:30:09 -0600
+@@ -291,7 +291,7 @@
+ top_builddir = @top_builddir@
+ top_srcdir = @top_srcdir@
+ AUTOMAKE_OPTIONS = foreign
+-SUBDIRS = schroedinger doc tools testsuite
++SUBDIRS = schroedinger doc tools
+ DISTCHECK_CONFIGURE_FLAGS = --enable-gtk-doc
+ DIST_SUBDIRS = schroedinger doc tools testsuite
+ EXTRA_DIST = COPYING COPYING.GPL COPYING.LGPL COPYING.MIT COPYING.MPL \
+
+--- schroedinger.pc.in 2011-03-21 17:08:39 -0600
++++ schroedinger.pc.in 2016-04-08 13:30:42 -0600
+@@ -7,9 +7,9 @@
+
+ Name: schroedinger-@SCHRO_MAJORMINOR@
+ Description: Dirac codec library
+-Requires.private: @SCHRO_PKG_DEPS@
++Requires: @SCHRO_PKG_DEPS@
+ Version: @VERSION@
+-Libs: -L${libdir} -lschroedinger-@SCHRO_MAJORMINOR@
++Libs: -L${libdir} -lschroedinger-@SCHRO_MAJORMINOR@ -lorc-0.4
+ Libs.private: @PTHREAD_LIBS@ @LIBM@
+ Cflags: -I${includedir}
+
+--- ./schroedinger/schrodecoder.c 2012-01-23 00:38:57.000000000 +0100
++++ ./schroedinger/schrodecoder.c 2016-05-15 06:07:24.000000000 +0200
+@@ -70,8 +70,8 @@
+ };
+
+
+-int _schro_decode_prediction_only;
+-int _schro_telemetry;
++int _schro_decode_prediction_only = 0;
++int _schro_telemetry = 0;
+
+ static void schro_decoder_x_decode_motion (SchroAsyncStage * stage);
+ static void schro_decoder_x_render_motion (SchroAsyncStage * stage);
diff --git a/build_files/build_environment/patches/sdl.diff b/build_files/build_environment/patches/sdl.diff
new file mode 100644
index 00000000000..b309d0230f3
--- /dev/null
+++ b/build_files/build_environment/patches/sdl.diff
@@ -0,0 +1,50 @@
+diff -ru /Users/brecht/dev/lib/deps/Downloads/SDL2-2.0.4/src/video/SDL_video.c ./src/video/SDL_video.c
+--- /Users/brecht/dev/lib/deps/Downloads/SDL2-2.0.4/src/video/SDL_video.c 2016-01-02 20:56:31.000000000 +0100
++++ ./src/video/SDL_video.c 2016-05-15 02:58:27.000000000 +0200
+@@ -137,7 +137,7 @@
+
+ #define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
+
+-#ifdef __MACOSX__
++#if SDL_VIDEO_DRIVER_COCOA
+ /* Support for Mac OS X fullscreen spaces */
+ extern SDL_bool Cocoa_IsWindowInFullscreenSpace(SDL_Window * window);
+ extern SDL_bool Cocoa_SetWindowFullscreenSpace(SDL_Window * window, SDL_bool state);
+@@ -1141,7 +1141,7 @@
+ if ( window->is_hiding && fullscreen )
+ return 0;
+
+-#ifdef __MACOSX__
++#if SDL_VIDEO_DRIVER_COCOA
+ /* if the window is going away and no resolution change is necessary,
+ do nothing, or else we may trigger an ugly double-transition
+ */
+@@ -2365,7 +2365,7 @@
+ return SDL_FALSE;
+ }
+
+-#ifdef __MACOSX__
++#if SDL_VIDEO_DRIVER_COCOA
+ if (Cocoa_IsWindowInFullscreenSpace(window)) {
+ return SDL_FALSE;
+ }
+--- CMakeLists.txt.old 2016-01-02 12:56:31 -0700
++++ CMakeLists.txt 2016-10-03 11:24:24 -0600
+@@ -609,7 +609,7 @@
+ list(APPEND EXTRA_LIBS m)
+ endif()
+
+- check_library_exists(iconv iconv_open "" HAVE_LIBICONV)
++ #check_library_exists(iconv iconv_open "" HAVE_LIBICONV)
+ if(HAVE_LIBICONV)
+ list(APPEND EXTRA_LIBS iconv)
+ set(HAVE_ICONV 1)
+@@ -1455,7 +1455,7 @@
+ set(_INSTALL_LIBS "SDL2main")
+
+ if(SDL_SHARED)
+- add_library(SDL2 SHARED ${SOURCE_FILES})
++ add_library(SDL2 SHARED ${SOURCE_FILES} ${VERSION_SOURCES})
+ if(UNIX)
+ set_target_properties(SDL2 PROPERTIES
+ VERSION ${LT_VERSION}
diff --git a/build_files/build_environment/patches/semi.txt b/build_files/build_environment/patches/semi.txt
new file mode 100644
index 00000000000..092bc2b0412
--- /dev/null
+++ b/build_files/build_environment/patches/semi.txt
@@ -0,0 +1 @@
+;
diff --git a/build_files/build_environment/windows/build_deps.cmd b/build_files/build_environment/windows/build_deps.cmd
new file mode 100644
index 00000000000..a18eb085e4f
--- /dev/null
+++ b/build_files/build_environment/windows/build_deps.cmd
@@ -0,0 +1,122 @@
+@echo off
+if NOT "%1" == "" (
+ if "%1" == "2013" (
+ echo "Building for VS2013"
+ set VSVER=12.0
+ set VSVER_SHORT=12
+ set BuildDir=VS12
+ goto par2
+ )
+ if "%1" == "2015" (
+ echo "Building for VS2015"
+ set VSVER=14.0
+ set VSVER_SHORT=14
+ set BuildDir=VS14
+ goto par2
+ )
+)
+:usage
+
+Echo Usage build_deps 2013/2015 x64/x86
+goto exit
+:par2
+if NOT "%2" == "" (
+ if "%2" == "x86" (
+ echo "Building for x86"
+ set HARVESTROOT=Windows_vc
+ set ARCH=86
+ if "%1" == "2013" (
+ set CMAKE_BUILDER=Visual Studio 12 2013
+ )
+ if "%1" == "2015" (
+ set CMAKE_BUILDER=Visual Studio 14 2015
+ )
+ goto start
+ )
+ if "%2" == "x64" (
+ echo "Building for x64"
+ set HARVESTROOT=Win64_vc
+ set ARCH=64
+ if "%1" == "2013" (
+ set CMAKE_BUILDER=Visual Studio 12 2013 Win64
+ )
+ if "%1" == "2015" (
+ set CMAKE_BUILDER=Visual Studio 14 2015 Win64
+ )
+ goto start
+ )
+)
+goto usage
+
+:start
+setlocal ENABLEEXTENSIONS
+set CMAKE_DEBUG_OPTIONS=-DWITH_OPTIMIZED_DEBUG=On
+if "%3" == "debug" set CMAKE_DEBUG_OPTIONS=-DWITH_OPTIMIZED_DEBUG=Off
+
+set SOURCE_DIR=%~dp0\..
+set BUILD_DIR=%cd%\build
+set HARVEST_DIR=%BUILD_DIR%\output
+set STAGING=%BUILD_DIR%\S
+
+rem for python module build
+set MSSdk=1
+set DISTUTILS_USE_SDK=1
+rem for python externals source to be shared between the various archs and compilers
+mkdir %BUILD_DIR%\downloads\externals
+
+REM Detect MSVC Installation
+if DEFINED VisualStudioVersion goto msvc_detect_finally
+set VALUE_NAME=ProductDir
+REM Check 64 bits
+set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%VSVER%\Setup\VC"
+for /F "usebackq skip=2 tokens=1-2*" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) DO set MSVC_VC_DIR=%%C
+if DEFINED MSVC_VC_DIR goto msvc_detect_finally
+REM Check 32 bits
+set KEY_NAME="HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\%VSVER%\Setup\VC"
+for /F "usebackq skip=2 tokens=1-2*" %%A IN (`REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul`) DO set MSVC_VC_DIR=%%C
+if DEFINED MSVC_VC_DIR goto msvc_detect_finally
+:msvc_detect_finally
+if DEFINED MSVC_VC_DIR call "%MSVC_VC_DIR%\vcvarsall.bat"
+echo on
+
+REM Sanity Checks
+where /Q msbuild
+if %ERRORLEVEL% NEQ 0 (
+ echo Error: "MSBuild" command not in the PATH.
+ echo You must have MSVC installed and run this from the "Developer Command Prompt"
+ echo ^(available from Visual Studio's Start menu entry^), aborting!
+ goto EOF
+)
+where /Q cmake
+if %ERRORLEVEL% NEQ 0 (
+ echo Error: "CMake" command not in the PATH.
+ echo You must have CMake installed and added to your PATH, aborting!
+ goto EOF
+)
+
+set StatusFile=%BUILD_DIR%\%1_%2.log
+set path=%BUILD_DIR%\downloads\mingw\mingw64\msys\1.0\bin\;%BUILD_DIR%\downloads\nasm-2.12.01\;%path%
+mkdir %STAGING%\%BuildDir%%ARCH%R
+cd %Staging%\%BuildDir%%ARCH%R
+echo %DATE% %TIME% : Start > %StatusFile%
+cmake -G "%CMAKE_BUILDER%" %SOURCE_DIR% -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DBUILD_MODE=Release -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/
+echo %DATE% %TIME% : Release Configuration done >> %StatusFile%
+msbuild /m "ll.vcxproj" /p:Configuration=Release /fl /flp:logfile=BlenderDeps_llvm.log
+msbuild /m "BlenderDependencies.sln" /p:Configuration=Release /fl /flp:logfile=BlenderDeps.log
+echo %DATE% %TIME% : Release Build done >> %StatusFile%
+cmake --build . --target Harvest_Release_Results > Harvest_Release.txt
+echo %DATE% %TIME% : Release Harvest done >> %StatusFile%
+cd %BUILD_DIR%
+mkdir %STAGING%\%BuildDir%%ARCH%D
+cd %Staging%\%BuildDir%%ARCH%D
+cmake -G "%CMAKE_BUILDER%" %SOURCE_DIR% -DDOWNLOAD_DIR=%BUILD_DIR%/downloads -DCMAKE_BUILD_TYPE=Debug -DBUILD_MODE=Debug -DHARVEST_TARGET=%HARVEST_DIR%/%HARVESTROOT%%VSVER_SHORT%/ %CMAKE_DEBUG_OPTIONS%
+echo %DATE% %TIME% : Debug Configuration done >> %StatusFile%
+msbuild /m "ll.vcxproj" /p:Configuration=Debug /fl /flp:logfile=BlenderDeps_llvm.log
+msbuild /m "BlenderDependencies.sln" /p:Configuration=Debug /fl /flp:logfile=BlenderDeps.log
+echo %DATE% %TIME% : Debug Build done >> %StatusFile%
+cmake --build . --target Harvest_Debug_Results> Harvest_Debug.txt
+echo %DATE% %TIME% : Debug Harvest done >> %StatusFile%
+cd %BUILD_DIR%
+
+:exit
+Echo .
diff --git a/build_files/build_environment/windows/buildall.cmd b/build_files/build_environment/windows/buildall.cmd
new file mode 100644
index 00000000000..480be8cde44
--- /dev/null
+++ b/build_files/build_environment/windows/buildall.cmd
@@ -0,0 +1,10 @@
+title building 1_4 - x86_2013
+call build_deps 2013 x86
+title building 2_4 - x86_2015
+call build_deps 2015 x86
+title building 3_4 - x64_2013
+call build_deps 2013 x64
+title building 4_4 - x64_2015
+call build_deps 2015 x64
+title done!
+echo done! \ No newline at end of file
diff --git a/build_files/build_environment/windows/nuke.cmd b/build_files/build_environment/windows/nuke.cmd
new file mode 100644
index 00000000000..68dbc8d1487
--- /dev/null
+++ b/build_files/build_environment/windows/nuke.cmd
@@ -0,0 +1,52 @@
+@echo off
+if "%1"=="" goto EOF:
+set ROOT=%~dp0\..\..\..\..\build_windows\deps
+
+set CurPath=%ROOT%\s\vs1264D\debug\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1264D\build\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1264R\release\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1264R\build\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\output\win64_vc12\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+
+set CurPath=%ROOT%\s\vs1464D\debug\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1464D\build\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1464R\release\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1464R\build\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\output\win64_vc14\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+
+set CurPath=%ROOT%\s\vs1286D\debug\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1286D\build\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1286R\release\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1286R\build\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\output\windows_vc12\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+
+set CurPath=%ROOT%\s\vs1486D\debug\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1486D\build\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1486R\release\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\s\vs1486R\build\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+set CurPath=%ROOT%\output\windows_vc14\%1\
+if EXIST %CurPath%\nul ( echo removing "%CurPath%" && rd /s /q "%CurPath%" )
+
+
+:EOF
+
+
diff --git a/build_files/buildbot/config/blender_linux.cmake b/build_files/buildbot/config/blender_linux.cmake
index 56f18967300..4fc6496728c 100644
--- a/build_files/buildbot/config/blender_linux.cmake
+++ b/build_files/buildbot/config/blender_linux.cmake
@@ -70,11 +70,11 @@ set(FFMPEG_LIBRARIES
)
# SndFile libraries
-set(SNDFILE_LIBRARY "/usr/lib/libsndfile.a;/usr/lib/libFLAC.a" CACHE STRING "" FORCE)
+set(LIBSNDFILE_LIBRARY "/usr/lib/libsndfile.a;/usr/lib/libFLAC.a" CACHE STRING "" FORCE)
# OpenAL libraries
set(OPENAL_ROOT_DIR "/opt/lib/openal" CACHE STRING "" FORCE)
-set(OPENAL_INCLUDE_DIR "${OPENAL_ROOT_DIR}/include" CACHE STRING "" FORCE)
+set(OPENAL_INCLUDE_DIR "${OPENAL_ROOT_DIR}/include/AL" CACHE STRING "" FORCE)
set(OPENAL_LIBRARY
${OPENAL_ROOT_DIR}/lib/libopenal.a
${OPENAL_ROOT_DIR}/lib/libcommon.a
diff --git a/build_files/cmake/Modules/FindSndFile.cmake b/build_files/cmake/Modules/FindSndFile.cmake
index 1b685eacfbd..dd1f560e61f 100644
--- a/build_files/cmake/Modules/FindSndFile.cmake
+++ b/build_files/cmake/Modules/FindSndFile.cmake
@@ -1,15 +1,15 @@
# - Find SndFile library
# Find the native SndFile includes and library
# This module defines
-# SNDFILE_INCLUDE_DIRS, where to find sndfile.h, Set when
-# SNDFILE_INCLUDE_DIR is found.
-# SNDFILE_LIBRARIES, libraries to link against to use SndFile.
-# SNDFILE_ROOT_DIR, The base directory to search for SndFile.
+# LIBSNDFILE_INCLUDE_DIRS, where to find sndfile.h, Set when
+# LIBSNDFILE_INCLUDE_DIR is found.
+# LIBSNDFILE_LIBRARIES, libraries to link against to use SndFile.
+# LIBSNDFILE_ROOT_DIR, The base directory to search for SndFile.
# This can also be an environment variable.
-# SNDFILE_FOUND, If false, do not try to use SndFile.
+# LIBSNDFILE_FOUND, If false, do not try to use SndFile.
#
# also defined, but not for general use are
-# SNDFILE_LIBRARY, where to find the SndFile library.
+# LIBSNDFILE_LIBRARY, where to find the SndFile library.
#=============================================================================
# Copyright 2011 Blender Foundation.
@@ -22,27 +22,27 @@
# See the License for more information.
#=============================================================================
-# If SNDFILE_ROOT_DIR was defined in the environment, use it.
-IF(NOT SNDFILE_ROOT_DIR AND NOT $ENV{SNDFILE_ROOT_DIR} STREQUAL "")
- SET(SNDFILE_ROOT_DIR $ENV{SNDFILE_ROOT_DIR})
+# If LIBSNDFILE_ROOT_DIR was defined in the environment, use it.
+IF(NOT LIBSNDFILE_ROOT_DIR AND NOT $ENV{LIBSNDFILE_ROOT_DIR} STREQUAL "")
+ SET(LIBSNDFILE_ROOT_DIR $ENV{LIBSNDFILE_ROOT_DIR})
ENDIF()
SET(_sndfile_SEARCH_DIRS
- ${SNDFILE_ROOT_DIR}
+ ${LIBSNDFILE_ROOT_DIR}
/usr/local
/sw # Fink
/opt/local # DarwinPorts
/opt/csw # Blastwave
)
-FIND_PATH(SNDFILE_INCLUDE_DIR sndfile.h
+FIND_PATH(LIBSNDFILE_INCLUDE_DIR sndfile.h
HINTS
${_sndfile_SEARCH_DIRS}
PATH_SUFFIXES
include
)
-FIND_LIBRARY(SNDFILE_LIBRARY
+FIND_LIBRARY(LIBSNDFILE_LIBRARY
NAMES
sndfile
HINTS
@@ -51,18 +51,18 @@ FIND_LIBRARY(SNDFILE_LIBRARY
lib64 lib
)
-# handle the QUIETLY and REQUIRED arguments and set SNDFILE_FOUND to TRUE if
+# handle the QUIETLY and REQUIRED arguments and set LIBSNDFILE_FOUND to TRUE if
# all listed variables are TRUE
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SndFile DEFAULT_MSG
- SNDFILE_LIBRARY SNDFILE_INCLUDE_DIR)
+ LIBSNDFILE_LIBRARY LIBSNDFILE_INCLUDE_DIR)
-IF(SNDFILE_FOUND)
- SET(SNDFILE_LIBRARIES ${SNDFILE_LIBRARY})
- SET(SNDFILE_INCLUDE_DIRS ${SNDFILE_INCLUDE_DIR})
-ENDIF(SNDFILE_FOUND)
+IF(LIBSNDFILE_FOUND)
+ SET(LIBSNDFILE_LIBRARIES ${LIBSNDFILE_LIBRARY})
+ SET(LIBSNDFILE_INCLUDE_DIRS ${LIBSNDFILE_INCLUDE_DIR})
+ENDIF(LIBSNDFILE_FOUND)
MARK_AS_ADVANCED(
- SNDFILE_INCLUDE_DIR
- SNDFILE_LIBRARY
+ LIBSNDFILE_INCLUDE_DIR
+ LIBSNDFILE_LIBRARY
)
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 8e3956d06ef..6c377b069fa 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -318,7 +318,7 @@ function(SETUP_LIBDIRS)
link_directories(${JACK_LIBPATH})
endif()
if(WITH_CODEC_SNDFILE)
- link_directories(${SNDFILE_LIBPATH})
+ link_directories(${LIBSNDFILE_LIBPATH})
endif()
if(WITH_FFTW3)
link_directories(${FFTW3_LIBPATH})
@@ -398,7 +398,7 @@ function(setup_liblinks
target_link_libraries(${target} ${JACK_LIBRARIES})
endif()
if(WITH_CODEC_SNDFILE)
- target_link_libraries(${target} ${SNDFILE_LIBRARIES})
+ target_link_libraries(${target} ${LIBSNDFILE_LIBRARIES})
endif()
if(WITH_SDL AND NOT WITH_SDL_DYNLOAD)
target_link_libraries(${target} ${SDL_LIBRARY})
@@ -549,6 +549,12 @@ function(SETUP_BLENDER_SORTED_LIBS)
endif()
endif()
+ if(WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE)
+ list(APPEND BLENDER_LINK_LIBS
+ audaspace
+ audaspace-py)
+ endif()
+
# Sort libraries
set(BLENDER_SORTED_LIBS
bf_windowmanager
@@ -600,6 +606,7 @@ function(SETUP_BLENDER_SORTED_LIBS)
bf_python
bf_python_ext
bf_python_mathutils
+ bf_python_gawain
bf_python_bmesh
bf_freestyle
bf_ikplugin
@@ -655,6 +662,8 @@ function(SETUP_BLENDER_SORTED_LIBS)
bf_blenfont
bf_blentranslation
bf_intern_audaspace
+ audaspace
+ audaspace-py
bf_intern_mikktspace
bf_intern_dualcon
bf_intern_cycles
@@ -1510,6 +1519,7 @@ function(find_python_package
NAMES
${package}
HINTS
+ "${PYTHON_LIBPATH}/"
"${PYTHON_LIBPATH}/python${PYTHON_VERSION}/"
"${PYTHON_LIBPATH}/python${_PY_VER_MAJOR}/"
PATH_SUFFIXES
diff --git a/build_files/cmake/platform/platform_apple.cmake b/build_files/cmake/platform/platform_apple.cmake
index 5336024b75c..e26466cc6d5 100644
--- a/build_files/cmake/platform/platform_apple.cmake
+++ b/build_files/cmake/platform/platform_apple.cmake
@@ -46,7 +46,7 @@ if(WITH_OPENAL)
find_package(OpenAL)
if(OPENAL_FOUND)
set(WITH_OPENAL ON)
- set(OPENAL_INCLUDE_DIR "${LIBDIR}/openal/include")
+ set(OPENAL_INCLUDE_DIR "${LIBDIR}/openal/include/AL")
else()
set(WITH_OPENAL OFF)
endif()
@@ -82,10 +82,10 @@ if(WITH_JACK)
endif()
if(WITH_CODEC_SNDFILE)
- set(SNDFILE ${LIBDIR}/sndfile)
- set(SNDFILE_INCLUDE_DIRS ${SNDFILE}/include)
- set(SNDFILE_LIBRARIES sndfile FLAC ogg vorbis vorbisenc)
- set(SNDFILE_LIBPATH ${SNDFILE}/lib ${LIBDIR}/ffmpeg/lib) # TODO, deprecate
+ set(LIBSNDFILE ${LIBDIR}/sndfile)
+ set(LIBSNDFILE_INCLUDE_DIRS ${LIBSNDFILE}/include)
+ set(LIBSNDFILE_LIBRARIES sndfile FLAC ogg vorbis vorbisenc)
+ set(LIBSNDFILE_LIBPATH ${LIBSNDFILE}/lib ${LIBDIR}/ffmpeg/lib) # TODO, deprecate
endif()
if(WITH_PYTHON)
@@ -95,7 +95,11 @@ if(WITH_PYTHON)
# normally cached but not since we include them with blender
set(PYTHON_INCLUDE_DIR "${LIBDIR}/python/include/python${PYTHON_VERSION}m")
set(PYTHON_EXECUTABLE "${LIBDIR}/python/bin/python${PYTHON_VERSION}m")
- set(PYTHON_LIBRARY python${PYTHON_VERSION}m)
+ if(WITH_CXX11)
+ set(PYTHON_LIBRARY ${LIBDIR}/python/lib/libpython${PYTHON_VERSION}m.a)
+ else()
+ set(PYTHON_LIBRARY python${PYTHON_VERSION}m)
+ endif()
set(PYTHON_LIBPATH "${LIBDIR}/python/lib/python${PYTHON_VERSION}")
# set(PYTHON_LINKFLAGS "-u _PyMac_Error") # won't build with this enabled
else()
@@ -115,6 +119,9 @@ if(WITH_PYTHON)
set(PYTHON_INCLUDE_DIRS "${PYTHON_INCLUDE_DIR}")
set(PYTHON_LIBRARIES "${PYTHON_LIBRARY}")
+ # needed for Audaspace, numpy is installed into python site-packages
+ set(NUMPY_INCLUDE_DIRS "${PYTHON_LIBPATH}/site-packages/numpy/core/include")
+
if(NOT EXISTS "${PYTHON_EXECUTABLE}")
message(FATAL_ERROR "Python executable missing: ${PYTHON_EXECUTABLE}")
endif()
diff --git a/build_files/cmake/platform/platform_unix.cmake b/build_files/cmake/platform/platform_unix.cmake
index 62e0caa7c43..d5875e9cd7f 100644
--- a/build_files/cmake/platform/platform_unix.cmake
+++ b/build_files/cmake/platform/platform_unix.cmake
@@ -135,7 +135,7 @@ endif()
# Codecs
if(WITH_CODEC_SNDFILE)
find_package_wrapper(SndFile)
- if(NOT SNDFILE_FOUND)
+ if(NOT LIBSNDFILE_FOUND)
set(WITH_CODEC_SNDFILE OFF)
endif()
endif()
diff --git a/build_files/cmake/platform/platform_win32.cmake b/build_files/cmake/platform/platform_win32.cmake
index 2f5d41dac32..4d2342e490e 100644
--- a/build_files/cmake/platform/platform_win32.cmake
+++ b/build_files/cmake/platform/platform_win32.cmake
@@ -36,7 +36,7 @@ set(WINTAB_INC ${LIBDIR}/wintab/include)
if(WITH_OPENAL)
set(OPENAL ${LIBDIR}/openal)
set(OPENALDIR ${LIBDIR}/openal)
- set(OPENAL_INCLUDE_DIR ${OPENAL}/include)
+ set(OPENAL_INCLUDE_DIR ${OPENAL}/include/AL)
if(MSVC)
set(OPENAL_LIBRARY openal32)
else()
@@ -46,10 +46,10 @@ if(WITH_OPENAL)
endif()
if(WITH_CODEC_SNDFILE)
- set(SNDFILE ${LIBDIR}/sndfile)
- set(SNDFILE_INCLUDE_DIRS ${SNDFILE}/include)
- set(SNDFILE_LIBRARIES libsndfile-1)
- set(SNDFILE_LIBPATH ${SNDFILE}/lib) # TODO, deprecate
+ set(LIBSNDFILE ${LIBDIR}/sndfile)
+ set(LIBSNDFILE_INCLUDE_DIRS ${LIBSNDFILE}/include)
+ set(LIBSNDFILE_LIBRARIES libsndfile-1)
+ set(LIBSNDFILE_LIBPATH ${LIBSNDFILE}/lib) # TODO, deprecate
endif()
if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD)
diff --git a/build_files/cmake/platform/platform_win32_msvc.cmake b/build_files/cmake/platform/platform_win32_msvc.cmake
index 3b417f79cbe..1b596e3d932 100644
--- a/build_files/cmake/platform/platform_win32_msvc.cmake
+++ b/build_files/cmake/platform/platform_win32_msvc.cmake
@@ -134,7 +134,10 @@ if(NOT DEFINED LIBDIR)
message(STATUS "32 bit compiler detected.")
set(LIBDIR_BASE "windows")
endif()
- if(MSVC_VERSION EQUAL 1910)
+ if(MSVC_VERSION EQUAL 1911)
+ message(STATUS "Visual Studio 2017 detected.")
+ set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc14)
+ elseif(MSVC_VERSION EQUAL 1910)
message(STATUS "Visual Studio 2017 detected.")
set(LIBDIR ${CMAKE_SOURCE_DIR}/../lib/${LIBDIR_BASE}_vc14)
elseif(MSVC_VERSION EQUAL 1900)
diff --git a/extern/CMakeLists.txt b/extern/CMakeLists.txt
index f7e98525b8b..0e4853ee458 100644
--- a/extern/CMakeLists.txt
+++ b/extern/CMakeLists.txt
@@ -113,3 +113,8 @@ endif()
if(WITH_SDL AND WITH_SDL_DYNLOAD)
add_subdirectory(sdlew)
endif()
+
+if(WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE)
+ set(AUDASPACE_CMAKE_CFG ${CMAKE_CURRENT_SOURCE_DIR}/audaspace/blender_config.cmake)
+ add_subdirectory(audaspace)
+endif()
diff --git a/extern/audaspace/AUTHORS b/extern/audaspace/AUTHORS
new file mode 100644
index 00000000000..08007912102
--- /dev/null
+++ b/extern/audaspace/AUTHORS
@@ -0,0 +1,16 @@
+Main author: Jörg Müller <nexyon@gmail.com>
+
+Minor improvements have been done while audaspace was an internal part of Blender by
+
+- Campbell Barton (bug fixes and cleanup)
+- Brecht Van Lommel (bug fixes and cleanup)
+- Sergey Sharybin (bug fixes and cleanup)
+- Nathan Letwory (bug fixes and cleanup)
+- Peter Schlaile (ffmpeg)
+- Jens Verwiebe (jack on Apple)
+
+The first three of them were employed by the Blender Foundation during that time.
+
+Some features (random sounds, dynamic music, playback manager, convolution and HRTFs support) were added as part of the VALS (Virtual Alliances for Learning Society) project by
+
+- Juan Francisco Crespo Galán <dethon_5@outlook.com>
diff --git a/extern/audaspace/CHANGES b/extern/audaspace/CHANGES
new file mode 100644
index 00000000000..bd5acaa88fb
--- /dev/null
+++ b/extern/audaspace/CHANGES
@@ -0,0 +1,115 @@
+Audaspace 1.3
+=============
+
+- New features:
+ - linear interpolation for volume changes in the software mixer
+ - dynamic Loading for JACK
+- Bug fixes:
+ - renamed Jack to JACK
+ - C API was not working
+ - filter python API parameter check
+ - finding ffmpeg with pkgconfig
+
+64884a7 Windows fixes.
+53ba3e6 Implemented JACK dynamic loading.
+5ee0ee1 Continues last commit.
+c24b384 Trying to fix travis-ci python versioning once and for all (at least for python3).
+1fbf3bf Rename Jack => JACK where possible.
+6e4b31f Implemented linear interpolation for volume changes in the software mixer.
+817043c Fixing C API not working.
+c384daf Maybe travis-ci works now.
+aa7ddd7 Fix (hopefully) for previous commit.
+57c5dd7 Configure MACOSX_DEPLOYMENT_TARGET for travis-ci.
+7ae6ff9 Fix travis-ci python path.
+552fea4 Added posibillity to use math constants on MinGW
+c18ed59 Bugfix: incorrect parameter check in python API.
+6f048c3 CMake: fix finding ffmpeg with pkgconfig.
+
+Audaspace 1.2
+=============
+
+- New features:
+ - sound list
+ - random sounds
+ - dynamic music playing
+ - playback manager
+ - convolution/reverbation
+ - multi-threading
+ - binaural audio
+- API changes:
+ - changing default sample rate from 44.1 to 48 kHz
+- Bug fixes:
+ - several standard library fixes.
+- Bindings API:
+ - mixdown C API refactored
+- CMake/Building:
+ - assuring numpy is installed
+ - building the Python module on Mac OS X with CMake
+
+a6b6e70 Changing default sample rate from 44.1 to 48 kHz.
+20f0164 Bugfix: CMake custom command for python module on OS X.
+98679a2 Bugfix: using standard library (s)rand.
+5ab4fe7 Bugfix: first step in fixing the vector of array problem.
+e83f01d FFTW: trying to use complex to circumvent vector of array problem.
+093ebc0 Bugfix: abs -> std::fabs.
+328d7cc Bugfix: standard library include and call fixes.
+f78e330 Bugfix: using correct includes.
+64d7825 Behavior change: C API Mixdown
+749896b Merge pull request #3 from DethonUSAL/master
+6e9491c CMake: finding NumPy.
+
+Audaspace 1.1
+=============
+
+- Bug fixes:
+ - pkgconfig uses cmake configured library directory
+ - FFMPEG file writing crashed, also corrected pts for encoding
+ - silenced Doxygen warnings about undefined defines
+- C++ API:
+ - ResampleReader uses specs instead of sample rate
+- Bindings API:
+ - writing sounds to files
+ - reading sound data, specs and length
+ - resampling sounds
+- CMake/Building:
+ - first steps towards building for Mac
+ - windows builds copy dlls automatically
+- Python module:
+ - using distutils instead of setuptools
+ - added numpy as dependency
+- Documentation:
+ - added windows building and plugin documentation
+ - disabled html timestamps in doxygen
+ - updated sphinx template
+ - build binding documentation without installing the python module
+
+Detailed list of changes:
+
+326a300 Documentation: windows, dll copying now done automatically.
+54cac4f Windows: install dlls.
+65c2d78 Bindings: Sound length and specs properties.
+c38da70 Bindings API: adding resampling.
+374822f Documentation: Added windows and plugin documentation.
+a9dc5b9 Python module: add numpy as dependency.
+c933a02 C API: implement new API based on the python API.
+ac54c52 Python API: silence numpy warnings.
+c9491bb Python API: checking for a positive sample rate.
+4eb1fa8 Python API: reorder functions.
+ec7c00b Sphinx update and fixes.
+e16d979 FFMPEG: correct pts during encoding.
+7ab3935 Documentation: git path fix.
+28d77bb Python: use distutils directly instead of setuptools.
+1f43284 Silence doxygen warning about undefined defines.
+0d52458 CMake: improvements and fixes for building on Mac.
+37daedf FFMPEG: bugfixes for file writing.
+780ca2a ResampleReader API change
+4d9863d Python API: Optimization for cached sounds' data access.
+ea04fee Python API: read sound data and create sound buffers as well as getting the specs of a sound.
+335b293 Python sound writing API.
+36a7252 Pkgconfig: use cmake configured library directory.
+5503908 Doxygen: disable html timestamps.
+
+Initial Release of Audaspace 1.0
+================================
+
+Audaspace has been the internal audio library of blender since blender 2.5. It is now released as a standalone library to be used in other projects as well.
diff --git a/extern/audaspace/CMakeLists.txt b/extern/audaspace/CMakeLists.txt
new file mode 100644
index 00000000000..ad856fd8743
--- /dev/null
+++ b/extern/audaspace/CMakeLists.txt
@@ -0,0 +1,983 @@
+################################################################################
+# Copyright 2009-2016 Jörg Müller
+#
+# 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.
+################################################################################
+
+cmake_minimum_required(VERSION 3.1)
+include(CMakeDependentOption)
+
+if(POLICY CMP0054)
+ cmake_policy(SET CMP0054 NEW)
+endif()
+
+project(audaspace)
+
+set(AUDASPACE_VERSION 1.3)
+set(AUDASPACE_LONG_VERSION ${AUDASPACE_VERSION}.0)
+
+if(DEFINED AUDASPACE_CMAKE_CFG)
+ include(${AUDASPACE_CMAKE_CFG})
+endif()
+
+if(NOT DEFINED AUDASPACE_STANDALONE)
+ set(AUDASPACE_STANDALONE TRUE)
+endif()
+
+# sources
+
+set(SRC
+ src/devices/DefaultSynchronizer.cpp
+ src/devices/DeviceManager.cpp
+ src/devices/NULLDevice.cpp
+ src/devices/ReadDevice.cpp
+ src/devices/SoftwareDevice.cpp
+ src/Exception.cpp
+ src/file/File.cpp
+ src/file/FileManager.cpp
+ src/file/FileWriter.cpp
+ src/fx/Accumulator.cpp
+ src/fx/ADSR.cpp
+ src/fx/ADSRReader.cpp
+ src/fx/BaseIIRFilterReader.cpp
+ src/fx/ButterworthCalculator.cpp
+ src/fx/Butterworth.cpp
+ src/fx/CallbackIIRFilterReader.cpp
+ src/fx/Delay.cpp
+ src/fx/DelayReader.cpp
+ src/fx/DynamicIIRFilter.cpp
+ src/fx/DynamicIIRFilterReader.cpp
+ src/fx/DynamicMusic.cpp
+ src/fx/Effect.cpp
+ src/fx/EffectReader.cpp
+ src/fx/Envelope.cpp
+ src/fx/Fader.cpp
+ src/fx/FaderReader.cpp
+ src/fx/HighpassCalculator.cpp
+ src/fx/Highpass.cpp
+ src/fx/IIRFilter.cpp
+ src/fx/IIRFilterReader.cpp
+ src/fx/Limiter.cpp
+ src/fx/LimiterReader.cpp
+ src/fx/Loop.cpp
+ src/fx/LoopReader.cpp
+ src/fx/LowpassCalculator.cpp
+ src/fx/Lowpass.cpp
+ src/fx/MutableReader.cpp
+ src/fx/MutableSound.cpp
+ src/fx/Pitch.cpp
+ src/fx/PitchReader.cpp
+ src/fx/PlaybackManager.cpp
+ src/fx/PlaybackCategory.cpp
+ src/fx/Reverse.cpp
+ src/fx/ReverseReader.cpp
+ src/fx/SoundList.cpp
+ src/fx/Source.cpp
+ src/fx/Sum.cpp
+ src/fx/Threshold.cpp
+ src/fx/Volume.cpp
+ src/fx/VolumeReader.cpp
+ src/fx/VolumeSound.cpp
+ src/fx/VolumeStorage.cpp
+ src/generator/Sawtooth.cpp
+ src/generator/SawtoothReader.cpp
+ src/generator/Silence.cpp
+ src/generator/SilenceReader.cpp
+ src/generator/Sine.cpp
+ src/generator/SineReader.cpp
+ src/generator/Square.cpp
+ src/generator/SquareReader.cpp
+ src/generator/Triangle.cpp
+ src/generator/TriangleReader.cpp
+ src/respec/ChannelMapper.cpp
+ src/respec/ChannelMapperReader.cpp
+ src/respec/Converter.cpp
+ src/respec/ConverterFunctions.cpp
+ src/respec/ConverterReader.cpp
+ src/respec/JOSResample.cpp
+ src/respec/JOSResampleReaderCoeff.cpp
+ src/respec/JOSResampleReader.cpp
+ src/respec/LinearResample.cpp
+ src/respec/LinearResampleReader.cpp
+ src/respec/Mixer.cpp
+ src/respec/ResampleReader.cpp
+ src/respec/SpecsChanger.cpp
+ src/sequence/AnimateableProperty.cpp
+ src/sequence/Double.cpp
+ src/sequence/DoubleReader.cpp
+ src/sequence/PingPong.cpp
+ src/sequence/Sequence.cpp
+ src/sequence/SequenceData.cpp
+ src/sequence/SequenceEntry.cpp
+ src/sequence/SequenceHandle.cpp
+ src/sequence/SequenceReader.cpp
+ src/sequence/Superpose.cpp
+ src/sequence/SuperposeReader.cpp
+ src/util/Barrier.cpp
+ src/util/Buffer.cpp
+ src/util/BufferReader.cpp
+ src/util/StreamBuffer.cpp
+ src/util/ThreadPool.cpp
+)
+
+set(PRIVATE_HDR
+ src/sequence/SequenceHandle.h
+)
+
+set(PUBLIC_HDR
+ include/devices/DefaultSynchronizer.h
+ include/devices/DeviceManager.h
+ include/devices/I3DDevice.h
+ include/devices/I3DHandle.h
+ include/devices/IDeviceFactory.h
+ include/devices/IDevice.h
+ include/devices/IHandle.h
+ include/devices/ISynchronizer.h
+ include/devices/NULLDevice.h
+ include/devices/ReadDevice.h
+ include/devices/SoftwareDevice.h
+ include/Exception.h
+ include/file/File.h
+ include/file/FileManager.h
+ include/file/FileWriter.h
+ include/file/IFileInput.h
+ include/file/IFileOutput.h
+ include/file/IWriter.h
+ include/fx/Accumulator.h
+ include/fx/ADSR.h
+ include/fx/ADSRReader.h
+ include/fx/BaseIIRFilterReader.h
+ include/fx/ButterworthCalculator.h
+ include/fx/Butterworth.h
+ include/fx/CallbackIIRFilterReader.h
+ include/fx/Delay.h
+ include/fx/DelayReader.h
+ include/fx/DynamicIIRFilter.h
+ include/fx/DynamicIIRFilterReader.h
+ include/fx/DynamicMusic.h
+ include/fx/Effect.h
+ include/fx/EffectReader.h
+ include/fx/Envelope.h
+ include/fx/Fader.h
+ include/fx/FaderReader.h
+ include/fx/HighpassCalculator.h
+ include/fx/Highpass.h
+ include/fx/IDynamicIIRFilterCalculator.h
+ include/fx/IIRFilter.h
+ include/fx/IIRFilterReader.h
+ include/fx/Limiter.h
+ include/fx/LimiterReader.h
+ include/fx/Loop.h
+ include/fx/LoopReader.h
+ include/fx/LowpassCalculator.h
+ include/fx/Lowpass.h
+ include/fx/MutableReader.h
+ include/fx/MutableSound.h
+ include/fx/Pitch.h
+ include/fx/PitchReader.h
+ include/fx/PlaybackManager.h
+ include/fx/PlaybackCategory.h
+ include/fx/Reverse.h
+ include/fx/ReverseReader.h
+ include/fx/SoundList.h
+ include/fx/Source.h
+ include/fx/Sum.h
+ include/fx/Threshold.h
+ include/fx/Volume.h
+ include/fx/VolumeReader.h
+ include/fx/VolumeSound.h
+ include/fx/VolumeStorage.h
+ include/generator/Sawtooth.h
+ include/generator/SawtoothReader.h
+ include/generator/Silence.h
+ include/generator/SilenceReader.h
+ include/generator/Sine.h
+ include/generator/SineReader.h
+ include/generator/Square.h
+ include/generator/SquareReader.h
+ include/generator/Triangle.h
+ include/generator/TriangleReader.h
+ include/IReader.h
+ include/ISound.h
+ include/plugin/PluginManager.h
+ include/respec/ChannelMapper.h
+ include/respec/ChannelMapperReader.h
+ include/respec/ConverterFunctions.h
+ include/respec/Converter.h
+ include/respec/ConverterReader.h
+ include/respec/JOSResample.h
+ include/respec/JOSResampleReader.h
+ include/respec/LinearResample.h
+ include/respec/LinearResampleReader.h
+ include/respec/Mixer.h
+ include/respec/ResampleReader.h
+ include/respec/Specification.h
+ include/respec/SpecsChanger.h
+ include/sequence/AnimateableProperty.h
+ include/sequence/Double.h
+ include/sequence/DoubleReader.h
+ include/sequence/PingPong.h
+ include/sequence/SequenceData.h
+ include/sequence/SequenceEntry.h
+ include/sequence/Sequence.h
+ include/sequence/SequenceReader.h
+ include/sequence/Superpose.h
+ include/sequence/SuperposeReader.h
+ include/util/Barrier.h
+ include/util/Buffer.h
+ include/util/BufferReader.h
+ include/util/ILockable.h
+ include/util/Math3D.h
+ include/util/StreamBuffer.h
+ include/util/ThreadPool.h
+)
+
+set(HDR ${PRIVATE_HDR} ${PUBLIC_HDR})
+
+set(INCLUDE ${CMAKE_CURRENT_BINARY_DIR} include)
+
+if(WIN32)
+ set(LIBRARIES)
+ if(AUDASPACE_STANDALONE)
+ set(DLLS)
+ set(LIBRARY_PATH "../lib" CACHE PATH "Path which contains the libraries.")
+ file(GLOB LIBRARY_DIRS ${LIBRARY_PATH}/*)
+ list(APPEND CMAKE_PREFIX_PATH ${LIBRARY_DIRS})
+ endif()
+else()
+ set(LIBRARIES ${CMAKE_DL_LIBS} -lpthread)
+endif()
+
+set(STATIC_PLUGINS "")
+
+# dependencies
+
+if(AUDASPACE_STANDALONE)
+ set(PACKAGE_OPTION QUIET)
+ list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
+
+ option(BUILD_DEMOS "Build and install demos" TRUE)
+
+ option(SHARED_LIBRARY "Build Shared Library" TRUE)
+
+ option(WITH_C "Build C Module" TRUE)
+ option(WITH_DOCS "Build C++ HTML Documentation with Doxygen" TRUE)
+ option(WITH_FFMPEG "Build With FFMPEG" TRUE)
+ option(WITH_FFTW "Build With FFTW" TRUE)
+ option(WITH_JACK "Build With Plugin" TRUE)
+ option(WITH_LIBSNDFILE "Build With LibSndFile" TRUE)
+ option(WITH_OPENAL "Build With OpenAL" TRUE)
+ option(WITH_PYTHON "Build With Python Library" TRUE)
+ option(WITH_SDL "Build With SDL" TRUE)
+ option(WITH_STRICT_DEPENDENCIES "Error and abort instead of warning if a library is not found." FALSE)
+
+ if(WITH_STRICT_DEPENDENCIES)
+ set(PACKAGE_OPTION REQUIRED)
+ endif()
+endif()
+
+if(WIN32)
+ set(DEFAULT_PLUGIN_PATH "." CACHE STRING "Default plugin installation and loading path.")
+ set(DOCUMENTATION_INSTALL_PATH "doc" CACHE PATH "Path where the documentation is installed.")
+else()
+ set(DEFAULT_PLUGIN_PATH "${CMAKE_INSTALL_PREFIX}/share/audaspace/plugins" CACHE STRING "Default plugin installation and loading path.")
+ set(DOCUMENTATION_INSTALL_PATH "share/doc/audaspace" CACHE PATH "Path where the documentation is installed.")
+endif()
+
+if(AUDASPACE_STANDALONE)
+ cmake_dependent_option(SEPARATE_C "Build C Binding as separate library" TRUE "WITH_C" FALSE)
+ cmake_dependent_option(PLUGIN_FFMPEG "Build FFMPEG Plugin" TRUE "WITH_FFMPEG;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(PLUGIN_JACK "Build JACK Plugin" TRUE "WITH_JACK;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(PLUGIN_LIBSNDFILE "Build LibSndFile Plugin" TRUE "WITH_LIBSNDFILE;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(PLUGIN_OPENAL "Build OpenAL Plugin" TRUE "WITH_OPENAL;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(PLUGIN_SDL "Build SDL Plugin" TRUE "WITH_SDL;SHARED_LIBRARY" FALSE)
+ cmake_dependent_option(WITH_PYTHON_MODULE "Build Python Module" TRUE "WITH_PYTHON" FALSE)
+ cmake_dependent_option(USE_SDL2 "Use SDL2 instead of 1 if available" TRUE "WITH_SDL" FALSE)
+ cmake_dependent_option(DYNLOAD_JACK "Dynamically load JACK" FALSE "WITH_JACK" FALSE)
+ cmake_dependent_option(WITH_BINDING_DOCS "Build C/Python HTML Documentation with Sphinx" TRUE "WITH_PYTHON_MODULE" FALSE)
+endif()
+
+# compiler options
+
+set(CMAKE_CXX_STANDARD 11)
+
+if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
+ list(APPEND CMAKE_C_COMPILER_FLAGS "-fvisibility=hidden")
+ list(APPEND CMAKE_CXX_COMPILER_FLAGS "-fvisibility=hidden")
+endif()
+
+if(MSVC)
+ if(AUDASPACE_STANDALONE)
+ list(APPEND CMAKE_C_FLAGS_DEBUG "/Zi /Od")
+ list(APPEND CMAKE_CXX_FLAGS_DEBUG "/Zi /Od")
+ list(APPEND CMAKE_SHARED_LINKER_FLAGS_DEBUG "/DEBUG")
+ list(APPEND CMAKE_STATIC_LINKER_FLAGS_DEBUG "/DEBUG")
+ list(APPEND CMAKE_EXE_LINKER_FLAGS_DEBUG "/DEBUG")
+ endif()
+ add_definitions(
+ /D_USE_MATH_DEFINES
+ /EHsc
+ /DNOMINMAX
+ /D_STDINT_H
+ )
+ if(SHARED_LIBRARY)
+ include(GenerateExportHeader)
+ endif()
+endif()
+
+if(APPLE AND NOT CMAKE_OSX_DEPLOYMENT_TARGET)
+ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9" CACHE STRING "" FORCE)
+endif()
+
+# platform specific options
+
+if(MSYS OR MINGW)
+ add_definitions(-D_USE_MATH_DEFINES)
+endif()
+
+# C
+if(WITH_C)
+ set(C_SRC
+ bindings/C/AUD_ThreadPool.cpp
+ bindings/C/AUD_Source.cpp
+ bindings/C/AUD_Device.cpp
+ bindings/C/AUD_DynamicMusic.cpp
+ bindings/C/AUD_Handle.cpp
+ bindings/C/AUD_PlaybackManager.cpp
+ bindings/C/AUD_Sequence.cpp
+ bindings/C/AUD_Sound.cpp
+ bindings/C/AUD_Special.cpp
+ )
+ set(C_HDR
+ bindings/C/AUD_ThreadPool.h
+ bindings/C/AUD_Source.h
+ bindings/C/AUD_Device.h
+ bindings/C/AUD_DynamicMusic.h
+ bindings/C/AUD_Handle.h
+ bindings/C/AUD_PlaybackManager.h
+ bindings/C/AUD_Sequence.h
+ bindings/C/AUD_Sound.h
+ bindings/C/AUD_Special.h
+ bindings/C/AUD_Types.h
+ )
+
+if(WITH_FFTW)
+ list(APPEND C_SRC
+ bindings/C/AUD_HRTF.cpp
+ bindings/C/AUD_ImpulseResponse.cpp
+ )
+
+ list(APPEND C_HDR
+ bindings/C/AUD_HRTF.h
+ bindings/C/AUD_ImpulseResponse.h
+ )
+ endif()
+
+ if(NOT SEPARATE_C)
+ list(APPEND SRC ${C_SRC})
+ list(APPEND HDR ${C_HDR})
+ else()
+ set(AUDASPACE_C_LIBRARY -laudaspace-c)
+ endif()
+endif()
+
+# FFMPEG
+if(WITH_FFMPEG)
+ if(AUDASPACE_STANDALONE)
+ find_package(FFMPEG ${PACKAGE_OPTION})
+ endif()
+
+ if(FFMPEG_FOUND)
+ set(FFMPEG_SRC
+ plugins/ffmpeg/FFMPEG.cpp
+ plugins/ffmpeg/FFMPEGReader.cpp
+ plugins/ffmpeg/FFMPEGWriter.cpp
+ )
+ set(FFMPEG_HDR
+ plugins/ffmpeg/FFMPEG.h
+ plugins/ffmpeg/FFMPEGReader.h
+ plugins/ffmpeg/FFMPEGWriter.h
+ )
+
+ if(NOT PLUGIN_FFMPEG)
+ list(APPEND INCLUDE ${FFMPEG_INCLUDE_DIRS})
+ list(APPEND LIBRARIES ${FFMPEG_LIBRARIES})
+ list(APPEND SRC ${FFMPEG_SRC})
+ list(APPEND HDR ${FFMPEG_HDR})
+ list(APPEND STATIC_PLUGINS FFMPEG)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB FFMPEG_DLLS ${LIBRARY_PATH}/ffmpeg/bin/*.dll)
+ list(APPEND DLLS ${FFMPEG_DLLS})
+ endif()
+ else()
+ set(WITH_FFMPEG FALSE CACHE BOOL "Build With FFMPEG" FORCE)
+ message(WARNING "FFMPEG not found, plugin will not be built.")
+ endif()
+endif()
+
+# FFTW
+if(WITH_FFTW)
+ if(AUDASPACE_STANDALONE)
+ find_package(FFTW ${PACKAGE_OPTION})
+ endif()
+
+ if(FFTW_FOUND)
+ set(FFTW_SRC
+ src/fx/BinauralSound.cpp
+ src/fx/BinauralReader.cpp
+ src/fx/Convolver.cpp
+ src/fx/ConvolverReader.cpp
+ src/fx/ConvolverSound.cpp
+ src/fx/FFTConvolver.cpp
+ src/fx/HRTF.cpp
+ src/fx/ImpulseResponse.cpp
+ src/util/FFTPlan.cpp
+ )
+ set(FFTW_HDR
+ include/fx/BinauralSound.h
+ include/fx/BinauralReader.h
+ include/fx/Convolver.h
+ include/fx/ConvolverReader.h
+ include/fx/ConvolverSound.h
+ include/fx/FFTConvolver.h
+ include/fx/HRTF.h
+ include/fx/HRTFLoader.h
+ include/fx/ImpulseResponse.h
+ include/util/FFTPlan.h
+ )
+
+ add_definitions(-DWITH_CONVOLUTION)
+
+ list(APPEND INCLUDE ${FFTW_INCLUDE_DIR})
+ list(APPEND LIBRARIES ${FFTW_LIBRARY})
+
+ list(APPEND SRC ${FFTW_SRC})
+ list(APPEND HDR ${FFTW_HDR})
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB FFTW_DLLS ${LIBRARY_PATH}/fftw/bin/*.dll)
+ list(APPEND DLLS ${FFTW_DLLS})
+ endif()
+ else()
+ set(WITH_FFTW FALSE CACHE BOOL "Build With FFTW" FORCE)
+ message(WARNING "FFTW not found, convolution functionality will not be built.")
+ endif()
+endif()
+
+# JACK
+if(WITH_JACK)
+ if(AUDASPACE_STANDALONE)
+ find_package(Jack ${PACKAGE_OPTION})
+ endif()
+
+ if(JACK_FOUND)
+ set(JACK_SRC
+ plugins/jack/JackDevice.cpp
+ plugins/jack/JackSynchronizer.cpp
+ plugins/jack/JackLibrary.cpp
+ )
+ set(JACK_HDR
+ plugins/jack/JackDevice.h
+ plugins/jack/JackSynchronizer.h
+ plugins/jack/JackLibrary.h
+ plugins/jack/JackSymbols.h
+ )
+
+ if(DYNLOAD_JACK)
+ add_definitions(-DDYNLOAD_JACK)
+ endif()
+
+ if(NOT PLUGIN_JACK)
+ list(APPEND INCLUDE ${JACK_INCLUDE_DIRS})
+ if(NOT DYNLOAD_JACK)
+ list(APPEND LIBRARIES ${JACK_LIBRARIES})
+ endif()
+ list(APPEND SRC ${JACK_SRC})
+ list(APPEND HDR ${JACK_HDR})
+ list(APPEND STATIC_PLUGINS JackDevice)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB JACK_DLLS ${LIBRARY_PATH}/jack/bin/*.dll)
+ list(APPEND DLLS ${JACK_DLLS})
+ endif()
+ else()
+ set(WITH_JACK FALSE CACHE BOOL "Build With JACK" FORCE)
+ message(WARNING "JACK not found, plugin will not be built.")
+ endif()
+endif()
+
+# LibSndFile
+if(WITH_LIBSNDFILE)
+ if(AUDASPACE_STANDALONE)
+ find_package(LibSndFile ${PACKAGE_OPTION})
+ endif()
+
+ if(LIBSNDFILE_FOUND)
+ set(LIBSNDFILE_SRC
+ plugins/libsndfile/SndFile.cpp
+ plugins/libsndfile/SndFileReader.cpp
+ plugins/libsndfile/SndFileWriter.cpp
+ )
+ set(LIBSNDFILE_HDR
+ plugins/libsndfile/SndFile.h
+ plugins/libsndfile/SndFileReader.h
+ plugins/libsndfile/SndFileWriter.h
+ )
+
+ if(NOT PLUGIN_LIBSNDFILE)
+ list(APPEND INCLUDE ${LIBSNDFILE_INCLUDE_DIRS})
+ list(APPEND LIBRARIES ${LIBSNDFILE_LIBRARIES})
+ list(APPEND SRC ${LIBSNDFILE_SRC})
+ list(APPEND HDR ${LIBSNDFILE_HDR})
+ list(APPEND STATIC_PLUGINS SndFile)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB LIBSNDFILE_DLLS ${LIBRARY_PATH}/libsndfile/bin/*.dll)
+ list(APPEND DLLS ${LIBSNDFILE_DLLS})
+ endif()
+ else()
+ set(WITH_LIBSNDFILE FALSE CACHE BOOL "Build With LibSndFile" FORCE)
+ message(WARNING "LibSndFile not found, plugin will not be built.")
+ endif()
+endif()
+
+# OpenAL
+if(WITH_OPENAL)
+ if(AUDASPACE_STANDALONE)
+ find_package(OpenAL ${PACKAGE_OPTION})
+ endif()
+
+ if(OPENAL_FOUND)
+ set(OPENAL_SRC
+ plugins/openal/OpenALDevice.cpp
+ plugins/openal/OpenALReader.cpp
+ )
+ set(OPENAL_HDR
+ plugins/openal/OpenALDevice.h
+ plugins/openal/OpenALReader.h
+ )
+
+ if(NOT PLUGIN_OPENAL)
+ list(APPEND INCLUDE ${OPENAL_INCLUDE_DIR})
+ list(APPEND LIBRARIES ${OPENAL_LIBRARY})
+ list(APPEND SRC ${OPENAL_SRC})
+ list(APPEND HDR ${OPENAL_HDR})
+ list(APPEND STATIC_PLUGINS OpenALDevice)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB OPENAL_DLLS ${LIBRARY_PATH}/OpenAL/bin/*.dll)
+ list(APPEND DLLS ${OPENAL_DLLS})
+ endif()
+ else()
+ set(WITH_OPENAL FALSE CACHE BOOL "Build With OpenAL" FORCE)
+ message(WARNING "OpenAL not found, plugin will not be built.")
+ endif()
+endif()
+
+# Python
+if(WITH_PYTHON)
+ if(AUDASPACE_STANDALONE)
+ find_package(PythonLibs 3.2 ${PACKAGE_OPTION})
+ find_package(NumPy ${PACKAGE_OPTION})
+ endif()
+
+ if(PYTHONLIBS_FOUND AND NUMPY_FOUND)
+ list(APPEND INCLUDE ${PYTHON_INCLUDE_DIRS} ${NUMPY_INCLUDE_DIRS})
+
+ if(WITH_PYTHON_MODULE)
+ find_package(PythonInterp 3.2 ${PACKAGE_OPTION})
+
+ if(NOT PYTHONINTERP_FOUND)
+ set(WITH_PYTHON_MODULE FALSE)
+ message(WARNING "Python interpreter not found, module will not be built.")
+ endif()
+ endif()
+
+ set(AUDASPACE_PY_LIBRARY -laudaspace-py)
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB PYTHON_DLLS ${LIBRARY_PATH}/Python/bin/*.dll)
+ list(APPEND DLLS ${PYTHON_DLLS})
+ endif()
+ else()
+ set(WITH_PYTHON FALSE CACHE BOOL "Build With Python Library" FORCE)
+ message(WARNING "Python libraries not found, language binding will not be built.")
+ endif()
+endif()
+
+# SDL
+if(WITH_SDL)
+ if(AUDASPACE_STANDALONE)
+ if(USE_SDL2)
+ find_package(SDL2)
+ if(SDL2_FOUND)
+ set(SDL_INCLUDE_DIR ${SDL2_INCLUDE_DIR})
+ set(SDL_LIBRARY ${SDL2_LIBRARY})
+ set(SDL_FOUND TRUE)
+ else()
+ find_package(SDL ${PACKAGE_OPTION})
+ endif()
+ else()
+ find_package(SDL ${PACKAGE_OPTION})
+ endif()
+ endif()
+
+ if(SDL_FOUND)
+ set(SDL_SRC
+ plugins/sdl/SDLDevice.cpp
+ )
+ set(SDL_HDR
+ plugins/sdl/SDLDevice.h
+ )
+
+ if(NOT PLUGIN_SDL)
+ list(APPEND INCLUDE ${SDL_INCLUDE_DIR})
+ list(APPEND LIBRARIES ${SDL_LIBRARY})
+ list(APPEND SRC ${SDL_SRC})
+ list(APPEND HDR ${SDL_HDR})
+ list(APPEND STATIC_PLUGINS SDLDevice)
+ endif()
+
+ if(WIN32 AND AUDASPACE_STANDALONE)
+ file(GLOB SDL_DLLS ${LIBRARY_PATH}/sdl/bin/*.dll)
+ list(APPEND DLLS ${SDL_DLLS})
+ endif()
+ else()
+ set(WITH_SDL FALSE CACHE BOOL "Build With SDL" FORCE)
+ message(WARNING "SDL not found, plugin will not be built.")
+ endif()
+endif()
+
+# library configuration
+
+if(SHARED_LIBRARY)
+ set(AUD_LIBRARY_TYPE AUD_SHARED_LIBRARY)
+ set(LIBRARY_TYPE SHARED)
+ add_definitions(-DAUD_BUILD_SHARED_LIBRARY)
+else()
+ set(AUD_LIBRARY_TYPE AUD_STATIC_LIBRARY)
+ set(LIBRARY_TYPE STATIC)
+endif()
+
+# file configuration
+
+configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config/Audaspace.h.in ${CMAKE_CURRENT_BINARY_DIR}/Audaspace.h ESCAPE_QUOTES @ONLY)
+
+list(APPEND HDR ${CMAKE_CURRENT_BINARY_DIR}/Audaspace.h)
+
+set(STATIC_PLUGIN_CLASSES "")
+set(STATIC_PLUGIN_REGISTERS "")
+
+foreach(PLUGIN ${STATIC_PLUGINS})
+ list(APPEND STATIC_PLUGIN_CLASSES "STATIC_PLUGIN_CLASS(" ${PLUGIN} ")\n")
+ list(APPEND STATIC_PLUGIN_REGISTERS "\tSTATIC_PLUGIN_REGISTER(" ${PLUGIN} ")\n")
+endforeach()
+
+string(CONCAT STATIC_PLUGIN_CLASSES ${STATIC_PLUGIN_CLASSES})
+string(CONCAT STATIC_PLUGIN_REGISTERS ${STATIC_PLUGIN_REGISTERS})
+
+if(WIN32)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/plugin/PluginManagerWindows.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/PluginManager.cpp ESCAPE_QUOTES @ONLY)
+ if(WITH_FFTW)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/fx/HRTFLoaderWindows.cpp ${CMAKE_CURRENT_BINARY_DIR}/HRTFLoader.cpp COPYONLY)
+ endif()
+else()
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/plugin/PluginManagerUnix.cpp.in ${CMAKE_CURRENT_BINARY_DIR}/PluginManager.cpp ESCAPE_QUOTES @ONLY)
+ if(WITH_FFTW)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/src/fx/HRTFLoaderUnix.cpp ${CMAKE_CURRENT_BINARY_DIR}/HRTFLoader.cpp COPYONLY)
+ endif()
+endif()
+
+list(APPEND SRC ${CMAKE_CURRENT_BINARY_DIR}/PluginManager.cpp)
+if(WITH_FFTW)
+ list(APPEND SRC ${CMAKE_CURRENT_BINARY_DIR}/HRTFLoader.cpp)
+endif()
+
+# directories
+
+include_directories(${INCLUDE})
+link_directories()
+
+# install configuration
+
+if(WIN32)
+ set(BIN_DESTINATION ".")
+else()
+ set(BIN_DESTINATION "bin")
+endif()
+
+set(LIB_DESTINATION "lib${LIB_SUFFIX}")
+
+# library
+
+add_library(audaspace ${LIBRARY_TYPE} ${SRC} ${HDR})
+target_link_libraries(audaspace ${LIBRARIES})
+set_target_properties(audaspace PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+
+if(AUDASPACE_STANDALONE)
+ install(TARGETS audaspace
+ RUNTIME DESTINATION ${BIN_DESTINATION}
+ LIBRARY DESTINATION ${LIB_DESTINATION}
+ ARCHIVE DESTINATION ${LIB_DESTINATION}
+ )
+
+ install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/ DESTINATION include/audaspace)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Audaspace.h DESTINATION include/audaspace)
+
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/packages/pkgconfig/audaspace.pc.in ${CMAKE_CURRENT_BINARY_DIR}/audaspace.pc @ONLY)
+
+ if(NOT WIN32 AND NOT APPLE)
+ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/audaspace.pc DESTINATION "lib${LIB_SUFFIX}/pkgconfig")
+ endif()
+endif()
+
+# plugins
+
+if(WITH_FFMPEG AND PLUGIN_FFMPEG)
+ add_definitions(-DFFMPEG_PLUGIN)
+ include_directories(${INCLUDE} ${FFMPEG_INCLUDE_DIRS})
+ add_library(audffmpeg SHARED ${FFMPEG_SRC} ${FFMPEG_HDR} ${HDR})
+ target_link_libraries(audffmpeg audaspace ${FFMPEG_LIBRARIES})
+ set_target_properties(audffmpeg PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ install(TARGETS audffmpeg DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+if(WITH_JACK AND PLUGIN_JACK)
+ add_definitions(-DJACK_PLUGIN)
+ include_directories(${INCLUDE} ${JACK_INCLUDE_DIRS})
+ add_library(audjack SHARED ${JACK_SRC} ${JACK_HDR} ${HDR})
+ if(DYNLOAD_JACK)
+ target_link_libraries(audjack audaspace)
+ else()
+ target_link_libraries(audjack audaspace ${JACK_LIBRARIES})
+ endif()
+ set_target_properties(audjack PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ install(TARGETS audjack DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+if(WITH_LIBSNDFILE AND PLUGIN_LIBSNDFILE)
+ add_definitions(-DLIBSNDFILE_PLUGIN)
+ include_directories(${INCLUDE} ${LIBSNDFILE_INCLUDE_DIRS})
+ add_library(audlibsndfile SHARED ${LIBSNDFILE_SRC} ${LIBSNDFILE_HDR} ${HDR})
+ set_target_properties(audlibsndfile PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ target_link_libraries(audlibsndfile audaspace ${LIBSNDFILE_LIBRARIES})
+ install(TARGETS audlibsndfile DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+if(WITH_OPENAL AND PLUGIN_OPENAL)
+ add_definitions(-DOPENAL_PLUGIN)
+ include_directories(${INCLUDE} ${OPENAL_INCLUDE_DIR})
+ add_library(audopenal SHARED ${OPENAL_SRC} ${OPENAL_HDR} ${HDR})
+ set_target_properties(audopenal PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ target_link_libraries(audopenal audaspace ${OPENAL_LIBRARY})
+ install(TARGETS audopenal DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+if(WITH_SDL AND PLUGIN_SDL)
+ add_definitions(-DSDL_PLUGIN)
+ include_directories(${INCLUDE} ${SDL_INCLUDE_DIR})
+ add_library(audsdl SHARED ${SDL_SRC} ${SDL_HDR} ${HDR})
+ set_target_properties(audsdl PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ target_link_libraries(audsdl audaspace ${SDL_LIBRARY})
+ install(TARGETS audsdl DESTINATION ${DEFAULT_PLUGIN_PATH})
+endif()
+
+# dlls
+
+if(WIN32)
+ if(DLLS)
+ install(FILES ${DLLS} DESTINATION ${BIN_DESTINATION})
+ endif()
+endif()
+
+# demos
+
+if(BUILD_DEMOS)
+ include_directories(${INCLUDE})
+
+ set(DEMOS audaplay audaconvert audaremap signalgen randsounds dynamicmusic playbackmanager)
+
+ add_executable(audaplay demos/audaplay.cpp)
+ target_link_libraries(audaplay audaspace)
+
+ add_executable(audaconvert demos/audaconvert.cpp)
+ target_link_libraries(audaconvert audaspace)
+
+ add_executable(audaremap demos/audaremap.cpp)
+ target_link_libraries(audaremap audaspace)
+
+ add_executable(signalgen demos/signalgen.cpp)
+ target_link_libraries(signalgen audaspace)
+
+ add_executable(randsounds demos/randsounds.cpp)
+ target_link_libraries(randsounds audaspace)
+
+ add_executable(dynamicmusic demos/dynamicmusic.cpp)
+ target_link_libraries(dynamicmusic audaspace)
+
+ add_executable(playbackmanager demos/playbackmanager.cpp)
+ target_link_libraries(playbackmanager audaspace)
+
+ if(WITH_FFTW)
+ list(APPEND DEMOS convolution binaural)
+
+ add_executable(convolution demos/convolution.cpp)
+ target_link_libraries(convolution audaspace)
+
+ add_executable(binaural demos/binaural.cpp)
+ target_link_libraries(binaural audaspace)
+ endif()
+
+ if(WITH_OPENAL)
+ list(APPEND DEMOS openaldevices)
+
+ add_executable(openaldevices demos/openaldevices.cpp)
+ if(PLUGIN_OPENAL)
+ target_link_libraries(openaldevices audaspace audopenal)
+ else()
+ target_link_libraries(openaldevices audaspace)
+ endif()
+ endif()
+
+ install(TARGETS ${DEMOS}
+ RUNTIME DESTINATION ${BIN_DESTINATION}
+ LIBRARY DESTINATION ${LIB_DESTINATION}
+ ARCHIVE DESTINATION ${LIB_DESTINATION}
+ )
+endif()
+
+# bindings
+
+if(WITH_C)
+ if(SEPARATE_C)
+ add_library(audaspace-c ${LIBRARY_TYPE} ${C_SRC} ${C_HDR})
+ target_link_libraries(audaspace-c audaspace)
+ set_target_properties(audaspace-c PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+ install(TARGETS audaspace-c
+ RUNTIME DESTINATION ${BIN_DESTINATION}
+ LIBRARY DESTINATION ${LIB_DESTINATION}
+ ARCHIVE DESTINATION ${LIB_DESTINATION}
+ )
+ endif()
+
+ if(AUDASPACE_STANDALONE)
+ install(FILES ${C_HDR} DESTINATION include/audaspace)
+ endif()
+endif()
+
+if(WITH_PYTHON)
+ set(PYTHON_SRC
+ bindings/python/PyAPI.cpp
+ bindings/python/PyDevice.cpp
+ bindings/python/PyDynamicMusic.cpp
+ bindings/python/PyHandle.cpp
+ bindings/python/PyPlaybackManager.cpp
+ bindings/python/PySequence.cpp
+ bindings/python/PySequenceEntry.cpp
+ bindings/python/PySound.cpp
+ bindings/python/PySource.cpp
+ bindings/python/PyThreadPool.cpp
+ )
+ set(PYTHON_HDR
+ bindings/python/PyAPI.h
+ bindings/python/PyDevice.h
+ bindings/python/PyDynamicMusic.h
+ bindings/python/PyHandle.h
+ bindings/python/PyPlaybackManager.h
+ bindings/python/PySequence.h
+ bindings/python/PySequenceEntry.h
+ bindings/python/PySound.h
+ bindings/python/PySource.h
+ bindings/python/PyThreadPool.h
+ )
+
+ if(WITH_FFTW)
+ list(APPEND PYTHON_SRC
+ bindings/python/PyHRTF.cpp
+ bindings/python/PyImpulseResponse.cpp
+ )
+ list(APPEND PYTHON_HDR
+ bindings/python/PyHRTF.h
+ bindings/python/PyImpulseResponse.h
+ )
+ endif()
+
+ add_library(audaspace-py ${LIBRARY_TYPE} ${PYTHON_SRC} ${PYTHON_HDR})
+ target_link_libraries(audaspace-py audaspace ${PYTHON_LIBRARIES})
+ set_target_properties(audaspace-py PROPERTIES SOVERSION ${AUDASPACE_VERSION})
+
+ if(AUDASPACE_STANDALONE)
+ install(TARGETS audaspace-py
+ RUNTIME DESTINATION ${BIN_DESTINATION}
+ LIBRARY DESTINATION ${LIB_DESTINATION}
+ ARCHIVE DESTINATION ${LIB_DESTINATION}
+ )
+
+ install(FILES ${PYTHON_HDR} DESTINATION include/audaspace/python)
+ endif()
+
+ if(WITH_PYTHON_MODULE)
+ set(PYTHON_SOURCE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/bindings/python)
+ configure_file(${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${CMAKE_CURRENT_BINARY_DIR}/setup.py ESCAPE_QUOTES @ONLY)
+
+ if(APPLE)
+ add_custom_command(OUTPUT build COMMAND MACOSX_DEPLOYMENT_TARGET=${CMAKE_OSX_DEPLOYMENT_TARGET} ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
+ elseif(WIN32)
+ set(ENV{VS100COMNTOOLS} $ENV{VS120COMNTOOLS})
+ add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
+ else()
+ add_custom_command(OUTPUT build COMMAND ${PYTHON_EXECUTABLE} setup.py build DEPENDS ${PYTHON_SRC} ${PYTHON_HDR})
+ endif()
+ add_custom_target(pythonmodule ALL DEPENDS build SOURCES ${PYTHON_SOURCE_DIRECTORY}/setup.py.in ${PYTHON_SRC} ${PYTHON_HDR})
+ add_dependencies(pythonmodule audaspace)
+
+ install(CODE "EXECUTE_PROCESS(COMMAND ${PYTHON_EXECUTABLE} setup.py install --root=\$ENV{DESTDIR} --prefix=${CMAKE_INSTALL_PREFIX})")
+ endif()
+endif()
+
+# docs
+
+if(WITH_DOCS)
+ find_package(Doxygen ${PACKAGE_OPTION})
+
+ if(DOXYGEN_FOUND AND DOXYGEN_DOT_FOUND)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/doc/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile @ONLY)
+
+ add_custom_target(audaspace_doc ALL ${DOXYGEN_EXECUTABLE} Doxyfile COMMENT "Building C++ HTML documentation with Doxygen.")
+ else()
+ set(WITH_DOCS FALSE CACHE BOOL "Build C++ HTML Documentation with Doxygen" FORCE)
+ message(WARNING "Doxygen (and/or dot) not found, documentation will not be built.")
+ endif()
+endif()
+
+if(WITH_BINDING_DOCS)
+ find_package(Sphinx ${PACKAGE_OPTION})
+
+ if(SPHINX_FOUND)
+ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/bindings/doc/conf.py.in ${CMAKE_CURRENT_BINARY_DIR}/conf.py @ONLY)
+
+ add_custom_target(bindings_doc ALL COMMAND ${PYTHON_EXECUTABLE} setup.py --build-docs ${SPHINX_EXECUTABLE} -q -b html -c "${CMAKE_CURRENT_BINARY_DIR}" -d "${CMAKE_CURRENT_BINARY_DIR}/_doctrees" "${CMAKE_CURRENT_SOURCE_DIR}/bindings/doc" "${CMAKE_CURRENT_BINARY_DIR}/doc/bindings" DEPENDS pythonmodule COMMENT "Building C/Python HTML documentation with Sphinx.")
+ else()
+ set(WITH_BINDING_DOCS FALSE CACHE BOOL "Build C/Python HTML Documentation with Sphinx" FORCE)
+ message(WARNING "Sphinx not found, binding documentation will not be built.")
+ endif()
+endif()
+
+if(WITH_DOCS OR WITH_BINDING_DOCS)
+ install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc/ DESTINATION ${DOCUMENTATION_INSTALL_PATH})
+endif()
diff --git a/extern/audaspace/INSTALL b/extern/audaspace/INSTALL
new file mode 100644
index 00000000000..c63206fb949
--- /dev/null
+++ b/extern/audaspace/INSTALL
@@ -0,0 +1,107 @@
+Audaspace Installation Guide
+============================
+
+This document guides through the building and installation of audaspace.
+
+The build system used to build audaspace is CMake and it allows very building the library for very different application scenarios from a very general shared library build with plugins that is suitable for system wide installations to building everything into a single static library to be linked into a standalone program.
+
+Build Dependencies
+------------------
+
+Audaspace is written in C++ 11 so a fairly recent compiler (g++ 4.8.2, clang 3.3, MSVC 2013) is needed to build it. The build system used is CMake and you need at least version 3.0. The following build dependencies are all optional, but without any it's neither possible to open sound files nor play back through the speakers. For windows a library folder called build-dependencies can be downloaded from https://github.com/audaspace/audaspace/releases.
+
+- OpenAL (input/output device)
+- SDL (output device)
+- Jack (output device)
+- libsndfile (file access)
+- ffmpeg (file access)
+- Python (language binding)
+
+Getting the Code
+----------------
+
+The audaspace source code or binary releases can be downloaded from https://github.com/audaspace/audaspace/releases.
+
+For the most recent version you can use git to get the source code.
+
+ git clone https://github.com/audaspace/audaspace.git
+
+Plugins
+-------
+
+Before diving into the exact build steps for each platform, we will have a look at plugins. There are so far two types of plugins: input and output plugins. Input plugins are for reading audio files in many different formats and output plugins are for output devices on different platforms. During the configuration audaspace's standard plugins can be enabled with their repsective `WITH_*` and `PLUGIN_*` configuration option. Plugins are built as shared libraries. By default audaspace looks in the `DEFAULT_PLUGIN_PATH` for shared libraries it can load. Building with a dependency (`WITH_*`) but without enabling the respective `PLUGIN_*` option will compile the plugin directly into the library, so the plugin always gets loaded when the plugins are initialised.
+
+Building for Linux
+------------------
+
+### Configuration ###
+
+It is highly recommended to build audaspace outside of the actual source code in a specific build directory.
+
+ mkdir build
+ cd build
+
+Configuration is then either done interactively by using ccmake
+
+ ccmake ../audaspace
+
+__or__ it can be done by defining variables directly during the run of cmake.
+
+ cmake ../build \
+ -DCMAKE_INSTALL_PREFIX:PATH=/usr \
+ -DCMAKE_BUILD_TYPE:STRING=Release \
+ -DBUILD_DEMOS:BOOL=TRUE \
+ -DSHARED_LIBRARY:BOOL=TRUE \
+ -DWITH_C:BOOL=TRUE \
+ -DWITH_FFMPEG:BOOL=TRUE \
+ -DWITH_JACK:BOOL=TRUE \
+ -DWITH_LIBSNDFILE:BOOL=TRUE \
+ -DWITH_OPENAL:BOOL=TRUE \
+ -DWITH_PYTHON:BOOL=TRUE \
+ -DWITH_SDL:BOOL=TRUE \
+ -DDEFAULT_PLUGIN_PATH:PATH=/usr/share/audaspace/plugins
+
+This specific configuration is recommended for a system wide installation of audaspace where all build dependencies are required.
+
+### Building ###
+
+After configuration the building is as easy as running
+
+ make
+
+### Installation ###
+
+Installation is then also simple using
+
+ make install
+
+### Using the library ###
+
+When audaspace is installed to the system, the required configuration for _pkgconfig_ is also installed and pkgconfig can then be used to compile projects with audaspace.
+
+It is also possible to build audaspace as a static library and use it directly in a project. For this the library has to be configured accordingly with ccmake and after building the resulting library file can be added to the project's build system.
+
+Building for Windows
+--------------------
+
+### Configuration ###
+
+Using cmake-gui select Visual Studio 2013 or 2015 for the architecture you want to build for and choose audaspace's source directory and a build directory. It is highly recommended to build audaspace outside of the source directory. During the first configuration cmake tries to find the dependencies. Dependencies that are not installed on the system are automatically disabled. To prevent this, enable `WITH_STRICT_DEPENDENCIES`. To use the build dependencies folder from the website, set the `LIBRARY_PATH` to point to the extracted directory. Also don't forget to set the `CMAKE_INSTALL_PREFIX` to a path where your user account can install to. Finally enable the dependencies that you want to use (`WITH_*`), configure and generate.
+
+### Building ###
+
+Open the project in Visual Studio and set the configuration to Release. Then you can simply hit the build button.
+
+### Installation ###
+
+To install audaspace to your target folder, build the INSTALL target.
+Note that if you don't use the libraries folder provided on the website, the INSTALL target might fail and you need to copy the files manually, including the dlls of the dependencies.
+
+### Using the library ###
+
+To use audaspace in your project, configure the include path and the libraries that you need, which you can find in the include and lib directories in your installation path.
+
+### Notes for plugins on windows ###
+
+- FFMPEG: Due to a problem with FFMPEG's 32 bit libraries, it is necessary to disable SAFESEH for the audffmpeg build target inside Visual Studio (Properties, Linker, Advanced). This has to be done after each generate step of CMake.
+- Jack: If no jack server is running on windows and your application or one of the demos tries to use the jack plugin, this adds a long delay to the device initialisation. In case you don't need jack, make sure to disable the plugin or for the prebuilt version of audaspace simply delete audjack.dll (and any files with jack in the name to clean up).
diff --git a/extern/audaspace/LICENSE b/extern/audaspace/LICENSE
new file mode 100644
index 00000000000..d6456956733
--- /dev/null
+++ b/extern/audaspace/LICENSE
@@ -0,0 +1,202 @@
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ 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.
diff --git a/extern/audaspace/README.md b/extern/audaspace/README.md
new file mode 100644
index 00000000000..7fdd515ab67
--- /dev/null
+++ b/extern/audaspace/README.md
@@ -0,0 +1,47 @@
+audaspace
+=========
+
+Audaspace (pronounced "outer space") is a high level audio library written in C++ with language bindings for Python for example. It started out as the audio engine of the 3D modelling application Blender and is now released as a standalone library.
+
+Documentation and Community
+---------------------------
+
+The documentation including guides for building and installing, demos, tutorials as well as the API reference for C++, C and python can be found on https://audaspace.github.io.
+
+Bug reports and feature requests should go to the [issue tracker](https://github.com/audaspace/audaspace/issues).
+
+For any other discussions about audaspace there is a [mailing list](https://groups.google.com/forum/#!forum/audaspace) and there is also the IRC channel #audaspace on irc.freenode.net.
+
+Features
+--------
+
+The following (probably incomplete) features are supported by audaspace:
+
+* input/output devices
+ * input from microphones, line in, etc.
+ * output devices including 3D audio support
+* file reading/writing
+* filters like low-/highpass and effects like delay, reverse or fading
+* generators for simple waveforms like silence, sine and triangle
+* respecification - this term is used for changing stream parameters which are
+ * channel count - channel remapping
+ * sample format - the library internally uses 32 bit floats
+ * sample rate - resampling
+* simple (superposition, joining and ping-pong aka forward-reverse) and more complex (non-linear audio editing) sequencing of sounds
+
+License
+-------
+
+> Copyright © 2009-2015 Jörg Müller. All rights reserved.
+>
+> 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.
diff --git a/extern/audaspace/bindings/C/AUD_Device.cpp b/extern/audaspace/bindings/C/AUD_Device.cpp
new file mode 100644
index 00000000000..441f228deac
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Device.cpp
@@ -0,0 +1,336 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "devices/DeviceManager.h"
+#include "devices/I3DDevice.h"
+#include "devices/IDeviceFactory.h"
+#include "devices/ReadDevice.h"
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Device.h"
+
+static inline aud::Specs convCToSpec(AUD_Specs specs)
+{
+ aud::Specs s;
+ s.channels = static_cast<Channels>(specs.channels);
+ s.rate = static_cast<SampleRate>(specs.rate);
+ return s;
+}
+
+static inline aud::DeviceSpecs convCToDSpec(AUD_DeviceSpecs specs)
+{
+ aud::DeviceSpecs s;
+ s.specs = convCToSpec(specs.specs);
+ s.format = static_cast<SampleFormat>(specs.format);
+ return s;
+}
+
+AUD_API AUD_Device* AUD_Device_open(const char* type, AUD_DeviceSpecs specs, int buffersize, const char* name)
+{
+ DeviceSpecs dspecs = convCToDSpec(specs);
+
+ if(dspecs.channels == CHANNELS_INVALID)
+ dspecs.channels = CHANNELS_STEREO;
+ if(dspecs.format == FORMAT_INVALID)
+ dspecs.format = FORMAT_FLOAT32;
+ if(dspecs.rate == RATE_INVALID)
+ dspecs.rate = RATE_48000;
+ if(buffersize < 128)
+ buffersize = AUD_DEFAULT_BUFFER_SIZE;
+ if(name == nullptr)
+ name = "";
+
+ try
+ {
+ if(!type)
+ {
+ auto device = DeviceManager::getDevice();
+ if(!device)
+ {
+ DeviceManager::openDefaultDevice();
+ device = DeviceManager::getDevice();
+ }
+ return new AUD_Device(device);
+ }
+
+ if(type == std::string("read"))
+ {
+ return new AUD_Device(new ReadDevice(dspecs));
+ }
+
+ std::shared_ptr<IDeviceFactory> factory;
+ if(!*type)
+ factory = DeviceManager::getDefaultDeviceFactory();
+ else
+ factory = DeviceManager::getDeviceFactory(type);
+
+ if(factory)
+ {
+ factory->setName(name);
+ factory->setSpecs(dspecs);
+ factory->setBufferSize(buffersize);
+ return new AUD_Device(factory->openDevice());
+ }
+ }
+ catch(Exception&)
+ {
+ }
+ return nullptr;
+}
+
+AUD_API void AUD_Device_lock(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ dev->lock();
+}
+
+AUD_API AUD_Handle* AUD_Device_play(AUD_Device* device, AUD_Sound* sound, int keep)
+{
+ assert(sound);
+ auto dev = device ? *device : DeviceManager::getDevice();
+
+ try
+ {
+ AUD_Handle handle = dev->play(*sound, keep);
+ if(handle.get())
+ {
+ return new AUD_Handle(handle);
+ }
+ }
+ catch(Exception&)
+ {
+ }
+ return nullptr;
+}
+
+AUD_API void AUD_Device_stopAll(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ dev->stopAll();
+}
+
+AUD_API void AUD_Device_unlock(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ dev->unlock();
+}
+
+AUD_API AUD_Channels AUD_Device_getChannels(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ return static_cast<AUD_Channels>(dev->getSpecs().channels);
+}
+
+AUD_API AUD_DistanceModel AUD_Device_getDistanceModel(AUD_Device* device)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ return static_cast<AUD_DistanceModel>(dev->getDistanceModel());
+}
+
+AUD_API void AUD_Device_setDistanceModel(AUD_Device* device, AUD_DistanceModel value)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ dev->setDistanceModel(static_cast<DistanceModel>(value));
+}
+
+AUD_API float AUD_Device_getDopplerFactor(AUD_Device* device)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ return dev->getDopplerFactor();
+}
+
+AUD_API void AUD_Device_setDopplerFactor(AUD_Device* device, float value)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ dev->setDopplerFactor(value);
+}
+
+AUD_API AUD_SampleFormat AUD_Device_getFormat(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ return static_cast<AUD_SampleFormat>(dev->getSpecs().format);
+}
+
+AUD_API void AUD_Device_getListenerLocation(AUD_Device* device, float value[3])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Vector3 v = dev->getListenerLocation();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+}
+
+AUD_API void AUD_Device_setListenerLocation(AUD_Device* device, const float value[3])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Vector3 v(value[0], value[1], value[2]);
+ dev->setListenerLocation(v);
+}
+
+AUD_API void AUD_Device_getListenerOrientation(AUD_Device* device, float value[4])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Quaternion v = dev->getListenerOrientation();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+ value[3] = v.w();
+}
+
+AUD_API void AUD_Device_setListenerOrientation(AUD_Device* device, const float value[4])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Quaternion v(value[3], value[0], value[1], value[2]);
+ dev->setListenerOrientation(v);
+}
+
+AUD_API void AUD_Device_getListenerVelocity(AUD_Device* device, float value[3])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Vector3 v = dev->getListenerVelocity();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+}
+
+AUD_API void AUD_Device_setListenerVelocity(AUD_Device* device, const float value[3])
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ Vector3 v(value[0], value[1], value[2]);
+ dev->setListenerVelocity(v);
+}
+
+AUD_API double AUD_Device_getRate(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ return dev->getSpecs().rate;
+}
+
+AUD_API float AUD_Device_getSpeedOfSound(AUD_Device* device)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ return dev->getSpeedOfSound();
+}
+
+AUD_API void AUD_Device_setSpeedOfSound(AUD_Device* device, float value)
+{
+ auto dev = device ? std::dynamic_pointer_cast<I3DDevice>(*device) : DeviceManager::get3DDevice();
+ dev->setSpeedOfSound(value);
+}
+
+AUD_API float AUD_Device_getVolume(AUD_Device* device)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ return dev->getVolume();
+}
+
+AUD_API void AUD_Device_setVolume(AUD_Device* device, float value)
+{
+ auto dev = device ? *device : DeviceManager::getDevice();
+ dev->setVolume(value);
+}
+
+AUD_API int AUD_Device_read(AUD_Device* device, unsigned char* buffer, int length)
+{
+ assert(device);
+ assert(buffer);
+
+ auto readDevice = std::dynamic_pointer_cast<ReadDevice>(*device);
+ if(!readDevice)
+ return false;
+
+ try
+ {
+ return readDevice->read(buffer, length);
+ }
+ catch(Exception&)
+ {
+ return false;
+ }
+}
+
+AUD_API void AUD_Device_free(AUD_Device* device)
+{
+ assert(device);
+
+ try
+ {
+ delete device;
+ }
+ catch(Exception&)
+ {
+ }
+}
+
+AUD_API AUD_Device* AUD_Device_getCurrent()
+{
+ auto device = DeviceManager::getDevice();
+
+ if(!device)
+ return nullptr;
+
+ return new AUD_Device(device);
+}
+
+AUD_API void AUD_seekSynchronizer(AUD_Handle* handle, float time)
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ synchronizer->seek(*reinterpret_cast<std::shared_ptr<IHandle>*>(handle), time);
+}
+
+AUD_API float AUD_getSynchronizerPosition(AUD_Handle* handle)
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ return synchronizer->getPosition(*reinterpret_cast<std::shared_ptr<IHandle>*>(handle));
+ return (*reinterpret_cast<std::shared_ptr<IHandle>*>(handle))->getPosition();
+}
+
+AUD_API void AUD_playSynchronizer()
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ synchronizer->play();
+}
+
+AUD_API void AUD_stopSynchronizer()
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ synchronizer->stop();
+}
+
+AUD_API void AUD_setSynchronizerCallback(AUD_syncFunction function, void* data)
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ synchronizer->setSyncCallback(function, data);
+}
+
+AUD_API int AUD_isSynchronizerPlaying()
+{
+ auto synchronizer = DeviceManager::getDevice()->getSynchronizer();
+ if(synchronizer)
+ return synchronizer->isPlaying();
+ return false;
+}
+
diff --git a/extern/audaspace/bindings/C/AUD_Device.h b/extern/audaspace/bindings/C/AUD_Device.h
new file mode 100644
index 00000000000..0dfa21f0660
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Device.h
@@ -0,0 +1,258 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Possible distance models for the 3D device.
+typedef enum
+{
+ AUD_DISTANCE_MODEL_INVALID = 0,
+ AUD_DISTANCE_MODEL_INVERSE,
+ AUD_DISTANCE_MODEL_INVERSE_CLAMPED,
+ AUD_DISTANCE_MODEL_LINEAR,
+ AUD_DISTANCE_MODEL_LINEAR_CLAMPED,
+ AUD_DISTANCE_MODEL_EXPONENT,
+ AUD_DISTANCE_MODEL_EXPONENT_CLAMPED
+} AUD_DistanceModel;
+
+typedef void (*AUD_syncFunction)(void*, int, float);
+
+/**
+ * Opens a new sound device.
+ * \param type The name of the device.
+ * Can be NULL to open the default device with default settings or return the handle to the already opened one.
+ * Can be "" to open the a default factory device with given settings.
+ * Can be "read" to open a readable device.
+ * \param specs Specification of the device parameters.
+ * \param buffersize Size of the mixing buffer.
+ * \param name Custom name of the device.
+ * \return A handle to the opened device or NULL on failure.
+ */
+extern AUD_API AUD_Device* AUD_Device_open(const char* type, AUD_DeviceSpecs specs, int buffersize, const char* name);
+
+/**
+ * Locks the playback device.
+ */
+extern AUD_API void AUD_Device_lock(AUD_Device* device);
+
+/**
+ * Plays back a sound file.
+ * \param sound The handle of the sound file.
+ * \param keep When keep is true the sound source will not be deleted but set to
+ * paused when its end has been reached.
+ * \return A handle to the played back sound.
+ */
+extern AUD_API AUD_Handle* AUD_Device_play(AUD_Device* device, AUD_Sound* sound, int keep);
+
+/**
+ * Stops all sounds playing.
+ */
+extern AUD_API void AUD_Device_stopAll(AUD_Device* device);
+
+/**
+ * Unlocks the device.
+ */
+extern AUD_API void AUD_Device_unlock(AUD_Device* device);
+
+/**
+ * Retrieves the channels of a device.
+ * param device The device to get the channels from.
+ * return The channels of the device.
+ */
+extern AUD_API AUD_Channels AUD_Device_getChannels(AUD_Device* device);
+
+/**
+ * Retrieves the distance model of a device.
+ * param device The device to get the distance model from.
+ * return The distance model of the device.
+ */
+extern AUD_API AUD_DistanceModel AUD_Device_getDistanceModel(AUD_Device* device);
+
+/**
+ * Sets the distance model of a device.
+ * param device The device to set the distance model from.
+ * param value The new distance model to set.
+ */
+extern AUD_API void AUD_Device_setDistanceModel(AUD_Device* device, AUD_DistanceModel value);
+
+/**
+ * Retrieves the doppler factor of a device.
+ * param device The device to get the doppler factor from.
+ * return The doppler factor of the device.
+ */
+extern AUD_API float AUD_Device_getDopplerFactor(AUD_Device* device);
+
+/**
+ * Sets the doppler factor of a device.
+ * param device The device to set the doppler factor from.
+ * param value The new doppler factor to set.
+ */
+extern AUD_API void AUD_Device_setDopplerFactor(AUD_Device* device, float value);
+
+/**
+ * Retrieves the format of a device.
+ * param device The device to get the format from.
+ * return The format of the device.
+ */
+extern AUD_API AUD_SampleFormat AUD_Device_getFormat(AUD_Device* device);
+
+/**
+ * Retrieves the listener location of a device.
+ * param device The device to get the listener location from.
+ * return The listener location of the device.
+ */
+extern AUD_API void AUD_Device_getListenerLocation(AUD_Device* device, float value[3]);
+
+/**
+ * Sets the listener location of a device.
+ * param device The device to set the listener location from.
+ * param value The new listener location to set.
+ */
+extern AUD_API void AUD_Device_setListenerLocation(AUD_Device* device, const float value[3]);
+
+/**
+ * Retrieves the listener orientation of a device.
+ * param device The device to get the listener orientation from.
+ * return The listener orientation of the device.
+ */
+extern AUD_API void AUD_Device_getListenerOrientation(AUD_Device* device, float value[4]);
+
+/**
+ * Sets the listener orientation of a device.
+ * param device The device to set the listener orientation from.
+ * param value The new listener orientation to set.
+ */
+extern AUD_API void AUD_Device_setListenerOrientation(AUD_Device* device, const float value[4]);
+
+/**
+ * Retrieves the listener velocity of a device.
+ * param device The device to get the listener velocity from.
+ * return The listener velocity of the device.
+ */
+extern AUD_API void AUD_Device_getListenerVelocity(AUD_Device* device, float value[3]);
+
+/**
+ * Sets the listener velocity of a device.
+ * param device The device to set the listener velocity from.
+ * param value The new listener velocity to set.
+ */
+extern AUD_API void AUD_Device_setListenerVelocity(AUD_Device* device, const float value[3]);
+
+/**
+ * Retrieves the rate of a device.
+ * param device The device to get the rate from.
+ * return The rate of the device.
+ */
+extern AUD_API double AUD_Device_getRate(AUD_Device* device);
+
+/**
+ * Retrieves the speed of sound of a device.
+ * param device The device to get the speed of sound from.
+ * return The speed of sound of the device.
+ */
+extern AUD_API float AUD_Device_getSpeedOfSound(AUD_Device* device);
+
+/**
+ * Sets the speed of sound of a device.
+ * param device The device to set the speed of sound from.
+ * param value The new speed of sound to set.
+ */
+extern AUD_API void AUD_Device_setSpeedOfSound(AUD_Device* device, float value);
+
+/**
+ * Retrieves the volume of a device.
+ * param device The device to get the volume from.
+ * return The volume of the device.
+ */
+extern AUD_API float AUD_Device_getVolume(AUD_Device* device);
+
+/**
+ * Sets the volume of a device.
+ * param device The device to set the volume from.
+ * param value The new volume to set.
+ */
+extern AUD_API void AUD_Device_setVolume(AUD_Device* device, float value);
+
+/**
+ * Reads the next samples into the supplied buffer.
+ * \param device The readable device.
+ * \param buffer The target buffer.
+ * \param length The length in samples to be filled.
+ * \return True if the reading succeeded, false if there are no sounds
+ * played back currently, in that case the buffer is filled with
+ * silence.
+ */
+extern AUD_API int AUD_Device_read(AUD_Device* device, unsigned char* buffer, int length);
+
+/**
+ * Closes a device. Handle becomes invalid afterwards.
+ * \param device The device to close.
+ */
+extern AUD_API void AUD_Device_free(AUD_Device* device);
+
+/**
+ * Retrieves the current device of the DeviceManager.
+ * \return A pointer to the current device, which needs to be freed with
+ * AUD_Device_free.
+ */
+extern AUD_API AUD_Device* AUD_Device_getCurrent();
+
+/**
+ * Seeks sequenced sound scene playback.
+ * \param handle Playback handle.
+ * \param time Time in seconds to seek to.
+ */
+extern AUD_API void AUD_seekSynchronizer(AUD_Handle* handle, float time);
+
+/**
+ * Returns the current sound scene playback time.
+ * \param handle Playback handle.
+ * \return The playback time in seconds.
+ */
+extern AUD_API float AUD_getSynchronizerPosition(AUD_Handle* handle);
+
+/**
+ * Starts the playback of jack transport if possible.
+ */
+extern AUD_API void AUD_playSynchronizer();
+
+/**
+ * Stops the playback of jack transport if possible.
+ */
+extern AUD_API void AUD_stopSynchronizer();
+
+/**
+ * Sets the sync callback for jack transport.
+ * \param function The callback function.
+ * \param data The data parameter for the callback.
+ */
+extern AUD_API void AUD_setSynchronizerCallback(AUD_syncFunction function, void* data);
+
+/**
+ * Returns whether jack transport is currently playing.
+ * \return Whether jack transport is currently playing.
+ */
+extern AUD_API int AUD_isSynchronizerPlaying();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_DynamicMusic.cpp b/extern/audaspace/bindings/C/AUD_DynamicMusic.cpp
new file mode 100644
index 00000000000..bb7a129dde3
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_DynamicMusic.cpp
@@ -0,0 +1,144 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_DynamicMusic.h"
+
+AUD_API AUD_DynamicMusic* AUD_DynamicMusic_create(AUD_Device* device)
+{
+ assert(device);
+
+ try
+ {
+ return new AUD_DynamicMusic(new DynamicMusic(*device));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_DynamicMusic_free(AUD_DynamicMusic* player)
+{
+ assert(player);
+ delete player;
+}
+
+AUD_API int AUD_DynamicMusic_addScene(AUD_DynamicMusic* player, AUD_Sound* scene)
+{
+ assert(player);
+ assert(scene);
+
+ return (*player)->addScene(*scene);
+}
+
+AUD_API int AUD_DynamicMusic_setSecene(AUD_DynamicMusic* player, int scene)
+{
+ assert(player);
+
+ return (*player)->changeScene(scene);
+}
+
+AUD_API int AUD_DynamicMusic_getScene(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->getScene();
+}
+
+AUD_API int AUD_DynamicMusic_addTransition(AUD_DynamicMusic* player, int ini, int end, AUD_Sound* transition)
+{
+ assert(player);
+ assert(transition);
+
+ return (*player)->addTransition(ini, end, *transition);
+}
+
+AUD_API void AUD_DynamicMusic_setFadeTime(AUD_DynamicMusic* player, float seconds)
+{
+ assert(player);
+
+ (*player)->setFadeTime(seconds);
+}
+
+AUD_API float AUD_DynamicMusic_getFadeTime(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->getFadeTime();
+}
+
+AUD_API int AUD_DynamicMusic_resume(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->resume();
+}
+
+AUD_API int AUD_DynamicMusic_pause(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->pause();
+}
+
+AUD_API int AUD_DynamicMusic_seek(AUD_DynamicMusic* player, float position)
+{
+ assert(player);
+
+ return (*player)->seek(position);
+}
+
+AUD_API float AUD_DynamicMusic_getPosition(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->getPosition();
+}
+
+AUD_API float AUD_DynamicMusic_getVolume(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->getVolume();
+}
+
+AUD_API int AUD_DynamicMusic_setVolume(AUD_DynamicMusic* player, float volume)
+{
+ assert(player);
+
+ return (*player)->setVolume(volume);
+}
+
+AUD_API AUD_Status AUD_DynamicMusic_getStatus(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return static_cast<AUD_Status>((*player)->getStatus());
+}
+
+AUD_API int AUD_DynamicMusic_stop(AUD_DynamicMusic* player)
+{
+ assert(player);
+
+ return (*player)->stop();
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_DynamicMusic.h b/extern/audaspace/bindings/C/AUD_DynamicMusic.h
new file mode 100644
index 00000000000..c362479591e
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_DynamicMusic.h
@@ -0,0 +1,145 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+#include "AUD_Handle.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new dynamic music player.
+* \param device The device that will be used to play sounds.
+* \return The new DynamicMusic object.
+*/
+extern AUD_API AUD_DynamicMusic* AUD_DynamicMusic_create(AUD_Device* device);
+
+/**
+* Deletes a dynamic music player.
+* \param player The DynamicMusic object to be deleted.
+*/
+extern AUD_API void AUD_DynamicMusic_free(AUD_DynamicMusic* player);
+
+/**
+* Adds a sound scene to a dynamic music player.
+* \param player The DynamicMusic object.
+* \param scene The sound to be added as a scene.
+* \return The index of the new scene.
+*/
+extern AUD_API int AUD_DynamicMusic_addScene(AUD_DynamicMusic* player, AUD_Sound* scene);
+
+/**
+* Changes the current sound scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \param scene The index of the scene to be played.
+* \return 0 if the target scene doesn't exist.
+*/
+extern AUD_API int AUD_DynamicMusic_setSecene(AUD_DynamicMusic* player, int scene);
+
+/**
+* Retrives the index of the current scene.
+* \param player The DynamicMusic object.
+* \return The index of the current scene.
+*/
+extern AUD_API int AUD_DynamicMusic_getScene(AUD_DynamicMusic* player);
+
+/**
+* Adds a new transition between two scenes.
+* \param player The DynamicMusic object.
+* \param ini The origin scene for the transition.
+* \param end The end scene for the transition.
+* \param transition A sound that will be used as transition between two scenes.
+* \return 0 if the ini or end scenes don't exist.
+*/
+extern AUD_API int AUD_DynamicMusic_addTransition(AUD_DynamicMusic* player, int ini, int end, AUD_Sound* transition);
+
+/**
+* Changes the fade time for the default transitions of a dynamic music player.
+* \param player The DynamicMusic object.
+* \param seconds The amount of secods that the crossfade transition will take.
+*/
+extern AUD_API void AUD_DynamicMusic_setFadeTime(AUD_DynamicMusic* player, float seconds);
+
+/**
+* Retrieves the fade time of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return The fade time of the player.
+*/
+extern AUD_API float AUD_DynamicMusic_getFadeTime(AUD_DynamicMusic* player);
+
+/**
+* Resumes the current scene playback of a dynamic music player if it is paused.
+* \param player The DynamicMusic object.
+* \return 0 if the playback wasn't resumed.
+*/
+extern AUD_API int AUD_DynamicMusic_resume(AUD_DynamicMusic* player);
+
+/**
+* Pauses the current scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return 0 if the playback wasn't paused.
+*/
+extern AUD_API int AUD_DynamicMusic_pause(AUD_DynamicMusic* player);
+
+/**
+* Seeks the current playing scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \param position The new position from which to play back, in seconds.
+* \return 0 if the seeking wasn't possible.
+*/
+extern AUD_API int AUD_DynamicMusic_seek(AUD_DynamicMusic* player, float position);
+
+/**
+* Retrieves the position of the current scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return The position of the current playing scene.
+*/
+extern AUD_API float AUD_DynamicMusic_getPosition(AUD_DynamicMusic* player);
+
+/**
+* Retrieves the volume of the current scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return The volume of the current playing scene.
+*/
+extern AUD_API float AUD_DynamicMusic_getVolume(AUD_DynamicMusic* player);
+
+/**
+* Changes the volume of the current scene in a dynamic music player.
+* \param player The DynamicMusic object.
+* \param 0 if the volume couldn't be changed.
+*/
+extern AUD_API int AUD_DynamicMusic_setVolume(AUD_DynamicMusic* player, float volume);
+
+/**
+* Retrieves the status of the current scene in a dynamic music player.
+* \param player The DynamicMusic object.
+* \return The Status of the current playing scene.
+*/
+extern AUD_API AUD_Status AUD_DynamicMusic_getStatus(AUD_DynamicMusic* player);
+
+/**
+* Stops the current scene of a dynamic music player.
+* \param player The DynamicMusic object.
+* \return 0 if the playback wasn't stopped.
+*/
+extern AUD_API int AUD_DynamicMusic_stop(AUD_DynamicMusic* player);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_HRTF.cpp b/extern/audaspace/bindings/C/AUD_HRTF.cpp
new file mode 100644
index 00000000000..002c5d61ddd
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_HRTF.cpp
@@ -0,0 +1,50 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_HRTF.h"
+
+extern AUD_API AUD_HRTF* AUD_HRTF_create()
+{
+ try
+ {
+ return new AUD_HRTF(new HRTF());
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+extern AUD_API void AUD_HRTF_free(AUD_HRTF* hrtfs)
+{
+ assert(hrtfs);
+ delete hrtfs;
+}
+
+extern AUD_API void AUD_HRTF_addImpulseResponseFromSound(AUD_HRTF* hrtfs, AUD_Sound* sound, float azimuth, float elevation)
+{
+ assert(hrtfs);
+ assert(sound);
+
+ (*hrtfs)->addImpulseResponse(std::make_shared<StreamBuffer>(*sound), azimuth, elevation);
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_HRTF.h b/extern/audaspace/bindings/C/AUD_HRTF.h
new file mode 100644
index 00000000000..29dda371695
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_HRTF.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new HRTF object.
+* \return The new HRTF object.
+*/
+extern AUD_API AUD_HRTF* AUD_HRTF_create();
+
+/**
+* Deletes a HRTF object.
+* \param hrtfs The HRTF object to be deleted.
+*/
+extern AUD_API void AUD_HRTF_free(AUD_HRTF* hrtfs);
+
+/**
+* Adds a new impulse response to an HRTF object.
+* \param hrtfs The HRTF object.
+* \param sound A Sound object representing an HRTF.
+* \param azimuth The azimuth angle of the HRTF.
+* \param elevation The elevation angle of the HRTF.
+*/
+extern AUD_API void AUD_HRTF_addImpulseResponseFromSound(AUD_HRTF* hrtfs, AUD_Sound* sound, float azimuth, float elevation);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_Handle.cpp b/extern/audaspace/bindings/C/AUD_Handle.cpp
new file mode 100644
index 00000000000..265c7bf08d2
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Handle.cpp
@@ -0,0 +1,384 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "devices/I3DHandle.h"
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Handle.h"
+
+AUD_API int AUD_Handle_pause(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->pause();
+}
+
+AUD_API int AUD_Handle_resume(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->resume();
+}
+
+AUD_API int AUD_Handle_stop(AUD_Handle* handle)
+{
+ assert(handle);
+ int result = (*handle)->stop();
+ delete handle;
+ return result;
+}
+
+AUD_API float AUD_Handle_getAttenuation(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getAttenuation();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setAttenuation(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setAttenuation(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getConeAngleInner(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getConeAngleInner();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setConeAngleInner(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setConeAngleInner(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getConeAngleOuter(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getConeAngleOuter();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setConeAngleOuter(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setConeAngleOuter(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getConeVolumeOuter(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getConeVolumeOuter();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setConeVolumeOuter(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setConeVolumeOuter(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getDistanceMaximum(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getDistanceMaximum();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setDistanceMaximum(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setDistanceMaximum(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getDistanceReference(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getDistanceReference();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setDistanceReference(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setDistanceReference(value);
+ return false;
+}
+
+AUD_API int AUD_Handle_doesKeep(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getKeep();
+}
+
+AUD_API int AUD_Handle_setKeep(AUD_Handle* handle, int value)
+{
+ assert(handle);
+ return (*handle)->setKeep(value);
+}
+
+AUD_API int AUD_Handle_getLocation(AUD_Handle* handle, float value[3])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Vector3 v = h->getLocation();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+ return true;
+ }
+ return false;
+}
+
+AUD_API int AUD_Handle_setLocation(AUD_Handle* handle, const float value[3])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Vector3 v = Vector3(value[0], value[1], value[2]);
+ return h->setLocation(v);
+ }
+ return false;
+}
+
+AUD_API int AUD_Handle_getLoopCount(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getLoopCount();
+}
+
+AUD_API int AUD_Handle_setLoopCount(AUD_Handle* handle, int value)
+{
+ assert(handle);
+ return (*handle)->setLoopCount(value);
+}
+
+AUD_API int AUD_Handle_getOrientation(AUD_Handle* handle, float value[4])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Quaternion v = h->getOrientation();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+ value[3] = v.w();
+ return true;
+ }
+ return false;
+}
+
+AUD_API int AUD_Handle_setOrientation(AUD_Handle* handle, const float value[4])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Quaternion v(value[3], value[0], value[1], value[2]);
+ return h->setOrientation(v);
+ }
+ return false;
+}
+
+AUD_API float AUD_Handle_getPitch(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getPitch();
+}
+
+AUD_API int AUD_Handle_setPitch(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ return (*handle)->setPitch(value);
+}
+
+AUD_API float AUD_Handle_getPosition(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getPosition();
+}
+
+AUD_API int AUD_Handle_setPosition(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ return (*handle)->seek(value);
+}
+
+AUD_API int AUD_Handle_isRelative(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->isRelative();
+ return true;
+}
+
+AUD_API int AUD_Handle_setRelative(AUD_Handle* handle, int value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setRelative(value);
+ return false;
+}
+
+AUD_API AUD_Status AUD_Handle_getStatus(AUD_Handle* handle)
+{
+ assert(handle);
+ return static_cast<AUD_Status>((*handle)->getStatus());
+}
+
+AUD_API int AUD_Handle_getVelocity(AUD_Handle* handle, float value[3])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Vector3 v = h->getVelocity();
+ value[0] = v.x();
+ value[1] = v.y();
+ value[2] = v.z();
+ return true;
+ }
+ return false;
+}
+
+AUD_API int AUD_Handle_setVelocity(AUD_Handle* handle, const float value[3])
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ {
+ Vector3 v = Vector3(value[0], value[1], value[2]);
+ return h->setVelocity(v);
+ }
+ return false;
+}
+
+AUD_API float AUD_Handle_getVolume(AUD_Handle* handle)
+{
+ assert(handle);
+ return (*handle)->getVolume();
+}
+
+AUD_API int AUD_Handle_setVolume(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ return (*handle)->setVolume(value);
+}
+
+AUD_API float AUD_Handle_getVolumeMaximum(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getVolumeMaximum();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setVolumeMaximum(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setVolumeMaximum(value);
+ return false;
+}
+
+AUD_API float AUD_Handle_getVolumeMinimum(AUD_Handle* handle)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->getVolumeMinimum();
+ return 0.0f;
+}
+
+AUD_API int AUD_Handle_setVolumeMinimum(AUD_Handle* handle, float value)
+{
+ assert(handle);
+ std::shared_ptr<I3DHandle> h = std::dynamic_pointer_cast<I3DHandle>(*handle);
+
+ if(h.get())
+ return h->setVolumeMinimum(value);
+ return false;
+}
+
+AUD_API void AUD_Handle_free(AUD_Handle* handle)
+{
+ delete handle;
+}
diff --git a/extern/audaspace/bindings/C/AUD_Handle.h b/extern/audaspace/bindings/C/AUD_Handle.h
new file mode 100644
index 00000000000..27cbd251de5
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Handle.h
@@ -0,0 +1,308 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Status of a playback handle.
+typedef enum
+{
+ AUD_STATUS_INVALID = 0, /// Invalid handle. Maybe due to stopping.
+ AUD_STATUS_PLAYING, /// Sound is playing.
+ AUD_STATUS_PAUSED, /// Sound is being paused.
+ AUD_STATUS_STOPPED /// Sound is stopped but kept in the device.
+} AUD_Status;
+
+/**
+ * Pauses a played back sound.
+ * \param handle The handle to the sound.
+ * \return Whether the handle has been playing or not.
+ */
+extern AUD_API int AUD_Handle_pause(AUD_Handle* handle);
+
+/**
+ * Resumes a paused sound.
+ * \param handle The handle to the sound.
+ * \return Whether the handle has been paused or not.
+ */
+extern AUD_API int AUD_Handle_resume(AUD_Handle* handle);
+
+/**
+ * Stops a playing or paused sound.
+ * \param handle The handle to the sound.
+ * \return Whether the handle has been valid or not.
+ */
+extern AUD_API int AUD_Handle_stop(AUD_Handle* handle);
+
+/**
+ * Retrieves the attenuation of a handle.
+ * param handle The handle to get the attenuation from.
+ * return The attenuation of the handle.
+ */
+extern AUD_API float AUD_Handle_getAttenuation(AUD_Handle* handle);
+
+/**
+ * Sets the attenuation of a handle.
+ * param handle The handle to set the attenuation from.
+ * param value The new attenuation to set.
+ */
+extern AUD_API int AUD_Handle_setAttenuation(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the cone angle inner of a handle.
+ * param handle The handle to get the cone angle inner from.
+ * return The cone angle inner of the handle.
+ */
+extern AUD_API float AUD_Handle_getConeAngleInner(AUD_Handle* handle);
+
+/**
+ * Sets the cone angle inner of a handle.
+ * param handle The handle to set the cone angle inner from.
+ * param value The new cone angle inner to set.
+ */
+extern AUD_API int AUD_Handle_setConeAngleInner(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the cone angle outer of a handle.
+ * param handle The handle to get the cone angle outer from.
+ * return The cone angle outer of the handle.
+ */
+extern AUD_API float AUD_Handle_getConeAngleOuter(AUD_Handle* handle);
+
+/**
+ * Sets the cone angle outer of a handle.
+ * param handle The handle to set the cone angle outer from.
+ * param value The new cone angle outer to set.
+ */
+extern AUD_API int AUD_Handle_setConeAngleOuter(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the cone volume outer of a handle.
+ * param handle The handle to get the cone volume outer from.
+ * return The cone volume outer of the handle.
+ */
+extern AUD_API float AUD_Handle_getConeVolumeOuter(AUD_Handle* handle);
+
+/**
+ * Sets the cone volume outer of a handle.
+ * param handle The handle to set the cone volume outer from.
+ * param value The new cone volume outer to set.
+ */
+extern AUD_API int AUD_Handle_setConeVolumeOuter(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the distance maximum of a handle.
+ * param handle The handle to get the distance maximum from.
+ * return The distance maximum of the handle.
+ */
+extern AUD_API float AUD_Handle_getDistanceMaximum(AUD_Handle* handle);
+
+/**
+ * Sets the distance maximum of a handle.
+ * param handle The handle to set the distance maximum from.
+ * param value The new distance maximum to set.
+ */
+extern AUD_API int AUD_Handle_setDistanceMaximum(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the distance reference of a handle.
+ * param handle The handle to get the distance reference from.
+ * return The distance reference of the handle.
+ */
+extern AUD_API float AUD_Handle_getDistanceReference(AUD_Handle* handle);
+
+/**
+ * Sets the distance reference of a handle.
+ * param handle The handle to set the distance reference from.
+ * param value The new distance reference to set.
+ */
+extern AUD_API int AUD_Handle_setDistanceReference(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the keep of a handle.
+ * param handle The handle to get the keep from.
+ * return The keep of the handle.
+ */
+extern AUD_API int AUD_Handle_doesKeep(AUD_Handle* handle);
+
+/**
+ * Sets the keep of a handle.
+ * param handle The handle to set the keep from.
+ * param value The new keep to set.
+ */
+extern AUD_API int AUD_Handle_setKeep(AUD_Handle* handle, int value);
+
+/**
+ * Retrieves the location of a handle.
+ * param handle The handle to get the location from.
+ * return The location of the handle.
+ */
+extern AUD_API int AUD_Handle_getLocation(AUD_Handle* handle, float value[3]);
+
+/**
+ * Sets the location of a handle.
+ * param handle The handle to set the location from.
+ * param value The new location to set.
+ */
+extern AUD_API int AUD_Handle_setLocation(AUD_Handle* handle, const float value[3]);
+
+/**
+ * Retrieves the loop count of a handle.
+ * param handle The handle to get the loop count from.
+ * return The loop count of the handle.
+ */
+extern AUD_API int AUD_Handle_getLoopCount(AUD_Handle* handle);
+
+/**
+ * Sets the loop count of a handle.
+ * param handle The handle to set the loop count from.
+ * param value The new loop count to set.
+ */
+extern AUD_API int AUD_Handle_setLoopCount(AUD_Handle* handle, int value);
+
+/**
+ * Retrieves the orientation of a handle.
+ * param handle The handle to get the orientation from.
+ * return The orientation of the handle.
+ */
+extern AUD_API int AUD_Handle_getOrientation(AUD_Handle* handle, float value[4]);
+
+/**
+ * Sets the orientation of a handle.
+ * param handle The handle to set the orientation from.
+ * param value The new orientation to set.
+ */
+extern AUD_API int AUD_Handle_setOrientation(AUD_Handle* handle, const float value[4]);
+
+/**
+ * Retrieves the pitch of a handle.
+ * param handle The handle to get the pitch from.
+ * return The pitch of the handle.
+ */
+extern AUD_API float AUD_Handle_getPitch(AUD_Handle* handle);
+
+/**
+ * Sets the pitch of a handle.
+ * param handle The handle to set the pitch from.
+ * param value The new pitch to set.
+ */
+extern AUD_API int AUD_Handle_setPitch(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the position of a handle.
+ * param handle The handle to get the position from.
+ * return The position of the handle.
+ */
+extern AUD_API float AUD_Handle_getPosition(AUD_Handle* handle);
+
+/**
+ * Sets the position of a handle.
+ * param handle The handle to set the position from.
+ * param value The new position to set.
+ */
+extern AUD_API int AUD_Handle_setPosition(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the relative of a handle.
+ * param handle The handle to get the relative from.
+ * return The relative of the handle.
+ */
+extern AUD_API int AUD_Handle_isRelative(AUD_Handle* handle);
+
+/**
+ * Sets the relative of a handle.
+ * param handle The handle to set the relative from.
+ * param value The new relative to set.
+ */
+extern AUD_API int AUD_Handle_setRelative(AUD_Handle* handle, int value);
+
+/**
+ * Retrieves the status of a handle.
+ * param handle The handle to get the status from.
+ * return The status of the handle.
+ */
+extern AUD_API AUD_Status AUD_Handle_getStatus(AUD_Handle* handle);
+
+/**
+ * Retrieves the velocity of a handle.
+ * param handle The handle to get the velocity from.
+ * return The velocity of the handle.
+ */
+extern AUD_API int AUD_Handle_getVelocity(AUD_Handle* handle, float value[3]);
+
+/**
+ * Sets the velocity of a handle.
+ * param handle The handle to set the velocity from.
+ * param value The new velocity to set.
+ */
+extern AUD_API int AUD_Handle_setVelocity(AUD_Handle* handle, const float value[3]);
+
+/**
+ * Retrieves the volume of a handle.
+ * param handle The handle to get the volume from.
+ * return The volume of the handle.
+ */
+extern AUD_API float AUD_Handle_getVolume(AUD_Handle* handle);
+
+/**
+ * Sets the volume of a handle.
+ * param handle The handle to set the volume from.
+ * param value The new volume to set.
+ */
+extern AUD_API int AUD_Handle_setVolume(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the volume maximum of a handle.
+ * param handle The handle to get the volume maximum from.
+ * return The volume maximum of the handle.
+ */
+extern AUD_API float AUD_Handle_getVolumeMaximum(AUD_Handle* handle);
+
+/**
+ * Sets the volume maximum of a handle.
+ * param handle The handle to set the volume maximum from.
+ * param value The new volume maximum to set.
+ */
+extern AUD_API int AUD_Handle_setVolumeMaximum(AUD_Handle* handle, float value);
+
+/**
+ * Retrieves the volume minimum of a handle.
+ * param handle The handle to get the volume minimum from.
+ * return The volume minimum of the handle.
+ */
+extern AUD_API float AUD_Handle_getVolumeMinimum(AUD_Handle* handle);
+
+/**
+ * Sets the volume minimum of a handle.
+ * param handle The handle to set the volume minimum from.
+ * param value The new volume minimum to set.
+ */
+extern AUD_API int AUD_Handle_setVolumeMinimum(AUD_Handle* handle, float value);
+
+/**
+ * Frees a handle.
+ * \param channel Handle to free.
+ */
+extern AUD_API void AUD_Handle_free(AUD_Handle* channel);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_ImpulseResponse.cpp b/extern/audaspace/bindings/C/AUD_ImpulseResponse.cpp
new file mode 100644
index 00000000000..f3c28d4d660
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_ImpulseResponse.cpp
@@ -0,0 +1,44 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_ImpulseResponse.h"
+
+AUD_API AUD_ImpulseResponse* AUD_ImpulseResponse_create(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_ImpulseResponse(new ImpulseResponse(std::make_shared<StreamBuffer>(*sound)));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_ImpulseResponse_free(AUD_ImpulseResponse* filter)
+{
+ assert(filter);
+ delete filter;
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_ImpulseResponse.h b/extern/audaspace/bindings/C/AUD_ImpulseResponse.h
new file mode 100644
index 00000000000..dad2e87e899
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_ImpulseResponse.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new ImpulseResponse object.
+* \param sound A Sound object representing a impulse response.
+* \return The new ImpulseResponse object.
+*/
+extern AUD_API AUD_ImpulseResponse* AUD_ImpulseResponse_create(AUD_Sound* sound);
+
+/**
+* Deletes a ImpulseResponse object.
+* \param threadPool The ImpulseResponse object to be deleted.
+*/
+extern AUD_API void AUD_ImpulseResponse_free(AUD_ImpulseResponse* filter);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_PlaybackManager.cpp b/extern/audaspace/bindings/C/AUD_PlaybackManager.cpp
new file mode 100644
index 00000000000..69ecb0987e1
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_PlaybackManager.cpp
@@ -0,0 +1,94 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_PlaybackManager.h"
+
+AUD_API AUD_PlaybackManager* AUD_PlaybackManager_create(AUD_Device* device)
+{
+ assert(device);
+
+ try
+ {
+ return new AUD_PlaybackManager(new PlaybackManager(*device));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_PlaybackManager_free(AUD_PlaybackManager* manager)
+{
+ assert(manager);
+ delete manager;
+}
+
+AUD_API void AUD_PlaybackManager_play(AUD_PlaybackManager* manager, AUD_Sound* sound, unsigned int catKey)
+{
+ assert(manager);
+ assert(sound);
+
+ (*manager)->play(*sound, catKey);
+}
+
+AUD_API int AUD_PlaybackManager_resume(AUD_PlaybackManager* manager, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->resume(catKey);
+}
+
+AUD_API int AUD_PlaybackManager_pause(AUD_PlaybackManager* manager, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->pause(catKey);
+}
+
+AUD_API unsigned int AUD_PlaybackManager_addCategory(AUD_PlaybackManager* manager, float volume)
+{
+ assert(manager);
+ return (*manager)->addCategory(volume);
+}
+
+AUD_API float AUD_PlaybackManager_getVolume(AUD_PlaybackManager* manager, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->getVolume(catKey);
+}
+
+AUD_API int AUD_PlaybackManager_setVolume(AUD_PlaybackManager* manager, float volume, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->setVolume(volume, catKey);
+}
+
+AUD_API int AUD_PlaybackManager_stop(AUD_PlaybackManager* manager, unsigned int catKey)
+{
+ assert(manager);
+ return (*manager)->stop(catKey);
+}
+
+AUD_API void AUD_PlaybackManager_clean(AUD_PlaybackManager* manager)
+{
+ assert(manager);
+ (*manager)->clean();
+}
diff --git a/extern/audaspace/bindings/C/AUD_PlaybackManager.h b/extern/audaspace/bindings/C/AUD_PlaybackManager.h
new file mode 100644
index 00000000000..0fa8171599d
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_PlaybackManager.h
@@ -0,0 +1,103 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new PlaybackManager object.
+* \param device The device that will be used to play sounds.
+* \return The new PlaybackManager object.
+*/
+extern AUD_API AUD_PlaybackManager* AUD_PlaybackManager_create(AUD_Device* device);
+
+/**
+* Deletes a PlaybackManager object.
+* \param manager The PlaybackManager object to be deleted.
+*/
+extern AUD_API void AUD_PlaybackManager_free(AUD_PlaybackManager* manager);
+
+/**
+* Plays a sound through the playback manager, adding it into a category.
+* \param manager The PlaybackManager object.
+* \param sound The sound to be played.
+* \param catKey The key of the category into which the sound will be added. If it doesn't exist a new one will be creatd.
+*/
+extern AUD_API void AUD_PlaybackManager_play(AUD_PlaybackManager* manager, AUD_Sound* sound, unsigned int catKey);
+
+/**
+* Resumes the playback of all the paused sounds assigned to a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param catKey The key of the category.
+* \return 0 if the category doesn't exist.
+*/
+extern AUD_API int AUD_PlaybackManager_resume(AUD_PlaybackManager* manager, unsigned int catKey);
+
+/**
+* Pauses all the sounds assigned to a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param catKey The key of the category.
+* \return 0 if the category doesn't exist.
+*/
+extern AUD_API int AUD_PlaybackManager_pause(AUD_PlaybackManager* manager, unsigned int catKey);
+
+/**
+* Adds a new category with a custom volume.
+* \param manager The PlaybackManager object.
+* \param volume The volume value.
+* \return The key of the new category.
+*/
+extern AUD_API unsigned int AUD_PlaybackManager_addCategory(AUD_PlaybackManager* manager, float volume);
+
+/**
+* Retrieves the volume of a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param catKey The key of the category.
+* \return The volume of the category.
+*/
+extern AUD_API float AUD_PlaybackManager_getVolume(AUD_PlaybackManager* manager, unsigned int catKey);
+
+/**
+* Changes the voulume of a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param volume The new volume of the category.
+* \param catKey The key of the category.
+* \return 0 if the category doesn't exist.
+*/
+extern AUD_API int AUD_PlaybackManager_setVolume(AUD_PlaybackManager* manager, float volume, unsigned int catKey);
+
+/**
+* Stops all the sounds assigned to a category of a playback manager.
+* \param manager The PlaybackManager object.
+* \param catKey The key of the category.
+* \return 0 if the category doesn't exist.
+*/
+extern AUD_API int AUD_PlaybackManager_stop(AUD_PlaybackManager* manager, unsigned int catKey);
+
+/**
+* Cleans all the invalid handles in a playback manager
+* \param manager The PlaybackManager object.
+*/
+extern AUD_API void AUD_PlaybackManager_clean(AUD_PlaybackManager* manager);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Sequence.cpp b/extern/audaspace/bindings/C/AUD_Sequence.cpp
new file mode 100644
index 00000000000..d278cb148a1
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Sequence.cpp
@@ -0,0 +1,315 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "devices/I3DDevice.h"
+#include "devices/DeviceManager.h"
+#include "sequence/Sequence.h"
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Sequence.h"
+
+AUD_API AUD_Sound* AUD_Sequence_create(float fps, int muted)
+{
+ // specs are changed at a later point!
+ Specs specs;
+ specs.channels = CHANNELS_STEREO;
+ specs.rate = RATE_48000;
+ AUD_Sound* sequence = new AUD_Sound(std::shared_ptr<Sequence>(new Sequence(specs, fps, muted)));
+ return sequence;
+}
+
+AUD_API void AUD_Sequence_free(AUD_Sound* sequence)
+{
+ delete sequence;
+}
+
+AUD_API AUD_SequenceEntry* AUD_Sequence_add(AUD_Sound* sequence, AUD_Sound* sound, float begin, float end, float skip)
+{
+ if(!sound)
+ return new AUD_SequenceEntry(((Sequence *)sequence->get())->add(AUD_Sound(), begin, end, skip));
+ return new AUD_SequenceEntry(((Sequence *)sequence->get())->add(*sound, begin, end, skip));
+}
+
+AUD_API void AUD_Sequence_remove(AUD_Sound* sequence, AUD_SequenceEntry* entry)
+{
+ dynamic_cast<Sequence *>(sequence->get())->remove(*entry);
+ delete entry;
+}
+
+AUD_API void AUD_Sequence_setAnimationData(AUD_Sound* sequence, AUD_AnimateablePropertyType type, int frame, float* data, char animated)
+{
+ AnimateableProperty* prop = dynamic_cast<Sequence *>(sequence->get())->getAnimProperty(static_cast<AnimateablePropertyType>(type));
+ if(animated)
+ {
+ if(frame >= 0)
+ {
+ prop->write(data, frame, 1);
+ }
+ }
+ else
+ {
+ prop->write(data);
+ }
+}
+
+AUD_API AUD_DistanceModel AUD_Sequence_getDistanceModel(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return static_cast<AUD_DistanceModel>(dynamic_cast<Sequence *>(sequence->get())->getDistanceModel());
+}
+
+AUD_API void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setDistanceModel(static_cast<DistanceModel>(value));
+}
+
+AUD_API float AUD_Sequence_getDopplerFactor(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return dynamic_cast<Sequence *>(sequence->get())->getDopplerFactor();
+}
+
+AUD_API void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setDopplerFactor(value);
+}
+
+AUD_API float AUD_Sequence_getFPS(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return dynamic_cast<Sequence *>(sequence->get())->getFPS();
+}
+
+AUD_API void AUD_Sequence_setFPS(AUD_Sound* sequence, float value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setFPS(value);
+}
+
+AUD_API int AUD_Sequence_isMuted(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return dynamic_cast<Sequence *>(sequence->get())->isMuted();
+}
+
+AUD_API void AUD_Sequence_setMuted(AUD_Sound* sequence, int value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->mute(value);
+}
+
+static inline AUD_Specs convSpecToC(aud::Specs specs)
+{
+ AUD_Specs s;
+ s.channels = static_cast<AUD_Channels>(specs.channels);
+ s.rate = static_cast<AUD_SampleRate>(specs.rate);
+ return s;
+}
+
+static inline aud::Specs convCToSpec(AUD_Specs specs)
+{
+ aud::Specs s;
+ s.channels = static_cast<Channels>(specs.channels);
+ s.rate = static_cast<SampleRate>(specs.rate);
+ return s;
+}
+
+AUD_API AUD_Specs AUD_Sequence_getSpecs(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return convSpecToC(dynamic_cast<Sequence *>(sequence->get())->getSpecs());
+}
+
+AUD_API void AUD_Sequence_setSpecs(AUD_Sound* sequence, AUD_Specs value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setSpecs(convCToSpec(value));
+}
+
+AUD_API float AUD_Sequence_getSpeedOfSound(AUD_Sound* sequence)
+{
+ assert(sequence);
+ return dynamic_cast<Sequence *>(sequence->get())->getSpeedOfSound();
+}
+
+AUD_API void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value)
+{
+ assert(sequence);
+ dynamic_cast<Sequence *>(sequence->get())->setSpeedOfSound(value);
+}
+
+
+
+AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, float begin, float end, float skip)
+{
+ (*entry)->move(begin, end, skip);
+}
+
+AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated)
+{
+ AnimateableProperty* prop = (*entry)->getAnimProperty(static_cast<AnimateablePropertyType>(type));
+ if(animated)
+ {
+ if(frame >= 0)
+ prop->write(data, frame, 1);
+ }
+ else
+ {
+ prop->write(data);
+ }
+}
+
+AUD_API float AUD_SequenceEntry_getAttenuation(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getAttenuation();
+}
+
+AUD_API void AUD_SequenceEntry_setAttenuation(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setAttenuation(value);
+}
+
+AUD_API float AUD_SequenceEntry_getConeAngleInner(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getConeAngleInner();
+}
+
+AUD_API void AUD_SequenceEntry_setConeAngleInner(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setConeAngleInner(value);
+}
+
+AUD_API float AUD_SequenceEntry_getConeAngleOuter(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getConeAngleOuter();
+}
+
+AUD_API void AUD_SequenceEntry_setConeAngleOuter(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setConeAngleOuter(value);
+}
+
+AUD_API float AUD_SequenceEntry_getConeVolumeOuter(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getConeVolumeOuter();
+}
+
+AUD_API void AUD_SequenceEntry_setConeVolumeOuter(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setConeVolumeOuter(value);
+}
+
+AUD_API float AUD_SequenceEntry_getDistanceMaximum(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getDistanceMaximum();
+}
+
+AUD_API void AUD_SequenceEntry_setDistanceMaximum(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setDistanceMaximum(value);
+}
+
+AUD_API float AUD_SequenceEntry_getDistanceReference(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getDistanceReference();
+}
+
+AUD_API void AUD_SequenceEntry_setDistanceReference(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setDistanceReference(value);
+}
+
+AUD_API int AUD_SequenceEntry_isMuted(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->isMuted();
+}
+
+AUD_API void AUD_SequenceEntry_setMuted(AUD_SequenceEntry* sequence_entry, int value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->mute(value);
+}
+
+AUD_API int AUD_SequenceEntry_isRelative(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->isRelative();
+}
+
+AUD_API void AUD_SequenceEntry_setRelative(AUD_SequenceEntry* sequence_entry, int value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setRelative(value);
+}
+
+AUD_API AUD_Sound* AUD_SequenceEntry_getSound(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return new std::shared_ptr<ISound>((*sequence_entry)->getSound());
+}
+
+AUD_API void AUD_SequenceEntry_setSound(AUD_SequenceEntry* sequence_entry, AUD_Sound* value)
+{
+ assert(sequence_entry);
+ if(value)
+ (*sequence_entry)->setSound(*value);
+ else
+ (*sequence_entry)->setSound(AUD_Sound());
+}
+
+AUD_API float AUD_SequenceEntry_getVolumeMaximum(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getVolumeMaximum();
+}
+
+AUD_API void AUD_SequenceEntry_setVolumeMaximum(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setVolumeMaximum(value);
+}
+
+AUD_API float AUD_SequenceEntry_getVolumeMinimum(AUD_SequenceEntry* sequence_entry)
+{
+ assert(sequence_entry);
+ return (*sequence_entry)->getVolumeMinimum();
+}
+
+AUD_API void AUD_SequenceEntry_setVolumeMinimum(AUD_SequenceEntry* sequence_entry, float value)
+{
+ assert(sequence_entry);
+ (*sequence_entry)->setVolumeMinimum(value);
+}
diff --git a/extern/audaspace/bindings/C/AUD_Sequence.h b/extern/audaspace/bindings/C/AUD_Sequence.h
new file mode 100644
index 00000000000..668960c7d50
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Sequence.h
@@ -0,0 +1,338 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Device.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/// Possible animatable properties for Sequence Factories and Entries.
+typedef enum
+{
+ AUD_AP_VOLUME,
+ AUD_AP_PANNING,
+ AUD_AP_PITCH,
+ AUD_AP_LOCATION,
+ AUD_AP_ORIENTATION
+} AUD_AnimateablePropertyType;
+
+/**
+ * Creates a new sequenced sound scene.
+ * \param fps The FPS of the scene.
+ * \param muted Whether the scene is muted.
+ * \return The new sound scene.
+ */
+extern AUD_API AUD_Sound* AUD_Sequence_create(float fps, int muted);
+
+/**
+ * Deletes a sound scene.
+ * \param sequence The sound scene.
+ */
+extern AUD_API void AUD_Sequence_free(AUD_Sound* sequence);
+
+/**
+ * Adds a new entry to the scene.
+ * \param sequence The sound 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.
+ */
+extern AUD_API AUD_SequenceEntry* AUD_Sequence_add(AUD_Sound* sequence, AUD_Sound* sound, float begin, float end, float skip);
+
+/**
+ * Removes an entry from the scene.
+ * \param sequence The sound scene.
+ * \param entry The entry to remove.
+ */
+extern AUD_API void AUD_Sequence_remove(AUD_Sound* sequence, AUD_SequenceEntry* entry);
+
+/**
+ * Writes animation data to a sequence.
+ * \param sequence The sound scene.
+ * \param type The type of animation data.
+ * \param frame The frame this data is for.
+ * \param data The data to write.
+ * \param animated Whether the attribute is animated.
+ */
+extern AUD_API void AUD_Sequence_setAnimationData(AUD_Sound* sequence, AUD_AnimateablePropertyType type, int frame, float* data, char animated);
+
+/**
+ * Retrieves the distance model of a sequence.
+ * param sequence The sequence to get the distance model from.
+ * return The distance model of the sequence.
+ */
+extern AUD_API AUD_DistanceModel AUD_Sequence_getDistanceModel(AUD_Sound* sequence);
+
+/**
+ * Sets the distance model of a sequence.
+ * param sequence The sequence to set the distance model from.
+ * param value The new distance model to set.
+ */
+extern AUD_API void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value);
+
+/**
+ * Retrieves the doppler factor of a sequence.
+ * param sequence The sequence to get the doppler factor from.
+ * return The doppler factor of the sequence.
+ */
+extern AUD_API float AUD_Sequence_getDopplerFactor(AUD_Sound* sequence);
+
+/**
+ * Sets the doppler factor of a sequence.
+ * param sequence The sequence to set the doppler factor from.
+ * param value The new doppler factor to set.
+ */
+extern AUD_API void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value);
+
+/**
+ * Retrieves the fps of a sequence.
+ * param sequence The sequence to get the fps from.
+ * return The fps of the sequence.
+ */
+extern AUD_API float AUD_Sequence_getFPS(AUD_Sound* sequence);
+
+/**
+ * Sets the fps of a sequence.
+ * param sequence The sequence to set the fps from.
+ * param value The new fps to set.
+ */
+extern AUD_API void AUD_Sequence_setFPS(AUD_Sound* sequence, float value);
+
+/**
+ * Retrieves the muted of a sequence.
+ * param sequence The sequence to get the muted from.
+ * return The muted of the sequence.
+ */
+extern AUD_API int AUD_Sequence_isMuted(AUD_Sound* sequence);
+
+/**
+ * Sets the muted of a sequence.
+ * param sequence The sequence to set the muted from.
+ * param value The new muted to set.
+ */
+extern AUD_API void AUD_Sequence_setMuted(AUD_Sound* sequence, int value);
+
+/**
+ * Retrieves the specs of a sequence.
+ * param sequence The sequence to get the specs from.
+ * return The specs of the sequence.
+ */
+extern AUD_API AUD_Specs AUD_Sequence_getSpecs(AUD_Sound* sequence);
+
+/**
+ * Sets the specs of a sequence.
+ * param sequence The sequence to set the specs from.
+ * param value The new specs to set.
+ */
+extern AUD_API void AUD_Sequence_setSpecs(AUD_Sound* sequence, AUD_Specs value);
+
+/**
+ * Retrieves the speed of sound of a sequence.
+ * param sequence The sequence to get the speed of sound from.
+ * return The speed of sound of the sequence.
+ */
+extern AUD_API float AUD_Sequence_getSpeedOfSound(AUD_Sound* sequence);
+
+/**
+ * Sets the speed of sound of a sequence.
+ * param sequence The sequence to set the speed of sound from.
+ * param value The new speed of sound to set.
+ */
+extern AUD_API void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value);
+
+
+
+/**
+ * Moves the entry.
+ * \param entry The sequenced entry.
+ * \param begin The new start time.
+ * \param end The new end time or a negative value if unknown.
+ * \param skip How many seconds to skip at the beginning.
+ */
+extern AUD_API void AUD_SequenceEntry_move(AUD_SequenceEntry* entry, float begin, float end, float skip);
+
+/**
+ * Writes animation data to a sequenced entry.
+ * \param entry The sequenced entry.
+ * \param type The type of animation data.
+ * \param frame The frame this data is for.
+ * \param data The data to write.
+ * \param animated Whether the attribute is animated.
+ */
+extern AUD_API void AUD_SequenceEntry_setAnimationData(AUD_SequenceEntry* entry, AUD_AnimateablePropertyType type, int frame, float* data, char animated);
+
+/**
+ * Retrieves the attenuation of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the attenuation from.
+ * return The attenuation of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getAttenuation(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the attenuation of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the attenuation from.
+ * param value The new attenuation to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setAttenuation(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the cone angle inner of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the cone angle inner from.
+ * return The cone angle inner of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getConeAngleInner(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the cone angle inner of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the cone angle inner from.
+ * param value The new cone angle inner to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setConeAngleInner(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the cone angle outer of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the cone angle outer from.
+ * return The cone angle outer of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getConeAngleOuter(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the cone angle outer of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the cone angle outer from.
+ * param value The new cone angle outer to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setConeAngleOuter(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the cone volume outer of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the cone volume outer from.
+ * return The cone volume outer of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getConeVolumeOuter(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the cone volume outer of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the cone volume outer from.
+ * param value The new cone volume outer to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setConeVolumeOuter(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the distance maximum of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the distance maximum from.
+ * return The distance maximum of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getDistanceMaximum(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the distance maximum of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the distance maximum from.
+ * param value The new distance maximum to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setDistanceMaximum(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the distance reference of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the distance reference from.
+ * return The distance reference of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getDistanceReference(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the distance reference of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the distance reference from.
+ * param value The new distance reference to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setDistanceReference(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the muted of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the muted from.
+ * return The muted of the sequence_entry.
+ */
+extern AUD_API int AUD_SequenceEntry_isMuted(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the muted of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the muted from.
+ * param value The new muted to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setMuted(AUD_SequenceEntry* sequence_entry, int value);
+
+/**
+ * Retrieves the relative of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the relative from.
+ * return The relative of the sequence_entry.
+ */
+extern AUD_API int AUD_SequenceEntry_isRelative(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the relative of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the relative from.
+ * param value The new relative to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setRelative(AUD_SequenceEntry* sequence_entry, int value);
+
+/**
+ * Retrieves the sound of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the sound from.
+ * return The sound of the sequence_entry.
+ */
+extern AUD_API AUD_Sound* AUD_SequenceEntry_getSound(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the sound of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the sound from.
+ * param value The new sound to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setSound(AUD_SequenceEntry* sequence_entry, AUD_Sound* value);
+
+/**
+ * Retrieves the volume maximum of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the volume maximum from.
+ * return The volume maximum of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getVolumeMaximum(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the volume maximum of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the volume maximum from.
+ * param value The new volume maximum to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setVolumeMaximum(AUD_SequenceEntry* sequence_entry, float value);
+
+/**
+ * Retrieves the volume minimum of a sequence_entry.
+ * param sequence_entry The sequence_entry to get the volume minimum from.
+ * return The volume minimum of the sequence_entry.
+ */
+extern AUD_API float AUD_SequenceEntry_getVolumeMinimum(AUD_SequenceEntry* sequence_entry);
+
+/**
+ * Sets the volume minimum of a sequence_entry.
+ * param sequence_entry The sequence_entry to set the volume minimum from.
+ * param value The new volume minimum to set.
+ */
+extern AUD_API void AUD_SequenceEntry_setVolumeMinimum(AUD_SequenceEntry* sequence_entry, float value);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Sound.cpp b/extern/audaspace/bindings/C/AUD_Sound.cpp
new file mode 100644
index 00000000000..30860acde62
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Sound.cpp
@@ -0,0 +1,709 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/Sawtooth.h"
+#include "generator/Sine.h"
+#include "generator/Silence.h"
+#include "generator/Square.h"
+#include "generator/Triangle.h"
+#include "file/File.h"
+#include "file/FileWriter.h"
+#include "util/StreamBuffer.h"
+#include "fx/Accumulator.h"
+#include "fx/ADSR.h"
+#include "fx/Delay.h"
+#include "fx/Envelope.h"
+#include "fx/Fader.h"
+#include "fx/Highpass.h"
+#include "fx/IIRFilter.h"
+#include "fx/Limiter.h"
+#include "fx/Loop.h"
+#include "fx/Lowpass.h"
+#include "fx/Pitch.h"
+#include "fx/Reverse.h"
+#include "fx/Sum.h"
+#include "fx/Threshold.h"
+#include "fx/Volume.h"
+#include "fx/SoundList.h"
+#include "fx/MutableSound.h"
+#include "sequence/Double.h"
+#include "sequence/Superpose.h"
+#include "sequence/PingPong.h"
+#include "respec/LinearResample.h"
+#include "respec/JOSResample.h"
+#include "respec/JOSResampleReader.h"
+#include "respec/ChannelMapper.h"
+#include "respec/ChannelMapperReader.h"
+#include "util/Buffer.h"
+#include "Exception.h"
+
+#ifdef WITH_CONVOLUTION
+#include "fx/BinauralSound.h"
+#include "fx/ConvolverSound.h"
+#endif
+
+#include <cassert>
+#include <cstring>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Sound.h"
+
+static inline AUD_Specs convSpecToC(aud::Specs specs)
+{
+ AUD_Specs s;
+ s.channels = static_cast<AUD_Channels>(specs.channels);
+ s.rate = static_cast<AUD_SampleRate>(specs.rate);
+ return s;
+}
+
+static inline aud::Specs convCToSpec(AUD_Specs specs)
+{
+ aud::Specs s;
+ s.channels = static_cast<Channels>(specs.channels);
+ s.rate = static_cast<SampleRate>(specs.rate);
+ return s;
+}
+
+AUD_API AUD_Specs AUD_Sound_getSpecs(AUD_Sound* sound)
+{
+ assert(sound);
+
+ return convSpecToC((*sound)->createReader()->getSpecs());
+}
+
+AUD_API int AUD_Sound_getLength(AUD_Sound* sound)
+{
+ assert(sound);
+
+ return (*sound)->createReader()->getLength();
+}
+
+AUD_API sample_t* AUD_Sound_data(AUD_Sound* sound, int* length, AUD_Specs* specs)
+{
+ assert(sound);
+ assert(length);
+ assert(specs);
+
+ auto stream_buffer = std::dynamic_pointer_cast<StreamBuffer>(*sound);
+ if(!stream_buffer)
+ stream_buffer = std::make_shared<StreamBuffer>(*sound);
+ *specs = convSpecToC(stream_buffer->getSpecs());
+ auto buffer = stream_buffer->getBuffer();
+
+ *length = buffer->getSize() / AUD_SAMPLE_SIZE((*specs));
+
+ sample_t* data = new sample_t[buffer->getSize()];
+
+ std::memcpy(data, buffer->getBuffer(), buffer->getSize());
+
+ return data;
+}
+
+AUD_API void AUD_Sound_freeData(sample_t* data)
+{
+ delete[] data;
+}
+
+AUD_API const char* AUD_Sound_write(AUD_Sound* sound, const char* filename, AUD_SampleRate rate, AUD_Channels channels, AUD_SampleFormat format, AUD_Container container, AUD_Codec codec, int bitrate, int buffersize)
+{
+ assert(sound);
+ assert(filename);
+
+ try
+ {
+ std::shared_ptr<IReader> reader = (*sound)->createReader();
+
+ DeviceSpecs specs;
+ specs.specs = reader->getSpecs();
+
+ if((rate != RATE_INVALID) && (specs.rate != rate))
+ {
+ specs.rate = rate;
+ reader = std::make_shared<JOSResampleReader>(reader, rate);
+ }
+
+ if((channels != AUD_CHANNELS_INVALID) && (specs.channels != static_cast<Channels>(channels)))
+ {
+ specs.channels = static_cast<Channels>(channels);
+ reader = std::make_shared<ChannelMapperReader>(reader, specs.channels);
+ }
+
+ if(format == AUD_FORMAT_INVALID)
+ format = AUD_FORMAT_S16;
+ specs.format = static_cast<SampleFormat>(format);
+
+ const char* invalid_container_error = "Container could not be determined from filename.";
+
+ if(container == AUD_CONTAINER_INVALID)
+ {
+ std::string path = filename;
+
+ if(path.length() < 4)
+ return invalid_container_error;
+
+ std::string extension = path.substr(path.length() - 4);
+
+ if(extension == ".ac3")
+ container = AUD_CONTAINER_AC3;
+ else if(extension == "flac")
+ container = AUD_CONTAINER_FLAC;
+ else if(extension == ".mkv")
+ container = AUD_CONTAINER_MATROSKA;
+ else if(extension == ".mp2")
+ container = AUD_CONTAINER_MP2;
+ else if(extension == ".mp3")
+ container = AUD_CONTAINER_MP3;
+ else if(extension == ".ogg")
+ container = AUD_CONTAINER_OGG;
+ else if(extension == ".wav")
+ container = AUD_CONTAINER_WAV;
+ else
+ return invalid_container_error;
+ }
+
+ if(codec == AUD_CODEC_INVALID)
+ {
+ switch(container)
+ {
+ case AUD_CONTAINER_AC3:
+ codec = AUD_CODEC_AC3;
+ break;
+ case AUD_CONTAINER_FLAC:
+ codec = AUD_CODEC_FLAC;
+ break;
+ case AUD_CONTAINER_MATROSKA:
+ codec = AUD_CODEC_OPUS;
+ break;
+ case AUD_CONTAINER_MP2:
+ codec = AUD_CODEC_MP2;
+ break;
+ case AUD_CONTAINER_MP3:
+ codec = AUD_CODEC_MP3;
+ break;
+ case AUD_CONTAINER_OGG:
+ codec = AUD_CODEC_VORBIS;
+ break;
+ case AUD_CONTAINER_WAV:
+ codec = AUD_CODEC_PCM;
+ break;
+ default:
+ return "Unknown container, cannot select default codec.";
+ }
+ }
+
+ if(buffersize <= 0)
+ buffersize = AUD_DEFAULT_BUFFER_SIZE;
+
+ std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, specs, static_cast<Container>(container), static_cast<Codec>(codec), bitrate);
+ FileWriter::writeReader(reader, writer, 0, buffersize);
+ }
+ catch(Exception& e)
+ {
+ return "An exception occured while writing.";
+ }
+
+ return nullptr;
+}
+
+AUD_API AUD_Sound* AUD_Sound_buffer(sample_t* data, int length, AUD_Specs specs)
+{
+ assert(data);
+
+ if(length <= 0 || specs.rate <= 0 || specs.channels <= 0)
+ {
+ return nullptr;
+ }
+
+ int size = length * AUD_SAMPLE_SIZE(specs);
+
+ std::shared_ptr<Buffer> buffer = std::make_shared<Buffer>(size);
+
+ std::memcpy(buffer->getBuffer(), data, size);
+
+ try
+ {
+ return new AUD_Sound(new StreamBuffer(buffer, convCToSpec(specs)));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_bufferFile(unsigned char* buffer, int size)
+{
+ assert(buffer);
+ return new AUD_Sound(new File(buffer, size));
+}
+
+AUD_API AUD_Sound* AUD_Sound_cache(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new StreamBuffer(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_file(const char* filename)
+{
+ assert(filename);
+ return new AUD_Sound(new File(filename));
+}
+
+AUD_API AUD_Sound* AUD_Sound_sawtooth(float frequency, AUD_SampleRate rate)
+{
+ return new AUD_Sound(new Sawtooth(frequency, rate));
+}
+
+AUD_API AUD_Sound*AUD_Sound_silence()
+{
+ return new AUD_Sound(new Silence());
+}
+
+AUD_API AUD_Sound* AUD_Sound_sine(float frequency, AUD_SampleRate rate)
+{
+ return new AUD_Sound(new Sine(frequency, rate));
+}
+
+AUD_API AUD_Sound* AUD_Sound_square(float frequency, AUD_SampleRate rate)
+{
+ return new AUD_Sound(new Square(frequency, rate));
+}
+
+AUD_API AUD_Sound* AUD_Sound_triangle(float frequency, AUD_SampleRate rate)
+{
+ return new AUD_Sound(new Triangle(frequency, rate));
+}
+
+AUD_API AUD_Sound* AUD_Sound_accumulate(AUD_Sound* sound, int additive)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Accumulator(*sound, additive));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_ADSR(AUD_Sound* sound, float attack, float decay, float sustain, float release)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new ADSR(*sound, attack, decay, sustain, release));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_delay(AUD_Sound* sound, float delay)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Delay(*sound, delay));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_envelope(AUD_Sound* sound, float attack, float release, float threshold, float arthreshold)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Envelope(*sound, attack, release, threshold, arthreshold));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_fadein(AUD_Sound* sound, float start, float length)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Fader(*sound, FADE_IN, start, length));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_fadeout(AUD_Sound* sound, float start, float length)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Fader(*sound, FADE_OUT, start, length));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_filter(AUD_Sound* sound, float* b, int b_length, float* a, int a_length)
+{
+ assert(sound);
+
+ try
+ {
+ std::vector<float> a_coeff, b_coeff;
+
+ if(b)
+ for(int i = 0; i < b_length; i++)
+ b_coeff.push_back(b[i]);
+
+ if(a)
+ {
+ for(int i = 0; i < a_length; i++)
+ a_coeff.push_back(a[i]);
+
+ if(*a == 0.0f)
+ a_coeff[0] = 1.0f;
+ }
+
+ return new AUD_Sound(new IIRFilter(*sound, b_coeff, a_coeff));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_highpass(AUD_Sound* sound, float frequency, float Q)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Highpass(*sound, frequency, Q));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_limit(AUD_Sound* sound, float start, float end)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Limiter(*sound, start, end));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_loop(AUD_Sound* sound, int count)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Loop(*sound, count));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_lowpass(AUD_Sound* sound, float frequency, float Q)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Lowpass(*sound, frequency, Q));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_pitch(AUD_Sound* sound, float factor)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Pitch(*sound, factor));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_rechannel(AUD_Sound* sound, AUD_Channels channels)
+{
+ assert(sound);
+
+ try
+ {
+ DeviceSpecs specs;
+ specs.channels = static_cast<Channels>(channels);
+ specs.rate = RATE_INVALID;
+ specs.format = FORMAT_INVALID;
+ return new AUD_Sound(new ChannelMapper(*sound, specs));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_resample(AUD_Sound* sound, AUD_SampleRate rate, bool high_quality)
+{
+ assert(sound);
+
+ try
+ {
+ DeviceSpecs specs;
+ specs.channels = CHANNELS_INVALID;
+ specs.rate = rate;
+ specs.format = FORMAT_INVALID;
+ if(high_quality)
+ return new AUD_Sound(new JOSResample(*sound, specs));
+ else
+ return new AUD_Sound(new LinearResample(*sound, specs));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_reverse(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Reverse(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_sum(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Sum(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_threshold(AUD_Sound* sound, float threshold)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Threshold(*sound, threshold));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_volume(AUD_Sound* sound, float volume)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new Volume(*sound, volume));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_join(AUD_Sound* first, AUD_Sound* second)
+{
+ assert(first);
+ assert(second);
+
+ try
+ {
+ return new AUD_Sound(new Double(*first, *second));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_mix(AUD_Sound* first, AUD_Sound* second)
+{
+ assert(first);
+ assert(second);
+
+ try
+ {
+ return new AUD_Sound(new Superpose(*first, *second));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_pingpong(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new PingPong(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_Sound_free(AUD_Sound* sound)
+{
+ assert(sound);
+ delete sound;
+}
+
+AUD_API AUD_Sound* AUD_Sound_copy(AUD_Sound* sound)
+{
+ return new std::shared_ptr<ISound>(*sound);
+}
+
+AUD_API AUD_Sound* AUD_Sound_list(int random)
+{
+ try
+ {
+ return new AUD_Sound(new SoundList(random));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API int AUD_SoundList_addSound(AUD_Sound* list, AUD_Sound* sound)
+{
+ assert(sound);
+ assert(list);
+
+ std::shared_ptr<SoundList> s = std::dynamic_pointer_cast<SoundList>(*list);
+ if(s.get())
+ {
+ s->addSound(*sound);
+ return 1;
+ }
+ else
+ return 0;
+
+}
+
+AUD_API AUD_Sound* AUD_Sound_mutable(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_Sound(new MutableSound(*sound));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+#ifdef WITH_CONVOLUTION
+
+AUD_API AUD_Sound* AUD_Sound_Convolver(AUD_Sound* sound, AUD_ImpulseResponse* filter, AUD_ThreadPool* threadPool)
+{
+ assert(sound);
+ assert(filter);
+ assert(threadPool);
+
+ try
+ {
+ return new AUD_Sound(new ConvolverSound(*sound, *filter, *threadPool));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API AUD_Sound* AUD_Sound_Binaural(AUD_Sound* sound, AUD_HRTF* hrtfs, AUD_Source* source, AUD_ThreadPool* threadPool)
+{
+ assert(sound);
+ assert(hrtfs);
+ assert(source);
+ assert(threadPool);
+
+ try
+ {
+ return new AUD_Sound(new BinauralSound(*sound, *hrtfs, *source, *threadPool));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Sound.h b/extern/audaspace/bindings/C/AUD_Sound.h
new file mode 100644
index 00000000000..b18e3c3a8eb
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Sound.h
@@ -0,0 +1,370 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Retrieves the sample specification of the sound.
+ * \param sound The sound to retrieve from.
+ * \return The sample specification of the sound.
+ * \note This function creates a reader from the sound and deletes it again.
+ */
+extern AUD_API AUD_Specs AUD_Sound_getSpecs(AUD_Sound* sound);
+
+/**
+ * Retrieves the approximate length of the sound.
+ * \param sound The sound to retrieve from.
+ * \return The length of the sound in samples.
+ * \note This function creates a reader from the sound and deletes it again.
+ */
+extern AUD_API int AUD_getLength(AUD_Sound* sound);
+
+/**
+ * Reads a sound's samples into memory.
+ * \param sound The sound to read.
+ * \param length Pointer to store the length of memory read.
+ * \param specs Pointer to store the data's sample specification.
+ * \return A pointer to the sample data.
+ * \warning The data has to be freed with AUD_Sound_freeData.
+ */
+extern AUD_API sample_t* AUD_Sound_data(AUD_Sound* sound, int* length, AUD_Specs* specs);
+
+/**
+ * Frees a buffer previously allocated with AUD_Sound_data.
+ * \param data The buffer to be freed.
+ */
+extern AUD_API void AUD_Sound_freeData(sample_t* data);
+
+/**
+ * Writes the sound to a file.
+ * \param sound The sound to write.
+ * \param filename The path to write to..
+ * \param rate The sample rate to write with.
+ * \param channels The number of channels to write with.
+ * \param format The sample format to write with.
+ * \param container The container format for the file.
+ * \param codec The codec to use in the file.
+ * \param bitrate The bitrate to write with.
+ * \param buffersize The size of the writing buffer.
+ * \return A nullptr or an error message in case of error.
+ * \note Most parameters can be set to zero for default values.
+ */
+extern AUD_API const char* AUD_Sound_write(AUD_Sound* sound, const char* filename, AUD_SampleRate rate, AUD_Channels channels, AUD_SampleFormat format, AUD_Container container, AUD_Codec codec, int bitrate, int buffersize);
+
+/**
+ * Creates a sound from a data buffer.
+ * \param data The data as interleaved samples.
+ * \param length The data's length in samples.
+ * \param specs The data's sample specification.
+ * \return A handle of the sound.
+ * \note The data gets copied to an internal memory buffer.
+ * The pointer does not need to stay valid for the lifetime of the object.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_buffer(sample_t* data, int length, AUD_Specs specs);
+
+/**
+ * Loads a sound file from a memory buffer.
+ * \param buffer The buffer which contains the sound file.
+ * \param size The size of the buffer.
+ * \return A handle of the sound file.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_bufferFile(unsigned char* buffer, int size);
+
+/**
+ * Caches a sound into a memory buffer.
+ * \param sound The sound to cache.
+ * \return A handle of the cached sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_cache(AUD_Sound* sound);
+
+/**
+ * Loads a sound file.
+ * \param filename The filename of the sound file.
+ * \return A handle of the sound file.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_file(const char* filename);
+
+/**
+ * Creates a sawtooth sound.
+ * \param frequency The frequency of the generated sawtooth sound.
+ * \param rate The sample rate of the sawtooth sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_sawtooth(float frequency, AUD_SampleRate rate);
+
+/**
+ * Creates a quiet sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_silence();
+
+/**
+ * Creates a sine sound.
+ * \param frequency The frequency of the generated sine sound.
+ * \param rate The sample rate of the sine sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_sine(float frequency, AUD_SampleRate rate);
+
+/**
+ * Creates a square sound.
+ * \param frequency The frequency of the generated square sound.
+ * \param rate The sample rate of the square sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_square(float frequency, AUD_SampleRate rate);
+
+/**
+ * Creates a triangle sound.
+ * \param frequency The frequency of the generated triangle sound.
+ * \param rate The sample rate of the triangle sound.
+ * \return A handle of the sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_triangle(float frequency, AUD_SampleRate rate);
+
+/**
+ * Accumulates a sound by summing over positive input differences thus generating a monotonic sigal.
+ * If additivity is set to true negative input differences get added too, but positive ones with a factor of two.
+ * Note that with additivity the signal is not monotonic anymore.
+ * \param sound The sound to accumulate.
+ * \param additive Whether the accumulation should be additive or not.
+ * \return A handle of the accumulated sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_accumulate(AUD_Sound* sound, int additive);
+
+/**
+ * Attack-Decay-Sustain-Release envelopes the volume of a sound.
+ * Note: there is currently no way to trigger the release with this API.
+ * \param sound The sound to filter.
+ * \param attack The attack time in seconds.
+ * \param decay The decay time in seconds.
+ * \param sustain The sustain level.
+ * \param release The release time in seconds.
+ * \return A handle of the filtered sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_ADSR(AUD_Sound* sound, float attack, float decay, float sustain, float release);
+
+/**
+ * Delays a sound.
+ * \param sound The sound to dealy.
+ * \param delay The delay in seconds.
+ * \return A handle of the delayed sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_delay(AUD_Sound* sound, float delay);
+
+/**
+ * Envelopes a sound.
+ * \param sound The sound to envelope.
+ * \param attack The attack factor.
+ * \param release The release factor.
+ * \param threshold The general threshold value.
+ * \param arthreshold The attack/release threshold value.
+ * \return A handle of the enveloped sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_envelope(AUD_Sound* sound, float attack, float release, float threshold, float arthreshold);
+
+/**
+ * Fade in a sound.
+ * \param sound The sound to be fade in.
+ * \param start The time when the fading should start in seconds.
+ * \param length The duration of the fade in seconds.
+ * \return A handle of the faded sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_fadein(AUD_Sound* sound, float start, float length);
+
+/**
+ * Fade out a sound.
+ * \param sound The sound to be fade out.
+ * \param start The time when the fading should start in seconds.
+ * \param length The duration of the fade in seconds.
+ * \return A handle of the faded sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_fadeout(AUD_Sound* sound, float start, float length);
+
+/**
+ * Filter a sound.
+ * \param sound The sound to be filtered.
+ * \param b The nominator filter coefficients, may be NULL.
+ * \param b_length The length of the b array.
+ * \param a The denominator filter coefficients, may be NULL.
+ * \param a_length The length of the a array.
+ * \return A handle of the filtered sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_filter(AUD_Sound* sound, float* b, int b_length, float* a, int a_length);
+
+/**
+ * Highpass filters a sound.
+ * \param sound The sound to filter.
+ * \param frequency The filter cut-off frequency.
+ * \param Q The filter quality. If usunsure which value to use, pass 1.0f.
+ * \return A handle of the filtered sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_highpass(AUD_Sound* sound, float frequency, float Q);
+
+/**
+ * Limits a sound.
+ * \param sound The sound to limit.
+ * \param start The start time in seconds.
+ * \param end The stop time in seconds.
+ * \return A handle of the limited sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_limit(AUD_Sound* sound, float start, float end);
+
+/**
+ * Loops a sound.
+ * \param sound The sound to loop.
+ * \param count How often the sound should be looped. Negative values mean endlessly.
+ * \return A handle of the looped sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_loop(AUD_Sound* sound, int count);
+
+/**
+ * Lowpass filters a sound.
+ * \param sound The sound to filter.
+ * \param frequency The filter cut-off frequency.
+ * \param Q The filter quality. If usunsure which value to use, pass 1.0f.
+ * \return A handle of the filtered sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_lowpass(AUD_Sound* sound, float frequency, float Q);
+
+/**
+ * Changes the pitch of a sound.
+ * \param sound The sound to change.
+ * \param factor The factor to change the pitch with.
+ * \return A handle of the pitched sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_pitch(AUD_Sound* sound, float factor);
+
+/**
+ * Rechannels the sound.
+ * \param sound The sound to rechannel.
+ * \param channels The new channel configuration.
+ * \return The rechanneled sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_rechannel(AUD_Sound* sound, AUD_Channels channels);
+
+/**
+ * Resamples the sound.
+ * \param sound The sound to resample.
+ * \param rate The new sample rate.
+ * \param high_quality When true use a higher quality but slower resampler.
+ * \return The resampled sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_resample(AUD_Sound* sound, AUD_SampleRate rate, bool high_quality);
+
+/**
+ * Reverses a sound. Make sure the sound source can be reversed.
+ * \param sound The sound to reverse.
+ * \return A handle of the reversed sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_reverse(AUD_Sound* sound);
+
+/**
+ * Sums the samples of a sound.
+ * \param sound The sound to sum.
+ * \return A handle of the summed sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_sum(AUD_Sound* sound);
+
+/**
+ * Turns a sound into a square wave by thresholding.
+ * \param sound The sound to threshold.
+ * \param threshold Threshold value over which an amplitude counts non-zero.
+ * \return A handle of the thresholded sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_threshold(AUD_Sound* sound, float threshold);
+
+/**
+ * Changes the volume of a sound.
+ * \param sound The sound to change.
+ * \param volume The new volume of the sound. Should be in the range 0 to 1. Use higher values with caution.
+ * \return A handle of the amplified sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_volume(AUD_Sound* sound, float volume);
+
+/**
+ * Joins two sound, which means playing them one after the other.
+ * \param first The first sound.
+ * \param second The second sound.
+ * \return A handle of the joined sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_join(AUD_Sound* first, AUD_Sound* second);
+
+/**
+ * Mixes two sound, which means superposing the sound samples.
+ * \param first The first sound.
+ * \param second The second sound.
+ * \return A handle of the mixed sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_mix(AUD_Sound* first, AUD_Sound* second);
+
+/**
+ * Ping pongs a sound.
+ * \param sound The sound to ping pong.
+ * \return A handle of the ping pong sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_pingpong(AUD_Sound* sound);
+
+/**
+ * Unloads a sound of any type.
+ * \param sound The handle of the sound.
+ */
+extern AUD_API void AUD_Sound_free(AUD_Sound* sound);
+
+/**
+ * Copies a sound.
+ * \param sound Sound to copy.
+ * \return Copied sound.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_copy(AUD_Sound* sound);
+
+/**
+ * Creates an empty sound list that can contain several sounds.
+ * \param random A flag that indicates how the list will be played: Randomly or sequentially.
+ * if 0 the playback will be sequential, if not 0 the playback will be random.
+ * \return A handle of the sound list.
+ */
+extern AUD_API AUD_Sound* AUD_Sound_list(int random);
+
+/**
+* Adds a new sound to a sound list.
+ * \param list The sound list in which the sound will be added.
+ * \param sound The sound that will be added to the list.
+ * \return 0 if the sound couldn't be added (the list parameter isn't a sound list).
+*/
+extern AUD_API int AUD_SoundList_addSound(AUD_Sound* list, AUD_Sound* sound);
+
+/**
+ * Creates a sound that will be restarted when sought backwards. If the original sound is a sound list, the playing sound can change.
+ * \param sound The handle of the sound.
+ * \return A handle of the mutable sound.
+*/
+extern AUD_API AUD_Sound* AUD_Sound_mutable(AUD_Sound* sound);
+
+#ifdef WITH_CONVOLUTION
+ extern AUD_API AUD_Sound* AUD_Sound_Convolver(AUD_Sound* sound, AUD_ImpulseResponse* filter, AUD_ThreadPool* threadPool);
+ extern AUD_API AUD_Sound* AUD_Sound_Binaural(AUD_Sound* sound, AUD_HRTF* hrtfs, AUD_Source* source, AUD_ThreadPool* threadPool);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Source.cpp b/extern/audaspace/bindings/C/AUD_Source.cpp
new file mode 100644
index 00000000000..c4bf6fea6a1
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Source.cpp
@@ -0,0 +1,84 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Source.h"
+
+extern AUD_API AUD_Source* AUD_Source_create(float azimuth, float elevation, float distance)
+{
+ try
+ {
+ return new AUD_Source(new Source(azimuth, elevation, distance));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+extern AUD_API void AUD_Source_free(AUD_Source* source)
+{
+ assert(source);
+ delete source;
+}
+
+extern AUD_API float AUD_Source_getAzimuth(AUD_Source* source)
+{
+ assert(source);
+
+ return (*source)->getAzimuth();
+}
+
+extern AUD_API float AUD_Source_getElevation(AUD_Source* source)
+{
+ assert(source);
+
+ return (*source)->getElevation();
+}
+
+extern AUD_API float AUD_Source_getDistance(AUD_Source* source)
+{
+ assert(source);
+
+ return (*source)->getDistance();
+}
+
+extern AUD_API void AUD_Source_setAzimuth(AUD_Source* source, float azimuth)
+{
+ assert(source);
+
+ (*source)->setAzimuth(azimuth);
+}
+
+extern AUD_API void AUD_Source_setElevation(AUD_Source* source, float elevation)
+{
+ assert(source);
+
+ (*source)->setElevation(elevation);
+}
+
+extern AUD_API void AUD_Source_setDistance(AUD_Source* source, float distance)
+{
+ assert(source);
+
+ (*source)->setDistance(distance);
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_Source.h b/extern/audaspace/bindings/C/AUD_Source.h
new file mode 100644
index 00000000000..6ff045ec848
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Source.h
@@ -0,0 +1,84 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new Source object.
+* \param azimuth The azimuth angle.
+* \param elevation The elevation angle.
+* \param elevation The distance value. [0,1]
+* \return The new Source object.
+*/
+extern AUD_API AUD_Source* AUD_Source_create(float azimuth, float elevation, float distance);
+
+/**
+* Deletes a Source object.
+* \param source The Source object to be deleted.
+*/
+extern AUD_API void AUD_Source_free(AUD_Source* source);
+
+/**
+* Retrieves the azimuth angle of a Source object.
+* \param source The Source object.
+* \return The azimuth angle.
+*/
+extern AUD_API float AUD_Source_getAzimuth(AUD_Source* source);
+
+/**
+* Retrieves the elevation angle oa a Source object.
+* \param source The Source object.
+* \return The elevation angle.
+*/
+extern AUD_API float AUD_Source_getElevation(AUD_Source* source);
+
+/**
+* Retrieves the distance of a Source object. [0,1]
+* \param source The Source object.
+* \return The distance.
+*/
+extern AUD_API float AUD_Source_getDistance(AUD_Source* distance);
+
+/**
+* Changes the azimuth angle of a Source object.
+* \param source The Source object.
+* \param azimuth The azimuth angle.
+*/
+extern AUD_API void AUD_Source_setAzimuth(AUD_Source* source, float azimuth);
+
+/**
+* Changes the elevation angle of a Source object.
+* \param source The Source object.
+* \param elevation The elevation angle.
+*/
+extern AUD_API void AUD_Source_setElevation(AUD_Source* source, float elevation);
+
+/**
+* Changes the distance of a Source object. [0,1]
+* \param source The Source object.
+* \param distance The distance.
+*/
+extern AUD_API void AUD_Source_setDistance(AUD_Source* source, float distance);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_Special.cpp b/extern/audaspace/bindings/C/AUD_Special.cpp
new file mode 100644
index 00000000000..f8f46651231
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Special.cpp
@@ -0,0 +1,420 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "Exception.h"
+#include "IReader.h"
+#include "file/File.h"
+#include "respec/ChannelMapper.h"
+#include "fx/Lowpass.h"
+#include "fx/Highpass.h"
+#include "fx/Envelope.h"
+#include "respec/LinearResample.h"
+#include "fx/Threshold.h"
+#include "fx/Accumulator.h"
+#include "fx/Sum.h"
+#include "generator/Silence.h"
+#include "fx/Limiter.h"
+#include "devices/DeviceManager.h"
+#include "sequence/Sequence.h"
+#include "file/FileWriter.h"
+#include "devices/ReadDevice.h"
+#include "plugin/PluginManager.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "devices/NULLDevice.h"
+
+#include <cassert>
+#include <cstring>
+#include <cmath>
+#include <sstream>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_Special.h"
+
+static inline AUD_Specs convSpecToC(aud::Specs specs)
+{
+ AUD_Specs s;
+ s.channels = static_cast<AUD_Channels>(specs.channels);
+ s.rate = static_cast<AUD_SampleRate>(specs.rate);
+ return s;
+}
+
+static inline aud::Specs convCToSpec(AUD_Specs specs)
+{
+ aud::Specs s;
+ s.channels = static_cast<Channels>(specs.channels);
+ s.rate = static_cast<SampleRate>(specs.rate);
+ return s;
+}
+
+static inline AUD_DeviceSpecs convDSpecToC(aud::DeviceSpecs specs)
+{
+ AUD_DeviceSpecs s;
+ s.specs = convSpecToC(specs.specs);
+ s.format = static_cast<AUD_SampleFormat>(specs.format);
+ return s;
+}
+
+static inline aud::DeviceSpecs convCToDSpec(AUD_DeviceSpecs specs)
+{
+ aud::DeviceSpecs s;
+ s.specs = convCToSpec(specs.specs);
+ s.format = static_cast<SampleFormat>(specs.format);
+ return s;
+}
+
+AUD_API AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
+{
+ assert(sound);
+
+ AUD_SoundInfo info;
+ info.specs.channels = AUD_CHANNELS_INVALID;
+ info.specs.rate = AUD_RATE_INVALID;
+ info.length = 0.0f;
+
+ try
+ {
+ std::shared_ptr<IReader> reader = (*sound)->createReader();
+
+ if(reader.get())
+ {
+ info.specs = convSpecToC(reader->getSpecs());
+ info.length = reader->getLength() / (float) info.specs.rate;
+ }
+ }
+ catch(Exception&)
+ {
+ }
+
+ return info;
+}
+
+AUD_API float* AUD_readSoundBuffer(const char* filename, float low, float high,
+ float attack, float release, float threshold,
+ int accumulate, int additive, int square,
+ float sthreshold, double samplerate, int* length)
+{
+ Buffer buffer;
+ DeviceSpecs specs;
+ specs.channels = CHANNELS_MONO;
+ specs.rate = (SampleRate)samplerate;
+ std::shared_ptr<ISound> sound;
+
+ std::shared_ptr<ISound> file = std::shared_ptr<ISound>(new File(filename));
+
+ int position = 0;
+
+ try
+ {
+ std::shared_ptr<IReader> reader = file->createReader();
+
+ SampleRate rate = reader->getSpecs().rate;
+
+ sound = std::shared_ptr<ISound>(new ChannelMapper(file, specs));
+
+ if(high < rate)
+ sound = std::shared_ptr<ISound>(new Lowpass(sound, high));
+ if(low > 0)
+ sound = std::shared_ptr<ISound>(new Highpass(sound, low));
+
+ sound = std::shared_ptr<ISound>(new Envelope(sound, attack, release, threshold, 0.1f));
+ sound = std::shared_ptr<ISound>(new LinearResample(sound, specs));
+
+ if(square)
+ sound = std::shared_ptr<ISound>(new Threshold(sound, sthreshold));
+
+ if(accumulate)
+ sound = std::shared_ptr<ISound>(new Accumulator(sound, additive));
+ else if(additive)
+ sound = std::shared_ptr<ISound>(new Sum(sound));
+
+ reader = sound->createReader();
+
+ if(!reader.get())
+ return nullptr;
+
+ int len;
+ bool eos;
+ do
+ {
+ len = samplerate;
+ buffer.resize((position + len) * sizeof(float), true);
+ reader->read(len, eos, buffer.getBuffer() + position);
+ position += len;
+ } while(!eos);
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+
+ float * result = (float *)malloc(position * sizeof(float));
+ std::memcpy(result, buffer.getBuffer(), position * sizeof(float));
+ *length = position;
+ return result;
+}
+
+static void pauseSound(AUD_Handle* handle)
+{
+ assert(handle);
+ (*handle)->pause();
+}
+
+AUD_API AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds)
+{
+ std::shared_ptr<ISound> silence = std::shared_ptr<ISound>(new Silence);
+ std::shared_ptr<ISound> limiter = std::shared_ptr<ISound>(new Limiter(silence, 0, seconds));
+
+ auto device = DeviceManager::getDevice();
+
+ std::lock_guard<ILockable> lock(*device);
+
+ try
+ {
+ AUD_Handle handle2 = device->play(limiter);
+ if(handle2.get())
+ {
+ handle2->setStopCallback((stopCallback)pauseSound, handle);
+ return new AUD_Handle(handle2);
+ }
+ }
+ catch(Exception&)
+ {
+ }
+
+ return nullptr;
+}
+
+AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int samples_per_second, short* interrupt)
+{
+ DeviceSpecs specs;
+ float* buf;
+ Buffer aBuffer;
+
+ specs.rate = RATE_INVALID;
+ specs.channels = CHANNELS_MONO;
+ specs.format = FORMAT_INVALID;
+
+ std::shared_ptr<IReader> reader = ChannelMapper(*sound, specs).createReader();
+
+ specs.specs = reader->getSpecs();
+ int len;
+ float samplejump = specs.rate / samples_per_second;
+ float min, max, power, overallmax;
+ bool eos;
+
+ overallmax = 0;
+
+ for(int i = 0; i < length; i++)
+ {
+ len = floor(samplejump * (i+1)) - floor(samplejump * i);
+
+ if(*interrupt)
+ return 0;
+
+ aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
+ buf = aBuffer.getBuffer();
+
+ reader->read(len, eos, buf);
+
+ max = min = *buf;
+ power = *buf * *buf;
+ for(int j = 1; j < len; j++)
+ {
+ if(buf[j] < min)
+ min = buf[j];
+ if(buf[j] > max)
+ max = buf[j];
+ power += buf[j] * buf[j];
+ }
+
+ buffer[i * 3] = min;
+ buffer[i * 3 + 1] = max;
+ buffer[i * 3 + 2] = sqrt(power) / len;
+
+ if(overallmax < max)
+ overallmax = max;
+ if(overallmax < -min)
+ overallmax = -min;
+
+ if(eos)
+ {
+ length = i;
+ break;
+ }
+ }
+
+ if(overallmax > 1.0f)
+ {
+ for(int i = 0; i < length * 3; i++)
+ {
+ buffer[i] /= overallmax;
+ }
+ }
+
+ return length;
+}
+
+AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
+{
+ try
+ {
+ Sequence* f = dynamic_cast<Sequence *>(sound->get());
+
+ f->setSpecs(convCToSpec(specs.specs));
+ std::shared_ptr<IReader> reader = f->createQualityReader();
+ reader->seek(start);
+ std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate);
+ FileWriter::writeReader(reader, writer, length, buffersize);
+
+ return nullptr;
+ }
+ catch(Exception& e)
+ {
+ return e.getMessage().c_str();
+ }
+}
+
+AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length, unsigned int buffersize, const char* filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
+{
+ try
+ {
+ Sequence* f = dynamic_cast<Sequence *>(sound->get());
+
+ f->setSpecs(convCToSpec(specs.specs));
+
+ std::vector<std::shared_ptr<IWriter> > writers;
+
+ int channels = specs.channels;
+ specs.channels = AUD_CHANNELS_MONO;
+
+ for(int i = 0; i < channels; i++)
+ {
+ std::stringstream stream;
+ std::string fn = filename;
+ size_t index = fn.find_last_of('.');
+ size_t index_slash = fn.find_last_of('/');
+ size_t index_backslash = fn.find_last_of('\\');
+
+ if((index == std::string::npos) ||
+ ((index < index_slash) && (index_slash != std::string::npos)) ||
+ ((index < index_backslash) && (index_backslash != std::string::npos)))
+ {
+ stream << filename << "_" << (i + 1);
+ }
+ else
+ {
+ stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
+ }
+ writers.push_back(FileWriter::createWriter(stream.str(), convCToDSpec(specs), static_cast<Container>(format), static_cast<Codec>(codec), bitrate));
+ }
+
+ std::shared_ptr<IReader> reader = f->createQualityReader();
+ reader->seek(start);
+ FileWriter::writeReader(reader, writers, length, buffersize);
+
+ return nullptr;
+ }
+ catch(Exception& e)
+ {
+ return e.getMessage().c_str();
+ }
+}
+
+AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start)
+{
+ try
+ {
+ ReadDevice* device = new ReadDevice(convCToDSpec(specs));
+ device->setQuality(true);
+ device->setVolume(volume);
+
+ Sequence* f = dynamic_cast<Sequence*>(sequencer->get());
+
+ f->setSpecs(convCToSpec(specs.specs));
+
+ AUD_Handle handle = device->play(f->createQualityReader());
+ if(handle.get())
+ {
+ handle->seek(start);
+ }
+
+ return new AUD_Device(device);
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_initOnce()
+{
+ PluginManager::loadPlugins();
+ NULLDevice::registerPlugin();
+}
+
+AUD_API void AUD_exitOnce()
+{
+}
+
+AUD_API AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name)
+{
+ try
+ {
+ std::shared_ptr<IDeviceFactory> factory = DeviceManager::getDeviceFactory(device);
+
+ if(factory)
+ {
+ factory->setName(name);
+ factory->setBufferSize(buffersize);
+ factory->setSpecs(convCToDSpec(specs));
+ auto device = factory->openDevice();
+ DeviceManager::setDevice(device);
+
+ return new AUD_Device(device);
+ }
+ }
+ catch(Exception&)
+ {
+ }
+ return nullptr;
+}
+
+AUD_API void AUD_exit(AUD_Device* device)
+{
+ delete device;
+ DeviceManager::releaseDevice();
+}
+
+
+AUD_API char** AUD_getDeviceNames()
+{
+ std::vector<std::string> v_names = DeviceManager::getAvailableDeviceNames();
+ char** names = (char**) malloc(sizeof(char*) * (v_names.size() + 1));
+
+ for(int i = 0; i < v_names.size(); i++)
+ {
+ std::string name = v_names[i];
+ names[i] = (char*) malloc(sizeof(char) * (name.length() + 1));
+ strcpy(names[i], name.c_str());
+ }
+
+ names[v_names.size()] = nullptr;
+
+ return names;
+}
diff --git a/extern/audaspace/bindings/C/AUD_Special.h b/extern/audaspace/bindings/C/AUD_Special.h
new file mode 100644
index 00000000000..ab79ae915a2
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Special.h
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Returns information about a sound.
+ * \param sound The sound to get the info about.
+ * \return The AUD_SoundInfo structure with filled in data.
+ */
+extern AUD_API AUD_SoundInfo AUD_getInfo(AUD_Sound* sound);
+
+/**
+ * Reads a sound file into a newly created float buffer.
+ * The sound is therefore bandpassed, rectified and resampled.
+ */
+extern AUD_API float* AUD_readSoundBuffer(const char* filename, float low, float high,
+ float attack, float release, float threshold,
+ int accumulate, int additive, int square,
+ float sthreshold, double samplerate,
+ int* length);
+
+/**
+ * Pauses a playing sound after a specific amount of time.
+ * \param handle The handle to the sound.
+ * \param seconds The time in seconds.
+ * \return The silence handle.
+ */
+extern AUD_API AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds);
+
+/**
+ * Reads a sound into a buffer for drawing at a specific sampling rate.
+ * \param sound The sound to read.
+ * \param buffer The buffer to write to. Must have a size of 3*4*length.
+ * \param length How many samples to read from the sound.
+ * \param samples_per_second How many samples to read per second of the sound.
+ * \return How many samples really have been read. Always <= length.
+ */
+extern AUD_API int AUD_readSound(AUD_Sound* sound, float* buffer, int length, int samples_per_second, short* interrupt);
+
+/**
+ * Mixes a sound down into a file.
+ * \param sound The sound scene to mix down.
+ * \param start The start frame.
+ * \param length The count of frames to write.
+ * \param buffersize How many samples should be written at once.
+ * \param filename The file to write to.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \return An error message or NULL in case of success.
+ */
+extern AUD_API const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int length,
+ unsigned int buffersize, const char* filename,
+ AUD_DeviceSpecs specs, AUD_Container format,
+ AUD_Codec codec, unsigned int bitrate);
+
+/**
+ * Mixes a sound down into multiple files.
+ * \param sound The sound scene to mix down.
+ * \param start The start frame.
+ * \param length The count of frames to write.
+ * \param buffersize How many samples should be written at once.
+ * \param filename The file to write to, the channel number and an underscore are added at the beginning.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \return An error message or NULL in case of success.
+ */
+extern AUD_API const char* AUD_mixdown_per_channel(AUD_Sound* sound, unsigned int start, unsigned int length,
+ unsigned int buffersize, const char* filename,
+ AUD_DeviceSpecs specs, AUD_Container format,
+ AUD_Codec codec, unsigned int bitrate);
+
+/**
+ * Opens a read device and prepares it for mixdown of the sound scene.
+ * \param specs Output audio specifications.
+ * \param sequencer The sound scene to mix down.
+ * \param volume The overall mixdown volume.
+ * \param start The start time of the mixdown in the sound scene.
+ * \return The read device for the mixdown.
+ */
+extern AUD_API AUD_Device* AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound* sequencer, float volume, float start);
+
+/**
+ * Initializes audio routines (FFMPEG/JACK if it is enabled).
+ */
+extern AUD_API void AUD_initOnce();
+
+/**
+ * Unitinitializes an audio routines.
+ */
+extern AUD_API void AUD_exitOnce();
+
+/**
+ * Initializes an audio device.
+ * \param device The device type that should be used.
+ * \param specs The audio specification to be used.
+ * \param buffersize The buffersize for the device.
+ * \return Whether the device has been initialized.
+ */
+extern AUD_API AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name);
+
+/**
+ * Unitinitializes an audio device.
+ * \param device The device to free.
+ */
+extern AUD_API void AUD_exit(AUD_Device* device);
+
+/**
+ * Retrieves available devices. Note that all memory returned has to be freed!
+ */
+extern AUD_API char** AUD_getDeviceNames();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/C/AUD_ThreadPool.cpp b/extern/audaspace/bindings/C/AUD_ThreadPool.cpp
new file mode 100644
index 00000000000..f22a904838b
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_ThreadPool.cpp
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "Exception.h"
+
+#include <cassert>
+
+using namespace aud;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_ThreadPool.h"
+
+AUD_API AUD_ThreadPool* AUD_ThreadPool_create(int nThreads)
+{
+ try
+ {
+ return new AUD_ThreadPool(new ThreadPool(nThreads));
+ }
+ catch(Exception&)
+ {
+ return nullptr;
+ }
+}
+
+AUD_API void AUD_ThreadPool_free(AUD_ThreadPool* pool)
+{
+ assert(pool);
+ delete pool;
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_ThreadPool.h b/extern/audaspace/bindings/C/AUD_ThreadPool.h
new file mode 100644
index 00000000000..c1b2204a80a
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_ThreadPool.h
@@ -0,0 +1,40 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include "AUD_Types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* Creates a new ThreadPool object.
+* \param nThreads The number of threads of the pool.
+* \return The new ThreadPool object.
+*/
+extern AUD_API AUD_ThreadPool* AUD_ThreadPool_create(int nThreads);
+
+/**
+* Deletes a ThreadPool object.
+* \param threadPool The ThreadPool object to be deleted.
+*/
+extern AUD_API void AUD_ThreadPool_free(AUD_ThreadPool* threadPool);
+
+#ifdef __cplusplus
+}
+#endif \ No newline at end of file
diff --git a/extern/audaspace/bindings/C/AUD_Types.h b/extern/audaspace/bindings/C/AUD_Types.h
new file mode 100644
index 00000000000..75e4ffae18c
--- /dev/null
+++ b/extern/audaspace/bindings/C/AUD_Types.h
@@ -0,0 +1,179 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include "Audaspace.h"
+
+#ifdef __cplusplus
+using namespace aud;
+#endif
+
+#ifdef AUD_CAPI_IMPLEMENTATION
+#include "ISound.h"
+#include "devices/IHandle.h"
+#include "devices/IDevice.h"
+#include "sequence/SequenceEntry.h"
+#include "fx/PlaybackManager.h"
+#include "fx/DynamicMusic.h"
+#include "fx/Source.h"
+#include "util/ThreadPool.h"
+#ifdef WITH_CONVOLUTION
+#include "fx/ImpulseResponse.h"
+#include "fx/HRTF.h"
+#endif
+
+typedef std::shared_ptr<aud::ISound> AUD_Sound;
+typedef std::shared_ptr<aud::IHandle> AUD_Handle;
+typedef std::shared_ptr<aud::IDevice> AUD_Device;
+typedef std::shared_ptr<aud::SequenceEntry> AUD_SequenceEntry;
+typedef std::shared_ptr<aud::PlaybackManager> AUD_PlaybackManager;
+typedef std::shared_ptr<aud::DynamicMusic> AUD_DynamicMusic;
+typedef std::shared_ptr<aud::ThreadPool> AUD_ThreadPool;
+typedef std::shared_ptr<aud::Source> AUD_Source;
+#ifdef WITH_CONVOLUTION
+typedef std::shared_ptr<aud::ImpulseResponse> AUD_ImpulseResponse;
+typedef std::shared_ptr<aud::HRTF> AUD_HRTF;
+#endif
+#else
+typedef void AUD_Sound;
+typedef void AUD_Handle;
+typedef void AUD_Device;
+typedef void AUD_SequenceEntry;
+typedef void AUD_PlaybackManager;
+typedef void AUD_DynamicMusic;
+typedef void AUD_ThreadPool;
+typedef void AUD_Source;
+#ifdef WITH_CONVOLUTION
+typedef void AUD_ImpulseResponse;
+typedef void AUD_HRTF;
+#endif
+#endif
+
+/// Container formats for writers.
+typedef enum
+{
+ AUD_CONTAINER_INVALID = 0,
+ AUD_CONTAINER_AC3,
+ AUD_CONTAINER_FLAC,
+ AUD_CONTAINER_MATROSKA,
+ AUD_CONTAINER_MP2,
+ AUD_CONTAINER_MP3,
+ AUD_CONTAINER_OGG,
+ AUD_CONTAINER_WAV
+} AUD_Container;
+
+/// Audio codecs for writers.
+typedef enum
+{
+ AUD_CODEC_INVALID = 0,
+ AUD_CODEC_AAC,
+ AUD_CODEC_AC3,
+ AUD_CODEC_FLAC,
+ AUD_CODEC_MP2,
+ AUD_CODEC_MP3,
+ AUD_CODEC_PCM,
+ AUD_CODEC_VORBIS,
+ AUD_CODEC_OPUS
+} AUD_Codec;
+
+/**
+ * The format of a sample.
+ * The last 4 bit save the byte count of the format.
+ */
+typedef enum
+{
+ AUD_FORMAT_INVALID = 0x00, /// Invalid sample format.
+ AUD_FORMAT_U8 = 0x01, /// 1 byte unsigned byte.
+ AUD_FORMAT_S16 = 0x12, /// 2 byte signed integer.
+ AUD_FORMAT_S24 = 0x13, /// 3 byte signed integer.
+ AUD_FORMAT_S32 = 0x14, /// 4 byte signed integer.
+ AUD_FORMAT_FLOAT32 = 0x24, /// 4 byte float.
+ AUD_FORMAT_FLOAT64 = 0x28 /// 8 byte float.
+} AUD_SampleFormat;
+
+/// The channel count.
+typedef enum
+{
+ AUD_CHANNELS_INVALID = 0, /// Invalid channel count.
+ AUD_CHANNELS_MONO = 1, /// Mono.
+ AUD_CHANNELS_STEREO = 2, /// Stereo.
+ AUD_CHANNELS_STEREO_LFE = 3, /// Stereo with LFE channel.
+ AUD_CHANNELS_SURROUND4 = 4, /// 4 channel surround sound.
+ AUD_CHANNELS_SURROUND5 = 5, /// 5 channel surround sound.
+ AUD_CHANNELS_SURROUND51 = 6, /// 5.1 surround sound.
+ AUD_CHANNELS_SURROUND61 = 7, /// 6.1 surround sound.
+ AUD_CHANNELS_SURROUND71 = 8 /// 7.1 surround sound.
+} AUD_Channels;
+
+/**
+ * The sample rate tells how many samples are played back within one second.
+ * Some exotic formats may use other sample rates than provided here.
+ */
+typedef enum
+{
+ AUD_RATE_INVALID = 0, /// Invalid sample rate.
+ AUD_RATE_8000 = 8000, /// 8000 Hz.
+ AUD_RATE_16000 = 16000, /// 16000 Hz.
+ AUD_RATE_11025 = 11025, /// 11025 Hz.
+ AUD_RATE_22050 = 22050, /// 22050 Hz.
+ AUD_RATE_32000 = 32000, /// 32000 Hz.
+ AUD_RATE_44100 = 44100, /// 44100 Hz.
+ AUD_RATE_48000 = 48000, /// 48000 Hz.
+ AUD_RATE_88200 = 88200, /// 88200 Hz.
+ AUD_RATE_96000 = 96000, /// 96000 Hz.
+ AUD_RATE_192000 = 192000 /// 192000 Hz.
+} AUD_DefaultSampleRate;
+
+/// Sample rate type.
+typedef double AUD_SampleRate;
+
+/// Specification of a sound source.
+typedef struct
+{
+ /// Sample rate in Hz.
+ AUD_SampleRate rate;
+
+ /// Channel count.
+ AUD_Channels channels;
+} AUD_Specs;
+
+/// Specification of a sound device.
+typedef struct
+{
+ /// Sample format.
+ AUD_SampleFormat format;
+
+ union
+ {
+ struct
+ {
+ /// Sample rate in Hz.
+ AUD_SampleRate rate;
+
+ /// Channel count.
+ AUD_Channels channels;
+ };
+ AUD_Specs specs;
+ };
+} AUD_DeviceSpecs;
+
+/// Sound information structure.
+typedef struct
+{
+ AUD_Specs specs;
+ float length;
+} AUD_SoundInfo;
diff --git a/extern/audaspace/bindings/doc/conf.py.in b/extern/audaspace/bindings/doc/conf.py.in
new file mode 100644
index 00000000000..e08efbcf7f6
--- /dev/null
+++ b/extern/audaspace/bindings/doc/conf.py.in
@@ -0,0 +1,261 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+#
+# audaspace documentation build configuration file, created by
+# sphinx-quickstart on Tue Sep 9 01:48:48 2014.
+#
+# This file is execfile()d with the current directory set to its
+# containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys
+import os
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#sys.path.insert(0, os.path.abspath('.'))
+
+# -- General configuration ------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+ 'sphinx.ext.autodoc',
+]
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = []
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = 'audaspace'
+copyright = '2009-2015, Jörg Müller'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '@AUDASPACE_VERSION@'
+# The full version, including alpha/beta/rc tags.
+release = '@AUDASPACE_LONG_VERSION@'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = []
+
+# The reST default role (used for this markup: `text`) to use for all
+# documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+# If true, keep warnings as "system message" paragraphs in the built documents.
+#keep_warnings = False
+
+
+# -- Options for HTML output ----------------------------------------------
+
+# The theme to use for HTML and HTML Help pages. See the documentation for
+# a list of builtin themes.
+html_theme = 'alabaster'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further. For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents. If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar. Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = []
+
+# Add any extra paths that contain custom files (such as robots.txt or
+# .htaccess) here, relative to this directory. These files are copied
+# directly to the root of the documentation.
+#html_extra_path = []
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it. The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'audaspacedoc'
+
+
+# -- Options for LaTeX output ---------------------------------------------
+
+latex_elements = {
+# The paper size ('letterpaper' or 'a4paper').
+#'papersize': 'letterpaper',
+
+# The font size ('10pt', '11pt' or '12pt').
+#'pointsize': '10pt',
+
+# Additional stuff for the LaTeX preamble.
+#'preamble': '',
+}
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title,
+# author, documentclass [howto, manual, or own class]).
+latex_documents = [
+ ('index', 'audaspace.tex', 'audaspace Documentation',
+ 'Jörg Müller', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output ---------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+ ('index', 'audaspace', 'audaspace Documentation',
+ ['Jörg Müller'], 1)
+]
+
+# If true, show URL addresses after external links.
+#man_show_urls = False
+
+
+# -- Options for Texinfo output -------------------------------------------
+
+# Grouping the document tree into Texinfo files. List of tuples
+# (source start file, target name, title, author,
+# dir menu entry, description, category)
+texinfo_documents = [
+ ('index', 'audaspace', 'audaspace Documentation',
+ 'Jörg Müller', 'audaspace', 'One line description of project.',
+ 'Miscellaneous'),
+]
+
+# Documents to append as an appendix to all manuals.
+#texinfo_appendices = []
+
+# If false, no module index is generated.
+#texinfo_domain_indices = True
+
+# How to display URL addresses: 'footnote', 'no', or 'inline'.
+#texinfo_show_urls = 'footnote'
+
+# If true, do not generate a @detailmenu in the "Top" node's menu.
+#texinfo_no_detailmenu = False
diff --git a/extern/audaspace/bindings/doc/device.rst b/extern/audaspace/bindings/doc/device.rst
new file mode 100644
index 00000000000..fd6b334022c
--- /dev/null
+++ b/extern/audaspace/bindings/doc/device.rst
@@ -0,0 +1,7 @@
+Device
+======
+
+.. currentmodule:: aud
+.. autoclass:: Device
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/handle.rst b/extern/audaspace/bindings/doc/handle.rst
new file mode 100644
index 00000000000..aceedbca3a6
--- /dev/null
+++ b/extern/audaspace/bindings/doc/handle.rst
@@ -0,0 +1,7 @@
+Handle
+======
+
+.. currentmodule:: aud
+.. autoclass:: Handle
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/index.rst b/extern/audaspace/bindings/doc/index.rst
new file mode 100644
index 00000000000..b8a26822949
--- /dev/null
+++ b/extern/audaspace/bindings/doc/index.rst
@@ -0,0 +1,35 @@
+.. audaspace documentation master file, created by
+ sphinx-quickstart on Tue Sep 9 01:48:48 2014.
+ You can adapt this file completely to your liking, but it should at least
+ contain the root `toctree` directive.
+
+Welcome to audaspace's documentation!
+=====================================
+
+.. automodule:: aud
+
+This documentation is valid for both the Python and C bindings of audaspace. If you are looking for installation instructions check the `C++ API documentation <../index.html>`_. As C is not an object oriented language everything is accessible via functions where the first paramter is always the object. For methods these are named as ``AUD_ClassName_method()`` and properties are accessed via ``AUD_ClassName_property_get/set()``. Python users simply ``import aud`` to access the library.
+
+.. toctree::
+ :maxdepth: 2
+
+ tutorials
+
+Classes:
+
+.. toctree::
+ :maxdepth: 2
+
+ device
+ sound
+ handle
+ sequence
+ sequence_entry
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
diff --git a/extern/audaspace/bindings/doc/sequence.rst b/extern/audaspace/bindings/doc/sequence.rst
new file mode 100644
index 00000000000..16fcb00f4dc
--- /dev/null
+++ b/extern/audaspace/bindings/doc/sequence.rst
@@ -0,0 +1,7 @@
+Sequence
+========
+
+.. currentmodule:: aud
+.. autoclass:: Sequence
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/sequence_entry.rst b/extern/audaspace/bindings/doc/sequence_entry.rst
new file mode 100644
index 00000000000..0a3d83388e9
--- /dev/null
+++ b/extern/audaspace/bindings/doc/sequence_entry.rst
@@ -0,0 +1,7 @@
+Sequence Entry
+==============
+
+.. currentmodule:: aud
+.. autoclass:: SequenceEntry
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/sound.rst b/extern/audaspace/bindings/doc/sound.rst
new file mode 100644
index 00000000000..2f14721cf3a
--- /dev/null
+++ b/extern/audaspace/bindings/doc/sound.rst
@@ -0,0 +1,7 @@
+Sound
+=====
+
+.. currentmodule:: aud
+.. autoclass:: Sound
+ :members:
+
diff --git a/extern/audaspace/bindings/doc/tutorials.rst b/extern/audaspace/bindings/doc/tutorials.rst
new file mode 100644
index 00000000000..55f51d9ee2f
--- /dev/null
+++ b/extern/audaspace/bindings/doc/tutorials.rst
@@ -0,0 +1,166 @@
+Tutorials
+=========
+
+Introduction
+------------
+
+The C and Python binding for audaspace were designed with simplicity in mind. This means however that to use the full capabilities of audaspace, there is no way around the C++ library.
+
+Simple Demo
+-----------
+
+The **simple.py** example program contains all the basic building blocks for an application using audaspace. These building blocks are basically the classes :class:`aud.Device`, :class:`aud.Sound` and :class:`aud.Handle`.
+
+We start with importing :mod:`aud` and :mod:`time` as the modules we need for our simple example.
+
+.. code-block:: python
+
+ #!/usr/bin/python
+ import aud, time
+
+The first step now is to open an output device and this can simply be done by allocating a :class:`aud.Device` object.
+
+.. code-block:: python
+
+ device = aud.Device()
+
+To create a sound we can choose to load one from a :func:`aud.Sound.file`, or we use one of our signal generators. We decide to do the latter and create a :func:`aud.Sound.sine` signal with a frequency of 440 Hz.
+
+.. code-block:: python
+
+ sine = aud.Sound.sine(440)
+
+.. note:: At this point nothing is playing back yet, :class:`aud.Sound` objects are just descriptions of sounds.
+
+However instead of a sine wave, we would like to have a square wave to produce a more retro gaming sound. We could of course use the :func:`aud.Sound.square` generator instead of sine, but we want to show how to apply effects, so we apply a :func:`aud.Sound.threshold` which makes a square wave out of our sine too, even if less efficient than directly generating the square wave.
+
+.. code-block:: python
+
+ square = sine.threshold()
+
+.. note:: The :class:`aud.Sound` class offers generator and effect functions.
+
+The we can play our sound by calling the :func:`aud.Device.play` method of our device. This method returns a :class:`aud.Handle` which is used to control the playback of the sound.
+
+.. code-block:: python
+
+ handle = device.play(square)
+
+Now if we do nothing else anymore the application will quit immediately, so we won't hear much of our square wave, so we decide to wait for three seconds before quitting the application by calling :func:`time.sleep`.
+
+.. code-block:: python
+
+ time.sleep(3)
+
+Audioplayer
+-----------
+
+Now that we know the basics of audaspace, we can build our own music player easily by just slightly changing the previous program. The **player.py** example does exactly that, let's have a short look at the differences:
+
+Instead of creating a sine signal and thresholding it, we in fact use the :func:`aud.Sound.file` function to load a sound from a file. The filename we pass is the first command line argument our application got.
+
+.. code-block:: python
+
+ sound = aud.Sound.file(sys.argv[1])
+
+When the sound gets played back we now want to wait until the whole file has been played, so we use the :data:`aud.Handle.status` property to determine whether the sound finished playing.
+
+.. code-block:: python
+
+ while handle.status:
+ time.sleep(0.1)
+
+We don't make any error checks if the user actually added a command line argument. As an exercise you could extend this program to play any number of command line supplied files in sequence.
+
+Siren
+-----
+
+Let's get a little bit more complex. The **siren.py** example plays a generated siren sound that circles around your head. Depending on how many speakers you have and if the output device used supports the speaker setup, you will hear this effect. With stereo speakers you should at least hear some left-right-panning.
+
+We start off again with importing the modules we need and we also define some properties of our siren sound. We want it to consist of two sine sounds with different frequencies. We define a length for the sine sounds and how long a fade in/out should take. We also know already how to open a device.
+
+.. code-block:: python
+
+ #!/usr/bin/python
+ import aud, math, time
+ length = 0.5
+ fadelength = 0.05
+
+ device = aud.Device()
+
+The next thing to do is to define our sine waves and apply all the required effects. As each of the effect functions returns the corresponding sound, we can easily chain those calls together.
+
+.. code-block:: python
+
+ high = aud.Sound.sine(880).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length)
+ low = aud.Sound.sine(700).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length).volume(0.6)
+
+The next step is to connect the two sines, which we do using the :func:`aud.Sound.join` function.
+
+.. code-block:: python
+
+ sound = high.join(low)
+
+The generated siren sound can now be played back and what we also do is to loop it. Therefore we set the :data:`aud.Handle.loop_count` to a negative value to loop forever.
+
+.. code-block:: python
+
+ handle = device.play(sound)
+ handle.loop_count = -1
+
+Now we use some timing code to make sure our demo runs for 10 seconds, but we also use the time to update the location of our playing sound, with the :data:`aud.Handle.location` property, which is a three dimensional vector. The trigonometic calculation based on the running time of the program keeps the sound on the XZ plane letting it follow a circle around us.
+
+.. code-block:: python
+
+ start = time.time()
+
+ while time.time() - start < 10:
+ angle = time.time() - start
+
+ handle.location = [math.sin(angle), 0, -math.cos(angle)]
+
+As an exercise you could try to let the sound come from the far left and go to the far right and a little bit in front of you within the 10 second runtime of the program. With this change you should be able to hear the volume of the sound change, depending on how far it is away from you. Updating the :data:`aud.Handle.velocity` property properly also enables the doppler effect. Compare your solution to the **siren2.py** demo.
+
+Tetris
+------
+
+The **tetris.py** demo application shows an even more complex application which generates retro tetris music. Looking at the source code there should be nothing new here, again the functions used from audaspace are the same as in the previous examples. In the :func:`parseNote` function all single notes get joined which leads to a very long chain of sounds. If you think of :func:`aud.Sound.join` as a function that creates a binary tree with the two joined sounds as leaves then the :func:`parseNote` function creates a very unbalanced tree.
+
+Insted we could rewrite the code to use two other classes: :class:`aud.Sequence` and :class:`aud.SequenceEntry` to sequence the notes. The **tetris2.py** application does exactly that. Before the while loop we add a variable that stores the current position in the score and create a new :class:`aud.Sequence` object.
+
+.. code-block:: python
+
+ position = 0
+ sequence = aud.Sequence()
+
+Then in the loop we can create the note simply by chaining the :func:`aud.Sound.square` generator and :func:`aud.Sound.fadein` and :func:`aud.Sound.fadeout` effects.
+
+.. code-block:: python
+
+ note = aud.Sound.square(freq, rate).fadein(0, fadelength).fadeout(length - fadelength, fadelength)
+
+Now instead of using :func:`aud.Sound.limit` and :func:`aud.Sound.join` we simply add the sound to the sequence.
+
+.. code-block:: python
+
+ entry = sequence.add(note, position, position + length, 0)
+
+The entry returned from the :func:`aud.Sequence.add` function is an object of the :class:`aud.SequenceEntry` class. We can use this entry to mute the note in case it's actually a pause.
+
+.. code-block:: python
+
+ if char == 'p':
+ entry.muted = True
+
+Lastly we have to update our position variable.
+
+.. code-block:: python
+
+ position += length
+
+Now in **tetris2.py** we used the :data:`aud.SequenceEntry.muted` property to show how the :class:`aud.SequenceEntry` class can be used, but it would actually be smarter to not even create a note for pauses and just skip them. You can try to implement this as an exercise and then check out the solution in **tetris3.py**.
+
+Conclusion
+----------
+
+We introduced all five currently available classes in the audaspace Python API. Of course all classes offer a lot more functions than have been used in these demo applications, check out the specific class documentation for more details.
diff --git a/extern/audaspace/bindings/python/PyAPI.cpp b/extern/audaspace/bindings/python/PyAPI.cpp
new file mode 100644
index 00000000000..cceadbc0992
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyAPI.cpp
@@ -0,0 +1,231 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "PyAPI.h"
+#include "PySound.h"
+#include "PyHandle.h"
+#include "PyDevice.h"
+#include "PySequenceEntry.h"
+#include "PySequence.h"
+#include "PyPlaybackManager.h"
+#include "PyDynamicMusic.h"
+#include "PyThreadPool.h"
+#include "PySource.h"
+
+#ifdef WITH_CONVOLUTION
+#include "PyImpulseResponse.h"
+#include "PyHRTF.h"
+#endif
+
+#include "respec/Specification.h"
+#include "devices/IHandle.h"
+#include "devices/I3DDevice.h"
+#include "file/IWriter.h"
+#include "plugin/PluginManager.h"
+#include "sequence/AnimateableProperty.h"
+#include "ISound.h"
+
+#include <memory>
+
+#include <structmember.h>
+
+using namespace aud;
+
+// ====================================================================
+
+#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
+
+// ====================================================================
+
+extern PyObject* AUDError;
+PyObject* AUDError = nullptr;
+
+// ====================================================================
+
+PyDoc_STRVAR(M_aud_doc,
+ "Audaspace (pronounced \"outer space\") is a high level audio library.");
+
+static struct PyModuleDef audmodule = {
+ PyModuleDef_HEAD_INIT,
+ "aud", /* name of module */
+ M_aud_doc, /* module documentation */
+ -1, /* size of per-interpreter state of the module,
+ or -1 if the module keeps state in global variables. */
+ nullptr, nullptr, nullptr, nullptr, nullptr
+};
+
+PyMODINIT_FUNC
+PyInit_aud()
+{
+ PyObject* module;
+
+ PluginManager::loadPlugins();
+
+ if(!initializeSound())
+ return nullptr;
+
+ if(!initializeDevice())
+ return nullptr;
+
+ if(!initializeHandle())
+ return nullptr;
+
+ if(!initializeSequenceEntry())
+ return nullptr;
+
+ if(!initializeSequence())
+ return nullptr;
+
+ if(!initializeDynamicMusic())
+ return nullptr;
+
+ if(!initializePlaybackManager())
+ return nullptr;
+
+ if(!initializeThreadPool())
+ return nullptr;
+
+ if(!initializeSource())
+ return nullptr;
+
+#ifdef WITH_CONVOLUTION
+ if(!initializeImpulseResponse())
+ return nullptr;
+
+ if(!initializeHRTF())
+ return nullptr;
+#endif
+
+ module = PyModule_Create(&audmodule);
+ if(module == nullptr)
+ return nullptr;
+
+ addSoundToModule(module);
+ addHandleToModule(module);
+ addDeviceToModule(module);
+ addSequenceEntryToModule(module);
+ addSequenceToModule(module);
+ addDynamicMusicToModule(module);
+ addPlaybackManagerToModule(module);
+ addThreadPoolToModule(module);
+ addSourceToModule(module);
+
+#ifdef WITH_CONVOLUTION
+ addImpulseResponseToModule(module);
+ addHRTFToModule(module);
+#endif
+
+ AUDError = PyErr_NewException("aud.error", nullptr, nullptr);
+ Py_INCREF(AUDError);
+ PyModule_AddObject(module, "error", AUDError);
+
+ // animatable property type constants
+ PY_MODULE_ADD_CONSTANT(module, AP_VOLUME);
+ PY_MODULE_ADD_CONSTANT(module, AP_PANNING);
+ PY_MODULE_ADD_CONSTANT(module, AP_PITCH);
+ PY_MODULE_ADD_CONSTANT(module, AP_LOCATION);
+ PY_MODULE_ADD_CONSTANT(module, AP_ORIENTATION);
+ // channels constants
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_MONO);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_STEREO);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_STEREO_LFE);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND4);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND5);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND51);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND61);
+ PY_MODULE_ADD_CONSTANT(module, CHANNELS_SURROUND71);
+ // codec constants
+ PY_MODULE_ADD_CONSTANT(module, CODEC_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_AAC);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_AC3);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_FLAC);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_MP2);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_MP3);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_PCM);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_VORBIS);
+ PY_MODULE_ADD_CONSTANT(module, CODEC_OPUS);
+ // container constants
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_AC3);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_FLAC);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_MATROSKA);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_MP2);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_MP3);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_OGG);
+ PY_MODULE_ADD_CONSTANT(module, CONTAINER_WAV);
+ // distance model constants
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_EXPONENT);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_EXPONENT_CLAMPED);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_INVERSE);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_INVERSE_CLAMPED);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_LINEAR);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_LINEAR_CLAMPED);
+ PY_MODULE_ADD_CONSTANT(module, DISTANCE_MODEL_INVALID);
+ // format constants
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_FLOAT32);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_FLOAT64);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_S16);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_S24);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_S32);
+ PY_MODULE_ADD_CONSTANT(module, FORMAT_U8);
+ // rate constants
+ PY_MODULE_ADD_CONSTANT(module, RATE_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, RATE_8000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_16000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_11025);
+ PY_MODULE_ADD_CONSTANT(module, RATE_22050);
+ PY_MODULE_ADD_CONSTANT(module, RATE_32000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_44100);
+ PY_MODULE_ADD_CONSTANT(module, RATE_48000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_88200);
+ PY_MODULE_ADD_CONSTANT(module, RATE_96000);
+ PY_MODULE_ADD_CONSTANT(module, RATE_192000);
+ // status constants
+ PY_MODULE_ADD_CONSTANT(module, STATUS_INVALID);
+ PY_MODULE_ADD_CONSTANT(module, STATUS_PAUSED);
+ PY_MODULE_ADD_CONSTANT(module, STATUS_PLAYING);
+ PY_MODULE_ADD_CONSTANT(module, STATUS_STOPPED);
+
+ return module;
+}
+
+AUD_API PyObject* AUD_getPythonSound(void* sound)
+{
+ if(sound)
+ {
+ Sound* object = (Sound*) Sound_empty();
+ if(object)
+ {
+ object->sound = new std::shared_ptr<ISound>(*reinterpret_cast<std::shared_ptr<ISound>*>(sound));
+ return (PyObject *) object;
+ }
+ }
+
+ return nullptr;
+}
+
+AUD_API void* AUD_getSoundFromPython(PyObject* object)
+{
+ Sound* sound = checkSound(object);
+
+ if(!sound)
+ return nullptr;
+
+ return new std::shared_ptr<ISound>(*reinterpret_cast<std::shared_ptr<ISound>*>(sound->sound));
+}
diff --git a/extern/audaspace/bindings/python/PyAPI.h b/extern/audaspace/bindings/python/PyAPI.h
new file mode 100644
index 00000000000..a413b4813d6
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyAPI.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+PyMODINIT_FUNC
+PyInit_aud();
+
+/**
+ * Retrieves the python factory of a sound.
+ * \param sound The sound factory.
+ * \return The python factory.
+ */
+extern AUD_API PyObject* AUD_getPythonSound(void* sound);
+
+/**
+ * Retrieves the sound factory of a python factory.
+ * \param sound The python factory.
+ * \return The sound factory.
+ */
+extern AUD_API void* AUD_getSoundFromPython(PyObject* object);
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/extern/audaspace/bindings/python/PyDevice.cpp b/extern/audaspace/bindings/python/PyDevice.cpp
new file mode 100644
index 00000000000..a6beef57d83
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyDevice.cpp
@@ -0,0 +1,785 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "PyDevice.h"
+
+#include "PySound.h"
+#include "PyHandle.h"
+
+#include "Exception.h"
+#include "devices/IDevice.h"
+#include "devices/I3DDevice.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+
+#include <structmember.h>
+
+using namespace aud;
+
+extern PyObject* AUDError;
+static const char* device_not_3d_error = "Device is not a 3D device!";
+
+// ====================================================================
+
+static void
+Device_dealloc(Device* self)
+{
+ if(self->device)
+ delete reinterpret_cast<std::shared_ptr<IDevice>*>(self->device);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyObject *
+Device_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ Device* self;
+
+ static const char* kwlist[] = {"type", "rate", "channels", "format", "buffer_size", "name", nullptr};
+ const char* device = nullptr;
+ double rate = RATE_48000;
+ int channels = CHANNELS_STEREO;
+ int format = FORMAT_FLOAT32;
+ int buffersize = AUD_DEFAULT_BUFFER_SIZE;
+ const char* name = "";
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|sdiiis:Device", const_cast<char**>(kwlist),
+ &device, &rate, &channels, &format, &buffersize, &name))
+ return nullptr;
+
+ if(buffersize < 128)
+ {
+ PyErr_SetString(PyExc_ValueError, "buffer_size must be at least 128!");
+ return nullptr;
+ }
+
+ self = (Device*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ DeviceSpecs specs;
+ specs.channels = (Channels)channels;
+ specs.format = (SampleFormat)format;
+ specs.rate = (SampleRate)rate;
+
+ self->device = nullptr;
+
+ try
+ {
+ if(!device)
+ {
+ auto dev = DeviceManager::getDevice();
+ if(!dev)
+ {
+ DeviceManager::openDefaultDevice();
+ dev = DeviceManager::getDevice();
+ }
+ self->device = new std::shared_ptr<IDevice>(dev);
+ }
+ else
+ {
+ std::shared_ptr<IDeviceFactory> factory;
+ if(!*device)
+ factory = DeviceManager::getDefaultDeviceFactory();
+ else
+ factory = DeviceManager::getDeviceFactory(device);
+
+ if(factory)
+ {
+ factory->setName(name);
+ factory->setSpecs(specs);
+ factory->setBufferSize(buffersize);
+ self->device = new std::shared_ptr<IDevice>(factory->openDevice());
+ }
+ }
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+
+ if(!self->device)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, "Unsupported device type!");
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Device_lock_doc,
+ "lock()\n\n"
+ "Locks the device so that it's guaranteed, that no samples are "
+ "read from the streams until :meth:`unlock` is called.\n"
+ "This is useful if you want to do start/stop/pause/resume some "
+ "sounds at the same time.\n\n"
+ ".. note:: The device has to be unlocked as often as locked to be "
+ "able to continue playback.\n\n"
+ ".. warning:: Make sure the time between locking and unlocking is "
+ "as short as possible to avoid clicks.");
+
+static PyObject *
+Device_lock(Device* self)
+{
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->lock();
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_play_doc,
+ "play(sound, keep=False)\n\n"
+ "Plays a sound.\n\n"
+ ":arg sound: The sound to play.\n"
+ ":type sound: :class:`Sound`\n"
+ ":arg keep: See :attr:`Handle.keep`.\n"
+ ":type keep: bool\n"
+ ":return: The playback handle with which playback can be "
+ "controlled with.\n"
+ ":rtype: :class:`Handle`");
+
+static PyObject *
+Device_play(Device* self, PyObject* args, PyObject* kwds)
+{
+ PyObject* object;
+ PyObject* keepo = nullptr;
+
+ bool keep = false;
+
+ static const char* kwlist[] = {"sound", "keep", nullptr};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:play", const_cast<char**>(kwlist), &object, &keepo))
+ return nullptr;
+
+ Sound* sound = checkSound(object);
+
+ if(!sound)
+ return nullptr;
+
+ if(keepo != nullptr)
+ {
+ if(!PyBool_Check(keepo))
+ {
+ PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
+ return nullptr;
+ }
+
+ keep = keepo == Py_True;
+ }
+
+ Handle* handle;
+
+ handle = (Handle*)Handle_empty();
+ if(handle != nullptr)
+ {
+ try
+ {
+ handle->handle = new std::shared_ptr<IHandle>((*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->play(*reinterpret_cast<std::shared_ptr<ISound>*>(sound->sound), keep));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(handle);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)handle;
+}
+
+PyDoc_STRVAR(M_aud_Device_stopAll_doc,
+ "stopAll()\n\n"
+ "Stops all playing and paused sounds.");
+
+static PyObject *
+Device_stopAll(Device* self)
+{
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->stopAll();
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_unlock_doc,
+ "unlock()\n\n"
+ "Unlocks the device after a lock call, see :meth:`lock` for "
+ "details.");
+
+static PyObject *
+Device_unlock(Device* self)
+{
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->unlock();
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef Device_methods[] = {
+ {"lock", (PyCFunction)Device_lock, METH_NOARGS,
+ M_aud_Device_lock_doc
+ },
+ {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
+ M_aud_Device_play_doc
+ },
+ {"stopAll", (PyCFunction)Device_stopAll, METH_NOARGS,
+ M_aud_Device_stopAll_doc
+ },
+ {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
+ M_aud_Device_unlock_doc
+ },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Device_channels_doc,
+ "The channel count of the device.");
+
+static PyObject *
+Device_get_channels(Device* self, void* nothing)
+{
+ try
+ {
+ DeviceSpecs specs = (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->getSpecs();
+ return Py_BuildValue("i", specs.channels);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_distance_model_doc,
+ "The distance model of the device.\n\n"
+ ".. seealso:: http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm#_Toc199835864");
+
+static PyObject *
+Device_get_distance_model(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ return Py_BuildValue("i", int(device->getDistanceModel()));
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Device_set_distance_model(Device* self, PyObject* args, void* nothing)
+{
+ int model;
+
+ if(!PyArg_Parse(args, "i:distance_model", &model))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ device->setDistanceModel(DistanceModel(model));
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_doppler_factor_doc,
+ "The doppler factor of the device.\n"
+ "This factor is a scaling factor for the velocity vectors in "
+ "doppler calculation. So a value bigger than 1 will exaggerate "
+ "the effect as it raises the velocity.");
+
+static PyObject *
+Device_get_doppler_factor(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ return Py_BuildValue("f", device->getDopplerFactor());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Device_set_doppler_factor(Device* self, PyObject* args, void* nothing)
+{
+ float factor;
+
+ if(!PyArg_Parse(args, "f:doppler_factor", &factor))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ device->setDopplerFactor(factor);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_format_doc,
+ "The native sample format of the device.");
+
+static PyObject *
+Device_get_format(Device* self, void* nothing)
+{
+ try
+ {
+ DeviceSpecs specs = (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->getSpecs();
+ return Py_BuildValue("i", specs.format);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_listener_location_doc,
+ "The listeners's location in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Device_get_listener_location(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Vector3 v = device->getListenerLocation();
+ return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Device_set_listener_location(Device* self, PyObject* args, void* nothing)
+{
+ float x, y, z;
+
+ if(!PyArg_Parse(args, "(fff):listener_location", &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Vector3 location(x, y, z);
+ device->setListenerLocation(location);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_listener_orientation_doc,
+ "The listener's orientation in 3D space as quaternion, a 4 float tuple.");
+
+static PyObject *
+Device_get_listener_orientation(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Quaternion o = device->getListenerOrientation();
+ return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Device_set_listener_orientation(Device* self, PyObject* args, void* nothing)
+{
+ float w, x, y, z;
+
+ if(!PyArg_Parse(args, "(ffff):listener_orientation", &w, &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Quaternion orientation(w, x, y, z);
+ device->setListenerOrientation(orientation);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_listener_velocity_doc,
+ "The listener's velocity in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Device_get_listener_velocity(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Vector3 v = device->getListenerVelocity();
+ return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Device_set_listener_velocity(Device* self, PyObject* args, void* nothing)
+{
+ float x, y, z;
+
+ if(!PyArg_Parse(args, "(fff):listener_velocity", &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ Vector3 velocity(x, y, z);
+ device->setListenerVelocity(velocity);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_rate_doc,
+ "The sampling rate of the device in Hz.");
+
+static PyObject *
+Device_get_rate(Device* self, void* nothing)
+{
+ try
+ {
+ DeviceSpecs specs = (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->getSpecs();
+ return Py_BuildValue("d", specs.rate);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
+ "The speed of sound of the device.\n"
+ "The speed of sound in air is typically 343.3 m/s.");
+
+static PyObject *
+Device_get_speed_of_sound(Device* self, void* nothing)
+{
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ return Py_BuildValue("f", device->getSpeedOfSound());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Device_set_speed_of_sound(Device* self, PyObject* args, void* nothing)
+{
+ float speed;
+
+ if(!PyArg_Parse(args, "f:speed_of_sound", &speed))
+ return -1;
+
+ try
+ {
+ I3DDevice* device = dynamic_cast<I3DDevice*>(reinterpret_cast<std::shared_ptr<IDevice>*>(self->device)->get());
+ if(device)
+ {
+ device->setSpeedOfSound(speed);
+ return 0;
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Device_volume_doc,
+ "The overall volume of the device.");
+
+static PyObject *
+Device_get_volume(Device* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->getVolume());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Device_set_volume(Device* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume", &volume))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<IDevice>*>(self->device))->setVolume(volume);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+static PyGetSetDef Device_properties[] = {
+ {(char*)"channels", (getter)Device_get_channels, nullptr,
+ M_aud_Device_channels_doc, nullptr },
+ {(char*)"distance_model", (getter)Device_get_distance_model, (setter)Device_set_distance_model,
+ M_aud_Device_distance_model_doc, nullptr },
+ {(char*)"doppler_factor", (getter)Device_get_doppler_factor, (setter)Device_set_doppler_factor,
+ M_aud_Device_doppler_factor_doc, nullptr },
+ {(char*)"format", (getter)Device_get_format, nullptr,
+ M_aud_Device_format_doc, nullptr },
+ {(char*)"listener_location", (getter)Device_get_listener_location, (setter)Device_set_listener_location,
+ M_aud_Device_listener_location_doc, nullptr },
+ {(char*)"listener_orientation", (getter)Device_get_listener_orientation, (setter)Device_set_listener_orientation,
+ M_aud_Device_listener_orientation_doc, nullptr },
+ {(char*)"listener_velocity", (getter)Device_get_listener_velocity, (setter)Device_set_listener_velocity,
+ M_aud_Device_listener_velocity_doc, nullptr },
+ {(char*)"rate", (getter)Device_get_rate, nullptr,
+ M_aud_Device_rate_doc, nullptr },
+ {(char*)"speed_of_sound", (getter)Device_get_speed_of_sound, (setter)Device_set_speed_of_sound,
+ M_aud_Device_speed_of_sound_doc, nullptr },
+ {(char*)"volume", (getter)Device_get_volume, (setter)Device_set_volume,
+ M_aud_Device_volume_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Device_doc,
+ "Device objects represent an audio output backend like OpenAL or "
+ "SDL, but might also represent a file output or RAM buffer "
+ "output.");
+
+static PyTypeObject DeviceType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Device", /* tp_name */
+ sizeof(Device), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Device_dealloc,/* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Device_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Device_methods, /* tp_methods */
+ 0, /* tp_members */
+ Device_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ Device_new, /* tp_new */
+};
+
+AUD_API PyObject* Device_empty()
+{
+ return DeviceType.tp_alloc(&DeviceType, 0);
+}
+
+
+AUD_API Device* checkDevice(PyObject* device)
+{
+ if(!PyObject_TypeCheck(device, &DeviceType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Device!");
+ return nullptr;
+ }
+
+ return (Device*)device;
+}
+
+
+bool initializeDevice()
+{
+ return PyType_Ready(&DeviceType) >= 0;
+}
+
+
+void addDeviceToModule(PyObject* module)
+{
+ Py_INCREF(&DeviceType);
+ PyModule_AddObject(module, "Device", (PyObject *)&DeviceType);
+}
diff --git a/extern/audaspace/bindings/python/PyDevice.h b/extern/audaspace/bindings/python/PyDevice.h
new file mode 100644
index 00000000000..610b5b4cd23
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyDevice.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_IDevice;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_IDevice* device;
+} Device;
+
+extern AUD_API PyObject* Device_empty();
+extern AUD_API Device* checkDevice(PyObject* device);
+
+bool initializeDevice();
+void addDeviceToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PyDynamicMusic.cpp b/extern/audaspace/bindings/python/PyDynamicMusic.cpp
new file mode 100644
index 00000000000..d49f73737c2
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyDynamicMusic.cpp
@@ -0,0 +1,467 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "PyDynamicMusic.h"
+#include "PySound.h"
+#include "PyHandle.h"
+#include "PyDevice.h"
+
+#include "Exception.h"
+#include "fx/DynamicMusic.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+DynamicMusic_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ DynamicMusicP* self = (DynamicMusicP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ PyObject* object;
+ if(!PyArg_ParseTuple(args, "O:device", &object))
+ return nullptr;
+ Device* device = checkDevice(object);
+
+ try
+ {
+ self->dynamicMusic = new std::shared_ptr<aud::DynamicMusic>(new aud::DynamicMusic(*reinterpret_cast<std::shared_ptr<aud::IDevice>*>(device->device)));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+DynamicMusic_dealloc(DynamicMusicP* self)
+{
+ if(self->dynamicMusic)
+ delete reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_addScene_doc,
+ "addScene(scene)\n\n"
+ "Adds a new scene.\n\n"
+ ":arg scene: The scene sound.\n"
+ ":type scene: :class:`Sound`\n"
+ ":return: The new scene id.\n"
+ ":rtype: int");
+
+static PyObject *
+DynamicMusic_addScene(DynamicMusicP* self, PyObject* args)
+{
+ PyObject* object;
+ if(!PyArg_Parse(args, "O:sound", &object))
+ return nullptr;
+
+ Sound* sound = checkSound(object);
+ if(!sound)
+ return nullptr;
+
+ try
+ {
+ return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->addScene(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound)));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_addTransition_doc,
+ "addTransition(ini, end, transition)\n\n"
+ "Adds a new scene.\n\n"
+ ":arg ini: the initial scene foor the transition.\n"
+ ":type ini: int\n"
+ ":arg end: The final scene for the transition.\n"
+ ":type end: int\n"
+ ":arg transition: The transition sound.\n"
+ ":type transition: :class:`Sound`\n"
+ ":return: false if the ini or end scenes don't exist, true othrwise.\n"
+ ":rtype: bool");
+
+static PyObject *
+DynamicMusic_addTransition(DynamicMusicP* self, PyObject* args)
+{
+ PyObject* object;
+ int ini, end;
+ if(!PyArg_ParseTuple(args, "iiO:sound", &ini, &end, &object))
+ return nullptr;
+ Sound* sound = checkSound(object);
+ if(!sound)
+ return nullptr;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->addTransition(ini, end, *reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound));
+ Py_RETURN_NONE;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_resume_doc,
+ "resume()\n\n"
+ "Resumes playback of the scene.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+DynamicMusic_resume(DynamicMusicP* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->resume());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_pause_doc,
+ "pause()\n\n"
+ "Pauses playback of the scene.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+DynamicMusic_pause(DynamicMusicP* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->pause());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_stop_doc,
+ "stop()\n\n"
+ "Stops playback of the scene.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool\n\n");
+
+static PyObject *
+DynamicMusic_stop(DynamicMusicP* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->stop());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef DynamicMusic_methods[] = {
+ { "addScene", (PyCFunction)DynamicMusic_addScene, METH_O,
+ M_aud_DynamicMusic_addScene_doc
+ },
+ { "addTransition", (PyCFunction)DynamicMusic_addTransition, METH_VARARGS,
+ M_aud_DynamicMusic_addTransition_doc
+ },
+ { "resume", (PyCFunction)DynamicMusic_resume, METH_NOARGS,
+ M_aud_DynamicMusic_resume_doc
+ },
+ { "pause", (PyCFunction)DynamicMusic_pause, METH_NOARGS,
+ M_aud_DynamicMusic_pause_doc
+ },
+ { "stop", (PyCFunction)DynamicMusic_stop, METH_NOARGS,
+ M_aud_DynamicMusic_stop_doc
+ },
+ { nullptr } /* Sentinel */
+};
+
+/////////////////////////////////////////////////////
+
+PyDoc_STRVAR(M_aud_DynamicMusic_status_doc,
+ "Whether the scene is playing, paused or stopped (=invalid).");
+
+static PyObject *
+DynamicMusic_get_status(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getStatus());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_position_doc,
+ "The playback position of the scene in seconds.");
+
+static int
+DynamicMusic_set_position(DynamicMusicP* self, PyObject* args, void* nothing)
+{
+ float position;
+
+ if(!PyArg_Parse(args, "f:position", &position))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->seek(position))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't seek the sound!");
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+DynamicMusic_get_position(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getPosition());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_fadeTime_doc,
+ "The length in seconds of the crossfade transition");
+
+static int
+DynamicMusic_set_fadeTime(DynamicMusicP* self, PyObject* args, void* nothing)
+{
+ float fadeTime;
+
+ if(!PyArg_Parse(args, "f:fadeTime", &fadeTime))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->setFadeTime(fadeTime);
+ return 0;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+DynamicMusic_get_fadeTime(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getFadeTime());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_scene_doc,
+ "The current scene");
+
+static int
+DynamicMusic_set_scene(DynamicMusicP* self, PyObject* args, void* nothing)
+{
+ int scene;
+
+ if(!PyArg_Parse(args, "i:scene", &scene))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->changeScene(scene))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't change the scene!");
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+DynamicMusic_get_scene(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getScene());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_DynamicMusic_volume_doc,
+ "The volume of the scene.");
+
+static int
+DynamicMusic_set_volume(DynamicMusicP* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume", &volume))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->setVolume(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't change the volume!");
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+DynamicMusic_get_volume(DynamicMusicP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::DynamicMusic>*>(self->dynamicMusic))->getVolume());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyGetSetDef DynamicMusic_properties[] = {
+ { (char*)"status", (getter)DynamicMusic_get_status, nullptr,
+ M_aud_DynamicMusic_status_doc, nullptr },
+ { (char*)"position", (getter)DynamicMusic_get_position, (setter)DynamicMusic_set_position,
+ M_aud_DynamicMusic_position_doc, nullptr },
+ { (char*)"fadeTime", (getter)DynamicMusic_get_fadeTime, (setter)DynamicMusic_set_fadeTime,
+ M_aud_DynamicMusic_fadeTime_doc, nullptr },
+ { (char*)"scene", (getter)DynamicMusic_get_scene, (setter)DynamicMusic_set_scene,
+ M_aud_DynamicMusic_scene_doc, nullptr },
+ { (char*)"volume", (getter)DynamicMusic_get_volume, (setter)DynamicMusic_set_volume,
+ M_aud_DynamicMusic_volume_doc, nullptr },
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_DynamicMusic_doc,
+ "The DynamicMusic object allows to play music depending on a current scene, scene changes are managed by the class, with the possibility of custom transitions.\n"
+ "The default transition is a crossfade effect, and the default scene is silent and has id 0");
+
+PyTypeObject DynamicMusicType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.DynamicMusic", /* tp_name */
+ sizeof(DynamicMusicP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)DynamicMusic_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_DynamicMusic_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ DynamicMusic_methods, /* tp_methods */
+ 0, /* tp_members */
+ DynamicMusic_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ DynamicMusic_new, /* tp_new */
+};
+
+AUD_API PyObject* DynamicMusic_empty()
+{
+ return DynamicMusicType.tp_alloc(&DynamicMusicType, 0);
+}
+
+
+AUD_API DynamicMusicP* checkDynamicMusic(PyObject* dynamicMusic)
+{
+ if(!PyObject_TypeCheck(dynamicMusic, &DynamicMusicType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type DynamicMusic!");
+ return nullptr;
+ }
+
+ return (DynamicMusicP*)dynamicMusic;
+}
+
+
+bool initializeDynamicMusic()
+{
+ return PyType_Ready(&DynamicMusicType) >= 0;
+}
+
+
+void addDynamicMusicToModule(PyObject* module)
+{
+ Py_INCREF(&DynamicMusicType);
+ PyModule_AddObject(module, "DynamicMusic", (PyObject *)&DynamicMusicType);
+} \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyDynamicMusic.h b/extern/audaspace/bindings/python/PyDynamicMusic.h
new file mode 100644
index 00000000000..f19de2d8c75
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyDynamicMusic.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_DynamicMusic;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_DynamicMusic* dynamicMusic;
+} DynamicMusicP;
+
+extern AUD_API PyObject* DynamicMusic_empty();
+extern AUD_API DynamicMusicP* checkDynamicMusic(PyObject* dynamicMusic);
+
+bool initializeDynamicMusic();
+void addDynamicMusicToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyHRTF.cpp b/extern/audaspace/bindings/python/PyHRTF.cpp
new file mode 100644
index 00000000000..2a5b6be624f
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyHRTF.cpp
@@ -0,0 +1,247 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "PyHRTF.h"
+#include "PySound.h"
+
+#include "Exception.h"
+#include "fx/HRTF.h"
+#include "fx/HRTFLoader.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+HRTF_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ HRTFP* self = (HRTFP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ try
+ {
+ self->hrtf = new std::shared_ptr<aud::HRTF>(new aud::HRTF());
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+HRTF_dealloc(HRTFP* self)
+{
+ if(self->hrtf)
+ delete reinterpret_cast<std::shared_ptr<aud::HRTF>*>(self->hrtf);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_HRTF_addImpulseResponse_doc,
+ "addImpulseResponseFromSound(sound, azimuth, elevation)\n\n"
+ "Adds a new hrtf to the HRTF object\n\n"
+ ":arg sound: The sound that contains the hrtf.\n"
+ ":type sound: :class:`Sound`\n"
+ ":arg azimuth: The azimuth angle of the hrtf.\n"
+ ":type azimuth: float\n"
+ ":arg elevation: The elevation angle of the hrtf.\n"
+ ":type elevation: float\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+HRTF_addImpulseResponseFromSound(HRTFP* self, PyObject* args)
+{
+ PyObject* object;
+ float azimuth, elevation;
+
+ if(!PyArg_ParseTuple(args, "Off:hrtf", &object, &azimuth, &elevation))
+ return nullptr;
+
+ Sound* ir = checkSound(object);
+ if(!ir)
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::HRTF>*>(self->hrtf))->addImpulseResponse(std::make_shared<aud::StreamBuffer>(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(ir->sound)), azimuth, elevation));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_HRTF_loadLeftHrtfSet_doc,
+ "loadLeftHrtfSet(extension, directory)\n\n"
+ "Loads all HRTFs from a directory.\n\n"
+ ":arg extension: The file extension of the hrtfs.\n"
+ ":type extension: string\n"
+ ":arg directory: The path to where the HRTF files are located.\n"
+ ":type extension: string\n"
+ ":return: The loaded :class:`HRTF` object.\n"
+ ":rtype: :class:`HRTF`\n\n");
+
+static PyObject *
+HRTF_loadLeftHrtfSet(PyTypeObject* type, PyObject* args)
+{
+ const char* dir = nullptr;
+ const char* ext = nullptr;
+
+ if(!PyArg_ParseTuple(args, "ss:hrtf", &ext, &dir))
+ return nullptr;
+
+ HRTFP* self;
+ self = (HRTFP*)type->tp_alloc(type, 0);
+
+ try
+ {
+ self->hrtf = new std::shared_ptr<aud::HRTF>(aud::HRTFLoader::loadLeftHRTFs(ext, dir));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_HRTF_loadRightHrtfSet_doc,
+ "loadLeftHrtfSet(extension, directory)\n\n"
+ "Loads all HRTFs from a directory.\n\n"
+ ":arg extension: The file extension of the hrtfs.\n"
+ ":type extension: string\n"
+ ":arg directory: The path to where the HRTF files are located.\n"
+ ":type extension: string\n"
+ ":return: The loaded :class:`HRTF` object.\n"
+ ":rtype: :class:`HRTF`\n\n");
+
+static PyObject *
+HRTF_loadRightHrtfSet(PyTypeObject* type, PyObject* args)
+{
+ const char* dir = nullptr;
+ const char* ext = nullptr;
+
+ if(!PyArg_ParseTuple(args, "ss:hrtf", &ext, &dir))
+ return nullptr;
+
+ HRTFP* self;
+ self = (HRTFP*)type->tp_alloc(type, 0);
+
+ try
+ {
+ self->hrtf = new std::shared_ptr<aud::HRTF>(aud::HRTFLoader::loadRightHRTFs(ext, dir));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ return (PyObject *)self;
+}
+
+static PyMethodDef HRTF_methods[] = {
+ { "addImpulseResponseFromSound", (PyCFunction)HRTF_addImpulseResponseFromSound, METH_VARARGS | METH_KEYWORDS,
+ M_aud_HRTF_addImpulseResponse_doc
+ },
+ { "loadLeftHrtfSet", (PyCFunction)HRTF_loadLeftHrtfSet, METH_VARARGS | METH_CLASS,
+ M_aud_HRTF_loadLeftHrtfSet_doc
+ },
+ { "loadRightHrtfSet", (PyCFunction)HRTF_loadRightHrtfSet, METH_VARARGS | METH_CLASS,
+ M_aud_HRTF_loadRightHrtfSet_doc
+ },
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_HRTF_doc,
+ "An HRTF object represents a set of head related transfer functions as impulse responses. It's used for binaural sound");
+
+PyTypeObject HRTFType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.HRTF", /* tp_name */
+ sizeof(HRTFP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)HRTF_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_HRTF_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ HRTF_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ HRTF_new, /* tp_new */
+};
+
+AUD_API PyObject* HRTF_empty()
+{
+ return HRTFType.tp_alloc(&HRTFType, 0);
+}
+
+
+AUD_API HRTFP* checkHRTF(PyObject* hrtf)
+{
+ if(!PyObject_TypeCheck(hrtf, &HRTFType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type HRTF!");
+ return nullptr;
+ }
+
+ return (HRTFP*)hrtf;
+}
+
+
+bool initializeHRTF()
+{
+ return PyType_Ready(&HRTFType) >= 0;
+}
+
+
+void addHRTFToModule(PyObject* module)
+{
+ Py_INCREF(&HRTFType);
+ PyModule_AddObject(module, "HRTF", (PyObject *)&HRTFType);
+}
diff --git a/extern/audaspace/bindings/python/PyHRTF.h b/extern/audaspace/bindings/python/PyHRTF.h
new file mode 100644
index 00000000000..0445069929f
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyHRTF.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_HRTF;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_HRTF* hrtf;
+} HRTFP;
+
+extern AUD_API PyObject* HRTF_empty();
+extern AUD_API HRTFP* checkHRTF(PyObject* hrtf);
+
+bool initializeHRTF();
+void addHRTFToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyHandle.cpp b/extern/audaspace/bindings/python/PyHandle.cpp
new file mode 100644
index 00000000000..7f7a7660049
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyHandle.cpp
@@ -0,0 +1,1126 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "PyHandle.h"
+
+#include "devices/IHandle.h"
+#include "devices/I3DHandle.h"
+#include "Exception.h"
+
+#include <memory>
+
+#include <structmember.h>
+
+using namespace aud;
+
+extern PyObject* AUDError;
+static const char* device_not_3d_error = "Device is not a 3D device!";
+
+static void
+Handle_dealloc(Handle* self)
+{
+ if(self->handle)
+ delete reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_Handle_pause_doc,
+ "pause()\n\n"
+ "Pauses playback.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+Handle_pause(Handle* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->pause());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Handle_resume_doc,
+ "resume()\n\n"
+ "Resumes playback.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+Handle_resume(Handle* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->resume());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Handle_stop_doc,
+ "stop()\n\n"
+ "Stops playback.\n\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool\n\n"
+ ".. note:: This makes the handle invalid.");
+
+static PyObject *
+Handle_stop(Handle* self)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->stop());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef Handle_methods[] = {
+ {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
+ M_aud_Handle_pause_doc
+ },
+ {"resume", (PyCFunction)Handle_resume, METH_NOARGS,
+ M_aud_Handle_resume_doc
+ },
+ {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
+ M_aud_Handle_stop_doc
+ },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
+ "This factor is used for distance based attenuation of the "
+ "source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_attenuation(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getAttenuation());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_attenuation(Handle* self, PyObject* args, void* nothing)
+{
+ float factor;
+
+ if(!PyArg_Parse(args, "f:attenuation", &factor))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setAttenuation(factor))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the attenuation!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
+ "The opening angle of the inner cone of the source. If the cone "
+ "values of a source are set there are two (audible) cones with "
+ "the apex at the :attr:`location` of the source and with infinite "
+ "height, heading in the direction of the source's "
+ ":attr:`orientation`.\n"
+ "In the inner cone the volume is normal. Outside the outer cone "
+ "the volume will be :attr:`cone_volume_outer` and in the area "
+ "between the volume will be interpolated linearly.");
+
+static PyObject *
+Handle_get_cone_angle_inner(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getConeAngleInner());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_cone_angle_inner(Handle* self, PyObject* args, void* nothing)
+{
+ float angle;
+
+ if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setConeAngleInner(angle))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
+ "The opening angle of the outer cone of the source.\n\n"
+ ".. seealso:: :attr:`cone_angle_inner`");
+
+static PyObject *
+Handle_get_cone_angle_outer(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getConeAngleOuter());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_cone_angle_outer(Handle* self, PyObject* args, void* nothing)
+{
+ float angle;
+
+ if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setConeAngleOuter(angle))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
+ "The volume outside the outer cone of the source.\n\n"
+ ".. seealso:: :attr:`cone_angle_inner`");
+
+static PyObject *
+Handle_get_cone_volume_outer(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getConeVolumeOuter());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_cone_volume_outer(Handle* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setConeVolumeOuter(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
+ "The maximum distance of the source.\n"
+ "If the listener is further away the source volume will be 0.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_distance_maximum(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getDistanceMaximum());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_distance_maximum(Handle* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance_maximum", &distance))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setDistanceMaximum(distance))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
+ "The reference distance of the source.\n"
+ "At this distance the volume will be exactly :attr:`volume`.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_distance_reference(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getDistanceReference());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_distance_reference(Handle* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance_reference", &distance))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setDistanceReference(distance))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the reference distance!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_keep_doc,
+ "Whether the sound should be kept paused in the device when its "
+ "end is reached.\n"
+ "This can be used to seek the sound to some position and start "
+ "playback again.\n\n"
+ ".. warning:: If this is set to true and you forget stopping this "
+ "equals a memory leak as the handle exists until the device is "
+ "destroyed.");
+
+static PyObject *
+Handle_get_keep(Handle* self, void* nothing)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getKeep());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_keep(Handle* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
+ return -1;
+ }
+
+ bool keep = args == Py_True;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setKeep(keep))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_location_doc,
+ "The source's location in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Handle_get_location(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Vector3 v = handle->getLocation();
+ return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Handle_set_location(Handle* self, PyObject* args, void* nothing)
+{
+ float x, y, z;
+
+ if(!PyArg_Parse(args, "(fff):location", &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Vector3 location(x, y, z);
+ if(handle->setLocation(location))
+ return 0;
+ PyErr_SetString(AUDError, "Location couldn't be set!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
+ "The (remaining) loop count of the sound. A negative value indicates infinity.");
+
+static PyObject *
+Handle_get_loop_count(Handle* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getLoopCount());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_loop_count(Handle* self, PyObject* args, void* nothing)
+{
+ int loops;
+
+ if(!PyArg_Parse(args, "i:loop_count", &loops))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setLoopCount(loops))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the loop count!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_orientation_doc,
+ "The source's orientation in 3D space as quaternion, a 4 float tuple.");
+
+static PyObject *
+Handle_get_orientation(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Quaternion o = handle->getOrientation();
+ return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Handle_set_orientation(Handle* self, PyObject* args, void* nothing)
+{
+ float w, x, y, z;
+
+ if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Quaternion orientation(w, x, y, z);
+ if(handle->setOrientation(orientation))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the orientation!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_pitch_doc,
+ "The pitch of the sound.");
+
+static PyObject *
+Handle_get_pitch(Handle* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getPitch());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_pitch(Handle* self, PyObject* args, void* nothing)
+{
+ float pitch;
+
+ if(!PyArg_Parse(args, "f:pitch", &pitch))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setPitch(pitch))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_position_doc,
+ "The playback position of the sound in seconds.");
+
+static PyObject *
+Handle_get_position(Handle* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getPosition());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_position(Handle* self, PyObject* args, void* nothing)
+{
+ float position;
+
+ if(!PyArg_Parse(args, "f:position", &position))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->seek(position))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't seek the sound!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_relative_doc,
+ "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
+
+static PyObject *
+Handle_get_relative(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return PyBool_FromLong((long)handle->isRelative());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Handle_set_relative(Handle* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
+ return -1;
+ }
+
+ bool relative = (args == Py_True);
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setRelative(relative))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the relativeness!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_status_doc,
+ "Whether the sound is playing, paused or stopped (=invalid).");
+
+static PyObject *
+Handle_get_status(Handle* self, void* nothing)
+{
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getStatus());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Handle_velocity_doc,
+ "The source's velocity in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Handle_get_velocity(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Vector3 v = handle->getVelocity();
+ return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+Handle_set_velocity(Handle* self, PyObject* args, void* nothing)
+{
+ float x, y, z;
+
+ if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ Vector3 velocity(x, y, z);
+ if(handle->setVelocity(velocity))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the velocity!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_doc,
+ "The volume of the sound.");
+
+static PyObject *
+Handle_get_volume(Handle* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->getVolume());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_volume(Handle* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume", &volume))
+ return -1;
+
+ try
+ {
+ if((*reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle))->setVolume(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the sound volume!");
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
+ "The maximum volume of the source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_volume_maximum(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getVolumeMaximum());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_volume_maximum(Handle* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume_maximum", &volume))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setVolumeMaximum(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the maximum volume!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
+ "The minimum volume of the source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+Handle_get_volume_minimum(Handle* self, void* nothing)
+{
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ return Py_BuildValue("f", handle->getVolumeMinimum());
+ }
+ else
+ {
+ PyErr_SetString(AUDError, device_not_3d_error);
+ return nullptr;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Handle_set_volume_minimum(Handle* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume_minimum", &volume))
+ return -1;
+
+ try
+ {
+ I3DHandle* handle = dynamic_cast<I3DHandle*>(reinterpret_cast<std::shared_ptr<IHandle>*>(self->handle)->get());
+ if(handle)
+ {
+ if(handle->setVolumeMinimum(volume))
+ return 0;
+ PyErr_SetString(AUDError, "Couldn't set the minimum volume!");
+ }
+ else
+ PyErr_SetString(AUDError, device_not_3d_error);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyGetSetDef Handle_properties[] = {
+ {(char*)"attenuation", (getter)Handle_get_attenuation, (setter)Handle_set_attenuation,
+ M_aud_Handle_attenuation_doc, nullptr },
+ {(char*)"cone_angle_inner", (getter)Handle_get_cone_angle_inner, (setter)Handle_set_cone_angle_inner,
+ M_aud_Handle_cone_angle_inner_doc, nullptr },
+ {(char*)"cone_angle_outer", (getter)Handle_get_cone_angle_outer, (setter)Handle_set_cone_angle_outer,
+ M_aud_Handle_cone_angle_outer_doc, nullptr },
+ {(char*)"cone_volume_outer", (getter)Handle_get_cone_volume_outer, (setter)Handle_set_cone_volume_outer,
+ M_aud_Handle_cone_volume_outer_doc, nullptr },
+ {(char*)"distance_maximum", (getter)Handle_get_distance_maximum, (setter)Handle_set_distance_maximum,
+ M_aud_Handle_distance_maximum_doc, nullptr },
+ {(char*)"distance_reference", (getter)Handle_get_distance_reference, (setter)Handle_set_distance_reference,
+ M_aud_Handle_distance_reference_doc, nullptr },
+ {(char*)"keep", (getter)Handle_get_keep, (setter)Handle_set_keep,
+ M_aud_Handle_keep_doc, nullptr },
+ {(char*)"location", (getter)Handle_get_location, (setter)Handle_set_location,
+ M_aud_Handle_location_doc, nullptr },
+ {(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count,
+ M_aud_Handle_loop_count_doc, nullptr },
+ {(char*)"orientation", (getter)Handle_get_orientation, (setter)Handle_set_orientation,
+ M_aud_Handle_orientation_doc, nullptr },
+ {(char*)"pitch", (getter)Handle_get_pitch, (setter)Handle_set_pitch,
+ M_aud_Handle_pitch_doc, nullptr },
+ {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position,
+ M_aud_Handle_position_doc, nullptr },
+ {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
+ M_aud_Handle_relative_doc, nullptr },
+ {(char*)"status", (getter)Handle_get_status, nullptr,
+ M_aud_Handle_status_doc, nullptr },
+ {(char*)"velocity", (getter)Handle_get_velocity, (setter)Handle_set_velocity,
+ M_aud_Handle_velocity_doc, nullptr },
+ {(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume,
+ M_aud_Handle_volume_doc, nullptr },
+ {(char*)"volume_maximum", (getter)Handle_get_volume_maximum, (setter)Handle_set_volume_maximum,
+ M_aud_Handle_volume_maximum_doc, nullptr },
+ {(char*)"volume_minimum", (getter)Handle_get_volume_minimum, (setter)Handle_set_volume_minimum,
+ M_aud_Handle_volume_minimum_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Handle_doc,
+ "Handle objects are playback handles that can be used to control "
+ "playback of a sound. If a sound is played back multiple times "
+ "then there are as many handles.");
+
+static PyTypeObject HandleType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Handle", /* tp_name */
+ sizeof(Handle), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Handle_dealloc,/* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Handle_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Handle_methods, /* tp_methods */
+ 0, /* tp_members */
+ Handle_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+
+AUD_API PyObject* Handle_empty()
+{
+ return HandleType.tp_alloc(&HandleType, 0);
+}
+
+
+AUD_API Handle*checkHandle(PyObject* handle)
+{
+ if(!PyObject_TypeCheck(handle, &HandleType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Handle!");
+ return nullptr;
+ }
+
+ return (Handle*)handle;
+}
+
+
+bool initializeHandle()
+{
+ return PyType_Ready(&HandleType) >= 0;
+}
+
+
+void addHandleToModule(PyObject* module)
+{
+ Py_INCREF(&HandleType);
+ PyModule_AddObject(module, "Handle", (PyObject *)&HandleType);
+}
+
+
diff --git a/extern/audaspace/bindings/python/PyHandle.h b/extern/audaspace/bindings/python/PyHandle.h
new file mode 100644
index 00000000000..95006c88da7
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyHandle.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_IHandle;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_IHandle* handle;
+} Handle;
+
+extern AUD_API PyObject* Handle_empty();
+extern AUD_API Handle* checkHandle(PyObject* handle);
+
+bool initializeHandle();
+void addHandleToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PyImpulseResponse.cpp b/extern/audaspace/bindings/python/PyImpulseResponse.cpp
new file mode 100644
index 00000000000..5200c938511
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyImpulseResponse.cpp
@@ -0,0 +1,137 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "PyImpulseResponse.h"
+#include "PySound.h"
+
+#include "Exception.h"
+#include "fx/ImpulseResponse.h"
+#include "util/StreamBuffer.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+ImpulseResponse_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ ImpulseResponseP* self = (ImpulseResponseP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ PyObject* object;
+ if(!PyArg_ParseTuple(args, "O:sound", &object))
+ return nullptr;
+ Sound* sound = checkSound(object);
+
+ try
+ {
+ self->impulseResponse = new std::shared_ptr<aud::ImpulseResponse>(new aud::ImpulseResponse(std::make_shared<aud::StreamBuffer>(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound))));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+ImpulseResponse_dealloc(ImpulseResponseP* self)
+{
+ if(self->impulseResponse)
+ delete reinterpret_cast<std::shared_ptr<aud::ImpulseResponse>*>(self->impulseResponse);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyMethodDef ImpulseResponse_methods[] = {
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_ImpulseResponse_doc,
+ "An ImpulseResponse object represents a filter with which to convolve a sound.");
+
+PyTypeObject ImpulseResponseType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.ImpulseResponse", /* tp_name */
+ sizeof(ImpulseResponseP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)ImpulseResponse_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_ImpulseResponse_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ ImpulseResponse_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ ImpulseResponse_new, /* tp_new */
+};
+
+AUD_API PyObject* ImpulseResponse_empty()
+{
+ return ImpulseResponseType.tp_alloc(&ImpulseResponseType, 0);
+}
+
+
+AUD_API ImpulseResponseP* checkImpulseResponse(PyObject* impulseResponse)
+{
+ if(!PyObject_TypeCheck(impulseResponse, &ImpulseResponseType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type ImpulseResponse!");
+ return nullptr;
+ }
+
+ return (ImpulseResponseP*)impulseResponse;
+}
+
+
+bool initializeImpulseResponse()
+{
+ return PyType_Ready(&ImpulseResponseType) >= 0;
+}
+
+
+void addImpulseResponseToModule(PyObject* module)
+{
+ Py_INCREF(&ImpulseResponseType);
+ PyModule_AddObject(module, "ImpulseResponse", (PyObject *)&ImpulseResponseType);
+}
diff --git a/extern/audaspace/bindings/python/PyImpulseResponse.h b/extern/audaspace/bindings/python/PyImpulseResponse.h
new file mode 100644
index 00000000000..3e974c0701c
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyImpulseResponse.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_ImpulseResponse;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_ImpulseResponse* impulseResponse;
+} ImpulseResponseP;
+
+extern AUD_API PyObject* ImpulseResponse_empty();
+extern AUD_API ImpulseResponseP* checkImpulseResponse(PyObject* impulseResponse);
+
+bool initializeImpulseResponse();
+void addImpulseResponseToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyPlaybackManager.cpp b/extern/audaspace/bindings/python/PyPlaybackManager.cpp
new file mode 100644
index 00000000000..9b6614cae9a
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyPlaybackManager.cpp
@@ -0,0 +1,389 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "PyPlaybackManager.h"
+#include "PySound.h"
+#include "PyHandle.h"
+#include "PyDevice.h"
+
+#include "Exception.h"
+#include "fx/PlaybackManager.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+PlaybackManager_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ PlaybackManagerP* self = (PlaybackManagerP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ PyObject* object;
+ if(!PyArg_ParseTuple(args, "O:catKey", &object))
+ return nullptr;
+ Device* device = checkDevice(object);
+
+ try
+ {
+ self->playbackManager = new std::shared_ptr<aud::PlaybackManager>(new aud::PlaybackManager(*reinterpret_cast<std::shared_ptr<aud::IDevice>*>(device->device)));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+PlaybackManager_dealloc(PlaybackManagerP* self)
+{
+ if(self->playbackManager)
+ delete reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_play_doc,
+ "setVolume(sound, catKey)\n\n"
+ "Plays a sound through the playback manager and assigns it to a category.\n\n"
+ ":arg sound: The sound to play.\n"
+ ":type sound: :class:`Sound`\n"
+ ":arg catKey: the key of the category in which the sound will be added, if it doesn't exist, a new one will be created.\n"
+ ":type catKey: int\n"
+ ":return: The playback handle with which playback can be controlled with.\n"
+ ":rtype: :class:`Handle`");
+
+static PyObject *
+PlaybackManager_play(PlaybackManagerP* self, PyObject* args)
+{
+ PyObject* object;
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "OI:catKey", &object, &cat))
+ return nullptr;
+
+ Sound* sound = checkSound(object);
+ if(!sound)
+ return nullptr;
+
+ Handle* handle;
+
+ handle = (Handle*)Handle_empty();
+ if(handle != nullptr)
+ {
+ try
+ {
+ handle->handle = new std::shared_ptr<aud::IHandle>((*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->play(*reinterpret_cast<std::shared_ptr<aud::ISound>*>(sound->sound), cat));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(handle);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)handle;
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_resume_doc,
+ "resume(catKey)\n\n"
+ "Resumes playback of the catgory.\n\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+PlaybackManager_resume(PlaybackManagerP* self, PyObject* args)
+{
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "I:catKey", &cat))
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->resume(cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_pause_doc,
+ "pause(catKey)\n\n"
+ "Pauses playback of the category.\n\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool");
+
+static PyObject *
+PlaybackManager_pause(PlaybackManagerP* self, PyObject* args)
+{
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "I:catKey", &cat))
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->pause(cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_add_category_doc,
+ "addCategory(volume)\n\n"
+ "Adds a category with a custom volume.\n\n"
+ ":arg volume: The volume for ther new category.\n"
+ ":type volume: float\n"
+ ":return: The key of the new category.\n"
+ ":rtype: int\n\n");
+
+static PyObject *
+PlaybackManager_add_category(PlaybackManagerP* self, PyObject* args)
+{
+ float vol;
+
+ if(!PyArg_ParseTuple(args, "f:volume", &vol))
+ return nullptr;
+
+ try
+ {
+ return Py_BuildValue("I", (*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->addCategory(vol));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_get_volume_doc,
+ "getVolume(catKey)\n\n"
+ "Retrieves the volume of a category.\n\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: The volume of the cateogry.\n"
+ ":rtype: float\n\n");
+
+static PyObject *
+PlaybackManager_get_volume(PlaybackManagerP* self, PyObject* args)
+{
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "I:catKey", &cat))
+ return nullptr;
+
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->getVolume(cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_set_volume_doc,
+ "setVolume(volume, catKey)\n\n"
+ "Changes the volume of a category.\n\n"
+ ":arg volume: the new volume value.\n"
+ ":type volume: float\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: int\n\n");
+
+static PyObject *
+PlaybackManager_set_volume(PlaybackManagerP* self, PyObject* args)
+{
+ float volume;
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "fI:volume", &volume, &cat))
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->setVolume(volume, cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_stop_doc,
+ "stop(catKey)\n\n"
+ "Stops playback of the category.\n\n"
+ ":arg catKey: the key of the category.\n"
+ ":type catKey: int\n"
+ ":return: Whether the action succeeded.\n"
+ ":rtype: bool\n\n");
+
+static PyObject *
+PlaybackManager_stop(PlaybackManagerP* self, PyObject* args)
+{
+ unsigned int cat;
+
+ if(!PyArg_ParseTuple(args, "I:catKey", &cat))
+ return nullptr;
+
+ try
+ {
+ return PyBool_FromLong((long)(*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->stop(cat));
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_PlaybackManager_clean_doc,
+ "clean()\n\n"
+ "Cleans all the invalid and finished sound from the playback manager.\n\n");
+
+static PyObject *
+PlaybackManager_clean(PlaybackManagerP* self)
+{
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::PlaybackManager>*>(self->playbackManager))->clean();
+ Py_RETURN_NONE;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef PlaybackManager_methods[] = {
+ { "play", (PyCFunction)PlaybackManager_play, METH_VARARGS | METH_KEYWORDS,
+ M_aud_PlaybackManager_play_doc
+ },
+ { "resume", (PyCFunction)PlaybackManager_resume, METH_VARARGS,
+ M_aud_PlaybackManager_resume_doc
+ },
+ { "pause", (PyCFunction)PlaybackManager_pause, METH_VARARGS,
+ M_aud_PlaybackManager_pause_doc
+ },
+ { "stop", (PyCFunction)PlaybackManager_stop, METH_VARARGS,
+ M_aud_PlaybackManager_stop_doc
+ },
+ { "addCategory", (PyCFunction)PlaybackManager_add_category, METH_VARARGS,
+ M_aud_PlaybackManager_add_category_doc
+ },
+ { "getVolume", (PyCFunction)PlaybackManager_get_volume, METH_VARARGS,
+ M_aud_PlaybackManager_get_volume_doc
+ },
+ { "setVolume", (PyCFunction)PlaybackManager_set_volume, METH_VARARGS,
+ M_aud_PlaybackManager_set_volume_doc
+ },
+ { "clean", (PyCFunction)PlaybackManager_clean, METH_NOARGS,
+ M_aud_PlaybackManager_clean_doc
+ },
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_PlaybackManager_doc,
+ "A PlabackManager object allows to easily control groups os sounds organized in categories.");
+
+PyTypeObject PlaybackManagerType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.PlaybackManager", /* tp_name */
+ sizeof(PlaybackManagerP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)PlaybackManager_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_PlaybackManager_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ PlaybackManager_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ PlaybackManager_new, /* tp_new */
+};
+
+AUD_API PyObject* PlaybackManager_empty()
+{
+ return PlaybackManagerType.tp_alloc(&PlaybackManagerType, 0);
+}
+
+
+AUD_API PlaybackManagerP* checkPlaybackManager(PyObject* playbackManager)
+{
+ if(!PyObject_TypeCheck(playbackManager, &PlaybackManagerType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type PlaybackManager!");
+ return nullptr;
+ }
+
+ return (PlaybackManagerP*)playbackManager;
+}
+
+
+bool initializePlaybackManager()
+{
+ return PyType_Ready(&PlaybackManagerType) >= 0;
+}
+
+
+void addPlaybackManagerToModule(PyObject* module)
+{
+ Py_INCREF(&PlaybackManagerType);
+ PyModule_AddObject(module, "PlaybackManager", (PyObject *)&PlaybackManagerType);
+}
diff --git a/extern/audaspace/bindings/python/PyPlaybackManager.h b/extern/audaspace/bindings/python/PyPlaybackManager.h
new file mode 100644
index 00000000000..f26df1b32d0
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyPlaybackManager.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_PlaybackManager;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_PlaybackManager* playbackManager;
+} PlaybackManagerP;
+
+extern AUD_API PyObject* PlaybackManager_empty();
+extern AUD_API PlaybackManagerP* checkPlaybackManager(PyObject* playbackManager);
+
+bool initializePlaybackManager();
+void addPlaybackManagerToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PySequence.cpp b/extern/audaspace/bindings/python/PySequence.cpp
new file mode 100644
index 00000000000..d4773c743ee
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySequence.cpp
@@ -0,0 +1,655 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "PySequence.h"
+
+#include "PySound.h"
+#include "PySequenceEntry.h"
+
+#include "sequence/AnimateableProperty.h"
+#include "sequence/Sequence.h"
+#include "Exception.h"
+
+#include <vector>
+#include <structmember.h>
+
+using aud::Channels;
+using aud::DistanceModel;
+using aud::Exception;
+using aud::ISound;
+using aud::AnimateableProperty;
+using aud::AnimateablePropertyType;
+using aud::Specs;
+
+extern PyObject* AUDError;
+
+// ====================================================================
+
+static void
+Sequence_dealloc(Sequence* self)
+{
+ if(self->sequence)
+ delete reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyObject *
+Sequence_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ Sequence* self;
+
+ int channels = aud::CHANNELS_STEREO;
+ double rate = aud::RATE_48000;
+ float fps = 30.0f;
+ bool muted = false;
+ PyObject* mutedo = nullptr;
+
+ self = (Sequence*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ static const char* kwlist[] = {"channels", "rate", "fps", "muted", nullptr};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|idfO:Sequence", const_cast<char**>(kwlist), &channels, &rate, &fps, &mutedo))
+ {
+ Py_DECREF(self);
+ return nullptr;
+ }
+
+ if(mutedo)
+ {
+ if(!PyBool_Check(mutedo))
+ {
+ PyErr_SetString(PyExc_TypeError, "muted is not a boolean!");
+ return nullptr;
+ }
+
+ muted = mutedo == Py_True;
+ }
+
+ aud::Specs specs;
+ specs.channels = static_cast<aud::Channels>(channels);
+ specs.rate = rate;
+
+ try
+ {
+ self->sequence = new std::shared_ptr<aud::Sequence>(new aud::Sequence(specs, fps, muted));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sequence_add_doc,
+ "add()\n\n"
+ "Adds a new entry to the scene.\n"
+ ":arg sound: The sound this entry should play.\n"
+ ":type sound: :class:`Sound`\n"
+ ":arg begin: The start time.\n"
+ ":type begin: float\n"
+ ":arg end: The end time or a negative value if determined by the sound.\n"
+ ":type end: float\n"
+ ":arg skip: How much seconds should be skipped at the beginning.\n"
+ ":type skip: float\n"
+ ":return: The entry added.\n"
+ ":rtype: :class:`SequenceEntry`");
+
+static PyObject *
+Sequence_add(Sequence* self, PyObject* args, PyObject* kwds)
+{
+ PyObject* object;
+ float begin;
+ float end = -1.0f;
+ float skip = 0.0f;
+
+ static const char* kwlist[] = {"sound", "begin", "end", "skip", nullptr};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "Of|ff:add", const_cast<char**>(kwlist), &object, &begin, &end, &skip))
+ return nullptr;
+
+ Sound* sound = checkSound(object);
+
+ if(!sound)
+ return nullptr;
+
+ SequenceEntry* entry;
+
+ entry = (SequenceEntry*)SequenceEntry_empty();
+ if(entry != nullptr)
+ {
+ try
+ {
+ entry->entry = new std::shared_ptr<aud::SequenceEntry>((*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->add(*reinterpret_cast<std::shared_ptr<ISound>*>(sound->sound), begin, end, skip));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(entry);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)entry;
+}
+
+PyDoc_STRVAR(M_aud_Sequence_remove_doc,
+ "reomve()\n\n"
+ "Adds a new entry to the scene.\n"
+ ":arg entry: The entry to remove.\n"
+ ":type entry: :class:`SequenceEntry`\n");
+
+static PyObject *
+Sequence_remove(Sequence* self, PyObject* args)
+{
+ PyObject* object;
+
+ if(!PyArg_ParseTuple(args, "O:remove", &object))
+ return nullptr;
+
+ SequenceEntry* entry = checkSequenceEntry(object);
+
+ if(!entry)
+ return nullptr;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->remove(*reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(entry->entry));
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(entry);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_setAnimationData_doc,
+ "setAnimationData()\n\n"
+ "Writes animation data to a sequence.\n\n"
+ ":arg type: The type of animation data.\n"
+ ":type type: int\n"
+ ":arg frame: The frame this data is for.\n"
+ ":type frame: int\n"
+ ":arg data: The data to write.\n"
+ ":type data: sequence of float\n"
+ ":arg animated: Whether the attribute is animated.\n"
+ ":type animated: bool");
+
+static PyObject *
+Sequence_setAnimationData(Sequence* self, PyObject* args)
+{
+ int type, frame;
+ PyObject* py_data;
+ Py_ssize_t py_data_len;
+ PyObject* animatedo;
+ bool animated;
+
+ if(!PyArg_ParseTuple(args, "iiOO:setAnimationData", &type, &frame, &py_data, &animatedo))
+ return nullptr;
+
+ if(!PySequence_Check(py_data))
+ {
+ PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
+ return nullptr;
+ }
+
+ py_data_len= PySequence_Size(py_data);
+
+ std::vector<float> data;
+ data.resize(py_data_len);
+
+ PyObject* py_value;
+ float value;
+
+ for(Py_ssize_t i = 0; i < py_data_len; i++)
+ {
+ py_value = PySequence_GetItem(py_data, i);
+ value= (float)PyFloat_AsDouble(py_value);
+ Py_DECREF(py_value);
+
+ if(value == -1.0f && PyErr_Occurred()) {
+ return nullptr;
+ }
+
+ data.push_back(value);
+ }
+
+ if(!PyBool_Check(animatedo))
+ {
+ PyErr_SetString(PyExc_TypeError, "animated is not a boolean!");
+ return nullptr;
+ }
+
+ animated = animatedo == Py_True;
+
+ try
+ {
+ AnimateableProperty* prop = (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getAnimProperty(static_cast<AnimateablePropertyType>(type));
+
+ if(prop->getCount() != py_data_len)
+ {
+ PyErr_SetString(PyExc_ValueError, "the amount of floats doesn't fit the animated property");
+ return nullptr;
+ }
+
+ if(animated)
+ {
+ if(frame >= 0)
+ prop->write(&data[0], frame, 1);
+ }
+ else
+ {
+ prop->write(&data[0]);
+ }
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef Sequence_methods[] = {
+ {"add", (PyCFunction)Sequence_add, METH_VARARGS | METH_KEYWORDS,
+ M_aud_Sequence_add_doc
+ },
+ {"remove", (PyCFunction)Sequence_remove, METH_VARARGS,
+ M_aud_Sequence_remove_doc
+ },
+ {"setAnimationData", (PyCFunction)Sequence_setAnimationData, METH_VARARGS,
+ M_aud_Sequence_setAnimationData_doc
+ },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sequence_channels_doc,
+ "The channel count of the sequence.");
+
+static PyObject *
+Sequence_get_channels(Sequence* self, void* nothing)
+{
+ try
+ {
+ Specs specs = (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getSpecs();
+ return Py_BuildValue("i", specs.channels);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_channels(Sequence* self, PyObject* args, void* nothing)
+{
+ int channels;
+
+ if(!PyArg_Parse(args, "i:channels", &channels))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::Sequence> sequence = *reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ Specs specs = sequence->getSpecs();
+ specs.channels = static_cast<Channels>(channels);
+ sequence->setSpecs(specs);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_distance_model_doc,
+ "The distance model of the sequence.\n\n"
+ ".. seealso:: http://connect.creativelabs.com/openal/Documentation/OpenAL%201.1%20Specification.htm#_Toc199835864");
+
+static PyObject *
+Sequence_get_distance_model(Sequence* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("i", (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getDistanceModel());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_distance_model(Sequence* self, PyObject* args, void* nothing)
+{
+ int distance_model;
+
+ if(!PyArg_Parse(args, "i:distance_model", &distance_model))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->setDistanceModel(static_cast<DistanceModel>(distance_model));
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_doppler_factor_doc,
+ "The doppler factor of the sequence.\n"
+ "This factor is a scaling factor for the velocity vectors in "
+ "doppler calculation. So a value bigger than 1 will exaggerate "
+ "the effect as it raises the velocity.");
+
+static PyObject *
+Sequence_get_doppler_factor(Sequence* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getDopplerFactor());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_doppler_factor(Sequence* self, PyObject* args, void* nothing)
+{
+ float factor;
+
+ if(!PyArg_Parse(args, "f:doppler_factor", &factor))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->setDopplerFactor(factor);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_fps_doc,
+ "The listeners's location in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Sequence_get_fps(Sequence* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getFPS());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_fps(Sequence* self, PyObject* args, void* nothing)
+{
+ float fps;
+
+ if(!PyArg_Parse(args, "f:fps", &fps))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->setFPS(fps);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_muted_doc,
+ "Whether the whole sequence is muted.\n");
+
+static PyObject *
+Sequence_get_muted(Sequence* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::Sequence>* sequence = reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ return PyBool_FromLong((long)(*sequence)->isMuted());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_muted(Sequence* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "muted is not a boolean!");
+ return -1;
+ }
+
+ bool muted = args == Py_True;
+
+ try
+ {
+ std::shared_ptr<aud::Sequence>* sequence = reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ (*sequence)->mute(muted);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_Sequence_rate_doc,
+ "The sampling rate of the sequence in Hz.");
+
+static PyObject *
+Sequence_get_rate(Sequence* self, void* nothing)
+{
+ try
+ {
+ Specs specs = (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getSpecs();
+ return Py_BuildValue("d", specs.rate);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_rate(Sequence* self, PyObject* args, void* nothing)
+{
+ double rate;
+
+ if(!PyArg_Parse(args, "d:rate", &rate))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::Sequence> sequence = *reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence);
+ Specs specs = sequence->getSpecs();
+ specs.rate = rate;
+ sequence->setSpecs(specs);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sequence_speed_of_sound_doc,
+ "The speed of sound of the sequence.\n"
+ "The speed of sound in air is typically 343.3 m/s.");
+
+static PyObject *
+Sequence_get_speed_of_sound(Sequence* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->getSpeedOfSound());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+Sequence_set_speed_of_sound(Sequence* self, PyObject* args, void* nothing)
+{
+ float speed;
+
+ if(!PyArg_Parse(args, "f:speed_of_sound", &speed))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Sequence>*>(self->sequence))->setSpeedOfSound(speed);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return -1;
+ }
+}
+
+static PyGetSetDef Sequence_properties[] = {
+ {(char*)"channels", (getter)Sequence_get_channels, (setter)Sequence_set_channels,
+ M_aud_Sequence_channels_doc, nullptr },
+ {(char*)"distance_model", (getter)Sequence_get_distance_model, (setter)Sequence_set_distance_model,
+ M_aud_Sequence_distance_model_doc, nullptr },
+ {(char*)"doppler_factor", (getter)Sequence_get_doppler_factor, (setter)Sequence_set_doppler_factor,
+ M_aud_Sequence_doppler_factor_doc, nullptr },
+ {(char*)"fps", (getter)Sequence_get_fps, (setter)Sequence_set_fps,
+ M_aud_Sequence_fps_doc, nullptr },
+ {(char*)"muted", (getter)Sequence_get_muted, (setter)Sequence_set_muted,
+ M_aud_Sequence_muted_doc, nullptr },
+ {(char*)"rate", (getter)Sequence_get_rate, (setter)Sequence_set_rate,
+ M_aud_Sequence_rate_doc, nullptr },
+ {(char*)"speed_of_sound", (getter)Sequence_get_speed_of_sound, (setter)Sequence_set_speed_of_sound,
+ M_aud_Sequence_speed_of_sound_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sequence_doc,
+ "This sound represents sequenced entries to play a sound scene.");
+
+extern PyTypeObject SoundType;
+
+static PyTypeObject SequenceType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Sequence", /* tp_name */
+ sizeof(Sequence), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Sequence_dealloc,/* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Sequence_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Sequence_methods, /* tp_methods */
+ 0, /* tp_members */
+ Sequence_properties, /* tp_getset */
+ &SoundType, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ Sequence_new, /* tp_new */
+};
+
+AUD_API PyObject* Sequence_empty()
+{
+ return SequenceType.tp_alloc(&SequenceType, 0);
+}
+
+
+AUD_API Sequence* checkSequence(PyObject* sequence)
+{
+ if(!PyObject_TypeCheck(sequence, &SequenceType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Sequence!");
+ return nullptr;
+ }
+
+ return (Sequence*)sequence;
+}
+
+
+bool initializeSequence()
+{
+ return PyType_Ready(&SequenceType) >= 0;
+}
+
+
+void addSequenceToModule(PyObject* module)
+{
+ Py_INCREF(&SequenceType);
+ PyModule_AddObject(module, "Sequence", (PyObject *)&SequenceType);
+}
diff --git a/extern/audaspace/bindings/python/PySequence.h b/extern/audaspace/bindings/python/PySequence.h
new file mode 100644
index 00000000000..17855121dda
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySequence.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_Sequence;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_Sequence* sequence;
+} Sequence;
+
+extern AUD_API PyObject* Sequence_empty();
+extern AUD_API Sequence* checkSequence(PyObject* sequence);
+
+bool initializeSequence();
+void addSequenceToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PySequenceEntry.cpp b/extern/audaspace/bindings/python/PySequenceEntry.cpp
new file mode 100644
index 00000000000..e6a034ed880
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySequenceEntry.cpp
@@ -0,0 +1,740 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "PySequenceEntry.h"
+
+#include "PySound.h"
+
+#include "Exception.h"
+#include "sequence/AnimateableProperty.h"
+#include "sequence/SequenceEntry.h"
+
+#include <structmember.h>
+#include <vector>
+
+using aud::Exception;
+using aud::AnimateableProperty;
+using aud::AnimateablePropertyType;
+using aud::ISound;
+
+extern PyObject* AUDError;
+
+// ====================================================================
+
+static void
+SequenceEntry_dealloc(SequenceEntry* self)
+{
+ if(self->entry)
+ delete reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_move_doc,
+ "move()\n\n"
+ "Moves the entry.\n\n"
+ ":arg begin: The new start time.\n"
+ ":type begin: float\n"
+ ":arg end: The new end time or a negative value if unknown.\n"
+ ":type end: float\n"
+ ":arg skip: How many seconds to skip at the beginning.\n"
+ ":type skip: float\n");
+
+static PyObject *
+SequenceEntry_move(SequenceEntry* self, PyObject* args)
+{
+ float begin, end, skip;
+
+ if(!PyArg_ParseTuple(args, "fff:move", &begin, &end, &skip))
+ return nullptr;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry))->move(begin, end, skip);
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_setAnimationData_doc,
+ "setAnimationData()\n\n"
+ "Writes animation data to a sequenced entry.\n\n"
+ ":arg type: The type of animation data.\n"
+ ":type type: int\n"
+ ":arg frame: The frame this data is for.\n"
+ ":type frame: int\n"
+ ":arg data: The data to write.\n"
+ ":type data: sequence of float\n"
+ ":arg animated: Whether the attribute is animated.\n"
+ ":type animated: bool");
+
+static PyObject *
+SequenceEntry_setAnimationData(SequenceEntry* self, PyObject* args)
+{
+ int type, frame;
+ PyObject* py_data;
+ Py_ssize_t py_data_len;
+ PyObject* animatedo;
+ bool animated;
+
+ if(!PyArg_ParseTuple(args, "iiOO:setAnimationData", &type, &frame, &py_data, &animatedo))
+ return nullptr;
+
+ if(!PySequence_Check(py_data))
+ {
+ PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
+ return nullptr;
+ }
+
+ py_data_len= PySequence_Size(py_data);
+
+ std::vector<float> data;
+ data.resize(py_data_len);
+
+ PyObject* py_value;
+ float value;
+
+ for(Py_ssize_t i = 0; i < py_data_len; i++)
+ {
+ py_value = PySequence_GetItem(py_data, i);
+ value= (float)PyFloat_AsDouble(py_value);
+ Py_DECREF(py_value);
+
+ if(value == -1.0f && PyErr_Occurred()) {
+ return nullptr;
+ }
+
+ data.push_back(value);
+ }
+
+ if(!PyBool_Check(animatedo))
+ {
+ PyErr_SetString(PyExc_TypeError, "animated is not a boolean!");
+ return nullptr;
+ }
+
+ animated = animatedo == Py_True;
+
+ try
+ {
+ AnimateableProperty* prop = (*reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry))->getAnimProperty(static_cast<AnimateablePropertyType>(type));
+
+ if(prop->getCount() != py_data_len)
+ {
+ PyErr_SetString(PyExc_ValueError, "the amount of floats doesn't fit the animated property");
+ return nullptr;
+ }
+
+ if(animated)
+ {
+ if(frame >= 0)
+ prop->write(&data[0], frame, 1);
+ }
+ else
+ {
+ prop->write(&data[0]);
+ }
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyMethodDef SequenceEntry_methods[] = {
+ {"move", (PyCFunction)SequenceEntry_move, METH_VARARGS,
+ M_aud_SequenceEntry_move_doc
+ },
+ {"setAnimationData", (PyCFunction)SequenceEntry_setAnimationData, METH_VARARGS,
+ M_aud_SequenceEntry_setAnimationData_doc
+ },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_SequenceEntry_attenuation_doc,
+ "This factor is used for distance based attenuation of the "
+ "source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_attenuation(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getAttenuation());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_attenuation(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float factor;
+
+ if(!PyArg_Parse(args, "f:attenuation", &factor))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setAttenuation(factor);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_cone_angle_inner_doc,
+ "The opening angle of the inner cone of the source. If the cone "
+ "values of a source are set there are two (audible) cones with "
+ "the apex at the :attr:`location` of the source and with infinite "
+ "height, heading in the direction of the source's "
+ ":attr:`orientation`.\n"
+ "In the inner cone the volume is normal. Outside the outer cone "
+ "the volume will be :attr:`cone_volume_outer` and in the area "
+ "between the volume will be interpolated linearly.");
+
+static PyObject *
+SequenceEntry_get_cone_angle_inner(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getConeAngleInner());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_cone_angle_inner(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float angle;
+
+ if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setConeAngleInner(angle);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_cone_angle_outer_doc,
+ "The opening angle of the outer cone of the source.\n\n"
+ ".. seealso:: :attr:`cone_angle_inner`");
+
+static PyObject *
+SequenceEntry_get_cone_angle_outer(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getConeAngleOuter());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_cone_angle_outer(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float angle;
+
+ if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setConeAngleOuter(angle);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_cone_volume_outer_doc,
+ "The volume outside the outer cone of the source.\n\n"
+ ".. seealso:: :attr:`cone_angle_inner`");
+
+static PyObject *
+SequenceEntry_get_cone_volume_outer(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getConeVolumeOuter());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_cone_volume_outer(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setConeVolumeOuter(volume);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_distance_maximum_doc,
+ "The maximum distance of the source.\n"
+ "If the listener is further away the source volume will be 0.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_distance_maximum(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getDistanceMaximum());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_distance_maximum(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance_maximum", &distance))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setDistanceMaximum(distance);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_distance_reference_doc,
+ "The reference distance of the source.\n"
+ "At this distance the volume will be exactly :attr:`volume`.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_distance_reference(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getDistanceReference());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_distance_reference(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance_reference", &distance))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setDistanceReference(distance);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_muted_doc,
+ "Whether the entry is muted.\n");
+
+static PyObject *
+SequenceEntry_get_muted(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return PyBool_FromLong((long)(*entry)->isMuted());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_muted(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "muted is not a boolean!");
+ return -1;
+ }
+
+ bool muted = args == Py_True;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->mute(muted);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_relative_doc,
+ "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
+
+static PyObject *
+SequenceEntry_get_relative(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return PyBool_FromLong((long)(*entry)->isRelative());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+SequenceEntry_set_relative(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ if(!PyBool_Check(args))
+ {
+ PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
+ return -1;
+ }
+
+ bool relative = (args == Py_True);
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setRelative(relative);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_sound_doc,
+ "The sound the entry is representing and will be played in the sequence.");
+
+static PyObject *
+SequenceEntry_get_sound(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ Sound* object = (Sound*) Sound_empty();
+ if(object)
+ {
+ object->sound = new std::shared_ptr<ISound>((*entry)->getSound());
+ return (PyObject *) object;
+ }
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return nullptr;
+}
+
+static int
+SequenceEntry_set_sound(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ Sound* sound = checkSound(args);
+
+ if(!sound)
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setSound(*reinterpret_cast<std::shared_ptr<ISound>*>(sound->sound));
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_volume_maximum_doc,
+ "The maximum volume of the source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_volume_maximum(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getVolumeMaximum());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_volume_maximum(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume_maximum", &volume))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setVolumeMaximum(volume);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+PyDoc_STRVAR(M_aud_SequenceEntry_volume_minimum_doc,
+ "The minimum volume of the source.\n\n"
+ ".. seealso:: :attr:`Device.distance_model`");
+
+static PyObject *
+SequenceEntry_get_volume_minimum(SequenceEntry* self, void* nothing)
+{
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ return Py_BuildValue("f", (*entry)->getVolumeMinimum());
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static int
+SequenceEntry_set_volume_minimum(SequenceEntry* self, PyObject* args, void* nothing)
+{
+ float volume;
+
+ if(!PyArg_Parse(args, "f:volume_minimum", &volume))
+ return -1;
+
+ try
+ {
+ std::shared_ptr<aud::SequenceEntry>* entry = reinterpret_cast<std::shared_ptr<aud::SequenceEntry>*>(self->entry);
+ (*entry)->setVolumeMinimum(volume);
+ return 0;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyGetSetDef SequenceEntry_properties[] = {
+ {(char*)"attenuation", (getter)SequenceEntry_get_attenuation, (setter)SequenceEntry_set_attenuation,
+ M_aud_SequenceEntry_attenuation_doc, nullptr },
+ {(char*)"cone_angle_inner", (getter)SequenceEntry_get_cone_angle_inner, (setter)SequenceEntry_set_cone_angle_inner,
+ M_aud_SequenceEntry_cone_angle_inner_doc, nullptr },
+ {(char*)"cone_angle_outer", (getter)SequenceEntry_get_cone_angle_outer, (setter)SequenceEntry_set_cone_angle_outer,
+ M_aud_SequenceEntry_cone_angle_outer_doc, nullptr },
+ {(char*)"cone_volume_outer", (getter)SequenceEntry_get_cone_volume_outer, (setter)SequenceEntry_set_cone_volume_outer,
+ M_aud_SequenceEntry_cone_volume_outer_doc, nullptr },
+ {(char*)"distance_maximum", (getter)SequenceEntry_get_distance_maximum, (setter)SequenceEntry_set_distance_maximum,
+ M_aud_SequenceEntry_distance_maximum_doc, nullptr },
+ {(char*)"distance_reference", (getter)SequenceEntry_get_distance_reference, (setter)SequenceEntry_set_distance_reference,
+ M_aud_SequenceEntry_distance_reference_doc, nullptr },
+ {(char*)"muted", (getter)SequenceEntry_get_muted, (setter)SequenceEntry_set_muted,
+ M_aud_SequenceEntry_muted_doc, nullptr },
+ {(char*)"relative", (getter)SequenceEntry_get_relative, (setter)SequenceEntry_set_relative,
+ M_aud_SequenceEntry_relative_doc, nullptr },
+ {(char*)"sound", (getter)SequenceEntry_get_sound, (setter)SequenceEntry_set_sound,
+ M_aud_SequenceEntry_sound_doc, nullptr },
+ {(char*)"volume_maximum", (getter)SequenceEntry_get_volume_maximum, (setter)SequenceEntry_set_volume_maximum,
+ M_aud_SequenceEntry_volume_maximum_doc, nullptr },
+ {(char*)"volume_minimum", (getter)SequenceEntry_get_volume_minimum, (setter)SequenceEntry_set_volume_minimum,
+ M_aud_SequenceEntry_volume_minimum_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_SequenceEntry_doc,
+ "SequenceEntry objects represent an entry of a sequenced sound.");
+
+static PyTypeObject SequenceEntryType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.SequenceEntry", /* tp_name */
+ sizeof(SequenceEntry), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)SequenceEntry_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_SequenceEntry_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ SequenceEntry_methods, /* tp_methods */
+ 0, /* tp_members */
+ SequenceEntry_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ 0, /* tp_new */
+};
+
+AUD_API PyObject* SequenceEntry_empty()
+{
+ return SequenceEntryType.tp_alloc(&SequenceEntryType, 0);
+}
+
+
+AUD_API SequenceEntry* checkSequenceEntry(PyObject* entry)
+{
+ if(!PyObject_TypeCheck(entry, &SequenceEntryType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type SequenceEntry!");
+ return nullptr;
+ }
+
+ return (SequenceEntry*)entry;
+}
+
+
+bool initializeSequenceEntry()
+{
+ return PyType_Ready(&SequenceEntryType) >= 0;
+}
+
+
+void addSequenceEntryToModule(PyObject* module)
+{
+ Py_INCREF(&SequenceEntryType);
+ PyModule_AddObject(module, "SequenceEntry", (PyObject *)&SequenceEntryType);
+}
diff --git a/extern/audaspace/bindings/python/PySequenceEntry.h b/extern/audaspace/bindings/python/PySequenceEntry.h
new file mode 100644
index 00000000000..7bb4ae4a281
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySequenceEntry.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_SequenceEntry;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_SequenceEntry* entry;
+} SequenceEntry;
+
+extern AUD_API PyObject* SequenceEntry_empty();
+extern AUD_API SequenceEntry* checkSequenceEntry(PyObject* entry);
+
+bool initializeSequenceEntry();
+void addSequenceEntryToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PySound.cpp b/extern/audaspace/bindings/python/PySound.cpp
new file mode 100644
index 00000000000..2ab1974be49
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySound.cpp
@@ -0,0 +1,1966 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "PySound.h"
+#include "PySource.h"
+#include "PyThreadPool.h"
+
+#ifdef WITH_CONVOLUTION
+#include "PyHRTF.h"
+#include "PyImpulseResponse.h"
+#endif
+
+#include "Exception.h"
+#include "file/File.h"
+#include "file/FileWriter.h"
+#include "util/StreamBuffer.h"
+#include "generator/Sawtooth.h"
+#include "generator/Silence.h"
+#include "generator/Sine.h"
+#include "generator/Square.h"
+#include "generator/Triangle.h"
+#include "fx/Accumulator.h"
+#include "fx/ADSR.h"
+#include "fx/Delay.h"
+#include "fx/Envelope.h"
+#include "fx/Fader.h"
+#include "fx/Highpass.h"
+#include "fx/IIRFilter.h"
+#include "fx/Limiter.h"
+#include "fx/Loop.h"
+#include "fx/Lowpass.h"
+#include "fx/MutableSound.h"
+#include "fx/Pitch.h"
+#include "fx/Reverse.h"
+#include "fx/SoundList.h"
+#include "fx/Sum.h"
+#include "fx/Threshold.h"
+#include "fx/Volume.h"
+#include "respec/ChannelMapper.h"
+#include "respec/ChannelMapperReader.h"
+#include "respec/LinearResample.h"
+#include "respec/JOSResample.h"
+#include "respec/JOSResampleReader.h"
+#include "sequence/Double.h"
+#include "sequence/PingPong.h"
+#include "sequence/Superpose.h"
+
+#ifdef WITH_CONVOLUTION
+#include "fx/BinauralSound.h"
+#include "fx/ConvolverSound.h"
+#endif
+
+#include <cstring>
+#include <structmember.h>
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+#include <numpy/ndarrayobject.h>
+
+using namespace aud;
+
+extern PyObject* AUDError;
+
+static void
+Sound_dealloc(Sound* self)
+{
+ if(self->sound)
+ delete reinterpret_cast<std::shared_ptr<ISound>*>(self->sound);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyObject *
+Sound_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ static const char* kwlist[] = {"filename", nullptr};
+ const char* filename = nullptr;
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "s:Sound", const_cast<char**>(kwlist), &filename))
+ {
+ Py_DECREF(self);
+ return nullptr;
+ }
+
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new File(filename));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_data_doc,
+ "data()\n\n"
+ "Retrieves the data of the sound as numpy array.\n\n"
+ ":return: A two dimensional numpy float array.\n"
+ ":rtype: :class:`numpy.ndarray`\n\n"
+ ".. note:: Best efficiency with cached sounds.");
+
+static PyObject *
+Sound_data(Sound* self)
+{
+ std::shared_ptr<ISound> sound = *reinterpret_cast<std::shared_ptr<ISound>*>(self->sound);
+
+ auto stream_buffer = std::dynamic_pointer_cast<StreamBuffer>(sound);
+ if(!stream_buffer)
+ stream_buffer = std::make_shared<StreamBuffer>(sound);
+ Specs specs = stream_buffer->getSpecs();
+ auto buffer = stream_buffer->getBuffer();
+
+ npy_intp dimensions[2];
+ dimensions[0] = buffer->getSize() / AUD_SAMPLE_SIZE(specs);
+ dimensions[1] = specs.channels;
+
+ PyArrayObject* array = reinterpret_cast<PyArrayObject*>(PyArray_SimpleNew(2, dimensions, NPY_FLOAT));
+
+ sample_t* data = reinterpret_cast<sample_t*>(PyArray_DATA(array));
+
+ std::memcpy(data, buffer->getBuffer(), buffer->getSize());
+
+ Py_INCREF(array);
+
+ return reinterpret_cast<PyObject*>(array);
+}
+
+PyDoc_STRVAR(M_aud_Sound_write_doc,
+ "write(filename, rate, channels, format, container, codec, bitrate, buffersize)\n\n"
+ "Writes the sound to a file.\n\n"
+ ":arg filename: The path to write to.\n"
+ ":type filename: string\n"
+ ":arg rate: The sample rate to write with.\n"
+ ":type rate: int\n"
+ ":arg channels: The number of channels to write with.\n"
+ ":type channels: int\n"
+ ":arg format: The sample format to write with.\n"
+ ":type format: int\n"
+ ":arg container: The container format for the file.\n"
+ ":type container: int\n"
+ ":arg codec: The codec to use in the file.\n"
+ ":type codec: int\n"
+ ":arg bitrate: The bitrate to write with.\n"
+ ":type bitrate: int\n"
+ ":arg buffersize: The size of the writing buffer.\n"
+ ":type buffersize: int\n");
+
+static PyObject *
+Sound_write(Sound* self, PyObject* args, PyObject* kwds)
+{
+ const char* filename = nullptr;
+ int rate = RATE_INVALID;
+ Channels channels = CHANNELS_INVALID;
+ SampleFormat format = FORMAT_INVALID;
+ Container container = CONTAINER_INVALID;
+ Codec codec = CODEC_INVALID;
+ int bitrate = 0;
+ int buffersize = 0;
+
+ static const char* kwlist[] = {"filename", "rate", "channels", "format", "container", "codec", "bitrate", "buffersize", nullptr};
+
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "s|iiiiiii:write", const_cast<char**>(kwlist), &filename, &rate, &channels, &format, &container, &codec, &bitrate, &buffersize))
+ return nullptr;
+
+ try
+ {
+ std::shared_ptr<IReader> reader = (*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound))->createReader();
+
+ DeviceSpecs specs;
+ specs.specs = reader->getSpecs();
+
+ if((rate != RATE_INVALID) && (specs.rate != rate))
+ {
+ specs.rate = rate;
+ reader = std::make_shared<JOSResampleReader>(reader, rate);
+ }
+
+ if((channels != CHANNELS_INVALID) && (specs.channels != channels))
+ {
+ specs.channels = channels;
+ reader = std::make_shared<ChannelMapperReader>(reader, channels);
+ }
+
+ if(format == FORMAT_INVALID)
+ format = FORMAT_S16;
+ specs.format = format;
+
+ const char* invalid_container_error = "Container could not be determined from filename.";
+
+ if(container == CONTAINER_INVALID)
+ {
+ std::string path = filename;
+
+ if(path.length() < 4)
+ {
+ PyErr_SetString(AUDError, invalid_container_error);
+ return nullptr;
+ }
+
+ std::string extension = path.substr(path.length() - 4);
+
+ if(extension == ".ac3")
+ container = CONTAINER_AC3;
+ else if(extension == "flac")
+ container = CONTAINER_FLAC;
+ else if(extension == ".mkv")
+ container = CONTAINER_MATROSKA;
+ else if(extension == ".mp2")
+ container = CONTAINER_MP2;
+ else if(extension == ".mp3")
+ container = CONTAINER_MP3;
+ else if(extension == ".ogg")
+ container = CONTAINER_OGG;
+ else if(extension == ".wav")
+ container = CONTAINER_WAV;
+ else
+ {
+ PyErr_SetString(AUDError, invalid_container_error);
+ return nullptr;
+ }
+ }
+
+ if(codec == CODEC_INVALID)
+ {
+ switch(container)
+ {
+ case CONTAINER_AC3:
+ codec = CODEC_AC3;
+ break;
+ case CONTAINER_FLAC:
+ codec = CODEC_FLAC;
+ break;
+ case CONTAINER_MATROSKA:
+ codec = CODEC_OPUS;
+ break;
+ case CONTAINER_MP2:
+ codec = CODEC_MP2;
+ break;
+ case CONTAINER_MP3:
+ codec = CODEC_MP3;
+ break;
+ case CONTAINER_OGG:
+ codec = CODEC_VORBIS;
+ break;
+ case CONTAINER_WAV:
+ codec = CODEC_PCM;
+ break;
+ default:
+ PyErr_SetString(AUDError, "Unknown container, cannot select default codec.");
+ return nullptr;
+ }
+ }
+
+ if(buffersize <= 0)
+ buffersize = AUD_DEFAULT_BUFFER_SIZE;
+
+ std::shared_ptr<IWriter> writer = FileWriter::createWriter(filename, specs, container, codec, bitrate);
+ FileWriter::writeReader(reader, writer, 0, buffersize);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(M_aud_Sound_buffer_doc,
+ "buffer(data, rate)\n\n"
+ "Creates a sound from a data buffer.\n\n"
+ ":arg data: The data as two dimensional numpy array.\n"
+ ":type data: numpy.ndarray\n"
+ ":arg rate: The sample rate.\n"
+ ":type rate: double\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_buffer(PyTypeObject* type, PyObject* args)
+{
+ PyArrayObject* array = nullptr;
+ double rate = RATE_INVALID;
+
+ if(!PyArg_ParseTuple(args, "Od:buffer", &array, &rate))
+ return nullptr;
+
+ if((!PyObject_TypeCheck(reinterpret_cast<PyObject*>(array), &PyArray_Type)) || (PyArray_TYPE(array) != NPY_FLOAT))
+ {
+ PyErr_SetString(PyExc_TypeError, "The data needs to be supplied as float32 numpy array!");
+ return nullptr;
+ }
+
+ if(PyArray_NDIM(array) > 2)
+ {
+ PyErr_SetString(PyExc_TypeError, "The array needs to have one or two dimensions!");
+ return nullptr;
+ }
+
+ if(rate <= 0)
+ {
+ PyErr_SetString(PyExc_TypeError, "The sample rate has to be positive!");
+ return nullptr;
+ }
+
+ Specs specs;
+ specs.rate = rate;
+ specs.channels = CHANNELS_MONO;
+
+ if(PyArray_NDIM(array) == 2)
+ specs.channels = static_cast<Channels>(PyArray_DIM(array, 1));
+
+ int size = PyArray_DIM(array, 0) * AUD_SAMPLE_SIZE(specs);
+
+ std::shared_ptr<Buffer> buffer = std::make_shared<Buffer>(size);
+
+ std::memcpy(buffer->getBuffer(), PyArray_DATA(array), size);
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<StreamBuffer>(new StreamBuffer(buffer, specs));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_cache_doc,
+ "cache()\n\n"
+ "Caches a sound into RAM.\n"
+ "This saves CPU usage needed for decoding and file access if the "
+ "underlying sound reads from a file on the harddisk, but it "
+ "consumes a lot of memory.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: Only known-length factories can be buffered.\n\n"
+ ".. warning:: Raw PCM data needs a lot of space, only buffer "
+ "short factories.");
+
+static PyObject *
+Sound_cache(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new StreamBuffer(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_file_doc,
+ "file(filename)\n\n"
+ "Creates a sound object of a sound file.\n\n"
+ ":arg filename: Path of the file.\n"
+ ":type filename: string\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. warning:: If the file doesn't exist or can't be read you will "
+ "not get an exception immediately, but when you try to start "
+ "playback of that sound.");
+
+static PyObject *
+Sound_file(PyTypeObject* type, PyObject* args)
+{
+ const char* filename = nullptr;
+
+ if(!PyArg_ParseTuple(args, "s:file", &filename))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new File(filename));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_sawtooth_doc,
+ "sawtooth(frequency, rate=48000)\n\n"
+ "Creates a sawtooth sound which plays a sawtooth wave.\n\n"
+ ":arg frequency: The frequency of the sawtooth wave in Hz.\n"
+ ":type frequency: float\n"
+ ":arg rate: The sampling rate in Hz. It's recommended to set this "
+ "value to the playback device's samling rate to avoid resamping.\n"
+ ":type rate: int\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_sawtooth(PyTypeObject* type, PyObject* args)
+{
+ float frequency;
+ double rate = 48000;
+
+ if(!PyArg_ParseTuple(args, "f|d:sawtooth", &frequency, &rate))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Sawtooth(frequency, (SampleRate)rate));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_silence_doc,
+ "silence()\n\n"
+ "Creates a silence sound which plays simple silence.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_silence(PyTypeObject* type)
+{
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Silence());
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_sine_doc,
+ "sine(frequency, rate=48000)\n\n"
+ "Creates a sine sound which plays a sine wave.\n\n"
+ ":arg frequency: The frequency of the sine wave in Hz.\n"
+ ":type frequency: float\n"
+ ":arg rate: The sampling rate in Hz. It's recommended to set this "
+ "value to the playback device's samling rate to avoid resamping.\n"
+ ":type rate: int\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_sine(PyTypeObject* type, PyObject* args)
+{
+ float frequency;
+ double rate = 48000;
+
+ if(!PyArg_ParseTuple(args, "f|d:sine", &frequency, &rate))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Sine(frequency, (SampleRate)rate));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_square_doc,
+ "square(frequency, rate=48000)\n\n"
+ "Creates a square sound which plays a square wave.\n\n"
+ ":arg frequency: The frequency of the square wave in Hz.\n"
+ ":type frequency: float\n"
+ ":arg rate: The sampling rate in Hz. It's recommended to set this "
+ "value to the playback device's samling rate to avoid resamping.\n"
+ ":type rate: int\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_square(PyTypeObject* type, PyObject* args)
+{
+ float frequency;
+ double rate = 48000;
+
+ if(!PyArg_ParseTuple(args, "f|d:square", &frequency, &rate))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Square(frequency, (SampleRate)rate));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_triangle_doc,
+ "triangle(frequency, rate=48000)\n\n"
+ "Creates a triangle sound which plays a triangle wave.\n\n"
+ ":arg frequency: The frequency of the triangle wave in Hz.\n"
+ ":type frequency: float\n"
+ ":arg rate: The sampling rate in Hz. It's recommended to set this "
+ "value to the playback device's samling rate to avoid resamping.\n"
+ ":type rate: int\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_triangle(PyTypeObject* type, PyObject* args)
+{
+ float frequency;
+ double rate = 48000;
+
+ if(!PyArg_ParseTuple(args, "f|d:triangle", &frequency, &rate))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new Triangle(frequency, (SampleRate)rate));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_accumulate_doc,
+ "accumulate(additive=False)\n\n"
+ "Accumulates a sound by summing over positive input differences thus generating a monotonic sigal. "
+ "If additivity is set to true negative input differences get added too, but positive ones with a factor of two. "
+ "Note that with additivity the signal is not monotonic anymore.\n\n"
+ ":arg additive: Whether the accumulation should be additive or not.\n"
+ ":type time: bool\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_accumulate(Sound* self, PyObject* args)
+{
+ bool additive = false;
+ PyObject* additiveo;
+
+ if(!PyArg_ParseTuple(args, "|O:accumulate", &additiveo))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ if(additiveo != nullptr)
+ {
+ if(!PyBool_Check(additiveo))
+ {
+ PyErr_SetString(PyExc_TypeError, "additive is not a boolean!");
+ return nullptr;
+ }
+
+ additive = additiveo == Py_True;
+ }
+
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Accumulator(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), additive));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_ADSR_doc,
+ "ADSR(attack,decay,sustain,release)\n\n"
+ "Attack-Decay-Sustain-Release envelopes the volume of a sound. "
+ "Note: there is currently no way to trigger the release with this API.\n\n"
+ ":arg attack: The attack time in seconds.\n"
+ ":type attack: float\n"
+ ":arg decay: The decay time in seconds.\n"
+ ":type decay: float\n"
+ ":arg sustain: The sustain level.\n"
+ ":type sustain: float\n"
+ ":arg release: The release level.\n"
+ ":type release: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_ADSR(Sound* self, PyObject* args)
+{
+ float attack, decay, sustain, release;
+
+ if(!PyArg_ParseTuple(args, "ffff:ADSR", &attack, &decay, &sustain, &release))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new ADSR(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), attack, decay, sustain, release));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_delay_doc,
+ "delay(time)\n\n"
+ "Delays by playing adding silence in front of the other sound's "
+ "data.\n\n"
+ ":arg time: How many seconds of silence should be added before "
+ "the sound.\n"
+ ":type time: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_delay(Sound* self, PyObject* args)
+{
+ float delay;
+
+ if(!PyArg_ParseTuple(args, "f:delay", &delay))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Delay(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), delay));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_envelope_doc,
+ "envelope(attack, release, threshold, arthreshold)\n\n"
+ "Delays by playing adding silence in front of the other sound's "
+ "data.\n\n"
+ ":arg attack: The attack factor.\n"
+ ":type attack: float\n"
+ ":arg release: The release factor.\n"
+ ":type release: float\n"
+ ":arg threshold: The general threshold value.\n"
+ ":type threshold: float\n"
+ ":arg arthreshold: The attack/release threshold value.\n"
+ ":type arthreshold: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_envelope(Sound* self, PyObject* args)
+{
+ float attack, release, threshold, arthreshold;
+
+ if(!PyArg_ParseTuple(args, "ffff:envelope", &attack, &release, &threshold, &arthreshold))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Envelope(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), attack, release, threshold, arthreshold));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_fadein_doc,
+ "fadein(start, length)\n\n"
+ "Fades a sound in by raising the volume linearly in the given "
+ "time interval.\n\n"
+ ":arg start: Time in seconds when the fading should start.\n"
+ ":type start: float\n"
+ ":arg length: Time in seconds how long the fading should last.\n"
+ ":type length: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: Before the fade starts it plays silence.");
+
+static PyObject *
+Sound_fadein(Sound* self, PyObject* args)
+{
+ float start, length;
+
+ if(!PyArg_ParseTuple(args, "ff:fadein", &start, &length))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Fader(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), FADE_IN, start, length));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_fadeout_doc,
+ "fadeout(start, length)\n\n"
+ "Fades a sound in by lowering the volume linearly in the given "
+ "time interval.\n\n"
+ ":arg start: Time in seconds when the fading should start.\n"
+ ":type start: float\n"
+ ":arg length: Time in seconds how long the fading should last.\n"
+ ":type length: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: After the fade this sound plays silence, so that "
+ "the length of the sound is not altered.");
+
+static PyObject *
+Sound_fadeout(Sound* self, PyObject* args)
+{
+ float start, length;
+
+ if(!PyArg_ParseTuple(args, "ff:fadeout", &start, &length))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Fader(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), FADE_OUT, start, length));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_filter_doc,
+ "filter(b, a = (1))\n\n"
+ "Filters a sound with the supplied IIR filter coefficients.\n"
+ "Without the second parameter you'll get a FIR filter.\n"
+ "If the first value of the a sequence is 0 it will be set to 1 "
+ "automatically.\n"
+ "If the first value of the a sequence is neither 0 nor 1, all "
+ "filter coefficients will be scaled by this value so that it is 1 "
+ "in the end, you don't have to scale yourself.\n\n"
+ ":arg b: The nominator filter coefficients.\n"
+ ":type b: sequence of float\n"
+ ":arg a: The denominator filter coefficients.\n"
+ ":type a: sequence of float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_filter(Sound* self, PyObject* args)
+{
+ PyObject* py_b;
+ PyObject* py_a = nullptr;
+ Py_ssize_t py_a_len;
+ Py_ssize_t py_b_len;
+
+ if(!PyArg_ParseTuple(args, "O|O:filter", &py_b, &py_a))
+ return nullptr;
+
+ if(!PySequence_Check(py_b) || (py_a != nullptr && !PySequence_Check(py_a)))
+ {
+ PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
+ return nullptr;
+ }
+
+ py_a_len= py_a ? PySequence_Size(py_a) : 0;
+ py_b_len= PySequence_Size(py_b);
+
+ if(!py_b_len || ((py_a != nullptr) && !py_a_len))
+ {
+ PyErr_SetString(PyExc_ValueError, "The sequence has to contain at least one value!");
+ return nullptr;
+ }
+
+ std::vector<float> a, b;
+ PyObject* py_value;
+ float value;
+
+ for(Py_ssize_t i = 0; i < py_b_len; i++)
+ {
+ py_value = PySequence_GetItem(py_b, i);
+ value= (float)PyFloat_AsDouble(py_value);
+ Py_DECREF(py_value);
+
+ if(value == -1.0f && PyErr_Occurred()) {
+ return nullptr;
+ }
+
+ b.push_back(value);
+ }
+
+ if(py_a)
+ {
+ for(Py_ssize_t i = 0; i < py_a_len; i++)
+ {
+ py_value = PySequence_GetItem(py_a, i);
+ value= (float)PyFloat_AsDouble(py_value);
+ Py_DECREF(py_value);
+
+ if(value == -1.0f && PyErr_Occurred()) {
+ return nullptr;
+ }
+
+ a.push_back(value);
+ }
+
+ if(a[0] == 0)
+ a[0] = 1;
+ }
+ else
+ a.push_back(1);
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new IIRFilter(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), b, a));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_highpass_doc,
+ "highpass(frequency, Q=0.5)\n\n"
+ "Creates a second order highpass filter based on the transfer "
+ "function H(s) = s^2 / (s^2 + s/Q + 1)\n\n"
+ ":arg frequency: The cut off trequency of the highpass.\n"
+ ":type frequency: float\n"
+ ":arg Q: Q factor of the lowpass.\n"
+ ":type Q: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_highpass(Sound* self, PyObject* args)
+{
+ float frequency;
+ float Q = 0.5;
+
+ if(!PyArg_ParseTuple(args, "f|f:highpass", &frequency, &Q))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Highpass(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), frequency, Q));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_limit_doc,
+ "limit(start, end)\n\n"
+ "Limits a sound within a specific start and end time.\n\n"
+ ":arg start: Start time in seconds.\n"
+ ":type start: float\n"
+ ":arg end: End time in seconds.\n"
+ ":type end: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_limit(Sound* self, PyObject* args)
+{
+ float start, end;
+
+ if(!PyArg_ParseTuple(args, "ff:limit", &start, &end))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Limiter(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), start, end));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_loop_doc,
+ "loop(count)\n\n"
+ "Loops a sound.\n\n"
+ ":arg count: How often the sound should be looped. "
+ "Negative values mean endlessly.\n"
+ ":type count: integer\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: This is a filter function, you might consider using "
+ ":attr:`Handle.loop_count` instead.");
+
+static PyObject *
+Sound_loop(Sound* self, PyObject* args)
+{
+ int loop;
+
+ if(!PyArg_ParseTuple(args, "i:loop", &loop))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Loop(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), loop));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_lowpass_doc,
+ "lowpass(frequency, Q=0.5)\n\n"
+ "Creates a second order lowpass filter based on the transfer "
+ "function H(s) = 1 / (s^2 + s/Q + 1)\n\n"
+ ":arg frequency: The cut off trequency of the lowpass.\n"
+ ":type frequency: float\n"
+ ":arg Q: Q factor of the lowpass.\n"
+ ":type Q: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_lowpass(Sound* self, PyObject* args)
+{
+ float frequency;
+ float Q = 0.5;
+
+ if(!PyArg_ParseTuple(args, "f|f:lowpass", &frequency, &Q))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Lowpass(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), frequency, Q));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_pitch_doc,
+ "pitch(factor)\n\n"
+ "Changes the pitch of a sound with a specific factor.\n\n"
+ ":arg factor: The factor to change the pitch with.\n"
+ ":type factor: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: This is done by changing the sample rate of the "
+ "underlying sound, which has to be an integer, so the factor "
+ "value rounded and the factor may not be 100 % accurate.\n\n"
+ ".. note:: This is a filter function, you might consider using "
+ ":attr:`Handle.pitch` instead.");
+
+static PyObject *
+Sound_pitch(Sound* self, PyObject* args)
+{
+ float factor;
+
+ if(!PyArg_ParseTuple(args, "f:pitch", &factor))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Pitch(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), factor));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_rechannel_doc,
+ "rechannel(channels)\n\n"
+ "Rechannels the sound.\n\n"
+ ":arg channels: The new channel configuration.\n"
+ ":type channels: int\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_rechannel(Sound* self, PyObject* args)
+{
+ int channels;
+
+ if(!PyArg_ParseTuple(args, "i:rechannel", &channels))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ DeviceSpecs specs;
+ specs.channels = static_cast<Channels>(channels);
+ specs.rate = RATE_INVALID;
+ specs.format = FORMAT_INVALID;
+ parent->sound = new std::shared_ptr<ISound>(new ChannelMapper(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), specs));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_resample_doc,
+ "resample(rate, high_quality)\n\n"
+ "Resamples the sound.\n\n"
+ ":arg rate: The new sample rate.\n"
+ ":type rate: double\n"
+ ":arg high_quality: When true use a higher quality but slower resampler.\n"
+ ":type high_quality: bool\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_resample(Sound* self, PyObject* args)
+{
+ double rate;
+ PyObject* high_qualityo;
+ bool high_quality = false;
+
+ if(!PyArg_ParseTuple(args, "d|O:resample", &rate, &high_qualityo))
+ return nullptr;
+
+ if(!PyBool_Check(high_qualityo))
+ {
+ PyErr_SetString(PyExc_TypeError, "high_quality is not a boolean!");
+ return nullptr;
+ }
+
+ high_quality = high_qualityo == Py_True;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ DeviceSpecs specs;
+ specs.channels = CHANNELS_INVALID;
+ specs.rate = rate;
+ specs.format = FORMAT_INVALID;
+ if(high_quality)
+ parent->sound = new std::shared_ptr<ISound>(new JOSResample(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), specs));
+ else
+ parent->sound = new std::shared_ptr<ISound>(new LinearResample(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), specs));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_reverse_doc,
+ "reverse()\n\n"
+ "Plays a sound reversed.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: The sound has to have a finite length and has to be "
+ "seekable. It's recommended to use this only with factories with "
+ "fast and accurate seeking, which is not true for encoded audio "
+ "files, such ones should be buffered using :meth:`cache` before "
+ "being played reversed.\n\n"
+ ".. warning:: If seeking is not accurate in the underlying sound "
+ "you'll likely hear skips/jumps/cracks.");
+
+static PyObject *
+Sound_reverse(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Reverse(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_sum_doc,
+ "sum()\n\n"
+ "Sums the samples of a sound.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_sum(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Sum(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_threshold_doc,
+ "threshold(threshold = 0)\n\n"
+ "Makes a threshold wave out of an audio wave by setting all samples "
+ "with a amplitude >= threshold to 1, all <= -threshold to -1 and "
+ "all between to 0.\n\n"
+ ":arg threshold: Threshold value over which an amplitude counts "
+ "non-zero.\n"
+ ":type threshold: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_threshold(Sound* self, PyObject* args)
+{
+ float threshold = 0;
+
+ if(!PyArg_ParseTuple(args, "|f:threshold", &threshold))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Threshold(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), threshold));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_volume_doc,
+ "volume(volume)\n\n"
+ "Changes the volume of a sound.\n\n"
+ ":arg volume: The new volume..\n"
+ ":type volume: float\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: Should be in the range [0, 1] to avoid clipping.\n\n"
+ ".. note:: This is a filter function, you might consider using "
+ ":attr:`Handle.volume` instead.");
+
+static PyObject *
+Sound_volume(Sound* self, PyObject* args)
+{
+ float volume;
+
+ if(!PyArg_ParseTuple(args, "f:volume", &volume))
+ return nullptr;
+
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Volume(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), volume));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_join_doc,
+ "join(sound)\n\n"
+ "Plays two factories in sequence.\n\n"
+ ":arg sound: The sound to play second.\n"
+ ":type sound: :class:`Sound`\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: The two factories have to have the same specifications "
+ "(channels and samplerate).");
+
+static PyObject *
+Sound_join(Sound* self, PyObject* object)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ if(!PyObject_TypeCheck(object, type))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object has to be of type Sound!");
+ return nullptr;
+ }
+
+ Sound* parent;
+ Sound* child = (Sound*)object;
+
+ parent = (Sound*)type->tp_alloc(type, 0);
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Double(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), *reinterpret_cast<std::shared_ptr<ISound>*>(child->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_mix_doc,
+ "mix(sound)\n\n"
+ "Mixes two factories.\n\n"
+ ":arg sound: The sound to mix over the other.\n"
+ ":type sound: :class:`Sound`\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`\n\n"
+ ".. note:: The two factories have to have the same specifications "
+ "(channels and samplerate).");
+
+static PyObject *
+Sound_mix(Sound* self, PyObject* object)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ if(!PyObject_TypeCheck(object, type))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Sound!");
+ return nullptr;
+ }
+
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+ Sound* child = (Sound*)object;
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new Superpose(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), *reinterpret_cast<std::shared_ptr<ISound>*>(child->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_pingpong_doc,
+ "pingpong()\n\n"
+ "Plays a sound forward and then backward.\n"
+ "This is like joining a sound with its reverse.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_pingpong(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new PingPong(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_list_doc,
+ "list()\n\n"
+ "Creates an empty sound list that can contain several sounds.\n\n"
+ ":arg random: wether the playback will be random or not.\n"
+ ":type random: int\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_list(PyTypeObject* type, PyObject* args)
+{
+ int random;
+
+ if(!PyArg_ParseTuple(args, "i:random", &random))
+ return nullptr;
+
+ Sound* self;
+
+ self = (Sound*)type->tp_alloc(type, 0);
+ if(self != nullptr)
+ {
+ try
+ {
+ self->sound = new std::shared_ptr<ISound>(new SoundList(random));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_mutable_doc,
+ "mutable()\n\n"
+ "Creates a sound that will be restarted when sought backwards.\n"
+ "If the original sound is a sound list, the playing sound can change.\n\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_mutable(Sound* self)
+{
+ PyTypeObject* type = Py_TYPE(self);
+ Sound* parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new MutableSound(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_list_addSound_doc,
+ "addSound(sound)\n\n"
+ "Adds a new sound to a sound list.\n\n"
+ ":arg sound: The sound that will be added to the list.\n"
+ ":type sound: :class:`Sound`\n\n"
+ ".. note:: You can only add a sound to a sound list.");
+
+static PyObject *
+Sound_list_addSound(Sound* self, PyObject* object)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ if(!PyObject_TypeCheck(object, type))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object has to be of type Sound!");
+ return nullptr;
+ }
+
+ Sound* child = (Sound*)object;
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<SoundList>*>(self->sound))->addSound(*reinterpret_cast<std::shared_ptr<ISound>*>(child->sound));
+ Py_RETURN_NONE;
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+#ifdef WITH_CONVOLUTION
+
+PyDoc_STRVAR(M_aud_Sound_convolver_doc,
+ "convolver()\n\n"
+ "Creates a sound that will apply convolution to another sound.\n\n"
+ ":arg impulseResponse: The filter with which convolve the sound.\n"
+ ":type impulseResponse: :class:`ImpulseResponse`\n"
+ ":arg threadPool: A thread pool used to parallelize convolution.\n"
+ ":type threadPool: :class:`ThreadPool`\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_convolver(Sound* self, PyObject* args)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ PyObject* object1;
+ PyObject* object2;
+
+ if(!PyArg_ParseTuple(args, "OO:convolver", &object1, &object2))
+ return nullptr;
+
+ ImpulseResponseP* filter = checkImpulseResponse(object1);
+ if(!filter)
+ return nullptr;
+
+ ThreadPoolP* threadPool = checkThreadPool(object2);
+ if(!threadPool)
+ return nullptr;
+
+ Sound* parent;
+ parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new ConvolverSound(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), *reinterpret_cast<std::shared_ptr<ImpulseResponse>*>(filter->impulseResponse), *reinterpret_cast<std::shared_ptr<ThreadPool>*>(threadPool->threadPool)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+PyDoc_STRVAR(M_aud_Sound_binaural_doc,
+ "convolver()\n\n"
+ "Creates a binaural sound using another sound as source. The original sound must be mono\n\n"
+ ":arg hrtfs: An HRTF set.\n"
+ ":type hrtf: :class:`HRTF`\n"
+ ":arg source: An object representing the source position of the sound.\n"
+ ":type source: :class:`Source`\n"
+ ":arg threadPool: A thread pool used to parallelize convolution.\n"
+ ":type threadPool: :class:`ThreadPool`\n"
+ ":return: The created :class:`Sound` object.\n"
+ ":rtype: :class:`Sound`");
+
+static PyObject *
+Sound_binaural(Sound* self, PyObject* args)
+{
+ PyTypeObject* type = Py_TYPE(self);
+
+ PyObject* object1;
+ PyObject* object2;
+ PyObject* object3;
+
+ if(!PyArg_ParseTuple(args, "OOO:binaural", &object1, &object2, &object3))
+ return nullptr;
+
+ HRTFP* hrtfs = checkHRTF(object1);
+ if(!hrtfs)
+ return nullptr;
+
+ SourceP* source = checkSource(object2);
+ if(!hrtfs)
+ return nullptr;
+
+ ThreadPoolP* threadPool = checkThreadPool(object3);
+ if(!threadPool)
+ return nullptr;
+
+ Sound* parent;
+ parent = (Sound*)type->tp_alloc(type, 0);
+
+ if(parent != nullptr)
+ {
+ try
+ {
+ parent->sound = new std::shared_ptr<ISound>(new BinauralSound(*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound), *reinterpret_cast<std::shared_ptr<HRTF>*>(hrtfs->hrtf), *reinterpret_cast<std::shared_ptr<Source>*>(source->source), *reinterpret_cast<std::shared_ptr<ThreadPool>*>(threadPool->threadPool)));
+ }
+ catch(Exception& e)
+ {
+ Py_DECREF(parent);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)parent;
+}
+
+#endif
+
+static PyMethodDef Sound_methods[] = {
+ {"data", (PyCFunction)Sound_data, METH_NOARGS,
+ M_aud_Sound_data_doc
+ },
+ {"write", (PyCFunction)Sound_write, METH_VARARGS | METH_KEYWORDS,
+ M_aud_Sound_write_doc
+ },
+ {"buffer", (PyCFunction)Sound_buffer, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_buffer_doc
+ },
+ {"cache", (PyCFunction)Sound_cache, METH_NOARGS,
+ M_aud_Sound_cache_doc
+ },
+ {"file", (PyCFunction)Sound_file, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_file_doc
+ },
+ {"sawtooth", (PyCFunction)Sound_sawtooth, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_sawtooth_doc
+ },
+ {"silence", (PyCFunction)Sound_silence, METH_NOARGS | METH_CLASS,
+ M_aud_Sound_silence_doc
+ },
+ {"sine", (PyCFunction)Sound_sine, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_sine_doc
+ },
+ {"square", (PyCFunction)Sound_square, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_square_doc
+ },
+ {"triangle", (PyCFunction)Sound_triangle, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_triangle_doc
+ },
+ {"accumulate", (PyCFunction)Sound_accumulate, METH_VARARGS,
+ M_aud_Sound_accumulate_doc
+ },
+ {"ADSR", (PyCFunction)Sound_ADSR, METH_VARARGS,
+ M_aud_Sound_ADSR_doc
+ },
+ {"delay", (PyCFunction)Sound_delay, METH_VARARGS,
+ M_aud_Sound_delay_doc
+ },
+ {"envelope", (PyCFunction)Sound_envelope, METH_VARARGS,
+ M_aud_Sound_envelope_doc
+ },
+ {"fadein", (PyCFunction)Sound_fadein, METH_VARARGS,
+ M_aud_Sound_fadein_doc
+ },
+ {"fadeout", (PyCFunction)Sound_fadeout, METH_VARARGS,
+ M_aud_Sound_fadeout_doc
+ },
+ {"filter", (PyCFunction)Sound_filter, METH_VARARGS,
+ M_aud_Sound_filter_doc
+ },
+ {"highpass", (PyCFunction)Sound_highpass, METH_VARARGS,
+ M_aud_Sound_highpass_doc
+ },
+ {"limit", (PyCFunction)Sound_limit, METH_VARARGS,
+ M_aud_Sound_limit_doc
+ },
+ {"loop", (PyCFunction)Sound_loop, METH_VARARGS,
+ M_aud_Sound_loop_doc
+ },
+ {"lowpass", (PyCFunction)Sound_lowpass, METH_VARARGS,
+ M_aud_Sound_lowpass_doc
+ },
+ {"pitch", (PyCFunction)Sound_pitch, METH_VARARGS,
+ M_aud_Sound_pitch_doc
+ },
+ {"rechannel", (PyCFunction)Sound_rechannel, METH_VARARGS,
+ M_aud_Sound_rechannel_doc
+ },
+ {"resample", (PyCFunction)Sound_resample, METH_VARARGS,
+ M_aud_Sound_resample_doc
+ },
+ {"reverse", (PyCFunction)Sound_reverse, METH_NOARGS,
+ M_aud_Sound_reverse_doc
+ },
+ {"sum", (PyCFunction)Sound_sum, METH_NOARGS,
+ M_aud_Sound_sum_doc
+ },
+ {"threshold", (PyCFunction)Sound_threshold, METH_VARARGS,
+ M_aud_Sound_threshold_doc
+ },
+ {"volume", (PyCFunction)Sound_volume, METH_VARARGS,
+ M_aud_Sound_volume_doc
+ },
+ {"join", (PyCFunction)Sound_join, METH_O,
+ M_aud_Sound_join_doc
+ },
+ {"mix", (PyCFunction)Sound_mix, METH_O,
+ M_aud_Sound_mix_doc
+ },
+ { "pingpong", (PyCFunction)Sound_pingpong, METH_NOARGS,
+ M_aud_Sound_pingpong_doc
+ },
+ { "list", (PyCFunction)Sound_list, METH_VARARGS | METH_CLASS,
+ M_aud_Sound_list_doc
+ },
+ { "mutable", (PyCFunction)Sound_mutable, METH_NOARGS,
+ M_aud_Sound_mutable_doc
+ },
+ { "addSound", (PyCFunction)Sound_list_addSound, METH_O,
+ M_aud_Sound_list_addSound_doc
+ },
+#ifdef WITH_CONVOLUTION
+ { "convolver", (PyCFunction)Sound_convolver, METH_VARARGS,
+ M_aud_Sound_convolver_doc
+ },
+ { "binaural", (PyCFunction)Sound_binaural, METH_VARARGS,
+ M_aud_Sound_binaural_doc
+ },
+#endif
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sound_specs_doc,
+ "The sample specification of the sound as a tuple with rate and channel count.");
+
+static PyObject *
+Sound_get_specs(Sound* self, void* nothing)
+{
+ try
+ {
+ Specs specs = (*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound))->createReader()->getSpecs();
+ return Py_BuildValue("(di)", specs.rate, specs.channels);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Sound_length_doc,
+ "The sample specification of the sound as a tuple with rate and channel count.");
+
+static PyObject *
+Sound_get_length(Sound* self, void* nothing)
+{
+ try
+ {
+ int length = (*reinterpret_cast<std::shared_ptr<ISound>*>(self->sound))->createReader()->getLength();
+ return Py_BuildValue("i", length);
+ }
+ catch(Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyGetSetDef Sound_properties[] = {
+ {(char*)"specs", (getter)Sound_get_specs, nullptr,
+ M_aud_Sound_specs_doc, nullptr },
+ {(char*)"length", (getter)Sound_get_length, nullptr,
+ M_aud_Sound_length_doc, nullptr },
+ {nullptr} /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sound_doc,
+ "Sound objects are immutable and represent a sound that can be "
+ "played simultaneously multiple times. They are called factories "
+ "because they create reader objects internally that are used for "
+ "playback.");
+
+PyTypeObject SoundType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Sound", /* tp_name */
+ sizeof(Sound), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Sound_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Sound_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Sound_methods, /* tp_methods */
+ 0, /* tp_members */
+ Sound_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ Sound_new, /* tp_new */
+};
+
+AUD_API PyObject* Sound_empty()
+{
+ return SoundType.tp_alloc(&SoundType, 0);
+}
+
+AUD_API Sound* checkSound(PyObject* sound)
+{
+ if(!PyObject_TypeCheck(sound, &SoundType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Sound!");
+ return nullptr;
+ }
+
+ return (Sound*)sound;
+}
+
+
+bool initializeSound()
+{
+ import_array();
+
+ return PyType_Ready(&SoundType) >= 0;
+}
+
+
+void addSoundToModule(PyObject* module)
+{
+ Py_INCREF(&SoundType);
+ PyModule_AddObject(module, "Sound", (PyObject *)&SoundType);
+}
diff --git a/extern/audaspace/bindings/python/PySound.h b/extern/audaspace/bindings/python/PySound.h
new file mode 100644
index 00000000000..657bb2131e6
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySound.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_ISound;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_ISound* sound;
+} Sound;
+
+extern AUD_API PyObject* Sound_empty();
+extern AUD_API Sound* checkSound(PyObject* sound);
+
+bool initializeSound();
+void addSoundToModule(PyObject* module);
diff --git a/extern/audaspace/bindings/python/PySource.cpp b/extern/audaspace/bindings/python/PySource.cpp
new file mode 100644
index 00000000000..a948cf46645
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySource.cpp
@@ -0,0 +1,260 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "PySource.h"
+
+#include "Exception.h"
+#include "fx/Source.h"
+
+#include <memory>
+
+extern PyObject* AUDError;
+
+static PyObject *
+Source_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ SourceP* self = (SourceP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ float azimuth, elevation, distance;
+ if(!PyArg_ParseTuple(args, "fff:angles", &azimuth, &elevation, &distance))
+ return nullptr;
+
+ try
+ {
+ self->source = new std::shared_ptr<aud::Source>(new aud::Source(azimuth, elevation, distance));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+Source_dealloc(SourceP* self)
+{
+ if(self->source)
+ delete reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyMethodDef Source_methods[] = {
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Source_azimuth_doc,
+ "The azimuth angle.");
+
+static int
+Source_set_azimuth(SourceP* self, PyObject* args, void* nothing)
+{
+ float azimuth;
+
+ if(!PyArg_Parse(args, "f:azimuth", &azimuth))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->setAzimuth(azimuth);
+ return 0;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+Source_get_azimuth(SourceP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->getAzimuth());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Source_elevation_doc,
+ "The elevation angle.");
+
+static int
+Source_set_elevation(SourceP* self, PyObject* args, void* nothing)
+{
+ float elevation;
+
+ if(!PyArg_Parse(args, "f:elevation", &elevation))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->setElevation(elevation);
+ return 0;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+Source_get_elevation(SourceP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->getElevation());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+PyDoc_STRVAR(M_aud_Source_distance_doc,
+ "The distance value. 0 is min, 1 is max.");
+
+static int
+Source_set_distance(SourceP* self, PyObject* args, void* nothing)
+{
+ float distance;
+
+ if(!PyArg_Parse(args, "f:distance", &distance))
+ return -1;
+
+ try
+ {
+ (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->setDistance(distance);
+ return 0;
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ }
+
+ return -1;
+}
+
+static PyObject *
+Source_get_distance(SourceP* self, void* nothing)
+{
+ try
+ {
+ return Py_BuildValue("f", (*reinterpret_cast<std::shared_ptr<aud::Source>*>(self->source))->getDistance());
+ }
+ catch(aud::Exception& e)
+ {
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+}
+
+static PyGetSetDef Source_properties[] = {
+ { (char*)"azimuth", (getter)Source_get_azimuth, (setter)Source_set_azimuth,
+ M_aud_Source_azimuth_doc, nullptr },
+ { (char*)"elevation", (getter)Source_get_elevation, (setter)Source_set_elevation,
+ M_aud_Source_elevation_doc, nullptr },
+ { (char*)"distance", (getter)Source_get_distance, (setter)Source_set_distance,
+ M_aud_Source_distance_doc, nullptr },
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Source_doc,
+ "The source object represents the source position of a binaural sound.");
+
+PyTypeObject SourceType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.Source", /* tp_name */
+ sizeof(SourceP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)Source_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_Source_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ Source_methods, /* tp_methods */
+ 0, /* tp_members */
+ Source_properties, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ Source_new, /* tp_new */
+};
+
+AUD_API PyObject* Source_empty()
+{
+ return SourceType.tp_alloc(&SourceType, 0);
+}
+
+
+AUD_API SourceP* checkSource(PyObject* source)
+{
+ if(!PyObject_TypeCheck(source, &SourceType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Source!");
+ return nullptr;
+ }
+
+ return (SourceP*)source;
+}
+
+
+bool initializeSource()
+{
+ return PyType_Ready(&SourceType) >= 0;
+}
+
+
+void addSourceToModule(PyObject* module)
+{
+ Py_INCREF(&SourceType);
+ PyModule_AddObject(module, "Source", (PyObject *)&SourceType);
+}
diff --git a/extern/audaspace/bindings/python/PySource.h b/extern/audaspace/bindings/python/PySource.h
new file mode 100644
index 00000000000..19960d80901
--- /dev/null
+++ b/extern/audaspace/bindings/python/PySource.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_Source;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_Source* source;
+} SourceP;
+
+extern AUD_API PyObject* Source_empty();
+extern AUD_API SourceP* checkSource(PyObject* source);
+
+bool initializeSource();
+void addSourceToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/PyThreadPool.cpp b/extern/audaspace/bindings/python/PyThreadPool.cpp
new file mode 100644
index 00000000000..75811f08273
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyThreadPool.cpp
@@ -0,0 +1,134 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "PyThreadPool.h"
+
+#include "Exception.h"
+#include "util/ThreadPool.h"
+
+extern PyObject* AUDError;
+
+static PyObject *
+ThreadPool_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
+{
+ ThreadPoolP* self = (ThreadPoolP*)type->tp_alloc(type, 0);
+
+ if(self != nullptr)
+ {
+ unsigned int nThreads;
+ if(!PyArg_ParseTuple(args, "I:nThreads", &nThreads))
+ return nullptr;
+
+ try
+ {
+ self->threadPool = new std::shared_ptr<aud::ThreadPool>(new aud::ThreadPool(nThreads));
+ }
+ catch(aud::Exception& e)
+ {
+ Py_DECREF(self);
+ PyErr_SetString(AUDError, e.what());
+ return nullptr;
+ }
+ }
+
+ return (PyObject *)self;
+}
+
+static void
+ThreadPool_dealloc(ThreadPoolP* self)
+{
+ if(self->threadPool)
+ delete reinterpret_cast<std::shared_ptr<aud::ThreadPool>*>(self->threadPool);
+ Py_TYPE(self)->tp_free((PyObject *)self);
+}
+
+static PyMethodDef ThreadPool_methods[] = {
+ { nullptr } /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_ThreadPool_doc,
+ "A ThreadPool is used to parallelize convolution efficiently.");
+
+PyTypeObject ThreadPoolType = {
+ PyVarObject_HEAD_INIT(nullptr, 0)
+ "aud.ThreadPool", /* tp_name */
+ sizeof(ThreadPoolP), /* tp_basicsize */
+ 0, /* tp_itemsize */
+ (destructor)ThreadPool_dealloc, /* tp_dealloc */
+ 0, /* tp_print */
+ 0, /* tp_getattr */
+ 0, /* tp_setattr */
+ 0, /* tp_reserved */
+ 0, /* tp_repr */
+ 0, /* tp_as_number */
+ 0, /* tp_as_sequence */
+ 0, /* tp_as_mapping */
+ 0, /* tp_hash */
+ 0, /* tp_call */
+ 0, /* tp_str */
+ 0, /* tp_getattro */
+ 0, /* tp_setattro */
+ 0, /* tp_as_buffer */
+ Py_TPFLAGS_DEFAULT, /* tp_flags */
+ M_aud_ThreadPool_doc, /* tp_doc */
+ 0, /* tp_traverse */
+ 0, /* tp_clear */
+ 0, /* tp_richcompare */
+ 0, /* tp_weaklistoffset */
+ 0, /* tp_iter */
+ 0, /* tp_iternext */
+ ThreadPool_methods, /* tp_methods */
+ 0, /* tp_members */
+ 0, /* tp_getset */
+ 0, /* tp_base */
+ 0, /* tp_dict */
+ 0, /* tp_descr_get */
+ 0, /* tp_descr_set */
+ 0, /* tp_dictoffset */
+ 0, /* tp_init */
+ 0, /* tp_alloc */
+ ThreadPool_new, /* tp_new */
+};
+
+AUD_API PyObject* ThreadPool_empty()
+{
+ return ThreadPoolType.tp_alloc(&ThreadPoolType, 0);
+}
+
+
+AUD_API ThreadPoolP* checkThreadPool(PyObject* threadPool)
+{
+ if(!PyObject_TypeCheck(threadPool, &ThreadPoolType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type ThreadPool!");
+ return nullptr;
+ }
+
+ return (ThreadPoolP*)threadPool;
+}
+
+
+bool initializeThreadPool()
+{
+ return PyType_Ready(&ThreadPoolType) >= 0;
+}
+
+
+void addThreadPoolToModule(PyObject* module)
+{
+ Py_INCREF(&ThreadPoolType);
+ PyModule_AddObject(module, "ThreadPool", (PyObject *)&ThreadPoolType);
+}
diff --git a/extern/audaspace/bindings/python/PyThreadPool.h b/extern/audaspace/bindings/python/PyThreadPool.h
new file mode 100644
index 00000000000..e38d905f52a
--- /dev/null
+++ b/extern/audaspace/bindings/python/PyThreadPool.h
@@ -0,0 +1,33 @@
+/*******************************************************************************
+* Copyright 2009-2015 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+#include <Python.h>
+#include "Audaspace.h"
+
+typedef void Reference_ThreadPool;
+
+typedef struct {
+ PyObject_HEAD
+ Reference_ThreadPool* threadPool;
+} ThreadPoolP;
+
+extern AUD_API PyObject* ThreadPool_empty();
+extern AUD_API ThreadPoolP* checkThreadPool(PyObject* ThreadPool);
+
+bool initializeThreadPool();
+void addThreadPoolToModule(PyObject* module); \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/binaural.py b/extern/audaspace/bindings/python/examples/binaural.py
new file mode 100644
index 00000000000..e7a2f6cf6d9
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/binaural.py
@@ -0,0 +1,13 @@
+#!/usr/bin/python
+import aud, sys, time, multiprocessing
+device = aud.Device()
+hrtf = aud.HRTF().loadLeftHrtfSet(".wav", sys.argv[2])
+threadPool = aud.ThreadPool(multiprocessing.cpu_count())
+source = aud.Source(0, 0, 0)
+sound = aud.Sound.file(sys.argv[1]).rechannel(1).binaural(hrtf, source, threadPool)
+handle = device.play(sound)
+
+while handle.status:
+ source.azimuth += 1
+ print("Azimuth: " + str(source.azimuth))
+ time.sleep(0.1) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/convolution.py b/extern/audaspace/bindings/python/examples/convolution.py
new file mode 100644
index 00000000000..4de25b0336a
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/convolution.py
@@ -0,0 +1,10 @@
+#!/usr/bin/python
+import aud, sys, time, multiprocessing
+device = aud.Device()
+ir = aud.ImpulseResponse(aud.Sound.file(sys.argv[2]))
+threadPool = aud.ThreadPool(multiprocessing.cpu_count())
+sound = aud.Sound.file(sys.argv[1]).convolver(ir, threadPool)
+handle = device.play(sound)
+handle.volume = 0.1
+while handle.status:
+ time.sleep(0.1) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/dynamicmusic.py b/extern/audaspace/bindings/python/examples/dynamicmusic.py
new file mode 100644
index 00000000000..348e2496c0a
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/dynamicmusic.py
@@ -0,0 +1,20 @@
+import aud, sys, time
+
+device=aud.Device()
+dMusic = aud.DynamicMusic(device)
+sound1 = aud.Sound.file(sys.argv[1])
+sound2 = aud.Sound.file(sys.argv[2])
+effect = aud.Sound.file(sys.argv[3])
+
+dMusic.addScene(sound1)
+dMusic.addScene(sound2)
+dMusic.addTransition(1,2,effect)
+
+dMusic.fadeTime=3
+dMusic.volume=0.5
+
+dMusic.scene=1
+time.sleep(5)
+dMusic.scene=2
+
+time.sleep(500) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/playbackmanager.py b/extern/audaspace/bindings/python/examples/playbackmanager.py
new file mode 100644
index 00000000000..2aa1c283545
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/playbackmanager.py
@@ -0,0 +1,27 @@
+import aud, sys, time
+
+device=aud.Device()
+manager = aud.PlaybackManager(device)
+sound1 = aud.Sound.file(sys.argv[1])
+sound2 = aud.Sound.file(sys.argv[2])
+sound3 = aud.Sound.file(sys.argv[3])
+sound4 = aud.Sound.file(sys.argv[4])
+
+manager.play(sound1, 0)
+manager.play(sound2, 0)
+manager.play(sound3, 1)
+manager.play(sound4, 1)
+
+manager.setVolume(0.2, 0)
+time.sleep(5)
+manager.setVolume(0.0, 1)
+time.sleep(5)
+manager.pause(0)
+time.sleep(5)
+manager.setVolume(0.5, 1)
+manager.setVolume(1.0, 0)
+time.sleep(5)
+manager.stop(1)
+manager.resume(0)
+
+time.sleep(500) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/player.py b/extern/audaspace/bindings/python/examples/player.py
new file mode 100644
index 00000000000..8acf4ac833f
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/player.py
@@ -0,0 +1,7 @@
+#!/usr/bin/python
+import aud, sys, time
+device = aud.Device()
+sound = aud.Sound.file(sys.argv[1])
+handle = device.play(sound)
+while handle.status:
+ time.sleep(0.1)
diff --git a/extern/audaspace/bindings/python/examples/randomSounds.py b/extern/audaspace/bindings/python/examples/randomSounds.py
new file mode 100644
index 00000000000..113b0921f09
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/randomSounds.py
@@ -0,0 +1,21 @@
+import aud, sys, time
+
+device=aud.Device()
+sound1 = aud.Sound.file(sys.argv[1])
+sound2 = aud.Sound.file(sys.argv[2])
+sound3 = aud.Sound.file(sys.argv[3])
+sound4 = aud.Sound.file(sys.argv[4])
+list=aud.Sound.list(True)
+
+list.addSound(sound1)
+list.addSound(sound2)
+list.addSound(sound3)
+list.addSound(sound4)
+mutable=aud.Sound.mutable(list)
+
+device.lock()
+handle=device.play(mutable)
+handle.loop_count=2
+device.unlock()
+
+time.sleep(500) \ No newline at end of file
diff --git a/extern/audaspace/bindings/python/examples/simple.py b/extern/audaspace/bindings/python/examples/simple.py
new file mode 100644
index 00000000000..7aa45b41042
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/simple.py
@@ -0,0 +1,7 @@
+#!/usr/bin/python
+import aud, time
+device = aud.Device()
+sine = aud.Sound.sine(440)
+square = sine.threshold()
+handle = device.play(square)
+time.sleep(3)
diff --git a/extern/audaspace/bindings/python/examples/siren.py b/extern/audaspace/bindings/python/examples/siren.py
new file mode 100644
index 00000000000..071279b162d
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/siren.py
@@ -0,0 +1,19 @@
+#!/usr/bin/python
+import aud, math, time
+length = 0.5
+fadelength = 0.05
+
+device = aud.Device()
+high = aud.Sound.sine(880).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length)
+low = aud.Sound.sine(700).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length).volume(0.6)
+sound = high.join(low)
+handle = device.play(sound)
+handle.loop_count = -1
+
+start = time.time()
+
+while time.time() - start < 10:
+ angle = time.time() - start
+
+ handle.location = [math.sin(angle), 0, -math.cos(angle)]
+
diff --git a/extern/audaspace/bindings/python/examples/siren2.py b/extern/audaspace/bindings/python/examples/siren2.py
new file mode 100644
index 00000000000..35e1a600581
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/siren2.py
@@ -0,0 +1,23 @@
+#!/usr/bin/python
+import aud, math, time
+length = 0.5
+fadelength = 0.05
+runtime = 10
+distance = 100
+velocity = 2 * distance / runtime
+
+device = aud.Device()
+high = aud.Sound.sine(880).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length)
+low = aud.Sound.sine(700).limit(0, length).fadein(0, fadelength).fadeout(length - fadelength, length).volume(0.6)
+sound = high.join(low)
+handle = device.play(sound)
+handle.loop_count = -1
+
+handle.velocity = [velocity, 0, 0]
+
+start = time.time()
+
+while time.time() - start < runtime:
+ location = -distance + velocity * (time.time() - start)
+
+ handle.location = [location, 10, 0]
diff --git a/extern/audaspace/bindings/python/examples/tetris.py b/extern/audaspace/bindings/python/examples/tetris.py
new file mode 100644
index 00000000000..236a6fa59c1
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/tetris.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python
+import aud, math, time
+
+def parseNotes(notes, bpm, basefreq, rate = 44100,
+ notechars = "XXXCXDXEFXGXAXHcXdXefXgXaXhp"):
+ pos = 0
+ fadelength = 60/bpm/10
+ halfchars = "#b"
+ durationchars = "2345678"
+ sound = None
+
+ while pos < len(notes):
+ char = notes[pos]
+ mod = None
+ dur = 1
+ pos += 1
+ while pos < len(notes) and notes[pos] not in notechars:
+ if notes[pos] in halfchars:
+ mod = notes[pos]
+ elif notes[pos] in durationchars:
+ dur = notes[pos]
+ pos += 1
+
+ freq = notechars.find(char)
+ if mod == '#':
+ freq += 1
+ elif mod == 'b':
+ freq -= 1
+
+ freq = math.pow(2, freq/12)*basefreq
+ length = float(dur)*60/bpm
+
+ snd = aud.Sound.square(freq, rate)
+ if char == 'p':
+ snd = snd.volume(0)
+ snd = snd.limit(0, length)
+ snd = snd.fadein(0, fadelength)
+ snd = snd.fadeout(length - fadelength, fadelength)
+
+ if sound:
+ sound = sound.join(snd)
+ else:
+ sound = snd
+ return sound
+
+def tetris(bpm = 300, freq = 220, rate = 44100):
+ notes = "e2Hcd2cH A2Ace2dc H3cd2e2 c2A2A4 pd2fa2gf e3ce2dc H2Hcd2e2 c2A2A2p2"
+ s11 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "e4c4 d4H4 c4A4 G#4p4 e4c4 d4H4 A2c2a4 g#4p4"
+ s12 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "EeEeEeEe AaAaAaAa AbabAbabAbabAbab AaAaAAHC DdDdDdDd CcCcCcCc HhHhHhHh AaAaA2p2"
+ s21 = parseNotes(notes, bpm, freq, rate, notechars = "AXHCXDXEFXGXaXhcXdXefXgXp")
+
+ notes = "aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2 aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2"
+ s22 = parseNotes(notes, bpm, freq/2, rate)
+
+ return s11.join(s12).join(s11).volume(0.5).mix(s21.join(s22).join(s21).volume(0.3))
+
+if __name__ == "__main__":
+ dev = aud.Device()
+ handle = dev.play(tetris(300, 220, dev.rate))
+ while handle.status:
+ time.sleep(0.1)
+
diff --git a/extern/audaspace/bindings/python/examples/tetris2.py b/extern/audaspace/bindings/python/examples/tetris2.py
new file mode 100644
index 00000000000..08708581af6
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/tetris2.py
@@ -0,0 +1,64 @@
+#!/usr/bin/python
+import aud, math, time
+
+def parseNotes(notes, bpm, basefreq, rate = 44100,
+ notechars = "XXXCXDXEFXGXAXHcXdXefXgXaXhp"):
+ pos = 0
+ fadelength = 60/bpm/10
+ halfchars = "#b"
+ durationchars = "2345678"
+ position = 0
+ sequence = aud.Sequence()
+
+ while pos < len(notes):
+ char = notes[pos]
+ mod = None
+ dur = 1
+ pos += 1
+ while pos < len(notes) and notes[pos] not in notechars:
+ if notes[pos] in halfchars:
+ mod = notes[pos]
+ elif notes[pos] in durationchars:
+ dur = notes[pos]
+ pos += 1
+
+ freq = notechars.find(char)
+ if mod == '#':
+ freq += 1
+ elif mod == 'b':
+ freq -= 1
+
+ freq = math.pow(2, freq/12)*basefreq
+ length = float(dur)*60/bpm
+
+ note = aud.Sound.square(freq, rate).fadein(0, fadelength).fadeout(length - fadelength, fadelength)
+
+ entry = sequence.add(note, position, position + length, 0)
+ if char == 'p':
+ entry.muted = True
+
+ position += length
+
+ return sequence.limit(0, position)
+
+def tetris(bpm = 300, freq = 220, rate = 44100):
+ notes = "e2Hcd2cH A2Ace2dc H3cd2e2 c2A2A4 pd2fa2gf e3ce2dc H2Hcd2e2 c2A2A2p2"
+ s11 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "e4c4 d4H4 c4A4 G#4p4 e4c4 d4H4 A2c2a4 g#4p4"
+ s12 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "EeEeEeEe AaAaAaAa AbabAbabAbabAbab AaAaAAHC DdDdDdDd CcCcCcCc HhHhHhHh AaAaA2p2"
+ s21 = parseNotes(notes, bpm, freq, rate, notechars = "AXHCXDXEFXGXaXhcXdXefXgXp")
+
+ notes = "aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2 aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2"
+ s22 = parseNotes(notes, bpm, freq/2, rate)
+
+ return s11.join(s12).join(s11).volume(0.5).mix(s21.join(s22).join(s21).volume(0.3))
+
+if __name__ == "__main__":
+ dev = aud.Device()
+ handle = dev.play(tetris(300, 220, dev.rate))
+ while handle.status:
+ time.sleep(0.1)
+
diff --git a/extern/audaspace/bindings/python/examples/tetris3.py b/extern/audaspace/bindings/python/examples/tetris3.py
new file mode 100644
index 00000000000..aa66d5457d3
--- /dev/null
+++ b/extern/audaspace/bindings/python/examples/tetris3.py
@@ -0,0 +1,63 @@
+#!/usr/bin/python
+import aud, math, time
+
+def parseNotes(notes, bpm, basefreq, rate = 44100,
+ notechars = "XXXCXDXEFXGXAXHcXdXefXgXaXhp"):
+ pos = 0
+ fadelength = 60/bpm/10
+ halfchars = "#b"
+ durationchars = "2345678"
+ position = 0
+ sequence = aud.Sequence()
+
+ while pos < len(notes):
+ char = notes[pos]
+ mod = None
+ dur = 1
+ pos += 1
+ while pos < len(notes) and notes[pos] not in notechars:
+ if notes[pos] in halfchars:
+ mod = notes[pos]
+ elif notes[pos] in durationchars:
+ dur = notes[pos]
+ pos += 1
+
+ freq = notechars.find(char)
+ if mod == '#':
+ freq += 1
+ elif mod == 'b':
+ freq -= 1
+
+ freq = math.pow(2, freq/12)*basefreq
+ length = float(dur)*60/bpm
+
+ if char != 'p':
+ note = aud.Sound.square(freq, rate).fadein(0, fadelength).fadeout(length - fadelength, fadelength)
+
+ sequence.add(note, position, position + length, 0)
+
+ position += length
+
+ return sequence.limit(0, position)
+
+def tetris(bpm = 300, freq = 220, rate = 44100):
+ notes = "e2Hcd2cH A2Ace2dc H3cd2e2 c2A2A4 pd2fa2gf e3ce2dc H2Hcd2e2 c2A2A2p2"
+ s11 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "e4c4 d4H4 c4A4 G#4p4 e4c4 d4H4 A2c2a4 g#4p4"
+ s12 = parseNotes(notes, bpm, freq, rate)
+
+ notes = "EeEeEeEe AaAaAaAa AbabAbabAbabAbab AaAaAAHC DdDdDdDd CcCcCcCc HhHhHhHh AaAaA2p2"
+ s21 = parseNotes(notes, bpm, freq, rate, notechars = "AXHCXDXEFXGXaXhcXdXefXgXp")
+
+ notes = "aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2 aeaeaeae g#dg#dg#dg#d aeaeaeae g#dg#dg#2p2"
+ s22 = parseNotes(notes, bpm, freq/2, rate)
+
+ return s11.join(s12).join(s11).volume(0.5).mix(s21.join(s22).join(s21).volume(0.3))
+
+if __name__ == "__main__":
+ dev = aud.Device()
+ handle = dev.play(tetris(300, 220, dev.rate))
+ while handle.status:
+ time.sleep(0.1)
+
diff --git a/extern/audaspace/bindings/python/setup.py.in b/extern/audaspace/bindings/python/setup.py.in
new file mode 100644
index 00000000000..add1a2d1475
--- /dev/null
+++ b/extern/audaspace/bindings/python/setup.py.in
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+
+import sys
+import os
+import codecs
+import numpy
+
+from distutils.core import setup, Extension
+
+if len(sys.argv) > 2 and sys.argv[1] == '--build-docs':
+ import subprocess
+ from distutils.core import Distribution
+ from distutils.command.build import build
+
+ dist = Distribution()
+ cmd = build(dist)
+ cmd.finalize_options()
+ #print(cmd.build_platlib)
+
+ os.environ['PYTHONPATH'] = os.path.join(os.getcwd(), cmd.build_platlib)
+ os.environ['LD_LIBRARY_PATH'] = os.getcwd()
+
+ ret = subprocess.call(sys.argv[2:])
+ sys.exit(ret)
+
+
+# the following line is not working due to https://bugs.python.org/issue9023
+#source_directory = os.path.relpath('@PYTHON_SOURCE_DIRECTORY@')
+source_directory = '@PYTHON_SOURCE_DIRECTORY@'
+
+extra_args = []
+
+if sys.platform == 'win32':
+ extra_args.append('/EHsc')
+ extra_args.append('/DAUD_BUILD_SHARED_LIBRARY')
+else:
+ extra_args.append('-std=c++11')
+
+audaspace = Extension(
+ 'aud',
+ include_dirs = ['@CMAKE_CURRENT_BINARY_DIR@', '@FFTW_INCLUDE_DIR@', os.path.join(source_directory, '../../include'), numpy.get_include()],
+ libraries = ['audaspace'],
+ library_dirs = ['.', 'Release', 'Debug'],
+ language = 'c++',
+ extra_compile_args = extra_args,
+ sources = [os.path.join(source_directory, file) for file in ['PyAPI.cpp', 'PyDevice.cpp', 'PyHandle.cpp', 'PySound.cpp', 'PySequenceEntry.cpp', 'PySequence.cpp', 'PyPlaybackManager.cpp', 'PyDynamicMusic.cpp', 'PyThreadPool.cpp', 'PySource.cpp'] + (['PyImpulseResponse.cpp', 'PyHRTF.cpp'] if '@WITH_FFTW@' == 'ON' else [])]
+)
+
+setup(
+ name = 'audaspace',
+ version = '@AUDASPACE_LONG_VERSION@',
+ description = 'Audaspace is a high level audio library.',
+ author = 'Jörg Müller',
+ author_email = 'nexyon@gmail.com',
+ url = 'https://github.com/audaspace/audaspace',
+ license = 'Apache License 2.0',
+ long_description = codecs.open(os.path.join(source_directory, '../../README.md'), 'r', 'utf-8').read(),
+ ext_modules = [audaspace],
+ headers = [os.path.join(source_directory, file) for file in ['PyAPI.h', 'PyDevice.h', 'PyHandle.h', 'PySound.h', 'PySequenceEntry.h', 'PySequence.h', 'PyPlaybackManager.h', 'PyDynamicMusic.h', 'PyThreadPool.h', 'PySource.h'] + (['PyImpulseResponse.h', 'PyHRTF.h'] if '@WITH_FFTW@' == 'ON' else [])] + ['Audaspace.h']
+)
+
diff --git a/extern/audaspace/blender_config.cmake b/extern/audaspace/blender_config.cmake
new file mode 100644
index 00000000000..5b5440920d0
--- /dev/null
+++ b/extern/audaspace/blender_config.cmake
@@ -0,0 +1,26 @@
+set(AUDASPACE_STANDALONE FALSE)
+set(BUILD_DEMOS FALSE)
+set(SHARED_LIBRARY FALSE)
+set(WITH_C TRUE)
+set(WITH_DOCS FALSE)
+set(WITH_FFMPEG ${WITH_CODEC_FFMPEG})
+set(WITH_FFTW FALSE)
+set(WITH_LIBSNDFILE ${WITH_CODEC_SNDFILE})
+set(SEPARATE_C FALSE)
+set(PLUGIN_FFMPEG FALSE)
+set(PLUGIN_JACK FALSE)
+set(PLUGIN_LIBSNDFILE FALSE)
+set(PLUGIN_OPENAL FALSE)
+set(PLUGIN_SDL FALSE)
+set(WITH_PYTHON_MODULE FALSE)
+set(DYNLOAD_JACK ${WITH_JACK_DYNLOAD})
+set(WITH_BINDING_DOCS FALSE)
+set(BLENDER_AUDASPACE TRUE)
+set(FFMPEG_FOUND ${WITH_CODEC_FFMPEG})
+set(JACK_FOUND ${WITH_JACK})
+set(LIBSNDFILE_FOUND ${WITH_CODEC_SNDFILE})
+set(OPENAL_FOUND ${WITH_OPENAL})
+set(PYTHONLIBS_FOUND TRUE)
+set(NUMPY_FOUND TRUE)
+set(NUMPY_INCLUDE_DIRS ${PYTHON_NUMPY_INCLUDE_DIRS})
+set(SDL_FOUND ${WITH_SDL})
diff --git a/extern/audaspace/config/Audaspace.h.in b/extern/audaspace/config/Audaspace.h.in
new file mode 100644
index 00000000000..3e6912727b8
--- /dev/null
+++ b/extern/audaspace/config/Audaspace.h.in
@@ -0,0 +1,131 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Audaspace.h
+ * @ingroup general
+ * The main header file of the library defining the namespace and basic data types.
+ */
+
+/**
+ * \def AUD_API
+ * Used for exporting symbols in the shared library.
+ */
+
+/**
+ * \def AUD_PLUGIN_API
+ * Used for exporting symbols in the shared library.
+ */
+
+/**
+ * \def AUD_EXPORT_API
+ * Used for using exporting symbols of the shared library.
+ */
+
+/**
+ * \def AUD_USE_API
+ * Used for using exporting symbols of the shared library.
+ */
+
+/**
+ * \def AUD_LOCAL
+ * Used for hiding symbols from export in the shared library.
+ */
+
+// the following two defines and undefines are a hack to silence an error by doxygen
+
+/**
+ * \def AUD_SHARED_LIBRARY
+ * Defined when audaspace was built as a shared library.
+ */
+#define AUD_SHARED_LIBRARY
+#undef AUD_SHARED_LIBRARY
+
+/**
+ * \def AUD_STATIC_LIBRARY
+ * Defined when audaspace was built as a static library.
+ */
+ #define AUD_STATIC_LIBRARY
+ #undef AUD_STATIC_LIBRARY
+
+#define @AUD_LIBRARY_TYPE@
+
+#ifdef _MSC_VER
+ #define AUD_EXPORT_API __declspec(dllexport)
+ #define AUD_USE_API __declspec(dllimport)
+ #define AUD_LOCAL
+#else
+ #ifdef __GNUC__
+ #define AUD_EXPORT_API __attribute__((visibility ("default")))
+ #define AUD_USE_API AUD_EXPORT_API
+ #define AUD_LOCAL __attribute__((visibility ("hidden")))
+ #else
+ #define AUD_EXPORT_API
+ #define AUD_USE_API
+ #define AUD_LOCAL
+ #endif
+#endif
+
+#ifdef AUD_SHARED_LIBRARY
+ #ifdef AUD_BUILD_PLUGIN
+ #define AUD_API AUD_USE_API
+ #define AUD_PLUGIN_API AUD_EXPORT_API
+ #else
+ #ifdef AUD_BUILD_SHARED_LIBRARY
+ #define AUD_API AUD_EXPORT_API
+ #define AUD_PLUGIN_API AUD_EXPORT_API
+ #else
+ #define AUD_API AUD_USE_API
+ #define AUD_PLUGIN_API AUD_USE_API
+ #endif
+ #endif
+#else
+ #define AUD_API
+ #define AUD_PLUGIN_API
+#endif
+
+/// The default playback buffer size of a device.
+#define AUD_DEFAULT_BUFFER_SIZE 1024
+
+#ifdef __cplusplus
+
+/// Opens the audaspace namespace aud.
+#define AUD_NAMESPACE_BEGIN namespace aud {
+
+/// Closes the audaspace namespace aud.
+#define AUD_NAMESPACE_END }
+
+#else
+
+/// Opens the audaspace namespace aud.
+#define AUD_NAMESPACE_BEGIN
+
+/// Closes the audaspace namespace aud.
+#define AUD_NAMESPACE_END
+
+#endif
+
+AUD_NAMESPACE_BEGIN
+
+/// Sample type.(float samples)
+typedef float sample_t;
+
+/// Sample data type (format samples)
+typedef unsigned char data_t;
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/Exception.h b/extern/audaspace/include/Exception.h
new file mode 100644
index 00000000000..b102bfade63
--- /dev/null
+++ b/extern/audaspace/include/Exception.h
@@ -0,0 +1,185 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * \def AUD_NOEXCEPT
+ * Compatibility macro for noexcept.
+ */
+#ifdef _MSC_VER
+#define AUD_NOEXCEPT
+#else
+#define AUD_NOEXCEPT noexcept
+#endif
+
+/**
+ * @file Exception.h
+ * @ingroup general
+ * Defines the Exception class as well as the AUD_THROW macro for easy throwing.
+ */
+
+#include "Audaspace.h"
+
+#include <exception>
+#include <string>
+
+/// Throws a Exception with the provided error code.
+#define AUD_THROW(exception, message) { throw exception(message, __FILE__, __LINE__); }
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The Exception class is the general exception base class.
+ */
+class AUD_API Exception : public std::exception
+{
+protected:
+ /// A message describing the problem.
+ const std::string m_message;
+
+ /// The source code file in which the exception was thrown.
+ const std::string m_file;
+
+ /// The source code line from which the exception was thrown.
+ const int m_line;
+
+ /**
+ * Copy constructor.
+ * @param exception The exception to be copied.
+ */
+ Exception(const Exception& exception);
+
+ /**
+ * Creates a new Exception object.
+ * @param message A message describing the problem.
+ * @param file The source code file in which the exception was thrown.
+ * @param line The source code line from which the exception was thrown.
+ */
+ Exception(std::string message, std::string file, int line);
+public:
+ /**
+ * Destroys the object.
+ */
+ virtual ~Exception() AUD_NOEXCEPT;
+
+ /**
+ * Returns the error message.
+ * @return A C string error message.
+ */
+ virtual const char* what() const AUD_NOEXCEPT;
+
+ /**
+ * Returns the error message plus file and line number for debugging purposes.
+ * @return The error message including debug information.
+ */
+ virtual std::string getDebugMessage() const;
+
+ /**
+ * Returns the error message.
+ * @return The error message as string.
+ */
+ const std::string& getMessage() const;
+
+ /**
+ * Returns the file in which the exception was thrown.
+ * @return The name of the file in which the exception was thrown.
+ */
+ const std::string& getFile() const;
+
+ /**
+ * Returns the line where the exception was originally thrown.
+ * @return The line of the source file where the exception was generated.
+ */
+ int getLine() const;
+};
+
+/**
+ * The FileException class is used for error cases in which files cannot
+ * be read or written due to unknown containers or codecs.
+ */
+class AUD_API FileException : public Exception
+{
+public:
+ /**
+ * Creates a new FileException object.
+ * @param message A message describing the problem.
+ * @param file The source code file in which the exception was thrown.
+ * @param line The source code line from which the exception was thrown.
+ */
+ FileException(std::string message, std::string file, int line);
+
+ /**
+ * Copy constructor.
+ * @param exception The exception to be copied.
+ */
+ FileException(const FileException& exception);
+
+ ~FileException() AUD_NOEXCEPT;
+};
+
+/**
+ * The DeviceException class is used for error cases in connection with
+ * devices, which usually happens when specific features or requests
+ * cannot be fulfilled by a device, for example when the device is opened.
+ */
+class AUD_API DeviceException : public Exception
+{
+public:
+ /**
+ * Creates a new DeviceException object.
+ * @param message A message describing the problem.
+ * @param file The source code file in which the exception was thrown.
+ * @param line The source code line from which the exception was thrown.
+ */
+ DeviceException(std::string message, std::string file, int line);
+
+ /**
+ * Copy constructor.
+ * @param exception The exception to be copied.
+ */
+ DeviceException(const DeviceException& exception);
+
+ ~DeviceException() AUD_NOEXCEPT;
+};
+
+/**
+ * The StateException class is used for error cases of sounds or readers
+ * with illegal states or requirements for states of dependent classes.
+ * It is used for example when an effect reader needs a specific
+ * specification from its input.
+ */
+class AUD_API StateException : public Exception
+{
+public:
+ /**
+ * Creates a new StateException object.
+ * @param message A message describing the problem.
+ * @param file The source code file in which the exception was thrown.
+ * @param line The source code line from which the exception was thrown.
+ */
+ StateException(std::string message, std::string file, int line);
+
+ /**
+ * Copy constructor.
+ * @param exception The exception to be copied.
+ */
+ StateException(const StateException& exception);
+
+ ~StateException() AUD_NOEXCEPT;
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_IReader.h b/extern/audaspace/include/IReader.h
index c2c9e607b55..c29900ca579 100644
--- a/intern/audaspace/intern/AUD_IReader.h
+++ b/extern/audaspace/include/IReader.h
@@ -1,48 +1,43 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_IReader.h
- * \ingroup audaspaceintern
- */
+#pragma once
+/**
+ * @file IReader.h
+ * @ingroup general
+ * The IReader interface.
+ */
-#ifndef __AUD_IREADER_H__
-#define __AUD_IREADER_H__
+#include "respec/Specification.h"
-#include "AUD_Space.h"
+AUD_NAMESPACE_BEGIN
/**
+ * @interface IReader
* This class represents a sound source as stream or as buffer which can be read
* for example by another reader, a device or whatever.
*/
-class AUD_IReader
+class AUD_API IReader
{
public:
/**
* Destroys the reader.
*/
- virtual ~AUD_IReader() {}
+ virtual ~IReader() {}
/**
* Tells whether the source provides seeking functionality or not.
@@ -77,9 +72,9 @@ public:
/**
* Returns the specification of the reader.
- * \return The AUD_Specs structure.
+ * \return The Specs structure.
*/
- virtual AUD_Specs getSpecs() const=0;
+ virtual Specs getSpecs() const=0;
/**
* Request to read the next length samples out of the source.
@@ -94,4 +89,4 @@ public:
virtual void read(int& length, bool& eos, sample_t* buffer)=0;
};
-#endif //__AUD_IREADER_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/ISound.h b/extern/audaspace/include/ISound.h
new file mode 100644
index 00000000000..c28337e1b4e
--- /dev/null
+++ b/extern/audaspace/include/ISound.h
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ISound.h
+ * @ingroup general
+ * The ISound interface.
+ */
+
+#include "Audaspace.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+
+/**
+ * @interface ISound
+ * 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
+ * of the respective sound source through the factory method createReader.
+ */
+class AUD_API ISound
+{
+public:
+ /**
+ * Destroys the sound.
+ */
+ virtual ~ISound() {}
+
+ /**
+ * Creates a reader for playback of the sound source.
+ * \return A pointer to an IReader object or nullptr if there has been an
+ * error.
+ * \exception Exception An exception may be thrown if there has been
+ * a more unexpected error during reader creation.
+ */
+ virtual std::shared_ptr<IReader> createReader()=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/DefaultSynchronizer.h b/extern/audaspace/include/devices/DefaultSynchronizer.h
new file mode 100644
index 00000000000..31f6c65219c
--- /dev/null
+++ b/extern/audaspace/include/devices/DefaultSynchronizer.h
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DefaultSynchronizer.h
+ * @ingroup devices
+ * The DefaultSynchronizer class.
+ */
+
+#include "ISynchronizer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is a default ISynchronizer implementation that actually does no
+ * synchronization and is intended for devices that don't support it.
+ */
+class AUD_API DefaultSynchronizer : public ISynchronizer
+{
+public:
+ virtual void seek(std::shared_ptr<IHandle> handle, float time);
+ virtual float getPosition(std::shared_ptr<IHandle> handle);
+ virtual void play();
+ virtual void stop();
+ virtual void setSyncCallback(syncFunction function, void* data);
+ virtual int isPlaying();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/DeviceManager.h b/extern/audaspace/include/devices/DeviceManager.h
new file mode 100644
index 00000000000..27a546630e8
--- /dev/null
+++ b/extern/audaspace/include/devices/DeviceManager.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DeviceManager.h
+ * @ingroup devices
+ * The DeviceManager class.
+ */
+
+#include "Audaspace.h"
+
+#include <memory>
+#include <vector>
+#include <unordered_map>
+
+AUD_NAMESPACE_BEGIN
+
+class IDevice;
+class IDeviceFactory;
+class I3DDevice;
+
+/**
+ * This class manages all device plugins and maintains a device if asked to do so.
+ *
+ * This enables applications to access their output device without having to carry
+ * it through the whole application.
+ */
+class AUD_API DeviceManager
+{
+private:
+ static std::unordered_map<std::string, std::shared_ptr<IDeviceFactory>> m_factories;
+
+ static std::shared_ptr<IDevice> m_device;
+
+ // delete copy constructor and operator=
+ DeviceManager(const DeviceManager&) = delete;
+ DeviceManager& operator=(const DeviceManager&) = delete;
+ DeviceManager() = delete;
+
+public:
+ /**
+ * Registers a device factory.
+ *
+ * This method is mostly used by plugin developers to add their device implementation
+ * for general use by the library end users.
+ * @param name A representative name for the device.
+ * @param factory The factory that creates the device.
+ */
+ static void registerDevice(std::string name, std::shared_ptr<IDeviceFactory> factory);
+
+ /**
+ * Returns the factory for a specific device.
+ * @param name The representative name of the device.
+ * @return The factory if it was found, or nullptr otherwise.
+ */
+ static std::shared_ptr<IDeviceFactory> getDeviceFactory(std::string name);
+
+ /**
+ * Returns the default device based on the priorities of the registered factories.
+ * @return The default device or nullptr if no factory has been registered.
+ */
+ static std::shared_ptr<IDeviceFactory> getDefaultDeviceFactory();
+
+
+ /**
+ * Sets a device that should be handled by the manager.
+ *
+ * If a device is currently being handled it will be released.
+ * @param device The device the manager should take care of.
+ */
+ static void setDevice(std::shared_ptr<IDevice> device);
+
+ /**
+ * Opens a device which will then be handled by the manager.
+ *
+ * If a device is currently being handled it will be released.
+ * @param name The representative name of the device.
+ */
+ static void openDevice(std::string name);
+
+ /**
+ * Opens the default device which will then be handled by the manager.
+ *
+ * The device to open is selected based on the priority of the registered factories.
+ * If a device is currently being handled it will be released.
+ */
+ static void openDefaultDevice();
+
+ /**
+ * Releases the currently handled device.
+ */
+ static void releaseDevice();
+
+ /**
+ * Returns the currently handled device.
+ * @return The handled device or nullptr if no device has been registered.
+ */
+ static std::shared_ptr<IDevice> getDevice();
+
+ /**
+ * Returns the currently handled 3D device.
+ * @return The handled device or nullptr if no device has been registered
+ * or the registered device is not an I3DDevice.
+ */
+ static std::shared_ptr<I3DDevice> get3DDevice();
+
+ /**
+ * Returns a list of available devices.
+ * @return A list of strings with the names of available devices.
+ */
+ static std::vector<std::string> getAvailableDeviceNames();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/I3DDevice.h b/extern/audaspace/include/devices/I3DDevice.h
new file mode 100644
index 00000000000..f49bbcbb07e
--- /dev/null
+++ b/extern/audaspace/include/devices/I3DDevice.h
@@ -0,0 +1,142 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file I3DDevice.h
+ * @ingroup devices
+ * Defines the I3DDevice interface as well as the different distance models.
+ */
+
+#include "util/Math3D.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * Possible distance models for the 3D device.
+ *
+ * The distance models supported are the same as documented in the [OpenAL Specification](http://openal.org/).
+ */
+enum DistanceModel
+{
+ DISTANCE_MODEL_INVALID = 0,
+ DISTANCE_MODEL_INVERSE,
+ DISTANCE_MODEL_INVERSE_CLAMPED,
+ DISTANCE_MODEL_LINEAR,
+ DISTANCE_MODEL_LINEAR_CLAMPED,
+ DISTANCE_MODEL_EXPONENT,
+ DISTANCE_MODEL_EXPONENT_CLAMPED
+};
+
+/**
+ * @interface I3DDevice
+ * The I3DDevice interface represents an output device for 3D sound.
+ *
+ * The interface has been modelled after the OpenAL 1.1 API,
+ * see the [OpenAL Specification](http://openal.org/) for lots of details.
+ */
+class AUD_API I3DDevice
+{
+public:
+ /**
+ * Retrieves the listener location.
+ * \return The listener location.
+ */
+ virtual Vector3 getListenerLocation() const=0;
+
+ /**
+ * Sets the listener location.
+ * \param location The new location.
+ * \note The location is not updated with the velocity and
+ * remains constant until the next call of this method.
+ */
+ virtual void setListenerLocation(const Vector3& location)=0;
+
+ /**
+ * Retrieves the listener velocity.
+ * \return The listener velocity.
+ */
+ virtual Vector3 getListenerVelocity() const=0;
+
+ /**
+ * Sets the listener velocity.
+ * \param velocity The new velocity.
+ * \note This velocity does not change the position of the listener
+ * over time, it is simply used for the calculation of the doppler effect.
+ */
+ virtual void setListenerVelocity(const Vector3& velocity)=0;
+
+ /**
+ * Retrieves the listener orientation.
+ * \return The listener orientation as quaternion.
+ */
+ virtual Quaternion getListenerOrientation() const=0;
+
+ /**
+ * Sets the listener orientation.
+ * \param orientation The new orientation as quaternion.
+ * \note The coordinate system used is right handed and the listener
+ * by default is oriented looking in the negative z direction with the
+ * positive y axis as up direction.
+ */
+ virtual void setListenerOrientation(const Quaternion& orientation)=0;
+
+
+ /**
+ * Retrieves the speed of sound.
+ * This value is needed for doppler effect calculation.
+ * \return The speed of sound.
+ */
+ virtual float getSpeedOfSound() const=0;
+
+ /**
+ * Sets the speed of sound.
+ * This value is needed for doppler effect calculation.
+ * \param speed The new speed of sound.
+ */
+ virtual void setSpeedOfSound(float speed)=0;
+
+ /**
+ * 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.
+ */
+ virtual float getDopplerFactor() const=0;
+
+ /**
+ * 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.
+ */
+ virtual void setDopplerFactor(float factor)=0;
+
+ /**
+ * Retrieves the distance model.
+ * \return The distance model.
+ */
+ virtual DistanceModel getDistanceModel() const=0;
+
+ /**
+ * Sets the distance model.
+ * \param model distance model.
+ */
+ virtual void setDistanceModel(DistanceModel model)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_I3DHandle.h b/extern/audaspace/include/devices/I3DHandle.h
index 69ca985630a..2ff29f9bd21 100644
--- a/intern/audaspace/intern/AUD_I3DHandle.h
+++ b/extern/audaspace/include/devices/I3DHandle.h
@@ -1,87 +1,94 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_I3DHandle.h
- * \ingroup audaspaceintern
- */
+#pragma once
+/**
+ * @file I3DHandle.h
+ * @ingroup devices
+ * The I3DHandle interface.
+ */
-#ifndef __AUD_I3DHANDLE_H__
-#define __AUD_I3DHANDLE_H__
+#include "util/Math3D.h"
-#include "AUD_Space.h"
-#include "AUD_3DMath.h"
+AUD_NAMESPACE_BEGIN
/**
- * This class represents a playback handle for 3D sources.
+ * @interface I3DHandle
+ * The I3DHandle interface represents a playback handle for 3D sources.
+ * If the playback IDevice class also implements the I3DDevice interface
+ * then all playback IHandle instances also implement this interface.
+ *
+ * The interface has been modelled after the OpenAL 1.1 API,
+ * see the [OpenAL Specification](http://openal.org/) for lots of details.
*/
-class AUD_I3DHandle
+class AUD_API I3DHandle
{
public:
/**
* Destroys the handle.
*/
- virtual ~AUD_I3DHandle() {}
+ virtual ~I3DHandle() {}
/**
- * Retrieves the location of a source.
+ * Retrieves the location of the source.
* \return The location.
*/
- virtual AUD_Vector3 getSourceLocation()=0;
+ virtual Vector3 getLocation()=0;
/**
- * Sets the location of a source.
+ * Sets the location of the source.
* \param location The new location.
* \return Whether the action succeeded.
+ * \note The location is not updated with the velocity and
+ * remains constant until the next call of this method.
*/
- virtual bool setSourceLocation(const AUD_Vector3& location)=0;
+ virtual bool setLocation(const Vector3& location)=0;
/**
- * Retrieves the velocity of a source.
+ * Retrieves the velocity of the source.
* \return The velocity.
*/
- virtual AUD_Vector3 getSourceVelocity()=0;
+ virtual Vector3 getVelocity()=0;
/**
- * Sets the velocity of a source.
+ * Sets the velocity of the source.
* \param velocity The new velocity.
* \return Whether the action succeeded.
+ * \note This velocity does not change the position of the listener
+ * over time, it is simply used for the calculation of the doppler effect.
*/
- virtual bool setSourceVelocity(const AUD_Vector3& velocity)=0;
+ virtual bool setVelocity(const Vector3& velocity)=0;
/**
- * Retrieves the orientation of a source.
+ * Retrieves the orientation of the source.
* \return The orientation as quaternion.
*/
- virtual AUD_Quaternion getSourceOrientation()=0;
+ virtual Quaternion getOrientation()=0;
/**
- * Sets the orientation of a source.
+ * Sets the orientation of the source.
* \param orientation The new orientation as quaternion.
* \return Whether the action succeeded.
+ * \note The coordinate system used is right handed and the source
+ * by default is oriented looking in the negative z direction with the
+ * positive y axis as up direction.
+ * \note This setting currently only affects sounds with non-default cone settings.
*/
- virtual bool setSourceOrientation(const AUD_Quaternion& orientation)=0;
+ virtual bool setOrientation(const Quaternion& orientation)=0;
/**
@@ -96,6 +103,7 @@ public:
* to the listener.
* \param relative Whether the source is relative.
* \return Whether the action succeeded.
+ * \note The default value is true as this setting is used to play sounds ordinarily without 3D.
*/
virtual bool setRelative(bool relative)=0;
@@ -170,28 +178,34 @@ public:
virtual bool setAttenuation(float factor)=0;
/**
- * Retrieves the outer angle of the cone of a source.
+ * Retrieves the outer opening angle of the cone of a source.
* \return The outer angle of the cone.
+ * \note This angle is defined in degrees.
*/
virtual float getConeAngleOuter()=0;
/**
- * Sets the outer angle of the cone of a source.
+ * Sets the outer opening angle of the cone of a source.
* \param angle The new outer angle of the cone.
* \return Whether the action succeeded.
+ * \note This angle is defined in degrees.
*/
virtual bool setConeAngleOuter(float angle)=0;
/**
- * Retrieves the inner angle of the cone of a source.
+ * Retrieves the inner opening angle of the cone of a source.
+ * The volume inside this cone is unaltered.
* \return The inner angle of the cone.
+ * \note This angle is defined in degrees.
*/
virtual float getConeAngleInner()=0;
/**
- * Sets the inner angle of the cone of a source.
+ * Sets the inner opening angle of the cone of a source.
+ * The volume inside this cone is unaltered.
* \param angle The new inner angle of the cone.
* \return Whether the action succeeded.
+ * \note This angle is defined in degrees.
*/
virtual bool setConeAngleInner(float angle)=0;
@@ -200,6 +214,7 @@ public:
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \return The outer volume of the cone.
+ * \note The general volume of the handle still applies on top of this.
*/
virtual float getConeVolumeOuter()=0;
@@ -209,8 +224,9 @@ public:
* volume and this value.
* \param volume The new outer volume of the cone.
* \return Whether the action succeeded.
+ * \note The general volume of the handle still applies on top of this.
*/
virtual bool setConeVolumeOuter(float volume)=0;
};
-#endif //__AUD_I3DHANDLE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/IDevice.h b/extern/audaspace/include/devices/IDevice.h
new file mode 100644
index 00000000000..92a85d900e2
--- /dev/null
+++ b/extern/audaspace/include/devices/IDevice.h
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IDevice.h
+ * @ingroup devices
+ * The IDevice interface.
+ */
+
+#include "respec/Specification.h"
+#include "util/ILockable.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IHandle;
+class IReader;
+class ISound;
+class ISynchronizer;
+
+/**
+ * @interface IDevice
+ * The IDevice interface represents an output device for sound sources.
+ * Output devices may be several backends such as plattform independand like
+ * SDL or OpenAL or plattform specific like ALSA, but they may also be
+ * files, RAM buffers or other types of streams.
+ * \warning Thread safety must be insured so that no reader is beeing called
+ * twice at the same time.
+ */
+class IDevice : public ILockable
+{
+public:
+ /**
+ * Destroys the device.
+ */
+ virtual ~IDevice() {}
+
+ /**
+ * Returns the specification of the device.
+ */
+ virtual DeviceSpecs getSpecs() const=0;
+
+ /**
+ * Plays a sound source.
+ * \param reader The reader to play.
+ * \param keep When keep is true the sound source will not be deleted but
+ * set to paused when its end has been reached.
+ * \return Returns a handle with which the playback can be controlled.
+ * This is nullptr if the sound couldn't be played back.
+ * \exception Exception Thrown if there's an unexpected (from the
+ * device side) error during creation of the reader.
+ */
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<IReader> reader, bool keep = false)=0;
+
+ /**
+ * Plays a sound source.
+ * \param sound The sound to create the reader for the sound source.
+ * \param keep When keep is true the sound source will not be deleted but
+ * set to paused when its end has been reached.
+ * \return Returns a handle with which the playback can be controlled.
+ * This is nullptr if the sound couldn't be played back.
+ * \exception Exception Thrown if there's an unexpected (from the
+ * device side) error during creation of the reader.
+ */
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, bool keep = false)=0;
+
+ /**
+ * Stops all playing sounds.
+ */
+ virtual void stopAll()=0;
+
+ /**
+ * Locks the device.
+ * Used to make sure that between lock and unlock, no buffers are read, so
+ * that it is possible to start, resume, pause, stop or seek several
+ * playback handles simultaneously.
+ * \warning Make sure the locking time is as small as possible to avoid
+ * playback delays that result in unexpected noise and cracks.
+ */
+ virtual void lock()=0;
+
+ /**
+ * Unlocks the previously locked device.
+ */
+ virtual void unlock()=0;
+
+ /**
+ * Retrieves the overall device volume.
+ * \return The overall device volume.
+ */
+ virtual float getVolume() const=0;
+
+ /**
+ * Sets the overall device volume.
+ * \param volume The overall device volume.
+ */
+ virtual void setVolume(float volume)=0;
+
+ /**
+ * Retrieves the synchronizer for this device, which enables accurate synchronization
+ * between audio playback and video playback for example.
+ * @return The synchronizer which will be the DefaultSynchronizer if synchonization is not supported.
+ */
+ virtual ISynchronizer* getSynchronizer()=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/IDeviceFactory.h b/extern/audaspace/include/devices/IDeviceFactory.h
new file mode 100644
index 00000000000..6a0f4537b13
--- /dev/null
+++ b/extern/audaspace/include/devices/IDeviceFactory.h
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IDeviceFactory.h
+ * @ingroup devices
+ * The IDeviceFactory interface.
+ */
+
+#include "respec/Specification.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * @interface IDeviceFactory
+ * The IDeviceFactory interface opens an output device.
+ */
+class AUD_API IDeviceFactory
+{
+public:
+ /**
+ * Opens an audio device for playback.
+ * \exception Exception Thrown if the audio device cannot be opened.
+ */
+ virtual std::shared_ptr<IDevice> openDevice()=0;
+
+ /**
+ * Returns the priority of the device to be the default device for a system.
+ * The higher the priority the more likely it is for this device to be used as the default device.
+ * \return Priority to be the default device.
+ */
+ virtual int getPriority()=0;
+
+ /**
+ * Sets the wanted device specifications for opening the device.
+ * \param specs The wanted audio specification.
+ */
+ virtual void setSpecs(DeviceSpecs specs)=0;
+
+ /**
+ * Sets the size for the internal playback buffers.
+ * The bigger the buffersize, the less likely clicks happen,
+ * but the latency increases too.
+ * \param buffersize The size of the internal buffer.
+ */
+ virtual void setBufferSize(int buffersize)=0;
+
+ /**
+ * Sets a name for the device.
+ * \param name The internal name for the device.
+ */
+ virtual void setName(std::string name)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_IHandle.h b/extern/audaspace/include/devices/IHandle.h
index c80fb4027b8..3f42fc33c3a 100644
--- a/intern/audaspace/intern/AUD_IHandle.h
+++ b/extern/audaspace/include/devices/IHandle.h
@@ -1,49 +1,57 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
+
+#pragma once
-/** \file audaspace/intern/AUD_IHandle.h
- * \ingroup audaspaceintern
+/**
+ * @file IHandle.h
+ * @ingroup devices
+ * Defines the IHandle interface as well as possible states of the handle.
*/
-#ifndef __AUD_IHANDLE_H__
-#define __AUD_IHANDLE_H__
+#include "Audaspace.h"
-//#include "AUD_Space.h"
-//#include "AUD_Reference.h"
+AUD_NAMESPACE_BEGIN
+/// Status of a playback handle.
+enum Status
+{
+ STATUS_INVALID = 0, /// Invalid handle. Maybe due to stopping.
+ STATUS_PLAYING, /// Sound is playing.
+ STATUS_PAUSED, /// Sound is being paused.
+ STATUS_STOPPED /// Sound is stopped but kept in the device.
+};
+
+/**
+ * The stopCallback is called when a handle reaches the end of the stream and
+ * thus gets stopped. A user defined pointer is supplied to the callback.
+ */
typedef void (*stopCallback)(void*);
/**
- * This class represents a playback handles for specific devices.
+ * @interface IHandle
+ * The IHandle interface represents a playback handles of a specific device.
*/
-class AUD_IHandle
+class AUD_API IHandle
{
public:
/**
* Destroys the handle.
*/
- virtual ~AUD_IHandle() {}
+ virtual ~IHandle() {}
/**
* Pauses a played back sound.
@@ -109,15 +117,15 @@ public:
/**
* Returns the status of a played back sound.
* \return
- * - AUD_STATUS_INVALID if the sound has stopped or the handle is
+ * - STATUS_INVALID if the sound has stopped or the handle is
*. invalid
- * - AUD_STATUS_PLAYING if the sound is currently played back.
- * - AUD_STATUS_PAUSED if the sound is currently paused.
- * - AUD_STATUS_STOPPED if the sound finished playing and is still
+ * - STATUS_PLAYING if the sound is currently played back.
+ * - STATUS_PAUSED if the sound is currently paused.
+ * - STATUS_STOPPED if the sound finished playing and is still
* kept in the device.
- * \see AUD_Status
+ * \see Status
*/
- virtual AUD_Status getStatus()=0;
+ virtual Status getStatus()=0;
/**
* Retrieves the volume of a playing sound.
@@ -178,4 +186,4 @@ public:
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0)=0;
};
-#endif //AUD_IHandle
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/ISynchronizer.h b/extern/audaspace/include/devices/ISynchronizer.h
new file mode 100644
index 00000000000..6f14de59565
--- /dev/null
+++ b/extern/audaspace/include/devices/ISynchronizer.h
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ISynchronizer.h
+ * @ingroup devices
+ * The ISynchronizer interface.
+ */
+
+#include "Audaspace.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IHandle;
+
+/**
+ * @interface ISynchronizer
+ * This class enables global synchronization of several audio applications if supported.
+ * JACK for example supports synchronization through JACK Transport.
+ */
+class AUD_API ISynchronizer
+{
+public:
+ /**
+ * Destroys the synchronizer.
+ */
+ virtual ~ISynchronizer() {}
+
+ /**
+ * The syncFunction is called when a synchronization event happens.
+ * The function awaits three parameters. The first one is a user defined
+ * pointer, the second informs about whether playback is on and the third
+ * is the current playback time in seconds.
+ */
+ typedef void (*syncFunction)(void*, int, float);
+
+ /**
+ * Sets the playback position of a handle and the synchronizer to a specific time.
+ * @param handle The handle that should be synchronized/seeked.
+ * @param time The absolute time to synchronize to.
+ */
+ virtual void seek(std::shared_ptr<IHandle> handle, float time) = 0;
+
+ /**
+ * Retrieves the position of the synchronizer.
+ * @param handle The handle which is synchronized.
+ * @return The position in seconds.
+ */
+ virtual float getPosition(std::shared_ptr<IHandle> handle) = 0;
+
+ /**
+ * Starts the synchronizer playback.
+ */
+ virtual void play() = 0;
+
+ /**
+ * Stops the synchronizer playback.
+ */
+ virtual void stop() = 0;
+
+ /**
+ * Sets the callback function that is called when a synchronization event happens.
+ * @param function The function to be called.
+ * @param data User data to be passed to the callback.
+ */
+ virtual void setSyncCallback(syncFunction function, void* data) = 0;
+
+ /**
+ * Retrieves whether the synchronizer is playing back.
+ * @return Whether the synchronizer plays back.
+ */
+ virtual int isPlaying() = 0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/NULLDevice.h b/extern/audaspace/include/devices/NULLDevice.h
new file mode 100644
index 00000000000..76211a799b9
--- /dev/null
+++ b/extern/audaspace/include/devices/NULLDevice.h
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file NULLDevice.h
+ * @ingroup devices
+ * The NULLDevice class.
+ */
+
+#include "devices/IDevice.h"
+#include "devices/IHandle.h"
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+
+/**
+ * This device plays nothing.
+ * It is similar to the linux device /dev/null.
+ */
+class AUD_API NULLDevice : public IDevice
+{
+private:
+ class AUD_LOCAL NULLHandle : public IHandle
+ {
+ private:
+ // delete copy constructor and operator=
+ NULLHandle(const NULLHandle&) = delete;
+ NULLHandle& operator=(const NULLHandle&) = delete;
+
+ public:
+
+ NULLHandle();
+
+ virtual ~NULLHandle() {}
+ virtual bool pause();
+ virtual bool resume();
+ virtual bool stop();
+ virtual bool getKeep();
+ virtual bool setKeep(bool keep);
+ virtual bool seek(float position);
+ virtual float getPosition();
+ virtual Status getStatus();
+ virtual float getVolume();
+ virtual bool setVolume(float volume);
+ virtual float getPitch();
+ virtual bool setPitch(float pitch);
+ virtual int getLoopCount();
+ virtual bool setLoopCount(int count);
+ virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
+ };
+
+ // delete copy constructor and operator=
+ NULLDevice(const NULLDevice&) = delete;
+ NULLDevice& operator=(const NULLDevice&) = delete;
+
+public:
+ /**
+ * Creates a new NULLDevice.
+ */
+ NULLDevice();
+
+ virtual ~NULLDevice();
+
+ virtual DeviceSpecs getSpecs() const;
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<IReader> reader, bool keep = false);
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, bool keep = false);
+ virtual void stopAll();
+ virtual void lock();
+ virtual void unlock();
+ virtual float getVolume() const;
+ virtual void setVolume(float volume);
+ virtual ISynchronizer* getSynchronizer();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/devices/ReadDevice.h b/extern/audaspace/include/devices/ReadDevice.h
new file mode 100644
index 00000000000..b56bd8ce5c4
--- /dev/null
+++ b/extern/audaspace/include/devices/ReadDevice.h
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ReadDevice.h
+ * @ingroup devices
+ * The ReadDevice class.
+ */
+
+#include "devices/SoftwareDevice.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This device enables to let the user read raw data out of it.
+ */
+class AUD_API ReadDevice : public SoftwareDevice
+{
+private:
+ /**
+ * Whether the device is currently playing back.
+ */
+ bool m_playing;
+
+ // delete copy constructor and operator=
+ ReadDevice(const ReadDevice&) = delete;
+ ReadDevice& operator=(const ReadDevice&) = delete;
+
+protected:
+ virtual void AUD_LOCAL playing(bool playing);
+
+public:
+ /**
+ * Creates a new read device.
+ * \param specs The wanted audio specification.
+ */
+ ReadDevice(DeviceSpecs specs);
+
+ /**
+ * Creates a new read device.
+ * \param specs The wanted audio specification.
+ */
+ ReadDevice(Specs specs);
+
+ /**
+ * Closes the device.
+ */
+ virtual ~ReadDevice();
+
+ /**
+ * Reads the next bytes into the supplied buffer.
+ * \param buffer The target buffer.
+ * \param length The length in samples to be filled.
+ * \return True if the reading succeeded, false if there are no sounds
+ * played back currently, in that case the buffer is filled with
+ * silence.
+ */
+ bool read(data_t* buffer, int length);
+
+ /**
+ * Changes the output specification.
+ * \param specs The new audio data specification.
+ */
+ void changeSpecs(Specs specs);
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/extern/audaspace/include/devices/SoftwareDevice.h
index 54e49c87b27..8f3846394c6 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/extern/audaspace/include/devices/SoftwareDevice.h
@@ -1,74 +1,76 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
+
+#pragma once
-/** \file audaspace/intern/AUD_SoftwareDevice.h
- * \ingroup audaspaceintern
+/**
+ * @file SoftwareDevice.h
+ * @ingroup devices
+ * The SoftwareDevice class.
*/
+#include "devices/IDevice.h"
+#include "devices/IHandle.h"
+#include "devices/I3DDevice.h"
+#include "devices/I3DHandle.h"
+#include "devices/DefaultSynchronizer.h"
+#include "util/Buffer.h"
-#ifndef __AUD_SOFTWAREDEVICE_H__
-#define __AUD_SOFTWAREDEVICE_H__
+#include <list>
+#include <mutex>
-#include "AUD_IDevice.h"
-#include "AUD_IHandle.h"
-#include "AUD_I3DDevice.h"
-#include "AUD_I3DHandle.h"
-#include "AUD_Mixer.h"
-#include "AUD_Buffer.h"
-#include "AUD_PitchReader.h"
-#include "AUD_ResampleReader.h"
-#include "AUD_ChannelMapperReader.h"
+AUD_NAMESPACE_BEGIN
-#include <list>
-#include <pthread.h>
+class Mixer;
+class PitchReader;
+class ResampleReader;
+class ChannelMapperReader;
/**
- * This device plays is a generic device with software mixing.
+ * The software device is a generic device with software mixing.
+ * It is a base class for all software mixing classes.
* Classes implementing this have to:
* - Implement the playing function.
* - Prepare the m_specs, m_mixer variables.
* - Call the create and destroy functions.
* - Call the mix function to retrieve their audio data.
*/
-class AUD_SoftwareDevice : public AUD_IDevice, public AUD_I3DDevice
+class AUD_API SoftwareDevice : public IDevice, public I3DDevice
{
protected:
/// Saves the data for playback.
- class AUD_SoftwareHandle : public AUD_IHandle, public AUD_I3DHandle
+ class AUD_API SoftwareHandle : public IHandle, public I3DHandle
{
+ private:
+ // delete copy constructor and operator=
+ SoftwareHandle(const SoftwareHandle&) = delete;
+ SoftwareHandle& operator=(const SoftwareHandle&) = delete;
+
public:
/// The reader source.
- boost::shared_ptr<AUD_IReader> m_reader;
+ std::shared_ptr<IReader> m_reader;
/// The pitch reader in between.
- boost::shared_ptr<AUD_PitchReader> m_pitch;
+ std::shared_ptr<PitchReader> m_pitch;
/// The resample reader in between.
- boost::shared_ptr<AUD_ResampleReader> m_resampler;
+ std::shared_ptr<ResampleReader> m_resampler;
/// The channel mapper reader in between.
- boost::shared_ptr<AUD_ChannelMapperReader> m_mapper;
+ std::shared_ptr<ChannelMapperReader> m_mapper;
/// Whether to keep the source if end of it is reached.
bool m_keep;
@@ -84,19 +86,21 @@ protected:
/// The calculated final volume of the source.
float m_volume;
+
+ /// The previous calculated final volume of the source.
float m_old_volume;
/// The loop count of the source.
int m_loopcount;
/// Location in 3D Space.
- AUD_Vector3 m_location;
+ Vector3 m_location;
/// Velocity in 3D Space.
- AUD_Vector3 m_velocity;
+ Vector3 m_velocity;
/// Orientation in 3D Space.
- AUD_Quaternion m_orientation;
+ Quaternion m_orientation;
/// Whether the position to the listener is relative or absolute
bool m_relative;
@@ -135,15 +139,19 @@ protected:
void* m_stop_data;
/// Current status of the handle
- AUD_Status m_status;
+ Status m_status;
/// Own device.
- AUD_SoftwareDevice* m_device;
+ SoftwareDevice* m_device;
+ /**
+ * This method is for internal use only.
+ * @param keep Whether the sound should be marked stopped or paused.
+ * @return Whether the action succeeded.
+ */
bool pause(bool keep);
public:
-
/**
* Creates a new software handle.
* \param device The device this handle is from.
@@ -153,7 +161,7 @@ protected:
* \param mapper The channel mapping reader.
* \param keep Whether to keep the handle when the sound ends.
*/
- 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);
+ SoftwareHandle(SoftwareDevice* device, std::shared_ptr<IReader> reader, std::shared_ptr<PitchReader> pitch, std::shared_ptr<ResampleReader> resampler, std::shared_ptr<ChannelMapperReader> mapper, bool keep);
/**
* Updates the handle's playback parameters.
@@ -162,11 +170,11 @@ protected:
/**
* Sets the audio output specification of the readers.
- * \param sepcs The output specification.
+ * \param specs The output specification.
*/
- void setSpecs(AUD_Specs specs);
+ void setSpecs(Specs specs);
- virtual ~AUD_SoftwareHandle() {}
+ virtual ~SoftwareHandle() {}
virtual bool pause();
virtual bool resume();
virtual bool stop();
@@ -174,7 +182,7 @@ protected:
virtual bool setKeep(bool keep);
virtual bool seek(float position);
virtual float getPosition();
- virtual AUD_Status getStatus();
+ virtual Status getStatus();
virtual float getVolume();
virtual bool setVolume(float volume);
virtual float getPitch();
@@ -183,12 +191,12 @@ protected:
virtual bool setLoopCount(int count);
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
- virtual AUD_Vector3 getSourceLocation();
- virtual bool setSourceLocation(const AUD_Vector3& location);
- virtual AUD_Vector3 getSourceVelocity();
- virtual bool setSourceVelocity(const AUD_Vector3& velocity);
- virtual AUD_Quaternion getSourceOrientation();
- virtual bool setSourceOrientation(const AUD_Quaternion& orientation);
+ virtual Vector3 getLocation();
+ virtual bool setLocation(const Vector3& location);
+ virtual Vector3 getVelocity();
+ virtual bool setVelocity(const Vector3& velocity);
+ virtual Quaternion getOrientation();
+ virtual bool setOrientation(const Quaternion& orientation);
virtual bool isRelative();
virtual bool setRelative(bool relative);
virtual float getVolumeMaximum();
@@ -209,17 +217,15 @@ protected:
virtual bool setConeVolumeOuter(float volume);
};
- typedef std::list<boost::shared_ptr<AUD_SoftwareHandle> >::iterator AUD_HandleIterator;
-
/**
* The specification of the device.
*/
- AUD_DeviceSpecs m_specs;
+ DeviceSpecs m_specs;
/**
* The mixer.
*/
- boost::shared_ptr<AUD_Mixer> m_mixer;
+ std::shared_ptr<Mixer> m_mixer;
/**
* Whether to do high or low quality resampling.
@@ -251,25 +257,31 @@ protected:
/**
* Sets the audio output specification of the device.
- * \param sepcs The output specification.
+ * \param specs The output specification.
+ */
+ void setSpecs(Specs specs);
+
+ /**
+ * Empty default constructor. To setup the device call the function create()
+ * and to uninitialize call destroy().
*/
- void setSpecs(AUD_Specs specs);
+ SoftwareDevice();
private:
/**
* The reading buffer.
*/
- AUD_Buffer m_buffer;
+ Buffer m_buffer;
/**
* The list of sounds that are currently playing.
*/
- std::list<boost::shared_ptr<AUD_SoftwareHandle> > m_playingSounds;
+ std::list<std::shared_ptr<SoftwareHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<boost::shared_ptr<AUD_SoftwareHandle> > m_pausedSounds;
+ std::list<std::shared_ptr<SoftwareHandle> > m_pausedSounds;
/**
* Whether there is currently playback.
@@ -279,7 +291,7 @@ private:
/**
* The mutex for locking.
*/
- pthread_mutex_t m_mutex;
+ std::recursive_mutex m_mutex;
/**
* The overall volume of the device.
@@ -287,13 +299,13 @@ private:
float m_volume;
/// Listener location.
- AUD_Vector3 m_location;
+ Vector3 m_location;
/// Listener velocity.
- AUD_Vector3 m_velocity;
+ Vector3 m_velocity;
/// Listener orientation.
- AUD_Quaternion m_orientation;
+ Quaternion m_orientation;
/// Speed of Sound.
float m_speed_of_sound;
@@ -302,11 +314,18 @@ private:
float m_doppler_factor;
/// Distance model.
- AUD_DistanceModel m_distance_model;
+ DistanceModel m_distance_model;
/// Rendering flags
int m_flags;
+ /// Synchronizer.
+ DefaultSynchronizer m_synchronizer;
+
+ // delete copy constructor and operator=
+ SoftwareDevice(const SoftwareDevice&) = delete;
+ SoftwareDevice& operator=(const SoftwareDevice&) = delete;
+
public:
/**
@@ -314,7 +333,7 @@ public:
* \param handle The handle to set the panning from.
* \param pan The new panning value, should be in the range [-2, 2].
*/
- static void setPanning(AUD_IHandle* handle, float pan);
+ static void setPanning(IHandle* handle, float pan);
/**
* Sets the resampling quality.
@@ -322,27 +341,28 @@ public:
*/
void setQuality(bool quality);
- virtual AUD_DeviceSpecs getSpecs() const;
- 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 DeviceSpecs getSpecs() const;
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<IReader> reader, bool keep = false);
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, bool keep = false);
virtual void stopAll();
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
-
- virtual AUD_Vector3 getListenerLocation() const;
- virtual void setListenerLocation(const AUD_Vector3& location);
- virtual AUD_Vector3 getListenerVelocity() const;
- virtual void setListenerVelocity(const AUD_Vector3& velocity);
- virtual AUD_Quaternion getListenerOrientation() const;
- virtual void setListenerOrientation(const AUD_Quaternion& orientation);
+ virtual ISynchronizer* getSynchronizer();
+
+ virtual Vector3 getListenerLocation() const;
+ virtual void setListenerLocation(const Vector3& location);
+ virtual Vector3 getListenerVelocity() const;
+ virtual void setListenerVelocity(const Vector3& velocity);
+ virtual Quaternion getListenerOrientation() const;
+ virtual void setListenerOrientation(const Quaternion& orientation);
virtual float getSpeedOfSound() const;
virtual void setSpeedOfSound(float speed);
virtual float getDopplerFactor() const;
virtual void setDopplerFactor(float factor);
- virtual AUD_DistanceModel getDistanceModel() const;
- virtual void setDistanceModel(AUD_DistanceModel model);
+ virtual DistanceModel getDistanceModel() const;
+ virtual void setDistanceModel(DistanceModel model);
};
-#endif //__AUD_SOFTWAREDEVICE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/File.h b/extern/audaspace/include/file/File.h
new file mode 100644
index 00000000000..24745a757e8
--- /dev/null
+++ b/extern/audaspace/include/file/File.h
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file File.h
+ * @ingroup file
+ * The File class.
+ */
+
+#include "ISound.h"
+
+#include <string>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class Buffer;
+
+/**
+ * The File sound tries to read a sound file via all available file inputs
+ * that have been registered in the FileManager class.
+ */
+class AUD_API File : public ISound
+{
+private:
+ /**
+ * The filename of the sound source file.
+ */
+ std::string m_filename;
+
+ /**
+ * The buffer to read from.
+ */
+ std::shared_ptr<Buffer> m_buffer;
+
+ // delete copy constructor and operator=
+ File(const File&) = delete;
+ File& operator=(const File&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * The file is read from the file system using the given path.
+ * \param filename The sound file path.
+ */
+ File(std::string filename);
+
+ /**
+ * Creates a new sound.
+ * The file is read from memory using the supplied buffer.
+ * \param buffer The buffer to read from.
+ * \param size The size of the buffer.
+ */
+ File(const data_t* buffer, int size);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/FileManager.h b/extern/audaspace/include/file/FileManager.h
new file mode 100644
index 00000000000..03943ea8ae0
--- /dev/null
+++ b/extern/audaspace/include/file/FileManager.h
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file FileManager.h
+ * @ingroup file
+ * The FileManager class.
+ */
+
+#include "respec/Specification.h"
+#include "IWriter.h"
+
+#include <list>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IFileInput;
+class IFileOutput;
+class IReader;
+class Buffer;
+
+/**
+ * The FileManager manages all file input and output plugins.
+ */
+class AUD_API FileManager
+{
+private:
+ static std::list<std::shared_ptr<IFileInput>>& inputs();
+ static std::list<std::shared_ptr<IFileOutput>>& outputs();
+
+ // delete copy constructor and operator=
+ FileManager(const FileManager&) = delete;
+ FileManager& operator=(const FileManager&) = delete;
+ FileManager() = delete;
+
+public:
+ /**
+ * Registers a file input used to create an IReader to read from a file.
+ * @param input The IFileInput to register.
+ */
+ static void registerInput(std::shared_ptr<IFileInput> input);
+
+ /**
+ * Registers a file output used to create an IWriter to write to a file.
+ * @param output The IFileOutput to register.
+ */
+ static void registerOutput(std::shared_ptr<IFileOutput> output);
+
+ /**
+ * Creates a file reader for the given filename if a registed IFileInput is able to read it.
+ * @param filename The path to the file.
+ * @return The reader created.
+ * @exception Exception If no file input can read the file an exception is thrown.
+ */
+ static std::shared_ptr<IReader> createReader(std::string filename);
+
+ /**
+ * Creates a file reader for the given buffer if a registed IFileInput is able to read it.
+ * @param buffer The buffer to read the file from.
+ * @return The reader created.
+ * @exception Exception If no file input can read the file an exception is thrown.
+ */
+ static std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer);
+
+ /**
+ * Creates a file writer that writes a sound to the given file path.
+ * Existing files will be overwritten.
+ * @param filename The file path to write to.
+ * @param specs The output specification.
+ * @param format The container format for the file.
+ * @param codec The codec used inside the container.
+ * @param bitrate The bitrate to write with.
+ * @return A writer that creates the file.
+ * @exception Exception If no file output can write the file with the given specification an exception is thrown.
+ */
+ static std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/FileWriter.h b/extern/audaspace/include/file/FileWriter.h
new file mode 100644
index 00000000000..dac842f2a8f
--- /dev/null
+++ b/extern/audaspace/include/file/FileWriter.h
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file FileWriter.h
+ * @ingroup file
+ * The FileWriter class.
+ */
+
+#include "respec/Specification.h"
+#include "file/IWriter.h"
+
+#include <string>
+#include <vector>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+
+/**
+ * The FileWriter class is able to create IWriter classes as well as write readers to them.
+ */
+class AUD_API FileWriter
+{
+private:
+ // hide default constructor, copy constructor and operator=
+ FileWriter() = delete;
+ FileWriter(const FileWriter&) = delete;
+ FileWriter& operator=(const FileWriter&) = delete;
+
+public:
+ /**
+ * Creates a new IWriter.
+ * \param filename The file to write to.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \return The writer to write data to.
+ */
+ static std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+
+ /**
+ * Writes a reader to a writer.
+ * \param reader The reader to read from.
+ * \param writer The writer to write to.
+ * \param length How many samples should be transferred.
+ * \param buffersize How many samples should be transferred at once.
+ */
+ static void writeReader(std::shared_ptr<IReader> reader, std::shared_ptr<IWriter> writer, unsigned int length, unsigned int buffersize);
+
+ /**
+ * Writes a reader to several writers.
+ * \param reader The reader to read from.
+ * \param writers The writers to write to.
+ * \param length How many samples should be transferred.
+ * \param buffersize How many samples should be transferred at once.
+ */
+ static void writeReader(std::shared_ptr<IReader> reader, std::vector<std::shared_ptr<IWriter> >& writers, unsigned int length, unsigned int buffersize);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/IFileInput.h b/extern/audaspace/include/file/IFileInput.h
new file mode 100644
index 00000000000..bb016a88602
--- /dev/null
+++ b/extern/audaspace/include/file/IFileInput.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IFileInput.h
+ * @ingroup file
+ * The IFileInput interface.
+ */
+
+#include "Audaspace.h"
+
+#include <memory>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+class Buffer;
+
+/**
+ * @interface IFileInput
+ * The IFileInput interface represents a file input plugin that can create file
+ * input readers from filenames or buffers.
+ */
+class AUD_API IFileInput
+{
+public:
+ /**
+ * Creates a reader for a file to be read.
+ * \param filename Path to the file to be read.
+ * \return The reader that reads the file.
+ * \exception Exception Thrown if the file specified cannot be read.
+ */
+ virtual std::shared_ptr<IReader> createReader(std::string filename)=0;
+
+ /**
+ * Creates a reader for a file to be read from memory.
+ * \param buffer The in-memory file buffer.
+ * \return The reader that reads the file.
+ * \exception Exception Thrown if the file specified cannot be read.
+ */
+ virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/IFileOutput.h b/extern/audaspace/include/file/IFileOutput.h
new file mode 100644
index 00000000000..5a6efacfe94
--- /dev/null
+++ b/extern/audaspace/include/file/IFileOutput.h
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IFileOutput.h
+ * @ingroup file
+ * The IFileOutput interface.
+ */
+
+#include "file/IWriter.h"
+#include "respec/Specification.h"
+
+#include <memory>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * @interface IFileOutput
+ * The IFileOutput interface represents a file output plugin that can write files.
+ */
+class AUD_API IFileOutput
+{
+public:
+ /**
+ * Creates a new file writer.
+ * \param filename The path to the file to be written.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \exception Exception Thrown if the file specified cannot be written.
+ */
+ virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/file/IWriter.h b/extern/audaspace/include/file/IWriter.h
new file mode 100644
index 00000000000..96decdda391
--- /dev/null
+++ b/extern/audaspace/include/file/IWriter.h
@@ -0,0 +1,89 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IWriter.h
+ * @ingroup file
+ * Defines the IWriter interface as well as Container and Codec types.
+ */
+
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/// Container formats for writers.
+enum Container
+{
+ CONTAINER_INVALID = 0,
+ CONTAINER_AC3,
+ CONTAINER_FLAC,
+ CONTAINER_MATROSKA,
+ CONTAINER_MP2,
+ CONTAINER_MP3,
+ CONTAINER_OGG,
+ CONTAINER_WAV
+};
+
+/// Audio codecs for writers.
+enum Codec
+{
+ CODEC_INVALID = 0,
+ CODEC_AAC,
+ CODEC_AC3,
+ CODEC_FLAC,
+ CODEC_MP2,
+ CODEC_MP3,
+ CODEC_PCM,
+ CODEC_VORBIS,
+ CODEC_OPUS
+};
+
+/**
+ * @interface IWriter
+ * This class represents a sound sink where audio data can be written to.
+ */
+class AUD_API IWriter
+{
+public:
+ /**
+ * Destroys the writer.
+ */
+ virtual ~IWriter() {}
+
+ /**
+ * Returns how many samples have been written so far.
+ * \return The writing position as sample count. May be negative if unknown.
+ */
+ virtual int getPosition() const=0;
+
+ /**
+ * Returns the specification of the audio data being written into the sink.
+ * \return The DeviceSpecs structure.
+ * \note Regardless of the format the input still has to be float!
+ */
+ virtual DeviceSpecs getSpecs() const=0;
+
+ /**
+ * Request to write the next length samples out into the sink.
+ * \param length The count of samples to write.
+ * \param buffer The pointer to the buffer containing the data.
+ */
+ virtual void write(unsigned int length, sample_t* buffer)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ADSR.h b/extern/audaspace/include/fx/ADSR.h
new file mode 100644
index 00000000000..c453f2477e1
--- /dev/null
+++ b/extern/audaspace/include/fx/ADSR.h
@@ -0,0 +1,121 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ADSR.h
+ * @ingroup fx
+ * The ADSR class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The ADSR effect implements the Attack-Delay-Sustain-Release behaviour of a sound.
+ */
+class AUD_API ADSR : public Effect
+{
+private:
+ /**
+ * Attack time.
+ */
+ float m_attack;
+
+ /**
+ * Decay time.
+ */
+ float m_decay;
+
+ /**
+ * Sustain level.
+ */
+ float m_sustain;
+
+ /**
+ * Release time.
+ */
+ float m_release;
+
+ // delete copy constructor and operator=
+ ADSR(const ADSR&) = delete;
+ ADSR& operator=(const ADSR&) = delete;
+
+public:
+ /**
+ * Creates a new ADSR object.
+ * @param sound The sound to apply this effect to.
+ * @param attack The attack time in seconds.
+ * @param decay The decay time in seconds.
+ * @param sustain The sustain level as linear volume.
+ * @param release The release time in seconds.
+ */
+ ADSR(std::shared_ptr<ISound> sound, float attack, float decay, float sustain, float release);
+
+ /**
+ * Returns the attack time.
+ * @return The attack time in seconds.
+ */
+ float getAttack() const;
+
+ /**
+ * Sets the attack time.
+ * @param attack The attack time in seconds.
+ */
+ void setAttack(float attack);
+
+ /**
+ * Returns the decay time.
+ * @return The decay time in seconds.
+ */
+ float getDecay() const;
+
+ /**
+ * Sets the decay time.
+ * @param decay The decay time in seconds.
+ */
+ void setDecay(float decay);
+
+ /**
+ * Returns the sustain level.
+ * @return The sustain level in linear volume.
+ */
+ float getSustain() const;
+
+ /**
+ * Sets the sustain level.
+ * @param sustain The sustain level in linear volume.
+ */
+ void setSustain(float sustain);
+
+ /**
+ * Returns the release time.
+ * @return The release time in seconds.
+ */
+ float getRelease() const;
+
+ /**
+ * Sets the release time.
+ * @param release The release time in seconds.
+ */
+ void setRelease(float release);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ADSRReader.h b/extern/audaspace/include/fx/ADSRReader.h
new file mode 100644
index 00000000000..a9ec076a1c5
--- /dev/null
+++ b/extern/audaspace/include/fx/ADSRReader.h
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ADSRReader.h
+ * @ingroup fx
+ * The ADSRReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is an ADSR filters.
+ */
+class AUD_API ADSRReader : public EffectReader
+{
+private:
+ enum ADSRState
+ {
+ ADSR_STATE_INVALID = 0, /// Invalid ADSR state or finished.
+ ADSR_STATE_ATTACK = 1, /// Initial attack state.
+ ADSR_STATE_DECAY = 2, /// Decay state.
+ ADSR_STATE_SUSTAIN = 3, /// Sustain state.
+ ADSR_STATE_RELEASE = 4 /// Release state.
+ };
+
+ /**
+ * Attack time.
+ */
+ float m_attack;
+
+ /**
+ * Decay time.
+ */
+ float m_decay;
+
+ /**
+ * Sustain level.
+ */
+ float m_sustain;
+
+ /**
+ * Release time.
+ */
+ float m_release;
+
+ /**
+ * Current state.
+ */
+ ADSRState m_state;
+
+ /**
+ * Current level.
+ */
+ float m_level;
+
+ // delete copy constructor and operator=
+ ADSRReader(const ADSRReader&) = delete;
+ ADSRReader& operator=(const ADSRReader&) = delete;
+
+ void AUD_LOCAL nextState(ADSRState state);
+
+public:
+ /**
+ * Creates a new ADSR reader.
+ * \param reader The reader to read from.
+ * \param attack The attack time in seconds.
+ * \param decay The decay time in seconds.
+ * \param sustain The sustain level, should be in range [0 - 1].
+ * \param release The release time in seconds.
+ */
+ ADSRReader(std::shared_ptr<IReader> reader, float attack, float decay, float sustain, float release);
+
+ virtual ~ADSRReader();
+
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+
+ /**
+ * Triggers the release.
+ */
+ void release();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Accumulator.h b/extern/audaspace/include/fx/Accumulator.h
new file mode 100644
index 00000000000..d0c635d663c
--- /dev/null
+++ b/extern/audaspace/include/fx/Accumulator.h
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Accumulator.h
+ * @ingroup fx
+ * The Accumulator class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+class CallbackIIRFilterReader;
+
+/**
+ * This sound creates an accumulator reader.
+ *
+ * The accumulator adds the difference at the input to the last output in case
+ * it's positive. In additive mode it additionaly adds the difference always.
+ * So in case the difference is positive, it's added twice.
+ */
+class AUD_API Accumulator : public Effect
+{
+private:
+ /**
+ * Whether the accumulator is additive.
+ */
+ const bool m_additive;
+
+ // delete copy constructor and operator=
+ Accumulator(const Accumulator&) = delete;
+ Accumulator& operator=(const Accumulator&) = delete;
+
+public:
+ /**
+ * Creates a new accumulator sound.
+ * \param sound The input sound.
+ * \param additive Whether the accumulator is additive.
+ */
+ Accumulator(std::shared_ptr<ISound> sound, bool additive = false);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * The accumulatorFilterAdditive function implements the doFilterIIR callback
+ * for the additive accumulator filter.
+ * @param reader The CallbackIIRFilterReader that executes the callback.
+ * @param useless A user defined pointer that is not needed for this filter.
+ * @return The filtered sample.
+ */
+ static sample_t AUD_LOCAL accumulatorFilterAdditive(CallbackIIRFilterReader* reader, void* useless);
+
+ /**
+ * The accumulatorFilter function implements the doFilterIIR callback
+ * for the non-additive accumulator filter.
+ * @param reader The CallbackIIRFilterReader that executes the callback.
+ * @param useless A user defined pointer that is not needed for this filter.
+ * @return The filtered sample.
+ */
+ static sample_t AUD_LOCAL accumulatorFilter(CallbackIIRFilterReader* reader, void* useless);
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h b/extern/audaspace/include/fx/BaseIIRFilterReader.h
index fe0a8efce64..193b98578de 100644
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
+++ b/extern/audaspace/include/fx/BaseIIRFilterReader.h
@@ -1,48 +1,41 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/FX/AUD_BaseIIRFilterReader.h
- * \ingroup audfx
- */
+#pragma once
+/**
+ * @file BaseIIRFilterReader.h
+ * @ingroup fx
+ * The BaseIIRFilterReader class.
+ */
-#ifndef __AUD_BASEIIRFILTERREADER_H__
-#define __AUD_BASEIIRFILTERREADER_H__
+#include "fx/EffectReader.h"
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
+AUD_NAMESPACE_BEGIN
/**
* This class is a base class for infinite impulse response filters.
*/
-class AUD_BaseIIRFilterReader : public AUD_EffectReader
+class AUD_API BaseIIRFilterReader : public EffectReader
{
private:
/**
* Specs.
*/
- AUD_Specs m_specs;
+ Specs m_specs;
/**
* Length of input samples needed.
@@ -79,9 +72,9 @@ private:
*/
int m_channel;
- // hide copy constructor and operator=
- AUD_BaseIIRFilterReader(const AUD_BaseIIRFilterReader&);
- AUD_BaseIIRFilterReader& operator=(const AUD_BaseIIRFilterReader&);
+ // delete copy constructor and operator=
+ BaseIIRFilterReader(const BaseIIRFilterReader&) = delete;
+ BaseIIRFilterReader& operator=(const BaseIIRFilterReader&) = delete;
protected:
/**
@@ -90,8 +83,13 @@ protected:
* \param in The count of past input samples needed.
* \param out The count of past output samples needed.
*/
- AUD_BaseIIRFilterReader(boost::shared_ptr<AUD_IReader> reader, int in, int out);
+ BaseIIRFilterReader(std::shared_ptr<IReader> reader, int in, int out);
+ /**
+ * Sets the length for the required input and output samples of the IIR filter.
+ * @param in The amount of past input samples needed, including the current one.
+ * @param out The amount of past output samples needed.
+ */
void setLengths(int in, int out);
public:
@@ -115,7 +113,7 @@ public:
return m_y[(m_ypos + pos + m_ylen) % m_ylen * m_specs.channels + m_channel];
}
- virtual ~AUD_BaseIIRFilterReader();
+ virtual ~BaseIIRFilterReader();
virtual void read(int& length, bool& eos, sample_t* buffer);
@@ -129,7 +127,7 @@ public:
* Notifies the filter about a sample rate change.
* \param rate The new sample rate.
*/
- virtual void sampleRateChanged(AUD_SampleRate rate);
+ virtual void sampleRateChanged(SampleRate rate);
};
-#endif //__AUD_BASEIIRFILTERREADER_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/BinauralReader.h b/extern/audaspace/include/fx/BinauralReader.h
new file mode 100644
index 00000000000..f5667a093f6
--- /dev/null
+++ b/extern/audaspace/include/fx/BinauralReader.h
@@ -0,0 +1,223 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file BinauralReader.h
+* @ingroup fx
+* The BinauralReader class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+#include "Convolver.h"
+#include "HRTF.h"
+#include "Source.h"
+#include "util/FFTPlan.h"
+#include "util/ThreadPool.h"
+
+#include <memory>
+#include <vector>
+#include <future>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a reader for a sound that can sound different depending on its realtive position with the listener.
+*/
+class AUD_API BinauralReader : public IReader
+{
+private:
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ /**
+ * The reader of the input sound.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+ /**
+ * The HRTF set.
+ */
+ std::shared_ptr<HRTF> m_hrtfs;
+
+ /**
+ * A Source object that will be used to change the source position of the sound.
+ */
+ std::shared_ptr<Source> m_source;
+
+ /**
+ * The intended azimuth.
+ */
+ float m_Azimuth;
+
+ /**
+ * The intended elevation.
+ */
+ float m_Elevation;
+
+ /**
+ * The real azimuth being used.
+ */
+ float m_RealAzimuth;
+
+ /**
+ * The real elevation being used.
+ */
+ float m_RealElevation;
+
+ /**
+ * The FFT size, given by the FFTPlan.
+ */
+ int m_N;
+
+ /**
+ * The length of the impulse response fragments, m_N/2 will be used.
+ */
+ int m_M;
+
+ /**
+ * The max length of the input slices, m_N/2 will be used.
+ */
+ int m_L;
+
+ /**
+ * The array of convolvers that will be used, one per channel.
+ */
+ std::vector<std::unique_ptr<Convolver>> m_convolvers;
+
+ /**
+ * True if a transition is happening.
+ */
+ bool m_transition;
+
+ /**
+ * The position of the current transition (decreasing)
+ */
+ int m_transPos;
+
+ /**
+ * The output buffer in which the convolved data will be written and from which the reader will read.
+ */
+ sample_t* m_outBuffer;
+
+ /**
+ * The input buffer that will hold the data to be convolved.
+ */
+ sample_t* m_inBuffer;
+
+ /**
+ * Current position in which the m_outBuffer is being read.
+ */
+ int m_outBufferPos;
+
+ /**
+ * Length of rhe m_outBuffer.
+ */
+ int m_outBufLen;
+
+ /**
+ * Effective length of rhe m_outBuffer.
+ */
+ int m_eOutBufLen;
+
+ /**
+ * Flag indicating whether the end of the sound has been reached or not.
+ */
+ bool m_eosReader;
+
+ /**
+ * Flag indicating whether the end of the extra data generated in the convolution has been reached or not.
+ */
+ bool m_eosTail;
+
+ /**
+ * A vector of buffers (one per channel) on which the audio signal will be separated per channel so it can be convolved.
+ */
+ std::vector<sample_t*> m_vecOut;
+
+ /**
+ * A shared ptr to a thread pool.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * Length of the input data to be used by the channel threads.
+ */
+ int m_lastLengthIn;
+
+ /**
+ * A vector of futures to sync tasks.
+ */
+ std::vector<std::future<int>> m_futures;
+
+ // delete copy constructor and operator=
+ BinauralReader(const BinauralReader&) = delete;
+ BinauralReader& operator=(const BinauralReader&) = delete;
+
+public:
+ /**
+ * Creates a new convolver reader.
+ * \param reader A reader of the input sound to be assigned to this reader. It must have one channel.
+ * \param hrtfs A shared pointer to an HRTF object that will be used to get a particular impulse response depending on the source.
+ * \param source A shared pointer to a Source object that will be used to change the source position of the sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to and FFT plan that will be used for convolution.
+ * \exception Exception thrown if the specs of the HRTFs and the sound don't match or if the provided HRTF object is empty.
+ */
+ BinauralReader(std::shared_ptr<IReader> reader, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+ virtual ~BinauralReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+
+private:
+ /**
+ * Joins several buffers (one per channel) into the m_outBuffer.
+ * \param start The starting position from which the m_outBuffer will be written.
+ * \param len The amout of samples that will be joined.
+ * \param nConvolvers The number of convolvers that have been used. Only use 2 or 4 as possible values.
+ If the value is 4 the result will be interpolated.
+ */
+ void joinByChannel(int start, int len, int nConvolvers);
+
+ /**
+ * Loads the m_outBuffer with data.
+ * \param nConvolvers The number of convolver objects that will be used. Only 2 or 4 should be used.
+ */
+ void loadBuffer(int nConvolvers);
+
+ /**
+ * The function that the threads will run. It will process a subset of channels.
+ * \param id An id number that will determine which subset of channels will be processed.
+ * \param input A flag that will indicate if thare is input data.
+ * -If true there is new input data.
+ * -If false there isn't new input data.
+ * \return The number of samples obtained.
+ */
+ int threadFunction(int id, bool input);
+
+ bool checkSource();
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/BinauralSound.h b/extern/audaspace/include/fx/BinauralSound.h
new file mode 100644
index 00000000000..733e111dc2b
--- /dev/null
+++ b/extern/audaspace/include/fx/BinauralSound.h
@@ -0,0 +1,119 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file BinauralSound.h
+* @ingroup fx
+* The BinauralSound class.
+*/
+
+#include "ISound.h"
+#include "HRTF.h"
+#include "Source.h"
+#include "util/ThreadPool.h"
+#include "util/FFTPlan.h"
+
+#include <memory>
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a sound that can sound different depending on its realtive position with the listener.
+*/
+class AUD_API BinauralSound : public ISound
+{
+private:
+ /**
+ * A pointer to the imput sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * A pointer to an HRTF object with a collection of impulse responses.
+ */
+ std::shared_ptr<HRTF> m_hrtfs;
+
+ /**
+ * A pointer to a Source object which represents the source of the sound.
+ */
+ std::shared_ptr<Source> m_source;
+
+ /**
+ * A shared ptr to a thread pool.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * A shared ponter to an FFT plan.
+ */
+ std::shared_ptr<FFTPlan> m_plan;
+
+ // delete copy constructor and operator=
+ BinauralSound(const BinauralSound&) = delete;
+ BinauralSound& operator=(const BinauralSound&) = delete;
+
+public:
+ /**
+ * Creates a new ConvolverSound.
+ * \param sound The sound that will be convolved. It must have only one channel.
+ * \param hrtfs The HRTF set that will be used.
+ * \param source A shared pointer to a Source object that contains the source of the sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to a FFTPlan object that will be used for convolution.
+ * \warning The same FFTPlan object must be used to construct both this and the HRTF object provided.
+ */
+ BinauralSound(std::shared_ptr<ISound> sound, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+
+ /**
+ * Creates a new BinauralSound. A default FFT plan will be created.
+ * \param sound The sound that will be convolved. Must have only one channel.
+ * \param hrtfs The HRTF set that will be used.
+ * \param source A shared pointer to a Source object that contains the source of the sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \warning To use this constructor no FFTPlan object must have been provided to the hrtfs.
+ */
+ BinauralSound(std::shared_ptr<ISound> sound, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * Retrieves the HRTF set being used.
+ * \return A shared pointer to the current HRTF object being used.
+ */
+ std::shared_ptr<HRTF> getHRTFs();
+
+ /**
+ * Changes the set of HRTFs used for convolution, it'll only affect newly created readers.
+ * \param hrtfs A shared pointer to the new HRTF object.
+ */
+ void setHRTFs(std::shared_ptr<HRTF> hrtfs);
+
+ /**
+ * Retrieves the Source object being used.
+ * \return A shared pointer to the current Source object being used.
+ */
+ std::shared_ptr<Source> getSource();
+
+ /**
+ * Changes the Source object used to change the source position of the sound.
+ * \param source A shared pointer to the new Source object.
+ */
+ void setSource(std::shared_ptr<Source> source);
+};
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/Butterworth.h b/extern/audaspace/include/fx/Butterworth.h
new file mode 100644
index 00000000000..db2ad743863
--- /dev/null
+++ b/extern/audaspace/include/fx/Butterworth.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Butterworth.h
+ * @ingroup fx
+ * The Butterworth class.
+ */
+
+#include "fx/DynamicIIRFilter.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a butterworth lowpass filter reader.
+ */
+class AUD_API Butterworth : public DynamicIIRFilter
+{
+private:
+ // delete copy constructor and operator=
+ Butterworth(const Butterworth&) = delete;
+ Butterworth& operator=(const Butterworth&) = delete;
+
+public:
+ /**
+ * Creates a new butterworth sound.
+ * \param sound The input sound.
+ * \param frequency The cutoff frequency.
+ */
+ Butterworth(std::shared_ptr<ISound> sound, float frequency);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ButterworthCalculator.h b/extern/audaspace/include/fx/ButterworthCalculator.h
new file mode 100644
index 00000000000..f4d4894c8b8
--- /dev/null
+++ b/extern/audaspace/include/fx/ButterworthCalculator.h
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ButterworthCalculator.h
+ * @ingroup fx
+ * The ButterworthCalculator class.
+ */
+
+#include "fx/IDynamicIIRFilterCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The ButterworthCalculator class calculates fourth order Butterworth low pass
+ * filter coefficients for a dynamic DynamicIIRFilter.
+ */
+class AUD_LOCAL ButterworthCalculator : public IDynamicIIRFilterCalculator
+{
+private:
+ /**
+ * The attack value in seconds.
+ */
+ const float m_frequency;
+
+ // delete copy constructor and operator=
+ ButterworthCalculator(const ButterworthCalculator&) = delete;
+ ButterworthCalculator& operator=(const ButterworthCalculator&) = delete;
+
+public:
+ /**
+ * Creates a ButterworthCalculator object.
+ * @param frequency The cutoff frequency.
+ */
+ ButterworthCalculator(float frequency);
+
+ virtual void recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/CallbackIIRFilterReader.h b/extern/audaspace/include/fx/CallbackIIRFilterReader.h
new file mode 100644
index 00000000000..f1dfab70d7f
--- /dev/null
+++ b/extern/audaspace/include/fx/CallbackIIRFilterReader.h
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file CallbackIIRFilterReader.h
+ * @ingroup fx
+ * The CallbackIIRFilterReader class.
+ */
+
+#include "fx/BaseIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+class CallbackIIRFilterReader;
+
+/**
+ * The doFilterIIR callback is executed when a new sample of a callback filter
+ * should be calculated. For sample access the CallbackIIRFilterReader is
+ * provided. Furthermore a user defined pointer is also handed to the callback.
+ */
+typedef sample_t (*doFilterIIR)(CallbackIIRFilterReader*, void*);
+
+/**
+ * The endFilterIIR callback is called when the callback filter is not needed
+ * anymore. The goal of this function should be to clean up the data behind the
+ * user supplied pointer which is handed to the callback.
+ */
+typedef void (*endFilterIIR)(void*);
+
+/**
+ * This class provides an interface for infinite impulse response filters via a
+ * callback filter function.
+ */
+class AUD_API CallbackIIRFilterReader : public BaseIIRFilterReader
+{
+private:
+ /**
+ * Filter function.
+ */
+ const doFilterIIR m_filter;
+
+ /**
+ * End filter function.
+ */
+ const endFilterIIR m_endFilter;
+
+ /**
+ * Data pointer.
+ */
+ void* m_data;
+
+ // delete copy constructor and operator=
+ CallbackIIRFilterReader(const CallbackIIRFilterReader&) = delete;
+ CallbackIIRFilterReader& operator=(const CallbackIIRFilterReader&) = delete;
+
+public:
+ /**
+ * Creates a new callback IIR filter reader.
+ * \param reader The reader to read from.
+ * \param in The count of past input samples needed.
+ * \param out The count of past output samples needed.
+ * \param doFilter The filter callback.
+ * \param endFilter The finishing callback.
+ * \param data Data pointer for the callbacks.
+ */
+ CallbackIIRFilterReader(std::shared_ptr<IReader> reader, int in, int out, doFilterIIR doFilter, endFilterIIR endFilter = 0, void* data = nullptr);
+
+ virtual ~CallbackIIRFilterReader();
+
+ virtual sample_t filter();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Convolver.h b/extern/audaspace/include/fx/Convolver.h
new file mode 100644
index 00000000000..5ce134839f6
--- /dev/null
+++ b/extern/audaspace/include/fx/Convolver.h
@@ -0,0 +1,177 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file Convolver.h
+* @ingroup fx
+* The Convolver class.
+*/
+
+#include "FFTConvolver.h"
+#include "util/ThreadPool.h"
+#include "util/FFTPlan.h"
+
+#include <memory>
+#include <vector>
+#include <mutex>
+#include <future>
+#include <atomic>
+#include <deque>
+
+AUD_NAMESPACE_BEGIN
+/**
+* This class allows to convolve a sound with a very large impulse response.
+*/
+class AUD_API Convolver
+{
+private:
+ /**
+ * The FFT size, must be at least M+L-1.
+ */
+ int m_N;
+
+ /**
+ * The length of the impulse response parts.
+ */
+ int m_M;
+
+ /**
+ * The max length of the input slices.
+ */
+ int m_L;
+
+ /**
+ * The impulse response divided in parts.
+ */
+ std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> m_irBuffers;
+
+ /**
+ * Accumulation buffers for the threads.
+ */
+ std::vector<fftwf_complex*> m_threadAccBuffers;
+
+ /**
+ * A vector of FFTConvolvers used to calculate the partial convolutions.
+ */
+ std::vector<std::unique_ptr<FFTConvolver>> m_fftConvolvers;
+
+ /**
+ * The actual number of threads being used.
+ */
+ int m_numThreads;
+
+ /**
+ * A pool of threads that will be used for convolution.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * A vector of futures used for thread sync
+ */
+ std::vector<std::future<bool>> m_futures;
+
+ /**
+ * A mutex for the sum of thread accumulators.
+ */
+ std::mutex m_sumMutex;
+
+ /**
+ * A flag to control thread execution when a reset is scheduled.
+ */
+ std::atomic_bool m_resetFlag;
+
+ /**
+ * Global accumulation buffer.
+ */
+ fftwf_complex* m_accBuffer;
+
+ /**
+ * Delay line.
+ */
+ std::deque<fftwf_complex*> m_delayLine;
+
+ /**
+ * The complete length of the impulse response.
+ */
+ int m_irLength;
+
+ /**
+ * Counter for the tail;
+ */
+ int m_tailCounter;
+
+ /**
+ * Flag end of sound;
+ */
+ bool m_eos;
+
+ // delete copy constructor and operator=
+ Convolver(const Convolver&) = delete;
+ Convolver& operator=(const Convolver&) = delete;
+
+public:
+
+ /**
+ * Creates a new FFTConvolver.
+ * \param ir A shared pointer to a vector with the data of the various impulse response parts in the frequency domain (see ImpulseResponse class for an easy way to obtain it).
+ * \param irLength The length of the full impulse response.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to a FFT plan that will be used for convolution.
+ */
+ Convolver(std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ir, int irLength, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+
+ virtual ~Convolver();
+
+ /**
+ * Convolves the data that is provided with the inpulse response.
+ * Given a plan of size N, the amount of samples convolved by one call to this method will be N/2.
+ * \param[in] inBuffer A buffer with the input data to be convolved, nullptr if the source sound has ended (the convolved sound is larger than the source sound).
+ * \param[in] outBuffer A buffer in which the convolved data will be written. Its size must be at least N/2.
+ * \param[in,out] length The number of samples you wish to obtain. If an inBuffer is provided this argument must match its length.
+ * When this method returns, the value of length represents the number of samples written into the outBuffer.
+ * \param[out] eos True if the end of the sound is reached, false otherwise.
+ */
+ void getNext(sample_t* inBuffer, sample_t* outBuffer, int& length, bool& eos);
+
+ /**
+ * Resets all the internally stored data so the convolution of a new sound can be started.
+ */
+ void reset();
+
+ /**
+ * Retrieves the current impulse response being used.
+ * \return The current impulse response.
+ */
+ std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> getImpulseResponse();
+
+ /**
+ * Changes the impulse response and resets the convolver.
+ * \param ir A shared pointer to a vector with the data of the various impulse response parts in the frequency domain (see ImpulseResponse class for an easy way to obtain it).
+ */
+ void setImpulseResponse(std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ir);
+
+private:
+
+ /**
+ * This function will be enqueued into the thread pool, and will process the input signal with a subset of the impulse response parts.
+ * \param id The id of the thread, starting with 0.
+ */
+ bool threadFunction(int id);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ConvolverReader.h b/extern/audaspace/include/fx/ConvolverReader.h
new file mode 100644
index 00000000000..2ce917daec5
--- /dev/null
+++ b/extern/audaspace/include/fx/ConvolverReader.h
@@ -0,0 +1,198 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file ConvolverReader.h
+* @ingroup fx
+* The ConvolverReader class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+#include "Convolver.h"
+#include "ImpulseResponse.h"
+#include "util/FFTPlan.h"
+#include "util/ThreadPool.h"
+
+#include <memory>
+#include <vector>
+#include <future>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a reader for a sound that can be modified depending on a given impulse response.
+*/
+class AUD_API ConvolverReader : public IReader
+{
+private:
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ /**
+ * The reader of the input sound.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+ /**
+ * The impulse response in the frequency domain.
+ */
+ std::shared_ptr<ImpulseResponse> m_ir;
+
+ /**
+ * The FFT size, given by the FFTPlan.
+ */
+ int m_N;
+
+ /**
+ * The length of the impulse response fragments, m_N/2 will be used.
+ */
+ int m_M;
+
+ /**
+ * The max length of the input slices, m_N/2 will be used.
+ */
+ int m_L;
+
+ /**
+ * The array of convolvers that will be used, one per channel.
+ */
+ std::vector<std::unique_ptr<Convolver>> m_convolvers;
+
+ /**
+ * The output buffer in which the convolved data will be written and from which the reader will read.
+ */
+ sample_t* m_outBuffer;
+
+ /**
+ * A vector of buffers (one per channel) on which the audio signal will be separated per channel so it can be convolved.
+ */
+ std::vector<sample_t*> m_vecInOut;
+
+ /**
+ * Current position in which the m_outBuffer is being read.
+ */
+ int m_outBufferPos;
+
+ /**
+ * Effective length of the m_outBuffer.
+ */
+ int m_eOutBufLen;
+
+ /**
+ * Real length of the m_outBuffer.
+ */
+ int m_outBufLen;
+
+ /**
+ * Flag indicating whether the end of the sound has been reached or not.
+ */
+ bool m_eosReader;
+
+ /**
+ * Flag indicating whether the end of the extra data generated in the convolution has been reached or not.
+ */
+ bool m_eosTail;
+
+ /**
+ * The number of channels of the sound to be convolved.
+ */
+ int m_inChannels;
+
+ /**
+ * The number of channels of the impulse response.
+ */
+ int m_irChannels;
+
+ /**
+ * The number of threads used for channels.
+ */
+ int m_nChannelThreads;
+
+ /**
+ * Length of the input data to be used by the channel threads.
+ */
+ int m_lastLengthIn;
+
+ /**
+ * A shared ptr to a thread pool.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * A vector of futures to sync tasks.
+ */
+ std::vector<std::future<int>> m_futures;
+
+ // delete copy constructor and operator=
+ ConvolverReader(const ConvolverReader&) = delete;
+ ConvolverReader& operator=(const ConvolverReader&) = delete;
+
+public:
+ /**
+ * Creates a new convolver reader.
+ * \param reader A reader of the input sound to be assigned to this reader.
+ * \param ir A shared pointer to an impulseResponse object that will be used to convolve the sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to and FFT plan that will be used for convolution.
+ * \exception Exception thrown if impulse response doesn't match the specs (number fo channels and rate) of the input reader.
+ */
+ ConvolverReader(std::shared_ptr<IReader> reader, std::shared_ptr<ImpulseResponse> ir, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+ virtual ~ConvolverReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+
+private:
+ /**
+ * Divides a sound buffer in several buffers, one per channel.
+ * \param buffer The buffer that will be divided.
+ * \param len The length of the buffer.
+ */
+ void divideByChannel(const sample_t* buffer, int len);
+
+ /**
+ * Joins several buffers (one per channel) into the m_outBuffer.
+ * \param start The starting position from which the m_outBuffer will be written.
+ * \param len The amout of samples that will be joined.
+ */
+ void joinByChannel(int start, int len);
+
+ /**
+ * Loads the m_outBuffer with data.
+ */
+ void loadBuffer();
+
+ /**
+ * The function that the threads will run. It will process a subset of channels.
+ * \param id An id number that will determine which subset of channels will be processed.
+ * \param input A flag that will indicate if thare is input data.
+ * -If true there is new input data.
+ * -If false there isn't new input data.
+ * \return The number of samples obtained.
+ */
+ int threadFunction(int id, bool input);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/ConvolverSound.h b/extern/audaspace/include/fx/ConvolverSound.h
new file mode 100644
index 00000000000..957e3b8af1c
--- /dev/null
+++ b/extern/audaspace/include/fx/ConvolverSound.h
@@ -0,0 +1,100 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file ConvolverSound.h
+* @ingroup fx
+* The ConvolverSound class.
+*/
+
+#include "ISound.h"
+#include "ImpulseResponse.h"
+#include "util/ThreadPool.h"
+#include "util/FFTPlan.h"
+
+#include <memory>
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a sound that can be modified depending on a given impulse response.
+*/
+class AUD_API ConvolverSound : public ISound
+{
+private:
+ /**
+ * A pointer to the imput sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * A pointer to the impulse response.
+ */
+ std::shared_ptr<ImpulseResponse> m_impulseResponse;
+
+ /**
+ * A shared ptr to a thread pool.
+ */
+ std::shared_ptr<ThreadPool> m_threadPool;
+
+ /**
+ * A shared ponter to an FFT plan.
+ */
+ std::shared_ptr<FFTPlan> m_plan;
+
+ // delete copy constructor and operator=
+ ConvolverSound(const ConvolverSound&) = delete;
+ ConvolverSound& operator=(const ConvolverSound&) = delete;
+
+public:
+ /**
+ * Creates a new ConvolverSound.
+ * \param sound The sound that will be convolved.
+ * \param impulseResponse The impulse response sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \param plan A shared pointer to a FFTPlan object that will be used for convolution.
+ * \warning The same FFTPlan object must be used to construct both this and the ImpulseResponse object provided.
+ */
+ ConvolverSound(std::shared_ptr<ISound> sound, std::shared_ptr<ImpulseResponse> impulseResponse, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan);
+
+ /**
+ * Creates a new ConvolverSound. A default FFT plan will be created.
+ * \param sound The sound that will be convolved.
+ * \param impulseResponse The impulse response sound.
+ * \param threadPool A shared pointer to a ThreadPool object with 1 or more threads.
+ * \warning To use this constructor no FFTPlan object must have been provided to the inpulseResponse.
+ */
+ ConvolverSound(std::shared_ptr<ISound> sound, std::shared_ptr<ImpulseResponse> impulseResponse, std::shared_ptr<ThreadPool> threadPool);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * Retrieves the impulse response sound being used.
+ * \return A shared pointer to the current impulse response being used.
+ */
+ std::shared_ptr<ImpulseResponse> getImpulseResponse();
+
+ /**
+ * Changes the inpulse response used for convolution, it'll only affect newly created readers.
+ * \param impulseResponse A shared pointer to the new impulse response sound.
+ */
+ void setImpulseResponse(std::shared_ptr<ImpulseResponse> impulseResponse);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/Delay.h b/extern/audaspace/include/fx/Delay.h
new file mode 100644
index 00000000000..d6ab93ca351
--- /dev/null
+++ b/extern/audaspace/include/fx/Delay.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Delay.h
+ * @ingroup fx
+ * The Delay class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound plays another sound delayed.
+ */
+class AUD_API Delay : public Effect
+{
+private:
+ /**
+ * The delay in samples.
+ */
+ const float m_delay;
+
+ // delete copy constructor and operator=
+ Delay(const Delay&) = delete;
+ Delay& operator=(const Delay&) = delete;
+
+public:
+ /**
+ * Creates a new delay sound.
+ * \param sound The input sound.
+ * \param delay The desired delay in seconds.
+ */
+ Delay(std::shared_ptr<ISound> sound, float delay = 0);
+
+ /**
+ * Returns the delay in seconds.
+ */
+ float getDelay() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/DelayReader.h b/extern/audaspace/include/fx/DelayReader.h
new file mode 100644
index 00000000000..fe37e56d83e
--- /dev/null
+++ b/extern/audaspace/include/fx/DelayReader.h
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DelayReader.h
+ * @ingroup fx
+ * The DelayReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads another reader and delays it.
+ */
+class AUD_API DelayReader : public EffectReader
+{
+private:
+ /**
+ * The delay level.
+ */
+ const int m_delay;
+
+ /**
+ * The remaining delay for playback.
+ */
+ int m_remdelay;
+
+ // delete copy constructor and operator=
+ DelayReader(const DelayReader&) = delete;
+ DelayReader& operator=(const DelayReader&) = delete;
+
+public:
+ /**
+ * Creates a new delay reader.
+ * \param reader The reader to read from.
+ * \param delay The delay in seconds.
+ */
+ DelayReader(std::shared_ptr<IReader> reader, float delay);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/DynamicIIRFilter.h b/extern/audaspace/include/fx/DynamicIIRFilter.h
new file mode 100644
index 00000000000..5528e7c7b9b
--- /dev/null
+++ b/extern/audaspace/include/fx/DynamicIIRFilter.h
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DynamicIIRFilter.h
+ * @ingroup fx
+ * The DynamicIIRFilter class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+class IDynamicIIRFilterCalculator;
+
+/**
+ * This sound creates a IIR filter reader.
+ *
+ * This means that on sample rate change the filter recalculates its
+ * coefficients.
+ */
+class AUD_API DynamicIIRFilter : public Effect
+{
+protected:
+ /// The IDynamicIIRFilterCalculator that calculates the dynamic filter coefficients.
+ std::shared_ptr<IDynamicIIRFilterCalculator> m_calculator;
+
+public:
+ /**
+ * Creates a new Dynmic IIR filter sound.
+ * \param sound The input sound.
+ * \param calculator The calculator which recalculates the dynamic filter coefficients.
+ */
+ DynamicIIRFilter(std::shared_ptr<ISound> sound, std::shared_ptr<IDynamicIIRFilterCalculator> calculator);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/DynamicIIRFilterReader.h b/extern/audaspace/include/fx/DynamicIIRFilterReader.h
new file mode 100644
index 00000000000..9e2267243ce
--- /dev/null
+++ b/extern/audaspace/include/fx/DynamicIIRFilterReader.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DynamicIIRFilterReader.h
+ * @ingroup fx
+ * The DynamicIIRFilterReader class.
+ */
+
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+class IDynamicIIRFilterCalculator;
+
+/**
+ * This class is for dynamic infinite impulse response filters with simple
+ * coefficients that change depending on the sample rate.
+ */
+class AUD_API DynamicIIRFilterReader : public IIRFilterReader
+{
+private:
+ /**
+ * The sound for dynamically recalculating filter coefficients.
+ */
+ std::shared_ptr<IDynamicIIRFilterCalculator> m_calculator;
+
+public:
+ /**
+ * Creates a new DynamicIIRFilterReader.
+ * @param reader The reader the filter is applied on.
+ * @param calculator The IDynamicIIRFilterCalculator that recalculates the filter coefficients.
+ */
+ DynamicIIRFilterReader(std::shared_ptr<IReader> reader,
+ std::shared_ptr<IDynamicIIRFilterCalculator> calculator);
+
+ /**
+ * The function sampleRateChanged is called whenever the sample rate of the
+ * underlying reader changes and thus updates the filter coefficients.
+ * @param rate The new sample rate.
+ */
+ virtual void sampleRateChanged(SampleRate rate);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/DynamicMusic.h b/extern/audaspace/include/fx/DynamicMusic.h
new file mode 100644
index 00000000000..5d59f77401a
--- /dev/null
+++ b/extern/audaspace/include/fx/DynamicMusic.h
@@ -0,0 +1,235 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file DynamicMusic.h
+* @ingroup fx
+* The DynamicMusic class.
+*/
+
+#include "devices/IHandle.h"
+#include "devices/IDevice.h"
+#include "ISound.h"
+
+#include <memory>
+#include <vector>
+#include <thread>
+#include <atomic>
+#include <condition_variable>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class allows to play music depending on a current "scene", scene changes are managed by the class.
+* The default scene is silent and has id 0.
+*/
+class AUD_API DynamicMusic
+{
+private:
+ /**
+ * Matrix of pointers which will store the sounds of the scenes and the transitions between them.
+ */
+ std::vector<std::vector<std::shared_ptr<ISound>>> m_scenes;
+
+ /**
+ * Id of the current scene.
+ */
+ std::atomic_int m_id;
+
+ /**
+ * Length of the crossfade transition in seconds, used when no custom transition has been set.
+ */
+ float m_fadeTime;
+
+ /**
+ * Handle to the playback of the current scene.
+ */
+ std::shared_ptr<IHandle> m_currentHandle;
+
+ /**
+ * Handle used during transitions.
+ */
+ std::shared_ptr<IHandle> m_transitionHandle;
+
+ /**
+ * Device used for playback.
+ */
+ std::shared_ptr<IDevice> m_device;
+
+ /**
+ * Flag that is true when a transition is happening.
+ */
+ std::atomic_bool m_transitioning;
+
+ /**
+ * Flag that is true when the music is paused.
+ */
+ std::atomic_bool m_stopThread;
+
+ /**
+ * Id of the sound that will play with the next transition.
+ */
+ std::atomic_int m_soundTarget;
+
+ /**
+ * Volume of the scenes.
+ */
+ float m_volume;
+
+ /**
+ * A thread that manages the crossfade transition.
+ */
+ std::thread m_fadeThread;
+
+ // delete copy constructor and operator=
+ DynamicMusic(const DynamicMusic&) = delete;
+ DynamicMusic& operator=(const DynamicMusic&) = delete;
+
+public:
+ /**
+ * Creates a new dynamic music manager with the default silent scene (id: 0).
+ * \param device The device that will be used to play sounds.
+ */
+ DynamicMusic(std::shared_ptr<IDevice> device);
+
+ virtual ~DynamicMusic();
+
+ /**
+ * Adds a new scene to the manager.
+ * \param sound The sound that will play when the scene is selected with the changeScene().
+ * \return The identifier of the new scene.
+ */
+ int addScene(std::shared_ptr<ISound> sound);
+
+ /**
+ * Changes to another scene.
+ * \param id The id of the scene which should start playing the changeScene method.
+ * \return
+ * - true if the change has been scheduled succesfully.
+ * - false if there already is a transition in course or the scene selected doesnt exist.
+ */
+ bool changeScene(int id);
+
+ /**
+ * Retrieves the scene currently selected.
+ * \return The identifier of the current scene.
+ */
+ int getScene();
+
+ /**
+ * Adds a new transition between scenes
+ * \param init The id of the initial scene that will allow the transition to play.
+ * \param end The id if the target scene for the transition.
+ * \param sound The sound that will play when the scene changes from init to end.
+ * \return false if the init or end scenes don't exist.
+ */
+ bool addTransition(int init, int end, std::shared_ptr<ISound> sound);
+
+ /**
+ * Sets the length of the crossfade transition (default 1 second).
+ * \param seconds The time in seconds.
+ */
+ void setFadeTime(float seconds);
+
+ /**
+ * Gets the length of the crossfade transition (default 1 second).
+ * \return The length of the cressfade transition in seconds.
+ */
+ float getFadeTime();
+
+ /**
+ * Resumes a paused sound.
+ * \return
+ * - true if the sound has been resumed.
+ * - false if the sound isn't paused or the handle is invalid.
+ */
+ bool resume();
+
+ /**
+ * Pauses the current played back sound.
+ * \return
+ * - true if the sound has been paused.
+ * - false if the sound isn't playing back or the handle is invalid.
+ */
+ bool pause();
+
+ /**
+ * Seeks in the current played back sound.
+ * \param position The new position from where to play back, in seconds.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ * \warning Whether the seek works or not depends on the sound source.
+ */
+ bool seek(float position);
+
+ /**
+ * Retrieves the current playback position of a sound.
+ * \return The playback position in seconds, or 0.0 if the handle is
+ * invalid.
+ */
+ float getPosition();
+
+ /**
+ * Retrieves the volume of the scenes.
+ * \return The volume.
+ */
+ float getVolume();
+
+ /**
+ * Sets the volume for the scenes.
+ * \param volume The volume.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ bool setVolume(float volume);
+
+ /**
+ * Returns the status of the current played back sound.
+ * \return
+ * - STATUS_INVALID if the sound has stopped or the handle is
+ *. invalid
+ * - STATUS_PLAYING if the sound is currently played back.
+ * - STATUS_PAUSED if the sound is currently paused.
+ * - STATUS_STOPPED if the sound finished playing and is still
+ * kept in the device.
+ * \see Status
+ */
+ Status getStatus();
+
+ /**
+ * Stops any played back or paused sound and sets the dynamic music player to default silent state (scene 0)
+ * \return
+ * - true if the sound has been stopped.
+ * - false if the handle is invalid.
+ */
+ bool stop();
+
+ private:
+ //Callbacks used to schedule transitions after a sound ends.
+ static void transitionCallback(void* player);
+ static void sceneCallback(void* player);
+ //These functions can fade sounds in and out if used with a thread.
+ void crossfadeThread();
+ void fadeInThread();
+ void fadeOutThread();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Effect.h b/extern/audaspace/include/fx/Effect.h
new file mode 100644
index 00000000000..471e37b5ecf
--- /dev/null
+++ b/extern/audaspace/include/fx/Effect.h
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Effect.h
+ * @ingroup fx
+ * The Effect class.
+ */
+
+#include "ISound.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound is a base class for all effect factories that take one other
+ * sound as input.
+ */
+class AUD_API Effect : public ISound
+{
+private:
+ // delete copy constructor and operator=
+ Effect(const Effect&) = delete;
+ Effect& operator=(const Effect&) = delete;
+
+protected:
+ /**
+ * If there is no reader it is created out of this sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * Returns the reader created out of the sound.
+ * This method can be used for the createReader function of the implementing
+ * classes.
+ * \return The reader created out of the sound.
+ */
+ inline std::shared_ptr<IReader> getReader() const
+ {
+ return m_sound->createReader();
+ }
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ */
+ Effect(std::shared_ptr<ISound> sound);
+
+ /**
+ * Destroys the sound.
+ */
+ virtual ~Effect();
+
+ /**
+ * Returns the saved sound.
+ * \return The sound or nullptr if there has no sound been saved.
+ */
+ std::shared_ptr<ISound> getSound() const;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/EffectReader.h b/extern/audaspace/include/fx/EffectReader.h
new file mode 100644
index 00000000000..85eff6a8ab9
--- /dev/null
+++ b/extern/audaspace/include/fx/EffectReader.h
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file EffectReader.h
+ * @ingroup fx
+ * The EffectReader class.
+ */
+
+#include "IReader.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This reader is a base class for all effect readers that take one other reader
+ * as input.
+ */
+class AUD_API EffectReader : public IReader
+{
+private:
+ // delete copy constructor and operator=
+ EffectReader(const EffectReader&) = delete;
+ EffectReader& operator=(const EffectReader&) = delete;
+
+protected:
+ /**
+ * The reader to read from.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+public:
+ /**
+ * Creates a new effect reader.
+ * \param reader The reader to read from.
+ */
+ EffectReader(std::shared_ptr<IReader> reader);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~EffectReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Envelope.h b/extern/audaspace/include/fx/Envelope.h
new file mode 100644
index 00000000000..3d44e897b3a
--- /dev/null
+++ b/extern/audaspace/include/fx/Envelope.h
@@ -0,0 +1,93 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Envelope.h
+ * @ingroup fx
+ * The Envelope class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+class CallbackIIRFilterReader;
+struct EnvelopeParameters;
+
+/**
+ * This sound creates an envelope follower reader.
+ */
+class AUD_API Envelope : public Effect
+{
+private:
+ /**
+ * The attack value in seconds.
+ */
+ const float m_attack;
+
+ /**
+ * The release value in seconds.
+ */
+ const float m_release;
+
+ /**
+ * The threshold value.
+ */
+ const float m_threshold;
+
+ /**
+ * The attack/release threshold value.
+ */
+ const float m_arthreshold;
+
+ // delete copy constructor and operator=
+ Envelope(const Envelope&) = delete;
+ Envelope& operator=(const Envelope&) = delete;
+
+public:
+ /**
+ * Creates a new envelope sound.
+ * \param sound The input sound.
+ * \param attack The attack value in seconds.
+ * \param release The release value in seconds.
+ * \param threshold The threshold value.
+ * \param arthreshold The attack/release threshold value.
+ */
+ Envelope(std::shared_ptr<ISound> sound, float attack, float release,
+ float threshold, float arthreshold);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * The envelopeFilter function implements the doFilterIIR callback
+ * for the callback IIR filter.
+ * @param reader The CallbackIIRFilterReader that executes the callback.
+ * @param param The envelope parameters.
+ * @return The filtered sample.
+ */
+ static sample_t AUD_LOCAL envelopeFilter(CallbackIIRFilterReader* reader, EnvelopeParameters* param);
+
+ /**
+ * The endEnvelopeFilter function implements the endFilterIIR callback
+ * for the callback IIR filter.
+ * @param param The envelope parameters.
+ */
+ static void AUD_LOCAL endEnvelopeFilter(EnvelopeParameters* param);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/FFTConvolver.h b/extern/audaspace/include/fx/FFTConvolver.h
new file mode 100644
index 00000000000..62ce1cbf5ad
--- /dev/null
+++ b/extern/audaspace/include/fx/FFTConvolver.h
@@ -0,0 +1,196 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file FFTConvolver.h
+* @ingroup fx
+* The FFTConvolver class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+#include "util/FFTPlan.h"
+
+#include <memory>
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+/**
+* This class allows to easily convolve a sound using the Fourier transform.
+*/
+class AUD_API FFTConvolver
+{
+private:
+ /**
+ * A shared pointer to an FFT plan.
+ */
+ std::shared_ptr<FFTPlan> m_plan;
+
+ /**
+ * The FFT size, must be at least M+L-1.
+ */
+ int m_N;
+
+ /**
+ * The length of the impulse response.
+ */
+ int m_M;
+
+ /**
+ * The max length of the input slices.
+ */
+ int m_L;
+
+ /**
+ * The real length of the internal buffer in fftwf_complex elements.
+ */
+ int m_realBufLen;
+
+ /**
+ * The internal buffer for the FFTS.
+ */
+ std::complex<sample_t>* m_inBuffer;
+
+ /**
+ * A shift buffer for the FDL method
+ */
+ sample_t* m_shiftBuffer;
+
+ /**
+ * A buffer to store the extra data obtained after each partial convolution.
+ */
+ float* m_tail;
+
+ /**
+ * The provided impulse response.
+ */
+ std::shared_ptr<std::vector<std::complex<sample_t>>> m_irBuffer;
+
+ /**
+ * If the tail is being read, this marks the current position.
+ */
+ int m_tailPos;
+
+ // delete copy constructor and operator=
+ FFTConvolver(const FFTConvolver&) = delete;
+ FFTConvolver& operator=(const FFTConvolver&) = delete;
+
+public:
+ /**
+ * Creates a new FFTConvolver.
+ * \param ir A shared pointer to a vector with the impulse response data in the frequency domain (see ImpulseResponse class for an easy way to obtain it).
+ * \param plan A shared pointer to and FFT plan.
+ */
+ FFTConvolver(std::shared_ptr<std::vector<std::complex<sample_t>>> ir, std::shared_ptr<FFTPlan> plan);
+ virtual ~FFTConvolver();
+
+ /**
+ * Convolves the data that is provided with the inpulse response.
+ * \param[in] inBuffer A buffer with the input data to be convolved.
+ * \param[in] outBuffer A pointer to the buffer in which the convolution result will be written.
+ * \param[in,out] length The number of samples to be convolved (the length of both the inBuffer and the outBuffer).
+ * The convolution output should be larger than the input, but since this class uses the overlap
+ * add method, the extra length will be saved internally.
+ * It must be equal or lower than N/2 (N=size of the FFTPlan) or the call will fail, setting this variable to 0 since no data would be
+ * written in the outBuffer.
+ */
+ void getNext(const sample_t* inBuffer, sample_t* outBuffer, int& length);
+
+ /**
+ * Convolves the data that is provided with the inpulse response.
+ * \param[in] inBuffer A buffer with the input data to be convolved.
+ * \param[in] outBuffer A pointer to the buffer in which the convolution result will be written.
+ * \param[in,out] length The number of samples to be convolved (the length of both the inBuffer and the outBuffer).
+ * The convolution output should be larger than the input, but since this class uses the overlap
+ * add method, the extra length will be saved internally.
+ * It must be equal or lower than N/2 (N=size of the FFTPlan) or the call will fail, setting this variable to 0 since no data would be
+ * written in the outBuffer.
+ * \param[in] transformedData A pointer to a buffer in which the Fourier transform of the input will be written.
+ */
+ void getNext(const sample_t* inBuffer, sample_t* outBuffer, int& length, fftwf_complex* transformedData);
+
+ /**
+ * Convolves the data that is provided with the inpulse response.
+ * \param[in] inBuffer A buffer with the input data to be convolved. Its length must be N/2 + 1
+ * \param[in] outBuffer A pointer to the buffer in which the convolution result will be written.
+ * \param[in,out] length The number of samples to be convolved and the length of the outBuffer.
+ * The convolution output should be larger than the input, but since this class uses the overlap
+ * add method, the extra length will be saved internally.
+ * It must be equal or lower than N/2 (N=size of the FFTPlan) or the call will fail and set the value of length to 0 since no data would be
+ * written in the outBuffer.
+ */
+ void getNext(const fftwf_complex* inBuffer, sample_t* outBuffer, int& length);
+
+ /**
+ * Gets the internally stored extra data which is result of the convolution.
+ * \param[in,out] length The count of samples that should be read. Shall
+ * contain the real count of samples after reading, in case
+ * there were only fewer samples available.
+ * A smaller value also indicates the end of the data.
+ * \param[out] eos End of stream, whether the end is reached or not.
+ * \param[in] buffer The pointer to the buffer to read into.
+ */
+ void getTail(int& length, bool& eos, sample_t* buffer);
+
+ /**
+ * Resets the internally stored data so a new convolution can be started.
+ */
+ void clear();
+
+ /**
+ * Calculates the Inverse Fast Fourier Transform of the input array.
+ * \param[in] inBuffer A buffer with the input data to be transformed. Its length must be N/2 + 1
+ * \param[in] outBuffer A pointer to the buffer in which the transform result will be written.
+ * \param[in,out] length The number of samples to be transformed and the length of the outBuffer.
+ * It must be equal or lower than N, but tipically N/2 should be used (N=size of the FFTPlan) or the call will fail and the value
+ * of length will be setted to 0, since no data would be written in the outBuffer.
+ */
+ void IFFT_FDL(const fftwf_complex* inBuffer, sample_t* outBuffer, int& length);
+
+ /**
+ * Multiplicates a frequency domain input by the impulse response and accumulates the result to a buffer.
+ * \param[in] inBuffer A buffer of complex numbers, samples in the frequency domain, that will be multiplied by the impulse response. Its length must be N/2 + 1
+ * \param[in] accBuffer A pointer to the buffer into which the result of the multiplication will be summed. Its length must be N/2 + 1
+ */
+ void getNextFDL(const std::complex<sample_t>* inBuffer, std::complex<sample_t>* accBuffer);
+
+ /**
+ * Transforms an input array of real data to the frequency domain and multiplies it by the impulse response. The result is accumulated to a buffer.
+ * \param[in] inBuffer A buffer of real numbers, samples in the time domain, that will be multiplied by the impulse response.
+ * \param[in] accBuffer A pointer to the buffer into which the result of the multiplication will be summed. Its length must be N/2 + 1.
+ * \param[in,out] length The number of samples to be transformed and the length of the inBuffer.
+ * It must be equal or lower than N/2 (N=size of the FFTPlan) or the call will fail and the value
+ * of length will be setted to 0, since no data would be written in the outBuffer.
+ * \param[in] transformedData A pointer to a buffer in which the Fourier transform of the input will be written.
+ */
+ void getNextFDL(const sample_t* inBuffer, std::complex<sample_t>* accBuffer, int& length, fftwf_complex* transformedData);
+
+ /**
+ * Changes the impulse response and resets the FFTConvolver.
+ * \param ir A shared pointer to a vector with the data of the impulse response in the frequency domain.
+ */
+ void setImpulseResponse(std::shared_ptr<std::vector<std::complex<sample_t>>> ir);
+
+ /**
+ * Retrieves the current impulse response being used.
+ * \return The current impulse response.
+ */
+ std::shared_ptr<std::vector<std::complex<sample_t>>> getImpulseResponse();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Fader.h b/extern/audaspace/include/fx/Fader.h
new file mode 100644
index 00000000000..63280aec292
--- /dev/null
+++ b/extern/audaspace/include/fx/Fader.h
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Fader.h
+ * @ingroup fx
+ * The Fader class.
+ */
+
+#include "fx/Effect.h"
+#include "fx/FaderReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound fades another sound.
+ * If the fading type is FADE_IN, everything before the fading start will be
+ * silenced, for FADE_OUT that's true for everything after fading ends.
+ */
+class AUD_API Fader : public Effect
+{
+private:
+ /**
+ * The fading type.
+ */
+ const FadeType m_type;
+
+ /**
+ * The fading start.
+ */
+ const float m_start;
+
+ /**
+ * The fading length.
+ */
+ const float m_length;
+
+ // delete copy constructor and operator=
+ Fader(const Fader&) = delete;
+ Fader& operator=(const Fader&) = delete;
+
+public:
+ /**
+ * Creates a new fader sound.
+ * \param sound The input sound.
+ * \param type The fading type.
+ * \param start The time where fading should start in seconds.
+ * \param length How long fading should last in seconds.
+ */
+ Fader(std::shared_ptr<ISound> sound,
+ FadeType type = FADE_IN,
+ float start = 0.0f, float length = 1.0f);
+
+ /**
+ * Returns the fading type.
+ */
+ FadeType getType() const;
+
+ /**
+ * Returns the fading start.
+ */
+ float getStart() const;
+
+ /**
+ * Returns the fading length.
+ */
+ float getLength() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/FaderReader.h b/extern/audaspace/include/fx/FaderReader.h
new file mode 100644
index 00000000000..99ea3d28938
--- /dev/null
+++ b/extern/audaspace/include/fx/FaderReader.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file FaderReader.h
+ * @ingroup fx
+ * Defines the FaderReader class as well as the two fading types.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/// Fading types.
+enum FadeType
+{
+ FADE_IN,
+ FADE_OUT
+};
+
+/**
+ * This class fades another reader.
+ * If the fading type is FADE_IN, everything before the fading start will be
+ * silenced, for FADE_OUT that's true for everything after fading ends.
+ */
+class AUD_API FaderReader : public EffectReader
+{
+private:
+ /**
+ * The fading type.
+ */
+ const FadeType m_type;
+
+ /**
+ * The fading start.
+ */
+ const float m_start;
+
+ /**
+ * The fading length.
+ */
+ const float m_length;
+
+ // delete copy constructor and operator=
+ FaderReader(const FaderReader&) = delete;
+ FaderReader& operator=(const FaderReader&) = delete;
+
+public:
+ /**
+ * Creates a new fader reader.
+ * \param reader The reader that this effect is applied on.
+ * \param type The fading type.
+ * \param start The time where fading should start in seconds.
+ * \param length How long fading should last in seconds.
+ */
+ FaderReader(std::shared_ptr<IReader> reader, FadeType type,
+ float start,float length);
+
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/HRTF.h b/extern/audaspace/include/fx/HRTF.h
new file mode 100644
index 00000000000..750d5f18991
--- /dev/null
+++ b/extern/audaspace/include/fx/HRTF.h
@@ -0,0 +1,108 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file HRTF.h
+* @ingroup fx
+* The HRTF class.
+*/
+
+#include "util/StreamBuffer.h"
+#include "util/FFTPlan.h"
+#include "ImpulseResponse.h"
+
+#include <memory>
+#include <vector>
+#include <unordered_map>
+#include <utility>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a complete set of HRTFs.
+*/
+class AUD_API HRTF
+{
+private:
+ /**
+ * An unordered map of unordered maps containing the ImpulseResponse objects of the HRTFs.
+ */
+ std::unordered_map<float, std::unordered_map<float, std::shared_ptr<ImpulseResponse>>> m_hrtfs;
+
+ /**
+ * The FFTPlan used to create the ImpulseResponses.
+ */
+ std::shared_ptr<FFTPlan> m_plan;
+
+ /**
+ * The specifications of the HRTFs.
+ */
+ Specs m_specs;
+
+ /**
+ * True if the HRTF object is empty.
+ */
+ bool m_empty;
+
+ // delete copy constructor and operator=
+ HRTF(const HRTF&) = delete;
+ HRTF& operator=(const HRTF&) = delete;
+
+public:
+ /**
+ * Creates a new empty HRTF object that will instance it own FFTPlan with default size.
+ */
+ HRTF();
+
+ /**
+ * Creates a new empty HRTF object.
+ * \param plan A shared pointer to a FFT plan used to transform the impulse responses added.
+ */
+ HRTF(std::shared_ptr<FFTPlan> plan);
+
+ /**
+ * Adds a new HRTF to the class.
+ * \param impulseResponse A shared pointer to an StreamBuffer with the HRTF.
+ * \param azimuth The azimuth angle of the HRTF. Interval [0,360).
+ * \param elevation The elevation angle of the HRTF.
+ * \return True if the impulse response was added successfully, false otherwise (the specs weren't correct).
+ */
+ bool addImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse, float azimuth, float elevation);
+
+ /**
+ * Retrieves a pair of HRTFs for a certain azimuth and elevation. If no exact match is found, the closest ones will be chosen (the elevation has priority over the azimuth).
+ * \param[in,out] azimuth The desired azimuth angle. If no exact match is found, the value of azimuth will represent the actual azimuth elevation of the chosen HRTF. Interval [0,360)
+ * \param[in,out] elevation The desired elevation angle. If no exact match is found, the value of elevation will represent the actual elevation angle of the chosen HRTF.
+ * \return A pair of shared pointers to ImpulseResponse objects containing the HRTFs for the left (first element) and right (second element) ears.
+ */
+ std::pair<std::shared_ptr<ImpulseResponse>, std::shared_ptr<ImpulseResponse>> getImpulseResponse(float &azimuth, float &elevation);
+
+ /**
+ * Retrieves the specs shared by all the HRTFs.
+ * \return The shared specs of all the HRTFs.
+ */
+ Specs getSpecs();
+
+ /**
+ * Retrieves the state of the HRTF object.
+ * \return True if it is empty, false otherwise.
+ */
+ bool isEmpty();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/HRTFLoader.h b/extern/audaspace/include/fx/HRTFLoader.h
new file mode 100644
index 00000000000..893184ae909
--- /dev/null
+++ b/extern/audaspace/include/fx/HRTFLoader.h
@@ -0,0 +1,99 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file HRTFLoader.h
+* @ingroup fx
+* The HRTFLoader class.
+*/
+
+#include "Audaspace.h"
+#include "fx/HRTF.h"
+#include "util/FFTPlan.h"
+
+#include <string>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This loader provides a method to load all the HRTFs in one directory, provided they follow the following naming scheme:
+* Example: L-10e210a.wav
+* The first character refers to the ear from which the HRTF was recorded: 'L' for a left ear and 'R' for a right ear.
+* Next is the elevation angle followed by the 'e' character. [-90, 90]
+* Then is the azimuth angle followed by the 'a' character. [0, 360)
+* For a sound source situated at the left of the listener the azimuth angle regarding the left ear is 90 while the angle regarding the right ear is 270.
+* KEMAR HRTFs use this naming scheme.
+*/
+class AUD_API HRTFLoader
+{
+private:
+ // delete normal constructor, copy constructor and operator=
+ HRTFLoader(const HRTFLoader&) = delete;
+ HRTFLoader& operator=(const HRTFLoader&) = delete;
+ HRTFLoader() = delete;
+
+public:
+ /**
+ * Loads all the left ear HRTFs in the directory.Onle one ear HRTFs for all azimuths [0,360) are needed for binaural sound.
+ * \param plan The plan that will be used to create the HRTF object.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ * \return A shared pointer to a loaded HRTF object.
+ */
+ static std::shared_ptr<HRTF> loadLeftHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path = "");
+
+ /**
+ * Loads all the right ear HRTFs in the directory. Onle one ear HRTFs for all azimuths [0,360) are needed for binaural sound.
+ * \param plan The plan that will be used to create the HRTF object.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ * \return A shared pointer to a loaded HRTF object.
+ */
+ static std::shared_ptr<HRTF> loadRightHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path = "");
+
+ /**
+ * Loads all the left ear HRTFs in the directory.Onle one ear HRTFs for all azimuths [0,360) are needed for binaural sound.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ * \return A shared pointer to a loaded HRTF object.
+ */
+ static std::shared_ptr<HRTF> loadLeftHRTFs(const std::string& fileExtension, const std::string& path = "");
+
+ /**
+ * Loads all the right ear HRTFs in the directory. Onle one ear HRTFs for all azimuths [0,360) are needed for binaural sound.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ * \return A shared pointer to a loaded HRTF object.
+ */
+ static std::shared_ptr<HRTF> loadRightHRTFs(const std::string& fileExtension, const std::string& path = "");
+
+
+private:
+
+ /**
+ * Loads all the HRTFs in the directory and subdirectories.
+ * \param hrtfs An HRTF object in which to load the HRTFs.
+ * \param ear 'L' to load left ear HRTFs, 'R' to load right ear HRTFs.
+ * \param fileExtension The extension of the HRTF files.
+ * \param path The path to the folder containing the HRTFs.
+ */
+ static void loadHRTFs(std::shared_ptr<HRTF>hrtfs, char ear, const std::string& fileExtension, const std::string& path = "");
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Highpass.h b/extern/audaspace/include/fx/Highpass.h
new file mode 100644
index 00000000000..6bfb6d7885d
--- /dev/null
+++ b/extern/audaspace/include/fx/Highpass.h
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Highpass.h
+ * @ingroup fx
+ * The Highpass class.
+ */
+
+#include "fx/DynamicIIRFilter.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a highpass filter reader.
+ */
+class AUD_API Highpass : public DynamicIIRFilter
+{
+private:
+ // delete copy constructor and operator=
+ Highpass(const Highpass&) = delete;
+ Highpass& operator=(const Highpass&) = delete;
+
+public:
+ /**
+ * Creates a new highpass sound.
+ * \param sound The input sound.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ */
+ Highpass(std::shared_ptr<ISound> sound, float frequency, float Q = 1.0f);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/HighpassCalculator.h b/extern/audaspace/include/fx/HighpassCalculator.h
new file mode 100644
index 00000000000..9306a3d20e5
--- /dev/null
+++ b/extern/audaspace/include/fx/HighpassCalculator.h
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file HighpassCalculator.h
+ * @ingroup fx
+ * The HighpassCalculator class.
+ */
+
+#include "fx/IDynamicIIRFilterCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The HighpassCalculator class calculates high pass filter coefficients for a
+ * dynamic DynamicIIRFilter.
+ */
+class AUD_LOCAL HighpassCalculator : public IDynamicIIRFilterCalculator
+{
+private:
+ /**
+ * The cutoff frequency.
+ */
+ const float m_frequency;
+
+ /**
+ * The Q factor.
+ */
+ const float m_Q;
+
+ // delete copy constructor and operator=
+ HighpassCalculator(const HighpassCalculator&) = delete;
+ HighpassCalculator& operator=(const HighpassCalculator&) = delete;
+
+public:
+ /**
+ * Creates a HighpassCalculator object.
+ * @param frequency The cutoff frequency.
+ * @param Q The Q factor of the filter. If unsure, use 1.0 as default.
+ */
+ HighpassCalculator(float frequency, float Q);
+
+ virtual void recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/IDynamicIIRFilterCalculator.h b/extern/audaspace/include/fx/IDynamicIIRFilterCalculator.h
new file mode 100644
index 00000000000..6c890b313b4
--- /dev/null
+++ b/extern/audaspace/include/fx/IDynamicIIRFilterCalculator.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IDynamicIIRFilterCalculator.h
+ * @ingroup fx
+ * The IDynamicIIRFilterCalculator interface.
+ */
+
+#include "respec/Specification.h"
+
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * @interface IDynamicIIRFilterCalculator
+ * This interface calculates dynamic filter coefficients which depend on the
+ * sampling rate for DynamicIIRFilterReaders.
+ */
+class AUD_API IDynamicIIRFilterCalculator
+{
+public:
+ virtual ~IDynamicIIRFilterCalculator() {}
+
+ /**
+ * 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(SampleRate rate, std::vector<float>& b, std::vector<float>& a)=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/IIRFilter.h b/extern/audaspace/include/fx/IIRFilter.h
new file mode 100644
index 00000000000..74099a30dc5
--- /dev/null
+++ b/extern/audaspace/include/fx/IIRFilter.h
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IIRFilter.h
+ * @ingroup fx
+ * The IIRFilter class.
+ */
+
+#include "fx/Effect.h"
+
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a IIR filter reader.
+ */
+class AUD_API IIRFilter : public Effect
+{
+private:
+ /**
+ * Output filter coefficients.
+ */
+ std::vector<float> m_a;
+
+ /**
+ * Input filter coefficients.
+ */
+ std::vector<float> m_b;
+
+ // delete copy constructor and operator=
+ IIRFilter(const IIRFilter&) = delete;
+ IIRFilter& operator=(const IIRFilter&) = delete;
+
+public:
+ /**
+ * Creates a new IIR filter sound.
+ * \param sound The input sound.
+ * \param b The input filter coefficients.
+ * \param a The output filter coefficients.
+ */
+ IIRFilter(std::shared_ptr<ISound> sound, const std::vector<float>& b, const std::vector<float>& a);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/IIRFilterReader.h b/extern/audaspace/include/fx/IIRFilterReader.h
new file mode 100644
index 00000000000..34518ce69c6
--- /dev/null
+++ b/extern/audaspace/include/fx/IIRFilterReader.h
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file IIRFilterReader.h
+ * @ingroup fx
+ * The IIRFilterReader class.
+ */
+
+#include "fx/BaseIIRFilterReader.h"
+
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is for infinite impulse response filters with simple coefficients.
+ */
+class AUD_API IIRFilterReader : public BaseIIRFilterReader
+{
+private:
+ /**
+ * Output filter coefficients.
+ */
+ std::vector<float> m_a;
+
+ /**
+ * Input filter coefficients.
+ */
+ std::vector<float> m_b;
+
+ // delete copy constructor and operator=
+ IIRFilterReader(const IIRFilterReader&) = delete;
+ IIRFilterReader& operator=(const IIRFilterReader&) = delete;
+
+public:
+ /**
+ * Creates a new IIR filter reader.
+ * \param reader The reader to read from.
+ * \param b The input filter coefficients.
+ * \param a The output filter coefficients.
+ */
+ IIRFilterReader(std::shared_ptr<IReader> reader, const std::vector<float>& b, const std::vector<float>& a);
+
+ virtual sample_t filter();
+
+ /**
+ * Sets new filter coefficients.
+ * @param b The input filter coefficients.
+ * @param a The output filter coefficients.
+ */
+ void setCoefficients(const std::vector<float>& b, const std::vector<float>& a);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ImpulseResponse.h b/extern/audaspace/include/fx/ImpulseResponse.h
new file mode 100644
index 00000000000..3cdb807ff99
--- /dev/null
+++ b/extern/audaspace/include/fx/ImpulseResponse.h
@@ -0,0 +1,108 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file ImpulseResponse.h
+* @ingroup fx
+* The ImpulseResponse class.
+*/
+
+#include "util/StreamBuffer.h"
+#include "util/FFTPlan.h"
+#include "IReader.h"
+
+#include <memory>
+#include <vector>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents an impulse response that can be used in convolution.
+* When this class is instanced, the impulse response is divided in channels and those channels are divided in parts of N/2 samples (N being the size of the FFT plan used).
+* The main objetive of this class is to allow the reutilization of an impulse response in various sounds without having to process it more than one time.
+* \warning The size of the FFTPlan used to process the impulse response must be the same as the one used in the convolver classes.
+*/
+class AUD_API ImpulseResponse
+{
+private:
+ /**
+ * A tri-dimensional array (channels, parts, values) The impulse response is divided in channels and those channels are divided
+ * in parts of N/2 samples. Those parts are transformed to the frequency domain transform which generates uni-dimensional
+ * arrays of fftwtf_complex data (complex numbers).
+ */
+ std::vector<std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>>> m_processedIR;
+
+ /**
+ * The specification of the samples.
+ */
+ Specs m_specs;
+
+ /**
+ * The length of the impulse response.
+ */
+ int m_length;
+
+ // delete copy constructor and operator=
+ ImpulseResponse(const ImpulseResponse&) = delete;
+ ImpulseResponse& operator=(const ImpulseResponse&) = delete;
+
+public:
+ /**
+ * Creates a new ImpulseResponse object.
+ * The impulse response will be split and transformed to the frequency domain.
+ * \param impulseResponse The impulse response sound.
+ * \param plan A shared pointer to a FFT plan used to transform the impulse response.
+ */
+ ImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse, std::shared_ptr<FFTPlan> plan);
+
+ /**
+ * Creates a new ImpulseResponse object. This overload instances its own FFTPlan with default size.
+ * The impulse response will be split and transformed to the frequency domain.
+ * \param impulseResponse The impulse response sound.
+ */
+ ImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse);
+
+ /**
+ * Returns the specification of the impulse response.
+ * \return The specification of the impulse response.
+ */
+ Specs getSpecs();
+
+ /**
+ * Retrieves the length of the impulse response.
+ * \return The length of the impulse response.
+ */
+ int getLength();
+
+ /**
+ * Retrieves one channel of the impulse response.
+ * \param n The desired channel number (from 0 to channels-1).
+ * \return The desired channel of the impulse response.
+ */
+ std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> getChannel(int n);
+
+private:
+ /**
+ * Processes the impulse response sound for its use in the convovler classes.
+ * \param A shared pointer to a reader of the desired sound.
+ * \param plan A shared pointer to a FFT plan used to transform the impulse response.
+ */
+ void processImpulseResponse(std::shared_ptr<IReader> reader, std::shared_ptr<FFTPlan> plan);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Limiter.h b/extern/audaspace/include/fx/Limiter.h
new file mode 100644
index 00000000000..0b5451b4eed
--- /dev/null
+++ b/extern/audaspace/include/fx/Limiter.h
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Limiter.h
+ * @ingroup fx
+ * The Limiter class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound limits another sound in start and end time.
+ */
+class AUD_API Limiter : public Effect
+{
+private:
+ /**
+ * The start time.
+ */
+ const float m_start;
+
+ /**
+ * The end time.
+ */
+ const float m_end;
+
+ // delete copy constructor and operator=
+ Limiter(const Limiter&) = delete;
+ Limiter& operator=(const Limiter&) = delete;
+
+public:
+ /**
+ * Creates a new limiter sound.
+ * \param sound The input sound.
+ * \param start The desired start time.
+ * \param end The desired end time, a negative value signals that it should
+ * play to the end.
+ */
+ Limiter(std::shared_ptr<ISound> sound,
+ float start = 0, float end = -1);
+
+ /**
+ * Returns the start time.
+ */
+ float getStart() const;
+
+ /**
+ * Returns the end time.
+ */
+ float getEnd() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/LimiterReader.h b/extern/audaspace/include/fx/LimiterReader.h
new file mode 100644
index 00000000000..49a07b5c29e
--- /dev/null
+++ b/extern/audaspace/include/fx/LimiterReader.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LimiterReader.h
+ * @ingroup fx
+ * The LimiterReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This reader limits another reader in start and end times.
+ */
+class AUD_API LimiterReader : public EffectReader
+{
+private:
+ /**
+ * The start sample: inclusive.
+ */
+ const float m_start;
+
+ /**
+ * The end sample: exlusive.
+ */
+ const float m_end;
+
+ // delete copy constructor and operator=
+ LimiterReader(const LimiterReader&) = delete;
+ LimiterReader& operator=(const LimiterReader&) = delete;
+
+public:
+ /**
+ * Creates a new limiter reader.
+ * \param reader The reader to read from.
+ * \param start The desired start time (inclusive).
+ * \param end The desired end time (sample exklusive), a negative value
+ * signals that it should play to the end.
+ */
+ LimiterReader(std::shared_ptr<IReader> reader, float start = 0, float end = -1);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Loop.h b/extern/audaspace/include/fx/Loop.h
new file mode 100644
index 00000000000..c8ba7609f23
--- /dev/null
+++ b/extern/audaspace/include/fx/Loop.h
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Loop.h
+ * @ingroup fx
+ * The Loop class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound loops another sound.
+ * \note The reader has to be seekable.
+ */
+class AUD_API Loop : public Effect
+{
+private:
+ /**
+ * The loop count.
+ */
+ const int m_loop;
+
+ // delete copy constructor and operator=
+ Loop(const Loop&) = delete;
+ Loop& operator=(const Loop&) = delete;
+
+public:
+ /**
+ * Creates a new loop sound.
+ * \param sound The input sound.
+ * \param loop The desired loop count, negative values result in endless
+ * looping.
+ */
+ Loop(std::shared_ptr<ISound> sound, int loop = -1);
+
+ /**
+ * Returns the loop count.
+ */
+ int getLoop() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/LoopReader.h b/extern/audaspace/include/fx/LoopReader.h
new file mode 100644
index 00000000000..72bb92c8b8f
--- /dev/null
+++ b/extern/audaspace/include/fx/LoopReader.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LoopReader.h
+ * @ingroup fx
+ * The LoopReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads another reader and loops it.
+ * \note The other reader must be seekable.
+ */
+class AUD_API LoopReader : public EffectReader
+{
+private:
+ /**
+ * The loop count.
+ */
+ const int m_count;
+
+ /**
+ * The left loop count.
+ */
+ int m_left;
+
+ // delete copy constructor and operator=
+ LoopReader(const LoopReader&) = delete;
+ LoopReader& operator=(const LoopReader&) = delete;
+
+public:
+ /**
+ * Creates a new loop reader.
+ * \param reader The reader to read from.
+ * \param loop The desired loop count, negative values result in endless
+ * looping.
+ */
+ LoopReader(std::shared_ptr<IReader> reader, int loop);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Lowpass.h b/extern/audaspace/include/fx/Lowpass.h
new file mode 100644
index 00000000000..c14e5e8e0e2
--- /dev/null
+++ b/extern/audaspace/include/fx/Lowpass.h
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Lowpass.h
+ * @ingroup fx
+ * The Lowpass class.
+ */
+
+#include "fx/DynamicIIRFilter.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a lowpass filter reader.
+ */
+class AUD_API Lowpass : public DynamicIIRFilter
+{
+private:
+ // delete copy constructor and operator=
+ Lowpass(const Lowpass&) = delete;
+ Lowpass& operator=(const Lowpass&) = delete;
+
+public:
+ /**
+ * Creates a new lowpass sound.
+ * \param sound The input sound.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
+ */
+ Lowpass(std::shared_ptr<ISound> sound, float frequency, float Q = 1.0f);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/LowpassCalculator.h b/extern/audaspace/include/fx/LowpassCalculator.h
new file mode 100644
index 00000000000..477adfb5b5b
--- /dev/null
+++ b/extern/audaspace/include/fx/LowpassCalculator.h
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LowpassCalculator.h
+ * @ingroup fx
+ * The LowpassCalculator class.
+ */
+
+#include "fx/IDynamicIIRFilterCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The LowpassCalculator class calculates low pass filter coefficients for a
+ * dynamic DynamicIIRFilter.
+ */
+class AUD_LOCAL LowpassCalculator : public IDynamicIIRFilterCalculator
+{
+private:
+ /**
+ * The cutoff frequency.
+ */
+ const float m_frequency;
+
+ /**
+ * The Q factor.
+ */
+ const float m_Q;
+
+ // delete copy constructor and operator=
+ LowpassCalculator(const LowpassCalculator&) = delete;
+ LowpassCalculator& operator=(const LowpassCalculator&) = delete;
+
+public:
+ /**
+ * Creates a LowpassCalculator object.
+ * @param frequency The cutoff frequency.
+ * @param Q The Q factor of the filter. If unsure, use 1.0 as default.
+ */
+ LowpassCalculator(float frequency, float Q);
+
+ virtual void recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/MutableReader.h b/extern/audaspace/include/fx/MutableReader.h
new file mode 100644
index 00000000000..217dd2aa5d4
--- /dev/null
+++ b/extern/audaspace/include/fx/MutableReader.h
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file MutableReader.h
+* @ingroup fx
+* The MutableReader class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a reader for a sound that can change with each playback. The change will occur when trying to seek backwards
+* If the sound doesn't support that, it will be restarted.
+* \warning Notice that if a SoundList object is assigned to several MutableReaders, sequential playback won't work correctly.
+* To prevent this the SoundList must be copied.
+*/
+class AUD_API MutableReader : public IReader
+{
+private:
+ /**
+ * The current reader.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+ /**
+ * A sound from which to get the reader.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+
+ // delete copy constructor and operator=
+ MutableReader(const MutableReader&) = delete;
+ MutableReader& operator=(const MutableReader&) = delete;
+
+public:
+ /**
+ * Creates a new mutable reader.
+ * \param sound A of sound you want to assign to this reader.
+ */
+ MutableReader(std::shared_ptr<ISound> sound);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/MutableSound.h b/extern/audaspace/include/fx/MutableSound.h
new file mode 100644
index 00000000000..9b5aa95cf18
--- /dev/null
+++ b/extern/audaspace/include/fx/MutableSound.h
@@ -0,0 +1,58 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file MutableSound.h
+* @ingroup fx
+* The MutableSound class.
+*/
+
+#include "ISound.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* Ths class allows to create MutableReaders for any sound.
+*/
+class AUD_API MutableSound : public ISound
+{
+private:
+ /**
+ * A pointer to a sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ // delete copy constructor and operator=
+ MutableSound(const MutableSound&) = delete;
+ MutableSound& operator=(const MutableSound&) = delete;
+
+public:
+ /**
+ * Creates a new MutableSound.
+ * \param sound The sound in which the MutabeReaders created with the createReader() method will be based.
+ * If shared pointer to a SoundList object is used in several mutable sounds the sequential
+ * playback will not work properly. A copy of the SoundList object must be made in this case.
+ */
+ MutableSound(std::shared_ptr<ISound> sound);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/Pitch.h b/extern/audaspace/include/fx/Pitch.h
new file mode 100644
index 00000000000..570366be549
--- /dev/null
+++ b/extern/audaspace/include/fx/Pitch.h
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Pitch.h
+ * @ingroup fx
+ * The Pitch class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound changes the pitch of another sound.
+ */
+class AUD_API Pitch : public Effect
+{
+private:
+ /**
+ * The pitch.
+ */
+ const float m_pitch;
+
+ // delete copy constructor and operator=
+ Pitch(const Pitch&) = delete;
+ Pitch& operator=(const Pitch&) = delete;
+
+public:
+ /**
+ * Creates a new pitch sound.
+ * \param sound The input sound.
+ * \param pitch The desired pitch.
+ */
+ Pitch(std::shared_ptr<ISound> sound, float pitch);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/PitchReader.h b/extern/audaspace/include/fx/PitchReader.h
new file mode 100644
index 00000000000..c82f71b61bf
--- /dev/null
+++ b/extern/audaspace/include/fx/PitchReader.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file PitchReader.h
+ * @ingroup fx
+ * The PitchReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads another reader and changes it's pitch.
+ */
+class AUD_API PitchReader : public EffectReader
+{
+private:
+ /**
+ * The pitch level.
+ */
+ float m_pitch;
+
+ // delete copy constructor and operator=
+ PitchReader(const PitchReader&) = delete;
+ PitchReader& operator=(const PitchReader&) = delete;
+
+public:
+ /**
+ * Creates a new pitch reader.
+ * \param reader The reader to read from.
+ * \param pitch The pitch value.
+ */
+ PitchReader(std::shared_ptr<IReader> reader, float pitch);
+
+ virtual Specs getSpecs() const;
+
+ /**
+ * Retrieves the pitch.
+ * \return The current pitch value.
+ */
+ float getPitch() const;
+
+ /**
+ * Sets the pitch.
+ * \param pitch The new pitch value.
+ */
+ void setPitch(float pitch);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/PlaybackCategory.h b/extern/audaspace/include/fx/PlaybackCategory.h
new file mode 100644
index 00000000000..7721623359f
--- /dev/null
+++ b/extern/audaspace/include/fx/PlaybackCategory.h
@@ -0,0 +1,127 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file PlaybackCategory.h
+* @ingroup fx
+* The PlaybackCategory class.
+*/
+
+#include "devices/IHandle.h"
+#include "devices/IDevice.h"
+#include "VolumeStorage.h"
+
+#include <unordered_map>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a category of related sounds which are currently playing and allows to control them easily.
+*/
+class AUD_API PlaybackCategory
+{
+private:
+ /**
+ * Next handle ID to be assigned.
+ */
+ unsigned int m_currentID;
+
+ /**
+ * Vector of handles that belong to the category.
+ */
+ std::unordered_map<unsigned int, std::shared_ptr<IHandle>> m_handles;
+
+ /**
+ * Device that will play the sounds.
+ */
+ std::shared_ptr<IDevice> m_device;
+
+ /**
+ * Status of the category.
+ */
+ Status m_status;
+
+ /**
+ * Volume of all the sounds of the category.
+ */
+ std::shared_ptr<VolumeStorage> m_volumeStorage;
+
+ // delete copy constructor and operator=
+ PlaybackCategory(const PlaybackCategory&) = delete;
+ PlaybackCategory& operator=(const PlaybackCategory&) = delete;
+
+public:
+ /**
+ * Creates a new PlaybackCategory.
+ * \param device A shared pointer to the device which will be used for playback.
+ */
+ PlaybackCategory(std::shared_ptr<IDevice> device);
+ ~PlaybackCategory();
+
+ /**
+ * Plays a new sound in the category.
+ * \param sound The sound to be played.
+ * \return A handle for the playback. If the playback failed, nullptr will be returned.
+ */
+ std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound);
+
+ /**
+ * Resumes all the paused sounds of the category.
+ */
+ void resume();
+
+ /**
+ * Pauses all current played back sounds of the category.
+ */
+ void pause();
+
+ /**
+ * Retrieves the volume of the category.
+ * \return The volume.
+ */
+ float getVolume();
+
+ /**
+ * Sets the volume for the category.
+ * \param volume The volume.
+ */
+ void setVolume(float volume);
+
+ /**
+ * Stops all the playing back or paused sounds.
+ */
+ void stop();
+
+ /**
+ * Retrieves the shared volume of the category.
+ * \return A shared pointer to the VolumeStorage object that represents the shared volume of the category.
+ */
+ std::shared_ptr<VolumeStorage> getSharedVolume();
+
+ /**
+ * Cleans the category erasing all the invalid handles.
+ * Only needed if individual sounds are stopped with their handles.
+ */
+ void cleanHandles();
+
+private:
+ static void cleanHandleCallback(void* data);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/PlaybackManager.h b/extern/audaspace/include/fx/PlaybackManager.h
new file mode 100644
index 00000000000..f660568b8db
--- /dev/null
+++ b/extern/audaspace/include/fx/PlaybackManager.h
@@ -0,0 +1,156 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file PlaybackManager.h
+* @ingroup fx
+* The PlaybackManager class.
+*/
+
+#include "PlaybackCategory.h"
+#include "devices/IDevice.h"
+#include "ISound.h"
+
+#include <unordered_map>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class allows to control groups of playing sounds easily.
+* The sounds are part of categories.
+*/
+class AUD_API PlaybackManager
+{
+private:
+ /**
+ * Unordered map of categories, each category has different name.
+ */
+ std::unordered_map<unsigned int, std::shared_ptr<PlaybackCategory>> m_categories;
+
+ /**
+ * Device used for playback.
+ */
+ std::shared_ptr<IDevice> m_device;
+
+ /**
+ * The current key used for new categories.
+ */
+ unsigned int m_currentKey;
+
+ // delete copy constructor and operator=
+ PlaybackManager(const PlaybackManager&) = delete;
+ PlaybackManager& operator=(const PlaybackManager&) = delete;
+
+public:
+ /**
+ * Creates a new PlaybackManager.
+ * \param device A shared pointer to the device which will be used for playback.
+ */
+ PlaybackManager(std::shared_ptr<IDevice> device);
+
+ /**
+ * Adds an existent category to the manager and returns a key to access it.
+ * \param category The category to be added.
+ * \return The category key.
+ */
+ unsigned int addCategory(std::shared_ptr<PlaybackCategory> category);
+
+ /**
+ * Adds an existent category to the manager and returns a key to access it.
+ * \param volume The volume of the new category.
+ * \return The category key.
+ */
+ unsigned int addCategory(float volume);
+
+ /**
+ * Plays a sound and adds it to a new or existent category.
+ * \param sound The sound to be played and added to a category.
+ * \param catKey Key of the category.
+ * \return The handle of the playback; nullptr if the sound couldn't be played.
+ */
+ std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, unsigned int catKey);
+
+ /**
+ * Resumes all the paused sounds of a category.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool resume(unsigned int catKey);
+
+ /**
+ * Pauses all current playing sounds of a category.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool pause(unsigned int catKey);
+
+ /**
+ * Retrieves the volume of a category.
+ * \param catKey Key of the category.
+ * \return The volume value of the category. If the category doesn't exist it returns a negative number.
+ */
+ float getVolume(unsigned int catKey);
+
+ /**
+ * Sets the volume for a category.
+ * \param volume The volume.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool setVolume(float volume, unsigned int catKey);
+
+ /**
+ * Stops and erases a category of sounds.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool stop(unsigned int catKey);
+
+ /**
+ * Removes all the invalid handles of all the categories.
+ * Only needed if individual sounds are stopped with their handles.
+ */
+ void clean();
+
+ /**
+ * Removes all the invalid handles of a category.
+ * Only needed if individual sounds are stopped with their handles.
+ * \param catKey Key of the category.
+ * \return
+ * - true if succesful.
+ * - false if the category doesn't exist.
+ */
+ bool clean(unsigned int catKey);
+
+ /**
+ * Retrieves the device of the PlaybackManager.
+ * \return A shared pointer to the device used by the playback manager.
+ */
+ std::shared_ptr<IDevice> getDevice();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Reverse.h b/extern/audaspace/include/fx/Reverse.h
new file mode 100644
index 00000000000..32227da977a
--- /dev/null
+++ b/extern/audaspace/include/fx/Reverse.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Reverse.h
+ * @ingroup fx
+ * The Reverse class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound reads another sound reverted.
+ * \note Readers from the underlying sound must be seekable.
+ */
+class AUD_API Reverse : public Effect
+{
+private:
+ // delete copy constructor and operator=
+ Reverse(const Reverse&) = delete;
+ Reverse& operator=(const Reverse&) = delete;
+
+public:
+ /**
+ * Creates a new reverse sound.
+ * \param sound The input sound.
+ */
+ Reverse(std::shared_ptr<ISound> sound);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/ReverseReader.h b/extern/audaspace/include/fx/ReverseReader.h
new file mode 100644
index 00000000000..a02608e1378
--- /dev/null
+++ b/extern/audaspace/include/fx/ReverseReader.h
@@ -0,0 +1,65 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ReverseReader.h
+ * @ingroup fx
+ * The ReverseReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads another reader from back to front.
+ * \note The underlying reader must be seekable.
+ */
+class AUD_API ReverseReader : public EffectReader
+{
+private:
+ /**
+ * The sample count.
+ */
+ const int m_length;
+
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ // delete copy constructor and operator=
+ ReverseReader(const ReverseReader&) = delete;
+ ReverseReader& operator=(const ReverseReader&) = delete;
+
+public:
+ /**
+ * Creates a new reverse reader.
+ * \param reader The reader to read from.
+ * \exception Exception Thrown if the reader specified has an
+ * undeterminable/infinite length or is not seekable.
+ */
+ ReverseReader(std::shared_ptr<IReader> reader);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/SoundList.h b/extern/audaspace/include/fx/SoundList.h
new file mode 100644
index 00000000000..ce3cb386969
--- /dev/null
+++ b/extern/audaspace/include/fx/SoundList.h
@@ -0,0 +1,110 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file SoundList.h
+* @ingroup fx
+* The SoundList class.
+*/
+
+#include "ISound.h"
+
+#include <vector>
+#include <memory>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class allows to have a list of sound that will play sequentially or randomly with each playback.
+*/
+class AUD_API SoundList : public ISound
+{
+private:
+ /**
+ * The list of sounds that will play.
+ */
+ std::vector<std::shared_ptr<ISound>> m_list;
+
+ /**
+ * Flag for random playback
+ */
+ bool m_random = false;
+
+ /**
+ * Current sound index. -1 if no reader has been created.
+ */
+ int m_index = -1;
+
+ /**
+ * Mutex to prevent multithreading crashes.
+ */
+ std::recursive_mutex m_mutex;
+
+ // delete copy constructor and operator=
+ SoundList(const SoundList&) = delete;
+ SoundList& operator=(const SoundList&) = delete;
+
+public:
+ /**
+ * Creates a new, empty sound list.
+ * Sounds must be added to the list using the addSound() method.
+ * \param random False if the sounds int he list must be played sequentially. True if random.
+ */
+ SoundList(bool random = false);
+
+ /**
+ * Creates a new sound list and initializes it.
+ * \param list A vector with sounds to initialize the list.
+ * \param random False if the sounds int he list must be played sequentially. True if random.
+ */
+ SoundList(std::vector<std::shared_ptr<ISound>>& list, bool random = false);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * Adds a sound to the list.
+ * The added sounds can be played sequentially or randomly dependig
+ * on the m_random flag
+ * \param sound A shared_ptr to the sound.
+ */
+ void addSound(std::shared_ptr<ISound> sound);
+
+ /**
+ * Sets the playback mode of the sound list.
+ * There are two posible modes, random and sequential.
+ * \param random True to activate the random mode, false to activate sequential mode.
+ */
+ void setRandomMode(bool random);
+
+ /**
+ * Returns the playback mode of the sound list.
+ * The two posible modes are random and sequential.
+ * \return True if the random mode is activated, false otherwise.
+ */
+ bool getRandomMode();
+
+ /**
+ * Returns the amount of sounds in the list.
+ * \return The amount of sounds in the list.
+ */
+ int getSize();
+
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Source.h b/extern/audaspace/include/fx/Source.h
new file mode 100644
index 00000000000..84448aa669d
--- /dev/null
+++ b/extern/audaspace/include/fx/Source.h
@@ -0,0 +1,109 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file Source.h
+* @ingroup fx
+* The Source class.
+*/
+
+#include "Audaspace.h"
+
+#include <atomic>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class stores the azimuth and elevation angles of a sound and allows to change them dynamically.
+* The azimuth angle goes clockwise. For a sound source situated at the right of the listener the azimuth angle is 90.
+*/
+class AUD_API Source
+{
+private:
+ /**
+ * Azimuth value.
+ */
+ std::atomic<float> m_azimuth;
+
+ /**
+ * Elevation value.
+ */
+ std::atomic<float> m_elevation;
+
+ /**
+ * Distance value. Between 0 and 1.
+ */
+ std::atomic<float> m_distance;
+
+ // delete copy constructor and operator=
+ Source(const Source&) = delete;
+ Source& operator=(const Source&) = delete;
+
+public:
+ /**
+ * Creates a Source instance with an initial value.
+ * \param azimuth The value of the azimuth.
+ * \param elevation The value of the elevation.
+ * \param distance The distance from the listener. Max distance is 1, min distance is 0.
+ */
+ Source(float azimuth, float elevation, float distance = 0.0);
+
+ /**
+ * Retrieves the current azimuth value.
+ * \return The current azimuth.
+ */
+ float getAzimuth();
+
+ /**
+ * Retrieves the current elevation value.
+ * \return The current elevation.
+ */
+ float getElevation();
+
+ /**
+ * Retrieves the current distance value.
+ * \return The current distance.
+ */
+ float getDistance();
+
+ /**
+ * Retrieves the current volume value based on the distance.
+ * \return The current volume based on the Distance.
+ */
+ float getVolume();
+
+ /**
+ * Changes the azimuth value.
+ * \param azimuth The new value for the azimuth.
+ */
+ void setAzimuth(float azimuth);
+
+ /**
+ * Changes the elevation value.
+ * \param elevation The new value for the elevation.
+ */
+ void setElevation(float elevation);
+
+ /**
+ * Changes the distance value.
+ * \param distance The new value for the distance. Max distance is 1, min distance is 0.
+ */
+ void setDistance(float distance);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/Sum.h b/extern/audaspace/include/fx/Sum.h
new file mode 100644
index 00000000000..b590aa7fcd1
--- /dev/null
+++ b/extern/audaspace/include/fx/Sum.h
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Sum.h
+ * @ingroup fx
+ * The Sum class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a sum reader.
+ */
+class AUD_API Sum : public Effect
+{
+private:
+ // delete copy constructor and operator=
+ Sum(const Sum&) = delete;
+ Sum& operator=(const Sum&) = delete;
+
+public:
+ /**
+ * Creates a new sum sound.
+ * \param sound The input sound.
+ */
+ Sum(std::shared_ptr<ISound> sound);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Threshold.h b/extern/audaspace/include/fx/Threshold.h
new file mode 100644
index 00000000000..10baef1714d
--- /dev/null
+++ b/extern/audaspace/include/fx/Threshold.h
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Threshold.h
+ * @ingroup fx
+ * The Threshold class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+class CallbackIIRFilterReader;
+
+/**
+ * This sound Transforms any signal to a square signal by thresholding.
+ */
+class AUD_API Threshold : public Effect
+{
+private:
+ /**
+ * The threshold.
+ */
+ const float m_threshold;
+
+ // delete copy constructor and operator=
+ Threshold(const Threshold&) = delete;
+ Threshold& operator=(const Threshold&) = delete;
+
+public:
+ /**
+ * Creates a new threshold sound.
+ * \param sound The input sound.
+ * \param threshold The threshold.
+ */
+ Threshold(std::shared_ptr<ISound> sound, float threshold = 0.0f);
+
+ /**
+ * Returns the threshold.
+ */
+ float getThreshold() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * The thresholdFilter function implements the doFilterIIR callback
+ * for the callback IIR filter.
+ * @param reader The CallbackIIRFilterReader that executes the callback.
+ * @param threshold The threshold value.
+ * @return The filtered sample.
+ */
+ static sample_t AUD_LOCAL thresholdFilter(CallbackIIRFilterReader* reader, float* threshold);
+
+ /**
+ * The endThresholdFilter function implements the endFilterIIR callback
+ * for the callback IIR filter.
+ * @param threshold The threshold value.
+ */
+ static void AUD_LOCAL endThresholdFilter(float* threshold);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/Volume.h b/extern/audaspace/include/fx/Volume.h
new file mode 100644
index 00000000000..0e56e8efd9b
--- /dev/null
+++ b/extern/audaspace/include/fx/Volume.h
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Volume.h
+ * @ingroup fx
+ * The Volume class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound changes the volume of another sound.
+ * The set volume should be a value between 0.0 and 1.0, higher values at your
+ * own risk!
+ */
+class AUD_API Volume : public Effect
+{
+private:
+ /**
+ * The volume.
+ */
+ const float m_volume;
+
+ // delete copy constructor and operator=
+ Volume(const Volume&) = delete;
+ Volume& operator=(const Volume&) = delete;
+
+public:
+ /**
+ * Creates a new volume sound.
+ * \param sound The input sound.
+ * \param volume The desired volume.
+ */
+ Volume(std::shared_ptr<ISound> sound, float volume);
+
+ /**
+ * Returns the volume.
+ * \return The current volume.
+ */
+ float getVolume() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/fx/VolumeReader.h b/extern/audaspace/include/fx/VolumeReader.h
new file mode 100644
index 00000000000..13b6845e931
--- /dev/null
+++ b/extern/audaspace/include/fx/VolumeReader.h
@@ -0,0 +1,70 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file VolumeReader.h
+* @ingroup fx
+* The VolumeReader class.
+*/
+
+#include "IReader.h"
+#include "ISound.h"
+#include "VolumeStorage.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class represents a reader for a sound that has its own shared volume
+*/
+class AUD_API VolumeReader : public IReader
+{
+private:
+ /**
+ * The current reader.
+ */
+ std::shared_ptr<IReader> m_reader;
+
+ /**
+ * A sound from which to get the reader.
+ */
+ std::shared_ptr<VolumeStorage> m_volumeStorage;
+
+
+ // delete copy constructor and operator=
+ VolumeReader(const VolumeReader&) = delete;
+ VolumeReader& operator=(const VolumeReader&) = delete;
+
+public:
+ /**
+ * Creates a new volume reader.
+ * \param reader A reader of the sound to be assigned to this reader.
+ * \param volumeStorage A shared pointer to a VolumeStorage object.
+ */
+ VolumeReader(std::shared_ptr<IReader> reader, std::shared_ptr<VolumeStorage> volumeStorage);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/VolumeSound.h b/extern/audaspace/include/fx/VolumeSound.h
new file mode 100644
index 00000000000..0aeffd53e87
--- /dev/null
+++ b/extern/audaspace/include/fx/VolumeSound.h
@@ -0,0 +1,74 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file VolumeSound.h
+* @ingroup fx
+* The VolumeSound class.
+*/
+
+#include "ISound.h"
+#include "VolumeStorage.h"
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class allows to create a sound with its own volume.
+*/
+class AUD_API VolumeSound : public ISound
+{
+private:
+ /**
+ * A pointer to a sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * A pointer to the shared volume being used.
+ */
+ std::shared_ptr<VolumeStorage> m_volumeStorage;
+
+ // delete copy constructor and operator=
+ VolumeSound(const VolumeSound&) = delete;
+ VolumeSound& operator=(const VolumeSound&) = delete;
+
+public:
+ /**
+ * Creates a new VolumeSound.
+ * \param sound The sound in which shall have its own volume.
+ * \param volumeStorage A shared pointer to a VolumeStorage object. It allows to change the volume of various sound in one go.
+ */
+ VolumeSound(std::shared_ptr<ISound> sound, std::shared_ptr<VolumeStorage> volumeStorage);
+
+ virtual std::shared_ptr<IReader> createReader();
+
+ /**
+ * Retrieves the shared volume of this sound.
+ * \return A shared pointer to the VolumeStorage object that this sound is using.
+ */
+ std::shared_ptr<VolumeStorage> getSharedVolume();
+
+ /**
+ * Changes the shared volume of this sound, it'll only affect newly created readers.
+ * \param volumeStorage A shared pointer to the new VolumeStorage object.
+ */
+ void setSharedVolume(std::shared_ptr<VolumeStorage> volumeStorage);
+};
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/fx/VolumeStorage.h b/extern/audaspace/include/fx/VolumeStorage.h
new file mode 100644
index 00000000000..5088a5e2ba9
--- /dev/null
+++ b/extern/audaspace/include/fx/VolumeStorage.h
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file VolumeStorage.h
+* @ingroup fx
+* The VolumeStorage class.
+*/
+
+#include "Audaspace.h"
+
+#include <atomic>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* This class stores a volume value and allows to change if for a number of sounds in one go.
+*/
+class AUD_API VolumeStorage
+{
+private:
+ /**
+ * Volume value.
+ */
+ std::atomic<float> m_volume;
+
+ // delete copy constructor and operator=
+ VolumeStorage(const VolumeStorage&) = delete;
+ VolumeStorage& operator=(const VolumeStorage&) = delete;
+
+public:
+ /**
+ * Creates a new VolumeStorage instance with volume 1
+ */
+ VolumeStorage();
+
+ /**
+ * Creates a VolumeStorage instance with an initial value.
+ * \param volume The value of the volume.
+ */
+ VolumeStorage(float volume);
+
+ /**
+ * Retrieves the current volume value.
+ * \return The current volume.
+ */
+ float getVolume();
+
+ /**
+ * Changes the volume value.
+ * \param volume The new value for the volume.
+ */
+ void setVolume(float volume);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Sawtooth.h b/extern/audaspace/include/generator/Sawtooth.h
new file mode 100644
index 00000000000..68f56ae83fd
--- /dev/null
+++ b/extern/audaspace/include/generator/Sawtooth.h
@@ -0,0 +1,66 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Sawtooth.h
+ * @ingroup generator
+ * The Sawtooth class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays a sawtooth tone.
+ */
+class AUD_API Sawtooth : public ISound
+{
+private:
+ /**
+ * The frequence of the sawtooth wave.
+ */
+ const float m_frequency;
+
+ /**
+ * The target sample rate for output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ Sawtooth(const Sawtooth&) = delete;
+ Sawtooth& operator=(const Sawtooth&) = delete;
+
+public:
+ /**
+ * Creates a new sawtooth sound.
+ * \param frequency The desired frequency.
+ * \param sampleRate The target sample rate for playback.
+ */
+ Sawtooth(float frequency, SampleRate sampleRate = RATE_48000);
+
+ /**
+ * Returns the frequency of the sawtooth wave.
+ */
+ float getFrequency() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/SawtoothReader.h b/extern/audaspace/include/generator/SawtoothReader.h
new file mode 100644
index 00000000000..b4045eb8820
--- /dev/null
+++ b/extern/audaspace/include/generator/SawtoothReader.h
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SawtoothReader.h
+ * @ingroup generator
+ * The SawtoothReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for sawtooth tone playback.
+ * The output format is in the 16 bit format and stereo, the sample rate can be
+ * specified.
+ * As the two channels both play the same the output could also be mono, but
+ * in most cases this will result in having to resample for output, so stereo
+ * sound is created directly.
+ */
+class AUD_API SawtoothReader : public IReader
+{
+private:
+ /**
+ * The frequency of the sine wave.
+ */
+ float m_frequency;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The value of the current sample.
+ */
+ float m_sample;
+
+ /**
+ * The sample rate for the output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ SawtoothReader(const SawtoothReader&) = delete;
+ SawtoothReader& operator=(const SawtoothReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param frequency The frequency of the sine wave.
+ * \param sampleRate The output sample rate.
+ */
+ SawtoothReader(float frequency, SampleRate sampleRate);
+
+ /**
+ * Sets the frequency of the wave.
+ * @param frequency The new frequency in Hertz.
+ */
+ void setFrequency(float frequency);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int & length, bool &eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Silence.h b/extern/audaspace/include/generator/Silence.h
new file mode 100644
index 00000000000..a35b83d37fc
--- /dev/null
+++ b/extern/audaspace/include/generator/Silence.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Silence.h
+ * @ingroup generator
+ * The Silence class.
+ */
+
+#include "ISound.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays silence.
+ */
+class AUD_API Silence : public ISound
+{
+private:
+ // delete copy constructor and operator=
+ Silence(const Silence&) = delete;
+ Silence& operator=(const Silence&) = delete;
+
+public:
+ /**
+ * Creates a new silence sound.
+ */
+ Silence();
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/SilenceReader.h b/extern/audaspace/include/generator/SilenceReader.h
new file mode 100644
index 00000000000..ecc0ce86da9
--- /dev/null
+++ b/extern/audaspace/include/generator/SilenceReader.h
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SilenceReader.h
+ * @ingroup generator
+ * The SilenceReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for silence playback.
+ * The signal generated is 44.1kHz mono.
+ */
+class AUD_API SilenceReader : public IReader
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ // delete copy constructor and operator=
+ SilenceReader(const SilenceReader&) = delete;
+ SilenceReader& operator=(const SilenceReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ */
+ SilenceReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Sine.h b/extern/audaspace/include/generator/Sine.h
new file mode 100644
index 00000000000..ee78fc7d06b
--- /dev/null
+++ b/extern/audaspace/include/generator/Sine.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Sine.h
+ * @ingroup generator
+ * The Sine class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays a sine tone.
+ */
+class AUD_API Sine : public ISound
+{
+private:
+ /**
+ * The frequence of the sine wave.
+ */
+ const float m_frequency;
+
+ /**
+ * The target sample rate for output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ Sine(const Sine&) = delete;
+ Sine& operator=(const Sine&) = delete;
+
+public:
+ /**
+ * Creates a new sine sound.
+ * \param frequency The desired frequency.
+ * \param sampleRate The target sample rate for playback.
+ */
+ Sine(float frequency,
+ SampleRate sampleRate = RATE_48000);
+
+ /**
+ * Returns the frequency of the sine wave.
+ */
+ float getFrequency() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/SineReader.h b/extern/audaspace/include/generator/SineReader.h
new file mode 100644
index 00000000000..49cd571bc65
--- /dev/null
+++ b/extern/audaspace/include/generator/SineReader.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SineReader.h
+ * @ingroup generator
+ * The SineReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for sine tone playback.
+ * The sample rate can be specified, the signal is mono.
+ */
+class AUD_API SineReader : public IReader
+{
+private:
+ /**
+ * The frequency of the sine wave.
+ */
+ float m_frequency;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The sample rate for the output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ SineReader(const SineReader&) = delete;
+ SineReader& operator=(const SineReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param frequency The frequency of the sine wave.
+ * \param sampleRate The output sample rate.
+ */
+ SineReader(float frequency, SampleRate sampleRate);
+
+ /**
+ * Sets the frequency of the wave.
+ * @param frequency The new frequency in Hertz.
+ */
+ void setFrequency(float frequency);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Square.h b/extern/audaspace/include/generator/Square.h
new file mode 100644
index 00000000000..0ba27677a81
--- /dev/null
+++ b/extern/audaspace/include/generator/Square.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Square.h
+ * @ingroup generator
+ * The Square class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays a square tone.
+ */
+class AUD_API Square : public ISound
+{
+private:
+ /**
+ * The frequence of the square wave.
+ */
+ const float m_frequency;
+
+ /**
+ * The target sample rate for output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ Square(const Square&) = delete;
+ Square& operator=(const Square&) = delete;
+
+public:
+ /**
+ * Creates a new square sound.
+ * \param frequency The desired frequency.
+ * \param sampleRate The target sample rate for playback.
+ */
+ Square(float frequency,
+ SampleRate sampleRate = RATE_48000);
+
+ /**
+ * Returns the frequency of the square wave.
+ */
+ float getFrequency() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/SquareReader.h b/extern/audaspace/include/generator/SquareReader.h
new file mode 100644
index 00000000000..53fc574c767
--- /dev/null
+++ b/extern/audaspace/include/generator/SquareReader.h
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SquareReader.h
+ * @ingroup generator
+ * The SquareReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for square tone playback.
+ * The output format is in the 16 bit format and stereo, the sample rate can be
+ * specified.
+ * As the two channels both play the same the output could also be mono, but
+ * in most cases this will result in having to resample for output, so stereo
+ * sound is created directly.
+ */
+class AUD_API SquareReader : public IReader
+{
+private:
+ /**
+ * The frequency of the sine wave.
+ */
+ float m_frequency;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The value of the current sample.
+ */
+ float m_sample;
+
+ /**
+ * The sample rate for the output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ SquareReader(const SquareReader&) = delete;
+ SquareReader& operator=(const SquareReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param frequency The frequency of the sine wave.
+ * \param sampleRate The output sample rate.
+ */
+ SquareReader(float frequency, SampleRate sampleRate);
+
+ /**
+ * Sets the frequency of the wave.
+ * @param frequency The new frequency in Hertz.
+ */
+ void setFrequency(float frequency);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int & length, bool &eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/Triangle.h b/extern/audaspace/include/generator/Triangle.h
new file mode 100644
index 00000000000..4f607fc23b5
--- /dev/null
+++ b/extern/audaspace/include/generator/Triangle.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Triangle.h
+ * @ingroup generator
+ * The Triangle class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that plays a triangle tone.
+ */
+class AUD_API Triangle : public ISound
+{
+private:
+ /**
+ * The frequence of the triangle wave.
+ */
+ const float m_frequency;
+
+ /**
+ * The target sample rate for output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ Triangle(const Triangle&) = delete;
+ Triangle& operator=(const Triangle&) = delete;
+
+public:
+ /**
+ * Creates a new triangle sound.
+ * \param frequency The desired frequency.
+ * \param sampleRate The target sample rate for playback.
+ */
+ Triangle(float frequency,
+ SampleRate sampleRate = RATE_48000);
+
+ /**
+ * Returns the frequency of the triangle wave.
+ */
+ float getFrequency() const;
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/generator/TriangleReader.h b/extern/audaspace/include/generator/TriangleReader.h
new file mode 100644
index 00000000000..15079404b75
--- /dev/null
+++ b/extern/audaspace/include/generator/TriangleReader.h
@@ -0,0 +1,86 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file TriangleReader.h
+ * @ingroup generator
+ * The TriangleReader class.
+ */
+
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for sawtooth tone playback.
+ * The output format is in the 16 bit format and stereo, the sample rate can be
+ * specified.
+ * As the two channels both play the same the output could also be mono, but
+ * in most cases this will result in having to resample for output, so stereo
+ * sound is created directly.
+ */
+class AUD_API TriangleReader : public IReader
+{
+private:
+ /**
+ * The frequency of the sine wave.
+ */
+ float m_frequency;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The value of the current sample.
+ */
+ float m_sample;
+
+ /**
+ * The sample rate for the output.
+ */
+ const SampleRate m_sampleRate;
+
+ // delete copy constructor and operator=
+ TriangleReader(const TriangleReader&) = delete;
+ TriangleReader& operator=(const TriangleReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param frequency The frequency of the sine wave.
+ * \param sampleRate The output sample rate.
+ */
+ TriangleReader(float frequency, SampleRate sampleRate);
+
+ /**
+ * Sets the frequency of the wave.
+ * @param frequency The new frequency in Hertz.
+ */
+ void setFrequency(float frequency);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int & length, bool &eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/plugin/PluginManager.h b/extern/audaspace/include/plugin/PluginManager.h
new file mode 100644
index 00000000000..af2f469c4ea
--- /dev/null
+++ b/extern/audaspace/include/plugin/PluginManager.h
@@ -0,0 +1,81 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file PluginManager.h
+ * @ingroup plugin
+ * The PluginManager class.
+ */
+
+#include "Audaspace.h"
+
+#include <unordered_map>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This manager provides utilities for plugin loading.
+ */
+class AUD_API PluginManager
+{
+private:
+ static std::unordered_map<std::string, void*> m_plugins;
+
+ // delete copy constructor and operator=
+ PluginManager(const PluginManager&) = delete;
+ PluginManager& operator=(const PluginManager&) = delete;
+ PluginManager() = delete;
+
+public:
+ /**
+ * Opens a shared library.
+ * @param path The path to the file.
+ * @return A handle to the library or nullptr if opening failed.
+ */
+ static void* openLibrary(const std::string& path);
+
+ /**
+ * Looks up a symbol from an opened library.
+ * @param handle The handle to the opened library.
+ * @param name The name of the symbol to look up.
+ * @return The symbol or nullptr if the symbol was not found.
+ */
+ static void* lookupLibrary(void* handle, const std::string& name);
+
+ /**
+ * Closes an opened shared library.
+ * @param handle The handle to the library to be closed.
+ */
+ static void closeLibrary(void* handle);
+
+ /**
+ * Loads a plugin from a file.
+ * @param path The path to the file.
+ * @return Whether the file could successfully be loaded.
+ */
+ static bool loadPlugin(const std::string& path);
+
+ /**
+ * Loads all plugins found in a folder.
+ * @param path The path to the folder containing the plugins.
+ */
+ static void loadPlugins(const std::string& path = "");
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ChannelMapper.h b/extern/audaspace/include/respec/ChannelMapper.h
new file mode 100644
index 00000000000..5481a42c433
--- /dev/null
+++ b/extern/audaspace/include/respec/ChannelMapper.h
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ChannelMapper.h
+ * @ingroup respec
+ * The ChannelMapper class.
+ */
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a reader that maps a sound source's channels to a
+ * specific output channel count.
+ */
+class AUD_API ChannelMapper : public SpecsChanger
+{
+private:
+ // delete copy constructor and operator=
+ ChannelMapper(const ChannelMapper&) = delete;
+ ChannelMapper& operator=(const ChannelMapper&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ * \param specs The target specifications.
+ */
+ ChannelMapper(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ChannelMapperReader.h b/extern/audaspace/include/respec/ChannelMapperReader.h
new file mode 100644
index 00000000000..00739ee995f
--- /dev/null
+++ b/extern/audaspace/include/respec/ChannelMapperReader.h
@@ -0,0 +1,151 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ChannelMapperReader.h
+ * @ingroup respec
+ * The ChannelMapperReader class.
+ */
+
+#include "fx/EffectReader.h"
+#include "util/Buffer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class maps a sound source's channels to a specific output channel count.
+ * \note The input sample format must be float.
+ */
+class AUD_API ChannelMapperReader : public EffectReader
+{
+private:
+ /**
+ * The sound reading buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * The output specification.
+ */
+ Channels m_target_channels;
+
+ /**
+ * The channel count of the reader.
+ */
+ Channels m_source_channels;
+
+ /**
+ * The mapping specification.
+ */
+ float* m_mapping;
+
+ /**
+ * The size of the mapping.
+ */
+ int m_map_size;
+
+ /**
+ * The mono source angle.
+ */
+ float m_mono_angle;
+
+ static const Channel MONO_MAP[];
+ static const Channel STEREO_MAP[];
+ static const Channel STEREO_LFE_MAP[];
+ static const Channel SURROUND4_MAP[];
+ static const Channel SURROUND5_MAP[];
+ static const Channel SURROUND51_MAP[];
+ static const Channel SURROUND61_MAP[];
+ static const Channel SURROUND71_MAP[];
+ static const Channel* CHANNEL_MAPS[];
+
+ static const float MONO_ANGLES[];
+ static const float STEREO_ANGLES[];
+ static const float STEREO_LFE_ANGLES[];
+ static const float SURROUND4_ANGLES[];
+ static const float SURROUND5_ANGLES[];
+ static const float SURROUND51_ANGLES[];
+ static const float SURROUND61_ANGLES[];
+ static const float SURROUND71_ANGLES[];
+ static const float* CHANNEL_ANGLES[];
+
+ // delete copy constructor and operator=
+ ChannelMapperReader(const ChannelMapperReader&) = delete;
+ ChannelMapperReader& operator=(const ChannelMapperReader&) = delete;
+
+ /**
+ * Calculates the mapping matrix.
+ */
+ void AUD_LOCAL calculateMapping();
+
+ /**
+ * Calculates the distance between two angles.
+ */
+ float AUD_LOCAL angleDistance(float alpha, float beta);
+
+public:
+ /**
+ * Creates a channel mapper reader.
+ * \param reader The reader to map.
+ * \param channels The target channel count this reader should map to.
+ */
+ ChannelMapperReader(std::shared_ptr<IReader> reader, Channels channels);
+
+ /**
+ * Destroys the reader.
+ */
+ ~ChannelMapperReader();
+
+ /**
+ * Returns the channel configuration of the source reader.
+ * @return The channel configuration of the reader.
+ */
+ Channels getSourceChannels() const;
+
+ /**
+ * Returns the target channel configuration.
+ * Equals getSpecs().channels.
+ * @return The target channel configuration.
+ */
+ Channels getChannels() const;
+
+ /**
+ * Sets the requested channel output count.
+ * \param channels The channel output count.
+ */
+ void setChannels(Channels channels);
+
+ /**
+ * Returns the mapping of the source channel to the target channel.
+ * @param source The number of the source channel. Should be in the range [0, source channels).
+ * @param target The number of the target channel. Should be in the range [0, target channels).
+ * @return The mapping value which should be between 0.0 and 1.0. If source or target are out of range, NaN is returned.
+ */
+ float getMapping(int source, int target);
+
+ /**
+ * Sets the angle for mono sources.
+ * \param angle The angle for mono sources.
+ */
+ void setMonoAngle(float angle);
+
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/Converter.h b/extern/audaspace/include/respec/Converter.h
new file mode 100644
index 00000000000..35664b28025
--- /dev/null
+++ b/extern/audaspace/include/respec/Converter.h
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Converter.h
+ * @ingroup respec
+ * The Converter class.
+ */
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a converter reader that is able to convert from one
+ * audio format to another.
+ */
+class AUD_API Converter : public SpecsChanger
+{
+private:
+ // delete copy constructor and operator=
+ Converter(const Converter&) = delete;
+ Converter& operator=(const Converter&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ * \param specs The target specifications.
+ */
+ Converter(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ConverterFunctions.h b/extern/audaspace/include/respec/ConverterFunctions.h
new file mode 100644
index 00000000000..3cc4a713cc9
--- /dev/null
+++ b/extern/audaspace/include/respec/ConverterFunctions.h
@@ -0,0 +1,377 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ConverterFunctions.h
+ * @ingroup respec
+ * Defines several conversion functions between different sample formats.
+ */
+
+#include "Audaspace.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The function template for functions converting from one sample format
+ * to another, having the same parameter order as std::memcpy.
+ */
+typedef void (*convert_f)(data_t* target, data_t* source, int length);
+
+/**
+ * The copy conversion function simply calls std::memcpy.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+template <class T>
+void convert_copy(data_t* target, data_t* source, int length)
+{
+ std::memcpy(target, source, length*sizeof(T));
+}
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_s16(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_s32(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_float(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_U8 to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_u8_double(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_u8(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_s32(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_float(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S16 to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s16_double(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_u8_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_u8_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s16_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s16_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 to FORMAT_S24 simply using std::memcpy.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s24(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s32_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_s32_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_float_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_float_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 big endian to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_double_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S24 little endian to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s24_double_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_u8(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_s16(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_float(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_S32 to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_s32_double(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_u8(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_s16(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_s32(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT32 to FORMAT_FLOAT64.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_float_double(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_U8.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_u8(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_S16.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_s16(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_S24 big endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_s24_be(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_S24 little endian.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_s24_le(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_S32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_s32(data_t* target, data_t* source, int length);
+
+/**
+ * @brief Converts from FORMAT_FLOAT64 to FORMAT_FLOAT32.
+ * @param target The target buffer.
+ * @param source The source buffer.
+ * @param length The amount of samples to be converted.
+ */
+void AUD_API convert_double_float(data_t* target, data_t* source, int length);
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ConverterReader.h b/extern/audaspace/include/respec/ConverterReader.h
new file mode 100644
index 00000000000..c5ff6ded9ad
--- /dev/null
+++ b/extern/audaspace/include/respec/ConverterReader.h
@@ -0,0 +1,67 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ConverterReader.h
+ * @ingroup respec
+ * The ConverterReader class.
+ */
+
+#include "fx/EffectReader.h"
+#include "respec/ConverterFunctions.h"
+#include "util/Buffer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class converts a sound source from one to another format.
+ */
+class AUD_API ConverterReader : public EffectReader
+{
+private:
+ /**
+ * The sound output buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * The target specification.
+ */
+ SampleFormat m_format;
+
+ /**
+ * Converter function.
+ */
+ convert_f m_convert;
+
+ // delete copy constructor and operator=
+ ConverterReader(const ConverterReader&) = delete;
+ ConverterReader& operator=(const ConverterReader&) = delete;
+
+public:
+ /**
+ * Creates a converter reader.
+ * \param reader The reader to convert.
+ * \param specs The target specification.
+ */
+ ConverterReader(std::shared_ptr<IReader> reader, DeviceSpecs specs);
+
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/JOSResample.h b/extern/audaspace/include/respec/JOSResample.h
new file mode 100644
index 00000000000..b1f4d757c3c
--- /dev/null
+++ b/extern/audaspace/include/respec/JOSResample.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file JOSResample.h
+ * @ingroup respec
+ * The JOSResample class.
+ */
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a resampling reader that does Julius O. Smith's resampling algorithm.
+ */
+class AUD_API JOSResample : public SpecsChanger
+{
+private:
+ // delete copy constructor and operator=
+ JOSResample(const JOSResample&) = delete;
+ JOSResample& operator=(const JOSResample&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ * \param specs The target specifications.
+ */
+ JOSResample(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/JOSResampleReader.h b/extern/audaspace/include/respec/JOSResampleReader.h
new file mode 100644
index 00000000000..e9dd3b4220b
--- /dev/null
+++ b/extern/audaspace/include/respec/JOSResampleReader.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file JOSResampleReader.h
+ * @ingroup respec
+ * The JOSResampleReader class.
+ */
+
+#include "respec/ResampleReader.h"
+#include "util/Buffer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This resampling reader uses Julius O. Smith's resampling algorithm.
+ */
+class AUD_API JOSResampleReader : public ResampleReader
+{
+private:
+ typedef void (JOSResampleReader::*resample_f)(double target_factor, int length, sample_t* buffer);
+
+ /**
+ * The half filter length.
+ */
+ static const int m_len;
+
+ /**
+ * The sample step size for the filter.
+ */
+ static const int m_L;
+
+ /**
+ * The filter coefficients.
+ */
+ static const float m_coeff[];
+
+ /**
+ * The reader channels.
+ */
+ Channels m_channels;
+
+ /**
+ * The sample position in the cache.
+ */
+ unsigned int m_n;
+
+ /**
+ * The subsample position in the cache.
+ */
+ double m_P;
+
+ /**
+ * The input data buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * Double buffer for the sums.
+ */
+ Buffer m_sums;
+
+ /**
+ * How many samples in the cache are valid.
+ */
+ int m_cache_valid;
+
+ /**
+ * Resample function.
+ */
+ resample_f m_resample;
+
+ /**
+ * Last resampling factor.
+ */
+ double m_last_factor;
+
+ // delete copy constructor and operator=
+ JOSResampleReader(const JOSResampleReader&) = delete;
+ JOSResampleReader& operator=(const JOSResampleReader&) = delete;
+
+ /**
+ * Resets the resampler to its initial state.
+ */
+ void AUD_LOCAL reset();
+
+ /**
+ * Updates the buffer to be as small as possible for the coming reading.
+ * \param size The size of samples to be read.
+ * \param factor The next resampling factor.
+ * \param samplesize The size of a sample.
+ */
+ void AUD_LOCAL updateBuffer(int size, double factor, int samplesize);
+
+ void AUD_LOCAL resample(double target_factor, int length, sample_t* buffer);
+ void AUD_LOCAL resample_mono(double target_factor, int length, sample_t* buffer);
+ void AUD_LOCAL resample_stereo(double target_factor, int length, sample_t* buffer);
+
+public:
+ /**
+ * Creates a resampling reader.
+ * \param reader The reader to mix.
+ * \param rate The target sampling rate.
+ */
+ JOSResampleReader(std::shared_ptr<IReader> reader, SampleRate rate);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/LinearResample.h b/extern/audaspace/include/respec/LinearResample.h
new file mode 100644
index 00000000000..207cf2a6548
--- /dev/null
+++ b/extern/audaspace/include/respec/LinearResample.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LinearResample.h
+ * @ingroup respec
+ * The LinearResample class.
+ */
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound creates a resampling reader that does simple linear resampling.
+ */
+class AUD_API LinearResample : public SpecsChanger
+{
+private:
+ // delete copy constructor and operator=
+ LinearResample(const LinearResample&) = delete;
+ LinearResample& operator=(const LinearResample&) = delete;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The input sound.
+ * \param specs The target specifications.
+ */
+ LinearResample(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/LinearResampleReader.h b/extern/audaspace/include/respec/LinearResampleReader.h
new file mode 100644
index 00000000000..aaf95672e55
--- /dev/null
+++ b/extern/audaspace/include/respec/LinearResampleReader.h
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file LinearResampleReader.h
+ * @ingroup respec
+ * The LinearResampleReader class.
+ */
+
+#include "respec/ResampleReader.h"
+#include "util/Buffer.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This resampling reader does simple first-order hold resampling.
+ */
+class AUD_API LinearResampleReader : public ResampleReader
+{
+private:
+ /**
+ * The reader channels.
+ */
+ Channels m_channels;
+
+ /**
+ * The position in the cache.
+ */
+ float m_cache_pos;
+
+ /**
+ * The sound output buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * The input caching buffer.
+ */
+ Buffer m_cache;
+
+ /**
+ * Whether the cache contains valid data.
+ */
+ bool m_cache_ok;
+
+ // delete copy constructor and operator=
+ LinearResampleReader(const LinearResampleReader&) = delete;
+ LinearResampleReader& operator=(const LinearResampleReader&) = delete;
+
+public:
+ /**
+ * Creates a resampling reader.
+ * \param reader The reader to mix.
+ * \param rate The target sampling rate.
+ */
+ LinearResampleReader(std::shared_ptr<IReader> reader, SampleRate rate);
+
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/Mixer.h b/extern/audaspace/include/respec/Mixer.h
new file mode 100644
index 00000000000..600467826cd
--- /dev/null
+++ b/extern/audaspace/include/respec/Mixer.h
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Mixer.h
+ * @ingroup respec
+ * The Mixer class.
+ */
+
+#include "respec/Specification.h"
+#include "respec/ConverterFunctions.h"
+#include "util/Buffer.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class IReader;
+
+/**
+ * This abstract class is able to mix audiosignals with same channel count
+ * and sample rate and convert it to a specific output format.
+ */
+class AUD_API Mixer
+{
+private:
+ // delete copy constructor and operator=
+ Mixer(const Mixer&) = delete;
+ Mixer& operator=(const Mixer&) = delete;
+
+protected:
+ /**
+ * The output specification.
+ */
+ DeviceSpecs m_specs;
+
+ /**
+ * The length of the mixing buffer.
+ */
+ int m_length;
+
+ /**
+ * The mixing buffer.
+ */
+ Buffer m_buffer;
+
+ /**
+ * Converter function.
+ */
+ convert_f m_convert;
+
+public:
+ /**
+ * Creates the mixer.
+ */
+ Mixer(DeviceSpecs specs);
+
+ /**
+ * Destroys the mixer.
+ */
+ virtual ~Mixer() {}
+
+ /**
+ * Returns the target specification for superposing.
+ * \return The target specification.
+ */
+ DeviceSpecs getSpecs() const;
+
+ /**
+ * Sets the target specification for superposing.
+ * \param specs The target specification.
+ */
+ void setSpecs(Specs specs);
+
+ /**
+ * Mixes a buffer.
+ * \param buffer The buffer to superpose.
+ * \param start The start sample of the buffer.
+ * \param length The length of the buffer in samples.
+ * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
+ */
+ void mix(sample_t* buffer, int start, int length, float volume);
+
+ /**
+ * Mixes a buffer with linear volume interpolation.
+ * \param buffer The buffer to superpose.
+ * \param start The start sample of the buffer.
+ * \param length The length of the buffer in samples.
+ * \param volume_to The target mixing volume. Must be a value between 0.0 and 1.0.
+ * \param volume_from The start mixing volume. Must be a value between 0.0 and 1.0.
+ */
+ void mix(sample_t* buffer, int start, int length, float volume_to, float volume_from);
+
+ /**
+ * Writes the mixing buffer into an output buffer.
+ * \param buffer The target buffer for superposing.
+ * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
+ */
+ void read(data_t* buffer, float volume);
+
+ /**
+ * Clears the mixing buffer.
+ * \param length The length of the buffer in samples.
+ */
+ void clear(int length);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/ResampleReader.h b/extern/audaspace/include/respec/ResampleReader.h
new file mode 100644
index 00000000000..b38a8d5eb18
--- /dev/null
+++ b/extern/audaspace/include/respec/ResampleReader.h
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ResampleReader.h
+ * @ingroup respec
+ * The ResampleReader class.
+ */
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This is the base class for all resampling readers.
+ */
+class AUD_API ResampleReader : public EffectReader
+{
+protected:
+ /**
+ * The target sampling rate.
+ */
+ SampleRate m_rate;
+
+ /**
+ * Creates a resampling reader.
+ * \param reader The reader to mix.
+ * \param rate The target sampling rate.
+ */
+ ResampleReader(std::shared_ptr<IReader> reader, SampleRate rate);
+
+public:
+ /**
+ * Sets the sample rate.
+ * \param rate The target sampling rate.
+ */
+ virtual void setRate(SampleRate rate);
+
+ /**
+ * Retrieves the sample rate.
+ * \return The target sampling rate.
+ */
+ virtual SampleRate getRate();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/Specification.h b/extern/audaspace/include/respec/Specification.h
new file mode 100644
index 00000000000..efcbb4cabce
--- /dev/null
+++ b/extern/audaspace/include/respec/Specification.h
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Specification.h
+ * @ingroup respec
+ * Defines all important macros and basic data structures for stream format descriptions.
+ */
+
+#include "Audaspace.h"
+
+/// The size of a format in bytes.
+#define AUD_FORMAT_SIZE(format) (format & 0x0F)
+/// The size of a sample in the specified device format in bytes.
+#define AUD_DEVICE_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
+/// The size of a sample in the specified format in bytes.
+#define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t))
+
+/// Compares two audio data specifications.
+#define AUD_COMPARE_SPECS(s1, s2) ((s1.rate == s2.rate) && (s1.channels == s2.channels))
+
+/// Returns the bit for a channel mask.
+#define AUD_CHANNEL_BIT(channel) (0x01 << channel)
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * The format of a sample.
+ * The last 4 bit save the byte count of the format.
+ */
+enum SampleFormat
+{
+ FORMAT_INVALID = 0x00, /// Invalid sample format.
+ FORMAT_U8 = 0x01, /// 1 byte unsigned byte.
+ FORMAT_S16 = 0x12, /// 2 byte signed integer.
+ FORMAT_S24 = 0x13, /// 3 byte signed integer.
+ FORMAT_S32 = 0x14, /// 4 byte signed integer.
+ FORMAT_FLOAT32 = 0x24, /// 4 byte float.
+ FORMAT_FLOAT64 = 0x28 /// 8 byte float.
+};
+
+/// The channel count.
+enum Channels
+{
+ CHANNELS_INVALID = 0, /// Invalid channel count.
+ CHANNELS_MONO = 1, /// Mono.
+ CHANNELS_STEREO = 2, /// Stereo.
+ CHANNELS_STEREO_LFE = 3, /// Stereo with LFE channel.
+ CHANNELS_SURROUND4 = 4, /// 4 channel surround sound.
+ CHANNELS_SURROUND5 = 5, /// 5 channel surround sound.
+ CHANNELS_SURROUND51 = 6, /// 5.1 surround sound.
+ CHANNELS_SURROUND61 = 7, /// 6.1 surround sound.
+ CHANNELS_SURROUND71 = 8 /// 7.1 surround sound.
+};
+
+/// The channel names.
+enum Channel
+{
+ CHANNEL_FRONT_LEFT = 0,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_LFE,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT,
+ CHANNEL_REAR_CENTER,
+ CHANNEL_SIDE_LEFT,
+ CHANNEL_SIDE_RIGHT,
+ CHANNEL_MAX
+};
+
+/**
+ * The sample rate tells how many samples are played back within one second.
+ * Some exotic formats may use other sample rates than provided here.
+ */
+enum DefaultSampleRate
+{
+ RATE_INVALID = 0, /// Invalid sample rate.
+ RATE_8000 = 8000, /// 8000 Hz.
+ RATE_16000 = 16000, /// 16000 Hz.
+ RATE_11025 = 11025, /// 11025 Hz.
+ RATE_22050 = 22050, /// 22050 Hz.
+ RATE_32000 = 32000, /// 32000 Hz.
+ RATE_44100 = 44100, /// 44100 Hz.
+ RATE_48000 = 48000, /// 48000 Hz.
+ RATE_88200 = 88200, /// 88200 Hz.
+ RATE_96000 = 96000, /// 96000 Hz.
+ RATE_192000 = 192000 /// 192000 Hz.
+};
+
+/// Sample rate type.
+typedef double SampleRate;
+
+/// Specification of a sound source.
+struct Specs
+{
+ /// Sample rate in Hz.
+ SampleRate rate;
+
+ /// Channel count.
+ Channels channels;
+};
+
+/// Specification of a sound device.
+struct DeviceSpecs
+{
+ /// Sample format.
+ SampleFormat format;
+
+ union
+ {
+ struct
+ {
+ /// Sample rate in Hz.
+ SampleRate rate;
+
+ /// Channel count.
+ Channels channels;
+ };
+ Specs specs;
+ };
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/respec/SpecsChanger.h b/extern/audaspace/include/respec/SpecsChanger.h
new file mode 100644
index 00000000000..2eb9f369497
--- /dev/null
+++ b/extern/audaspace/include/respec/SpecsChanger.h
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SpecsChanger.h
+ * @ingroup respec
+ * The SpecsChanger class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound is a base class for all mixer factories.
+ */
+class AUD_API SpecsChanger : public ISound
+{
+protected:
+ /**
+ * The target specification for resampling.
+ */
+ const DeviceSpecs m_specs;
+
+ /**
+ * If there is no reader it is created out of this sound.
+ */
+ std::shared_ptr<ISound> m_sound;
+
+ /**
+ * Returns the reader created out of the sound.
+ * This method can be used for the createReader function of the implementing
+ * classes.
+ * \return The reader to mix.
+ */
+ std::shared_ptr<IReader> getReader() const;
+
+public:
+ /**
+ * Creates a new sound.
+ * \param sound The sound to create the readers to mix out of.
+ * \param specs The target specification.
+ */
+ SpecsChanger(std::shared_ptr<ISound> sound, DeviceSpecs specs);
+
+ /**
+ * Returns the target specification for resampling.
+ */
+ DeviceSpecs getSpecs() const;
+
+ /**
+ * Returns the saved sound.
+ * \return The sound.
+ */
+ std::shared_ptr<ISound> getSound() const;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/AnimateableProperty.h b/extern/audaspace/include/sequence/AnimateableProperty.h
new file mode 100644
index 00000000000..2c3fcf23f8b
--- /dev/null
+++ b/extern/audaspace/include/sequence/AnimateableProperty.h
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file AnimateableProperty.h
+ * @ingroup sequence
+ * Defines the AnimateableProperty class as well as existing property types.
+ */
+
+#include "util/Buffer.h"
+#include "util/ILockable.h"
+
+#include <mutex>
+#include <list>
+
+AUD_NAMESPACE_BEGIN
+
+/// Possible animatable properties for Sequencer Factories and Entries.
+enum AnimateablePropertyType
+{
+ AP_VOLUME,
+ AP_PANNING,
+ AP_PITCH,
+ AP_LOCATION,
+ AP_ORIENTATION
+};
+
+/**
+ * This class saves animation data for float properties.
+ */
+class AUD_API AnimateableProperty : private Buffer
+{
+private:
+ struct Unknown {
+ int start;
+ int end;
+
+ Unknown(int start, int end) :
+ start(start), end(end) {}
+ };
+
+ /// The count of floats for a single property.
+ const int m_count;
+
+ /// Whether the property is animated or not.
+ bool m_isAnimated;
+
+ /// The mutex for locking.
+ std::recursive_mutex m_mutex;
+
+ /// The list of unknown buffer areas.
+ std::list<Unknown> m_unknown;
+
+ // delete copy constructor and operator=
+ AnimateableProperty(const AnimateableProperty&) = delete;
+ AnimateableProperty& operator=(const AnimateableProperty&) = delete;
+
+ void AUD_LOCAL updateUnknownCache(int start, int end);
+
+public:
+ /**
+ * Creates a new animateable property.
+ * \param count The count of floats for a single property.
+ */
+ AnimateableProperty(int count = 1);
+
+ /**
+ * Creates a new animateable property.
+ * \param count The count of floats for a single property.
+ * \param value The value that the property should get initialized with.
+ * All count floats will be initialized to the same value.
+ */
+ AnimateableProperty(int count, float value);
+
+ /**
+ * Destroys the animateable property.
+ */
+ ~AnimateableProperty();
+
+ /**
+ * Returns the count of floats for a single property.
+ * \return The count of floats stored per frame.
+ */
+ int getCount() const;
+
+ /**
+ * Writes the properties value and marks it non-animated.
+ * \param data The new value.
+ */
+ void write(const float* data);
+
+ /**
+ * Writes the properties value and marks it animated.
+ * \param data The new value.
+ * \param position The position in the animation in frames.
+ * \param count The count of frames to write.
+ */
+ void write(const float* data, int position, int count);
+
+ /**
+ * Reads the properties value.
+ * \param position The position in the animation in frames.
+ * \param[out] out Where to write the value to.
+ */
+ void read(float position, float* out);
+
+ /**
+ * Returns whether the property is animated.
+ * \return Whether the property is animated.
+ */
+ bool isAnimated() const;
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/Double.h b/extern/audaspace/include/sequence/Double.h
new file mode 100644
index 00000000000..dc40ae29e0d
--- /dev/null
+++ b/extern/audaspace/include/sequence/Double.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Double.h
+ * @ingroup sequence
+ * The Double class.
+ */
+
+#include "ISound.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound plays two other factories behind each other.
+ */
+class AUD_API Double : public ISound
+{
+private:
+ /**
+ * First played sound.
+ */
+ std::shared_ptr<ISound> m_sound1;
+
+ /**
+ * Second played sound.
+ */
+ std::shared_ptr<ISound> m_sound2;
+
+ // delete copy constructor and operator=
+ Double(const Double&) = delete;
+ Double& operator=(const Double&) = delete;
+
+public:
+ /**
+ * Creates a new double sound.
+ * \param sound1 The first input sound.
+ * \param sound2 The second input sound.
+ */
+ Double(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/DoubleReader.h b/extern/audaspace/include/sequence/DoubleReader.h
new file mode 100644
index 00000000000..012dcc8e832
--- /dev/null
+++ b/extern/audaspace/include/sequence/DoubleReader.h
@@ -0,0 +1,77 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file DoubleReader.h
+ * @ingroup sequence
+ * The DoubleReader class.
+ */
+
+#include "IReader.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This reader plays two readers sequently.
+ */
+class AUD_API DoubleReader : public IReader
+{
+private:
+ /**
+ * The first reader.
+ */
+ std::shared_ptr<IReader> m_reader1;
+
+ /**
+ * The second reader.
+ */
+ std::shared_ptr<IReader> m_reader2;
+
+ /**
+ * Whether we've reached the end of the first reader.
+ */
+ bool m_finished1;
+
+ // delete copy constructor and operator=
+ DoubleReader(const DoubleReader&) = delete;
+ DoubleReader& operator=(const DoubleReader&) = delete;
+
+public:
+ /**
+ * Creates a new double reader.
+ * \param reader1 The first reader to read from.
+ * \param reader2 The second reader to read from.
+ */
+ DoubleReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~DoubleReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/PingPong.h b/extern/audaspace/include/sequence/PingPong.h
new file mode 100644
index 00000000000..8b1bf792095
--- /dev/null
+++ b/extern/audaspace/include/sequence/PingPong.h
@@ -0,0 +1,50 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file PingPong.h
+ * @ingroup sequence
+ * The PingPong class.
+ */
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound plays another sound first normal, then reversed.
+ * \note Readers from the underlying sound must be reversable with seeking.
+ */
+class AUD_API PingPong : public Effect
+{
+private:
+ // delete copy constructor and operator=
+ PingPong(const PingPong&) = delete;
+ PingPong& operator=(const PingPong&) = delete;
+
+public:
+ /**
+ * Creates a new ping pong sound.
+ * \param sound The input sound.
+ */
+ PingPong(std::shared_ptr<ISound> sound);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.h b/extern/audaspace/include/sequence/Sequence.h
index 3ef847d4b34..7005171e2c8 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.h
+++ b/extern/audaspace/include/sequence/Sequence.h
@@ -1,58 +1,52 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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_SequencerFactory.h
- * \ingroup audaspaceintern
- */
+ * 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.
+ ******************************************************************************/
+#pragma once
-#ifndef __AUD_SEQUENCERFACTORY_H__
-#define __AUD_SEQUENCERFACTORY_H__
+/**
+ * @file Sequence.h
+ * @ingroup sequence
+ * The Sequence class.
+ */
-#include "AUD_IFactory.h"
-#include "AUD_AnimateableProperty.h"
-//#include "AUD_ILockable.h"
-#include "AUD_Sequencer.h"
+#include "ISound.h"
+#include "respec/Specification.h"
+#include "devices/I3DDevice.h"
+#include "sequence/AnimateableProperty.h"
#include <list>
-#include <pthread.h>
-class AUD_SequencerEntry;
+AUD_NAMESPACE_BEGIN
+
+class SequenceEntry;
+class SequenceData;
/**
- * This factory represents sequenced entries to play a sound scene.
+ * This sound represents sequenced entries to play a sound scene.
*/
-class AUD_SequencerFactory : public AUD_IFactory//, public AUD_ILockable
+class AUD_API Sequence : public ISound
{
- friend class AUD_SequencerReader;
+ friend class SequenceReader;
private:
/// The sequence.
- boost::shared_ptr<AUD_Sequencer> m_sequence;
+ std::shared_ptr<SequenceData> m_sequence;
- // hide copy constructor and operator=
- AUD_SequencerFactory(const AUD_SequencerFactory&);
- AUD_SequencerFactory& operator=(const AUD_SequencerFactory&);
+ // delete copy constructor and operator=
+ Sequence(const Sequence&) = delete;
+ Sequence& operator=(const Sequence&) = delete;
public:
/**
@@ -61,25 +55,25 @@ public:
* \param fps The FPS of the scene.
* \param muted Whether the whole scene is muted.
*/
- AUD_SequencerFactory(AUD_Specs specs, float fps, bool muted);
+ Sequence(Specs specs, float fps, bool muted);
-#if 0
/**
- * Locks the factory.
+ * Retrieves the audio output specification.
+ * \return The specification.
*/
- virtual void lock();
+ Specs getSpecs();
/**
- * Unlocks the previously locked factory.
+ * Sets the audio output specification.
+ * \param specs The new specification.
*/
- virtual void unlock();
-#endif
+ void setSpecs(Specs specs);
/**
- * Sets the audio output specification.
- * \param specs The new specification.
+ * Retrieves the scene's FPS.
+ * \return The scene's FPS.
*/
- void setSpecs(AUD_Specs specs);
+ float getFPS() const;
/**
* Sets the scene's FPS.
@@ -97,7 +91,7 @@ public:
* Retrieves the muting state of the scene.
* \return Whether the scene is muted.
*/
- bool getMute() const;
+ bool isMuted() const;
/**
* Retrieves the speed of sound.
@@ -133,21 +127,21 @@ public:
* Retrieves the distance model.
* \return The distance model.
*/
- AUD_DistanceModel getDistanceModel() const;
+ DistanceModel getDistanceModel() const;
/**
* Sets the distance model.
* \param model distance model.
*/
- void setDistanceModel(AUD_DistanceModel model);
+ void setDistanceModel(DistanceModel model);
/**
- * Retrieves one of the animated properties of the factory.
+ * Retrieves one of the animated properties of the sound.
* \param type Which animated property to retrieve.
* \return A pointer to the animated property, valid as long as the
- * factory is.
+ * sound is.
*/
- AUD_AnimateableProperty* getAnimProperty(AUD_AnimateablePropertyType type);
+ AnimateableProperty* getAnimProperty(AnimateablePropertyType type);
/**
* Adds a new entry to the scene.
@@ -157,21 +151,21 @@ public:
* \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);
+ std::shared_ptr<SequenceEntry> add(std::shared_ptr<ISound> 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);
+ void remove(std::shared_ptr<SequenceEntry> entry);
/**
* Creates a new reader with high quality resampling.
* \return The new reader.
*/
- boost::shared_ptr<AUD_IReader> createQualityReader();
+ std::shared_ptr<IReader> createQualityReader();
- virtual boost::shared_ptr<AUD_IReader> createReader();
+ virtual std::shared_ptr<IReader> createReader();
};
-#endif //__AUD_SEQUENCERFACTORY_H__
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_Sequencer.h b/extern/audaspace/include/sequence/SequenceData.h
index 1066eeae8e3..b3df0548a4d 100644
--- a/intern/audaspace/intern/AUD_Sequencer.h
+++ b/extern/audaspace/include/sequence/SequenceData.h
@@ -1,53 +1,50 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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
- */
+ * 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.
+ ******************************************************************************/
+#pragma once
-#ifndef __AUD_SEQUENCER_H__
-#define __AUD_SEQUENCER_H__
+/**
+ * @file SequenceData.h
+ * @ingroup sequence
+ * The SequenceData class.
+ */
-#include "AUD_AnimateableProperty.h"
-#include "AUD_IFactory.h"
-#include "AUD_ILockable.h"
+#include "respec/Specification.h"
+#include "sequence/AnimateableProperty.h"
+#include "devices/I3DDevice.h"
+#include "util/ILockable.h"
#include <list>
-#include <pthread.h>
+#include <memory>
+#include <mutex>
-class AUD_SequencerEntry;
+AUD_NAMESPACE_BEGIN
+
+class SequenceEntry;
+class ISound;
/**
* This class represents sequenced entries to play a sound scene.
*/
-class AUD_Sequencer : public AUD_ILockable
+class AUD_API SequenceData : public ILockable
{
- friend class AUD_SequencerReader;
+ friend class SequenceReader;
private:
/// The target specification.
- AUD_Specs m_specs;
+ Specs m_specs;
/// The status of the sequence. Changes every time a non-animated parameter changes.
int m_status;
@@ -59,7 +56,7 @@ private:
int m_id;
/// The sequenced entries.
- std::list<boost::shared_ptr<AUD_SequencerEntry> > m_entries;
+ std::list<std::shared_ptr<SequenceEntry> > m_entries;
/// Whether the whole scene is muted.
bool m_muted;
@@ -74,23 +71,23 @@ private:
float m_doppler_factor;
/// Distance model.
- AUD_DistanceModel m_distance_model;
+ DistanceModel m_distance_model;
/// The animated volume.
- AUD_AnimateableProperty m_volume;
+ AnimateableProperty m_volume;
/// The animated listener location.
- AUD_AnimateableProperty m_location;
+ AnimateableProperty m_location;
/// The animated listener orientation.
- AUD_AnimateableProperty m_orientation;
+ AnimateableProperty m_orientation;
/// The mutex for locking.
- pthread_mutex_t m_mutex;
+ std::recursive_mutex m_mutex;
- // hide copy constructor and operator=
- AUD_Sequencer(const AUD_Sequencer&);
- AUD_Sequencer& operator=(const AUD_Sequencer&);
+ // delete copy constructor and operator=
+ SequenceData(const SequenceData&) = delete;
+ SequenceData& operator=(const SequenceData&) = delete;
public:
/**
@@ -99,8 +96,8 @@ public:
* \param fps The FPS of the scene.
* \param muted Whether the whole scene is muted.
*/
- AUD_Sequencer(AUD_Specs specs, float fps, bool muted);
- virtual ~AUD_Sequencer();
+ SequenceData(Specs specs, float fps, bool muted);
+ virtual ~SequenceData();
/**
* Locks the sequence.
@@ -113,10 +110,22 @@ public:
virtual void unlock();
/**
+ * Retrieves the audio output specification.
+ * \return The specification.
+ */
+ Specs getSpecs();
+
+ /**
* Sets the audio output specification.
* \param specs The new specification.
*/
- void setSpecs(AUD_Specs specs);
+ void setSpecs(Specs specs);
+
+ /**
+ * Retrieves the scene's FPS.
+ * \return The scene's FPS.
+ */
+ float getFPS() const;
/**
* Sets the scene's FPS.
@@ -134,7 +143,7 @@ public:
* Retrieves the muting state of the scene.
* \return Whether the scene is muted.
*/
- bool getMute() const;
+ bool isMuted() const;
/**
* Retrieves the speed of sound.
@@ -170,13 +179,13 @@ public:
* Retrieves the distance model.
* \return The distance model.
*/
- AUD_DistanceModel getDistanceModel() const;
+ DistanceModel getDistanceModel() const;
/**
* Sets the distance model.
* \param model distance model.
*/
- void setDistanceModel(AUD_DistanceModel model);
+ void setDistanceModel(DistanceModel model);
/**
* Retrieves one of the animated properties of the sequence.
@@ -184,7 +193,7 @@ public:
* \return A pointer to the animated property, valid as long as the
* sequence is.
*/
- AUD_AnimateableProperty* getAnimProperty(AUD_AnimateablePropertyType type);
+ AnimateableProperty* getAnimProperty(AnimateablePropertyType type);
/**
* Adds a new entry to the scene.
@@ -194,13 +203,13 @@ public:
* \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);
+ std::shared_ptr<SequenceEntry> add(std::shared_ptr<ISound> 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);
+ void remove(std::shared_ptr<SequenceEntry> entry);
};
-#endif //__AUD_SEQUENCER_H__
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SequencerEntry.h b/extern/audaspace/include/sequence/SequenceEntry.h
index aa1edebfc2f..98f15faf7ff 100644
--- a/intern/audaspace/intern/AUD_SequencerEntry.h
+++ b/extern/audaspace/include/sequence/SequenceEntry.h
@@ -1,48 +1,43 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_SequencerEntry.h
- * \ingroup audaspaceintern
+#pragma once
+
+/**
+ * @file SequenceEntry.h
+ * @ingroup sequence
+ * The SequenceEntry class.
*/
+#include "sequence/AnimateableProperty.h"
+#include "util/ILockable.h"
-#ifndef __AUD_SEQUENCERENTRY_H__
-#define __AUD_SEQUENCERENTRY_H__
+#include <mutex>
+#include <memory>
-#include "AUD_AnimateableProperty.h"
-#include "AUD_IFactory.h"
-#include "AUD_ILockable.h"
+AUD_NAMESPACE_BEGIN
-#include <pthread.h>
-#include <boost/shared_ptr.hpp>
+class ISound;
/**
- * This class represents a sequenced entry in a sequencer factory.
+ * This class represents a sequenced entry in a sequencer sound.
*/
-class AUD_SequencerEntry : public AUD_ILockable
+class AUD_API SequenceEntry : public ILockable
{
- friend class AUD_SequencerHandle;
+ friend class SequenceHandle;
private:
/// The status of the entry. Changes every time a non-animated parameter changes.
int m_status;
@@ -53,11 +48,11 @@ private:
/// The sound status, changed when the sound is changed.
int m_sound_status;
- /// The unique (regarding the factory) ID of the entry.
+ /// The unique (regarding the sound) ID of the entry.
int m_id;
/// The sound this entry plays.
- boost::shared_ptr<AUD_IFactory> m_sound;
+ std::shared_ptr<ISound> m_sound;
/// The begin time.
float m_begin;
@@ -99,22 +94,26 @@ private:
float m_cone_volume_outer;
/// The mutex for locking.
- pthread_mutex_t m_mutex;
+ std::recursive_mutex m_mutex;
/// The animated volume.
- AUD_AnimateableProperty m_volume;
+ AnimateableProperty m_volume;
/// The animated panning.
- AUD_AnimateableProperty m_panning;
+ AnimateableProperty m_panning;
/// The animated pitch.
- AUD_AnimateableProperty m_pitch;
+ AnimateableProperty m_pitch;
/// The animated location.
- AUD_AnimateableProperty m_location;
+ AnimateableProperty m_location;
/// The animated orientation.
- AUD_AnimateableProperty m_orientation;
+ AnimateableProperty m_orientation;
+
+ // delete copy constructor and operator=
+ SequenceEntry(const SequenceEntry&) = delete;
+ SequenceEntry& operator=(const SequenceEntry&) = delete;
public:
/**
@@ -125,8 +124,8 @@ public:
* \param skip How much seconds should be skipped at the beginning.
* \param id The ID of the entry.
*/
- AUD_SequencerEntry(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip, int id);
- virtual ~AUD_SequencerEntry();
+ SequenceEntry(std::shared_ptr<ISound> sound, float begin, float end, float skip, int id);
+ virtual ~SequenceEntry();
/**
* Locks the entry.
@@ -139,10 +138,16 @@ public:
virtual void unlock();
/**
+ * Retrieves the sound of the entry.
+ * \return The sound.
+ */
+ std::shared_ptr<ISound> getSound();
+
+ /**
* Sets the sound of the entry.
* \param sound The new sound.
*/
- void setSound(boost::shared_ptr<AUD_IFactory> sound);
+ void setSound(std::shared_ptr<ISound> sound);
/**
* Moves the entry.
@@ -153,6 +158,12 @@ public:
void move(float begin, float end, float skip);
/**
+ * Retrieves the muting state of the entry.
+ * \return Whether the entry should is muted or not.
+ */
+ bool isMuted();
+
+ /**
* Sets the muting state of the entry.
* \param mute Whether the entry should be muted or not.
*/
@@ -170,22 +181,7 @@ public:
* \return A pointer to the animated property, valid as long as the
* entry is.
*/
- AUD_AnimateableProperty* getAnimProperty(AUD_AnimateablePropertyType type);
-
- /**
- * Updates all non-animated parameters of the entry.
- * \param volume_max The maximum volume.
- * \param volume_min The minimum volume.
- * \param distance_max The maximum distance.
- * \param distance_reference The reference distance.
- * \param attenuation The attenuation.
- * \param cone_angle_outer The outer cone opening angle.
- * \param cone_angle_inner The inner cone opening angle.
- * \param cone_volume_outer The volume outside the outer cone.
- */
- void updateAll(float volume_max, float volume_min, float distance_max,
- float distance_reference, float attenuation, float cone_angle_outer,
- float cone_angle_inner, float cone_volume_outer);
+ AnimateableProperty* getAnimProperty(AnimateablePropertyType type);
/**
* Checks whether the source location, velocity and orientation are relative
@@ -316,4 +312,4 @@ public:
void setConeVolumeOuter(float volume);
};
-#endif //__AUD_SEQUENCERENTRY_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/SequenceReader.h b/extern/audaspace/include/sequence/SequenceReader.h
new file mode 100644
index 00000000000..196d969e102
--- /dev/null
+++ b/extern/audaspace/include/sequence/SequenceReader.h
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SequenceReader.h
+ * @ingroup sequence
+ * The SequenceReader class.
+ */
+
+#include "IReader.h"
+#include "devices/ReadDevice.h"
+
+AUD_NAMESPACE_BEGIN
+
+class SequenceHandle;
+class SequenceData;
+
+/**
+ * This reader plays back sequenced entries.
+ */
+class AUD_API SequenceReader : public IReader
+{
+private:
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ /**
+ * The read device used to mix the sounds correctly.
+ */
+ ReadDevice m_device;
+
+ /**
+ * Saves the sequence the reader belongs to.
+ */
+ std::shared_ptr<SequenceData> m_sequence;
+
+ /**
+ * The list of playback handles for the entries.
+ */
+ std::list<std::shared_ptr<SequenceHandle> > m_handles;
+
+ /**
+ * Last status read from the sequence.
+ */
+ int m_status;
+
+ /**
+ * Last entry status read from the sequence.
+ */
+ int m_entry_status;
+
+ // delete copy constructor and operator=
+ SequenceReader(const SequenceReader&) = delete;
+ SequenceReader& operator=(const SequenceReader&) = delete;
+
+public:
+ /**
+ * Creates a resampling reader.
+ * \param sequence The sequence data.
+ * \param quality Whether a high quality resample should be used for resampling.
+ */
+ SequenceReader(std::shared_ptr<SequenceData> sequence, bool quality = false);
+
+ /**
+ * Destroys the reader.
+ */
+ ~SequenceReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/Superpose.h b/extern/audaspace/include/sequence/Superpose.h
new file mode 100644
index 00000000000..2a3a6166b3b
--- /dev/null
+++ b/extern/audaspace/include/sequence/Superpose.h
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Superpose.h
+ * @ingroup sequence
+ * The Superpose class.
+ */
+
+#include "ISound.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This sound mixes two other factories, playing them the same time.
+ * \note Readers from the underlying factories must have the same sample rate
+ * and channel count.
+ */
+class AUD_API Superpose : public ISound
+{
+private:
+ /**
+ * First played sound.
+ */
+ std::shared_ptr<ISound> m_sound1;
+
+ /**
+ * Second played sound.
+ */
+ std::shared_ptr<ISound> m_sound2;
+
+ // delete copy constructor and operator=
+ Superpose(const Superpose&) = delete;
+ Superpose& operator=(const Superpose&) = delete;
+
+public:
+ /**
+ * Creates a new superpose sound.
+ * \param sound1 The first input sound.
+ * \param sound2 The second input sound.
+ */
+ Superpose(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2);
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/sequence/SuperposeReader.h b/extern/audaspace/include/sequence/SuperposeReader.h
new file mode 100644
index 00000000000..8bd38ade4c3
--- /dev/null
+++ b/extern/audaspace/include/sequence/SuperposeReader.h
@@ -0,0 +1,79 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file SuperposeReader.h
+ * @ingroup sequence
+ * The SuperposeReader class.
+ */
+
+#include "IReader.h"
+#include "util/Buffer.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This reader plays two readers with the same specs in parallel.
+ */
+class AUD_API SuperposeReader : public IReader
+{
+private:
+ /**
+ * The first reader.
+ */
+ std::shared_ptr<IReader> m_reader1;
+
+ /**
+ * The second reader.
+ */
+ std::shared_ptr<IReader> m_reader2;
+
+ /**
+ * Buffer used for mixing.
+ */
+ Buffer m_buffer;
+
+ // delete copy constructor and operator=
+ SuperposeReader(const SuperposeReader&) = delete;
+ SuperposeReader& operator=(const SuperposeReader&) = delete;
+
+public:
+ /**
+ * Creates a new superpose reader.
+ * \param reader1 The first reader to read from.
+ * \param reader2 The second reader to read from.
+ * \exception Exception Thrown if the specs from the readers differ.
+ */
+ SuperposeReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~SuperposeReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/Barrier.h b/extern/audaspace/include/util/Barrier.h
new file mode 100644
index 00000000000..d9e8bf07f82
--- /dev/null
+++ b/extern/audaspace/include/util/Barrier.h
@@ -0,0 +1,78 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file Barrier.h
+* @ingroup util
+* The Barrier class.
+*/
+
+#include "Audaspace.h"
+
+#include <mutex>
+#include <condition_variable>
+
+AUD_NAMESPACE_BEGIN
+/**
+* This represents a barrier mechanism for thread sychronization.
+*/
+class Barrier
+{
+private:
+ /**
+ * A mutex needed to use a condition variable.
+ */
+ std::mutex m_mutex;
+
+ /**
+ * Condition varieble used to sync threads.
+ */
+ std::condition_variable m_condition;
+
+ /**
+ * Number of threads that need to reach the barrier for it to lift.
+ */
+ unsigned int m_threshold;
+
+ /**
+ * Conter that count from threshold to 0.
+ */
+ unsigned int m_count;
+
+ /**
+ * Variable used for predicate check in the condition variable wait.
+ */
+ unsigned int m_generation;
+
+ // delete copy constructor and operator=
+ Barrier(const Barrier&) = delete;
+ Barrier& operator=(const Barrier&) = delete;
+public:
+ /**
+ * Creates a new Barrier object.
+ * \param count the number of threads that need to reach the barrier for it to lift.
+ */
+ Barrier(unsigned int count);
+ virtual ~Barrier();
+
+ /**
+ * Makes the caller thread wait until enough threads are stopped by this method.
+ */
+ void wait();
+};
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/include/util/Buffer.h b/extern/audaspace/include/util/Buffer.h
new file mode 100644
index 00000000000..9934e53625e
--- /dev/null
+++ b/extern/audaspace/include/util/Buffer.h
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file Buffer.h
+ * @ingroup util
+ * The Buffer class.
+ */
+
+#include "Audaspace.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is a simple buffer in RAM which is 32 Byte aligned and provides
+ * resize functionality.
+ */
+class AUD_API Buffer
+{
+private:
+ /// The size of the buffer in bytes.
+ int m_size;
+
+ /// The pointer to the buffer memory.
+ data_t* m_buffer;
+
+ // delete copy constructor and operator=
+ Buffer(const Buffer&) = delete;
+ Buffer& operator=(const Buffer&) = delete;
+
+public:
+ /**
+ * Creates a new buffer.
+ * \param size The size of the buffer in bytes.
+ */
+ Buffer(int size = 0);
+
+ /**
+ * Destroys the buffer.
+ */
+ ~Buffer();
+
+ /**
+ * Returns the pointer to the buffer in memory.
+ */
+ sample_t* getBuffer() const;
+
+ /**
+ * Returns the size of the buffer in bytes.
+ */
+ int getSize() const;
+
+ /**
+ * Resizes the buffer.
+ * \param size The new size of the buffer, measured in bytes.
+ * \param keep Whether to keep the old data. If the new buffer is smaller,
+ * the data at the end will be lost.
+ */
+ void resize(int size, bool keep = false);
+
+ /**
+ * Makes sure the buffer has a minimum size.
+ * If size is >= current size, nothing will happen.
+ * Otherwise the buffer is resized with keep as parameter.
+ * \param size The new minimum size of the buffer, measured in bytes.
+ * \param keep Whether to keep the old data. If the new buffer is smaller,
+ * the data at the end will be lost.
+ */
+ void assureSize(int size, bool keep = false);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/BufferReader.h b/extern/audaspace/include/util/BufferReader.h
new file mode 100644
index 00000000000..b98313726bc
--- /dev/null
+++ b/extern/audaspace/include/util/BufferReader.h
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file BufferReader.h
+ * @ingroup util
+ * The BufferReader class.
+ */
+
+#include "IReader.h"
+
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class Buffer;
+
+/**
+ * This class represents a simple reader from a buffer that exists in memory.
+ * \warning Notice that the buffer is not multi-threading ready, so changing the
+ * buffer while the reader is reading is potentially dangerous.
+ */
+class AUD_API BufferReader : public IReader
+{
+private:
+ /**
+ * The current position in the buffer.
+ */
+ int m_position;
+
+ /**
+ * The buffer that is read.
+ */
+ std::shared_ptr<Buffer> m_buffer;
+
+ /**
+ * The specification of the sample data in the buffer.
+ */
+ Specs m_specs;
+
+ // delete copy constructor and operator=
+ BufferReader(const BufferReader&) = delete;
+ BufferReader& operator=(const BufferReader&) = delete;
+
+public:
+ /**
+ * Creates a new buffer reader.
+ * \param buffer The buffer to read from.
+ * \param specs The specification of the sample data in the buffer.
+ */
+ BufferReader(std::shared_ptr<Buffer> buffer, Specs specs);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/FFTPlan.h b/extern/audaspace/include/util/FFTPlan.h
new file mode 100644
index 00000000000..7d533ca8773
--- /dev/null
+++ b/extern/audaspace/include/util/FFTPlan.h
@@ -0,0 +1,120 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file FFTPlan.h
+* @ingroup util
+* The FFTPlan class.
+*/
+
+#include <complex>
+#include <fftw3.h>
+#include "Audaspace.h"
+
+#include <memory>
+#include <vector>
+
+/**Default FFT size.*/
+#define DEFAULT_N 4096
+
+AUD_NAMESPACE_BEGIN
+
+/**
+* Thas class represents an plan object that allows to calculate FFTs and IFFTs.
+*/
+class AUD_API FFTPlan
+{
+private:
+ /**
+ * The size of the FFT plan.
+ */
+ int m_N;
+
+ /**
+ * The plan to transform the input to the frequency domain.
+ */
+ fftwf_plan m_fftPlanR2C;
+
+ /**
+ * The plan to transform the input to the time domain again.
+ */
+ fftwf_plan m_fftPlanC2R;
+
+ /**
+ * The size of a buffer for its use with the FFT plan (in bytes).
+ */
+ unsigned int m_bufferSize;
+
+ // delete copy constructor and operator=
+ FFTPlan(const FFTPlan&) = delete;
+ FFTPlan& operator=(const FFTPlan&) = delete;
+
+public:
+ /**
+ * Creates a new FFTPlan object with DEFAULT_N size (4096).
+ * \param measureTime The aproximate amount of seconds that FFTW will spend searching for the optimal plan,
+ * which means faster FFTs and IFFTs while using this plan. If measureTime is negative, it will take all the time it needs.
+ */
+ FFTPlan(double measureTime = 0);
+
+ /**
+ * Creates a new FFTPlan object with a custom size.
+ * \param n The size of the FFT plan. Values that are a power of two are faster.
+ * The useful range usually is between 2048 and 8192, but bigger values can be useful
+ * in certain situations (when using the StreamBuffer class per example).
+ * Generally, low values use more CPU power and are a bit faster than large ones,
+ * there is also a huge decrease in efficiency when n is lower than 2048.
+ * \param measureTime The aproximate amount of seconds that FFTW will spend searching for the optimal plan,
+ * which means faster FFTs while using this plan. If measureTime is negative, it will take all the time it needs.
+ */
+ FFTPlan(int n, double measureTime = 0);
+ ~FFTPlan();
+
+ /**
+ * Retrieves the size of the FFT plan.
+ * \return The size of the plan.
+ */
+ int getSize();
+
+ /**
+ * Calculates the FFT of an input buffer with the current plan.
+ * \param[in,out] buffer A buffer with the input data an in which the output data will be written.
+ */
+ void FFT(void* buffer);
+
+ /**
+ * Calculates the IFFT of an input buffer with the current plan.
+ * \param[in,out] buffer A buffer with the input data an in which the output data will be written.
+ */
+ void IFFT(void* buffer);
+
+ /**
+ * Reserves memory for a buffer that can be used for inplace transformations with this plan.
+ * \return A pointer to a buffer of size ((N/2)+1)*2*sizeof(fftwf_complex).
+ * \warning The returned buffer must be freed with the freeBuffer method of this class.
+ */
+ void* getBuffer();
+
+ /**
+ * Frees one of the buffers reserved with the getRealOnlyBuffer(), getComplexOnlyBuffer() or getInplaceBuffer() method.
+ * \param buffer A pointer to the buufer taht must be freed.
+ */
+ void freeBuffer(void* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/ILockable.h b/extern/audaspace/include/util/ILockable.h
new file mode 100644
index 00000000000..8300fbd2845
--- /dev/null
+++ b/extern/audaspace/include/util/ILockable.h
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file ILockable.h
+ * @ingroup util
+ * The ILockable interface.
+ */
+
+#include "Audaspace.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * @interface ILockable
+ * This class provides an interface for lockable objects.
+ */
+class AUD_API ILockable
+{
+public:
+ /**
+ * Locks the object.
+ */
+ virtual void lock()=0;
+ /**
+ * Unlocks the previously locked object.
+ */
+ virtual void unlock()=0;
+};
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_3DMath.h b/extern/audaspace/include/util/Math3D.h
index 1b109ebee1e..7ded12c1ba8 100644
--- a/intern/audaspace/intern/AUD_3DMath.h
+++ b/extern/audaspace/include/util/Math3D.h
@@ -1,42 +1,38 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_3DMath.h
- * \ingroup audaspaceintern
- */
+#pragma once
+/**
+ * @file Math3D.h
+ * @ingroup util
+ * Defines the Vector3 and Quaternion classes.
+ */
-#ifndef __AUD_3DMATH_H__
-#define __AUD_3DMATH_H__
+#include "Audaspace.h"
#include <cmath>
#include <cstring>
+AUD_NAMESPACE_BEGIN
+
/**
* This class represents a 3 dimensional vector.
*/
-class AUD_Vector3
+class AUD_API Vector3
{
private:
/**
@@ -60,7 +56,7 @@ public:
* \param y The y component.
* \param z The z component.
*/
- inline AUD_Vector3(float x = 0, float y = 0, float z = 0) :
+ inline Vector3(float x = 0, float y = 0, float z = 0) :
m_x(x), m_y(y), m_z(z)
{
}
@@ -98,7 +94,7 @@ public:
*/
inline void get(float* destination) const
{
- memcpy(destination, m_v, sizeof(m_v));
+ std::memcpy(destination, m_v, sizeof(m_v));
}
/**
@@ -125,7 +121,7 @@ public:
*/
inline float length() const
{
- return sqrt(m_x*m_x + m_y*m_y + m_z*m_z);
+ return std::sqrt(m_x*m_x + m_y*m_y + m_z*m_z);
}
/**
@@ -133,11 +129,11 @@ public:
* \param op The second operand.
* \return The cross product of the two vectors.
*/
- inline AUD_Vector3 cross(const AUD_Vector3& op) const
+ inline Vector3 cross(const Vector3& op) const
{
- return AUD_Vector3(m_y * op.m_z - m_z * op.m_y,
- m_z * op.m_x - m_x * op.m_z,
- m_x * op.m_y - m_y * op.m_x);
+ return Vector3(m_y * op.m_z - m_z * op.m_y,
+ m_z * op.m_x - m_x * op.m_z,
+ m_x * op.m_y - m_y * op.m_x);
}
/**
@@ -145,7 +141,7 @@ public:
* \param op The second operand.
* \return The dot product of the two vectors.
*/
- inline float operator*(const AUD_Vector3& op) const
+ inline float operator*(const Vector3& op) const
{
return m_x * op.m_x + m_y * op.m_y + m_z * op.m_z;
}
@@ -155,9 +151,9 @@ public:
* \param op The second operand.
* \return The scaled vector.
*/
- inline AUD_Vector3 operator*(const float& op) const
+ inline Vector3 operator*(const float& op) const
{
- return AUD_Vector3(m_x * op, m_y * op, m_z * op);
+ return Vector3(m_x * op, m_y * op, m_z * op);
}
/**
@@ -165,9 +161,9 @@ public:
* \param op The second operand.
* \return The sum vector.
*/
- inline AUD_Vector3 operator+(const AUD_Vector3& op) const
+ inline Vector3 operator+(const Vector3& op) const
{
- return AUD_Vector3(m_x + op.m_x, m_y + op.m_y, m_z + op.m_z);
+ return Vector3(m_x + op.m_x, m_y + op.m_y, m_z + op.m_z);
}
/**
@@ -175,18 +171,18 @@ public:
* \param op The second operand.
* \return The difference vector.
*/
- inline AUD_Vector3 operator-(const AUD_Vector3& op) const
+ inline Vector3 operator-(const Vector3& op) const
{
- return AUD_Vector3(m_x - op.m_x, m_y - op.m_y, m_z - op.m_z);
+ return Vector3(m_x - op.m_x, m_y - op.m_y, m_z - op.m_z);
}
/**
* Negates the vector.
* \return The vector facing in the opposite direction.
*/
- inline AUD_Vector3 operator-() const
+ inline Vector3 operator-() const
{
- return AUD_Vector3(-m_x, -m_y, -m_z);
+ return Vector3(-m_x, -m_y, -m_z);
}
/**
@@ -194,7 +190,7 @@ public:
* \param op The second operand.
* \return The difference vector.
*/
- inline AUD_Vector3& operator-=(const AUD_Vector3& op)
+ inline Vector3& operator-=(const Vector3& op)
{
m_x -= op.m_x;
m_y -= op.m_y;
@@ -206,7 +202,7 @@ public:
/**
* This class represents a quaternion used for 3D rotations.
*/
-class AUD_Quaternion
+class AUD_API Quaternion
{
private:
/**
@@ -232,7 +228,7 @@ public:
* \param y The y component.
* \param z The z component.
*/
- inline AUD_Quaternion(float w = 1, float x = 0, float y = 0, float z = 0) :
+ inline Quaternion(float w = 1, float x = 0, float y = 0, float z = 0) :
m_w(w), m_x(x), m_y(y), m_z(z)
{
}
@@ -279,7 +275,7 @@ public:
*/
inline void get(float* destination) const
{
- memcpy(destination, m_v, sizeof(m_v));
+ std::memcpy(destination, m_v, sizeof(m_v));
}
/**
@@ -305,11 +301,11 @@ public:
* z axis vector.
* \return The negative z axis vector.
*/
- inline AUD_Vector3 getLookAt() const
+ inline Vector3 getLookAt() const
{
- return AUD_Vector3(-2 * (m_w * m_y + m_x * m_z),
- 2 * (m_x * m_w - m_z * m_y),
- 2 * (m_x * m_x + m_y * m_y) - 1);
+ return Vector3(-2 * (m_w * m_y + m_x * m_z),
+ 2 * (m_x * m_w - m_z * m_y),
+ 2 * (m_x * m_x + m_y * m_y) - 1);
}
/**
@@ -317,12 +313,12 @@ public:
* vector.
* \return The y axis vector.
*/
- inline AUD_Vector3 getUp() const
+ inline Vector3 getUp() const
{
- return AUD_Vector3(2 * (m_x * m_y - m_w * m_z),
+ return Vector3(2 * (m_x * m_y - m_w * m_z),
1 - 2 * (m_x * m_x + m_z * m_z),
2 * (m_w * m_x + m_y * m_z));
}
};
-#endif //__AUD_3DMATH_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/StreamBuffer.h b/extern/audaspace/include/util/StreamBuffer.h
new file mode 100644
index 00000000000..8ec4cfcf46d
--- /dev/null
+++ b/extern/audaspace/include/util/StreamBuffer.h
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+/**
+ * @file StreamBuffer.h
+ * @ingroup util
+ * The StreamBuffer class.
+ */
+
+#include "ISound.h"
+#include "respec/Specification.h"
+
+AUD_NAMESPACE_BEGIN
+
+class Buffer;
+
+/**
+ * This sound creates a buffer out of a reader. This way normally streamed
+ * sound sources can be loaded into memory for buffered playback.
+ */
+class AUD_API StreamBuffer : public ISound
+{
+private:
+ /**
+ * The buffer that holds the audio data.
+ */
+ std::shared_ptr<Buffer> m_buffer;
+
+ /**
+ * The specification of the samples.
+ */
+ Specs m_specs;
+
+ // delete copy constructor and operator=
+ StreamBuffer(const StreamBuffer&) = delete;
+ StreamBuffer& operator=(const StreamBuffer&) = delete;
+
+public:
+ /**
+ * Creates the sound and reads the reader created by the sound supplied
+ * to the buffer.
+ * \param sound The sound that creates the reader for buffering.
+ * \exception Exception Thrown if the reader cannot be created.
+ */
+ StreamBuffer(std::shared_ptr<ISound> sound);
+
+ /**
+ * Creates the sound from an preexisting buffer.
+ * \param buffer The buffer to stream from.
+ * \param specs The specification of the data in the buffer.
+ * \exception Exception Thrown if the reader cannot be created.
+ */
+ StreamBuffer(std::shared_ptr<Buffer> buffer, Specs specs);
+
+ /**
+ * Returns the buffer to be streamed.
+ * @return The buffer to stream.
+ */
+ std::shared_ptr<Buffer> getBuffer();
+
+ /**
+ * Returns the specification of the buffer.
+ * @return The specification of the buffer.
+ */
+ Specs getSpecs();
+
+ virtual std::shared_ptr<IReader> createReader();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/include/util/ThreadPool.h b/extern/audaspace/include/util/ThreadPool.h
new file mode 100644
index 00000000000..24ec089d52c
--- /dev/null
+++ b/extern/audaspace/include/util/ThreadPool.h
@@ -0,0 +1,119 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#pragma once
+
+/**
+* @file ThreadPool.h
+* @ingroup util
+* The ThreadPool class.
+*/
+
+#include "Audaspace.h"
+
+#include <mutex>
+#include <condition_variable>
+#include <vector>
+#include <thread>
+#include <queue>
+#include <future>
+#include <functional>
+
+AUD_NAMESPACE_BEGIN
+/**
+* This represents pool of threads.
+*/
+class AUD_API ThreadPool
+{
+private:
+ /**
+ * A queue of tasks.
+ */
+ std::queue<std::function<void()>> m_queue;
+
+ /**
+ * A vector of thread objects.
+ */
+ std::vector<std::thread> m_threads;
+
+ /**
+ * A mutex for synchronization.
+ */
+ std::mutex m_mutex;
+
+ /**
+ * A condition variable used to stop the threads when there are no tasks.
+ */
+ std::condition_variable m_condition;
+
+ /**
+ * Stop flag.
+ */
+ bool m_stopFlag;
+
+ /**
+ * The number fo threads.
+ */
+ unsigned int m_numThreads;
+
+ // delete copy constructor and operator=
+ ThreadPool(const ThreadPool&) = delete;
+ ThreadPool& operator=(const ThreadPool&) = delete;
+public:
+ /**
+ * Creates a new ThreadPool object.
+ * \param count The number of threads of the pool. It must not be 0.
+ */
+ ThreadPool(unsigned int count);
+
+ virtual ~ThreadPool();
+
+ /**
+ * Enqueues a new task for the threads to realize.
+ * \param t A function that realices a task.
+ * \param args The arguments of the task.
+ * \return A future of the same type as the return type of the task.
+ */
+ template<class T, class... Args>
+ std::future<typename std::result_of<T(Args...)>::type> enqueue(T&& t, Args&&... args)
+ {
+ using pkgdTask = std::packaged_task<typename std::result_of<T(Args...)>::type()>;
+
+ std::shared_ptr<pkgdTask> task = std::make_shared<pkgdTask>(std::bind(std::forward<T>(t), std::forward<Args>(args)...));
+ auto result = task->get_future();
+
+ m_mutex.lock();
+ m_queue.emplace([task]() { (*task)(); });
+ m_mutex.unlock();
+
+ m_condition.notify_one();
+ return result;
+ }
+
+ /**
+ * Retrieves the number of threads of the pool.
+ * \return The number of threads.
+ */
+ unsigned int getNumOfThreads();
+
+private:
+
+ /**
+ * Worker thread function.
+ */
+ void threadFunction();
+};
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
new file mode 100644
index 00000000000..7f9b762f816
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEG.cpp
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "FFMPEG.h"
+#include "FFMPEGReader.h"
+#include "FFMPEGWriter.h"
+#include "file/FileManager.h"
+
+AUD_NAMESPACE_BEGIN
+
+FFMPEG::FFMPEG()
+{
+ av_register_all();
+}
+
+void FFMPEG::registerPlugin()
+{
+ std::shared_ptr<FFMPEG> plugin = std::shared_ptr<FFMPEG>(new FFMPEG);
+ FileManager::registerInput(plugin);
+ FileManager::registerOutput(plugin);
+}
+
+std::shared_ptr<IReader> FFMPEG::createReader(std::string filename)
+{
+ return std::shared_ptr<IReader>(new FFMPEGReader(filename));
+}
+
+std::shared_ptr<IReader> FFMPEG::createReader(std::shared_ptr<Buffer> buffer)
+{
+ return std::shared_ptr<IReader>(new FFMPEGReader(buffer));
+}
+
+std::shared_ptr<IWriter> FFMPEG::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
+{
+ return std::shared_ptr<IWriter>(new FFMPEGWriter(filename, specs, format, codec, bitrate));
+}
+
+#ifdef FFMPEG_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ FFMPEG::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "FFMPEG";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEG.h b/extern/audaspace/plugins/ffmpeg/FFMPEG.h
new file mode 100644
index 00000000000..108ba547e0f
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEG.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef FFMPEG_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file FFMPEG.h
+ * @ingroup plugin
+ * The FFMPEG class.
+ */
+
+#include "file/IFileInput.h"
+#include "file/IFileOutput.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This plugin class reads and writes sounds via ffmpeg.
+ */
+class AUD_PLUGIN_API FFMPEG : public IFileInput, public IFileOutput
+{
+private:
+ // delete copy constructor and operator=
+ FFMPEG(const FFMPEG&) = delete;
+ FFMPEG& operator=(const FFMPEG&) = delete;
+
+public:
+ /**
+ * Creates a new ffmpeg plugin.
+ */
+ FFMPEG();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
+
+ virtual std::shared_ptr<IReader> createReader(std::string filename);
+ virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer);
+ virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
new file mode 100644
index 00000000000..6b79cc5abfd
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
@@ -0,0 +1,397 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "FFMPEGReader.h"
+#include "Exception.h"
+
+#include <algorithm>
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avio.h>
+}
+
+AUD_NAMESPACE_BEGIN
+
+int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
+{
+ AVFrame* frame = nullptr;
+ int got_frame;
+ int read_length;
+ uint8_t* orig_data = packet.data;
+ int orig_size = packet.size;
+
+ int buf_size = buffer.getSize();
+ int buf_pos = 0;
+
+ while(packet.size > 0)
+ {
+ got_frame = 0;
+
+ if(!frame)
+ frame = av_frame_alloc();
+ else
+ av_frame_unref(frame);
+
+ read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
+ if(read_length < 0)
+ break;
+
+ if(got_frame)
+ {
+ int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1);
+
+ if(buf_size - buf_pos < data_size)
+ {
+ buffer.resize(buf_size + data_size, true);
+ buf_size += data_size;
+ }
+
+ if(m_tointerleave)
+ {
+ int single_size = data_size / m_codecCtx->channels / frame->nb_samples;
+ for(int channel = 0; channel < m_codecCtx->channels; channel++)
+ {
+ for(int i = 0; i < frame->nb_samples; i++)
+ {
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
+ frame->data[channel] + i * single_size, single_size);
+ }
+ }
+ }
+ else
+ std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[0], data_size);
+
+ buf_pos += data_size;
+ }
+ packet.size -= read_length;
+ packet.data += read_length;
+ }
+
+ packet.data = orig_data;
+ packet.size = orig_size;
+ av_free(frame);
+
+ return buf_pos;
+}
+
+void FFMPEGReader::init()
+{
+ m_position = 0;
+ m_pkgbuf_left = 0;
+
+ if(avformat_find_stream_info(m_formatCtx, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg couldn't find the stream info.");
+
+ // find audio stream and codec
+ m_stream = -1;
+
+ for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
+ {
+ if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
+ && (m_stream < 0))
+ {
+ m_stream=i;
+ break;
+ }
+ }
+
+ if(m_stream == -1)
+ AUD_THROW(FileException, "File couldn't be read, no audio stream found by ffmpeg.");
+
+ m_codecCtx = m_formatCtx->streams[m_stream]->codec;
+
+ // get a decoder and open it
+ AVCodec* aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+ if(!aCodec)
+ AUD_THROW(FileException, "File couldn't be read, no decoder found with ffmpeg.");
+
+ if(avcodec_open2(m_codecCtx, aCodec, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg codec couldn't be opened.");
+
+ m_specs.channels = (Channels) m_codecCtx->channels;
+ m_tointerleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
+
+ switch(av_get_packed_sample_fmt(m_codecCtx->sample_fmt))
+ {
+ case AV_SAMPLE_FMT_U8:
+ m_convert = convert_u8_float;
+ m_specs.format = FORMAT_U8;
+ break;
+ case AV_SAMPLE_FMT_S16:
+ m_convert = convert_s16_float;
+ m_specs.format = FORMAT_S16;
+ break;
+ case AV_SAMPLE_FMT_S32:
+ m_convert = convert_s32_float;
+ m_specs.format = FORMAT_S32;
+ break;
+ case AV_SAMPLE_FMT_FLT:
+ m_convert = convert_copy<float>;
+ m_specs.format = FORMAT_FLOAT32;
+ break;
+ case AV_SAMPLE_FMT_DBL:
+ m_convert = convert_double_float;
+ m_specs.format = FORMAT_FLOAT64;
+ break;
+ default:
+ AUD_THROW(FileException, "File couldn't be read, ffmpeg sample format unknown.");
+ }
+
+ m_specs.rate = (SampleRate) m_codecCtx->sample_rate;
+}
+
+FFMPEGReader::FFMPEGReader(std::string filename) :
+ m_pkgbuf(),
+ m_formatCtx(nullptr),
+ m_aviocontext(nullptr),
+ m_membuf(nullptr)
+{
+ // open file
+ if(avformat_open_input(&m_formatCtx, filename.c_str(), nullptr, nullptr)!=0)
+ AUD_THROW(FileException, "File couldn't be opened with ffmpeg.");
+
+ try
+ {
+ init();
+ }
+ catch(Exception&)
+ {
+ avformat_close_input(&m_formatCtx);
+ throw;
+ }
+}
+
+FFMPEGReader::FFMPEGReader(std::shared_ptr<Buffer> buffer) :
+ m_pkgbuf(),
+ m_membuffer(buffer),
+ m_membufferpos(0)
+{
+ m_membuf = reinterpret_cast<data_t*>(av_malloc(FF_MIN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE));
+
+ m_aviocontext = avio_alloc_context(m_membuf, FF_MIN_BUFFER_SIZE, 0, this, read_packet, nullptr, seek_packet);
+
+ if(!m_aviocontext)
+ {
+ av_free(m_aviocontext);
+ AUD_THROW(FileException, "Buffer reading context couldn't be created with ffmpeg.");
+ }
+
+ m_formatCtx = avformat_alloc_context();
+ m_formatCtx->pb = m_aviocontext;
+ if(avformat_open_input(&m_formatCtx, "", nullptr, nullptr)!=0)
+ {
+ av_free(m_aviocontext);
+ AUD_THROW(FileException, "Buffer couldn't be read with ffmpeg.");
+ }
+
+ try
+ {
+ init();
+ }
+ catch(Exception&)
+ {
+ avformat_close_input(&m_formatCtx);
+ av_free(m_aviocontext);
+ throw;
+ }
+}
+
+FFMPEGReader::~FFMPEGReader()
+{
+ avcodec_close(m_codecCtx);
+ avformat_close_input(&m_formatCtx);
+}
+
+int FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
+{
+ FFMPEGReader* reader = reinterpret_cast<FFMPEGReader*>(opaque);
+
+ int size = std::min(buf_size, int(reader->m_membuffer->getSize() - reader->m_membufferpos));
+
+ if(size < 0)
+ return -1;
+
+ std::memcpy(buf, ((data_t*)reader->m_membuffer->getBuffer()) + reader->m_membufferpos, size);
+ reader->m_membufferpos += size;
+
+ return size;
+}
+
+int64_t FFMPEGReader::seek_packet(void* opaque, int64_t offset, int whence)
+{
+ FFMPEGReader* reader = reinterpret_cast<FFMPEGReader*>(opaque);
+
+ switch(whence)
+ {
+ case SEEK_SET:
+ reader->m_membufferpos = 0;
+ break;
+ case SEEK_END:
+ reader->m_membufferpos = reader->m_membuffer->getSize();
+ break;
+ case AVSEEK_SIZE:
+ return reader->m_membuffer->getSize();
+ }
+
+ return (reader->m_membufferpos += offset);
+}
+
+bool FFMPEGReader::isSeekable() const
+{
+ return true;
+}
+
+void FFMPEGReader::seek(int position)
+{
+ if(position >= 0)
+ {
+ uint64_t st_time = m_formatCtx->start_time;
+ uint64_t seek_pos = ((uint64_t)position) * ((uint64_t)AV_TIME_BASE) / ((uint64_t)m_specs.rate);
+
+ if(st_time != AV_NOPTS_VALUE) {
+ seek_pos += st_time;
+ }
+
+ double pts_time_base =
+ av_q2d(m_formatCtx->streams[m_stream]->time_base);
+ uint64_t pts_st_time =
+ ((st_time != AV_NOPTS_VALUE) ? st_time : 0)
+ / pts_time_base / (uint64_t) AV_TIME_BASE;
+
+ // a value < 0 tells us that seeking failed
+ if(av_seek_frame(m_formatCtx, -1, seek_pos,
+ AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
+ {
+ avcodec_flush_buffers(m_codecCtx);
+ m_position = position;
+
+ AVPacket packet;
+ bool search = true;
+
+ while(search && av_read_frame(m_formatCtx, &packet) >= 0)
+ {
+ // is it a frame from the audio stream?
+ if(packet.stream_index == m_stream)
+ {
+ // decode the package
+ m_pkgbuf_left = decode(packet, m_pkgbuf);
+ search = false;
+
+ // check position
+ if(packet.pts != AV_NOPTS_VALUE)
+ {
+ // calculate real position, and read to frame!
+ m_position = (packet.pts - pts_st_time) * pts_time_base * m_specs.rate;
+
+ if(m_position < position)
+ {
+ // read until we're at the right position
+ int length = AUD_DEFAULT_BUFFER_SIZE;
+ Buffer buffer(length * AUD_SAMPLE_SIZE(m_specs));
+ bool eos;
+ for(int len = position - m_position; len > 0; len -= AUD_DEFAULT_BUFFER_SIZE)
+ {
+ if(len < AUD_DEFAULT_BUFFER_SIZE)
+ length = len;
+ read(length, eos, buffer.getBuffer());
+ }
+ }
+ }
+ }
+ av_free_packet(&packet);
+ }
+ }
+ else
+ {
+ fprintf(stderr, "seeking failed!\n");
+ // Seeking failed, do nothing.
+ }
+ }
+}
+
+int FFMPEGReader::getLength() const
+{
+ // return approximated remaning size
+ return (int)((m_formatCtx->duration * m_codecCtx->sample_rate)
+ / AV_TIME_BASE)-m_position;
+}
+
+int FFMPEGReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs FFMPEGReader::getSpecs() const
+{
+ return m_specs.specs;
+}
+
+void FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ // read packages and decode them
+ AVPacket packet;
+ int data_size = 0;
+ int pkgbuf_pos;
+ int left = length;
+ int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
+
+ sample_t* buf = buffer;
+ pkgbuf_pos = m_pkgbuf_left;
+ m_pkgbuf_left = 0;
+
+ // there may still be data in the buffer from the last call
+ if(pkgbuf_pos > 0)
+ {
+ data_size = std::min(pkgbuf_pos, left * sample_size);
+ m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
+ buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
+ left -= data_size/sample_size;
+ }
+
+ // for each frame read as long as there isn't enough data already
+ while((left > 0) && (av_read_frame(m_formatCtx, &packet) >= 0))
+ {
+ // is it a frame from the audio stream?
+ if(packet.stream_index == m_stream)
+ {
+ // decode the package
+ pkgbuf_pos = decode(packet, m_pkgbuf);
+
+ // copy to output buffer
+ data_size = std::min(pkgbuf_pos, left * sample_size);
+ m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(), data_size / AUD_FORMAT_SIZE(m_specs.format));
+ buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
+ left -= data_size/sample_size;
+ }
+ av_free_packet(&packet);
+ }
+ // read more data than necessary?
+ if(pkgbuf_pos > data_size)
+ {
+ m_pkgbuf_left = pkgbuf_pos-data_size;
+ memmove(m_pkgbuf.getBuffer(),
+ ((data_t*)m_pkgbuf.getBuffer())+data_size,
+ pkgbuf_pos-data_size);
+ }
+
+ if((eos = (left > 0)))
+ length -= left;
+
+ m_position += length;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
new file mode 100644
index 00000000000..e2ae959912d
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.h
@@ -0,0 +1,184 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef FFMPEG_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file FFMPEGReader.h
+ * @ingroup plugin
+ * The FFMPEGReader class.
+ */
+
+#include "respec/ConverterFunctions.h"
+#include "IReader.h"
+#include "util/Buffer.h"
+
+#include <string>
+#include <memory>
+
+struct AVCodecContext;
+extern "C" {
+#include <libavformat/avformat.h>
+}
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class reads a sound file via ffmpeg.
+ * \warning Seeking may not be accurate! Moreover the position is updated after
+ * a buffer reading call. So calling getPosition right after seek
+ * normally results in a wrong value.
+ */
+class AUD_PLUGIN_API FFMPEGReader : public IReader
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The specification of the audio data.
+ */
+ DeviceSpecs m_specs;
+
+ /**
+ * The buffer for package reading.
+ */
+ Buffer m_pkgbuf;
+
+ /**
+ * The count of samples still available from the last read package.
+ */
+ int m_pkgbuf_left;
+
+ /**
+ * The AVFormatContext structure for using ffmpeg.
+ */
+ AVFormatContext* m_formatCtx;
+
+ /**
+ * The AVCodecContext structure for using ffmpeg.
+ */
+ AVCodecContext* m_codecCtx;
+
+ /**
+ * The AVIOContext to read the data from.
+ */
+ AVIOContext* m_aviocontext;
+
+ /**
+ * The stream ID in the file.
+ */
+ int m_stream;
+
+ /**
+ * Converter function.
+ */
+ convert_f m_convert;
+
+ /**
+ * The memory file to read from.
+ */
+ std::shared_ptr<Buffer> m_membuffer;
+
+ /**
+ * The buffer to read with.
+ */
+ data_t* m_membuf;
+
+ /**
+ * Reading position of the buffer.
+ */
+ int64_t m_membufferpos;
+
+ /**
+ * Whether the audio data has to be interleaved after reading.
+ */
+ bool m_tointerleave;
+
+ /**
+ * Decodes a packet into the given buffer.
+ * \param packet The AVPacket to decode.
+ * \param buffer The target buffer.
+ * \return The count of read bytes.
+ */
+ AUD_LOCAL int decode(AVPacket& packet, Buffer& buffer);
+
+ /**
+ * Initializes the object.
+ */
+ AUD_LOCAL void init();
+
+ // delete copy constructor and operator=
+ FFMPEGReader(const FFMPEGReader&) = delete;
+ FFMPEGReader& operator=(const FFMPEGReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param filename The path to the file to be read.
+ * \exception Exception Thrown if the file specified does not exist or
+ * cannot be read with ffmpeg.
+ */
+ FFMPEGReader(std::string filename);
+
+ /**
+ * Creates a new reader.
+ * \param buffer The buffer to read from.
+ * \exception Exception Thrown if the buffer specified cannot be read
+ * with ffmpeg.
+ */
+ FFMPEGReader(std::shared_ptr<Buffer> buffer);
+
+ /**
+ * Destroys the reader and closes the file.
+ */
+ virtual ~FFMPEGReader();
+
+ /**
+ * Reads data to a memory buffer.
+ * This function is used for avio only.
+ * @param opaque The FFMPEGReader.
+ * @param buf The buffer to read to.
+ * @param buf_size The size of the buffer.
+ * @return How many bytes have been read.
+ */
+ static int read_packet(void* opaque, uint8_t* buf, int buf_size);
+
+ /**
+ * Seeks within data.
+ * This function is used for avio only.
+ * @param opaque The FFMPEGReader.
+ * @param offset The byte offset to seek to.
+ * @param whence The seeking action.
+ * @return The current position or the size of the data if requested.
+ */
+ static int64_t seek_packet(void* opaque, int64_t offset, int whence);
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
new file mode 100644
index 00000000000..f79f0f7fc6b
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
@@ -0,0 +1,427 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "FFMPEGWriter.h"
+#include "Exception.h"
+
+#include <algorithm>
+#include <cstring>
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avio.h>
+}
+
+AUD_NAMESPACE_BEGIN
+
+void FFMPEGWriter::encode()
+{
+ sample_t* data = m_input_buffer.getBuffer();
+
+ if(m_deinterleave)
+ {
+ m_deinterleave_buffer.assureSize(m_input_buffer.getSize());
+
+ sample_t* dbuf = m_deinterleave_buffer.getBuffer();
+ // deinterleave
+ int single_size = sizeof(sample_t);
+ for(int channel = 0; channel < m_specs.channels; channel++)
+ {
+ for(int i = 0; i < m_input_buffer.getSize() / AUD_SAMPLE_SIZE(m_specs); i++)
+ {
+ std::memcpy(((data_t*)dbuf) + (m_input_samples * channel + i) * single_size,
+ ((data_t*)data) + ((m_specs.channels * i) + channel) * single_size, single_size);
+ }
+ }
+
+ // convert first
+ if(m_input_size)
+ m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(dbuf), m_input_samples * m_specs.channels);
+ else
+ std::memcpy(data, dbuf, m_input_buffer.getSize());
+ }
+ else
+ // convert first
+ if(m_input_size)
+ m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(data), m_input_samples * m_specs.channels);
+
+ AVPacket packet;
+
+ packet.data = nullptr;
+ packet.size = 0;
+
+ av_init_packet(&packet);
+
+ AVFrame* frame = av_frame_alloc();
+ av_frame_unref(frame);
+ int got_packet;
+
+ frame->nb_samples = m_input_samples;
+ frame->format = m_codecCtx->sample_fmt;
+ frame->channel_layout = m_codecCtx->channel_layout;
+
+ if(avcodec_fill_audio_frame(frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast<data_t*>(data), m_input_buffer.getSize(), 0) < 0)
+ AUD_THROW(FileException, "File couldn't be written, filling the audio frame failed with ffmpeg.");
+
+ AVRational sample_time = { 1, static_cast<int>(m_specs.rate) };
+ frame->pts = av_rescale_q(m_position - m_input_samples, m_codecCtx->time_base, sample_time);
+
+ if(avcodec_encode_audio2(m_codecCtx, &packet, frame, &got_packet))
+ {
+ av_frame_free(&frame);
+ AUD_THROW(FileException, "File couldn't be written, audio encoding failed with ffmpeg.");
+ }
+
+ if(got_packet)
+ {
+ packet.flags |= AV_PKT_FLAG_KEY;
+ packet.stream_index = m_stream->index;
+ if(av_write_frame(m_formatCtx, &packet) < 0)
+ {
+ av_free_packet(&packet);
+ av_frame_free(&frame);
+ AUD_THROW(FileException, "Frame couldn't be writen to the file with ffmpeg.");
+ }
+ av_free_packet(&packet);
+ }
+
+ av_frame_free(&frame);
+}
+
+void FFMPEGWriter::close()
+{
+ int got_packet = true;
+
+ while(got_packet)
+ {
+ AVPacket packet;
+
+ packet.data = nullptr;
+ packet.size = 0;
+
+ av_init_packet(&packet);
+
+ if(avcodec_encode_audio2(m_codecCtx, &packet, nullptr, &got_packet))
+ AUD_THROW(FileException, "File end couldn't be written, audio encoding failed with ffmpeg.");
+
+ if(got_packet)
+ {
+ packet.flags |= AV_PKT_FLAG_KEY;
+ packet.stream_index = m_stream->index;
+ if(av_write_frame(m_formatCtx, &packet))
+ {
+ av_free_packet(&packet);
+ AUD_THROW(FileException, "Final frames couldn't be writen to the file with ffmpeg.");
+ }
+ av_free_packet(&packet);
+ }
+ }
+}
+
+FFMPEGWriter::FFMPEGWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate) :
+ m_position(0),
+ m_specs(specs),
+ m_input_samples(0),
+ m_deinterleave(false)
+{
+ static const char* formats[] = { nullptr, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav" };
+
+ if(avformat_alloc_output_context2(&m_formatCtx, nullptr, formats[format], filename.c_str()) < 0)
+ AUD_THROW(FileException, "File couldn't be written, format couldn't be found with ffmpeg.");
+
+ m_outputFmt = m_formatCtx->oformat;
+
+ if(!m_outputFmt) {
+ avformat_free_context(m_formatCtx);
+ AUD_THROW(FileException, "File couldn't be written, output format couldn't be found with ffmpeg.");
+ }
+
+ m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+
+ switch(codec)
+ {
+ case CODEC_AAC:
+ m_outputFmt->audio_codec = AV_CODEC_ID_AAC;
+ break;
+ case CODEC_AC3:
+ m_outputFmt->audio_codec = AV_CODEC_ID_AC3;
+ break;
+ case CODEC_FLAC:
+ m_outputFmt->audio_codec = AV_CODEC_ID_FLAC;
+ break;
+ case CODEC_MP2:
+ m_outputFmt->audio_codec = AV_CODEC_ID_MP2;
+ break;
+ case CODEC_MP3:
+ m_outputFmt->audio_codec = AV_CODEC_ID_MP3;
+ break;
+ case CODEC_OPUS:
+ m_outputFmt->audio_codec = AV_CODEC_ID_OPUS;
+ break;
+ case CODEC_PCM:
+ switch(specs.format)
+ {
+ case FORMAT_U8:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
+ break;
+ case FORMAT_S16:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
+ break;
+ case FORMAT_S24:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
+ break;
+ case FORMAT_S32:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
+ break;
+ case FORMAT_FLOAT32:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
+ break;
+ case FORMAT_FLOAT64:
+ m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
+ break;
+ default:
+ m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ break;
+ }
+ break;
+ case CODEC_VORBIS:
+ m_outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
+ break;
+ default:
+ m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
+ break;
+ }
+
+ try
+ {
+ if(m_outputFmt->audio_codec == AV_CODEC_ID_NONE)
+ AUD_THROW(FileException, "File couldn't be written, audio codec not found with ffmpeg.");
+
+ AVCodec* codec = avcodec_find_encoder(m_outputFmt->audio_codec);
+ if(!codec)
+ AUD_THROW(FileException, "File couldn't be written, audio encoder couldn't be found with ffmpeg.");
+
+ m_stream = avformat_new_stream(m_formatCtx, codec);
+ if(!m_stream)
+ AUD_THROW(FileException, "File couldn't be written, stream creation failed with ffmpeg.");
+
+ m_stream->id = m_formatCtx->nb_streams - 1;
+
+ m_codecCtx = m_stream->codec;
+
+ switch(m_specs.format)
+ {
+ case FORMAT_U8:
+ m_convert = convert_float_u8;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_U8;
+ break;
+ case FORMAT_S16:
+ m_convert = convert_float_s16;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
+ break;
+ case FORMAT_S32:
+ m_convert = convert_float_s32;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_S32;
+ break;
+ case FORMAT_FLOAT64:
+ m_convert = convert_float_double;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_DBL;
+ break;
+ default:
+ m_convert = convert_copy<sample_t>;
+ m_codecCtx->sample_fmt = AV_SAMPLE_FMT_FLT;
+ break;
+ }
+
+ if(m_formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
+ m_codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
+
+ bool format_supported = false;
+
+ for(int i = 0; codec->sample_fmts[i] != -1; i++)
+ {
+ if(av_get_alt_sample_fmt(codec->sample_fmts[i], false) == m_codecCtx->sample_fmt)
+ {
+ m_deinterleave = av_sample_fmt_is_planar(codec->sample_fmts[i]);
+ m_codecCtx->sample_fmt = codec->sample_fmts[i];
+ format_supported = true;
+ }
+ }
+
+ if(!format_supported)
+ {
+ int chosen_index = 0;
+ auto chosen = av_get_alt_sample_fmt(codec->sample_fmts[chosen_index], false);
+ for(int i = 1; codec->sample_fmts[i] != -1; i++)
+ {
+ auto fmt = av_get_alt_sample_fmt(codec->sample_fmts[i], false);
+ if((fmt > chosen && chosen < m_codecCtx->sample_fmt) || (fmt > m_codecCtx->sample_fmt && fmt < chosen))
+ {
+ chosen = fmt;
+ chosen_index = i;
+ }
+ }
+
+ m_codecCtx->sample_fmt = codec->sample_fmts[chosen_index];
+ m_deinterleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
+ switch(av_get_alt_sample_fmt(m_codecCtx->sample_fmt, false))
+ {
+ case AV_SAMPLE_FMT_U8:
+ specs.format = FORMAT_U8;
+ m_convert = convert_float_u8;
+ break;
+ case AV_SAMPLE_FMT_S16:
+ specs.format = FORMAT_S16;
+ m_convert = convert_float_s16;
+ break;
+ case AV_SAMPLE_FMT_S32:
+ specs.format = FORMAT_S32;
+ m_convert = convert_float_s32;
+ break;
+ case AV_SAMPLE_FMT_FLT:
+ specs.format = FORMAT_FLOAT32;
+ m_convert = convert_copy<sample_t>;
+ break;
+ case AV_SAMPLE_FMT_DBL:
+ specs.format = FORMAT_FLOAT64;
+ m_convert = convert_float_double;
+ break;
+ default:
+ AUD_THROW(FileException, "File couldn't be written, sample format not supported with ffmpeg.");
+ }
+ }
+
+ m_codecCtx->sample_rate = 0;
+
+ if(codec->supported_samplerates)
+ {
+ for(int i = 0; codec->supported_samplerates[i]; i++)
+ {
+ if(codec->supported_samplerates[i] == m_specs.rate)
+ {
+ m_codecCtx->sample_rate = codec->supported_samplerates[i];
+ break;
+ }
+ else if((codec->supported_samplerates[i] > m_codecCtx->sample_rate && m_specs.rate > m_codecCtx->sample_rate) ||
+ (codec->supported_samplerates[i] < m_codecCtx->sample_rate && m_specs.rate < codec->supported_samplerates[i]))
+ {
+ m_codecCtx->sample_rate = codec->supported_samplerates[i];
+ }
+ }
+ }
+
+ if(m_codecCtx->sample_rate == 0)
+ m_codecCtx->sample_rate = m_specs.rate;
+
+ m_specs.rate = m_codecCtx->sample_rate;
+
+ m_codecCtx->codec_id = m_outputFmt->audio_codec;
+ m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
+ m_codecCtx->bit_rate = bitrate;
+ m_codecCtx->channels = m_specs.channels;
+ m_stream->time_base.num = m_codecCtx->time_base.num = 1;
+ m_stream->time_base.den = m_codecCtx->time_base.den = m_codecCtx->sample_rate;
+
+ if(avcodec_open2(m_codecCtx, codec, nullptr) < 0)
+ AUD_THROW(FileException, "File couldn't be written, encoder couldn't be opened with ffmpeg.");
+
+ int samplesize = std::max(int(AUD_SAMPLE_SIZE(m_specs)), AUD_DEVICE_SAMPLE_SIZE(m_specs));
+
+ if((m_input_size = m_codecCtx->frame_size))
+ m_input_buffer.resize(m_input_size * samplesize);
+
+ if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
+ AUD_THROW(FileException, "File couldn't be written, file opening failed with ffmpeg.");
+
+ avformat_write_header(m_formatCtx, nullptr);
+ }
+ catch(Exception&)
+ {
+ avformat_free_context(m_formatCtx);
+ throw;
+ }
+}
+
+FFMPEGWriter::~FFMPEGWriter()
+{
+ // writte missing data
+ if(m_input_samples)
+ encode();
+
+ close();
+
+ av_write_trailer(m_formatCtx);
+
+ avcodec_close(m_codecCtx);
+
+ avio_close(m_formatCtx->pb);
+ avformat_free_context(m_formatCtx);
+}
+
+int FFMPEGWriter::getPosition() const
+{
+ return m_position;
+}
+
+DeviceSpecs FFMPEGWriter::getSpecs() const
+{
+ return m_specs;
+}
+
+void FFMPEGWriter::write(unsigned int length, sample_t* buffer)
+{
+ unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
+
+ if(m_input_size)
+ {
+ sample_t* inbuf = m_input_buffer.getBuffer();
+
+ while(length)
+ {
+ unsigned int len = std::min(m_input_size - m_input_samples, length);
+
+ std::memcpy(inbuf + m_input_samples * m_specs.channels, buffer, len * samplesize);
+
+ buffer += len * m_specs.channels;
+ m_input_samples += len;
+ m_position += len;
+ length -= len;
+
+ if(m_input_samples == m_input_size)
+ {
+ encode();
+
+ m_input_samples = 0;
+ }
+ }
+ }
+ else // PCM data, can write directly!
+ {
+ int samplesize = AUD_SAMPLE_SIZE(m_specs);
+ m_input_buffer.assureSize(length * std::max(AUD_DEVICE_SAMPLE_SIZE(m_specs), samplesize));
+
+ sample_t* buf = m_input_buffer.getBuffer();
+ m_convert(reinterpret_cast<data_t*>(buf), reinterpret_cast<data_t*>(buffer), length * m_specs.channels);
+
+ m_input_samples = length;
+
+ m_position += length;
+
+ encode();
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
new file mode 100644
index 00000000000..690185deb64
--- /dev/null
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.h
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef FFMPEG_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file FFMPEGWriter.h
+ * @ingroup plugin
+ * The FFMPEGWriter class.
+ */
+
+#include "respec/ConverterFunctions.h"
+#include "util/Buffer.h"
+#include "file/IWriter.h"
+
+#include <string>
+
+struct AVCodecContext;
+extern "C" {
+#include <libavformat/avformat.h>
+}
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class writes a sound file via ffmpeg.
+ */
+class AUD_PLUGIN_API FFMPEGWriter : public IWriter
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The specification of the audio data.
+ */
+ DeviceSpecs m_specs;
+
+ /**
+ * The AVFormatContext structure for using ffmpeg.
+ */
+ AVFormatContext* m_formatCtx;
+
+ /**
+ * The AVCodecContext structure for using ffmpeg.
+ */
+ AVCodecContext* m_codecCtx;
+
+ /**
+ * The AVOutputFormat structure for using ffmpeg.
+ */
+ AVOutputFormat* m_outputFmt;
+
+ /**
+ * The AVStream structure for using ffmpeg.
+ */
+ AVStream* m_stream;
+
+ /**
+ * The input buffer for the format converted data before encoding.
+ */
+ Buffer m_input_buffer;
+
+ /**
+ * The buffer used for deinterleaving.
+ */
+ Buffer m_deinterleave_buffer;
+
+ /**
+ * The count of input samples we have so far.
+ */
+ unsigned int m_input_samples;
+
+ /**
+ * The count of input samples necessary to encode a packet.
+ */
+ unsigned int m_input_size;
+
+ /**
+ * Whether the ouput has to be deinterleaved before writing.
+ */
+ bool m_deinterleave;
+
+ /**
+ * Converter function.
+ */
+ convert_f m_convert;
+
+ // delete copy constructor and operator=
+ FFMPEGWriter(const FFMPEGWriter&) = delete;
+ FFMPEGWriter& operator=(const FFMPEGWriter&) = delete;
+
+ /**
+ * Encodes to the output buffer.
+ */
+ AUD_LOCAL void encode();
+
+ /**
+ * Finishes writing to the file.
+ */
+ AUD_LOCAL void close();
+
+public:
+ /**
+ * Creates a new writer.
+ * \param filename The path to the file to be read.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \exception Exception Thrown if the file specified does not exist or
+ * cannot be read with ffmpeg.
+ */
+ FFMPEGWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+
+ /**
+ * Destroys the writer and closes the file.
+ */
+ virtual ~FFMPEGWriter();
+
+ virtual int getPosition() const;
+ virtual DeviceSpecs getSpecs() const;
+ virtual void write(unsigned int length, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackDevice.cpp b/extern/audaspace/plugins/jack/JackDevice.cpp
new file mode 100644
index 00000000000..1d238f74c3a
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackDevice.cpp
@@ -0,0 +1,385 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "JackDevice.h"
+#include "JackLibrary.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "Exception.h"
+#include "IReader.h"
+
+#include <cstring>
+#include <algorithm>
+
+AUD_NAMESPACE_BEGIN
+
+void JackDevice::updateRingBuffers()
+{
+ size_t size, temp;
+ unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
+ unsigned int i, j;
+ unsigned int channels = m_specs.channels;
+ sample_t* buffer = m_buffer.getBuffer();
+ float* deinterleave = m_deinterleavebuf.getBuffer();
+ jack_transport_state_t state;
+ jack_position_t position;
+
+ std::unique_lock<std::mutex> lock(m_mixingLock);
+
+ while(m_valid)
+ {
+ if(m_sync > 1)
+ {
+ if(m_syncFunc)
+ {
+ state = AUD_jack_transport_query(m_client, &position);
+ m_syncFunc(m_syncFuncData, state != JackTransportStopped, position.frame / (float) m_specs.rate);
+ }
+
+ for(i = 0; i < channels; i++)
+ AUD_jack_ringbuffer_reset(m_ringbuffers[i]);
+ }
+
+ size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
+ for(i = 1; i < channels; i++)
+ if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
+ size = temp;
+
+ while(size > samplesize)
+ {
+ size /= samplesize;
+ mix((data_t*)buffer, size);
+ for(i = 0; i < channels; i++)
+ {
+ for(j = 0; j < size; j++)
+ deinterleave[i * size + j] = buffer[i + j * channels];
+ AUD_jack_ringbuffer_write(m_ringbuffers[i], (char*)(deinterleave + i * size), size * sizeof(float));
+ }
+
+ size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
+ for(i = 1; i < channels; i++)
+ if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
+ size = temp;
+ }
+
+ if(m_sync > 1)
+ {
+ m_sync = 3;
+ }
+
+ m_mixingCondition.wait(lock);
+ }
+}
+
+int JackDevice::jack_mix(jack_nframes_t length, void* data)
+{
+ JackDevice* device = (JackDevice*)data;
+ unsigned int i;
+ int count = device->m_specs.channels;
+ char* buffer;
+
+ if(device->m_sync)
+ {
+ // play silence while syncing
+ for(unsigned int i = 0; i < count; i++)
+ std::memset(AUD_jack_port_get_buffer(device->m_ports[i], length), 0, length * sizeof(float));
+ }
+ else
+ {
+ size_t temp;
+ size_t readsamples = AUD_jack_ringbuffer_read_space(device->m_ringbuffers[0]);
+ for(i = 1; i < count; i++)
+ if((temp = AUD_jack_ringbuffer_read_space(device->m_ringbuffers[i])) < readsamples)
+ readsamples = temp;
+
+ readsamples = std::min(readsamples / sizeof(float), size_t(length));
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ buffer = (char*)AUD_jack_port_get_buffer(device->m_ports[i], length);
+ AUD_jack_ringbuffer_read(device->m_ringbuffers[i], buffer, readsamples * sizeof(float));
+ if(readsamples < length)
+ std::memset(buffer + readsamples * sizeof(float), 0, (length - readsamples) * sizeof(float));
+ }
+
+ if(device->m_mixingLock.try_lock())
+ {
+ device->m_mixingCondition.notify_all();
+ device->m_mixingLock.unlock();
+ }
+ }
+
+ return 0;
+}
+
+int JackDevice::jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data)
+{
+ JackDevice* device = (JackDevice*)data;
+
+ if(state == JackTransportStopped)
+ return 1;
+
+ if(device->m_mixingLock.try_lock())
+ {
+ if(device->m_sync > 2)
+ {
+ if(device->m_sync == 3)
+ {
+ device->m_sync = 0;
+ device->m_mixingLock.unlock();
+ return 1;
+ }
+ }
+ else
+ {
+ device->m_sync = 2;
+ device->m_mixingCondition.notify_all();
+ }
+ device->m_mixingLock.unlock();
+ }
+ else if(!device->m_sync)
+ device->m_sync = 1;
+
+ return 0;
+}
+
+void JackDevice::jack_shutdown(void* data)
+{
+ JackDevice* device = (JackDevice*)data;
+ device->m_valid = false;
+}
+
+JackDevice::JackDevice(std::string name, DeviceSpecs specs, int buffersize) :
+ m_synchronizer(this)
+{
+ if(specs.channels == CHANNELS_INVALID)
+ specs.channels = CHANNELS_STEREO;
+
+ // jack uses floats
+ m_specs = specs;
+ m_specs.format = FORMAT_FLOAT32;
+
+ jack_options_t options = JackNullOption;
+ jack_status_t status;
+
+ // open client
+ m_client = AUD_jack_client_open(name.c_str(), options, &status);
+ if(m_client == nullptr)
+ AUD_THROW(DeviceException, "Connecting to the JACK server failed.");
+
+ // set callbacks
+ AUD_jack_set_process_callback(m_client, JackDevice::jack_mix, this);
+ AUD_jack_on_shutdown(m_client, JackDevice::jack_shutdown, this);
+ AUD_jack_set_sync_callback(m_client, JackDevice::jack_sync, this);
+
+ // register our output channels which are called ports in jack
+ m_ports = new jack_port_t*[m_specs.channels];
+
+ try
+ {
+ char portname[64];
+ for(int i = 0; i < m_specs.channels; i++)
+ {
+ sprintf(portname, "out %d", i+1);
+ m_ports[i] = AUD_jack_port_register(m_client, portname, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0);
+ if(m_ports[i] == nullptr)
+ AUD_THROW(DeviceException, "Registering output port with JACK failed.");
+ }
+ }
+ catch(Exception&)
+ {
+ AUD_jack_client_close(m_client);
+ delete[] m_ports;
+ throw;
+ }
+
+ m_specs.rate = (SampleRate)AUD_jack_get_sample_rate(m_client);
+
+ buffersize *= sizeof(sample_t);
+ m_ringbuffers = new jack_ringbuffer_t*[specs.channels];
+ for(unsigned int i = 0; i < specs.channels; i++)
+ m_ringbuffers[i] = AUD_jack_ringbuffer_create(buffersize);
+ buffersize *= specs.channels;
+ m_deinterleavebuf.resize(buffersize);
+ m_buffer.resize(buffersize);
+
+ create();
+
+ m_valid = true;
+ m_sync = 0;
+ m_syncFunc = nullptr;
+ m_nextState = m_state = AUD_jack_transport_query(m_client, nullptr);
+
+ // activate the client
+ if(AUD_jack_activate(m_client))
+ {
+ AUD_jack_client_close(m_client);
+ delete[] m_ports;
+ for(unsigned int i = 0; i < specs.channels; i++)
+ AUD_jack_ringbuffer_free(m_ringbuffers[i]);
+ delete[] m_ringbuffers;
+ destroy();
+
+ AUD_THROW(DeviceException, "Client activation with JACK failed.");
+ }
+
+ const char** ports = AUD_jack_get_ports(m_client, nullptr, nullptr,
+ JackPortIsPhysical | JackPortIsInput);
+ if(ports != nullptr)
+ {
+ for(int i = 0; i < m_specs.channels && ports[i]; i++)
+ AUD_jack_connect(m_client, AUD_jack_port_name(m_ports[i]), ports[i]);
+
+ AUD_jack_free(ports);
+ }
+
+ m_mixingThread = std::thread(&JackDevice::updateRingBuffers, this);
+}
+
+JackDevice::~JackDevice()
+{
+ if(m_valid)
+ AUD_jack_client_close(m_client);
+ m_valid = false;
+
+ delete[] m_ports;
+
+ m_mixingLock.lock();
+ m_mixingCondition.notify_all();
+ m_mixingLock.unlock();
+
+ m_mixingThread.join();
+
+ for(unsigned int i = 0; i < m_specs.channels; i++)
+ AUD_jack_ringbuffer_free(m_ringbuffers[i]);
+ delete[] m_ringbuffers;
+
+ destroy();
+}
+
+ISynchronizer* JackDevice::getSynchronizer()
+{
+ return &m_synchronizer;
+}
+
+void JackDevice::playing(bool playing)
+{
+ // Do nothing.
+}
+
+void JackDevice::startPlayback()
+{
+ AUD_jack_transport_start(m_client);
+ m_nextState = JackTransportRolling;
+}
+
+void JackDevice::stopPlayback()
+{
+ AUD_jack_transport_stop(m_client);
+ m_nextState = JackTransportStopped;
+}
+
+void JackDevice::seekPlayback(float time)
+{
+ if(time >= 0.0f)
+ AUD_jack_transport_locate(m_client, time * m_specs.rate);
+}
+
+void JackDevice::setSyncCallback(ISynchronizer::syncFunction sync, void* data)
+{
+ m_syncFunc = sync;
+ m_syncFuncData = data;
+}
+
+float JackDevice::getPlaybackPosition()
+{
+ jack_position_t position;
+ AUD_jack_transport_query(m_client, &position);
+ return position.frame / (float) m_specs.rate;
+}
+
+bool JackDevice::doesPlayback()
+{
+ jack_transport_state_t state = AUD_jack_transport_query(m_client, nullptr);
+
+ if(state != m_state)
+ m_nextState = m_state = state;
+
+ return m_nextState != JackTransportStopped;
+}
+
+class JackDeviceFactory : public IDeviceFactory
+{
+private:
+ DeviceSpecs m_specs;
+ int m_buffersize;
+ std::string m_name;
+
+public:
+ JackDeviceFactory() :
+ m_buffersize(AUD_DEFAULT_BUFFER_SIZE),
+ m_name("Audaspace")
+ {
+ m_specs.format = FORMAT_FLOAT32;
+ m_specs.channels = CHANNELS_STEREO;
+ m_specs.rate = RATE_48000;
+ }
+
+ virtual std::shared_ptr<IDevice> openDevice()
+ {
+ return std::shared_ptr<IDevice>(new JackDevice(m_name, m_specs, m_buffersize));
+ }
+
+ virtual int getPriority()
+ {
+ return 0;
+ }
+
+ virtual void setSpecs(DeviceSpecs specs)
+ {
+ m_specs = specs;
+ }
+
+ virtual void setBufferSize(int buffersize)
+ {
+ m_buffersize = buffersize;
+ }
+
+ virtual void setName(std::string name)
+ {
+ m_name = name;
+ }
+};
+
+void JackDevice::registerPlugin()
+{
+ if(loadJACK())
+ DeviceManager::registerDevice("JACK", std::shared_ptr<IDeviceFactory>(new JackDeviceFactory));
+}
+
+#ifdef JACK_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ JackDevice::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "JACK";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/jack/AUD_JackDevice.h b/extern/audaspace/plugins/jack/JackDevice.h
index ccf3bfd6341..72143eda149 100644
--- a/intern/audaspace/jack/AUD_JackDevice.h
+++ b/extern/audaspace/plugins/jack/JackDevice.h
@@ -1,49 +1,47 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/jack/AUD_JackDevice.h
- * \ingroup audjack
- */
+#pragma once
+#ifdef JACK_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
-#ifndef __AUD_JACKDEVICE_H__
-#define __AUD_JACKDEVICE_H__
-
+/**
+ * @file JackDevice.h
+ * @ingroup plugin
+ * The JackDevice class.
+ */
-#include "AUD_SoftwareDevice.h"
-#include "AUD_Buffer.h"
+#include "JackSynchronizer.h"
+#include "devices/SoftwareDevice.h"
+#include "util/Buffer.h"
#include <string>
+#include <condition_variable>
+#include <thread>
+#include <jack/jack.h>
+#include <jack/ringbuffer.h>
-#include <AUD_JackLibrary.h>
-
-typedef void (*AUD_syncFunction)(void*, int, float);
+AUD_NAMESPACE_BEGIN
/**
* This device plays back through JACK.
*/
-class AUD_JackDevice : public AUD_SoftwareDevice
+class AUD_PLUGIN_API JackDevice : public SoftwareDevice
{
private:
/**
@@ -59,12 +57,12 @@ private:
/**
* The output buffer.
*/
- AUD_Buffer m_buffer;
+ Buffer m_buffer;
/**
* The deinterleaving buffer.
*/
- AUD_Buffer m_deinterleavebuf;
+ Buffer m_deinterleavebuf;
jack_ringbuffer_t** m_ringbuffers;
@@ -73,11 +71,14 @@ private:
*/
bool m_valid;
+ /// Synchronizer.
+ JackSynchronizer m_synchronizer;
+
/**
* Invalidates the jack device.
* \param data The jack device that gets invalidet by jack.
*/
- static void jack_shutdown(void *data);
+ AUD_LOCAL static void jack_shutdown(void* data);
/**
* Mixes the next bytes into the buffer.
@@ -85,9 +86,9 @@ private:
* \param data A pointer to the jack device.
* \return 0 what shows success.
*/
- static int jack_mix(jack_nframes_t length, void *data);
+ AUD_LOCAL static int jack_mix(jack_nframes_t length, void* data);
- static int jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data);
+ AUD_LOCAL static int jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data);
/**
* Next JACK Transport state (-1 if not expected to change).
@@ -107,7 +108,7 @@ private:
/**
* External syncronisation callback function.
*/
- AUD_syncFunction m_syncFunc;
+ ISynchronizer::syncFunction m_syncFunc;
/**
* Data for the sync function.
@@ -117,33 +118,26 @@ private:
/**
* The mixing thread.
*/
- pthread_t m_mixingThread;
+ std::thread m_mixingThread;
/**
* Mutex for mixing.
*/
- pthread_mutex_t m_mixingLock;
+ std::mutex m_mixingLock;
/**
* Condition for mixing.
*/
- pthread_cond_t m_mixingCondition;
-
- /**
- * Mixing thread function.
- * \param device The this pointer.
- * \return NULL.
- */
- static void* runMixingThread(void* device);
+ std::condition_variable m_mixingCondition;
/**
* Updates the ring buffers.
*/
- void updateRingBuffers();
+ AUD_LOCAL void updateRingBuffers();
- // hide copy constructor and operator=
- AUD_JackDevice(const AUD_JackDevice&);
- AUD_JackDevice& operator=(const AUD_JackDevice&);
+ // delete copy constructor and operator=
+ JackDevice(const JackDevice&) = delete;
+ JackDevice& operator=(const JackDevice&) = delete;
protected:
virtual void playing(bool playing);
@@ -155,14 +149,16 @@ public:
* \param specs The wanted audio specification, where only the channel count
* is important.
* \param buffersize The size of the internal buffer.
- * \exception AUD_Exception Thrown if the audio device cannot be opened.
+ * \exception Exception Thrown if the audio device cannot be opened.
*/
- AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+ JackDevice(std::string name, DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
/**
* Closes the JACK client.
*/
- virtual ~AUD_JackDevice();
+ virtual ~JackDevice();
+
+ virtual ISynchronizer* getSynchronizer();
/**
* Starts jack transport playback.
@@ -185,7 +181,7 @@ public:
* \param sync The callback function.
* \param data The data for the function.
*/
- void setSyncCallback(AUD_syncFunction sync, void* data);
+ void setSyncCallback(ISynchronizer::syncFunction sync, void* data);
/**
* Retrieves the jack transport playback time.
@@ -198,6 +194,11 @@ public:
* \return Whether jack transport plays back.
*/
bool doesPlayback();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
};
-#endif //__AUD_JACKDEVICE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackLibrary.cpp b/extern/audaspace/plugins/jack/JackLibrary.cpp
new file mode 100644
index 00000000000..92462a34cca
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackLibrary.cpp
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#define JACK_LIBRARY_IMPLEMENTATION
+
+#include <string>
+#include <array>
+
+#include "JackLibrary.h"
+
+#ifdef DYNLOAD_JACK
+#include "plugin/PluginManager.h"
+#endif
+
+AUD_NAMESPACE_BEGIN
+
+bool loadJACK()
+{
+#ifdef DYNLOAD_JACK
+ std::array<const std::string, 5> names = {"libjack.so", "libjack.so.0", "libjack.so.1", "libjack.so.2", "libjack.dll"};
+
+ void* handle = nullptr;
+
+ for(auto& name : names)
+ {
+ handle = PluginManager::openLibrary(name);
+ if(handle)
+ break;
+ }
+
+ if (!handle)
+ return false;
+
+#define JACK_SYMBOL(sym) AUD_##sym = reinterpret_cast<decltype(&sym)>(PluginManager::lookupLibrary(handle, #sym))
+#else
+#define JACK_SYMBOL(sym) AUD_##sym = &sym
+#endif
+
+#include "JackSymbols.h"
+
+#undef JACK_SYMBOL
+
+ return AUD_jack_client_open != nullptr;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackLibrary.h b/extern/audaspace/plugins/jack/JackLibrary.h
new file mode 100644
index 00000000000..4e210852702
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackLibrary.h
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef JACK_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file JackDevice.h
+ * @ingroup plugin
+ * The JackDevice class.
+ */
+
+#include "Audaspace.h"
+
+#include <jack/jack.h>
+#include <jack/ringbuffer.h>
+
+AUD_NAMESPACE_BEGIN
+
+#ifdef JACK_LIBRARY_IMPLEMENTATION
+#define JACK_SYMBOL(sym) decltype(&sym) AUD_##sym
+#else
+#define JACK_SYMBOL(sym) extern decltype(&sym) AUD_##sym
+#endif
+
+#include "JackSymbols.h"
+
+#undef JACK_SYMBOL
+
+bool loadJACK();
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackSymbols.h b/extern/audaspace/plugins/jack/JackSymbols.h
new file mode 100644
index 00000000000..f8e22a7da34
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackSymbols.h
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+JACK_SYMBOL(jack_transport_query);
+JACK_SYMBOL(jack_transport_locate);
+
+JACK_SYMBOL(jack_transport_start);
+JACK_SYMBOL(jack_transport_stop);
+
+JACK_SYMBOL(jack_ringbuffer_reset);
+JACK_SYMBOL(jack_ringbuffer_write);
+JACK_SYMBOL(jack_ringbuffer_write_space);
+JACK_SYMBOL(jack_ringbuffer_write_advance);
+JACK_SYMBOL(jack_ringbuffer_read);
+JACK_SYMBOL(jack_ringbuffer_create);
+JACK_SYMBOL(jack_ringbuffer_free);
+JACK_SYMBOL(jack_ringbuffer_read_space);
+JACK_SYMBOL(jack_set_sync_callback);
+
+JACK_SYMBOL(jack_port_get_buffer);
+
+JACK_SYMBOL(jack_client_open);
+JACK_SYMBOL(jack_set_process_callback);
+JACK_SYMBOL(jack_on_shutdown);
+JACK_SYMBOL(jack_port_register);
+JACK_SYMBOL(jack_client_close);
+JACK_SYMBOL(jack_get_sample_rate);
+JACK_SYMBOL(jack_activate);
+JACK_SYMBOL(jack_get_ports);
+JACK_SYMBOL(jack_port_name);
+JACK_SYMBOL(jack_connect);
+JACK_SYMBOL(jack_free);
diff --git a/extern/audaspace/plugins/jack/JackSynchronizer.cpp b/extern/audaspace/plugins/jack/JackSynchronizer.cpp
new file mode 100644
index 00000000000..cd4c448786d
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackSynchronizer.cpp
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "JackSynchronizer.h"
+
+#include "JackDevice.h"
+
+AUD_NAMESPACE_BEGIN
+
+JackSynchronizer::JackSynchronizer(JackDevice* device) :
+ m_device(device)
+{
+}
+
+void JackSynchronizer::seek(std::shared_ptr<IHandle> handle, float time)
+{
+ m_device->seekPlayback(time);
+}
+
+float JackSynchronizer::getPosition(std::shared_ptr<IHandle> handle)
+{
+ return m_device->getPlaybackPosition();
+}
+
+void JackSynchronizer::play()
+{
+ m_device->startPlayback();
+}
+
+void JackSynchronizer::stop()
+{
+ m_device->stopPlayback();
+}
+
+void JackSynchronizer::setSyncCallback(ISynchronizer::syncFunction function, void* data)
+{
+ m_device->setSyncCallback(function, data);
+}
+
+int JackSynchronizer::isPlaying()
+{
+ return m_device->doesPlayback();
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/jack/JackSynchronizer.h b/extern/audaspace/plugins/jack/JackSynchronizer.h
new file mode 100644
index 00000000000..5c7341a7872
--- /dev/null
+++ b/extern/audaspace/plugins/jack/JackSynchronizer.h
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef JACK_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file JackSynchronizer.h
+ * @ingroup plugin
+ * The JackSynchronizer class.
+ */
+
+#include "devices/ISynchronizer.h"
+
+AUD_NAMESPACE_BEGIN
+
+class JackDevice;
+
+/**
+ * This class is a Synchronizer implementation using JACK Transport.
+ */
+class AUD_PLUGIN_API JackSynchronizer : public ISynchronizer
+{
+private:
+ /// The device that is being synchronized.
+ JackDevice* m_device;
+
+public:
+ /**
+ * Creates a new JackSynchronizer.
+ * @param device The device that should be synchronized.
+ */
+ JackSynchronizer(JackDevice* device);
+
+ virtual void seek(std::shared_ptr<IHandle> handle, float time);
+ virtual float getPosition(std::shared_ptr<IHandle> handle);
+ virtual void play();
+ virtual void stop();
+ virtual void setSyncCallback(syncFunction function, void* data);
+ virtual int isPlaying();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFile.cpp b/extern/audaspace/plugins/libsndfile/SndFile.cpp
new file mode 100644
index 00000000000..ba4ff24ad68
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFile.cpp
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "SndFile.h"
+#include "SndFileReader.h"
+#include "SndFileWriter.h"
+#include "file/FileManager.h"
+
+AUD_NAMESPACE_BEGIN
+
+SndFile::SndFile()
+{
+}
+
+void SndFile::registerPlugin()
+{
+ std::shared_ptr<SndFile> plugin = std::shared_ptr<SndFile>(new SndFile);
+ FileManager::registerInput(plugin);
+ FileManager::registerOutput(plugin);
+}
+
+std::shared_ptr<IReader> SndFile::createReader(std::string filename)
+{
+ return std::shared_ptr<IReader>(new SndFileReader(filename));
+}
+
+std::shared_ptr<IReader> SndFile::createReader(std::shared_ptr<Buffer> buffer)
+{
+ return std::shared_ptr<IReader>(new SndFileReader(buffer));
+}
+
+std::shared_ptr<IWriter> SndFile::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
+{
+ return std::shared_ptr<IWriter>(new SndFileWriter(filename, specs, format, codec, bitrate));
+}
+
+#ifdef LIBSNDFILE_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ SndFile::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "LibSndFile";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFile.h b/extern/audaspace/plugins/libsndfile/SndFile.h
new file mode 100644
index 00000000000..61afed1d564
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFile.h
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef LIBSNDFILE_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file SndFile.h
+ * @ingroup plugin
+ * The SndFile class.
+ */
+
+#include "file/IFileInput.h"
+#include "file/IFileOutput.h"
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This plugin class reads and writes sounds via libsndfile.
+ */
+class AUD_PLUGIN_API SndFile : public IFileInput, public IFileOutput
+{
+private:
+ // delete copy constructor and operator=
+ SndFile(const SndFile&) = delete;
+ SndFile& operator=(const SndFile&) = delete;
+
+public:
+ /**
+ * Creates a new libsndfile plugin.
+ */
+ SndFile();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
+
+ virtual std::shared_ptr<IReader> createReader(std::string filename);
+ virtual std::shared_ptr<IReader> createReader(std::shared_ptr<Buffer> buffer);
+ virtual std::shared_ptr<IWriter> createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFileReader.cpp b/extern/audaspace/plugins/libsndfile/SndFileReader.cpp
new file mode 100644
index 00000000000..d2d89814c07
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFileReader.cpp
@@ -0,0 +1,161 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "SndFileReader.h"
+#include "util/Buffer.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+sf_count_t SndFileReader::vio_get_filelen(void* user_data)
+{
+ SndFileReader* reader = (SndFileReader*)user_data;
+ return reader->m_membuffer->getSize();
+}
+
+sf_count_t SndFileReader::vio_seek(sf_count_t offset, int whence,
+ void* user_data)
+{
+ SndFileReader* reader = (SndFileReader*)user_data;
+
+ switch(whence)
+ {
+ case SEEK_SET:
+ reader->m_memoffset = offset;
+ break;
+ case SEEK_CUR:
+ reader->m_memoffset = reader->m_memoffset + offset;
+ break;
+ case SEEK_END:
+ reader->m_memoffset = reader->m_membuffer->getSize() + offset;
+ break;
+ }
+
+ return reader->m_memoffset;
+}
+
+sf_count_t SndFileReader::vio_read(void* ptr, sf_count_t count,
+ void* user_data)
+{
+ SndFileReader* reader = (SndFileReader*)user_data;
+
+ if(reader->m_memoffset + count > reader->m_membuffer->getSize())
+ count = reader->m_membuffer->getSize() - reader->m_memoffset;
+
+ std::memcpy(ptr, ((data_t*)reader->m_membuffer->getBuffer()) +
+ reader->m_memoffset, count);
+ reader->m_memoffset += count;
+
+ return count;
+}
+
+sf_count_t SndFileReader::vio_tell(void* user_data)
+{
+ SndFileReader* reader = (SndFileReader*)user_data;
+
+ return reader->m_memoffset;
+}
+
+SndFileReader::SndFileReader(std::string filename) :
+ m_position(0)
+{
+ SF_INFO sfinfo;
+
+ sfinfo.format = 0;
+ m_sndfile = sf_open(filename.c_str(), SFM_READ, &sfinfo);
+
+ if(!m_sndfile)
+ AUD_THROW(FileException, "The file couldn't be opened with libsndfile.");
+
+ m_specs.channels = (Channels) sfinfo.channels;
+ m_specs.rate = (SampleRate) sfinfo.samplerate;
+ m_length = sfinfo.frames;
+ m_seekable = sfinfo.seekable;
+}
+
+SndFileReader::SndFileReader(std::shared_ptr<Buffer> buffer) :
+ m_position(0),
+ m_membuffer(buffer),
+ m_memoffset(0)
+{
+ m_vio.get_filelen = vio_get_filelen;
+ m_vio.read = vio_read;
+ m_vio.seek = vio_seek;
+ m_vio.tell = vio_tell;
+ m_vio.write = nullptr;
+
+ SF_INFO sfinfo;
+
+ sfinfo.format = 0;
+ m_sndfile = sf_open_virtual(&m_vio, SFM_READ, &sfinfo, this);
+
+ if(!m_sndfile)
+ AUD_THROW(FileException, "The buffer couldn't be read with libsndfile.");
+
+ m_specs.channels = (Channels) sfinfo.channels;
+ m_specs.rate = (SampleRate) sfinfo.samplerate;
+ m_length = sfinfo.frames;
+ m_seekable = sfinfo.seekable;
+}
+
+SndFileReader::~SndFileReader()
+{
+ sf_close(m_sndfile);
+}
+
+bool SndFileReader::isSeekable() const
+{
+ return m_seekable;
+}
+
+void SndFileReader::seek(int position)
+{
+ if(m_seekable)
+ {
+ position = sf_seek(m_sndfile, position, SEEK_SET);
+ m_position = position;
+ }
+}
+
+int SndFileReader::getLength() const
+{
+ return m_length;
+}
+
+int SndFileReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SndFileReader::getSpecs() const
+{
+ return m_specs;
+}
+
+void SndFileReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ int olen = length;
+
+ length = sf_readf_float(m_sndfile, buffer, length);
+
+ m_position += length;
+
+ eos = length < olen;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFileReader.h b/extern/audaspace/plugins/libsndfile/SndFileReader.h
new file mode 100644
index 00000000000..081c29c686c
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFileReader.h
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#include "IReader.h"
+
+#ifdef LIBSNDFILE_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file SndFileReader.h
+ * @ingroup plugin
+ * The SndFileReader class.
+ */
+
+#include <string>
+#include <sndfile.h>
+#include <memory>
+
+AUD_NAMESPACE_BEGIN
+
+class Buffer;
+
+/**
+ * This class reads a sound file via libsndfile.
+ */
+class AUD_PLUGIN_API SndFileReader : public IReader
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The sample count in the file.
+ */
+ int m_length;
+
+ /**
+ * Whether the file is seekable.
+ */
+ bool m_seekable;
+
+ /**
+ * The specification of the audio data.
+ */
+ Specs m_specs;
+
+ /**
+ * The sndfile.
+ */
+ SNDFILE* m_sndfile;
+
+ /**
+ * The virtual IO structure for memory file reading.
+ */
+ SF_VIRTUAL_IO m_vio;
+
+ /**
+ * The pointer to the memory file.
+ */
+ std::shared_ptr<Buffer> m_membuffer;
+
+ /**
+ * The current reading pointer of the memory file.
+ */
+ int m_memoffset;
+
+ // Functions for libsndfile virtual IO functionality
+ AUD_LOCAL static sf_count_t vio_get_filelen(void* user_data);
+ AUD_LOCAL static sf_count_t vio_seek(sf_count_t offset, int whence, void* user_data);
+ AUD_LOCAL static sf_count_t vio_read(void* ptr, sf_count_t count, void* user_data);
+ AUD_LOCAL static sf_count_t vio_tell(void* user_data);
+
+ // delete copy constructor and operator=
+ SndFileReader(const SndFileReader&) = delete;
+ SndFileReader& operator=(const SndFileReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param filename The path to the file to be read.
+ * \exception Exception Thrown if the file specified does not exist or
+ * cannot be read with libsndfile.
+ */
+ SndFileReader(std::string filename);
+
+ /**
+ * Creates a new reader.
+ * \param buffer The buffer to read from.
+ * \exception Exception Thrown if the buffer specified cannot be read
+ * with libsndfile.
+ */
+ SndFileReader(std::shared_ptr<Buffer> buffer);
+
+ /**
+ * Destroys the reader and closes the file.
+ */
+ virtual ~SndFileReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int& length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFileWriter.cpp b/extern/audaspace/plugins/libsndfile/SndFileWriter.cpp
new file mode 100644
index 00000000000..d2ab117132d
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFileWriter.cpp
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "SndFileWriter.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+SndFileWriter::SndFileWriter(std::string filename, DeviceSpecs specs,
+ Container format, Codec codec, unsigned int bitrate) :
+ m_position(0), m_specs(specs)
+{
+ SF_INFO sfinfo;
+
+ sfinfo.channels = specs.channels;
+ sfinfo.samplerate = int(specs.rate);
+
+ switch(format)
+ {
+ case CONTAINER_FLAC:
+ sfinfo.format = SF_FORMAT_FLAC;
+ switch(specs.format)
+ {
+ case FORMAT_S16:
+ sfinfo.format |= SF_FORMAT_PCM_16;
+ break;
+ case FORMAT_S24:
+ sfinfo.format |= SF_FORMAT_PCM_24;
+ break;
+ case FORMAT_S32:
+ sfinfo.format |= SF_FORMAT_PCM_32;
+ break;
+ case FORMAT_FLOAT32:
+ sfinfo.format |= SF_FORMAT_FLOAT;
+ break;
+ case FORMAT_FLOAT64:
+ sfinfo.format |= SF_FORMAT_DOUBLE;
+ break;
+ default:
+ sfinfo.format = 0;
+ break;
+ }
+ break;
+ case CONTAINER_OGG:
+ if(codec == CODEC_VORBIS)
+ sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
+ else
+ sfinfo.format = 0;
+ break;
+ case CONTAINER_WAV:
+ sfinfo.format = SF_FORMAT_WAV;
+ switch(specs.format)
+ {
+ case FORMAT_U8:
+ sfinfo.format |= SF_FORMAT_PCM_U8;
+ break;
+ case FORMAT_S16:
+ sfinfo.format |= SF_FORMAT_PCM_16;
+ break;
+ case FORMAT_S24:
+ sfinfo.format |= SF_FORMAT_PCM_24;
+ break;
+ case FORMAT_S32:
+ sfinfo.format |= SF_FORMAT_PCM_32;
+ break;
+ case FORMAT_FLOAT32:
+ sfinfo.format |= SF_FORMAT_FLOAT;
+ break;
+ case FORMAT_FLOAT64:
+ sfinfo.format |= SF_FORMAT_DOUBLE;
+ break;
+ default:
+ sfinfo.format = 0;
+ break;
+ }
+ break;
+ default:
+ sfinfo.format = 0;
+ break;
+ }
+
+ if(sfinfo.format == 0)
+ AUD_THROW(FileException, "This format couldn't be written with libsndfile.");
+
+ m_sndfile = sf_open(filename.c_str(), SFM_WRITE, &sfinfo);
+
+ if(!m_sndfile)
+ AUD_THROW(FileException, "The file couldn't be written with libsndfile.");
+}
+
+SndFileWriter::~SndFileWriter()
+{
+ sf_close(m_sndfile);
+}
+
+int SndFileWriter::getPosition() const
+{
+ return m_position;
+}
+
+DeviceSpecs SndFileWriter::getSpecs() const
+{
+ return m_specs;
+}
+
+void SndFileWriter::write(unsigned int length, sample_t* buffer)
+{
+ length = sf_writef_float(m_sndfile, buffer, length);
+
+ m_position += length;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/libsndfile/SndFileWriter.h b/extern/audaspace/plugins/libsndfile/SndFileWriter.h
new file mode 100644
index 00000000000..75d761f5163
--- /dev/null
+++ b/extern/audaspace/plugins/libsndfile/SndFileWriter.h
@@ -0,0 +1,84 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef LIBSNDFILE_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file SndFileWriter.h
+ * @ingroup plugin
+ * The SndFileWriter class.
+ */
+
+#include "file/IWriter.h"
+
+#include <string>
+#include <sndfile.h>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class writes a sound file via libsndfile.
+ */
+class AUD_PLUGIN_API SndFileWriter : public IWriter
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The specification of the audio data.
+ */
+ DeviceSpecs m_specs;
+
+ /**
+ * The sndfile.
+ */
+ SNDFILE* m_sndfile;
+
+ // delete copy constructor and operator=
+ SndFileWriter(const SndFileWriter&) = delete;
+ SndFileWriter& operator=(const SndFileWriter&) = delete;
+
+public:
+ /**
+ * Creates a new writer.
+ * \param filename The path to the file to be read.
+ * \param specs The file's audio specification.
+ * \param format The file's container format.
+ * \param codec The codec used for encoding the audio data.
+ * \param bitrate The bitrate for encoding.
+ * \exception Exception Thrown if the file specified cannot be written
+ * with libsndfile.
+ */
+ SndFileWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate);
+
+ /**
+ * Destroys the writer and closes the file.
+ */
+ virtual ~SndFileWriter();
+
+ virtual int getPosition() const;
+ virtual DeviceSpecs getSpecs() const;
+ virtual void write(unsigned int length, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/openal/OpenALDevice.cpp b/extern/audaspace/plugins/openal/OpenALDevice.cpp
new file mode 100644
index 00000000000..2a609789a6d
--- /dev/null
+++ b/extern/audaspace/plugins/openal/OpenALDevice.cpp
@@ -0,0 +1,1490 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "OpenALDevice.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "respec/ConverterReader.h"
+#include "Exception.h"
+#include "ISound.h"
+
+#include <chrono>
+#include <cstring>
+#include <iostream>
+
+AUD_NAMESPACE_BEGIN
+
+/******************************************************************************/
+/*********************** OpenALHandle Handle Code *************************/
+/******************************************************************************/
+
+bool OpenALDevice::OpenALHandle::pause(bool keep)
+{
+ if(m_status)
+ {
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(m_status == STATUS_PLAYING)
+ {
+ for(auto it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<OpenALHandle> This = *it;
+
+ m_device->m_playingSounds.erase(it);
+ m_device->m_pausedSounds.push_back(This);
+
+ alSourcePause(m_source);
+
+ m_status = keep ? STATUS_STOPPED : STATUS_PAUSED;
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+OpenALDevice::OpenALHandle::OpenALHandle(OpenALDevice* device, ALenum format, std::shared_ptr<IReader> reader, bool keep) :
+ m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format),
+ m_eos(false), m_loopcount(0), m_stop(nullptr), m_stop_data(nullptr), m_status(STATUS_PLAYING),
+ m_device(device)
+{
+ DeviceSpecs specs = m_device->m_specs;
+ specs.specs = m_reader->getSpecs();
+
+ // OpenAL playback code
+ alGenBuffers(CYCLE_BUFFERS, m_buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(DeviceException, "Buffer generation failed while staring playback with OpenAL.");
+
+ try
+ {
+ m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+ int length;
+ bool eos;
+
+ for(m_current = 0; m_current < CYCLE_BUFFERS; m_current++)
+ {
+ length = m_device->m_buffersize;
+ reader->read(length, eos, m_device->m_buffer.getBuffer());
+
+ if(length == 0)
+ break;
+
+ alBufferData(m_buffers[m_current], m_format, m_device->m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
+
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(DeviceException, "Filling the buffer with data failed while starting playback with OpenAL.");
+ }
+
+ alGenSources(1, &m_source);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(DeviceException, "Source generation failed while starting playback with OpenAL.");
+
+ try
+ {
+ alSourceQueueBuffers(m_source, m_current, m_buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(DeviceException, "Buffer queuing failed while starting playback with OpenAL.");
+ }
+ catch(Exception&)
+ {
+ alDeleteSources(1, &m_source);
+ throw;
+ }
+ }
+ catch(Exception&)
+ {
+ alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
+ throw;
+ }
+ alSourcei(m_source, AL_SOURCE_RELATIVE, 1);
+}
+
+bool OpenALDevice::OpenALHandle::pause()
+{
+ return pause(false);
+}
+
+bool OpenALDevice::OpenALHandle::resume()
+{
+ if(m_status)
+ {
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(m_status == STATUS_PAUSED)
+ {
+ for(auto it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<OpenALHandle> This = *it;
+
+ m_device->m_pausedSounds.erase(it);
+ m_device->m_playingSounds.push_back(This);
+
+ m_device->start();
+ m_status = STATUS_PLAYING;
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+bool OpenALDevice::OpenALHandle::stop()
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_status = STATUS_INVALID;
+
+ alDeleteSources(1, &m_source);
+ if(!m_isBuffered)
+ alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
+
+ for(auto it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<OpenALHandle> This = *it;
+
+ m_device->m_playingSounds.erase(it);
+
+ return true;
+ }
+ }
+
+ for(auto it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<OpenALHandle> This = *it;
+
+ m_device->m_pausedSounds.erase(it);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool OpenALDevice::OpenALHandle::getKeep()
+{
+ if(m_status)
+ return m_keep;
+
+ return false;
+}
+
+bool OpenALDevice::OpenALHandle::setKeep(bool keep)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_keep = keep;
+
+ return true;
+}
+
+bool OpenALDevice::OpenALHandle::seek(float position)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(m_isBuffered)
+ alSourcef(m_source, AL_SEC_OFFSET, position);
+ else
+ {
+ m_reader->seek((int)(position * m_reader->getSpecs().rate));
+ m_eos = false;
+
+ ALint info;
+
+ alGetSourcei(m_source, AL_SOURCE_STATE, &info);
+
+ // we need to stop playing sounds as well to clear the buffers
+ // this might cause clicks, but fixes a bug regarding position determination
+ if(info == AL_PAUSED || info == AL_PLAYING)
+ alSourceStop(m_source);
+
+ alSourcei(m_source, AL_BUFFER, 0);
+
+ ALenum err;
+ if((err = alGetError()) == AL_NO_ERROR)
+ {
+ int length;
+ DeviceSpecs specs = m_device->m_specs;
+ specs.specs = m_reader->getSpecs();
+ m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+
+ for(m_current = 0; m_current < CYCLE_BUFFERS; m_current++)
+ {
+ length = m_device->m_buffersize;
+
+ m_reader->read(length, m_eos, m_device->m_buffer.getBuffer());
+
+ if(length == 0)
+ break;
+
+ alBufferData(m_buffers[m_current], m_format, m_device->m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
+
+ if(alGetError() != AL_NO_ERROR)
+ break;
+ }
+
+ if(m_loopcount != 0)
+ m_eos = false;
+
+ alSourceQueueBuffers(m_source, m_current, m_buffers);
+ }
+
+ alSourceRewind(m_source);
+ }
+
+ if(m_status == STATUS_STOPPED)
+ m_status = STATUS_PAUSED;
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getPosition()
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return 0.0f;
+
+ float position = 0.0f;
+
+ alGetSourcef(m_source, AL_SEC_OFFSET, &position);
+
+ if(!m_isBuffered)
+ {
+ int queued;
+
+ // this usually always returns CYCLE_BUFFERS
+ alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queued);
+
+ Specs specs = m_reader->getSpecs();
+ position += (m_reader->getPosition() - m_device->m_buffersize * queued) / (float)specs.rate;
+ }
+
+ return position;
+}
+
+Status OpenALDevice::OpenALHandle::getStatus()
+{
+ return m_status;
+}
+
+float OpenALDevice::OpenALHandle::getVolume()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_GAIN, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setVolume(float volume)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(volume >= 0.0f)
+ alSourcef(m_source, AL_GAIN, volume);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getPitch()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_PITCH, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setPitch(float pitch)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(pitch > 0.0f)
+ alSourcef(m_source, AL_PITCH, pitch);
+
+ return true;
+}
+
+int OpenALDevice::OpenALHandle::getLoopCount()
+{
+ if(!m_status)
+ return 0;
+ return m_loopcount;
+}
+
+bool OpenALDevice::OpenALHandle::setLoopCount(int count)
+{
+ if(!m_status)
+ return false;
+
+ if(m_status == STATUS_STOPPED && (count > m_loopcount || count < 0))
+ m_status = STATUS_PAUSED;
+
+ m_loopcount = count;
+
+ return true;
+}
+
+bool OpenALDevice::OpenALHandle::setStopCallback(stopCallback callback, void* data)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_stop = callback;
+ m_stop_data = data;
+
+ return true;
+}
+
+/******************************************************************************/
+/********************* OpenALHandle 3DHandle Code *************************/
+/******************************************************************************/
+
+Vector3 OpenALDevice::OpenALHandle::getLocation()
+{
+ Vector3 result = Vector3(0, 0, 0);
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ ALfloat p[3];
+ alGetSourcefv(m_source, AL_POSITION, p);
+
+ result = Vector3(p[0], p[1], p[2]);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setLocation(const Vector3& location)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
+
+ return true;
+}
+
+Vector3 OpenALDevice::OpenALHandle::getVelocity()
+{
+ Vector3 result = Vector3(0, 0, 0);
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ ALfloat v[3];
+ alGetSourcefv(m_source, AL_VELOCITY, v);
+
+ result = Vector3(v[0], v[1], v[2]);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setVelocity(const Vector3& velocity)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
+
+ return true;
+}
+
+Quaternion OpenALDevice::OpenALHandle::getOrientation()
+{
+ return m_orientation;
+}
+
+bool OpenALDevice::OpenALHandle::setOrientation(const Quaternion& orientation)
+{
+ ALfloat direction[3];
+ direction[0] = -2 * (orientation.w() * orientation.y() +
+ orientation.x() * orientation.z());
+ direction[1] = 2 * (orientation.x() * orientation.w() -
+ orientation.z() * orientation.y());
+ direction[2] = 2 * (orientation.x() * orientation.x() +
+ orientation.y() * orientation.y()) - 1;
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcefv(m_source, AL_DIRECTION, direction);
+
+ m_orientation = orientation;
+
+ return true;
+}
+
+bool OpenALDevice::OpenALHandle::isRelative()
+{
+ int result;
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setRelative(bool relative)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getVolumeMaximum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_MAX_GAIN, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setVolumeMaximum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(volume >= 0.0f && volume <= 1.0f)
+ alSourcef(m_source, AL_MAX_GAIN, volume);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getVolumeMinimum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_MIN_GAIN, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setVolumeMinimum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(volume >= 0.0f && volume <= 1.0f)
+ alSourcef(m_source, AL_MIN_GAIN, volume);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getDistanceMaximum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setDistanceMaximum(float distance)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(distance >= 0.0f)
+ alSourcef(m_source, AL_MAX_DISTANCE, distance);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getDistanceReference()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setDistanceReference(float distance)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(distance >= 0.0f)
+ alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getAttenuation()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setAttenuation(float factor)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(factor >= 0.0f)
+ alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getConeAngleOuter()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setConeAngleOuter(float angle)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getConeAngleInner()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setConeAngleInner(float angle)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
+
+ return true;
+}
+
+float OpenALDevice::OpenALHandle::getConeVolumeOuter()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return result;
+
+ alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
+
+ return result;
+}
+
+bool OpenALDevice::OpenALHandle::setConeVolumeOuter(float volume)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ if(volume >= 0.0f && volume <= 1.0f)
+ alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
+
+ return true;
+}
+
+/******************************************************************************/
+/**************************** Threading Code **********************************/
+/******************************************************************************/
+
+void OpenALDevice::start()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(!m_playing)
+ {
+ if(m_thread.joinable())
+ m_thread.join();
+
+ m_thread = std::thread(&OpenALDevice::updateStreams, this);
+
+ m_playing = true;
+ }
+}
+
+void OpenALDevice::updateStreams()
+{
+ int length;
+
+ ALint info;
+ DeviceSpecs specs = m_specs;
+ ALCenum cerr;
+ std::list<std::shared_ptr<OpenALHandle> > stopSounds;
+ std::list<std::shared_ptr<OpenALHandle> > pauseSounds;
+
+ auto sleepDuration = std::chrono::milliseconds(20);
+
+ for(;;)
+ {
+ lock();
+
+ alcSuspendContext(m_context);
+ cerr = alcGetError(m_device);
+ if(cerr == ALC_NO_ERROR)
+ {
+ // for all sounds
+ for(auto& sound : m_playingSounds)
+ {
+ // is it a streamed sound?
+ if(!sound->m_isBuffered)
+ {
+ // check for buffer refilling
+ alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info);
+
+ info += (OpenALHandle::CYCLE_BUFFERS - sound->m_current);
+
+ if(info)
+ {
+ specs.specs = sound->m_reader->getSpecs();
+ m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+
+ // for all empty buffers
+ while(info--)
+ {
+ // if there's still data to play back
+ if(!sound->m_eos)
+ {
+ // read data
+ length = m_buffersize;
+
+ try
+ {
+ sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
+
+ // looping necessary?
+ if(length == 0 && sound->m_loopcount)
+ {
+ if(sound->m_loopcount > 0)
+ sound->m_loopcount--;
+
+ sound->m_reader->seek(0);
+
+ length = m_buffersize;
+ sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
+ }
+ }
+ catch(Exception& e)
+ {
+ length = 0;
+ std::cerr << "Caught exception while reading sound data during playback with OpenAL: " << e.getMessage() << std::endl;
+ }
+
+ if(sound->m_loopcount != 0)
+ sound->m_eos = false;
+
+ // read nothing?
+ if(length == 0)
+ {
+ break;
+ }
+
+ ALuint buffer;
+
+ if(sound->m_current < OpenALHandle::CYCLE_BUFFERS)
+ buffer = sound->m_buffers[sound->m_current++];
+ else
+ alSourceUnqueueBuffers(sound->m_source, 1, &buffer);
+
+ ALenum err;
+ if((err = alGetError()) != AL_NO_ERROR)
+ {
+ sound->m_eos = true;
+ break;
+ }
+
+ // fill with new data
+ alBufferData(buffer, sound->m_format, m_buffer.getBuffer(), length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
+
+ if((err = alGetError()) != AL_NO_ERROR)
+ {
+ sound->m_eos = true;
+ break;
+ }
+
+ // and queue again
+ alSourceQueueBuffers(sound->m_source, 1,&buffer);
+ if(alGetError() != AL_NO_ERROR)
+ {
+ sound->m_eos = true;
+ break;
+ }
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ // check if the sound has been stopped
+ alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info);
+
+ if(info != AL_PLAYING)
+ {
+ // if it really stopped
+ if(sound->m_eos && info != AL_INITIAL)
+ {
+ if(sound->m_stop)
+ sound->m_stop(sound->m_stop_data);
+
+ // pause or
+ if(sound->m_keep)
+ pauseSounds.push_back(sound);
+ // stop
+ else
+ stopSounds.push_back(sound);
+ }
+ // continue playing
+ else
+ alSourcePlay(sound->m_source);
+ }
+ }
+
+ for(auto& sound : pauseSounds)
+ sound->pause(true);
+
+ for(auto& sound : stopSounds)
+ sound->stop();
+
+ pauseSounds.clear();
+ stopSounds.clear();
+
+ alcProcessContext(m_context);
+ }
+
+ // stop thread
+ if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
+ {
+ m_playing = false;
+ unlock();
+
+ return;
+ }
+
+ unlock();
+
+ std::this_thread::sleep_for(sleepDuration);
+ }
+}
+
+/******************************************************************************/
+/**************************** IDevice Code ************************************/
+/******************************************************************************/
+
+OpenALDevice::OpenALDevice(DeviceSpecs specs, int buffersize, std::string name) :
+ m_playing(false), m_buffersize(buffersize)
+{
+ // cannot determine how many channels or which format OpenAL uses, but
+ // it at least is able to play 16 bit stereo audio
+ specs.format = FORMAT_S16;
+
+ if(name.empty())
+ m_device = alcOpenDevice(nullptr);
+ else
+ m_device = alcOpenDevice(name.c_str());
+
+ if(!m_device)
+ AUD_THROW(DeviceException, "The audio device couldn't be opened with OpenAL.");
+
+ // at least try to set the frequency
+ ALCint attribs[] = { ALC_FREQUENCY, (ALCint)specs.rate, 0 };
+ ALCint* attributes = attribs;
+ if(specs.rate == RATE_INVALID)
+ attributes = nullptr;
+
+ m_context = alcCreateContext(m_device, attributes);
+ alcMakeContextCurrent(m_context);
+
+ alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate);
+
+ // check for specific formats and channel counts to be played back
+ if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
+ specs.format = FORMAT_FLOAT32;
+
+ m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
+
+ if((!m_useMC && specs.channels > CHANNELS_STEREO) ||
+ specs.channels == CHANNELS_STEREO_LFE ||
+ specs.channels == CHANNELS_SURROUND5)
+ specs.channels = CHANNELS_STEREO;
+
+ alGetError();
+ alcGetError(m_device);
+
+ m_specs = specs;
+}
+
+OpenALDevice::~OpenALDevice()
+{
+ lock();
+ alcSuspendContext(m_context);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+
+ alcProcessContext(m_context);
+
+ // wait for the thread to stop
+ unlock();
+ if(m_thread.joinable())
+ m_thread.join();
+
+ // quit OpenAL
+ alcMakeContextCurrent(nullptr);
+ alcDestroyContext(m_context);
+ alcCloseDevice(m_device);
+}
+
+DeviceSpecs OpenALDevice::getSpecs() const
+{
+ return m_specs;
+}
+
+bool OpenALDevice::getFormat(ALenum &format, Specs specs)
+{
+ bool valid = true;
+ format = 0;
+
+ switch(m_specs.format)
+ {
+ case FORMAT_S16:
+ switch(specs.channels)
+ {
+ case CHANNELS_MONO:
+ format = AL_FORMAT_MONO16;
+ break;
+ case CHANNELS_STEREO:
+ format = AL_FORMAT_STEREO16;
+ break;
+ case CHANNELS_SURROUND4:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_QUAD16");
+ break;
+ }
+ case CHANNELS_SURROUND51:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_51CHN16");
+ break;
+ }
+ case CHANNELS_SURROUND61:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_61CHN16");
+ break;
+ }
+ case CHANNELS_SURROUND71:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_71CHN16");
+ break;
+ }
+ default:
+ valid = false;
+ }
+ break;
+ case FORMAT_FLOAT32:
+ switch(specs.channels)
+ {
+ case CHANNELS_MONO:
+ format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
+ break;
+ case CHANNELS_STEREO:
+ format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
+ break;
+ case CHANNELS_SURROUND4:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_QUAD32");
+ break;
+ }
+ case CHANNELS_SURROUND51:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_51CHN32");
+ break;
+ }
+ case CHANNELS_SURROUND61:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_61CHN32");
+ break;
+ }
+ case CHANNELS_SURROUND71:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_71CHN32");
+ break;
+ }
+ default:
+ valid = false;
+ }
+ break;
+ default:
+ valid = false;
+ }
+
+ if(!format)
+ valid = false;
+
+ return valid;
+}
+
+std::shared_ptr<IHandle> OpenALDevice::play(std::shared_ptr<IReader> reader, bool keep)
+{
+ Specs specs = reader->getSpecs();
+
+ // check format
+ if(specs.channels == CHANNELS_INVALID)
+ return std::shared_ptr<IHandle>();
+
+ if(m_specs.format != FORMAT_FLOAT32)
+ reader = std::shared_ptr<IReader>(new ConverterReader(reader, m_specs));
+
+ ALenum format;
+
+ if(!getFormat(format, specs))
+ return std::shared_ptr<IHandle>();
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alcSuspendContext(m_context);
+
+ std::shared_ptr<OpenALDevice::OpenALHandle> sound;
+
+ try
+ {
+ // create the handle
+ sound = std::shared_ptr<OpenALDevice::OpenALHandle>(new OpenALDevice::OpenALHandle(this, format, reader, keep));
+ }
+ catch(Exception&)
+ {
+ alcProcessContext(m_context);
+ throw;
+ }
+
+ alcProcessContext(m_context);
+
+ // play sound
+ m_playingSounds.push_back(sound);
+
+ start();
+
+ return std::shared_ptr<IHandle>(sound);
+}
+
+std::shared_ptr<IHandle> OpenALDevice::play(std::shared_ptr<ISound> sound, bool keep)
+{
+ return play(sound->createReader(), keep);
+}
+
+void OpenALDevice::stopAll()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alcSuspendContext(m_context);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+
+ alcProcessContext(m_context);
+}
+
+void OpenALDevice::lock()
+{
+ m_mutex.lock();
+}
+
+void OpenALDevice::unlock()
+{
+ m_mutex.unlock();
+}
+
+float OpenALDevice::getVolume() const
+{
+ float result;
+
+ alGetListenerf(AL_GAIN, &result);
+ return result;
+}
+
+void OpenALDevice::setVolume(float volume)
+{
+ if(volume < 0.0f)
+ return;
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alListenerf(AL_GAIN, volume);
+}
+
+ISynchronizer* OpenALDevice::getSynchronizer()
+{
+ return &m_synchronizer;
+}
+
+/******************************************************************************/
+/**************************** 3D Device Code **********************************/
+/******************************************************************************/
+
+Vector3 OpenALDevice::getListenerLocation() const
+{
+ ALfloat p[3];
+
+ alGetListenerfv(AL_POSITION, p);
+ return Vector3(p[0], p[1], p[2]);
+}
+
+void OpenALDevice::setListenerLocation(const Vector3& location)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alListenerfv(AL_POSITION, (ALfloat*)location.get());
+}
+
+Vector3 OpenALDevice::getListenerVelocity() const
+{
+ ALfloat v[3];
+
+ alGetListenerfv(AL_VELOCITY, v);
+ return Vector3(v[0], v[1], v[2]);
+}
+
+void OpenALDevice::setListenerVelocity(const Vector3& velocity)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alListenerfv(AL_VELOCITY, (ALfloat*)velocity.get());
+}
+
+Quaternion OpenALDevice::getListenerOrientation() const
+{
+ return m_orientation;
+}
+
+void OpenALDevice::setListenerOrientation(const Quaternion& orientation)
+{
+ ALfloat direction[6];
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ direction[0] = -2 * (orientation.w() * orientation.y() +
+ orientation.x() * orientation.z());
+ direction[1] = 2 * (orientation.x() * orientation.w() -
+ orientation.z() * orientation.y());
+ direction[2] = 2 * (orientation.x() * orientation.x() +
+ orientation.y() * orientation.y()) - 1;
+ direction[3] = 2 * (orientation.x() * orientation.y() -
+ orientation.w() * orientation.z());
+ direction[4] = 1 - 2 * (orientation.x() * orientation.x() +
+ orientation.z() * orientation.z());
+ direction[5] = 2 * (orientation.w() * orientation.x() +
+ orientation.y() * orientation.z());
+ alListenerfv(AL_ORIENTATION, direction);
+ m_orientation = orientation;
+}
+
+float OpenALDevice::getSpeedOfSound() const
+{
+ return alGetFloat(AL_SPEED_OF_SOUND);
+}
+
+void OpenALDevice::setSpeedOfSound(float speed)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alSpeedOfSound(speed);
+}
+
+float OpenALDevice::getDopplerFactor() const
+{
+ return alGetFloat(AL_DOPPLER_FACTOR);
+}
+
+void OpenALDevice::setDopplerFactor(float factor)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ alDopplerFactor(factor);
+}
+
+DistanceModel OpenALDevice::getDistanceModel() const
+{
+ switch(alGetInteger(AL_DISTANCE_MODEL))
+ {
+ case AL_INVERSE_DISTANCE:
+ return DISTANCE_MODEL_INVERSE;
+ case AL_INVERSE_DISTANCE_CLAMPED:
+ return DISTANCE_MODEL_INVERSE_CLAMPED;
+ case AL_LINEAR_DISTANCE:
+ return DISTANCE_MODEL_LINEAR;
+ case AL_LINEAR_DISTANCE_CLAMPED:
+ return DISTANCE_MODEL_LINEAR_CLAMPED;
+ case AL_EXPONENT_DISTANCE:
+ return DISTANCE_MODEL_EXPONENT;
+ case AL_EXPONENT_DISTANCE_CLAMPED:
+ return DISTANCE_MODEL_EXPONENT_CLAMPED;
+ default:
+ return DISTANCE_MODEL_INVALID;
+ }
+}
+
+void OpenALDevice::setDistanceModel(DistanceModel model)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ switch(model)
+ {
+ case DISTANCE_MODEL_INVERSE:
+ alDistanceModel(AL_INVERSE_DISTANCE);
+ break;
+ case DISTANCE_MODEL_INVERSE_CLAMPED:
+ alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+ break;
+ case DISTANCE_MODEL_LINEAR:
+ alDistanceModel(AL_LINEAR_DISTANCE);
+ break;
+ case DISTANCE_MODEL_LINEAR_CLAMPED:
+ alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
+ break;
+ case DISTANCE_MODEL_EXPONENT:
+ alDistanceModel(AL_EXPONENT_DISTANCE);
+ break;
+ case DISTANCE_MODEL_EXPONENT_CLAMPED:
+ alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
+ break;
+ default:
+ alDistanceModel(AL_NONE);
+ }
+}
+
+std::list<std::string> OpenALDevice::getDeviceNames()
+{
+ std::list<std::string> names;
+
+ if(alcIsExtensionPresent(nullptr, "ALC_ENUMERATION_EXT") == AL_TRUE)
+ {
+ ALCchar* devices = const_cast<ALCchar*>(alcGetString(nullptr, ALC_DEVICE_SPECIFIER));
+ std::string default_device = alcGetString(nullptr, ALC_DEFAULT_DEVICE_SPECIFIER);
+
+ while(*devices)
+ {
+ std::string device = devices;
+
+ if(device == default_device)
+ names.push_front(device);
+ else
+ names.push_back(device);
+
+ devices += strlen(devices) + 1;
+ }
+ }
+
+ return names;
+}
+
+class OpenALDeviceFactory : public IDeviceFactory
+{
+private:
+ DeviceSpecs m_specs;
+ int m_buffersize;
+ std::string m_name;
+
+public:
+ OpenALDeviceFactory(std::string name = "") :
+ m_buffersize(AUD_DEFAULT_BUFFER_SIZE),
+ m_name(name)
+ {
+ m_specs.format = FORMAT_FLOAT32;
+ m_specs.channels = CHANNELS_SURROUND51;
+ m_specs.rate = RATE_48000;
+ }
+
+ virtual std::shared_ptr<IDevice> openDevice()
+ {
+ return std::shared_ptr<IDevice>(new OpenALDevice(m_specs, m_buffersize, m_name));
+ }
+
+ virtual int getPriority()
+ {
+ return 1 << 10;
+ }
+
+ virtual void setSpecs(DeviceSpecs specs)
+ {
+ m_specs = specs;
+ }
+
+ virtual void setBufferSize(int buffersize)
+ {
+ m_buffersize = buffersize;
+ }
+
+ virtual void setName(std::string name)
+ {
+ }
+};
+
+void OpenALDevice::registerPlugin()
+{
+ auto names = OpenALDevice::getDeviceNames();
+ DeviceManager::registerDevice("OpenAL", std::shared_ptr<IDeviceFactory>(new OpenALDeviceFactory));
+ for(std::string &name : names)
+ {
+ DeviceManager::registerDevice("OpenAL - " + name, std::shared_ptr<IDeviceFactory>(new OpenALDeviceFactory(name)));
+ }
+}
+
+#ifdef OPENAL_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ OpenALDevice::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "OpenAL";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/extern/audaspace/plugins/openal/OpenALDevice.h
index f0e47824967..b9b461a327c 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/extern/audaspace/plugins/openal/OpenALDevice.h
@@ -1,64 +1,66 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/OpenAL/AUD_OpenALDevice.h
- * \ingroup audopenal
- */
+#pragma once
+#ifdef OPENAL_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
-#ifndef __AUD_OPENALDEVICE_H__
-#define __AUD_OPENALDEVICE_H__
+/**
+ * @file OpenALDevice.h
+ * @ingroup plugin
+ * The OpenALDevice class.
+ */
-#include "AUD_IDevice.h"
-#include "AUD_IHandle.h"
-#include "AUD_I3DDevice.h"
-#include "AUD_I3DHandle.h"
-#include "AUD_Buffer.h"
-//struct AUD_OpenALBufferedFactory;
+#include "devices/IDevice.h"
+#include "devices/IHandle.h"
+#include "devices/I3DDevice.h"
+#include "devices/I3DHandle.h"
+#include "devices/DefaultSynchronizer.h"
+#include "util/Buffer.h"
-#include <AL/al.h>
-#include <AL/alc.h>
+#include <al.h>
+#include <alc.h>
#include <list>
-#include <pthread.h>
+#include <mutex>
+#include <thread>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
/**
* This device plays through OpenAL.
*/
-class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice
+class AUD_PLUGIN_API OpenALDevice : public IDevice, public I3DDevice
{
private:
/// Saves the data for playback.
- class AUD_OpenALHandle : public AUD_IHandle, public AUD_I3DHandle
+ class OpenALHandle : public IHandle, public I3DHandle
{
- public:
+ private:
+ friend class OpenALDevice;
+
static const int CYCLE_BUFFERS = 3;
/// Whether it's a buffered or a streamed source.
bool m_isBuffered;
/// The reader source.
- boost::shared_ptr<AUD_IReader> m_reader;
+ std::shared_ptr<IReader> m_reader;
/// Whether to keep the source if end of it is reached.
bool m_keep;
@@ -88,15 +90,19 @@ private:
void* m_stop_data;
/// Orientation.
- AUD_Quaternion m_orientation;
+ Quaternion m_orientation;
/// Current status of the handle
- AUD_Status m_status;
+ Status m_status;
/// Own device.
- AUD_OpenALDevice* m_device;
+ OpenALDevice* m_device;
- bool pause(bool keep);
+ AUD_LOCAL bool pause(bool keep);
+
+ // delete copy constructor and operator=
+ OpenALHandle(const OpenALHandle&) = delete;
+ OpenALHandle& operator=(const OpenALHandle&) = delete;
public:
@@ -107,9 +113,9 @@ 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, boost::shared_ptr<AUD_IReader> reader, bool keep);
+ OpenALHandle(OpenALDevice* device, ALenum format, std::shared_ptr<IReader> reader, bool keep);
- virtual ~AUD_OpenALHandle() {}
+ virtual ~OpenALHandle() {}
virtual bool pause();
virtual bool resume();
virtual bool stop();
@@ -117,7 +123,7 @@ private:
virtual bool setKeep(bool keep);
virtual bool seek(float position);
virtual float getPosition();
- virtual AUD_Status getStatus();
+ virtual Status getStatus();
virtual float getVolume();
virtual bool setVolume(float volume);
virtual float getPitch();
@@ -126,12 +132,12 @@ private:
virtual bool setLoopCount(int count);
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
- virtual AUD_Vector3 getSourceLocation();
- virtual bool setSourceLocation(const AUD_Vector3& location);
- virtual AUD_Vector3 getSourceVelocity();
- virtual bool setSourceVelocity(const AUD_Vector3& velocity);
- virtual AUD_Quaternion getSourceOrientation();
- virtual bool setSourceOrientation(const AUD_Quaternion& orientation);
+ virtual Vector3 getLocation();
+ virtual bool setLocation(const Vector3& location);
+ virtual Vector3 getVelocity();
+ virtual bool setVelocity(const Vector3& velocity);
+ virtual Quaternion getOrientation();
+ virtual bool setOrientation(const Quaternion& orientation);
virtual bool isRelative();
virtual bool setRelative(bool relative);
virtual float getVolumeMaximum();
@@ -152,8 +158,6 @@ private:
virtual bool setConeVolumeOuter(float volume);
};
- typedef std::list<boost::shared_ptr<AUD_OpenALHandle> >::iterator AUD_HandleIterator;
-
/**
* The OpenAL device handle.
*/
@@ -167,7 +171,7 @@ private:
/**
* The specification of the device.
*/
- AUD_DeviceSpecs m_specs;
+ DeviceSpecs m_specs;
/**
* Whether the device has the AL_EXT_MCFORMATS extension.
@@ -177,27 +181,22 @@ private:
/**
* The list of sounds that are currently playing.
*/
- std::list<boost::shared_ptr<AUD_OpenALHandle> > m_playingSounds;
+ std::list<std::shared_ptr<OpenALHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<boost::shared_ptr<AUD_OpenALHandle> > m_pausedSounds;
-
- /**
- * The list of buffered factories.
- */
- //std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
+ std::list<std::shared_ptr<OpenALHandle> > m_pausedSounds;
/**
* The mutex for locking.
*/
- pthread_mutex_t m_mutex;
+ std::recursive_mutex m_mutex;
/**
* The streaming thread.
*/
- pthread_t m_thread;
+ std::thread m_thread;
/**
* The condition for streaming thread wakeup.
@@ -212,18 +211,26 @@ private:
/**
* Device buffer.
*/
- AUD_Buffer m_buffer;
+ Buffer m_buffer;
/**
* Orientation.
*/
- AUD_Quaternion m_orientation;
+ Quaternion m_orientation;
+
+ /// Synchronizer.
+ DefaultSynchronizer m_synchronizer;
/**
* Starts the streaming thread.
* \param Whether the previous thread should be joined.
*/
- void start(bool join = true);
+ AUD_LOCAL void start();
+
+ /**
+ * Streaming thread main function.
+ */
+ AUD_LOCAL void updateStreams();
/**
* Gets the format according to the specs.
@@ -231,52 +238,59 @@ private:
* \param specs The specs to read the channel count from.
* \return Whether the format is valid or not.
*/
- bool getFormat(ALenum &format, AUD_Specs specs);
+ AUD_LOCAL bool getFormat(ALenum &format, Specs specs);
- // hide copy constructor and operator=
- AUD_OpenALDevice(const AUD_OpenALDevice&);
- AUD_OpenALDevice& operator=(const AUD_OpenALDevice&);
+ // delete copy constructor and operator=
+ OpenALDevice(const OpenALDevice&) = delete;
+ OpenALDevice& operator=(const OpenALDevice&) = delete;
public:
/**
* Opens the OpenAL audio device for playback.
* \param specs The wanted audio specification.
* \param buffersize The size of the internal buffer.
+ * \param name The name of the device to be opened.
* \note The specification really used for opening the device may differ.
* \note The buffersize will be multiplicated by three for this device.
- * \exception AUD_Exception Thrown if the audio device cannot be opened.
- */
- AUD_OpenALDevice(AUD_DeviceSpecs specs,
- int buffersize = AUD_DEFAULT_BUFFER_SIZE);
-
- /**
- * Streaming thread main function.
+ * \exception DeviceException Thrown if the audio device cannot be opened.
*/
- void updateStreams();
+ OpenALDevice(DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE, std::string name = "");
- virtual ~AUD_OpenALDevice();
+ virtual ~OpenALDevice();
- virtual AUD_DeviceSpecs getSpecs() const;
- 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 DeviceSpecs getSpecs() const;
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<IReader> reader, bool keep = false);
+ virtual std::shared_ptr<IHandle> play(std::shared_ptr<ISound> sound, bool keep = false);
virtual void stopAll();
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
-
- virtual AUD_Vector3 getListenerLocation() const;
- virtual void setListenerLocation(const AUD_Vector3& location);
- virtual AUD_Vector3 getListenerVelocity() const;
- virtual void setListenerVelocity(const AUD_Vector3& velocity);
- virtual AUD_Quaternion getListenerOrientation() const;
- virtual void setListenerOrientation(const AUD_Quaternion& orientation);
+ virtual ISynchronizer* getSynchronizer();
+
+ virtual Vector3 getListenerLocation() const;
+ virtual void setListenerLocation(const Vector3& location);
+ virtual Vector3 getListenerVelocity() const;
+ virtual void setListenerVelocity(const Vector3& velocity);
+ virtual Quaternion getListenerOrientation() const;
+ virtual void setListenerOrientation(const Quaternion& orientation);
virtual float getSpeedOfSound() const;
virtual void setSpeedOfSound(float speed);
virtual float getDopplerFactor() const;
virtual void setDopplerFactor(float factor);
- virtual AUD_DistanceModel getDistanceModel() const;
- virtual void setDistanceModel(AUD_DistanceModel model);
+ virtual DistanceModel getDistanceModel() const;
+ virtual void setDistanceModel(DistanceModel model);
+
+ /**
+ * Retrieves a list of available hardware devices to open with OpenAL.
+ * @return The list of devices to open.
+ */
+ static std::list<std::string> getDeviceNames();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
};
-#endif //__AUD_OPENALDEVICE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/openal/OpenALReader.cpp b/extern/audaspace/plugins/openal/OpenALReader.cpp
new file mode 100644
index 00000000000..52356d4f7ec
--- /dev/null
+++ b/extern/audaspace/plugins/openal/OpenALReader.cpp
@@ -0,0 +1,96 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "OpenALReader.h"
+#include "respec/ConverterFunctions.h"
+#include "Exception.h"
+
+#include <algorithm>
+#include <al.h>
+
+AUD_NAMESPACE_BEGIN
+
+OpenALReader::OpenALReader(Specs specs, int buffersize) :
+ m_specs(specs),
+ m_position(0),
+ m_device(nullptr)
+{
+ if((specs.channels != CHANNELS_MONO) && (specs.channels != CHANNELS_STEREO))
+ specs.channels = CHANNELS_MONO;
+
+ m_device = alcCaptureOpenDevice(nullptr, specs.rate,
+ specs.channels == CHANNELS_MONO ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16,
+ buffersize * specs.channels * 2);
+
+ if(!m_device)
+ AUD_THROW(DeviceException, "The capture device couldn't be opened with OpenAL.");
+
+ alcCaptureStart(m_device);
+}
+
+OpenALReader::~OpenALReader()
+{
+ if(m_device)
+ {
+ //alcCaptureStop(m_device);
+ alcCaptureCloseDevice(m_device);
+ }
+}
+
+bool OpenALReader::isSeekable() const
+{
+ return false;
+}
+
+void OpenALReader::seek(int position)
+{
+ m_position = position;
+}
+
+int OpenALReader::getLength() const
+{
+ int length;
+ alcGetIntegerv(m_device, ALC_CAPTURE_SAMPLES, 1, &length);
+ return length;
+}
+
+int OpenALReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs OpenALReader::getSpecs() const
+{
+ return m_specs;
+}
+
+void OpenALReader::read(int & length, bool& eos, sample_t* buffer)
+{
+ int len = getLength();
+ length = std::min(length, len);
+
+ if(length > 0)
+ {
+ alcCaptureSamples(m_device, buffer, length);
+ convert_s16_float((data_t*)buffer, (data_t*)buffer, length * m_specs.channels);
+ }
+
+ eos = false;
+
+ m_position += length;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/openal/OpenALReader.h b/extern/audaspace/plugins/openal/OpenALReader.h
new file mode 100644
index 00000000000..5d96ea9b027
--- /dev/null
+++ b/extern/audaspace/plugins/openal/OpenALReader.h
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef OPENAL_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file OpenALReader.h
+ * @ingroup plugin
+ * The OpenALReader class.
+ */
+
+#include "IReader.h"
+
+#include <alc.h>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This class is used for sine tone playback.
+ * The output format is in the 16 bit format and stereo, the sample rate can be
+ * specified.
+ * As the two channels both play the same the output could also be mono, but
+ * in most cases this will result in having to resample for output, so stereo
+ * sound is created directly.
+ */
+class AUD_PLUGIN_API OpenALReader : public IReader
+{
+private:
+ /**
+ * The specs of the reader.
+ */
+ Specs m_specs;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The capture device.
+ */
+ ALCdevice* m_device;
+
+ // delete copy constructor and operator=
+ OpenALReader(const OpenALReader&) = delete;
+ OpenALReader& operator=(const OpenALReader&) = delete;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param specs The desired specification of the output samples.
+ * \param buffersize The buffer size used to read from the device.
+ */
+ OpenALReader(Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+
+ virtual ~OpenALReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual Specs getSpecs() const;
+ virtual void read(int & length, bool& eos, sample_t* buffer);
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/sdl/SDLDevice.cpp b/extern/audaspace/plugins/sdl/SDLDevice.cpp
new file mode 100644
index 00000000000..603e16001b8
--- /dev/null
+++ b/extern/audaspace/plugins/sdl/SDLDevice.cpp
@@ -0,0 +1,156 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "SDLDevice.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "Exception.h"
+#include "IReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+void SDLDevice::SDL_mix(void* data, Uint8* buffer, int length)
+{
+ SDLDevice* device = (SDLDevice*)data;
+
+ if(!device->m_playback)
+ {
+ SDL_PauseAudio(1);
+
+ std::memset(buffer, 0, length);
+
+ return;
+ }
+
+ device->mix((data_t*)buffer, length / AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
+}
+
+void SDLDevice::playing(bool playing)
+{
+ if(!m_playback)
+ SDL_PauseAudio(playing ? 0 : 1);
+
+ m_playback = playing;
+}
+
+SDLDevice::SDLDevice(DeviceSpecs specs, int buffersize) :
+ m_playback(false)
+{
+ if(specs.channels == CHANNELS_INVALID)
+ specs.channels = CHANNELS_STEREO;
+ if(specs.format == FORMAT_INVALID)
+ specs.format = FORMAT_S16;
+ if(specs.rate == RATE_INVALID)
+ specs.rate = RATE_48000;
+
+ m_specs = specs;
+
+ SDL_AudioSpec format, obtained;
+
+ format.freq = m_specs.rate;
+ if(m_specs.format == FORMAT_U8)
+ format.format = AUDIO_U8;
+ else
+ format.format = AUDIO_S16SYS;
+ format.channels = m_specs.channels;
+ format.samples = buffersize;
+ format.callback = SDLDevice::SDL_mix;
+ format.userdata = this;
+
+ if(SDL_OpenAudio(&format, &obtained) != 0)
+ AUD_THROW(DeviceException, "The audio device couldn't be opened with SDL.");
+
+ m_specs.rate = (SampleRate)obtained.freq;
+ m_specs.channels = (Channels)obtained.channels;
+ if(obtained.format == AUDIO_U8)
+ m_specs.format = FORMAT_U8;
+ else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB)
+ m_specs.format = FORMAT_S16;
+ else
+ {
+ SDL_CloseAudio();
+ AUD_THROW(DeviceException, "The sample format obtained from SDL is not supported.");
+ }
+
+ create();
+}
+
+SDLDevice::~SDLDevice()
+{
+ SDL_PauseAudio(1);
+ SDL_CloseAudio();
+
+ destroy();
+}
+
+class SDLDeviceFactory : public IDeviceFactory
+{
+private:
+ DeviceSpecs m_specs;
+ int m_buffersize;
+
+public:
+ SDLDeviceFactory() :
+ m_buffersize(AUD_DEFAULT_BUFFER_SIZE)
+ {
+ m_specs.format = FORMAT_S16;
+ m_specs.channels = CHANNELS_STEREO;
+ m_specs.rate = RATE_48000;
+ }
+
+ virtual std::shared_ptr<IDevice> openDevice()
+ {
+ return std::shared_ptr<IDevice>(new SDLDevice(m_specs, m_buffersize));
+ }
+
+ virtual int getPriority()
+ {
+ return 1 << 5;
+ }
+
+ virtual void setSpecs(DeviceSpecs specs)
+ {
+ m_specs = specs;
+ }
+
+ virtual void setBufferSize(int buffersize)
+ {
+ m_buffersize = buffersize;
+ }
+
+ virtual void setName(std::string name)
+ {
+ }
+};
+
+void SDLDevice::registerPlugin()
+{
+ DeviceManager::registerDevice("SDL", std::shared_ptr<IDeviceFactory>(new SDLDeviceFactory));
+}
+
+#ifdef SDL_PLUGIN
+extern "C" AUD_PLUGIN_API void registerPlugin()
+{
+ SDLDevice::registerPlugin();
+}
+
+extern "C" AUD_PLUGIN_API const char* getName()
+{
+ return "SDL";
+}
+#endif
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/plugins/sdl/SDLDevice.h b/extern/audaspace/plugins/sdl/SDLDevice.h
new file mode 100644
index 00000000000..935732bb281
--- /dev/null
+++ b/extern/audaspace/plugins/sdl/SDLDevice.h
@@ -0,0 +1,82 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#pragma once
+
+#ifdef SDL_PLUGIN
+#define AUD_BUILD_PLUGIN
+#endif
+
+/**
+ * @file SDLDevice.h
+ * @ingroup plugin
+ * The SDLDevice class.
+ */
+
+#include "devices/SoftwareDevice.h"
+
+#include <SDL.h>
+
+AUD_NAMESPACE_BEGIN
+
+/**
+ * This device plays back through SDL, the simple direct media layer.
+ */
+class AUD_PLUGIN_API SDLDevice : public SoftwareDevice
+{
+private:
+ /**
+ * Whether there is currently playback.
+ */
+ bool m_playback;
+
+ /**
+ * Mixes the next bytes into the buffer.
+ * \param data The SDL device.
+ * \param buffer The target buffer.
+ * \param length The length in bytes to be filled.
+ */
+ AUD_LOCAL static void SDL_mix(void* data, Uint8* buffer, int length);
+
+ // delete copy constructor and operator=
+ SDLDevice(const SDLDevice&) = delete;
+ SDLDevice& operator=(const SDLDevice&) = delete;
+
+protected:
+ virtual void playing(bool playing);
+
+public:
+ /**
+ * Opens the SDL audio device for playback.
+ * \param specs The wanted audio specification.
+ * \param buffersize The size of the internal buffer.
+ * \note The specification really used for opening the device may differ.
+ * \exception Exception Thrown if the audio device cannot be opened.
+ */
+ SDLDevice(DeviceSpecs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+
+ /**
+ * Closes the SDL audio device.
+ */
+ virtual ~SDLDevice();
+
+ /**
+ * Registers this plugin.
+ */
+ static void registerPlugin();
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/Exception.cpp b/extern/audaspace/src/Exception.cpp
new file mode 100644
index 00000000000..1c31cb29555
--- /dev/null
+++ b/extern/audaspace/src/Exception.cpp
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "Exception.h"
+
+#include <sstream>
+
+AUD_NAMESPACE_BEGIN
+
+Exception::Exception(const Exception& exception) :
+ Exception(exception.m_message, exception.m_file, exception.m_line)
+{
+}
+
+Exception::Exception(std::string message, std::string file, int line) :
+ m_message(message),
+ m_file(file),
+ m_line(line)
+{
+}
+
+Exception::~Exception() AUD_NOEXCEPT
+{
+}
+
+const char* Exception::what() const AUD_NOEXCEPT
+{
+ return m_message.c_str();
+}
+
+std::string Exception::getDebugMessage() const
+{
+ std::stringstream out;
+
+ out << m_message << " File " << m_file << ":" << m_line;
+
+ return out.str();
+}
+
+const std::string& Exception::getMessage() const
+{
+ return m_message;
+}
+
+const std::string& Exception::getFile() const
+{
+ return m_file;
+}
+
+int Exception::getLine() const
+{
+ return m_line;
+}
+
+FileException::FileException(std::string message, std::string file, int line) :
+ Exception(message, file, line)
+{
+}
+
+FileException::FileException(const FileException& exception) :
+ Exception(exception)
+{
+}
+
+FileException::~FileException() AUD_NOEXCEPT
+{
+}
+
+DeviceException::DeviceException(std::string message, std::string file, int line) :
+ Exception(message, file, line)
+{
+}
+
+DeviceException::DeviceException(const DeviceException& exception) :
+ Exception(exception)
+{
+}
+
+DeviceException::~DeviceException() AUD_NOEXCEPT
+{
+}
+
+StateException::StateException(std::string message, std::string file, int line) :
+ Exception(message, file, line)
+{
+}
+
+StateException::StateException(const StateException& exception) :
+ Exception(exception)
+{
+}
+
+StateException::~StateException() AUD_NOEXCEPT
+{
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/DefaultSynchronizer.cpp b/extern/audaspace/src/devices/DefaultSynchronizer.cpp
new file mode 100644
index 00000000000..aa8945dadaa
--- /dev/null
+++ b/extern/audaspace/src/devices/DefaultSynchronizer.cpp
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "devices/DefaultSynchronizer.h"
+#include "devices/IHandle.h"
+
+AUD_NAMESPACE_BEGIN
+
+void DefaultSynchronizer::seek(std::shared_ptr<IHandle> handle, float time)
+{
+ handle->seek(time);
+}
+
+float DefaultSynchronizer::getPosition(std::shared_ptr<IHandle> handle)
+{
+ return handle->getPosition();
+}
+
+void DefaultSynchronizer::play()
+{
+}
+
+void DefaultSynchronizer::stop()
+{
+}
+
+void DefaultSynchronizer::setSyncCallback(ISynchronizer::syncFunction function, void* data)
+{
+}
+
+int DefaultSynchronizer::isPlaying()
+{
+ return -1;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/DeviceManager.cpp b/extern/audaspace/src/devices/DeviceManager.cpp
new file mode 100644
index 00000000000..2ebc3d58c86
--- /dev/null
+++ b/extern/audaspace/src/devices/DeviceManager.cpp
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+#include "devices/IDevice.h"
+#include "devices/I3DDevice.h"
+
+#include <limits>
+#include <string>
+#include <algorithm>
+
+AUD_NAMESPACE_BEGIN
+
+std::unordered_map<std::string, std::shared_ptr<IDeviceFactory>> DeviceManager::m_factories;
+std::shared_ptr<IDevice> DeviceManager::m_device;
+
+void DeviceManager::registerDevice(std::string name, std::shared_ptr<IDeviceFactory> factory)
+{
+ m_factories[name] = factory;
+}
+
+std::shared_ptr<IDeviceFactory> DeviceManager::getDeviceFactory(std::string name)
+{
+ return m_factories[name];
+}
+
+std::shared_ptr<IDeviceFactory> DeviceManager::getDefaultDeviceFactory()
+{
+ int min = std::numeric_limits<int>::min();
+
+ std::shared_ptr<IDeviceFactory> result;
+
+ for(auto factory : m_factories)
+ {
+ if(factory.second->getPriority() >= min)
+ {
+ result = factory.second;
+ min = result->getPriority();
+ }
+ }
+
+ return result;
+}
+
+void DeviceManager::setDevice(std::shared_ptr<IDevice> device)
+{
+ m_device = device;
+}
+
+void DeviceManager::openDevice(std::string name)
+{
+ setDevice(getDeviceFactory(name)->openDevice());
+}
+
+void DeviceManager::openDefaultDevice()
+{
+ setDevice(getDefaultDeviceFactory()->openDevice());
+}
+
+void DeviceManager::releaseDevice()
+{
+ m_device = nullptr;
+}
+
+std::shared_ptr<IDevice> DeviceManager::getDevice()
+{
+ return m_device;
+}
+
+std::shared_ptr<I3DDevice> DeviceManager::get3DDevice()
+{
+ return std::dynamic_pointer_cast<I3DDevice>(m_device);
+}
+
+std::vector<std::string> DeviceManager::getAvailableDeviceNames()
+{
+ struct DeviceNamePriority {
+ std::string name;
+ int priority;
+ };
+
+ std::vector<DeviceNamePriority> devices;
+ devices.reserve(m_factories.size());
+
+ for(const auto& pair : m_factories)
+ devices.push_back({pair.first, pair.second->getPriority()});
+
+ auto sort = [](const DeviceNamePriority& lhs, const DeviceNamePriority& rhs){
+ return lhs.priority > rhs.priority;
+ };
+
+ std::sort(devices.begin(), devices.end(), sort);
+
+ std::vector<std::string> names;
+ names.reserve(devices.size());
+
+ for(const auto& device : devices)
+ names.push_back(device.name);
+
+ return names;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/NULLDevice.cpp b/extern/audaspace/src/devices/NULLDevice.cpp
new file mode 100644
index 00000000000..a82537f43b2
--- /dev/null
+++ b/extern/audaspace/src/devices/NULLDevice.cpp
@@ -0,0 +1,193 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "devices/NULLDevice.h"
+#include "devices/DeviceManager.h"
+#include "devices/IDeviceFactory.h"
+
+#include <limits>
+#include <string>
+
+AUD_NAMESPACE_BEGIN
+
+NULLDevice::NULLHandle::NULLHandle()
+{
+}
+
+bool NULLDevice::NULLHandle::pause()
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::resume()
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::stop()
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::getKeep()
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::setKeep(bool keep)
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::seek(float position)
+{
+ return false;
+}
+
+float NULLDevice::NULLHandle::getPosition()
+{
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+Status NULLDevice::NULLHandle::getStatus()
+{
+ return STATUS_INVALID;
+}
+
+float NULLDevice::NULLHandle::getVolume()
+{
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+bool NULLDevice::NULLHandle::setVolume(float volume)
+{
+ return false;
+}
+
+float NULLDevice::NULLHandle::getPitch()
+{
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+bool NULLDevice::NULLHandle::setPitch(float pitch)
+{
+ return false;
+}
+
+int NULLDevice::NULLHandle::getLoopCount()
+{
+ return 0;
+}
+
+bool NULLDevice::NULLHandle::setLoopCount(int count)
+{
+ return false;
+}
+
+bool NULLDevice::NULLHandle::setStopCallback(stopCallback callback, void* data)
+{
+ return false;
+}
+
+NULLDevice::NULLDevice()
+{
+}
+
+NULLDevice::~NULLDevice()
+{
+}
+
+DeviceSpecs NULLDevice::getSpecs() const
+{
+ DeviceSpecs specs;
+ specs.channels = CHANNELS_INVALID;
+ specs.format = FORMAT_INVALID;
+ specs.rate = RATE_INVALID;
+ return specs;
+}
+
+std::shared_ptr<IHandle> NULLDevice::play(std::shared_ptr<IReader> reader, bool keep)
+{
+ return std::shared_ptr<IHandle>(new NULLHandle());
+}
+
+std::shared_ptr<IHandle> NULLDevice::play(std::shared_ptr<ISound> sound, bool keep)
+{
+ return std::shared_ptr<IHandle>(new NULLHandle());
+}
+
+void NULLDevice::stopAll()
+{
+}
+
+void NULLDevice::lock()
+{
+}
+
+void NULLDevice::unlock()
+{
+}
+
+float NULLDevice::getVolume() const
+{
+ return std::numeric_limits<float>::quiet_NaN();
+}
+
+void NULLDevice::setVolume(float volume)
+{
+}
+
+ISynchronizer* NULLDevice::getSynchronizer()
+{
+ return nullptr;
+}
+
+class NULLDeviceFactory : public IDeviceFactory
+{
+public:
+ NULLDeviceFactory()
+ {
+ }
+
+ virtual std::shared_ptr<IDevice> openDevice()
+ {
+ return std::shared_ptr<IDevice>(new NULLDevice());
+ }
+
+ virtual int getPriority()
+ {
+ return std::numeric_limits<int>::min();
+ }
+
+ virtual void setSpecs(DeviceSpecs specs)
+ {
+ }
+
+ virtual void setBufferSize(int buffersize)
+ {
+ }
+
+ virtual void setName(std::string name)
+ {
+ }
+};
+
+void NULLDevice::registerPlugin()
+{
+ DeviceManager::registerDevice("Null", std::shared_ptr<IDeviceFactory>(new NULLDeviceFactory));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/ReadDevice.cpp b/extern/audaspace/src/devices/ReadDevice.cpp
new file mode 100644
index 00000000000..487fee1f59a
--- /dev/null
+++ b/extern/audaspace/src/devices/ReadDevice.cpp
@@ -0,0 +1,69 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "devices/ReadDevice.h"
+#include "IReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+ReadDevice::ReadDevice(DeviceSpecs specs) :
+ m_playing(false)
+{
+ m_specs = specs;
+
+ create();
+}
+
+ReadDevice::ReadDevice(Specs specs) :
+ m_playing(false)
+{
+ m_specs.specs = specs;
+ m_specs.format = FORMAT_FLOAT32;
+
+ create();
+}
+
+ReadDevice::~ReadDevice()
+{
+ destroy();
+}
+
+bool ReadDevice::read(data_t* buffer, int length)
+{
+ if(m_playing)
+ mix(buffer, length);
+ else
+ if(m_specs.format == FORMAT_U8)
+ std::memset(buffer, 0x80, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
+ else
+ std::memset(buffer, 0, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
+ return m_playing;
+}
+
+void ReadDevice::changeSpecs(Specs specs)
+{
+ if(!AUD_COMPARE_SPECS(specs, m_specs.specs))
+ setSpecs(specs);
+}
+
+void ReadDevice::playing(bool playing)
+{
+ m_playing = playing;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/devices/SoftwareDevice.cpp b/extern/audaspace/src/devices/SoftwareDevice.cpp
new file mode 100644
index 00000000000..c944b9ed12d
--- /dev/null
+++ b/extern/audaspace/src/devices/SoftwareDevice.cpp
@@ -0,0 +1,989 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "devices/SoftwareDevice.h"
+#include "fx/PitchReader.h"
+#include "respec/ChannelMapperReader.h"
+#include "respec/JOSResampleReader.h"
+#include "respec/LinearResampleReader.h"
+#include "respec/Mixer.h"
+#include "Exception.h"
+#include "ISound.h"
+
+#include <algorithm>
+#include <cmath>
+#include <cstring>
+#include <iostream>
+#include <limits>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+enum RenderFlags
+{
+ RENDER_DISTANCE = 0x01,
+ RENDER_DOPPLER = 0x02,
+ RENDER_CONE = 0x04,
+ RENDER_VOLUME = 0x08
+};
+
+#define PITCH_MAX 10
+
+/******************************************************************************/
+/********************** SoftwareHandle Handle Code ************************/
+/******************************************************************************/
+
+bool SoftwareDevice::SoftwareHandle::pause(bool keep)
+{
+ if(m_status)
+ {
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(m_status == STATUS_PLAYING)
+ {
+ for(auto it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<SoftwareHandle> This = *it;
+
+ m_device->m_playingSounds.erase(it);
+ m_device->m_pausedSounds.push_back(This);
+
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
+
+ m_status = keep ? STATUS_STOPPED : STATUS_PAUSED;
+
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+SoftwareDevice::SoftwareHandle::SoftwareHandle(SoftwareDevice* device, std::shared_ptr<IReader> reader, std::shared_ptr<PitchReader> pitch, std::shared_ptr<ResampleReader> resampler, std::shared_ptr<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_old_volume(0), 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),
+ m_flags(RENDER_CONE), m_stop(nullptr), m_stop_data(nullptr), m_status(STATUS_PLAYING), m_device(device)
+{
+}
+
+void SoftwareDevice::SoftwareHandle::update()
+{
+ int flags = 0;
+
+ m_old_volume = m_volume;
+
+ Vector3 SL;
+ if(m_relative)
+ SL = -m_location;
+ else
+ SL = m_device->m_location - m_location;
+ float distance = SL * SL;
+
+ if(distance > 0)
+ distance = sqrt(distance);
+ else
+ flags |= RENDER_DOPPLER | RENDER_DISTANCE;
+
+ if(m_pitch->getSpecs().channels != CHANNELS_MONO)
+ {
+ m_volume = m_user_volume;
+ m_pitch->setPitch(m_user_pitch);
+ return;
+ }
+
+ flags = ~(flags | m_flags | m_device->m_flags);
+
+ // Doppler and Pitch
+
+ if(flags & RENDER_DOPPLER)
+ {
+ float vls;
+ if(m_relative)
+ vls = 0;
+ else
+ vls = SL * m_device->m_velocity / distance;
+ float vss = SL * m_velocity / distance;
+ float max = m_device->m_speed_of_sound / m_device->m_doppler_factor;
+ if(vss >= max)
+ {
+ m_pitch->setPitch(PITCH_MAX);
+ }
+ else
+ {
+ if(vls > max)
+ vls = max;
+
+ m_pitch->setPitch((m_device->m_speed_of_sound - m_device->m_doppler_factor * vls) / (m_device->m_speed_of_sound - m_device->m_doppler_factor * vss) * m_user_pitch);
+ }
+ }
+ else
+ m_pitch->setPitch(m_user_pitch);
+
+ if(flags & RENDER_VOLUME)
+ {
+ // Distance
+
+ if(flags & RENDER_DISTANCE)
+ {
+ if(m_device->m_distance_model == DISTANCE_MODEL_INVERSE_CLAMPED ||
+ m_device->m_distance_model == DISTANCE_MODEL_LINEAR_CLAMPED ||
+ m_device->m_distance_model == DISTANCE_MODEL_EXPONENT_CLAMPED)
+ {
+ distance = std::max(std::min(m_distance_max, distance), m_distance_reference);
+ }
+
+ switch(m_device->m_distance_model)
+ {
+ case DISTANCE_MODEL_INVERSE:
+ case DISTANCE_MODEL_INVERSE_CLAMPED:
+ m_volume = m_distance_reference / (m_distance_reference + m_attenuation * (distance - m_distance_reference));
+ break;
+ case DISTANCE_MODEL_LINEAR:
+ case DISTANCE_MODEL_LINEAR_CLAMPED:
+ {
+ float temp = m_distance_max - m_distance_reference;
+ if(temp == 0)
+ {
+ if(distance > m_distance_reference)
+ m_volume = 0.0f;
+ else
+ m_volume = 1.0f;
+ }
+ else
+ m_volume = 1.0f - m_attenuation * (distance - m_distance_reference) / (m_distance_max - m_distance_reference);
+ break;
+ }
+ case DISTANCE_MODEL_EXPONENT:
+ case DISTANCE_MODEL_EXPONENT_CLAMPED:
+ if(m_distance_reference == 0)
+ m_volume = 0;
+ else
+ m_volume = std::pow(distance / m_distance_reference, -m_attenuation);
+ break;
+ default:
+ m_volume = 1.0f;
+ }
+ }
+ else
+ m_volume = 1.0f;
+
+ // Cone
+
+ if(flags & RENDER_CONE)
+ {
+ Vector3 SZ = m_orientation.getLookAt();
+
+ float phi = std::acos(float(SZ * SL / (SZ.length() * SL.length())));
+ float t = (phi - m_cone_angle_inner)/(m_cone_angle_outer - m_cone_angle_inner);
+
+ if(t > 0)
+ {
+ if(t > 1)
+ m_volume *= m_cone_volume_outer;
+ else
+ m_volume *= 1 + t * (m_cone_volume_outer - 1);
+ }
+ }
+
+ if(m_volume > m_volume_max)
+ m_volume = m_volume_max;
+ else if(m_volume < m_volume_min)
+ m_volume = m_volume_min;
+
+ // Volume
+
+ m_volume *= m_user_volume;
+ }
+
+ // 3D Cue
+
+ Quaternion orientation;
+
+ if(!m_relative)
+ orientation = m_device->m_orientation;
+
+ Vector3 Z = orientation.getLookAt();
+ Vector3 N = orientation.getUp();
+ Vector3 A = N * ((SL * N) / (N * N)) - SL;
+
+ float Asquare = A * A;
+
+ if(Asquare > 0)
+ {
+ float phi = std::acos(float(Z * A / (Z.length() * std::sqrt(Asquare))));
+ if(N.cross(Z) * A > 0)
+ phi = -phi;
+
+ m_mapper->setMonoAngle(phi);
+ }
+ else
+ m_mapper->setMonoAngle(m_relative ? m_user_pan * M_PI / 2.0 : 0);
+}
+
+void SoftwareDevice::SoftwareHandle::setSpecs(Specs specs)
+{
+ m_mapper->setChannels(specs.channels);
+ m_resampler->setRate(specs.rate);
+}
+
+bool SoftwareDevice::SoftwareHandle::pause()
+{
+ return pause(false);
+}
+
+bool SoftwareDevice::SoftwareHandle::resume()
+{
+ if(m_status)
+ {
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(m_status == STATUS_PAUSED)
+ {
+ for(auto it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<SoftwareHandle> This = *it;
+
+ 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 = STATUS_PLAYING;
+
+ return true;
+ }
+ }
+ }
+
+ }
+
+ return false;
+}
+
+bool SoftwareDevice::SoftwareHandle::stop()
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_status = STATUS_INVALID;
+
+ for(auto it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<SoftwareHandle> This = *it;
+
+ m_device->m_playingSounds.erase(it);
+
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
+
+ return true;
+ }
+ }
+
+ for(auto it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
+ {
+ if(it->get() == this)
+ {
+ std::shared_ptr<SoftwareHandle> This = *it;
+
+ m_device->m_pausedSounds.erase(it);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool SoftwareDevice::SoftwareHandle::getKeep()
+{
+ if(m_status)
+ return m_keep;
+
+ return false;
+}
+
+bool SoftwareDevice::SoftwareHandle::setKeep(bool keep)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_keep = keep;
+
+ return true;
+}
+
+bool SoftwareDevice::SoftwareHandle::seek(float position)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_pitch->setPitch(m_user_pitch);
+ m_reader->seek((int)(position * m_reader->getSpecs().rate));
+
+ if(m_status == STATUS_STOPPED)
+ m_status = STATUS_PAUSED;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getPosition()
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return 0.0f;
+
+ float position = m_reader->getPosition() / (float)m_device->m_specs.rate;
+
+ return position;
+}
+
+Status SoftwareDevice::SoftwareHandle::getStatus()
+{
+ return m_status;
+}
+
+float SoftwareDevice::SoftwareHandle::getVolume()
+{
+ return m_user_volume;
+}
+
+bool SoftwareDevice::SoftwareHandle::setVolume(float volume)
+{
+ if(!m_status)
+ return false;
+ m_user_volume = volume;
+
+ if(volume == 0)
+ {
+ m_old_volume = m_volume = volume;
+ m_flags |= RENDER_VOLUME;
+ }
+ else
+ m_flags &= ~RENDER_VOLUME;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getPitch()
+{
+ return m_user_pitch;
+}
+
+bool SoftwareDevice::SoftwareHandle::setPitch(float pitch)
+{
+ if(!m_status)
+ return false;
+ if(pitch > 0.0f)
+ m_user_pitch = pitch;
+ return true;
+}
+
+int SoftwareDevice::SoftwareHandle::getLoopCount()
+{
+ if(!m_status)
+ return 0;
+ return m_loopcount;
+}
+
+bool SoftwareDevice::SoftwareHandle::setLoopCount(int count)
+{
+ if(!m_status)
+ return false;
+
+ if(m_status == STATUS_STOPPED && (count > m_loopcount || count < 0))
+ m_status = STATUS_PAUSED;
+
+ m_loopcount = count;
+
+ return true;
+}
+
+bool SoftwareDevice::SoftwareHandle::setStopCallback(stopCallback callback, void* data)
+{
+ if(!m_status)
+ return false;
+
+ std::lock_guard<ILockable> lock(*m_device);
+
+ if(!m_status)
+ return false;
+
+ m_stop = callback;
+ m_stop_data = data;
+
+ return true;
+}
+
+
+
+/******************************************************************************/
+/******************** SoftwareHandle 3DHandle Code ************************/
+/******************************************************************************/
+
+Vector3 SoftwareDevice::SoftwareHandle::getLocation()
+{
+ if(!m_status)
+ return Vector3();
+
+ return m_location;
+}
+
+bool SoftwareDevice::SoftwareHandle::setLocation(const Vector3& location)
+{
+ if(!m_status)
+ return false;
+
+ m_location = location;
+
+ return true;
+}
+
+Vector3 SoftwareDevice::SoftwareHandle::getVelocity()
+{
+ if(!m_status)
+ return Vector3();
+
+ return m_velocity;
+}
+
+bool SoftwareDevice::SoftwareHandle::setVelocity(const Vector3& velocity)
+{
+ if(!m_status)
+ return false;
+
+ m_velocity = velocity;
+
+ return true;
+}
+
+Quaternion SoftwareDevice::SoftwareHandle::getOrientation()
+{
+ if(!m_status)
+ return Quaternion();
+
+ return m_orientation;
+}
+
+bool SoftwareDevice::SoftwareHandle::setOrientation(const Quaternion& orientation)
+{
+ if(!m_status)
+ return false;
+
+ m_orientation = orientation;
+
+ return true;
+}
+
+bool SoftwareDevice::SoftwareHandle::isRelative()
+{
+ if(!m_status)
+ return false;
+
+ return m_relative;
+}
+
+bool SoftwareDevice::SoftwareHandle::setRelative(bool relative)
+{
+ if(!m_status)
+ return false;
+
+ m_relative = relative;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getVolumeMaximum()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_volume_max;
+}
+
+bool SoftwareDevice::SoftwareHandle::setVolumeMaximum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_volume_max = volume;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getVolumeMinimum()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_volume_min;
+}
+
+bool SoftwareDevice::SoftwareHandle::setVolumeMinimum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_volume_min = volume;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getDistanceMaximum()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_distance_max;
+}
+
+bool SoftwareDevice::SoftwareHandle::setDistanceMaximum(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_distance_max = distance;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getDistanceReference()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_distance_reference;
+}
+
+bool SoftwareDevice::SoftwareHandle::setDistanceReference(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_distance_reference = distance;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getAttenuation()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_attenuation;
+}
+
+bool SoftwareDevice::SoftwareHandle::setAttenuation(float factor)
+{
+ if(!m_status)
+ return false;
+
+ m_attenuation = factor;
+
+ if(factor == 0)
+ m_flags |= RENDER_DISTANCE;
+ else
+ m_flags &= ~RENDER_DISTANCE;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getConeAngleOuter()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_cone_angle_outer * 360.0f / M_PI;
+}
+
+bool SoftwareDevice::SoftwareHandle::setConeAngleOuter(float angle)
+{
+ if(!m_status)
+ return false;
+
+ m_cone_angle_outer = angle * M_PI / 360.0f;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getConeAngleInner()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_cone_angle_inner * 360.0f / M_PI;
+}
+
+bool SoftwareDevice::SoftwareHandle::setConeAngleInner(float angle)
+{
+ if(!m_status)
+ return false;
+
+ if(angle >= 360)
+ m_flags |= RENDER_CONE;
+ else
+ m_flags &= ~RENDER_CONE;
+
+ m_cone_angle_inner = angle * M_PI / 360.0f;
+
+ return true;
+}
+
+float SoftwareDevice::SoftwareHandle::getConeVolumeOuter()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_cone_volume_outer;
+}
+
+bool SoftwareDevice::SoftwareHandle::setConeVolumeOuter(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_cone_volume_outer = volume;
+
+ return true;
+}
+
+/******************************************************************************/
+/**************************** IDevice Code ************************************/
+/******************************************************************************/
+
+void SoftwareDevice::create()
+{
+ m_playback = false;
+ m_volume = 1.0f;
+ m_mixer = std::shared_ptr<Mixer>(new Mixer(m_specs));
+ m_speed_of_sound = 343.3f;
+ m_doppler_factor = 1.0f;
+ m_distance_model = DISTANCE_MODEL_INVERSE_CLAMPED;
+ m_flags = 0;
+ m_quality = false;
+}
+
+void SoftwareDevice::destroy()
+{
+ if(m_playback)
+ playing(m_playback = false);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+}
+
+void SoftwareDevice::mix(data_t* buffer, int length)
+{
+ m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_specs));
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ {
+ std::shared_ptr<SoftwareDevice::SoftwareHandle> sound;
+ int len;
+ int pos;
+ bool eos;
+ std::list<std::shared_ptr<SoftwareDevice::SoftwareHandle> > stopSounds;
+ std::list<std::shared_ptr<SoftwareDevice::SoftwareHandle> > pauseSounds;
+ sample_t* buf = m_buffer.getBuffer();
+
+ m_mixer->clear(length);
+
+ // for all sounds
+ for(auto& sound : m_playingSounds)
+ {
+ // get the buffer from the source
+ pos = 0;
+ len = length;
+
+ // update 3D Info
+ sound->update();
+
+ try
+ {
+ sound->m_reader->read(len, eos, buf);
+
+ // in case of looping
+ while(pos + len < length && sound->m_loopcount && eos)
+ {
+ m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
+
+ pos += len;
+
+ if(sound->m_loopcount > 0)
+ sound->m_loopcount--;
+
+ sound->m_reader->seek(0);
+
+ len = length - pos;
+ sound->m_reader->read(len, eos, buf);
+
+ // prevent endless loop
+ if(!len)
+ break;
+ }
+ }
+ catch(Exception& e)
+ {
+ len = 0;
+ std::cerr << "Caught exception while reading sound data during playback with software mixing: " << e.getMessage() << std::endl;
+ }
+
+ m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
+
+ // in case the end of the sound is reached
+ if(eos && !sound->m_loopcount)
+ {
+ if(sound->m_stop)
+ sound->m_stop(sound->m_stop_data);
+
+ if(sound->m_keep)
+ pauseSounds.push_back(sound);
+ else
+ stopSounds.push_back(sound);
+ }
+ }
+
+ // superpose
+ m_mixer->read(buffer, m_volume);
+
+ // cleanup
+ for(auto& sound : pauseSounds)
+ sound->pause(true);
+
+ for(auto& sound : stopSounds)
+ sound->stop();
+
+ pauseSounds.clear();
+ stopSounds.clear();
+ }
+}
+
+void SoftwareDevice::setPanning(IHandle* handle, float pan)
+{
+ SoftwareDevice::SoftwareHandle* h = dynamic_cast<SoftwareDevice::SoftwareHandle*>(handle);
+ h->m_user_pan = pan;
+}
+
+void SoftwareDevice::setQuality(bool quality)
+{
+ m_quality = quality;
+}
+
+void SoftwareDevice::setSpecs(Specs specs)
+{
+ m_specs.specs = specs;
+ m_mixer->setSpecs(specs);
+
+ for(auto& sound : m_playingSounds)
+ {
+ sound->setSpecs(specs);
+ }
+}
+
+SoftwareDevice::SoftwareDevice()
+{
+}
+
+DeviceSpecs SoftwareDevice::getSpecs() const
+{
+ return m_specs;
+}
+
+std::shared_ptr<IHandle> SoftwareDevice::play(std::shared_ptr<IReader> reader, bool keep)
+{
+ // prepare the reader
+ // pitch
+
+ std::shared_ptr<PitchReader> pitch = std::shared_ptr<PitchReader>(new PitchReader(reader, 1));
+ reader = std::shared_ptr<IReader>(pitch);
+
+ std::shared_ptr<ResampleReader> resampler;
+
+ // resample
+ if(m_quality)
+ resampler = std::shared_ptr<ResampleReader>(new JOSResampleReader(reader, m_specs.rate));
+ else
+ resampler = std::shared_ptr<ResampleReader>(new LinearResampleReader(reader, m_specs.rate));
+ reader = std::shared_ptr<IReader>(resampler);
+
+ // rechannel
+ std::shared_ptr<ChannelMapperReader> mapper = std::shared_ptr<ChannelMapperReader>(new ChannelMapperReader(reader, m_specs.channels));
+ reader = std::shared_ptr<IReader>(mapper);
+
+ if(!reader.get())
+ return std::shared_ptr<IHandle>();
+
+ // play sound
+ std::shared_ptr<SoftwareDevice::SoftwareHandle> sound = std::shared_ptr<SoftwareDevice::SoftwareHandle>(new SoftwareDevice::SoftwareHandle(this, reader, pitch, resampler, mapper, keep));
+
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_playingSounds.push_back(sound);
+
+ if(!m_playback)
+ playing(m_playback = true);
+
+ return std::shared_ptr<IHandle>(sound);
+}
+
+std::shared_ptr<IHandle> SoftwareDevice::play(std::shared_ptr<ISound> sound, bool keep)
+{
+ return play(sound->createReader(), keep);
+}
+
+void SoftwareDevice::stopAll()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+}
+
+void SoftwareDevice::lock()
+{
+ m_mutex.lock();
+}
+
+void SoftwareDevice::unlock()
+{
+ m_mutex.unlock();
+}
+
+float SoftwareDevice::getVolume() const
+{
+ return m_volume;
+}
+
+void SoftwareDevice::setVolume(float volume)
+{
+ m_volume = volume;
+}
+
+ISynchronizer* SoftwareDevice::getSynchronizer()
+{
+ return &m_synchronizer;
+}
+
+/******************************************************************************/
+/**************************** 3D Device Code **********************************/
+/******************************************************************************/
+
+Vector3 SoftwareDevice::getListenerLocation() const
+{
+ return m_location;
+}
+
+void SoftwareDevice::setListenerLocation(const Vector3& location)
+{
+ m_location = location;
+}
+
+Vector3 SoftwareDevice::getListenerVelocity() const
+{
+ return m_velocity;
+}
+
+void SoftwareDevice::setListenerVelocity(const Vector3& velocity)
+{
+ m_velocity = velocity;
+}
+
+Quaternion SoftwareDevice::getListenerOrientation() const
+{
+ return m_orientation;
+}
+
+void SoftwareDevice::setListenerOrientation(const Quaternion& orientation)
+{
+ m_orientation = orientation;
+}
+
+float SoftwareDevice::getSpeedOfSound() const
+{
+ return m_speed_of_sound;
+}
+
+void SoftwareDevice::setSpeedOfSound(float speed)
+{
+ m_speed_of_sound = speed;
+}
+
+float SoftwareDevice::getDopplerFactor() const
+{
+ return m_doppler_factor;
+}
+
+void SoftwareDevice::setDopplerFactor(float factor)
+{
+ m_doppler_factor = factor;
+ if(factor == 0)
+ m_flags |= RENDER_DOPPLER;
+ else
+ m_flags &= ~RENDER_DOPPLER;
+}
+
+DistanceModel SoftwareDevice::getDistanceModel() const
+{
+ return m_distance_model;
+}
+
+void SoftwareDevice::setDistanceModel(DistanceModel model)
+{
+ m_distance_model = model;
+ if(model == DISTANCE_MODEL_INVALID)
+ m_flags |= RENDER_DISTANCE;
+ else
+ m_flags &= ~RENDER_DISTANCE;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/file/File.cpp b/extern/audaspace/src/file/File.cpp
new file mode 100644
index 00000000000..0cdecb03657
--- /dev/null
+++ b/extern/audaspace/src/file/File.cpp
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "file/File.h"
+#include "file/FileManager.h"
+#include "util/Buffer.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+File::File(std::string filename) :
+ m_filename(filename)
+{
+}
+
+File::File(const data_t* buffer, int size) :
+ m_buffer(new Buffer(size))
+{
+ std::memcpy(m_buffer->getBuffer(), buffer, size);
+}
+
+std::shared_ptr<IReader> File::createReader()
+{
+ if(m_buffer.get())
+ return FileManager::createReader(m_buffer);
+ else
+ return FileManager::createReader(m_filename);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/file/FileManager.cpp b/extern/audaspace/src/file/FileManager.cpp
new file mode 100644
index 00000000000..f8ef8deb409
--- /dev/null
+++ b/extern/audaspace/src/file/FileManager.cpp
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "file/FileManager.h"
+#include "file/IFileInput.h"
+#include "file/IFileOutput.h"
+#include "Exception.h"
+
+AUD_NAMESPACE_BEGIN
+
+std::list<std::shared_ptr<IFileInput>>& FileManager::inputs()
+{
+ static std::list<std::shared_ptr<IFileInput>> inputs;
+ return inputs;
+}
+
+std::list<std::shared_ptr<IFileOutput>>& FileManager::outputs()
+{
+ static std::list<std::shared_ptr<IFileOutput>> outputs;
+ return outputs;
+}
+
+void FileManager::registerInput(std::shared_ptr<IFileInput> input)
+{
+ inputs().push_back(input);
+}
+
+void FileManager::registerOutput(std::shared_ptr<aud::IFileOutput> output)
+{
+ outputs().push_back(output);
+}
+
+std::shared_ptr<IReader> FileManager::createReader(std::string filename)
+{
+ for(std::shared_ptr<IFileInput> input : inputs())
+ {
+ try
+ {
+ return input->createReader(filename);
+ }
+ catch(Exception&) {}
+ }
+
+ AUD_THROW(FileException, "The file couldn't be read with any installed file reader.");
+}
+
+std::shared_ptr<IReader> FileManager::createReader(std::shared_ptr<Buffer> buffer)
+{
+ for(std::shared_ptr<IFileInput> input : inputs())
+ {
+ try
+ {
+ return input->createReader(buffer);
+ }
+ catch(Exception&) {}
+ }
+
+ AUD_THROW(FileException, "The file couldn't be read with any installed file reader.");
+}
+
+std::shared_ptr<IWriter> FileManager::createWriter(std::string filename, DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
+{
+ for(std::shared_ptr<IFileOutput> output : outputs())
+ {
+ try
+ {
+ return output->createWriter(filename, specs, format, codec, bitrate);
+ }
+ catch(Exception&) {}
+ }
+
+ AUD_THROW(FileException, "The file couldn't be written with any installed writer.");
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/file/FileWriter.cpp b/extern/audaspace/src/file/FileWriter.cpp
new file mode 100644
index 00000000000..a6bb0f0049a
--- /dev/null
+++ b/extern/audaspace/src/file/FileWriter.cpp
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "file/FileWriter.h"
+#include "file/FileManager.h"
+#include "util/Buffer.h"
+#include "IReader.h"
+#include "Exception.h"
+
+AUD_NAMESPACE_BEGIN
+
+std::shared_ptr<IWriter> FileWriter::createWriter(std::string filename,DeviceSpecs specs, Container format, Codec codec, unsigned int bitrate)
+{
+ return FileManager::createWriter(filename, specs, format, codec, bitrate);
+}
+
+void FileWriter::writeReader(std::shared_ptr<IReader> reader, std::shared_ptr<IWriter> writer, unsigned int length, unsigned int buffersize)
+{
+ Buffer buffer(buffersize * AUD_SAMPLE_SIZE(writer->getSpecs()));
+ sample_t* buf = buffer.getBuffer();
+
+ int len;
+ bool eos = false;
+ int channels = writer->getSpecs().channels;
+
+ for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
+ {
+ len = buffersize;
+ if((len > length - pos) && (length > 0))
+ len = length - pos;
+ reader->read(len, eos, buf);
+
+ for(int i = 0; i < len * channels; i++)
+ {
+ // clamping!
+ if(buf[i] > 1)
+ buf[i] = 1;
+ else if(buf[i] < -1)
+ buf[i] = -1;
+ }
+
+ writer->write(len, buf);
+ }
+}
+
+void FileWriter::writeReader(std::shared_ptr<IReader> reader, std::vector<std::shared_ptr<IWriter> >& writers, unsigned int length, unsigned int buffersize)
+{
+ Buffer buffer(buffersize * AUD_SAMPLE_SIZE(reader->getSpecs()));
+ Buffer buffer2(buffersize * sizeof(sample_t));
+ sample_t* buf = buffer.getBuffer();
+ sample_t* buf2 = buffer2.getBuffer();
+
+ int len;
+ bool eos = false;
+ int channels = reader->getSpecs().channels;
+
+ for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
+ {
+ len = buffersize;
+ if((len > length - pos) && (length > 0))
+ len = length - pos;
+ reader->read(len, eos, buf);
+
+ for(int channel = 0; channel < channels; channel++)
+ {
+ for(int i = 0; i < len; i++)
+ {
+ // clamping!
+ if(buf[i * channels + channel] > 1)
+ buf2[i] = 1;
+ else if(buf[i * channels + channel] < -1)
+ buf2[i] = -1;
+ else
+ buf2[i] = buf[i * channels + channel];
+ }
+
+ writers[channel]->write(len, buf2);
+ }
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ADSR.cpp b/extern/audaspace/src/fx/ADSR.cpp
new file mode 100644
index 00000000000..f147affda72
--- /dev/null
+++ b/extern/audaspace/src/fx/ADSR.cpp
@@ -0,0 +1,73 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/ADSR.h"
+#include "fx/ADSRReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+ADSR::ADSR(std::shared_ptr<ISound> sound, float attack, float decay, float sustain, float release) :
+ Effect(sound),
+ m_attack(attack), m_decay(decay), m_sustain(sustain), m_release(release)
+{
+}
+
+float ADSR::getAttack() const
+{
+ return m_attack;
+}
+
+void ADSR::setAttack(float attack)
+{
+ m_attack = attack;
+}
+
+float ADSR::getDecay() const
+{
+ return m_decay;
+}
+
+void ADSR::setDecay(float decay)
+{
+ m_decay = decay;
+}
+
+float ADSR::getSustain() const
+{
+ return m_sustain;
+}
+
+void ADSR::setSustain(float sustain)
+{
+ m_sustain = sustain;
+}
+
+float ADSR::getRelease() const
+{
+ return m_release;
+}
+
+void ADSR::setRelease(float release)
+{
+ m_release = release;
+}
+
+std::shared_ptr<IReader> ADSR::createReader()
+{
+ return std::shared_ptr<IReader>(new ADSRReader(getReader(), m_attack, m_decay, m_sustain, m_release));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ADSRReader.cpp b/extern/audaspace/src/fx/ADSRReader.cpp
new file mode 100644
index 00000000000..6499b55468e
--- /dev/null
+++ b/extern/audaspace/src/fx/ADSRReader.cpp
@@ -0,0 +1,115 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/ADSRReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+ADSRReader::ADSRReader(std::shared_ptr<IReader> reader, float attack, float decay, float sustain, float release) :
+ EffectReader(reader),
+ m_attack(attack), m_decay(decay), m_sustain(sustain), m_release(release)
+{
+ nextState(ADSR_STATE_ATTACK);
+}
+
+ADSRReader::~ADSRReader()
+{
+}
+
+void ADSRReader::nextState(ADSRState state)
+{
+ m_state = state;
+
+ switch(m_state)
+ {
+ case ADSR_STATE_ATTACK:
+ m_level = 0;
+ if(m_attack <= 0)
+ {
+ nextState(ADSR_STATE_DECAY);
+ return;
+ }
+ return;
+ case ADSR_STATE_DECAY:
+ if(m_decay <= 0)
+ {
+ nextState(ADSR_STATE_SUSTAIN);
+ return;
+ }
+ if(m_level > 1.0)
+ m_level = 1 - (m_level - 1) * m_attack / m_decay * (1 - m_sustain);
+ if(m_level <= m_sustain)
+ nextState(ADSR_STATE_SUSTAIN);
+ break;
+ case ADSR_STATE_SUSTAIN:
+ m_level = m_sustain;
+ break;
+ case ADSR_STATE_RELEASE:
+ if(m_release <= 0)
+ {
+ nextState(ADSR_STATE_INVALID);
+ return;
+ }
+ break;
+ case ADSR_STATE_INVALID:
+ break;
+ }
+}
+
+void ADSRReader::read(int & length, bool &eos, sample_t* buffer)
+{
+ Specs specs = m_reader->getSpecs();
+ m_reader->read(length, eos, buffer);
+
+ for(int i = 0; i < length; i++)
+ {
+ for(int channel = 0; channel < specs.channels; channel++)
+ {
+ buffer[i * specs.channels + channel] *= m_level;
+ }
+
+ switch(m_state)
+ {
+ case ADSR_STATE_ATTACK:
+ m_level += 1 / m_attack / specs.rate;
+ if(m_level >= 1)
+ nextState(ADSR_STATE_DECAY);
+ break;
+ case ADSR_STATE_DECAY:
+ m_level -= (1 - m_sustain) / m_decay / specs.rate;
+ if(m_level <= m_sustain)
+ nextState(ADSR_STATE_SUSTAIN);
+ break;
+ case ADSR_STATE_SUSTAIN:
+ break;
+ case ADSR_STATE_RELEASE:
+ m_level -= m_sustain / m_release / specs.rate ;
+ if(m_level <= 0)
+ nextState(ADSR_STATE_INVALID);
+ break;
+ case ADSR_STATE_INVALID:
+ length = i;
+ return;
+ }
+ }
+}
+
+void ADSRReader::release()
+{
+ nextState(ADSR_STATE_RELEASE);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Accumulator.cpp b/extern/audaspace/src/fx/Accumulator.cpp
new file mode 100644
index 00000000000..ba8e6a2841e
--- /dev/null
+++ b/extern/audaspace/src/fx/Accumulator.cpp
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Accumulator.h"
+#include "fx/CallbackIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+sample_t Accumulator::accumulatorFilterAdditive(CallbackIIRFilterReader* reader, void* useless)
+{
+ float in = reader->x(0);
+ float lastin = reader->x(-1);
+ float out = reader->y(-1) + in - lastin;
+ if(in > lastin)
+ out += in - lastin;
+ return out;
+}
+
+sample_t Accumulator::accumulatorFilter(CallbackIIRFilterReader* reader, void* useless)
+{
+ float in = reader->x(0);
+ float lastin = reader->x(-1);
+ float out = reader->y(-1);
+ if(in > lastin)
+ out += in - lastin;
+ return out;
+}
+
+Accumulator::Accumulator(std::shared_ptr<ISound> sound,
+ bool additive) :
+ Effect(sound),
+ m_additive(additive)
+{
+}
+
+std::shared_ptr<IReader> Accumulator::createReader()
+{
+ return std::shared_ptr<IReader>(new CallbackIIRFilterReader(getReader(), 2, 2, m_additive ? accumulatorFilterAdditive : accumulatorFilter));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/BaseIIRFilterReader.cpp b/extern/audaspace/src/fx/BaseIIRFilterReader.cpp
new file mode 100644
index 00000000000..6505e5ea600
--- /dev/null
+++ b/extern/audaspace/src/fx/BaseIIRFilterReader.cpp
@@ -0,0 +1,125 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/BaseIIRFilterReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+BaseIIRFilterReader::BaseIIRFilterReader(std::shared_ptr<IReader> reader, int in, int out) :
+ EffectReader(reader),
+ m_specs(reader->getSpecs()),
+ m_xlen(in), m_ylen(out),
+ m_xpos(0), m_ypos(0), m_channel(0)
+{
+ m_x = new sample_t[m_xlen * m_specs.channels];
+ m_y = new sample_t[m_ylen * m_specs.channels];
+
+ std::memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
+ std::memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
+}
+
+BaseIIRFilterReader::~BaseIIRFilterReader()
+{
+ delete[] m_x;
+ delete[] m_y;
+}
+
+void BaseIIRFilterReader::setLengths(int in, int out)
+{
+ if(in != m_xlen)
+ {
+ sample_t* xn = new sample_t[in * m_specs.channels];
+ std::memset(xn, 0, sizeof(sample_t) * in * m_specs.channels);
+
+ for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
+ {
+ for(int i = 1; i <= in && i <= m_xlen; i++)
+ {
+ xn[(in - i) * m_specs.channels + m_channel] = x(-i);
+ }
+ }
+
+ delete[] m_x;
+ m_x = xn;
+ m_xpos = 0;
+ m_xlen = in;
+ }
+
+ if(out != m_ylen)
+ {
+ sample_t* yn = new sample_t[out * m_specs.channels];
+ std::memset(yn, 0, sizeof(sample_t) * out * m_specs.channels);
+
+ for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
+ {
+ for(int i = 1; i <= out && i <= m_ylen; i++)
+ {
+ yn[(out - i) * m_specs.channels + m_channel] = y(-i);
+ }
+ }
+
+ delete[] m_y;
+ m_y = yn;
+ m_ypos = 0;
+ m_ylen = out;
+ }
+}
+
+void BaseIIRFilterReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ Specs specs = m_reader->getSpecs();
+ if(specs.channels != m_specs.channels)
+ {
+ m_specs.channels = specs.channels;
+
+ delete[] m_x;
+ delete[] m_y;
+
+ m_x = new sample_t[m_xlen * m_specs.channels];
+ m_y = new sample_t[m_ylen * m_specs.channels];
+
+ std::memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
+ std::memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
+ }
+
+ if(specs.rate != m_specs.rate)
+ {
+ m_specs = specs;
+ sampleRateChanged(m_specs.rate);
+ }
+
+ m_reader->read(length, eos, buffer);
+
+ for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ m_x[m_xpos * m_specs.channels + m_channel] = buffer[i * m_specs.channels + m_channel];
+ m_y[m_ypos * m_specs.channels + m_channel] = buffer[i * m_specs.channels + m_channel] = filter();
+
+ m_xpos = m_xlen ? (m_xpos + 1) % m_xlen : 0;
+ m_ypos = m_ylen ? (m_ypos + 1) % m_ylen : 0;
+ }
+ }
+}
+
+void BaseIIRFilterReader::sampleRateChanged(SampleRate rate)
+{
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/BinauralReader.cpp b/extern/audaspace/src/fx/BinauralReader.cpp
new file mode 100644
index 00000000000..2792adada8a
--- /dev/null
+++ b/extern/audaspace/src/fx/BinauralReader.cpp
@@ -0,0 +1,255 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/BinauralReader.h"
+#include "Exception.h"
+
+#include <cstring>
+#include <cstdlib>
+#include <algorithm>
+
+#define NUM_OUTCHANNELS 2
+#define NUM_CONVOLVERS 4
+#define CROSSFADE_SAMPLES 1024
+
+AUD_NAMESPACE_BEGIN
+BinauralReader::BinauralReader(std::shared_ptr<IReader> reader, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_reader(reader), m_hrtfs(hrtfs), m_source(source), m_N(plan->getSize()), m_threadPool(threadPool), m_position(0), m_eosReader(false), m_eosTail(false), m_transition(false), m_transPos(CROSSFADE_SAMPLES*NUM_OUTCHANNELS)
+{
+ if(m_hrtfs->isEmpty())
+ AUD_THROW(StateException, "The provided HRTF object is empty");
+ if(m_reader->getSpecs().channels != 1)
+ AUD_THROW(StateException, "The sound must have only one channel");
+ if(m_reader->getSpecs().rate != m_hrtfs->getSpecs().rate)
+ AUD_THROW(StateException, "The sound and the HRTFs must have the same rate");
+ m_M = m_L = m_N / 2;
+
+ m_RealAzimuth = m_Azimuth = m_source->getAzimuth();
+ m_RealElevation = m_Elevation = m_source->getElevation();
+ auto irs = m_hrtfs->getImpulseResponse(m_RealAzimuth, m_RealElevation);
+ for(unsigned int i = 0; i < NUM_CONVOLVERS; i++)
+ if(i%NUM_OUTCHANNELS==0)
+ m_convolvers.push_back(std::unique_ptr<Convolver>(new Convolver(irs.first->getChannel(0), irs.first->getLength(), m_threadPool, plan)));
+ else
+ m_convolvers.push_back(std::unique_ptr<Convolver>(new Convolver(irs.second->getChannel(0), irs.second->getLength(), m_threadPool, plan)));
+ m_futures.resize(NUM_CONVOLVERS);
+
+ m_outBuffer = (sample_t*)std::malloc(m_L*NUM_OUTCHANNELS*sizeof(sample_t));
+ m_eOutBufLen = m_outBufLen = m_outBufferPos = m_L * NUM_OUTCHANNELS;
+ m_inBuffer = (sample_t*)std::malloc(m_L * sizeof(sample_t));
+ for(int i = 0; i < NUM_CONVOLVERS; i++)
+ m_vecOut.push_back((sample_t*)std::calloc(m_L, sizeof(sample_t)));
+}
+
+BinauralReader::~BinauralReader()
+{
+ std::free(m_outBuffer);
+ std::free(m_inBuffer);
+ for(int i = 0; i < m_vecOut.size(); i++)
+ std::free(m_vecOut[i]);
+}
+
+bool BinauralReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void BinauralReader::seek(int position)
+{
+ m_position = position;
+ m_reader->seek(position);
+ for(int i = 0; i < NUM_CONVOLVERS; i++)
+ m_convolvers[i]->reset();
+ m_eosTail = false;
+ m_eosReader = false;
+ m_outBufferPos = m_eOutBufLen = m_outBufLen;
+ m_transition = false;
+ m_transPos = CROSSFADE_SAMPLES*NUM_OUTCHANNELS;
+}
+
+int BinauralReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int BinauralReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs BinauralReader::getSpecs() const
+{
+ Specs specs = m_reader->getSpecs();
+ specs.channels = CHANNELS_STEREO;
+ return specs;
+}
+
+void BinauralReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ int samples = 0;
+ int iteration = 0;
+ if(length <= 0)
+ {
+ length = 0;
+ eos = (m_eosTail && m_outBufferPos >= m_eOutBufLen);
+ return;
+ }
+
+ eos = false;
+ int writePos = 0;
+ do
+ {
+ int bufRest = m_eOutBufLen - m_outBufferPos;
+ int writeLength = std::min((length*NUM_OUTCHANNELS) - writePos, m_eOutBufLen + bufRest);
+ if(bufRest < writeLength || (m_eOutBufLen == 0 && m_eosTail))
+ {
+ if(bufRest > 0)
+ std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, bufRest*sizeof(sample_t));
+ if(!m_eosTail)
+ {
+ int n = NUM_OUTCHANNELS;
+ if(m_transition)
+ n = NUM_CONVOLVERS;
+ else if(checkSource())
+ n = NUM_CONVOLVERS;
+ loadBuffer(n);
+
+ int len = std::min(std::abs(writeLength - bufRest), m_eOutBufLen);
+ std::memcpy(buffer + writePos + bufRest, m_outBuffer, len*sizeof(sample_t));
+ samples += len;
+ m_outBufferPos = len;
+ writeLength = std::min((length*NUM_OUTCHANNELS) - writePos, m_eOutBufLen + bufRest);
+ }
+ else
+ {
+ m_outBufferPos += bufRest;
+ length = (writePos+bufRest) / NUM_OUTCHANNELS;
+ eos = true;
+ return;
+ }
+ }
+ else
+ {
+ std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, writeLength*sizeof(sample_t));
+ m_outBufferPos += writeLength;
+ }
+ writePos += writeLength;
+ iteration++;
+ } while(writePos < length*NUM_OUTCHANNELS);
+ m_position += length;
+}
+
+bool BinauralReader::checkSource()
+{
+ if((m_Azimuth != m_source->getAzimuth() || m_Elevation != m_source->getElevation()) && (!m_eosReader && !m_eosTail))
+ {
+ float az = m_Azimuth = m_source->getAzimuth();
+ float el = m_Elevation = m_source->getElevation();
+ auto irs = m_hrtfs->getImpulseResponse(az, el);
+ if(az != m_RealAzimuth || el != m_RealElevation)
+ {
+ m_RealAzimuth = az;
+ m_RealElevation = el;
+ for(int i = 0; i < NUM_OUTCHANNELS; i++)
+ {
+ auto temp = std::move(m_convolvers[i]);
+ m_convolvers[i] = std::move(m_convolvers[i + NUM_OUTCHANNELS]);
+ m_convolvers[i + NUM_OUTCHANNELS] = std::move(temp);
+ }
+ for(int i = 0; i < NUM_OUTCHANNELS; i++)
+ if(i%NUM_OUTCHANNELS == 0)
+ m_convolvers[i]->setImpulseResponse(irs.first->getChannel(0));
+ else
+ m_convolvers[i]->setImpulseResponse(irs.second->getChannel(0));
+
+ m_transPos = CROSSFADE_SAMPLES*NUM_OUTCHANNELS;
+ m_transition = true;
+ return true;
+ }
+ }
+ return false;
+}
+
+void BinauralReader::loadBuffer(int nConvolvers)
+{
+ m_lastLengthIn = m_L;
+ m_reader->read(m_lastLengthIn, m_eosReader, m_inBuffer);
+ if(!m_eosReader || m_lastLengthIn > 0)
+ {
+ int len = m_lastLengthIn;
+ for(int i = 0; i < nConvolvers; i++)
+ m_futures[i] = m_threadPool->enqueue(&BinauralReader::threadFunction, this, i, true);
+ for(int i = 0; i < nConvolvers; i++)
+ len = m_futures[i].get();
+
+ joinByChannel(0, len, nConvolvers);
+ m_eOutBufLen = len*NUM_OUTCHANNELS;
+ }
+ else if(!m_eosTail)
+ {
+ int len = m_lastLengthIn = m_L;
+ for(int i = 0; i < nConvolvers; i++)
+ m_futures[i] = m_threadPool->enqueue(&BinauralReader::threadFunction, this, i, false);
+ for(int i = 0; i < nConvolvers; i++)
+ len = m_futures[i].get();
+
+ joinByChannel(0, len, nConvolvers);
+ m_eOutBufLen = len*NUM_OUTCHANNELS;
+ }
+}
+
+void BinauralReader::joinByChannel(int start, int len, int nConvolvers)
+{
+ int k = 0;
+ float vol = 0;
+ const int l = CROSSFADE_SAMPLES*NUM_OUTCHANNELS;
+ for(int i = 0; i < len*NUM_OUTCHANNELS; i += NUM_OUTCHANNELS)
+ {
+ if(m_transition)
+ {
+ vol = (m_transPos - i) / (float)l;
+ if(vol > 1.0f)
+ vol = 1.0f;
+ else if(vol < 0.0f)
+ vol = 0.0f;
+ }
+
+ for(int j = 0; j < NUM_OUTCHANNELS; j++)
+ m_outBuffer[i + j + start] = ((m_vecOut[j][k] * (1.0f - vol)) + (m_vecOut[j + NUM_OUTCHANNELS][k] * vol))*m_source->getVolume();
+ k++;
+ }
+ if(m_transition)
+ {
+ m_transPos -= len*NUM_OUTCHANNELS;
+ if(m_transPos <= 0)
+ {
+ m_transition = false;
+ m_transPos = l;
+ }
+ }
+}
+
+int BinauralReader::threadFunction(int id, bool input)
+{
+ int l = m_lastLengthIn;
+ if(input)
+ m_convolvers[id]->getNext(m_inBuffer, m_vecOut[id], l, m_eosTail);
+ else
+ m_convolvers[id]->getNext(nullptr, m_vecOut[id], l, m_eosTail);
+ return l;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/BinauralSound.cpp b/extern/audaspace/src/fx/BinauralSound.cpp
new file mode 100644
index 00000000000..7b9508c9944
--- /dev/null
+++ b/extern/audaspace/src/fx/BinauralSound.cpp
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/BinauralSound.h"
+#include "fx/BinauralReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+BinauralSound::BinauralSound(std::shared_ptr<ISound> sound, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool) :
+ BinauralSound(sound, hrtfs, source, threadPool, std::make_shared<FFTPlan>(0.0))
+{
+}
+
+BinauralSound::BinauralSound(std::shared_ptr<ISound> sound, std::shared_ptr<HRTF> hrtfs, std::shared_ptr<Source> source, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_sound(sound), m_hrtfs(hrtfs), m_source(source), m_threadPool(threadPool), m_plan(plan)
+{
+}
+
+std::shared_ptr<IReader> BinauralSound::createReader()
+{
+ return std::make_shared<BinauralReader>(m_sound->createReader(), m_hrtfs, m_source, m_threadPool, m_plan);
+}
+
+std::shared_ptr<HRTF> BinauralSound::getHRTFs()
+{
+ return m_hrtfs;
+}
+
+void BinauralSound::setHRTFs(std::shared_ptr<HRTF> hrtfs)
+{
+ m_hrtfs = hrtfs;
+}
+
+std::shared_ptr<Source> BinauralSound::getSource()
+{
+ return m_source;
+}
+
+void BinauralSound::setSource(std::shared_ptr<Source> source)
+{
+ m_source = source;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Butterworth.cpp b/extern/audaspace/src/fx/Butterworth.cpp
new file mode 100644
index 00000000000..1d86cd799b8
--- /dev/null
+++ b/extern/audaspace/src/fx/Butterworth.cpp
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Butterworth.h"
+#include "fx/ButterworthCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+Butterworth::Butterworth(std::shared_ptr<ISound> sound, float frequency) :
+ DynamicIIRFilter(sound, std::shared_ptr<IDynamicIIRFilterCalculator>(new ButterworthCalculator(frequency)))
+{
+}
+
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ButterworthCalculator.cpp b/extern/audaspace/src/fx/ButterworthCalculator.cpp
new file mode 100644
index 00000000000..f249fd45f15
--- /dev/null
+++ b/extern/audaspace/src/fx/ButterworthCalculator.cpp
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/ButterworthCalculator.h"
+
+#include <cmath>
+
+#define BWPB41 0.76536686473
+#define BWPB42 1.84775906502
+
+AUD_NAMESPACE_BEGIN
+
+ButterworthCalculator::ButterworthCalculator(float frequency) :
+ m_frequency(frequency)
+{
+}
+
+void ButterworthCalculator::recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a)
+{
+ float omega = 2 * std::tan(m_frequency * M_PI / rate);
+ float o2 = omega * omega;
+ float o4 = o2 * o2;
+ 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);
+ a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
+ a.push_back((y1 + y2) * o228 / norm);
+ a.push_back(y1 * y2 / norm);
+ b.push_back(o4 / norm);
+ b.push_back(4 * o4 / norm);
+ b.push_back(6 * o4 / norm);
+ b.push_back(b[1]);
+ b.push_back(b[0]);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/CallbackIIRFilterReader.cpp b/extern/audaspace/src/fx/CallbackIIRFilterReader.cpp
new file mode 100644
index 00000000000..f24b6b6c9ec
--- /dev/null
+++ b/extern/audaspace/src/fx/CallbackIIRFilterReader.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/CallbackIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+CallbackIIRFilterReader::CallbackIIRFilterReader(std::shared_ptr<IReader> reader, int in, int out, doFilterIIR doFilter, endFilterIIR endFilter, void* data) :
+ BaseIIRFilterReader(reader, in, out),
+ m_filter(doFilter), m_endFilter(endFilter), m_data(data)
+{
+}
+
+CallbackIIRFilterReader::~CallbackIIRFilterReader()
+{
+ if(m_endFilter)
+ m_endFilter(m_data);
+}
+
+sample_t CallbackIIRFilterReader::filter()
+{
+ return m_filter(this, m_data);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Convolver.cpp b/extern/audaspace/src/fx/Convolver.cpp
new file mode 100644
index 00000000000..24b205e9282
--- /dev/null
+++ b/extern/audaspace/src/fx/Convolver.cpp
@@ -0,0 +1,156 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/Convolver.h"
+
+#include <cmath>
+#include <cstdlib>
+#include <algorithm>
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+Convolver::Convolver(std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ir, int irLength, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_irBuffers(ir), m_irLength(irLength), m_threadPool(threadPool), m_numThreads(std::min(threadPool->getNumOfThreads(), static_cast<unsigned int>(m_irBuffers->size() - 1))), m_tailCounter(0), m_eos(false)
+
+{
+ m_resetFlag = false;
+ m_futures.resize(m_numThreads);
+ for(int i = 0; i < m_irBuffers->size(); i++)
+ {
+ m_fftConvolvers.push_back(std::unique_ptr<FFTConvolver>(new FFTConvolver((*m_irBuffers)[i], plan)));
+ m_delayLine.push_front((fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex)));
+ }
+
+ m_accBuffer = (fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex));
+ for(int i = 0; i < m_numThreads; i++)
+ m_threadAccBuffers.push_back((fftwf_complex*)std::calloc((m_N / 2) + 1, sizeof(fftwf_complex)));
+}
+
+Convolver::~Convolver()
+{
+ m_resetFlag = true;
+ for(auto &fut : m_futures)
+ if(fut.valid())
+ fut.get();
+
+ std::free(m_accBuffer);
+ for(auto buf : m_threadAccBuffers)
+ std::free(buf);
+ while(!m_delayLine.empty())
+ {
+ std::free(m_delayLine.front());
+ m_delayLine.pop_front();
+ }
+}
+
+void Convolver::getNext(sample_t* inBuffer, sample_t* outBuffer, int& length, bool& eos)
+{
+ if(length > m_L)
+ {
+ length = 0;
+ eos = m_eos;
+ return;
+ }
+ if(m_eos)
+ {
+ eos = m_eos;
+ length = 0;
+ return;
+ }
+
+ eos = false;
+ for(auto &fut : m_futures)
+ if(fut.valid())
+ fut.get();
+
+ if(inBuffer != nullptr)
+ m_fftConvolvers[0]->getNextFDL(inBuffer, reinterpret_cast<std::complex<sample_t>*>(m_accBuffer), length, m_delayLine[0]);
+ else
+ {
+ m_tailCounter++;
+ std::memset(outBuffer, 0, m_L*sizeof(sample_t));
+ m_fftConvolvers[0]->getNextFDL(outBuffer, reinterpret_cast<std::complex<sample_t>*>(m_accBuffer), length, m_delayLine[0]);
+ }
+ m_delayLine.push_front(m_delayLine.back());
+ m_delayLine.pop_back();
+ length = m_L;
+ m_fftConvolvers[0]->IFFT_FDL(m_accBuffer, outBuffer, length);
+ std::memset(m_accBuffer, 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
+
+ if(m_tailCounter >= m_delayLine.size() && inBuffer == nullptr)
+ {
+ eos = m_eos = true;
+ length = m_irLength%m_M;
+ if(length == 0)
+ length = m_M;
+ }
+ else
+ for(int i = 0; i < m_futures.size(); i++)
+ m_futures[i] = m_threadPool->enqueue(&Convolver::threadFunction, this, i);
+}
+
+void Convolver::reset()
+{
+ m_resetFlag = true;
+ for(auto &fut : m_futures)
+ if(fut.valid())
+ fut.get();
+
+ for(int i = 0; i < m_delayLine.size();i++)
+ std::memset(m_delayLine[i], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
+ for(int i = 0; i < m_fftConvolvers.size(); i++)
+ m_fftConvolvers[i]->clear();
+ std::memset(m_accBuffer, 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
+ m_tailCounter = 0;
+ m_eos = false;
+ m_resetFlag = false;
+}
+
+std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> Convolver::getImpulseResponse()
+{
+ return m_irBuffers;
+}
+
+void Convolver::setImpulseResponse(std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ir)
+{
+ reset();
+ m_irBuffers = ir;
+ for(int i = 0; i < m_irBuffers->size(); i++)
+ m_fftConvolvers[i]->setImpulseResponse((*m_irBuffers)[i]);
+}
+
+bool Convolver::threadFunction(int id)
+{
+ int total = m_irBuffers->size();
+ int share = std::ceil(((float)total - 1) / (float)m_numThreads);
+ int start = id*share + 1;
+ int end = std::min(start + share, total);
+
+ std::memset(m_threadAccBuffers[id], 0, ((m_N / 2) + 1)*sizeof(fftwf_complex));
+
+ for(int i = start; i < end && !m_resetFlag; i++)
+ m_fftConvolvers[i]->getNextFDL(reinterpret_cast<std::complex<sample_t>*>(m_delayLine[i]), reinterpret_cast<std::complex<sample_t>*>(m_threadAccBuffers[id]));
+
+ m_sumMutex.lock();
+ for(int i = 0; (i < m_N / 2 + 1) && !m_resetFlag; i++)
+ {
+ m_accBuffer[i][0] += m_threadAccBuffers[id][i][0];
+ m_accBuffer[i][1] += m_threadAccBuffers[id][i][1];
+ }
+ m_sumMutex.unlock();
+ return true;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ConvolverReader.cpp b/extern/audaspace/src/fx/ConvolverReader.cpp
new file mode 100644
index 00000000000..d5d9050f9a1
--- /dev/null
+++ b/extern/audaspace/src/fx/ConvolverReader.cpp
@@ -0,0 +1,203 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/ConvolverReader.h"
+#include "Exception.h"
+
+#include <cstring>
+#include <algorithm>
+#include <cmath>
+#include <cstdlib>
+
+AUD_NAMESPACE_BEGIN
+ConvolverReader::ConvolverReader(std::shared_ptr<IReader> reader, std::shared_ptr<ImpulseResponse> ir, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_reader(reader), m_ir(ir), m_N(plan->getSize()), m_eosReader(false), m_eosTail(false), m_inChannels(reader->getSpecs().channels), m_irChannels(ir->getSpecs().channels), m_threadPool(threadPool), m_position(0)
+{
+ m_nChannelThreads = std::min((int)threadPool->getNumOfThreads(), m_inChannels);
+ m_futures.resize(m_nChannelThreads);
+
+ int irLength = m_ir->getLength();
+ if(m_irChannels != 1 && m_irChannels != m_inChannels)
+ AUD_THROW(StateException, "The impulse response and the sound must either have the same amount of channels or the impulse response must be mono");
+ if(m_reader->getSpecs().rate != m_ir->getSpecs().rate)
+ AUD_THROW(StateException, "The sound and the impulse response. must have the same rate");
+
+ m_M = m_L = m_N / 2;
+
+ if(m_irChannels > 1)
+ for(int i = 0; i < m_inChannels; i++)
+ m_convolvers.push_back(std::unique_ptr<Convolver>(new Convolver(ir->getChannel(i), irLength, m_threadPool, plan)));
+ else
+ for(int i = 0; i < m_inChannels; i++)
+ m_convolvers.push_back(std::unique_ptr<Convolver>(new Convolver(ir->getChannel(0), irLength, m_threadPool, plan)));
+
+ for(int i = 0; i < m_inChannels; i++)
+ m_vecInOut.push_back((sample_t*)std::malloc(m_L*sizeof(sample_t)));
+ m_outBuffer = (sample_t*)std::malloc(m_L*m_inChannels*sizeof(sample_t));
+ m_outBufLen = m_eOutBufLen = m_outBufferPos = m_L*m_inChannels;
+}
+
+ConvolverReader::~ConvolverReader()
+{
+ std::free(m_outBuffer);
+ for(int i = 0; i < m_inChannels; i++)
+ std::free(m_vecInOut[i]);
+}
+
+bool ConvolverReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void ConvolverReader::seek(int position)
+{
+ m_position = position;
+ m_reader->seek(position);
+ for(int i = 0; i < m_inChannels; i++)
+ m_convolvers[i]->reset();
+ m_eosTail = false;
+ m_eosReader = false;
+ m_outBufferPos = m_eOutBufLen = m_outBufLen;
+}
+
+int ConvolverReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int ConvolverReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs ConvolverReader::getSpecs() const
+{
+ return m_reader->getSpecs();
+}
+
+void ConvolverReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ if(length <= 0)
+ {
+ length = 0;
+ eos = (m_eosTail && m_outBufferPos >= m_eOutBufLen);
+ return;
+ }
+ eos = false;
+ int writePos = 0;
+ do
+ {
+ int bufRest = m_eOutBufLen - m_outBufferPos;
+ int writeLength = std::min((length*m_inChannels) - writePos, m_eOutBufLen + bufRest);
+ if(bufRest < writeLength || (m_eOutBufLen == 0 && m_eosTail))
+ {
+ if(bufRest > 0)
+ std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, bufRest*sizeof(sample_t));
+ if(!m_eosTail)
+ {
+ loadBuffer();
+ int len = std::min(std::abs(writeLength - bufRest), m_eOutBufLen);
+ std::memcpy(buffer + writePos + bufRest, m_outBuffer, len*sizeof(sample_t));
+ m_outBufferPos = len;
+ writeLength = std::min((length*m_inChannels) - writePos, m_eOutBufLen + bufRest);
+ }
+ else
+ {
+ m_outBufferPos += bufRest;
+ length = (writePos + bufRest) / m_inChannels;
+ eos = true;
+ return;
+ }
+ }
+ else
+ {
+ std::memcpy(buffer + writePos, m_outBuffer + m_outBufferPos, writeLength*sizeof(sample_t));
+ m_outBufferPos += writeLength;
+ }
+ writePos += writeLength;
+ } while(writePos < length*m_inChannels);
+ m_position += length;
+}
+
+void ConvolverReader::loadBuffer()
+{
+ m_lastLengthIn = m_L;
+ m_reader->read(m_lastLengthIn, m_eosReader, m_outBuffer);
+ if(!m_eosReader || m_lastLengthIn>0)
+ {
+ divideByChannel(m_outBuffer, m_lastLengthIn*m_inChannels);
+ int len = m_lastLengthIn;
+
+ for(int i = 0; i < m_futures.size(); i++)
+ m_futures[i] = m_threadPool->enqueue(&ConvolverReader::threadFunction, this, i, true);
+ for(auto &fut : m_futures)
+ len = fut.get();
+
+ joinByChannel(0, len);
+ m_eOutBufLen = len*m_inChannels;
+ }
+ else if(!m_eosTail)
+ {
+ int len = m_lastLengthIn = m_L;
+ for(int i = 0; i < m_futures.size(); i++)
+ m_futures[i] = m_threadPool->enqueue(&ConvolverReader::threadFunction, this, i, false);
+ for(auto &fut : m_futures)
+ len = fut.get();
+
+ joinByChannel(0, len);
+ m_eOutBufLen = len*m_inChannels;
+ }
+}
+
+void ConvolverReader::divideByChannel(const sample_t* buffer, int len)
+{
+ int k = 0;
+ for(int i = 0; i < len; i += m_inChannels)
+ {
+ for(int j = 0; j < m_inChannels; j++)
+ m_vecInOut[j][k] = buffer[i + j];
+ k++;
+ }
+}
+
+void ConvolverReader::joinByChannel(int start, int len)
+{
+ int k = 0;
+ for(int i = 0; i < len*m_inChannels; i += m_inChannels)
+ {
+ for(int j = 0; j < m_vecInOut.size(); j++)
+ m_outBuffer[i + j + start] = m_vecInOut[j][k];
+ k++;
+ }
+}
+
+int ConvolverReader::threadFunction(int id, bool input)
+{
+ int share = std::ceil((float)m_inChannels / (float)m_nChannelThreads);
+ int start = id*share;
+ int end = std::min(start + share, m_inChannels);
+
+ int l=m_lastLengthIn;
+ for(int i = start; i < end; i++)
+ if(input)
+ m_convolvers[i]->getNext(m_vecInOut[i], m_vecInOut[i], l, m_eosTail);
+ else
+ m_convolvers[i]->getNext(nullptr, m_vecInOut[i], l, m_eosTail);
+
+ return l;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ConvolverSound.cpp b/extern/audaspace/src/fx/ConvolverSound.cpp
new file mode 100644
index 00000000000..9bdf5a66652
--- /dev/null
+++ b/extern/audaspace/src/fx/ConvolverSound.cpp
@@ -0,0 +1,50 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/ConvolverSound.h"
+#include "fx/ConvolverReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+ConvolverSound::ConvolverSound(std::shared_ptr<ISound> sound, std::shared_ptr<ImpulseResponse> impulseResponse, std::shared_ptr<ThreadPool> threadPool) :
+ ConvolverSound(sound, impulseResponse, threadPool, std::make_shared<FFTPlan>(0.0))
+{
+}
+
+ConvolverSound::ConvolverSound(std::shared_ptr<ISound> sound, std::shared_ptr<ImpulseResponse> impulseResponse, std::shared_ptr<ThreadPool> threadPool, std::shared_ptr<FFTPlan> plan) :
+ m_sound(sound), m_impulseResponse(impulseResponse), m_threadPool(threadPool), m_plan(plan)
+{
+}
+
+std::shared_ptr<IReader> ConvolverSound::createReader()
+{
+ return std::make_shared<ConvolverReader>(m_sound->createReader(), m_impulseResponse, m_threadPool, m_plan);
+}
+
+std::shared_ptr<ImpulseResponse> ConvolverSound::getImpulseResponse()
+{
+ return m_impulseResponse;
+}
+
+void ConvolverSound::setImpulseResponse(std::shared_ptr<ImpulseResponse> impulseResponse)
+{
+ m_impulseResponse = impulseResponse;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Delay.cpp b/extern/audaspace/src/fx/Delay.cpp
new file mode 100644
index 00000000000..e2a82299bc0
--- /dev/null
+++ b/extern/audaspace/src/fx/Delay.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Delay.h"
+#include "fx/DelayReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Delay::Delay(std::shared_ptr<ISound> sound, float delay) :
+ Effect(sound),
+ m_delay(delay)
+{
+}
+
+float Delay::getDelay() const
+{
+ return m_delay;
+}
+
+std::shared_ptr<IReader> Delay::createReader()
+{
+ return std::shared_ptr<IReader>(new DelayReader(getReader(), m_delay));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/DelayReader.cpp b/extern/audaspace/src/fx/DelayReader.cpp
new file mode 100644
index 00000000000..530aed69cba
--- /dev/null
+++ b/extern/audaspace/src/fx/DelayReader.cpp
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/DelayReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+DelayReader::DelayReader(std::shared_ptr<IReader> reader, float delay) :
+ EffectReader(reader),
+ m_delay(int((SampleRate)delay * reader->getSpecs().rate)),
+ m_remdelay(int((SampleRate)delay * reader->getSpecs().rate))
+{
+}
+
+void DelayReader::seek(int position)
+{
+ if(position < m_delay)
+ {
+ m_remdelay = m_delay - position;
+ m_reader->seek(0);
+ }
+ else
+ {
+ m_remdelay = 0;
+ m_reader->seek(position - m_delay);
+ }
+}
+
+int DelayReader::getLength() const
+{
+ int len = m_reader->getLength();
+ if(len < 0)
+ return len;
+ return len + m_delay;
+}
+
+int DelayReader::getPosition() const
+{
+ if(m_remdelay > 0)
+ return m_delay - m_remdelay;
+ return m_reader->getPosition() + m_delay;
+}
+
+void DelayReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ if(m_remdelay > 0)
+ {
+ Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ if(length > m_remdelay)
+ {
+ std::memset(buffer, 0, m_remdelay * samplesize);
+
+ int len = length - m_remdelay;
+ m_reader->read(len, eos, buffer + m_remdelay * specs.channels);
+
+ length = m_remdelay + len;
+
+ m_remdelay = 0;
+ }
+ else
+ {
+ std::memset(buffer, 0, length * samplesize);
+ m_remdelay -= length;
+ }
+ }
+ else
+ m_reader->read(length, eos, buffer);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/DynamicIIRFilter.cpp b/extern/audaspace/src/fx/DynamicIIRFilter.cpp
new file mode 100644
index 00000000000..02a8b0b65ac
--- /dev/null
+++ b/extern/audaspace/src/fx/DynamicIIRFilter.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/DynamicIIRFilter.h"
+#include "fx/DynamicIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+DynamicIIRFilter::DynamicIIRFilter(std::shared_ptr<ISound> sound,
+ std::shared_ptr<IDynamicIIRFilterCalculator> calculator) :
+ Effect(sound),
+ m_calculator(calculator)
+{
+}
+
+std::shared_ptr<IReader> DynamicIIRFilter::createReader()
+{
+ return std::shared_ptr<IReader>(new DynamicIIRFilterReader(getReader(), m_calculator));
+}
+
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/DynamicIIRFilterReader.cpp b/extern/audaspace/src/fx/DynamicIIRFilterReader.cpp
new file mode 100644
index 00000000000..948b467aaa4
--- /dev/null
+++ b/extern/audaspace/src/fx/DynamicIIRFilterReader.cpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/DynamicIIRFilterReader.h"
+#include "fx/IDynamicIIRFilterCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+DynamicIIRFilterReader::DynamicIIRFilterReader(std::shared_ptr<IReader> reader, std::shared_ptr<IDynamicIIRFilterCalculator> calculator) :
+ IIRFilterReader(reader, std::vector<float>(), std::vector<float>()),
+ m_calculator(calculator)
+{
+ sampleRateChanged(reader->getSpecs().rate);
+}
+
+void DynamicIIRFilterReader::sampleRateChanged(SampleRate rate)
+{
+ std::vector<float> a, b;
+ m_calculator->recalculateCoefficients(rate, b, a);
+ setCoefficients(b, a);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/DynamicMusic.cpp b/extern/audaspace/src/fx/DynamicMusic.cpp
new file mode 100644
index 00000000000..b77cd749576
--- /dev/null
+++ b/extern/audaspace/src/fx/DynamicMusic.cpp
@@ -0,0 +1,346 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/DynamicMusic.h"
+#include "generator/Silence.h"
+#include "fx/Fader.h"
+#include "fx/Limiter.h"
+
+#include <mutex>
+#include <condition_variable>
+
+AUD_NAMESPACE_BEGIN
+
+DynamicMusic::DynamicMusic(std::shared_ptr<IDevice> device) :
+m_device(device), m_fadeTime(1.0f)
+{
+ m_id = 0;
+ m_transitioning = false;
+ m_stopThread = false;
+ m_volume = m_device->getVolume();
+ m_scenes.push_back(std::vector<std::shared_ptr<ISound>>(1, nullptr));
+}
+
+DynamicMusic::~DynamicMusic()
+{
+ stop();
+}
+
+int DynamicMusic::addScene(std::shared_ptr<ISound> sound)
+{
+ std::vector<std::shared_ptr<ISound>> v;
+ m_scenes.push_back(v);
+ for(int i = 0; i < m_scenes.size()-1; i++)
+ m_scenes.back().push_back(nullptr);
+ for(int i = 0; i < m_scenes.size()-1; i++)
+ m_scenes[i].push_back(nullptr);
+ m_scenes.back().push_back(sound);
+
+ return m_scenes.size() - 1;
+}
+
+bool DynamicMusic::changeScene(int id)
+{
+ if(id >= m_scenes.size() || m_transitioning)
+ return false;
+ else
+ {
+ if(m_fadeThread.joinable())
+ m_fadeThread.join();
+ m_device->lock();
+ if(id == m_id)
+ {
+ m_currentHandle->setVolume(m_volume);
+ m_currentHandle->setLoopCount(-1);
+ }
+ else
+ {
+ m_soundTarget = id;
+ if(m_scenes[m_id][id] == nullptr)
+ {
+ m_stopThread = false;
+ if((m_scenes[m_id][m_id] != nullptr && m_currentHandle->getStatus() != STATUS_INVALID) || m_scenes[m_soundTarget][m_soundTarget] != nullptr)
+ {
+ m_transitioning = true;
+ if(m_scenes[m_id][m_id] == nullptr || m_currentHandle->getStatus() == STATUS_INVALID)
+ {
+ m_device->lock();
+ m_currentHandle = m_device->play(m_scenes[m_soundTarget][m_soundTarget]);
+ m_currentHandle->setVolume(0.0f);
+ m_currentHandle->setLoopCount(-1);
+ m_device->unlock();
+ m_fadeThread = std::thread(&DynamicMusic::fadeInThread, this);
+ }
+ else
+ {
+ if(m_scenes[m_soundTarget][m_soundTarget] != nullptr)
+ {
+ m_device->lock();
+ m_transitionHandle = m_currentHandle;
+ m_currentHandle = m_device->play(m_scenes[m_soundTarget][m_soundTarget]);
+ m_currentHandle->setVolume(0.0f);
+ m_currentHandle->setLoopCount(-1);
+ m_device->unlock();
+ m_fadeThread = std::thread(&DynamicMusic::crossfadeThread, this);
+ }
+ else
+ {
+ m_transitionHandle = m_currentHandle;
+ m_currentHandle = nullptr;
+ m_fadeThread = std::thread(&DynamicMusic::fadeOutThread, this);
+ }
+ }
+ }
+ }
+ else
+ {
+ if(m_scenes[m_id][m_id] == nullptr || m_currentHandle->getStatus() == STATUS_INVALID)
+ transitionCallback(this);
+ else
+ {
+ m_currentHandle->setLoopCount(0);
+ m_currentHandle->setStopCallback(transitionCallback, this);
+ }
+ }
+ }
+ m_device->unlock();
+ return true;
+ }
+}
+
+int DynamicMusic::getScene()
+{
+ return m_id;
+}
+
+bool DynamicMusic::addTransition(int init, int end, std::shared_ptr<ISound> sound)
+{
+ if(init != end && init < m_scenes.size() && end < m_scenes.size() && init >= 0 && end >= 0)
+ {
+ m_scenes[init][end] = sound;
+ return true;
+ }
+ return false;
+}
+
+void DynamicMusic::setFadeTime(float seconds)
+{
+ m_device->lock();
+ m_fadeTime = seconds;
+ m_device->unlock();
+}
+
+float DynamicMusic::getFadeTime()
+{
+ return m_fadeTime;
+}
+
+bool DynamicMusic::resume()
+{
+ bool result = false, resultTrans = false;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->resume();
+ if(m_transitionHandle != nullptr)
+ resultTrans = m_transitionHandle->resume();
+
+ return result || resultTrans;
+}
+
+bool DynamicMusic::pause()
+{
+ bool result = false, resultTrans = false;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->pause();
+ if(m_transitionHandle != nullptr)
+ resultTrans = m_transitionHandle->pause();
+
+ return result || resultTrans;
+}
+
+bool DynamicMusic::seek(float position)
+{
+ bool result;
+
+ if(m_currentHandle != nullptr)
+ {
+ result = m_currentHandle->seek(position);
+ if(m_transitionHandle != nullptr && result == true)
+ m_transitionHandle->stop();
+ }
+
+ return result;
+}
+
+float DynamicMusic::getPosition()
+{
+ float result = 0.0f;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->getPosition();
+
+ return result;
+}
+
+float DynamicMusic::getVolume()
+{
+ return m_volume;
+}
+
+bool DynamicMusic::setVolume(float volume)
+{
+ m_volume = volume;
+ bool result = false, resultTrans = false;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->setVolume(volume);
+ if(m_transitionHandle != nullptr)
+ {
+ m_device->lock();
+ if(volume<m_transitionHandle->getVolume())
+ resultTrans = m_transitionHandle->setVolume(0.0f);
+ m_device->unlock();
+ }
+ if(m_currentHandle == nullptr && m_transitionHandle == nullptr)
+ result = true;
+
+ return result || resultTrans;
+}
+
+Status DynamicMusic::getStatus()
+{
+ if(m_currentHandle != nullptr)
+ {
+ Status result = m_currentHandle->getStatus();
+ return result;
+ }
+ else
+ return STATUS_INVALID;
+}
+
+bool DynamicMusic::stop()
+{
+ m_stopThread = true;
+ bool result = false, resultTrans = false;
+
+ if(m_currentHandle != nullptr)
+ result = m_currentHandle->stop();
+ if(m_transitionHandle != nullptr)
+
+ resultTrans = m_transitionHandle->stop();
+
+ if(m_fadeThread.joinable())
+ m_fadeThread.join();
+ m_id = 0;
+
+ return result || resultTrans;
+}
+
+void DynamicMusic::transitionCallback(void* player)
+{
+ auto dat = reinterpret_cast<DynamicMusic*>(player);
+ dat->m_transitioning = true;
+ dat->m_device->lock();
+ dat->m_currentHandle = dat->m_device->play(dat->m_scenes[dat->m_id][dat->m_soundTarget]);
+ dat->m_currentHandle->setVolume(dat->m_volume);
+ if(dat->m_scenes[dat->m_soundTarget][dat->m_soundTarget] != nullptr)
+ dat->m_currentHandle->setStopCallback(sceneCallback, player);
+ dat->m_device->unlock();
+}
+
+void DynamicMusic::sceneCallback(void* player)
+{
+ auto dat = reinterpret_cast<DynamicMusic*>(player);
+ dat->m_device->lock();
+ dat->m_currentHandle = dat->m_device->play(dat->m_scenes[dat->m_soundTarget][dat->m_soundTarget]);
+ dat->m_currentHandle->setVolume(dat->m_volume);
+ dat->m_currentHandle->setLoopCount(-1);
+ dat->m_device->unlock();
+ dat->m_id = int(dat->m_soundTarget);
+ dat->m_soundTarget = -1;
+ dat->m_transitioning = false;
+}
+
+void DynamicMusic::crossfadeThread()
+{
+ float currentVol = m_transitionHandle->getVolume();
+ float nextVol = m_currentHandle->getVolume();
+ float increment;
+
+ while(nextVol < m_volume && !m_stopThread)
+ {
+ increment = (m_volume / (m_fadeTime * 1000)) * 20;
+ currentVol -= increment;
+ nextVol += increment;
+ if(currentVol < 0)
+ currentVol = 0;
+ if(nextVol > m_volume)
+ nextVol = m_volume;
+ m_transitionHandle->setVolume(currentVol);
+ m_currentHandle->setVolume(nextVol);
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
+ }
+ if(m_stopThread)
+ m_transitionHandle->setVolume(m_volume);
+
+ m_transitionHandle->stop();
+
+ m_id = int(m_soundTarget);
+ m_transitioning = false;
+}
+
+void DynamicMusic::fadeInThread()
+{
+ float nextVol = m_currentHandle->getVolume();
+ float increment;
+
+ while(nextVol < m_volume && !m_stopThread)
+ {
+ increment = (m_volume / (m_fadeTime * 1000)) * 20;
+ nextVol += increment;
+ if(nextVol > m_volume)
+ nextVol = m_volume;
+ m_currentHandle->setVolume(nextVol);
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
+ }
+ if(m_stopThread)
+ m_currentHandle->setVolume(m_volume);
+
+ m_id = int(m_soundTarget);
+ m_transitioning = false;
+}
+
+void DynamicMusic::fadeOutThread()
+{
+ float currentVol = m_transitionHandle->getVolume();
+ float increment;
+
+ while(currentVol > 0.0f && !m_stopThread)
+ {
+ increment = (m_volume / (m_fadeTime * 1000)) * 20;
+ currentVol -= increment;
+ if(currentVol < 0)
+ currentVol = 0;
+ m_transitionHandle->setVolume(currentVol);
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
+ }
+
+ m_transitionHandle->stop();
+ m_id = int(m_soundTarget);
+ m_transitioning = false;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Effect.cpp b/extern/audaspace/src/fx/Effect.cpp
new file mode 100644
index 00000000000..af59ba440f9
--- /dev/null
+++ b/extern/audaspace/src/fx/Effect.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Effect.h"
+
+AUD_NAMESPACE_BEGIN
+
+Effect::Effect(std::shared_ptr<ISound> sound)
+{
+ m_sound = sound;
+}
+
+Effect::~Effect()
+{
+}
+
+std::shared_ptr<ISound> Effect::getSound() const
+{
+ return m_sound;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/EffectReader.cpp b/extern/audaspace/src/fx/EffectReader.cpp
new file mode 100644
index 00000000000..93a9d3cbf1c
--- /dev/null
+++ b/extern/audaspace/src/fx/EffectReader.cpp
@@ -0,0 +1,60 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/EffectReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+EffectReader::EffectReader(std::shared_ptr<IReader> reader)
+{
+ m_reader = reader;
+}
+
+EffectReader::~EffectReader()
+{
+}
+
+bool EffectReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void EffectReader::seek(int position)
+{
+ m_reader->seek(position);
+}
+
+int EffectReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int EffectReader::getPosition() const
+{
+ return m_reader->getPosition();
+}
+
+Specs EffectReader::getSpecs() const
+{
+ return m_reader->getSpecs();
+}
+
+void EffectReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ m_reader->read(length, eos, buffer);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Envelope.cpp b/extern/audaspace/src/fx/Envelope.cpp
new file mode 100644
index 00000000000..0637706c0a9
--- /dev/null
+++ b/extern/audaspace/src/fx/Envelope.cpp
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Envelope.h"
+#include "fx/CallbackIIRFilterReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+struct EnvelopeParameters
+{
+ float attack;
+ float release;
+ float threshold;
+ float arthreshold;
+};
+
+sample_t Envelope::envelopeFilter(CallbackIIRFilterReader* reader, EnvelopeParameters* param)
+{
+ float in = std::fabs(reader->x(0));
+ float out = reader->y(-1);
+ if(in < param->threshold)
+ in = 0.0f;
+ return (in > out ? param->attack : param->release) * (out - in) + in;
+}
+
+void Envelope::endEnvelopeFilter(EnvelopeParameters* param)
+{
+ delete param;
+}
+
+Envelope::Envelope(std::shared_ptr<ISound> sound, float attack, float release, float threshold, float arthreshold) :
+ Effect(sound),
+ m_attack(attack),
+ m_release(release),
+ m_threshold(threshold),
+ m_arthreshold(arthreshold)
+{
+}
+
+std::shared_ptr<IReader> Envelope::createReader()
+{
+ std::shared_ptr<IReader> reader = getReader();
+
+ EnvelopeParameters* param = new EnvelopeParameters();
+ param->arthreshold = m_arthreshold;
+ param->attack = std::pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_attack));
+ param->release = std::pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release));
+ param->threshold = m_threshold;
+
+ return std::shared_ptr<IReader>(new CallbackIIRFilterReader(reader, 1, 2,
+ (doFilterIIR) envelopeFilter,
+ (endFilterIIR) endEnvelopeFilter,
+ param));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/FFTConvolver.cpp b/extern/audaspace/src/fx/FFTConvolver.cpp
new file mode 100644
index 00000000000..868a1ebbaf3
--- /dev/null
+++ b/extern/audaspace/src/fx/FFTConvolver.cpp
@@ -0,0 +1,214 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/FFTConvolver.h"
+
+#include <cstring>
+#include <cstdlib>
+
+AUD_NAMESPACE_BEGIN
+
+FFTConvolver::FFTConvolver(std::shared_ptr<std::vector<std::complex<sample_t>>> ir, std::shared_ptr<FFTPlan> plan) :
+ m_plan(plan), m_N(plan->getSize()), m_M(plan->getSize()/2), m_L(plan->getSize()/2), m_tailPos(0), m_irBuffer(ir)
+{
+ m_tail = (float*)calloc(m_M - 1, sizeof(float));
+ m_realBufLen = ((m_N / 2) + 1) * 2;
+ m_inBuffer = nullptr;
+ m_shiftBuffer = (sample_t*)std::calloc(m_N, sizeof(sample_t));
+}
+
+FFTConvolver::~FFTConvolver()
+{
+ std::free(m_tail);
+ std::free(m_shiftBuffer);
+ if(m_inBuffer != nullptr)
+ m_plan->freeBuffer(m_inBuffer);
+}
+
+void FFTConvolver::getNext(const sample_t* inBuffer, sample_t* outBuffer, int& length)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ std::memcpy(m_inBuffer, inBuffer, length*sizeof(sample_t));
+
+ m_plan->FFT(m_inBuffer);
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ m_inBuffer[i] = m_inBuffer[i] * (*m_irBuffer)[i] / sample_t(m_N);
+ }
+ m_plan->IFFT(m_inBuffer);
+
+ for(int i = 0; i < m_M - 1; i++)
+ ((float*)m_inBuffer)[i] += m_tail[i];
+
+ for(int i = 0; i < m_M - 1; i++)
+ m_tail[i] = ((float*)m_inBuffer)[i + length];
+
+ std::memcpy(outBuffer, m_inBuffer, length * sizeof(sample_t));
+}
+
+void FFTConvolver::getNext(const sample_t* inBuffer, sample_t* outBuffer, int& length, fftwf_complex* transformedData)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ std::memcpy(m_inBuffer, inBuffer, length*sizeof(sample_t));
+
+ m_plan->FFT(m_inBuffer);
+ std::memcpy(transformedData, m_inBuffer, (m_realBufLen / 2)*sizeof(fftwf_complex));
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ m_inBuffer[i] = m_inBuffer[i] * (*m_irBuffer)[i] / sample_t(m_N);
+ }
+ m_plan->IFFT(m_inBuffer);
+
+ for(int i = 0; i < m_M - 1; i++)
+ ((float*)m_inBuffer)[i] += m_tail[i];
+
+ for(int i = 0; i < m_M - 1; i++)
+ m_tail[i] = ((float*)m_inBuffer)[i + length];
+
+ std::memcpy(outBuffer, m_inBuffer, length * sizeof(sample_t));
+}
+
+void FFTConvolver::getNext(const fftwf_complex* inBuffer, sample_t* outBuffer, int& length)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ m_inBuffer[i] = m_inBuffer[i] * (*m_irBuffer)[i] / sample_t(m_N);
+ }
+ m_plan->IFFT(m_inBuffer);
+
+ for(int i = 0; i < m_M - 1; i++)
+ ((float*)m_inBuffer)[i] += m_tail[i];
+
+ for(int i = 0; i < m_M - 1; i++)
+ m_tail[i] = ((float*)m_inBuffer)[i + length];
+
+ std::memcpy(outBuffer, m_inBuffer, length * sizeof(sample_t));
+}
+
+void FFTConvolver::getTail(int& length, bool& eos, sample_t* buffer)
+{
+ if(length <= 0)
+ {
+ length = 0;
+ eos = m_tailPos >= m_M - 1;
+ return;
+ }
+
+ eos = false;
+ if(m_tailPos + length > m_M - 1)
+ {
+ length = m_M - 1 - m_tailPos;
+ if(length < 0)
+ length = 0;
+ eos = true;
+ m_tailPos = m_M - 1;
+ }
+ else
+ m_tailPos += length;
+ std::memcpy(buffer, m_tail, length*sizeof(sample_t));
+}
+
+void FFTConvolver::clear()
+{
+ std::memset(m_shiftBuffer, 0, m_N * sizeof(sample_t));
+ std::memset(m_tail, 0, m_M - 1);
+}
+
+void FFTConvolver::IFFT_FDL(const fftwf_complex* inBuffer, sample_t* outBuffer, int& length)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ std::memcpy(m_inBuffer, inBuffer, (m_realBufLen / 2)*sizeof(fftwf_complex));
+ m_plan->IFFT(m_inBuffer);
+ std::memcpy(outBuffer, ((sample_t*)m_inBuffer)+m_L, length*sizeof(sample_t));
+}
+
+void FFTConvolver::getNextFDL(const std::complex<sample_t>* inBuffer, std::complex<sample_t>* accBuffer)
+{
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ accBuffer[i] += (inBuffer[i] * (*m_irBuffer)[i]) / sample_t(m_N);
+ }
+}
+
+void FFTConvolver::getNextFDL(const sample_t* inBuffer, std::complex<sample_t>* accBuffer, int& length, fftwf_complex* transformedData)
+{
+ if(length > m_L || length <= 0)
+ {
+ length = 0;
+ return;
+ }
+ if(m_inBuffer == nullptr)
+ m_inBuffer = reinterpret_cast<std::complex<sample_t>*>(m_plan->getBuffer());
+
+ std::memcpy(m_shiftBuffer, m_shiftBuffer + m_L, m_L*sizeof(sample_t));
+ std::memcpy(m_shiftBuffer + m_L, inBuffer, length*sizeof(sample_t));
+
+ std::memset(m_inBuffer, 0, m_realBufLen * sizeof(fftwf_complex));
+ std::memcpy(m_inBuffer, m_shiftBuffer, (m_L+length)*sizeof(sample_t));
+
+ m_plan->FFT(m_inBuffer);
+ std::memcpy(transformedData, m_inBuffer, (m_realBufLen / 2)*sizeof(fftwf_complex));
+ for(int i = 0; i < m_realBufLen / 2; i++)
+ {
+ accBuffer[i] += (m_inBuffer[i] * (*m_irBuffer)[i]) / sample_t(m_N);
+ }
+}
+
+
+void FFTConvolver::setImpulseResponse(std::shared_ptr<std::vector<std::complex<sample_t>>> ir)
+{
+ clear();
+ m_irBuffer = ir;
+}
+
+std::shared_ptr<std::vector<std::complex<sample_t>>> FFTConvolver::getImpulseResponse()
+{
+ return m_irBuffer;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Fader.cpp b/extern/audaspace/src/fx/Fader.cpp
new file mode 100644
index 00000000000..041d8369a01
--- /dev/null
+++ b/extern/audaspace/src/fx/Fader.cpp
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Fader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Fader::Fader(std::shared_ptr<ISound> sound, FadeType type, float start, float length) :
+ Effect(sound),
+ m_type(type),
+ m_start(start),
+ m_length(length)
+{
+}
+
+FadeType Fader::getType() const
+{
+ return m_type;
+}
+
+float Fader::getStart() const
+{
+ return m_start;
+}
+
+float Fader::getLength() const
+{
+ return m_length;
+}
+
+std::shared_ptr<IReader> Fader::createReader()
+{
+ return std::shared_ptr<IReader>(new FaderReader(getReader(), m_type, m_start, m_length));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/FaderReader.cpp b/extern/audaspace/src/fx/FaderReader.cpp
new file mode 100644
index 00000000000..b1e23b993f3
--- /dev/null
+++ b/extern/audaspace/src/fx/FaderReader.cpp
@@ -0,0 +1,76 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/FaderReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+FaderReader::FaderReader(std::shared_ptr<IReader> reader, FadeType type, float start,float length) :
+ EffectReader(reader),
+ m_type(type),
+ m_start(start),
+ m_length(length)
+{
+}
+
+void FaderReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ int position = m_reader->getPosition();
+ Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_reader->read(length, eos, buffer);
+
+ if((position + length) / (float)specs.rate <= m_start)
+ {
+ if(m_type != FADE_OUT)
+ {
+ std::memset(buffer, 0, length * samplesize);
+ }
+ }
+ else if(position / (float)specs.rate >= m_start+m_length)
+ {
+ if(m_type == FADE_OUT)
+ {
+ std::memset(buffer, 0, length * samplesize);
+ }
+ }
+ else
+ {
+ float volume = 1.0f;
+
+ for(int i = 0; i < length * specs.channels; i++)
+ {
+ if(i % specs.channels == 0)
+ {
+ volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
+ if(volume > 1.0f)
+ volume = 1.0f;
+ else if(volume < 0.0f)
+ volume = 0.0f;
+
+ if(m_type == FADE_OUT)
+ volume = 1.0f - volume;
+ }
+
+ buffer[i] = buffer[i] * volume;
+ }
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/HRTF.cpp b/extern/audaspace/src/fx/HRTF.cpp
new file mode 100644
index 00000000000..14ef3ad0912
--- /dev/null
+++ b/extern/audaspace/src/fx/HRTF.cpp
@@ -0,0 +1,122 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/HRTF.h"
+#include "Exception.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+HRTF::HRTF() :
+ HRTF(std::make_shared<FFTPlan>(0.0))
+{
+}
+
+HRTF::HRTF(std::shared_ptr<FFTPlan> plan) :
+ m_plan(plan)
+{
+ m_specs.channels = CHANNELS_INVALID;
+ m_specs.rate = 0;
+ m_empty = true;
+}
+
+bool HRTF::addImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse, float azimuth, float elevation)
+{
+ Specs spec = impulseResponse->getSpecs();
+
+ azimuth = std::fmod(azimuth, 360);
+ if(azimuth < 0)
+ azimuth += 360;
+
+ if((spec.channels != CHANNELS_MONO) || (spec.rate != m_specs.rate && m_specs.rate > 0.0))
+ return false;
+
+ m_hrtfs[elevation][azimuth] = std::make_shared<ImpulseResponse>(impulseResponse, m_plan);
+ m_specs.channels = CHANNELS_MONO;
+ m_specs.rate = spec.rate;
+ m_empty = false;
+ return true;
+}
+
+std::pair<std::shared_ptr<ImpulseResponse>, std::shared_ptr<ImpulseResponse>> HRTF::getImpulseResponse(float &azimuth, float &elevation)
+{
+ if(m_hrtfs.empty())
+ return std::make_pair(nullptr, nullptr);
+ azimuth = std::fmod(azimuth, 360);
+ if(azimuth < 0)
+ azimuth += 360;
+
+ std::shared_ptr<ImpulseResponse> R, L;
+ float az = 0, el = 0, dif=0, minDif=360;
+
+ for(auto elem : m_hrtfs)
+ {
+ dif = std::fabs(elevation - elem.first);
+ if(dif < minDif)
+ {
+ minDif = dif;
+ el = elem.first;
+ }
+ }
+ elevation = el;
+ dif = 0;
+ minDif = 360;
+
+ for(auto elem : m_hrtfs[elevation])
+ {
+ dif = std::fabs(azimuth - elem.first);
+ if(dif < minDif)
+ {
+ minDif = dif;
+ az = elem.first;
+ R = elem.second;
+ }
+ }
+ azimuth = az;
+ float azL = 360 - azimuth;
+ if(azL == 360)
+ azL = 0;
+
+ auto iter = m_hrtfs[elevation].find(azL);
+ if(iter != m_hrtfs[elevation].end())
+ L = iter->second;
+ else
+ {
+ dif = 0;
+ minDif = 360;
+ for(auto elem : m_hrtfs[elevation])
+ {
+ dif = std::fabs(azL - elem.first);
+ if(dif < minDif)
+ {
+ minDif = dif;
+ L = elem.second;
+ }
+ }
+ }
+ return std::make_pair(L, R);
+}
+
+Specs HRTF::getSpecs()
+{
+ return m_specs;
+}
+
+bool HRTF::isEmpty()
+{
+ return m_empty;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/HRTFLoaderUnix.cpp b/extern/audaspace/src/fx/HRTFLoaderUnix.cpp
new file mode 100644
index 00000000000..12a23913912
--- /dev/null
+++ b/extern/audaspace/src/fx/HRTFLoaderUnix.cpp
@@ -0,0 +1,89 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/HRTFLoader.h"
+#include "file/File.h"
+#include "Exception.h"
+
+#include <dirent.h>
+#include <exception>
+
+AUD_NAMESPACE_BEGIN
+
+std::shared_ptr<HRTF> HRTFLoader::loadLeftHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>(plan));
+ loadHRTFs(hrtfs, 'L', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadRightHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>(plan));
+ loadHRTFs(hrtfs, 'R', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadLeftHRTFs(const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>());
+ loadHRTFs(hrtfs, 'L', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadRightHRTFs(const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>());
+ loadHRTFs(hrtfs, 'R', fileExtension, path);
+ return hrtfs;
+}
+
+void HRTFLoader::loadHRTFs(std::shared_ptr<HRTF> hrtfs, char ear, const std::string& fileExtension, const std::string& path)
+{
+ std::string readpath = path;
+ if(path == "")
+ readpath = ".";
+
+ DIR* dir = opendir(path.c_str());
+ if(!dir)
+ return;
+
+ float azim, elev;
+
+ while(dirent* entry = readdir(dir))
+ {
+ std::string filename = entry->d_name;
+ if(filename.front() == ear && filename.length() >= fileExtension.length() && filename.substr(filename.length() - fileExtension.length()) == fileExtension)
+ {
+ try
+ {
+ elev = std::stof(filename.substr(1, filename.find("e") - 1));
+ azim = std::stof(filename.substr(filename.find("e") + 1, filename.find("a") - filename.find("e") - 1));
+ if(ear == 'L')
+ azim = 360 - azim;
+ }
+ catch(std::exception& e)
+ {
+ AUD_THROW(FileException, "The HRTF name doesn't follow the naming scheme: " + filename);
+ }
+ hrtfs->addImpulseResponse(std::make_shared<StreamBuffer>(std::make_shared<File>(readpath + "/" + filename)), azim, elev);
+ }
+ }
+ closedir(dir);
+ return;
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/HRTFLoaderWindows.cpp b/extern/audaspace/src/fx/HRTFLoaderWindows.cpp
new file mode 100644
index 00000000000..148f1fa015d
--- /dev/null
+++ b/extern/audaspace/src/fx/HRTFLoaderWindows.cpp
@@ -0,0 +1,93 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/HRTFLoader.h"
+#include "file/File.h"
+#include "Exception.h"
+
+#include <windows.h>
+#include <exception>
+
+AUD_NAMESPACE_BEGIN
+
+std::shared_ptr<HRTF> HRTFLoader::loadLeftHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>(plan));
+ loadHRTFs(hrtfs, 'L', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadRightHRTFs(std::shared_ptr<FFTPlan> plan, const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>(plan));
+ loadHRTFs(hrtfs, 'R', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadLeftHRTFs(const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>());
+ loadHRTFs(hrtfs, 'L', fileExtension, path);
+ return hrtfs;
+}
+
+std::shared_ptr<HRTF> HRTFLoader::loadRightHRTFs(const std::string& fileExtension, const std::string& path)
+{
+ std::shared_ptr<HRTF> hrtfs(std::make_shared<HRTF>());
+ loadHRTFs(hrtfs, 'R', fileExtension, path);
+ return hrtfs;
+}
+
+void HRTFLoader::loadHRTFs(std::shared_ptr<HRTF> hrtfs, char ear, const std::string& fileExtension, const std::string& path)
+{
+ std::string readpath = path;
+ if(path == "")
+ readpath = ".";
+
+ WIN32_FIND_DATA entry;
+ bool found_file = true;
+ std::string search = readpath + "\\*";
+ HANDLE dir = FindFirstFile(search.c_str(), &entry);
+ if(dir == INVALID_HANDLE_VALUE)
+ return;
+
+ float azim, elev;
+
+ while(found_file)
+ {
+ std::string filename = entry.cFileName;
+ if(filename.front() == ear && filename.length() >= fileExtension.length() && filename.substr(filename.length() - fileExtension.length()) == fileExtension)
+ {
+ try
+ {
+ elev = std::stof(filename.substr(1, filename.find("e") - 1));
+ azim = std::stof(filename.substr(filename.find("e") + 1, filename.find("a") - filename.find("e") - 1));
+ if(ear == 'L')
+ azim = 360 - azim;
+ }
+ catch(std::exception& e)
+ {
+ AUD_THROW(FileException, "The HRTF name doesn't follow the naming scheme: " + filename);
+ }
+ hrtfs->addImpulseResponse(std::make_shared<StreamBuffer>(std::make_shared<File>(readpath + "/" + filename)), azim, elev);
+ }
+ found_file = FindNextFile(dir, &entry);
+ }
+ FindClose(dir);
+ return;
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/Highpass.cpp b/extern/audaspace/src/fx/Highpass.cpp
new file mode 100644
index 00000000000..2490d512078
--- /dev/null
+++ b/extern/audaspace/src/fx/Highpass.cpp
@@ -0,0 +1,28 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Highpass.h"
+#include "fx/IIRFilterReader.h"
+#include "fx/HighpassCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+Highpass::Highpass(std::shared_ptr<ISound> sound, float frequency, float Q) :
+ DynamicIIRFilter(sound, std::shared_ptr<IDynamicIIRFilterCalculator>(new HighpassCalculator(frequency, Q)))
+{
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/HighpassCalculator.cpp b/extern/audaspace/src/fx/HighpassCalculator.cpp
new file mode 100644
index 00000000000..2b69efe2fa7
--- /dev/null
+++ b/extern/audaspace/src/fx/HighpassCalculator.cpp
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/HighpassCalculator.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+HighpassCalculator::HighpassCalculator(float frequency, float Q) :
+ m_frequency(frequency),
+ m_Q(Q)
+{
+}
+
+void HighpassCalculator::recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a)
+{
+ float w0 = 2.0 * M_PI * (SampleRate)m_frequency / rate;
+ float alpha = (float)(std::sin(w0) / (2.0 * (double)m_Q));
+ float norm = 1 + alpha;
+ float c = std::cos(w0);
+ a.push_back(1);
+ a.push_back(-2 * c / norm);
+ a.push_back((1 - alpha) / norm);
+ b.push_back((1 + c) / (2 * norm));
+ b.push_back((-1 - c) / norm);
+ b.push_back(b[0]);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/IIRFilter.cpp b/extern/audaspace/src/fx/IIRFilter.cpp
new file mode 100644
index 00000000000..fce6d01e4bf
--- /dev/null
+++ b/extern/audaspace/src/fx/IIRFilter.cpp
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/IIRFilter.h"
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+IIRFilter::IIRFilter(std::shared_ptr<ISound> sound, const std::vector<float>& b, const std::vector<float>& a) :
+ Effect(sound), m_a(a), m_b(b)
+{
+}
+
+std::shared_ptr<IReader> IIRFilter::createReader()
+{
+ return std::shared_ptr<IReader>(new IIRFilterReader(getReader(), m_b, m_a));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/IIRFilterReader.cpp b/extern/audaspace/src/fx/IIRFilterReader.cpp
new file mode 100644
index 00000000000..8d879a85846
--- /dev/null
+++ b/extern/audaspace/src/fx/IIRFilterReader.cpp
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+IIRFilterReader::IIRFilterReader(std::shared_ptr<IReader> reader, const std::vector<float>& b, const std::vector<float>& a) :
+ BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b)
+{
+ if(m_a.empty() == false)
+ {
+ for(int i = 1; i < m_a.size(); i++)
+ m_a[i] /= m_a[0];
+ for(int i = 0; i < m_b.size(); i++)
+ m_b[i] /= m_a[0];
+ m_a[0] = 1;
+ }
+}
+
+sample_t IIRFilterReader::filter()
+{
+ sample_t out = 0;
+
+ for(int i = 1; i < m_a.size(); i++)
+ out -= y(-i) * m_a[i];
+ for(int i = 0; i < m_b.size(); i++)
+ out += x(-i) * m_b[i];
+
+ return out;
+}
+
+void IIRFilterReader::setCoefficients(const std::vector<float>& b, const std::vector<float>& a)
+{
+ setLengths(b.size(), a.size());
+ m_a = a;
+ m_b = b;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ImpulseResponse.cpp b/extern/audaspace/src/fx/ImpulseResponse.cpp
new file mode 100644
index 00000000000..babb628eb7a
--- /dev/null
+++ b/extern/audaspace/src/fx/ImpulseResponse.cpp
@@ -0,0 +1,97 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/ImpulseResponse.h"
+
+#include <algorithm>
+#include <cstring>
+#include <cstdlib>
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+ImpulseResponse::ImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse) :
+ ImpulseResponse(impulseResponse, std::make_shared<FFTPlan>(0.0))
+{
+}
+
+ImpulseResponse::ImpulseResponse(std::shared_ptr<StreamBuffer> impulseResponse, std::shared_ptr<FFTPlan> plan)
+{
+ auto reader = impulseResponse->createReader();
+ m_length = reader->getLength();
+ processImpulseResponse(impulseResponse->createReader(), plan);
+}
+
+Specs ImpulseResponse::getSpecs()
+{
+ return m_specs;
+}
+
+int ImpulseResponse::getLength()
+{
+ return m_length;
+}
+
+std::shared_ptr<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>> ImpulseResponse::getChannel(int n)
+{
+ return m_processedIR[n];
+}
+
+void ImpulseResponse::processImpulseResponse(std::shared_ptr<IReader> reader, std::shared_ptr<FFTPlan> plan)
+{
+ m_specs.channels = reader->getSpecs().channels;
+ m_specs.rate = reader->getSpecs().rate;
+ int N = plan->getSize();
+ bool eos = false;
+ int length = reader->getLength();
+ sample_t* buffer = (sample_t*)std::malloc(length * m_specs.channels * sizeof(sample_t));
+ int numParts = std::ceil((float)length / (plan->getSize() / 2));
+
+ for(int i = 0; i < m_specs.channels; i++)
+ {
+ m_processedIR.push_back(std::make_shared<std::vector<std::shared_ptr<std::vector<std::complex<sample_t>>>>>());
+ for(int j = 0; j < numParts; j++)
+ (*m_processedIR[i]).push_back(std::make_shared<std::vector<std::complex<sample_t>>>((N / 2) + 1));
+ }
+ length += reader->getSpecs().rate;
+ reader->read(length, eos, buffer);
+
+
+ void* bufferFFT = plan->getBuffer();
+ for(int i = 0; i < m_specs.channels; i++)
+ {
+ int partStart = 0;
+ for(int h = 0; h < numParts; h++)
+ {
+ int k = 0;
+ int len = std::min(partStart + ((N / 2)*m_specs.channels), length*m_specs.channels);
+ std::memset(bufferFFT, 0, ((N / 2) + 1) * 2 * sizeof(fftwf_complex));
+ for(int j = partStart; j < len; j += m_specs.channels)
+ {
+ ((float*)bufferFFT)[k] = buffer[j + i];
+ k++;
+ }
+ plan->FFT(bufferFFT);
+ for(int j = 0; j < (N / 2) + 1; j++)
+ {
+ (*(*m_processedIR[i])[h])[j] = reinterpret_cast<std::complex<sample_t>*>(bufferFFT)[j];
+ }
+ partStart += N / 2 * m_specs.channels;
+ }
+ }
+ plan->freeBuffer(bufferFFT);
+ std::free(buffer);
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Limiter.cpp b/extern/audaspace/src/fx/Limiter.cpp
new file mode 100644
index 00000000000..38a7288e8d7
--- /dev/null
+++ b/extern/audaspace/src/fx/Limiter.cpp
@@ -0,0 +1,45 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Limiter.h"
+#include "fx/LimiterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Limiter::Limiter(std::shared_ptr<ISound> sound,
+ float start, float end) :
+ Effect(sound),
+ m_start(start),
+ m_end(end)
+{
+}
+
+float Limiter::getStart() const
+{
+ return m_start;
+}
+
+float Limiter::getEnd() const
+{
+ return m_end;
+}
+
+std::shared_ptr<IReader> Limiter::createReader()
+{
+ return std::shared_ptr<IReader>(new LimiterReader(getReader(), m_start, m_end));
+}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/extern/audaspace/src/fx/LimiterReader.cpp
index 7d850ac7b5f..1d003c29679 100644
--- a/intern/audaspace/FX/AUD_LimiterReader.cpp
+++ b/extern/audaspace/src/fx/LimiterReader.cpp
@@ -1,45 +1,35 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/FX/AUD_LimiterReader.cpp
- * \ingroup audfx
- */
+#include "fx/LimiterReader.h"
+#include "util/Buffer.h"
+#include <algorithm>
-#include "AUD_LimiterReader.h"
-#include "AUD_Buffer.h"
+AUD_NAMESPACE_BEGIN
-AUD_LimiterReader::AUD_LimiterReader(boost::shared_ptr<AUD_IReader> reader,
- float start, float end) :
- AUD_EffectReader(reader),
+LimiterReader::LimiterReader(std::shared_ptr<IReader> reader, float start, float end) :
+ EffectReader(reader),
m_start(start),
m_end(end)
{
if(m_start > 0)
{
- AUD_Specs specs = m_reader->getSpecs();
- AUD_Specs specs2;
+ Specs specs = m_reader->getSpecs();
+ Specs specs2;
if(m_reader->isSeekable())
m_reader->seek(m_start * specs.rate);
@@ -47,7 +37,7 @@ AUD_LimiterReader::AUD_LimiterReader(boost::shared_ptr<AUD_IReader> reader,
{
// skip first m_start samples by reading them
int length = AUD_DEFAULT_BUFFER_SIZE;
- AUD_Buffer buffer(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
+ Buffer buffer(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
bool eos = false;
for(int len = m_start * specs.rate;
length > 0 && !eos;
@@ -75,34 +65,34 @@ AUD_LimiterReader::AUD_LimiterReader(boost::shared_ptr<AUD_IReader> reader,
}
}
-void AUD_LimiterReader::seek(int position)
+void LimiterReader::seek(int position)
{
m_reader->seek(position + m_start * m_reader->getSpecs().rate);
}
-int AUD_LimiterReader::getLength() const
+int LimiterReader::getLength() const
{
int len = m_reader->getLength();
- AUD_SampleRate rate = m_reader->getSpecs().rate;
+ SampleRate rate = m_reader->getSpecs().rate;
if(len < 0 || (len > m_end * rate && m_end >= 0))
len = m_end * rate;
return len - m_start * rate;
}
-int AUD_LimiterReader::getPosition() const
+int LimiterReader::getPosition() const
{
int pos = m_reader->getPosition();
- AUD_SampleRate rate = m_reader->getSpecs().rate;
- return AUD_MIN(pos, m_end * rate) - m_start * rate;
+ SampleRate rate = m_reader->getSpecs().rate;
+ return std::min(pos, int(m_end * rate)) - m_start * rate;
}
-void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer)
+void LimiterReader::read(int& length, bool& eos, sample_t* buffer)
{
eos = false;
if(m_end >= 0)
{
int position = m_reader->getPosition();
- AUD_SampleRate rate = m_reader->getSpecs().rate;
+ SampleRate rate = m_reader->getSpecs().rate;
if(position + length > m_end * rate)
{
@@ -145,3 +135,5 @@ void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer)
else
m_reader->read(length, eos, buffer);
}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Loop.cpp b/extern/audaspace/src/fx/Loop.cpp
new file mode 100644
index 00000000000..1695fcf1662
--- /dev/null
+++ b/extern/audaspace/src/fx/Loop.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Loop.h"
+#include "fx/LoopReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Loop::Loop(std::shared_ptr<ISound> sound, int loop) :
+ Effect(sound),
+ m_loop(loop)
+{
+}
+
+int Loop::getLoop() const
+{
+ return m_loop;
+}
+
+std::shared_ptr<IReader> Loop::createReader()
+{
+ return std::shared_ptr<IReader>(new LoopReader(getReader(), m_loop));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/LoopReader.cpp b/extern/audaspace/src/fx/LoopReader.cpp
new file mode 100644
index 00000000000..2f13a5880eb
--- /dev/null
+++ b/extern/audaspace/src/fx/LoopReader.cpp
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/LoopReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+LoopReader::LoopReader(std::shared_ptr<IReader> reader, int loop) :
+ EffectReader(reader), m_count(loop), m_left(loop)
+{
+}
+
+void LoopReader::seek(int position)
+{
+ int len = m_reader->getLength();
+ if(len < 0)
+ m_reader->seek(position);
+ else
+ {
+ if(m_count >= 0)
+ {
+ m_left = m_count - (position / len);
+ if(m_left < 0)
+ m_left = 0;
+ }
+ m_reader->seek(position % len);
+ }
+}
+
+int LoopReader::getLength() const
+{
+ if(m_count < 0)
+ return -1;
+ return m_reader->getLength() * m_count;
+}
+
+int LoopReader::getPosition() const
+{
+ return m_reader->getPosition() * (m_count < 0 ? 1 : m_count);
+}
+
+void LoopReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ const Specs specs = m_reader->getSpecs();
+
+ int len = length;
+
+ m_reader->read(length, eos, buffer);
+
+ if(length < len && eos && m_left)
+ {
+ int pos = length;
+ length = len;
+
+ while(pos < length && eos && m_left)
+ {
+ if(m_left > 0)
+ m_left--;
+
+ m_reader->seek(0);
+
+ len = length - pos;
+ m_reader->read(len, eos, buffer + pos * specs.channels);
+
+ // prevent endless loop
+ if(!len)
+ break;
+
+ pos += len;
+ }
+
+ length = pos;
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Lowpass.cpp b/extern/audaspace/src/fx/Lowpass.cpp
new file mode 100644
index 00000000000..8c33291baa3
--- /dev/null
+++ b/extern/audaspace/src/fx/Lowpass.cpp
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Lowpass.h"
+#include "fx/LowpassCalculator.h"
+
+AUD_NAMESPACE_BEGIN
+
+Lowpass::Lowpass(std::shared_ptr<ISound> sound, float frequency, float Q) :
+ DynamicIIRFilter(sound, std::shared_ptr<IDynamicIIRFilterCalculator>(new LowpassCalculator(frequency, Q)))
+{
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/LowpassCalculator.cpp b/extern/audaspace/src/fx/LowpassCalculator.cpp
new file mode 100644
index 00000000000..f2a53ed7514
--- /dev/null
+++ b/extern/audaspace/src/fx/LowpassCalculator.cpp
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/LowpassCalculator.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+LowpassCalculator::LowpassCalculator(float frequency, float Q) :
+ m_frequency(frequency),
+ m_Q(Q)
+{
+}
+
+void LowpassCalculator::recalculateCoefficients(SampleRate rate, std::vector<float> &b, std::vector<float> &a)
+{
+ float w0 = 2 * M_PI * m_frequency / rate;
+ float alpha = std::sin(w0) / (2 * m_Q);
+ float norm = 1 + alpha;
+ float c = std::cos(w0);
+ a.push_back(1);
+ a.push_back(-2 * c / norm);
+ a.push_back((1 - alpha) / norm);
+ b.push_back((1 - c) / (2 * norm));
+ b.push_back((1 - c) / norm);
+ b.push_back(b[0]);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/MutableReader.cpp b/extern/audaspace/src/fx/MutableReader.cpp
new file mode 100644
index 00000000000..aa867d83f03
--- /dev/null
+++ b/extern/audaspace/src/fx/MutableReader.cpp
@@ -0,0 +1,64 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/MutableReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+MutableReader::MutableReader(std::shared_ptr<ISound> sound) :
+m_sound(sound)
+{
+ m_reader = m_sound->createReader();
+}
+
+bool MutableReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void MutableReader::seek(int position)
+{
+ if(position < m_reader->getPosition())
+ {
+ m_reader = m_sound->createReader();
+ }
+ else
+ m_reader->seek(position);
+}
+
+int MutableReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int MutableReader::getPosition() const
+{
+ return m_reader->getPosition();
+}
+
+Specs MutableReader::getSpecs() const
+{
+ return m_reader->getSpecs();
+}
+
+void MutableReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ m_reader->read(length, eos, buffer);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/MutableSound.cpp b/extern/audaspace/src/fx/MutableSound.cpp
new file mode 100644
index 00000000000..5326b640394
--- /dev/null
+++ b/extern/audaspace/src/fx/MutableSound.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/MutableSound.h"
+#include "fx/MutableReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+MutableSound::MutableSound(std::shared_ptr<ISound> sound) :
+m_sound(sound)
+{
+}
+
+std::shared_ptr<IReader> MutableSound::createReader()
+{
+ return std::make_shared<MutableReader>(m_sound);
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/Pitch.cpp b/extern/audaspace/src/fx/Pitch.cpp
new file mode 100644
index 00000000000..d7348a2d49e
--- /dev/null
+++ b/extern/audaspace/src/fx/Pitch.cpp
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Pitch.h"
+#include "fx/PitchReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Pitch::Pitch(std::shared_ptr<ISound> sound, float pitch) :
+ Effect(sound),
+ m_pitch(pitch)
+{
+}
+
+std::shared_ptr<IReader> Pitch::createReader()
+{
+ return std::shared_ptr<IReader>(new PitchReader(getReader(), m_pitch));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/PitchReader.cpp b/extern/audaspace/src/fx/PitchReader.cpp
new file mode 100644
index 00000000000..f44be0261e6
--- /dev/null
+++ b/extern/audaspace/src/fx/PitchReader.cpp
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/PitchReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+PitchReader::PitchReader(std::shared_ptr<IReader> reader, float pitch) :
+ EffectReader(reader), m_pitch(pitch)
+{
+}
+
+Specs PitchReader::getSpecs() const
+{
+ Specs specs = m_reader->getSpecs();
+ specs.rate *= m_pitch;
+ return specs;
+}
+
+float PitchReader::getPitch() const
+{
+ return m_pitch;
+}
+
+void PitchReader::setPitch(float pitch)
+{
+ if(pitch > 0.0f)
+ m_pitch = pitch;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/PlaybackCategory.cpp b/extern/audaspace/src/fx/PlaybackCategory.cpp
new file mode 100644
index 00000000000..e09a74c4017
--- /dev/null
+++ b/extern/audaspace/src/fx/PlaybackCategory.cpp
@@ -0,0 +1,144 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/PlaybackCategory.h"
+#include "fx/VolumeSound.h"
+
+AUD_NAMESPACE_BEGIN
+
+struct HandleData {
+ unsigned int id;
+ PlaybackCategory* category;
+};
+
+PlaybackCategory::PlaybackCategory(std::shared_ptr<IDevice> device) :
+ m_device(device), m_volumeStorage(std::make_shared<VolumeStorage>(1.0f)), m_status(STATUS_PLAYING), m_currentID(0)
+{
+}
+
+PlaybackCategory::~PlaybackCategory()
+{
+ stop();
+}
+
+std::shared_ptr<IHandle> PlaybackCategory::play(std::shared_ptr<ISound> sound)
+{
+ std::shared_ptr<ISound> vs(std::make_shared<VolumeSound>(sound, m_volumeStorage));
+ m_device->lock();
+ auto handle = m_device->play(vs);
+ if(handle == nullptr)
+ return nullptr;
+ switch (m_status)
+ {
+ case STATUS_PAUSED:
+ handle->pause();
+ break;
+ default:
+ m_status = STATUS_PLAYING;
+ };
+ m_handles[m_currentID] = handle;
+ HandleData* data = new HandleData;
+ data->category = this;
+ data->id = m_currentID;
+ handle->setStopCallback(cleanHandleCallback, data);
+ m_device->unlock();
+
+ m_currentID++;
+ return handle;
+}
+
+void PlaybackCategory::resume()
+{
+ m_device->lock();
+ for(auto i = m_handles.begin(); i != m_handles.end();)
+ {
+ if(i->second->getStatus() == STATUS_INVALID)
+ i = m_handles.erase(i);
+ else
+ {
+ i->second->resume();
+ i++;
+ }
+ }
+ m_device->unlock();
+ m_status = STATUS_PLAYING;
+}
+
+void PlaybackCategory::pause()
+{
+ m_device->lock();
+ for(auto i = m_handles.begin(); i != m_handles.end();)
+ {
+ if(i->second->getStatus() == STATUS_INVALID)
+ i = m_handles.erase(i);
+ else
+ {
+ i->second->pause();
+ i++;
+ }
+ }
+ m_device->unlock();
+ m_status = STATUS_PAUSED;
+}
+
+float PlaybackCategory::getVolume()
+{
+ return m_volumeStorage->getVolume();
+}
+
+void PlaybackCategory::setVolume(float volume)
+{
+ m_volumeStorage->setVolume(volume);
+}
+
+void PlaybackCategory::stop()
+{
+ m_device->lock();
+ for(auto i = m_handles.begin(); i != m_handles.end();)
+ {
+ i->second->stop();
+ if(i->second->getStatus() == STATUS_INVALID)
+ i = m_handles.erase(i);
+ else
+ i++;
+ }
+ m_device->unlock();
+ m_status = STATUS_STOPPED;
+}
+
+std::shared_ptr<VolumeStorage> PlaybackCategory::getSharedVolume()
+{
+ return m_volumeStorage;
+}
+
+void PlaybackCategory::cleanHandles()
+{
+ for(auto i = m_handles.begin(); i != m_handles.end();)
+ {
+ if(i->second->getStatus() == STATUS_INVALID)
+ i = m_handles.erase(i);
+ else
+ i++;
+ }
+}
+
+void PlaybackCategory::cleanHandleCallback(void* data)
+{
+ auto dat = reinterpret_cast<HandleData*>(data);
+ dat->category->m_handles.erase(dat->id);
+ delete dat;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/PlaybackManager.cpp b/extern/audaspace/src/fx/PlaybackManager.cpp
new file mode 100644
index 00000000000..0fbeeba04e2
--- /dev/null
+++ b/extern/audaspace/src/fx/PlaybackManager.cpp
@@ -0,0 +1,186 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/PlaybackManager.h"
+#include "fx/VolumeSound.h"
+
+#include <stdexcept>
+
+AUD_NAMESPACE_BEGIN
+PlaybackManager::PlaybackManager(std::shared_ptr<IDevice> device) :
+ m_device(device), m_currentKey(0)
+{
+}
+
+unsigned int PlaybackManager::addCategory(std::shared_ptr<PlaybackCategory> category)
+{
+ bool flag = true;
+ unsigned int k = -1;
+ do {
+ auto iter = m_categories.find(m_currentKey);
+ if(iter == m_categories.end())
+ {
+ m_categories[m_currentKey] = category;
+ k = m_currentKey;
+ m_currentKey++;
+ flag = false;
+ }
+ else
+ m_currentKey++;
+ } while(flag);
+
+ return k;
+}
+
+unsigned int PlaybackManager::addCategory(float volume)
+{
+ std::shared_ptr<PlaybackCategory> category = std::make_shared<PlaybackCategory>(m_device);
+ category->setVolume(volume);
+ bool flag = true;
+ unsigned int k = -1;
+ do {
+ auto iter = m_categories.find(m_currentKey);
+ if(iter == m_categories.end())
+ {
+ m_categories[m_currentKey] = category;
+ k = m_currentKey;
+ m_currentKey++;
+ flag = false;
+ }
+ else
+ m_currentKey++;
+ } while(flag);
+
+ return k;
+}
+
+std::shared_ptr<IHandle> PlaybackManager::play(std::shared_ptr<ISound> sound, unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+ std::shared_ptr<PlaybackCategory> category;
+
+ if(iter != m_categories.end())
+ {
+ category = iter->second;
+ }
+ else
+ {
+ category = std::make_shared<PlaybackCategory>(m_device);
+ m_categories[catKey] = category;
+ }
+ return category->play(sound);
+}
+
+bool PlaybackManager::resume(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->resume();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool PlaybackManager::pause(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->pause();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+float PlaybackManager::getVolume(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ return iter->second->getVolume();
+ }
+ else
+ {
+ return -1.0;
+ }
+}
+
+bool PlaybackManager::setVolume(float volume, unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->setVolume(volume);
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+bool PlaybackManager::stop(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->stop();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+void PlaybackManager::clean()
+{
+ for(auto cat : m_categories)
+ cat.second->cleanHandles();
+}
+
+bool PlaybackManager::clean(unsigned int catKey)
+{
+ auto iter = m_categories.find(catKey);
+
+ if(iter != m_categories.end())
+ {
+ iter->second->cleanHandles();
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+std::shared_ptr<IDevice> PlaybackManager::getDevice()
+{
+ return m_device;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Reverse.cpp b/extern/audaspace/src/fx/Reverse.cpp
new file mode 100644
index 00000000000..7d906056071
--- /dev/null
+++ b/extern/audaspace/src/fx/Reverse.cpp
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Reverse.h"
+#include "fx/ReverseReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Reverse::Reverse(std::shared_ptr<ISound> sound) :
+ Effect(sound)
+{
+}
+
+std::shared_ptr<IReader> Reverse::createReader()
+{
+ return std::shared_ptr<IReader>(new ReverseReader(getReader()));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/ReverseReader.cpp b/extern/audaspace/src/fx/ReverseReader.cpp
new file mode 100644
index 00000000000..19a1e25ce4f
--- /dev/null
+++ b/extern/audaspace/src/fx/ReverseReader.cpp
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/ReverseReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+ReverseReader::ReverseReader(std::shared_ptr<IReader> reader) :
+ EffectReader(reader),
+ m_length(reader->getLength()),
+ m_position(0)
+{
+ if(m_length < 0 || !reader->isSeekable())
+ AUD_THROW(StateException, "A reader has to be seekable and have finite length to be reversible.");
+}
+
+void ReverseReader::seek(int position)
+{
+ m_position = position;
+}
+
+int ReverseReader::getLength() const
+{
+ return m_length;
+}
+
+int ReverseReader::getPosition() const
+{
+ return m_position;
+}
+
+void ReverseReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ // first correct the length
+ if(m_position + length > m_length)
+ length = m_length - m_position;
+
+ if(length <= 0)
+ {
+ length = 0;
+ eos = true;
+ return;
+ }
+
+ const Specs specs = getSpecs();
+ const int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ sample_t temp[CHANNEL_MAX];
+
+ int len = length;
+
+ // read from reader
+ m_reader->seek(m_length - m_position - len);
+ m_reader->read(len, eos, buffer);
+
+ // set null if reader didn't give enough data
+ if(len < length)
+ std::memset(buffer, 0, (length - len) * samplesize);
+
+ // copy the samples reverted
+ for(int i = 0; i < length / 2; i++)
+ {
+ std::memcpy(temp, buffer + (len - 1 - i) * specs.channels, samplesize);
+ std::memcpy(buffer + (len - 1 - i) * specs.channels, buffer + i * specs.channels, samplesize);
+ std::memcpy(buffer + i * specs.channels, temp, samplesize);
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/SoundList.cpp b/extern/audaspace/src/fx/SoundList.cpp
new file mode 100644
index 00000000000..81239ca5baa
--- /dev/null
+++ b/extern/audaspace/src/fx/SoundList.cpp
@@ -0,0 +1,84 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/SoundList.h"
+#include "Exception.h"
+
+#include <cstring>
+#include <cstdlib>
+#include <chrono>
+
+AUD_NAMESPACE_BEGIN
+
+SoundList::SoundList(bool random) :
+m_random(random)
+{
+ std::srand(time(NULL));
+}
+
+SoundList::SoundList(std::vector<std::shared_ptr<ISound>>& list, bool random) :
+m_list(list), m_random(random)
+{
+ std::srand(time(NULL));
+}
+
+std::shared_ptr<IReader> SoundList::createReader()
+{
+ if(m_list.size() > 0)
+ {
+ m_mutex.lock();
+
+ if(!m_random){
+ m_index++;
+ if(m_index >= m_list.size())
+ m_index = 0;
+ }
+ else
+ {
+ int temp;
+ do{
+ temp = std::rand() % m_list.size();
+ } while(temp == m_index && m_list.size()>1);
+ m_index = temp;
+ }
+ auto reader = m_list[m_index]->createReader();
+ m_mutex.unlock();
+ return reader;
+ }
+ else
+ AUD_THROW(FileException, "The sound list is empty");
+}
+
+void SoundList::addSound(std::shared_ptr<ISound> sound)
+{
+ m_list.push_back(sound);
+}
+
+void SoundList::setRandomMode(bool random)
+{
+ m_random = random;
+}
+
+bool SoundList::getRandomMode()
+{
+ return m_random;
+}
+
+int SoundList::getSize()
+{
+ return m_list.size();
+}
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/Source.cpp b/extern/audaspace/src/fx/Source.cpp
new file mode 100644
index 00000000000..354ed69674b
--- /dev/null
+++ b/extern/audaspace/src/fx/Source.cpp
@@ -0,0 +1,71 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/Source.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+Source::Source(float azimuth, float elevation, float distance) :
+ m_elevation(elevation), m_distance(distance)
+{
+ azimuth = std::fmod(azimuth, 360);
+ if(azimuth < 0)
+ azimuth += 360;
+ m_azimuth = azimuth;
+}
+
+float Source::getAzimuth()
+{
+ return m_azimuth;
+}
+
+float Source::getElevation()
+{
+ return m_elevation;
+}
+
+float Source::getDistance()
+{
+ return m_distance;
+}
+
+float Source::getVolume()
+{
+ float volume = 1.0f - m_distance;
+ if(volume < 0.0f)
+ volume = 0.0f;
+ return volume;
+}
+
+void Source::setAzimuth(float azimuth)
+{
+ azimuth = std::fmod(azimuth, 360);
+ if(azimuth < 0)
+ azimuth += 360;
+ m_azimuth = azimuth;
+}
+
+void Source::setElevation(float elevation)
+{
+ m_elevation = elevation;
+}
+
+void Source::setDistance(float distance)
+{
+ m_distance = distance;
+}
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/Sum.cpp b/extern/audaspace/src/fx/Sum.cpp
new file mode 100644
index 00000000000..306bc5de953
--- /dev/null
+++ b/extern/audaspace/src/fx/Sum.cpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Sum.h"
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Sum::Sum(std::shared_ptr<ISound> sound) :
+ Effect(sound)
+{
+}
+
+std::shared_ptr<IReader> Sum::createReader()
+{
+ std::vector<float> a, b;
+ a.push_back(1);
+ a.push_back(-1);
+ b.push_back(1);
+ return std::shared_ptr<IReader>(new IIRFilterReader(getReader(), b, a));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Threshold.cpp b/extern/audaspace/src/fx/Threshold.cpp
new file mode 100644
index 00000000000..03c4ae4c8a5
--- /dev/null
+++ b/extern/audaspace/src/fx/Threshold.cpp
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Threshold.h"
+#include "fx/CallbackIIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+sample_t Threshold::thresholdFilter(CallbackIIRFilterReader* reader, float* threshold)
+{
+ float in = reader->x(0);
+ if(in >= *threshold)
+ return 1;
+ else if(in <= -*threshold)
+ return -1;
+ else
+ return 0;
+}
+
+void Threshold::endThresholdFilter(float* threshold)
+{
+ delete threshold;
+}
+
+Threshold::Threshold(std::shared_ptr<ISound> sound, float threshold) :
+ Effect(sound),
+ m_threshold(threshold)
+{
+}
+
+float Threshold::getThreshold() const
+{
+ return m_threshold;
+}
+
+std::shared_ptr<IReader> Threshold::createReader()
+{
+ return std::shared_ptr<IReader>(new CallbackIIRFilterReader(getReader(), 1, 0, doFilterIIR(thresholdFilter), endFilterIIR(endThresholdFilter), new float(m_threshold)));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/Volume.cpp b/extern/audaspace/src/fx/Volume.cpp
new file mode 100644
index 00000000000..231f5856a6c
--- /dev/null
+++ b/extern/audaspace/src/fx/Volume.cpp
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "fx/Volume.h"
+#include "fx/IIRFilterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Volume::Volume(std::shared_ptr<ISound> sound, float volume) :
+ Effect(sound),
+ m_volume(volume)
+{
+}
+
+float Volume::getVolume() const
+{
+ return m_volume;
+}
+
+std::shared_ptr<IReader> Volume::createReader()
+{
+ std::vector<float> a, b;
+ a.push_back(1);
+ b.push_back(m_volume);
+ return std::shared_ptr<IReader>(new IIRFilterReader(getReader(), b, a));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/fx/VolumeReader.cpp b/extern/audaspace/src/fx/VolumeReader.cpp
new file mode 100644
index 00000000000..ac1d4882a87
--- /dev/null
+++ b/extern/audaspace/src/fx/VolumeReader.cpp
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/VolumeReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+VolumeReader::VolumeReader(std::shared_ptr<IReader> reader, std::shared_ptr<VolumeStorage> volumeStorage) :
+ m_reader(reader), m_volumeStorage(volumeStorage)
+{
+}
+
+bool VolumeReader::isSeekable() const
+{
+ return m_reader->isSeekable();
+}
+
+void VolumeReader::seek(int position)
+{
+ m_reader->seek(position);
+}
+
+int VolumeReader::getLength() const
+{
+ return m_reader->getLength();
+}
+
+int VolumeReader::getPosition() const
+{
+ return m_reader->getPosition();
+}
+
+Specs VolumeReader::getSpecs() const
+{
+ return m_reader->getSpecs();
+}
+
+void VolumeReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ m_reader->read(length, eos, buffer);
+ for(int i = 0; i < length * m_reader->getSpecs().channels; i++)
+ buffer[i] = buffer[i] * m_volumeStorage->getVolume();
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/VolumeSound.cpp b/extern/audaspace/src/fx/VolumeSound.cpp
new file mode 100644
index 00000000000..b7f96225682
--- /dev/null
+++ b/extern/audaspace/src/fx/VolumeSound.cpp
@@ -0,0 +1,45 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/VolumeSound.h"
+#include "fx/VolumeReader.h"
+#include "Exception.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+VolumeSound::VolumeSound(std::shared_ptr<ISound> sound, std::shared_ptr<VolumeStorage> volumeStorage) :
+ m_sound(sound), m_volumeStorage(volumeStorage)
+{
+}
+
+std::shared_ptr<IReader> VolumeSound::createReader()
+{
+ return std::make_shared<VolumeReader>(m_sound->createReader(), m_volumeStorage);
+}
+
+std::shared_ptr<VolumeStorage> VolumeSound::getSharedVolume()
+{
+ return m_volumeStorage;
+}
+
+void VolumeSound::setSharedVolume(std::shared_ptr<VolumeStorage> volumeStorage)
+{
+ m_volumeStorage = volumeStorage;
+}
+
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/fx/VolumeStorage.cpp b/extern/audaspace/src/fx/VolumeStorage.cpp
new file mode 100644
index 00000000000..4c5164d0ea1
--- /dev/null
+++ b/extern/audaspace/src/fx/VolumeStorage.cpp
@@ -0,0 +1,39 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "fx/VolumeStorage.h"
+
+AUD_NAMESPACE_BEGIN
+VolumeStorage::VolumeStorage() :
+ m_volume(1.0f)
+{
+}
+
+VolumeStorage::VolumeStorage(float volume) :
+ m_volume(volume)
+{
+}
+
+float VolumeStorage::getVolume()
+{
+ return m_volume;
+}
+
+void VolumeStorage::setVolume(float volume)
+{
+ m_volume = volume;
+}
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Sawtooth.cpp b/extern/audaspace/src/generator/Sawtooth.cpp
new file mode 100644
index 00000000000..f5acad44839
--- /dev/null
+++ b/extern/audaspace/src/generator/Sawtooth.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/Sawtooth.h"
+#include "generator/SawtoothReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Sawtooth::Sawtooth(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_sampleRate(sampleRate)
+{
+}
+
+float Sawtooth::getFrequency() const
+{
+ return m_frequency;
+}
+
+std::shared_ptr<IReader> Sawtooth::createReader()
+{
+ return std::shared_ptr<IReader>(new SawtoothReader(m_frequency, m_sampleRate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/SawtoothReader.cpp b/extern/audaspace/src/generator/SawtoothReader.cpp
new file mode 100644
index 00000000000..3664b8d3b61
--- /dev/null
+++ b/extern/audaspace/src/generator/SawtoothReader.cpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/SawtoothReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+SawtoothReader::SawtoothReader(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_position(0),
+ m_sample(0),
+ m_sampleRate(sampleRate)
+{
+}
+
+void SawtoothReader::setFrequency(float frequency)
+{
+ m_frequency = frequency;
+}
+
+bool SawtoothReader::isSeekable() const
+{
+ return true;
+}
+
+void SawtoothReader::seek(int position)
+{
+ m_position = position;
+ m_sample = std::fmod(m_position * m_frequency / (float)m_sampleRate + 1.0f, 2.0f) - 1.0f;
+}
+
+int SawtoothReader::getLength() const
+{
+ return -1;
+}
+
+int SawtoothReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SawtoothReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = m_sampleRate;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void SawtoothReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ float k = 2.0 * m_frequency / m_sampleRate;
+
+ for(int i = 0; i < length; i++)
+ {
+ m_sample += k;
+
+ if(m_sample >= 1.0f)
+ m_sample -= std::floor(m_sample) + 1.0f;
+
+ buffer[i] = m_sample;
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Silence.cpp b/extern/audaspace/src/generator/Silence.cpp
new file mode 100644
index 00000000000..a173a1bc5f6
--- /dev/null
+++ b/extern/audaspace/src/generator/Silence.cpp
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/Silence.h"
+#include "generator/SilenceReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Silence::Silence()
+{
+}
+
+std::shared_ptr<IReader> Silence::createReader()
+{
+ return std::shared_ptr<IReader>(new SilenceReader());
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/SilenceReader.cpp b/extern/audaspace/src/generator/SilenceReader.cpp
new file mode 100644
index 00000000000..39358cc087a
--- /dev/null
+++ b/extern/audaspace/src/generator/SilenceReader.cpp
@@ -0,0 +1,63 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/SilenceReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+SilenceReader::SilenceReader() :
+ m_position(0)
+{
+}
+
+bool SilenceReader::isSeekable() const
+{
+ return true;
+}
+
+void SilenceReader::seek(int position)
+{
+ m_position = position;
+}
+
+int SilenceReader::getLength() const
+{
+ return -1;
+}
+
+int SilenceReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SilenceReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = RATE_48000;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void SilenceReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ std::memset(buffer, 0, length * sizeof(sample_t));
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Sine.cpp b/extern/audaspace/src/generator/Sine.cpp
new file mode 100644
index 00000000000..b7cdc132df6
--- /dev/null
+++ b/extern/audaspace/src/generator/Sine.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/Sine.h"
+#include "generator/SineReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Sine::Sine(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_sampleRate(sampleRate)
+{
+}
+
+float Sine::getFrequency() const
+{
+ return m_frequency;
+}
+
+std::shared_ptr<IReader> Sine::createReader()
+{
+ return std::shared_ptr<IReader>(new SineReader(m_frequency, m_sampleRate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/SineReader.cpp b/extern/audaspace/src/generator/SineReader.cpp
new file mode 100644
index 00000000000..49b7cc3114b
--- /dev/null
+++ b/extern/audaspace/src/generator/SineReader.cpp
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/SineReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+SineReader::SineReader(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_position(0),
+ m_sampleRate(sampleRate)
+{
+}
+
+void SineReader::setFrequency(float frequency)
+{
+ m_frequency = frequency;
+}
+
+bool SineReader::isSeekable() const
+{
+ return true;
+}
+
+void SineReader::seek(int position)
+{
+ m_position = position;
+}
+
+int SineReader::getLength() const
+{
+ return -1;
+}
+
+int SineReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SineReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = m_sampleRate;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void SineReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ // fill with sine data
+ for(int i = 0; i < length; i++)
+ {
+ buffer[i] = std::sin((m_position + i) * 2 * M_PI * m_frequency / m_sampleRate);
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Square.cpp b/extern/audaspace/src/generator/Square.cpp
new file mode 100644
index 00000000000..361c243c549
--- /dev/null
+++ b/extern/audaspace/src/generator/Square.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/Square.h"
+#include "generator/SquareReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Square::Square(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_sampleRate(sampleRate)
+{
+}
+
+float Square::getFrequency() const
+{
+ return m_frequency;
+}
+
+std::shared_ptr<IReader> Square::createReader()
+{
+ return std::shared_ptr<IReader>(new SquareReader(m_frequency, m_sampleRate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/SquareReader.cpp b/extern/audaspace/src/generator/SquareReader.cpp
new file mode 100644
index 00000000000..8f49b097487
--- /dev/null
+++ b/extern/audaspace/src/generator/SquareReader.cpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/SquareReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+SquareReader::SquareReader(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_position(0),
+ m_sample(0),
+ m_sampleRate(sampleRate)
+{
+}
+
+void SquareReader::setFrequency(float frequency)
+{
+ m_frequency = frequency;
+}
+
+bool SquareReader::isSeekable() const
+{
+ return true;
+}
+
+void SquareReader::seek(int position)
+{
+ m_position = position;
+ m_sample = std::fmod(m_position * m_frequency / (float)m_sampleRate, 2.0f);
+}
+
+int SquareReader::getLength() const
+{
+ return -1;
+}
+
+int SquareReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SquareReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = m_sampleRate;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void SquareReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ float k = 2.0 * m_frequency / m_sampleRate;
+
+ for(int i = 0; i < length; i++)
+ {
+ m_sample += k;
+
+ if(m_sample >= 2.0f)
+ m_sample = std::fmod(m_sample, 2.0f);
+
+ buffer[i] = (m_sample < 1.0f) * 2.0f - 1.0f;
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/Triangle.cpp b/extern/audaspace/src/generator/Triangle.cpp
new file mode 100644
index 00000000000..ca8f1b63fb9
--- /dev/null
+++ b/extern/audaspace/src/generator/Triangle.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/Triangle.h"
+#include "generator/TriangleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Triangle::Triangle(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_sampleRate(sampleRate)
+{
+}
+
+float Triangle::getFrequency() const
+{
+ return m_frequency;
+}
+
+std::shared_ptr<IReader> Triangle::createReader()
+{
+ return std::shared_ptr<IReader>(new TriangleReader(m_frequency, m_sampleRate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/generator/TriangleReader.cpp b/extern/audaspace/src/generator/TriangleReader.cpp
new file mode 100644
index 00000000000..c363d3850ca
--- /dev/null
+++ b/extern/audaspace/src/generator/TriangleReader.cpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "generator/TriangleReader.h"
+
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+TriangleReader::TriangleReader(float frequency, SampleRate sampleRate) :
+ m_frequency(frequency),
+ m_position(0),
+ m_sample(0.5f),
+ m_sampleRate(sampleRate)
+{
+}
+
+void TriangleReader::setFrequency(float frequency)
+{
+ m_frequency = frequency;
+}
+
+bool TriangleReader::isSeekable() const
+{
+ return true;
+}
+
+void TriangleReader::seek(int position)
+{
+ m_position = position;
+ m_sample = std::fmod(m_position * m_frequency / (float)m_sampleRate + 1.5f, 2.0f) - 1.0f;
+}
+
+int TriangleReader::getLength() const
+{
+ return -1;
+}
+
+int TriangleReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs TriangleReader::getSpecs() const
+{
+ Specs specs;
+ specs.rate = m_sampleRate;
+ specs.channels = CHANNELS_MONO;
+ return specs;
+}
+
+void TriangleReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ float k = 2.0 * m_frequency / m_sampleRate;
+
+ for(int i = 0; i < length; i++)
+ {
+ m_sample += k;
+
+ if(m_sample >= 1.0f)
+ m_sample -= std::floor(m_sample) + 1.0f;
+
+ buffer[i] = std::fabs(m_sample) * 2.0f - 1.0f;
+ }
+
+ m_position += length;
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/plugin/PluginManagerUnix.cpp.in b/extern/audaspace/src/plugin/PluginManagerUnix.cpp.in
new file mode 100644
index 00000000000..d08804bc2e7
--- /dev/null
+++ b/extern/audaspace/src/plugin/PluginManagerUnix.cpp.in
@@ -0,0 +1,98 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "plugin/PluginManager.h"
+
+#include <dlfcn.h>
+#include <dirent.h>
+
+AUD_NAMESPACE_BEGIN
+
+std::unordered_map<std::string, void*> PluginManager::m_plugins;
+
+void* PluginManager::openLibrary(const std::string& path)
+{
+ return dlopen(path.c_str(), RTLD_LAZY);
+}
+
+void *PluginManager::lookupLibrary(void *handle, const std::string &name)
+{
+ return dlsym(handle, name.c_str());
+}
+
+void PluginManager::closeLibrary(void *handle)
+{
+ dlclose(handle);
+}
+
+bool PluginManager::loadPlugin(const std::string& path)
+{
+ void* handle = openLibrary(path);
+
+ if (!handle)
+ return false;
+
+ void (*registerPlugin)() = (void (*)())lookupLibrary(handle, "registerPlugin");
+ const char* (*getName)() = (const char* (*)())lookupLibrary(handle, "getName");
+
+ if(!registerPlugin || !getName)
+ {
+ closeLibrary(handle);
+ return false;
+ }
+
+ registerPlugin();
+
+ m_plugins[getName()] = handle;
+
+ return true;
+}
+
+#define STATIC_PLUGIN_CLASS(name) class name { public: static void registerPlugin(); };
+#define STATIC_PLUGIN_REGISTER(name) name::registerPlugin();
+
+@STATIC_PLUGIN_CLASSES@
+
+void PluginManager::loadPlugins(const std::string& path)
+{
+@STATIC_PLUGIN_REGISTERS@
+
+ std::string readpath = path;
+
+ if(path == "")
+ readpath = "@DEFAULT_PLUGIN_PATH@";
+
+ DIR* dir = opendir(readpath.c_str());
+
+ if(!dir)
+ return;
+
+ while(dirent* entry = readdir(dir))
+ {
+ const std::string filename = entry->d_name;
+ const std::string end = ".so";
+
+ if(filename.length() >= end.length() && filename.substr(filename.length() - end.length()) == end)
+ {
+ if(!loadPlugin(readpath + "/" + filename + ".@AUDASPACE_VERSION@"))
+ loadPlugin(readpath + "/" + filename);
+ }
+ }
+
+ closedir(dir);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/plugin/PluginManagerWindows.cpp.in b/extern/audaspace/src/plugin/PluginManagerWindows.cpp.in
new file mode 100644
index 00000000000..62350fd24fd
--- /dev/null
+++ b/extern/audaspace/src/plugin/PluginManagerWindows.cpp.in
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "plugin/PluginManager.h"
+
+#include <windows.h>
+
+AUD_NAMESPACE_BEGIN
+
+std::unordered_map<std::string, void*> PluginManager::m_plugins;
+
+void* PluginManager::openLibrary(const std::string& path)
+{
+ return reinterpret_cast<void*>(LoadLibrary(path.c_str()));
+}
+
+void *PluginManager::lookupLibrary(void *handle, const std::string &name)
+{
+ return GetProcAddress(reinterpret_cast<HMODULE>(handle), name.c_str());
+}
+
+void PluginManager::closeLibrary(void *handle)
+{
+ FreeLibrary(reinterpret_cast<HMODULE>(handle));
+}
+
+bool PluginManager::loadPlugin(const std::string& path)
+{
+ void* handle = openLibrary(path);
+
+ if (!handle)
+ return false;
+
+ void (*registerPlugin)() = (void (*)())lookupLibrary(handle, "registerPlugin");
+ const char* (*getName)() = (const char* (*)())lookupLibrary(handle, "getName");
+
+ if(!registerPlugin || !getName)
+ {
+ closeLibrary(handle);
+ return false;
+ }
+
+ registerPlugin();
+
+ m_plugins[getName()] = handle;
+
+ return true;
+}
+
+#define STATIC_PLUGIN_CLASS(name) class name { public: static void registerPlugin(); };
+#define STATIC_PLUGIN_REGISTER(name) name::registerPlugin();
+
+@STATIC_PLUGIN_CLASSES@
+
+void PluginManager::loadPlugins(const std::string& path)
+{
+@STATIC_PLUGIN_REGISTERS@
+
+ std::string readpath = path;
+
+ if(path == "")
+ readpath = "@DEFAULT_PLUGIN_PATH@";
+
+ WIN32_FIND_DATA entry;
+ bool found_file = true;
+ std::string search = readpath + "\\*";
+ HANDLE dir = FindFirstFile(search.c_str(), &entry);
+
+ if(dir == INVALID_HANDLE_VALUE)
+ return;
+
+ while(found_file)
+ {
+ const std::string filename = entry.cFileName;
+ const std::string end = ".dll";
+
+ if(filename.length() >= end.length() && filename.substr(filename.length() - end.length()) == end)
+ {
+ loadPlugin(readpath + "/" + filename);
+ }
+
+ found_file = FindNextFile(dir, &entry);
+ }
+
+ FindClose(dir);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ChannelMapper.cpp b/extern/audaspace/src/respec/ChannelMapper.cpp
new file mode 100644
index 00000000000..e6e214598cb
--- /dev/null
+++ b/extern/audaspace/src/respec/ChannelMapper.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/ChannelMapper.h"
+#include "respec/ChannelMapperReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+ChannelMapper::ChannelMapper(std::shared_ptr<ISound> sound, DeviceSpecs specs) :
+ SpecsChanger(sound, specs)
+{
+}
+
+std::shared_ptr<IReader> ChannelMapper::createReader()
+{
+ std::shared_ptr<IReader> reader = getReader();
+ return std::shared_ptr<IReader>(new ChannelMapperReader(reader, m_specs.channels));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ChannelMapperReader.cpp b/extern/audaspace/src/respec/ChannelMapperReader.cpp
new file mode 100644
index 00000000000..850e54b73cf
--- /dev/null
+++ b/extern/audaspace/src/respec/ChannelMapperReader.cpp
@@ -0,0 +1,379 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/ChannelMapperReader.h"
+
+#include <cmath>
+#include <limits>
+
+AUD_NAMESPACE_BEGIN
+
+ChannelMapperReader::ChannelMapperReader(std::shared_ptr<IReader> reader,
+ Channels channels) :
+ EffectReader(reader), m_target_channels(channels),
+ m_source_channels(CHANNELS_INVALID), m_mapping(nullptr), m_map_size(0), m_mono_angle(0)
+{
+}
+
+ChannelMapperReader::~ChannelMapperReader()
+{
+ delete[] m_mapping;
+}
+
+Channels ChannelMapperReader::getSourceChannels() const
+{
+ return m_reader->getSpecs().channels;
+}
+
+Channels ChannelMapperReader::getChannels() const
+{
+ return m_target_channels;
+}
+
+void ChannelMapperReader::setChannels(Channels channels)
+{
+ m_target_channels = channels;
+ calculateMapping();
+}
+
+float ChannelMapperReader::getMapping(int source, int target)
+{
+ Channels source_channels = m_reader->getSpecs().channels;
+ if(source_channels != m_source_channels)
+ {
+ m_source_channels = source_channels;
+ calculateMapping();
+ }
+
+ if(source < 0 || source >= source_channels || target < 0 || target >= m_target_channels)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_mapping[target * source_channels + source];
+}
+
+void ChannelMapperReader::setMonoAngle(float angle)
+{
+ if(angle != angle)
+ angle = 0;
+ m_mono_angle = angle;
+ if(m_source_channels == CHANNELS_MONO)
+ calculateMapping();
+}
+
+float ChannelMapperReader::angleDistance(float alpha, float beta)
+{
+ alpha = beta - alpha;
+
+ if(alpha > M_PI)
+ alpha -= 2 * M_PI;
+ if(alpha < -M_PI)
+ alpha += 2 * M_PI;
+
+ return alpha;
+}
+
+void ChannelMapperReader::calculateMapping()
+{
+ if(m_map_size < m_source_channels * m_target_channels)
+ {
+ delete[] m_mapping;
+ m_mapping = new float[m_source_channels * m_target_channels];
+ m_map_size = m_source_channels * m_target_channels;
+ }
+
+ for(int i = 0; i < m_source_channels * m_target_channels; i++)
+ m_mapping[i] = 0;
+
+ const Channel* source_channels = CHANNEL_MAPS[m_source_channels - 1];
+ const Channel* target_channels = CHANNEL_MAPS[m_target_channels - 1];
+
+ int lfe = -1;
+
+ for(int i = 0; i < m_target_channels; i++)
+ {
+ if(target_channels[i] == CHANNEL_LFE)
+ {
+ lfe = i;
+ break;
+ }
+ }
+
+ const float* source_angles = CHANNEL_ANGLES[m_source_channels - 1];
+ const float* target_angles = CHANNEL_ANGLES[m_target_channels - 1];
+
+ if(m_source_channels == CHANNELS_MONO)
+ source_angles = &m_mono_angle;
+
+ int channel_left, channel_right;
+ float angle_left, angle_right, angle;
+
+ for(int i = 0; i < m_source_channels; i++)
+ {
+ if(source_channels[i] == CHANNEL_LFE)
+ {
+ if(lfe != -1)
+ m_mapping[lfe * m_source_channels + i] = 1;
+
+ continue;
+ }
+
+ 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 < 0)
+ {
+ if(angle > angle_left)
+ {
+ angle_left = angle;
+ channel_left = j;
+ }
+ }
+ else
+ {
+ if(angle < angle_right)
+ {
+ angle_right = angle;
+ channel_right = j;
+ }
+ }
+ }
+
+ 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_right * m_source_channels + i] = 1;
+ }
+ else
+ {
+ m_mapping[channel_left * m_source_channels + i] = std::cos(M_PI_2 * angle_left / angle);
+ m_mapping[channel_right * m_source_channels + i] = std::cos(M_PI_2 * angle_right / angle);
+ }
+ }
+}
+
+Specs ChannelMapperReader::getSpecs() const
+{
+ Specs specs = m_reader->getSpecs();
+ specs.channels = m_target_channels;
+ return specs;
+}
+
+void ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ Channels channels = m_reader->getSpecs().channels;
+ if(channels != m_source_channels)
+ {
+ m_source_channels = channels;
+ calculateMapping();
+ }
+
+ if(m_source_channels == m_target_channels)
+ {
+ m_reader->read(length, eos, buffer);
+ return;
+ }
+
+ m_buffer.assureSize(length * channels * sizeof(sample_t));
+
+ sample_t* in = m_buffer.getBuffer();
+
+ m_reader->read(length, eos, in);
+
+ sample_t sum;
+
+ for(int i = 0; i < length; i++)
+ {
+ for(int j = 0; j < m_target_channels; j++)
+ {
+ sum = 0;
+ for(int k = 0; k < m_source_channels; k++)
+ sum += m_mapping[j * m_source_channels + k] * in[i * m_source_channels + k];
+ buffer[i * m_target_channels + j] = sum;
+ }
+ }
+}
+
+const Channel ChannelMapperReader::MONO_MAP[] =
+{
+ CHANNEL_FRONT_CENTER
+};
+
+const Channel ChannelMapperReader::STEREO_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT
+};
+
+const Channel ChannelMapperReader::STEREO_LFE_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_LFE
+};
+
+const Channel ChannelMapperReader::SURROUND4_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT
+};
+
+const Channel ChannelMapperReader::SURROUND5_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT
+};
+
+const Channel ChannelMapperReader::SURROUND51_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_LFE,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT
+};
+
+const Channel ChannelMapperReader::SURROUND61_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_LFE,
+ CHANNEL_REAR_CENTER,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT
+};
+
+const Channel ChannelMapperReader::SURROUND71_MAP[] =
+{
+ CHANNEL_FRONT_LEFT,
+ CHANNEL_FRONT_RIGHT,
+ CHANNEL_FRONT_CENTER,
+ CHANNEL_LFE,
+ CHANNEL_REAR_LEFT,
+ CHANNEL_REAR_RIGHT,
+ CHANNEL_SIDE_LEFT,
+ CHANNEL_SIDE_RIGHT
+};
+
+const Channel* ChannelMapperReader::CHANNEL_MAPS[] =
+{
+ ChannelMapperReader::MONO_MAP,
+ ChannelMapperReader::STEREO_MAP,
+ ChannelMapperReader::STEREO_LFE_MAP,
+ ChannelMapperReader::SURROUND4_MAP,
+ ChannelMapperReader::SURROUND5_MAP,
+ ChannelMapperReader::SURROUND51_MAP,
+ ChannelMapperReader::SURROUND61_MAP,
+ ChannelMapperReader::SURROUND71_MAP
+};
+
+const float ChannelMapperReader::MONO_ANGLES[] =
+{
+ 0.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::STEREO_ANGLES[] =
+{
+ -90.0f * M_PI / 180.0f,
+ 90.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::STEREO_LFE_ANGLES[] =
+{
+ -90.0f * M_PI / 180.0f,
+ 90.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND4_ANGLES[] =
+{
+ -45.0f * M_PI / 180.0f,
+ 45.0f * M_PI / 180.0f,
+ -135.0f * M_PI / 180.0f,
+ 135.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND5_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND51_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND61_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 180.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+};
+
+const float ChannelMapperReader::SURROUND71_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f,
+ -150.0f * M_PI / 180.0f,
+ 150.0f * M_PI / 180.0f
+};
+
+const float* ChannelMapperReader::CHANNEL_ANGLES[] =
+{
+ ChannelMapperReader::MONO_ANGLES,
+ ChannelMapperReader::STEREO_ANGLES,
+ ChannelMapperReader::STEREO_LFE_ANGLES,
+ ChannelMapperReader::SURROUND4_ANGLES,
+ ChannelMapperReader::SURROUND5_ANGLES,
+ ChannelMapperReader::SURROUND51_ANGLES,
+ ChannelMapperReader::SURROUND61_ANGLES,
+ ChannelMapperReader::SURROUND71_ANGLES
+};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/Converter.cpp b/extern/audaspace/src/respec/Converter.cpp
new file mode 100644
index 00000000000..f3cca20c741
--- /dev/null
+++ b/extern/audaspace/src/respec/Converter.cpp
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/Converter.h"
+#include "respec/ConverterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Converter::Converter(std::shared_ptr<ISound> sound,
+ DeviceSpecs specs) :
+ SpecsChanger(sound, specs)
+{
+}
+
+std::shared_ptr<IReader> Converter::createReader()
+{
+ std::shared_ptr<IReader> reader = getReader();
+
+ if(m_specs.format != FORMAT_FLOAT32)
+ reader = std::shared_ptr<IReader>(new ConverterReader(reader, m_specs));
+
+ return reader;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ConverterFunctions.cpp b/extern/audaspace/src/respec/ConverterFunctions.cpp
new file mode 100644
index 00000000000..d3df4a9ecbb
--- /dev/null
+++ b/extern/audaspace/src/respec/ConverterFunctions.cpp
@@ -0,0 +1,464 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/ConverterFunctions.h"
+
+#include <stdint.h>
+
+#define U8_0 0x80
+#define S16_MAX ((int16_t)0x7FFF)
+#define S16_MIN ((int16_t)0x8000)
+#define S16_FLT 32767.0f
+#define S32_MAX ((int32_t)0x7FFFFFFF)
+#define S32_MIN ((int32_t)0x80000000)
+#define S32_FLT 2147483647.0f
+#define FLT_MAX 1.0f
+#define FLT_MIN -1.0f
+
+AUD_NAMESPACE_BEGIN
+
+void convert_u8_s16(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = (((int16_t)source[i]) - U8_0) << 8;
+}
+
+void convert_u8_s24_be(data_t* target, data_t* source, int length)
+{
+ for(int i = length - 1; i >= 0; i--)
+ {
+ target[i*3] = source[i] - U8_0;
+ target[i*3+1] = 0;
+ target[i*3+2] = 0;
+ }
+}
+
+void convert_u8_s24_le(data_t* target, data_t* source, int length)
+{
+ for(int i = length - 1; i >= 0; i--)
+ {
+ target[i*3+2] = source[i] - U8_0;
+ target[i*3+1] = 0;
+ target[i*3] = 0;
+ }
+}
+
+void convert_u8_s32(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = (((int32_t)source[i]) - U8_0) << 24;
+}
+
+void convert_u8_float(data_t* target, data_t* source, int length)
+{
+ float* t = (float*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = (((int32_t)source[i]) - U8_0) / ((float)U8_0);
+}
+
+void convert_u8_double(data_t* target, data_t* source, int length)
+{
+ double* t = (double*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = (((int32_t)source[i]) - U8_0) / ((double)U8_0);
+}
+
+void convert_s16_u8(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ for(int i = 0; i < length; i++)
+ target[i] = (unsigned char)((s[i] >> 8) + U8_0);
+}
+
+void convert_s16_s24_be(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ int16_t t;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ t = s[i];
+ target[i*3] = t >> 8 & 0xFF;
+ target[i*3+1] = t & 0xFF;
+ target[i*3+2] = 0;
+ }
+}
+
+void convert_s16_s24_le(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ int16_t t;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ t = s[i];
+ target[i*3+2] = t >> 8 & 0xFF;
+ target[i*3+1] = t & 0xFF;
+ target[i*3] = 0;
+ }
+}
+
+void convert_s16_s32(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ int32_t* t = (int32_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = ((int32_t)s[i]) << 16;
+}
+
+void convert_s16_float(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ float* t = (float*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = s[i] / S16_FLT;
+}
+
+void convert_s16_double(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ double* t = (double*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = s[i] / S16_FLT;
+}
+
+void convert_s24_u8_be(data_t* target, data_t* source, int length)
+{
+ for(int i = 0; i < length; i++)
+ target[i] = source[i*3] ^ U8_0;
+}
+
+void convert_s24_u8_le(data_t* target, data_t* source, int length)
+{
+ for(int i = 0; i < length; i++)
+ target[i] = source[i*3+2] ^ U8_0;
+}
+
+void convert_s24_s16_be(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = source[i*3] << 8 | source[i*3+1];
+}
+
+void convert_s24_s16_le(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = source[i*3+2] << 8 | source[i*3+1];
+}
+
+void convert_s24_s24(data_t* target, data_t* source, int length)
+{
+ std::memcpy(target, source, length * 3);
+}
+
+void convert_s24_s32_be(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
+}
+
+void convert_s24_s32_le(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
+}
+
+void convert_s24_float_be(data_t* target, data_t* source, int length)
+{
+ float* t = (float*) target;
+ int32_t s;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
+ t[i] = s / S32_FLT;
+ }
+}
+
+void convert_s24_float_le(data_t* target, data_t* source, int length)
+{
+ float* t = (float*) target;
+ int32_t s;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
+ t[i] = s / S32_FLT;
+ }
+}
+
+void convert_s24_double_be(data_t* target, data_t* source, int length)
+{
+ double* t = (double*) target;
+ int32_t s;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
+ t[i] = s / S32_FLT;
+ }
+}
+
+void convert_s24_double_le(data_t* target, data_t* source, int length)
+{
+ double* t = (double*) target;
+ int32_t s;
+ for(int i = length - 1; i >= 0; i--)
+ {
+ s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
+ t[i] = s / S32_FLT;
+ }
+}
+
+void convert_s32_u8(data_t* target, data_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ for(int i = 0; i < length; i++)
+ target[i] = (unsigned char)((s[i] >> 24) + U8_0);
+}
+
+void convert_s32_s16(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ int32_t* s = (int32_t*) source;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i] >> 16;
+}
+
+void convert_s32_s24_be(data_t* target, data_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ int32_t t;
+ for(int i = 0; i < length; i++)
+ {
+ t = s[i];
+ target[i*3] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3+2] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_s32_s24_le(data_t* target, data_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ int32_t t;
+ for(int i = 0; i < length; i++)
+ {
+ t = s[i];
+ target[i*3+2] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_s32_float(data_t* target, data_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ float* t = (float*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i] / S32_FLT;
+}
+
+void convert_s32_double(data_t* target, data_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ double* t = (double*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = s[i] / S32_FLT;
+}
+
+void convert_float_u8(data_t* target, data_t* source, int length)
+{
+ float* s = (float*) source;
+ float t;
+ for(int i = 0; i < length; i++)
+ {
+ t = s[i] + FLT_MAX;
+ if(t <= 0.0f)
+ target[i] = 0;
+ else if(t >= 2.0f)
+ target[i] = 255;
+ else
+ target[i] = (unsigned char)(t*127);
+ }
+}
+
+void convert_float_s16(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ float* s = (float*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t[i] = S16_MIN;
+ else if(s[i] >= FLT_MAX)
+ t[i] = S16_MAX;
+ else
+ t[i] = (int16_t)(s[i] * S16_MAX);
+ }
+}
+
+void convert_float_s24_be(data_t* target, data_t* source, int length)
+{
+ int32_t t;
+ float* s = (float*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t = S32_MAX;
+ else
+ t = (int32_t)(s[i]*S32_MAX);
+ target[i*3] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3+2] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_float_s24_le(data_t* target, data_t* source, int length)
+{
+ int32_t t;
+ float* s = (float*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t = S32_MAX;
+ else
+ t = (int32_t)(s[i]*S32_MAX);
+ target[i*3+2] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_float_s32(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ float* s = (float*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t[i] = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t[i] = S32_MAX;
+ else
+ t[i] = (int32_t)(s[i]*S32_MAX);
+ }
+}
+
+void convert_float_double(data_t* target, data_t* source, int length)
+{
+ float* s = (float*) source;
+ double* t = (double*) target;
+ for(int i = length - 1; i >= 0; i--)
+ t[i] = s[i];
+}
+
+void convert_double_u8(data_t* target, data_t* source, int length)
+{
+ double* s = (double*) source;
+ double t;
+ for(int i = 0; i < length; i++)
+ {
+ t = s[i] + FLT_MAX;
+ if(t <= 0.0)
+ target[i] = 0;
+ else if(t >= 2.0)
+ target[i] = 255;
+ else
+ target[i] = (unsigned char)(t*127);
+ }
+}
+
+void convert_double_s16(data_t* target, data_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ double* s = (double*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t[i] = S16_MIN;
+ else if(s[i] >= FLT_MAX)
+ t[i] = S16_MAX;
+ else
+ t[i] = (int16_t)(s[i]*S16_MAX);
+ }
+}
+
+void convert_double_s24_be(data_t* target, data_t* source, int length)
+{
+ int32_t t;
+ double* s = (double*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t = S32_MAX;
+ else
+ t = (int32_t)(s[i]*S32_MAX);
+ target[i*3] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3+2] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_double_s24_le(data_t* target, data_t* source, int length)
+{
+ int32_t t;
+ double* s = (double*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t = S32_MAX;
+ else
+ t = (int32_t)(s[i]*S32_MAX);
+ target[i*3+2] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3] = t >> 8 & 0xFF;
+ }
+}
+
+void convert_double_s32(data_t* target, data_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ double* s = (double*) source;
+ for(int i = 0; i < length; i++)
+ {
+ if(s[i] <= FLT_MIN)
+ t[i] = S32_MIN;
+ else if(s[i] >= FLT_MAX)
+ t[i] = S32_MAX;
+ else
+ t[i] = (int32_t)(s[i]*S32_MAX);
+ }
+}
+
+void convert_double_float(data_t* target, data_t* source, int length)
+{
+ double* s = (double*) source;
+ float* t = (float*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i];
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ConverterReader.cpp b/extern/audaspace/src/respec/ConverterReader.cpp
new file mode 100644
index 00000000000..88a5e7f225d
--- /dev/null
+++ b/extern/audaspace/src/respec/ConverterReader.cpp
@@ -0,0 +1,68 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/ConverterReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+ConverterReader::ConverterReader(std::shared_ptr<IReader> reader,
+ DeviceSpecs specs) :
+ EffectReader(reader),
+ m_format(specs.format)
+{
+ switch(m_format)
+ {
+ case FORMAT_U8:
+ m_convert = convert_float_u8;
+ break;
+ case FORMAT_S16:
+ m_convert = convert_float_s16;
+ break;
+ case FORMAT_S24:
+#ifdef __BIG_ENDIAN__
+ m_convert = convert_float_s24_be;
+#else
+ m_convert = convert_float_s24_le;
+#endif
+ break;
+ case FORMAT_S32:
+ m_convert = convert_float_s32;
+ break;
+ case FORMAT_FLOAT32:
+ m_convert = convert_copy<float>;
+ break;
+ case FORMAT_FLOAT64:
+ m_convert = convert_float_double;
+ break;
+ default:
+ break;
+ }
+}
+
+void ConverterReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer.assureSize(length * samplesize);
+
+ m_reader->read(length, eos, m_buffer.getBuffer());
+
+ m_convert((data_t*)buffer, (data_t*)m_buffer.getBuffer(),
+ length * specs.channels);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/JOSResample.cpp b/extern/audaspace/src/respec/JOSResample.cpp
new file mode 100644
index 00000000000..fae116d057a
--- /dev/null
+++ b/extern/audaspace/src/respec/JOSResample.cpp
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/JOSResample.h"
+#include "respec/JOSResampleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+JOSResample::JOSResample(std::shared_ptr<ISound> sound,
+ DeviceSpecs specs) :
+ SpecsChanger(sound, specs)
+{
+}
+
+std::shared_ptr<IReader> JOSResample::createReader()
+{
+ return std::shared_ptr<IReader>(new JOSResampleReader(getReader(), m_specs.rate));
+}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_JOSResampleReader.cpp b/extern/audaspace/src/respec/JOSResampleReader.cpp
index 0448c75d777..6753a2e8b6b 100644
--- a/intern/audaspace/intern/AUD_JOSResampleReader.cpp
+++ b/extern/audaspace/src/respec/JOSResampleReader.cpp
@@ -1,68 +1,26 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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_JOSResampleReader.cpp
- * \ingroup audaspaceintern
- */
+ * 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.
+ ******************************************************************************/
-#include "AUD_JOSResampleReader.h"
-
-#include "AUD_JOSResampleReaderCoeff.cpp"
+#include "respec/JOSResampleReader.h"
+#include <algorithm>
#include <cmath>
#include <cstring>
-#include <iostream>
-
-/* MSVC does not have lrint */
-#ifdef _MSC_VER
-#if _MSC_VER < 1800
-#ifdef _M_X64
-#include <emmintrin.h>
-static inline int lrint(double d)
-{
- return _mm_cvtsd_si32(_mm_load_sd(&d));
-}
-#else
-static inline int lrint(double d)
-{
- int i;
-
- _asm{
- fld d
- fistp i
- };
-
- return i;
-}
-#endif
-#endif
-#endif
-// UNUSED
-// #define CC m_channels + channel
-
-#define AUD_RATE_MAX 256
+#define RATE_MAX 256
#define SHIFT_BITS 12
#define double_to_fp(x) (lrint(x * double(1 << SHIFT_BITS)))
#define int_to_fp(x) (x << SHIFT_BITS)
@@ -71,9 +29,11 @@ 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(boost::shared_ptr<AUD_IReader> reader, AUD_Specs specs) :
- AUD_ResampleReader(reader, specs.rate),
- m_channels(AUD_CHANNELS_INVALID),
+AUD_NAMESPACE_BEGIN
+
+JOSResampleReader::JOSResampleReader(std::shared_ptr<IReader> reader, SampleRate rate) :
+ ResampleReader(reader, rate),
+ m_channels(CHANNELS_INVALID),
m_n(0),
m_P(0),
m_cache_valid(0),
@@ -81,7 +41,7 @@ AUD_JOSResampleReader::AUD_JOSResampleReader(boost::shared_ptr<AUD_IReader> read
{
}
-void AUD_JOSResampleReader::reset()
+void JOSResampleReader::reset()
{
m_cache_valid = 0;
m_n = 0;
@@ -89,25 +49,25 @@ void AUD_JOSResampleReader::reset()
m_last_factor = 0;
}
-void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize)
+void JOSResampleReader::updateBuffer(int size, double factor, int samplesize)
{
unsigned int len;
double num_samples = double(m_len) / double(m_L);
// first calculate what length we need right now
if(factor >= 1)
- len = ceil(num_samples);
+ len = std::ceil(num_samples);
else
- len = (unsigned int)(ceil(num_samples / factor));
+ len = (unsigned int)(std::ceil(num_samples / factor));
// then check if afterwards the length is enough for the maximum rate
- if(len + size < num_samples * AUD_RATE_MAX)
- len = num_samples * AUD_RATE_MAX - size;
+ if(len + size < num_samples * RATE_MAX)
+ len = num_samples * RATE_MAX - size;
if(m_n > len)
{
sample_t* buf = m_buffer.getBuffer();
len = m_n - len;
- memmove(buf, buf + len * m_channels, (m_cache_valid - len) * samplesize);
+ std::memmove(buf, buf + len * m_channels, (m_cache_valid - len) * samplesize);
m_n -= len;
m_cache_valid -= len;
}
@@ -115,7 +75,7 @@ void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize
m_buffer.assureSize((m_cache_valid + size) * samplesize, true);
}
-#define RESAMPLE_METHOD(name, left, right) void AUD_JOSResampleReader::name(double target_factor, int length, sample_t* buffer)\
+#define RESAMPLE_METHOD(name, left, right) void JOSResampleReader::name(double target_factor, int length, sample_t* buffer)\
{\
sample_t* buf = m_buffer.getBuffer();\
\
@@ -134,13 +94,13 @@ void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize
{\
factor = (m_last_factor * (length - t - 1) + target_factor * (t + 1)) / length;\
\
- memset(sums, 0, sizeof(double) * m_channels);\
+ std::memset(sums, 0, sizeof(double) * m_channels);\
\
if(factor >= 1)\
{\
P = double_to_fp(m_P * m_L);\
\
- end = floor(m_len / double(m_L) - m_P) - 1;\
+ end = std::floor(m_len / double(m_L) - m_P) - 1;\
if(m_n < end)\
end = m_n;\
\
@@ -158,7 +118,7 @@ void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize
\
P = int_to_fp(m_L) - P;\
\
- end = floor((m_len - 1) / double(m_L) + m_P) - 1;\
+ end = std::floor((m_len - 1) / double(m_L) + m_P) - 1;\
if(m_cache_valid - m_n - 2 < end)\
end = m_cache_valid - m_n - 2;\
\
@@ -224,13 +184,13 @@ void AUD_JOSResampleReader::updateBuffer(int size, double factor, int samplesize
\
for(channel = 0; channel < m_channels; channel++)\
{\
- *buffer = factor * sums[channel];\
+ *buffer = factor * sums[channel];\
buffer++;\
}\
}\
\
- m_P += fmod(1.0 / factor, 1.0);\
- m_n += floor(1.0 / factor);\
+ m_P += std::fmod(1.0 / factor, 1.0);\
+ m_n += std::floor(1.0 / factor);\
\
while(m_P >= 1.0)\
{\
@@ -278,37 +238,36 @@ RESAMPLE_METHOD(resample_stereo, {
sums[1] += data[2] * v;
})
-void AUD_JOSResampleReader::seek(int position)
+void JOSResampleReader::seek(int position)
{
- position = floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
+ position = std::floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
m_reader->seek(position);
reset();
}
-int AUD_JOSResampleReader::getLength() const
+int JOSResampleReader::getLength() const
{
- return floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
+ return std::floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
}
-int AUD_JOSResampleReader::getPosition() const
+int JOSResampleReader::getPosition() const
{
- return floor((m_reader->getPosition() + double(m_P))
- * m_rate / m_reader->getSpecs().rate);
+ return std::floor((m_reader->getPosition() + double(m_P)) * m_rate / m_reader->getSpecs().rate);
}
-AUD_Specs AUD_JOSResampleReader::getSpecs() const
+Specs JOSResampleReader::getSpecs() const
{
- AUD_Specs specs = m_reader->getSpecs();
+ Specs specs = m_reader->getSpecs();
specs.rate = m_rate;
return specs;
}
-void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
+void JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
{
if(length == 0)
return;
- AUD_Specs specs = m_reader->getSpecs();
+ Specs specs = m_reader->getSpecs();
int samplesize = AUD_SAMPLE_SIZE(specs);
double target_factor = double(m_rate) / double(specs.rate);
@@ -324,14 +283,14 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
switch(m_channels)
{
- case AUD_CHANNELS_MONO:
- m_resample = &AUD_JOSResampleReader::resample_mono;
+ case CHANNELS_MONO:
+ m_resample = &JOSResampleReader::resample_mono;
break;
- case AUD_CHANNELS_STEREO:
- m_resample = &AUD_JOSResampleReader::resample_stereo;
+ case CHANNELS_STEREO:
+ m_resample = &JOSResampleReader::resample_stereo;
break;
default:
- m_resample = &AUD_JOSResampleReader::resample;
+ m_resample = &JOSResampleReader::resample;
break;
}
}
@@ -355,7 +314,7 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
if(length > 0)
{
- memcpy(buffer, buf + m_n * m_channels, length * samplesize);
+ std::memcpy(buffer, buf + m_n * m_channels, length * samplesize);
m_n += length;
}
@@ -363,12 +322,12 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
}
// use minimum for the following calculations
- double factor = AUD_MIN(target_factor, m_last_factor);
+ double factor = std::min(target_factor, m_last_factor);
if(factor >= 1)
- len = (int(m_n) - m_cache_valid) + int(ceil(length / factor)) + ceil(num_samples);
+ len = (int(m_n) - m_cache_valid) + int(std::ceil(length / factor)) + std::ceil(num_samples);
else
- len = (int(m_n) - m_cache_valid) + int(ceil(length / factor) + ceil(num_samples / factor));
+ len = (int(m_n) - m_cache_valid) + int(std::ceil(length / factor) + std::ceil(num_samples / factor));
if(len > 0)
{
@@ -386,22 +345,22 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
else
{
// use maximum for the following calculations
- factor = AUD_MAX(target_factor, m_last_factor);
+ factor = std::max(target_factor, m_last_factor);
if(eos)
{
// end of stream, let's check how many more samples we can produce
- len = floor((m_cache_valid - m_n) * factor);
+ len = std::floor((m_cache_valid - m_n) * factor);
if(len < length)
length = len;
}
else
{
- // not enough data available yet, so we recalculate how many samples we can calculate
+ // not enough data available yet, so we recalculate how many samples we can calculate
if(factor >= 1)
- len = floor((num_samples + m_cache_valid - m_n) * factor);
+ len = std::floor((num_samples + m_cache_valid - m_n) * factor);
else
- len = floor((num_samples * factor + m_cache_valid - m_n) * factor);
+ len = std::floor((num_samples * factor + m_cache_valid - m_n) * factor);
if(len < length)
length = len;
}
@@ -420,3 +379,5 @@ void AUD_JOSResampleReader::read(int& length, bool& eos, sample_t* buffer)
eos = eos && ((m_n == m_cache_valid) || (length == 0));
}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp b/extern/audaspace/src/respec/JOSResampleReaderCoeff.cpp
index f8fefd5b88f..133e081f4a7 100644
--- a/intern/audaspace/intern/AUD_JOSResampleReaderCoeff.cpp
+++ b/extern/audaspace/src/respec/JOSResampleReaderCoeff.cpp
@@ -1,39 +1,29 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_JOSResampleReaderCoeff.cpp
- * \ingroup audaspaceintern
- */
-
-#include "AUD_JOSResampleReader.h"
+#include "respec/JOSResampleReader.h"
// sinc filter coefficients, Nz = 136, L = 2304, freq = 0.963904, Kaiser Window B = 16
-const int AUD_JOSResampleReader::m_len = 325078;
-const int AUD_JOSResampleReader::m_L = 2304;
+AUD_NAMESPACE_BEGIN
+
+const int JOSResampleReader::m_len = 325078;
+const int JOSResampleReader::m_L = 2304;
-const float AUD_JOSResampleReader::m_coeff[] = {
+const float JOSResampleReader::m_coeff[] = {
9.639035268e-01f, 9.639032492e-01f, 9.639024165e-01f, 9.639010286e-01f, 9.638990855e-01f, 9.638965872e-01f, 9.638935338e-01f, 9.638899253e-01f, 9.638857615e-01f, 9.638810427e-01f,
9.638757686e-01f, 9.638699395e-01f, 9.638635552e-01f, 9.638566158e-01f, 9.638491212e-01f, 9.638410716e-01f, 9.638324668e-01f, 9.638233070e-01f, 9.638135921e-01f, 9.638033220e-01f,
9.637924970e-01f, 9.637811168e-01f, 9.637691817e-01f, 9.637566915e-01f, 9.637436463e-01f, 9.637300461e-01f, 9.637158908e-01f, 9.637011807e-01f, 9.636859155e-01f, 9.636700955e-01f,
@@ -32543,3 +32533,5 @@ const float AUD_JOSResampleReader::m_coeff[] = {
-6.072286860e-11f, -5.735986806e-11f, -5.399941461e-11f, -5.064151335e-11f, -4.728616936e-11f, -4.393338771e-11f, -4.058317348e-11f, -3.723553173e-11f, -3.389046751e-11f, -3.054798585e-11f,
-2.720809180e-11f, -2.387079037e-11f, -2.053608658e-11f, -1.720398544e-11f, -1.387449194e-11f, -1.054761107e-11f, -7.223347816e-12f, -3.901707142e-12f, -3.901707142e-12f
};
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/LinearResample.cpp b/extern/audaspace/src/respec/LinearResample.cpp
new file mode 100644
index 00000000000..bcdc3409771
--- /dev/null
+++ b/extern/audaspace/src/respec/LinearResample.cpp
@@ -0,0 +1,32 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/LinearResample.h"
+#include "respec/LinearResampleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+LinearResample::LinearResample(std::shared_ptr<ISound> sound, DeviceSpecs specs) :
+ SpecsChanger(sound, specs)
+{
+}
+
+std::shared_ptr<IReader> LinearResample::createReader()
+{
+ return std::shared_ptr<IReader>(new LinearResampleReader(getReader(), m_specs.rate));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/LinearResampleReader.cpp b/extern/audaspace/src/respec/LinearResampleReader.cpp
new file mode 100644
index 00000000000..53d506115ce
--- /dev/null
+++ b/extern/audaspace/src/respec/LinearResampleReader.cpp
@@ -0,0 +1,174 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/LinearResampleReader.h"
+
+#include <cmath>
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+LinearResampleReader::LinearResampleReader(std::shared_ptr<IReader> reader, SampleRate rate) :
+ ResampleReader(reader, rate),
+ m_channels(reader->getSpecs().channels),
+ m_cache_pos(0),
+ m_cache_ok(false)
+{
+ Specs specs = { rate, m_channels };
+ m_cache.resize(2 * AUD_SAMPLE_SIZE(specs));
+}
+
+void LinearResampleReader::seek(int position)
+{
+ position = std::floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
+ m_reader->seek(position);
+ m_cache_ok = false;
+ m_cache_pos = 0;
+}
+
+int LinearResampleReader::getLength() const
+{
+ return std::floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
+}
+
+int LinearResampleReader::getPosition() const
+{
+ return std::floor((m_reader->getPosition() + (m_cache_ok ? m_cache_pos - 1 : 0))
+ * m_rate / m_reader->getSpecs().rate);
+}
+
+Specs LinearResampleReader::getSpecs() const
+{
+ Specs specs = m_reader->getSpecs();
+ specs.rate = m_rate;
+ return specs;
+}
+
+void LinearResampleReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ if(length == 0)
+ return;
+
+ Specs specs = m_reader->getSpecs();
+
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+ int size = length;
+ float factor = m_rate / m_reader->getSpecs().rate;
+ float spos = 0.0f;
+ sample_t low, high;
+ eos = false;
+
+ // check for channels changed
+
+ if(specs.channels != m_channels)
+ {
+ m_cache.resize(2 * samplesize);
+ m_channels = specs.channels;
+ m_cache_ok = false;
+ }
+
+ if(factor == 1 && (!m_cache_ok || m_cache_pos == 1))
+ {
+ // can read directly!
+ m_reader->read(length, eos, buffer);
+
+ if(length > 0)
+ {
+ std::memcpy(m_cache.getBuffer() + m_channels, buffer + m_channels * (length - 1), samplesize);
+ m_cache_pos = 1;
+ m_cache_ok = true;
+ }
+
+ return;
+ }
+
+ int len;
+ sample_t* buf;
+
+ if(m_cache_ok)
+ {
+ int need = std::ceil(length / factor + m_cache_pos) - 1;
+
+ len = need;
+
+ m_buffer.assureSize((len + 2) * samplesize);
+ buf = m_buffer.getBuffer();
+
+ std::memcpy(buf, m_cache.getBuffer(), 2 * samplesize);
+ m_reader->read(len, eos, buf + 2 * m_channels);
+
+ if(len < need)
+ length = std::floor((len + 1 - m_cache_pos) * factor);
+ }
+ else
+ {
+ m_cache_pos = 1 - 1 / factor;
+
+ int need = std::ceil(length / factor + m_cache_pos);
+
+ len = need;
+
+ m_buffer.assureSize((len + 1) * samplesize);
+ buf = m_buffer.getBuffer();
+
+ std::memset(buf, 0, samplesize);
+ m_reader->read(len, eos, buf + m_channels);
+
+ if(len == 0)
+ {
+ length = 0;
+ return;
+ }
+
+ if(len < need)
+ {
+ length = std::floor((len - m_cache_pos) * factor);
+ }
+
+ m_cache_ok = true;
+ }
+
+ if(length == 0)
+ return;
+
+ for(int channel = 0; channel < m_channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ spos = (i + 1) / factor + m_cache_pos;
+
+ low = buf[(int)std::floor(spos) * m_channels + channel];
+ high = buf[(int)std::ceil(spos) * m_channels + channel];
+
+ buffer[i * m_channels + channel] = low + (spos - std::floor(spos)) * (high - low);
+ }
+ }
+
+ if(std::floor(spos) == spos)
+ {
+ std::memcpy(m_cache.getBuffer() + m_channels, buf + int(std::floor(spos)) * m_channels, samplesize);
+ m_cache_pos = 1;
+ }
+ else
+ {
+ std::memcpy(m_cache.getBuffer(), buf + int(std::floor(spos)) * m_channels, 2 * samplesize);
+ m_cache_pos = spos - std::floor(spos);
+ }
+
+ eos &= length < size;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/Mixer.cpp b/extern/audaspace/src/respec/Mixer.cpp
new file mode 100644
index 00000000000..d63f0bab2bb
--- /dev/null
+++ b/extern/audaspace/src/respec/Mixer.cpp
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/Mixer.h"
+
+#include <algorithm>
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+Mixer::Mixer(DeviceSpecs specs) :
+ m_specs(specs)
+{
+ switch(m_specs.format)
+ {
+ case FORMAT_U8:
+ m_convert = convert_float_u8;
+ break;
+ case FORMAT_S16:
+ m_convert = convert_float_s16;
+ break;
+ case FORMAT_S24:
+
+#ifdef __BIG_ENDIAN__
+ m_convert = convert_float_s24_be;
+#else
+ m_convert = convert_float_s24_le;
+#endif
+ break;
+ case FORMAT_S32:
+ m_convert = convert_float_s32;
+ break;
+ case FORMAT_FLOAT32:
+ m_convert = convert_copy<float>;
+ break;
+ case FORMAT_FLOAT64:
+ m_convert = convert_float_double;
+ break;
+ default:
+ break;
+ }
+}
+
+DeviceSpecs Mixer::getSpecs() const
+{
+ return m_specs;
+}
+
+void Mixer::setSpecs(Specs specs)
+{
+ m_specs.specs = specs;
+}
+
+void Mixer::clear(int length)
+{
+ m_buffer.assureSize(length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
+
+ m_length = length;
+
+ std::memset(m_buffer.getBuffer(), 0, length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
+}
+
+void Mixer::mix(sample_t* buffer, int start, int length, float volume)
+{
+ sample_t* out = m_buffer.getBuffer();
+
+ length = (std::min(m_length, length + start) - start) * m_specs.channels;
+ start *= m_specs.channels;
+
+ for(int i = 0; i < length; i++)
+ out[i + start] += buffer[i] * volume;
+}
+
+void Mixer::mix(sample_t* buffer, int start, int length, float volume_to, float volume_from)
+{
+ sample_t* out = m_buffer.getBuffer();
+
+ length = (std::min(m_length, length + start) - start);
+
+ for(int i = 0; i < length; i++)
+ {
+ float volume = volume_from * (1.0f - i / float(length)) + volume_to * (i / float(length));
+
+ for(int c = 0; c < m_specs.channels; c++)
+ out[(i + start) * m_specs.channels + c] += buffer[i * m_specs.channels + c] * volume;
+ }
+}
+
+void Mixer::read(data_t* buffer, float volume)
+{
+ sample_t* out = m_buffer.getBuffer();
+
+ for(int i = 0; i < m_length * m_specs.channels; i++)
+ out[i] *= volume;
+
+ m_convert(buffer, (data_t*) out, m_length * m_specs.channels);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/ResampleReader.cpp b/extern/audaspace/src/respec/ResampleReader.cpp
new file mode 100644
index 00000000000..d7f5bff3a51
--- /dev/null
+++ b/extern/audaspace/src/respec/ResampleReader.cpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/ResampleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+ResampleReader::ResampleReader(std::shared_ptr<IReader> reader, SampleRate rate) :
+ EffectReader(reader), m_rate(rate)
+{
+}
+
+void ResampleReader::setRate(SampleRate rate)
+{
+ m_rate = rate;
+}
+
+SampleRate ResampleReader::getRate()
+{
+ return m_rate;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/respec/SpecsChanger.cpp b/extern/audaspace/src/respec/SpecsChanger.cpp
new file mode 100644
index 00000000000..146d9789160
--- /dev/null
+++ b/extern/audaspace/src/respec/SpecsChanger.cpp
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "respec/SpecsChanger.h"
+
+AUD_NAMESPACE_BEGIN
+
+std::shared_ptr<IReader> SpecsChanger::getReader() const
+{
+ return m_sound->createReader();
+}
+
+SpecsChanger::SpecsChanger(std::shared_ptr<ISound> sound,
+ DeviceSpecs specs) :
+ m_specs(specs), m_sound(sound)
+{
+}
+
+DeviceSpecs SpecsChanger::getSpecs() const
+{
+ return m_specs;
+}
+
+std::shared_ptr<ISound> SpecsChanger::getSound() const
+{
+ return m_sound;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/AnimateableProperty.cpp b/extern/audaspace/src/sequence/AnimateableProperty.cpp
new file mode 100644
index 00000000000..306ba8e07f5
--- /dev/null
+++ b/extern/audaspace/src/sequence/AnimateableProperty.cpp
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/AnimateableProperty.h"
+
+#include <cstring>
+#include <cmath>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+AnimateableProperty::AnimateableProperty(int count) :
+ Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
+{
+ std::memset(getBuffer(), 0, count * sizeof(float));
+}
+
+AnimateableProperty::AnimateableProperty(int count, float value) :
+ Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
+{
+ sample_t* buf = getBuffer();
+
+ for(int i = 0; i < count; i++)
+ buf[i] = value;
+}
+
+void AnimateableProperty::updateUnknownCache(int start, int end)
+{
+ float* buf = getBuffer();
+
+ // we could do a better interpolation than zero order, but that doesn't work with Blender's animation system
+ // as frames are only written when changing, so to support jumps, we need zero order interpolation here.
+ for(int i = start; i <= end; i++)
+ std::memcpy(buf + i * m_count, buf + (start - 1) * m_count, m_count * sizeof(float));
+}
+
+AnimateableProperty::~AnimateableProperty()
+{
+}
+
+int AnimateableProperty::getCount() const
+{
+ return m_count;
+}
+
+void AnimateableProperty::write(const float* data)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_isAnimated = false;
+ m_unknown.clear();
+ std::memcpy(getBuffer(), data, m_count * sizeof(float));
+}
+
+void AnimateableProperty::write(const float* data, int position, int count)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ int pos = getSize() / (sizeof(float) * m_count);
+
+ if(!m_isAnimated)
+ pos = 0;
+
+ m_isAnimated = true;
+
+ assureSize((count + position) * m_count * sizeof(float), true);
+
+ float* buf = getBuffer();
+
+ std::memcpy(buf + position * m_count, data, count * m_count * sizeof(float));
+
+ // have to fill up space between?
+ if(pos < position)
+ {
+ m_unknown.push_back(Unknown(pos, position - 1));
+
+ // if the buffer was not animated before, we copy the previous static value
+ if(pos == 0)
+ pos = 1;
+
+ updateUnknownCache(pos, position - 1);
+ }
+ // otherwise it's not at the end, let's check if some unknown part got filled
+ else
+ {
+ bool erased = false;
+
+ for(auto it = m_unknown.begin(); it != m_unknown.end(); erased ? it : it++)
+ {
+ erased = false;
+
+ // unknown area before position
+ if(it->end < position)
+ continue;
+
+ // we're after the new area, let's stop
+ if(it->start >= position + count)
+ break;
+
+ // we have an intersection, now 4 cases:
+ // the start is included
+ if(position <= it->start)
+ {
+ // the end is included
+ if(position + count > it->end)
+ {
+ // simply delete
+ it = m_unknown.erase(it);
+ erased = true;
+ }
+ // the end is excluded, a second part remains
+ else
+ {
+ // update second part
+ it->start = position + count;
+ updateUnknownCache(it->start, it->end);
+ break;
+ }
+ }
+ // start is excluded, a first part remains
+ else
+ {
+ // the end is included
+ if(position + count > it->end)
+ {
+ // update first part
+ it->end = position - 1;
+ }
+ // the end is excluded, a second part remains
+ else
+ {
+ // add another item and update both parts
+ m_unknown.insert(it, Unknown(it->start, position - 1));
+ it->start = position + count;
+ updateUnknownCache(it->start, it->end);
+ }
+ }
+ }
+ }
+}
+
+void AnimateableProperty::read(float position, float* out)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(!m_isAnimated)
+ {
+ std::memcpy(out, getBuffer(), m_count * sizeof(float));
+ return;
+ }
+
+ int last = getSize() / (sizeof(float) * m_count) - 1;
+ float t = position - std::floor(position);
+
+ if(position >= last)
+ {
+ position = last;
+ t = 0;
+ }
+
+ if(t == 0)
+ {
+ std::memcpy(out, getBuffer() + int(std::floor(position)) * m_count, m_count * sizeof(float));
+ }
+ else
+ {
+ int pos = int(std::floor(position)) * m_count;
+ float t2 = t * t;
+ float t3 = t2 * t;
+ float m0, m1;
+ float* p0;
+ float* p1 = getBuffer() + pos;
+ float* p2;
+ float* p3;
+ last *= m_count;
+
+ if(pos == 0)
+ p0 = p1;
+ else
+ p0 = p1 - m_count;
+
+ p2 = p1 + m_count;
+ if(pos + m_count == last)
+ p3 = p2;
+ else
+ p3 = p2 + m_count;
+
+ for(int i = 0; i < m_count; i++)
+ {
+ m0 = (p2[i] - p0[i]) / 2.0f;
+ m1 = (p3[i] - p1[i]) / 2.0f;
+
+ out[i] = (2 * t3 - 3 * t2 + 1) * p0[i] + (-2 * t3 + 3 * t2) * p1[i] +
+ (t3 - 2 * t2 + t) * m0 + (t3 - t2) * m1;
+ }
+ }
+}
+
+bool AnimateableProperty::isAnimated() const
+{
+ return m_isAnimated;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/Double.cpp b/extern/audaspace/src/sequence/Double.cpp
new file mode 100644
index 00000000000..1086be84a11
--- /dev/null
+++ b/extern/audaspace/src/sequence/Double.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/Double.h"
+#include "sequence/DoubleReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Double::Double(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2) :
+ m_sound1(sound1), m_sound2(sound2)
+{
+}
+
+std::shared_ptr<IReader> Double::createReader()
+{
+ std::shared_ptr<IReader> reader1 = m_sound1->createReader();
+ std::shared_ptr<IReader> reader2 = m_sound2->createReader();
+
+ return std::shared_ptr<IReader>(new DoubleReader(reader1, reader2));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/DoubleReader.cpp b/extern/audaspace/src/sequence/DoubleReader.cpp
new file mode 100644
index 00000000000..33ab34ce366
--- /dev/null
+++ b/extern/audaspace/src/sequence/DoubleReader.cpp
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/DoubleReader.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+DoubleReader::DoubleReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2) :
+ m_reader1(reader1), m_reader2(reader2), m_finished1(false)
+{
+ Specs s1, s2;
+ s1 = reader1->getSpecs();
+ s2 = reader2->getSpecs();
+}
+
+DoubleReader::~DoubleReader()
+{
+}
+
+bool DoubleReader::isSeekable() const
+{
+ return m_reader1->isSeekable() && m_reader2->isSeekable();
+}
+
+void DoubleReader::seek(int position)
+{
+ m_reader1->seek(position);
+
+ int pos1 = m_reader1->getPosition();
+
+ if((m_finished1 = (pos1 < position)))
+ m_reader2->seek(position - pos1);
+ else
+ m_reader2->seek(0);
+}
+
+int DoubleReader::getLength() const
+{
+ int len1 = m_reader1->getLength();
+ int len2 = m_reader2->getLength();
+ if(len1 < 0 || len2 < 0)
+ return -1;
+ return len1 + len2;
+}
+
+int DoubleReader::getPosition() const
+{
+ return m_reader1->getPosition() + m_reader2->getPosition();
+}
+
+Specs DoubleReader::getSpecs() const
+{
+ return m_finished1 ? m_reader1->getSpecs() : m_reader2->getSpecs();
+}
+
+void DoubleReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ eos = false;
+
+ if(!m_finished1)
+ {
+ int len = length;
+
+ m_reader1->read(len, m_finished1, buffer);
+
+ if(len < length)
+ {
+ Specs specs1, specs2;
+ specs1 = m_reader1->getSpecs();
+ specs2 = m_reader2->getSpecs();
+ if(AUD_COMPARE_SPECS(specs1, specs2))
+ {
+ int len2 = length - len;
+ m_reader2->read(len2, eos, buffer + specs1.channels * len);
+ length = len + len2;
+ }
+ else
+ length = len;
+ }
+ }
+ else
+ {
+ m_reader2->read(length, eos, buffer);
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/PingPong.cpp b/extern/audaspace/src/sequence/PingPong.cpp
new file mode 100644
index 00000000000..19bfb10fc2d
--- /dev/null
+++ b/extern/audaspace/src/sequence/PingPong.cpp
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/PingPong.h"
+#include "sequence/DoubleReader.h"
+#include "fx/ReverseReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+PingPong::PingPong(std::shared_ptr<ISound> sound) :
+ Effect(sound)
+{
+}
+
+std::shared_ptr<IReader> PingPong::createReader()
+{
+ std::shared_ptr<IReader> reader = getReader();
+ std::shared_ptr<IReader> reader2 = std::shared_ptr<IReader>(new ReverseReader(getReader()));
+
+ return std::shared_ptr<IReader>(new DoubleReader(reader, reader2));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/Sequence.cpp b/extern/audaspace/src/sequence/Sequence.cpp
new file mode 100644
index 00000000000..eaec4d84ae1
--- /dev/null
+++ b/extern/audaspace/src/sequence/Sequence.cpp
@@ -0,0 +1,113 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/Sequence.h"
+#include "sequence/SequenceReader.h"
+#include "sequence/SequenceData.h"
+
+AUD_NAMESPACE_BEGIN
+
+Sequence::Sequence(Specs specs, float fps, bool muted)
+{
+ m_sequence = std::shared_ptr<SequenceData>(new SequenceData(specs, fps, muted));
+}
+
+Specs Sequence::getSpecs()
+{
+ return m_sequence->getSpecs();
+}
+
+void Sequence::setSpecs(Specs specs)
+{
+ m_sequence->setSpecs(specs);
+}
+
+float Sequence::getFPS() const
+{
+ return m_sequence->getFPS();
+}
+
+void Sequence::setFPS(float fps)
+{
+ m_sequence->setFPS(fps);
+}
+
+void Sequence::mute(bool muted)
+{
+ m_sequence->mute(muted);
+}
+
+bool Sequence::isMuted() const
+{
+ return m_sequence->isMuted();
+}
+
+float Sequence::getSpeedOfSound() const
+{
+ return m_sequence->getSpeedOfSound();
+}
+
+void Sequence::setSpeedOfSound(float speed)
+{
+ m_sequence->setSpeedOfSound(speed);
+}
+
+float Sequence::getDopplerFactor() const
+{
+ return m_sequence->getDopplerFactor();
+}
+
+void Sequence::setDopplerFactor(float factor)
+{
+ m_sequence->setDopplerFactor(factor);
+}
+
+DistanceModel Sequence::getDistanceModel() const
+{
+ return m_sequence->getDistanceModel();
+}
+
+void Sequence::setDistanceModel(DistanceModel model)
+{
+ m_sequence->setDistanceModel(model);
+}
+
+AnimateableProperty* Sequence::getAnimProperty(AnimateablePropertyType type)
+{
+ return m_sequence->getAnimProperty(type);
+}
+
+std::shared_ptr<SequenceEntry> Sequence::add(std::shared_ptr<ISound> sound, float begin, float end, float skip)
+{
+ return m_sequence->add(sound, begin, end, skip);
+}
+
+void Sequence::remove(std::shared_ptr<SequenceEntry> entry)
+{
+ m_sequence->remove(entry);
+}
+
+std::shared_ptr<IReader> Sequence::createQualityReader()
+{
+ return std::shared_ptr<IReader>(new SequenceReader(m_sequence, true));
+}
+
+std::shared_ptr<IReader> Sequence::createReader()
+{
+ return std::shared_ptr<IReader>(new SequenceReader(m_sequence));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/SequenceData.cpp b/extern/audaspace/src/sequence/SequenceData.cpp
new file mode 100644
index 00000000000..fb920acc1a8
--- /dev/null
+++ b/extern/audaspace/src/sequence/SequenceData.cpp
@@ -0,0 +1,172 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/SequenceData.h"
+#include "sequence/SequenceReader.h"
+#include "sequence/SequenceEntry.h"
+
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+SequenceData::SequenceData(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(343.3f),
+ m_doppler_factor(1),
+ m_distance_model(DISTANCE_MODEL_INVERSE_CLAMPED),
+ m_volume(1, 1.0f),
+ m_location(3),
+ m_orientation(4)
+{
+ Quaternion q;
+ m_orientation.write(q.get());
+ float f = 1;
+ m_volume.write(&f);
+}
+
+SequenceData::~SequenceData()
+{
+}
+
+void SequenceData::lock()
+{
+ m_mutex.lock();
+}
+
+void SequenceData::unlock()
+{
+ m_mutex.unlock();
+}
+
+Specs SequenceData::getSpecs()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ return m_specs;
+}
+
+void SequenceData::setSpecs(Specs specs)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_specs = specs;
+ m_status++;
+}
+
+float SequenceData::getFPS() const
+{
+ return m_fps;
+}
+
+void SequenceData::setFPS(float fps)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_fps = fps;
+}
+
+void SequenceData::mute(bool muted)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_muted = muted;
+}
+
+bool SequenceData::isMuted() const
+{
+ return m_muted;
+}
+
+float SequenceData::getSpeedOfSound() const
+{
+ return m_speed_of_sound;
+}
+
+void SequenceData::setSpeedOfSound(float speed)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_speed_of_sound = speed;
+ m_status++;
+}
+
+float SequenceData::getDopplerFactor() const
+{
+ return m_doppler_factor;
+}
+
+void SequenceData::setDopplerFactor(float factor)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_doppler_factor = factor;
+ m_status++;
+}
+
+DistanceModel SequenceData::getDistanceModel() const
+{
+ return m_distance_model;
+}
+
+void SequenceData::setDistanceModel(DistanceModel model)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_distance_model = model;
+ m_status++;
+}
+
+AnimateableProperty* SequenceData::getAnimProperty(AnimateablePropertyType type)
+{
+ switch(type)
+ {
+ case AP_VOLUME:
+ return &m_volume;
+ case AP_LOCATION:
+ return &m_location;
+ case AP_ORIENTATION:
+ return &m_orientation;
+ default:
+ return nullptr;
+ }
+}
+
+std::shared_ptr<SequenceEntry> SequenceData::add(std::shared_ptr<ISound> sound, float begin, float end, float skip)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ std::shared_ptr<SequenceEntry> entry = std::shared_ptr<SequenceEntry>(new SequenceEntry(sound, begin, end, skip, m_id++));
+
+ m_entries.push_back(entry);
+ m_entry_status++;
+
+ return entry;
+}
+
+void SequenceData::remove(std::shared_ptr<SequenceEntry> entry)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_entries.remove(entry);
+ m_entry_status++;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/SequenceEntry.cpp b/extern/audaspace/src/sequence/SequenceEntry.cpp
new file mode 100644
index 00000000000..de538199d7d
--- /dev/null
+++ b/extern/audaspace/src/sequence/SequenceEntry.cpp
@@ -0,0 +1,256 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/SequenceEntry.h"
+#include "sequence/SequenceReader.h"
+
+#include <limits>
+#include <mutex>
+
+AUD_NAMESPACE_BEGIN
+
+SequenceEntry::SequenceEntry(std::shared_ptr<ISound> sound, float begin, float end, float skip, int id) :
+ m_status(0),
+ m_pos_status(1),
+ m_sound_status(0),
+ m_id(id),
+ m_sound(sound),
+ m_begin(begin),
+ m_end(end),
+ m_skip(skip),
+ m_muted(false),
+ 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(360),
+ m_cone_angle_inner(360),
+ m_cone_volume_outer(0),
+ m_volume(1, 1.0f),
+ m_pitch(1, 1.0f),
+ m_location(3),
+ m_orientation(4)
+{
+ Quaternion q;
+ m_orientation.write(q.get());
+ float f = 1;
+ m_volume.write(&f);
+ m_pitch.write(&f);
+}
+
+SequenceEntry::~SequenceEntry()
+{
+}
+
+void SequenceEntry::lock()
+{
+ m_mutex.lock();
+}
+
+void SequenceEntry::unlock()
+{
+ m_mutex.unlock();
+}
+
+std::shared_ptr<ISound> SequenceEntry::getSound()
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+ return m_sound;
+}
+
+void SequenceEntry::setSound(std::shared_ptr<ISound> sound)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(m_sound.get() != sound.get())
+ {
+ m_sound = sound;
+ m_sound_status++;
+ }
+}
+
+void SequenceEntry::move(float begin, float end, float skip)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(m_begin != begin || m_skip != skip || m_end != end)
+ {
+ m_begin = begin;
+ m_skip = skip;
+ m_end = end;
+ m_pos_status++;
+ }
+}
+
+bool SequenceEntry::isMuted()
+{
+ return m_muted;
+}
+
+void SequenceEntry::mute(bool mute)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_muted = mute;
+}
+
+int SequenceEntry::getID() const
+{
+ return m_id;
+}
+
+AnimateableProperty* SequenceEntry::getAnimProperty(AnimateablePropertyType type)
+{
+ switch(type)
+ {
+ case AP_VOLUME:
+ return &m_volume;
+ case AP_PITCH:
+ return &m_pitch;
+ case AP_PANNING:
+ return &m_panning;
+ case AP_LOCATION:
+ return &m_location;
+ case AP_ORIENTATION:
+ return &m_orientation;
+ default:
+ return nullptr;
+ }
+}
+
+bool SequenceEntry::isRelative()
+{
+ return m_relative;
+}
+
+void SequenceEntry::setRelative(bool relative)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ if(m_relative != relative)
+ {
+ m_relative = relative;
+ m_status++;
+ }
+}
+
+float SequenceEntry::getVolumeMaximum()
+{
+ return m_volume_max;
+}
+
+void SequenceEntry::setVolumeMaximum(float volume)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_volume_max = volume;
+ m_status++;
+}
+
+float SequenceEntry::getVolumeMinimum()
+{
+ return m_volume_min;
+}
+
+void SequenceEntry::setVolumeMinimum(float volume)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_volume_min = volume;
+ m_status++;
+}
+
+float SequenceEntry::getDistanceMaximum()
+{
+ return m_distance_max;
+}
+
+void SequenceEntry::setDistanceMaximum(float distance)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_distance_max = distance;
+ m_status++;
+}
+
+float SequenceEntry::getDistanceReference()
+{
+ return m_distance_reference;
+}
+
+void SequenceEntry::setDistanceReference(float distance)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_distance_reference = distance;
+ m_status++;
+}
+
+float SequenceEntry::getAttenuation()
+{
+ return m_attenuation;
+}
+
+void SequenceEntry::setAttenuation(float factor)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_attenuation = factor;
+ m_status++;
+}
+
+float SequenceEntry::getConeAngleOuter()
+{
+ return m_cone_angle_outer;
+}
+
+void SequenceEntry::setConeAngleOuter(float angle)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_cone_angle_outer = angle;
+ m_status++;
+}
+
+float SequenceEntry::getConeAngleInner()
+{
+ return m_cone_angle_inner;
+}
+
+void SequenceEntry::setConeAngleInner(float angle)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_cone_angle_inner = angle;
+ m_status++;
+}
+
+float SequenceEntry::getConeVolumeOuter()
+{
+ return m_cone_volume_outer;
+}
+
+void SequenceEntry::setConeVolumeOuter(float volume)
+{
+ std::lock_guard<std::recursive_mutex> lock(m_mutex);
+
+ m_cone_volume_outer = volume;
+ m_status++;
+}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.cpp b/extern/audaspace/src/sequence/SequenceHandle.cpp
index aa742f7b8db..140b1fbd94a 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.cpp
+++ b/extern/audaspace/src/sequence/SequenceHandle.cpp
@@ -1,39 +1,31 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_SequencerHandle.cpp
- * \ingroup audaspaceintern
- */
+#include "SequenceHandle.h"
+#include "sequence/SequenceEntry.h"
+#include "devices/ReadDevice.h"
+#include "Exception.h"
-
-#include "AUD_SequencerHandle.h"
-#include "AUD_ReadDevice.h"
-#include "AUD_MutexLock.h"
+#include <mutex>
#define KEEP_TIME 10
-void AUD_SequencerHandle::start()
+AUD_NAMESPACE_BEGIN
+
+void SequenceHandle::start()
{
// we already tried to start, aborting
if(!m_valid)
@@ -42,7 +34,7 @@ void AUD_SequencerHandle::start()
// in case the sound is playing, we need to stop first
stop();
- AUD_MutexLock lock(*m_entry);
+ std::lock_guard<ILockable> lock(*m_entry);
// let's try playing
if(m_entry->m_sound.get())
@@ -50,9 +42,9 @@ void AUD_SequencerHandle::start()
try
{
m_handle = m_device.play(m_entry->m_sound, true);
- m_3dhandle = boost::dynamic_pointer_cast<AUD_I3DHandle>(m_handle);
+ m_3dhandle = std::dynamic_pointer_cast<I3DHandle>(m_handle);
}
- catch(AUD_Exception&)
+ catch(Exception&)
{
// handle stays invalid in case we get an exception
}
@@ -65,9 +57,9 @@ void AUD_SequencerHandle::start()
m_valid = m_handle.get();
}
-bool AUD_SequencerHandle::updatePosition(float position)
+bool SequenceHandle::updatePosition(float position)
{
- AUD_MutexLock lock(*m_entry);
+ std::lock_guard<ILockable> lock(*m_entry);
if(m_handle.get())
{
@@ -116,7 +108,7 @@ bool AUD_SequencerHandle::updatePosition(float position)
return false;
}
-AUD_SequencerHandle::AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> entry, AUD_ReadDevice& device) :
+SequenceHandle::SequenceHandle(std::shared_ptr<SequenceEntry> entry, ReadDevice& device) :
m_entry(entry),
m_valid(true),
m_status(0),
@@ -126,12 +118,12 @@ AUD_SequencerHandle::AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> e
{
}
-AUD_SequencerHandle::~AUD_SequencerHandle()
+SequenceHandle::~SequenceHandle()
{
stop();
}
-int AUD_SequencerHandle::compare(boost::shared_ptr<AUD_SequencerEntry> entry) const
+int SequenceHandle::compare(std::shared_ptr<SequenceEntry> entry) const
{
if(m_entry->getID() < entry->getID())
return -1;
@@ -140,15 +132,15 @@ int AUD_SequencerHandle::compare(boost::shared_ptr<AUD_SequencerEntry> entry) co
return 1;
}
-void AUD_SequencerHandle::stop()
+void SequenceHandle::stop()
{
if(m_handle.get())
m_handle->stop();
- m_handle = boost::shared_ptr<AUD_IHandle>();
- m_3dhandle = boost::shared_ptr<AUD_I3DHandle>();
+ m_handle = nullptr;
+ m_3dhandle = nullptr;
}
-void AUD_SequencerHandle::update(float position, float frame, float fps)
+void SequenceHandle::update(float position, float frame, float fps)
{
if(m_sound_status != m_entry->m_sound_status)
{
@@ -185,7 +177,7 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
}
}
- AUD_MutexLock lock(*m_entry);
+ std::lock_guard<ILockable> lock(*m_entry);
if(m_pos_status != m_entry->m_pos_status)
{
m_pos_status = m_entry->m_pos_status;
@@ -200,8 +192,6 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
if(m_status != m_entry->m_status)
{
- m_status = m_entry->m_status;
-
m_3dhandle->setRelative(m_entry->m_relative);
m_3dhandle->setVolumeMaximum(m_entry->m_volume_max);
m_3dhandle->setVolumeMinimum(m_entry->m_volume_min);
@@ -211,6 +201,8 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
m_3dhandle->setConeAngleOuter(m_entry->m_cone_angle_outer);
m_3dhandle->setConeAngleInner(m_entry->m_cone_angle_inner);
m_3dhandle->setConeVolumeOuter(m_entry->m_cone_volume_outer);
+
+ m_status = m_entry->m_status;
}
float value;
@@ -220,24 +212,24 @@ void AUD_SequencerHandle::update(float position, float frame, float fps)
m_entry->m_pitch.read(frame, &value);
m_handle->setPitch(value);
m_entry->m_panning.read(frame, &value);
- AUD_SoftwareDevice::setPanning(m_handle.get(), value);
+ SoftwareDevice::setPanning(m_handle.get(), value);
- AUD_Vector3 v, v2;
- AUD_Quaternion q;
+ Vector3 v, v2;
+ Quaternion q;
m_entry->m_orientation.read(frame, q.get());
- m_3dhandle->setSourceOrientation(q);
+ m_3dhandle->setOrientation(q);
m_entry->m_location.read(frame, v.get());
- m_3dhandle->setSourceLocation(v);
+ m_3dhandle->setLocation(v);
m_entry->m_location.read(frame + 1, v2.get());
v2 -= v;
- m_3dhandle->setSourceVelocity(v2 * fps);
+ m_3dhandle->setVelocity(v2 * fps);
if(m_entry->m_muted)
m_handle->setVolume(0);
}
-bool AUD_SequencerHandle::seek(float position)
+bool SequenceHandle::seek(float position)
{
if(!m_valid)
// sound not valid, aborting
@@ -247,7 +239,7 @@ bool AUD_SequencerHandle::seek(float position)
// no handle, aborting
return false;
- AUD_MutexLock lock(*m_entry);
+ std::lock_guard<ILockable> lock(*m_entry);
float seekpos = position - m_entry->m_begin;
if(seekpos < 0)
seekpos = 0;
@@ -257,3 +249,5 @@ bool AUD_SequencerHandle::seek(float position)
return true;
}
+
+AUD_NAMESPACE_END
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.h b/extern/audaspace/src/sequence/SequenceHandle.h
index 306df4a84b9..9a77489a8f8 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.h
+++ b/extern/audaspace/src/sequence/SequenceHandle.h
@@ -1,55 +1,46 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
*
- * Copyright 2009-2011 Jörg Hermann Müller
+ * 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
*
- * This file is part of AudaSpace.
+ * http://www.apache.org/licenses/LICENSE-2.0
*
- * 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 *****
- */
+ * 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.
+ ******************************************************************************/
-/** \file audaspace/intern/AUD_SequencerHandle.h
- * \ingroup audaspaceintern
- */
+#pragma once
+#include "Audaspace.h"
-#ifndef __AUD_SEQUENCERHANDLE_H__
-#define __AUD_SEQUENCERHANDLE_H__
+#include <memory>
-#include "AUD_SequencerEntry.h"
-#include "AUD_IHandle.h"
-#include "AUD_I3DHandle.h"
+AUD_NAMESPACE_BEGIN
-class AUD_ReadDevice;
+class ReadDevice;
+class IHandle;
+class I3DHandle;
+class SequenceEntry;
/**
* Represents a playing sequenced entry.
*/
-class AUD_SequencerHandle
+class SequenceHandle
{
private:
/// The entry this handle belongs to.
- boost::shared_ptr<AUD_SequencerEntry> m_entry;
+ std::shared_ptr<SequenceEntry> m_entry;
/// The handle in the read device.
- boost::shared_ptr<AUD_IHandle> m_handle;
+ std::shared_ptr<IHandle> m_handle;
/// The 3D handle in the read device.
- boost::shared_ptr<AUD_I3DHandle> m_3dhandle;
+ std::shared_ptr<I3DHandle> m_3dhandle;
/// Whether the sound is playable.
bool m_valid;
@@ -64,7 +55,11 @@ private:
int m_sound_status;
/// The read device this handle is played on.
- AUD_ReadDevice& m_device;
+ ReadDevice& m_device;
+
+ // delete copy constructor and operator=
+ SequenceHandle(const SequenceHandle&) = delete;
+ SequenceHandle& operator=(const SequenceHandle&) = delete;
/**
* Starts playing back the handle.
@@ -84,19 +79,19 @@ public:
* \param entry The entry this handle plays.
* \param device The read device to play on.
*/
- AUD_SequencerHandle(boost::shared_ptr<AUD_SequencerEntry> entry, AUD_ReadDevice& device);
+ SequenceHandle(std::shared_ptr<SequenceEntry> entry, ReadDevice& device);
/**
* Destroys the handle.
*/
- ~AUD_SequencerHandle();
+ ~SequenceHandle();
/**
* Compares whether this handle is playing the same entry as supplied.
* \param entry The entry to compare to.
* \return Whether the entries ID is smaller, equal or bigger.
*/
- int compare(boost::shared_ptr<AUD_SequencerEntry> entry) const;
+ int compare(std::shared_ptr<SequenceEntry> entry) const;
/**
* Stops playing back the handle.
@@ -119,4 +114,4 @@ public:
bool seek(float position);
};
-#endif //__AUD_SEQUENCERHANDLE_H__
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/SequenceReader.cpp b/extern/audaspace/src/sequence/SequenceReader.cpp
new file mode 100644
index 00000000000..38647aaeadf
--- /dev/null
+++ b/extern/audaspace/src/sequence/SequenceReader.cpp
@@ -0,0 +1,198 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/SequenceReader.h"
+#include "sequence/SequenceData.h"
+#include "Exception.h"
+#include "SequenceHandle.h"
+
+#include <algorithm>
+#include <mutex>
+#include <cmath>
+
+AUD_NAMESPACE_BEGIN
+
+SequenceReader::SequenceReader(std::shared_ptr<SequenceData> 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);
+}
+
+SequenceReader::~SequenceReader()
+{
+}
+
+bool SequenceReader::isSeekable() const
+{
+ return true;
+}
+
+void SequenceReader::seek(int position)
+{
+ if(position < 0)
+ return;
+
+ m_position = position;
+
+ for(auto& handle : m_handles)
+ {
+ handle->seek(position / m_sequence->m_specs.rate);
+ }
+}
+
+int SequenceReader::getLength() const
+{
+ return -1;
+}
+
+int SequenceReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs SequenceReader::getSpecs() const
+{
+ return m_sequence->m_specs;
+}
+
+void SequenceReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ std::lock_guard<ILockable> lock(*m_sequence);
+
+ if(m_sequence->m_status != m_status)
+ {
+ 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_sequence->m_status;
+ }
+
+ if(m_sequence->m_entry_status != m_entry_status)
+ {
+ std::list<std::shared_ptr<SequenceHandle> > handles;
+
+ auto hit = m_handles.begin();
+ auto eit = m_sequence->m_entries.begin();
+
+ int result;
+ std::shared_ptr<SequenceHandle> handle;
+
+ while(hit != m_handles.end() && eit != m_sequence->m_entries.end())
+ {
+ handle = *hit;
+ std::shared_ptr<SequenceEntry> entry = *eit;
+
+ result = handle->compare(entry);
+
+ if(result < 0)
+ {
+ try
+ {
+ handle = std::shared_ptr<SequenceHandle>(new SequenceHandle(entry, m_device));
+ handles.push_back(handle);
+ }
+ catch(Exception&)
+ {
+ }
+ eit++;
+ }
+ else if(result == 0)
+ {
+ handles.push_back(handle);
+ hit++;
+ eit++;
+ }
+ else
+ {
+ handle->stop();
+ hit++;
+ }
+ }
+
+ while(hit != m_handles.end())
+ {
+ (*hit)->stop();
+ hit++;
+ }
+
+ while(eit != m_sequence->m_entries.end())
+ {
+ try
+ {
+ handle = std::shared_ptr<SequenceHandle>(new SequenceHandle(*eit, m_device));
+ handles.push_back(handle);
+ }
+ catch(Exception&)
+ {
+ }
+ eit++;
+ }
+
+ m_handles = handles;
+
+ m_entry_status = m_sequence->m_entry_status;
+ }
+
+ Specs specs = m_sequence->m_specs;
+ int pos = 0;
+ float time = float(m_position) / float(specs.rate);
+ float volume, frame;
+ int len, cfra;
+ Vector3 v, v2;
+ Quaternion q;
+
+
+ while(pos < length)
+ {
+ frame = time * m_sequence->m_fps;
+ cfra = int(std::floor(frame));
+
+ len = int(std::ceil((cfra + 1) / m_sequence->m_fps * specs.rate)) - m_position;
+ len = std::min(length - pos, len);
+ len = std::max(len, 1);
+
+ for(auto& handle : m_handles)
+ {
+ handle->update(time, frame, m_sequence->m_fps);
+ }
+
+ m_sequence->m_volume.read(frame, &volume);
+ if(m_sequence->m_muted)
+ volume = 0.0f;
+ m_device.setVolume(volume);
+
+ m_sequence->m_orientation.read(frame, q.get());
+ m_device.setListenerOrientation(q);
+ m_sequence->m_location.read(frame, v.get());
+ m_device.setListenerLocation(v);
+ m_sequence->m_location.read(frame + 1, v2.get());
+ v2 -= v;
+ m_device.setListenerVelocity(v2 * m_sequence->m_fps);
+
+ m_device.read(reinterpret_cast<data_t*>(buffer + specs.channels * pos), len);
+
+ pos += len;
+ time += float(len) / float(specs.rate);
+ }
+
+ m_position += length;
+
+ eos = false;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/Superpose.cpp b/extern/audaspace/src/sequence/Superpose.cpp
new file mode 100644
index 00000000000..3d13f7db627
--- /dev/null
+++ b/extern/audaspace/src/sequence/Superpose.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/Superpose.h"
+#include "sequence/SuperposeReader.h"
+
+AUD_NAMESPACE_BEGIN
+
+Superpose::Superpose(std::shared_ptr<ISound> sound1, std::shared_ptr<ISound> sound2) :
+ m_sound1(sound1), m_sound2(sound2)
+{
+}
+
+std::shared_ptr<IReader> Superpose::createReader()
+{
+ std::shared_ptr<IReader> reader1 = m_sound1->createReader();
+ std::shared_ptr<IReader> reader2 = m_sound2->createReader();
+
+ return std::shared_ptr<IReader>(new SuperposeReader(reader1, reader2));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/sequence/SuperposeReader.cpp b/extern/audaspace/src/sequence/SuperposeReader.cpp
new file mode 100644
index 00000000000..9206a7a96ef
--- /dev/null
+++ b/extern/audaspace/src/sequence/SuperposeReader.cpp
@@ -0,0 +1,95 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "sequence/SuperposeReader.h"
+#include "Exception.h"
+
+#include <algorithm>
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+SuperposeReader::SuperposeReader(std::shared_ptr<IReader> reader1, std::shared_ptr<IReader> reader2) :
+ m_reader1(reader1), m_reader2(reader2)
+{
+}
+
+SuperposeReader::~SuperposeReader()
+{
+}
+
+bool SuperposeReader::isSeekable() const
+{
+ return m_reader1->isSeekable() && m_reader2->isSeekable();
+}
+
+void SuperposeReader::seek(int position)
+{
+ m_reader1->seek(position);
+ m_reader2->seek(position);
+}
+
+int SuperposeReader::getLength() const
+{
+ int len1 = m_reader1->getLength();
+ int len2 = m_reader2->getLength();
+ if((len1 < 0) || (len2 < 0))
+ return -1;
+ return std::min(len1, len2);
+}
+
+int SuperposeReader::getPosition() const
+{
+ int pos1 = m_reader1->getPosition();
+ int pos2 = m_reader2->getPosition();
+ return std::max(pos1, pos2);
+}
+
+Specs SuperposeReader::getSpecs() const
+{
+ return m_reader1->getSpecs();
+}
+
+void SuperposeReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ Specs specs = m_reader1->getSpecs();
+ Specs s2 = m_reader2->getSpecs();
+ if(!AUD_COMPARE_SPECS(specs, s2))
+ AUD_THROW(StateException, "Two readers with different specifiactions cannot be superposed.");
+
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_buffer.assureSize(length * samplesize);
+
+ int len1 = length;
+ m_reader1->read(len1, eos, buffer);
+
+ if(len1 < length)
+ std::memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
+
+ int len2 = length;
+ bool eos2;
+ sample_t* buf = m_buffer.getBuffer();
+ m_reader2->read(len2, eos2, buf);
+
+ for(int i = 0; i < len2 * specs.channels; i++)
+ buffer[i] += buf[i];
+
+ length = std::max(len1, len2);
+ eos &= eos2;
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/Barrier.cpp b/extern/audaspace/src/util/Barrier.cpp
new file mode 100644
index 00000000000..3347a38092b
--- /dev/null
+++ b/extern/audaspace/src/util/Barrier.cpp
@@ -0,0 +1,42 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "util/Barrier.h"
+
+AUD_NAMESPACE_BEGIN
+Barrier::Barrier(unsigned int count) :
+ m_threshold(count), m_count(count), m_generation(0)
+{
+}
+
+Barrier::~Barrier()
+{
+}
+
+void Barrier::wait()
+{
+ std::unique_lock<std::mutex> lck(m_mutex);
+ int gen = m_generation;
+ if(!--m_count)
+ {
+ m_count = m_threshold;
+ m_generation++;
+ m_condition.notify_all();
+ }
+ else
+ m_condition.wait(lck, [this, gen] { return gen != m_generation; });
+}
+AUD_NAMESPACE_END \ No newline at end of file
diff --git a/extern/audaspace/src/util/Buffer.cpp b/extern/audaspace/src/util/Buffer.cpp
new file mode 100644
index 00000000000..d212278cacc
--- /dev/null
+++ b/extern/audaspace/src/util/Buffer.cpp
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "util/Buffer.h"
+
+#include <algorithm>
+#include <cstring>
+#include <cstdlib>
+
+#define ALIGNMENT 32
+#define ALIGN(a) (a + ALIGNMENT - ((long long)a & (ALIGNMENT-1)))
+
+AUD_NAMESPACE_BEGIN
+
+Buffer::Buffer(int size)
+{
+ m_size = size;
+ m_buffer = (data_t*) std::malloc(size + ALIGNMENT);
+}
+
+Buffer::~Buffer()
+{
+ std::free(m_buffer);
+}
+
+sample_t* Buffer::getBuffer() const
+{
+ return (sample_t*) ALIGN(m_buffer);
+}
+
+int Buffer::getSize() const
+{
+ return m_size;
+}
+
+void Buffer::resize(int size, bool keep)
+{
+ if(keep)
+ {
+ data_t* buffer = (data_t*) std::malloc(size + ALIGNMENT);
+
+ std::memcpy(ALIGN(buffer), ALIGN(m_buffer), std::min(size, m_size));
+
+ std::free(m_buffer);
+ m_buffer = buffer;
+ }
+ else
+ m_buffer = (data_t*) std::realloc(m_buffer, size + ALIGNMENT);
+
+ m_size = size;
+}
+
+void Buffer::assureSize(int size, bool keep)
+{
+ if(m_size < size)
+ resize(size, keep);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/BufferReader.cpp b/extern/audaspace/src/util/BufferReader.cpp
new file mode 100644
index 00000000000..37744420ab8
--- /dev/null
+++ b/extern/audaspace/src/util/BufferReader.cpp
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "util/BufferReader.h"
+#include "util/Buffer.h"
+
+#include <cstring>
+
+AUD_NAMESPACE_BEGIN
+
+BufferReader::BufferReader(std::shared_ptr<Buffer> buffer,
+ Specs specs) :
+ m_position(0), m_buffer(buffer), m_specs(specs)
+{
+}
+
+bool BufferReader::isSeekable() const
+{
+ return true;
+}
+
+void BufferReader::seek(int position)
+{
+ m_position = position;
+}
+
+int BufferReader::getLength() const
+{
+ return m_buffer->getSize() / AUD_SAMPLE_SIZE(m_specs);
+}
+
+int BufferReader::getPosition() const
+{
+ return m_position;
+}
+
+Specs BufferReader::getSpecs() const
+{
+ return m_specs;
+}
+
+void BufferReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ eos = false;
+
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+
+ sample_t* buf = m_buffer->getBuffer() + m_position * m_specs.channels;
+
+ // in case the end of the buffer is reached
+ if(m_buffer->getSize() < (m_position + length) * sample_size)
+ {
+ length = m_buffer->getSize() / sample_size - m_position;
+ eos = true;
+ }
+
+ if(length < 0)
+ {
+ length = 0;
+ return;
+ }
+
+ m_position += length;
+ std::memcpy(buffer, buf, length * sample_size);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/FFTPlan.cpp b/extern/audaspace/src/util/FFTPlan.cpp
new file mode 100644
index 00000000000..5e99dbff247
--- /dev/null
+++ b/extern/audaspace/src/util/FFTPlan.cpp
@@ -0,0 +1,66 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "util/FFTPlan.h"
+
+AUD_NAMESPACE_BEGIN
+FFTPlan::FFTPlan(double measureTime) :
+ FFTPlan(DEFAULT_N, measureTime)
+{
+}
+
+FFTPlan::FFTPlan(int n, double measureTime) :
+ m_N(n), m_bufferSize(((n/2)+1)*2*sizeof(fftwf_complex))
+{
+ fftwf_set_timelimit(measureTime);
+ void* buf = fftwf_malloc(m_bufferSize);
+ m_fftPlanR2C = fftwf_plan_dft_r2c_1d(m_N, (float*)buf, (fftwf_complex*)buf, FFTW_EXHAUSTIVE);
+ m_fftPlanC2R = fftwf_plan_dft_c2r_1d(m_N, (fftwf_complex*)buf, (float*)buf, FFTW_EXHAUSTIVE);
+ fftwf_free(buf);
+}
+
+FFTPlan::~FFTPlan()
+{
+ fftwf_destroy_plan(m_fftPlanC2R);
+ fftwf_destroy_plan(m_fftPlanR2C);
+}
+
+int FFTPlan::getSize()
+{
+ return m_N;
+}
+
+void FFTPlan::FFT(void* buffer)
+{
+ fftwf_execute_dft_r2c(m_fftPlanR2C, (float*)buffer, (fftwf_complex*)buffer);
+}
+
+void FFTPlan::IFFT(void* buffer)
+{
+ fftwf_execute_dft_c2r(m_fftPlanC2R, (fftwf_complex*)buffer, (float*)buffer);
+}
+
+void* FFTPlan::getBuffer()
+{
+ return fftwf_malloc(m_bufferSize);
+}
+
+void FFTPlan::freeBuffer(void* buffer)
+{
+ fftwf_free(buffer);
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/StreamBuffer.cpp b/extern/audaspace/src/util/StreamBuffer.cpp
new file mode 100644
index 00000000000..b87b363377d
--- /dev/null
+++ b/extern/audaspace/src/util/StreamBuffer.cpp
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * Copyright 2009-2016 Jörg Müller
+ *
+ * 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.
+ ******************************************************************************/
+
+#include "util/StreamBuffer.h"
+#include "util/BufferReader.h"
+#include "util/Buffer.h"
+
+// 5 sec * 48000 samples/sec * 4 bytes/sample * 6 channels
+#define BUFFER_RESIZE_BYTES 5760000
+
+AUD_NAMESPACE_BEGIN
+
+StreamBuffer::StreamBuffer(std::shared_ptr<ISound> sound) :
+ m_buffer(new Buffer())
+{
+ std::shared_ptr<IReader> reader = sound->createReader();
+
+ m_specs = reader->getSpecs();
+
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+ int length;
+ int index = 0;
+ bool eos = false;
+
+ // get an approximated size if possible
+ int size = reader->getLength();
+
+ if(size <= 0)
+ size = BUFFER_RESIZE_BYTES / sample_size;
+ else
+ size += m_specs.rate;
+
+ // as long as the end of the stream is not reached
+ while(!eos)
+ {
+ // increase
+ m_buffer->resize(size*sample_size, true);
+
+ // read more
+ length = size-index;
+ reader->read(length, eos, m_buffer->getBuffer() + index * m_specs.channels);
+ if(index == m_buffer->getSize() / sample_size)
+ size += BUFFER_RESIZE_BYTES / sample_size;
+ index += length;
+ }
+
+ m_buffer->resize(index * sample_size, true);
+}
+
+StreamBuffer::StreamBuffer(std::shared_ptr<Buffer> buffer, Specs specs) :
+ m_buffer(buffer), m_specs(specs)
+{
+}
+
+std::shared_ptr<Buffer> StreamBuffer::getBuffer()
+{
+ return m_buffer;
+}
+
+Specs StreamBuffer::getSpecs()
+{
+ return m_specs;
+}
+
+std::shared_ptr<IReader> StreamBuffer::createReader()
+{
+ return std::shared_ptr<IReader>(new BufferReader(m_buffer, m_specs));
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/audaspace/src/util/ThreadPool.cpp b/extern/audaspace/src/util/ThreadPool.cpp
new file mode 100644
index 00000000000..74051902c3b
--- /dev/null
+++ b/extern/audaspace/src/util/ThreadPool.cpp
@@ -0,0 +1,60 @@
+/*******************************************************************************
+* Copyright 2015-2016 Juan Francisco Crespo Galán
+*
+* 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.
+******************************************************************************/
+
+#include "util/ThreadPool.h"
+
+AUD_NAMESPACE_BEGIN
+
+ThreadPool::ThreadPool(unsigned int count) :
+ m_stopFlag(false), m_numThreads(count)
+{
+ for(unsigned int i = 0; i < count; i++)
+ m_threads.emplace_back(&ThreadPool::threadFunction, this);
+}
+
+ThreadPool::~ThreadPool()
+{
+ m_mutex.lock();
+ m_stopFlag = true;
+ m_mutex.unlock();
+ m_condition.notify_all();
+ for(unsigned int i = 0; i < m_threads.size(); i++)
+ m_threads[i].join();
+}
+
+unsigned int ThreadPool::getNumOfThreads()
+{
+ return m_numThreads;
+}
+
+void ThreadPool::threadFunction()
+{
+ while(true)
+ {
+ std::function<void()> task;
+ {
+ std::unique_lock<std::mutex> lock(m_mutex);
+ m_condition.wait(lock, [this] { return m_stopFlag || !m_queue.empty(); });
+ if(m_stopFlag && m_queue.empty())
+ return;
+ task = std::move(m_queue.front());
+ this->m_queue.pop();
+ }
+ task();
+ }
+}
+
+AUD_NAMESPACE_END
diff --git a/extern/cuew/README.blender b/extern/cuew/README.blender
index 7b77935d750..a53a927c25f 100644
--- a/extern/cuew/README.blender
+++ b/extern/cuew/README.blender
@@ -1,5 +1,5 @@
Project: Cuda Wrangler
URL: https://github.com/CudaWrangler/cuew
License: Apache 2.0
-Upstream version: 63d2a0f
+Upstream version: cbf465b
Local modifications: None
diff --git a/extern/cuew/include/cuew.h b/extern/cuew/include/cuew.h
index 4cce29d38ab..0eace96bc3f 100644
--- a/extern/cuew/include/cuew.h
+++ b/extern/cuew/include/cuew.h
@@ -27,7 +27,7 @@ extern "C" {
#define CUEW_VERSION_MAJOR 1
#define CUEW_VERSION_MINOR 2
-#define CUDA_VERSION 7050
+#define CUDA_VERSION 8000
#define CU_IPC_HANDLE_SIZE 64
#define CU_STREAM_LEGACY ((CUstream)0x1)
#define CU_STREAM_PER_THREAD ((CUstream)0x2)
@@ -51,6 +51,8 @@ extern "C" {
#define CU_LAUNCH_PARAM_BUFFER_POINTER ((void*)0x01)
#define CU_LAUNCH_PARAM_BUFFER_SIZE ((void*)0x02)
#define CU_PARAM_TR_DEFAULT -1
+#define CU_DEVICE_CPU ((CUdevice)-1)
+#define CU_DEVICE_INVALID ((CUdevice)-2)
/* Functions which changed 3.1 -> 3.2 for 64 bit stuff,
* the cuda library has both the old ones for compatibility and new
@@ -114,12 +116,30 @@ extern "C" {
#define cuGLGetDevices cuGLGetDevices_v2
/* Types. */
+#ifdef _MSC_VER
+typedef unsigned __int32 cuuint32_t;
+typedef unsigned __int64 cuuint64_t;
+#else
+#include <stdint.h>
+typedef uint32_t cuuint32_t;
+typedef uint64_t cuuint64_t;
+#endif
+
#if defined(__x86_64) || defined(AMD64) || defined(_M_AMD64) || defined (__aarch64__)
typedef unsigned long long CUdeviceptr;
#else
typedef unsigned int CUdeviceptr;
#endif
+
+#ifdef _WIN32
+# define CUDAAPI __stdcall
+# define CUDA_CB __stdcall
+#else
+# define CUDAAPI
+# define CUDA_CB
+#endif
+
typedef int CUdevice;
typedef struct CUctx_st* CUcontext;
typedef struct CUmod_st* CUmodule;
@@ -180,6 +200,53 @@ typedef enum CUevent_flags_enum {
CU_EVENT_INTERPROCESS = 0x4,
} CUevent_flags;
+typedef enum CUstreamWaitValue_flags_enum {
+ CU_STREAM_WAIT_VALUE_GEQ = 0x0,
+ CU_STREAM_WAIT_VALUE_EQ = 0x1,
+ CU_STREAM_WAIT_VALUE_AND = 0x2,
+ CU_STREAM_WAIT_VALUE_FLUSH = (1 << 30),
+} CUstreamWaitValue_flags;
+
+typedef enum CUstreamWriteValue_flags_enum {
+ CU_STREAM_WRITE_VALUE_DEFAULT = 0x0,
+ CU_STREAM_WRITE_VALUE_NO_MEMORY_BARRIER = 0x1,
+} CUstreamWriteValue_flags;
+
+typedef enum CUstreamBatchMemOpType_enum {
+ CU_STREAM_MEM_OP_WAIT_VALUE_32 = 1,
+ CU_STREAM_MEM_OP_WRITE_VALUE_32 = 2,
+ CU_STREAM_MEM_OP_FLUSH_REMOTE_WRITES = 3,
+} CUstreamBatchMemOpType;
+
+typedef union CUstreamBatchMemOpParams_union {
+ CUstreamBatchMemOpType operation;
+ struct CUstreamMemOpWaitValueParams_st {
+ CUstreamBatchMemOpType operation;
+ CUdeviceptr address;
+ union {
+ cuuint32_t value;
+ cuuint64_t pad;
+ };
+ unsigned int flags;
+ CUdeviceptr alias;
+ } waitValue;
+ struct CUstreamMemOpWriteValueParams_st {
+ CUstreamBatchMemOpType operation;
+ CUdeviceptr address;
+ union {
+ cuuint32_t value;
+ cuuint64_t pad;
+ };
+ unsigned int flags;
+ CUdeviceptr alias;
+ } writeValue;
+ struct CUstreamMemOpFlushRemoteWritesParams_st {
+ CUstreamBatchMemOpType operation;
+ unsigned int flags;
+ } flushRemoteWrites;
+ cuuint64_t pad[6];
+} CUstreamBatchMemOpParams;
+
typedef enum CUoccupancy_flags_enum {
CU_OCCUPANCY_DEFAULT = 0x0,
CU_OCCUPANCY_DISABLE_CACHING_OVERRIDE = 0x1,
@@ -299,6 +366,12 @@ typedef enum CUdevice_attribute_enum {
CU_DEVICE_ATTRIBUTE_MANAGED_MEMORY = 83,
CU_DEVICE_ATTRIBUTE_MULTI_GPU_BOARD = 84,
CU_DEVICE_ATTRIBUTE_MULTI_GPU_BOARD_GROUP_ID = 85,
+ CU_DEVICE_ATTRIBUTE_HOST_NATIVE_ATOMIC_SUPPORTED = 86,
+ CU_DEVICE_ATTRIBUTE_SINGLE_TO_DOUBLE_PRECISION_PERF_RATIO = 87,
+ CU_DEVICE_ATTRIBUTE_PAGEABLE_MEMORY_ACCESS = 88,
+ CU_DEVICE_ATTRIBUTE_CONCURRENT_MANAGED_ACCESS = 89,
+ CU_DEVICE_ATTRIBUTE_COMPUTE_PREEMPTION_SUPPORTED = 90,
+ CU_DEVICE_ATTRIBUTE_CAN_USE_HOST_POINTER_FOR_REGISTERED_MEM = 91,
CU_DEVICE_ATTRIBUTE_MAX,
} CUdevice_attribute;
@@ -360,11 +433,26 @@ typedef enum CUmemorytype_enum {
typedef enum CUcomputemode_enum {
CU_COMPUTEMODE_DEFAULT = 0,
- CU_COMPUTEMODE_EXCLUSIVE = 1,
CU_COMPUTEMODE_PROHIBITED = 2,
CU_COMPUTEMODE_EXCLUSIVE_PROCESS = 3,
} CUcomputemode;
+typedef enum CUmem_advise_enum {
+ CU_MEM_ADVISE_SET_READ_MOSTLY = 1,
+ CU_MEM_ADVISE_UNSET_READ_MOSTLY = 2,
+ CU_MEM_ADVISE_SET_PREFERRED_LOCATION = 3,
+ CU_MEM_ADVISE_UNSET_PREFERRED_LOCATION = 4,
+ CU_MEM_ADVISE_SET_ACCESSED_BY = 5,
+ CU_MEM_ADVISE_UNSET_ACCESSED_BY = 6,
+} CUmem_advise;
+
+typedef enum CUmem_range_attribute_enum {
+ CU_MEM_RANGE_ATTRIBUTE_READ_MOSTLY = 1,
+ CU_MEM_RANGE_ATTRIBUTE_PREFERRED_LOCATION = 2,
+ CU_MEM_RANGE_ATTRIBUTE_ACCESSED_BY = 3,
+ CU_MEM_RANGE_ATTRIBUTE_LAST_PREFETCH_LOCATION = 4,
+} CUmem_range_attribute;
+
typedef enum CUjit_option_enum {
CU_JIT_MAX_REGISTERS = 0,
CU_JIT_THREADS_PER_BLOCK,
@@ -381,6 +469,8 @@ typedef enum CUjit_option_enum {
CU_JIT_LOG_VERBOSE,
CU_JIT_GENERATE_LINE_INFO,
CU_JIT_CACHE_MODE,
+ CU_JIT_NEW_SM3X_OPT,
+ CU_JIT_FAST_COMPILE,
CU_JIT_NUM_OPTIONS,
} CUjit_option;
@@ -397,6 +487,10 @@ typedef enum CUjit_target_enum {
CU_TARGET_COMPUTE_37 = 37,
CU_TARGET_COMPUTE_50 = 50,
CU_TARGET_COMPUTE_52 = 52,
+ CU_TARGET_COMPUTE_53 = 53,
+ CU_TARGET_COMPUTE_60 = 60,
+ CU_TARGET_COMPUTE_61 = 61,
+ CU_TARGET_COMPUTE_62 = 62,
} CUjit_target;
typedef enum CUjit_fallback_enum {
@@ -490,6 +584,7 @@ typedef enum cudaError_enum {
CUDA_ERROR_PEER_ACCESS_UNSUPPORTED = 217,
CUDA_ERROR_INVALID_PTX = 218,
CUDA_ERROR_INVALID_GRAPHICS_CONTEXT = 219,
+ CUDA_ERROR_NVLINK_UNCORRECTABLE = 220,
CUDA_ERROR_INVALID_SOURCE = 300,
CUDA_ERROR_FILE_NOT_FOUND = 301,
CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND = 302,
@@ -521,8 +616,14 @@ typedef enum cudaError_enum {
CUDA_ERROR_UNKNOWN = 999,
} CUresult;
-typedef void* CUstreamCallback;
-typedef size_t* CUoccupancyB2DSize;
+typedef enum CUdevice_P2PAttribute_enum {
+ CU_DEVICE_P2P_ATTRIBUTE_PERFORMANCE_RANK = 0x01,
+ CU_DEVICE_P2P_ATTRIBUTE_ACCESS_SUPPORTED = 0x02,
+ CU_DEVICE_P2P_ATTRIBUTE_NATIVE_ATOMIC_SUPPORTED = 0x03,
+} CUdevice_P2PAttribute;
+
+typedef void (CUDA_CB *CUstreamCallback)(CUstream hStream, CUresult status, void* userData);
+typedef size_t (CUDA_CB *CUoccupancyB2DSize)(int blockSize);
typedef struct CUDA_MEMCPY2D_st {
size_t srcXInBytes;
@@ -654,7 +755,8 @@ typedef struct CUDA_TEXTURE_DESC_st {
float mipmapLevelBias;
float minMipmapLevelClamp;
float maxMipmapLevelClamp;
- int reserved[16];
+ float borderColor[4];
+ int reserved[12];
} CUDA_TEXTURE_DESC;
typedef enum CUresourceViewFormat_enum {
@@ -736,21 +838,16 @@ typedef enum {
NVRTC_ERROR_INVALID_OPTION = 5,
NVRTC_ERROR_COMPILATION = 6,
NVRTC_ERROR_BUILTIN_OPERATION_FAILURE = 7,
+ NVRTC_ERROR_NO_NAME_EXPRESSIONS_AFTER_COMPILATION = 8,
+ NVRTC_ERROR_NO_LOWERED_NAMES_BEFORE_COMPILATION = 9,
+ NVRTC_ERROR_NAME_EXPRESSION_NOT_VALID = 10,
+ NVRTC_ERROR_INTERNAL_ERROR = 11,
} nvrtcResult;
typedef struct _nvrtcProgram* nvrtcProgram;
-
-#ifdef _WIN32
-# define CUDAAPI __stdcall
-# define CUDA_CB __stdcall
-#else
-# define CUDAAPI
-# define CUDA_CB
-#endif
-
/* Function types. */
-typedef CUresult CUDAAPI tcuGetErrorString(CUresult error, const char* pStr);
-typedef CUresult CUDAAPI tcuGetErrorName(CUresult error, const char* pStr);
+typedef CUresult CUDAAPI tcuGetErrorString(CUresult error, const char** pStr);
+typedef CUresult CUDAAPI tcuGetErrorName(CUresult error, const char** pStr);
typedef CUresult CUDAAPI tcuInit(unsigned int Flags);
typedef CUresult CUDAAPI tcuDriverGetVersion(int* driverVersion);
typedef CUresult CUDAAPI tcuDeviceGet(CUdevice* device, int ordinal);
@@ -786,26 +883,26 @@ typedef CUresult CUDAAPI tcuCtxAttach(CUcontext* pctx, unsigned int flags);
typedef CUresult CUDAAPI tcuCtxDetach(CUcontext ctx);
typedef CUresult CUDAAPI tcuModuleLoad(CUmodule* module, const char* fname);
typedef CUresult CUDAAPI tcuModuleLoadData(CUmodule* module, const void* image);
-typedef CUresult CUDAAPI tcuModuleLoadDataEx(CUmodule* module, const void* image, unsigned int numOptions, CUjit_option* options, void* optionValues);
+typedef CUresult CUDAAPI tcuModuleLoadDataEx(CUmodule* module, const void* image, unsigned int numOptions, CUjit_option* options, void** optionValues);
typedef CUresult CUDAAPI tcuModuleLoadFatBinary(CUmodule* module, const void* fatCubin);
typedef CUresult CUDAAPI tcuModuleUnload(CUmodule hmod);
typedef CUresult CUDAAPI tcuModuleGetFunction(CUfunction* hfunc, CUmodule hmod, const char* name);
typedef CUresult CUDAAPI tcuModuleGetGlobal_v2(CUdeviceptr* dptr, size_t* bytes, CUmodule hmod, const char* name);
typedef CUresult CUDAAPI tcuModuleGetTexRef(CUtexref* pTexRef, CUmodule hmod, const char* name);
typedef CUresult CUDAAPI tcuModuleGetSurfRef(CUsurfref* pSurfRef, CUmodule hmod, const char* name);
-typedef CUresult CUDAAPI tcuLinkCreate_v2(unsigned int numOptions, CUjit_option* options, void* optionValues, CUlinkState* stateOut);
-typedef CUresult CUDAAPI tcuLinkAddData_v2(CUlinkState state, CUjitInputType type, void* data, size_t size, const char* name, unsigned int numOptions, CUjit_option* options, void* optionValues);
-typedef CUresult CUDAAPI tcuLinkAddFile_v2(CUlinkState state, CUjitInputType type, const char* path, unsigned int numOptions, CUjit_option* options, void* optionValues);
-typedef CUresult CUDAAPI tcuLinkComplete(CUlinkState state, void* cubinOut, size_t* sizeOut);
+typedef CUresult CUDAAPI tcuLinkCreate_v2(unsigned int numOptions, CUjit_option* options, void** optionValues, CUlinkState* stateOut);
+typedef CUresult CUDAAPI tcuLinkAddData_v2(CUlinkState state, CUjitInputType type, void* data, size_t size, const char* name, unsigned int numOptions, CUjit_option* options, void** optionValues);
+typedef CUresult CUDAAPI tcuLinkAddFile_v2(CUlinkState state, CUjitInputType type, const char* path, unsigned int numOptions, CUjit_option* options, void** optionValues);
+typedef CUresult CUDAAPI tcuLinkComplete(CUlinkState state, void** cubinOut, size_t* sizeOut);
typedef CUresult CUDAAPI tcuLinkDestroy(CUlinkState state);
typedef CUresult CUDAAPI tcuMemGetInfo_v2(size_t* free, size_t* total);
typedef CUresult CUDAAPI tcuMemAlloc_v2(CUdeviceptr* dptr, size_t bytesize);
typedef CUresult CUDAAPI tcuMemAllocPitch_v2(CUdeviceptr* dptr, size_t* pPitch, size_t WidthInBytes, size_t Height, unsigned int ElementSizeBytes);
typedef CUresult CUDAAPI tcuMemFree_v2(CUdeviceptr dptr);
typedef CUresult CUDAAPI tcuMemGetAddressRange_v2(CUdeviceptr* pbase, size_t* psize, CUdeviceptr dptr);
-typedef CUresult CUDAAPI tcuMemAllocHost_v2(void* pp, size_t bytesize);
+typedef CUresult CUDAAPI tcuMemAllocHost_v2(void** pp, size_t bytesize);
typedef CUresult CUDAAPI tcuMemFreeHost(void* p);
-typedef CUresult CUDAAPI tcuMemHostAlloc(void* pp, size_t bytesize, unsigned int Flags);
+typedef CUresult CUDAAPI tcuMemHostAlloc(void** pp, size_t bytesize, unsigned int Flags);
typedef CUresult CUDAAPI tcuMemHostGetDevicePointer_v2(CUdeviceptr* pdptr, void* p, unsigned int Flags);
typedef CUresult CUDAAPI tcuMemHostGetFlags(unsigned int* pFlags, void* p);
typedef CUresult CUDAAPI tcuMemAllocManaged(CUdeviceptr* dptr, size_t bytesize, unsigned int flags);
@@ -863,8 +960,12 @@ typedef CUresult CUDAAPI tcuMipmappedArrayCreate(CUmipmappedArray* pHandle, cons
typedef CUresult CUDAAPI tcuMipmappedArrayGetLevel(CUarray* pLevelArray, CUmipmappedArray hMipmappedArray, unsigned int level);
typedef CUresult CUDAAPI tcuMipmappedArrayDestroy(CUmipmappedArray hMipmappedArray);
typedef CUresult CUDAAPI tcuPointerGetAttribute(void* data, CUpointer_attribute attribute, CUdeviceptr ptr);
+typedef CUresult CUDAAPI tcuMemPrefetchAsync(CUdeviceptr devPtr, size_t count, CUdevice dstDevice, CUstream hStream);
+typedef CUresult CUDAAPI tcuMemAdvise(CUdeviceptr devPtr, size_t count, CUmem_advise advice, CUdevice device);
+typedef CUresult CUDAAPI tcuMemRangeGetAttribute(void* data, size_t dataSize, CUmem_range_attribute attribute, CUdeviceptr devPtr, size_t count);
+typedef CUresult CUDAAPI tcuMemRangeGetAttributes(void** data, size_t* dataSizes, CUmem_range_attribute* attributes, size_t numAttributes, CUdeviceptr devPtr, size_t count);
typedef CUresult CUDAAPI tcuPointerSetAttribute(const void* value, CUpointer_attribute attribute, CUdeviceptr ptr);
-typedef CUresult CUDAAPI tcuPointerGetAttributes(unsigned int numAttributes, CUpointer_attribute* attributes, void* data, CUdeviceptr ptr);
+typedef CUresult CUDAAPI tcuPointerGetAttributes(unsigned int numAttributes, CUpointer_attribute* attributes, void** data, CUdeviceptr ptr);
typedef CUresult CUDAAPI tcuStreamCreate(CUstream* phStream, unsigned int Flags);
typedef CUresult CUDAAPI tcuStreamCreateWithPriority(CUstream* phStream, unsigned int flags, int priority);
typedef CUresult CUDAAPI tcuStreamGetPriority(CUstream hStream, int* priority);
@@ -881,10 +982,13 @@ typedef CUresult CUDAAPI tcuEventQuery(CUevent hEvent);
typedef CUresult CUDAAPI tcuEventSynchronize(CUevent hEvent);
typedef CUresult CUDAAPI tcuEventDestroy_v2(CUevent hEvent);
typedef CUresult CUDAAPI tcuEventElapsedTime(float* pMilliseconds, CUevent hStart, CUevent hEnd);
+typedef CUresult CUDAAPI tcuStreamWaitValue32(CUstream stream, CUdeviceptr addr, cuuint32_t value, unsigned int flags);
+typedef CUresult CUDAAPI tcuStreamWriteValue32(CUstream stream, CUdeviceptr addr, cuuint32_t value, unsigned int flags);
+typedef CUresult CUDAAPI tcuStreamBatchMemOp(CUstream stream, unsigned int count, CUstreamBatchMemOpParams* paramArray, unsigned int flags);
typedef CUresult CUDAAPI tcuFuncGetAttribute(int* pi, CUfunction_attribute attrib, CUfunction hfunc);
typedef CUresult CUDAAPI tcuFuncSetCacheConfig(CUfunction hfunc, CUfunc_cache config);
typedef CUresult CUDAAPI tcuFuncSetSharedMemConfig(CUfunction hfunc, CUsharedconfig config);
-typedef CUresult CUDAAPI tcuLaunchKernel(CUfunction f, unsigned int gridDimX, unsigned int gridDimY, unsigned int gridDimZ, unsigned int blockDimX, unsigned int blockDimY, unsigned int blockDimZ, unsigned int sharedMemBytes, CUstream hStream, void* kernelParams, void* extra);
+typedef CUresult CUDAAPI tcuLaunchKernel(CUfunction f, unsigned int gridDimX, unsigned int gridDimY, unsigned int gridDimZ, unsigned int blockDimX, unsigned int blockDimY, unsigned int blockDimZ, unsigned int sharedMemBytes, CUstream hStream, void** kernelParams, void** extra);
typedef CUresult CUDAAPI tcuFuncSetBlockShape(CUfunction hfunc, int x, int y, int z);
typedef CUresult CUDAAPI tcuFuncSetSharedSize(CUfunction hfunc, unsigned int bytes);
typedef CUresult CUDAAPI tcuParamSetSize(CUfunction hfunc, unsigned int numbytes);
@@ -910,6 +1014,7 @@ typedef CUresult CUDAAPI tcuTexRefSetMipmapFilterMode(CUtexref hTexRef, CUfilter
typedef CUresult CUDAAPI tcuTexRefSetMipmapLevelBias(CUtexref hTexRef, float bias);
typedef CUresult CUDAAPI tcuTexRefSetMipmapLevelClamp(CUtexref hTexRef, float minMipmapLevelClamp, float maxMipmapLevelClamp);
typedef CUresult CUDAAPI tcuTexRefSetMaxAnisotropy(CUtexref hTexRef, unsigned int maxAniso);
+typedef CUresult CUDAAPI tcuTexRefSetBorderColor(CUtexref hTexRef, float* pBorderColor);
typedef CUresult CUDAAPI tcuTexRefSetFlags(CUtexref hTexRef, unsigned int Flags);
typedef CUresult CUDAAPI tcuTexRefGetAddress_v2(CUdeviceptr* pdptr, CUtexref hTexRef);
typedef CUresult CUDAAPI tcuTexRefGetArray(CUarray* phArray, CUtexref hTexRef);
@@ -921,6 +1026,7 @@ typedef CUresult CUDAAPI tcuTexRefGetMipmapFilterMode(CUfilter_mode* pfm, CUtexr
typedef CUresult CUDAAPI tcuTexRefGetMipmapLevelBias(float* pbias, CUtexref hTexRef);
typedef CUresult CUDAAPI tcuTexRefGetMipmapLevelClamp(float* pminMipmapLevelClamp, float* pmaxMipmapLevelClamp, CUtexref hTexRef);
typedef CUresult CUDAAPI tcuTexRefGetMaxAnisotropy(int* pmaxAniso, CUtexref hTexRef);
+typedef CUresult CUDAAPI tcuTexRefGetBorderColor(float* pBorderColor, CUtexref hTexRef);
typedef CUresult CUDAAPI tcuTexRefGetFlags(unsigned int* pFlags, CUtexref hTexRef);
typedef CUresult CUDAAPI tcuTexRefCreate(CUtexref* pTexRef);
typedef CUresult CUDAAPI tcuTexRefDestroy(CUtexref hTexRef);
@@ -935,6 +1041,7 @@ typedef CUresult CUDAAPI tcuSurfObjectCreate(CUsurfObject* pSurfObject, const CU
typedef CUresult CUDAAPI tcuSurfObjectDestroy(CUsurfObject surfObject);
typedef CUresult CUDAAPI tcuSurfObjectGetResourceDesc(CUDA_RESOURCE_DESC* pResDesc, CUsurfObject surfObject);
typedef CUresult CUDAAPI tcuDeviceCanAccessPeer(int* canAccessPeer, CUdevice dev, CUdevice peerDev);
+typedef CUresult CUDAAPI tcuDeviceGetP2PAttribute(int* value, CUdevice_P2PAttribute attrib, CUdevice srcDevice, CUdevice dstDevice);
typedef CUresult CUDAAPI tcuCtxEnablePeerAccess(CUcontext peerContext, unsigned int Flags);
typedef CUresult CUDAAPI tcuCtxDisablePeerAccess(CUcontext peerContext);
typedef CUresult CUDAAPI tcuGraphicsUnregisterResource(CUgraphicsResource resource);
@@ -944,7 +1051,7 @@ typedef CUresult CUDAAPI tcuGraphicsResourceGetMappedPointer_v2(CUdeviceptr* pDe
typedef CUresult CUDAAPI tcuGraphicsResourceSetMapFlags_v2(CUgraphicsResource resource, unsigned int flags);
typedef CUresult CUDAAPI tcuGraphicsMapResources(unsigned int count, CUgraphicsResource* resources, CUstream hStream);
typedef CUresult CUDAAPI tcuGraphicsUnmapResources(unsigned int count, CUgraphicsResource* resources, CUstream hStream);
-typedef CUresult CUDAAPI tcuGetExportTable(const void* ppExportTable, const CUuuid* pExportTableId);
+typedef CUresult CUDAAPI tcuGetExportTable(const void** ppExportTable, const CUuuid* pExportTableId);
typedef CUresult CUDAAPI tcuGraphicsGLRegisterBuffer(CUgraphicsResource* pCudaResource, GLuint buffer, unsigned int Flags);
typedef CUresult CUDAAPI tcuGraphicsGLRegisterImage(CUgraphicsResource* pCudaResource, GLuint image, GLenum target, unsigned int Flags);
@@ -961,13 +1068,15 @@ typedef CUresult CUDAAPI tcuGLUnmapBufferObjectAsync(GLuint buffer, CUstream hSt
typedef const char* CUDAAPI tnvrtcGetErrorString(nvrtcResult result);
typedef nvrtcResult CUDAAPI tnvrtcVersion(int* major, int* minor);
-typedef nvrtcResult CUDAAPI tnvrtcCreateProgram(nvrtcProgram* prog, const char* src, const char* name, int numHeaders, const char* headers, const char* includeNames);
+typedef nvrtcResult CUDAAPI tnvrtcCreateProgram(nvrtcProgram* prog, const char* src, const char* name, int numHeaders, const char** headers, const char** includeNames);
typedef nvrtcResult CUDAAPI tnvrtcDestroyProgram(nvrtcProgram* prog);
-typedef nvrtcResult CUDAAPI tnvrtcCompileProgram(nvrtcProgram prog, int numOptions, const char* options);
+typedef nvrtcResult CUDAAPI tnvrtcCompileProgram(nvrtcProgram prog, int numOptions, const char** options);
typedef nvrtcResult CUDAAPI tnvrtcGetPTXSize(nvrtcProgram prog, size_t* ptxSizeRet);
typedef nvrtcResult CUDAAPI tnvrtcGetPTX(nvrtcProgram prog, char* ptx);
typedef nvrtcResult CUDAAPI tnvrtcGetProgramLogSize(nvrtcProgram prog, size_t* logSizeRet);
typedef nvrtcResult CUDAAPI tnvrtcGetProgramLog(nvrtcProgram prog, char* log);
+typedef nvrtcResult CUDAAPI tnvrtcAddNameExpression(nvrtcProgram prog, const char* name_expression);
+typedef nvrtcResult CUDAAPI tnvrtcGetLoweredName(nvrtcProgram prog, const char* name_expression, const char** lowered_name);
/* Function declarations. */
@@ -1085,6 +1194,10 @@ extern tcuMipmappedArrayCreate *cuMipmappedArrayCreate;
extern tcuMipmappedArrayGetLevel *cuMipmappedArrayGetLevel;
extern tcuMipmappedArrayDestroy *cuMipmappedArrayDestroy;
extern tcuPointerGetAttribute *cuPointerGetAttribute;
+extern tcuMemPrefetchAsync *cuMemPrefetchAsync;
+extern tcuMemAdvise *cuMemAdvise;
+extern tcuMemRangeGetAttribute *cuMemRangeGetAttribute;
+extern tcuMemRangeGetAttributes *cuMemRangeGetAttributes;
extern tcuPointerSetAttribute *cuPointerSetAttribute;
extern tcuPointerGetAttributes *cuPointerGetAttributes;
extern tcuStreamCreate *cuStreamCreate;
@@ -1103,6 +1216,9 @@ extern tcuEventQuery *cuEventQuery;
extern tcuEventSynchronize *cuEventSynchronize;
extern tcuEventDestroy_v2 *cuEventDestroy_v2;
extern tcuEventElapsedTime *cuEventElapsedTime;
+extern tcuStreamWaitValue32 *cuStreamWaitValue32;
+extern tcuStreamWriteValue32 *cuStreamWriteValue32;
+extern tcuStreamBatchMemOp *cuStreamBatchMemOp;
extern tcuFuncGetAttribute *cuFuncGetAttribute;
extern tcuFuncSetCacheConfig *cuFuncSetCacheConfig;
extern tcuFuncSetSharedMemConfig *cuFuncSetSharedMemConfig;
@@ -1132,6 +1248,7 @@ extern tcuTexRefSetMipmapFilterMode *cuTexRefSetMipmapFilterMode;
extern tcuTexRefSetMipmapLevelBias *cuTexRefSetMipmapLevelBias;
extern tcuTexRefSetMipmapLevelClamp *cuTexRefSetMipmapLevelClamp;
extern tcuTexRefSetMaxAnisotropy *cuTexRefSetMaxAnisotropy;
+extern tcuTexRefSetBorderColor *cuTexRefSetBorderColor;
extern tcuTexRefSetFlags *cuTexRefSetFlags;
extern tcuTexRefGetAddress_v2 *cuTexRefGetAddress_v2;
extern tcuTexRefGetArray *cuTexRefGetArray;
@@ -1143,6 +1260,7 @@ extern tcuTexRefGetMipmapFilterMode *cuTexRefGetMipmapFilterMode;
extern tcuTexRefGetMipmapLevelBias *cuTexRefGetMipmapLevelBias;
extern tcuTexRefGetMipmapLevelClamp *cuTexRefGetMipmapLevelClamp;
extern tcuTexRefGetMaxAnisotropy *cuTexRefGetMaxAnisotropy;
+extern tcuTexRefGetBorderColor *cuTexRefGetBorderColor;
extern tcuTexRefGetFlags *cuTexRefGetFlags;
extern tcuTexRefCreate *cuTexRefCreate;
extern tcuTexRefDestroy *cuTexRefDestroy;
@@ -1157,6 +1275,7 @@ extern tcuSurfObjectCreate *cuSurfObjectCreate;
extern tcuSurfObjectDestroy *cuSurfObjectDestroy;
extern tcuSurfObjectGetResourceDesc *cuSurfObjectGetResourceDesc;
extern tcuDeviceCanAccessPeer *cuDeviceCanAccessPeer;
+extern tcuDeviceGetP2PAttribute *cuDeviceGetP2PAttribute;
extern tcuCtxEnablePeerAccess *cuCtxEnablePeerAccess;
extern tcuCtxDisablePeerAccess *cuCtxDisablePeerAccess;
extern tcuGraphicsUnregisterResource *cuGraphicsUnregisterResource;
@@ -1190,6 +1309,8 @@ extern tnvrtcGetPTXSize *nvrtcGetPTXSize;
extern tnvrtcGetPTX *nvrtcGetPTX;
extern tnvrtcGetProgramLogSize *nvrtcGetProgramLogSize;
extern tnvrtcGetProgramLog *nvrtcGetProgramLog;
+extern tnvrtcAddNameExpression *nvrtcAddNameExpression;
+extern tnvrtcGetLoweredName *nvrtcGetLoweredName;
enum {
diff --git a/extern/cuew/src/cuew.c b/extern/cuew/src/cuew.c
index c96ea2c1959..962059bfcce 100644
--- a/extern/cuew/src/cuew.c
+++ b/extern/cuew/src/cuew.c
@@ -184,6 +184,10 @@ tcuMipmappedArrayCreate *cuMipmappedArrayCreate;
tcuMipmappedArrayGetLevel *cuMipmappedArrayGetLevel;
tcuMipmappedArrayDestroy *cuMipmappedArrayDestroy;
tcuPointerGetAttribute *cuPointerGetAttribute;
+tcuMemPrefetchAsync *cuMemPrefetchAsync;
+tcuMemAdvise *cuMemAdvise;
+tcuMemRangeGetAttribute *cuMemRangeGetAttribute;
+tcuMemRangeGetAttributes *cuMemRangeGetAttributes;
tcuPointerSetAttribute *cuPointerSetAttribute;
tcuPointerGetAttributes *cuPointerGetAttributes;
tcuStreamCreate *cuStreamCreate;
@@ -202,6 +206,9 @@ tcuEventQuery *cuEventQuery;
tcuEventSynchronize *cuEventSynchronize;
tcuEventDestroy_v2 *cuEventDestroy_v2;
tcuEventElapsedTime *cuEventElapsedTime;
+tcuStreamWaitValue32 *cuStreamWaitValue32;
+tcuStreamWriteValue32 *cuStreamWriteValue32;
+tcuStreamBatchMemOp *cuStreamBatchMemOp;
tcuFuncGetAttribute *cuFuncGetAttribute;
tcuFuncSetCacheConfig *cuFuncSetCacheConfig;
tcuFuncSetSharedMemConfig *cuFuncSetSharedMemConfig;
@@ -231,6 +238,7 @@ tcuTexRefSetMipmapFilterMode *cuTexRefSetMipmapFilterMode;
tcuTexRefSetMipmapLevelBias *cuTexRefSetMipmapLevelBias;
tcuTexRefSetMipmapLevelClamp *cuTexRefSetMipmapLevelClamp;
tcuTexRefSetMaxAnisotropy *cuTexRefSetMaxAnisotropy;
+tcuTexRefSetBorderColor *cuTexRefSetBorderColor;
tcuTexRefSetFlags *cuTexRefSetFlags;
tcuTexRefGetAddress_v2 *cuTexRefGetAddress_v2;
tcuTexRefGetArray *cuTexRefGetArray;
@@ -242,6 +250,7 @@ tcuTexRefGetMipmapFilterMode *cuTexRefGetMipmapFilterMode;
tcuTexRefGetMipmapLevelBias *cuTexRefGetMipmapLevelBias;
tcuTexRefGetMipmapLevelClamp *cuTexRefGetMipmapLevelClamp;
tcuTexRefGetMaxAnisotropy *cuTexRefGetMaxAnisotropy;
+tcuTexRefGetBorderColor *cuTexRefGetBorderColor;
tcuTexRefGetFlags *cuTexRefGetFlags;
tcuTexRefCreate *cuTexRefCreate;
tcuTexRefDestroy *cuTexRefDestroy;
@@ -256,6 +265,7 @@ tcuSurfObjectCreate *cuSurfObjectCreate;
tcuSurfObjectDestroy *cuSurfObjectDestroy;
tcuSurfObjectGetResourceDesc *cuSurfObjectGetResourceDesc;
tcuDeviceCanAccessPeer *cuDeviceCanAccessPeer;
+tcuDeviceGetP2PAttribute *cuDeviceGetP2PAttribute;
tcuCtxEnablePeerAccess *cuCtxEnablePeerAccess;
tcuCtxDisablePeerAccess *cuCtxDisablePeerAccess;
tcuGraphicsUnregisterResource *cuGraphicsUnregisterResource;
@@ -289,6 +299,8 @@ tnvrtcGetPTXSize *nvrtcGetPTXSize;
tnvrtcGetPTX *nvrtcGetPTX;
tnvrtcGetProgramLogSize *nvrtcGetProgramLogSize;
tnvrtcGetProgramLog *nvrtcGetProgramLog;
+tnvrtcAddNameExpression *nvrtcAddNameExpression;
+tnvrtcGetLoweredName *nvrtcGetLoweredName;
static DynamicLibrary dynamic_library_open_find(const char **paths) {
@@ -486,6 +498,10 @@ int cuewInit(void) {
CUDA_LIBRARY_FIND(cuMipmappedArrayGetLevel);
CUDA_LIBRARY_FIND(cuMipmappedArrayDestroy);
CUDA_LIBRARY_FIND(cuPointerGetAttribute);
+ CUDA_LIBRARY_FIND(cuMemPrefetchAsync);
+ CUDA_LIBRARY_FIND(cuMemAdvise);
+ CUDA_LIBRARY_FIND(cuMemRangeGetAttribute);
+ CUDA_LIBRARY_FIND(cuMemRangeGetAttributes);
CUDA_LIBRARY_FIND(cuPointerSetAttribute);
CUDA_LIBRARY_FIND(cuPointerGetAttributes);
CUDA_LIBRARY_FIND(cuStreamCreate);
@@ -504,6 +520,9 @@ int cuewInit(void) {
CUDA_LIBRARY_FIND(cuEventSynchronize);
CUDA_LIBRARY_FIND(cuEventDestroy_v2);
CUDA_LIBRARY_FIND(cuEventElapsedTime);
+ CUDA_LIBRARY_FIND(cuStreamWaitValue32);
+ CUDA_LIBRARY_FIND(cuStreamWriteValue32);
+ CUDA_LIBRARY_FIND(cuStreamBatchMemOp);
CUDA_LIBRARY_FIND(cuFuncGetAttribute);
CUDA_LIBRARY_FIND(cuFuncSetCacheConfig);
CUDA_LIBRARY_FIND(cuFuncSetSharedMemConfig);
@@ -533,6 +552,7 @@ int cuewInit(void) {
CUDA_LIBRARY_FIND(cuTexRefSetMipmapLevelBias);
CUDA_LIBRARY_FIND(cuTexRefSetMipmapLevelClamp);
CUDA_LIBRARY_FIND(cuTexRefSetMaxAnisotropy);
+ CUDA_LIBRARY_FIND(cuTexRefSetBorderColor);
CUDA_LIBRARY_FIND(cuTexRefSetFlags);
CUDA_LIBRARY_FIND(cuTexRefGetAddress_v2);
CUDA_LIBRARY_FIND(cuTexRefGetArray);
@@ -544,6 +564,7 @@ int cuewInit(void) {
CUDA_LIBRARY_FIND(cuTexRefGetMipmapLevelBias);
CUDA_LIBRARY_FIND(cuTexRefGetMipmapLevelClamp);
CUDA_LIBRARY_FIND(cuTexRefGetMaxAnisotropy);
+ CUDA_LIBRARY_FIND(cuTexRefGetBorderColor);
CUDA_LIBRARY_FIND(cuTexRefGetFlags);
CUDA_LIBRARY_FIND(cuTexRefCreate);
CUDA_LIBRARY_FIND(cuTexRefDestroy);
@@ -558,6 +579,7 @@ int cuewInit(void) {
CUDA_LIBRARY_FIND(cuSurfObjectDestroy);
CUDA_LIBRARY_FIND(cuSurfObjectGetResourceDesc);
CUDA_LIBRARY_FIND(cuDeviceCanAccessPeer);
+ CUDA_LIBRARY_FIND(cuDeviceGetP2PAttribute);
CUDA_LIBRARY_FIND(cuCtxEnablePeerAccess);
CUDA_LIBRARY_FIND(cuCtxDisablePeerAccess);
CUDA_LIBRARY_FIND(cuGraphicsUnregisterResource);
@@ -593,6 +615,8 @@ int cuewInit(void) {
NVRTC_LIBRARY_FIND(nvrtcGetPTX);
NVRTC_LIBRARY_FIND(nvrtcGetProgramLogSize);
NVRTC_LIBRARY_FIND(nvrtcGetProgramLog);
+ NVRTC_LIBRARY_FIND(nvrtcAddNameExpression);
+ NVRTC_LIBRARY_FIND(nvrtcGetLoweredName);
}
result = CUEW_SUCCESS;
@@ -630,6 +654,7 @@ const char *cuewErrorString(CUresult result) {
case CUDA_ERROR_PEER_ACCESS_UNSUPPORTED: return "Peer access unsupported";
case CUDA_ERROR_INVALID_PTX: return "Invalid ptx";
case CUDA_ERROR_INVALID_GRAPHICS_CONTEXT: return "Invalid graphics context";
+ case CUDA_ERROR_NVLINK_UNCORRECTABLE: return "Nvlink uncorrectable";
case CUDA_ERROR_INVALID_SOURCE: return "Invalid source";
case CUDA_ERROR_FILE_NOT_FOUND: return "File not found";
case CUDA_ERROR_SHARED_OBJECT_SYMBOL_NOT_FOUND: return "Link to a shared object failed to resolve";
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index dd446613fd0..e359a631532 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -24,9 +24,6 @@ remove_strict_flags()
if(CMAKE_COMPILER_IS_GNUCC)
remove_cc_flag("-Wunused-macros")
endif()
-
-if(WITH_SYSTEM_AUDASPACE)
-
set(INC
.
)
@@ -52,305 +49,4 @@ if(WITH_PYTHON)
add_definitions(-DWITH_PYTHON)
endif()
-else()
-
-set(INC
- .
- FX
- intern
- ../ffmpeg
-)
-
-set(INC_SYS
- ${PTHREADS_INCLUDE_DIRS}
- ${BOOST_INCLUDE_DIR}
-)
-
-set(SRC
- FX/AUD_AccumulatorFactory.cpp
- FX/AUD_BandpassCalculator.cpp
- FX/AUD_BaseIIRFilterReader.cpp
- FX/AUD_ButterworthCalculator.cpp
- FX/AUD_ButterworthFactory.cpp
- FX/AUD_CallbackIIRFilterReader.cpp
- FX/AUD_DelayFactory.cpp
- FX/AUD_DelayReader.cpp
- FX/AUD_DoubleFactory.cpp
- FX/AUD_DoubleReader.cpp
- FX/AUD_DynamicIIRFilterFactory.cpp
- FX/AUD_DynamicIIRFilterReader.cpp
- FX/AUD_EffectFactory.cpp
- FX/AUD_EffectReader.cpp
- FX/AUD_EnvelopeFactory.cpp
- FX/AUD_FaderFactory.cpp
- FX/AUD_FaderReader.cpp
- FX/AUD_HighpassCalculator.cpp
- FX/AUD_HighpassFactory.cpp
- FX/AUD_IIRFilterFactory.cpp
- FX/AUD_IIRFilterReader.cpp
- FX/AUD_LimiterFactory.cpp
- FX/AUD_LimiterReader.cpp
- FX/AUD_LoopFactory.cpp
- FX/AUD_LoopReader.cpp
- FX/AUD_LowpassCalculator.cpp
- FX/AUD_LowpassFactory.cpp
- FX/AUD_PingPongFactory.cpp
- FX/AUD_PitchFactory.cpp
- FX/AUD_PitchReader.cpp
- FX/AUD_RectifyFactory.cpp
- FX/AUD_ReverseFactory.cpp
- FX/AUD_ReverseReader.cpp
- FX/AUD_SquareFactory.cpp
- FX/AUD_SumFactory.cpp
- FX/AUD_SuperposeFactory.cpp
- FX/AUD_SuperposeReader.cpp
- FX/AUD_VolumeFactory.cpp
-
- intern/AUD_3DMath.h
- intern/AUD_AnimateableProperty.cpp
- intern/AUD_AnimateableProperty.h
- intern/AUD_Buffer.cpp
- intern/AUD_Buffer.h
- intern/AUD_BufferReader.cpp
- intern/AUD_BufferReader.h
- intern/AUD_C-API.cpp
- intern/AUD_C-API.h
- intern/AUD_ChannelMapperFactory.cpp
- intern/AUD_ChannelMapperFactory.h
- intern/AUD_ChannelMapperReader.cpp
- intern/AUD_ChannelMapperReader.h
- intern/AUD_ConverterFactory.cpp
- intern/AUD_ConverterFactory.h
- intern/AUD_ConverterFunctions.cpp
- intern/AUD_ConverterFunctions.h
- intern/AUD_ConverterReader.cpp
- intern/AUD_ConverterReader.h
- intern/AUD_FileFactory.cpp
- intern/AUD_FileFactory.h
- intern/AUD_FileWriter.cpp
- intern/AUD_FileWriter.h
- intern/AUD_I3DDevice.h
- intern/AUD_I3DHandle.h
- 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
- intern/AUD_JOSResampleFactory.h
- intern/AUD_JOSResampleReader.cpp
- intern/AUD_JOSResampleReader.h
- intern/AUD_LinearResampleFactory.cpp
- intern/AUD_LinearResampleFactory.h
- intern/AUD_LinearResampleReader.cpp
- intern/AUD_LinearResampleReader.h
- intern/AUD_Mixer.cpp
- 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_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
- intern/AUD_SequencerFactory.h
- intern/AUD_SequencerHandle.cpp
- intern/AUD_SequencerHandle.h
- intern/AUD_SequencerReader.cpp
- intern/AUD_SequencerReader.h
- intern/AUD_Set.cpp
- intern/AUD_Set.h
- intern/AUD_SilenceFactory.cpp
- intern/AUD_SilenceFactory.h
- intern/AUD_SilenceReader.cpp
- intern/AUD_SilenceReader.h
- intern/AUD_SinusFactory.cpp
- intern/AUD_SinusFactory.h
- intern/AUD_SinusReader.cpp
- intern/AUD_SinusReader.h
- intern/AUD_SoftwareDevice.cpp
- intern/AUD_SoftwareDevice.h
- intern/AUD_Space.h
- intern/AUD_StreamBufferFactory.cpp
- intern/AUD_StreamBufferFactory.h
-
- FX/AUD_AccumulatorFactory.h
- FX/AUD_BandpassCalculator.h
- FX/AUD_BaseIIRFilterReader.h
- FX/AUD_ButterworthCalculator.h
- FX/AUD_ButterworthFactory.h
- FX/AUD_CallbackIIRFilterReader.h
- FX/AUD_DelayFactory.h
- 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
- FX/AUD_EffectReader.h
- FX/AUD_EnvelopeFactory.h
- FX/AUD_FaderFactory.h
- FX/AUD_FaderReader.h
- FX/AUD_HighpassCalculator.h
- FX/AUD_HighpassFactory.h
- FX/AUD_IIRFilterFactory.h
- FX/AUD_IIRFilterReader.h
- FX/AUD_LimiterFactory.h
- FX/AUD_LimiterReader.h
- FX/AUD_LoopFactory.h
- FX/AUD_LoopReader.h
- FX/AUD_LowpassCalculator.h
- FX/AUD_LowpassFactory.h
- FX/AUD_PingPongFactory.h
- FX/AUD_PitchFactory.h
- FX/AUD_PitchReader.h
- FX/AUD_RectifyFactory.h
- FX/AUD_ReverseFactory.h
- FX/AUD_ReverseReader.h
- FX/AUD_SquareFactory.h
- FX/AUD_SumFactory.h
- FX/AUD_SuperposeFactory.h
- FX/AUD_SuperposeReader.h
- FX/AUD_VolumeFactory.h
-)
-
-if(WITH_CODEC_FFMPEG)
- add_definitions(-DWITH_FFMPEG)
- list(APPEND INC
- ffmpeg
- )
- list(APPEND INC_SYS
- ${FFMPEG_INCLUDE_DIRS}
- )
- list(APPEND SRC
- ffmpeg/AUD_FFMPEGFactory.cpp
- ffmpeg/AUD_FFMPEGReader.cpp
- ffmpeg/AUD_FFMPEGWriter.cpp
-
- ffmpeg/AUD_FFMPEGFactory.h
- ffmpeg/AUD_FFMPEGReader.h
- ffmpeg/AUD_FFMPEGWriter.h
- )
-
- remove_strict_flags_file(
- ffmpeg/AUD_FFMPEGFactory.cpp
- ffmpeg/AUD_FFMPEGReader.cpp
- ffmpeg/AUD_FFMPEGWriter.cpp
- )
-endif()
-
-if(WITH_SDL)
- add_definitions(-DWITH_SDL)
- list(APPEND INC
- SDL
- )
- list(APPEND INC_SYS
- ${SDL_INCLUDE_DIR}
- )
- list(APPEND SRC
- SDL/AUD_SDLDevice.cpp
-
- SDL/AUD_SDLDevice.h
- )
-endif()
-
-if(WITH_OPENAL)
- add_definitions(-DWITH_OPENAL)
- list(APPEND INC
- OpenAL
- )
- list(APPEND INC_SYS
- ${OPENAL_INCLUDE_DIR}
- )
- list(APPEND SRC
- OpenAL/AUD_OpenALDevice.cpp
-
- OpenAL/AUD_OpenALDevice.h
- )
-endif()
-
-if(WITH_JACK)
- add_definitions(-DWITH_JACK)
- list(APPEND INC
- jack
- )
- list(APPEND INC_SYS
- ${JACK_INCLUDE_DIRS}
- )
- list(APPEND SRC
- jack/AUD_JackDevice.cpp
- jack/AUD_JackLibrary.cpp
-
- jack/AUD_JackDevice.h
- jack/AUD_JackLibrary.h
- )
-
- if(WITH_JACK_DYNLOAD)
- add_definitions(-DWITH_JACK_DYNLOAD)
- endif()
-endif()
-
-if(WITH_CODEC_SNDFILE)
- add_definitions(-DWITH_SNDFILE)
- list(APPEND INC
- sndfile
- )
- list(APPEND INC_SYS
- ${SNDFILE_INCLUDE_DIRS}
- )
- list(APPEND SRC
- sndfile/AUD_SndFileFactory.cpp
- sndfile/AUD_SndFileReader.cpp
- sndfile/AUD_SndFileWriter.cpp
-
- sndfile/AUD_SndFileFactory.h
- sndfile/AUD_SndFileReader.h
- sndfile/AUD_SndFileWriter.h
- )
-endif()
-
-if(WITH_FFTW3 AND FALSE)
- add_definitions(-DWITH_FFTW3)
- list(APPEND INC
- fftw
- )
- list(APPEND INC_SYS
- ${FFTW3_INCLUDE_DIRS}
- )
- list(APPEND SRC
- fftw/AUD_BandPassFactory.cpp
- fftw/AUD_BandPassReader.cpp
-
- fftw/AUD_BandPassFactory.h
- fftw/AUD_BandPassReader.h
- )
-endif()
-
-if(WITH_PYTHON)
- list(APPEND INC
- Python
- )
- list(APPEND INC_SYS
- ${PYTHON_INCLUDE_DIRS}
- )
- list(APPEND SRC
- Python/AUD_PyAPI.cpp
-
- Python/AUD_PyAPI.h
- )
- add_definitions(-DWITH_PYTHON)
-endif()
-endif()
-
blender_add_lib(bf_intern_audaspace "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/intern/audaspace/COPYING b/intern/audaspace/COPYING
deleted file mode 100644
index a330e6d9193..00000000000
--- a/intern/audaspace/COPYING
+++ /dev/null
@@ -1,339 +0,0 @@
- GNU GENERAL PUBLIC LICENSE
- Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
- 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
- Preamble
-
- The licenses for most software are designed to take away your
-freedom to share and change it. By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users. This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it. (Some other Free Software Foundation software is covered by
-the GNU Lesser General Public License instead.) You can apply it to
-your programs, too.
-
- When we speak of free software, we are referring to freedom, not
-price. Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
- To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
- For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have. You must make sure that they, too, receive or can get the
-source code. And you must show them these terms so they know their
-rights.
-
- We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
- Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software. If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
- Finally, any free program is threatened constantly by software
-patents. We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary. To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
- The precise terms and conditions for copying, distribution and
-modification follow.
-
- GNU GENERAL PUBLIC LICENSE
- TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
- 0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License. The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language. (Hereinafter, translation is included without limitation in
-the term "modification".) Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope. The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
- 1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
- 2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
- a) You must cause the modified files to carry prominent notices
- stating that you changed the files and the date of any change.
-
- b) You must cause any work that you distribute or publish, that in
- whole or in part contains or is derived from the Program or any
- part thereof, to be licensed as a whole at no charge to all third
- parties under the terms of this License.
-
- c) If the modified program normally reads commands interactively
- when run, you must cause it, when started running for such
- interactive use in the most ordinary way, to print or display an
- announcement including an appropriate copyright notice and a
- notice that there is no warranty (or else, saying that you provide
- a warranty) and that users may redistribute the program under
- these conditions, and telling the user how to view a copy of this
- License. (Exception: if the Program itself is interactive but
- does not normally print such an announcement, your work based on
- the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole. If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
- 3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
- a) Accompany it with the complete corresponding machine-readable
- source code, which must be distributed under the terms of Sections
- 1 and 2 above on a medium customarily used for software interchange; or,
-
- b) Accompany it with a written offer, valid for at least three
- years, to give any third party, for a charge no more than your
- cost of physically performing source distribution, a complete
- machine-readable copy of the corresponding source code, to be
- distributed under the terms of Sections 1 and 2 above on a medium
- customarily used for software interchange; or,
-
- c) Accompany it with the information you received as to the offer
- to distribute corresponding source code. (This alternative is
- allowed only for noncommercial distribution and only if you
- received the program in object code or executable form with such
- an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it. For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable. However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
- 4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License. Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
- 5. You are not required to accept this License, since you have not
-signed it. However, nothing else grants you permission to modify or
-distribute the Program or its derivative works. These actions are
-prohibited by law if you do not accept this License. Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
- 6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions. You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
- 7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License. If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all. For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices. Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
- 8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded. In such case, this License incorporates
-the limitation as if written in the body of this License.
-
- 9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time. Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number. If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation. If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
- 10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission. For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this. Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
- NO WARRANTY
-
- 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
- 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
- END OF TERMS AND CONDITIONS
-
- How to Apply These Terms to Your New Programs
-
- If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
- To do so, attach the following notices to the program. It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
- <one line to give the program's name and a brief idea of what it does.>
- Copyright (C) <year> <name of author>
-
- 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.
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
- Gnomovision version 69, Copyright (C) year name of author
- Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
- This is free software, and you are welcome to redistribute it
- under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License. Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary. Here is a sample; alter the names:
-
- Yoyodyne, Inc., hereby disclaims all copyright interest in the program
- `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
- <signature of Ty Coon>, 1 April 1989
- Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs. If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library. If this is what you want to do, use the GNU Lesser General
-Public License instead of this License.
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
deleted file mode 100644
index 00d3a9f2395..00000000000
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
+++ /dev/null
@@ -1,64 +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/FX/AUD_AccumulatorFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_AccumulatorFactory.h"
-#include "AUD_CallbackIIRFilterReader.h"
-
-sample_t AUD_AccumulatorFactory::accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless)
-{
- float in = reader->x(0);
- float lastin = reader->x(-1);
- float out = reader->y(-1) + in - lastin;
- if(in > lastin)
- out += in - lastin;
- return out;
-}
-
-sample_t AUD_AccumulatorFactory::accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
-{
- float in = reader->x(0);
- float lastin = reader->x(-1);
- float out = reader->y(-1);
- if(in > lastin)
- out += in - lastin;
- return out;
-}
-
-AUD_AccumulatorFactory::AUD_AccumulatorFactory(boost::shared_ptr<AUD_IFactory> factory,
- bool additive) :
- AUD_EffectFactory(factory),
- m_additive(additive)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_AccumulatorFactory::createReader()
-{
- 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
deleted file mode 100644
index 9087218a5f9..00000000000
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.h
+++ /dev/null
@@ -1,69 +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/FX/AUD_AccumulatorFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_ACCUMULATORFACTORY_H__
-#define __AUD_ACCUMULATORFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-class AUD_CallbackIIRFilterReader;
-
-/**
- * This factory creates an accumulator reader.
- *
- * The accumulator adds the difference at the input to the last output in case
- * it's positive. In additive mode it additionaly adds the difference always.
- * So in case the difference is positive, it's added twice.
- */
-class AUD_AccumulatorFactory : public AUD_EffectFactory
-{
-private:
- /**
- * Whether the accumulator is additive.
- */
- const bool m_additive;
-
- // hide copy constructor and operator=
- AUD_AccumulatorFactory(const AUD_AccumulatorFactory&);
- AUD_AccumulatorFactory& operator=(const AUD_AccumulatorFactory&);
-
-public:
- /**
- * Creates a new accumulator factory.
- * \param factory The input factory.
- * \param additive Whether the accumulator is additive.
- */
- AUD_AccumulatorFactory(boost::shared_ptr<AUD_IFactory> factory, bool additive = false);
-
- 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);
-};
-
-#endif //__AUD_ACCUMULATORFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_BandpassCalculator.cpp b/intern/audaspace/FX/AUD_BandpassCalculator.cpp
deleted file mode 100644
index f5bbd63f81c..00000000000
--- a/intern/audaspace/FX/AUD_BandpassCalculator.cpp
+++ /dev/null
@@ -1,5 +0,0 @@
-#include "AUD_BandpassCalculator.h"
-
-AUD_BandpassCalculator::AUD_BandpassCalculator()
-{
-}
diff --git a/intern/audaspace/FX/AUD_BandpassCalculator.h b/intern/audaspace/FX/AUD_BandpassCalculator.h
deleted file mode 100644
index b5b3cad17ca..00000000000
--- a/intern/audaspace/FX/AUD_BandpassCalculator.h
+++ /dev/null
@@ -1,10 +0,0 @@
-#ifndef AUD_BANDPASSCALCULATOR_H
-#define AUD_BANDPASSCALCULATOR_H
-
-class AUD_BandpassCalculator
-{
-public:
- AUD_BandpassCalculator();
-};
-
-#endif // AUD_BANDPASSCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
deleted file mode 100644
index eadfc525f96..00000000000
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
+++ /dev/null
@@ -1,137 +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/FX/AUD_BaseIIRFilterReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_BaseIIRFilterReader.h"
-
-#include <cstring>
-
-#define CC m_specs.channels + m_channel
-
-AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(boost::shared_ptr<AUD_IReader> reader, int in,
- int out) :
- AUD_EffectReader(reader),
- m_specs(reader->getSpecs()),
- m_xlen(in), m_ylen(out),
- m_xpos(0), m_ypos(0), m_channel(0)
-{
- m_x = new sample_t[m_xlen * m_specs.channels];
- m_y = new sample_t[m_ylen * m_specs.channels];
-
- memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
- memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
-}
-
-AUD_BaseIIRFilterReader::~AUD_BaseIIRFilterReader()
-{
- delete[] m_x;
- delete[] m_y;
-}
-
-void AUD_BaseIIRFilterReader::setLengths(int in, int out)
-{
- if(in != m_xlen)
- {
- sample_t* xn = new sample_t[in * m_specs.channels];
- memset(xn, 0, sizeof(sample_t) * in * m_specs.channels);
-
- for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
- {
- for(int i = 1; i <= in && i <= m_xlen; i++)
- {
- xn[(in - i) * CC] = x(-i);
- }
- }
-
- delete[] m_x;
- m_x = xn;
- m_xpos = 0;
- m_xlen = in;
- }
-
- if(out != m_ylen)
- {
- sample_t* yn = new sample_t[out * m_specs.channels];
- memset(yn, 0, sizeof(sample_t) * out * m_specs.channels);
-
- for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
- {
- for(int i = 1; i <= out && i <= m_ylen; i++)
- {
- yn[(out - i) * CC] = y(-i);
- }
- }
-
- delete[] m_y;
- m_y = yn;
- m_ypos = 0;
- m_ylen = out;
- }
-}
-
-void AUD_BaseIIRFilterReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_Specs specs = m_reader->getSpecs();
- if(specs.channels != m_specs.channels)
- {
- m_specs.channels = specs.channels;
-
- delete[] m_x;
- delete[] m_y;
-
- m_x = new sample_t[m_xlen * m_specs.channels];
- m_y = new sample_t[m_ylen * m_specs.channels];
-
- memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
- memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
- }
-
- if(specs.rate != m_specs.rate)
- {
- m_specs = specs;
- sampleRateChanged(m_specs.rate);
- }
-
- m_reader->read(length, eos, buffer);
-
- for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
- {
- for(int i = 0; i < length; i++)
- {
- m_x[m_xpos * CC] = buffer[i * CC];
- m_y[m_ypos * CC] = buffer[i * CC] = filter();
-
- m_xpos = (m_xpos + 1) % m_xlen;
- m_ypos = (m_ypos + 1) % m_ylen;
- }
- }
-}
-
-void AUD_BaseIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
-{
-}
diff --git a/intern/audaspace/FX/AUD_ButterworthCalculator.cpp b/intern/audaspace/FX/AUD_ButterworthCalculator.cpp
deleted file mode 100644
index 7a3c6f71e15..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthCalculator.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-#include "AUD_ButterworthCalculator.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define BWPB41 0.76536686473
-#define BWPB42 1.84775906502
-
-AUD_ButterworthCalculator::AUD_ButterworthCalculator(float frequency) :
- m_frequency(frequency)
-{
-}
-
-void AUD_ButterworthCalculator::recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a)
-{
- float omega = 2 * tan(m_frequency * M_PI / rate);
- float o2 = omega * omega;
- float o4 = o2 * o2;
- 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);
- a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
- a.push_back((y1 + y2) * o228 / norm);
- a.push_back(y1 * y2 / norm);
- b.push_back(o4 / norm);
- b.push_back(4 * o4 / norm);
- b.push_back(6 * o4 / norm);
- b.push_back(b[1]);
- b.push_back(b[0]);
-}
diff --git a/intern/audaspace/FX/AUD_ButterworthCalculator.h b/intern/audaspace/FX/AUD_ButterworthCalculator.h
deleted file mode 100644
index a7ae196afda..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthCalculator.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef AUD_BUTTERWORTHCALCULATOR_H
-#define AUD_BUTTERWORTHCALCULATOR_H
-
-#include "AUD_IDynamicIIRFilterCalculator.h"
-
-class AUD_ButterworthCalculator : public AUD_IDynamicIIRFilterCalculator
-{
-private:
- /**
- * The attack value in seconds.
- */
- const float m_frequency;
-
-public:
- AUD_ButterworthCalculator(float frequency);
-
- virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
-};
-
-#endif // AUD_BUTTERWORTHCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
deleted file mode 100644
index 12c4306c2f7..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthFactory.cpp
+++ /dev/null
@@ -1,39 +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/FX/AUD_ButterworthFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_ButterworthFactory.h"
-#include "AUD_IIRFilterReader.h"
-#include "AUD_ButterworthCalculator.h"
-
-AUD_ButterworthFactory::AUD_ButterworthFactory(boost::shared_ptr<AUD_IFactory> factory,
- float frequency) :
- AUD_DynamicIIRFilterFactory(factory, boost::shared_ptr<AUD_IDynamicIIRFilterCalculator>(new AUD_ButterworthCalculator(frequency)))
-{
-}
-
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h
deleted file mode 100644
index 3a86b14a7a6..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthFactory.h
+++ /dev/null
@@ -1,54 +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/FX/AUD_ButterworthFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_BUTTERWORTHFACTORY_H__
-#define __AUD_BUTTERWORTHFACTORY_H__
-
-#include "AUD_DynamicIIRFilterFactory.h"
-
-/**
- * This factory creates a butterworth lowpass filter reader.
- */
-class AUD_ButterworthFactory : public AUD_DynamicIIRFilterFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_ButterworthFactory(const AUD_ButterworthFactory&);
- AUD_ButterworthFactory& operator=(const AUD_ButterworthFactory&);
-
-public:
- /**
- * Creates a new butterworth factory.
- * \param factory The input factory.
- * \param frequency The cutoff frequency.
- */
- AUD_ButterworthFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency);
-};
-
-#endif //__AUD_BUTTERWORTHFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
deleted file mode 100644
index b5157d47666..00000000000
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
+++ /dev/null
@@ -1,51 +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/FX/AUD_CallbackIIRFilterReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_CallbackIIRFilterReader.h"
-
-AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(boost::shared_ptr<AUD_IReader> reader,
- int in, int out,
- doFilterIIR doFilter,
- endFilterIIR endFilter,
- void* data) :
- AUD_BaseIIRFilterReader(reader, in, out),
- m_filter(doFilter), m_endFilter(endFilter), m_data(data)
-{
-}
-
-AUD_CallbackIIRFilterReader::~AUD_CallbackIIRFilterReader()
-{
- if(m_endFilter)
- m_endFilter(m_data);
-}
-
-sample_t AUD_CallbackIIRFilterReader::filter()
-{
- return m_filter(this, m_data);
-}
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
deleted file mode 100644
index 66f82ba1a01..00000000000
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
+++ /dev/null
@@ -1,87 +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/FX/AUD_CallbackIIRFilterReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_CALLBACKIIRFILTERREADER_H__
-#define __AUD_CALLBACKIIRFILTERREADER_H__
-
-#include "AUD_BaseIIRFilterReader.h"
-#include "AUD_Buffer.h"
-
-class AUD_CallbackIIRFilterReader;
-
-typedef sample_t (*doFilterIIR)(AUD_CallbackIIRFilterReader*, void*);
-typedef void (*endFilterIIR)(void*);
-
-/**
- * This class provides an interface for infinite impulse response filters via a
- * callback filter function.
- */
-class AUD_CallbackIIRFilterReader : public AUD_BaseIIRFilterReader
-{
-private:
- /**
- * Filter function.
- */
- const doFilterIIR m_filter;
-
- /**
- * End filter function.
- */
- const endFilterIIR m_endFilter;
-
- /**
- * Data pointer.
- */
- void* m_data;
-
- // hide copy constructor and operator=
- AUD_CallbackIIRFilterReader(const AUD_CallbackIIRFilterReader&);
- AUD_CallbackIIRFilterReader& operator=(const AUD_CallbackIIRFilterReader&);
-
-public:
- /**
- * Creates a new callback IIR filter reader.
- * \param reader The reader to read from.
- * \param in The count of past input samples needed.
- * \param out The count of past output samples needed.
- * \param doFilter The filter callback.
- * \param endFilter The finishing callback.
- * \param data Data pointer for the callbacks.
- */
- AUD_CallbackIIRFilterReader(boost::shared_ptr<AUD_IReader> reader, int in, int out,
- doFilterIIR doFilter,
- endFilterIIR endFilter = 0,
- void* data = NULL);
-
- virtual ~AUD_CallbackIIRFilterReader();
-
- virtual sample_t filter();
-};
-
-#endif //__AUD_CALLBACKIIRFILTERREADER_H__
diff --git a/intern/audaspace/FX/AUD_DelayFactory.cpp b/intern/audaspace/FX/AUD_DelayFactory.cpp
deleted file mode 100644
index 3e5a7cfd2f8..00000000000
--- a/intern/audaspace/FX/AUD_DelayFactory.cpp
+++ /dev/null
@@ -1,48 +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/FX/AUD_DelayFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_DelayFactory.h"
-#include "AUD_DelayReader.h"
-#include "AUD_Space.h"
-
-AUD_DelayFactory::AUD_DelayFactory(boost::shared_ptr<AUD_IFactory> factory, float delay) :
- AUD_EffectFactory(factory),
- m_delay(delay)
-{
-}
-
-float AUD_DelayFactory::getDelay() const
-{
- return m_delay;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_DelayFactory::createReader()
-{
- 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
deleted file mode 100644
index 8cfb2be9ac8..00000000000
--- a/intern/audaspace/FX/AUD_DelayFactory.h
+++ /dev/null
@@ -1,66 +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/FX/AUD_DelayFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_DELAYFACTORY_H__
-#define __AUD_DELAYFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory plays another factory delayed.
- */
-class AUD_DelayFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The delay in samples.
- */
- const float m_delay;
-
- // hide copy constructor and operator=
- AUD_DelayFactory(const AUD_DelayFactory&);
- AUD_DelayFactory& operator=(const AUD_DelayFactory&);
-
-public:
- /**
- * Creates a new delay factory.
- * \param factory The input factory.
- * \param delay The desired delay in seconds.
- */
- AUD_DelayFactory(boost::shared_ptr<AUD_IFactory> factory, float delay = 0);
-
- /**
- * Returns the delay in seconds.
- */
- float getDelay() const;
-
- 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
deleted file mode 100644
index 050508f28da..00000000000
--- a/intern/audaspace/FX/AUD_DelayReader.cpp
+++ /dev/null
@@ -1,96 +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/FX/AUD_DelayReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_DelayReader.h"
-
-#include <cstring>
-
-AUD_DelayReader::AUD_DelayReader(boost::shared_ptr<AUD_IReader> reader, float delay) :
- AUD_EffectReader(reader),
- m_delay(int((AUD_SampleRate)delay * reader->getSpecs().rate)),
- m_remdelay(int((AUD_SampleRate)delay * reader->getSpecs().rate))
-{
-}
-
-void AUD_DelayReader::seek(int position)
-{
- if(position < m_delay)
- {
- m_remdelay = m_delay - position;
- m_reader->seek(0);
- }
- else
- {
- m_remdelay = 0;
- m_reader->seek(position - m_delay);
- }
-}
-
-int AUD_DelayReader::getLength() const
-{
- int len = m_reader->getLength();
- if(len < 0)
- return len;
- return len + m_delay;
-}
-
-int AUD_DelayReader::getPosition() const
-{
- if(m_remdelay > 0)
- return m_delay - m_remdelay;
- return m_reader->getPosition() + m_delay;
-}
-
-void AUD_DelayReader::read(int& length, bool& eos, sample_t* buffer)
-{
- if(m_remdelay > 0)
- {
- AUD_Specs specs = m_reader->getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
-
- if(length > m_remdelay)
- {
- memset(buffer, 0, m_remdelay * samplesize);
-
- int len = length - m_remdelay;
- m_reader->read(len, eos, buffer + m_remdelay * specs.channels);
-
- length = m_remdelay + len;
-
- m_remdelay = 0;
- }
- else
- {
- memset(buffer, 0, length * samplesize);
- m_remdelay -= length;
- }
- }
- else
- m_reader->read(length, eos, buffer);
-}
diff --git a/intern/audaspace/FX/AUD_DelayReader.h b/intern/audaspace/FX/AUD_DelayReader.h
deleted file mode 100644
index d4388e3befc..00000000000
--- a/intern/audaspace/FX/AUD_DelayReader.h
+++ /dev/null
@@ -1,70 +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/FX/AUD_DelayReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_DELAYREADER_H__
-#define __AUD_DELAYREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class reads another reader and delays it.
- */
-class AUD_DelayReader : public AUD_EffectReader
-{
-private:
- /**
- * The delay level.
- */
- const int m_delay;
-
- /**
- * The remaining delay for playback.
- */
- int m_remdelay;
-
- // hide copy constructor and operator=
- AUD_DelayReader(const AUD_DelayReader&);
- AUD_DelayReader& operator=(const AUD_DelayReader&);
-
-public:
- /**
- * Creates a new delay reader.
- * \param reader The reader to read from.
- * \param delay The delay in seconds.
- */
- AUD_DelayReader(boost::shared_ptr<AUD_IReader> reader, float delay);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_DELAYREADER_H__
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.cpp b/intern/audaspace/FX/AUD_DoubleFactory.cpp
deleted file mode 100644
index 21bcbc2f649..00000000000
--- a/intern/audaspace/FX/AUD_DoubleFactory.cpp
+++ /dev/null
@@ -1,44 +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/FX/AUD_DoubleFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_DoubleFactory.h"
-#include "AUD_DoubleReader.h"
-
-AUD_DoubleFactory::AUD_DoubleFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2) :
- m_factory1(factory1), m_factory2(factory2)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_DoubleFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader1 = m_factory1->createReader();
- boost::shared_ptr<AUD_IReader> reader2 = m_factory2->createReader();
-
- 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
deleted file mode 100644
index 4a02cc7bcdb..00000000000
--- a/intern/audaspace/FX/AUD_DoubleFactory.h
+++ /dev/null
@@ -1,66 +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/FX/AUD_DoubleFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_DOUBLEFACTORY_H__
-#define __AUD_DOUBLEFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory plays two other factories behind each other.
- */
-class AUD_DoubleFactory : public AUD_IFactory
-{
-private:
- /**
- * First played factory.
- */
- boost::shared_ptr<AUD_IFactory> m_factory1;
-
- /**
- * Second played factory.
- */
- boost::shared_ptr<AUD_IFactory> m_factory2;
-
- // hide copy constructor and operator=
- AUD_DoubleFactory(const AUD_DoubleFactory&);
- AUD_DoubleFactory& operator=(const AUD_DoubleFactory&);
-
-public:
- /**
- * Creates a new double factory.
- * \param factory1 The first input factory.
- * \param factory2 The second input factory.
- */
- AUD_DoubleFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2);
-
- 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
deleted file mode 100644
index ee18914e93f..00000000000
--- a/intern/audaspace/FX/AUD_DoubleReader.cpp
+++ /dev/null
@@ -1,112 +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/FX/AUD_DoubleReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_DoubleReader.h"
-
-#include <cstring>
-
-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;
- s1 = reader1->getSpecs();
- s2 = reader2->getSpecs();
-}
-
-AUD_DoubleReader::~AUD_DoubleReader()
-{
-}
-
-bool AUD_DoubleReader::isSeekable() const
-{
- return m_reader1->isSeekable() && m_reader2->isSeekable();
-}
-
-void AUD_DoubleReader::seek(int position)
-{
- m_reader1->seek(position);
-
- int pos1 = m_reader1->getPosition();
-
- if((m_finished1 = (pos1 < position)))
- m_reader2->seek(position - pos1);
- else
- m_reader2->seek(0);
-}
-
-int AUD_DoubleReader::getLength() const
-{
- int len1 = m_reader1->getLength();
- int len2 = m_reader2->getLength();
- if(len1 < 0 || len2 < 0)
- return -1;
- return len1 + len2;
-}
-
-int AUD_DoubleReader::getPosition() const
-{
- return m_reader1->getPosition() + m_reader2->getPosition();
-}
-
-AUD_Specs AUD_DoubleReader::getSpecs() const
-{
- return m_finished1 ? m_reader1->getSpecs() : m_reader2->getSpecs();
-}
-
-void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer)
-{
- eos = false;
-
- if(!m_finished1)
- {
- int len = length;
-
- m_reader1->read(len, m_finished1, buffer);
-
- if(len < length)
- {
- AUD_Specs specs1, specs2;
- specs1 = m_reader1->getSpecs();
- specs2 = m_reader2->getSpecs();
- if(AUD_COMPARE_SPECS(specs1, specs2))
- {
- int len2 = length - len;
- m_reader2->read(len2, eos, buffer + specs1.channels * len);
- length = len + len2;
- }
- else
- length = len;
- }
- }
- else
- {
- m_reader2->read(length, eos, buffer);
- }
-}
diff --git a/intern/audaspace/FX/AUD_DoubleReader.h b/intern/audaspace/FX/AUD_DoubleReader.h
deleted file mode 100644
index 5d2f65f1a90..00000000000
--- a/intern/audaspace/FX/AUD_DoubleReader.h
+++ /dev/null
@@ -1,84 +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/FX/AUD_DoubleReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_DOUBLEREADER_H__
-#define __AUD_DOUBLEREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This reader plays two readers sequently.
- */
-class AUD_DoubleReader : public AUD_IReader
-{
-private:
- /**
- * The first reader.
- */
- boost::shared_ptr<AUD_IReader> m_reader1;
-
- /**
- * The second reader.
- */
- boost::shared_ptr<AUD_IReader> m_reader2;
-
- /**
- * Whether we've reached the end of the first reader.
- */
- bool m_finished1;
-
- // hide copy constructor and operator=
- AUD_DoubleReader(const AUD_DoubleReader&);
- AUD_DoubleReader& operator=(const AUD_DoubleReader&);
-
-public:
- /**
- * Creates a new double reader.
- * \param reader1 The first reader to read from.
- * \param reader2 The second reader to read from.
- */
- AUD_DoubleReader(boost::shared_ptr<AUD_IReader> reader1, boost::shared_ptr<AUD_IReader> reader2);
-
- /**
- * Destroys the reader.
- */
- virtual ~AUD_DoubleReader();
-
- virtual bool isSeekable() const;
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_DOUBLEREADER_H__
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
deleted file mode 100644
index 319a78cfedd..00000000000
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
+++ /dev/null
@@ -1,44 +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/FX/AUD_DynamicIIRFilterFactory.cpp
- * \ingroup audfx
- */
-
-#include "AUD_DynamicIIRFilterFactory.h"
-#include "AUD_DynamicIIRFilterReader.h"
-
-
-AUD_DynamicIIRFilterFactory::AUD_DynamicIIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory,
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator) :
- AUD_EffectFactory(factory),
- m_calculator(calculator)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_DynamicIIRFilterFactory::createReader()
-{
- 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
deleted file mode 100644
index aece7a8c2ef..00000000000
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
+++ /dev/null
@@ -1,58 +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/FX/AUD_DynamicIIRFilterFactory.h
- * \ingroup audfx
- */
-
-#ifndef __AUD_DYNAMICIIRFILTERFACTORY_H__
-#define __AUD_DYNAMICIIRFILTERFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-#include "AUD_IDynamicIIRFilterCalculator.h"
-#include <vector>
-
-/**
- * This factory creates a IIR filter reader.
- *
- * This means that on sample rate change the filter recalculates its
- * coefficients.
- */
-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(boost::shared_ptr<AUD_IFactory> factory,
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator);
-
- 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
deleted file mode 100644
index 52aaf2311c0..00000000000
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
+++ /dev/null
@@ -1,44 +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/FX/AUD_DynamicIIRFilterReader.cpp
- * \ingroup audfx
- */
-
-#include "AUD_DynamicIIRFilterReader.h"
-
-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_calculator(calculator)
-{
- sampleRateChanged(reader->getSpecs().rate);
-}
-
-void AUD_DynamicIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
-{
- std::vector<float> a, b;
- 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
deleted file mode 100644
index 0b68578bc53..00000000000
--- a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
+++ /dev/null
@@ -1,54 +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/FX/AUD_DynamicIIRFilterReader.h
- * \ingroup audfx
- */
-
-#ifndef __AUD_DYNAMICIIRFILTERREADER_H__
-#define __AUD_DYNAMICIIRFILTERREADER_H__
-
-#include "AUD_IIRFilterReader.h"
-#include "AUD_IDynamicIIRFilterCalculator.h"
-
-/**
- * This class is for dynamic infinite impulse response filters with simple
- * coefficients that change depending on the sample rate.
- */
-class AUD_DynamicIIRFilterReader : public AUD_IIRFilterReader
-{
-private:
- /**
- * The factory for dynamically recalculating filter coefficients.
- */
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> m_calculator;
-
-public:
- AUD_DynamicIIRFilterReader(boost::shared_ptr<AUD_IReader> reader,
- boost::shared_ptr<AUD_IDynamicIIRFilterCalculator> calculator);
-
- virtual void sampleRateChanged(AUD_SampleRate rate);
-};
-
-#endif // __AUD_DYNAMICIIRFILTERREADER_H__
diff --git a/intern/audaspace/FX/AUD_EffectFactory.cpp b/intern/audaspace/FX/AUD_EffectFactory.cpp
deleted file mode 100644
index 6018ed561ca..00000000000
--- a/intern/audaspace/FX/AUD_EffectFactory.cpp
+++ /dev/null
@@ -1,45 +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/FX/AUD_EffectFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_EffectFactory.h"
-#include "AUD_IReader.h"
-
-AUD_EffectFactory::AUD_EffectFactory(boost::shared_ptr<AUD_IFactory> factory)
-{
- m_factory = factory;
-}
-
-AUD_EffectFactory::~AUD_EffectFactory()
-{
-}
-
-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
deleted file mode 100644
index d09872638be..00000000000
--- a/intern/audaspace/FX/AUD_EffectFactory.h
+++ /dev/null
@@ -1,82 +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/FX/AUD_EffectFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_EFFECTFACTORY_H__
-#define __AUD_EFFECTFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory is a base class for all effect factories that take one other
- * factory as input.
- */
-class AUD_EffectFactory : public AUD_IFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_EffectFactory(const AUD_EffectFactory&);
- AUD_EffectFactory& operator=(const AUD_EffectFactory&);
-
-protected:
- /**
- * If there is no reader it is created out of this factory.
- */
- boost::shared_ptr<AUD_IFactory> m_factory;
-
- /**
- * Returns the reader created out of the factory.
- * This method can be used for the createReader function of the implementing
- * classes.
- * \return The reader created out of the factory.
- */
- inline boost::shared_ptr<AUD_IReader> getReader() const
- {
- return m_factory->createReader();
- }
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- */
- AUD_EffectFactory(boost::shared_ptr<AUD_IFactory> factory);
-
- /**
- * Destroys the factory.
- */
- virtual ~AUD_EffectFactory();
-
- /**
- * Returns the saved factory.
- * \return The factory or NULL if there has no factory been saved.
- */
- 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
deleted file mode 100644
index b3e80bef03b..00000000000
--- a/intern/audaspace/FX/AUD_EffectReader.cpp
+++ /dev/null
@@ -1,69 +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/FX/AUD_EffectReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_EffectReader.h"
-
-AUD_EffectReader::AUD_EffectReader(boost::shared_ptr<AUD_IReader> reader)
-{
- m_reader = reader;
-}
-
-AUD_EffectReader::~AUD_EffectReader()
-{
-}
-
-bool AUD_EffectReader::isSeekable() const
-{
- return m_reader->isSeekable();
-}
-
-void AUD_EffectReader::seek(int position)
-{
- m_reader->seek(position);
-}
-
-int AUD_EffectReader::getLength() const
-{
- return m_reader->getLength();
-}
-
-int AUD_EffectReader::getPosition() const
-{
- return m_reader->getPosition();
-}
-
-AUD_Specs AUD_EffectReader::getSpecs() const
-{
- return m_reader->getSpecs();
-}
-
-void AUD_EffectReader::read(int& length, bool& eos, sample_t* buffer)
-{
- m_reader->read(length, eos, buffer);
-}
diff --git a/intern/audaspace/FX/AUD_EffectReader.h b/intern/audaspace/FX/AUD_EffectReader.h
deleted file mode 100644
index 2745c12afaf..00000000000
--- a/intern/audaspace/FX/AUD_EffectReader.h
+++ /dev/null
@@ -1,74 +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/FX/AUD_EffectReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_EFFECTREADER_H__
-#define __AUD_EFFECTREADER_H__
-
-#include "AUD_IReader.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This reader is a base class for all effect readers that take one other reader
- * as input.
- */
-class AUD_EffectReader : public AUD_IReader
-{
-private:
- // hide copy constructor and operator=
- AUD_EffectReader(const AUD_EffectReader&);
- AUD_EffectReader& operator=(const AUD_EffectReader&);
-
-protected:
- /**
- * The reader to read from.
- */
- boost::shared_ptr<AUD_IReader> m_reader;
-
-public:
- /**
- * Creates a new effect reader.
- * \param reader The reader to read from.
- */
- AUD_EffectReader(boost::shared_ptr<AUD_IReader> reader);
-
- /**
- * Destroys the reader.
- */
- virtual ~AUD_EffectReader();
-
- virtual bool isSeekable() const;
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_EFFECTREADER_H__
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
deleted file mode 100644
index 1e5737557c1..00000000000
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
+++ /dev/null
@@ -1,82 +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/FX/AUD_EnvelopeFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_EnvelopeFactory.h"
-#include "AUD_CallbackIIRFilterReader.h"
-
-#include <cmath>
-
-struct EnvelopeParameters
-{
- float attack;
- float release;
- float threshold;
- float arthreshold;
-};
-
-sample_t AUD_EnvelopeFactory::envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param)
-{
- float in = fabs(reader->x(0));
- float out = reader->y(-1);
- if(in < param->threshold)
- in = 0.0f;
- return (in > out ? param->attack : param->release) * (out - in) + in;
-}
-
-void AUD_EnvelopeFactory::endEnvelopeFilter(EnvelopeParameters* param)
-{
- delete param;
-}
-
-AUD_EnvelopeFactory::AUD_EnvelopeFactory(boost::shared_ptr<AUD_IFactory> factory, float attack,
- float release, float threshold,
- float arthreshold) :
- AUD_EffectFactory(factory),
- m_attack(attack),
- m_release(release),
- m_threshold(threshold),
- m_arthreshold(arthreshold)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_EnvelopeFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader = getReader();
-
- EnvelopeParameters* param = new EnvelopeParameters();
- param->arthreshold = m_arthreshold;
- param->attack = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_attack));
- param->release = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release));
- param->threshold = m_threshold;
-
- return boost::shared_ptr<AUD_IReader>(new AUD_CallbackIIRFilterReader(reader, 1, 2,
- (doFilterIIR) envelopeFilter,
- (endFilterIIR) endEnvelopeFilter,
- param));
-}
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.h b/intern/audaspace/FX/AUD_EnvelopeFactory.h
deleted file mode 100644
index 656212c8cac..00000000000
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.h
+++ /dev/null
@@ -1,85 +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/FX/AUD_EnvelopeFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_ENVELOPEFACTORY_H__
-#define __AUD_ENVELOPEFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-class AUD_CallbackIIRFilterReader;
-struct EnvelopeParameters;
-
-/**
- * This factory creates an envelope follower reader.
- */
-class AUD_EnvelopeFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The attack value in seconds.
- */
- const float m_attack;
-
- /**
- * The release value in seconds.
- */
- const float m_release;
-
- /**
- * The threshold value.
- */
- const float m_threshold;
-
- /**
- * The attack/release threshold value.
- */
- const float m_arthreshold;
-
- // hide copy constructor and operator=
- AUD_EnvelopeFactory(const AUD_EnvelopeFactory&);
- AUD_EnvelopeFactory& operator=(const AUD_EnvelopeFactory&);
-
-public:
- /**
- * Creates a new envelope factory.
- * \param factory The input factory.
- * \param attack The attack value in seconds.
- * \param release The release value in seconds.
- * \param threshold The threshold value.
- * \param arthreshold The attack/release threshold value.
- */
- AUD_EnvelopeFactory(boost::shared_ptr<AUD_IFactory> factory, float attack, float release,
- float threshold, float arthreshold);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-
- static sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param);
- static void endEnvelopeFilter(EnvelopeParameters* param);
-};
-
-#endif //__AUD_ENVELOPEFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_FaderFactory.cpp b/intern/audaspace/FX/AUD_FaderFactory.cpp
deleted file mode 100644
index b34d2134385..00000000000
--- a/intern/audaspace/FX/AUD_FaderFactory.cpp
+++ /dev/null
@@ -1,60 +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/FX/AUD_FaderFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_FaderFactory.h"
-#include "AUD_FaderReader.h"
-
-AUD_FaderFactory::AUD_FaderFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_FadeType type,
- float start, float length) :
- AUD_EffectFactory(factory),
- m_type(type),
- m_start(start),
- m_length(length)
-{
-}
-
-AUD_FadeType AUD_FaderFactory::getType() const
-{
- return m_type;
-}
-
-float AUD_FaderFactory::getStart() const
-{
- return m_start;
-}
-
-float AUD_FaderFactory::getLength() const
-{
- return m_length;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_FaderFactory::createReader()
-{
- 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
deleted file mode 100644
index f9ad88a751d..00000000000
--- a/intern/audaspace/FX/AUD_FaderFactory.h
+++ /dev/null
@@ -1,92 +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/FX/AUD_FaderFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_FADERFACTORY_H__
-#define __AUD_FADERFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory fades another factory.
- * If the fading type is AUD_FADE_IN, everything before the fading start will be
- * silenced, for AUD_FADE_OUT that's true for everything after fading ends.
- */
-class AUD_FaderFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The fading type.
- */
- const AUD_FadeType m_type;
-
- /**
- * The fading start.
- */
- const float m_start;
-
- /**
- * The fading length.
- */
- const float m_length;
-
- // hide copy constructor and operator=
- AUD_FaderFactory(const AUD_FaderFactory&);
- AUD_FaderFactory& operator=(const AUD_FaderFactory&);
-
-public:
- /**
- * Creates a new fader factory.
- * \param factory The input factory.
- * \param type The fading type.
- * \param start The time where fading should start in seconds.
- * \param length How long fading should last in seconds.
- */
- AUD_FaderFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_FadeType type = AUD_FADE_IN,
- float start = 0.0f, float length = 1.0f);
-
- /**
- * Returns the fading type.
- */
- AUD_FadeType getType() const;
-
- /**
- * Returns the fading start.
- */
- float getStart() const;
-
- /**
- * Returns the fading length.
- */
- float getLength() const;
-
- 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
deleted file mode 100644
index e09072054cb..00000000000
--- a/intern/audaspace/FX/AUD_FaderReader.cpp
+++ /dev/null
@@ -1,86 +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/FX/AUD_FaderReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_FaderReader.h"
-
-#include <cstring>
-
-AUD_FaderReader::AUD_FaderReader(boost::shared_ptr<AUD_IReader> reader, AUD_FadeType type,
- float start,float length) :
- AUD_EffectReader(reader),
- m_type(type),
- m_start(start),
- m_length(length)
-{
-}
-
-void AUD_FaderReader::read(int& length, bool& eos, sample_t* buffer)
-{
- int position = m_reader->getPosition();
- AUD_Specs specs = m_reader->getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
-
- m_reader->read(length, eos, buffer);
-
- if((position + length) / (float)specs.rate <= m_start)
- {
- if(m_type != AUD_FADE_OUT)
- {
- memset(buffer, 0, length * samplesize);
- }
- }
- else if(position / (float)specs.rate >= m_start+m_length)
- {
- if(m_type == AUD_FADE_OUT)
- {
- memset(buffer, 0, length * samplesize);
- }
- }
- else
- {
- float volume = 1.0f;
-
- for(int i = 0; i < length * specs.channels; i++)
- {
- if(i % specs.channels == 0)
- {
- volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
- if(volume > 1.0f)
- volume = 1.0f;
- else if(volume < 0.0f)
- volume = 0.0f;
-
- if(m_type == AUD_FADE_OUT)
- volume = 1.0f - volume;
- }
-
- buffer[i] = buffer[i] * volume;
- }
- }
-}
diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h
deleted file mode 100644
index a49960b30fb..00000000000
--- a/intern/audaspace/FX/AUD_FaderReader.h
+++ /dev/null
@@ -1,76 +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/FX/AUD_FaderReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_FADERREADER_H__
-#define __AUD_FADERREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class fades another reader.
- * If the fading type is AUD_FADE_IN, everything before the fading start will be
- * silenced, for AUD_FADE_OUT that's true for everything after fading ends.
- */
-class AUD_FaderReader : public AUD_EffectReader
-{
-private:
- /**
- * The fading type.
- */
- const AUD_FadeType m_type;
-
- /**
- * The fading start.
- */
- const float m_start;
-
- /**
- * The fading length.
- */
- const float m_length;
-
- // hide copy constructor and operator=
- AUD_FaderReader(const AUD_FaderReader&);
- AUD_FaderReader& operator=(const AUD_FaderReader&);
-
-public:
- /**
- * Creates a new fader reader.
- * \param type The fading type.
- * \param start The time where fading should start in seconds.
- * \param length How long fading should last in seconds.
- */
- 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);
-};
-
-#endif //__AUD_FADERREADER_H__
diff --git a/intern/audaspace/FX/AUD_HighpassCalculator.cpp b/intern/audaspace/FX/AUD_HighpassCalculator.cpp
deleted file mode 100644
index 573bba1c62b..00000000000
--- a/intern/audaspace/FX/AUD_HighpassCalculator.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "AUD_HighpassCalculator.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-AUD_HighpassCalculator::AUD_HighpassCalculator(float frequency, float Q) :
- m_frequency(frequency),
- m_Q(Q)
-{
-}
-
-void AUD_HighpassCalculator::recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a)
-{
- 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);
- a.push_back(-2 * c / norm);
- a.push_back((1 - alpha) / norm);
- b.push_back((1 + c) / (2 * norm));
- b.push_back((-1 - c) / norm);
- b.push_back(b[0]);
-}
diff --git a/intern/audaspace/FX/AUD_HighpassCalculator.h b/intern/audaspace/FX/AUD_HighpassCalculator.h
deleted file mode 100644
index bad1c08f7c7..00000000000
--- a/intern/audaspace/FX/AUD_HighpassCalculator.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef AUD_HIGHPASSCALCULATOR_H
-#define AUD_HIGHPASSCALCULATOR_H
-
-#include "AUD_IDynamicIIRFilterCalculator.h"
-
-class AUD_HighpassCalculator : public AUD_IDynamicIIRFilterCalculator
-{
-private:
- /**
- * The cutoff frequency.
- */
- const float m_frequency;
-
- /**
- * The Q factor.
- */
- const float m_Q;
-
-public:
- AUD_HighpassCalculator(float frequency, float Q);
-
- virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
-};
-
-#endif // AUD_HIGHPASSCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
deleted file mode 100644
index 2456085a8a1..00000000000
--- a/intern/audaspace/FX/AUD_HighpassFactory.cpp
+++ /dev/null
@@ -1,39 +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/FX/AUD_HighpassFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_HighpassFactory.h"
-#include "AUD_IIRFilterReader.h"
-#include "AUD_HighpassCalculator.h"
-
-AUD_HighpassFactory::AUD_HighpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency,
- float Q) :
- AUD_DynamicIIRFilterFactory(factory, boost::shared_ptr<AUD_IDynamicIIRFilterCalculator>(new AUD_HighpassCalculator(frequency, Q)))
-{
-}
-
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h
deleted file mode 100644
index 56ced91c53c..00000000000
--- a/intern/audaspace/FX/AUD_HighpassFactory.h
+++ /dev/null
@@ -1,55 +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/FX/AUD_HighpassFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_HIGHPASSFACTORY_H__
-#define __AUD_HIGHPASSFACTORY_H__
-
-#include "AUD_DynamicIIRFilterFactory.h"
-
-/**
- * This factory creates a highpass filter reader.
- */
-class AUD_HighpassFactory : public AUD_DynamicIIRFilterFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_HighpassFactory(const AUD_HighpassFactory&);
- AUD_HighpassFactory& operator=(const AUD_HighpassFactory&);
-
-public:
- /**
- * Creates a new highpass factory.
- * \param factory The input factory.
- * \param frequency The cutoff frequency.
- * \param Q The Q factor.
- */
- AUD_HighpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency, float Q = 1.0f);
-};
-
-#endif //__AUD_HIGHPASSFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h b/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
deleted file mode 100644
index 2e0d8418571..00000000000
--- a/intern/audaspace/FX/AUD_IDynamicIIRFilterCalculator.h
+++ /dev/null
@@ -1,56 +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/FX/AUD_IDynamicIIRFilterCalculator.h
- * \ingroup audfx
- */
-
-#ifndef AUD_IDYNAMICIIRFILTERCALCULATOR_H
-#define AUD_IDYNAMICIIRFILTERCALCULATOR_H
-
-#include "AUD_Space.h"
-
-#include <vector>
-
-/**
- * This interface calculates dynamic filter coefficients which depend on the
- * sampling rate for AUD_DynamicIIRFilterReaders.
- */
-class AUD_IDynamicIIRFilterCalculator
-{
-public:
- virtual ~AUD_IDynamicIIRFilterCalculator() {}
-
- /**
- * 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
deleted file mode 100644
index c4f94a2dc27..00000000000
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
+++ /dev/null
@@ -1,43 +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/FX/AUD_IIRFilterFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_IIRFilterFactory.h"
-#include "AUD_IIRFilterReader.h"
-
-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)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_IIRFilterFactory::createReader()
-{
- 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
deleted file mode 100644
index 0b55c120384..00000000000
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.h
+++ /dev/null
@@ -1,71 +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/FX/AUD_IIRFilterFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_IIRFILTERFACTORY_H__
-#define __AUD_IIRFILTERFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-#include "AUD_IDynamicIIRFilterCalculator.h"
-
-#include <vector>
-
-/**
- * This factory creates a IIR filter reader.
- */
-class AUD_IIRFilterFactory : public AUD_EffectFactory
-{
-private:
- /**
- * Output filter coefficients.
- */
- std::vector<float> m_a;
-
- /**
- * Input filter coefficients.
- */
- std::vector<float> m_b;
-
- // hide copy constructor and operator=
- AUD_IIRFilterFactory(const AUD_IIRFilterFactory&);
- AUD_IIRFilterFactory& operator=(const AUD_IIRFilterFactory&);
-
-public:
- /**
- * Creates a new IIR filter factory.
- * \param factory The input factory.
- * \param b The input filter coefficients.
- * \param a The output filter coefficients.
- */
- AUD_IIRFilterFactory(boost::shared_ptr<AUD_IFactory> factory, std::vector<float> b,
- std::vector<float> a);
-
- 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
deleted file mode 100644
index 6716e6b9ddc..00000000000
--- a/intern/audaspace/FX/AUD_IIRFilterReader.cpp
+++ /dev/null
@@ -1,65 +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/FX/AUD_IIRFilterReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_IIRFilterReader.h"
-
-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)
-{
- if(m_a.empty() == false)
- {
- for(int i = 1; i < m_a.size(); i++)
- m_a[i] /= m_a[0];
- for(int i = 0; i < m_b.size(); i++)
- m_b[i] /= m_a[0];
- m_a[0] = 1;
- }
-}
-
-sample_t AUD_IIRFilterReader::filter()
-{
- sample_t out = 0;
-
- for(int i = 1; i < m_a.size(); i++)
- out -= y(-i) * m_a[i];
- for(int i = 0; i < m_b.size(); i++)
- out += x(-i) * m_b[i];
-
- return out;
-}
-
-void AUD_IIRFilterReader::setCoefficients(const std::vector<float>& b,
- const std::vector<float>& a)
-{
- setLengths(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
deleted file mode 100644
index d663805b50f..00000000000
--- a/intern/audaspace/FX/AUD_IIRFilterReader.h
+++ /dev/null
@@ -1,73 +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/FX/AUD_IIRFilterReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_IIRFILTERREADER_H__
-#define __AUD_IIRFILTERREADER_H__
-
-#include "AUD_BaseIIRFilterReader.h"
-
-#include <vector>
-
-/**
- * This class is for infinite impulse response filters with simple coefficients.
- */
-class AUD_IIRFilterReader : public AUD_BaseIIRFilterReader
-{
-private:
- /**
- * Output filter coefficients.
- */
- std::vector<float> m_a;
-
- /**
- * Input filter coefficients.
- */
- std::vector<float> m_b;
-
- // hide copy constructor and operator=
- AUD_IIRFilterReader(const AUD_IIRFilterReader&);
- AUD_IIRFilterReader& operator=(const AUD_IIRFilterReader&);
-
-public:
- /**
- * Creates a new IIR filter reader.
- * \param reader The reader to read from.
- * \param b The input filter coefficients.
- * \param a The output filter coefficients.
- */
- AUD_IIRFilterReader(boost::shared_ptr<AUD_IReader> reader, const std::vector<float>& b,
- const std::vector<float>& a);
-
- virtual sample_t filter();
-
- void setCoefficients(const std::vector<float>& b,
- const std::vector<float>& a);
-};
-
-#endif //__AUD_IIRFILTERREADER_H__
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.cpp b/intern/audaspace/FX/AUD_LimiterFactory.cpp
deleted file mode 100644
index 679ed3a6b8b..00000000000
--- a/intern/audaspace/FX/AUD_LimiterFactory.cpp
+++ /dev/null
@@ -1,55 +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/FX/AUD_LimiterFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_LimiterFactory.h"
-#include "AUD_LimiterReader.h"
-#include "AUD_Space.h"
-
-AUD_LimiterFactory::AUD_LimiterFactory(boost::shared_ptr<AUD_IFactory> factory,
- float start, float end) :
- AUD_EffectFactory(factory),
- m_start(start),
- m_end(end)
-{
-}
-
-float AUD_LimiterFactory::getStart() const
-{
- return m_start;
-}
-
-float AUD_LimiterFactory::getEnd() const
-{
- return m_end;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_LimiterFactory::createReader()
-{
- 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
deleted file mode 100644
index 0376952b4bd..00000000000
--- a/intern/audaspace/FX/AUD_LimiterFactory.h
+++ /dev/null
@@ -1,79 +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/FX/AUD_LimiterFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LIMITERFACTORY_H__
-#define __AUD_LIMITERFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory limits another factory in start and end time.
- */
-class AUD_LimiterFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The start time.
- */
- const float m_start;
-
- /**
- * The end time.
- */
- const float m_end;
-
- // hide copy constructor and operator=
- AUD_LimiterFactory(const AUD_LimiterFactory&);
- AUD_LimiterFactory& operator=(const AUD_LimiterFactory&);
-
-public:
- /**
- * Creates a new limiter factory.
- * \param factory The input factory.
- * \param start The desired start time.
- * \param end The desired end time, a negative value signals that it should
- * play to the end.
- */
- AUD_LimiterFactory(boost::shared_ptr<AUD_IFactory> factory,
- float start = 0, float end = -1);
-
- /**
- * Returns the start time.
- */
- float getStart() const;
-
- /**
- * Returns the end time.
- */
- float getEnd() const;
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_LIMITERFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_LimiterReader.h b/intern/audaspace/FX/AUD_LimiterReader.h
deleted file mode 100644
index 607eb9e5bec..00000000000
--- a/intern/audaspace/FX/AUD_LimiterReader.h
+++ /dev/null
@@ -1,71 +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/FX/AUD_LimiterReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LIMITERREADER_H__
-#define __AUD_LIMITERREADER_H__
-
-#include "AUD_EffectReader.h"
-
-/**
- * This reader limits another reader in start and end times.
- */
-class AUD_LimiterReader : public AUD_EffectReader
-{
-private:
- /**
- * The start sample: inclusive.
- */
- const float m_start;
-
- /**
- * The end sample: exlusive.
- */
- const float m_end;
-
- // hide copy constructor and operator=
- AUD_LimiterReader(const AUD_LimiterReader&);
- AUD_LimiterReader& operator=(const AUD_LimiterReader&);
-
-public:
- /**
- * Creates a new limiter reader.
- * \param reader The reader to read from.
- * \param start The desired start time (inclusive).
- * \param end The desired end time (sample exklusive), a negative value
- * signals that it should play to the end.
- */
- AUD_LimiterReader(boost::shared_ptr<AUD_IReader> reader, float start = 0, float end = -1);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_LIMITERREADER_H__
diff --git a/intern/audaspace/FX/AUD_LoopFactory.cpp b/intern/audaspace/FX/AUD_LoopFactory.cpp
deleted file mode 100644
index a9e83e349a0..00000000000
--- a/intern/audaspace/FX/AUD_LoopFactory.cpp
+++ /dev/null
@@ -1,47 +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/FX/AUD_LoopFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_LoopFactory.h"
-#include "AUD_LoopReader.h"
-
-AUD_LoopFactory::AUD_LoopFactory(boost::shared_ptr<AUD_IFactory> factory, int loop) :
- AUD_EffectFactory(factory),
- m_loop(loop)
-{
-}
-
-int AUD_LoopFactory::getLoop() const
-{
- return m_loop;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_LoopFactory::createReader()
-{
- 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
deleted file mode 100644
index 570536bee9a..00000000000
--- a/intern/audaspace/FX/AUD_LoopFactory.h
+++ /dev/null
@@ -1,68 +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/FX/AUD_LoopFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LOOPFACTORY_H__
-#define __AUD_LOOPFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory loops another factory.
- * \note The reader has to be seekable.
- */
-class AUD_LoopFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The loop count.
- */
- const int m_loop;
-
- // hide copy constructor and operator=
- AUD_LoopFactory(const AUD_LoopFactory&);
- AUD_LoopFactory& operator=(const AUD_LoopFactory&);
-
-public:
- /**
- * Creates a new loop factory.
- * \param factory The input factory.
- * \param loop The desired loop count, negative values result in endless
- * looping.
- */
- AUD_LoopFactory(boost::shared_ptr<AUD_IFactory> factory, int loop = -1);
-
- /**
- * Returns the loop count.
- */
- int getLoop() const;
-
- 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
deleted file mode 100644
index 6fbcaa5af37..00000000000
--- a/intern/audaspace/FX/AUD_LoopReader.cpp
+++ /dev/null
@@ -1,101 +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/FX/AUD_LoopReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_LoopReader.h"
-#include "AUD_Buffer.h"
-
-#include <cstring>
-
-AUD_LoopReader::AUD_LoopReader(boost::shared_ptr<AUD_IReader> reader, int loop) :
- AUD_EffectReader(reader), m_count(loop), m_left(loop)
-{
-}
-
-void AUD_LoopReader::seek(int position)
-{
- int len = m_reader->getLength();
- if(len < 0)
- m_reader->seek(position);
- else
- {
- if(m_count >= 0)
- {
- m_left = m_count - (position / len);
- if(m_left < 0)
- m_left = 0;
- }
- m_reader->seek(position % len);
- }
-}
-
-int AUD_LoopReader::getLength() const
-{
- if(m_count < 0)
- return -1;
- return m_reader->getLength() * m_count;
-}
-
-int AUD_LoopReader::getPosition() const
-{
- return m_reader->getPosition() * (m_count < 0 ? 1 : m_count);
-}
-
-void AUD_LoopReader::read(int& length, bool& eos, sample_t* buffer)
-{
- const AUD_Specs specs = m_reader->getSpecs();
-
- int len = length;
-
- m_reader->read(length, eos, buffer);
-
- if(length < len && eos && m_left)
- {
- int pos = length;
- length = len;
-
- while(pos < length && eos && m_left)
- {
- if(m_left > 0)
- m_left--;
-
- m_reader->seek(0);
-
- len = length - pos;
- m_reader->read(len, eos, buffer + pos * specs.channels);
-
- // prevent endless loop
- if(!len)
- break;
-
- pos += len;
- }
-
- length = pos;
- }
-}
diff --git a/intern/audaspace/FX/AUD_LoopReader.h b/intern/audaspace/FX/AUD_LoopReader.h
deleted file mode 100644
index 12b8078b12d..00000000000
--- a/intern/audaspace/FX/AUD_LoopReader.h
+++ /dev/null
@@ -1,72 +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/FX/AUD_LoopReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LOOPREADER_H__
-#define __AUD_LOOPREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class reads another reader and loops it.
- * \note The other reader must be seekable.
- */
-class AUD_LoopReader : public AUD_EffectReader
-{
-private:
- /**
- * The loop count.
- */
- const int m_count;
-
- /**
- * The left loop count.
- */
- int m_left;
-
- // hide copy constructor and operator=
- AUD_LoopReader(const AUD_LoopReader&);
- AUD_LoopReader& operator=(const AUD_LoopReader&);
-
-public:
- /**
- * Creates a new loop reader.
- * \param reader The reader to read from.
- * \param loop The desired loop count, negative values result in endless
- * looping.
- */
- AUD_LoopReader(boost::shared_ptr<AUD_IReader> reader, int loop);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_LOOPREADER_H__
diff --git a/intern/audaspace/FX/AUD_LowpassCalculator.cpp b/intern/audaspace/FX/AUD_LowpassCalculator.cpp
deleted file mode 100644
index 57452f09038..00000000000
--- a/intern/audaspace/FX/AUD_LowpassCalculator.cpp
+++ /dev/null
@@ -1,27 +0,0 @@
-#include "AUD_LowpassCalculator.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-AUD_LowpassCalculator::AUD_LowpassCalculator(float frequency, float Q) :
- m_frequency(frequency),
- m_Q(Q)
-{
-}
-
-void AUD_LowpassCalculator::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 norm = 1 + alpha;
- float c = cos(w0);
- a.push_back(1);
- a.push_back(-2 * c / norm);
- a.push_back((1 - alpha) / norm);
- b.push_back((1 - c) / (2 * norm));
- b.push_back((1 - c) / norm);
- b.push_back(b[0]);
-}
diff --git a/intern/audaspace/FX/AUD_LowpassCalculator.h b/intern/audaspace/FX/AUD_LowpassCalculator.h
deleted file mode 100644
index 18bb11feda7..00000000000
--- a/intern/audaspace/FX/AUD_LowpassCalculator.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef AUD_LOWPASSCALCULATOR_H
-#define AUD_LOWPASSCALCULATOR_H
-
-#include "AUD_IDynamicIIRFilterCalculator.h"
-
-class AUD_LowpassCalculator : public AUD_IDynamicIIRFilterCalculator
-{
-private:
- /**
- * The cutoff frequency.
- */
- const float m_frequency;
-
- /**
- * The Q factor.
- */
- const float m_Q;
-
-public:
- AUD_LowpassCalculator(float frequency, float Q);
-
- virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
-};
-
-#endif // AUD_LOWPASSCALCULATOR_H
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
deleted file mode 100644
index bd225998392..00000000000
--- a/intern/audaspace/FX/AUD_LowpassFactory.cpp
+++ /dev/null
@@ -1,38 +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/FX/AUD_LowpassFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_LowpassFactory.h"
-#include "AUD_IIRFilterReader.h"
-#include "AUD_LowpassCalculator.h"
-
-AUD_LowpassFactory::AUD_LowpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency,
- float Q) :
- AUD_DynamicIIRFilterFactory(factory, boost::shared_ptr<AUD_IDynamicIIRFilterCalculator>(new AUD_LowpassCalculator(frequency, Q)))
-{
-}
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h
deleted file mode 100644
index dfd8ab35521..00000000000
--- a/intern/audaspace/FX/AUD_LowpassFactory.h
+++ /dev/null
@@ -1,55 +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/FX/AUD_LowpassFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_LOWPASSFACTORY_H__
-#define __AUD_LOWPASSFACTORY_H__
-
-#include "AUD_DynamicIIRFilterFactory.h"
-
-/**
- * This factory creates a lowpass filter reader.
- */
-class AUD_LowpassFactory : public AUD_DynamicIIRFilterFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_LowpassFactory(const AUD_LowpassFactory&);
- AUD_LowpassFactory& operator=(const AUD_LowpassFactory&);
-
-public:
- /**
- * Creates a new lowpass factory.
- * \param factory The input factory.
- * \param frequency The cutoff frequency.
- * \param Q The Q factor.
- */
- AUD_LowpassFactory(boost::shared_ptr<AUD_IFactory> factory, float frequency, float Q = 1.0f);
-};
-
-#endif //__AUD_LOWPASSFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.cpp b/intern/audaspace/FX/AUD_PingPongFactory.cpp
deleted file mode 100644
index 84e4b29415e..00000000000
--- a/intern/audaspace/FX/AUD_PingPongFactory.cpp
+++ /dev/null
@@ -1,46 +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/FX/AUD_PingPongFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_PingPongFactory.h"
-#include "AUD_DoubleReader.h"
-#include "AUD_ReverseFactory.h"
-
-AUD_PingPongFactory::AUD_PingPongFactory(boost::shared_ptr<AUD_IFactory> factory) :
- AUD_EffectFactory(factory)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_PingPongFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader = getReader();
- AUD_ReverseFactory factory(m_factory);
- boost::shared_ptr<AUD_IReader> reader2 = factory.createReader();
-
- 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
deleted file mode 100644
index e8ee5c9e389..00000000000
--- a/intern/audaspace/FX/AUD_PingPongFactory.h
+++ /dev/null
@@ -1,56 +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/FX/AUD_PingPongFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_PINGPONGFACTORY_H__
-#define __AUD_PINGPONGFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory plays another factory first normal, then reversed.
- * \note Readers from the underlying factory must be reversable with seeking.
- */
-class AUD_PingPongFactory : public AUD_EffectFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_PingPongFactory(const AUD_PingPongFactory&);
- AUD_PingPongFactory& operator=(const AUD_PingPongFactory&);
-
-public:
- /**
- * Creates a new ping pong factory.
- * \param factory The input factory.
- */
- AUD_PingPongFactory(boost::shared_ptr<AUD_IFactory> factory);
-
- 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
deleted file mode 100644
index 9dc27a58162..00000000000
--- a/intern/audaspace/FX/AUD_PitchFactory.cpp
+++ /dev/null
@@ -1,43 +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/FX/AUD_PitchFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_PitchFactory.h"
-#include "AUD_PitchReader.h"
-#include "AUD_Space.h"
-
-AUD_PitchFactory::AUD_PitchFactory(boost::shared_ptr<AUD_IFactory> factory, float pitch) :
- AUD_EffectFactory(factory),
- m_pitch(pitch)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_PitchFactory::createReader()
-{
- 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
deleted file mode 100644
index 159388b28dd..00000000000
--- a/intern/audaspace/FX/AUD_PitchFactory.h
+++ /dev/null
@@ -1,61 +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/FX/AUD_PitchFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_PITCHFACTORY_H__
-#define __AUD_PITCHFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory changes the pitch of another factory.
- */
-class AUD_PitchFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The pitch.
- */
- const float m_pitch;
-
- // hide copy constructor and operator=
- AUD_PitchFactory(const AUD_PitchFactory&);
- AUD_PitchFactory& operator=(const AUD_PitchFactory&);
-
-public:
- /**
- * Creates a new pitch factory.
- * \param factory The input factory.
- * \param pitch The desired pitch.
- */
- AUD_PitchFactory(boost::shared_ptr<AUD_IFactory> factory, float pitch);
-
- 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
deleted file mode 100644
index b3775c71a28..00000000000
--- a/intern/audaspace/FX/AUD_PitchReader.cpp
+++ /dev/null
@@ -1,54 +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/FX/AUD_PitchReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_PitchReader.h"
-
-AUD_PitchReader::AUD_PitchReader(boost::shared_ptr<AUD_IReader> reader, float pitch) :
- AUD_EffectReader(reader), m_pitch(pitch)
-{
-}
-
-AUD_Specs AUD_PitchReader::getSpecs() const
-{
- AUD_Specs specs = m_reader->getSpecs();
- specs.rate *= m_pitch;
- return specs;
-}
-
-float AUD_PitchReader::getPitch() const
-{
- return m_pitch;
-}
-
-void AUD_PitchReader::setPitch(float pitch)
-{
- if(pitch <= 0)
- pitch = 1;
- m_pitch = pitch;
-}
diff --git a/intern/audaspace/FX/AUD_PitchReader.h b/intern/audaspace/FX/AUD_PitchReader.h
deleted file mode 100644
index d22e589b05d..00000000000
--- a/intern/audaspace/FX/AUD_PitchReader.h
+++ /dev/null
@@ -1,73 +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/FX/AUD_PitchReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_PITCHREADER_H__
-#define __AUD_PITCHREADER_H__
-
-#include "AUD_EffectReader.h"
-
-/**
- * This class reads another reader and changes it's pitch.
- */
-class AUD_PitchReader : public AUD_EffectReader
-{
-private:
- /**
- * The pitch level.
- */
- float m_pitch;
-
- // hide copy constructor and operator=
- AUD_PitchReader(const AUD_PitchReader&);
- AUD_PitchReader& operator=(const AUD_PitchReader&);
-
-public:
- /**
- * Creates a new pitch reader.
- * \param reader The reader to read from.
- * \param pitch The pitch value.
- */
- AUD_PitchReader(boost::shared_ptr<AUD_IReader> reader, float pitch);
-
- virtual AUD_Specs getSpecs() const;
-
- /**
- * Retrieves the pitch.
- * \return The current pitch value.
- */
- float getPitch() const;
-
- /**
- * Sets the pitch.
- * \param pitch The new pitch value.
- */
- void setPitch(float pitch);
-};
-
-#endif //__AUD_PITCHREADER_H__
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.cpp b/intern/audaspace/FX/AUD_RectifyFactory.cpp
deleted file mode 100644
index 26bb5615dad..00000000000
--- a/intern/audaspace/FX/AUD_RectifyFactory.cpp
+++ /dev/null
@@ -1,48 +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/FX/AUD_RectifyFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_RectifyFactory.h"
-#include "AUD_CallbackIIRFilterReader.h"
-
-#include <cmath>
-
-sample_t AUD_RectifyFactory::rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
-{
- return fabs(reader->x(0));
-}
-
-AUD_RectifyFactory::AUD_RectifyFactory(boost::shared_ptr<AUD_IFactory> factory) :
- AUD_EffectFactory(factory)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_RectifyFactory::createReader()
-{
- 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
deleted file mode 100644
index eb595e43e4f..00000000000
--- a/intern/audaspace/FX/AUD_RectifyFactory.h
+++ /dev/null
@@ -1,58 +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/FX/AUD_RectifyFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_RECTIFYFACTORY_H__
-#define __AUD_RECTIFYFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-class AUD_CallbackIIRFilterReader;
-
-/**
- * This factory rectifies another factory.
- */
-class AUD_RectifyFactory : public AUD_EffectFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_RectifyFactory(const AUD_RectifyFactory&);
- AUD_RectifyFactory& operator=(const AUD_RectifyFactory&);
-
-public:
- /**
- * Creates a new rectify factory.
- * \param factory The input factory.
- */
- AUD_RectifyFactory(boost::shared_ptr<AUD_IFactory> factory);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-
- static sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
-};
-
-#endif //__AUD_RECTIFYFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.cpp b/intern/audaspace/FX/AUD_ReverseFactory.cpp
deleted file mode 100644
index afb4ad2bec9..00000000000
--- a/intern/audaspace/FX/AUD_ReverseFactory.cpp
+++ /dev/null
@@ -1,42 +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/FX/AUD_ReverseFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_ReverseFactory.h"
-#include "AUD_ReverseReader.h"
-#include "AUD_Space.h"
-
-AUD_ReverseFactory::AUD_ReverseFactory(boost::shared_ptr<AUD_IFactory> factory) :
- AUD_EffectFactory(factory)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_ReverseFactory::createReader()
-{
- 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
deleted file mode 100644
index 5b0c9e3c29a..00000000000
--- a/intern/audaspace/FX/AUD_ReverseFactory.h
+++ /dev/null
@@ -1,56 +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/FX/AUD_ReverseFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_REVERSEFACTORY_H__
-#define __AUD_REVERSEFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory reads another factory reverted.
- * \note Readers from the underlying factory must be seekable.
- */
-class AUD_ReverseFactory : public AUD_EffectFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_ReverseFactory(const AUD_ReverseFactory&);
- AUD_ReverseFactory& operator=(const AUD_ReverseFactory&);
-
-public:
- /**
- * Creates a new reverse factory.
- * \param factory The input factory.
- */
- AUD_ReverseFactory(boost::shared_ptr<AUD_IFactory> factory);
-
- 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
deleted file mode 100644
index c0a5962a299..00000000000
--- a/intern/audaspace/FX/AUD_ReverseReader.cpp
+++ /dev/null
@@ -1,105 +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/FX/AUD_ReverseReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_ReverseReader.h"
-
-#include <cstring>
-
-static const char* props_error = "AUD_ReverseReader: The reader has to be "
- "seekable and a finite length.";
-
-AUD_ReverseReader::AUD_ReverseReader(boost::shared_ptr<AUD_IReader> reader) :
- AUD_EffectReader(reader),
- m_length(reader->getLength()),
- m_position(0)
-{
- if(m_length < 0 || !reader->isSeekable())
- AUD_THROW(AUD_ERROR_PROPS, props_error);
-}
-
-void AUD_ReverseReader::seek(int position)
-{
- m_position = position;
-}
-
-int AUD_ReverseReader::getLength() const
-{
- return m_length;
-}
-
-int AUD_ReverseReader::getPosition() const
-{
- return m_position;
-}
-
-void AUD_ReverseReader::read(int& length, bool& eos, sample_t* buffer)
-{
- // first correct the length
- if(m_position + length > m_length)
- length = m_length - m_position;
-
- if(length <= 0)
- {
- length = 0;
- eos = true;
- return;
- }
-
- const AUD_Specs specs = getSpecs();
- const int samplesize = AUD_SAMPLE_SIZE(specs);
-
- sample_t temp[AUD_CHANNEL_MAX];
-
- int len = length;
-
- // read from reader
- m_reader->seek(m_length - m_position - len);
- m_reader->read(len, eos, buffer);
-
- // set null if reader didn't give enough data
- if(len < length)
- memset(buffer, 0, (length - len) * samplesize);
-
- // copy the samples reverted
- for(int i = 0; i < length / 2; i++)
- {
- memcpy(temp,
- buffer + (len - 1 - i) * specs.channels,
- samplesize);
- memcpy(buffer + (len - 1 - i) * specs.channels,
- buffer + i * specs.channels,
- samplesize);
- memcpy(buffer + i * specs.channels,
- temp,
- samplesize);
- }
-
- m_position += length;
- eos = false;
-}
diff --git a/intern/audaspace/FX/AUD_ReverseReader.h b/intern/audaspace/FX/AUD_ReverseReader.h
deleted file mode 100644
index 219047915bd..00000000000
--- a/intern/audaspace/FX/AUD_ReverseReader.h
+++ /dev/null
@@ -1,72 +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/FX/AUD_ReverseReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_REVERSEREADER_H__
-#define __AUD_REVERSEREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class reads another reader from back to front.
- * \note The underlying reader must be seekable.
- */
-class AUD_ReverseReader : public AUD_EffectReader
-{
-private:
- /**
- * The sample count.
- */
- const int m_length;
-
- /**
- * The current position.
- */
- int m_position;
-
- // hide copy constructor and operator=
- AUD_ReverseReader(const AUD_ReverseReader&);
- AUD_ReverseReader& operator=(const AUD_ReverseReader&);
-
-public:
- /**
- * Creates a new reverse reader.
- * \param reader The reader to read from.
- * \exception AUD_Exception Thrown if the reader specified has an
- * undeterminable/infinite length or is not seekable.
- */
- AUD_ReverseReader(boost::shared_ptr<AUD_IReader> reader);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_REVERSEREADER_H__
diff --git a/intern/audaspace/FX/AUD_SquareFactory.cpp b/intern/audaspace/FX/AUD_SquareFactory.cpp
deleted file mode 100644
index 4b4dccb6e6b..00000000000
--- a/intern/audaspace/FX/AUD_SquareFactory.cpp
+++ /dev/null
@@ -1,66 +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/FX/AUD_SquareFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_SquareFactory.h"
-#include "AUD_CallbackIIRFilterReader.h"
-
-sample_t AUD_SquareFactory::squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
-{
- float in = reader->x(0);
- if(in >= *threshold)
- return 1;
- else if(in <= -*threshold)
- return -1;
- else
- return 0;
-}
-
-void AUD_SquareFactory::endSquareFilter(float* threshold)
-{
- delete threshold;
-}
-
-AUD_SquareFactory::AUD_SquareFactory(boost::shared_ptr<AUD_IFactory> factory, float threshold) :
- AUD_EffectFactory(factory),
- m_threshold(threshold)
-{
-}
-
-float AUD_SquareFactory::getThreshold() const
-{
- return m_threshold;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SquareFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_CallbackIIRFilterReader(getReader(), 1, 1,
- (doFilterIIR) squareFilter,
- (endFilterIIR) endSquareFilter,
- new float(m_threshold)));
-}
diff --git a/intern/audaspace/FX/AUD_SquareFactory.h b/intern/audaspace/FX/AUD_SquareFactory.h
deleted file mode 100644
index 27e62b6f4cc..00000000000
--- a/intern/audaspace/FX/AUD_SquareFactory.h
+++ /dev/null
@@ -1,70 +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/FX/AUD_SquareFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_SQUAREFACTORY_H__
-#define __AUD_SQUAREFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-class AUD_CallbackIIRFilterReader;
-
-/**
- * This factory Transforms any signal to a square signal.
- */
-class AUD_SquareFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The threshold.
- */
- const float m_threshold;
-
- // hide copy constructor and operator=
- AUD_SquareFactory(const AUD_SquareFactory&);
- AUD_SquareFactory& operator=(const AUD_SquareFactory&);
-
-public:
- /**
- * Creates a new square factory.
- * \param factory The input factory.
- * \param threshold The threshold.
- */
- AUD_SquareFactory(boost::shared_ptr<AUD_IFactory> factory, float threshold = 0.0f);
-
- /**
- * Returns the threshold.
- */
- float getThreshold() const;
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-
- static sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold);
- static void endSquareFilter(float* threshold);
-};
-
-#endif //__AUD_SQUAREFACTORY_H__
diff --git a/intern/audaspace/FX/AUD_SumFactory.cpp b/intern/audaspace/FX/AUD_SumFactory.cpp
deleted file mode 100644
index 7f82233a0b7..00000000000
--- a/intern/audaspace/FX/AUD_SumFactory.cpp
+++ /dev/null
@@ -1,45 +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/FX/AUD_SumFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_SumFactory.h"
-#include "AUD_IIRFilterReader.h"
-
-AUD_SumFactory::AUD_SumFactory(boost::shared_ptr<AUD_IFactory> factory) :
- AUD_EffectFactory(factory)
-{
-}
-
-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 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
deleted file mode 100644
index a916f3509cb..00000000000
--- a/intern/audaspace/FX/AUD_SumFactory.h
+++ /dev/null
@@ -1,55 +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/FX/AUD_SumFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_SUMFACTORY_H__
-#define __AUD_SUMFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory creates a sum reader.
- */
-class AUD_SumFactory : public AUD_EffectFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_SumFactory(const AUD_SumFactory&);
- AUD_SumFactory& operator=(const AUD_SumFactory&);
-
-public:
- /**
- * Creates a new sum factory.
- * \param factory The input factory.
- */
- AUD_SumFactory(boost::shared_ptr<AUD_IFactory> factory);
-
- 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
deleted file mode 100644
index 3efad37a5b3..00000000000
--- a/intern/audaspace/FX/AUD_SuperposeFactory.cpp
+++ /dev/null
@@ -1,44 +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/FX/AUD_SuperposeFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_SuperposeFactory.h"
-#include "AUD_SuperposeReader.h"
-
-AUD_SuperposeFactory::AUD_SuperposeFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2) :
- m_factory1(factory1), m_factory2(factory2)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SuperposeFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader1 = m_factory1->createReader();
- boost::shared_ptr<AUD_IReader> reader2 = m_factory2->createReader();
-
- 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
deleted file mode 100644
index caa0dfb752f..00000000000
--- a/intern/audaspace/FX/AUD_SuperposeFactory.h
+++ /dev/null
@@ -1,68 +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/FX/AUD_SuperposeFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_SUPERPOSEFACTORY_H__
-#define __AUD_SUPERPOSEFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory mixes two other factories, playing them the same time.
- * \note Readers from the underlying factories must have the same sample rate
- * and channel count.
- */
-class AUD_SuperposeFactory : public AUD_IFactory
-{
-private:
- /**
- * First played factory.
- */
- boost::shared_ptr<AUD_IFactory> m_factory1;
-
- /**
- * Second played factory.
- */
- boost::shared_ptr<AUD_IFactory> m_factory2;
-
- // hide copy constructor and operator=
- AUD_SuperposeFactory(const AUD_SuperposeFactory&);
- AUD_SuperposeFactory& operator=(const AUD_SuperposeFactory&);
-
-public:
- /**
- * Creates a new superpose factory.
- * \param factory1 The first input factory.
- * \param factory2 The second input factory.
- */
- AUD_SuperposeFactory(boost::shared_ptr<AUD_IFactory> factory1, boost::shared_ptr<AUD_IFactory> factory2);
-
- 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
deleted file mode 100644
index 294a48b3e7a..00000000000
--- a/intern/audaspace/FX/AUD_SuperposeReader.cpp
+++ /dev/null
@@ -1,105 +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/FX/AUD_SuperposeReader.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_SuperposeReader.h"
-
-#include <cstring>
-
-static const char* specs_error = "AUD_SuperposeReader: Both readers have to "
- "have the same specs.";
-
-AUD_SuperposeReader::AUD_SuperposeReader(boost::shared_ptr<AUD_IReader> reader1, boost::shared_ptr<AUD_IReader> reader2) :
- m_reader1(reader1), m_reader2(reader2)
-{
-}
-
-AUD_SuperposeReader::~AUD_SuperposeReader()
-{
-}
-
-bool AUD_SuperposeReader::isSeekable() const
-{
- return m_reader1->isSeekable() && m_reader2->isSeekable();
-}
-
-void AUD_SuperposeReader::seek(int position)
-{
- m_reader1->seek(position);
- m_reader2->seek(position);
-}
-
-int AUD_SuperposeReader::getLength() const
-{
- int len1 = m_reader1->getLength();
- int len2 = m_reader2->getLength();
- if((len1 < 0) || (len2 < 0))
- return -1;
- return AUD_MIN(len1, len2);
-}
-
-int AUD_SuperposeReader::getPosition() const
-{
- int pos1 = m_reader1->getPosition();
- int pos2 = m_reader2->getPosition();
- return AUD_MAX(pos1, pos2);
-}
-
-AUD_Specs AUD_SuperposeReader::getSpecs() const
-{
- return m_reader1->getSpecs();
-}
-
-void AUD_SuperposeReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_Specs specs = m_reader1->getSpecs();
- AUD_Specs s2 = m_reader2->getSpecs();
- if(!AUD_COMPARE_SPECS(specs, s2))
- AUD_THROW(AUD_ERROR_SPECS, specs_error);
-
- int samplesize = AUD_SAMPLE_SIZE(specs);
-
- m_buffer.assureSize(length * samplesize);
-
- int len1 = length;
- m_reader1->read(len1, eos, buffer);
-
- if(len1 < length)
- memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
-
- int len2 = length;
- bool eos2;
- sample_t* buf = m_buffer.getBuffer();
- m_reader2->read(len2, eos2, buf);
-
- for(int i = 0; i < len2 * specs.channels; i++)
- buffer[i] += buf[i];
-
- length = AUD_MAX(len1, len2);
- eos &= eos2;
-}
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h
deleted file mode 100644
index a04ab90fe43..00000000000
--- a/intern/audaspace/FX/AUD_SuperposeReader.h
+++ /dev/null
@@ -1,85 +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/FX/AUD_SuperposeReader.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_SUPERPOSEREADER_H__
-#define __AUD_SUPERPOSEREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-#include <boost/shared_ptr.hpp>
-
-/**
- * This reader plays two readers with the same specs in parallel.
- */
-class AUD_SuperposeReader : public AUD_IReader
-{
-private:
- /**
- * The first reader.
- */
- boost::shared_ptr<AUD_IReader> m_reader1;
-
- /**
- * The second reader.
- */
- boost::shared_ptr<AUD_IReader> m_reader2;
-
- /**
- * Buffer used for mixing.
- */
- AUD_Buffer m_buffer;
-
- // hide copy constructor and operator=
- AUD_SuperposeReader(const AUD_SuperposeReader&);
- AUD_SuperposeReader& operator=(const AUD_SuperposeReader&);
-
-public:
- /**
- * Creates a new superpose reader.
- * \param reader1 The first reader to read from.
- * \param reader2 The second reader to read from.
- * \exception AUD_Exception Thrown if the specs from the readers differ.
- */
- AUD_SuperposeReader(boost::shared_ptr<AUD_IReader> reader1, boost::shared_ptr<AUD_IReader> reader2);
-
- /**
- * Destroys the reader.
- */
- virtual ~AUD_SuperposeReader();
-
- virtual bool isSeekable() const;
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SUPERPOSEREADER_H__
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.cpp b/intern/audaspace/FX/AUD_VolumeFactory.cpp
deleted file mode 100644
index 4f0e1e425e6..00000000000
--- a/intern/audaspace/FX/AUD_VolumeFactory.cpp
+++ /dev/null
@@ -1,50 +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/FX/AUD_VolumeFactory.cpp
- * \ingroup audfx
- */
-
-
-#include "AUD_VolumeFactory.h"
-#include "AUD_IIRFilterReader.h"
-
-AUD_VolumeFactory::AUD_VolumeFactory(boost::shared_ptr<AUD_IFactory> factory, float volume) :
- AUD_EffectFactory(factory),
- m_volume(volume)
-{
-}
-
-float AUD_VolumeFactory::getVolume() const
-{
- return m_volume;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_VolumeFactory::createReader()
-{
- std::vector<float> a, b;
- a.push_back(1);
- b.push_back(m_volume);
- 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
deleted file mode 100644
index 6fe779ffb88..00000000000
--- a/intern/audaspace/FX/AUD_VolumeFactory.h
+++ /dev/null
@@ -1,69 +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/FX/AUD_VolumeFactory.h
- * \ingroup audfx
- */
-
-
-#ifndef __AUD_VOLUMEFACTORY_H__
-#define __AUD_VOLUMEFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory changes the volume of another factory.
- * The set volume should be a value between 0.0 and 1.0, higher values at your
- * own risk!
- */
-class AUD_VolumeFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The volume.
- */
- const float m_volume;
-
- // hide copy constructor and operator=
- AUD_VolumeFactory(const AUD_VolumeFactory&);
- AUD_VolumeFactory& operator=(const AUD_VolumeFactory&);
-
-public:
- /**
- * Creates a new volume factory.
- * \param factory The input factory.
- * \param volume The desired volume.
- */
- AUD_VolumeFactory(boost::shared_ptr<AUD_IFactory> factory, float volume);
-
- /**
- * Returns the volume.
- * \return The current volume.
- */
- float getVolume() const;
-
- 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
deleted file mode 100644
index c0c77b6f917..00000000000
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ /dev/null
@@ -1,1647 +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/OpenAL/AUD_OpenALDevice.cpp
- * \ingroup audopenal
- */
-
-
-#include "AUD_OpenALDevice.h"
-#include "AUD_IFactory.h"
-#include "AUD_IReader.h"
-#include "AUD_ConverterReader.h"
-#include "AUD_MutexLock.h"
-
-#include <cstring>
-#include <limits>
-
-#ifdef WIN32
-#include <windows.h>
-#else
-#include <unistd.h>
-#endif
-
-/*struct AUD_OpenALBufferedFactory
-{
- /// The factory.
- AUD_IFactory* factory;
-
- /// The OpenAL buffer.
- ALuint buffer;
-};*/
-
-//typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
-
-
-/******************************************************************************/
-/*********************** AUD_OpenALHandle Handle Code *************************/
-/******************************************************************************/
-
-static const char* genbuffer_error = "AUD_OpenALDevice: Buffer couldn't be "
- "generated.";
-static const char* gensource_error = "AUD_OpenALDevice: Source couldn't be "
- "generated.";
-static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
- "queued to the source.";
-static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
- "filled with data.";
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::pause(bool keep)
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PLAYING)
- {
- 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);
- m_device->m_pausedSounds.push_back(This);
-
- alSourcePause(m_source);
-
- m_status = keep ? AUD_STATUS_STOPPED : AUD_STATUS_PAUSED;
-
- return true;
- }
- }
- }
- }
-
- return false;}
-
-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)
-{
- AUD_DeviceSpecs specs = m_device->m_specs;
- specs.specs = m_reader->getSpecs();
-
- // OpenAL playback code
- alGenBuffers(CYCLE_BUFFERS, m_buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
-
- try
- {
- m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
- int length;
- bool eos;
-
- for(int i = 0; i < CYCLE_BUFFERS; i++)
- {
- length = m_device->m_buffersize;
- reader->read(length, eos, m_device->m_buffer.getBuffer());
-
- if(length == 0)
- {
- // AUD_XXX: TODO: don't fill all buffers and enqueue them later
- length = 1;
- memset(m_device->m_buffer.getBuffer(), 0, length * AUD_DEVICE_SAMPLE_SIZE(specs));
- }
-
- alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
- length * AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
- }
-
- alGenSources(1, &m_source);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
-
- try
- {
- alSourceQueueBuffers(m_source, CYCLE_BUFFERS, m_buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, queue_error);
- }
- catch(AUD_Exception&)
- {
- alDeleteSources(1, &m_source);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
- throw;
- }
- alSourcei(m_source, AL_SOURCE_RELATIVE, 1);
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
-{
- return pause(false);
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PAUSED)
- {
- 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->m_pausedSounds.erase(it);
- m_device->m_playingSounds.push_back(This);
-
- m_device->start();
- m_status = AUD_STATUS_PLAYING;
-
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::stop()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_status = AUD_STATUS_INVALID;
-
- alDeleteSources(1, &m_source);
- if(!m_isBuffered)
- alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
-
- 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()
-{
- if(m_status)
- return m_keep;
-
- return false;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setKeep(bool keep)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_keep = keep;
-
- return true;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- if(m_isBuffered)
- alSourcef(m_source, AL_SEC_OFFSET, position);
- else
- {
- m_reader->seek((int)(position * m_reader->getSpecs().rate));
- m_eos = false;
-
- ALint info;
-
- alGetSourcei(m_source, AL_SOURCE_STATE, &info);
-
- // we need to stop playing sounds as well to clear the buffers
- // this might cause clicks, but fixes a bug regarding position determination
- if(info == AL_PAUSED || info == AL_PLAYING)
- alSourceStop(m_source);
-
- alSourcei(m_source, AL_BUFFER, 0);
- m_current = 0;
-
- ALenum err;
- if((err = alGetError()) == AL_NO_ERROR)
- {
- int length;
- AUD_DeviceSpecs specs = m_device->m_specs;
- specs.specs = m_reader->getSpecs();
- m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
-
- for(int i = 0; i < CYCLE_BUFFERS; i++)
- {
- length = m_device->m_buffersize;
- m_reader->read(length, m_eos, m_device->m_buffer.getBuffer());
-
- if(length == 0)
- {
- // AUD_XXX: TODO: don't fill all buffers and enqueue them later
- length = 1;
- memset(m_device->m_buffer.getBuffer(), 0, length * AUD_DEVICE_SAMPLE_SIZE(specs));
- }
-
- alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
- length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
-
- if(alGetError() != AL_NO_ERROR)
- break;
- }
-
- if(m_loopcount != 0)
- m_eos = false;
-
- alSourceQueueBuffers(m_source, CYCLE_BUFFERS, m_buffers);
- }
-
- alSourceRewind(m_source);
- }
-
- if(m_status == AUD_STATUS_STOPPED)
- m_status = AUD_STATUS_PAUSED;
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getPosition()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return 0.0f;
-
- float position = 0.0f;
-
- alGetSourcef(m_source, AL_SEC_OFFSET, &position);
-
- if(!m_isBuffered)
- {
- int queued;
-
- // this usually always returns CYCLE_BUFFERS
- alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queued);
-
- AUD_Specs specs = m_reader->getSpecs();
- position += (m_reader->getPosition() - m_device->m_buffersize *
- queued) / (float)specs.rate;
- }
-
- return position;
-}
-
-AUD_Status AUD_OpenALDevice::AUD_OpenALHandle::getStatus()
-{
- return m_status;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getVolume()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setVolume(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_GAIN, volume);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getPitch()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_PITCH, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setPitch(float pitch)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_PITCH, pitch);
-
- return true;
-}
-
-int AUD_OpenALDevice::AUD_OpenALHandle::getLoopCount()
-{
- if(!m_status)
- return 0;
- return m_loopcount;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setLoopCount(int count)
-{
- if(!m_status)
- return false;
-
- if(m_status == AUD_STATUS_STOPPED && (count > m_loopcount || count < 0))
- m_status = AUD_STATUS_PAUSED;
-
- m_loopcount = count;
-
- return true;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setStopCallback(stopCallback callback, void* data)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_stop = callback;
- m_stop_data = data;
-
- return true;
-}
-
-/******************************************************************************/
-/********************* AUD_OpenALHandle 3DHandle Code *************************/
-/******************************************************************************/
-
-AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceLocation()
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- ALfloat p[3];
- alGetSourcefv(m_source, AL_POSITION, p);
-
- result = AUD_Vector3(p[0], p[1], p[2]);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceLocation(const AUD_Vector3& location)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
-
- return true;
-}
-
-AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceVelocity()
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- ALfloat v[3];
- alGetSourcefv(m_source, AL_VELOCITY, v);
-
- result = AUD_Vector3(v[0], v[1], v[2]);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceVelocity(const AUD_Vector3& velocity)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
-
- return true;
-}
-
-AUD_Quaternion AUD_OpenALDevice::AUD_OpenALHandle::getSourceOrientation()
-{
- return m_orientation;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaternion& orientation)
-{
- ALfloat direction[3];
- direction[0] = -2 * (orientation.w() * orientation.y() +
- orientation.x() * orientation.z());
- direction[1] = 2 * (orientation.x() * orientation.w() -
- orientation.z() * orientation.y());
- direction[2] = 2 * (orientation.x() * orientation.x() +
- orientation.y() * orientation.y()) - 1;
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcefv(m_source, AL_DIRECTION, direction);
-
- m_orientation = orientation;
-
- return true;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::isRelative()
-{
- int result;
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setRelative(bool relative)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMaximum()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_MAX_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMaximum(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_MAX_GAIN, volume);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMinimum()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_MIN_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMinimum(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_MIN_GAIN, volume);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceMaximum()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceMaximum(float distance)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_MAX_DISTANCE, distance);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceReference()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceReference(float distance)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getAttenuation()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setAttenuation(float factor)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleOuter()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getConeVolumeOuter()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setConeVolumeOuter(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
-
- return true;
-}
-
-/******************************************************************************/
-/**************************** Threading Code **********************************/
-/******************************************************************************/
-
-static void *AUD_openalRunThread(void *device)
-{
- AUD_OpenALDevice* dev = (AUD_OpenALDevice*)device;
- dev->updateStreams();
- return NULL;
-}
-
-void AUD_OpenALDevice::start(bool join)
-{
- AUD_MutexLock lock(*this);
-
- if(!m_playing)
- {
- if(join)
- pthread_join(m_thread, NULL);
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- pthread_create(&m_thread, &attr, AUD_openalRunThread, this);
-
- pthread_attr_destroy(&attr);
-
- m_playing = true;
- }
-}
-
-void AUD_OpenALDevice::updateStreams()
-{
- boost::shared_ptr<AUD_OpenALHandle> sound;
-
- int length;
-
- ALint info;
- AUD_DeviceSpecs specs = m_specs;
- ALCenum cerr;
- std::list<boost::shared_ptr<AUD_OpenALHandle> > stopSounds;
- std::list<boost::shared_ptr<AUD_OpenALHandle> > pauseSounds;
- AUD_HandleIterator it;
-
- while(1)
- {
- lock();
-
- alcSuspendContext(m_context);
- cerr = alcGetError(m_device);
- if(cerr == ALC_NO_ERROR)
- {
- // for all sounds
- for(it = m_playingSounds.begin(); it != m_playingSounds.end(); it++)
- {
- sound = *it;
-
- // is it a streamed sound?
- if(!sound->m_isBuffered)
- {
- // check for buffer refilling
- alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info);
-
- if(info)
- {
- specs.specs = sound->m_reader->getSpecs();
- m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
-
- // for all empty buffers
- while(info--)
- {
- // if there's still data to play back
- if(!sound->m_eos)
- {
- // read data
- length = m_buffersize;
- sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
-
- // looping necessary?
- if(length == 0 && sound->m_loopcount)
- {
- if(sound->m_loopcount > 0)
- sound->m_loopcount--;
-
- sound->m_reader->seek(0);
-
- length = m_buffersize;
- sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
- }
-
- if(sound->m_loopcount != 0)
- sound->m_eos = false;
-
- // read nothing?
- if(length == 0)
- {
- break;
- }
-
- // unqueue buffer (warning: this might fail for slow early returning sources (none exist so far) if the buffer was not queued due to recent changes - has to be tested)
- alSourceUnqueueBuffers(sound->m_source, 1, &sound->m_buffers[sound->m_current]);
- ALenum err;
- if((err = alGetError()) != AL_NO_ERROR)
- {
- sound->m_eos = true;
- break;
- }
-
- // fill with new data
- alBufferData(sound->m_buffers[sound->m_current],
- sound->m_format,
- m_buffer.getBuffer(), length *
- AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
-
- if((err = alGetError()) != AL_NO_ERROR)
- {
- sound->m_eos = true;
- break;
- }
-
- // and queue again
- alSourceQueueBuffers(sound->m_source, 1,
- &sound->m_buffers[sound->m_current]);
- if(alGetError() != AL_NO_ERROR)
- {
- sound->m_eos = true;
- break;
- }
-
- sound->m_current = (sound->m_current+1) %
- AUD_OpenALHandle::CYCLE_BUFFERS;
- }
- else
- break;
- }
- }
- }
-
- // check if the sound has been stopped
- alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info);
-
- if(info != AL_PLAYING)
- {
- // if it really stopped
- if(sound->m_eos && info != AL_INITIAL)
- {
- if(sound->m_stop)
- sound->m_stop(sound->m_stop_data);
-
- // pause or
- if(sound->m_keep)
- pauseSounds.push_back(sound);
- // stop
- else
- stopSounds.push_back(sound);
- }
- // continue playing
- else
- alSourcePlay(sound->m_source);
- }
- }
-
- for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
- (*it)->pause(true);
-
- for(it = stopSounds.begin(); it != stopSounds.end(); it++)
- (*it)->stop();
-
- pauseSounds.clear();
- stopSounds.clear();
-
- alcProcessContext(m_context);
- }
-
- // stop thread
- if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
- {
- m_playing = false;
- unlock();
- pthread_exit(NULL);
- }
-
- unlock();
-
-#ifdef WIN32
- Sleep(20);
-#else
- usleep(20000);
-#endif
- }
-}
-
-/******************************************************************************/
-/**************************** IDevice Code ************************************/
-/******************************************************************************/
-
-static const char* open_error = "AUD_OpenALDevice: Device couldn't be opened.";
-
-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.format = AUD_FORMAT_S16;
-
-#if 0
- if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE)
- {
- ALCchar* devices = const_cast<ALCchar*>(alcGetString(NULL, ALC_DEVICE_SPECIFIER));
- printf("OpenAL devices (standard is: %s):\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
-
- while(*devices)
- {
- printf("%s\n", devices);
- devices += strlen(devices) + 1;
- }
- }
-#endif
-
- m_device = alcOpenDevice(NULL);
-
- if(!m_device)
- AUD_THROW(AUD_ERROR_OPENAL, open_error);
-
- // at least try to set the frequency
- ALCint attribs[] = { ALC_FREQUENCY, (ALCint)specs.rate, 0 };
- ALCint* attributes = attribs;
- if(specs.rate == AUD_RATE_INVALID)
- attributes = NULL;
-
- m_context = alcCreateContext(m_device, attributes);
- alcMakeContextCurrent(m_context);
-
- alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate);
-
- // check for specific formats and channel counts to be played back
- if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
- specs.format = AUD_FORMAT_FLOAT32;
-
- 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);
-
- m_specs = specs;
- m_buffersize = buffersize;
- m_playing = false;
-
-// m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
-
- 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);
-
- start(false);
-}
-
-AUD_OpenALDevice::~AUD_OpenALDevice()
-{
- lock();
- alcSuspendContext(m_context);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-
-
- // delete all buffered factories
- /*while(!m_bufferedFactories->empty())
- {
- alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
- delete *m_bufferedFactories->begin();
- m_bufferedFactories->erase(m_bufferedFactories->begin());
- }*/
-
- alcProcessContext(m_context);
-
- // wait for the thread to stop
- unlock();
- pthread_join(m_thread, NULL);
-
- //delete m_bufferedFactories;
-
- // quit OpenAL
- alcMakeContextCurrent(NULL);
- alcDestroyContext(m_context);
- alcCloseDevice(m_device);
-
- pthread_mutex_destroy(&m_mutex);
-}
-
-AUD_DeviceSpecs AUD_OpenALDevice::getSpecs() const
-{
- return m_specs;
-}
-
-bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
-{
- bool valid = true;
- format = 0;
-
- switch(m_specs.format)
- {
- case AUD_FORMAT_S16:
- switch(specs.channels)
- {
- case AUD_CHANNELS_MONO:
- format = AL_FORMAT_MONO16;
- break;
- case AUD_CHANNELS_STEREO:
- format = AL_FORMAT_STEREO16;
- break;
- case AUD_CHANNELS_SURROUND4:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_QUAD16");
- break;
- }
- case AUD_CHANNELS_SURROUND51:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_51CHN16");
- break;
- }
- case AUD_CHANNELS_SURROUND61:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_61CHN16");
- break;
- }
- case AUD_CHANNELS_SURROUND71:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_71CHN16");
- break;
- }
- default:
- valid = false;
- }
- break;
- case AUD_FORMAT_FLOAT32:
- switch(specs.channels)
- {
- case AUD_CHANNELS_MONO:
- format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
- break;
- case AUD_CHANNELS_STEREO:
- format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
- break;
- case AUD_CHANNELS_SURROUND4:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_QUAD32");
- break;
- }
- case AUD_CHANNELS_SURROUND51:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_51CHN32");
- break;
- }
- case AUD_CHANNELS_SURROUND61:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_61CHN32");
- break;
- }
- case AUD_CHANNELS_SURROUND71:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_71CHN32");
- break;
- }
- default:
- valid = false;
- }
- break;
- default:
- valid = false;
- }
-
- if(!format)
- valid = false;
-
- return valid;
-}
-
-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 boost::shared_ptr<AUD_IHandle>();
-
- if(m_specs.format != AUD_FORMAT_FLOAT32)
- reader = boost::shared_ptr<AUD_IReader>(new AUD_ConverterReader(reader, m_specs));
-
- ALenum format;
-
- if(!getFormat(format, specs))
- return boost::shared_ptr<AUD_IHandle>();
-
- AUD_MutexLock lock(*this);
-
- alcSuspendContext(m_context);
-
- boost::shared_ptr<AUD_OpenALDevice::AUD_OpenALHandle> sound;
-
- try
- {
- // create the handle
- sound = boost::shared_ptr<AUD_OpenALDevice::AUD_OpenALHandle>(new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep));
- }
- catch(AUD_Exception&)
- {
- alcProcessContext(m_context);
- throw;
- }
-
- alcProcessContext(m_context);
-
- // play sound
- m_playingSounds.push_back(sound);
-
- start();
-
- return boost::shared_ptr<AUD_IHandle>(sound);
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_OpenALDevice::play(boost::shared_ptr<AUD_IFactory> factory, bool keep)
-{
- /* AUD_XXX disabled
- AUD_OpenALHandle* sound = NULL;
-
- lock();
-
- try
- {
- // check if it is a buffered factory
- for(AUD_BFIterator i = m_bufferedFactories->begin();
- i != m_bufferedFactories->end(); i++)
- {
- if((*i)->factory == factory)
- {
- // create the handle
- sound = new AUD_OpenALHandle;
- sound->keep = keep;
- sound->current = -1;
- sound->isBuffered = true;
- sound->eos = true;
- sound->loopcount = 0;
- sound->stop = NULL;
- sound->stop_data = NULL;
-
- alcSuspendContext(m_context);
-
- // OpenAL playback code
- try
- {
- alGenSources(1, &sound->source);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
-
- try
- {
- alSourcei(sound->source, AL_BUFFER, (*i)->buffer);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, queue_error);
- }
- catch(AUD_Exception&)
- {
- alDeleteSources(1, &sound->source);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- delete sound;
- alcProcessContext(m_context);
- throw;
- }
-
- // play sound
- m_playingSounds->push_back(sound);
-
- alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
- start();
-
- alcProcessContext(m_context);
- }
- }
- }
- catch(AUD_Exception&)
- {
- unlock();
- throw;
- }
-
- unlock();
-
- if(sound)
- return sound;*/
-
- return play(factory->createReader(), keep);
-}
-
-void AUD_OpenALDevice::stopAll()
-{
- AUD_MutexLock lock(*this);
-
- alcSuspendContext(m_context);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-
- alcProcessContext(m_context);
-}
-
-void AUD_OpenALDevice::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_OpenALDevice::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}
-
-float AUD_OpenALDevice::getVolume() const
-{
- float result;
- alGetListenerf(AL_GAIN, &result);
- return result;
-}
-
-void AUD_OpenALDevice::setVolume(float volume)
-{
- alListenerf(AL_GAIN, volume);
-}
-
-/* AUD_XXX Temorary disabled
-
-bool AUD_OpenALDevice::bufferFactory(void *value)
-{
- bool result = false;
- AUD_IFactory* factory = (AUD_IFactory*) value;
-
- // load the factory into an OpenAL buffer
- if(factory)
- {
- // check if the factory is already buffered
- lock();
- for(AUD_BFIterator i = m_bufferedFactories->begin();
- i != m_bufferedFactories->end(); i++)
- {
- if((*i)->factory == factory)
- {
- result = true;
- break;
- }
- }
- unlock();
- if(result)
- return result;
-
- AUD_IReader* reader = factory->createReader();
-
- if(reader == NULL)
- return false;
-
- AUD_DeviceSpecs specs = m_specs;
- specs.specs = reader->getSpecs();
-
- if(m_specs.format != AUD_FORMAT_FLOAT32)
- reader = new AUD_ConverterReader(reader, m_specs);
-
- ALenum format;
-
- if(!getFormat(format, specs.specs))
- {
- return false;
- }
-
- // load into a buffer
- lock();
- alcSuspendContext(m_context);
-
- AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
- bf->factory = factory;
-
- try
- {
- alGenBuffers(1, &bf->buffer);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL);
-
- try
- {
- sample_t* buf;
- int length = reader->getLength();
-
- reader->read(length, buf);
- alBufferData(bf->buffer, format, buf,
- length * AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL);
- }
- catch(AUD_Exception&)
- {
- alDeleteBuffers(1, &bf->buffer);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- delete bf;
- alcProcessContext(m_context);
- unlock();
- return false;
- }
-
- m_bufferedFactories->push_back(bf);
-
- alcProcessContext(m_context);
- unlock();
- }
- else
- {
- // stop all playing and paused buffered sources
- lock();
- alcSuspendContext(m_context);
-
- AUD_OpenALHandle* sound;
- AUD_HandleIterator it = m_playingSounds->begin();
- while(it != m_playingSounds->end())
- {
- sound = *it;
- ++it;
-
- if(sound->isBuffered)
- stop(sound);
- }
- alcProcessContext(m_context);
-
- while(!m_bufferedFactories->empty())
- {
- alDeleteBuffers(1,
- &(*(m_bufferedFactories->begin()))->buffer);
- delete *m_bufferedFactories->begin();
- m_bufferedFactories->erase(m_bufferedFactories->begin());
- }
- unlock();
- }
-
- return true;
-}*/
-
-/******************************************************************************/
-/**************************** 3D Device Code **********************************/
-/******************************************************************************/
-
-AUD_Vector3 AUD_OpenALDevice::getListenerLocation() const
-{
- ALfloat p[3];
- alGetListenerfv(AL_POSITION, p);
- return AUD_Vector3(p[0], p[1], p[2]);
-}
-
-void AUD_OpenALDevice::setListenerLocation(const AUD_Vector3& location)
-{
- alListenerfv(AL_POSITION, (ALfloat*)location.get());
-}
-
-AUD_Vector3 AUD_OpenALDevice::getListenerVelocity() const
-{
- ALfloat v[3];
- alGetListenerfv(AL_VELOCITY, v);
- return AUD_Vector3(v[0], v[1], v[2]);
-}
-
-void AUD_OpenALDevice::setListenerVelocity(const AUD_Vector3& velocity)
-{
- alListenerfv(AL_VELOCITY, (ALfloat*)velocity.get());
-}
-
-AUD_Quaternion AUD_OpenALDevice::getListenerOrientation() const
-{
- return m_orientation;
-}
-
-void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
-{
- ALfloat direction[6];
- direction[0] = -2 * (orientation.w() * orientation.y() +
- orientation.x() * orientation.z());
- direction[1] = 2 * (orientation.x() * orientation.w() -
- orientation.z() * orientation.y());
- direction[2] = 2 * (orientation.x() * orientation.x() +
- orientation.y() * orientation.y()) - 1;
- direction[3] = 2 * (orientation.x() * orientation.y() -
- orientation.w() * orientation.z());
- direction[4] = 1 - 2 * (orientation.x() * orientation.x() +
- orientation.z() * orientation.z());
- direction[5] = 2 * (orientation.w() * orientation.x() +
- orientation.y() * orientation.z());
- alListenerfv(AL_ORIENTATION, direction);
- m_orientation = orientation;
-}
-
-float AUD_OpenALDevice::getSpeedOfSound() const
-{
- return alGetFloat(AL_SPEED_OF_SOUND);
-}
-
-void AUD_OpenALDevice::setSpeedOfSound(float speed)
-{
- alSpeedOfSound(speed);
-}
-
-float AUD_OpenALDevice::getDopplerFactor() const
-{
- return alGetFloat(AL_DOPPLER_FACTOR);
-}
-
-void AUD_OpenALDevice::setDopplerFactor(float factor)
-{
- alDopplerFactor(factor);
-}
-
-AUD_DistanceModel AUD_OpenALDevice::getDistanceModel() const
-{
- switch(alGetInteger(AL_DISTANCE_MODEL))
- {
- case AL_INVERSE_DISTANCE:
- return AUD_DISTANCE_MODEL_INVERSE;
- case AL_INVERSE_DISTANCE_CLAMPED:
- return AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
- case AL_LINEAR_DISTANCE:
- return AUD_DISTANCE_MODEL_LINEAR;
- case AL_LINEAR_DISTANCE_CLAMPED:
- return AUD_DISTANCE_MODEL_LINEAR_CLAMPED;
- case AL_EXPONENT_DISTANCE:
- return AUD_DISTANCE_MODEL_EXPONENT;
- case AL_EXPONENT_DISTANCE_CLAMPED:
- return AUD_DISTANCE_MODEL_EXPONENT_CLAMPED;
- default:
- return AUD_DISTANCE_MODEL_INVALID;
- }
-}
-
-void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model)
-{
- switch(model)
- {
- case AUD_DISTANCE_MODEL_INVERSE:
- alDistanceModel(AL_INVERSE_DISTANCE);
- break;
- case AUD_DISTANCE_MODEL_INVERSE_CLAMPED:
- alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
- break;
- case AUD_DISTANCE_MODEL_LINEAR:
- alDistanceModel(AL_LINEAR_DISTANCE);
- break;
- case AUD_DISTANCE_MODEL_LINEAR_CLAMPED:
- alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
- break;
- case AUD_DISTANCE_MODEL_EXPONENT:
- alDistanceModel(AL_EXPONENT_DISTANCE);
- break;
- case AUD_DISTANCE_MODEL_EXPONENT_CLAMPED:
- alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
- break;
- default:
- alDistanceModel(AL_NONE);
- }
-}
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
deleted file mode 100644
index 6d4939bf96c..00000000000
--- a/intern/audaspace/Python/AUD_PyAPI.cpp
+++ /dev/null
@@ -1,2922 +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/Python/AUD_PyAPI.cpp
- * \ingroup audpython
- */
-
-
-#include "AUD_PyAPI.h"
-#include <structmember.h>
-
-#include "AUD_I3DDevice.h"
-#include "AUD_I3DHandle.h"
-#include "AUD_NULLDevice.h"
-#include "AUD_DelayFactory.h"
-#include "AUD_DoubleFactory.h"
-#include "AUD_FaderFactory.h"
-#include "AUD_HighpassFactory.h"
-#include "AUD_LimiterFactory.h"
-#include "AUD_LoopFactory.h"
-#include "AUD_LowpassFactory.h"
-#include "AUD_PingPongFactory.h"
-#include "AUD_PitchFactory.h"
-#include "AUD_ReverseFactory.h"
-#include "AUD_SinusFactory.h"
-#include "AUD_FileFactory.h"
-#include "AUD_SquareFactory.h"
-#include "AUD_StreamBufferFactory.h"
-#include "AUD_SuperposeFactory.h"
-#include "AUD_VolumeFactory.h"
-#include "AUD_IIRFilterFactory.h"
-
-#ifdef WITH_SDL
-#include "AUD_SDLDevice.h"
-#endif
-
-#ifdef WITH_OPENAL
-#include "AUD_OpenALDevice.h"
-#endif
-
-#ifdef WITH_JACK
-#include "AUD_JackDevice.h"
-#endif
-
-// ====================================================================
-
-typedef enum
-{
- AUD_DEVICE_NULL = 0,
- AUD_DEVICE_OPENAL,
- AUD_DEVICE_SDL,
- AUD_DEVICE_JACK,
- AUD_DEVICE_READ,
-} AUD_DeviceTypes;
-
-// ====================================================================
-
-#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
-
-// ====================================================================
-
-static PyObject *AUDError;
-
-static const char* device_not_3d_error = "Device is not a 3D device!";
-
-// ====================================================================
-
-static void
-Factory_dealloc(Factory* self)
-{
- if(self->factory)
- delete reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory);
- Py_XDECREF(self->child_list);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *
-Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Factory *self;
-
- self = (Factory*)type->tp_alloc(type, 0);
- if(self != NULL)
- {
- static const char *kwlist[] = {"filename", NULL};
- const char* filename = NULL;
-
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "s:Factory", const_cast<char**>(kwlist), &filename))
- {
- Py_DECREF(self);
- return NULL;
- }
-
- try
- {
- self->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(self);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)self;
-}
-
-PyDoc_STRVAR(M_aud_Factory_sine_doc,
- "sine(frequency, rate=48000)\n\n"
- "Creates a sine factory which plays a sine wave.\n\n"
- ":arg frequency: The frequency of the sine wave in Hz.\n"
- ":type frequency: float\n"
- ":arg rate: The sampling rate in Hz. It's recommended to set this "
- "value to the playback device's samling rate to avoid resamping.\n"
- ":type rate: int\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_sine(PyTypeObject* type, PyObject *args)
-{
- float frequency;
- double rate = 48000;
-
- if(!PyArg_ParseTuple(args, "f|d:sine", &frequency, &rate))
- return NULL;
-
- Factory *self;
-
- self = (Factory*)type->tp_alloc(type, 0);
- if(self != NULL)
- {
- try
- {
- self->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_SinusFactory(frequency, (AUD_SampleRate)rate));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(self);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)self;
-}
-
-PyDoc_STRVAR(M_aud_Factory_file_doc,
- "file(filename)\n\n"
- "Creates a factory object of a sound file.\n\n"
- ":arg filename: Path of the file.\n"
- ":type filename: string\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. warning:: If the file doesn't exist or can't be read you will "
- "not get an exception immediately, but when you try to start "
- "playback of that factory.");
-
-static PyObject *
-Factory_file(PyTypeObject* type, PyObject *args)
-{
- const char* filename = NULL;
-
- if(!PyArg_ParseTuple(args, "s:file", &filename))
- return NULL;
-
- Factory *self;
-
- self = (Factory*)type->tp_alloc(type, 0);
- if(self != NULL)
- {
- try
- {
- self->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(self);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)self;
-}
-
-PyDoc_STRVAR(M_aud_Factory_lowpass_doc,
- "lowpass(frequency, Q=0.5)\n\n"
- "Creates a second order lowpass filter based on the transfer "
- "function H(s) = 1 / (s^2 + s/Q + 1)\n\n"
- ":arg frequency: The cut off trequency of the lowpass.\n"
- ":type frequency: float\n"
- ":arg Q: Q factor of the lowpass.\n"
- ":type Q: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_lowpass(Factory* self, PyObject *args)
-{
- float frequency;
- float Q = 0.5;
-
- if(!PyArg_ParseTuple(args, "f|f:lowpass", &frequency, &Q))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_delay_doc,
- "delay(time)\n\n"
- "Delays by playing adding silence in front of the other factory's "
- "data.\n\n"
- ":arg time: How many seconds of silence should be added before "
- "the factory.\n"
- ":type time: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_delay(Factory* self, PyObject *args)
-{
- float delay;
-
- if(!PyArg_ParseTuple(args, "f:delay", &delay))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_join_doc,
- "join(factory)\n\n"
- "Plays two factories in sequence.\n\n"
- ":arg factory: The factory to play second.\n"
- ":type factory: :class:`Factory`\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: The two factories have to have the same specifications "
- "(channels and samplerate).");
-
-static PyObject *
-Factory_join(Factory* self, PyObject *object)
-{
- PyTypeObject* type = Py_TYPE(self);
-
- if(!PyObject_TypeCheck(object, type))
- {
- PyErr_SetString(PyExc_TypeError, "Object has to be of type Factory!");
- return NULL;
- }
-
- Factory *parent;
- Factory *child = (Factory*)object;
-
- parent = (Factory*)type->tp_alloc(type, 0);
- if(parent != NULL)
- {
- parent->child_list = Py_BuildValue("(OO)", self, object);
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_highpass_doc,
- "highpass(frequency, Q=0.5)\n\n"
- "Creates a second order highpass filter based on the transfer "
- "function H(s) = s^2 / (s^2 + s/Q + 1)\n\n"
- ":arg frequency: The cut off trequency of the highpass.\n"
- ":type frequency: float\n"
- ":arg Q: Q factor of the lowpass.\n"
- ":type Q: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_highpass(Factory* self, PyObject *args)
-{
- float frequency;
- float Q = 0.5;
-
- if(!PyArg_ParseTuple(args, "f|f:highpass", &frequency, &Q))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_limit_doc,
- "limit(start, end)\n\n"
- "Limits a factory within a specific start and end time.\n\n"
- ":arg start: Start time in seconds.\n"
- ":type start: float\n"
- ":arg end: End time in seconds.\n"
- ":type end: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_limit(Factory* self, PyObject *args)
-{
- float start, end;
-
- if(!PyArg_ParseTuple(args, "ff:limit", &start, &end))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_pitch_doc,
- "pitch(factor)\n\n"
- "Changes the pitch of a factory with a specific factor.\n\n"
- ":arg factor: The factor to change the pitch with.\n"
- ":type factor: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: This is done by changing the sample rate of the "
- "underlying factory, which has to be an integer, so the factor "
- "value rounded and the factor may not be 100 % accurate.\n\n"
- ".. note:: This is a filter function, you might consider using "
- ":attr:`Handle.pitch` instead.");
-
-static PyObject *
-Factory_pitch(Factory* self, PyObject *args)
-{
- float factor;
-
- if(!PyArg_ParseTuple(args, "f:pitch", &factor))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_volume_doc,
- "volume(volume)\n\n"
- "Changes the volume of a factory.\n\n"
- ":arg volume: The new volume..\n"
- ":type volume: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: Should be in the range [0, 1] to avoid clipping.\n\n"
- ".. note:: This is a filter function, you might consider using "
- ":attr:`Handle.volume` instead.");
-
-static PyObject *
-Factory_volume(Factory* self, PyObject *args)
-{
- float volume;
-
- if(!PyArg_ParseTuple(args, "f:volume", &volume))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_fadein_doc,
- "fadein(start, length)\n\n"
- "Fades a factory in by raising the volume linearly in the given "
- "time interval.\n\n"
- ":arg start: Time in seconds when the fading should start.\n"
- ":type start: float\n"
- ":arg length: Time in seconds how long the fading should last.\n"
- ":type length: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: Before the fade starts it plays silence.");
-
-static PyObject *
-Factory_fadein(Factory* self, PyObject *args)
-{
- float start, length;
-
- if(!PyArg_ParseTuple(args, "ff:fadein", &start, &length))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_fadeout_doc,
- "fadeout(start, length)\n\n"
- "Fades a factory in by lowering the volume linearly in the given "
- "time interval.\n\n"
- ":arg start: Time in seconds when the fading should start.\n"
- ":type start: float\n"
- ":arg length: Time in seconds how long the fading should last.\n"
- ":type length: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: After the fade this factory plays silence, so that "
- "the length of the factory is not altered.");
-
-static PyObject *
-Factory_fadeout(Factory* self, PyObject *args)
-{
- float start, length;
-
- if(!PyArg_ParseTuple(args, "ff:fadeout", &start, &length))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_loop_doc,
- "loop(count)\n\n"
- "Loops a factory.\n\n"
- ":arg count: How often the factory should be looped. "
- "Negative values mean endlessly.\n"
- ":type count: integer\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: This is a filter function, you might consider using "
- ":attr:`Handle.loop_count` instead.");
-
-static PyObject *
-Factory_loop(Factory* self, PyObject *args)
-{
- int loop;
-
- if(!PyArg_ParseTuple(args, "i:loop", &loop))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_mix_doc,
- "mix(factory)\n\n"
- "Mixes two factories.\n\n"
- ":arg factory: The factory to mix over the other.\n"
- ":type factory: :class:`Factory`\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: The two factories have to have the same specifications "
- "(channels and samplerate).");
-
-static PyObject *
-Factory_mix(Factory* self, PyObject *object)
-{
- PyTypeObject* type = Py_TYPE(self);
-
- if(!PyObject_TypeCheck(object, type))
- {
- PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!");
- return NULL;
- }
-
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
- Factory *child = (Factory*)object;
-
- if(parent != NULL)
- {
- parent->child_list = Py_BuildValue("(OO)", self, object);
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_pingpong_doc,
- "pingpong()\n\n"
- "Plays a factory forward and then backward.\n"
- "This is like joining a factory with its reverse.\n\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_pingpong(Factory* self)
-{
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_PingPongFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory)));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_reverse_doc,
- "reverse()\n\n"
- "Plays a factory reversed.\n\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: The factory has to have a finite length and has to be "
- "seekable. It's recommended to use this only with factories with "
- "fast and accurate seeking, which is not true for encoded audio "
- "files, such ones should be buffered using :meth:`buffer` before "
- "being played reversed.\n\n"
- ".. warning:: If seeking is not accurate in the underlying factory "
- "you'll likely hear skips/jumps/cracks.");
-
-static PyObject *
-Factory_reverse(Factory* self)
-{
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_ReverseFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory)));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_buffer_doc,
- "buffer()\n\n"
- "Buffers a factory into RAM.\n"
- "This saves CPU usage needed for decoding and file access if the "
- "underlying factory reads from a file on the harddisk, but it "
- "consumes a lot of memory.\n\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`\n\n"
- ".. note:: Only known-length factories can be buffered.\n\n"
- ".. warning:: Raw PCM data needs a lot of space, only buffer "
- "short factories.");
-
-static PyObject *
-Factory_buffer(Factory* self)
-{
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- try
- {
- parent->factory = new boost::shared_ptr<AUD_IFactory>(new AUD_StreamBufferFactory(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(self->factory)));
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_square_doc,
- "square(threshold = 0)\n\n"
- "Makes a square wave out of an audio wave by setting all samples "
- "with a amplitude >= threshold to 1, all <= -threshold to -1 and "
- "all between to 0.\n\n"
- ":arg threshold: Threshold value over which an amplitude counts "
- "non-zero.\n"
- ":type threshold: float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_square(Factory* self, PyObject *args)
-{
- float threshold = 0;
-
- if(!PyArg_ParseTuple(args, "|f:square", &threshold))
- return NULL;
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-PyDoc_STRVAR(M_aud_Factory_filter_doc,
- "filter(b, a = (1))\n\n"
- "Filters a factory with the supplied IIR filter coefficients.\n"
- "Without the second parameter you'll get a FIR filter.\n"
- "If the first value of the a sequence is 0 it will be set to 1 "
- "automatically.\n"
- "If the first value of the a sequence is neither 0 nor 1, all "
- "filter coefficients will be scaled by this value so that it is 1 "
- "in the end, you don't have to scale yourself.\n\n"
- ":arg b: The nominator filter coefficients.\n"
- ":type b: sequence of float\n"
- ":arg a: The denominator filter coefficients.\n"
- ":type a: sequence of float\n"
- ":return: The created :class:`Factory` object.\n"
- ":rtype: :class:`Factory`");
-
-static PyObject *
-Factory_filter(Factory* self, PyObject *args)
-{
- PyObject *py_b;
- PyObject *py_a = NULL;
- Py_ssize_t py_a_len;
- Py_ssize_t py_b_len;
-
- if(!PyArg_ParseTuple(args, "O|O:filter", &py_b, &py_a))
- return NULL;
-
- if(!PySequence_Check(py_b) || (py_a != NULL && !PySequence_Check(py_a)))
- {
- PyErr_SetString(PyExc_TypeError, "Parameter is not a sequence!");
- return NULL;
- }
-
- py_a_len= py_a ? PySequence_Size(py_a) : 0;
- py_b_len= PySequence_Size(py_b);
-
- if(!py_b_len || ((py_a != NULL) && !py_a_len))
- {
- PyErr_SetString(PyExc_ValueError, "The sequence has to contain at least one value!");
- return NULL;
- }
-
- std::vector<float> a, b;
- PyObject *py_value;
- float value;
-
- for(Py_ssize_t i = 0; i < py_b_len; i++)
- {
- py_value = PySequence_GetItem(py_b, i);
- value= (float)PyFloat_AsDouble(py_value);
- Py_DECREF(py_value);
-
- if (value==-1.0f && PyErr_Occurred()) {
- return NULL;
- }
-
- b.push_back(value);
- }
-
- if(py_a)
- {
- for(Py_ssize_t i = 0; i < py_a_len; i++)
- {
- py_value = PySequence_GetItem(py_a, i);
- value= (float)PyFloat_AsDouble(py_value);
- Py_DECREF(py_value);
-
- if (value==-1.0f && PyErr_Occurred()) {
- return NULL;
- }
-
- a.push_back(value);
- }
-
- if(a[0] == 0)
- a[0] = 1;
- }
- else
- a.push_back(1);
-
- PyTypeObject* type = Py_TYPE(self);
- Factory *parent = (Factory*)type->tp_alloc(type, 0);
-
- if(parent != NULL)
- {
- Py_INCREF(self);
- parent->child_list = (PyObject *)self;
-
- try
- {
- 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)
- {
- Py_DECREF(parent);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)parent;
-}
-
-static PyMethodDef Factory_methods[] = {
- {"sine", (PyCFunction)Factory_sine, METH_VARARGS | METH_CLASS,
- M_aud_Factory_sine_doc
- },
- {"file", (PyCFunction)Factory_file, METH_VARARGS | METH_CLASS,
- M_aud_Factory_file_doc
- },
- {"lowpass", (PyCFunction)Factory_lowpass, METH_VARARGS,
- M_aud_Factory_lowpass_doc
- },
- {"delay", (PyCFunction)Factory_delay, METH_VARARGS,
- M_aud_Factory_delay_doc
- },
- {"join", (PyCFunction)Factory_join, METH_O,
- M_aud_Factory_join_doc
- },
- {"highpass", (PyCFunction)Factory_highpass, METH_VARARGS,
- M_aud_Factory_highpass_doc
- },
- {"limit", (PyCFunction)Factory_limit, METH_VARARGS,
- M_aud_Factory_limit_doc
- },
- {"pitch", (PyCFunction)Factory_pitch, METH_VARARGS,
- M_aud_Factory_pitch_doc
- },
- {"volume", (PyCFunction)Factory_volume, METH_VARARGS,
- M_aud_Factory_volume_doc
- },
- {"fadein", (PyCFunction)Factory_fadein, METH_VARARGS,
- M_aud_Factory_fadein_doc
- },
- {"fadeout", (PyCFunction)Factory_fadeout, METH_VARARGS,
- M_aud_Factory_fadeout_doc
- },
- {"loop", (PyCFunction)Factory_loop, METH_VARARGS,
- M_aud_Factory_loop_doc
- },
- {"mix", (PyCFunction)Factory_mix, METH_O,
- M_aud_Factory_mix_doc
- },
- {"pingpong", (PyCFunction)Factory_pingpong, METH_NOARGS,
- M_aud_Factory_pingpong_doc
- },
- {"reverse", (PyCFunction)Factory_reverse, METH_NOARGS,
- M_aud_Factory_reverse_doc
- },
- {"buffer", (PyCFunction)Factory_buffer, METH_NOARGS,
- M_aud_Factory_buffer_doc
- },
- {"square", (PyCFunction)Factory_square, METH_VARARGS,
- M_aud_Factory_square_doc
- },
- {"filter", (PyCFunction)Factory_filter, METH_VARARGS,
- M_aud_Factory_filter_doc
- },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Factory_doc,
- "Factory objects are immutable and represent a sound that can be "
- "played simultaneously multiple times. They are called factories "
- "because they create reader objects internally that are used for "
- "playback.");
-
-static PyTypeObject FactoryType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "aud.Factory", /* tp_name */
- sizeof(Factory), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Factory_dealloc, /* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- M_aud_Factory_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Factory_methods, /* tp_methods */
- 0, /* tp_members */
- 0, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- Factory_new, /* tp_new */
-};
-
-// ========== Handle ==================================================
-
-static void
-Handle_dealloc(Handle* self)
-{
- if(self->handle)
- delete reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-PyDoc_STRVAR(M_aud_Handle_pause_doc,
- "pause()\n\n"
- "Pauses playback.\n\n"
- ":return: Whether the action succeeded.\n"
- ":rtype: bool");
-
-static PyObject *
-Handle_pause(Handle *self)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->pause());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Handle_resume_doc,
- "resume()\n\n"
- "Resumes playback.\n\n"
- ":return: Whether the action succeeded.\n"
- ":rtype: bool");
-
-static PyObject *
-Handle_resume(Handle *self)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->resume());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Handle_stop_doc,
- "stop()\n\n"
- "Stops playback.\n\n"
- ":return: Whether the action succeeded.\n"
- ":rtype: bool\n\n"
- ".. note:: This makes the handle invalid.");
-
-static PyObject *
-Handle_stop(Handle *self)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->stop());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static PyMethodDef Handle_methods[] = {
- {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
- M_aud_Handle_pause_doc
- },
- {"resume", (PyCFunction)Handle_resume, METH_NOARGS,
- M_aud_Handle_resume_doc
- },
- {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
- M_aud_Handle_stop_doc
- },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Handle_position_doc,
- "The playback position of the sound in seconds.");
-
-static PyObject *
-Handle_get_position(Handle *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getPosition());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_position(Handle *self, PyObject *args, void* nothing)
-{
- float position;
-
- if(!PyArg_Parse(args, "f:position", &position))
- return -1;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->seek(position))
- return 0;
- PyErr_SetString(AUDError, "Couldn't seek the sound!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_keep_doc,
- "Whether the sound should be kept paused in the device when its "
- "end is reached.\n"
- "This can be used to seek the sound to some position and start "
- "playback again.\n\n"
- ".. warning:: If this is set to true and you forget stopping this "
- "equals a memory leak as the handle exists until the device is "
- "destroyed.");
-
-static PyObject *
-Handle_get_keep(Handle *self, void* nothing)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getKeep());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_keep(Handle *self, PyObject *args, void* nothing)
-{
- if(!PyBool_Check(args))
- {
- PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
- return -1;
- }
-
- bool keep = args == Py_True;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setKeep(keep))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_status_doc,
- "Whether the sound is playing, paused or stopped (=invalid).");
-
-static PyObject *
-Handle_get_status(Handle *self, void* nothing)
-{
- try
- {
- return PyBool_FromLong((long)(*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getStatus());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Handle_volume_doc,
- "The volume of the sound.");
-
-static PyObject *
-Handle_get_volume(Handle *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getVolume());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_volume(Handle *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:volume", &volume))
- return -1;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setVolume(volume))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the sound volume!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_pitch_doc,
- "The pitch of the sound.");
-
-static PyObject *
-Handle_get_pitch(Handle *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getPitch());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_pitch(Handle *self, PyObject *args, void* nothing)
-{
- float pitch;
-
- if(!PyArg_Parse(args, "f:pitch", &pitch))
- return -1;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setPitch(pitch))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
- "The (remaining) loop count of the sound. A negative value indicates infinity.");
-
-static PyObject *
-Handle_get_loop_count(Handle *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("i", (*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->getLoopCount());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_loop_count(Handle *self, PyObject *args, void* nothing)
-{
- int loops;
-
- if(!PyArg_Parse(args, "i:loop_count", &loops))
- return -1;
-
- try
- {
- if((*reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle))->setLoopCount(loops))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the loop count!");
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_location_doc,
- "The source's location in 3D space, a 3D tuple of floats.");
-
-static PyObject *
-Handle_get_location(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- AUD_Vector3 v = handle->getSourceLocation();
- return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Handle_set_location(Handle *self, PyObject *args, void* nothing)
-{
- float x, y, z;
-
- if(!PyArg_Parse(args, "(fff):location", &x, &y, &z))
- return -1;
-
- try
- {
- 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);
- if(handle->setSourceLocation(location))
- return 0;
- PyErr_SetString(AUDError, "Location couldn't be set!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_velocity_doc,
- "The source's velocity in 3D space, a 3D tuple of floats.");
-
-static PyObject *
-Handle_get_velocity(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- AUD_Vector3 v = handle->getSourceVelocity();
- return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Handle_set_velocity(Handle *self, PyObject *args, void* nothing)
-{
- float x, y, z;
-
- if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z))
- return -1;
-
- try
- {
- 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);
- if(handle->setSourceVelocity(velocity))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the velocity!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_orientation_doc,
- "The source's orientation in 3D space as quaternion, a 4 float tuple.");
-
-static PyObject *
-Handle_get_orientation(Handle *self, void* nothing)
-{
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- AUD_Quaternion o = handle->getSourceOrientation();
- return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Handle_set_orientation(Handle *self, PyObject *args, void* nothing)
-{
- float w, x, y, z;
-
- if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z))
- return -1;
-
- try
- {
- 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);
- if(handle->setSourceOrientation(orientation))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the orientation!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_relative_doc,
- "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
-
-static PyObject *
-Handle_get_relative(Handle *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Handle_set_relative(Handle *self, PyObject *args, void* nothing)
-{
- if(!PyBool_Check(args))
- {
- PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
- return -1;
- }
-
- bool relative = (args == Py_True);
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setRelative(relative))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the relativeness!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
- "The minimum volume of the source.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_volume_minimum(Handle *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_volume_minimum(Handle *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:volume_minimum", &volume))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setVolumeMinimum(volume))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the minimum volume!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
- "The maximum volume of the source.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_volume_maximum(Handle *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_volume_maximum(Handle *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:volume_maximum", &volume))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setVolumeMaximum(volume))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the maximum volume!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
- "The reference distance of the source.\n"
- "At this distance the volume will be exactly :attr:`volume`.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_distance_reference(Handle *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_distance_reference(Handle *self, PyObject *args, void* nothing)
-{
- float distance;
-
- if(!PyArg_Parse(args, "f:distance_reference", &distance))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setDistanceReference(distance))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the reference distance!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
- "The maximum distance of the source.\n"
- "If the listener is further away the source volume will be 0.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_distance_maximum(Handle *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_distance_maximum(Handle *self, PyObject *args, void* nothing)
-{
- float distance;
-
- if(!PyArg_Parse(args, "f:distance_maximum", &distance))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setDistanceMaximum(distance))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
- "This factor is used for distance based attenuation of the "
- "source.\n\n"
- ".. seealso:: :attr:`Device.distance_model`");
-
-static PyObject *
-Handle_get_attenuation(Handle *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_attenuation(Handle *self, PyObject *args, void* nothing)
-{
- float factor;
-
- if(!PyArg_Parse(args, "f:attenuation", &factor))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setAttenuation(factor))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the attenuation!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
- "The opening angle of the inner cone of the source. If the cone "
- "values of a source are set there are two (audible) cones with "
- "the apex at the :attr:`location` of the source and with infinite "
- "height, heading in the direction of the source's "
- ":attr:`orientation`.\n"
- "In the inner cone the volume is normal. Outside the outer cone "
- "the volume will be :attr:`cone_volume_outer` and in the area "
- "between the volume will be interpolated linearly.");
-
-static PyObject *
-Handle_get_cone_angle_inner(Handle *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_cone_angle_inner(Handle *self, PyObject *args, void* nothing)
-{
- float angle;
-
- if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setConeAngleInner(angle))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
- "The opening angle of the outer cone of the source.\n\n"
- ".. seealso:: :attr:`cone_angle_inner`");
-
-static PyObject *
-Handle_get_cone_angle_outer(Handle *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_cone_angle_outer(Handle *self, PyObject *args, void* nothing)
-{
- float angle;
-
- if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setConeAngleOuter(angle))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
- "The volume outside the outer cone of the source.\n\n"
- ".. seealso:: :attr:`cone_angle_inner`");
-
-static PyObject *
-Handle_get_cone_volume_outer(Handle *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Handle_set_cone_volume_outer(Handle *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
- return -1;
-
- try
- {
- AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<boost::shared_ptr<AUD_IHandle>*>(self->handle)->get());
- if(handle)
- {
- if(handle->setConeVolumeOuter(volume))
- return 0;
- PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-static PyGetSetDef Handle_properties[] = {
- {(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position,
- M_aud_Handle_position_doc, NULL },
- {(char*)"keep", (getter)Handle_get_keep, (setter)Handle_set_keep,
- M_aud_Handle_keep_doc, NULL },
- {(char*)"status", (getter)Handle_get_status, NULL,
- M_aud_Handle_status_doc, NULL },
- {(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume,
- M_aud_Handle_volume_doc, NULL },
- {(char*)"pitch", (getter)Handle_get_pitch, (setter)Handle_set_pitch,
- M_aud_Handle_pitch_doc, NULL },
- {(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count,
- M_aud_Handle_loop_count_doc, NULL },
- {(char*)"location", (getter)Handle_get_location, (setter)Handle_set_location,
- M_aud_Handle_location_doc, NULL },
- {(char*)"velocity", (getter)Handle_get_velocity, (setter)Handle_set_velocity,
- M_aud_Handle_velocity_doc, NULL },
- {(char*)"orientation", (getter)Handle_get_orientation, (setter)Handle_set_orientation,
- M_aud_Handle_orientation_doc, NULL },
- {(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
- M_aud_Handle_relative_doc, NULL },
- {(char*)"volume_minimum", (getter)Handle_get_volume_minimum, (setter)Handle_set_volume_minimum,
- M_aud_Handle_volume_minimum_doc, NULL },
- {(char*)"volume_maximum", (getter)Handle_get_volume_maximum, (setter)Handle_set_volume_maximum,
- M_aud_Handle_volume_maximum_doc, NULL },
- {(char*)"distance_reference", (getter)Handle_get_distance_reference, (setter)Handle_set_distance_reference,
- M_aud_Handle_distance_reference_doc, NULL },
- {(char*)"distance_maximum", (getter)Handle_get_distance_maximum, (setter)Handle_set_distance_maximum,
- M_aud_Handle_distance_maximum_doc, NULL },
- {(char*)"attenuation", (getter)Handle_get_attenuation, (setter)Handle_set_attenuation,
- M_aud_Handle_attenuation_doc, NULL },
- {(char*)"cone_angle_inner", (getter)Handle_get_cone_angle_inner, (setter)Handle_set_cone_angle_inner,
- M_aud_Handle_cone_angle_inner_doc, NULL },
- {(char*)"cone_angle_outer", (getter)Handle_get_cone_angle_outer, (setter)Handle_set_cone_angle_outer,
- M_aud_Handle_cone_angle_outer_doc, NULL },
- {(char*)"cone_volume_outer", (getter)Handle_get_cone_volume_outer, (setter)Handle_set_cone_volume_outer,
- M_aud_Handle_cone_volume_outer_doc, NULL },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Handle_doc,
- "Handle objects are playback handles that can be used to control "
- "playback of a sound. If a sound is played back multiple times "
- "then there are as many handles.");
-
-static PyTypeObject HandleType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "aud.Handle", /* tp_name */
- sizeof(Handle), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Handle_dealloc,/* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- M_aud_Handle_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Handle_methods, /* tp_methods */
- 0, /* tp_members */
- Handle_properties, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- 0, /* tp_new */
-};
-
-// ========== Device ==================================================
-
-static void
-Device_dealloc(Device* self)
-{
- if(self->device)
- delete reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *
-Device_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- Device *self;
-
- static const char *kwlist[] = {"type", "rate", "channels", "format", "buffer_size", "name", NULL};
- int device;
- double rate = AUD_RATE_48000;
- int channels = AUD_CHANNELS_STEREO;
- int format = AUD_FORMAT_FLOAT32;
- int buffersize = AUD_DEFAULT_BUFFER_SIZE;
- const char* name = "Audaspace";
-
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "i|diiis:Device", const_cast<char**>(kwlist),
- &device, &rate, &channels, &format, &buffersize, &name))
- return NULL;
-
- if(buffersize < 128)
- {
- PyErr_SetString(PyExc_ValueError, "buffer_size must be greater than 127!");
- return NULL;
- }
-
- self = (Device*)type->tp_alloc(type, 0);
- if(self != NULL)
- {
- AUD_DeviceSpecs specs;
- specs.channels = (AUD_Channels)channels;
- specs.format = (AUD_SampleFormat)format;
- specs.rate = (AUD_SampleRate)rate;
-
- self->device = NULL;
-
- try
- {
- switch(device)
- {
- case AUD_DEVICE_NULL:
- (void)specs; /* quiet warning when others disabled */
- self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_NULLDevice());
- break;
- case AUD_DEVICE_OPENAL:
-#ifdef WITH_OPENAL
- 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 boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
-#endif
- break;
- case AUD_DEVICE_JACK:
-#ifdef WITH_JACK
- self->device = new boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
-#endif
- break;
- case AUD_DEVICE_READ:
- break;
- }
-
- }
- catch(AUD_Exception& e)
- {
- Py_DECREF(self);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-
- if(!self->device)
- {
- Py_DECREF(self);
- PyErr_SetString(AUDError, "Unsupported device type!");
- return NULL;
- }
- }
-
- return (PyObject *)self;
-}
-
-PyDoc_STRVAR(M_aud_Device_play_doc,
- "play(factory, keep=False)\n\n"
- "Plays a factory.\n\n"
- ":arg factory: The factory to play.\n"
- ":type factory: :class:`Factory`\n"
- ":arg keep: See :attr:`Handle.keep`.\n"
- ":type keep: bool\n"
- ":return: The playback handle with which playback can be "
- "controlled with.\n"
- ":rtype: :class:`Handle`");
-
-static PyObject *
-Device_play(Device *self, PyObject *args, PyObject *kwds)
-{
- PyObject *object;
- PyObject *keepo = NULL;
-
- bool keep = false;
-
- static const char *kwlist[] = {"factory", "keep", NULL};
-
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:play", const_cast<char**>(kwlist), &object, &keepo))
- return NULL;
-
- if(!PyObject_TypeCheck(object, &FactoryType))
- {
- PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!");
- return NULL;
- }
-
- if(keepo != NULL)
- {
- if(!PyBool_Check(keepo))
- {
- PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
- return NULL;
- }
-
- keep = keepo == Py_True;
- }
-
- Factory* sound = (Factory*)object;
- Handle *handle;
-
- handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
- if(handle != NULL)
- {
- try
- {
- 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)
- {
- Py_DECREF(handle);
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
- }
-
- return (PyObject *)handle;
-}
-
-PyDoc_STRVAR(M_aud_Device_stopAll_doc,
- "stopAll()\n\n"
- "Stops all playing and paused sounds.");
-
-static PyObject *
-Device_stopAll(Device *self)
-{
- try
- {
- (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->stopAll();
- Py_RETURN_NONE;
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_lock_doc,
- "lock()\n\n"
- "Locks the device so that it's guaranteed, that no samples are "
- "read from the streams until :meth:`unlock` is called.\n"
- "This is useful if you want to do start/stop/pause/resume some "
- "sounds at the same time.\n\n"
- ".. note:: The device has to be unlocked as often as locked to be "
- "able to continue playback.\n\n"
- ".. warning:: Make sure the time between locking and unlocking is "
- "as short as possible to avoid clicks.");
-
-static PyObject *
-Device_lock(Device *self)
-{
- try
- {
- (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->lock();
- Py_RETURN_NONE;
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_unlock_doc,
- "unlock()\n\n"
- "Unlocks the device after a lock call, see :meth:`lock` for "
- "details.");
-
-static PyObject *
-Device_unlock(Device *self)
-{
- try
- {
- (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->unlock();
- Py_RETURN_NONE;
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static PyMethodDef Device_methods[] = {
- {"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
- M_aud_Device_play_doc
- },
- {"stopAll", (PyCFunction)Device_stopAll, METH_NOARGS,
- M_aud_Device_stopAll_doc
- },
- {"lock", (PyCFunction)Device_lock, METH_NOARGS,
- M_aud_Device_lock_doc
- },
- {"unlock", (PyCFunction)Device_unlock, METH_NOARGS,
- M_aud_Device_unlock_doc
- },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Device_rate_doc,
- "The sampling rate of the device in Hz.");
-
-static PyObject *
-Device_get_rate(Device *self, void* nothing)
-{
- try
- {
- AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs();
- return Py_BuildValue("d", specs.rate);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_format_doc,
- "The native sample format of the device.");
-
-static PyObject *
-Device_get_format(Device *self, void* nothing)
-{
- try
- {
- AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs();
- return Py_BuildValue("i", specs.format);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_channels_doc,
- "The channel count of the device.");
-
-static PyObject *
-Device_get_channels(Device *self, void* nothing)
-{
- try
- {
- AUD_DeviceSpecs specs = (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getSpecs();
- return Py_BuildValue("i", specs.channels);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_volume_doc,
- "The overall volume of the device.");
-
-static PyObject *
-Device_get_volume(Device *self, void* nothing)
-{
- try
- {
- return Py_BuildValue("f", (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->getVolume());
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Device_set_volume(Device *self, PyObject *args, void* nothing)
-{
- float volume;
-
- if(!PyArg_Parse(args, "f:volume", &volume))
- return -1;
-
- try
- {
- (*reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device))->setVolume(volume);
- return 0;
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return -1;
- }
-}
-
-PyDoc_STRVAR(M_aud_Device_listener_location_doc,
- "The listeners's location in 3D space, a 3D tuple of floats.");
-
-static PyObject *
-Device_get_listener_location(Device *self, void* nothing)
-{
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- AUD_Vector3 v = device->getListenerLocation();
- return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Device_set_listener_location(Device *self, PyObject *args, void* nothing)
-{
- float x, y, z;
-
- if(!PyArg_Parse(args, "(fff):listener_location", &x, &y, &z))
- return -1;
-
- try
- {
- 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);
- device->setListenerLocation(location);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_listener_velocity_doc,
- "The listener's velocity in 3D space, a 3D tuple of floats.");
-
-static PyObject *
-Device_get_listener_velocity(Device *self, void* nothing)
-{
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- AUD_Vector3 v = device->getListenerVelocity();
- return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Device_set_listener_velocity(Device *self, PyObject *args, void* nothing)
-{
- float x, y, z;
-
- if(!PyArg_Parse(args, "(fff):listener_velocity", &x, &y, &z))
- return -1;
-
- try
- {
- 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);
- device->setListenerVelocity(velocity);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_listener_orientation_doc,
- "The listener's orientation in 3D space as quaternion, a 4 float tuple.");
-
-static PyObject *
-Device_get_listener_orientation(Device *self, void* nothing)
-{
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- AUD_Quaternion o = device->getListenerOrientation();
- return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return NULL;
-}
-
-static int
-Device_set_listener_orientation(Device *self, PyObject *args, void* nothing)
-{
- float w, x, y, z;
-
- if(!PyArg_Parse(args, "(ffff):listener_orientation", &w, &x, &y, &z))
- return -1;
-
- try
- {
- 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);
- device->setListenerOrientation(orientation);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
- "The speed of sound of the device.\n"
- "The speed of sound in air is typically 343.3 m/s.");
-
-static PyObject *
-Device_get_speed_of_sound(Device *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Device_set_speed_of_sound(Device *self, PyObject *args, void* nothing)
-{
- float speed;
-
- if(!PyArg_Parse(args, "f:speed_of_sound", &speed))
- return -1;
-
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- device->setSpeedOfSound(speed);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_doppler_factor_doc,
- "The doppler factor of the device.\n"
- "This factor is a scaling factor for the velocity vectors in "
- "doppler calculation. So a value bigger than 1 will exaggerate "
- "the effect as it raises the velocity.");
-
-static PyObject *
-Device_get_doppler_factor(Device *self, void* nothing)
-{
- try
- {
- 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());
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Device_set_doppler_factor(Device *self, PyObject *args, void* nothing)
-{
- float factor;
-
- if(!PyArg_Parse(args, "f:doppler_factor", &factor))
- return -1;
-
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- device->setDopplerFactor(factor);
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-PyDoc_STRVAR(M_aud_Device_distance_model_doc,
- "The distance model of the device.\n\n"
- ".. seealso:: `OpenAL documentation <https://www.openal.org/documentation>`");
-
-static PyObject *
-Device_get_distance_model(Device *self, void* nothing)
-{
- try
- {
- 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()));
- }
- else
- {
- PyErr_SetString(AUDError, device_not_3d_error);
- return NULL;
- }
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- return NULL;
- }
-}
-
-static int
-Device_set_distance_model(Device *self, PyObject *args, void* nothing)
-{
- int model;
-
- if(!PyArg_Parse(args, "i:distance_model", &model))
- return -1;
-
- try
- {
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<boost::shared_ptr<AUD_IDevice>*>(self->device)->get());
- if(device)
- {
- device->setDistanceModel(AUD_DistanceModel(model));
- return 0;
- }
- else
- PyErr_SetString(AUDError, device_not_3d_error);
- }
- catch(AUD_Exception& e)
- {
- PyErr_SetString(AUDError, e.str);
- }
-
- return -1;
-}
-
-static PyGetSetDef Device_properties[] = {
- {(char*)"rate", (getter)Device_get_rate, NULL,
- M_aud_Device_rate_doc, NULL },
- {(char*)"format", (getter)Device_get_format, NULL,
- M_aud_Device_format_doc, NULL },
- {(char*)"channels", (getter)Device_get_channels, NULL,
- M_aud_Device_channels_doc, NULL },
- {(char*)"volume", (getter)Device_get_volume, (setter)Device_set_volume,
- M_aud_Device_volume_doc, NULL },
- {(char*)"listener_location", (getter)Device_get_listener_location, (setter)Device_set_listener_location,
- M_aud_Device_listener_location_doc, NULL },
- {(char*)"listener_velocity", (getter)Device_get_listener_velocity, (setter)Device_set_listener_velocity,
- M_aud_Device_listener_velocity_doc, NULL },
- {(char*)"listener_orientation", (getter)Device_get_listener_orientation, (setter)Device_set_listener_orientation,
- M_aud_Device_listener_orientation_doc, NULL },
- {(char*)"speed_of_sound", (getter)Device_get_speed_of_sound, (setter)Device_set_speed_of_sound,
- M_aud_Device_speed_of_sound_doc, NULL },
- {(char*)"doppler_factor", (getter)Device_get_doppler_factor, (setter)Device_set_doppler_factor,
- M_aud_Device_doppler_factor_doc, NULL },
- {(char*)"distance_model", (getter)Device_get_distance_model, (setter)Device_set_distance_model,
- M_aud_Device_distance_model_doc, NULL },
- {NULL} /* Sentinel */
-};
-
-PyDoc_STRVAR(M_aud_Device_doc,
- "Device objects represent an audio output backend like OpenAL or "
- "SDL, but might also represent a file output or RAM buffer "
- "output.");
-
-static PyTypeObject DeviceType = {
- PyVarObject_HEAD_INIT(NULL, 0)
- "aud.Device", /* tp_name */
- sizeof(Device), /* tp_basicsize */
- 0, /* tp_itemsize */
- (destructor)Device_dealloc,/* tp_dealloc */
- 0, /* tp_print */
- 0, /* tp_getattr */
- 0, /* tp_setattr */
- 0, /* tp_reserved */
- 0, /* tp_repr */
- 0, /* tp_as_number */
- 0, /* tp_as_sequence */
- 0, /* tp_as_mapping */
- 0, /* tp_hash */
- 0, /* tp_call */
- 0, /* tp_str */
- 0, /* tp_getattro */
- 0, /* tp_setattro */
- 0, /* tp_as_buffer */
- Py_TPFLAGS_DEFAULT, /* tp_flags */
- M_aud_Device_doc, /* tp_doc */
- 0, /* tp_traverse */
- 0, /* tp_clear */
- 0, /* tp_richcompare */
- 0, /* tp_weaklistoffset */
- 0, /* tp_iter */
- 0, /* tp_iternext */
- Device_methods, /* tp_methods */
- 0, /* tp_members */
- Device_properties, /* tp_getset */
- 0, /* tp_base */
- 0, /* tp_dict */
- 0, /* tp_descr_get */
- 0, /* tp_descr_set */
- 0, /* tp_dictoffset */
- 0, /* tp_init */
- 0, /* tp_alloc */
- Device_new, /* tp_new */
-};
-
-PyObject *
-Device_empty()
-{
- return DeviceType.tp_alloc(&DeviceType, 0);
-}
-
-PyObject *
-Factory_empty()
-{
- return FactoryType.tp_alloc(&FactoryType, 0);
-}
-
-Factory*
-checkFactory(PyObject *factory)
-{
- if(!PyObject_TypeCheck(factory, &FactoryType))
- {
- PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!");
- return NULL;
- }
-
- return (Factory*)factory;
-}
-
-
-// ====================================================================
-
-PyDoc_STRVAR(M_aud_doc,
- "This module provides access to the audaspace audio library.");
-
-static struct PyModuleDef audmodule = {
- PyModuleDef_HEAD_INIT,
- "aud", /* name of module */
- M_aud_doc, /* module documentation */
- -1, /* size of per-interpreter state of the module,
- or -1 if the module keeps state in global variables. */
- NULL, NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_aud(void)
-{
- PyObject *m;
-
- if(PyType_Ready(&FactoryType) < 0)
- return NULL;
-
- if(PyType_Ready(&DeviceType) < 0)
- return NULL;
-
- if(PyType_Ready(&HandleType) < 0)
- return NULL;
-
- m = PyModule_Create(&audmodule);
- if(m == NULL)
- return NULL;
-
- Py_INCREF(&FactoryType);
- PyModule_AddObject(m, "Factory", (PyObject *)&FactoryType);
-
- Py_INCREF(&DeviceType);
- PyModule_AddObject(m, "Device", (PyObject *)&DeviceType);
-
- Py_INCREF(&HandleType);
- PyModule_AddObject(m, "Handle", (PyObject *)&HandleType);
-
- AUDError = PyErr_NewException("aud.error", NULL, NULL);
- Py_INCREF(AUDError);
- PyModule_AddObject(m, "error", AUDError);
-
- // device constants
- PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_NULL);
- PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_OPENAL);
- PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_SDL);
- PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_JACK);
- //PY_MODULE_ADD_CONSTANT(m, AUD_DEVICE_READ);
- // format constants
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT32);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_FLOAT64);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_INVALID);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S16);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S24);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_S32);
- PY_MODULE_ADD_CONSTANT(m, AUD_FORMAT_U8);
- // status constants
- PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_INVALID);
- PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PAUSED);
- PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PLAYING);
- PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_STOPPED);
- // distance model constants
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT_CLAMPED);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVERSE_CLAMPED);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_LINEAR_CLAMPED);
- PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_INVALID);
-
- return m;
-}
diff --git a/intern/audaspace/Python/AUD_PyAPI.h b/intern/audaspace/Python/AUD_PyAPI.h
deleted file mode 100644
index 0183a2df6b2..00000000000
--- a/intern/audaspace/Python/AUD_PyAPI.h
+++ /dev/null
@@ -1,74 +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/Python/AUD_PyAPI.h
- * \ingroup audpython
- */
-
-
-#ifndef __AUD_PYAPI_H__
-#define __AUD_PYAPI_H__
-
-#include "Python.h"
-
-#ifdef __cplusplus
-extern "C" {
-#else
-typedef void AUD_IFactory;
-typedef void AUD_IDevice;
-typedef void AUD_IHandle;
-#endif
-
-typedef void AUD_Reference_AUD_IFactory;
-typedef void AUD_Reference_AUD_IDevice;
-typedef void AUD_Reference_AUD_IHandle;
-
-typedef struct {
- PyObject_HEAD
- PyObject *child_list;
- AUD_Reference_AUD_IFactory* factory;
-} Factory;
-
-typedef struct {
- PyObject_HEAD
- AUD_Reference_AUD_IHandle* handle;
-} Handle;
-
-typedef struct {
- PyObject_HEAD
- AUD_Reference_AUD_IDevice* device;
-} Device;
-
-PyMODINIT_FUNC
-PyInit_aud(void);
-
-extern PyObject *Device_empty();
-extern PyObject *Factory_empty();
-extern Factory *checkFactory(PyObject *factory);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //__AUD_PYAPI_H__
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.cpp b/intern/audaspace/SDL/AUD_SDLDevice.cpp
deleted file mode 100644
index 23729a7a171..00000000000
--- a/intern/audaspace/SDL/AUD_SDLDevice.cpp
+++ /dev/null
@@ -1,97 +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/SDL/AUD_SDLDevice.cpp
- * \ingroup audsdl
- */
-
-
-#include "AUD_SDLDevice.h"
-#include "AUD_IReader.h"
-
-void AUD_SDLDevice::SDL_mix(void *data, Uint8* buffer, int length)
-{
- AUD_SDLDevice* device = (AUD_SDLDevice*)data;
-
- device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
-}
-
-static const char* open_error = "AUD_SDLDevice: Device couldn't be opened.";
-static const char* format_error = "AUD_SDLDevice: Obtained unsupported sample "
- "format.";
-
-AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
-{
- if(specs.channels == AUD_CHANNELS_INVALID)
- specs.channels = AUD_CHANNELS_STEREO;
- if(specs.format == AUD_FORMAT_INVALID)
- specs.format = AUD_FORMAT_S16;
- if(specs.rate == AUD_RATE_INVALID)
- specs.rate = AUD_RATE_48000;
-
- m_specs = specs;
-
- SDL_AudioSpec format, obtained;
-
- format.freq = m_specs.rate;
- if(m_specs.format == AUD_FORMAT_U8)
- format.format = AUDIO_U8;
- else
- format.format = AUDIO_S16SYS;
- format.channels = m_specs.channels;
- format.samples = buffersize;
- format.callback = AUD_SDLDevice::SDL_mix;
- format.userdata = this;
-
- if(SDL_OpenAudio(&format, &obtained) != 0)
- AUD_THROW(AUD_ERROR_SDL, open_error);
-
- m_specs.rate = (AUD_SampleRate)obtained.freq;
- m_specs.channels = (AUD_Channels)obtained.channels;
- if(obtained.format == AUDIO_U8)
- m_specs.format = AUD_FORMAT_U8;
- else if(obtained.format == AUDIO_S16LSB || obtained.format == AUDIO_S16MSB)
- m_specs.format = AUD_FORMAT_S16;
- else
- {
- SDL_CloseAudio();
- AUD_THROW(AUD_ERROR_SDL, format_error);
- }
-
- create();
-}
-
-AUD_SDLDevice::~AUD_SDLDevice()
-{
- lock();
- SDL_CloseAudio();
- unlock();
-
- destroy();
-}
-
-void AUD_SDLDevice::playing(bool playing)
-{
- SDL_PauseAudio(playing ? 0 : 1);
-}
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.h b/intern/audaspace/SDL/AUD_SDLDevice.h
deleted file mode 100644
index c4ff9e80aa9..00000000000
--- a/intern/audaspace/SDL/AUD_SDLDevice.h
+++ /dev/null
@@ -1,86 +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/SDL/AUD_SDLDevice.h
- * \ingroup audsdl
- */
-
-
-#ifndef __AUD_SDLDEVICE_H__
-#define __AUD_SDLDEVICE_H__
-
-#include "AUD_SoftwareDevice.h"
-
-/* SDL force defines __SSE__ and __SSE2__ flags, which generates warnings
- * because we pass those defines via command line as well. For until there's
- * proper ifndef added to SDL headers we ignore the redefinition warning.
- */
-#ifdef _MSC_VER
-# pragma warning(push)
-# pragma warning(disable : 4005)
-#endif
-#include <SDL.h>
-#ifdef _MSC_VER
-# pragma warning(pop)
-#endif
-
-/**
- * This device plays back through SDL, the simple direct media layer.
- */
-class AUD_SDLDevice : public AUD_SoftwareDevice
-{
-private:
- /**
- * Mixes the next bytes into the buffer.
- * \param data The SDL device.
- * \param buffer The target buffer.
- * \param length The length in bytes to be filled.
- */
- static void SDL_mix(void *data, Uint8* buffer, int length);
-
- // hide copy constructor and operator=
- AUD_SDLDevice(const AUD_SDLDevice&);
- AUD_SDLDevice& operator=(const AUD_SDLDevice&);
-
-protected:
- virtual void playing(bool playing);
-
-public:
- /**
- * Opens the SDL audio device for playback.
- * \param specs The wanted audio specification.
- * \param buffersize The size of the internal buffer.
- * \note The specification really used for opening the device may differ.
- * \exception AUD_Exception Thrown if the audio device cannot be opened.
- */
- AUD_SDLDevice(AUD_DeviceSpecs specs,
- int buffersize = AUD_DEFAULT_BUFFER_SIZE);
-
- /**
- * Closes the SDL audio device.
- */
- virtual ~AUD_SDLDevice();
-};
-
-#endif //__AUD_SDLDEVICE_H__
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
deleted file mode 100644
index 6861e878abc..00000000000
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
+++ /dev/null
@@ -1,42 +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/SRC/AUD_SRCResampleFactory.cpp
- * \ingroup audsrc
- */
-
-
-#include "AUD_SRCResampleFactory.h"
-#include "AUD_SRCResampleReader.h"
-
-AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Reference<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-AUD_Reference<AUD_IReader> AUD_SRCResampleFactory::createReader()
-{
- return new AUD_SRCResampleReader(getReader(), m_specs.specs);
-}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.h b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
deleted file mode 100644
index 858bb0c130a..00000000000
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.h
+++ /dev/null
@@ -1,57 +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/SRC/AUD_SRCResampleFactory.h
- * \ingroup audsrc
- */
-
-
-#ifndef __AUD_SRCRESAMPLEFACTORY_H__
-#define __AUD_SRCRESAMPLEFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a resampling reader that uses libsamplerate for
- * resampling.
- */
-class AUD_SRCResampleFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_SRCResampleFactory(const AUD_SRCResampleFactory&);
- AUD_SRCResampleFactory& operator=(const AUD_SRCResampleFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_SRCResampleFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- virtual AUD_Reference<AUD_IReader> createReader();
-};
-
-#endif //__AUD_SRCRESAMPLEFACTORY_H__
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
deleted file mode 100644
index 242a7135aff..00000000000
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
+++ /dev/null
@@ -1,150 +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/SRC/AUD_SRCResampleReader.cpp
- * \ingroup audsrc
- */
-
-
-#include "AUD_SRCResampleReader.h"
-
-#include <cmath>
-#include <cstring>
-#include <cstdio>
-
-static long src_callback(void *cb_data, float **data)
-{
- return ((AUD_SRCResampleReader*)cb_data)->doCallback(data);
-}
-
-static const char* state_error = "AUD_SRCResampleReader: SRC State couldn't be "
- "created.";
-
-AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader,
- AUD_Specs specs) :
- AUD_ResampleReader(reader, specs.rate),
- m_channels(reader->getSpecs().channels),
- m_position(0)
-{
- int error;
- m_src = src_callback_new(src_callback,
- SRC_SINC_MEDIUM_QUALITY,
- m_channels,
- &error,
- this);
-
- if(!m_src)
- {
- // XXX printf("%s\n", src_strerror(error));
- AUD_THROW(AUD_ERROR_SRC, state_error);
- }
-}
-
-AUD_SRCResampleReader::~AUD_SRCResampleReader()
-{
- src_delete(m_src);
-}
-
-long AUD_SRCResampleReader::doCallback(float** data)
-{
- AUD_Specs specs;
- specs.channels = m_channels;
- specs.rate = m_rate;
-
- int length = m_buffer.getSize() / AUD_SAMPLE_SIZE(specs);
-
- *data = m_buffer.getBuffer();
- m_reader->read(length, m_eos, *data);
-
- return length;
-}
-
-void AUD_SRCResampleReader::seek(int position)
-{
- AUD_Specs specs = m_reader->getSpecs();
- double factor = double(m_rate) / double(specs.rate);
- m_reader->seek(position / factor);
- src_reset(m_src);
- m_position = position;
-}
-
-int AUD_SRCResampleReader::getLength() const
-{
- AUD_Specs specs = m_reader->getSpecs();
- double factor = double(m_rate) / double(specs.rate);
- return m_reader->getLength() * factor;
-}
-
-int AUD_SRCResampleReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SRCResampleReader::getSpecs() const
-{
- AUD_Specs specs = m_reader->getSpecs();
- specs.rate = m_rate;
- return specs;
-}
-
-void AUD_SRCResampleReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_Specs specs = m_reader->getSpecs();
-
- double factor = double(m_rate) / double(specs.rate);
-
- specs.rate = m_rate;
-
- int size = length;
-
- m_buffer.assureSize(length * AUD_SAMPLE_SIZE(specs));
-
- if(specs.channels != m_channels)
- {
- src_delete(m_src);
-
- m_channels = specs.channels;
-
- int error;
- m_src = src_callback_new(src_callback,
- SRC_SINC_MEDIUM_QUALITY,
- m_channels,
- &error,
- this);
-
- if(!m_src)
- {
- // XXX printf("%s\n", src_strerror(error));
- AUD_THROW(AUD_ERROR_SRC, state_error);
- }
- }
-
- m_eos = false;
-
- length = src_callback_read(m_src, factor, length, buffer);
-
- m_position += length;
-
- eos = m_eos && (length < size);
-}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.h b/intern/audaspace/SRC/AUD_SRCResampleReader.h
deleted file mode 100644
index 891b28b0993..00000000000
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.h
+++ /dev/null
@@ -1,103 +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/SRC/AUD_SRCResampleReader.h
- * \ingroup audsrc
- */
-
-
-#ifndef __AUD_SRCRESAMPLEREADER_H__
-#define __AUD_SRCRESAMPLEREADER_H__
-
-#include "AUD_ResampleReader.h"
-#include "AUD_Buffer.h"
-
-#include <samplerate.h>
-
-/**
- * This resampling reader uses libsamplerate for resampling.
- */
-class AUD_SRCResampleReader : public AUD_ResampleReader
-{
-private:
- /**
- * The sound output buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * The reader channels.
- */
- AUD_Channels m_channels;
-
- /**
- * The src state structure.
- */
- SRC_STATE* m_src;
-
- /**
- * The current playback position;
- */
- int m_position;
-
- /**
- * Whether reader reached end of stream.
- */
- bool m_eos;
-
- // hide copy constructor and operator=
- AUD_SRCResampleReader(const AUD_SRCResampleReader&);
- AUD_SRCResampleReader& operator=(const AUD_SRCResampleReader&);
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- * \exception AUD_Exception Thrown if the source specification cannot be
- * resampled to the target specification.
- */
- AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs);
-
- /**
- * Destroys the reader.
- */
- ~AUD_SRCResampleReader();
-
- /**
- * The callback function for SRC.
- * \warning Do not call!
- * \param data The pointer to the float data.
- * \return The count of samples in the float data.
- */
- long doCallback(float** data);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SRCRESAMPLEREADER_H__
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
deleted file mode 100644
index 403c367fccc..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
+++ /dev/null
@@ -1,55 +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/ffmpeg/AUD_FFMPEGFactory.cpp
- * \ingroup audffmpeg
- */
-
-
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include "AUD_FFMPEGFactory.h"
-#include "AUD_FFMPEGReader.h"
-
-AUD_FFMPEGFactory::AUD_FFMPEGFactory(std::string filename) :
- m_filename(filename)
-{
-}
-
-AUD_FFMPEGFactory::AUD_FFMPEGFactory(const data_t* buffer, int size) :
- m_buffer(new AUD_Buffer(size))
-{
- memcpy(m_buffer->getBuffer(), buffer, size);
-}
-
-boost::shared_ptr<AUD_IReader> AUD_FFMPEGFactory::createReader()
-{
- if(m_buffer.get())
- return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_buffer));
- else
- 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
deleted file mode 100644
index 23d0f07ed0b..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
+++ /dev/null
@@ -1,78 +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/ffmpeg/AUD_FFMPEGFactory.h
- * \ingroup audffmpeg
- */
-
-
-#ifndef __AUD_FFMPEGFACTORY_H__
-#define __AUD_FFMPEGFACTORY_H__
-
-#include "AUD_IFactory.h"
-#include "AUD_Buffer.h"
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-
-/**
- * This factory reads a sound file via ffmpeg.
- * \warning Notice that the needed formats and codecs have to be registered
- * for ffmpeg before this class can be used.
- */
-class AUD_FFMPEGFactory : public AUD_IFactory
-{
-private:
- /**
- * The filename of the sound source file.
- */
- const std::string m_filename;
-
- /**
- * The buffer to read from.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- // hide copy constructor and operator=
- AUD_FFMPEGFactory(const AUD_FFMPEGFactory&);
- AUD_FFMPEGFactory& operator=(const AUD_FFMPEGFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param filename The sound file path.
- */
- AUD_FFMPEGFactory(std::string filename);
-
- /**
- * Creates a new factory.
- * \param buffer The buffer to read from.
- * \param size The size of the buffer.
- */
- AUD_FFMPEGFactory(const data_t* buffer, int size);
-
- 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
deleted file mode 100644
index e9eea195208..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ /dev/null
@@ -1,483 +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/ffmpeg/AUD_FFMPEGReader.cpp
- * \ingroup audffmpeg
- */
-
-
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include "AUD_FFMPEGReader.h"
-
-extern "C" {
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <libavformat/avio.h>
-#include "ffmpeg_compat.h"
-}
-
-int AUD_FFMPEGReader::decode(AVPacket& packet, AUD_Buffer& buffer)
-{
-#ifdef FFMPEG_HAVE_DECODE_AUDIO4
- AVFrame* frame = NULL;
- int got_frame;
- int read_length;
- uint8_t* orig_data = packet.data;
- int orig_size = packet.size;
-
- int buf_size = buffer.getSize();
- int buf_pos = 0;
-
- while(packet.size > 0)
- {
- got_frame = 0;
-
- if(!frame)
- frame = av_frame_alloc();
- else
- av_frame_unref(frame);
-
- read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet);
- if(read_length < 0)
- break;
-
- if(got_frame)
- {
- int data_size = av_samples_get_buffer_size(NULL, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1);
-
- if(buf_size - buf_pos < data_size)
- {
- buffer.resize(buf_size + data_size, true);
- buf_size += data_size;
- }
-
- if(m_tointerleave)
- {
- int single_size = data_size / m_codecCtx->channels / frame->nb_samples;
- for(int channel = 0; channel < m_codecCtx->channels; channel++)
- {
- for(int i = 0; i < frame->nb_samples; i++)
- {
- memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
- frame->data[channel] + i * single_size, single_size);
- }
- }
- }
- else
- memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[0], data_size);
-
- buf_pos += data_size;
- }
- packet.size -= read_length;
- packet.data += read_length;
- }
-
- packet.data = orig_data;
- packet.size = orig_size;
- av_free(frame);
-
- return buf_pos;
-#else
- // save packet parameters
- uint8_t *audio_pkg_data = packet.data;
- int audio_pkg_size = packet.size;
-
- int buf_size = buffer.getSize();
- int buf_pos = 0;
-
- int read_length, data_size;
-
- AVPacket tmp_pkt;
-
- av_init_packet(&tmp_pkt);
-
- // as long as there is still data in the package
- while(audio_pkg_size > 0)
- {
- // resize buffer if needed
- if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE)
- {
- buffer.resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, true);
- buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE;
- }
-
- // read samples from the packet
- data_size = buf_size - buf_pos;
-
- tmp_pkt.data = audio_pkg_data;
- tmp_pkt.size = audio_pkg_size;
-
- read_length = avcodec_decode_audio3(
- m_codecCtx,
- (int16_t*)(((data_t*)buffer.getBuffer()) + buf_pos),
- &data_size, &tmp_pkt);
-
- // read error, next packet!
- if(read_length < 0)
- break;
-
- buf_pos += data_size;
-
- // move packet parameters
- audio_pkg_data += read_length;
- audio_pkg_size -= read_length;
- }
-
- return buf_pos;
-#endif
-}
-
-static const char* streaminfo_error = "AUD_FFMPEGReader: Stream info couldn't "
- "be found.";
-static const char* noaudio_error = "AUD_FFMPEGReader: File doesn't include an "
- "audio stream.";
-static const char* nodecoder_error = "AUD_FFMPEGReader: No decoder found for "
- "the audio stream.";
-static const char* codecopen_error = "AUD_FFMPEGReader: Codec couldn't be "
- "opened.";
-static const char* format_error = "AUD_FFMPEGReader: Unsupported sample "
- "format.";
-
-void AUD_FFMPEGReader::init()
-{
- m_position = 0;
- m_pkgbuf_left = 0;
-
- if(avformat_find_stream_info(m_formatCtx, NULL) < 0)
- AUD_THROW(AUD_ERROR_FFMPEG, streaminfo_error);
-
- // find audio stream and codec
- m_stream = -1;
-
- for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
- {
- if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
- && (m_stream < 0))
- {
- m_stream=i;
- break;
- }
- }
-
- if(m_stream == -1)
- AUD_THROW(AUD_ERROR_FFMPEG, noaudio_error);
-
- m_codecCtx = m_formatCtx->streams[m_stream]->codec;
-
- // get a decoder and open it
- AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
- if(!aCodec)
- AUD_THROW(AUD_ERROR_FFMPEG, nodecoder_error);
-
- if(avcodec_open2(m_codecCtx, aCodec, NULL) < 0)
- AUD_THROW(AUD_ERROR_FFMPEG, codecopen_error);
-
- // XXX this prints file information to stdout:
- //dump_format(m_formatCtx, 0, NULL, 0);
-
- m_specs.channels = (AUD_Channels) m_codecCtx->channels;
- m_tointerleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
-
- switch(av_get_packed_sample_fmt(m_codecCtx->sample_fmt))
- {
- case AV_SAMPLE_FMT_U8:
- m_convert = AUD_convert_u8_float;
- m_specs.format = AUD_FORMAT_U8;
- break;
- case AV_SAMPLE_FMT_S16:
- m_convert = AUD_convert_s16_float;
- m_specs.format = AUD_FORMAT_S16;
- break;
- case AV_SAMPLE_FMT_S32:
- m_convert = AUD_convert_s32_float;
- m_specs.format = AUD_FORMAT_S32;
- break;
- case AV_SAMPLE_FMT_FLT:
- m_convert = AUD_convert_copy<float>;
- m_specs.format = AUD_FORMAT_FLOAT32;
- break;
- case AV_SAMPLE_FMT_DBL:
- m_convert = AUD_convert_double_float;
- m_specs.format = AUD_FORMAT_FLOAT64;
- break;
- default:
- AUD_THROW(AUD_ERROR_FFMPEG, format_error);
- }
-
- m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
-}
-
-static const char* fileopen_error = "AUD_FFMPEGReader: File couldn't be "
- "opened.";
-
-AUD_FFMPEGReader::AUD_FFMPEGReader(std::string filename) :
- m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1),
- m_formatCtx(NULL),
- m_aviocontext(NULL),
- m_membuf(NULL)
-{
- // open file
- if(avformat_open_input(&m_formatCtx, filename.c_str(), NULL, NULL)!=0)
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
-
- try
- {
- init();
- }
- catch(AUD_Exception&)
- {
- avformat_close_input(&m_formatCtx);
- throw;
- }
-}
-
-static const char* streamopen_error = "AUD_FFMPEGReader: Stream couldn't be "
- "opened.";
-
-AUD_FFMPEGReader::AUD_FFMPEGReader(boost::shared_ptr<AUD_Buffer> buffer) :
- m_pkgbuf(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1),
- m_membuffer(buffer),
- m_membufferpos(0)
-{
- m_membuf = reinterpret_cast<data_t*>(av_malloc(FF_MIN_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE));
-
- m_aviocontext = avio_alloc_context(m_membuf, FF_MIN_BUFFER_SIZE, 0, this,
- read_packet, NULL, seek_packet);
-
- if(!m_aviocontext)
- {
- av_free(m_aviocontext);
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
- }
-
- m_formatCtx = avformat_alloc_context();
- m_formatCtx->pb = m_aviocontext;
- if(avformat_open_input(&m_formatCtx, "", NULL, NULL)!=0)
- {
- av_free(m_aviocontext);
- AUD_THROW(AUD_ERROR_FILE, streamopen_error);
- }
-
- try
- {
- init();
- }
- catch(AUD_Exception&)
- {
- avformat_close_input(&m_formatCtx);
- av_free(m_aviocontext);
- throw;
- }
-}
-
-AUD_FFMPEGReader::~AUD_FFMPEGReader()
-{
- avcodec_close(m_codecCtx);
- avformat_close_input(&m_formatCtx);
-}
-
-int AUD_FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
-{
- AUD_FFMPEGReader* reader = reinterpret_cast<AUD_FFMPEGReader*>(opaque);
-
- int size = AUD_MIN(buf_size, reader->m_membuffer->getSize() - reader->m_membufferpos);
-
- if(size < 0)
- return -1;
-
- memcpy(buf, ((data_t*)reader->m_membuffer->getBuffer()) + reader->m_membufferpos, size);
- reader->m_membufferpos += size;
-
- return size;
-}
-
-int64_t AUD_FFMPEGReader::seek_packet(void* opaque, int64_t offset, int whence)
-{
- AUD_FFMPEGReader* reader = reinterpret_cast<AUD_FFMPEGReader*>(opaque);
-
- switch(whence)
- {
- case SEEK_SET:
- reader->m_membufferpos = 0;
- break;
- case SEEK_END:
- reader->m_membufferpos = reader->m_membuffer->getSize();
- break;
- case AVSEEK_SIZE:
- return reader->m_membuffer->getSize();
- }
-
- return (reader->m_membufferpos += offset);
-}
-
-bool AUD_FFMPEGReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_FFMPEGReader::seek(int position)
-{
- if(position >= 0)
- {
- uint64_t st_time = m_formatCtx->start_time;
- uint64_t seek_pos = ((uint64_t)position) * ((uint64_t)AV_TIME_BASE) / ((uint64_t)m_specs.rate);
-
- if (st_time != AV_NOPTS_VALUE) {
- seek_pos += st_time;
- }
-
- double pts_time_base =
- av_q2d(m_formatCtx->streams[m_stream]->time_base);
- uint64_t pts_st_time =
- ((st_time != AV_NOPTS_VALUE) ? st_time : 0)
- / pts_time_base / (uint64_t) AV_TIME_BASE;
-
- // a value < 0 tells us that seeking failed
- if(av_seek_frame(m_formatCtx, -1, seek_pos,
- AVSEEK_FLAG_BACKWARD | AVSEEK_FLAG_ANY) >= 0)
- {
- avcodec_flush_buffers(m_codecCtx);
- m_position = position;
-
- AVPacket packet;
- bool search = true;
-
- while(search && av_read_frame(m_formatCtx, &packet) >= 0)
- {
- // is it a frame from the audio stream?
- if(packet.stream_index == m_stream)
- {
- // decode the package
- m_pkgbuf_left = decode(packet, m_pkgbuf);
- search = false;
-
- // check position
- if(packet.pts != AV_NOPTS_VALUE)
- {
- // calculate real position, and read to frame!
- m_position = (packet.pts -
- pts_st_time) * pts_time_base * m_specs.rate;
-
- if(m_position < position)
- {
- // read until we're at the right position
- int length = AUD_DEFAULT_BUFFER_SIZE;
- AUD_Buffer buffer(length * AUD_SAMPLE_SIZE(m_specs));
- bool eos;
- for(int len = position - m_position; len > 0; len -= AUD_DEFAULT_BUFFER_SIZE)
- {
- if(len < AUD_DEFAULT_BUFFER_SIZE)
- length = len;
- read(length, eos, buffer.getBuffer());
- }
- }
- }
- }
- av_free_packet(&packet);
- }
- }
- else
- {
- fprintf(stderr, "seeking failed!\n");
- // Seeking failed, do nothing.
- }
- }
-}
-
-int AUD_FFMPEGReader::getLength() const
-{
- // return approximated remaning size
- return (int)((m_formatCtx->duration * m_codecCtx->sample_rate)
- / AV_TIME_BASE)-m_position;
-}
-
-int AUD_FFMPEGReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_FFMPEGReader::getSpecs() const
-{
- return m_specs.specs;
-}
-
-void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
-{
- // read packages and decode them
- AVPacket packet;
- int data_size = 0;
- int pkgbuf_pos;
- int left = length;
- int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
-
- sample_t* buf = buffer;
- pkgbuf_pos = m_pkgbuf_left;
- m_pkgbuf_left = 0;
-
- // there may still be data in the buffer from the last call
- if(pkgbuf_pos > 0)
- {
- data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(),
- data_size / AUD_FORMAT_SIZE(m_specs.format));
- buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
- left -= data_size/sample_size;
- }
-
- // for each frame read as long as there isn't enough data already
- while((left > 0) && (av_read_frame(m_formatCtx, &packet) >= 0))
- {
- // is it a frame from the audio stream?
- if(packet.stream_index == m_stream)
- {
- // decode the package
- pkgbuf_pos = decode(packet, m_pkgbuf);
-
- // copy to output buffer
- data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(),
- data_size / AUD_FORMAT_SIZE(m_specs.format));
- buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
- left -= data_size/sample_size;
- }
- av_free_packet(&packet);
- }
- // read more data than necessary?
- if(pkgbuf_pos > data_size)
- {
- m_pkgbuf_left = pkgbuf_pos-data_size;
- memmove(m_pkgbuf.getBuffer(),
- ((data_t*)m_pkgbuf.getBuffer())+data_size,
- pkgbuf_pos-data_size);
- }
-
- if((eos = (left > 0)))
- length -= left;
-
- m_position += length;
-}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
deleted file mode 100644
index 377086e2625..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
+++ /dev/null
@@ -1,169 +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/ffmpeg/AUD_FFMPEGReader.h
- * \ingroup audffmpeg
- */
-
-
-#ifndef __AUD_FFMPEGREADER_H__
-#define __AUD_FFMPEGREADER_H__
-
-#include "AUD_ConverterFunctions.h"
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-
-struct AVCodecContext;
-extern "C" {
-#include <libavformat/avformat.h>
-}
-
-/**
- * This class reads a sound file via ffmpeg.
- * \warning Seeking may not be accurate! Moreover the position is updated after
- * a buffer reading call. So calling getPosition right after seek
- * normally results in a wrong value.
- */
-class AUD_FFMPEGReader : public AUD_IReader
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The specification of the audio data.
- */
- AUD_DeviceSpecs m_specs;
-
- /**
- * The buffer for package reading.
- */
- AUD_Buffer m_pkgbuf;
-
- /**
- * The count of samples still available from the last read package.
- */
- int m_pkgbuf_left;
-
- /**
- * The AVFormatContext structure for using ffmpeg.
- */
- AVFormatContext* m_formatCtx;
-
- /**
- * The AVCodecContext structure for using ffmpeg.
- */
- AVCodecContext* m_codecCtx;
-
- /**
- * The AVIOContext to read the data from.
- */
- AVIOContext* m_aviocontext;
-
- /**
- * The stream ID in the file.
- */
- int m_stream;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
- /**
- * The memory file to read from.
- */
- boost::shared_ptr<AUD_Buffer> m_membuffer;
-
- /**
- * The buffer to read with.
- */
- data_t* m_membuf;
-
- /**
- * Reading position of the buffer.
- */
- int64_t m_membufferpos;
-
- /**
- * Whether the audio data has to be interleaved after reading.
- */
- bool m_tointerleave;
-
- /**
- * Decodes a packet into the given buffer.
- * \param packet The AVPacket to decode.
- * \param buffer The target buffer.
- * \return The count of read bytes.
- */
- int decode(AVPacket& packet, AUD_Buffer& buffer);
-
- /**
- * Initializes the object.
- */
- void init();
-
- // hide copy constructor and operator=
- AUD_FFMPEGReader(const AUD_FFMPEGReader&);
- AUD_FFMPEGReader& operator=(const AUD_FFMPEGReader&);
-
-public:
- /**
- * Creates a new reader.
- * \param filename The path to the file to be read.
- * \exception AUD_Exception Thrown if the file specified does not exist or
- * cannot be read with ffmpeg.
- */
- AUD_FFMPEGReader(std::string filename);
-
- /**
- * Creates a new reader.
- * \param buffer The buffer to read from.
- * \exception AUD_Exception Thrown if the buffer specified cannot be read
- * with ffmpeg.
- */
- AUD_FFMPEGReader(boost::shared_ptr<AUD_Buffer> buffer);
-
- /**
- * Destroys the reader and closes the file.
- */
- virtual ~AUD_FFMPEGReader();
-
- static int read_packet(void* opaque, uint8_t* buf, int buf_size);
- static int64_t seek_packet(void* opaque, int64_t offset, int whence);
-
- virtual bool isSeekable() const;
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_FFMPEGREADER_H__
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
deleted file mode 100644
index 3f95ac7a4da..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
+++ /dev/null
@@ -1,395 +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/ffmpeg/AUD_FFMPEGWriter.cpp
- * \ingroup audffmpeg
- */
-
-
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-#include "AUD_FFMPEGWriter.h"
-
-extern "C" {
-#include <libavcodec/avcodec.h>
-#include <libavformat/avformat.h>
-#include <libavformat/avio.h>
-#include "ffmpeg_compat.h"
-}
-
-static const char* context_error = "AUD_FFMPEGWriter: Couldn't allocate context.";
-static const char* codec_error = "AUD_FFMPEGWriter: Invalid codec or codec not found.";
-static const char* stream_error = "AUD_FFMPEGWriter: Couldn't allocate stream.";
-static const char* format_error = "AUD_FFMPEGWriter: Unsupported sample format.";
-static const char* file_error = "AUD_FFMPEGWriter: File couldn't be written.";
-static const char* write_error = "AUD_FFMPEGWriter: Error writing packet.";
-
-AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate) :
- m_position(0),
- m_specs(specs),
- m_input_samples(0)
-{
- static const char* formats[] = { NULL, "ac3", "flac", "matroska", "mp2", "mp3", "ogg", "wav" };
-
- m_formatCtx = avformat_alloc_context();
- if (!m_formatCtx) AUD_THROW(AUD_ERROR_FFMPEG, context_error);
-
- strcpy(m_formatCtx->filename, filename.c_str());
- m_outputFmt = m_formatCtx->oformat = av_guess_format(formats[format], filename.c_str(), NULL);
- if (!m_outputFmt) {
- avformat_free_context(m_formatCtx);
- AUD_THROW(AUD_ERROR_FFMPEG, context_error);
- }
-
- switch(codec)
- {
- case AUD_CODEC_AAC:
- m_outputFmt->audio_codec = AV_CODEC_ID_AAC;
- break;
- case AUD_CODEC_AC3:
- m_outputFmt->audio_codec = AV_CODEC_ID_AC3;
- break;
- case AUD_CODEC_FLAC:
- m_outputFmt->audio_codec = AV_CODEC_ID_FLAC;
- break;
- case AUD_CODEC_MP2:
- m_outputFmt->audio_codec = AV_CODEC_ID_MP2;
- break;
- case AUD_CODEC_MP3:
- m_outputFmt->audio_codec = AV_CODEC_ID_MP3;
- break;
- case AUD_CODEC_PCM:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_U8;
- break;
- case AUD_FORMAT_S16:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S16LE;
- break;
- case AUD_FORMAT_S24:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S24LE;
- break;
- case AUD_FORMAT_S32:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_S32LE;
- break;
- case AUD_FORMAT_FLOAT32:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F32LE;
- break;
- case AUD_FORMAT_FLOAT64:
- m_outputFmt->audio_codec = AV_CODEC_ID_PCM_F64LE;
- break;
- default:
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
- break;
- }
- break;
- case AUD_CODEC_VORBIS:
- m_outputFmt->audio_codec = AV_CODEC_ID_VORBIS;
- break;
- default:
- m_outputFmt->audio_codec = AV_CODEC_ID_NONE;
- break;
- }
-
- try
- {
- if(m_outputFmt->audio_codec == AV_CODEC_ID_NONE)
- AUD_THROW(AUD_ERROR_SPECS, codec_error);
-
- m_stream = avformat_new_stream(m_formatCtx, NULL);
- if(!m_stream)
- AUD_THROW(AUD_ERROR_FFMPEG, stream_error);
-
- m_codecCtx = m_stream->codec;
- m_codecCtx->codec_id = m_outputFmt->audio_codec;
- m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
- m_codecCtx->bit_rate = bitrate;
- m_codecCtx->sample_rate = int(m_specs.rate);
- m_codecCtx->channels = m_specs.channels;
- m_codecCtx->time_base.num = 1;
- m_codecCtx->time_base.den = m_codecCtx->sample_rate;
-
- switch(m_specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_float_u8;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_U8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_float_s16;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_S16;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_float_s32;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_S32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_copy<float>;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_FLT;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_float_double;
- m_codecCtx->sample_fmt = AV_SAMPLE_FMT_DBL;
- break;
- default:
- AUD_THROW(AUD_ERROR_FFMPEG, format_error);
- }
-
- try
- {
- if(m_formatCtx->oformat->flags & AVFMT_GLOBALHEADER)
- m_codecCtx->flags |= CODEC_FLAG_GLOBAL_HEADER;
-
- AVCodec* codec = avcodec_find_encoder(m_codecCtx->codec_id);
- if(!codec)
- AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
-
- if(codec->sample_fmts) {
- // Check if the preferred sample format for this codec is supported.
- const enum AVSampleFormat *p = codec->sample_fmts;
- for(; *p != -1; p++) {
- if(*p == m_stream->codec->sample_fmt)
- break;
- }
- if(*p == -1) {
- // Sample format incompatible with codec. Defaulting to a format known to work.
- m_stream->codec->sample_fmt = codec->sample_fmts[0];
- }
- }
-
- if(avcodec_open2(m_codecCtx, codec, NULL))
- AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
-
- m_output_buffer.resize(FF_MIN_BUFFER_SIZE);
- int samplesize = AUD_MAX(AUD_SAMPLE_SIZE(m_specs), AUD_DEVICE_SAMPLE_SIZE(m_specs));
-
- if(m_codecCtx->frame_size <= 1) {
- m_input_size = FF_MIN_BUFFER_SIZE * 8 / m_codecCtx->bits_per_coded_sample / m_codecCtx->channels;
- m_input_buffer.resize(m_input_size * samplesize);
- }
- else
- {
- m_input_buffer.resize(m_codecCtx->frame_size * samplesize);
- m_input_size = m_codecCtx->frame_size;
- }
-
-#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
- m_frame = av_frame_alloc();
- if (!m_frame)
- AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
- av_frame_unref(m_frame);
- m_frame->linesize[0] = m_input_size * samplesize;
- m_frame->format = m_codecCtx->sample_fmt;
- m_frame->nb_samples = m_input_size;
-# ifdef FFMPEG_HAVE_AVFRAME_SAMPLE_RATE
- m_frame->sample_rate = m_codecCtx->sample_rate;
-# endif
-# ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
- m_frame->channel_layout = m_codecCtx->channel_layout;
-# endif
- m_sample_size = av_get_bytes_per_sample(m_codecCtx->sample_fmt);
- m_frame_pts = 0;
- m_deinterleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
- if(m_deinterleave)
- m_deinterleave_buffer.resize(m_input_size * m_codecCtx->channels * m_sample_size);
-#endif
-
- try
- {
- if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
- AUD_THROW(AUD_ERROR_FILE, file_error);
-
- if(avformat_write_header(m_formatCtx, NULL) < 0) {
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- avcodec_close(m_codecCtx);
- av_freep(&m_formatCtx->streams[0]->codec);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- av_freep(&m_formatCtx->streams[0]);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- av_free(m_formatCtx);
- throw;
- }
-}
-
-AUD_FFMPEGWriter::~AUD_FFMPEGWriter()
-{
- // writte missing data
- if(m_input_samples)
- {
- sample_t* buf = m_input_buffer.getBuffer();
- memset(buf + m_specs.channels * m_input_samples, 0,
- (m_input_size - m_input_samples) * AUD_DEVICE_SAMPLE_SIZE(m_specs));
-
- encode(buf);
- }
-
- av_write_trailer(m_formatCtx);
-
- avcodec_close(m_codecCtx);
-
- av_freep(&m_formatCtx->streams[0]->codec);
- av_freep(&m_formatCtx->streams[0]);
-
-#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
- av_frame_free(&m_frame);
-#endif
-
- avio_close(m_formatCtx->pb);
- av_free(m_formatCtx);
-}
-
-int AUD_FFMPEGWriter::getPosition() const
-{
- return m_position;
-}
-
-AUD_DeviceSpecs AUD_FFMPEGWriter::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_FFMPEGWriter::encode(sample_t* data)
-{
- // convert first
- if(m_input_size)
- m_convert(reinterpret_cast<data_t*>(data), reinterpret_cast<data_t*>(data), m_input_size * m_specs.channels);
-
- AVPacket packet = { 0 };
- av_init_packet(&packet);
-
-#ifdef FFMPEG_HAVE_ENCODE_AUDIO2
- int got_output, ret;
- m_frame->pts = m_frame_pts / av_q2d(m_codecCtx->time_base);
- m_frame_pts++;
-#ifdef FFMPEG_HAVE_FRAME_CHANNEL_LAYOUT
- m_frame->channel_layout = m_codecCtx->channel_layout;
-#endif
-
- if(m_deinterleave) {
- for(int channel = 0; channel < m_codecCtx->channels; channel++) {
- for(int i = 0; i < m_frame->nb_samples; i++) {
- memcpy(reinterpret_cast<uint8_t*>(m_deinterleave_buffer.getBuffer()) + (i + channel * m_frame->nb_samples) * m_sample_size,
- reinterpret_cast<uint8_t*>(data) + (m_codecCtx->channels * i + channel) * m_sample_size, m_sample_size);
- }
- }
-
- data = m_deinterleave_buffer.getBuffer();
- }
-
- avcodec_fill_audio_frame(m_frame, m_codecCtx->channels, m_codecCtx->sample_fmt, reinterpret_cast<uint8_t*>(data),
- m_frame->nb_samples * av_get_bytes_per_sample(m_codecCtx->sample_fmt) * m_codecCtx->channels, 1);
-
- ret = avcodec_encode_audio2(m_codecCtx, &packet, m_frame, &got_output);
- if(ret < 0)
- AUD_THROW(AUD_ERROR_FFMPEG, codec_error);
-
- if(!got_output)
- return;
-#else
- sample_t* outbuf = m_output_buffer.getBuffer();
-
- packet.size = avcodec_encode_audio(m_codecCtx, reinterpret_cast<uint8_t*>(outbuf), m_output_buffer.getSize(), reinterpret_cast<short*>(data));
- if(m_codecCtx->coded_frame && m_codecCtx->coded_frame->pts != AV_NOPTS_VALUE)
- packet.pts = av_rescale_q(m_codecCtx->coded_frame->pts, m_codecCtx->time_base, m_stream->time_base);
- packet.flags |= AV_PKT_FLAG_KEY;
- packet.data = reinterpret_cast<uint8_t*>(outbuf);
-#endif
-
- if(packet.pts != AV_NOPTS_VALUE)
- packet.pts = av_rescale_q(packet.pts, m_codecCtx->time_base, m_stream->time_base);
- if(packet.dts != AV_NOPTS_VALUE)
- packet.dts = av_rescale_q(packet.dts, m_codecCtx->time_base, m_stream->time_base);
- if(packet.duration > 0)
- packet.duration = av_rescale_q(packet.duration, m_codecCtx->time_base, m_stream->time_base);
-
- packet.stream_index = m_stream->index;
-
- packet.flags |= AV_PKT_FLAG_KEY;
-
- if(av_interleaved_write_frame(m_formatCtx, &packet)) {
- av_free_packet(&packet);
- AUD_THROW(AUD_ERROR_FFMPEG, write_error);
- }
-
- av_free_packet(&packet);
-}
-
-void AUD_FFMPEGWriter::write(unsigned int length, sample_t* buffer)
-{
- unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
-
- if(m_input_size)
- {
- sample_t* inbuf = m_input_buffer.getBuffer();
-
- while(length)
- {
- unsigned int len = AUD_MIN(m_input_size - m_input_samples, length);
-
- memcpy(inbuf + m_input_samples * m_specs.channels, buffer, len * samplesize);
-
- buffer += len * m_specs.channels;
- m_input_samples += len;
- m_position += len;
- length -= len;
-
- if(m_input_samples == m_input_size)
- {
- encode(inbuf);
-
- m_input_samples = 0;
- }
- }
- }
- else // PCM data, can write directly!
- {
- int samplesize = AUD_SAMPLE_SIZE(m_specs);
- if(m_output_buffer.getSize() != length * m_specs.channels * m_codecCtx->bits_per_coded_sample / 8)
- m_output_buffer.resize(length * m_specs.channels * m_codecCtx->bits_per_coded_sample / 8);
- m_input_buffer.assureSize(length * AUD_MAX(AUD_DEVICE_SAMPLE_SIZE(m_specs), samplesize));
-
- sample_t* buf = m_input_buffer.getBuffer();
- m_convert(reinterpret_cast<data_t*>(buf), reinterpret_cast<data_t*>(buffer), length * m_specs.channels);
-
- encode(buf);
-
- m_position += length;
- }
-}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
deleted file mode 100644
index 492aa35ff12..00000000000
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.h
+++ /dev/null
@@ -1,160 +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/ffmpeg/AUD_FFMPEGWriter.h
- * \ingroup audffmpeg
- */
-
-
-#ifndef __AUD_FFMPEGWRITER_H__
-#define __AUD_FFMPEGWRITER_H__
-
-#include "AUD_ConverterFunctions.h"
-#include "AUD_Buffer.h"
-#include "AUD_IWriter.h"
-
-#include <string>
-
-struct AVCodecContext;
-extern "C" {
-#include <libavformat/avformat.h>
-}
-
-/**
- * This class writes a sound file via ffmpeg.
- */
-class AUD_FFMPEGWriter : public AUD_IWriter
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The specification of the audio data.
- */
- AUD_DeviceSpecs m_specs;
-
- /**
- * The AVFormatContext structure for using ffmpeg.
- */
- AVFormatContext* m_formatCtx;
-
- /**
- * The AVCodecContext structure for using ffmpeg.
- */
- AVCodecContext* m_codecCtx;
-
- /**
- * The AVOutputFormat structure for using ffmpeg.
- */
- AVOutputFormat* m_outputFmt;
-
- /**
- * The AVStream structure for using ffmpeg.
- */
- AVStream* m_stream;
-
- /**
- * Frame sent to the encoder.
- */
- AVFrame *m_frame;
-
- /**
- * PTS of next frame to write.
- */
- int m_frame_pts;
-
- /**
- * Number of bytes per sample.
- */
- int m_sample_size;
-
- /**
- * Need to de-interleave audio for planar sample formats.
- */
- bool m_deinterleave;
-
- AUD_Buffer m_deinterleave_buffer;
-
- /**
- * The input buffer for the format converted data before encoding.
- */
- AUD_Buffer m_input_buffer;
-
- /**
- * The output buffer for the encoded audio data.
- */
- AUD_Buffer m_output_buffer;
-
- /**
- * The count of input samples we have so far.
- */
- unsigned int m_input_samples;
-
- /**
- * The count of input samples necessary to encode a packet.
- */
- unsigned int m_input_size;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
- // hide copy constructor and operator=
- AUD_FFMPEGWriter(const AUD_FFMPEGWriter&);
- AUD_FFMPEGWriter& operator=(const AUD_FFMPEGWriter&);
-
- /**
- * Encodes to the output buffer.
- * \param data Pointer to the data to encode.
- */
- void encode(sample_t* data);
-
-public:
- /**
- * Creates a new writer.
- * \param filename The path to the file to be read.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \exception AUD_Exception Thrown if the file specified does not exist or
- * cannot be read with ffmpeg.
- */
- AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
-
- /**
- * Destroys the writer and closes the file.
- */
- virtual ~AUD_FFMPEGWriter();
-
- virtual int getPosition() const;
- virtual AUD_DeviceSpecs getSpecs() const;
- virtual void write(unsigned int length, sample_t* buffer);
-};
-
-#endif //__AUD_FFMPEGWRITER_H__
diff --git a/intern/audaspace/fftw/AUD_BandPassFactory.cpp b/intern/audaspace/fftw/AUD_BandPassFactory.cpp
deleted file mode 100644
index 1e6538d80de..00000000000
--- a/intern/audaspace/fftw/AUD_BandPassFactory.cpp
+++ /dev/null
@@ -1,75 +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/fftw/AUD_BandPassFactory.cpp
- * \ingroup audfftw
- */
-
-
-#include "AUD_BandPassFactory.h"
-#include "AUD_BandPassReader.h"
-
-AUD_BandPassFactory::AUD_BandPassFactory(AUD_IFactory* factory, float low,
- float high) :
- AUD_EffectFactory(factory),
- m_low(low),
- m_high(high) {}
-
-AUD_BandPassFactory::AUD_BandPassFactory(float low, float high) :
- AUD_EffectFactory(0),
- m_low(low),
- m_high(high) {}
-
-float AUD_BandPassFactory::getLow()
-{
- return m_low;
-}
-
-float AUD_BandPassFactory::getHigh()
-{
- return m_high;
-}
-
-void AUD_BandPassFactory::setLow(float low)
-{
- m_low = low;
-}
-
-void AUD_BandPassFactory::setHigh(float high)
-{
- m_high = high;
-}
-
-AUD_IReader* AUD_BandPassFactory::createReader()
-{
- AUD_IReader* reader = getReader();
-
- if(reader != 0)
- {
- reader = new AUD_BandPassReader(reader, m_low, m_high);
- AUD_NEW("reader")
- }
-
- return reader;
-}
diff --git a/intern/audaspace/fftw/AUD_BandPassFactory.h b/intern/audaspace/fftw/AUD_BandPassFactory.h
deleted file mode 100644
index 90b090dce16..00000000000
--- a/intern/audaspace/fftw/AUD_BandPassFactory.h
+++ /dev/null
@@ -1,92 +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/fftw/AUD_BandPassFactory.h
- * \ingroup audfftw
- */
-
-
-#ifndef __AUD_BANDPASSFACTORY_H__
-#define __AUD_BANDPASSFACTORY_H__
-
-#include "AUD_EffectFactory.h"
-
-/**
- * This factory creates a band pass filter for a sound wave.
- */
-class AUD_BandPassFactory : public AUD_EffectFactory
-{
-private:
- /**
- * The lowest frequency to be passed.
- */
- float m_low;
-
- /**
- * The highest frequency to be passed.
- */
- float m_high;
-
-public:
- /**
- * Creates a new band pass factory.
- * \param factory The input factory.
- * \param low The lowest passed frequency.
- * \param high The highest passed frequency.
- */
- AUD_BandPassFactory(AUD_IFactory* factory, float low, float high);
-
- /**
- * Creates a new band pass factory.
- * \param low The lowest passed frequency.
- * \param high The highest passed frequency.
- */
- AUD_BandPassFactory(float low, float high);
-
- /**
- * Returns the lowest passed frequency.
- */
- float getLow();
-
- /**
- * Returns the highest passed frequency.
- */
- float getHigh();
-
- /**
- * Sets the lowest passed frequency.
- * \param low The lowest passed frequency.
- */
- void setLow(float low);
-
- /**
- * Sets the highest passed frequency.
- * \param high The highest passed frequency.
- */
- void setHigh(float high);
-
- virtual AUD_IReader* createReader();
-};
-
-#endif //__AUD_BANDPASSFACTORY_H__
diff --git a/intern/audaspace/fftw/AUD_BandPassReader.cpp b/intern/audaspace/fftw/AUD_BandPassReader.cpp
deleted file mode 100644
index 7e181fb499d..00000000000
--- a/intern/audaspace/fftw/AUD_BandPassReader.cpp
+++ /dev/null
@@ -1,127 +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/fftw/AUD_BandPassReader.cpp
- * \ingroup audfftw
- */
-
-
-#include "AUD_BandPassReader.h"
-#include "AUD_Buffer.h"
-
-#include <cstring>
-#include <stdio.h>
-
-AUD_BandPassReader::AUD_BandPassReader(AUD_IReader* reader, float low,
- float high) :
- AUD_EffectReader(reader), m_low(low), m_high(high)
-{
- m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
- m_in = new AUD_Buffer(); AUD_NEW("buffer")
- m_out = new AUD_Buffer(); AUD_NEW("buffer")
- m_length = 0;
-}
-
-AUD_BandPassReader::~AUD_BandPassReader()
-{
- if(m_length != 0)
- {
- fftw_destroy_plan(m_forward);
- fftw_destroy_plan(m_backward);
- }
-
- delete m_buffer; AUD_DELETE("buffer")
- delete m_in; AUD_DELETE("buffer")
- delete m_out; AUD_DELETE("buffer")
-}
-
-AUD_ReaderType AUD_BandPassReader::getType()
-{
- return m_reader->getType();
-}
-
-void AUD_BandPassReader::read(int & length, sample_t* & buffer)
-{
- AUD_Specs specs = m_reader->getSpecs();
-
- m_reader->read(length, buffer);
-
- if(length > 0)
- {
- m_buffer->assureSize(length * AUD_SAMPLE_SIZE(specs));
-
- if(length != m_length)
- {
- if(m_length != 0)
- {
- fftw_destroy_plan(m_forward);
- fftw_destroy_plan(m_backward);
- }
-
- m_length = length;
-
- if(m_length * sizeof(double) > m_in->getSize())
- {
- m_in->resize(m_length * sizeof(double));
- m_out->resize((m_length / 2 + 1) * sizeof(fftw_complex));
- }
-
- m_forward = fftw_plan_dft_r2c_1d(m_length,
- (double*)m_in->getBuffer(),
- (fftw_complex*)m_out->getBuffer(),
- FFTW_ESTIMATE);
- m_backward = fftw_plan_dft_c2r_1d(m_length,
- (fftw_complex*)m_out->getBuffer(),
- (double*)m_in->getBuffer(),
- FFTW_ESTIMATE);
- }
-
- double* target = (double*) m_in->getBuffer();
- sample_t* target2 = m_buffer->getBuffer();
- fftw_complex* complex = (fftw_complex*) m_out->getBuffer();
- float frequency;
-
- for(int channel = 0; channel < specs.channels; channel++)
- {
- for(int i = 0; i < m_length; i++)
- target[i] = buffer[i * specs.channels + channel];
-
- fftw_execute(m_forward);
-
- for(int i = 0; i < m_length / 2 + 1; i++)
- {
- frequency = i * specs.rate / (m_length / 2.0f + 1.0f);
- if((frequency < m_low) || (frequency > m_high))
- complex[i][0] = complex[i][1] = 0.0;
- }
-
- fftw_execute(m_backward);
-
- for(int i = 0; i < m_length; i++)
- target2[i * specs.channels + channel] = target[i] / m_length;
- }
- }
-
- buffer = m_buffer->getBuffer();
-}
diff --git a/intern/audaspace/fftw/AUD_BandPassReader.h b/intern/audaspace/fftw/AUD_BandPassReader.h
deleted file mode 100644
index 55a950818e0..00000000000
--- a/intern/audaspace/fftw/AUD_BandPassReader.h
+++ /dev/null
@@ -1,102 +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/fftw/AUD_BandPassReader.h
- * \ingroup audfftw
- */
-
-
-#ifndef __AUD_BANDPASSREADER_H__
-#define __AUD_BANDPASSREADER_H__
-
-#include <fftw3.h>
-
-#include "AUD_EffectReader.h"
-class AUD_Buffer;
-
-/**
- * This class only passes a specific frequency band of another reader.
- */
-class AUD_BandPassReader : public AUD_EffectReader
-{
-private:
- /**
- * The playback buffer.
- */
- AUD_Buffer *m_buffer;
-
- /**
- * The input buffer for fourier transformations.
- */
- AUD_Buffer *m_in;
-
- /**
- * The output buffer for fourier transformations.
- */
- AUD_Buffer *m_out;
-
- /**
- * The lowest passed frequency.
- */
- float m_low;
-
- /**
- * The highest passed frequency.
- */
- float m_high;
-
- /**
- * The fftw plan for forward transformation.
- */
- fftw_plan m_forward;
-
- /**
- * The fftw plan for backward transformation.
- */
- fftw_plan m_backward;
-
- /**
- * The length of the plans.
- */
- int m_length;
-
-public:
- /**
- * Creates a new band pass reader.
- * \param reader The reader to read from.
- * \param low The lowest passed frequency.
- * \param high The highest passed frequency.
- */
- AUD_BandPassReader(AUD_IReader* reader, float low, float high);
-
- /**
- * Destroys the reader.
- */
- virtual ~AUD_BandPassReader();
-
- virtual AUD_ReaderType getType();
- virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //__AUD_BANDPASSREADER_H__
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.cpp b/intern/audaspace/intern/AUD_AnimateableProperty.cpp
deleted file mode 100644
index e0bc18ea520..00000000000
--- a/intern/audaspace/intern/AUD_AnimateableProperty.cpp
+++ /dev/null
@@ -1,247 +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_AnimateableProperty.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_AnimateableProperty.h"
-#include "AUD_MutexLock.h"
-
-#include <cstring>
-#include <cmath>
-
-AUD_AnimateableProperty::AUD_AnimateableProperty(int count) :
- AUD_Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
-{
- memset(getBuffer(), 0, count * sizeof(float));
-
- 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_AnimateableProperty::AUD_AnimateableProperty(int count, float value) :
- AUD_Buffer(count * sizeof(float)), m_count(count), m_isAnimated(false)
-{
- sample_t* buf = getBuffer();
-
- for(int i = 0; i < count; i++)
- buf[i] = value;
-
- 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);
-}
-
-void AUD_AnimateableProperty::updateUnknownCache(int start, int end)
-{
- float* buf = getBuffer();
-
- for(int i = start; i <= end; i++)
- // TODO: maybe first instead of zero order interpolation?
- memcpy(buf + i * m_count, buf + (start - 1) * m_count, m_count * sizeof(float));
-}
-
-AUD_AnimateableProperty::~AUD_AnimateableProperty()
-{
- pthread_mutex_destroy(&m_mutex);
-}
-
-void AUD_AnimateableProperty::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_AnimateableProperty::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}
-
-void AUD_AnimateableProperty::write(const float* data)
-{
- AUD_MutexLock lock(*this);
-
- m_isAnimated = false;
- m_unknown.clear();
- memcpy(getBuffer(), data, m_count * sizeof(float));
-}
-
-void AUD_AnimateableProperty::write(const float* data, int position, int count)
-{
- AUD_MutexLock lock(*this);
-
- int pos = getSize() / (sizeof(float) * m_count);
-
- if(!m_isAnimated)
- pos = 0;
-
- m_isAnimated = true;
-
- assureSize((count + position) * m_count * sizeof(float), true);
-
- float* buf = getBuffer();
-
- memcpy(buf + position * m_count, data, count * m_count * sizeof(float));
-
- // have to fill up space between?
- if(pos < position)
- {
- m_unknown.push_back(Unknown(pos, position - 1));
-
- // if the buffer was not animated before, we copy the previous static value
- if(pos == 0)
- pos = 1;
-
- updateUnknownCache(pos, position - 1);
- }
- // otherwise it's not at the end, let's check if some unknown part got filled
- else
- {
- bool erased = false;
-
- for(std::list<Unknown>::iterator it = m_unknown.begin(); it != m_unknown.end(); erased ? it : it++)
- {
- erased = false;
-
- // unknown area before position
- if(it->end < position)
- continue;
-
- // we're after the new area, let's stop
- if(it->start >= position + count)
- break;
-
- // we have an intersection, now 4 cases:
- // the start is included
- if(position <= it->start)
- {
- // the end is included
- if(position + count > it->end)
- {
- // simply delete
- it = m_unknown.erase(it);
- erased = true;
- }
- // the end is excluded, a second part remains
- else
- {
- // update second part
- it->start = position + count;
- updateUnknownCache(it->start, it->end);
- break;
- }
- }
- // start is excluded, a first part remains
- else
- {
- // the end is included
- if(position + count > it->end)
- {
- // update first part
- it->end = position - 1;
- }
- // the end is excluded, a second part remains
- else
- {
- // add another item and update both parts
- m_unknown.insert(it, Unknown(it->start, position - 1));
- it->start = position + count;
- updateUnknownCache(it->start, it->end);
- }
- }
- }
- }
-}
-
-void AUD_AnimateableProperty::read(float position, float* out)
-{
- AUD_MutexLock lock(*this);
-
- if(!m_isAnimated)
- {
- memcpy(out, getBuffer(), m_count * sizeof(float));
- return;
- }
-
- int last = getSize() / (sizeof(float) * m_count) - 1;
- float t = position - floor(position);
-
- if(position >= last)
- {
- position = last;
- t = 0;
- }
-
- if(t == 0)
- {
- memcpy(out, getBuffer() + int(floor(position)) * m_count, m_count * sizeof(float));
- }
- else
- {
- int pos = int(floor(position)) * m_count;
- float t2 = t * t;
- float t3 = t2 * t;
- float m0, m1;
- float* p0;
- float* p1 = getBuffer() + pos;
- float* p2;
- float* p3;
- last *= m_count;
-
- if(pos == 0)
- p0 = p1;
- else
- p0 = p1 - m_count;
-
- p2 = p1 + m_count;
- if(pos + m_count == last)
- p3 = p2;
- else
- p3 = p2 + m_count;
-
- for(int i = 0; i < m_count; i++)
- {
- m0 = (p2[i] - p0[i]) / 2.0f;
- m1 = (p3[i] - p1[i]) / 2.0f;
-
- out[i] = (2 * t3 - 3 * t2 + 1) * p0[i] + (-2 * t3 + 3 * t2) * p1[i] +
- (t3 - 2 * t2 + t) * m0 + (t3 - t2) * m1;
- }
- }
-}
-
-bool AUD_AnimateableProperty::isAnimated() const
-{
- return m_isAnimated;
-}
diff --git a/intern/audaspace/intern/AUD_AnimateableProperty.h b/intern/audaspace/intern/AUD_AnimateableProperty.h
deleted file mode 100644
index f07e5916b25..00000000000
--- a/intern/audaspace/intern/AUD_AnimateableProperty.h
+++ /dev/null
@@ -1,128 +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_AnimateableProperty.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_ANIMATEABLEPROPERTY_H__
-#define __AUD_ANIMATEABLEPROPERTY_H__
-
-#include "AUD_Buffer.h"
-#include "AUD_ILockable.h"
-
-#include <pthread.h>
-#include <list>
-
-/**
- * This class saves animation data for float properties.
- */
-class AUD_AnimateableProperty : private AUD_Buffer, public AUD_ILockable
-{
-private:
- struct Unknown {
- int start;
- int end;
-
- Unknown(int start, int end) :
- start(start), end(end) {}
- };
-
- /// The count of floats for a single property.
- const int m_count;
-
- /// Whether the property is animated or not.
- bool m_isAnimated;
-
- /// The mutex for locking.
- pthread_mutex_t m_mutex;
-
- /// The list of unknown buffer areas.
- std::list<Unknown> m_unknown;
-
- // hide copy constructor and operator=
- AUD_AnimateableProperty(const AUD_AnimateableProperty&);
- AUD_AnimateableProperty& operator=(const AUD_AnimateableProperty&);
-
- void updateUnknownCache(int start, int end);
-
-public:
- /**
- * Creates a new animateable property.
- * \param count The count of floats for a single property.
- */
- AUD_AnimateableProperty(int count = 1);
-
- /**
- * Creates a new animateable property.
- * \param count The count of floats for a single property.
- * \param count The value that the property should get initialized with. All count floats will be initialized to the same value.
- */
- AUD_AnimateableProperty(int count, float value);
-
- /**
- * Destroys the animateable property.
- */
- ~AUD_AnimateableProperty();
-
- /**
- * Locks the property.
- */
- virtual void lock();
-
- /**
- * Unlocks the previously locked property.
- */
- virtual void unlock();
-
- /**
- * Writes the properties value and marks it non-animated.
- * \param data The new value.
- */
- void write(const float* data);
-
- /**
- * Writes the properties value and marks it animated.
- * \param data The new value.
- * \param position The position in the animation in frames.
- * \param count The count of frames to write.
- */
- void write(const float* data, int position, int count);
-
- /**
- * Reads the properties value.
- * \param position The position in the animation in frames.
- * \param[out] out Where to write the value to.
- */
- void read(float position, float* out);
-
- /**
- * Returns whether the property is animated.
- * \return Whether the property is animated.
- */
- bool isAnimated() const;
-};
-
-#endif //__AUD_ANIMATEABLEPROPERTY_H__
diff --git a/intern/audaspace/intern/AUD_Buffer.cpp b/intern/audaspace/intern/AUD_Buffer.cpp
deleted file mode 100644
index b7157f672b4..00000000000
--- a/intern/audaspace/intern/AUD_Buffer.cpp
+++ /dev/null
@@ -1,80 +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_Buffer.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_Buffer.h"
-#include "AUD_Space.h"
-
-#include <cstring>
-#include <cstdlib>
-
-#define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
-
-AUD_Buffer::AUD_Buffer(int size)
-{
- m_size = size;
- m_buffer = (data_t*) malloc(size+16);
-}
-
-AUD_Buffer::~AUD_Buffer()
-{
- free(m_buffer);
-}
-
-sample_t* AUD_Buffer::getBuffer() const
-{
- return (sample_t*) AUD_ALIGN(m_buffer);
-}
-
-int AUD_Buffer::getSize() const
-{
- return m_size;
-}
-
-void AUD_Buffer::resize(int size, bool keep)
-{
- if(keep)
- {
- data_t* buffer = (data_t*) malloc(size + 16);
-
- memcpy(AUD_ALIGN(buffer), AUD_ALIGN(m_buffer), AUD_MIN(size, m_size));
-
- free(m_buffer);
- m_buffer = buffer;
- }
- else
- m_buffer = (data_t*) realloc(m_buffer, size + 16);
-
- m_size = size;
-}
-
-void AUD_Buffer::assureSize(int size, bool keep)
-{
- if(m_size < size)
- resize(size, keep);
-}
diff --git a/intern/audaspace/intern/AUD_Buffer.h b/intern/audaspace/intern/AUD_Buffer.h
deleted file mode 100644
index d3207f04f83..00000000000
--- a/intern/audaspace/intern/AUD_Buffer.h
+++ /dev/null
@@ -1,93 +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_Buffer.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_BUFFER_H__
-#define __AUD_BUFFER_H__
-
-#include "AUD_Space.h"
-
-/**
- * This class is a simple buffer in RAM which is 16 Byte aligned and provides
- * resize functionality.
- */
-class AUD_Buffer
-{
-private:
- /// The size of the buffer in bytes.
- int m_size;
-
- /// The pointer to the buffer memory.
- data_t* m_buffer;
-
- // hide copy constructor and operator=
- AUD_Buffer(const AUD_Buffer&);
- AUD_Buffer& operator=(const AUD_Buffer&);
-
-public:
- /**
- * Creates a new buffer.
- * \param size The size of the buffer in bytes.
- */
- AUD_Buffer(int size = 0);
-
- /**
- * Destroys the buffer.
- */
- ~AUD_Buffer();
-
- /**
- * Returns the pointer to the buffer in memory.
- */
- sample_t* getBuffer() const;
-
- /**
- * Returns the size of the buffer in bytes.
- */
- int getSize() const;
-
- /**
- * Resizes the buffer.
- * \param size The new size of the buffer, measured in bytes.
- * \param keep Whether to keep the old data. If the new buffer is smaller,
- * the data at the end will be lost.
- */
- void resize(int size, bool keep = false);
-
- /**
- * Makes sure the buffer has a minimum size.
- * If size is >= current size, nothing will happen.
- * Otherwise the buffer is resized with keep as parameter.
- * \param size The new minimum size of the buffer, measured in bytes.
- * \param keep Whether to keep the old data. If the new buffer is smaller,
- * the data at the end will be lost.
- */
- void assureSize(int size, bool keep = false);
-};
-
-#endif //__AUD_BUFFER_H__
diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp
deleted file mode 100644
index b9d819ff774..00000000000
--- a/intern/audaspace/intern/AUD_BufferReader.cpp
+++ /dev/null
@@ -1,90 +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_BufferReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_BufferReader.h"
-#include "AUD_Buffer.h"
-#include "AUD_Space.h"
-
-#include <cstring>
-
-AUD_BufferReader::AUD_BufferReader(boost::shared_ptr<AUD_Buffer> buffer,
- AUD_Specs specs) :
- m_position(0), m_buffer(buffer), m_specs(specs)
-{
-}
-
-bool AUD_BufferReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_BufferReader::seek(int position)
-{
- m_position = position;
-}
-
-int AUD_BufferReader::getLength() const
-{
- return m_buffer->getSize() / AUD_SAMPLE_SIZE(m_specs);
-}
-
-int AUD_BufferReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_BufferReader::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_BufferReader::read(int& length, bool& eos, sample_t* buffer)
-{
- eos = false;
-
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
-
- sample_t* buf = m_buffer->getBuffer() + m_position * m_specs.channels;
-
- // in case the end of the buffer is reached
- if(m_buffer->getSize() < (m_position + length) * sample_size)
- {
- length = m_buffer->getSize() / sample_size - m_position;
- eos = true;
- }
-
- if(length < 0)
- {
- length = 0;
- return;
- }
-
- m_position += length;
- memcpy(buffer, buf, length * sample_size);
-}
diff --git a/intern/audaspace/intern/AUD_BufferReader.h b/intern/audaspace/intern/AUD_BufferReader.h
deleted file mode 100644
index d0c90ce7e61..00000000000
--- a/intern/audaspace/intern/AUD_BufferReader.h
+++ /dev/null
@@ -1,81 +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_BufferReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_BUFFERREADER_H__
-#define __AUD_BUFFERREADER_H__
-
-#include "AUD_IReader.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
- * long as the reader exists.
- */
-class AUD_BufferReader : public AUD_IReader
-{
-private:
- /**
- * The current position in the buffer.
- */
- int m_position;
-
- /**
- * The buffer that is read.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- /**
- * The specification of the sample data in the buffer.
- */
- AUD_Specs m_specs;
-
- // hide copy constructor and operator=
- AUD_BufferReader(const AUD_BufferReader&);
- AUD_BufferReader& operator=(const AUD_BufferReader&);
-
-public:
- /**
- * Creates a new buffer reader.
- * \param buffer The buffer to read from.
- * \param specs The specification of the sample data in the buffer.
- */
- AUD_BufferReader(boost::shared_ptr<AUD_Buffer> buffer, AUD_Specs specs);
-
- virtual bool isSeekable() const;
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_BUFFERREADER_H__
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
deleted file mode 100644
index 52cf256147f..00000000000
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ /dev/null
@@ -1,1323 +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_C-API.cpp
- * \ingroup audaspaceintern
- */
-
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-
-// quiet unudef define warning
-#ifdef __STDC_CONSTANT_MACROS
-// pass
-#endif
-
-#ifdef WITH_PYTHON
-# include "AUD_PyInit.h"
-# include "AUD_PyAPI.h"
-#endif
-
-#include <cstdlib>
-#include <cstring>
-#include <cmath>
-#include <sstream>
-#include <iostream>
-
-#include "AUD_NULLDevice.h"
-#include "AUD_I3DDevice.h"
-#include "AUD_I3DHandle.h"
-#include "AUD_FileFactory.h"
-#include "AUD_FileWriter.h"
-#include "AUD_StreamBufferFactory.h"
-#include "AUD_DelayFactory.h"
-#include "AUD_LimiterFactory.h"
-#include "AUD_PingPongFactory.h"
-#include "AUD_LoopFactory.h"
-#include "AUD_RectifyFactory.h"
-#include "AUD_EnvelopeFactory.h"
-#include "AUD_LinearResampleFactory.h"
-#include "AUD_LowpassFactory.h"
-#include "AUD_HighpassFactory.h"
-#include "AUD_AccumulatorFactory.h"
-#include "AUD_SumFactory.h"
-#include "AUD_SquareFactory.h"
-#include "AUD_ChannelMapperFactory.h"
-#include "AUD_Buffer.h"
-#include "AUD_ReadDevice.h"
-#include "AUD_IReader.h"
-#include "AUD_SequencerFactory.h"
-#include "AUD_SequencerEntry.h"
-#include "AUD_SilenceFactory.h"
-#include "AUD_MutexLock.h"
-
-#ifdef WITH_SDL
-#include "AUD_SDLDevice.h"
-#endif
-
-#ifdef WITH_OPENAL
-#include "AUD_OpenALDevice.h"
-#endif
-
-#ifdef WITH_JACK
-#include "AUD_JackDevice.h"
-#include "AUD_JackLibrary.h"
-#endif
-
-
-#ifdef WITH_FFMPEG
-extern "C" {
-#include <libavformat/avformat.h>
-}
-#endif
-
-#include <cassert>
-
-typedef boost::shared_ptr<AUD_IFactory> AUD_Sound;
-typedef boost::shared_ptr<AUD_IDevice> 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"
-
-#ifndef NULL
-# define NULL (void *)0
-#endif
-
-static boost::shared_ptr<AUD_IDevice> AUD_device;
-static AUD_I3DDevice *AUD_3ddevice;
-
-void AUD_initOnce()
-{
-#ifdef WITH_FFMPEG
- av_register_all();
-#endif
-#ifdef WITH_JACK
- AUD_jack_init();
-#endif
-}
-
-void AUD_exitOnce()
-{
-#ifdef WITH_JACK
- AUD_jack_exit();
-#endif
-}
-
-AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name)
-{
- boost::shared_ptr<AUD_IDevice> dev;
-
- if (AUD_device.get()) {
- AUD_exit(NULL);
- }
-
- std::string dname = device;
-
- try {
- if(dname == "Null") {
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_NULLDevice());
- }
-#ifdef WITH_SDL
- else if(dname == "SDL")
- {
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
- }
-#endif
-#ifdef WITH_OPENAL
- else if(dname == "OpenAL")
- {
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
- }
-#endif
-#ifdef WITH_JACK
- else if(dname == "JACK")
- {
-#ifdef __APPLE__
- struct stat st;
- if (stat("/Library/Frameworks/Jackmp.framework", &st) != 0) {
- printf("Warning: JACK Framework not installed\n");
- return NULL;
- }
- else
-#endif
- if (!AUD_jack_supported()) {
- printf("Warning: JACK cllient not installed\n");
- return NULL;
- }
- else {
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
- }
- }
-#endif
- else
- {
- return NULL;
- }
-
- AUD_device = dev;
- AUD_3ddevice = dynamic_cast<AUD_I3DDevice *>(AUD_device.get());
-
- return (AUD_Device*)1;
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-void AUD_exit(AUD_Device* device)
-{
- AUD_device = boost::shared_ptr<AUD_IDevice>();
- AUD_3ddevice = NULL;
-}
-
-#ifdef WITH_PYTHON
-static PyObject *AUD_getCDevice(PyObject *self)
-{
- if (AUD_device.get()) {
- Device *device = (Device *)Device_empty();
- if (device != NULL) {
- device->device = new boost::shared_ptr<AUD_IDevice>(AUD_device);
- return (PyObject *)device;
- }
- }
-
- Py_RETURN_NONE;
-}
-
-static PyMethodDef meth_getcdevice[] = {
- {"device", (PyCFunction)AUD_getCDevice, METH_NOARGS,
- "device()\n\n"
- "Returns the application's :class:`Device`.\n\n"
- ":return: The application's :class:`Device`.\n"
- ":rtype: :class:`Device`"}
-};
-
-extern "C" {
-extern void *BKE_sound_get_factory(void *sound);
-}
-
-static PyObject *AUD_getSoundFromPointer(PyObject *self, PyObject *args)
-{
- long int lptr;
-
- if (PyArg_Parse(args, "l:_sound_from_pointer", &lptr)) {
- if (lptr) {
- boost::shared_ptr<AUD_IFactory>* factory = (boost::shared_ptr<AUD_IFactory>*) BKE_sound_get_factory((void *) lptr);
-
- if (factory) {
- Factory *obj = (Factory *)Factory_empty();
- if (obj) {
- obj->factory = new boost::shared_ptr<AUD_IFactory>(*factory);
- return (PyObject *) obj;
- }
- }
- }
- }
-
- Py_RETURN_NONE;
-}
-
-static PyMethodDef meth_sound_from_pointer[] = {
- {"_sound_from_pointer", (PyCFunction)AUD_getSoundFromPointer, METH_O,
- "_sound_from_pointer(pointer)\n\n"
- "Returns the corresponding :class:`Factory` object.\n\n"
- ":arg pointer: The pointer to the bSound object as long.\n"
- ":type pointer: long\n"
- ":return: The corresponding :class:`Factory` object.\n"
- ":rtype: :class:`Factory`"}
-};
-
-PyObject *AUD_initPython()
-{
- PyObject *module = PyInit_aud();
- PyModule_AddObject(module, "device", (PyObject *)PyCFunction_New(meth_getcdevice, NULL));
- PyModule_AddObject(module, "_sound_from_pointer", (PyObject *)PyCFunction_New(meth_sound_from_pointer, NULL));
- PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
-
- return module;
-}
-
-void *AUD_getPythonSound(AUD_Sound *sound)
-{
- if (sound) {
- Factory *obj = (Factory *) Factory_empty();
- if (obj) {
- obj->factory = new boost::shared_ptr<AUD_IFactory>(*sound);
- return (PyObject *) obj;
- }
- }
-
- return NULL;
-}
-
-AUD_Sound *AUD_getSoundFromPython(void *sound)
-{
- Factory *factory = checkFactory((PyObject *)sound);
-
- if (!factory)
- return NULL;
-
- return new boost::shared_ptr<AUD_IFactory>(*reinterpret_cast<boost::shared_ptr<AUD_IFactory>*>(factory->factory));
-}
-
-#endif
-
-void AUD_Device_lock(AUD_Device* device)
-{
- AUD_device->lock();
-}
-
-void AUD_Device_unlock(AUD_Device* device)
-{
- AUD_device->unlock();
-}
-
-AUD_Channels AUD_Device_getChannels(AUD_Device* device)
-{
- return AUD_device->getSpecs().channels;
-}
-
-AUD_SampleRate AUD_Device_getRate(AUD_Device* device)
-{
- return AUD_device->getSpecs().rate;
-}
-
-AUD_SoundInfo AUD_getInfo(AUD_Sound *sound)
-{
- assert(sound);
-
- AUD_SoundInfo info;
- info.specs.channels = AUD_CHANNELS_INVALID;
- info.specs.rate = AUD_RATE_INVALID;
- info.length = 0.0f;
-
- try {
- boost::shared_ptr<AUD_IReader> reader = (*sound)->createReader();
-
- if (reader.get()) {
- info.specs = reader->getSpecs();
- info.length = reader->getLength() / (float) info.specs.rate;
- }
- }
- catch(AUD_Exception &ae)
- {
- std::cout << ae.str << std::endl;
- }
-
- return info;
-}
-
-AUD_Sound *AUD_Sound_file(const char *filename)
-{
- assert(filename);
- return new AUD_Sound(new AUD_FileFactory(filename));
-}
-
-AUD_Sound *AUD_Sound_bufferFile(unsigned char *buffer, int size)
-{
- assert(buffer);
- return new AUD_Sound(new AUD_FileFactory(buffer, size));
-}
-
-AUD_Sound *AUD_Sound_cache(AUD_Sound *sound)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_StreamBufferFactory(*sound));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_rechannel(AUD_Sound *sound, AUD_Channels channels)
-{
- assert(sound);
-
- try {
- AUD_DeviceSpecs specs;
- specs.channels = channels;
- specs.rate = AUD_RATE_INVALID;
- specs.format = AUD_FORMAT_INVALID;
- return new AUD_Sound(new AUD_ChannelMapperFactory(*sound, specs));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_delay(AUD_Sound *sound, float delay)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_DelayFactory(*sound, delay));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_limit(AUD_Sound *sound, float start, float end)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_LimiterFactory(*sound, start, end));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_pingpong(AUD_Sound *sound)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_PingPongFactory(*sound));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Sound *AUD_Sound_loop(AUD_Sound *sound)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_LoopFactory(*sound));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-int AUD_Handle_setLoopCount(AUD_Handle *handle, int loops)
-{
- assert(handle);
-
- try {
- return (*handle)->setLoopCount(loops);
- }
- catch(AUD_Exception&)
- {
- }
-
- return false;
-}
-
-AUD_Sound *AUD_rectifySound(AUD_Sound *sound)
-{
- assert(sound);
-
- try {
- return new AUD_Sound(new AUD_RectifyFactory(*sound));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-void AUD_Sound_free(AUD_Sound *sound)
-{
- assert(sound);
- delete sound;
-}
-
-AUD_Handle *AUD_Device_play(AUD_Device* device, AUD_Sound *sound, int keep)
-{
- assert(sound);
- try {
- AUD_Handle handle = AUD_device->play(*sound, keep);
- if (handle.get()) {
- return new AUD_Handle(handle);
- }
- }
- catch(AUD_Exception&)
- {
- }
- return NULL;
-}
-
-int AUD_Handle_pause(AUD_Handle *handle)
-{
- assert(handle);
- return (*handle)->pause();
-}
-
-int AUD_Handle_resume(AUD_Handle *handle)
-{
- assert(handle);
- return (*handle)->resume();
-}
-
-int AUD_Handle_stop(AUD_Handle *handle)
-{
- assert(handle);
- int result = (*handle)->stop();
- delete handle;
- return result;
-}
-
-void AUD_Device_stopAll(void* device)
-{
- AUD_device->stopAll();
-}
-
-int AUD_Handle_setKeep(AUD_Handle *handle, int keep)
-{
- assert(handle);
- return (*handle)->setKeep(keep);
-}
-
-int AUD_Handle_setPosition(AUD_Handle *handle, float seekTo)
-{
- assert(handle);
- return (*handle)->seek(seekTo);
-}
-
-float AUD_Handle_getPosition(AUD_Handle *handle)
-{
- assert(handle);
- return (*handle)->getPosition();
-}
-
-AUD_Status AUD_Handle_getStatus(AUD_Handle *handle)
-{
- assert(handle);
- return (*handle)->getStatus();
-}
-
-int AUD_Device_setListenerLocation(const float location[3])
-{
- if (AUD_3ddevice) {
- AUD_Vector3 v(location[0], location[1], location[2]);
- AUD_3ddevice->setListenerLocation(v);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setListenerVelocity(const float velocity[3])
-{
- if (AUD_3ddevice) {
- AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
- AUD_3ddevice->setListenerVelocity(v);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setListenerOrientation(const float orientation[4])
-{
- if (AUD_3ddevice) {
- AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
- AUD_3ddevice->setListenerOrientation(q);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setSpeedOfSound(void* device, float speed)
-{
- if (AUD_3ddevice) {
- AUD_3ddevice->setSpeedOfSound(speed);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setDopplerFactor(void* device, float factor)
-{
- if (AUD_3ddevice) {
- AUD_3ddevice->setDopplerFactor(factor);
- return true;
- }
-
- return false;
-}
-
-int AUD_Device_setDistanceModel(void* device, AUD_DistanceModel model)
-{
- if (AUD_3ddevice) {
- AUD_3ddevice->setDistanceModel(model);
- return true;
- }
-
- return false;
-}
-
-int AUD_Handle_setLocation(AUD_Handle *handle, const float location[3])
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- AUD_Vector3 v(location[0], location[1], location[2]);
- return h->setSourceLocation(v);
- }
-
- return false;
-}
-
-int AUD_Handle_setVelocity(AUD_Handle *handle, const float velocity[3])
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
- return h->setSourceVelocity(v);
- }
-
- return false;
-}
-
-int AUD_Handle_setOrientation(AUD_Handle *handle, const float orientation[4])
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
- return h->setSourceOrientation(q);
- }
-
- return false;
-}
-
-int AUD_Handle_setRelative(AUD_Handle *handle, int relative)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setRelative(relative);
- }
-
- return false;
-}
-
-int AUD_Handle_setVolumeMaximum(AUD_Handle *handle, float volume)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setVolumeMaximum(volume);
- }
-
- return false;
-}
-
-int AUD_Handle_setVolumeMinimum(AUD_Handle *handle, float volume)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setVolumeMinimum(volume);
- }
-
- return false;
-}
-
-int AUD_Handle_setDistanceMaximum(AUD_Handle *handle, float distance)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setDistanceMaximum(distance);
- }
-
- return false;
-}
-
-int AUD_Handle_setDistanceReference(AUD_Handle *handle, float distance)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setDistanceReference(distance);
- }
-
- return false;
-}
-
-int AUD_Handle_setAttenuation(AUD_Handle *handle, float factor)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setAttenuation(factor);
- }
-
- return false;
-}
-
-int AUD_Handle_setConeAngleOuter(AUD_Handle *handle, float angle)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setConeAngleOuter(angle);
- }
-
- return false;
-}
-
-int AUD_Handle_setConeAngleInner(AUD_Handle *handle, float angle)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setConeAngleInner(angle);
- }
-
- return false;
-}
-
-int AUD_Handle_setConeVolumeOuter(AUD_Handle *handle, float volume)
-{
- assert(handle);
- boost::shared_ptr<AUD_I3DHandle> h = boost::dynamic_pointer_cast<AUD_I3DHandle>(*handle);
-
- if (h.get()) {
- return h->setConeVolumeOuter(volume);
- }
-
- return false;
-}
-
-int AUD_Handle_setVolume(AUD_Handle *handle, float volume)
-{
- assert(handle);
- try {
- return (*handle)->setVolume(volume);
- }
- catch(AUD_Exception&) {}
- return false;
-}
-
-int AUD_Handle_setPitch(AUD_Handle *handle, float pitch)
-{
- assert(handle);
- try {
- return (*handle)->setPitch(pitch);
- }
- catch(AUD_Exception&) {}
- return false;
-}
-
-AUD_Device *AUD_openReadDevice(AUD_DeviceSpecs specs)
-{
- try {
- return new AUD_Device(new AUD_ReadDevice(specs));
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Handle *AUD_playDevice(AUD_Device *device, AUD_Sound *sound, float seek)
-{
- assert(device);
- assert(sound);
-
- try {
- AUD_Handle handle = (*device)->play(*sound);
- if (handle.get()) {
- handle->seek(seek);
- return new AUD_Handle(handle);
- }
- }
- catch(AUD_Exception&)
- {
- }
- return NULL;
-}
-
-int AUD_setDeviceVolume(AUD_Device *device, float volume)
-{
- assert(device);
-
- try {
- (*device)->setVolume(volume);
- return true;
- }
- catch(AUD_Exception&) {}
-
- return false;
-}
-
-int AUD_Device_read(AUD_Device *device, data_t *buffer, int length)
-{
- assert(device);
- assert(buffer);
-
- try {
- return boost::dynamic_pointer_cast<AUD_ReadDevice>(*device)->read(buffer, length);
- }
- catch(AUD_Exception&)
- {
- return false;
- }
-}
-
-void AUD_Device_free(AUD_Device *device)
-{
- try {
- if(device != &AUD_device)
- delete device;
- }
- catch(AUD_Exception&)
- {
- }
-}
-
-float *AUD_readSoundBuffer(const char *filename, float low, float high,
- float attack, float release, float threshold,
- int accumulate, int additive, int square,
- float sthreshold, double samplerate, int *length)
-{
- AUD_Buffer buffer;
- AUD_DeviceSpecs specs;
- specs.channels = AUD_CHANNELS_MONO;
- specs.rate = (AUD_SampleRate)samplerate;
- boost::shared_ptr<AUD_IFactory> sound;
-
- boost::shared_ptr<AUD_IFactory> file = boost::shared_ptr<AUD_IFactory>(new AUD_FileFactory(filename));
-
- int position = 0;
-
- try {
- boost::shared_ptr<AUD_IReader> reader = file->createReader();
-
- AUD_SampleRate rate = reader->getSpecs().rate;
-
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_ChannelMapperFactory(file, specs));
-
- if (high < rate)
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_LowpassFactory(sound, high));
- if (low > 0)
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_HighpassFactory(sound, low));
-
- 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 = boost::shared_ptr<AUD_IFactory>(new AUD_SquareFactory(sound, sthreshold));
-
- if (accumulate)
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_AccumulatorFactory(sound, additive));
- else if (additive)
- sound = boost::shared_ptr<AUD_IFactory>(new AUD_SumFactory(sound));
-
- reader = sound->createReader();
-
- if (!reader.get())
- return NULL;
-
- int len;
- bool eos;
- do
- {
- len = samplerate;
- buffer.resize((position + len) * sizeof(float), true);
- reader->read(len, eos, buffer.getBuffer() + position);
- position += len;
- } while(!eos);
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-
- float * result = (float *)malloc(position * sizeof(float));
- memcpy(result, buffer.getBuffer(), position * sizeof(float));
- *length = position;
- return result;
-}
-
-static void pauseSound(AUD_Handle *handle)
-{
- assert(handle);
- (*handle)->pause();
-}
-
-AUD_Handle *AUD_pauseAfter(AUD_Handle *handle, float 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_MutexLock lock(*AUD_device);
-
- try {
- AUD_Handle handle2 = AUD_device->play(limiter);
- if (handle2.get()) {
- handle2->setStopCallback((stopCallback)pauseSound, handle);
- return new AUD_Handle(handle2);
- }
- }
- catch(AUD_Exception&)
- {
- }
-
- return NULL;
-}
-
-AUD_Sound *AUD_Sequence_create(float fps, int muted)
-{
- // specs are changed at a later point!
- AUD_Specs specs;
- specs.channels = AUD_CHANNELS_STEREO;
- specs.rate = AUD_RATE_48000;
- AUD_Sound *sequencer = new AUD_Sound(boost::shared_ptr<AUD_SequencerFactory>(new AUD_SequencerFactory(specs, fps, muted)));
- return sequencer;
-}
-
-void AUD_Sequence_free(AUD_Sound *sequencer)
-{
- delete sequencer;
-}
-
-void AUD_Sequence_setMuted(AUD_Sound *sequencer, int muted)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->mute(muted);
-}
-
-void AUD_Sequence_setFPS(AUD_Sound *sequencer, float fps)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setFPS(fps);
-}
-
-AUD_SEntry *AUD_Sequence_add(AUD_Sound *sequencer, AUD_Sound *sound,
- float begin, float end, float skip)
-{
- if (!sound)
- return new AUD_SEntry(((AUD_SequencerFactory *)sequencer->get())->add(AUD_Sound(), begin, end, skip));
- return new AUD_SEntry(((AUD_SequencerFactory *)sequencer->get())->add(*sound, begin, end, skip));
-}
-
-void AUD_Sequence_remove(AUD_Sound *sequencer, AUD_SEntry *entry)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->remove(*entry);
- delete entry;
-}
-
-void AUD_SequenceEntry_move(AUD_SEntry *entry, float begin, float end, float skip)
-{
- (*entry)->move(begin, end, skip);
-}
-
-void AUD_SequenceEntry_setMuted(AUD_SEntry *entry, char mute)
-{
- (*entry)->mute(mute);
-}
-
-void AUD_SequenceEntry_setSound(AUD_SEntry *entry, AUD_Sound *sound)
-{
- if (sound)
- (*entry)->setSound(*sound);
- else
- (*entry)->setSound(AUD_Sound());
-}
-
-void AUD_SequenceEntry_setAnimationData(AUD_SEntry *entry, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
-{
- AUD_AnimateableProperty *prop = (*entry)->getAnimProperty(type);
- if (animated) {
- if (frame >= 0)
- prop->write(data, frame, 1);
- }
- else {
- prop->write(data);
- }
-}
-
-void AUD_Sequence_setAnimationData(AUD_Sound *sequencer, AUD_AnimateablePropertyType type, int frame, float *data, char animated)
-{
- AUD_AnimateableProperty *prop = dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->getAnimProperty(type);
- if (animated) {
- if (frame >= 0) {
- prop->write(data, frame, 1);
- }
- }
- else {
- prop->write(data);
- }
-}
-
-void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value)
-{
- assert(sequence);
- dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setDistanceModel(static_cast<AUD_DistanceModel>(value));
-}
-
-void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value)
-{
- assert(sequence);
- dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setDopplerFactor(value);
-}
-
-void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value)
-{
- assert(sequence);
- dynamic_cast<AUD_SequencerFactory *>(sequence->get())->setSpeedOfSound(value);
-}
-
-void AUD_SequenceEntry_setAttenuation(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setAttenuation(value);
-}
-
-void AUD_SequenceEntry_setConeAngleInner(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setConeAngleInner(value);
-}
-
-void AUD_SequenceEntry_setConeAngleOuter(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setConeAngleOuter(value);
-}
-
-void AUD_SequenceEntry_setConeVolumeOuter(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setConeVolumeOuter(value);
-}
-
-void AUD_SequenceEntry_setDistanceMaximum(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setDistanceMaximum(value);
-}
-
-void AUD_SequenceEntry_setDistanceReference(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setDistanceReference(value);
-}
-
-void AUD_SequenceEntry_setRelative(AUD_SEntry* sequence_entry, int value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setRelative(value);
-}
-
-void AUD_SequenceEntry_setVolumeMaximum(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setVolumeMaximum(value);
-}
-
-void AUD_SequenceEntry_setVolumeMinimum(AUD_SEntry* sequence_entry, float value)
-{
- assert(sequence_entry);
- (*sequence_entry)->setVolumeMinimum(value);
-}
-
-void AUD_setSequencerDeviceSpecs(AUD_Sound *sequencer)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setSpecs(AUD_device->getSpecs().specs);
-}
-
-void AUD_Sequence_setSpecs(AUD_Sound *sequencer, AUD_Specs specs)
-{
- dynamic_cast<AUD_SequencerFactory *>(sequencer->get())->setSpecs(specs);
-}
-
-void AUD_seekSynchronizer(AUD_Handle *handle, float time)
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- device->seekPlayback(time);
- }
- else
-#endif
- {
- assert(handle);
- (*handle)->seek(time);
- }
-}
-
-float AUD_getSynchronizerPosition(AUD_Handle *handle)
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- return device->getPlaybackPosition();
- }
- else
-#endif
- {
- assert(handle);
- return (*handle)->getPosition();
- }
-}
-
-void AUD_playSynchronizer()
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- device->startPlayback();
- }
-#endif
-}
-
-void AUD_stopSynchronizer()
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- device->stopPlayback();
- }
-#endif
-}
-
-#ifdef WITH_JACK
-void AUD_setSynchronizerCallback(AUD_syncFunction function, void *data)
-{
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- device->setSyncCallback(function, data);
- }
-}
-#endif
-
-int AUD_isSynchronizerPlaying()
-{
-#ifdef WITH_JACK
- AUD_JackDevice *device = dynamic_cast<AUD_JackDevice *>(AUD_device.get());
- if (device) {
- return device->doesPlayback();
- }
-#endif
- return -1;
-}
-
-int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second, short *interrupt)
-{
- AUD_DeviceSpecs specs;
- sample_t *buf;
- AUD_Buffer aBuffer;
-
- specs.rate = AUD_RATE_INVALID;
- specs.channels = AUD_CHANNELS_MONO;
- specs.format = AUD_FORMAT_INVALID;
-
- boost::shared_ptr<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();
-
- specs.specs = reader->getSpecs();
- int len;
- float samplejump = specs.rate / samples_per_second;
- float min, max, power, overallmax;
- bool eos;
-
- overallmax = 0;
-
- for (int i = 0; i < length; i++) {
- len = floor(samplejump * (i+1)) - floor(samplejump * i);
-
- if (*interrupt) {
- return 0;
- }
- aBuffer.assureSize(len * AUD_SAMPLE_SIZE(specs));
- buf = aBuffer.getBuffer();
-
- reader->read(len, eos, buf);
-
- max = min = *buf;
- power = *buf * *buf;
- for (int j = 1; j < len; j++) {
- if (buf[j] < min)
- min = buf[j];
- if (buf[j] > max)
- max = buf[j];
- power += buf[j] * buf[j];
- }
-
- buffer[i * 3] = min;
- buffer[i * 3 + 1] = max;
- buffer[i * 3 + 2] = sqrt(power) / len;
-
- if (overallmax < max)
- overallmax = max;
- if (overallmax < -min)
- overallmax = -min;
-
- if (eos) {
- length = i;
- break;
- }
- }
-
- if (overallmax > 1.0f) {
- for (int i = 0; i < length * 3; i++) {
- buffer[i] /= overallmax;
- }
- }
-
- return length;
-}
-
-AUD_Sound *AUD_Sound_copy(AUD_Sound *sound)
-{
- return new boost::shared_ptr<AUD_IFactory>(*sound);
-}
-
-void AUD_Handle_free(AUD_Handle *handle)
-{
- delete handle;
-}
-
-const char *AUD_mixdown(AUD_Sound *sound, unsigned int start, unsigned int length, unsigned int buffersize, const char *filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
-{
- try {
- AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sound->get());
-
- f->setSpecs(specs.specs);
- boost::shared_ptr<AUD_IReader> reader = f->createQualityReader();
- reader->seek(start);
- boost::shared_ptr<AUD_IWriter> writer = AUD_FileWriter::createWriter(filename, specs, format, codec, bitrate);
- AUD_FileWriter::writeReader(reader, writer, length, buffersize);
-
- return NULL;
- }
- catch(AUD_Exception& e)
- {
- return e.str;
- }
-}
-
-const char *AUD_mixdown_per_channel(AUD_Sound *sound, unsigned int start, unsigned int length, unsigned int buffersize, const char *filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate)
-{
- try {
- AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sound->get());
-
- f->setSpecs(specs.specs);
-
- std::vector<boost::shared_ptr<AUD_IWriter> > writers;
-
- int channels = specs.channels;
- specs.channels = AUD_CHANNELS_MONO;
-
- for (int i = 0; i < channels; i++) {
- std::stringstream stream;
- std::string fn = filename;
- size_t index = fn.find_last_of('.');
- size_t index_slash = fn.find_last_of('/');
- size_t index_backslash = fn.find_last_of('\\');
-
- if ((index == std::string::npos) ||
- ((index < index_slash) && (index_slash != std::string::npos)) ||
- ((index < index_backslash) && (index_backslash != std::string::npos)))
- {
- stream << filename << "_" << (i + 1);
- }
- else {
- stream << fn.substr(0, index) << "_" << (i + 1) << fn.substr(index);
- }
- writers.push_back(AUD_FileWriter::createWriter(stream.str(), specs, format, codec, bitrate));
- }
-
- boost::shared_ptr<AUD_IReader> reader = f->createQualityReader();
- reader->seek(start);
- AUD_FileWriter::writeReader(reader, writers, length, buffersize);
-
- return NULL;
- }
- catch(AUD_Exception& e)
- {
- return e.str;
- }
-}
-
-AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, float volume, float start)
-{
- try {
- AUD_ReadDevice *device = new AUD_ReadDevice(specs);
- device->setQuality(true);
- device->setVolume(volume);
-
- AUD_SequencerFactory *f = dynamic_cast<AUD_SequencerFactory *>(sequencer->get());
-
- f->setSpecs(specs.specs);
-
- AUD_Handle handle = device->play(f->createQualityReader());
- if (handle.get()) {
- handle->seek(start);
- }
-
- return new AUD_Device(device);
- }
- catch(AUD_Exception&)
- {
- return NULL;
- }
-}
-
-AUD_Device *AUD_Device_getCurrent(void)
-{
- return &AUD_device;
-}
-
-int AUD_isJackSupported(void)
-{
-#ifdef WITH_JACK
- return AUD_jack_supported();
-#else
- return 0;
-#endif
-}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
deleted file mode 100644
index cc9059a8e09..00000000000
--- a/intern/audaspace/intern/AUD_C-API.h
+++ /dev/null
@@ -1,822 +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 AUD_C-API.h
- * \ingroup audaspace
- */
-
-#ifndef __AUD_C_API_H__
-#define __AUD_C_API_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "AUD_Space.h"
-
-/// Supported output devices.
-typedef enum
-{
- AUD_NULL_DEVICE = 0,
- AUD_SDL_DEVICE,
- AUD_OPENAL_DEVICE,
- AUD_JACK_DEVICE
-} AUD_DeviceType;
-
-/// Sound information structure.
-typedef struct
-{
- AUD_Specs specs;
- float length;
-} AUD_SoundInfo;
-
-#ifndef AUD_CAPI_IMPLEMENTATION
- typedef void AUD_Sound;
- typedef void AUD_Handle;
- typedef void AUD_Device;
- typedef void AUD_SEntry;
- typedef float (*AUD_volumeFunction)(void *, void *, float);
- typedef void (*AUD_syncFunction)(void *, int, float);
-#endif
-
-/**
- * Initializes audio routines (FFMPEG/JACK if it is enabled).
- */
-extern void AUD_initOnce(void);
-
-/**
- * Unitinitializes an audio routines.
- */
-extern void AUD_exitOnce(void);
-
-/**
- * Initializes an audio device.
- * \param device The device type that should be used.
- * \param specs The audio specification to be used.
- * \param buffersize The buffersize for the device.
- * \return Whether the device has been initialized.
- */
-extern AUD_Device* AUD_init(const char* device, AUD_DeviceSpecs specs, int buffersize, const char* name);
-
-/**
- * Unitinitializes an audio device.
- */
-extern void AUD_exit(AUD_Device* device);
-
-/**
- * Locks the playback device.
- */
-extern void AUD_Device_lock(AUD_Device* device);
-
-/**
- * Unlocks the device.
- */
-extern void AUD_Device_unlock(AUD_Device* device);
-
-extern AUD_Channels AUD_Device_getChannels(AUD_Device* device);
-
-extern AUD_SampleRate AUD_Device_getRate(AUD_Device* device);
-
-/**
- * Returns information about a sound.
- * \param sound The sound to get the info about.
- * \return The AUD_SoundInfo structure with filled in data.
- */
-extern AUD_SoundInfo AUD_getInfo(AUD_Sound *sound);
-
-/**
- * Loads a sound file.
- * \param filename The filename of the sound file.
- * \return A handle of the sound file.
- */
-extern AUD_Sound *AUD_Sound_file(const char *filename);
-
-/**
- * Loads a sound file.
- * \param buffer The buffer which contains the sound file.
- * \param size The size of the buffer.
- * \return A handle of the sound file.
- */
-extern AUD_Sound *AUD_Sound_bufferFile(unsigned char *buffer, int size);
-
-/**
- * Buffers a sound.
- * \param sound The sound to buffer.
- * \return A handle of the sound buffer.
- */
-extern AUD_Sound *AUD_Sound_cache(AUD_Sound *sound);
-
-/**
- * Rechannels the sound to be mono.
- * \param sound The sound to rechannel.
- * \return The mono sound.
- */
-extern AUD_Sound *AUD_Sound_rechannel(AUD_Sound *sound, AUD_Channels channels);
-
-/**
- * Delays a sound.
- * \param sound The sound to dealy.
- * \param delay The delay in seconds.
- * \return A handle of the delayed sound.
- */
-extern AUD_Sound *AUD_Sound_delay(AUD_Sound *sound, float delay);
-
-/**
- * Limits a sound.
- * \param sound The sound to limit.
- * \param start The start time in seconds.
- * \param end The stop time in seconds.
- * \return A handle of the limited sound.
- */
-extern AUD_Sound *AUD_Sound_limit(AUD_Sound *sound, float start, float end);
-
-/**
- * Ping pongs a sound.
- * \param sound The sound to ping pong.
- * \return A handle of the ping pong sound.
- */
-extern AUD_Sound *AUD_Sound_pingpong(AUD_Sound *sound);
-
-/**
- * Loops a sound.
- * \param sound The sound to loop.
- * \return A handle of the looped sound.
- */
-extern AUD_Sound *AUD_Sound_loop(AUD_Sound *sound);
-
-/**
- * Sets a remaining loop count of a looping sound that currently plays.
- * \param handle The playback handle.
- * \param loops The count of remaining loops, -1 for infinity.
- * \return Whether the handle is valid.
- */
-extern int AUD_Handle_setLoopCount(AUD_Handle *handle, int loops);
-
-/**
- * Rectifies a sound.
- * \param sound The sound to rectify.
- * \return A handle of the rectified sound.
- */
-extern AUD_Sound *AUD_rectifySound(AUD_Sound *sound);
-
-/**
- * Unloads a sound of any type.
- * \param sound The handle of the sound.
- */
-extern void AUD_Sound_free(AUD_Sound *sound);
-
-/**
- * Plays back a sound file.
- * \param sound The handle of the sound file.
- * \param keep When keep is true the sound source will not be deleted but set to
- * paused when its end has been reached.
- * \return A handle to the played back sound.
- */
-extern AUD_Handle *AUD_Device_play(AUD_Device* device, AUD_Sound *sound, int keep);
-
-/**
- * Pauses a played back sound.
- * \param handle The handle to the sound.
- * \return Whether the handle has been playing or not.
- */
-extern int AUD_Handle_pause(AUD_Handle *handle);
-
-/**
- * Resumes a paused sound.
- * \param handle The handle to the sound.
- * \return Whether the handle has been paused or not.
- */
-extern int AUD_Handle_resume(AUD_Handle *handle);
-
-/**
- * Stops a playing or paused sound.
- * \param handle The handle to the sound.
- * \return Whether the handle has been valid or not.
- */
-extern int AUD_Handle_stop(AUD_Handle *handle);
-
-extern void AUD_Device_stopAll(void* device);
-
-/**
- * Sets the end behaviour of a playing or paused sound.
- * \param handle The handle to the sound.
- * \param keep When keep is true the sound source will not be deleted but set to
- * paused when its end has been reached.
- * \return Whether the handle has been valid or not.
- */
-extern int AUD_Handle_setKeep(AUD_Handle *handle, int keep);
-
-/**
- * Seeks a playing or paused sound.
- * \param handle The handle to the sound.
- * \param seekTo From where the sound file should be played back in seconds.
- * \return Whether the handle has been valid or not.
- */
-extern int AUD_Handle_setPosition(AUD_Handle *handle, float seekTo);
-
-/**
- * Retrieves the playback position of a handle.
- * \param handle The handle to the sound.
- * \return The current playback position in seconds or 0.0 if the handle is
- * invalid.
- */
-extern float AUD_Handle_getPosition(AUD_Handle *handle);
-
-/**
- * Returns the status of a playing, paused or stopped sound.
- * \param handle The handle to the sound.
- * \return The status of the sound behind the handle.
- */
-extern AUD_Status AUD_Handle_getStatus(AUD_Handle *handle);
-
-/**
- * Sets the listener location.
- * \param location The new location.
- */
-extern int AUD_Device_setListenerLocation(const float location[3]);
-
-/**
- * Sets the listener velocity.
- * \param velocity The new velocity.
- */
-extern int AUD_Device_setListenerVelocity(const float velocity[3]);
-
-/**
- * Sets the listener orientation.
- * \param orientation The new orientation as quaternion.
- */
-extern int AUD_Device_setListenerOrientation(const float orientation[4]);
-
-/**
- * Sets the speed of sound.
- * This value is needed for doppler effect calculation.
- * \param speed The new speed of sound.
- */
-extern int AUD_Device_setSpeedOfSound(void* device, float speed);
-
-/**
- * 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.
- */
-extern int AUD_Device_setDopplerFactor(void* device, float factor);
-
-/**
- * Sets the distance model.
- * \param model distance model.
- */
-extern int AUD_Device_setDistanceModel(void* device, AUD_DistanceModel model);
-
-/**
- * Sets the location of a source.
- * \param handle The handle of the source.
- * \param location The new location.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setLocation(AUD_Handle *handle, const float location[3]);
-
-/**
- * Sets the velocity of a source.
- * \param handle The handle of the source.
- * \param velocity The new velocity.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setVelocity(AUD_Handle *handle, const float velocity[3]);
-
-/**
- * Sets the orientation of a source.
- * \param handle The handle of the source.
- * \param orientation The new orientation as quaternion.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setOrientation(AUD_Handle *handle, const float orientation[4]);
-
-/**
- * Sets whether the source location, velocity and orientation are relative
- * to the listener.
- * \param handle The handle of the source.
- * \param relative Whether the source is relative.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setRelative(AUD_Handle *handle, int relative);
-
-/**
- * Sets the maximum volume of a source.
- * \param handle The handle of the source.
- * \param volume The new maximum volume.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setVolumeMaximum(AUD_Handle *handle, float volume);
-
-/**
- * Sets the minimum volume of a source.
- * \param handle The handle of the source.
- * \param volume The new minimum volume.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setVolumeMinimum(AUD_Handle *handle, float volume);
-
-/**
- * Sets the maximum distance of a source.
- * If a source is further away from the reader than this distance, the
- * volume will automatically be set to 0.
- * \param handle The handle of the source.
- * \param distance The new maximum distance.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setDistanceMaximum(AUD_Handle *handle, float distance);
-
-/**
- * Sets the reference distance of a source.
- * \param handle The handle of the source.
- * \param distance The new reference distance.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setDistanceReference(AUD_Handle *handle, float distance);
-
-/**
- * Sets the attenuation of a source.
- * This value is used for distance calculation.
- * \param handle The handle of the source.
- * \param factor The new attenuation.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setAttenuation(AUD_Handle *handle, float factor);
-
-/**
- * Sets the outer angle of the cone of a source.
- * \param handle The handle of the source.
- * \param angle The new outer angle of the cone.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setConeAngleOuter(AUD_Handle *handle, float angle);
-
-/**
- * Sets the inner angle of the cone of a source.
- * \param handle The handle of the source.
- * \param angle The new inner angle of the cone.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setConeAngleInner(AUD_Handle *handle, float angle);
-
-/**
- * Sets the outer volume of the cone of a source.
- * The volume between inner and outer angle is interpolated between inner
- * volume and this value.
- * \param handle The handle of the source.
- * \param volume The new outer volume of the cone.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setConeVolumeOuter(AUD_Handle *handle, float volume);
-
-/**
- * Sets the volume of a played back sound.
- * \param handle The handle to the sound.
- * \param volume The new volume, must be between 0.0 and 1.0.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setVolume(AUD_Handle *handle, float volume);
-
-/**
- * Sets the pitch of a played back sound.
- * \param handle The handle to the sound.
- * \param pitch The new pitch.
- * \return Whether the action succeeded.
- */
-extern int AUD_Handle_setPitch(AUD_Handle *handle, float pitch);
-
-/**
- * Opens a read device, with which audio data can be read.
- * \param specs The specification of the audio data.
- * \return A device handle.
- */
-extern AUD_Device *AUD_openReadDevice(AUD_DeviceSpecs specs);
-
-/**
- * Sets the main volume of a device.
- * \param device The device.
- * \param volume The new volume, must be between 0.0 and 1.0.
- * \return Whether the action succeeded.
- */
-extern int AUD_setDeviceVolume(AUD_Device *device, float volume);
-
-/**
- * Plays back a sound file through a read device.
- * \param device The read device.
- * \param sound The handle of the sound file.
- * \param seek The position where the sound should be seeked to.
- * \return A handle to the played back sound.
- */
-extern AUD_Handle *AUD_playDevice(AUD_Device *device, AUD_Sound *sound, float seek);
-
-/**
- * Reads the next samples into the supplied buffer.
- * \param device The read device.
- * \param buffer The target buffer.
- * \param length The length in samples to be filled.
- * \return True if the reading succeeded, false if there are no sounds
- * played back currently, in that case the buffer is filled with
- * silence.
- */
-extern int AUD_Device_read(AUD_Device *device, data_t *buffer, int length);
-
-/**
- * Closes a read device.
- * \param device The read device.
- */
-extern void AUD_Device_free(AUD_Device *device);
-
-/**
- * Reads a sound file into a newly created float buffer.
- * The sound is therefore bandpassed, rectified and resampled.
- */
-extern float *AUD_readSoundBuffer(const char *filename, float low, float high,
- float attack, float release, float threshold,
- int accumulate, int additive, int square,
- float sthreshold, double samplerate,
- int *length);
-
-/**
- * Pauses a playing sound after a specific amount of time.
- * \param handle The handle to the sound.
- * \param seconds The time in seconds.
- * \return The silence handle.
- */
-extern AUD_Handle *AUD_pauseAfter(AUD_Handle *handle, float seconds);
-
-/**
- * Creates a new sequenced sound scene.
- * \param fps The FPS of the scene.
- * \param muted Whether the scene is muted.
- * \return The new sound scene.
- */
-extern AUD_Sound *AUD_Sequence_create(float fps, int muted);
-
-/**
- * Deletes a sound scene.
- * \param sequencer The sound scene.
- */
-extern void AUD_Sequence_free(AUD_Sound *sequencer);
-
-/**
- * Sets the muting state of the scene.
- * \param sequencer The sound scene.
- * \param muted Whether the scene is muted.
- */
-extern void AUD_Sequence_setMuted(AUD_Sound *sequencer, int muted);
-
-/**
- * Sets the scene's FPS.
- * \param sequencer The sound scene.
- * \param fps The new FPS.
- */
-extern void AUD_Sequence_setFPS(AUD_Sound *sequencer, float fps);
-
-/**
- * Adds a new entry to the scene.
- * \param sequencer The sound 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.
- */
-extern AUD_SEntry *AUD_Sequence_add(AUD_Sound *sequencer, AUD_Sound *sound,
- float begin, float end, float skip);
-
-/**
- * Removes an entry from the scene.
- * \param sequencer The sound scene.
- * \param entry The entry to remove.
- */
-extern void AUD_Sequence_remove(AUD_Sound *sequencer, AUD_SEntry *entry);
-
-/**
- * Moves the entry.
- * \param entry The sequenced entry.
- * \param begin The new start time.
- * \param end The new end time or a negative value if unknown.
- * \param skip How many seconds to skip at the beginning.
- */
-extern void AUD_SequenceEntry_move(AUD_SEntry *entry, float begin, float end, float skip);
-
-/**
- * Sets the muting state of the entry.
- * \param entry The sequenced entry.
- * \param mute Whether the entry should be muted or not.
- */
-extern void AUD_SequenceEntry_setMuted(AUD_SEntry *entry, char mute);
-
-/**
- * Sets the sound of the entry.
- * \param entry The sequenced entry.
- * \param sound The new sound.
- */
-extern void AUD_SequenceEntry_setSound(AUD_SEntry *entry, AUD_Sound *sound);
-
-/**
- * Writes animation data to a sequenced entry.
- * \param entry The sequenced entry.
- * \param type The type of animation data.
- * \param frame The frame this data is for.
- * \param data The data to write.
- * \param animated Whether the attribute is animated.
- */
-extern void AUD_SequenceEntry_setAnimationData(AUD_SEntry *entry, AUD_AnimateablePropertyType type, int frame, float *data, char animated);
-
-/**
- * Writes animation data to a sequenced entry.
- * \param sequencer The sound scene.
- * \param type The type of animation data.
- * \param frame The frame this data is for.
- * \param data The data to write.
- * \param animated Whether the attribute is animated.
- */
-extern void AUD_Sequence_setAnimationData(AUD_Sound *sequencer, AUD_AnimateablePropertyType type, int frame, float *data, char animated);
-
-/**
- * Sets the distance model of a sequence.
- * param sequence The sequence to set the distance model from.
- * param value The new distance model to set.
- */
-extern void AUD_Sequence_setDistanceModel(AUD_Sound* sequence, AUD_DistanceModel value);
-
-/**
- * Sets the doppler factor of a sequence.
- * param sequence The sequence to set the doppler factor from.
- * param value The new doppler factor to set.
- */
-extern void AUD_Sequence_setDopplerFactor(AUD_Sound* sequence, float value);
-
-/**
- * Sets the speed of sound of a sequence.
- * param sequence The sequence to set the speed of sound from.
- * param value The new speed of sound to set.
- */
-extern void AUD_Sequence_setSpeedOfSound(AUD_Sound* sequence, float value);
-/**
- * Sets the attenuation of a sequence_entry.
- * param sequence_entry The sequence_entry to set the attenuation from.
- * param value The new attenuation to set.
- */
-extern void AUD_SequenceEntry_setAttenuation(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the cone angle inner of a sequence_entry.
- * param sequence_entry The sequence_entry to set the cone angle inner from.
- * param value The new cone angle inner to set.
- */
-extern void AUD_SequenceEntry_setConeAngleInner(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the cone angle outer of a sequence_entry.
- * param sequence_entry The sequence_entry to set the cone angle outer from.
- * param value The new cone angle outer to set.
- */
-extern void AUD_SequenceEntry_setConeAngleOuter(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the cone volume outer of a sequence_entry.
- * param sequence_entry The sequence_entry to set the cone volume outer from.
- * param value The new cone volume outer to set.
- */
-extern void AUD_SequenceEntry_setConeVolumeOuter(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the distance maximum of a sequence_entry.
- * param sequence_entry The sequence_entry to set the distance maximum from.
- * param value The new distance maximum to set.
- */
-extern void AUD_SequenceEntry_setDistanceMaximum(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the distance reference of a sequence_entry.
- * param sequence_entry The sequence_entry to set the distance reference from.
- * param value The new distance reference to set.
- */
-extern void AUD_SequenceEntry_setDistanceReference(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the relative of a sequence_entry.
- * param sequence_entry The sequence_entry to set the relative from.
- * param value The new relative to set.
- */
-extern void AUD_SequenceEntry_setRelative(AUD_SEntry* sequence_entry, int value);
-
-/**
- * Sets the volume maximum of a sequence_entry.
- * param sequence_entry The sequence_entry to set the volume maximum from.
- * param value The new volume maximum to set.
- */
-extern void AUD_SequenceEntry_setVolumeMaximum(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the volume minimum of a sequence_entry.
- * param sequence_entry The sequence_entry to set the volume minimum from.
- * param value The new volume minimum to set.
- */
-extern void AUD_SequenceEntry_setVolumeMinimum(AUD_SEntry* sequence_entry, float value);
-
-/**
- * Sets the audio output specification of the sound scene to the specs of the
- * current playback device.
- * \param sequencer The sound scene.
- */
-extern void AUD_setSequencerDeviceSpecs(AUD_Sound *sequencer);
-
-/**
- * Sets the audio output specification of the sound scene.
- * \param sequencer The sound scene.
- * \param specs The new specification.
- */
-extern void AUD_Sequence_setSpecs(AUD_Sound *sequencer, AUD_Specs specs);
-
-/**
- * Seeks sequenced sound scene playback.
- * \param handle Playback handle.
- * \param time Time in seconds to seek to.
- */
-extern void AUD_seekSynchronizer(AUD_Handle *handle, float time);
-
-/**
- * Returns the current sound scene playback time.
- * \param handle Playback handle.
- * \return The playback time in seconds.
- */
-extern float AUD_getSynchronizerPosition(AUD_Handle *handle);
-
-/**
- * Starts the playback of jack transport if possible.
- */
-extern void AUD_playSynchronizer(void);
-
-/**
- * Stops the playback of jack transport if possible.
- */
-extern void AUD_stopSynchronizer(void);
-
-#ifdef WITH_JACK
-/**
- * Sets the sync callback for jack transport.
- * \param function The callback function.
- * \param data The data parameter for the callback.
- */
-extern void AUD_setSynchronizerCallback(AUD_syncFunction function, void *data);
-#endif
-
-/**
- * Returns whether jack transport is currently playing.
- * \return Whether jack transport is currently playing.
- */
-extern int AUD_isSynchronizerPlaying(void);
-
-/**
- * Reads a sound into a buffer for drawing at a specific sampling rate.
- * \param sound The sound to read.
- * \param buffer The buffer to write to. Must have a size of 3*4*length.
- * \param length How many samples to read from the sound.
- * \param samples_per_second How many samples to read per second of the sound.
- * \return How many samples really have been read. Always <= length.
- */
-extern int AUD_readSound(AUD_Sound *sound, sample_t *buffer, int length, int samples_per_second, short *interrupt);
-
-/**
- * Copies a sound.
- * \param sound Sound to copy.
- * \return Copied sound.
- */
-extern AUD_Sound *AUD_Sound_copy(AUD_Sound *sound);
-
-/**
- * Frees a handle.
- * \param channel Handle to free.
- */
-extern void AUD_Handle_free(AUD_Handle *channel);
-
-/**
- * Creates a new set.
- * \return The new set.
- */
-extern void *AUD_createSet(void);
-
-/**
- * Deletes a set.
- * \param set The set to delete.
- */
-extern void AUD_destroySet(void *set);
-
-/**
- * Removes an entry from a set.
- * \param set The set work on.
- * \param entry The entry to remove.
- * \return Whether the entry was in the set or not.
- */
-extern char AUD_removeSet(void *set, void *entry);
-
-/**
- * Adds a new entry to a set.
- * \param set The set work on.
- * \param entry The entry to add.
- */
-extern void AUD_addSet(void *set, void *entry);
-
-/**
- * Removes one entry from a set and returns it.
- * \param set The set work on.
- * \return The entry or NULL if the set is empty.
- */
-extern void *AUD_getSet(void *set);
-
-/**
- * Mixes a sound down into a file.
- * \param sound The sound scene to mix down.
- * \param start The start frame.
- * \param length The count of frames to write.
- * \param buffersize How many samples should be written at once.
- * \param filename The file to write to.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \return An error message or NULL in case of success.
- */
-extern const char *AUD_mixdown(AUD_Sound *sound, unsigned int start, unsigned int length,
- unsigned int buffersize, const char *filename,
- AUD_DeviceSpecs specs, AUD_Container format,
- AUD_Codec codec, unsigned int bitrate);
-
-/**
- * Mixes a sound down into multiple files.
- * \param sound The sound scene to mix down.
- * \param start The start frame.
- * \param length The count of frames to write.
- * \param buffersize How many samples should be written at once.
- * \param filename The file to write to, the channel number and an underscore are added at the beginning.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \return An error message or NULL in case of success.
- */
-extern const char *AUD_mixdown_per_channel(AUD_Sound *sound, unsigned int start, unsigned int length,
- unsigned int buffersize, const char *filename,
- AUD_DeviceSpecs specs, AUD_Container format,
- AUD_Codec codec, unsigned int bitrate);
-
-/**
- * Opens a read device and prepares it for mixdown of the sound scene.
- * \param specs Output audio specifications.
- * \param sequencer The sound scene to mix down.
- * \param volume The overall mixdown volume.
- * \param start The start time of the mixdown in the sound scene.
- * \return The read device for the mixdown.
- */
-extern AUD_Device *AUD_openMixdownDevice(AUD_DeviceSpecs specs, AUD_Sound *sequencer, float volume, float start);
-
-#ifdef WITH_PYTHON
-/**
- * Retrieves the python factory of a sound.
- * \param sound The sound factory.
- * \return The python factory.
- */
-extern void *AUD_getPythonSound(AUD_Sound *sound);
-
-/**
- * Retrieves the sound factory of a python factory.
- * \param sound The python factory.
- * \return The sound factory.
- */
-extern AUD_Sound *AUD_getSoundFromPython(void *sound);
-#endif
-
-extern AUD_Device *AUD_Device_getCurrent(void);
-
-extern int AUD_isJackSupported(void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //__AUD_C_API_H__
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
deleted file mode 100644
index f4ba5d05ff0..00000000000
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
+++ /dev/null
@@ -1,45 +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_ChannelMapperFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ChannelMapperFactory.h"
-#include "AUD_ChannelMapperReader.h"
-
-#include <cstring>
-
-AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_ChannelMapperFactory::createReader()
-{
- 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
deleted file mode 100644
index 611b5041c39..00000000000
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.h
+++ /dev/null
@@ -1,57 +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_ChannelMapperFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CHANNELMAPPERFACTORY_H__
-#define __AUD_CHANNELMAPPERFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a reader that maps a sound source's channels to a
- * specific output channel count.
- */
-class AUD_ChannelMapperFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_ChannelMapperFactory(const AUD_ChannelMapperFactory&);
- AUD_ChannelMapperFactory& operator=(const AUD_ChannelMapperFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_ChannelMapperFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- 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
deleted file mode 100644
index 8b983d5c43d..00000000000
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
+++ /dev/null
@@ -1,378 +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_ChannelMapperReader.cpp
- * \ingroup audaspaceintern
- */
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#ifndef M_PI_2
-#define M_PI_2 1.57079632679489661923
-#endif
-
-#include "AUD_ChannelMapperReader.h"
-
-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)
-{
-}
-
-AUD_ChannelMapperReader::~AUD_ChannelMapperReader()
-{
- delete[] m_mapping;
-}
-
-void AUD_ChannelMapperReader::setChannels(AUD_Channels channels)
-{
- m_target_channels = channels;
- calculateMapping();
-}
-
-void AUD_ChannelMapperReader::setMonoAngle(float angle)
-{
- if(angle != angle)
- angle = 0;
- m_mono_angle = angle;
- if(m_source_channels == AUD_CHANNELS_MONO)
- calculateMapping();
-}
-
-float AUD_ChannelMapperReader::angleDistance(float alpha, float beta)
-{
- alpha = beta - alpha;
-
- if(alpha > M_PI)
- alpha -= 2 * M_PI;
- if(alpha < -M_PI)
- alpha += 2 * M_PI;
-
- return alpha;
-}
-
-void AUD_ChannelMapperReader::calculateMapping()
-{
- if(m_map_size < m_source_channels * m_target_channels)
- {
- delete[] m_mapping;
- m_mapping = new float[m_source_channels * m_target_channels];
- m_map_size = m_source_channels * m_target_channels;
- }
-
- for(int i = 0; i < m_source_channels * m_target_channels; i++)
- m_mapping[i] = 0;
-
- const AUD_Channel* source_channels = CHANNEL_MAPS[m_source_channels - 1];
- const AUD_Channel* target_channels = CHANNEL_MAPS[m_target_channels - 1];
-
- int lfe = -1;
-
- for(int i = 0; i < m_target_channels; i++)
- {
- if(target_channels[i] == AUD_CHANNEL_LFE)
- {
- lfe = i;
- break;
- }
- }
-
- const float* source_angles = CHANNEL_ANGLES[m_source_channels - 1];
- const float* target_angles = CHANNEL_ANGLES[m_target_channels - 1];
-
- if(m_source_channels == AUD_CHANNELS_MONO)
- source_angles = &m_mono_angle;
-
- int channel_left, channel_right;
- float angle_left, angle_right, angle;
-
- for(int i = 0; i < m_source_channels; i++)
- {
- if(source_channels[i] == AUD_CHANNEL_LFE)
- {
- if(lfe != -1)
- m_mapping[lfe * m_source_channels + i] = 1;
-
- continue;
- }
-
- 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 < 0)
- {
- if(angle > angle_left)
- {
- angle_left = angle;
- channel_left = j;
- }
- }
- else
- {
- if(angle < angle_right)
- {
- angle_right = angle;
- channel_right = j;
- }
- }
- }
-
- 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_right * m_source_channels + i] = 1;
- }
- else
- {
- 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);
- }
- }
-
- /* AUD_XXX for(int i = 0; i < m_source_channels; i++)
- {
- for(int j = 0; j < m_target_channels; j++)
- {
- std::cout << m_mapping[i * m_source_channels + j] << " ";
- }
- std::cout << std::endl;
- }*/
-}
-
-AUD_Specs AUD_ChannelMapperReader::getSpecs() const
-{
- AUD_Specs specs = m_reader->getSpecs();
- specs.channels = m_target_channels;
- return specs;
-}
-
-void AUD_ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_Channels channels = m_reader->getSpecs().channels;
- if(channels != m_source_channels)
- {
- m_source_channels = channels;
- calculateMapping();
- }
-
- if(m_source_channels == m_target_channels)
- {
- m_reader->read(length, eos, buffer);
- return;
- }
-
- m_buffer.assureSize(length * channels * sizeof(sample_t));
-
- sample_t* in = m_buffer.getBuffer();
-
- m_reader->read(length, eos, in);
-
- sample_t sum;
-
- for(int i = 0; i < length; i++)
- {
- for(int j = 0; j < m_target_channels; j++)
- {
- sum = 0;
- for(int k = 0; k < m_source_channels; k++)
- sum += m_mapping[j * m_source_channels + k] * in[i * m_source_channels + k];
- buffer[i * m_target_channels + j] = sum;
- }
- }
-}
-
-const AUD_Channel AUD_ChannelMapperReader::MONO_MAP[] =
-{
- AUD_CHANNEL_FRONT_CENTER
-};
-
-const AUD_Channel AUD_ChannelMapperReader::STEREO_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::STEREO_LFE_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_LFE
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND4_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND5_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND51_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_LFE,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND61_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_LFE,
- AUD_CHANNEL_REAR_CENTER,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT
-};
-
-const AUD_Channel AUD_ChannelMapperReader::SURROUND71_MAP[] =
-{
- AUD_CHANNEL_FRONT_LEFT,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_LFE,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT,
- AUD_CHANNEL_SIDE_LEFT,
- AUD_CHANNEL_SIDE_RIGHT
-};
-
-const AUD_Channel* AUD_ChannelMapperReader::CHANNEL_MAPS[] =
-{
- AUD_ChannelMapperReader::MONO_MAP,
- AUD_ChannelMapperReader::STEREO_MAP,
- AUD_ChannelMapperReader::STEREO_LFE_MAP,
- AUD_ChannelMapperReader::SURROUND4_MAP,
- AUD_ChannelMapperReader::SURROUND5_MAP,
- AUD_ChannelMapperReader::SURROUND51_MAP,
- AUD_ChannelMapperReader::SURROUND61_MAP,
- AUD_ChannelMapperReader::SURROUND71_MAP
-};
-
-const float AUD_ChannelMapperReader::MONO_ANGLES[] =
-{
- 0.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::STEREO_ANGLES[] =
-{
- -90.0f * M_PI / 180.0f,
- 90.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::STEREO_LFE_ANGLES[] =
-{
- -90.0f * M_PI / 180.0f,
- 90.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND4_ANGLES[] =
-{
- -45.0f * M_PI / 180.0f,
- 45.0f * M_PI / 180.0f,
- -135.0f * M_PI / 180.0f,
- 135.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND5_ANGLES[] =
-{
- -30.0f * M_PI / 180.0f,
- 30.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- -110.0f * M_PI / 180.0f,
- 110.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND51_ANGLES[] =
-{
- -30.0f * M_PI / 180.0f,
- 30.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- -110.0f * M_PI / 180.0f,
- 110.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND61_ANGLES[] =
-{
- -30.0f * M_PI / 180.0f,
- 30.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- 180.0f * M_PI / 180.0f,
- -110.0f * M_PI / 180.0f,
- 110.0f * M_PI / 180.0f
-};
-
-const float AUD_ChannelMapperReader::SURROUND71_ANGLES[] =
-{
- -30.0f * M_PI / 180.0f,
- 30.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- 0.0f * M_PI / 180.0f,
- -110.0f * M_PI / 180.0f,
- 110.0f * M_PI / 180.0f,
- -150.0f * M_PI / 180.0f,
- 150.0f * M_PI / 180.0f
-};
-
-const float* AUD_ChannelMapperReader::CHANNEL_ANGLES[] =
-{
- AUD_ChannelMapperReader::MONO_ANGLES,
- AUD_ChannelMapperReader::STEREO_ANGLES,
- AUD_ChannelMapperReader::STEREO_LFE_ANGLES,
- AUD_ChannelMapperReader::SURROUND4_ANGLES,
- AUD_ChannelMapperReader::SURROUND5_ANGLES,
- AUD_ChannelMapperReader::SURROUND51_ANGLES,
- AUD_ChannelMapperReader::SURROUND61_ANGLES,
- AUD_ChannelMapperReader::SURROUND71_ANGLES
-};
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.h b/intern/audaspace/intern/AUD_ChannelMapperReader.h
deleted file mode 100644
index b122b070d29..00000000000
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.h
+++ /dev/null
@@ -1,136 +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_ChannelMapperReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CHANNELMAPPERREADER_H__
-#define __AUD_CHANNELMAPPERREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class maps a sound source's channels to a specific output channel count.
- * \note The input sample format must be float.
- */
-class AUD_ChannelMapperReader : public AUD_EffectReader
-{
-private:
- /**
- * The sound reading buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * The output specification.
- */
- AUD_Channels m_target_channels;
-
- /**
- * The channel count of the reader.
- */
- AUD_Channels m_source_channels;
-
- /**
- * The mapping specification.
- */
- float* m_mapping;
-
- /**
- * The size of the mapping.
- */
- int m_map_size;
-
- /**
- * The mono source angle.
- */
- float m_mono_angle;
-
- static const AUD_Channel MONO_MAP[];
- static const AUD_Channel STEREO_MAP[];
- static const AUD_Channel STEREO_LFE_MAP[];
- static const AUD_Channel SURROUND4_MAP[];
- static const AUD_Channel SURROUND5_MAP[];
- static const AUD_Channel SURROUND51_MAP[];
- static const AUD_Channel SURROUND61_MAP[];
- static const AUD_Channel SURROUND71_MAP[];
- static const AUD_Channel* CHANNEL_MAPS[];
-
- static const float MONO_ANGLES[];
- static const float STEREO_ANGLES[];
- static const float STEREO_LFE_ANGLES[];
- static const float SURROUND4_ANGLES[];
- static const float SURROUND5_ANGLES[];
- static const float SURROUND51_ANGLES[];
- static const float SURROUND61_ANGLES[];
- static const float SURROUND71_ANGLES[];
- static const float* CHANNEL_ANGLES[];
-
- // hide copy constructor and operator=
- AUD_ChannelMapperReader(const AUD_ChannelMapperReader&);
- AUD_ChannelMapperReader& operator=(const AUD_ChannelMapperReader&);
-
- /**
- * Calculates the mapping matrix.
- */
- void calculateMapping();
-
- /**
- * Calculates the distance between two angles.
- */
- float angleDistance(float alpha, float beta);
-
-public:
- /**
- * Creates a channel mapper reader.
- * \param reader The reader to map.
- * \param mapping The mapping specification as two dimensional float array.
- */
- AUD_ChannelMapperReader(boost::shared_ptr<AUD_IReader> reader, AUD_Channels channels);
-
- /**
- * Destroys the reader.
- */
- ~AUD_ChannelMapperReader();
-
- /**
- * Sets the requested channel output count.
- * \param channels The channel output count.
- */
- void setChannels(AUD_Channels channels);
-
- /**
- * Sets the angle for mono sources.
- * \param angle The angle for mono sources.
- */
- void setMonoAngle(float angle);
-
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_CHANNELMAPPERREADER_H__
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.cpp b/intern/audaspace/intern/AUD_ConverterFactory.cpp
deleted file mode 100644
index 7cbf64f1697..00000000000
--- a/intern/audaspace/intern/AUD_ConverterFactory.cpp
+++ /dev/null
@@ -1,47 +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_ConverterFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ConverterFactory.h"
-#include "AUD_ConverterReader.h"
-
-AUD_ConverterFactory::AUD_ConverterFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_ConverterFactory::createReader()
-{
- boost::shared_ptr<AUD_IReader> reader = getReader();
-
- if(m_specs.format != AUD_FORMAT_FLOAT32)
- 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
deleted file mode 100644
index 2c9c82d235b..00000000000
--- a/intern/audaspace/intern/AUD_ConverterFactory.h
+++ /dev/null
@@ -1,57 +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_ConverterFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CONVERTERFACTORY_H__
-#define __AUD_CONVERTERFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a converter reader that is able to convert from one
- * audio format to another.
- */
-class AUD_ConverterFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_ConverterFactory(const AUD_ConverterFactory&);
- AUD_ConverterFactory& operator=(const AUD_ConverterFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_ConverterFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_CONVERTERFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.cpp b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
deleted file mode 100644
index c20f19a7e67..00000000000
--- a/intern/audaspace/intern/AUD_ConverterFunctions.cpp
+++ /dev/null
@@ -1,472 +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_ConverterFunctions.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ConverterFunctions.h"
-#include "AUD_Buffer.h"
-
-#define AUD_U8_0 0x80
-#define AUD_S16_MAX ((int16_t)0x7FFF)
-#define AUD_S16_MIN ((int16_t)0x8000)
-#define AUD_S16_FLT 32767.0f
-#define AUD_S32_MAX ((int32_t)0x7FFFFFFF)
-#define AUD_S32_MIN ((int32_t)0x80000000)
-#define AUD_S32_FLT 2147483647.0f
-#define AUD_FLT_MAX 1.0f
-#define AUD_FLT_MIN -1.0f
-
-void AUD_convert_u8_s16(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
-}
-
-void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length)
-{
- for(int i = length - 1; i >= 0; i--)
- {
- target[i*3] = source[i] - AUD_U8_0;
- target[i*3+1] = 0;
- target[i*3+2] = 0;
- }
-}
-
-void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length)
-{
- for(int i = length - 1; i >= 0; i--)
- {
- target[i*3+2] = source[i] - AUD_U8_0;
- target[i*3+1] = 0;
- target[i*3] = 0;
- }
-}
-
-void AUD_convert_u8_s32(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
-}
-
-void AUD_convert_u8_float(data_t* target, data_t* source, int length)
-{
- float* t = (float*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
-}
-
-void AUD_convert_u8_double(data_t* target, data_t* source, int length)
-{
- double* t = (double*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
-}
-
-void AUD_convert_s16_u8(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- for(int i = 0; i < length; i++)
- target[i] = (unsigned char)((s[i] >> 8) + AUD_U8_0);
-}
-
-void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- int16_t t;
- for(int i = length - 1; i >= 0; i--)
- {
- t = s[i];
- target[i*3] = t >> 8 & 0xFF;
- target[i*3+1] = t & 0xFF;
- target[i*3+2] = 0;
- }
-}
-
-void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- int16_t t;
- for(int i = length - 1; i >= 0; i--)
- {
- t = s[i];
- target[i*3+2] = t >> 8 & 0xFF;
- target[i*3+1] = t & 0xFF;
- target[i*3] = 0;
- }
-}
-
-void AUD_convert_s16_s32(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- int32_t* t = (int32_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = ((int32_t)s[i]) << 16;
-}
-
-void AUD_convert_s16_float(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- float* t = (float*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = s[i] / AUD_S16_FLT;
-}
-
-void AUD_convert_s16_double(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- double* t = (double*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = s[i] / AUD_S16_FLT;
-}
-
-void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length)
-{
- for(int i = 0; i < length; i++)
- target[i] = source[i*3] ^ AUD_U8_0;
-}
-
-void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length)
-{
- for(int i = 0; i < length; i++)
- target[i] = source[i*3+2] ^ AUD_U8_0;
-}
-
-void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- for(int i = 0; i < length; i++)
- t[i] = source[i*3] << 8 | source[i*3+1];
-}
-
-void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- for(int i = 0; i < length; i++)
- t[i] = source[i*3+2] << 8 | source[i*3+1];
-}
-
-void AUD_convert_s24_s24(data_t* target, data_t* source, int length)
-{
- memcpy(target, source, length * 3);
-}
-
-void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
-}
-
-void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
-}
-
-void AUD_convert_s24_float_be(data_t* target, data_t* source, int length)
-{
- float* t = (float*) target;
- int32_t s;
- for(int i = length - 1; i >= 0; i--)
- {
- s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
- t[i] = s / AUD_S32_FLT;
- }
-}
-
-void AUD_convert_s24_float_le(data_t* target, data_t* source, int length)
-{
- float* t = (float*) target;
- int32_t s;
- for(int i = length - 1; i >= 0; i--)
- {
- s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
- t[i] = s / AUD_S32_FLT;
- }
-}
-
-void AUD_convert_s24_double_be(data_t* target, data_t* source, int length)
-{
- double* t = (double*) target;
- int32_t s;
- for(int i = length - 1; i >= 0; i--)
- {
- s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
- t[i] = s / AUD_S32_FLT;
- }
-}
-
-void AUD_convert_s24_double_le(data_t* target, data_t* source, int length)
-{
- double* t = (double*) target;
- int32_t s;
- for(int i = length - 1; i >= 0; i--)
- {
- s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
- t[i] = s / AUD_S32_FLT;
- }
-}
-
-void AUD_convert_s32_u8(data_t* target, data_t* source, int length)
-{
- int16_t* s = (int16_t*) source;
- for(int i = 0; i < length; i++)
- target[i] = (unsigned char)((s[i] >> 24) + AUD_U8_0);
-}
-
-void AUD_convert_s32_s16(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- int32_t* s = (int32_t*) source;
- for(int i = 0; i < length; i++)
- t[i] = s[i] >> 16;
-}
-
-void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length)
-{
- int32_t* s = (int32_t*) source;
- int32_t t;
- for(int i = 0; i < length; i++)
- {
- t = s[i];
- target[i*3] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3+2] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length)
-{
- int32_t* s = (int32_t*) source;
- int32_t t;
- for(int i = 0; i < length; i++)
- {
- t = s[i];
- target[i*3+2] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_s32_float(data_t* target, data_t* source, int length)
-{
- int32_t* s = (int32_t*) source;
- float* t = (float*) target;
- for(int i = 0; i < length; i++)
- t[i] = s[i] / AUD_S32_FLT;
-}
-
-void AUD_convert_s32_double(data_t* target, data_t* source, int length)
-{
- int32_t* s = (int32_t*) source;
- double* t = (double*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = s[i] / AUD_S32_FLT;
-}
-
-void AUD_convert_float_u8(data_t* target, data_t* source, int length)
-{
- float* s = (float*) source;
- float t;
- for(int i = 0; i < length; i++)
- {
- t = s[i] + AUD_FLT_MAX;
- if(t <= 0.0f)
- target[i] = 0;
- else if(t >= 2.0f)
- target[i] = 255;
- else
- target[i] = (unsigned char)(t*127);
- }
-}
-
-void AUD_convert_float_s16(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- float* s = (float*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t[i] = AUD_S16_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t[i] = AUD_S16_MAX;
- else
- t[i] = (int16_t)(s[i] * AUD_S16_MAX);
- }
-}
-
-void AUD_convert_float_s24_be(data_t* target, data_t* source, int length)
-{
- int32_t t;
- float* s = (float*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t = AUD_S32_MAX;
- else
- t = (int32_t)(s[i]*AUD_S32_MAX);
- target[i*3] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3+2] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_float_s24_le(data_t* target, data_t* source, int length)
-{
- int32_t t;
- float* s = (float*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t = AUD_S32_MAX;
- else
- t = (int32_t)(s[i]*AUD_S32_MAX);
- target[i*3+2] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_float_s32(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- float* s = (float*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t[i] = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t[i] = AUD_S32_MAX;
- else
- t[i] = (int32_t)(s[i]*AUD_S32_MAX);
- }
-}
-
-void AUD_convert_float_double(data_t* target, data_t* source, int length)
-{
- float* s = (float*) source;
- double* t = (double*) target;
- for(int i = length - 1; i >= 0; i--)
- t[i] = s[i];
-}
-
-void AUD_convert_double_u8(data_t* target, data_t* source, int length)
-{
- double* s = (double*) source;
- double t;
- for(int i = 0; i < length; i++)
- {
- t = s[i] + AUD_FLT_MAX;
- if(t <= 0.0)
- target[i] = 0;
- else if(t >= 2.0)
- target[i] = 255;
- else
- target[i] = (unsigned char)(t*127);
- }
-}
-
-void AUD_convert_double_s16(data_t* target, data_t* source, int length)
-{
- int16_t* t = (int16_t*) target;
- double* s = (double*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t[i] = AUD_S16_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t[i] = AUD_S16_MAX;
- else
- t[i] = (int16_t)(s[i]*AUD_S16_MAX);
- }
-}
-
-void AUD_convert_double_s24_be(data_t* target, data_t* source, int length)
-{
- int32_t t;
- double* s = (double*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t = AUD_S32_MAX;
- else
- t = (int32_t)(s[i]*AUD_S32_MAX);
- target[i*3] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3+2] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_double_s24_le(data_t* target, data_t* source, int length)
-{
- int32_t t;
- double* s = (double*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t = AUD_S32_MAX;
- else
- t = (int32_t)(s[i]*AUD_S32_MAX);
- target[i*3+2] = t >> 24 & 0xFF;
- target[i*3+1] = t >> 16 & 0xFF;
- target[i*3] = t >> 8 & 0xFF;
- }
-}
-
-void AUD_convert_double_s32(data_t* target, data_t* source, int length)
-{
- int32_t* t = (int32_t*) target;
- double* s = (double*) source;
- for(int i = 0; i < length; i++)
- {
- if(s[i] <= AUD_FLT_MIN)
- t[i] = AUD_S32_MIN;
- else if(s[i] >= AUD_FLT_MAX)
- t[i] = AUD_S32_MAX;
- else
- t[i] = (int32_t)(s[i]*AUD_S32_MAX);
- }
-}
-
-void AUD_convert_double_float(data_t* target, data_t* source, int length)
-{
- double* s = (double*) source;
- float* t = (float*) target;
- for(int i = 0; i < length; i++)
- t[i] = s[i];
-}
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.h b/intern/audaspace/intern/AUD_ConverterFunctions.h
deleted file mode 100644
index eca2b327b8c..00000000000
--- a/intern/audaspace/intern/AUD_ConverterFunctions.h
+++ /dev/null
@@ -1,128 +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_ConverterFunctions.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CONVERTERFUNCTIONS_H__
-#define __AUD_CONVERTERFUNCTIONS_H__
-
-#include "AUD_Space.h"
-
-#include <cstring>
-#include <stdint.h>
-
-typedef void (*AUD_convert_f)(data_t* target, data_t* source, int length);
-
-template <class T>
-void AUD_convert_copy(data_t* target, data_t* source, int length)
-{
- memcpy(target, source, length*sizeof(T));
-}
-
-void AUD_convert_u8_s16(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_s32(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_float(data_t* target, data_t* source, int length);
-
-void AUD_convert_u8_double(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_u8(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_s32(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_float(data_t* target, data_t* source, int length);
-
-void AUD_convert_s16_double(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s24(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_float_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_float_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_double_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s24_double_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_u8(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_s16(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_float(data_t* target, data_t* source, int length);
-
-void AUD_convert_s32_double(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_u8(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_s16(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_s32(data_t* target, data_t* source, int length);
-
-void AUD_convert_float_double(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_u8(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_s16(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_s24_be(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_s24_le(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_s32(data_t* target, data_t* source, int length);
-
-void AUD_convert_double_float(data_t* target, data_t* source, int length);
-
-#endif //__AUD_CONVERTERFUNCTIONS_H__
diff --git a/intern/audaspace/intern/AUD_ConverterReader.cpp b/intern/audaspace/intern/AUD_ConverterReader.cpp
deleted file mode 100644
index a90a54670e8..00000000000
--- a/intern/audaspace/intern/AUD_ConverterReader.cpp
+++ /dev/null
@@ -1,77 +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_ConverterReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ConverterReader.h"
-
-AUD_ConverterReader::AUD_ConverterReader(boost::shared_ptr<AUD_IReader> reader,
- AUD_DeviceSpecs specs) :
- AUD_EffectReader(reader),
- m_format(specs.format)
-{
- switch(m_format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_float_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_float_s16;
- break;
- case AUD_FORMAT_S24:
-#ifdef __BIG_ENDIAN__
- m_convert = AUD_convert_float_s24_be;
-#else
- m_convert = AUD_convert_float_s24_le;
-#endif
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_float_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_copy<float>;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_float_double;
- break;
- default:
- break;
- }
-}
-
-void AUD_ConverterReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_Specs specs = m_reader->getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
-
- m_buffer.assureSize(length * samplesize);
-
- m_reader->read(length, eos, m_buffer.getBuffer());
-
- m_convert((data_t*)buffer, (data_t*)m_buffer.getBuffer(),
- length * specs.channels);
-}
diff --git a/intern/audaspace/intern/AUD_ConverterReader.h b/intern/audaspace/intern/AUD_ConverterReader.h
deleted file mode 100644
index 987b7c70279..00000000000
--- a/intern/audaspace/intern/AUD_ConverterReader.h
+++ /dev/null
@@ -1,73 +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_ConverterReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_CONVERTERREADER_H__
-#define __AUD_CONVERTERREADER_H__
-
-#include "AUD_EffectReader.h"
-#include "AUD_ConverterFunctions.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class converts a sound source from one to another format.
- */
-class AUD_ConverterReader : public AUD_EffectReader
-{
-private:
- /**
- * The sound output buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * The target specification.
- */
- AUD_SampleFormat m_format;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
- // hide copy constructor and operator=
- AUD_ConverterReader(const AUD_ConverterReader&);
- AUD_ConverterReader& operator=(const AUD_ConverterReader&);
-
-public:
- /**
- * Creates a converter reader.
- * \param reader The reader to convert.
- * \param specs The target specification.
- */
- AUD_ConverterReader(boost::shared_ptr<AUD_IReader> reader, AUD_DeviceSpecs specs);
-
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_CONVERTERREADER_H__
diff --git a/intern/audaspace/intern/AUD_FileFactory.cpp b/intern/audaspace/intern/AUD_FileFactory.cpp
deleted file mode 100644
index f9353db6677..00000000000
--- a/intern/audaspace/intern/AUD_FileFactory.cpp
+++ /dev/null
@@ -1,84 +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_FileFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#ifdef WITH_FFMPEG
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-#include "AUD_FFMPEGReader.h"
-#endif
-
-#include "AUD_FileFactory.h"
-
-#include <cstring>
-
-#ifdef WITH_SNDFILE
-#include "AUD_SndFileReader.h"
-#endif
-
-AUD_FileFactory::AUD_FileFactory(std::string filename) :
- m_filename(filename)
-{
-}
-
-AUD_FileFactory::AUD_FileFactory(const data_t* buffer, int size) :
- m_buffer(new AUD_Buffer(size))
-{
- memcpy(m_buffer->getBuffer(), buffer, size);
-}
-
-static const char* read_error = "AUD_FileFactory: File couldn't be read.";
-
-boost::shared_ptr<AUD_IReader> AUD_FileFactory::createReader()
-{
-#ifdef WITH_SNDFILE
- try
- {
- if(m_buffer.get())
- return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_buffer));
- else
- return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_filename));
- }
- catch(AUD_Exception&) {}
-#endif
-
-#ifdef WITH_FFMPEG
- try
- {
- if(m_buffer.get())
- return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_buffer));
- else
- return boost::shared_ptr<AUD_IReader>(new AUD_FFMPEGReader(m_filename));
- }
- catch(AUD_Exception&) {}
-#endif
-
- AUD_THROW(AUD_ERROR_FILE, read_error);
-}
diff --git a/intern/audaspace/intern/AUD_FileFactory.h b/intern/audaspace/intern/AUD_FileFactory.h
deleted file mode 100644
index 35c8db731b4..00000000000
--- a/intern/audaspace/intern/AUD_FileFactory.h
+++ /dev/null
@@ -1,76 +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_FileFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_FILEFACTORY_H__
-#define __AUD_FILEFACTORY_H__
-
-#include "AUD_IFactory.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.
- */
-class AUD_FileFactory : public AUD_IFactory
-{
-private:
- /**
- * The filename of the sound source file.
- */
- std::string m_filename;
-
- /**
- * The buffer to read from.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- // hide copy constructor and operator=
- AUD_FileFactory(const AUD_FileFactory&);
- AUD_FileFactory& operator=(const AUD_FileFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param filename The sound file path.
- */
- AUD_FileFactory(std::string filename);
-
- /**
- * Creates a new factory.
- * \param buffer The buffer to read from.
- * \param size The size of the buffer.
- */
- AUD_FileFactory(const data_t* buffer, int size);
-
- 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
deleted file mode 100644
index e3072fa82e0..00000000000
--- a/intern/audaspace/intern/AUD_FileWriter.cpp
+++ /dev/null
@@ -1,131 +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_FileWriter.cpp
- * \ingroup audaspaceintern
- */
-
-#ifdef WITH_FFMPEG
-// needed for INT64_C
-#ifndef __STDC_CONSTANT_MACROS
-#define __STDC_CONSTANT_MACROS
-#endif
-#include "AUD_FFMPEGWriter.h"
-#endif
-
-#ifdef WITH_SNDFILE
-#include "AUD_SndFileWriter.h"
-#endif
-
-#include "AUD_FileWriter.h"
-#include "AUD_Buffer.h"
-
-static const char* write_error = "AUD_FileWriter: File couldn't be written.";
-
-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 boost::shared_ptr<AUD_IWriter>(new AUD_SndFileWriter(filename, specs, format, codec, bitrate));
- }
- catch(AUD_Exception&) {}
-#endif
-
-#ifdef WITH_FFMPEG
- try
- {
- return boost::shared_ptr<AUD_IWriter>(new AUD_FFMPEGWriter(filename, specs, format, codec, bitrate));
- }
- catch(AUD_Exception&) {}
-#endif
-
- AUD_THROW(AUD_ERROR_SPECS, write_error);
-}
-
-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();
-
- int len;
- bool eos = false;
- int channels = writer->getSpecs().channels;
-
- for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
- {
- len = buffersize;
- if((len > length - pos) && (length > 0))
- len = length - pos;
- reader->read(len, eos, buf);
-
- for(int i = 0; i < len * channels; i++)
- {
- // clamping!
- if(buf[i] > 1)
- buf[i] = 1;
- else if(buf[i] < -1)
- buf[i] = -1;
- }
-
- writer->write(len, buf);
- }
-}
-
-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));
- sample_t* buf = buffer.getBuffer();
- sample_t* buf2 = buffer2.getBuffer();
-
- int len;
- bool eos = false;
- int channels = reader->getSpecs().channels;
-
- for(unsigned int pos = 0; ((pos < length) || (length <= 0)) && !eos; pos += len)
- {
- len = buffersize;
- if((len > length - pos) && (length > 0))
- len = length - pos;
- reader->read(len, eos, buf);
-
- for(int channel = 0; channel < channels; channel++)
- {
- for(int i = 0; i < len; i++)
- {
- // clamping!
- if(buf[i * channels + channel] > 1)
- buf2[i] = 1;
- else if(buf[i * channels + channel] < -1)
- buf2[i] = -1;
- else
- buf2[i] = buf[i * channels + channel];
- }
-
- writers[channel]->write(len, buf2);
- }
- }
-}
diff --git a/intern/audaspace/intern/AUD_FileWriter.h b/intern/audaspace/intern/AUD_FileWriter.h
deleted file mode 100644
index 3291c1ad03a..00000000000
--- a/intern/audaspace/intern/AUD_FileWriter.h
+++ /dev/null
@@ -1,82 +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_FileWriter.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_FILEWRITER_H__
-#define __AUD_FILEWRITER_H__
-
-#include <string>
-#include <vector>
-#include <boost/shared_ptr.hpp>
-
-#include "AUD_IWriter.h"
-#include "AUD_IReader.h"
-
-/**
- * This class is able to create IWriter classes as well as write reads to them.
- */
-class AUD_FileWriter
-{
-private:
- // hide default constructor, copy constructor and operator=
- AUD_FileWriter();
- AUD_FileWriter(const AUD_FileWriter&);
- AUD_FileWriter& operator=(const AUD_FileWriter&);
-
-public:
- /**
- * Creates a new IWriter.
- * \param filename The file to write to.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \return The writer to write data to.
- */
- 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.
- * \param reader The reader to read from.
- * \param writer The writer to write to.
- * \param length How many samples should be transferred.
- * \param buffersize How many samples should be transferred at once.
- */
- 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.
- * \param reader The reader to read from.
- * \param writers The writers to write to.
- * \param length How many samples should be transferred.
- * \param buffersize How many samples should be transferred at once.
- */
- 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_I3DDevice.h b/intern/audaspace/intern/AUD_I3DDevice.h
deleted file mode 100644
index 1df710b7e5b..00000000000
--- a/intern/audaspace/intern/AUD_I3DDevice.h
+++ /dev/null
@@ -1,122 +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_I3DDevice.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_I3DDEVICE_H__
-#define __AUD_I3DDEVICE_H__
-
-#include "AUD_Space.h"
-#include "AUD_3DMath.h"
-
-/**
- * This class represents an output device for 3D sound.
- */
-class AUD_I3DDevice
-{
-public:
- /**
- * Retrieves the listener location.
- * \return The listener location.
- */
- virtual AUD_Vector3 getListenerLocation() const=0;
-
- /**
- * Sets the listener location.
- * \param location The new location.
- */
- virtual void setListenerLocation(const AUD_Vector3& location)=0;
-
- /**
- * Retrieves the listener velocity.
- * \return The listener velocity.
- */
- virtual AUD_Vector3 getListenerVelocity() const=0;
-
- /**
- * Sets the listener velocity.
- * \param velocity The new velocity.
- */
- virtual void setListenerVelocity(const AUD_Vector3& velocity)=0;
-
- /**
- * Retrieves the listener orientation.
- * \return The listener orientation as quaternion.
- */
- virtual AUD_Quaternion getListenerOrientation() const=0;
-
- /**
- * Sets the listener orientation.
- * \param orientation The new orientation as quaternion.
- */
- virtual void setListenerOrientation(const AUD_Quaternion& orientation)=0;
-
-
- /**
- * Retrieves the speed of sound.
- * This value is needed for doppler effect calculation.
- * \return The speed of sound.
- */
- virtual float getSpeedOfSound() const=0;
-
- /**
- * Sets the speed of sound.
- * This value is needed for doppler effect calculation.
- * \param speed The new speed of sound.
- */
- virtual void setSpeedOfSound(float speed)=0;
-
- /**
- * 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.
- */
- virtual float getDopplerFactor() const=0;
-
- /**
- * 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.
- */
- virtual void setDopplerFactor(float factor)=0;
-
- /**
- * Retrieves the distance model.
- * \return The distance model.
- */
- virtual AUD_DistanceModel getDistanceModel() const=0;
-
- /**
- * Sets the distance model.
- * \param model distance model.
- */
- virtual void setDistanceModel(AUD_DistanceModel model)=0;
-};
-
-#endif //__AUD_I3DDEVICE_H__
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
deleted file mode 100644
index a7f9a985ce4..00000000000
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ /dev/null
@@ -1,120 +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_IDevice.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_IDEVICE_H__
-#define __AUD_IDEVICE_H__
-
-#include "AUD_Space.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.
- * Output devices may be several backends such as plattform independand like
- * SDL or OpenAL or plattform specific like DirectSound, but they may also be
- * files, RAM buffers or other types of streams.
- * \warning Thread safety must be insured so that no reader is beeing called
- * twice at the same time.
- */
-class AUD_IDevice : public AUD_ILockable
-{
-public:
- /**
- * Destroys the device.
- */
- virtual ~AUD_IDevice() {}
-
- /**
- * Returns the specification of the device.
- */
- virtual AUD_DeviceSpecs getSpecs() const=0;
-
- /**
- * Plays a sound source.
- * \param reader The reader to play.
- * \param keep When keep is true the sound source will not be deleted but
- * set to paused when its end has been reached.
- * \return Returns a handle with which the playback can be controlled.
- * This is NULL if the sound couldn't be played back.
- * \exception AUD_Exception Thrown if there's an unexpected (from the
- * device side) error during creation of the reader.
- */
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false)=0;
-
- /**
- * Plays a sound source.
- * \param factory The factory to create the reader for the sound source.
- * \param keep When keep is true the sound source will not be deleted but
- * set to paused when its end has been reached.
- * \return Returns a handle with which the playback can be controlled.
- * This is NULL if the sound couldn't be played back.
- * \exception AUD_Exception Thrown if there's an unexpected (from the
- * device side) error during creation of the reader.
- */
- virtual boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false)=0;
-
- /**
- * Stops all playing sounds.
- */
- virtual void stopAll()=0;
-
- /**
- * Locks the device.
- * Used to make sure that between lock and unlock, no buffers are read, so
- * that it is possible to start, resume, pause, stop or seek several
- * playback handles simultaneously.
- * \warning Make sure the locking time is as small as possible to avoid
- * playback delays that result in unexpected noise and cracks.
- */
- virtual void lock()=0;
-
- /**
- * Unlocks the previously locked device.
- */
- virtual void unlock()=0;
-
- /**
- * Retrieves the overall device volume.
- * \return The overall device volume.
- */
- virtual float getVolume() const=0;
-
- /**
- * Sets the overall device volume.
- * \param handle The sound handle.
- * \param volume The overall device volume.
- */
- virtual void setVolume(float volume)=0;
-};
-
-#endif //AUD_IDevice
diff --git a/intern/audaspace/intern/AUD_IFactory.h b/intern/audaspace/intern/AUD_IFactory.h
deleted file mode 100644
index 75103963c68..00000000000
--- a/intern/audaspace/intern/AUD_IFactory.h
+++ /dev/null
@@ -1,61 +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_IFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_IFACTORY_H__
-#define __AUD_IFACTORY_H__
-
-#include "AUD_Space.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
- * of the respective sound source through the factory method createReader.
- */
-class AUD_IFactory
-{
-public:
- /**
- * Destroys the factory.
- */
- virtual ~AUD_IFactory() {}
-
- /**
- * Creates a reader for playback of the sound source.
- * \return A pointer to an AUD_IReader object or NULL if there has been an
- * error.
- * \exception AUD_Exception An exception may be thrown if there has been
- * a more unexpected error during reader creation.
- */
- 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
deleted file mode 100644
index 9bc417504fe..00000000000
--- a/intern/audaspace/intern/AUD_ILockable.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#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_IWriter.h b/intern/audaspace/intern/AUD_IWriter.h
deleted file mode 100644
index 5406577dd50..00000000000
--- a/intern/audaspace/intern/AUD_IWriter.h
+++ /dev/null
@@ -1,67 +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_IWriter.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_IWRITER_H__
-#define __AUD_IWRITER_H__
-
-#include "AUD_Space.h"
-
-/**
- * This class represents a sound sink where audio data can be written to.
- */
-class AUD_IWriter
-{
-public:
- /**
- * Destroys the writer.
- */
- virtual ~AUD_IWriter() {}
-
- /**
- * Returns how many samples have been written so far.
- * \return The writing position as sample count. May be negative if unknown.
- */
- virtual int getPosition() const=0;
-
- /**
- * Returns the specification of the audio data being written into the sink.
- * \return The AUD_DeviceSpecs structure.
- * \note Regardless of the format the input still has to be float!
- */
- virtual AUD_DeviceSpecs getSpecs() const=0;
-
- /**
- * Request to write the next length samples out into the sink.
- * \param length The count of samples to write.
- * \param buffer The pointer to the buffer containing the data.
- */
- virtual void write(unsigned int length, sample_t* buffer)=0;
-};
-
-#endif //__AUD_IWRITER_H__
diff --git a/intern/audaspace/intern/AUD_JOSResampleFactory.cpp b/intern/audaspace/intern/AUD_JOSResampleFactory.cpp
deleted file mode 100644
index 188960f986f..00000000000
--- a/intern/audaspace/intern/AUD_JOSResampleFactory.cpp
+++ /dev/null
@@ -1,42 +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_JOSResampleFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_JOSResampleFactory.h"
-#include "AUD_JOSResampleReader.h"
-
-AUD_JOSResampleFactory::AUD_JOSResampleFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_JOSResampleFactory::createReader()
-{
- 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
deleted file mode 100644
index b6c2961c88a..00000000000
--- a/intern/audaspace/intern/AUD_JOSResampleFactory.h
+++ /dev/null
@@ -1,56 +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_JOSResampleFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_JOSRESAMPLEFACTORY_H__
-#define __AUD_JOSRESAMPLEFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a resampling reader that does Julius O. Smith's resampling algorithm.
- */
-class AUD_JOSResampleFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_JOSResampleFactory(const AUD_JOSResampleFactory&);
- AUD_JOSResampleFactory& operator=(const AUD_JOSResampleFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_JOSResampleFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_JOSRESAMPLEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_JOSResampleReader.h b/intern/audaspace/intern/AUD_JOSResampleReader.h
deleted file mode 100644
index fb68e4dc9f5..00000000000
--- a/intern/audaspace/intern/AUD_JOSResampleReader.h
+++ /dev/null
@@ -1,135 +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_JOSResampleReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_JOSRESAMPLEREADER_H__
-#define __AUD_JOSRESAMPLEREADER_H__
-
-#include "AUD_ResampleReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This resampling reader uses Julius O. Smith's resampling algorithm.
- */
-class AUD_JOSResampleReader : public AUD_ResampleReader
-{
-private:
- typedef void (AUD_JOSResampleReader::*AUD_resample_f)(double target_factor, int length, sample_t* buffer);
-
- /**
- * The half filter length.
- */
- static const int m_len;
-
- /**
- * The sample step size for the filter.
- */
- static const int m_L;
-
- /**
- * The filter coefficients.
- */
- static const float m_coeff[];
-
- /**
- * The reader channels.
- */
- AUD_Channels m_channels;
-
- /**
- * The sample position in the cache.
- */
- unsigned int m_n;
-
- /**
- * The subsample position in the cache.
- */
- double m_P;
-
- /**
- * The input data buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * Double buffer for the sums.
- */
- AUD_Buffer m_sums;
-
- /**
- * How many samples in the cache are valid.
- */
- int m_cache_valid;
-
- /**
- * Resample function.
- */
- AUD_resample_f m_resample;
-
- /**
- * Last resampling factor.
- */
- double m_last_factor;
-
- // hide copy constructor and operator=
- AUD_JOSResampleReader(const AUD_JOSResampleReader&);
- AUD_JOSResampleReader& operator=(const AUD_JOSResampleReader&);
-
- /**
- * Resets the resampler to its initial state.
- */
- void reset();
-
- /**
- * Updates the buffer to be as small as possible for the coming reading.
- * \param size The size of samples to be read.
- * \param factor The next resampling factor.
- * \param samplesize The size of a sample.
- */
- void updateBuffer(int size, double factor, int samplesize);
-
- void resample(double target_factor, int length, sample_t* buffer);
- void resample_mono(double target_factor, int length, sample_t* buffer);
- void resample_stereo(double target_factor, int length, sample_t* buffer);
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- */
- AUD_JOSResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_Specs specs);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_JOSRESAMPLEREADER_H__
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
deleted file mode 100644
index cd573f1047c..00000000000
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
+++ /dev/null
@@ -1,42 +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_LinearResampleFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_LinearResampleFactory.h"
-#include "AUD_LinearResampleReader.h"
-
-AUD_LinearResampleFactory::AUD_LinearResampleFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- AUD_MixerFactory(factory, specs)
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_LinearResampleFactory::createReader()
-{
- 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
deleted file mode 100644
index ceb29ef2edd..00000000000
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.h
+++ /dev/null
@@ -1,56 +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_LinearResampleFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_LINEARRESAMPLEFACTORY_H__
-#define __AUD_LINEARRESAMPLEFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-/**
- * This factory creates a resampling reader that does simple linear resampling.
- */
-class AUD_LinearResampleFactory : public AUD_MixerFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_LinearResampleFactory(const AUD_LinearResampleFactory&);
- AUD_LinearResampleFactory& operator=(const AUD_LinearResampleFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param factory The input factory.
- * \param specs The target specifications.
- */
- AUD_LinearResampleFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- 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
deleted file mode 100644
index b342b8f31fb..00000000000
--- a/intern/audaspace/intern/AUD_LinearResampleReader.cpp
+++ /dev/null
@@ -1,186 +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_LinearResampleReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_LinearResampleReader.h"
-
-#include <cmath>
-#include <cstring>
-
-#define CC m_channels + channel
-
-AUD_LinearResampleReader::AUD_LinearResampleReader(boost::shared_ptr<AUD_IReader> reader,
- AUD_Specs specs) :
- AUD_ResampleReader(reader, specs.rate),
- m_channels(reader->getSpecs().channels),
- m_cache_pos(0),
- m_cache_ok(false)
-{
- specs.channels = m_channels;
- m_cache.resize(2 * AUD_SAMPLE_SIZE(specs));
-}
-
-void AUD_LinearResampleReader::seek(int position)
-{
- position = floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
- m_reader->seek(position);
- m_cache_ok = false;
- m_cache_pos = 0;
-}
-
-int AUD_LinearResampleReader::getLength() const
-{
- return floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
-}
-
-int AUD_LinearResampleReader::getPosition() const
-{
- return floor((m_reader->getPosition() + (m_cache_ok ? m_cache_pos - 1 : 0))
- * m_rate / m_reader->getSpecs().rate);
-}
-
-AUD_Specs AUD_LinearResampleReader::getSpecs() const
-{
- AUD_Specs specs = m_reader->getSpecs();
- specs.rate = m_rate;
- return specs;
-}
-
-void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer)
-{
- if(length == 0)
- return;
-
- AUD_Specs specs = m_reader->getSpecs();
-
- int samplesize = AUD_SAMPLE_SIZE(specs);
- int size = length;
- float factor = m_rate / m_reader->getSpecs().rate;
- float spos = 0.0f;
- sample_t low, high;
- eos = false;
-
- // check for channels changed
-
- if(specs.channels != m_channels)
- {
- m_cache.resize(2 * samplesize);
- m_channels = specs.channels;
- m_cache_ok = false;
- }
-
- if(factor == 1 && (!m_cache_ok || m_cache_pos == 1))
- {
- // can read directly!
- m_reader->read(length, eos, buffer);
-
- if(length > 0)
- {
- memcpy(m_cache.getBuffer() + m_channels, buffer + m_channels * (length - 1), samplesize);
- m_cache_pos = 1;
- m_cache_ok = true;
- }
-
- return;
- }
-
- int len;
- sample_t* buf;
-
- if(m_cache_ok)
- {
- int need = ceil(length / factor + m_cache_pos) - 1;
-
- len = need;
-
- m_buffer.assureSize((len + 2) * samplesize);
- buf = m_buffer.getBuffer();
-
- memcpy(buf, m_cache.getBuffer(), 2 * samplesize);
- m_reader->read(len, eos, buf + 2 * m_channels);
-
- if(len < need)
- length = floor((len + 1 - m_cache_pos) * factor);
- }
- else
- {
- m_cache_pos = 1 - 1 / factor;
-
- int need = ceil(length / factor + m_cache_pos);
-
- len = need;
-
- m_buffer.assureSize((len + 1) * samplesize);
- buf = m_buffer.getBuffer();
-
- memset(buf, 0, samplesize);
- m_reader->read(len, eos, buf + m_channels);
-
- if(len == 0)
- {
- length = 0;
- return;
- }
-
- if(len < need)
- {
- length = floor((len - m_cache_pos) * factor);
- }
-
- m_cache_ok = true;
- }
-
- if(length == 0)
- return;
-
- for(int channel = 0; channel < m_channels; channel++)
- {
- for(int i = 0; i < length; i++)
- {
- spos = (i + 1) / factor + m_cache_pos;
-
- low = buf[(int)floor(spos) * CC];
- high = buf[(int)ceil(spos) * CC];
-
- buffer[i * CC] = low + (spos - floor(spos)) * (high - low);
- }
- }
-
- if(floor(spos) == spos)
- {
- memcpy(m_cache.getBuffer() + m_channels, buf + int(floor(spos)) * m_channels, samplesize);
- m_cache_pos = 1;
- }
- else
- {
- memcpy(m_cache.getBuffer(), buf + int(floor(spos)) * m_channels, 2 * samplesize);
- m_cache_pos = spos - floor(spos);
- }
-
- eos &= length < size;
-}
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.h b/intern/audaspace/intern/AUD_LinearResampleReader.h
deleted file mode 100644
index 9beea251c07..00000000000
--- a/intern/audaspace/intern/AUD_LinearResampleReader.h
+++ /dev/null
@@ -1,86 +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_LinearResampleReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_LINEARRESAMPLEREADER_H__
-#define __AUD_LINEARRESAMPLEREADER_H__
-
-#include "AUD_ResampleReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This resampling reader does simple first-order hold resampling.
- */
-class AUD_LinearResampleReader : public AUD_ResampleReader
-{
-private:
- /**
- * The reader channels.
- */
- AUD_Channels m_channels;
-
- /**
- * The position in the cache.
- */
- float m_cache_pos;
-
- /**
- * The sound output buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * The input caching buffer.
- */
- AUD_Buffer m_cache;
-
- /**
- * Whether the cache contains valid data.
- */
- bool m_cache_ok;
-
- // hide copy constructor and operator=
- AUD_LinearResampleReader(const AUD_LinearResampleReader&);
- AUD_LinearResampleReader& operator=(const AUD_LinearResampleReader&);
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- */
- AUD_LinearResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_Specs specs);
-
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_LINEARRESAMPLEREADER_H__
diff --git a/intern/audaspace/intern/AUD_Mixer.cpp b/intern/audaspace/intern/AUD_Mixer.cpp
deleted file mode 100644
index 78dfaddd27a..00000000000
--- a/intern/audaspace/intern/AUD_Mixer.cpp
+++ /dev/null
@@ -1,121 +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_Mixer.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_Mixer.h"
-#include "AUD_IReader.h"
-
-#include <cstring>
-
-AUD_Mixer::AUD_Mixer(AUD_DeviceSpecs specs) :
- m_specs(specs)
-{
- switch(m_specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_float_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_float_s16;
- break;
- case AUD_FORMAT_S24:
-
-#ifdef __BIG_ENDIAN__
- m_convert = AUD_convert_float_s24_be;
-#else
- m_convert = AUD_convert_float_s24_le;
-#endif
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_float_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_copy<float>;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_float_double;
- break;
- default:
- break;
- }
-}
-
-AUD_DeviceSpecs AUD_Mixer::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_Mixer::setSpecs(AUD_Specs specs)
-{
- m_specs.specs = specs;
-}
-
-void AUD_Mixer::clear(int length)
-{
- m_buffer.assureSize(length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
-
- m_length = length;
-
- memset(m_buffer.getBuffer(), 0, length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
-}
-
-void AUD_Mixer::mix(sample_t* buffer, int start, int length, float volume)
-{
- sample_t* out = m_buffer.getBuffer();
-
- length = (AUD_MIN(m_length, length + start) - start) * m_specs.channels;
- start *= m_specs.channels;
-
- for(int i = 0; i < length; i++)
- out[i + start] += buffer[i] * volume;
-}
-
-void AUD_Mixer::mix(sample_t* buffer, int start, int length, float volume_to, float volume_from)
-{
- sample_t* out = m_buffer.getBuffer();
-
- length = (std::min(m_length, length + start) - start);
-
- for(int i = 0; i < length; i++)
- {
- float volume = volume_from * (1.0f - i / float(length)) + volume_to * (i / float(length));
-
- for(int c = 0; c < m_specs.channels; c++)
- out[(i + start) * m_specs.channels + c] += buffer[i * m_specs.channels + c] * volume;
- }
-}
-
-void AUD_Mixer::read(data_t* buffer, float volume)
-{
- sample_t* out = m_buffer.getBuffer();
-
- for(int i = 0; i < m_length * m_specs.channels; i++)
- out[i] *= volume;
-
- m_convert(buffer, (data_t*) out, m_length * m_specs.channels);
-}
diff --git a/intern/audaspace/intern/AUD_Mixer.h b/intern/audaspace/intern/AUD_Mixer.h
deleted file mode 100644
index 0735fee715b..00000000000
--- a/intern/audaspace/intern/AUD_Mixer.h
+++ /dev/null
@@ -1,114 +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_Mixer.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_MIXER_H__
-#define __AUD_MIXER_H__
-
-#include "AUD_ConverterFunctions.h"
-#include "AUD_Buffer.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.
- */
-class AUD_Mixer
-{
-protected:
- /**
- * The output specification.
- */
- AUD_DeviceSpecs m_specs;
-
- /**
- * The length of the mixing buffer.
- */
- int m_length;
-
- /**
- * The mixing buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
-public:
- /**
- * Creates the mixer.
- */
- AUD_Mixer(AUD_DeviceSpecs specs);
-
- /**
- * Destroys the mixer.
- */
- virtual ~AUD_Mixer() {}
-
- /**
- * Returns the target specification for superposing.
- * \return The target specification.
- */
- AUD_DeviceSpecs getSpecs() const;
-
- /**
- * Sets the target specification for superposing.
- * \param specs The target specification.
- */
- void setSpecs(AUD_Specs specs);
-
- /**
- * Mixes a buffer.
- * \param buffer The buffer to superpose.
- * \param start The start sample of the buffer.
- * \param length The length of the buffer in samples.
- * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
- */
- void mix(sample_t* buffer, int start, int length, float volume);
-
- void mix(sample_t* buffer, int start, int length, float volume_to, float volume_from);
-
- /**
- * Writes the mixing buffer into an output buffer.
- * \param buffer The target buffer for superposing.
- * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
- */
- void read(data_t* buffer, float volume);
-
- /**
- * Clears the mixing buffer.
- * \param length The length of the buffer in samples.
- */
- void clear(int length);
-};
-
-#endif //__AUD_MIXER_H__
diff --git a/intern/audaspace/intern/AUD_MixerFactory.cpp b/intern/audaspace/intern/AUD_MixerFactory.cpp
deleted file mode 100644
index f3f00ea2cb6..00000000000
--- a/intern/audaspace/intern/AUD_MixerFactory.cpp
+++ /dev/null
@@ -1,52 +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_MixerFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_MixerFactory.h"
-#include "AUD_IReader.h"
-
-boost::shared_ptr<AUD_IReader> AUD_MixerFactory::getReader() const
-{
- return m_factory->createReader();
-}
-
-AUD_MixerFactory::AUD_MixerFactory(boost::shared_ptr<AUD_IFactory> factory,
- AUD_DeviceSpecs specs) :
- m_specs(specs), m_factory(factory)
-{
-}
-
-AUD_DeviceSpecs AUD_MixerFactory::getSpecs() const
-{
- return m_specs;
-}
-
-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
deleted file mode 100644
index 1d2b6a4cc91..00000000000
--- a/intern/audaspace/intern/AUD_MixerFactory.h
+++ /dev/null
@@ -1,79 +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_MixerFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_MIXERFACTORY_H__
-#define __AUD_MIXERFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory is a base class for all mixer factories.
- */
-class AUD_MixerFactory : public AUD_IFactory
-{
-protected:
- /**
- * The target specification for resampling.
- */
- const AUD_DeviceSpecs m_specs;
-
- /**
- * If there is no reader it is created out of this factory.
- */
- boost::shared_ptr<AUD_IFactory> m_factory;
-
- /**
- * Returns the reader created out of the factory.
- * This method can be used for the createReader function of the implementing
- * classes.
- * \return The reader to mix.
- */
- boost::shared_ptr<AUD_IReader> getReader() const;
-
-public:
- /**
- * Creates a new factory.
- * \param factory The factory to create the readers to mix out of.
- * \param specs The target specification.
- */
- AUD_MixerFactory(boost::shared_ptr<AUD_IFactory> factory, AUD_DeviceSpecs specs);
-
- /**
- * Returns the target specification for resampling.
- */
- AUD_DeviceSpecs getSpecs() const;
-
- /**
- * Returns the saved factory.
- * \return The factory.
- */
- 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
deleted file mode 100644
index b6f6d2b4334..00000000000
--- a/intern/audaspace/intern/AUD_MutexLock.h
+++ /dev/null
@@ -1,24 +0,0 @@
-#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
deleted file mode 100644
index 98a0d324c61..00000000000
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ /dev/null
@@ -1,159 +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_NULLDevice.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include <limits>
-
-#include "AUD_NULLDevice.h"
-
-AUD_NULLDevice::AUD_NULLHandle::AUD_NULLHandle()
-{
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::pause()
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::resume()
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::stop()
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::getKeep()
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setKeep(bool keep)
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::seek(float position)
-{
- return false;
-}
-
-float AUD_NULLDevice::AUD_NULLHandle::getPosition()
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-AUD_Status AUD_NULLDevice::AUD_NULLHandle::getStatus()
-{
- return AUD_STATUS_INVALID;
-}
-
-float AUD_NULLDevice::AUD_NULLHandle::getVolume()
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setVolume(float volume)
-{
- return false;
-}
-
-float AUD_NULLDevice::AUD_NULLHandle::getPitch()
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setPitch(float pitch)
-{
- return false;
-}
-
-int AUD_NULLDevice::AUD_NULLHandle::getLoopCount()
-{
- return 0;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setLoopCount(int count)
-{
- return false;
-}
-
-bool AUD_NULLDevice::AUD_NULLHandle::setStopCallback(stopCallback callback, void* data)
-{
- return false;
-}
-
-AUD_NULLDevice::AUD_NULLDevice()
-{
-}
-
-AUD_NULLDevice::~AUD_NULLDevice()
-{
-}
-
-AUD_DeviceSpecs AUD_NULLDevice::getSpecs() const
-{
- AUD_DeviceSpecs specs;
- specs.channels = AUD_CHANNELS_INVALID;
- specs.format = AUD_FORMAT_INVALID;
- specs.rate = AUD_RATE_INVALID;
- return specs;
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_NULLDevice::play(boost::shared_ptr<AUD_IReader> reader, bool keep)
-{
- return boost::shared_ptr<AUD_IHandle>(new AUD_NULLHandle());
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_NULLDevice::play(boost::shared_ptr<AUD_IFactory> factory, bool keep)
-{
- return boost::shared_ptr<AUD_IHandle>(new AUD_NULLHandle());
-}
-
-void AUD_NULLDevice::stopAll()
-{
-}
-
-void AUD_NULLDevice::lock()
-{
-}
-
-void AUD_NULLDevice::unlock()
-{
-}
-
-float AUD_NULLDevice::getVolume() const
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-void AUD_NULLDevice::setVolume(float volume)
-{
-}
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
deleted file mode 100644
index ae1435bbeea..00000000000
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ /dev/null
@@ -1,84 +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_NULLDevice.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_NULLDEVICE_H__
-#define __AUD_NULLDEVICE_H__
-
-#include "AUD_IReader.h"
-#include "AUD_IDevice.h"
-#include "AUD_IHandle.h"
-
-/**
- * This device plays nothing.
- */
-class AUD_NULLDevice : public AUD_IDevice
-{
-private:
- class AUD_NULLHandle : public AUD_IHandle
- {
- public:
-
- AUD_NULLHandle();
-
- virtual ~AUD_NULLHandle() {}
- virtual bool pause();
- virtual bool resume();
- virtual bool stop();
- virtual bool getKeep();
- virtual bool setKeep(bool keep);
- virtual bool seek(float position);
- virtual float getPosition();
- virtual AUD_Status getStatus();
- virtual float getVolume();
- virtual bool setVolume(float volume);
- virtual float getPitch();
- virtual bool setPitch(float pitch);
- virtual int getLoopCount();
- virtual bool setLoopCount(int count);
- virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
- };
-public:
- /**
- * Creates a new NULL device.
- */
- AUD_NULLDevice();
-
- virtual ~AUD_NULLDevice();
-
- virtual AUD_DeviceSpecs getSpecs() const;
- 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();
- virtual float getVolume() const;
- virtual void setVolume(float volume);
-};
-
-#endif //__AUD_NULLDEVICE_H__
diff --git a/intern/audaspace/intern/AUD_ReadDevice.cpp b/intern/audaspace/intern/AUD_ReadDevice.cpp
deleted file mode 100644
index bab6ce4f001..00000000000
--- a/intern/audaspace/intern/AUD_ReadDevice.cpp
+++ /dev/null
@@ -1,78 +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_ReadDevice.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ReadDevice.h"
-#include "AUD_IReader.h"
-
-#include <cstring>
-
-AUD_ReadDevice::AUD_ReadDevice(AUD_DeviceSpecs specs) :
- m_playing(false)
-{
- m_specs = specs;
-
- create();
-}
-
-AUD_ReadDevice::AUD_ReadDevice(AUD_Specs specs) :
- m_playing(false)
-{
- m_specs.specs = specs;
- m_specs.format = AUD_FORMAT_FLOAT32;
-
- create();
-}
-
-AUD_ReadDevice::~AUD_ReadDevice()
-{
- destroy();
-}
-
-bool AUD_ReadDevice::read(data_t* buffer, int length)
-{
- if(m_playing)
- mix(buffer, length);
- else
- if(m_specs.format == AUD_FORMAT_U8)
- memset(buffer, 0x80, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
- else
- memset(buffer, 0, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
- return m_playing;
-}
-
-void AUD_ReadDevice::changeSpecs(AUD_Specs specs)
-{
- if(!AUD_COMPARE_SPECS(specs, m_specs.specs))
- setSpecs(specs);
-}
-
-void AUD_ReadDevice::playing(bool playing)
-{
- m_playing = playing;
-}
diff --git a/intern/audaspace/intern/AUD_ReadDevice.h b/intern/audaspace/intern/AUD_ReadDevice.h
deleted file mode 100644
index 0f077fe5d7e..00000000000
--- a/intern/audaspace/intern/AUD_ReadDevice.h
+++ /dev/null
@@ -1,88 +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_ReadDevice.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_READDEVICE_H__
-#define __AUD_READDEVICE_H__
-
-#include "AUD_SoftwareDevice.h"
-
-/**
- * This device enables to let the user read raw data out of it.
- */
-class AUD_ReadDevice : public AUD_SoftwareDevice
-{
-private:
- /**
- * Whether the device currently.
- */
- bool m_playing;
-
- // hide copy constructor and operator=
- AUD_ReadDevice(const AUD_ReadDevice&);
- AUD_ReadDevice& operator=(const AUD_ReadDevice&);
-
-protected:
- virtual void playing(bool playing);
-
-public:
- /**
- * Creates a new read device.
- * \param specs The wanted audio specification.
- */
- AUD_ReadDevice(AUD_DeviceSpecs specs);
-
- /**
- * Creates a new read device.
- * \param specs The wanted audio specification.
- */
- AUD_ReadDevice(AUD_Specs specs);
-
- /**
- * Closes the device.
- */
- virtual ~AUD_ReadDevice();
-
- /**
- * Reads the next bytes into the supplied buffer.
- * \param buffer The target buffer.
- * \param length The length in samples to be filled.
- * \return True if the reading succeeded, false if there are no sounds
- * played back currently, in that case the buffer is filled with
- * silence.
- */
- bool read(data_t* buffer, int length);
-
- /**
- * Changes the output specification.
- * \param specs The new audio data specification.
- */
- void changeSpecs(AUD_Specs specs);
-};
-
-#endif //__AUD_READDEVICE_H__
diff --git a/intern/audaspace/intern/AUD_ResampleFactory.h b/intern/audaspace/intern/AUD_ResampleFactory.h
deleted file mode 100644
index 11f8dc15f03..00000000000
--- a/intern/audaspace/intern/AUD_ResampleFactory.h
+++ /dev/null
@@ -1,37 +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_ResampleFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_RESAMPLEFACTORY_H__
-#define __AUD_RESAMPLEFACTORY_H__
-
-#include "AUD_MixerFactory.h"
-
-typedef AUD_MixerFactory AUD_ResampleFactory;
-
-#endif //__AUD_RESAMPLEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_ResampleReader.cpp b/intern/audaspace/intern/AUD_ResampleReader.cpp
deleted file mode 100644
index 4b247ffd862..00000000000
--- a/intern/audaspace/intern/AUD_ResampleReader.cpp
+++ /dev/null
@@ -1,45 +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_ResampleReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_ResampleReader.h"
-
-AUD_ResampleReader::AUD_ResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_SampleRate rate) :
- AUD_EffectReader(reader), m_rate(rate)
-{
-}
-
-void AUD_ResampleReader::setRate(AUD_SampleRate rate)
-{
- m_rate = rate;
-}
-
-AUD_SampleRate AUD_ResampleReader::getRate()
-{
- return m_rate;
-}
diff --git a/intern/audaspace/intern/AUD_ResampleReader.h b/intern/audaspace/intern/AUD_ResampleReader.h
deleted file mode 100644
index 7e21989bfa8..00000000000
--- a/intern/audaspace/intern/AUD_ResampleReader.h
+++ /dev/null
@@ -1,66 +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_ResampleReader.h
- * \ingroup audaspaceintern
- */
-
-#ifndef __AUD_RESAMPLEREADER_H__
-#define __AUD_RESAMPLEREADER_H__
-
-#include "AUD_EffectReader.h"
-
-/**
- * This is the base class for all resampling readers.
- */
-class AUD_ResampleReader : public AUD_EffectReader
-{
-protected:
- /**
- * The target sampling rate.
- */
- AUD_SampleRate m_rate;
-
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param rate The target sampling rate.
- */
- AUD_ResampleReader(boost::shared_ptr<AUD_IReader> reader, AUD_SampleRate rate);
-
-public:
- /**
- * Sets the sample rate.
- * \param rate The target sampling rate.
- */
- virtual void setRate(AUD_SampleRate rate);
-
- /**
- * Retrieves the sample rate.
- * \return The target sampling rate.
- */
- virtual AUD_SampleRate getRate();
-};
-
-#endif // __AUD_RESAMPLEREADER_H__
diff --git a/intern/audaspace/intern/AUD_Sequencer.cpp b/intern/audaspace/intern/AUD_Sequencer.cpp
deleted file mode 100644
index ddcf97e2ea1..00000000000
--- a/intern/audaspace/intern/AUD_Sequencer.cpp
+++ /dev/null
@@ -1,177 +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_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(343.3f),
- m_doppler_factor(1),
- m_distance_model(AUD_DISTANCE_MODEL_INVERSE_CLAMPED),
- m_volume(1, 1.0f),
- 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_back(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_SequencerEntry.cpp b/intern/audaspace/intern/AUD_SequencerEntry.cpp
deleted file mode 100644
index 6ef8479cdb8..00000000000
--- a/intern/audaspace/intern/AUD_SequencerEntry.cpp
+++ /dev/null
@@ -1,319 +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_SequencerEntry.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SequencerEntry.h"
-#include "AUD_SequencerReader.h"
-#include "AUD_MutexLock.h"
-
-#include <cmath>
-#include <limits>
-
-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),
- m_id(id),
- m_sound(sound),
- m_begin(begin),
- m_end(end),
- m_skip(skip),
- m_muted(false),
- 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(360),
- m_cone_angle_inner(360),
- m_cone_volume_outer(0),
- m_volume(1, 1.0f),
- m_pitch(1, 1.0f),
- m_location(3),
- m_orientation(4)
-{
- AUD_Quaternion q;
- m_orientation.write(q.get());
- float f = 1;
- m_volume.write(&f);
- m_pitch.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_SequencerEntry::~AUD_SequencerEntry()
-{
- pthread_mutex_destroy(&m_mutex);
-}
-
-void AUD_SequencerEntry::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_SequencerEntry::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}
-
-void AUD_SequencerEntry::setSound(boost::shared_ptr<AUD_IFactory> sound)
-{
- AUD_MutexLock lock(*this);
-
- if(m_sound.get() != sound.get())
- {
- m_sound = sound;
- m_sound_status++;
- }
-}
-
-void AUD_SequencerEntry::move(float begin, float end, float skip)
-{
- AUD_MutexLock lock(*this);
-
- if(m_begin != begin || m_skip != skip || m_end != end)
- {
- m_begin = begin;
- m_skip = skip;
- m_end = end;
- m_pos_status++;
- }
-}
-
-void AUD_SequencerEntry::mute(bool mute)
-{
- AUD_MutexLock lock(*this);
-
- m_muted = mute;
-}
-
-int AUD_SequencerEntry::getID() const
-{
- return m_id;
-}
-
-AUD_AnimateableProperty* AUD_SequencerEntry::getAnimProperty(AUD_AnimateablePropertyType type)
-{
- switch(type)
- {
- case AUD_AP_VOLUME:
- return &m_volume;
- case AUD_AP_PITCH:
- return &m_pitch;
- case AUD_AP_PANNING:
- return &m_panning;
- case AUD_AP_LOCATION:
- return &m_location;
- case AUD_AP_ORIENTATION:
- return &m_orientation;
- default:
- return NULL;
- }
-}
-
-void AUD_SequencerEntry::updateAll(float volume_max, float volume_min, float distance_max,
- float distance_reference, float attenuation, float cone_angle_outer,
- float cone_angle_inner, float cone_volume_outer)
-{
- AUD_MutexLock lock(*this);
-
- if(volume_max != m_volume_max)
- {
- m_volume_max = volume_max;
- m_status++;
- }
-
- if(volume_min != m_volume_min)
- {
- m_volume_min = volume_min;
- m_status++;
- }
-
- if(distance_max != m_distance_max)
- {
- m_distance_max = distance_max;
- m_status++;
- }
-
- if(distance_reference != m_distance_reference)
- {
- m_distance_reference = distance_reference;
- m_status++;
- }
-
- if(attenuation != m_attenuation)
- {
- m_attenuation = attenuation;
- m_status++;
- }
-
- if(cone_angle_outer != m_cone_angle_outer)
- {
- m_cone_angle_outer = cone_angle_outer;
- m_status++;
- }
-
- if(cone_angle_inner != m_cone_angle_inner)
- {
- m_cone_angle_inner = cone_angle_inner;
- m_status++;
- }
-
- if(cone_volume_outer != m_cone_volume_outer)
- {
- m_cone_volume_outer = cone_volume_outer;
- m_status++;
- }
-}
-
-bool AUD_SequencerEntry::isRelative()
-{
- return m_relative;
-}
-
-void AUD_SequencerEntry::setRelative(bool relative)
-{
- AUD_MutexLock lock(*this);
-
- if(m_relative != relative)
- {
- m_relative = relative;
- m_status++;
- }
-}
-
-float AUD_SequencerEntry::getVolumeMaximum()
-{
- return m_volume_max;
-}
-
-void AUD_SequencerEntry::setVolumeMaximum(float volume)
-{
- AUD_MutexLock lock(*this);
-
- m_volume_max = volume;
- m_status++;
-}
-
-float AUD_SequencerEntry::getVolumeMinimum()
-{
- return m_volume_min;
-}
-
-void AUD_SequencerEntry::setVolumeMinimum(float volume)
-{
- AUD_MutexLock lock(*this);
-
- m_volume_min = volume;
- m_status++;
-}
-
-float AUD_SequencerEntry::getDistanceMaximum()
-{
- return m_distance_max;
-}
-
-void AUD_SequencerEntry::setDistanceMaximum(float distance)
-{
- AUD_MutexLock lock(*this);
-
- m_distance_max = distance;
- m_status++;
-}
-
-float AUD_SequencerEntry::getDistanceReference()
-{
- return m_distance_reference;
-}
-
-void AUD_SequencerEntry::setDistanceReference(float distance)
-{
- AUD_MutexLock lock(*this);
-
- m_distance_reference = distance;
- m_status++;
-}
-
-float AUD_SequencerEntry::getAttenuation()
-{
- return m_attenuation;
-}
-
-void AUD_SequencerEntry::setAttenuation(float factor)
-{
- AUD_MutexLock lock(*this);
-
- m_attenuation = factor;
- m_status++;
-}
-
-float AUD_SequencerEntry::getConeAngleOuter()
-{
- return m_cone_angle_outer;
-}
-
-void AUD_SequencerEntry::setConeAngleOuter(float angle)
-{
- AUD_MutexLock lock(*this);
-
- m_cone_angle_outer = angle;
- m_status++;
-}
-
-float AUD_SequencerEntry::getConeAngleInner()
-{
- return m_cone_angle_inner;
-}
-
-void AUD_SequencerEntry::setConeAngleInner(float angle)
-{
- AUD_MutexLock lock(*this);
-
- m_cone_angle_inner = angle;
- m_status++;
-}
-
-float AUD_SequencerEntry::getConeVolumeOuter()
-{
- return m_cone_volume_outer;
-}
-
-void AUD_SequencerEntry::setConeVolumeOuter(float volume)
-{
- AUD_MutexLock lock(*this);
-
- m_cone_volume_outer = volume;
- m_status++;
-}
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.cpp b/intern/audaspace/intern/AUD_SequencerFactory.cpp
deleted file mode 100644
index f6076603c2b..00000000000
--- a/intern/audaspace/intern/AUD_SequencerFactory.cpp
+++ /dev/null
@@ -1,123 +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_SequencerFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#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_sequence = boost::shared_ptr<AUD_Sequencer>(new AUD_Sequencer(specs, fps, muted));
-}
-
-/*void AUD_SequencerFactory::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_SequencerFactory::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}*/
-
-void AUD_SequencerFactory::setSpecs(AUD_Specs specs)
-{
- m_sequence->setSpecs(specs);
-}
-
-void AUD_SequencerFactory::setFPS(float fps)
-{
- m_sequence->setFPS(fps);
-}
-
-void AUD_SequencerFactory::mute(bool muted)
-{
- m_sequence->mute(muted);
-}
-
-bool AUD_SequencerFactory::getMute() const
-{
- return m_sequence->getMute();
-}
-
-float AUD_SequencerFactory::getSpeedOfSound() const
-{
- return m_sequence->getSpeedOfSound();
-}
-
-void AUD_SequencerFactory::setSpeedOfSound(float speed)
-{
- m_sequence->setSpeedOfSound(speed);
-}
-
-float AUD_SequencerFactory::getDopplerFactor() const
-{
- return m_sequence->getDopplerFactor();
-}
-
-void AUD_SequencerFactory::setDopplerFactor(float factor)
-{
- m_sequence->setDopplerFactor(factor);
-}
-
-AUD_DistanceModel AUD_SequencerFactory::getDistanceModel() const
-{
- return m_sequence->getDistanceModel();
-}
-
-void AUD_SequencerFactory::setDistanceModel(AUD_DistanceModel model)
-{
- m_sequence->setDistanceModel(model);
-}
-
-AUD_AnimateableProperty* AUD_SequencerFactory::getAnimProperty(AUD_AnimateablePropertyType type)
-{
- return m_sequence->getAnimProperty(type);
-}
-
-boost::shared_ptr<AUD_SequencerEntry> AUD_SequencerFactory::add(boost::shared_ptr<AUD_IFactory> sound, float begin, float end, float skip)
-{
- return m_sequence->add(sound, begin, end, skip);
-}
-
-void AUD_SequencerFactory::remove(boost::shared_ptr<AUD_SequencerEntry> entry)
-{
- m_sequence->remove(entry);
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SequencerFactory::createQualityReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_SequencerReader(m_sequence, true));
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SequencerFactory::createReader()
-{
- return boost::shared_ptr<AUD_IReader>(new AUD_SequencerReader(m_sequence));
-}
diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp
deleted file mode 100644
index aef93cd3896..00000000000
--- a/intern/audaspace/intern/AUD_SequencerReader.cpp
+++ /dev/null
@@ -1,204 +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_SequencerReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SequencerReader.h"
-#include "AUD_MutexLock.h"
-
-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(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);
-}
-
-AUD_SequencerReader::~AUD_SequencerReader()
-{
-}
-
-bool AUD_SequencerReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_SequencerReader::seek(int position)
-{
- if(position < 0)
- return;
-
- m_position = position;
-
- for(AUD_HandleIterator it = m_handles.begin(); it != m_handles.end(); it++)
- {
- (*it)->seek(position / m_sequence->m_specs.rate);
- }
-}
-
-int AUD_SequencerReader::getLength() const
-{
- return -1;
-}
-
-int AUD_SequencerReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SequencerReader::getSpecs() const
-{
- return m_sequence->m_specs;
-}
-
-void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
-{
- AUD_MutexLock lock(*m_sequence);
-
- if(m_sequence->m_status != m_status)
- {
- 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_sequence->m_status;
- }
-
- if(m_sequence->m_entry_status != m_entry_status)
- {
- std::list<boost::shared_ptr<AUD_SequencerHandle> > handles;
-
- AUD_HandleIterator hit = m_handles.begin();
- AUD_EntryIterator eit = m_sequence->m_entries.begin();
-
- int result;
- boost::shared_ptr<AUD_SequencerHandle> handle;
-
- while(hit != m_handles.end() && eit != m_sequence->m_entries.end())
- {
- handle = *hit;
- boost::shared_ptr<AUD_SequencerEntry> entry = *eit;
-
- result = handle->compare(entry);
-
- if(result < 0)
- {
- try
- {
- handle = boost::shared_ptr<AUD_SequencerHandle>(new AUD_SequencerHandle(entry, m_device));
- handles.push_back(handle);
- }
- catch(AUD_Exception&)
- {
- }
- eit++;
- }
- else if(result == 0)
- {
- handles.push_back(handle);
- hit++;
- eit++;
- }
- else
- {
- handle->stop();
- hit++;
- }
- }
-
- while(hit != m_handles.end())
- {
- (*hit)->stop();
- hit++;
- }
-
- while(eit != m_sequence->m_entries.end())
- {
- try
- {
- handle = boost::shared_ptr<AUD_SequencerHandle>(new AUD_SequencerHandle(*eit, m_device));
- handles.push_back(handle);
- }
- catch(AUD_Exception&)
- {
- }
- eit++;
- }
-
- m_handles = handles;
-
- m_entry_status = m_sequence->m_entry_status;
- }
-
- AUD_Specs specs = m_sequence->m_specs;
- int pos = 0;
- float time = float(m_position) / float(specs.rate);
- float volume, frame;
- int len, cfra;
- AUD_Vector3 v, v2;
- AUD_Quaternion q;
-
-
- while(pos < length)
- {
- frame = time * m_sequence->m_fps;
- cfra = int(floor(frame));
-
- 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_sequence->m_fps);
- }
-
- m_sequence->m_volume.read(frame, &volume);
- if(m_sequence->m_muted)
- volume = 0.0f;
- m_device.setVolume(volume);
-
- m_sequence->m_orientation.read(frame, q.get());
- m_device.setListenerOrientation(q);
- m_sequence->m_location.read(frame, v.get());
- m_device.setListenerLocation(v);
- m_sequence->m_location.read(frame + 1, v2.get());
- v2 -= v;
- m_device.setListenerVelocity(v2 * m_sequence->m_fps);
-
- m_device.read(reinterpret_cast<data_t*>(buffer + specs.channels * pos), len);
-
- pos += len;
- time += float(len) / float(specs.rate);
- }
-
- m_position += length;
-
- eos = false;
-}
diff --git a/intern/audaspace/intern/AUD_SequencerReader.h b/intern/audaspace/intern/AUD_SequencerReader.h
deleted file mode 100644
index 6b3dbc9313e..00000000000
--- a/intern/audaspace/intern/AUD_SequencerReader.h
+++ /dev/null
@@ -1,99 +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_SequencerReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SEQUENCERREADER_H__
-#define __AUD_SEQUENCERREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_ReadDevice.h"
-#include "AUD_Sequencer.h"
-#include "AUD_SequencerHandle.h"
-
-/**
- * This reader plays back sequenced entries.
- */
-class AUD_SequencerReader : public AUD_IReader
-{
-private:
- /**
- * The current position.
- */
- int m_position;
-
- /**
- * The read device used to mix the sounds correctly.
- */
- AUD_ReadDevice m_device;
-
- /**
- * Saves the sequence the reader belongs to.
- */
- boost::shared_ptr<AUD_Sequencer> m_sequence;
-
- /**
- * The list of playback handles for the entries.
- */
- std::list<boost::shared_ptr<AUD_SequencerHandle> > m_handles;
-
- /**
- * Last status read from the sequence.
- */
- int m_status;
-
- /**
- * Last entry status read from the sequence.
- */
- int m_entry_status;
-
- // hide copy constructor and operator=
- AUD_SequencerReader(const AUD_SequencerReader&);
- AUD_SequencerReader& operator=(const AUD_SequencerReader&);
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- */
- AUD_SequencerReader(boost::shared_ptr<AUD_Sequencer> sequence, bool quality = false);
-
- /**
- * Destroys the reader.
- */
- ~AUD_SequencerReader();
-
- virtual bool isSeekable() const;
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SEQUENCERREADER_H__
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.cpp b/intern/audaspace/intern/AUD_SilenceFactory.cpp
deleted file mode 100644
index 85034b316ca..00000000000
--- a/intern/audaspace/intern/AUD_SilenceFactory.cpp
+++ /dev/null
@@ -1,41 +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_SilenceFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SilenceFactory.h"
-#include "AUD_SilenceReader.h"
-#include "AUD_Space.h"
-
-AUD_SilenceFactory::AUD_SilenceFactory()
-{
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SilenceFactory::createReader()
-{
- 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
deleted file mode 100644
index de62a2f94fc..00000000000
--- a/intern/audaspace/intern/AUD_SilenceFactory.h
+++ /dev/null
@@ -1,54 +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_SilenceFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SILENCEFACTORY_H__
-#define __AUD_SILENCEFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory creates a reader that plays silence.
- */
-class AUD_SilenceFactory : public AUD_IFactory
-{
-private:
- // hide copy constructor and operator=
- AUD_SilenceFactory(const AUD_SilenceFactory&);
- AUD_SilenceFactory& operator=(const AUD_SilenceFactory&);
-
-public:
- /**
- * Creates a new silence factory.
- */
- AUD_SilenceFactory();
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_SILENCEFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_SilenceReader.cpp b/intern/audaspace/intern/AUD_SilenceReader.cpp
deleted file mode 100644
index 5d7e83f7f09..00000000000
--- a/intern/audaspace/intern/AUD_SilenceReader.cpp
+++ /dev/null
@@ -1,72 +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_SilenceReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SilenceReader.h"
-
-#include <cstring>
-
-AUD_SilenceReader::AUD_SilenceReader() :
- m_position(0)
-{
-}
-
-bool AUD_SilenceReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_SilenceReader::seek(int position)
-{
- m_position = position;
-}
-
-int AUD_SilenceReader::getLength() const
-{
- return -1;
-}
-
-int AUD_SilenceReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SilenceReader::getSpecs() const
-{
- AUD_Specs specs;
- specs.rate = AUD_RATE_48000;
- specs.channels = AUD_CHANNELS_MONO;
- return specs;
-}
-
-void AUD_SilenceReader::read(int& length, bool& eos, sample_t* buffer)
-{
- memset(buffer, 0, length * sizeof(sample_t));
- m_position += length;
- eos = false;
-}
diff --git a/intern/audaspace/intern/AUD_SilenceReader.h b/intern/audaspace/intern/AUD_SilenceReader.h
deleted file mode 100644
index cac56a0861b..00000000000
--- a/intern/audaspace/intern/AUD_SilenceReader.h
+++ /dev/null
@@ -1,66 +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_SilenceReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SILENCEREADER_H__
-#define __AUD_SILENCEREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class is used for silence playback.
- * The signal generated is 44.1kHz mono.
- */
-class AUD_SilenceReader : public AUD_IReader
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- // hide copy constructor and operator=
- AUD_SilenceReader(const AUD_SilenceReader&);
- AUD_SilenceReader& operator=(const AUD_SilenceReader&);
-
-public:
- /**
- * Creates a new reader.
- */
- AUD_SilenceReader();
-
- virtual bool isSeekable() const;
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SILENCEREADER_H__
diff --git a/intern/audaspace/intern/AUD_SinusFactory.cpp b/intern/audaspace/intern/AUD_SinusFactory.cpp
deleted file mode 100644
index 2b9742cc90c..00000000000
--- a/intern/audaspace/intern/AUD_SinusFactory.cpp
+++ /dev/null
@@ -1,48 +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_SinusFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SinusFactory.h"
-#include "AUD_SinusReader.h"
-#include "AUD_Space.h"
-
-AUD_SinusFactory::AUD_SinusFactory(float frequency, AUD_SampleRate sampleRate) :
- m_frequency(frequency),
- m_sampleRate(sampleRate)
-{
-}
-
-float AUD_SinusFactory::getFrequency() const
-{
- return m_frequency;
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SinusFactory::createReader()
-{
- 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
deleted file mode 100644
index c8d409a4aff..00000000000
--- a/intern/audaspace/intern/AUD_SinusFactory.h
+++ /dev/null
@@ -1,72 +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_SinusFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SINUSFACTORY_H__
-#define __AUD_SINUSFACTORY_H__
-
-#include "AUD_IFactory.h"
-
-/**
- * This factory creates a reader that plays a sine tone.
- */
-class AUD_SinusFactory : public AUD_IFactory
-{
-private:
- /**
- * The frequence of the sine wave.
- */
- const float m_frequency;
-
- /**
- * The target sample rate for output.
- */
- const AUD_SampleRate m_sampleRate;
-
- // hide copy constructor and operator=
- AUD_SinusFactory(const AUD_SinusFactory&);
- AUD_SinusFactory& operator=(const AUD_SinusFactory&);
-
-public:
- /**
- * Creates a new sine factory.
- * \param frequency The desired frequency.
- * \param sampleRate The target sample rate for playback.
- */
- AUD_SinusFactory(float frequency,
- AUD_SampleRate sampleRate = AUD_RATE_48000);
-
- /**
- * Returns the frequency of the sine wave.
- */
- float getFrequency() const;
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_SINUSFACTORY_H__
diff --git a/intern/audaspace/intern/AUD_SinusReader.cpp b/intern/audaspace/intern/AUD_SinusReader.cpp
deleted file mode 100644
index 2e89126bd7b..00000000000
--- a/intern/audaspace/intern/AUD_SinusReader.cpp
+++ /dev/null
@@ -1,83 +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_SinusReader.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SinusReader.h"
-
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-AUD_SinusReader::AUD_SinusReader(float frequency, AUD_SampleRate sampleRate) :
- m_frequency(frequency),
- m_position(0),
- m_sampleRate(sampleRate)
-{
-}
-
-bool AUD_SinusReader::isSeekable() const
-{
- return true;
-}
-
-void AUD_SinusReader::seek(int position)
-{
- m_position = position;
-}
-
-int AUD_SinusReader::getLength() const
-{
- return -1;
-}
-
-int AUD_SinusReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SinusReader::getSpecs() const
-{
- AUD_Specs specs;
- specs.rate = m_sampleRate;
- specs.channels = AUD_CHANNELS_MONO;
- return specs;
-}
-
-void AUD_SinusReader::read(int& length, bool& eos, sample_t* buffer)
-{
- // fill with sine data
- for(int i = 0; i < length; i++)
- {
- buffer[i] = sin((m_position + i) * 2 * M_PI * m_frequency / m_sampleRate);
- }
-
- m_position += length;
- eos = false;
-}
diff --git a/intern/audaspace/intern/AUD_SinusReader.h b/intern/audaspace/intern/AUD_SinusReader.h
deleted file mode 100644
index 50487ea94aa..00000000000
--- a/intern/audaspace/intern/AUD_SinusReader.h
+++ /dev/null
@@ -1,78 +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_SinusReader.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SINUSREADER_H__
-#define __AUD_SINUSREADER_H__
-
-#include "AUD_IReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class is used for sine tone playback.
- * The sample rate can be specified, the signal is mono.
- */
-class AUD_SinusReader : public AUD_IReader
-{
-private:
- /**
- * The frequency of the sine wave.
- */
- const float m_frequency;
-
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The sample rate for the output.
- */
- const AUD_SampleRate m_sampleRate;
-
- // hide copy constructor and operator=
- AUD_SinusReader(const AUD_SinusReader&);
- AUD_SinusReader& operator=(const AUD_SinusReader&);
-
-public:
- /**
- * Creates a new reader.
- * \param frequency The frequency of the sine wave.
- * \param sampleRate The output sample rate.
- */
- AUD_SinusReader(float frequency, AUD_SampleRate sampleRate);
-
- virtual bool isSeekable() const;
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SINUSREADER_H__
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
deleted file mode 100644
index f9d65aa2363..00000000000
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ /dev/null
@@ -1,995 +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_SoftwareDevice.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_SoftwareDevice.h"
-#include "AUD_IReader.h"
-#include "AUD_Mixer.h"
-#include "AUD_IFactory.h"
-#include "AUD_JOSResampleReader.h"
-#include "AUD_LinearResampleReader.h"
-#include "AUD_MutexLock.h"
-
-#include <cstring>
-#include <cmath>
-#include <limits>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-typedef enum
-{
- AUD_RENDER_DISTANCE = 0x01,
- AUD_RENDER_DOPPLER = 0x02,
- AUD_RENDER_CONE = 0x04,
- AUD_RENDER_VOLUME = 0x08
-} AUD_RenderFlags;
-
-#define AUD_PITCH_MAX 10
-
-/******************************************************************************/
-/********************** AUD_SoftwareHandle Handle Code ************************/
-/******************************************************************************/
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause(bool keep)
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PLAYING)
- {
- 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;
-
- m_device->m_playingSounds.erase(it);
- m_device->m_pausedSounds.push_back(This);
-
- if(m_device->m_playingSounds.empty())
- m_device->playing(m_device->m_playback = false);
-
- m_status = keep ? AUD_STATUS_STOPPED : AUD_STATUS_PAUSED;
-
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-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_old_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),
- m_flags(AUD_RENDER_CONE), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING), m_device(device)
-{
-}
-
-void AUD_SoftwareDevice::AUD_SoftwareHandle::update()
-{
- int flags = 0;
-
- m_old_volume = m_volume;
-
- AUD_Vector3 SL;
- if(m_relative)
- SL = -m_location;
- else
- SL = m_device->m_location - m_location;
- float distance = SL * SL;
-
- if(distance > 0)
- distance = sqrt(distance);
- else
- flags |= AUD_RENDER_DOPPLER | AUD_RENDER_DISTANCE;
-
- if(m_pitch->getSpecs().channels != AUD_CHANNELS_MONO)
- {
- m_volume = m_user_volume;
- m_pitch->setPitch(m_user_pitch);
- return;
- }
-
- flags = ~(flags | m_flags | m_device->m_flags);
-
- // Doppler and Pitch
-
- if(flags & AUD_RENDER_DOPPLER)
- {
- float vls;
- if(m_relative)
- vls = 0;
- else
- vls = SL * m_device->m_velocity / distance;
- float vss = SL * m_velocity / distance;
- float max = m_device->m_speed_of_sound / m_device->m_doppler_factor;
- if(vss >= max)
- {
- m_pitch->setPitch(AUD_PITCH_MAX);
- }
- else
- {
- if(vls > max)
- vls = max;
-
- m_pitch->setPitch((m_device->m_speed_of_sound - m_device->m_doppler_factor * vls) / (m_device->m_speed_of_sound - m_device->m_doppler_factor * vss) * m_user_pitch);
- }
- }
- else
- m_pitch->setPitch(m_user_pitch);
-
- if(flags & AUD_RENDER_VOLUME)
- {
- // Distance
-
- if(flags & AUD_RENDER_DISTANCE)
- {
- if(m_device->m_distance_model == AUD_DISTANCE_MODEL_INVERSE_CLAMPED ||
- m_device->m_distance_model == AUD_DISTANCE_MODEL_LINEAR_CLAMPED ||
- m_device->m_distance_model == AUD_DISTANCE_MODEL_EXPONENT_CLAMPED)
- {
- distance = AUD_MAX(AUD_MIN(m_distance_max, distance), m_distance_reference);
- }
-
- switch(m_device->m_distance_model)
- {
- case AUD_DISTANCE_MODEL_INVERSE:
- case AUD_DISTANCE_MODEL_INVERSE_CLAMPED:
- m_volume = m_distance_reference / (m_distance_reference + m_attenuation * (distance - m_distance_reference));
- break;
- case AUD_DISTANCE_MODEL_LINEAR:
- case AUD_DISTANCE_MODEL_LINEAR_CLAMPED:
- {
- float temp = m_distance_max - m_distance_reference;
- if(temp == 0)
- {
- if(distance > m_distance_reference)
- m_volume = 0.0f;
- else
- m_volume = 1.0f;
- }
- else
- m_volume = 1.0f - m_attenuation * (distance - m_distance_reference) / (m_distance_max - m_distance_reference);
- break;
- }
- case AUD_DISTANCE_MODEL_EXPONENT:
- case AUD_DISTANCE_MODEL_EXPONENT_CLAMPED:
- if(m_distance_reference == 0)
- m_volume = 0;
- else
- m_volume = pow(distance / m_distance_reference, -m_attenuation);
- break;
- default:
- m_volume = 1.0f;
- }
- }
- else
- m_volume = 1.0f;
-
- // Cone
-
- if(flags & AUD_RENDER_CONE)
- {
- AUD_Vector3 SZ = m_orientation.getLookAt();
-
- float phi = acos(float(SZ * SL / (SZ.length() * SL.length())));
- float t = (phi - m_cone_angle_inner)/(m_cone_angle_outer - m_cone_angle_inner);
-
- if(t > 0)
- {
- if(t > 1)
- m_volume *= m_cone_volume_outer;
- else
- m_volume *= 1 + t * (m_cone_volume_outer - 1);
- }
- }
-
- if(m_volume > m_volume_max)
- m_volume = m_volume_max;
- else if(m_volume < m_volume_min)
- m_volume = m_volume_min;
-
- // Volume
-
- m_volume *= m_user_volume;
- }
-
- // 3D Cue
-
- AUD_Quaternion orientation;
-
- if(!m_relative)
- orientation = m_device->m_orientation;
-
- AUD_Vector3 Z = orientation.getLookAt();
- AUD_Vector3 N = orientation.getUp();
- AUD_Vector3 A = N * ((SL * N) / (N * N)) - SL;
-
- float Asquare = A * A;
-
- if(Asquare > 0)
- {
- float phi = acos(float(Z * A / (Z.length() * sqrt(Asquare))));
- if(N.cross(Z) * A > 0)
- phi = -phi;
-
- m_mapper->setMonoAngle(phi);
- }
- else
- m_mapper->setMonoAngle(m_relative ? m_user_pan * M_PI / 2.0 : 0);
-}
-
-void AUD_SoftwareDevice::AUD_SoftwareHandle::setSpecs(AUD_Specs specs)
-{
- m_mapper->setChannels(specs.channels);
- m_resampler->setRate(specs.rate);
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause()
-{
- return pause(false);
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::resume()
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PAUSED)
- {
- 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;
-
- 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;
- }
- }
- }
-
- }
-
- return false;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::stop()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_status = AUD_STATUS_INVALID;
-
- 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;
-
- m_device->m_playingSounds.erase(it);
-
- if(m_device->m_playingSounds.empty())
- m_device->playing(m_device->m_playback = false);
-
- 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()
-{
- if(m_status)
- return m_keep;
-
- return false;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setKeep(bool keep)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_keep = keep;
-
- return true;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_pitch->setPitch(m_user_pitch);
- m_reader->seek((int)(position * m_reader->getSpecs().rate));
-
- if(m_status == AUD_STATUS_STOPPED)
- m_status = AUD_STATUS_PAUSED;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getPosition()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return 0.0f;
-
- float position = m_reader->getPosition() / (float)m_device->m_specs.rate;
-
- return position;
-}
-
-AUD_Status AUD_SoftwareDevice::AUD_SoftwareHandle::getStatus()
-{
- return m_status;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolume()
-{
- return m_user_volume;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolume(float volume)
-{
- if(!m_status)
- return false;
- m_user_volume = volume;
-
- if(volume == 0)
- {
- m_old_volume = m_volume = volume;
- m_flags |= AUD_RENDER_VOLUME;
- }
- else
- m_flags &= ~AUD_RENDER_VOLUME;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getPitch()
-{
- return m_user_pitch;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setPitch(float pitch)
-{
- if(!m_status)
- return false;
- if(pitch <= 0)
- pitch = 1;
- m_user_pitch = pitch;
- return true;
-}
-
-int AUD_SoftwareDevice::AUD_SoftwareHandle::getLoopCount()
-{
- if(!m_status)
- return 0;
- return m_loopcount;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setLoopCount(int count)
-{
- if(!m_status)
- return false;
-
- if(m_status == AUD_STATUS_STOPPED && (count > m_loopcount || count < 0))
- m_status = AUD_STATUS_PAUSED;
-
- m_loopcount = count;
-
- return true;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setStopCallback(stopCallback callback, void* data)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_stop = callback;
- m_stop_data = data;
-
- return true;
-}
-
-
-
-/******************************************************************************/
-/******************** AUD_SoftwareHandle 3DHandle Code ************************/
-/******************************************************************************/
-
-AUD_Vector3 AUD_SoftwareDevice::AUD_SoftwareHandle::getSourceLocation()
-{
- if(!m_status)
- return AUD_Vector3();
-
- return m_location;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setSourceLocation(const AUD_Vector3& location)
-{
- if(!m_status)
- return false;
-
- m_location = location;
-
- return true;
-}
-
-AUD_Vector3 AUD_SoftwareDevice::AUD_SoftwareHandle::getSourceVelocity()
-{
- if(!m_status)
- return AUD_Vector3();
-
- return m_velocity;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setSourceVelocity(const AUD_Vector3& velocity)
-{
- if(!m_status)
- return false;
-
- m_velocity = velocity;
-
- return true;
-}
-
-AUD_Quaternion AUD_SoftwareDevice::AUD_SoftwareHandle::getSourceOrientation()
-{
- if(!m_status)
- return AUD_Quaternion();
-
- return m_orientation;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setSourceOrientation(const AUD_Quaternion& orientation)
-{
- if(!m_status)
- return false;
-
- m_orientation = orientation;
-
- return true;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::isRelative()
-{
- if(!m_status)
- return false;
-
- return m_relative;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setRelative(bool relative)
-{
- if(!m_status)
- return false;
-
- m_relative = relative;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolumeMaximum()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_volume_max;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolumeMaximum(float volume)
-{
- if(!m_status)
- return false;
-
- m_volume_max = volume;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolumeMinimum()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_volume_min;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolumeMinimum(float volume)
-{
- if(!m_status)
- return false;
-
- m_volume_min = volume;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getDistanceMaximum()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_distance_max;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setDistanceMaximum(float distance)
-{
- if(!m_status)
- return false;
-
- m_distance_max = distance;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getDistanceReference()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_distance_reference;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setDistanceReference(float distance)
-{
- if(!m_status)
- return false;
-
- m_distance_reference = distance;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getAttenuation()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_attenuation;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setAttenuation(float factor)
-{
- if(!m_status)
- return false;
-
- m_attenuation = factor;
-
- if(factor == 0)
- m_flags |= AUD_RENDER_DISTANCE;
- else
- m_flags &= ~AUD_RENDER_DISTANCE;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getConeAngleOuter()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_cone_angle_outer * 360.0f / M_PI;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setConeAngleOuter(float angle)
-{
- if(!m_status)
- return false;
-
- m_cone_angle_outer = angle * M_PI / 360.0f;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getConeAngleInner()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_cone_angle_inner * 360.0f / M_PI;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setConeAngleInner(float angle)
-{
- if(!m_status)
- return false;
-
- if(angle >= 360)
- m_flags |= AUD_RENDER_CONE;
- else
- m_flags &= ~AUD_RENDER_CONE;
-
- m_cone_angle_inner = angle * M_PI / 360.0f;
-
- return true;
-}
-
-float AUD_SoftwareDevice::AUD_SoftwareHandle::getConeVolumeOuter()
-{
- if(!m_status)
- return std::numeric_limits<float>::quiet_NaN();
-
- return m_cone_volume_outer;
-}
-
-bool AUD_SoftwareDevice::AUD_SoftwareHandle::setConeVolumeOuter(float volume)
-{
- if(!m_status)
- return false;
-
- m_cone_volume_outer = volume;
-
- return true;
-}
-
-/******************************************************************************/
-/**************************** IDevice Code ************************************/
-/******************************************************************************/
-
-void AUD_SoftwareDevice::create()
-{
- m_playback = false;
- m_volume = 1.0f;
- m_mixer = boost::shared_ptr<AUD_Mixer>(new AUD_Mixer(m_specs));
- m_speed_of_sound = 343.3f;
- m_doppler_factor = 1.0f;
- m_distance_model = AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
- m_flags = 0;
- m_quality = false;
-
- 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);
-}
-
-void AUD_SoftwareDevice::destroy()
-{
- if(m_playback)
- playing(m_playback = false);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-
- pthread_mutex_destroy(&m_mutex);
-}
-
-void AUD_SoftwareDevice::mix(data_t* buffer, int length)
-{
- m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_specs));
-
- AUD_MutexLock lock(*this);
-
- {
- boost::shared_ptr<AUD_SoftwareDevice::AUD_SoftwareHandle> sound;
- int len;
- int pos;
- bool eos;
- 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);
-
- // for all sounds
- AUD_HandleIterator it = m_playingSounds.begin();
- while(it != m_playingSounds.end())
- {
- sound = *it;
- // increment the iterator to make sure it's valid,
- // in case the sound gets deleted after stopping
- ++it;
-
- // get the buffer from the source
- pos = 0;
- len = length;
-
- // update 3D Info
- sound->update();
-
- sound->m_reader->read(len, eos, buf);
-
- // in case of looping
- while(pos + len < length && sound->m_loopcount && eos)
- {
- m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
-
- pos += len;
-
- if(sound->m_loopcount > 0)
- sound->m_loopcount--;
-
- sound->m_reader->seek(0);
-
- len = length - pos;
- sound->m_reader->read(len, eos, buf);
-
- // prevent endless loop
- if(!len)
- break;
- }
-
- m_mixer->mix(buf, pos, len, sound->m_volume, sound->m_old_volume);
-
- // in case the end of the sound is reached
- if(eos && !sound->m_loopcount)
- {
- if(sound->m_stop)
- sound->m_stop(sound->m_stop_data);
-
- if(sound->m_keep)
- pauseSounds.push_back(sound);
- else
- stopSounds.push_back(sound);
- }
- }
-
- // superpose
- m_mixer->read(buffer, m_volume);
-
- // cleanup
- for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
- (*it)->pause(true);
-
- for(it = stopSounds.begin(); it != stopSounds.end(); it++)
- (*it)->stop();
-
- pauseSounds.clear();
- stopSounds.clear();
- }
-}
-
-void AUD_SoftwareDevice::setPanning(AUD_IHandle* handle, float pan)
-{
- AUD_SoftwareDevice::AUD_SoftwareHandle* h = dynamic_cast<AUD_SoftwareDevice::AUD_SoftwareHandle*>(handle);
- h->m_user_pan = pan;
-}
-
-void AUD_SoftwareDevice::setQuality(bool quality)
-{
- m_quality = quality;
-}
-
-void AUD_SoftwareDevice::setSpecs(AUD_Specs specs)
-{
- m_specs.specs = specs;
- m_mixer->setSpecs(specs);
-
- for(AUD_HandleIterator it = m_playingSounds.begin(); it != m_playingSounds.end(); it++)
- {
- (*it)->setSpecs(specs);
- }
-}
-
-AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const
-{
- return m_specs;
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_SoftwareDevice::play(boost::shared_ptr<AUD_IReader> reader, bool keep)
-{
- // prepare the reader
- // pitch
-
- boost::shared_ptr<AUD_PitchReader> pitch = boost::shared_ptr<AUD_PitchReader>(new AUD_PitchReader(reader, 1));
- reader = boost::shared_ptr<AUD_IReader>(pitch);
-
- boost::shared_ptr<AUD_ResampleReader> resampler;
-
- // resample
- if(m_quality)
- resampler = boost::shared_ptr<AUD_ResampleReader>(new AUD_JOSResampleReader(reader, m_specs.specs));
- else
- resampler = boost::shared_ptr<AUD_ResampleReader>(new AUD_LinearResampleReader(reader, m_specs.specs));
- reader = boost::shared_ptr<AUD_IReader>(resampler);
-
- // rechannel
- 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.get())
- return boost::shared_ptr<AUD_IHandle>();
-
- // play sound
- 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);
-
- m_playingSounds.push_back(sound);
-
- if(!m_playback)
- playing(m_playback = true);
-
- return boost::shared_ptr<AUD_IHandle>(sound);
-}
-
-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()
-{
- AUD_MutexLock lock(*this);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-}
-
-void AUD_SoftwareDevice::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_SoftwareDevice::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}
-
-float AUD_SoftwareDevice::getVolume() const
-{
- return m_volume;
-}
-
-void AUD_SoftwareDevice::setVolume(float volume)
-{
- m_volume = volume;
-}
-
-/******************************************************************************/
-/**************************** 3D Device Code **********************************/
-/******************************************************************************/
-
-AUD_Vector3 AUD_SoftwareDevice::getListenerLocation() const
-{
- return m_location;
-}
-
-void AUD_SoftwareDevice::setListenerLocation(const AUD_Vector3& location)
-{
- m_location = location;
-}
-
-AUD_Vector3 AUD_SoftwareDevice::getListenerVelocity() const
-{
- return m_velocity;
-}
-
-void AUD_SoftwareDevice::setListenerVelocity(const AUD_Vector3& velocity)
-{
- m_velocity = velocity;
-}
-
-AUD_Quaternion AUD_SoftwareDevice::getListenerOrientation() const
-{
- return m_orientation;
-}
-
-void AUD_SoftwareDevice::setListenerOrientation(const AUD_Quaternion& orientation)
-{
- m_orientation = orientation;
-}
-
-float AUD_SoftwareDevice::getSpeedOfSound() const
-{
- return m_speed_of_sound;
-}
-
-void AUD_SoftwareDevice::setSpeedOfSound(float speed)
-{
- m_speed_of_sound = speed;
-}
-
-float AUD_SoftwareDevice::getDopplerFactor() const
-{
- return m_doppler_factor;
-}
-
-void AUD_SoftwareDevice::setDopplerFactor(float factor)
-{
- m_doppler_factor = factor;
- if(factor == 0)
- m_flags |= AUD_RENDER_DOPPLER;
- else
- m_flags &= ~AUD_RENDER_DOPPLER;
-}
-
-AUD_DistanceModel AUD_SoftwareDevice::getDistanceModel() const
-{
- return m_distance_model;
-}
-
-void AUD_SoftwareDevice::setDistanceModel(AUD_DistanceModel model)
-{
- m_distance_model = model;
- if(model == AUD_DISTANCE_MODEL_INVALID)
- m_flags |= AUD_RENDER_DISTANCE;
- else
- m_flags &= ~AUD_RENDER_DISTANCE;
-}
diff --git a/intern/audaspace/intern/AUD_Space.h b/intern/audaspace/intern/AUD_Space.h
deleted file mode 100644
index 26bbdc5a8f7..00000000000
--- a/intern/audaspace/intern/AUD_Space.h
+++ /dev/null
@@ -1,257 +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_Space.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_SPACE_H__
-#define __AUD_SPACE_H__
-
-/// The size of a format in bytes.
-#define AUD_FORMAT_SIZE(format) (format & 0x0F)
-/// The size of a sample in the specified device format in bytes.
-#define AUD_DEVICE_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
-/// The size of a sample in the specified format in bytes.
-#define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t))
-/// Throws a AUD_Exception with the provided error code.
-#define AUD_THROW(exception, errorstr) { AUD_Exception e; e.error = exception; e.str = errorstr; throw e; }
-
-/// Compares two audio data specifications.
-#define AUD_COMPARE_SPECS(s1, s2) ((s1.rate == s2.rate) && (s1.channels == s2.channels))
-
-/// Returns the bit for a channel mask.
-#define AUD_CHANNEL_BIT(channel) (0x01 << channel)
-
-/// Returns the smaller of the two values.
-#define AUD_MIN(a, b) (((a) < (b)) ? (a) : (b))
-/// Returns the bigger of the two values.
-#define AUD_MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-// 5 sec * 48000 samples/sec * 4 bytes/sample * 6 channels
-/// The size by which a buffer should be resized if the final extent is unknown.
-#define AUD_BUFFER_RESIZE_BYTES 5760000
-
-/// The default playback buffer size of a device.
-#define AUD_DEFAULT_BUFFER_SIZE 1024
-
-/**
- * The format of a sample.
- * The last 4 bit save the byte count of the format.
- */
-typedef enum
-{
- AUD_FORMAT_INVALID = 0x00, /// Invalid sample format.
- AUD_FORMAT_U8 = 0x01, /// 1 byte unsigned byte.
- AUD_FORMAT_S16 = 0x12, /// 2 byte signed integer.
- AUD_FORMAT_S24 = 0x13, /// 3 byte signed integer.
- AUD_FORMAT_S32 = 0x14, /// 4 byte signed integer.
- AUD_FORMAT_FLOAT32 = 0x24, /// 4 byte float.
- AUD_FORMAT_FLOAT64 = 0x28 /// 8 byte float.
-} AUD_SampleFormat;
-
-/// The channel count.
-typedef enum
-{
- AUD_CHANNELS_INVALID = 0, /// Invalid channel count.
- AUD_CHANNELS_MONO = 1, /// Mono.
- AUD_CHANNELS_STEREO = 2, /// Stereo.
- AUD_CHANNELS_STEREO_LFE = 3, /// Stereo with LFE channel.
- AUD_CHANNELS_SURROUND4 = 4, /// 4 channel surround sound.
- AUD_CHANNELS_SURROUND5 = 5, /// 5 channel surround sound.
- AUD_CHANNELS_SURROUND51 = 6, /// 5.1 surround sound.
- AUD_CHANNELS_SURROUND61 = 7, /// 6.1 surround sound.
- AUD_CHANNELS_SURROUND71 = 8 /// 7.1 surround sound.
-} AUD_Channels;
-
-/// The channel names.
-typedef enum
-{
- AUD_CHANNEL_FRONT_LEFT = 0,
- AUD_CHANNEL_FRONT_RIGHT,
- AUD_CHANNEL_FRONT_CENTER,
- AUD_CHANNEL_LFE,
- AUD_CHANNEL_REAR_LEFT,
- AUD_CHANNEL_REAR_RIGHT,
- AUD_CHANNEL_REAR_CENTER,
- AUD_CHANNEL_SIDE_LEFT,
- AUD_CHANNEL_SIDE_RIGHT,
- AUD_CHANNEL_MAX
-} AUD_Channel;
-
-/**
- * The sample rate tells how many samples are played back within one second.
- * Some exotic formats may use other sample rates than provided here.
- */
-typedef enum
-{
- AUD_RATE_INVALID = 0, /// Invalid sample rate.
- AUD_RATE_8000 = 8000, /// 8000 Hz.
- AUD_RATE_16000 = 16000, /// 16000 Hz.
- AUD_RATE_11025 = 11025, /// 11025 Hz.
- AUD_RATE_22050 = 22050, /// 22050 Hz.
- AUD_RATE_32000 = 32000, /// 32000 Hz.
- AUD_RATE_44100 = 44100, /// 44100 Hz.
- AUD_RATE_48000 = 48000, /// 48000 Hz.
- AUD_RATE_88200 = 88200, /// 88200 Hz.
- AUD_RATE_96000 = 96000, /// 96000 Hz.
- AUD_RATE_192000 = 192000 /// 192000 Hz.
-} AUD_DefaultSampleRate;
-
-/// Status of a playback handle.
-typedef enum
-{
- AUD_STATUS_INVALID = 0, /// Invalid handle. Maybe due to stopping.
- AUD_STATUS_PLAYING, /// Sound is playing.
- AUD_STATUS_PAUSED, /// Sound is being paused.
- AUD_STATUS_STOPPED /// Sound is stopped but kept in the device.
-} AUD_Status;
-
-/// Error codes for exceptions (C++ library) or for return values (C API).
-typedef enum
-{
- AUD_NO_ERROR = 0,
- AUD_ERROR_SPECS,
- AUD_ERROR_PROPS,
- AUD_ERROR_FILE,
- AUD_ERROR_SRC,
- AUD_ERROR_FFMPEG,
- AUD_ERROR_OPENAL,
- AUD_ERROR_SDL,
- AUD_ERROR_JACK
-} AUD_Error;
-
-/// Fading types.
-typedef enum
-{
- AUD_FADE_IN,
- AUD_FADE_OUT
-} AUD_FadeType;
-
-/// Possible distance models for the 3D device.
-typedef enum
-{
- AUD_DISTANCE_MODEL_INVALID = 0,
- AUD_DISTANCE_MODEL_INVERSE,
- AUD_DISTANCE_MODEL_INVERSE_CLAMPED,
- AUD_DISTANCE_MODEL_LINEAR,
- AUD_DISTANCE_MODEL_LINEAR_CLAMPED,
- AUD_DISTANCE_MODEL_EXPONENT,
- AUD_DISTANCE_MODEL_EXPONENT_CLAMPED
-} AUD_DistanceModel;
-
-/// Possible animatable properties for Sequencer Factories and Entries.
-typedef enum
-{
- AUD_AP_VOLUME,
- AUD_AP_PANNING,
- AUD_AP_PITCH,
- AUD_AP_LOCATION,
- AUD_AP_ORIENTATION
-} AUD_AnimateablePropertyType;
-
-/// Container formats for writers.
-typedef enum
-{
- AUD_CONTAINER_INVALID = 0,
- AUD_CONTAINER_AC3,
- AUD_CONTAINER_FLAC,
- AUD_CONTAINER_MATROSKA,
- AUD_CONTAINER_MP2,
- AUD_CONTAINER_MP3,
- AUD_CONTAINER_OGG,
- AUD_CONTAINER_WAV
-} AUD_Container;
-
-/// Audio codecs for writers.
-typedef enum
-{
- AUD_CODEC_INVALID = 0,
- AUD_CODEC_AAC,
- AUD_CODEC_AC3,
- AUD_CODEC_FLAC,
- AUD_CODEC_MP2,
- AUD_CODEC_MP3,
- AUD_CODEC_PCM,
- AUD_CODEC_VORBIS
-} AUD_Codec;
-
-/// Sample type.(float samples)
-typedef float sample_t;
-
-/// Sample data type (format samples)
-typedef unsigned char data_t;
-
-/// Sample rate type.
-typedef double AUD_SampleRate;
-
-/// Specification of a sound source.
-typedef struct
-{
- /// Sample rate in Hz.
- AUD_SampleRate rate;
-
- /// Channel count.
- AUD_Channels channels;
-} AUD_Specs;
-
-/// Specification of a sound device.
-typedef struct
-{
- /// Sample format.
- AUD_SampleFormat format;
-
- union
- {
- struct
- {
- /// Sample rate in Hz.
- AUD_SampleRate rate;
-
- /// Channel count.
- AUD_Channels channels;
- };
- AUD_Specs specs;
- };
-} AUD_DeviceSpecs;
-
-/// Exception structure.
-typedef struct
-{
- /**
- * Error code.
- * \see AUD_Error
- */
- AUD_Error error;
-
- /**
- * Error string.
- */
- const char* str;
-
- // void* userData; - for the case it is needed someday
-} AUD_Exception;
-
-#endif //__AUD_SPACE_H__
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
deleted file mode 100644
index daa714aeec3..00000000000
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
+++ /dev/null
@@ -1,76 +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_StreamBufferFactory.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_StreamBufferFactory.h"
-#include "AUD_BufferReader.h"
-#include "AUD_Buffer.h"
-
-#include <cstring>
-
-AUD_StreamBufferFactory::AUD_StreamBufferFactory(boost::shared_ptr<AUD_IFactory> factory) :
- m_buffer(new AUD_Buffer())
-{
- boost::shared_ptr<AUD_IReader> reader = factory->createReader();
-
- m_specs = reader->getSpecs();
-
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
- int length;
- int index = 0;
- bool eos = false;
-
- // get an approximated size if possible
- int size = reader->getLength();
-
- if(size <= 0)
- size = AUD_BUFFER_RESIZE_BYTES / sample_size;
- else
- size += m_specs.rate;
-
- // as long as the end of the stream is not reached
- while(!eos)
- {
- // increase
- m_buffer->resize(size*sample_size, true);
-
- // read more
- length = size-index;
- reader->read(length, eos, m_buffer->getBuffer() + index * m_specs.channels);
- if(index == m_buffer->getSize() / sample_size)
- size += AUD_BUFFER_RESIZE_BYTES / sample_size;
- index += length;
- }
-
- m_buffer->resize(index * sample_size, true);
-}
-
-boost::shared_ptr<AUD_IReader> AUD_StreamBufferFactory::createReader()
-{
- 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
deleted file mode 100644
index 1bcd73d59b6..00000000000
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.h
+++ /dev/null
@@ -1,71 +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_StreamBufferFactory.h
- * \ingroup audaspaceintern
- */
-
-
-#ifndef __AUD_STREAMBUFFERFACTORY_H__
-#define __AUD_STREAMBUFFERFACTORY_H__
-
-#include "AUD_IFactory.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.
- */
-class AUD_StreamBufferFactory : public AUD_IFactory
-{
-private:
- /**
- * The buffer that holds the audio data.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- /**
- * The specification of the samples.
- */
- AUD_Specs m_specs;
-
- // hide copy constructor and operator=
- AUD_StreamBufferFactory(const AUD_StreamBufferFactory&);
- AUD_StreamBufferFactory& operator=(const AUD_StreamBufferFactory&);
-
-public:
- /**
- * Creates the factory and reads the reader created by the factory supplied
- * to the buffer.
- * \param factory The factory that creates the reader for buffering.
- * \exception AUD_Exception Thrown if the reader cannot be created.
- */
- AUD_StreamBufferFactory(boost::shared_ptr<AUD_IFactory> factory);
-
- virtual boost::shared_ptr<AUD_IReader> createReader();
-};
-
-#endif //__AUD_STREAMBUFFERFACTORY_H__
diff --git a/intern/audaspace/jack/AUD_JackDevice.cpp b/intern/audaspace/jack/AUD_JackDevice.cpp
deleted file mode 100644
index cfbf80ac110..00000000000
--- a/intern/audaspace/jack/AUD_JackDevice.cpp
+++ /dev/null
@@ -1,348 +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/jack/AUD_JackDevice.cpp
- * \ingroup audjack
- */
-
-#include "AUD_JackDevice.h"
-#include "AUD_IReader.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-
-void* AUD_JackDevice::runMixingThread(void* device)
-{
- ((AUD_JackDevice*)device)->updateRingBuffers();
- return NULL;
-}
-
-void AUD_JackDevice::updateRingBuffers()
-{
- size_t size, temp;
- unsigned int samplesize = AUD_SAMPLE_SIZE(m_specs);
- unsigned int i, j;
- unsigned int channels = m_specs.channels;
- sample_t* buffer = m_buffer.getBuffer();
- float* deinterleave = m_deinterleavebuf.getBuffer();
- jack_transport_state_t state;
- jack_position_t position;
-
- pthread_mutex_lock(&m_mixingLock);
- while(m_valid)
- {
- if(m_sync > 1)
- {
- if(m_syncFunc)
- {
- state = AUD_jack_transport_query(m_client, &position);
- m_syncFunc(m_syncFuncData, state != JackTransportStopped, position.frame / (float) m_specs.rate);
- }
-
- for(i = 0; i < channels; i++)
- AUD_jack_ringbuffer_reset(m_ringbuffers[i]);
- }
-
- size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
- for(i = 1; i < channels; i++)
- if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
- size = temp;
-
- while(size > samplesize)
- {
- size /= samplesize;
- mix((data_t*)buffer, size);
- for(i = 0; i < channels; i++)
- {
- for(j = 0; j < size; j++)
- deinterleave[i * size + j] = buffer[i + j * channels];
- AUD_jack_ringbuffer_write(m_ringbuffers[i], (char*)(deinterleave + i * size), size * sizeof(float));
- }
-
- size = AUD_jack_ringbuffer_write_space(m_ringbuffers[0]);
- for(i = 1; i < channels; i++)
- if((temp = AUD_jack_ringbuffer_write_space(m_ringbuffers[i])) < size)
- size = temp;
- }
-
- if(m_sync > 1)
- {
- m_sync = 3;
- }
-
- pthread_cond_wait(&m_mixingCondition, &m_mixingLock);
- }
- pthread_mutex_unlock(&m_mixingLock);
-}
-
-int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
-{
- AUD_JackDevice* device = (AUD_JackDevice*)data;
- unsigned int i;
- int count = device->m_specs.channels;
- char* buffer;
-
- if(device->m_sync)
- {
- // play silence while syncing
- for(unsigned int i = 0; i < count; i++)
- memset(AUD_jack_port_get_buffer(device->m_ports[i], length), 0, length * sizeof(float));
- }
- else
- {
- size_t temp;
- size_t readsamples = AUD_jack_ringbuffer_read_space(device->m_ringbuffers[0]);
- for(i = 1; i < count; i++)
- if((temp = AUD_jack_ringbuffer_read_space(device->m_ringbuffers[i])) < readsamples)
- readsamples = temp;
-
- readsamples = AUD_MIN(readsamples / sizeof(float), length);
-
- for(unsigned int i = 0; i < count; i++)
- {
- buffer = (char*)AUD_jack_port_get_buffer(device->m_ports[i], length);
- AUD_jack_ringbuffer_read(device->m_ringbuffers[i], buffer, readsamples * sizeof(float));
- if(readsamples < length)
- memset(buffer + readsamples * sizeof(float), 0, (length - readsamples) * sizeof(float));
- }
-
- if(pthread_mutex_trylock(&(device->m_mixingLock)) == 0)
- {
- pthread_cond_signal(&(device->m_mixingCondition));
- pthread_mutex_unlock(&(device->m_mixingLock));
- }
- }
-
- return 0;
-}
-
-int AUD_JackDevice::jack_sync(jack_transport_state_t state, jack_position_t* pos, void* data)
-{
- AUD_JackDevice* device = (AUD_JackDevice*)data;
-
- if(state == JackTransportStopped)
- return 1;
-
- if(pthread_mutex_trylock(&(device->m_mixingLock)) == 0)
- {
- if(device->m_sync > 2)
- {
- if(device->m_sync == 3)
- {
- device->m_sync = 0;
- pthread_mutex_unlock(&(device->m_mixingLock));
- return 1;
- }
- }
- else
- {
- device->m_sync = 2;
- pthread_cond_signal(&(device->m_mixingCondition));
- }
- pthread_mutex_unlock(&(device->m_mixingLock));
- }
- else if(!device->m_sync)
- device->m_sync = 1;
-
- return 0;
-}
-
-void AUD_JackDevice::jack_shutdown(void *data)
-{
- AUD_JackDevice* device = (AUD_JackDevice*)data;
- device->m_valid = false;
-}
-
-static const char* clientopen_error = "AUD_JackDevice: Couldn't connect to "
- "jack server.";
-static const char* port_error = "AUD_JackDevice: Couldn't create output port.";
-static const char* activate_error = "AUD_JackDevice: Couldn't activate the "
- "client.";
-
-AUD_JackDevice::AUD_JackDevice(std::string name, AUD_DeviceSpecs specs, int buffersize)
-{
- if(specs.channels == AUD_CHANNELS_INVALID)
- specs.channels = AUD_CHANNELS_STEREO;
-
- // jack uses floats
- m_specs = specs;
- m_specs.format = AUD_FORMAT_FLOAT32;
-
- jack_options_t options = JackNullOption;
- jack_status_t status;
-
- // open client
- m_client = AUD_jack_client_open(name.c_str(), options, &status);
- if(m_client == NULL)
- AUD_THROW(AUD_ERROR_JACK, clientopen_error);
-
- // set callbacks
- AUD_jack_set_process_callback(m_client, AUD_JackDevice::jack_mix, this);
- AUD_jack_on_shutdown(m_client, AUD_JackDevice::jack_shutdown, this);
- AUD_jack_set_sync_callback(m_client, AUD_JackDevice::jack_sync, this);
-
- // register our output channels which are called ports in jack
- m_ports = new jack_port_t*[m_specs.channels];
-
- try
- {
- char portname[64];
- for(int i = 0; i < m_specs.channels; i++)
- {
- sprintf(portname, "out %d", i+1);
- m_ports[i] = AUD_jack_port_register(m_client, portname,
- JACK_DEFAULT_AUDIO_TYPE,
- JackPortIsOutput, 0);
- if(m_ports[i] == NULL)
- AUD_THROW(AUD_ERROR_JACK, port_error);
- }
- }
- catch(AUD_Exception&)
- {
- AUD_jack_client_close(m_client);
- delete[] m_ports;
- throw;
- }
-
- m_specs.rate = (AUD_SampleRate)AUD_jack_get_sample_rate(m_client);
-
- buffersize *= sizeof(sample_t);
- m_ringbuffers = new jack_ringbuffer_t*[specs.channels];
- for(unsigned int i = 0; i < specs.channels; i++)
- m_ringbuffers[i] = AUD_jack_ringbuffer_create(buffersize);
- buffersize *= specs.channels;
- m_deinterleavebuf.resize(buffersize);
- m_buffer.resize(buffersize);
-
- create();
-
- m_valid = true;
- m_sync = 0;
- m_syncFunc = NULL;
- m_nextState = m_state = AUD_jack_transport_query(m_client, NULL);
-
- pthread_mutex_init(&m_mixingLock, NULL);
- pthread_cond_init(&m_mixingCondition, NULL);
-
- // activate the client
- if(AUD_jack_activate(m_client))
- {
- AUD_jack_client_close(m_client);
- delete[] m_ports;
- for(unsigned int i = 0; i < specs.channels; i++)
- AUD_jack_ringbuffer_free(m_ringbuffers[i]);
- delete[] m_ringbuffers;
- pthread_mutex_destroy(&m_mixingLock);
- pthread_cond_destroy(&m_mixingCondition);
- destroy();
-
- AUD_THROW(AUD_ERROR_JACK, activate_error);
- }
-
- const char** ports = AUD_jack_get_ports(m_client, NULL, NULL,
- JackPortIsPhysical | JackPortIsInput);
- if(ports != NULL)
- {
- for(int i = 0; i < m_specs.channels && ports[i]; i++)
- AUD_jack_connect(m_client, AUD_jack_port_name(m_ports[i]), ports[i]);
-
- free(ports);
- }
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- pthread_create(&m_mixingThread, &attr, runMixingThread, this);
-
- pthread_attr_destroy(&attr);
-}
-
-AUD_JackDevice::~AUD_JackDevice()
-{
- if(m_valid)
- AUD_jack_client_close(m_client);
- m_valid = false;
-
- delete[] m_ports;
-
- pthread_mutex_lock(&m_mixingLock);
- pthread_cond_signal(&m_mixingCondition);
- pthread_mutex_unlock(&m_mixingLock);
- pthread_join(m_mixingThread, NULL);
-
- pthread_cond_destroy(&m_mixingCondition);
- pthread_mutex_destroy(&m_mixingLock);
- for(unsigned int i = 0; i < m_specs.channels; i++)
- AUD_jack_ringbuffer_free(m_ringbuffers[i]);
- delete[] m_ringbuffers;
-
- destroy();
-}
-
-void AUD_JackDevice::playing(bool playing)
-{
- // Do nothing.
-}
-
-void AUD_JackDevice::startPlayback()
-{
- AUD_jack_transport_start(m_client);
- m_nextState = JackTransportRolling;
-}
-
-void AUD_JackDevice::stopPlayback()
-{
- AUD_jack_transport_stop(m_client);
- m_nextState = JackTransportStopped;
-}
-
-void AUD_JackDevice::seekPlayback(float time)
-{
- if(time >= 0.0f)
- AUD_jack_transport_locate(m_client, time * m_specs.rate);
-}
-
-void AUD_JackDevice::setSyncCallback(AUD_syncFunction sync, void* data)
-{
- m_syncFunc = sync;
- m_syncFuncData = data;
-}
-
-float AUD_JackDevice::getPlaybackPosition()
-{
- jack_position_t position;
- AUD_jack_transport_query(m_client, &position);
- return position.frame / (float) m_specs.rate;
-}
-
-bool AUD_JackDevice::doesPlayback()
-{
- jack_transport_state_t state = AUD_jack_transport_query(m_client, NULL);
-
- if(state != m_state)
- m_nextState = m_state = state;
-
- return m_nextState != JackTransportStopped;
-}
diff --git a/intern/audaspace/jack/AUD_JackLibrary.cpp b/intern/audaspace/jack/AUD_JackLibrary.cpp
deleted file mode 100644
index 9ed6862bbb9..00000000000
--- a/intern/audaspace/jack/AUD_JackLibrary.cpp
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2013 Blender Foundation
- *
- * 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/jack/AUD_JackLibrary.cpp
- * \ingroup audjack
- */
-
-#define AUD_JACK_LIBRARY_IMPL
-
-#include "AUD_JackLibrary.h"
-
-#ifdef WITH_JACK_DYNLOAD
-# include <dlfcn.h>
-# include <stdio.h>
-#endif
-
-#ifdef WITH_JACK_DYNLOAD
-static void *jack_handle = NULL;
-#endif
-
-static bool jack_supported = false;
-
-void AUD_jack_init(void)
-{
-#ifdef WITH_JACK_DYNLOAD
- const char *names[] = {"libjack.so",
- "libjack.so.0",
- "libjack.so.1",
- "libjack.so.2",
- NULL};
- int index = 0;
- while (names[index] != NULL) {
- jack_handle = dlopen(names[index], RTLD_LAZY);
- if (jack_handle != NULL) {
- // Found existing library.
- break;
- }
- ++index;
- }
-
- if (!jack_handle) {
- return;
- }
-
-# define JACK_SYMBOL(sym) \
- { \
- char *error; \
- *(void **) (&(AUD_##sym)) = dlsym(jack_handle, #sym); \
- if ((error = dlerror()) != NULL) { \
- fprintf(stderr, "%s\n", error); \
- return; \
- } \
- } (void)0
-
- dlerror(); /* Clear any existing error */
-#else // WITH_JACK_DYNLOAD
-# define JACK_SYMBOL(sym) AUD_##sym = sym
-#endif // WITH_JACK_DYNLOAD
-
- JACK_SYMBOL(jack_transport_query);
- JACK_SYMBOL(jack_transport_locate);
-
- JACK_SYMBOL(jack_transport_start);
- JACK_SYMBOL(jack_transport_stop);
-
- JACK_SYMBOL(jack_ringbuffer_reset);
- JACK_SYMBOL(jack_ringbuffer_write);
- JACK_SYMBOL(jack_ringbuffer_write_space);
- JACK_SYMBOL(jack_ringbuffer_write_advance);
- JACK_SYMBOL(jack_ringbuffer_read);
- JACK_SYMBOL(jack_ringbuffer_create);
- JACK_SYMBOL(jack_ringbuffer_free);
- JACK_SYMBOL(jack_ringbuffer_read_space);
- JACK_SYMBOL(jack_set_sync_callback);
-
- JACK_SYMBOL(jack_port_get_buffer);
-
- JACK_SYMBOL(jack_client_open);
- JACK_SYMBOL(jack_set_process_callback);
- JACK_SYMBOL(jack_on_shutdown);
- JACK_SYMBOL(jack_port_register);
- JACK_SYMBOL(jack_client_close);
- JACK_SYMBOL(jack_get_sample_rate);
- JACK_SYMBOL(jack_activate);
- JACK_SYMBOL(jack_get_ports);
- JACK_SYMBOL(jack_port_name);
- JACK_SYMBOL(jack_connect);
-
- jack_supported = true;
-
-#undef JACK_SYMBOL
-}
-
-void AUD_jack_exit(void)
-{
-#ifdef WITH_JACK_DYNLOAD
- if (jack_handle) {
- dlclose(jack_handle);
- }
-#endif
- jack_supported = false;
-}
-
-bool AUD_jack_supported(void)
-{
- return jack_supported;
-}
diff --git a/intern/audaspace/jack/AUD_JackLibrary.h b/intern/audaspace/jack/AUD_JackLibrary.h
deleted file mode 100644
index d74d9ba8021..00000000000
--- a/intern/audaspace/jack/AUD_JackLibrary.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2013 Blender Foundation
- *
- * 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/jack/AUD_JackLibrary.cpp
- * \ingroup audjack
- */
-
-#ifndef __AUD_JACKLIBRARY__
-#define __AUD_JACKLIBRARY__
-
-#if defined(__APPLE__) // always first include for jack weaklinking !
-#include <weakjack.h>
-#endif
-
-#include <jack.h>
-#include <ringbuffer.h>
-
-#ifdef AUD_JACK_LIBRARY_IMPL
-# define JACK_SYM
-#else
-# define JACK_SYM extern
-#endif
-
-/* All loadable JACK sumbols, prototypes from original jack.h */
-
-JACK_SYM jack_transport_state_t (*AUD_jack_transport_query) (
- const jack_client_t *client,
- jack_position_t *pos);
-
-JACK_SYM int (*AUD_jack_transport_locate) (jack_client_t *client,
- jack_nframes_t frame);
-
-JACK_SYM void (*AUD_jack_transport_start) (jack_client_t *client);
-JACK_SYM void (*AUD_jack_transport_stop) (jack_client_t *client);
-
-JACK_SYM void (*AUD_jack_ringbuffer_reset) (jack_ringbuffer_t *rb);
-JACK_SYM size_t (*AUD_jack_ringbuffer_write) (jack_ringbuffer_t *rb,
- const char *src, size_t cnt);
-JACK_SYM size_t (*AUD_jack_ringbuffer_write_space) (const jack_ringbuffer_t *rb);
-JACK_SYM void (*AUD_jack_ringbuffer_write_advance) (jack_ringbuffer_t *rb,
- size_t cnt);
-JACK_SYM size_t (*AUD_jack_ringbuffer_read) (jack_ringbuffer_t *rb, char *dest,
- size_t cnt);
-JACK_SYM jack_ringbuffer_t *(*AUD_jack_ringbuffer_create) (size_t sz);
-JACK_SYM void (*AUD_jack_ringbuffer_free) (jack_ringbuffer_t *rb);
-JACK_SYM size_t (*AUD_jack_ringbuffer_read_space) (const jack_ringbuffer_t *rb);
-JACK_SYM int (*AUD_jack_set_sync_callback) (jack_client_t *client,
- JackSyncCallback sync_callback,
- void *arg);
-
-JACK_SYM void *(*AUD_jack_port_get_buffer) (jack_port_t *, jack_nframes_t);
-
-JACK_SYM jack_client_t *(*AUD_jack_client_open) (const char *client_name,
- jack_options_t options,
- jack_status_t *status, ...);
-JACK_SYM int (*AUD_jack_set_process_callback) (jack_client_t *client,
- JackProcessCallback process_callback, void *arg);
-JACK_SYM void (*AUD_jack_on_shutdown) (jack_client_t *client,
- JackShutdownCallback function, void *arg);
-JACK_SYM jack_port_t *(*AUD_jack_port_register) (jack_client_t *client,
- const char *port_name,
- const char *port_type,
- unsigned long flags,
- unsigned long buffer_size);
-JACK_SYM int (*AUD_jack_client_close) (jack_client_t *client);
-JACK_SYM jack_nframes_t (*AUD_jack_get_sample_rate) (jack_client_t *);
-JACK_SYM int (*AUD_jack_activate) (jack_client_t *client);
-JACK_SYM const char **(*AUD_jack_get_ports) (jack_client_t *,
- const char *port_name_pattern,
- const char *type_name_pattern,
- unsigned long flags);
-JACK_SYM const char *(*AUD_jack_port_name) (const jack_port_t *port);
-JACK_SYM int (*AUD_jack_connect) (jack_client_t *,
- const char *source_port,
- const char *destination_port);
-
-/* Public API */
-
-void AUD_jack_init(void);
-void AUD_jack_exit(void);
-bool AUD_jack_supported(void);
-
-#endif // __AUD_JACKLIBRARY__
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
deleted file mode 100644
index 106b2937a06..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
+++ /dev/null
@@ -1,52 +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/sndfile/AUD_SndFileFactory.cpp
- * \ingroup audsndfile
- */
-
-
-#include "AUD_SndFileFactory.h"
-#include "AUD_SndFileReader.h"
-
-#include <cstring>
-
-AUD_SndFileFactory::AUD_SndFileFactory(std::string filename) :
- m_filename(filename)
-{
-}
-
-AUD_SndFileFactory::AUD_SndFileFactory(const data_t* buffer, int size) :
- m_buffer(new AUD_Buffer(size))
-{
- memcpy(m_buffer->getBuffer(), buffer, size);
-}
-
-boost::shared_ptr<AUD_IReader> AUD_SndFileFactory::createReader()
-{
- if(m_buffer.get())
- return boost::shared_ptr<AUD_IReader>(new AUD_SndFileReader(m_buffer));
- else
- 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
deleted file mode 100644
index bc96325d6eb..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.h
+++ /dev/null
@@ -1,76 +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/sndfile/AUD_SndFileFactory.h
- * \ingroup audsndfile
- */
-
-
-#ifndef __AUD_SNDFILEFACTORY_H__
-#define __AUD_SNDFILEFACTORY_H__
-
-#include "AUD_IFactory.h"
-#include "AUD_Buffer.h"
-
-#include <string>
-#include <boost/shared_ptr.hpp>
-
-/**
- * This factory reads a sound file via libsndfile.
- */
-class AUD_SndFileFactory : public AUD_IFactory
-{
-private:
- /**
- * The filename of the sound source file.
- */
- std::string m_filename;
-
- /**
- * The buffer to read from.
- */
- boost::shared_ptr<AUD_Buffer> m_buffer;
-
- // hide copy constructor and operator=
- AUD_SndFileFactory(const AUD_SndFileFactory&);
- AUD_SndFileFactory& operator=(const AUD_SndFileFactory&);
-
-public:
- /**
- * Creates a new factory.
- * \param filename The sound file path.
- */
- AUD_SndFileFactory(std::string filename);
-
- /**
- * Creates a new factory.
- * \param buffer The buffer to read from.
- * \param size The size of the buffer.
- */
- AUD_SndFileFactory(const data_t* buffer, int size);
-
- 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
deleted file mode 100644
index aaee814f56b..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileReader.cpp
+++ /dev/null
@@ -1,171 +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/sndfile/AUD_SndFileReader.cpp
- * \ingroup audsndfile
- */
-
-
-#include "AUD_SndFileReader.h"
-
-#include <cstring>
-
-sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
-{
- AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
- return reader->m_membuffer->getSize();
-}
-
-sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
- void *user_data)
-{
- AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
-
- switch(whence)
- {
- case SEEK_SET:
- reader->m_memoffset = offset;
- break;
- case SEEK_CUR:
- reader->m_memoffset = reader->m_memoffset + offset;
- break;
- case SEEK_END:
- reader->m_memoffset = reader->m_membuffer->getSize() + offset;
- break;
- }
-
- return reader->m_memoffset;
-}
-
-sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count,
- void *user_data)
-{
- AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
-
- if(reader->m_memoffset + count > reader->m_membuffer->getSize())
- count = reader->m_membuffer->getSize() - reader->m_memoffset;
-
- memcpy(ptr, ((data_t*)reader->m_membuffer->getBuffer()) +
- reader->m_memoffset, count);
- reader->m_memoffset += count;
-
- return count;
-}
-
-sf_count_t AUD_SndFileReader::vio_tell(void *user_data)
-{
- AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
-
- return reader->m_memoffset;
-}
-
-static const char* fileopen_error = "AUD_SndFileReader: File couldn't be "
- "read.";
-
-AUD_SndFileReader::AUD_SndFileReader(std::string filename) :
- m_position(0)
-{
- SF_INFO sfinfo;
-
- sfinfo.format = 0;
- m_sndfile = sf_open(filename.c_str(), SFM_READ, &sfinfo);
-
- if(!m_sndfile)
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
-
- m_specs.channels = (AUD_Channels) sfinfo.channels;
- m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
- m_length = sfinfo.frames;
- m_seekable = sfinfo.seekable;
-}
-
-AUD_SndFileReader::AUD_SndFileReader(boost::shared_ptr<AUD_Buffer> buffer) :
- m_position(0),
- m_membuffer(buffer),
- m_memoffset(0)
-{
- m_vio.get_filelen = vio_get_filelen;
- m_vio.read = vio_read;
- m_vio.seek = vio_seek;
- m_vio.tell = vio_tell;
- m_vio.write = NULL;
-
- SF_INFO sfinfo;
-
- sfinfo.format = 0;
- m_sndfile = sf_open_virtual(&m_vio, SFM_READ, &sfinfo, this);
-
- if(!m_sndfile)
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
-
- m_specs.channels = (AUD_Channels) sfinfo.channels;
- m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
- m_length = sfinfo.frames;
- m_seekable = sfinfo.seekable;
-}
-
-AUD_SndFileReader::~AUD_SndFileReader()
-{
- sf_close(m_sndfile);
-}
-
-bool AUD_SndFileReader::isSeekable() const
-{
- return m_seekable;
-}
-
-void AUD_SndFileReader::seek(int position)
-{
- if(m_seekable)
- {
- position = sf_seek(m_sndfile, position, SEEK_SET);
- m_position = position;
- }
-}
-
-int AUD_SndFileReader::getLength() const
-{
- return m_length;
-}
-
-int AUD_SndFileReader::getPosition() const
-{
- return m_position;
-}
-
-AUD_Specs AUD_SndFileReader::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_SndFileReader::read(int& length, bool& eos, sample_t* buffer)
-{
- int olen = length;
-
- length = sf_readf_float(m_sndfile, buffer, length);
-
- m_position += length;
-
- eos = length < olen;
-}
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.h b/intern/audaspace/sndfile/AUD_SndFileReader.h
deleted file mode 100644
index 5cac5051ee2..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileReader.h
+++ /dev/null
@@ -1,128 +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/sndfile/AUD_SndFileReader.h
- * \ingroup audsndfile
- */
-
-
-#ifndef __AUD_SNDFILEREADER_H__
-#define __AUD_SNDFILEREADER_H__
-
-#include "AUD_IReader.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);
-
-/**
- * This class reads a sound file via libsndfile.
- */
-class AUD_SndFileReader : public AUD_IReader
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The sample count in the file.
- */
- int m_length;
-
- /**
- * Whether the file is seekable.
- */
- bool m_seekable;
-
- /**
- * The specification of the audio data.
- */
- AUD_Specs m_specs;
-
- /**
- * The sndfile.
- */
- SNDFILE* m_sndfile;
-
- /**
- * The virtual IO structure for memory file reading.
- */
- SF_VIRTUAL_IO m_vio;
-
- /**
- * The pointer to the memory file.
- */
- boost::shared_ptr<AUD_Buffer> m_membuffer;
-
- /**
- * The current reading pointer of the memory file.
- */
- int m_memoffset;
-
- // Functions for libsndfile virtual IO functionality
- static sf_count_t vio_get_filelen(void *user_data);
- static sf_count_t vio_seek(sf_count_t offset, int whence, void *user_data);
- static sf_count_t vio_read(void *ptr, sf_count_t count, void *user_data);
- static sf_count_t vio_tell(void *user_data);
-
- // hide copy constructor and operator=
- AUD_SndFileReader(const AUD_SndFileReader&);
- AUD_SndFileReader& operator=(const AUD_SndFileReader&);
-
-public:
- /**
- * Creates a new reader.
- * \param filename The path to the file to be read.
- * \exception AUD_Exception Thrown if the file specified does not exist or
- * cannot be read with libsndfile.
- */
- AUD_SndFileReader(std::string filename);
-
- /**
- * Creates a new reader.
- * \param buffer The buffer to read from.
- * \exception AUD_Exception Thrown if the buffer specified cannot be read
- * with libsndfile.
- */
- AUD_SndFileReader(boost::shared_ptr<AUD_Buffer> buffer);
-
- /**
- * Destroys the reader and closes the file.
- */
- virtual ~AUD_SndFileReader();
-
- virtual bool isSeekable() const;
- virtual void seek(int position);
- virtual int getLength() const;
- virtual int getPosition() const;
- virtual AUD_Specs getSpecs() const;
- virtual void read(int& length, bool& eos, sample_t* buffer);
-};
-
-#endif //__AUD_SNDFILEREADER_H__
diff --git a/intern/audaspace/sndfile/AUD_SndFileWriter.cpp b/intern/audaspace/sndfile/AUD_SndFileWriter.cpp
deleted file mode 100644
index da3464751cb..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileWriter.cpp
+++ /dev/null
@@ -1,139 +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/sndfile/AUD_SndFileWriter.cpp
- * \ingroup audsndfile
- */
-
-
-#include "AUD_SndFileWriter.h"
-
-#include <cstring>
-
-static const char* fileopen_error = "AUD_SndFileWriter: File couldn't be written.";
-static const char* format_error = "AUD_SndFileWriter: Unsupported format.";
-
-AUD_SndFileWriter::AUD_SndFileWriter(std::string filename, AUD_DeviceSpecs specs,
- AUD_Container format, AUD_Codec codec, unsigned int bitrate) :
- m_specs(specs)
-{
- SF_INFO sfinfo;
-
- sfinfo.channels = specs.channels;
- sfinfo.samplerate = int(specs.rate);
-
- switch(format)
- {
- case AUD_CONTAINER_FLAC:
- sfinfo.format = SF_FORMAT_FLAC;
- switch(specs.format)
- {
- case AUD_FORMAT_S16:
- sfinfo.format |= SF_FORMAT_PCM_16;
- break;
- case AUD_FORMAT_S24:
- sfinfo.format |= SF_FORMAT_PCM_24;
- break;
- case AUD_FORMAT_S32:
- sfinfo.format |= SF_FORMAT_PCM_32;
- break;
- case AUD_FORMAT_FLOAT32:
- sfinfo.format |= SF_FORMAT_FLOAT;
- break;
- case AUD_FORMAT_FLOAT64:
- sfinfo.format |= SF_FORMAT_DOUBLE;
- break;
- default:
- sfinfo.format = 0;
- break;
- }
- break;
- case AUD_CONTAINER_OGG:
- if(codec == AUD_CODEC_VORBIS)
- sfinfo.format = SF_FORMAT_OGG | SF_FORMAT_VORBIS;
- else
- sfinfo.format = 0;
- break;
- case AUD_CONTAINER_WAV:
- sfinfo.format = SF_FORMAT_WAV;
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- sfinfo.format |= SF_FORMAT_PCM_U8;
- break;
- case AUD_FORMAT_S16:
- sfinfo.format |= SF_FORMAT_PCM_16;
- break;
- case AUD_FORMAT_S24:
- sfinfo.format |= SF_FORMAT_PCM_24;
- break;
- case AUD_FORMAT_S32:
- sfinfo.format |= SF_FORMAT_PCM_32;
- break;
- case AUD_FORMAT_FLOAT32:
- sfinfo.format |= SF_FORMAT_FLOAT;
- break;
- case AUD_FORMAT_FLOAT64:
- sfinfo.format |= SF_FORMAT_DOUBLE;
- break;
- default:
- sfinfo.format = 0;
- break;
- }
- break;
- default:
- sfinfo.format = 0;
- break;
- }
-
- if(sfinfo.format == 0)
- AUD_THROW(AUD_ERROR_SPECS, format_error);
-
- m_sndfile = sf_open(filename.c_str(), SFM_WRITE, &sfinfo);
-
- if(!m_sndfile)
- AUD_THROW(AUD_ERROR_FILE, fileopen_error);
-}
-
-AUD_SndFileWriter::~AUD_SndFileWriter()
-{
- sf_close(m_sndfile);
-}
-
-int AUD_SndFileWriter::getPosition() const
-{
- return m_position;
-}
-
-AUD_DeviceSpecs AUD_SndFileWriter::getSpecs() const
-{
- return m_specs;
-}
-
-void AUD_SndFileWriter::write(unsigned int length, sample_t* buffer)
-{
- length = sf_writef_float(m_sndfile, buffer, length);
-
- m_position += length;
-}
diff --git a/intern/audaspace/sndfile/AUD_SndFileWriter.h b/intern/audaspace/sndfile/AUD_SndFileWriter.h
deleted file mode 100644
index 0cadbd19a09..00000000000
--- a/intern/audaspace/sndfile/AUD_SndFileWriter.h
+++ /dev/null
@@ -1,86 +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/sndfile/AUD_SndFileWriter.h
- * \ingroup audsndfile
- */
-
-
-#ifndef __AUD_SNDFILEWRITER_H__
-#define __AUD_SNDFILEWRITER_H__
-
-#include "AUD_IWriter.h"
-
-#include <string>
-#include <sndfile.h>
-
-/**
- * This class writes a sound file via libsndfile.
- */
-class AUD_SndFileWriter : public AUD_IWriter
-{
-private:
- /**
- * The current position in samples.
- */
- int m_position;
-
- /**
- * The specification of the audio data.
- */
- AUD_DeviceSpecs m_specs;
-
- /**
- * The sndfile.
- */
- SNDFILE* m_sndfile;
-
- // hide copy constructor and operator=
- AUD_SndFileWriter(const AUD_SndFileWriter&);
- AUD_SndFileWriter& operator=(const AUD_SndFileWriter&);
-
-public:
- /**
- * Creates a new writer.
- * \param filename The path to the file to be read.
- * \param specs The file's audio specification.
- * \param format The file's container format.
- * \param codec The codec used for encoding the audio data.
- * \param bitrate The bitrate for encoding.
- * \exception AUD_Exception Thrown if the file specified cannot be written
- * with libsndfile.
- */
- AUD_SndFileWriter(std::string filename, AUD_DeviceSpecs specs, AUD_Container format, AUD_Codec codec, unsigned int bitrate);
-
- /**
- * Destroys the writer and closes the file.
- */
- virtual ~AUD_SndFileWriter();
-
- virtual int getPosition() const;
- virtual AUD_DeviceSpecs getSpecs() const;
- virtual void write(unsigned int length, sample_t* buffer);
-};
-
-#endif //__AUD_SNDFILEWRITER_H__
diff --git a/intern/cycles/blender/addon/presets.py b/intern/cycles/blender/addon/presets.py
index 440221b8470..dd4e8e60a42 100644
--- a/intern/cycles/blender/addon/presets.py
+++ b/intern/cycles/blender/addon/presets.py
@@ -37,7 +37,6 @@ class AddPresetIntegrator(AddPresetBase, Operator):
"cycles.transmission_bounces",
"cycles.volume_bounces",
"cycles.transparent_max_bounces",
- "cycles.use_transparent_shadows",
"cycles.caustics_reflective",
"cycles.caustics_refractive",
"cycles.blur_glossy"
@@ -68,7 +67,6 @@ class AddPresetSampling(AddPresetBase, Operator):
"cycles.mesh_light_samples",
"cycles.subsurface_samples",
"cycles.volume_samples",
- "cycles.use_square_samples",
"cycles.progressive",
"cycles.seed",
"cycles.sample_clamp_direct",
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index cfffe5362ca..cd71183acb6 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -172,12 +172,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
default='PATH',
)
- cls.use_square_samples = BoolProperty(
- name="Square Samples",
- description="Square sampling values for easier artist control",
- default=False,
- )
-
cls.samples = IntProperty(
name="Samples",
description="Number of samples to render for each pixel",
@@ -199,13 +193,13 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
name="AA Samples",
description="Number of antialiasing samples to render for each pixel",
min=1, max=2097151,
- default=4,
+ default=128,
)
cls.preview_aa_samples = IntProperty(
name="AA Samples",
description="Number of antialiasing samples to render in the viewport, unlimited if 0",
min=0, max=2097151,
- default=4,
+ default=32,
)
cls.diffuse_samples = IntProperty(
name="Diffuse Samples",
@@ -302,7 +296,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
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,
+ default=1.0,
)
cls.max_bounces = IntProperty(
@@ -343,11 +337,6 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
min=0, max=1024,
default=8,
)
- cls.use_transparent_shadows = BoolProperty(
- name="Transparent Shadows",
- description="Use transparency of surfaces for rendering shadows",
- default=True,
- )
cls.volume_step_size = FloatProperty(
name="Step Size",
@@ -452,7 +441,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
"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,
+ default=10.0,
)
cls.debug_tile_size = IntProperty(
diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py
index 59ee053efb9..5ae9466b40c 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -101,8 +101,6 @@ def draw_samples_info(layout, context):
# Calculate sample values
if integrator == 'PATH':
aa = cscene.samples
- if cscene.use_square_samples:
- aa = aa * aa
else:
aa = cscene.aa_samples
d = cscene.diffuse_samples
@@ -113,19 +111,9 @@ def draw_samples_info(layout, context):
sss = cscene.subsurface_samples
vol = cscene.volume_samples
- if cscene.use_square_samples:
- aa = aa * aa
- d = d * d
- g = g * g
- t = t * t
- ao = ao * ao
- ml = ml * ml
- sss = sss * sss
- vol = vol * vol
-
# Draw interface
# Do not draw for progressive, when Square Samples are disabled
- if use_branched_path(context) or (cscene.use_square_samples and integrator == 'PATH'):
+ if use_branched_path(context):
col = layout.column(align=True)
col.scale_y = 0.6
col.label("Total Samples:")
@@ -158,7 +146,7 @@ class CyclesRender_PT_sampling(CyclesButtonsPanel, Panel):
row = layout.row()
sub = row.row()
sub.prop(cscene, "progressive", text="")
- row.prop(cscene, "use_square_samples")
+ sub.label()
split = layout.split()
@@ -293,7 +281,6 @@ class CyclesRender_PT_light_paths(CyclesButtonsPanel, Panel):
sub = col.column(align=True)
sub.label("Transparency:")
sub.prop(cscene, "transparent_max_bounces", text="Max")
- sub.prop(cscene, "use_transparent_shadows", text="Shadows")
col.separator()
@@ -416,6 +403,7 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel):
col.prop(cscene, "debug_bvh_type", text="")
col.separator()
col.prop(cscene, "preview_start_resolution")
+ col.prop(rd, "preview_pixel_size", text="")
col.separator()
diff --git a/intern/cycles/blender/addon/version_update.py b/intern/cycles/blender/addon/version_update.py
index b2a745500a1..a37ac38c101 100644
--- a/intern/cycles/blender/addon/version_update.py
+++ b/intern/cycles/blender/addon/version_update.py
@@ -302,3 +302,36 @@ def do_versions(self):
cscene = scene.cycles
if not cscene.is_property_set("light_sampling_threshold"):
cscene.light_sampling_threshold = 0.0
+
+ if bpy.data.version <= (2, 79, 0):
+ for scene in bpy.data.scenes:
+ cscene = scene.cycles
+ # Default changes
+ if not cscene.is_property_set("aa_samples"):
+ cscene.aa_samples = 4
+ if not cscene.is_property_set("preview_aa_samples"):
+ cscene.preview_aa_samples = 4
+ if not cscene.is_property_set("blur_glossy"):
+ cscene.blur_glossy = 0.0
+ if not cscene.is_property_set("sample_clamp_indirect"):
+ cscene.sample_clamp_indirect = 0.0
+
+ # Remove and apply square samples
+ use_square_samples = cscene.get("use_square_samples", False)
+ if use_square_samples:
+ del cscene["use_square_samples"]
+
+ cscene.samples *= cscene.samples
+ cscene.preview_samples *= cscene.preview_samples
+ cscene.aa_samples *= cscene.aa_samples
+ cscene.preview_aa_samples *= cscene.preview_aa_samples
+ cscene.diffuse_samples *= cscene.diffuse_samples
+ cscene.glossy_samples *= cscene.glossy_samples
+ cscene.transmission_samples *= cscene.transmission_samples
+ cscene.ao_samples *= cscene.ao_samples
+ cscene.mesh_light_samples *= cscene.mesh_light_samples
+ cscene.subsurface_samples *= cscene.subsurface_samples
+ cscene.volume_samples *= cscene.volume_samples
+
+ for layer in scene.render.layers:
+ layer.samples *= layer.samples
diff --git a/intern/cycles/blender/blender_camera.cpp b/intern/cycles/blender/blender_camera.cpp
index 40d6b25f2b7..b29711d30d3 100644
--- a/intern/cycles/blender/blender_camera.cpp
+++ b/intern/cycles/blender/blender_camera.cpp
@@ -544,7 +544,11 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings& b_render,
if(tfm != cam->matrix) {
VLOG(1) << "Camera " << b_ob.name() << " motion detected.";
- if(motion_time == -1.0f) {
+ if(motion_time == 0.0f) {
+ /* When motion blur is not centered in frame, cam->matrix gets reset. */
+ cam->matrix = tfm;
+ }
+ else if(motion_time == -1.0f) {
cam->motion.pre = tfm;
cam->use_motion = true;
}
@@ -573,7 +577,10 @@ void BlenderSync::sync_camera_motion(BL::RenderSettings& b_render,
float fov = 2.0f * atanf((0.5f * sensor_size) / bcam.lens / aspectratio);
if(fov != cam->fov) {
VLOG(1) << "Camera " << b_ob.name() << " FOV change detected.";
- if(motion_time == -1.0f) {
+ if(motion_time == 0.0f) {
+ cam->fov = fov;
+ }
+ else if(motion_time == -1.0f) {
cam->fov_pre = fov;
cam->use_perspective_motion = true;
}
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 991b834dcfa..6b46402730e 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -163,16 +163,11 @@ void BlenderSync::sync_light(BL::Object& b_parent,
light->shader = used_shaders[0];
/* shadow */
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
PointerRNA clamp = RNA_pointer_get(&b_lamp.ptr, "cycles");
light->cast_shadow = get_boolean(clamp, "cast_shadow");
light->use_mis = get_boolean(clamp, "use_multiple_importance_sampling");
- int samples = get_int(clamp, "samples");
- if(get_boolean(cscene, "use_square_samples"))
- light->samples = samples * samples;
- else
- light->samples = samples;
+ light->samples = get_int(clamp, "samples");
light->max_bounces = get_int(clamp, "max_bounces");
@@ -200,7 +195,6 @@ void BlenderSync::sync_background_light(bool use_portal)
BL::World b_world = b_scene.world();
if(b_world) {
- PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles");
PointerRNA cworld = RNA_pointer_get(&b_world.ptr, "cycles");
bool sample_as_light = get_boolean(cworld, "sample_as_light");
@@ -219,11 +213,7 @@ void BlenderSync::sync_background_light(bool use_portal)
light->use_mis = sample_as_light;
light->max_bounces = get_int(cworld, "max_bounces");
- int samples = get_int(cworld, "samples");
- if(get_boolean(cscene, "use_square_samples"))
- light->samples = samples * samples;
- else
- light->samples = samples;
+ light->samples = get_int(cworld, "samples");
light->tag_update(scene);
light_map.set_recalc(b_world);
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index bbf7dc720a8..b9af0dd0bf6 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -947,7 +947,6 @@ static BL::ShaderNode find_output_node(BL::ShaderNodeTree& b_ntree)
{
BL::ShaderNodeTree::nodes_iterator b_node;
BL::ShaderNode output_node(PointerRNA_NULL);
- BL::ShaderNode eevee_output_node(PointerRNA_NULL);
for(b_ntree.nodes.begin(b_node); b_node != b_ntree.nodes.end(); ++b_node) {
BL::ShaderNodeOutputMaterial b_output_node(*b_node);
@@ -964,19 +963,9 @@ static BL::ShaderNode find_output_node(BL::ShaderNodeTree& b_ntree)
output_node = b_output_node;
}
}
- else if (b_output_node.is_a(&RNA_ShaderNodeOutputEeveeMaterial)) {
- /* Eevee output used if no Cycles node exists */
- if(b_output_node.is_active_output()) {
- eevee_output_node = b_output_node;
- }
- else if(!eevee_output_node.ptr.data) {
- eevee_output_node = b_output_node;
- }
-
- }
}
- return (output_node.ptr.data) ? output_node : eevee_output_node;
+ return output_node;
}
static void add_nodes(Scene *scene,
diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp
index 15ad4ff301c..423f781dc17 100644
--- a/intern/cycles/blender/blender_sync.cpp
+++ b/intern/cycles/blender/blender_sync.cpp
@@ -245,7 +245,6 @@ void BlenderSync::sync_integrator()
integrator->max_volume_bounce = get_int(cscene, "volume_bounces");
integrator->transparent_max_bounce = get_int(cscene, "transparent_max_bounces");
- integrator->transparent_shadows = get_boolean(cscene, "use_transparent_shadows");
integrator->volume_max_steps = get_int(cscene, "volume_max_steps");
integrator->volume_step_size = get_float(cscene, "volume_step_size");
@@ -295,32 +294,13 @@ void BlenderSync::sync_integrator()
integrator->sample_all_lights_indirect = get_boolean(cscene, "sample_all_lights_indirect");
integrator->light_sampling_threshold = get_float(cscene, "light_sampling_threshold");
- int diffuse_samples = get_int(cscene, "diffuse_samples");
- int glossy_samples = get_int(cscene, "glossy_samples");
- int transmission_samples = get_int(cscene, "transmission_samples");
- int ao_samples = get_int(cscene, "ao_samples");
- int mesh_light_samples = get_int(cscene, "mesh_light_samples");
- int subsurface_samples = get_int(cscene, "subsurface_samples");
- int volume_samples = get_int(cscene, "volume_samples");
-
- if(get_boolean(cscene, "use_square_samples")) {
- integrator->diffuse_samples = diffuse_samples * diffuse_samples;
- integrator->glossy_samples = glossy_samples * glossy_samples;
- integrator->transmission_samples = transmission_samples * transmission_samples;
- integrator->ao_samples = ao_samples * ao_samples;
- integrator->mesh_light_samples = mesh_light_samples * mesh_light_samples;
- integrator->subsurface_samples = subsurface_samples * subsurface_samples;
- integrator->volume_samples = volume_samples * volume_samples;
- }
- else {
- integrator->diffuse_samples = diffuse_samples;
- integrator->glossy_samples = glossy_samples;
- integrator->transmission_samples = transmission_samples;
- integrator->ao_samples = ao_samples;
- integrator->mesh_light_samples = mesh_light_samples;
- integrator->subsurface_samples = subsurface_samples;
- integrator->volume_samples = volume_samples;
- }
+ integrator->diffuse_samples = get_int(cscene, "diffuse_samples");
+ integrator->glossy_samples = get_int(cscene, "glossy_samples");
+ integrator->transmission_samples = get_int(cscene, "transmission_samples");
+ integrator->ao_samples = get_int(cscene, "ao_samples");
+ integrator->mesh_light_samples = get_int(cscene, "mesh_light_samples");
+ integrator->subsurface_samples = get_int(cscene, "subsurface_samples");
+ integrator->volume_samples = get_int(cscene, "volume_samples");
if(b_scene.render().use_simplify()) {
if(preview) {
@@ -420,11 +400,7 @@ void BlenderSync::sync_render_layers(BL::SpaceView3D& b_v3d, const char *layer)
render_layer.bound_samples = (use_layer_samples == 1);
if(use_layer_samples != 2) {
- int samples = b_rlay->samples();
- if(get_boolean(cscene, "use_square_samples"))
- render_layer.samples = samples * samples;
- else
- render_layer.samples = samples;
+ render_layer.samples = b_rlay->samples();
}
}
@@ -739,14 +715,6 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
int preview_samples = get_int(cscene, "preview_samples");
int preview_aa_samples = get_int(cscene, "preview_aa_samples");
- if(get_boolean(cscene, "use_square_samples")) {
- aa_samples = aa_samples * aa_samples;
- preview_aa_samples = preview_aa_samples * preview_aa_samples;
-
- samples = samples * samples;
- preview_samples = preview_samples * preview_samples;
- }
-
if(get_enum(cscene, "progressive") == 0) {
if(background) {
params.samples = aa_samples;
@@ -793,6 +761,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
}
params.start_resolution = get_int(cscene, "preview_start_resolution");
+ params.pixel_size = b_engine.get_preview_pixel_size(b_scene);
/* other parameters */
if(b_scene.render().threads_mode() == BL::RenderSettings::threads_mode_FIXED)
@@ -813,6 +782,7 @@ SessionParams BlenderSync::get_session_params(BL::RenderEngine& b_engine,
params.progressive = false;
params.start_resolution = INT_MAX;
+ params.pixel_size = 1;
}
else
params.progressive = true;
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 33143e2d8aa..0ad3c8a7429 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -153,7 +153,6 @@ void BVH::pack_primitives()
if(pack.prim_index[i] != -1) {
int tob = pack.prim_object[i];
Object *ob = objects[tob];
-
if((pack.prim_type[i] & PRIMITIVE_ALL_TRIANGLE) != 0) {
pack_triangle(i, (float4*)&pack.prim_tri_verts[3 * prim_triangle_index]);
pack.prim_tri_index[i] = 3 * prim_triangle_index;
@@ -162,11 +161,10 @@ void BVH::pack_primitives()
else {
pack.prim_tri_index[i] = -1;
}
-
- pack.prim_visibility[i] = ob->visibility;
-
- if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE)
+ pack.prim_visibility[i] = ob->visibility_for_tracing();
+ if(pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
pack.prim_visibility[i] |= PATH_RAY_CURVE;
+ }
}
else {
pack.prim_tri_index[i] = -1;
diff --git a/intern/cycles/bvh/bvh2.cpp b/intern/cycles/bvh/bvh2.cpp
index 340ba7dcf53..9aa8e71dfd0 100644
--- a/intern/cycles/bvh/bvh2.cpp
+++ b/intern/cycles/bvh/bvh2.cpp
@@ -312,10 +312,8 @@ void BVH2::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
}
}
}
-
- visibility |= ob->visibility;
+ visibility |= ob->visibility_for_tracing();
}
-
/* TODO(sergey): De-duplicate with pack_leaf(). */
float4 leaf_data[BVH_NODE_LEAF_SIZE];
leaf_data[0].x = __int_as_float(c0);
diff --git a/intern/cycles/bvh/bvh4.cpp b/intern/cycles/bvh/bvh4.cpp
index 5034ab811d5..aeedd802f49 100644
--- a/intern/cycles/bvh/bvh4.cpp
+++ b/intern/cycles/bvh/bvh4.cpp
@@ -438,10 +438,8 @@ void BVH4::refit_node(int idx, bool leaf, BoundBox& bbox, uint& visibility)
}
}
}
-
- visibility |= ob->visibility;
+ visibility |= ob->visibility_for_tracing();
}
-
/* TODO(sergey): This is actually a copy of pack_leaf(),
* but this chunk of code only knows actual data and has
* no idea about BVHNode.
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index 1880964355c..eb1d89729fb 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -865,7 +865,7 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
prim_time[start] = make_float2(ref->time_from(), ref->time_to());
}
- uint visibility = objects[ref->prim_object()]->visibility;
+ const uint visibility = objects[ref->prim_object()]->visibility_for_tracing();
BVHNode *leaf_node = new LeafNode(ref->bounds(), visibility, start, start+1);
leaf_node->time_from = ref->time_from();
leaf_node->time_to = ref->time_to();
@@ -939,7 +939,7 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
ref.time_to()));
bounds[type_index].grow(ref.bounds());
- visibility[type_index] |= objects[ref.prim_object()]->visibility;
+ visibility[type_index] |= objects[ref.prim_object()]->visibility_for_tracing();
if(ref.prim_type() & PRIMITIVE_ALL_CURVE) {
visibility[type_index] |= PATH_RAY_CURVE;
}
@@ -1040,7 +1040,6 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
*/
start_index = spatial_free_index;
spatial_free_index += range.size();
-
/* Extend an array when needed. */
const size_t range_end = start_index + range.size();
if(prim_type.size() < range_end) {
@@ -1066,8 +1065,6 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
prim_time.resize(range_end);
}
}
- spatial_spin_lock.unlock();
-
/* Perform actual data copy. */
if(new_leaf_data_size > 0) {
memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
@@ -1077,6 +1074,7 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
}
}
+ spatial_spin_lock.unlock();
}
else {
/* For the regular BVH builder we simply copy new data starting at the
diff --git a/intern/cycles/device/CMakeLists.txt b/intern/cycles/device/CMakeLists.txt
index 74ec57ddf74..3c632160fbd 100644
--- a/intern/cycles/device/CMakeLists.txt
+++ b/intern/cycles/device/CMakeLists.txt
@@ -34,11 +34,13 @@ set(SRC
set(SRC_OPENCL
opencl/opencl.h
+ opencl/memory_manager.h
opencl/opencl_base.cpp
opencl/opencl_mega.cpp
opencl/opencl_split.cpp
opencl/opencl_util.cpp
+ opencl/memory_manager.cpp
)
if(WITH_CYCLES_NETWORK)
diff --git a/intern/cycles/device/device.cpp b/intern/cycles/device/device.cpp
index 31671e76ec3..5ae83b56fcd 100644
--- a/intern/cycles/device/device.cpp
+++ b/intern/cycles/device/device.cpp
@@ -526,11 +526,9 @@ DeviceInfo Device::get_multi_device(vector<DeviceInfo> subdevices)
info.num = 0;
info.has_bindless_textures = true;
- info.pack_images = false;
foreach(DeviceInfo &device, subdevices) {
assert(device.type == info.multi_devices[0].type);
- info.pack_images |= device.pack_images;
info.has_bindless_textures &= device.has_bindless_textures;
}
diff --git a/intern/cycles/device/device.h b/intern/cycles/device/device.h
index 68a555c1a93..8736a6927e0 100644
--- a/intern/cycles/device/device.h
+++ b/intern/cycles/device/device.h
@@ -53,7 +53,6 @@ public:
int num;
bool display_device;
bool advanced_shading;
- bool pack_images;
bool has_bindless_textures; /* flag for GPU and Multi device */
bool use_split_kernel; /* Denotes if the device is going to run cycles using split-kernel */
vector<DeviceInfo> multi_devices;
@@ -65,7 +64,6 @@ public:
num = 0;
display_device = false;
advanced_shading = true;
- pack_images = false;
has_bindless_textures = false;
use_split_kernel = false;
}
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 18112437b45..6e09c5f88c2 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -48,6 +48,7 @@
#include "util/util_logging.h"
#include "util/util_map.h"
#include "util/util_opengl.h"
+#include "util/util_optimization.h"
#include "util/util_progress.h"
#include "util/util_system.h"
#include "util/util_thread.h"
@@ -976,7 +977,6 @@ void device_cpu_info(vector<DeviceInfo>& devices)
info.id = "CPU";
info.num = 0;
info.advanced_shading = true;
- info.pack_images = false;
devices.insert(devices.begin(), info);
}
diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp
index e53aec0fbb9..c68eba7bef6 100644
--- a/intern/cycles/device/device_cuda.cpp
+++ b/intern/cycles/device/device_cuda.cpp
@@ -1919,17 +1919,13 @@ public:
int threads_per_block;
cuda_assert(cuFuncGetAttribute(&threads_per_block, CU_FUNC_ATTRIBUTE_MAX_THREADS_PER_BLOCK, func));
- int xthreads = (int)sqrt(threads_per_block);
- int ythreads = (int)sqrt(threads_per_block);
-
- int xblocks = (dim.global_size[0] + xthreads - 1)/xthreads;
- int yblocks = (dim.global_size[1] + ythreads - 1)/ythreads;
+ int xblocks = (dim.global_size[0]*dim.global_size[1] + threads_per_block - 1)/threads_per_block;
cuda_assert(cuFuncSetCacheConfig(func, CU_FUNC_CACHE_PREFER_L1));
cuda_assert(cuLaunchKernel(func,
- xblocks , yblocks, 1, /* blocks */
- xthreads, ythreads, 1, /* threads */
+ xblocks, 1, 1, /* blocks */
+ threads_per_block, 1, 1, /* threads */
0, 0, args, 0));
device->cuda_pop_context();
@@ -2189,7 +2185,6 @@ void device_cuda_info(vector<DeviceInfo>& devices)
info.advanced_shading = (major >= 2);
info.has_bindless_textures = (major >= 3);
- info.pack_images = false;
int pci_location[3] = {0, 0, 0};
cuDeviceGetAttribute(&pci_location[0], CU_DEVICE_ATTRIBUTE_PCI_DOMAIN_ID, num);
diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp
index 681b8214b03..aa380ec4b94 100644
--- a/intern/cycles/device/device_opencl.cpp
+++ b/intern/cycles/device/device_opencl.cpp
@@ -95,7 +95,6 @@ void device_opencl_info(vector<DeviceInfo>& devices)
/* We don't know if it's used for display, but assume it is. */
info.display_device = true;
info.advanced_shading = OpenCLInfo::kernel_use_advanced_shading(platform_name);
- info.pack_images = true;
info.use_split_kernel = OpenCLInfo::kernel_use_split(platform_name,
device_type);
info.id = string("OPENCL_") + platform_name + "_" + device_name + "_" + hardware_id;
diff --git a/intern/cycles/device/opencl/memory_manager.cpp b/intern/cycles/device/opencl/memory_manager.cpp
new file mode 100644
index 00000000000..b67dfef88aa
--- /dev/null
+++ b/intern/cycles/device/opencl/memory_manager.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright 2011-2017 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.
+ */
+
+#ifdef WITH_OPENCL
+
+#include "util/util_foreach.h"
+
+#include "device/opencl/opencl.h"
+#include "device/opencl/memory_manager.h"
+
+CCL_NAMESPACE_BEGIN
+
+void MemoryManager::DeviceBuffer::add_allocation(Allocation& allocation)
+{
+ allocations.push_back(&allocation);
+}
+
+void MemoryManager::DeviceBuffer::update_device_memory(OpenCLDeviceBase *device)
+{
+ bool need_realloc = false;
+
+ /* Calculate total size and remove any freed. */
+ size_t total_size = 0;
+
+ for(int i = allocations.size()-1; i >= 0; i--) {
+ Allocation* allocation = allocations[i];
+
+ /* Remove allocations that have been freed. */
+ if(!allocation->mem || allocation->mem->memory_size() == 0) {
+ allocation->device_buffer = NULL;
+ allocation->size = 0;
+
+ allocations.erase(allocations.begin()+i);
+
+ need_realloc = true;
+
+ continue;
+ }
+
+ /* Get actual size for allocation. */
+ size_t alloc_size = align_up(allocation->mem->memory_size(), 16);
+
+ if(allocation->size != alloc_size) {
+ /* Allocation is either new or resized. */
+ allocation->size = alloc_size;
+ allocation->needs_copy_to_device = true;
+
+ need_realloc = true;
+ }
+
+ total_size += alloc_size;
+ }
+
+ if(need_realloc) {
+ cl_ulong max_buffer_size;
+ clGetDeviceInfo(device->cdDevice, CL_DEVICE_MAX_MEM_ALLOC_SIZE, sizeof(cl_ulong), &max_buffer_size, NULL);
+
+ if(total_size > max_buffer_size) {
+ device->set_error("Scene too complex to fit in available memory.");
+ return;
+ }
+
+ device_memory *new_buffer = new device_memory;
+
+ new_buffer->resize(total_size);
+ device->mem_alloc(string_printf("buffer_%p", this).data(), *new_buffer, MEM_READ_ONLY);
+
+ size_t offset = 0;
+
+ foreach(Allocation* allocation, allocations) {
+ if(allocation->needs_copy_to_device) {
+ /* Copy from host to device. */
+ opencl_device_assert(device, clEnqueueWriteBuffer(device->cqCommandQueue,
+ CL_MEM_PTR(new_buffer->device_pointer),
+ CL_FALSE,
+ offset,
+ allocation->mem->memory_size(),
+ (void*)allocation->mem->data_pointer,
+ 0, NULL, NULL
+ ));
+
+ allocation->needs_copy_to_device = false;
+ }
+ else {
+ /* Fast copy from memory already on device. */
+ opencl_device_assert(device, clEnqueueCopyBuffer(device->cqCommandQueue,
+ CL_MEM_PTR(buffer->device_pointer),
+ CL_MEM_PTR(new_buffer->device_pointer),
+ allocation->desc.offset,
+ offset,
+ allocation->mem->memory_size(),
+ 0, NULL, NULL
+ ));
+ }
+
+ allocation->desc.offset = offset;
+ offset += allocation->size;
+ }
+
+ device->mem_free(*buffer);
+ delete buffer;
+
+ buffer = new_buffer;
+ }
+ else {
+ assert(total_size == buffer->data_size);
+
+ size_t offset = 0;
+
+ foreach(Allocation* allocation, allocations) {
+ if(allocation->needs_copy_to_device) {
+ /* Copy from host to device. */
+ opencl_device_assert(device, clEnqueueWriteBuffer(device->cqCommandQueue,
+ CL_MEM_PTR(buffer->device_pointer),
+ CL_FALSE,
+ offset,
+ allocation->mem->memory_size(),
+ (void*)allocation->mem->data_pointer,
+ 0, NULL, NULL
+ ));
+
+ allocation->needs_copy_to_device = false;
+ }
+
+ offset += allocation->size;
+ }
+ }
+
+ /* Not really necessary, but seems to improve responsiveness for some reason. */
+ clFinish(device->cqCommandQueue);
+}
+
+void MemoryManager::DeviceBuffer::free(OpenCLDeviceBase *device)
+{
+ device->mem_free(*buffer);
+}
+
+MemoryManager::DeviceBuffer* MemoryManager::smallest_device_buffer()
+{
+ DeviceBuffer* smallest = device_buffers;
+
+ foreach(DeviceBuffer& device_buffer, device_buffers) {
+ if(device_buffer.size < smallest->size) {
+ smallest = &device_buffer;
+ }
+ }
+
+ return smallest;
+}
+
+MemoryManager::MemoryManager(OpenCLDeviceBase *device) : device(device), need_update(false)
+{
+}
+
+void MemoryManager::free()
+{
+ foreach(DeviceBuffer& device_buffer, device_buffers) {
+ device_buffer.free(device);
+ }
+}
+
+void MemoryManager::alloc(const char *name, device_memory& mem)
+{
+ Allocation& allocation = allocations[name];
+
+ allocation.mem = &mem;
+ allocation.needs_copy_to_device = true;
+
+ if(!allocation.device_buffer) {
+ DeviceBuffer* device_buffer = smallest_device_buffer();
+ allocation.device_buffer = device_buffer;
+
+ allocation.desc.device_buffer = device_buffer - device_buffers;
+
+ device_buffer->add_allocation(allocation);
+
+ device_buffer->size += mem.memory_size();
+ }
+
+ need_update = true;
+}
+
+bool MemoryManager::free(device_memory& mem)
+{
+ foreach(AllocationsMap::value_type& value, allocations) {
+ Allocation& allocation = value.second;
+ if(allocation.mem == &mem) {
+
+ allocation.device_buffer->size -= mem.memory_size();
+
+ allocation.mem = NULL;
+ allocation.needs_copy_to_device = false;
+
+ need_update = true;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+MemoryManager::BufferDescriptor MemoryManager::get_descriptor(string name)
+{
+ update_device_memory();
+
+ Allocation& allocation = allocations[name];
+ return allocation.desc;
+}
+
+void MemoryManager::update_device_memory()
+{
+ if(!need_update) {
+ return;
+ }
+
+ need_update = false;
+
+ foreach(DeviceBuffer& device_buffer, device_buffers) {
+ device_buffer.update_device_memory(device);
+ }
+}
+
+void MemoryManager::set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg)
+{
+ update_device_memory();
+
+ foreach(DeviceBuffer& device_buffer, device_buffers) {
+ if(device_buffer.buffer->device_pointer) {
+ device->kernel_set_args(kernel, (*narg)++, *device_buffer.buffer);
+ }
+ else {
+ device->kernel_set_args(kernel, (*narg)++, device->null_mem);
+ }
+ }
+}
+
+CCL_NAMESPACE_END
+
+#endif /* WITH_OPENCL */
+
diff --git a/intern/cycles/device/opencl/memory_manager.h b/intern/cycles/device/opencl/memory_manager.h
new file mode 100644
index 00000000000..3714405d026
--- /dev/null
+++ b/intern/cycles/device/opencl/memory_manager.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2011-2017 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.
+ */
+
+#pragma once
+
+#include "device/device.h"
+
+#include "util/util_map.h"
+#include "util/util_vector.h"
+#include "util/util_string.h"
+
+#include "clew.h"
+
+CCL_NAMESPACE_BEGIN
+
+class OpenCLDeviceBase;
+
+class MemoryManager {
+public:
+ static const int NUM_DEVICE_BUFFERS = 8;
+
+ struct BufferDescriptor {
+ uint device_buffer;
+ cl_ulong offset;
+ };
+
+private:
+ struct DeviceBuffer;
+
+ struct Allocation {
+ device_memory *mem;
+
+ DeviceBuffer *device_buffer;
+ size_t size; /* Size of actual allocation, may be larger than requested. */
+
+ BufferDescriptor desc;
+
+ bool needs_copy_to_device;
+
+ Allocation() : mem(NULL), device_buffer(NULL), size(0), needs_copy_to_device(false)
+ {
+ }
+ };
+
+ struct DeviceBuffer {
+ device_memory *buffer;
+ vector<Allocation*> allocations;
+ size_t size; /* Size of all allocations. */
+
+ DeviceBuffer() : buffer(new device_memory), size(0)
+ {
+ }
+
+ ~DeviceBuffer() {
+ delete buffer;
+ buffer = NULL;
+ }
+
+ void add_allocation(Allocation& allocation);
+
+ void update_device_memory(OpenCLDeviceBase *device);
+
+ void free(OpenCLDeviceBase *device);
+ };
+
+ OpenCLDeviceBase *device;
+
+ DeviceBuffer device_buffers[NUM_DEVICE_BUFFERS];
+
+ typedef unordered_map<string, Allocation> AllocationsMap;
+ AllocationsMap allocations;
+
+ bool need_update;
+
+ DeviceBuffer* smallest_device_buffer();
+
+public:
+ MemoryManager(OpenCLDeviceBase *device);
+
+ void free(); /* Free all memory. */
+
+ void alloc(const char *name, device_memory& mem);
+ bool free(device_memory& mem);
+
+ BufferDescriptor get_descriptor(string name);
+
+ void update_device_memory();
+ void set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg);
+};
+
+CCL_NAMESPACE_END
+
diff --git a/intern/cycles/device/opencl/opencl.h b/intern/cycles/device/opencl/opencl.h
index 78ca377d933..26bf4a9af5b 100644
--- a/intern/cycles/device/opencl/opencl.h
+++ b/intern/cycles/device/opencl/opencl.h
@@ -25,6 +25,8 @@
#include "clew.h"
+#include "device/opencl/memory_manager.h"
+
CCL_NAMESPACE_BEGIN
/* Disable workarounds, seems to be working fine on latest drivers. */
@@ -224,6 +226,18 @@ public:
static string get_kernel_md5();
};
+#define opencl_device_assert(device, stmt) \
+ { \
+ cl_int err = stmt; \
+ \
+ if(err != CL_SUCCESS) { \
+ string message = string_printf("OpenCL error: %s in %s (%s:%d)", clewErrorString(err), #stmt, __FILE__, __LINE__); \
+ if((device)->error_message() == "") \
+ (device)->set_error(message); \
+ fprintf(stderr, "%s\n", message.c_str()); \
+ } \
+ } (void)0
+
#define opencl_assert(stmt) \
{ \
cl_int err = stmt; \
@@ -344,6 +358,7 @@ public:
size_t global_size_round_up(int group_size, int global_size);
void enqueue_kernel(cl_kernel kernel, size_t w, size_t h, size_t max_workgroup_size = -1);
void set_kernel_arg_mem(cl_kernel kernel, cl_uint *narg, const char *name);
+ void set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg);
void film_convert(DeviceTask& task, device_ptr buffer, device_ptr rgba_byte, device_ptr rgba_half);
void shader(DeviceTask& task);
@@ -525,6 +540,42 @@ protected:
virtual string build_options_for_base_program(
const DeviceRequestedFeatures& /*requested_features*/);
+
+private:
+ MemoryManager memory_manager;
+ friend class MemoryManager;
+
+ struct tex_info_t {
+ uint buffer, padding;
+ cl_ulong offset;
+ uint width, height, depth, options;
+ };
+ static_assert_align(tex_info_t, 16);
+
+ vector<tex_info_t> texture_descriptors;
+ device_memory texture_descriptors_buffer;
+
+ struct Texture {
+ Texture() {}
+ Texture(device_memory* mem,
+ InterpolationType interpolation,
+ ExtensionType extension)
+ : mem(mem),
+ interpolation(interpolation),
+ extension(extension) {
+ }
+ device_memory* mem;
+ InterpolationType interpolation;
+ ExtensionType extension;
+ };
+
+ typedef map<string, Texture> TexturesMap;
+ TexturesMap textures;
+
+ bool textures_need_update;
+
+protected:
+ void flush_texture_buffers();
};
Device *opencl_create_mega_device(DeviceInfo& info, Stats& stats, bool background);
diff --git a/intern/cycles/device/opencl/opencl_base.cpp b/intern/cycles/device/opencl/opencl_base.cpp
index 509da7a0a84..7bdf81462b8 100644
--- a/intern/cycles/device/opencl/opencl_base.cpp
+++ b/intern/cycles/device/opencl/opencl_base.cpp
@@ -29,6 +29,15 @@
CCL_NAMESPACE_BEGIN
+struct texture_slot_t {
+ texture_slot_t(const string& name, int slot)
+ : name(name),
+ slot(slot) {
+ }
+ string name;
+ int slot;
+};
+
bool OpenCLDeviceBase::opencl_error(cl_int err)
{
if(err != CL_SUCCESS) {
@@ -63,7 +72,7 @@ void OpenCLDeviceBase::opencl_assert_err(cl_int err, const char* where)
}
OpenCLDeviceBase::OpenCLDeviceBase(DeviceInfo& info, Stats &stats, bool background_)
-: Device(info, stats, background_)
+: Device(info, stats, background_), memory_manager(this)
{
cpPlatform = NULL;
cdDevice = NULL;
@@ -71,6 +80,7 @@ OpenCLDeviceBase::OpenCLDeviceBase(DeviceInfo& info, Stats &stats, bool backgrou
cqCommandQueue = NULL;
null_mem = 0;
device_initialized = false;
+ textures_need_update = true;
vector<OpenCLPlatformDevice> usable_devices;
OpenCLInfo::get_usable_devices(&usable_devices);
@@ -126,6 +136,12 @@ OpenCLDeviceBase::OpenCLDeviceBase(DeviceInfo& info, Stats &stats, bool backgrou
return;
}
+ /* Allocate this right away so that texture_descriptors_buffer is placed at offset 0 in the device memory buffers */
+ texture_descriptors.resize(1);
+ texture_descriptors_buffer.resize(1);
+ texture_descriptors_buffer.data_pointer = (device_ptr)&texture_descriptors[0];
+ memory_manager.alloc("texture_descriptors", texture_descriptors_buffer);
+
fprintf(stderr, "Device init success\n");
device_initialized = true;
}
@@ -134,6 +150,8 @@ OpenCLDeviceBase::~OpenCLDeviceBase()
{
task_pool.stop();
+ memory_manager.free();
+
if(null_mem)
clReleaseMemObject(CL_MEM_PTR(null_mem));
@@ -493,29 +511,35 @@ void OpenCLDeviceBase::const_copy_to(const char *name, void *host, size_t size)
void OpenCLDeviceBase::tex_alloc(const char *name,
device_memory& mem,
- InterpolationType /*interpolation*/,
- ExtensionType /*extension*/)
+ InterpolationType interpolation,
+ ExtensionType extension)
{
VLOG(1) << "Texture allocate: " << name << ", "
<< string_human_readable_number(mem.memory_size()) << " bytes. ("
<< string_human_readable_size(mem.memory_size()) << ")";
- mem_alloc(NULL, mem, MEM_READ_ONLY);
- mem_copy_to(mem);
- assert(mem_map.find(name) == mem_map.end());
- mem_map.insert(MemMap::value_type(name, mem.device_pointer));
+
+ memory_manager.alloc(name, mem);
+ /* Set the pointer to non-null to keep code that inspects its value from thinking its unallocated. */
+ mem.device_pointer = 1;
+ textures[name] = Texture(&mem, interpolation, extension);
+ textures_need_update = true;
}
void OpenCLDeviceBase::tex_free(device_memory& mem)
{
if(mem.device_pointer) {
- foreach(const MemMap::value_type& value, mem_map) {
- if(value.second == mem.device_pointer) {
- mem_map.erase(value.first);
+ mem.device_pointer = 0;
+
+ if(memory_manager.free(mem)) {
+ textures_need_update = true;
+ }
+
+ foreach(TexturesMap::value_type& value, textures) {
+ if(value.second.mem == &mem) {
+ textures.erase(value.first);
break;
}
}
-
- mem_free(mem);
}
}
@@ -581,6 +605,98 @@ void OpenCLDeviceBase::set_kernel_arg_mem(cl_kernel kernel, cl_uint *narg, const
opencl_assert(clSetKernelArg(kernel, (*narg)++, sizeof(ptr), (void*)&ptr));
}
+void OpenCLDeviceBase::set_kernel_arg_buffers(cl_kernel kernel, cl_uint *narg)
+{
+ flush_texture_buffers();
+
+ memory_manager.set_kernel_arg_buffers(kernel, narg);
+}
+
+void OpenCLDeviceBase::flush_texture_buffers()
+{
+ if(!textures_need_update) {
+ return;
+ }
+ textures_need_update = false;
+
+ /* Setup slots for textures. */
+ int num_slots = 0;
+
+ vector<texture_slot_t> texture_slots;
+
+#define KERNEL_TEX(type, ttype, name) \
+ if(textures.find(#name) != textures.end()) { \
+ texture_slots.push_back(texture_slot_t(#name, num_slots)); \
+ } \
+ num_slots++;
+#include "kernel/kernel_textures.h"
+
+ int num_data_slots = num_slots;
+
+ foreach(TexturesMap::value_type& tex, textures) {
+ string name = tex.first;
+
+ if(string_startswith(name, "__tex_image")) {
+ int pos = name.rfind("_");
+ int id = atoi(name.data() + pos + 1);
+ texture_slots.push_back(texture_slot_t(name,
+ num_data_slots + id));
+ num_slots = max(num_slots, num_data_slots + id + 1);
+ }
+ }
+
+ /* Realloc texture descriptors buffer. */
+ memory_manager.free(texture_descriptors_buffer);
+
+ texture_descriptors.resize(num_slots);
+ texture_descriptors_buffer.resize(num_slots * sizeof(tex_info_t));
+ texture_descriptors_buffer.data_pointer = (device_ptr)&texture_descriptors[0];
+
+ memory_manager.alloc("texture_descriptors", texture_descriptors_buffer);
+
+ /* Fill in descriptors */
+ foreach(texture_slot_t& slot, texture_slots) {
+ Texture& tex = textures[slot.name];
+
+ tex_info_t& info = texture_descriptors[slot.slot];
+
+ MemoryManager::BufferDescriptor desc = memory_manager.get_descriptor(slot.name);
+
+ info.offset = desc.offset;
+ info.buffer = desc.device_buffer;
+
+ if(string_startswith(slot.name, "__tex_image")) {
+ info.width = tex.mem->data_width;
+ info.height = tex.mem->data_height;
+ info.depth = tex.mem->data_depth;
+
+ info.options = 0;
+
+ if(tex.interpolation == INTERPOLATION_CLOSEST) {
+ info.options |= (1 << 0);
+ }
+
+ switch(tex.extension) {
+ case EXTENSION_REPEAT:
+ info.options |= (1 << 1);
+ break;
+ case EXTENSION_EXTEND:
+ info.options |= (1 << 2);
+ break;
+ case EXTENSION_CLIP:
+ info.options |= (1 << 3);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /* Force write of descriptors. */
+ memory_manager.free(texture_descriptors_buffer);
+ memory_manager.alloc("texture_descriptors", texture_descriptors_buffer);
+}
+
void OpenCLDeviceBase::film_convert(DeviceTask& task, device_ptr buffer, device_ptr rgba_byte, device_ptr rgba_half)
{
/* cast arguments to cl types */
@@ -605,10 +721,7 @@ void OpenCLDeviceBase::film_convert(DeviceTask& task, device_ptr buffer, device_
d_rgba,
d_buffer);
-#define KERNEL_TEX(type, ttype, name) \
-set_kernel_arg_mem(ckFilmConvertKernel, &start_arg_index, #name);
-#include "kernel/kernel_textures.h"
-#undef KERNEL_TEX
+ set_kernel_arg_buffers(ckFilmConvertKernel, &start_arg_index);
start_arg_index += kernel_set_args(ckFilmConvertKernel,
start_arg_index,
@@ -1030,10 +1143,7 @@ void OpenCLDeviceBase::shader(DeviceTask& task)
d_output_luma);
}
-#define KERNEL_TEX(type, ttype, name) \
- set_kernel_arg_mem(kernel, &start_arg_index, #name);
-#include "kernel/kernel_textures.h"
-#undef KERNEL_TEX
+ set_kernel_arg_buffers(kernel, &start_arg_index);
start_arg_index += kernel_set_args(kernel,
start_arg_index,
diff --git a/intern/cycles/device/opencl/opencl_mega.cpp b/intern/cycles/device/opencl/opencl_mega.cpp
index 06c15bcf401..ec47fdafa3d 100644
--- a/intern/cycles/device/opencl/opencl_mega.cpp
+++ b/intern/cycles/device/opencl/opencl_mega.cpp
@@ -82,10 +82,7 @@ public:
d_buffer,
d_rng_state);
-#define KERNEL_TEX(type, ttype, name) \
- set_kernel_arg_mem(ckPathTraceKernel, &start_arg_index, #name);
-#include "kernel/kernel_textures.h"
-#undef KERNEL_TEX
+ set_kernel_arg_buffers(ckPathTraceKernel, &start_arg_index);
start_arg_index += kernel_set_args(ckPathTraceKernel,
start_arg_index,
diff --git a/intern/cycles/device/opencl/opencl_split.cpp b/intern/cycles/device/opencl/opencl_split.cpp
index 76d9983e9a2..16a96213100 100644
--- a/intern/cycles/device/opencl/opencl_split.cpp
+++ b/intern/cycles/device/opencl/opencl_split.cpp
@@ -99,6 +99,8 @@ public:
void thread_run(DeviceTask *task)
{
+ flush_texture_buffers();
+
if(task->type == DeviceTask::FILM_CONVERT) {
film_convert(*task, task->buffer, task->rgba_byte, task->rgba_half);
}
@@ -113,10 +115,19 @@ public:
*/
typedef struct KernelGlobals {
ccl_constant KernelData *data;
+ ccl_global char *buffers[8];
+
+ typedef struct _tex_info_t {
+ uint buffer, padding;
+ uint64_t offset;
+ uint width, height, depth, options;
+ } _tex_info_t;
+
#define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name;
+ _tex_info_t name;
#include "kernel/kernel_textures.h"
#undef KERNEL_TEX
+
SplitData split_data;
SplitParams split_param_data;
} KernelGlobals;
@@ -217,11 +228,7 @@ public:
*cached_memory.ray_state,
*cached_memory.rng_state);
-/* TODO(sergey): Avoid map lookup here. */
-#define KERNEL_TEX(type, ttype, name) \
- device->set_kernel_arg_mem(program(), &start_arg_index, #name);
-#include "kernel/kernel_textures.h"
-#undef KERNEL_TEX
+ device->set_kernel_arg_buffers(program(), &start_arg_index);
start_arg_index +=
device->kernel_set_args(program(),
@@ -352,11 +359,7 @@ public:
ray_state,
rtile.rng_state);
-/* TODO(sergey): Avoid map lookup here. */
-#define KERNEL_TEX(type, ttype, name) \
- device->set_kernel_arg_mem(device->program_data_init(), &start_arg_index, #name);
-#include "kernel/kernel_textures.h"
-#undef KERNEL_TEX
+ device->set_kernel_arg_buffers(device->program_data_init(), &start_arg_index);
start_arg_index +=
device->kernel_set_args(device->program_data_init(),
diff --git a/intern/cycles/device/opencl/opencl_util.cpp b/intern/cycles/device/opencl/opencl_util.cpp
index 0d34af3e040..7d5173a5f1d 100644
--- a/intern/cycles/device/opencl/opencl_util.cpp
+++ b/intern/cycles/device/opencl/opencl_util.cpp
@@ -635,7 +635,7 @@ bool OpenCLInfo::device_supported(const string& platform_name,
"Tahiti", "Pitcairn", "Capeverde", "Oland",
NULL
};
- for (int i = 0; blacklist[i] != NULL; i++) {
+ for(int i = 0; blacklist[i] != NULL; i++) {
if(device_name == blacklist[i]) {
VLOG(1) << "AMD device " << device_name << " not supported";
return false;
diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt
index 23e9bd311c4..b4ca16bdb48 100644
--- a/intern/cycles/kernel/CMakeLists.txt
+++ b/intern/cycles/kernel/CMakeLists.txt
@@ -79,7 +79,6 @@ set(SRC_HEADERS
kernel_compat_cpu.h
kernel_compat_cuda.h
kernel_compat_opencl.h
- kernel_debug.h
kernel_differential.h
kernel_emission.h
kernel_film.h
@@ -202,6 +201,7 @@ set(SRC_GEOM_HEADERS
geom/geom.h
geom/geom_attribute.h
geom/geom_curve.h
+ geom/geom_curve_intersect.h
geom/geom_motion_curve.h
geom/geom_motion_triangle.h
geom/geom_motion_triangle_intersect.h
@@ -233,6 +233,7 @@ set(SRC_FILTER_HEADERS
set(SRC_UTIL_HEADERS
../util/util_atomic.h
../util/util_color.h
+ ../util/util_defines.h
../util/util_half.h
../util/util_hash.h
../util/util_math.h
diff --git a/intern/cycles/kernel/bvh/bvh.h b/intern/cycles/kernel/bvh/bvh.h
index 85741016b25..cf0c8542d69 100644
--- a/intern/cycles/kernel/bvh/bvh.h
+++ b/intern/cycles/kernel/bvh/bvh.h
@@ -233,7 +233,7 @@ ccl_device_intersect void scene_intersect_subsurface(KernelGlobals *kg,
ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
const Ray *ray,
Intersection *isect,
- int skip_object,
+ uint visibility,
uint max_hits,
uint *num_hits)
{
@@ -244,7 +244,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
return bvh_intersect_shadow_all_hair_motion(kg,
ray,
isect,
- skip_object,
+ visibility,
max_hits,
num_hits);
}
@@ -253,7 +253,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
return bvh_intersect_shadow_all_motion(kg,
ray,
isect,
- skip_object,
+ visibility,
max_hits,
num_hits);
}
@@ -264,7 +264,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
return bvh_intersect_shadow_all_hair(kg,
ray,
isect,
- skip_object,
+ visibility,
max_hits,
num_hits);
}
@@ -275,7 +275,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
return bvh_intersect_shadow_all_instancing(kg,
ray,
isect,
- skip_object,
+ visibility,
max_hits,
num_hits);
}
@@ -284,7 +284,7 @@ ccl_device_intersect bool scene_intersect_shadow_all(KernelGlobals *kg,
return bvh_intersect_shadow_all(kg,
ray,
isect,
- skip_object,
+ visibility,
max_hits,
num_hits);
}
diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h
index 267e098f912..a6a4353562c 100644
--- a/intern/cycles/kernel/bvh/bvh_shadow_all.h
+++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h
@@ -45,7 +45,7 @@ ccl_device_inline
bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
const Ray *ray,
Intersection *isect_array,
- const int skip_object,
+ const uint visibility,
const uint max_hits,
uint *num_hits)
{
@@ -119,7 +119,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
idir,
isect_t,
node_addr,
- PATH_RAY_SHADOW,
+ visibility,
dist);
#else // __KERNEL_SSE2__
traverse_mask = NODE_INTERSECT(kg,
@@ -134,7 +134,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
idirsplat,
shufflexyz,
node_addr,
- PATH_RAY_SHADOW,
+ visibility,
dist);
#endif // __KERNEL_SSE2__
@@ -186,17 +186,6 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
/* primitive intersection */
while(prim_addr < prim_addr2) {
kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
-
-#ifdef __SHADOW_TRICKS__
- uint tri_object = (object == OBJECT_NONE)
- ? kernel_tex_fetch(__prim_object, prim_addr)
- : object;
- if(tri_object == skip_object) {
- ++prim_addr;
- continue;
- }
-#endif
-
bool hit;
/* todo: specialized intersect functions which don't fill in
@@ -209,7 +198,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
isect_array,
P,
dir,
- PATH_RAY_SHADOW,
+ visibility,
object,
prim_addr);
break;
@@ -221,7 +210,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
P,
dir,
ray->time,
- PATH_RAY_SHADOW,
+ visibility,
object,
prim_addr);
break;
@@ -232,30 +221,30 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
case PRIMITIVE_MOTION_CURVE: {
const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = bvh_cardinal_curve_intersect(kg,
- isect_array,
- P,
- dir,
- PATH_RAY_SHADOW,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
+ hit = cardinal_curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0, 0);
}
else {
- hit = bvh_curve_intersect(kg,
- isect_array,
- P,
- dir,
- PATH_RAY_SHADOW,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
+ hit = curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0, 0);
}
break;
}
@@ -402,7 +391,7 @@ bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
const Ray *ray,
Intersection *isect_array,
- const int skip_object,
+ const uint visibility,
const uint max_hits,
uint *num_hits)
{
@@ -411,7 +400,7 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
return BVH_FUNCTION_FULL_NAME(QBVH)(kg,
ray,
isect_array,
- skip_object,
+ visibility,
max_hits,
num_hits);
}
@@ -422,7 +411,7 @@ ccl_device_inline bool BVH_FUNCTION_NAME(KernelGlobals *kg,
return BVH_FUNCTION_FULL_NAME(BVH)(kg,
ray,
isect_array,
- skip_object,
+ visibility,
max_hits,
num_hits);
}
diff --git a/intern/cycles/kernel/bvh/bvh_traversal.h b/intern/cycles/kernel/bvh/bvh_traversal.h
index c58d3b0316c..ae8f54821f2 100644
--- a/intern/cycles/kernel/bvh/bvh_traversal.h
+++ b/intern/cycles/kernel/bvh/bvh_traversal.h
@@ -244,14 +244,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
{
/* shadow ray early termination */
#if defined(__KERNEL_SSE2__)
- if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ if(visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
tfar = ssef(isect->t);
# endif
#else
- if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ if(visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
#endif
}
@@ -274,14 +274,14 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
{
/* shadow ray early termination */
# if defined(__KERNEL_SSE2__)
- if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ if(visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
tfar = ssef(isect->t);
# endif
# else
- if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ if(visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
# endif
}
@@ -298,44 +298,44 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg,
kernel_assert((curve_type & PRIMITIVE_ALL) == (type & PRIMITIVE_ALL));
bool hit;
if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = bvh_cardinal_curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
+ hit = cardinal_curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
}
else {
- hit = bvh_curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
+ hit = curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
}
if(hit) {
/* shadow ray early termination */
# if defined(__KERNEL_SSE2__)
- if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ if(visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
tsplat = ssef(0.0f, 0.0f, -isect->t, -isect->t);
# if BVH_FEATURE(BVH_HAIR)
tfar = ssef(isect->t);
# endif
# else
- if(visibility == PATH_RAY_SHADOW_OPAQUE)
+ if(visibility & PATH_RAY_SHADOW_OPAQUE)
return true;
# endif
}
diff --git a/intern/cycles/kernel/bvh/qbvh_shadow_all.h b/intern/cycles/kernel/bvh/qbvh_shadow_all.h
index ce474438f2c..522213f30ca 100644
--- a/intern/cycles/kernel/bvh/qbvh_shadow_all.h
+++ b/intern/cycles/kernel/bvh/qbvh_shadow_all.h
@@ -33,7 +33,7 @@
ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
const Ray *ray,
Intersection *isect_array,
- const int skip_object,
+ const uint visibility,
const uint max_hits,
uint *num_hits)
{
@@ -107,7 +107,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
if(false
#ifdef __VISIBILITY_FLAG__
- || ((__float_as_uint(inodes.x) & PATH_RAY_SHADOW) == 0)
+ || ((__float_as_uint(inodes.x) & visibility) == 0)
#endif
#if BVH_FEATURE(BVH_MOTION)
|| UNLIKELY(ray->time < inodes.y)
@@ -244,7 +244,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
if(node_addr < 0) {
float4 leaf = kernel_tex_fetch(__bvh_leaf_nodes, (-node_addr-1));
#ifdef __VISIBILITY_FLAG__
- if((__float_as_uint(leaf.z) & PATH_RAY_SHADOW) == 0) {
+ if((__float_as_uint(leaf.z) & visibility) == 0) {
/* Pop. */
node_addr = traversal_stack[stack_ptr].addr;
--stack_ptr;
@@ -268,17 +268,6 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
/* Primitive intersection. */
while(prim_addr < prim_addr2) {
kernel_assert((kernel_tex_fetch(__prim_type, prim_addr) & PRIMITIVE_ALL) == p_type);
-
-#ifdef __SHADOW_TRICKS__
- uint tri_object = (object == OBJECT_NONE)
- ? kernel_tex_fetch(__prim_object, prim_addr)
- : object;
- if(tri_object == skip_object) {
- ++prim_addr;
- continue;
- }
-#endif
-
bool hit;
/* todo: specialized intersect functions which don't fill in
@@ -291,7 +280,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
isect_array,
P,
dir,
- PATH_RAY_SHADOW,
+ visibility,
object,
prim_addr);
break;
@@ -303,7 +292,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
P,
dir,
ray->time,
- PATH_RAY_SHADOW,
+ visibility,
object,
prim_addr);
break;
@@ -314,30 +303,30 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
case PRIMITIVE_MOTION_CURVE: {
const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr);
if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = bvh_cardinal_curve_intersect(kg,
- isect_array,
- P,
- dir,
- PATH_RAY_SHADOW,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
+ hit = cardinal_curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0, 0);
}
else {
- hit = bvh_curve_intersect(kg,
- isect_array,
- P,
- dir,
- PATH_RAY_SHADOW,
- object,
- prim_addr,
- ray->time,
- curve_type,
- NULL,
- 0, 0);
+ hit = curve_intersect(kg,
+ isect_array,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ NULL,
+ 0, 0);
}
break;
}
diff --git a/intern/cycles/kernel/bvh/qbvh_traversal.h b/intern/cycles/kernel/bvh/qbvh_traversal.h
index fca75a1d416..335a4afd47a 100644
--- a/intern/cycles/kernel/bvh/qbvh_traversal.h
+++ b/intern/cycles/kernel/bvh/qbvh_traversal.h
@@ -340,7 +340,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
prim_addr)) {
tfar = ssef(isect->t);
/* Shadow ray early termination. */
- if(visibility == PATH_RAY_SHADOW_OPAQUE) {
+ if(visibility & PATH_RAY_SHADOW_OPAQUE) {
return true;
}
}
@@ -362,7 +362,7 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
prim_addr)) {
tfar = ssef(isect->t);
/* Shadow ray early termination. */
- if(visibility == PATH_RAY_SHADOW_OPAQUE) {
+ if(visibility & PATH_RAY_SHADOW_OPAQUE) {
return true;
}
}
@@ -379,37 +379,37 @@ ccl_device bool BVH_FUNCTION_FULL_NAME(QBVH)(KernelGlobals *kg,
kernel_assert((curve_type & PRIMITIVE_ALL) == (type & PRIMITIVE_ALL));
bool hit;
if(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) {
- hit = bvh_cardinal_curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
+ hit = cardinal_curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
}
else {
- hit = bvh_curve_intersect(kg,
- isect,
- P,
- dir,
- visibility,
- object,
- prim_addr,
- ray->time,
- curve_type,
- lcg_state,
- difl,
- extmax);
+ hit = curve_intersect(kg,
+ isect,
+ P,
+ dir,
+ visibility,
+ object,
+ prim_addr,
+ ray->time,
+ curve_type,
+ lcg_state,
+ difl,
+ extmax);
}
if(hit) {
tfar = ssef(isect->t);
/* Shadow ray early termination. */
- if(visibility == PATH_RAY_SHADOW_OPAQUE) {
+ if(visibility & PATH_RAY_SHADOW_OPAQUE) {
return true;
}
}
diff --git a/intern/cycles/kernel/filter/filter_features_sse.h b/intern/cycles/kernel/filter/filter_features_sse.h
index 3185330994c..3ddd8712266 100644
--- a/intern/cycles/kernel/filter/filter_features_sse.h
+++ b/intern/cycles/kernel/filter/filter_features_sse.h
@@ -16,7 +16,7 @@
CCL_NAMESPACE_BEGIN
-#define ccl_get_feature_sse(pass) _mm_loadu_ps(buffer + (pass)*pass_stride)
+#define ccl_get_feature_sse(pass) load_float4(buffer + (pass)*pass_stride)
/* Loop over the pixels in the range [low.x, high.x) x [low.y, high.y), 4 at a time.
* pixel_buffer always points to the first of the 4 current pixel in the first pass.
@@ -24,25 +24,25 @@ CCL_NAMESPACE_BEGIN
#define FOR_PIXEL_WINDOW_SSE pixel_buffer = buffer + (low.y - rect.y)*buffer_w + (low.x - rect.x); \
for(pixel.y = low.y; pixel.y < high.y; pixel.y++) { \
- __m128 y4 = _mm_set1_ps(pixel.y); \
+ float4 y4 = make_float4(pixel.y); \
for(pixel.x = low.x; pixel.x < high.x; pixel.x += 4, pixel_buffer += 4) { \
- __m128 x4 = _mm_add_ps(_mm_set1_ps(pixel.x), _mm_set_ps(3.0f, 2.0f, 1.0f, 0.0f)); \
- __m128 active_pixels = _mm_cmplt_ps(x4, _mm_set1_ps(high.x));
+ float4 x4 = make_float4(pixel.x) + make_float4(0.0f, 1.0f, 2.0f, 3.0f); \
+ int4 active_pixels = x4 < make_float4(high.x);
#define END_FOR_PIXEL_WINDOW_SSE } \
pixel_buffer += buffer_w - (pixel.x - low.x); \
}
-ccl_device_inline void filter_get_features_sse(__m128 x, __m128 y,
- __m128 active_pixels,
+ccl_device_inline void filter_get_features_sse(float4 x, float4 y,
+ int4 active_pixels,
const float *ccl_restrict buffer,
- __m128 *features,
- const __m128 *ccl_restrict mean,
+ float4 *features,
+ const float4 *ccl_restrict mean,
int pass_stride)
{
features[0] = x;
features[1] = y;
- features[2] = _mm_fabs_ps(ccl_get_feature_sse(0));
+ features[2] = fabs(ccl_get_feature_sse(0));
features[3] = ccl_get_feature_sse(1);
features[4] = ccl_get_feature_sse(2);
features[5] = ccl_get_feature_sse(3);
@@ -52,53 +52,41 @@ ccl_device_inline void filter_get_features_sse(__m128 x, __m128 y,
features[9] = ccl_get_feature_sse(7);
if(mean) {
for(int i = 0; i < DENOISE_FEATURES; i++)
- features[i] = _mm_sub_ps(features[i], mean[i]);
+ features[i] = features[i] - mean[i];
}
for(int i = 0; i < DENOISE_FEATURES; i++)
- features[i] = _mm_mask_ps(features[i], active_pixels);
+ features[i] = mask(active_pixels, features[i]);
}
-ccl_device_inline void filter_get_feature_scales_sse(__m128 x, __m128 y,
- __m128 active_pixels,
+ccl_device_inline void filter_get_feature_scales_sse(float4 x, float4 y,
+ int4 active_pixels,
const float *ccl_restrict buffer,
- __m128 *scales,
- const __m128 *ccl_restrict mean,
+ float4 *scales,
+ const float4 *ccl_restrict mean,
int pass_stride)
{
- scales[0] = _mm_mask_ps(_mm_fabs_ps(_mm_sub_ps(x, mean[0])), active_pixels);
- scales[1] = _mm_mask_ps(_mm_fabs_ps(_mm_sub_ps(y, mean[1])), active_pixels);
-
- scales[2] = _mm_mask_ps(_mm_fabs_ps(_mm_sub_ps(_mm_fabs_ps(ccl_get_feature_sse(0)), mean[2])), active_pixels);
-
- __m128 diff, scale;
- diff = _mm_sub_ps(ccl_get_feature_sse(1), mean[3]);
- scale = _mm_mul_ps(diff, diff);
- diff = _mm_sub_ps(ccl_get_feature_sse(2), mean[4]);
- scale = _mm_add_ps(scale, _mm_mul_ps(diff, diff));
- diff = _mm_sub_ps(ccl_get_feature_sse(3), mean[5]);
- scale = _mm_add_ps(scale, _mm_mul_ps(diff, diff));
- scales[3] = _mm_mask_ps(scale, active_pixels);
-
- scales[4] = _mm_mask_ps(_mm_fabs_ps(_mm_sub_ps(ccl_get_feature_sse(4), mean[6])), active_pixels);
-
- diff = _mm_sub_ps(ccl_get_feature_sse(5), mean[7]);
- scale = _mm_mul_ps(diff, diff);
- diff = _mm_sub_ps(ccl_get_feature_sse(6), mean[8]);
- scale = _mm_add_ps(scale, _mm_mul_ps(diff, diff));
- diff = _mm_sub_ps(ccl_get_feature_sse(7), mean[9]);
- scale = _mm_add_ps(scale, _mm_mul_ps(diff, diff));
- scales[5] = _mm_mask_ps(scale, active_pixels);
+ scales[0] = fabs(x - mean[0]);
+ scales[1] = fabs(y - mean[1]);
+ scales[2] = fabs(fabs(ccl_get_feature_sse(0)) - mean[2]);
+ scales[3] = sqr(ccl_get_feature_sse(1) - mean[3]) +
+ sqr(ccl_get_feature_sse(2) - mean[4]) +
+ sqr(ccl_get_feature_sse(3) - mean[5]);
+ scales[4] = fabs(ccl_get_feature_sse(4) - mean[6]);
+ scales[5] = sqr(ccl_get_feature_sse(5) - mean[7]) +
+ sqr(ccl_get_feature_sse(6) - mean[8]) +
+ sqr(ccl_get_feature_sse(7) - mean[9]);
+ for(int i = 0; i < 6; i++)
+ scales[i] = mask(active_pixels, scales[i]);
}
-ccl_device_inline void filter_calculate_scale_sse(__m128 *scale)
+ccl_device_inline void filter_calculate_scale_sse(float4 *scale)
{
- scale[0] = _mm_rcp_ps(_mm_max_ps(_mm_hmax_ps(scale[0]), _mm_set1_ps(0.01f)));
- scale[1] = _mm_rcp_ps(_mm_max_ps(_mm_hmax_ps(scale[1]), _mm_set1_ps(0.01f)));
- scale[2] = _mm_rcp_ps(_mm_max_ps(_mm_hmax_ps(scale[2]), _mm_set1_ps(0.01f)));
- scale[6] = _mm_rcp_ps(_mm_max_ps(_mm_hmax_ps(scale[4]), _mm_set1_ps(0.01f)));
-
- scale[7] = scale[8] = scale[9] = _mm_rcp_ps(_mm_max_ps(_mm_hmax_ps(_mm_sqrt_ps(scale[5])), _mm_set1_ps(0.01f)));
- scale[3] = scale[4] = scale[5] = _mm_rcp_ps(_mm_max_ps(_mm_hmax_ps(_mm_sqrt_ps(scale[3])), _mm_set1_ps(0.01f)));
+ scale[0] = rcp(max(reduce_max(scale[0]), make_float4(0.01f)));
+ scale[1] = rcp(max(reduce_max(scale[1]), make_float4(0.01f)));
+ scale[2] = rcp(max(reduce_max(scale[2]), make_float4(0.01f)));
+ scale[6] = rcp(max(reduce_max(scale[4]), make_float4(0.01f)));
+ scale[7] = scale[8] = scale[9] = rcp(max(reduce_max(sqrt(scale[5])), make_float4(0.01f)));
+ scale[3] = scale[4] = scale[5] = rcp(max(reduce_max(sqrt(scale[3])), make_float4(0.01f)));
}
diff --git a/intern/cycles/kernel/filter/filter_nlm_cpu.h b/intern/cycles/kernel/filter/filter_nlm_cpu.h
index 3e752bce68f..5e989331bc2 100644
--- a/intern/cycles/kernel/filter/filter_nlm_cpu.h
+++ b/intern/cycles/kernel/filter/filter_nlm_cpu.h
@@ -50,10 +50,8 @@ ccl_device_inline void kernel_filter_nlm_blur(const float *ccl_restrict differen
int w,
int f)
{
-#ifdef __KERNEL_SSE3__
- int aligned_lowx = (rect.x & ~(3));
- int aligned_highx = ((rect.z + 3) & ~(3));
-#endif
+ int aligned_lowx = rect.x / 4;
+ int aligned_highx = (rect.z + 3) / 4;
for(int y = rect.y; y < rect.w; y++) {
const int low = max(rect.y, y-f);
const int high = min(rect.w, y+f+1);
@@ -61,15 +59,11 @@ ccl_device_inline void kernel_filter_nlm_blur(const float *ccl_restrict differen
out_image[y*w+x] = 0.0f;
}
for(int y1 = low; y1 < high; y1++) {
-#ifdef __KERNEL_SSE3__
- for(int x = aligned_lowx; x < aligned_highx; x+=4) {
- _mm_store_ps(out_image + y*w+x, _mm_add_ps(_mm_load_ps(out_image + y*w+x), _mm_load_ps(difference_image + y1*w+x)));
+ float4* out_image4 = (float4*)(out_image + y*w);
+ float4* difference_image4 = (float4*)(difference_image + y1*w);
+ for(int x = aligned_lowx; x < aligned_highx; x++) {
+ out_image4[x] += difference_image4[x];
}
-#else
- for(int x = rect.x; x < rect.z; x++) {
- out_image[y*w+x] += difference_image[y1*w+x];
- }
-#endif
}
for(int x = rect.x; x < rect.z; x++) {
out_image[y*w+x] *= 1.0f/(high - low);
diff --git a/intern/cycles/kernel/filter/filter_prefilter.h b/intern/cycles/kernel/filter/filter_prefilter.h
index a0b89c1111f..c6a70cbeab5 100644
--- a/intern/cycles/kernel/filter/filter_prefilter.h
+++ b/intern/cycles/kernel/filter/filter_prefilter.h
@@ -96,7 +96,7 @@ ccl_device void kernel_filter_get_feature(int sample,
int idx = (y-rect.y)*buffer_w + (x - rect.x);
mean[idx] = center_buffer[m_offset] / sample;
- if (sample > 1) {
+ if(sample > 1) {
if(use_split_variance) {
variance[idx] = max(0.0f, (center_buffer[v_offset] - mean[idx]*mean[idx]*sample) / (sample * (sample-1)));
}
diff --git a/intern/cycles/kernel/filter/filter_transform_sse.h b/intern/cycles/kernel/filter/filter_transform_sse.h
index 30dc2969b11..9e65f61664b 100644
--- a/intern/cycles/kernel/filter/filter_transform_sse.h
+++ b/intern/cycles/kernel/filter/filter_transform_sse.h
@@ -24,7 +24,7 @@ ccl_device void kernel_filter_construct_transform(const float *ccl_restrict buff
{
int buffer_w = align_up(rect.z - rect.x, 4);
- __m128 features[DENOISE_FEATURES];
+ float4 features[DENOISE_FEATURES];
const float *ccl_restrict pixel_buffer;
int2 pixel;
@@ -34,19 +34,19 @@ ccl_device void kernel_filter_construct_transform(const float *ccl_restrict buff
min(rect.w, y + radius + 1));
int num_pixels = (high.y - low.y) * (high.x - low.x);
- __m128 feature_means[DENOISE_FEATURES];
+ float4 feature_means[DENOISE_FEATURES];
math_vector_zero_sse(feature_means, DENOISE_FEATURES);
FOR_PIXEL_WINDOW_SSE {
filter_get_features_sse(x4, y4, active_pixels, pixel_buffer, features, NULL, pass_stride);
math_vector_add_sse(feature_means, DENOISE_FEATURES, features);
} END_FOR_PIXEL_WINDOW_SSE
- __m128 pixel_scale = _mm_set1_ps(1.0f / num_pixels);
+ float4 pixel_scale = make_float4(1.0f / num_pixels);
for(int i = 0; i < DENOISE_FEATURES; i++) {
- feature_means[i] = _mm_mul_ps(_mm_hsum_ps(feature_means[i]), pixel_scale);
+ feature_means[i] = reduce_add(feature_means[i]) * pixel_scale;
}
- __m128 feature_scale[DENOISE_FEATURES];
+ float4 feature_scale[DENOISE_FEATURES];
math_vector_zero_sse(feature_scale, DENOISE_FEATURES);
FOR_PIXEL_WINDOW_SSE {
filter_get_feature_scales_sse(x4, y4, active_pixels, pixel_buffer, features, feature_means, pass_stride);
@@ -55,12 +55,12 @@ ccl_device void kernel_filter_construct_transform(const float *ccl_restrict buff
filter_calculate_scale_sse(feature_scale);
- __m128 feature_matrix_sse[DENOISE_FEATURES*DENOISE_FEATURES];
+ float4 feature_matrix_sse[DENOISE_FEATURES*DENOISE_FEATURES];
math_matrix_zero_sse(feature_matrix_sse, DENOISE_FEATURES);
FOR_PIXEL_WINDOW_SSE {
filter_get_features_sse(x4, y4, active_pixels, pixel_buffer, features, feature_means, pass_stride);
math_vector_mul_sse(features, DENOISE_FEATURES, feature_scale);
- math_matrix_add_gramian_sse(feature_matrix_sse, DENOISE_FEATURES, features, _mm_set1_ps(1.0f));
+ math_matrix_add_gramian_sse(feature_matrix_sse, DENOISE_FEATURES, features, make_float4(1.0f));
} END_FOR_PIXEL_WINDOW_SSE
float feature_matrix[DENOISE_FEATURES*DENOISE_FEATURES];
@@ -98,7 +98,7 @@ ccl_device void kernel_filter_construct_transform(const float *ccl_restrict buff
/* Bake the feature scaling into the transformation matrix. */
for(int i = 0; i < DENOISE_FEATURES; i++) {
- math_vector_scale(transform + i*DENOISE_FEATURES, _mm_cvtss_f32(feature_scale[i]), *rank);
+ math_vector_scale(transform + i*DENOISE_FEATURES, feature_scale[i][0], *rank);
}
}
diff --git a/intern/cycles/kernel/geom/geom.h b/intern/cycles/kernel/geom/geom.h
index c623e3490fd..f34b77ebc07 100644
--- a/intern/cycles/kernel/geom/geom.h
+++ b/intern/cycles/kernel/geom/geom.h
@@ -27,6 +27,7 @@
#include "kernel/geom/geom_motion_triangle_shader.h"
#include "kernel/geom/geom_motion_curve.h"
#include "kernel/geom/geom_curve.h"
+#include "kernel/geom/geom_curve_intersect.h"
#include "kernel/geom/geom_volume.h"
#include "kernel/geom/geom_primitive.h"
diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h
index 5c3b0ee3c15..e35267f02bf 100644
--- a/intern/cycles/kernel/geom/geom_curve.h
+++ b/intern/cycles/kernel/geom/geom_curve.h
@@ -16,18 +16,13 @@ CCL_NAMESPACE_BEGIN
/* Curve Primitive
*
- * Curve primitive for rendering hair and fur. These can be render as flat ribbons
- * or curves with actual thickness. The curve can also be rendered as line segments
- * rather than curves for better performance */
+ * Curve primitive for rendering hair and fur. These can be render as flat
+ * ribbons or curves with actual thickness. The curve can also be rendered as
+ * line segments rather than curves for better performance.
+ */
#ifdef __HAIR__
-#if defined(__KERNEL_CUDA__) && (__CUDA_ARCH__ < 300)
-# define ccl_device_curveintersect ccl_device
-#else
-# define ccl_device_curveintersect ccl_device_forceinline
-#endif
-
/* Reading attributes on various curve elements */
ccl_device float curve_attribute_float(KernelGlobals *kg, const ShaderData *sd, const AttributeDescriptor desc, float *dx, float *dy)
@@ -151,7 +146,7 @@ ccl_device float3 curve_motion_center_location(KernelGlobals *kg, ShaderData *sd
/* Curve tangent normal */
ccl_device float3 curve_tangent_normal(KernelGlobals *kg, ShaderData *sd)
-{
+{
float3 tgN = make_float3(0.0f,0.0f,0.0f);
if(sd->type & PRIMITIVE_ALL_CURVE) {
@@ -219,893 +214,6 @@ ccl_device_inline void curvebounds(float *lower, float *upper, float *extremta,
}
}
-#ifdef __KERNEL_SSE2__
-ccl_device_inline ssef transform_point_T3(const ssef t[3], const ssef &a)
-{
- return madd(shuffle<0>(a), t[0], madd(shuffle<1>(a), t[1], shuffle<2>(a) * t[2]));
-}
-#endif
-
-#ifdef __KERNEL_SSE2__
-/* Pass P and dir by reference to aligned vector */
-ccl_device_curveintersect bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
- const float3 &P, const float3 &dir, uint visibility, int object, int curveAddr, float time, int type, uint *lcg_state, float difl, float extmax)
-#else
-ccl_device_curveintersect bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Intersection *isect,
- float3 P, float3 dir, uint visibility, int object, int curveAddr, float time,int type, uint *lcg_state, float difl, float extmax)
-#endif
-{
- const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
-
- if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
- const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
- if(time < prim_time.x || time > prim_time.y) {
- return false;
- }
- }
-
- int segment = PRIMITIVE_UNPACK_SEGMENT(type);
- float epsilon = 0.0f;
- float r_st, r_en;
-
- int depth = kernel_data.curve.subdivisions;
- int flags = kernel_data.curve.curveflags;
- int prim = kernel_tex_fetch(__prim_index, curveAddr);
-
-#ifdef __KERNEL_SSE2__
- ssef vdir = load4f(dir);
- ssef vcurve_coef[4];
- const float3 *curve_coef = (float3 *)vcurve_coef;
-
- {
- ssef dtmp = vdir * vdir;
- ssef d_ss = mm_sqrt(dtmp + shuffle<2>(dtmp));
- ssef rd_ss = load1f_first(1.0f) / d_ss;
-
- ssei v00vec = load4i((ssei *)&kg->__curves.data[prim]);
- int2 &v00 = (int2 &)v00vec;
-
- int k0 = v00.x + segment;
- int k1 = k0 + 1;
- int ka = max(k0 - 1, v00.x);
- int kb = min(k1 + 1, v00.x + v00.y - 1);
-
-#if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) && (!defined(_MSC_VER) || _MSC_VER > 1800)
- avxf P_curve_0_1, P_curve_2_3;
- if(is_curve_primitive) {
- P_curve_0_1 = _mm256_loadu2_m128(&kg->__curve_keys.data[k0].x, &kg->__curve_keys.data[ka].x);
- P_curve_2_3 = _mm256_loadu2_m128(&kg->__curve_keys.data[kb].x, &kg->__curve_keys.data[k1].x);
- }
- else {
- int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
- motion_cardinal_curve_keys_avx(kg, fobject, prim, time, ka, k0, k1, kb, &P_curve_0_1,&P_curve_2_3);
- }
-#else /* __KERNEL_AVX2__ */
- ssef P_curve[4];
-
- if(is_curve_primitive) {
- P_curve[0] = load4f(&kg->__curve_keys.data[ka].x);
- P_curve[1] = load4f(&kg->__curve_keys.data[k0].x);
- P_curve[2] = load4f(&kg->__curve_keys.data[k1].x);
- P_curve[3] = load4f(&kg->__curve_keys.data[kb].x);
- }
- else {
- int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
- motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, (float4*)&P_curve);
- }
-#endif /* __KERNEL_AVX2__ */
-
- ssef rd_sgn = set_sign_bit<0, 1, 1, 1>(shuffle<0>(rd_ss));
- ssef mul_zxxy = shuffle<2, 0, 0, 1>(vdir) * rd_sgn;
- ssef mul_yz = shuffle<1, 2, 1, 2>(vdir) * mul_zxxy;
- ssef mul_shuf = shuffle<0, 1, 2, 3>(mul_zxxy, mul_yz);
- ssef vdir0 = vdir & cast(ssei(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0));
-
- ssef htfm0 = shuffle<0, 2, 0, 3>(mul_shuf, vdir0);
- ssef htfm1 = shuffle<1, 0, 1, 3>(load1f_first(extract<0>(d_ss)), vdir0);
- ssef htfm2 = shuffle<1, 3, 2, 3>(mul_shuf, vdir0);
-
-#if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) && (!defined(_MSC_VER) || _MSC_VER > 1800)
- const avxf vPP = _mm256_broadcast_ps(&P.m128);
- const avxf htfm00 = avxf(htfm0.m128, htfm0.m128);
- const avxf htfm11 = avxf(htfm1.m128, htfm1.m128);
- const avxf htfm22 = avxf(htfm2.m128, htfm2.m128);
-
- const avxf p01 = madd(shuffle<0>(P_curve_0_1 - vPP),
- htfm00,
- madd(shuffle<1>(P_curve_0_1 - vPP),
- htfm11,
- shuffle<2>(P_curve_0_1 - vPP) * htfm22));
- const avxf p23 = madd(shuffle<0>(P_curve_2_3 - vPP),
- htfm00,
- madd(shuffle<1>(P_curve_2_3 - vPP),
- htfm11,
- shuffle<2>(P_curve_2_3 - vPP)*htfm22));
-
- const ssef p0 = _mm256_castps256_ps128(p01);
- const ssef p1 = _mm256_extractf128_ps(p01, 1);
- const ssef p2 = _mm256_castps256_ps128(p23);
- const ssef p3 = _mm256_extractf128_ps(p23, 1);
-
- const ssef P_curve_1 = _mm256_extractf128_ps(P_curve_0_1, 1);
- r_st = ((float4 &)P_curve_1).w;
- const ssef P_curve_2 = _mm256_castps256_ps128(P_curve_2_3);
- r_en = ((float4 &)P_curve_2).w;
-#else /* __KERNEL_AVX2__ */
- ssef htfm[] = { htfm0, htfm1, htfm2 };
- ssef vP = load4f(P);
- ssef p0 = transform_point_T3(htfm, P_curve[0] - vP);
- ssef p1 = transform_point_T3(htfm, P_curve[1] - vP);
- ssef p2 = transform_point_T3(htfm, P_curve[2] - vP);
- ssef p3 = transform_point_T3(htfm, P_curve[3] - vP);
-
- r_st = ((float4 &)P_curve[1]).w;
- r_en = ((float4 &)P_curve[2]).w;
-#endif /* __KERNEL_AVX2__ */
-
- float fc = 0.71f;
- ssef vfc = ssef(fc);
- ssef vfcxp3 = vfc * p3;
-
- vcurve_coef[0] = p1;
- vcurve_coef[1] = vfc * (p2 - p0);
- vcurve_coef[2] = madd(ssef(fc * 2.0f), p0, madd(ssef(fc - 3.0f), p1, msub(ssef(3.0f - 2.0f * fc), p2, vfcxp3)));
- vcurve_coef[3] = msub(ssef(fc - 2.0f), p2 - p1, msub(vfc, p0, vfcxp3));
-
- }
-#else
- float3 curve_coef[4];
-
- /* curve Intersection check */
- /* obtain curve parameters */
- {
- /* ray transform created - this should be created at beginning of intersection loop */
- Transform htfm;
- float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
- htfm = make_transform(
- dir.z / d, 0, -dir.x /d, 0,
- -dir.x * dir.y /d, d, -dir.y * dir.z /d, 0,
- dir.x, dir.y, dir.z, 0,
- 0, 0, 0, 1);
-
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int k0 = __float_as_int(v00.x) + segment;
- int k1 = k0 + 1;
-
- int ka = max(k0 - 1,__float_as_int(v00.x));
- int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
-
- float4 P_curve[4];
-
- if(is_curve_primitive) {
- P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
- P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
- }
- else {
- int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
- motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, P_curve);
- }
-
- float3 p0 = transform_point(&htfm, float4_to_float3(P_curve[0]) - P);
- float3 p1 = transform_point(&htfm, float4_to_float3(P_curve[1]) - P);
- float3 p2 = transform_point(&htfm, float4_to_float3(P_curve[2]) - P);
- float3 p3 = transform_point(&htfm, float4_to_float3(P_curve[3]) - P);
-
- float fc = 0.71f;
- curve_coef[0] = p1;
- curve_coef[1] = -fc*p0 + fc*p2;
- curve_coef[2] = 2.0f * fc * p0 + (fc - 3.0f) * p1 + (3.0f - 2.0f * fc) * p2 - fc * p3;
- curve_coef[3] = -fc * p0 + (2.0f - fc) * p1 + (fc - 2.0f) * p2 + fc * p3;
- r_st = P_curve[1].w;
- r_en = P_curve[2].w;
- }
-#endif
-
- float r_curr = max(r_st, r_en);
-
- if((flags & CURVE_KN_RIBBONS) || !(flags & CURVE_KN_BACKFACING))
- epsilon = 2 * r_curr;
-
- /* find bounds - this is slow for cubic curves */
- float upper, lower;
-
- float zextrem[4];
- curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
- if(lower - r_curr > isect->t || upper + r_curr < epsilon)
- return false;
-
- /* minimum width extension */
- float mw_extension = min(difl * fabsf(upper), extmax);
- float r_ext = mw_extension + r_curr;
-
- float xextrem[4];
- curvebounds(&lower, &upper, &xextrem[0], &xextrem[1], &xextrem[2], &xextrem[3], curve_coef[0].x, curve_coef[1].x, curve_coef[2].x, curve_coef[3].x);
- if(lower > r_ext || upper < -r_ext)
- return false;
-
- float yextrem[4];
- curvebounds(&lower, &upper, &yextrem[0], &yextrem[1], &yextrem[2], &yextrem[3], curve_coef[0].y, curve_coef[1].y, curve_coef[2].y, curve_coef[3].y);
- if(lower > r_ext || upper < -r_ext)
- return false;
-
- /* setup recurrent loop */
- int level = 1 << depth;
- int tree = 0;
- float resol = 1.0f / (float)level;
- bool hit = false;
-
- /* begin loop */
- while(!(tree >> (depth))) {
- const float i_st = tree * resol;
- const float i_en = i_st + (level * resol);
-
-#ifdef __KERNEL_SSE2__
- ssef vi_st = ssef(i_st), vi_en = ssef(i_en);
- ssef vp_st = madd(madd(madd(vcurve_coef[3], vi_st, vcurve_coef[2]), vi_st, vcurve_coef[1]), vi_st, vcurve_coef[0]);
- ssef vp_en = madd(madd(madd(vcurve_coef[3], vi_en, vcurve_coef[2]), vi_en, vcurve_coef[1]), vi_en, vcurve_coef[0]);
-
- ssef vbmin = min(vp_st, vp_en);
- ssef vbmax = max(vp_st, vp_en);
-
- float3 &bmin = (float3 &)vbmin, &bmax = (float3 &)vbmax;
- float &bminx = bmin.x, &bminy = bmin.y, &bminz = bmin.z;
- float &bmaxx = bmax.x, &bmaxy = bmax.y, &bmaxz = bmax.z;
- float3 &p_st = (float3 &)vp_st, &p_en = (float3 &)vp_en;
-#else
- float3 p_st = ((curve_coef[3] * i_st + curve_coef[2]) * i_st + curve_coef[1]) * i_st + curve_coef[0];
- float3 p_en = ((curve_coef[3] * i_en + curve_coef[2]) * i_en + curve_coef[1]) * i_en + curve_coef[0];
-
- float bminx = min(p_st.x, p_en.x);
- float bmaxx = max(p_st.x, p_en.x);
- float bminy = min(p_st.y, p_en.y);
- float bmaxy = max(p_st.y, p_en.y);
- float bminz = min(p_st.z, p_en.z);
- float bmaxz = max(p_st.z, p_en.z);
-#endif
-
- if(xextrem[0] >= i_st && xextrem[0] <= i_en) {
- bminx = min(bminx,xextrem[1]);
- bmaxx = max(bmaxx,xextrem[1]);
- }
- if(xextrem[2] >= i_st && xextrem[2] <= i_en) {
- bminx = min(bminx,xextrem[3]);
- bmaxx = max(bmaxx,xextrem[3]);
- }
- if(yextrem[0] >= i_st && yextrem[0] <= i_en) {
- bminy = min(bminy,yextrem[1]);
- bmaxy = max(bmaxy,yextrem[1]);
- }
- if(yextrem[2] >= i_st && yextrem[2] <= i_en) {
- bminy = min(bminy,yextrem[3]);
- bmaxy = max(bmaxy,yextrem[3]);
- }
- if(zextrem[0] >= i_st && zextrem[0] <= i_en) {
- bminz = min(bminz,zextrem[1]);
- bmaxz = max(bmaxz,zextrem[1]);
- }
- if(zextrem[2] >= i_st && zextrem[2] <= i_en) {
- bminz = min(bminz,zextrem[3]);
- bmaxz = max(bmaxz,zextrem[3]);
- }
-
- float r1 = r_st + (r_en - r_st) * i_st;
- float r2 = r_st + (r_en - r_st) * i_en;
- r_curr = max(r1, r2);
-
- mw_extension = min(difl * fabsf(bmaxz), extmax);
- float r_ext = mw_extension + r_curr;
- float coverage = 1.0f;
-
- if(bminz - r_curr > isect->t || bmaxz + r_curr < epsilon || bminx > r_ext|| bmaxx < -r_ext|| bminy > r_ext|| bmaxy < -r_ext) {
- /* the bounding box does not overlap the square centered at O */
- tree += level;
- level = tree & -tree;
- }
- else if(level == 1) {
-
- /* the maximum recursion depth is reached.
- * check if dP0.(Q-P0)>=0 and dPn.(Pn-Q)>=0.
- * dP* is reversed if necessary.*/
- float t = isect->t;
- float u = 0.0f;
- float gd = 0.0f;
-
- if(flags & CURVE_KN_RIBBONS) {
- float3 tg = (p_en - p_st);
-#ifdef __KERNEL_SSE__
- const float3 tg_sq = tg * tg;
- float w = tg_sq.x + tg_sq.y;
-#else
- float w = tg.x * tg.x + tg.y * tg.y;
-#endif
- if(w == 0) {
- tree++;
- level = tree & -tree;
- continue;
- }
-#ifdef __KERNEL_SSE__
- const float3 p_sttg = p_st * tg;
- w = -(p_sttg.x + p_sttg.y) / w;
-#else
- w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
-#endif
- w = saturate(w);
-
- /* compute u on the curve segment */
- u = i_st * (1 - w) + i_en * w;
- r_curr = r_st + (r_en - r_st) * u;
- /* compare x-y distances */
- float3 p_curr = ((curve_coef[3] * u + curve_coef[2]) * u + curve_coef[1]) * u + curve_coef[0];
-
- float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
- if(dot(tg, dp_st)< 0)
- dp_st *= -1;
- if(dot(dp_st, -p_st) + p_curr.z * dp_st.z < 0) {
- tree++;
- level = tree & -tree;
- continue;
- }
- float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
- if(dot(tg, dp_en) < 0)
- dp_en *= -1;
- if(dot(dp_en, p_en) - p_curr.z * dp_en.z < 0) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- /* compute coverage */
- float r_ext = r_curr;
- coverage = 1.0f;
- if(difl != 0.0f) {
- mw_extension = min(difl * fabsf(bmaxz), extmax);
- r_ext = mw_extension + r_curr;
-#ifdef __KERNEL_SSE__
- const float3 p_curr_sq = p_curr * p_curr;
- const float3 dxxx(_mm_sqrt_ss(_mm_hadd_ps(p_curr_sq.m128, p_curr_sq.m128)));
- float d = dxxx.x;
-#else
- float d = sqrtf(p_curr.x * p_curr.x + p_curr.y * p_curr.y);
-#endif
- float d0 = d - r_curr;
- float d1 = d + r_curr;
- float inv_mw_extension = 1.0f/mw_extension;
- if(d0 >= 0)
- coverage = (min(d1 * inv_mw_extension, 1.0f) - min(d0 * inv_mw_extension, 1.0f)) * 0.5f;
- else // inside
- coverage = (min(d1 * inv_mw_extension, 1.0f) + min(-d0 * inv_mw_extension, 1.0f)) * 0.5f;
- }
-
- if(p_curr.x * p_curr.x + p_curr.y * p_curr.y >= r_ext * r_ext || p_curr.z <= epsilon || isect->t < p_curr.z) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- t = p_curr.z;
-
- /* stochastic fade from minimum width */
- if(difl != 0.0f && lcg_state) {
- if(coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
- return hit;
- }
- }
- else {
- float l = len(p_en - p_st);
- /* minimum width extension */
- float or1 = r1;
- float or2 = r2;
-
- if(difl != 0.0f) {
- mw_extension = min(len(p_st - P) * difl, extmax);
- or1 = r1 < mw_extension ? mw_extension : r1;
- mw_extension = min(len(p_en - P) * difl, extmax);
- or2 = r2 < mw_extension ? mw_extension : r2;
- }
- /* --- */
- float invl = 1.0f/l;
- float3 tg = (p_en - p_st) * invl;
- gd = (or2 - or1) * invl;
- float difz = -dot(p_st,tg);
- float cyla = 1.0f - (tg.z * tg.z * (1 + gd*gd));
- float invcyla = 1.0f/cyla;
- float halfb = (-p_st.z - tg.z*(difz + gd*(difz*gd + or1)));
- float tcentre = -halfb*invcyla;
- float zcentre = difz + (tg.z * tcentre);
- float3 tdif = - p_st;
- tdif.z += tcentre;
- float tdifz = dot(tdif,tg);
- float tb = 2*(tdif.z - tg.z*(tdifz + gd*(tdifz*gd + or1)));
- float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - or1*or1 - 2*or1*tdifz*gd;
- float td = tb*tb - 4*cyla*tc;
- if(td < 0.0f) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- float rootd = sqrtf(td);
- float correction = (-tb - rootd) * 0.5f * invcyla;
- t = tcentre + correction;
-
- float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
- if(dot(tg, dp_st)< 0)
- dp_st *= -1;
- float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
- if(dot(tg, dp_en) < 0)
- dp_en *= -1;
-
- if(flags & CURVE_KN_BACKFACING && (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f)) {
- correction = (-tb + rootd) * 0.5f * invcyla;
- t = tcentre + correction;
- }
-
- if(dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f) {
- tree++;
- level = tree & -tree;
- continue;
- }
-
- float w = (zcentre + (tg.z * correction)) * invl;
- w = saturate(w);
- /* compute u on the curve segment */
- u = i_st * (1 - w) + i_en * w;
-
- /* stochastic fade from minimum width */
- if(difl != 0.0f && lcg_state) {
- r_curr = r1 + (r2 - r1) * w;
- r_ext = or1 + (or2 - or1) * w;
- coverage = r_curr/r_ext;
-
- if(coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
- return hit;
- }
- }
- /* we found a new intersection */
-
-#ifdef __VISIBILITY_FLAG__
- /* visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags */
- if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
-#endif
- {
- /* record intersection */
- isect->t = t;
- isect->u = u;
- isect->v = gd;
- isect->prim = curveAddr;
- isect->object = object;
- isect->type = type;
- hit = true;
- }
-
- tree++;
- level = tree & -tree;
- }
- else {
- /* split the curve into two curves and process */
- level = level >> 1;
- }
- }
-
- return hit;
-}
-
-ccl_device_curveintersect bool bvh_curve_intersect(KernelGlobals *kg, Intersection *isect,
- float3 P, float3 direction, uint visibility, int object, int curveAddr, float time, int type, uint *lcg_state, float difl, float extmax)
-{
- /* define few macros to minimize code duplication for SSE */
-#ifndef __KERNEL_SSE2__
-# define len3_squared(x) len_squared(x)
-# define len3(x) len(x)
-# define dot3(x, y) dot(x, y)
-#endif
-
- const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
-
- if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
- const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
- if(time < prim_time.x || time > prim_time.y) {
- return false;
- }
- }
-
- int segment = PRIMITIVE_UNPACK_SEGMENT(type);
- /* curve Intersection check */
- int flags = kernel_data.curve.curveflags;
-
- int prim = kernel_tex_fetch(__prim_index, curveAddr);
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int cnum = __float_as_int(v00.x);
- int k0 = cnum + segment;
- int k1 = k0 + 1;
-
-#ifndef __KERNEL_SSE2__
- float4 P_curve[2];
-
- if(is_curve_primitive) {
- P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
- }
- else {
- int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
- motion_curve_keys(kg, fobject, prim, time, k0, k1, P_curve);
- }
-
- float or1 = P_curve[0].w;
- float or2 = P_curve[1].w;
- float3 p1 = float4_to_float3(P_curve[0]);
- float3 p2 = float4_to_float3(P_curve[1]);
-
- /* minimum width extension */
- float r1 = or1;
- float r2 = or2;
- float3 dif = P - p1;
- float3 dif_second = P - p2;
- if(difl != 0.0f) {
- float pixelsize = min(len3(dif) * difl, extmax);
- r1 = or1 < pixelsize ? pixelsize : or1;
- pixelsize = min(len3(dif_second) * difl, extmax);
- r2 = or2 < pixelsize ? pixelsize : or2;
- }
- /* --- */
-
- float3 p21_diff = p2 - p1;
- float3 sphere_dif1 = (dif + dif_second) * 0.5f;
- float3 dir = direction;
- float sphere_b_tmp = dot3(dir, sphere_dif1);
- float3 sphere_dif2 = sphere_dif1 - sphere_b_tmp * dir;
-#else
- ssef P_curve[2];
-
- if(is_curve_primitive) {
- P_curve[0] = load4f(&kg->__curve_keys.data[k0].x);
- P_curve[1] = load4f(&kg->__curve_keys.data[k1].x);
- }
- else {
- int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
- motion_curve_keys(kg, fobject, prim, time, k0, k1, (float4*)&P_curve);
- }
-
- const ssef or12 = shuffle<3, 3, 3, 3>(P_curve[0], P_curve[1]);
-
- ssef r12 = or12;
- const ssef vP = load4f(P);
- const ssef dif = vP - P_curve[0];
- const ssef dif_second = vP - P_curve[1];
- if(difl != 0.0f) {
- const ssef len1_sq = len3_squared_splat(dif);
- const ssef len2_sq = len3_squared_splat(dif_second);
- const ssef len12 = mm_sqrt(shuffle<0, 0, 0, 0>(len1_sq, len2_sq));
- const ssef pixelsize12 = min(len12 * difl, ssef(extmax));
- r12 = max(or12, pixelsize12);
- }
- float or1 = extract<0>(or12), or2 = extract<0>(shuffle<2>(or12));
- float r1 = extract<0>(r12), r2 = extract<0>(shuffle<2>(r12));
-
- const ssef p21_diff = P_curve[1] - P_curve[0];
- const ssef sphere_dif1 = (dif + dif_second) * 0.5f;
- const ssef dir = load4f(direction);
- const ssef sphere_b_tmp = dot3_splat(dir, sphere_dif1);
- const ssef sphere_dif2 = nmadd(sphere_b_tmp, dir, sphere_dif1);
-#endif
-
- float mr = max(r1, r2);
- float l = len3(p21_diff);
- float invl = 1.0f / l;
- float sp_r = mr + 0.5f * l;
-
- float sphere_b = dot3(dir, sphere_dif2);
- float sdisc = sphere_b * sphere_b - len3_squared(sphere_dif2) + sp_r * sp_r;
-
- if(sdisc < 0.0f)
- return false;
-
- /* obtain parameters and test midpoint distance for suitable modes */
-#ifndef __KERNEL_SSE2__
- float3 tg = p21_diff * invl;
-#else
- const ssef tg = p21_diff * invl;
-#endif
- float gd = (r2 - r1) * invl;
-
- float dirz = dot3(dir, tg);
- float difz = dot3(dif, tg);
-
- float a = 1.0f - (dirz*dirz*(1 + gd*gd));
-
- float halfb = dot3(dir, dif) - dirz*(difz + gd*(difz*gd + r1));
-
- float tcentre = -halfb/a;
- float zcentre = difz + (dirz * tcentre);
-
- if((tcentre > isect->t) && !(flags & CURVE_KN_ACCURATE))
- return false;
- if((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) && !(flags & CURVE_KN_INTERSECTCORRECTION))
- return false;
-
- /* test minimum separation */
-#ifndef __KERNEL_SSE2__
- float3 cprod = cross(tg, dir);
- float cprod2sq = len3_squared(cross(tg, dif));
-#else
- const ssef cprod = cross(tg, dir);
- float cprod2sq = len3_squared(cross_zxy(tg, dif));
-#endif
- float cprodsq = len3_squared(cprod);
- float distscaled = dot3(cprod, dif);
-
- if(cprodsq == 0)
- distscaled = cprod2sq;
- else
- distscaled = (distscaled*distscaled)/cprodsq;
-
- if(distscaled > mr*mr)
- return false;
-
- /* calculate true intersection */
-#ifndef __KERNEL_SSE2__
- float3 tdif = dif + tcentre * dir;
-#else
- const ssef tdif = madd(ssef(tcentre), dir, dif);
-#endif
- float tdifz = dot3(tdif, tg);
- float tdifma = tdifz*gd + r1;
- float tb = 2*(dot3(dir, tdif) - dirz*(tdifz + gd*tdifma));
- float tc = dot3(tdif, tdif) - tdifz*tdifz - tdifma*tdifma;
- float td = tb*tb - 4*a*tc;
-
- if(td < 0.0f)
- return false;
-
- float rootd = 0.0f;
- float correction = 0.0f;
- if(flags & CURVE_KN_ACCURATE) {
- rootd = sqrtf(td);
- correction = ((-tb - rootd)/(2*a));
- }
-
- float t = tcentre + correction;
-
- if(t < isect->t) {
-
- if(flags & CURVE_KN_INTERSECTCORRECTION) {
- rootd = sqrtf(td);
- correction = ((-tb - rootd)/(2*a));
- t = tcentre + correction;
- }
-
- float z = zcentre + (dirz * correction);
- // bool backface = false;
-
- if(flags & CURVE_KN_BACKFACING && (t < 0.0f || z < 0 || z > l)) {
- // backface = true;
- correction = ((-tb + rootd)/(2*a));
- t = tcentre + correction;
- z = zcentre + (dirz * correction);
- }
-
- /* stochastic fade from minimum width */
- float adjradius = or1 + z * (or2 - or1) * invl;
- adjradius = adjradius / (r1 + z * gd);
- if(lcg_state && adjradius != 1.0f) {
- if(lcg_step_float(lcg_state) > adjradius)
- return false;
- }
- /* --- */
-
- if(t > 0.0f && t < isect->t && z >= 0 && z <= l) {
-
- if(flags & CURVE_KN_ENCLOSEFILTER) {
- float enc_ratio = 1.01f;
- if((difz > -r1 * enc_ratio) && (dot3(dif_second, tg) < r2 * enc_ratio)) {
- float a2 = 1.0f - (dirz*dirz*(1 + gd*gd*enc_ratio*enc_ratio));
- float c2 = dot3(dif, dif) - difz * difz * (1 + gd*gd*enc_ratio*enc_ratio) - r1*r1*enc_ratio*enc_ratio - 2*r1*difz*gd*enc_ratio;
- if(a2*c2 < 0.0f)
- return false;
- }
- }
-
-#ifdef __VISIBILITY_FLAG__
- /* visibility flag test. we do it here under the assumption
- * that most triangles are culled by node flags */
- if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
-#endif
- {
- /* record intersection */
- isect->t = t;
- isect->u = z*invl;
- isect->v = gd;
- isect->prim = curveAddr;
- isect->object = object;
- isect->type = type;
-
- return true;
- }
- }
- }
-
- return false;
-
-#ifndef __KERNEL_SSE2__
-# undef len3_squared
-# undef len3
-# undef dot3
-#endif
-}
-
-ccl_device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3)
-{
- float fc = 0.71f;
- float data[4];
- float t2 = t * t;
- data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc;
- data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t;
- data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc;
- data[3] = 3.0f * fc * t2 - 2.0f * fc * t;
- return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
-}
-
-ccl_device_inline float3 curvepoint(float t, float3 p0, float3 p1, float3 p2, float3 p3)
-{
- float data[4];
- float fc = 0.71f;
- float t2 = t * t;
- float t3 = t2 * t;
- data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
- data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
- data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
- data[3] = fc * t3 - fc * t2;
- return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
-}
-
-ccl_device_inline float3 bvh_curve_refine(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray)
-{
- int flag = kernel_data.curve.curveflags;
- float t = isect->t;
- float3 P = ray->P;
- float3 D = ray->D;
-
- if(isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_itfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- D = transform_direction(&tfm, D*t);
- D = normalize_len(D, &t);
- }
-
- int prim = kernel_tex_fetch(__prim_index, isect->prim);
- float4 v00 = kernel_tex_fetch(__curves, prim);
-
- int k0 = __float_as_int(v00.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
- int k1 = k0 + 1;
-
- float3 tg;
-
- if(flag & CURVE_KN_INTERPOLATE) {
- int ka = max(k0 - 1,__float_as_int(v00.x));
- int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
-
- float4 P_curve[4];
-
- if(sd->type & PRIMITIVE_CURVE) {
- P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
- P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
- P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
- P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
- }
- else {
- motion_cardinal_curve_keys(kg, sd->object, sd->prim, sd->time, ka, k0, k1, kb, P_curve);
- }
-
- float3 p[4];
- p[0] = float4_to_float3(P_curve[0]);
- p[1] = float4_to_float3(P_curve[1]);
- p[2] = float4_to_float3(P_curve[2]);
- p[3] = float4_to_float3(P_curve[3]);
-
- P = P + D*t;
-
-#ifdef __UV__
- sd->u = isect->u;
- sd->v = 0.0f;
-#endif
-
- tg = normalize(curvetangent(isect->u, p[0], p[1], p[2], p[3]));
-
- if(kernel_data.curve.curveflags & CURVE_KN_RIBBONS) {
- sd->Ng = normalize(-(D - tg * (dot(tg, D))));
- }
- else {
- /* direction from inside to surface of curve */
- float3 p_curr = curvepoint(isect->u, p[0], p[1], p[2], p[3]);
- sd->Ng = normalize(P - p_curr);
-
- /* adjustment for changing radius */
- float gd = isect->v;
-
- if(gd != 0.0f) {
- sd->Ng = sd->Ng - gd * tg;
- sd->Ng = normalize(sd->Ng);
- }
- }
-
- /* todo: sometimes the normal is still so that this is detected as
- * backfacing even if cull backfaces is enabled */
-
- sd->N = sd->Ng;
- }
- else {
- float4 P_curve[2];
-
- if(sd->type & PRIMITIVE_CURVE) {
- P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
- P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
- }
- else {
- motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
- }
-
- float l = 1.0f;
- tg = normalize_len(float4_to_float3(P_curve[1] - P_curve[0]), &l);
-
- P = P + D*t;
-
- float3 dif = P - float4_to_float3(P_curve[0]);
-
-#ifdef __UV__
- sd->u = dot(dif,tg)/l;
- sd->v = 0.0f;
-#endif
-
- if(flag & CURVE_KN_TRUETANGENTGNORMAL) {
- sd->Ng = -(D - tg * dot(tg, D));
- sd->Ng = normalize(sd->Ng);
- }
- else {
- float gd = isect->v;
-
- /* direction from inside to surface of curve */
- sd->Ng = (dif - tg * sd->u * l) / (P_curve[0].w + sd->u * l * gd);
-
- /* adjustment for changing radius */
- if(gd != 0.0f) {
- sd->Ng = sd->Ng - gd * tg;
- sd->Ng = normalize(sd->Ng);
- }
- }
-
- sd->N = sd->Ng;
- }
-
-#ifdef __DPDU__
- /* dPdu/dPdv */
- sd->dPdu = tg;
- sd->dPdv = cross(tg, sd->Ng);
-#endif
-
- if(isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
- Transform tfm = sd->ob_tfm;
-#else
- Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
-#endif
-
- P = transform_point(&tfm, P);
- }
-
- return P;
-}
-
-#endif
+#endif /* __HAIR__ */
CCL_NAMESPACE_END
-
diff --git a/intern/cycles/kernel/geom/geom_curve_intersect.h b/intern/cycles/kernel/geom/geom_curve_intersect.h
new file mode 100644
index 00000000000..e9a149ea1ab
--- /dev/null
+++ b/intern/cycles/kernel/geom/geom_curve_intersect.h
@@ -0,0 +1,934 @@
+/*
+ * 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
+
+/* Curve primitive intersection functions. */
+
+#ifdef __HAIR__
+
+#if defined(__KERNEL_CUDA__) && (__CUDA_ARCH__ < 300)
+# define ccl_device_curveintersect ccl_device
+#else
+# define ccl_device_curveintersect ccl_device_forceinline
+#endif
+
+#ifdef __KERNEL_SSE2__
+ccl_device_inline ssef transform_point_T3(const ssef t[3], const ssef &a)
+{
+ return madd(shuffle<0>(a), t[0], madd(shuffle<1>(a), t[1], shuffle<2>(a) * t[2]));
+}
+#endif
+
+/* On CPU pass P and dir by reference to aligned vector. */
+ccl_device_curveintersect bool cardinal_curve_intersect(
+ KernelGlobals *kg,
+ Intersection *isect,
+ const float3 ccl_ref P,
+ const float3 ccl_ref dir,
+ uint visibility,
+ int object,
+ int curveAddr,
+ float time,
+ int type,
+ uint *lcg_state,
+ float difl,
+ float extmax)
+{
+ const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
+
+ if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
+ const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
+ if(time < prim_time.x || time > prim_time.y) {
+ return false;
+ }
+ }
+
+ int segment = PRIMITIVE_UNPACK_SEGMENT(type);
+ float epsilon = 0.0f;
+ float r_st, r_en;
+
+ int depth = kernel_data.curve.subdivisions;
+ int flags = kernel_data.curve.curveflags;
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+
+#ifdef __KERNEL_SSE2__
+ ssef vdir = load4f(dir);
+ ssef vcurve_coef[4];
+ const float3 *curve_coef = (float3 *)vcurve_coef;
+
+ {
+ ssef dtmp = vdir * vdir;
+ ssef d_ss = mm_sqrt(dtmp + shuffle<2>(dtmp));
+ ssef rd_ss = load1f_first(1.0f) / d_ss;
+
+ ssei v00vec = load4i((ssei *)&kg->__curves.data[prim]);
+ int2 &v00 = (int2 &)v00vec;
+
+ int k0 = v00.x + segment;
+ int k1 = k0 + 1;
+ int ka = max(k0 - 1, v00.x);
+ int kb = min(k1 + 1, v00.x + v00.y - 1);
+
+#if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) && (!defined(_MSC_VER) || _MSC_VER > 1800)
+ avxf P_curve_0_1, P_curve_2_3;
+ if(is_curve_primitive) {
+ P_curve_0_1 = _mm256_loadu2_m128(&kg->__curve_keys.data[k0].x, &kg->__curve_keys.data[ka].x);
+ P_curve_2_3 = _mm256_loadu2_m128(&kg->__curve_keys.data[kb].x, &kg->__curve_keys.data[k1].x);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
+ motion_cardinal_curve_keys_avx(kg, fobject, prim, time, ka, k0, k1, kb, &P_curve_0_1,&P_curve_2_3);
+ }
+#else /* __KERNEL_AVX2__ */
+ ssef P_curve[4];
+
+ if(is_curve_primitive) {
+ P_curve[0] = load4f(&kg->__curve_keys.data[ka].x);
+ P_curve[1] = load4f(&kg->__curve_keys.data[k0].x);
+ P_curve[2] = load4f(&kg->__curve_keys.data[k1].x);
+ P_curve[3] = load4f(&kg->__curve_keys.data[kb].x);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, (float4*)&P_curve);
+ }
+#endif /* __KERNEL_AVX2__ */
+
+ ssef rd_sgn = set_sign_bit<0, 1, 1, 1>(shuffle<0>(rd_ss));
+ ssef mul_zxxy = shuffle<2, 0, 0, 1>(vdir) * rd_sgn;
+ ssef mul_yz = shuffle<1, 2, 1, 2>(vdir) * mul_zxxy;
+ ssef mul_shuf = shuffle<0, 1, 2, 3>(mul_zxxy, mul_yz);
+ ssef vdir0 = vdir & cast(ssei(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0));
+
+ ssef htfm0 = shuffle<0, 2, 0, 3>(mul_shuf, vdir0);
+ ssef htfm1 = shuffle<1, 0, 1, 3>(load1f_first(extract<0>(d_ss)), vdir0);
+ ssef htfm2 = shuffle<1, 3, 2, 3>(mul_shuf, vdir0);
+
+#if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__) && (!defined(_MSC_VER) || _MSC_VER > 1800)
+ const avxf vPP = _mm256_broadcast_ps(&P.m128);
+ const avxf htfm00 = avxf(htfm0.m128, htfm0.m128);
+ const avxf htfm11 = avxf(htfm1.m128, htfm1.m128);
+ const avxf htfm22 = avxf(htfm2.m128, htfm2.m128);
+
+ const avxf p01 = madd(shuffle<0>(P_curve_0_1 - vPP),
+ htfm00,
+ madd(shuffle<1>(P_curve_0_1 - vPP),
+ htfm11,
+ shuffle<2>(P_curve_0_1 - vPP) * htfm22));
+ const avxf p23 = madd(shuffle<0>(P_curve_2_3 - vPP),
+ htfm00,
+ madd(shuffle<1>(P_curve_2_3 - vPP),
+ htfm11,
+ shuffle<2>(P_curve_2_3 - vPP)*htfm22));
+
+ const ssef p0 = _mm256_castps256_ps128(p01);
+ const ssef p1 = _mm256_extractf128_ps(p01, 1);
+ const ssef p2 = _mm256_castps256_ps128(p23);
+ const ssef p3 = _mm256_extractf128_ps(p23, 1);
+
+ const ssef P_curve_1 = _mm256_extractf128_ps(P_curve_0_1, 1);
+ r_st = ((float4 &)P_curve_1).w;
+ const ssef P_curve_2 = _mm256_castps256_ps128(P_curve_2_3);
+ r_en = ((float4 &)P_curve_2).w;
+#else /* __KERNEL_AVX2__ */
+ ssef htfm[] = { htfm0, htfm1, htfm2 };
+ ssef vP = load4f(P);
+ ssef p0 = transform_point_T3(htfm, P_curve[0] - vP);
+ ssef p1 = transform_point_T3(htfm, P_curve[1] - vP);
+ ssef p2 = transform_point_T3(htfm, P_curve[2] - vP);
+ ssef p3 = transform_point_T3(htfm, P_curve[3] - vP);
+
+ r_st = ((float4 &)P_curve[1]).w;
+ r_en = ((float4 &)P_curve[2]).w;
+#endif /* __KERNEL_AVX2__ */
+
+ float fc = 0.71f;
+ ssef vfc = ssef(fc);
+ ssef vfcxp3 = vfc * p3;
+
+ vcurve_coef[0] = p1;
+ vcurve_coef[1] = vfc * (p2 - p0);
+ vcurve_coef[2] = madd(ssef(fc * 2.0f), p0, madd(ssef(fc - 3.0f), p1, msub(ssef(3.0f - 2.0f * fc), p2, vfcxp3)));
+ vcurve_coef[3] = msub(ssef(fc - 2.0f), p2 - p1, msub(vfc, p0, vfcxp3));
+
+ }
+#else
+ float3 curve_coef[4];
+
+ /* curve Intersection check */
+ /* obtain curve parameters */
+ {
+ /* ray transform created - this should be created at beginning of intersection loop */
+ Transform htfm;
+ float d = sqrtf(dir.x * dir.x + dir.z * dir.z);
+ htfm = make_transform(
+ dir.z / d, 0, -dir.x /d, 0,
+ -dir.x * dir.y /d, d, -dir.y * dir.z /d, 0,
+ dir.x, dir.y, dir.z, 0,
+ 0, 0, 0, 1);
+
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + segment;
+ int k1 = k0 + 1;
+
+ int ka = max(k0 - 1,__float_as_int(v00.x));
+ int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
+
+ float4 P_curve[4];
+
+ if(is_curve_primitive) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, P_curve);
+ }
+
+ float3 p0 = transform_point(&htfm, float4_to_float3(P_curve[0]) - P);
+ float3 p1 = transform_point(&htfm, float4_to_float3(P_curve[1]) - P);
+ float3 p2 = transform_point(&htfm, float4_to_float3(P_curve[2]) - P);
+ float3 p3 = transform_point(&htfm, float4_to_float3(P_curve[3]) - P);
+
+ float fc = 0.71f;
+ curve_coef[0] = p1;
+ curve_coef[1] = -fc*p0 + fc*p2;
+ curve_coef[2] = 2.0f * fc * p0 + (fc - 3.0f) * p1 + (3.0f - 2.0f * fc) * p2 - fc * p3;
+ curve_coef[3] = -fc * p0 + (2.0f - fc) * p1 + (fc - 2.0f) * p2 + fc * p3;
+ r_st = P_curve[1].w;
+ r_en = P_curve[2].w;
+ }
+#endif
+
+ float r_curr = max(r_st, r_en);
+
+ if((flags & CURVE_KN_RIBBONS) || !(flags & CURVE_KN_BACKFACING))
+ epsilon = 2 * r_curr;
+
+ /* find bounds - this is slow for cubic curves */
+ float upper, lower;
+
+ float zextrem[4];
+ curvebounds(&lower, &upper, &zextrem[0], &zextrem[1], &zextrem[2], &zextrem[3], curve_coef[0].z, curve_coef[1].z, curve_coef[2].z, curve_coef[3].z);
+ if(lower - r_curr > isect->t || upper + r_curr < epsilon)
+ return false;
+
+ /* minimum width extension */
+ float mw_extension = min(difl * fabsf(upper), extmax);
+ float r_ext = mw_extension + r_curr;
+
+ float xextrem[4];
+ curvebounds(&lower, &upper, &xextrem[0], &xextrem[1], &xextrem[2], &xextrem[3], curve_coef[0].x, curve_coef[1].x, curve_coef[2].x, curve_coef[3].x);
+ if(lower > r_ext || upper < -r_ext)
+ return false;
+
+ float yextrem[4];
+ curvebounds(&lower, &upper, &yextrem[0], &yextrem[1], &yextrem[2], &yextrem[3], curve_coef[0].y, curve_coef[1].y, curve_coef[2].y, curve_coef[3].y);
+ if(lower > r_ext || upper < -r_ext)
+ return false;
+
+ /* setup recurrent loop */
+ int level = 1 << depth;
+ int tree = 0;
+ float resol = 1.0f / (float)level;
+ bool hit = false;
+
+ /* begin loop */
+ while(!(tree >> (depth))) {
+ const float i_st = tree * resol;
+ const float i_en = i_st + (level * resol);
+
+#ifdef __KERNEL_SSE2__
+ ssef vi_st = ssef(i_st), vi_en = ssef(i_en);
+ ssef vp_st = madd(madd(madd(vcurve_coef[3], vi_st, vcurve_coef[2]), vi_st, vcurve_coef[1]), vi_st, vcurve_coef[0]);
+ ssef vp_en = madd(madd(madd(vcurve_coef[3], vi_en, vcurve_coef[2]), vi_en, vcurve_coef[1]), vi_en, vcurve_coef[0]);
+
+ ssef vbmin = min(vp_st, vp_en);
+ ssef vbmax = max(vp_st, vp_en);
+
+ float3 &bmin = (float3 &)vbmin, &bmax = (float3 &)vbmax;
+ float &bminx = bmin.x, &bminy = bmin.y, &bminz = bmin.z;
+ float &bmaxx = bmax.x, &bmaxy = bmax.y, &bmaxz = bmax.z;
+ float3 &p_st = (float3 &)vp_st, &p_en = (float3 &)vp_en;
+#else
+ float3 p_st = ((curve_coef[3] * i_st + curve_coef[2]) * i_st + curve_coef[1]) * i_st + curve_coef[0];
+ float3 p_en = ((curve_coef[3] * i_en + curve_coef[2]) * i_en + curve_coef[1]) * i_en + curve_coef[0];
+
+ float bminx = min(p_st.x, p_en.x);
+ float bmaxx = max(p_st.x, p_en.x);
+ float bminy = min(p_st.y, p_en.y);
+ float bmaxy = max(p_st.y, p_en.y);
+ float bminz = min(p_st.z, p_en.z);
+ float bmaxz = max(p_st.z, p_en.z);
+#endif
+
+ if(xextrem[0] >= i_st && xextrem[0] <= i_en) {
+ bminx = min(bminx,xextrem[1]);
+ bmaxx = max(bmaxx,xextrem[1]);
+ }
+ if(xextrem[2] >= i_st && xextrem[2] <= i_en) {
+ bminx = min(bminx,xextrem[3]);
+ bmaxx = max(bmaxx,xextrem[3]);
+ }
+ if(yextrem[0] >= i_st && yextrem[0] <= i_en) {
+ bminy = min(bminy,yextrem[1]);
+ bmaxy = max(bmaxy,yextrem[1]);
+ }
+ if(yextrem[2] >= i_st && yextrem[2] <= i_en) {
+ bminy = min(bminy,yextrem[3]);
+ bmaxy = max(bmaxy,yextrem[3]);
+ }
+ if(zextrem[0] >= i_st && zextrem[0] <= i_en) {
+ bminz = min(bminz,zextrem[1]);
+ bmaxz = max(bmaxz,zextrem[1]);
+ }
+ if(zextrem[2] >= i_st && zextrem[2] <= i_en) {
+ bminz = min(bminz,zextrem[3]);
+ bmaxz = max(bmaxz,zextrem[3]);
+ }
+
+ float r1 = r_st + (r_en - r_st) * i_st;
+ float r2 = r_st + (r_en - r_st) * i_en;
+ r_curr = max(r1, r2);
+
+ mw_extension = min(difl * fabsf(bmaxz), extmax);
+ float r_ext = mw_extension + r_curr;
+ float coverage = 1.0f;
+
+ if(bminz - r_curr > isect->t || bmaxz + r_curr < epsilon || bminx > r_ext|| bmaxx < -r_ext|| bminy > r_ext|| bmaxy < -r_ext) {
+ /* the bounding box does not overlap the square centered at O */
+ tree += level;
+ level = tree & -tree;
+ }
+ else if(level == 1) {
+
+ /* the maximum recursion depth is reached.
+ * check if dP0.(Q-P0)>=0 and dPn.(Pn-Q)>=0.
+ * dP* is reversed if necessary.*/
+ float t = isect->t;
+ float u = 0.0f;
+ float gd = 0.0f;
+
+ if(flags & CURVE_KN_RIBBONS) {
+ float3 tg = (p_en - p_st);
+#ifdef __KERNEL_SSE__
+ const float3 tg_sq = tg * tg;
+ float w = tg_sq.x + tg_sq.y;
+#else
+ float w = tg.x * tg.x + tg.y * tg.y;
+#endif
+ if(w == 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+#ifdef __KERNEL_SSE__
+ const float3 p_sttg = p_st * tg;
+ w = -(p_sttg.x + p_sttg.y) / w;
+#else
+ w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
+#endif
+ w = saturate(w);
+
+ /* compute u on the curve segment */
+ u = i_st * (1 - w) + i_en * w;
+ r_curr = r_st + (r_en - r_st) * u;
+ /* compare x-y distances */
+ float3 p_curr = ((curve_coef[3] * u + curve_coef[2]) * u + curve_coef[1]) * u + curve_coef[0];
+
+ float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
+ if(dot(tg, dp_st)< 0)
+ dp_st *= -1;
+ if(dot(dp_st, -p_st) + p_curr.z * dp_st.z < 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+ float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
+ if(dot(tg, dp_en) < 0)
+ dp_en *= -1;
+ if(dot(dp_en, p_en) - p_curr.z * dp_en.z < 0) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ /* compute coverage */
+ float r_ext = r_curr;
+ coverage = 1.0f;
+ if(difl != 0.0f) {
+ mw_extension = min(difl * fabsf(bmaxz), extmax);
+ r_ext = mw_extension + r_curr;
+#ifdef __KERNEL_SSE__
+ const float3 p_curr_sq = p_curr * p_curr;
+ const float3 dxxx(_mm_sqrt_ss(_mm_hadd_ps(p_curr_sq.m128, p_curr_sq.m128)));
+ float d = dxxx.x;
+#else
+ float d = sqrtf(p_curr.x * p_curr.x + p_curr.y * p_curr.y);
+#endif
+ float d0 = d - r_curr;
+ float d1 = d + r_curr;
+ float inv_mw_extension = 1.0f/mw_extension;
+ if(d0 >= 0)
+ coverage = (min(d1 * inv_mw_extension, 1.0f) - min(d0 * inv_mw_extension, 1.0f)) * 0.5f;
+ else // inside
+ coverage = (min(d1 * inv_mw_extension, 1.0f) + min(-d0 * inv_mw_extension, 1.0f)) * 0.5f;
+ }
+
+ if(p_curr.x * p_curr.x + p_curr.y * p_curr.y >= r_ext * r_ext || p_curr.z <= epsilon || isect->t < p_curr.z) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ t = p_curr.z;
+
+ /* stochastic fade from minimum width */
+ if(difl != 0.0f && lcg_state) {
+ if(coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
+ return hit;
+ }
+ }
+ else {
+ float l = len(p_en - p_st);
+ /* minimum width extension */
+ float or1 = r1;
+ float or2 = r2;
+
+ if(difl != 0.0f) {
+ mw_extension = min(len(p_st - P) * difl, extmax);
+ or1 = r1 < mw_extension ? mw_extension : r1;
+ mw_extension = min(len(p_en - P) * difl, extmax);
+ or2 = r2 < mw_extension ? mw_extension : r2;
+ }
+ /* --- */
+ float invl = 1.0f/l;
+ float3 tg = (p_en - p_st) * invl;
+ gd = (or2 - or1) * invl;
+ float difz = -dot(p_st,tg);
+ float cyla = 1.0f - (tg.z * tg.z * (1 + gd*gd));
+ float invcyla = 1.0f/cyla;
+ float halfb = (-p_st.z - tg.z*(difz + gd*(difz*gd + or1)));
+ float tcentre = -halfb*invcyla;
+ float zcentre = difz + (tg.z * tcentre);
+ float3 tdif = - p_st;
+ tdif.z += tcentre;
+ float tdifz = dot(tdif,tg);
+ float tb = 2*(tdif.z - tg.z*(tdifz + gd*(tdifz*gd + or1)));
+ float tc = dot(tdif,tdif) - tdifz * tdifz * (1 + gd*gd) - or1*or1 - 2*or1*tdifz*gd;
+ float td = tb*tb - 4*cyla*tc;
+ if(td < 0.0f) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ float rootd = sqrtf(td);
+ float correction = (-tb - rootd) * 0.5f * invcyla;
+ t = tcentre + correction;
+
+ float3 dp_st = (3 * curve_coef[3] * i_st + 2 * curve_coef[2]) * i_st + curve_coef[1];
+ if(dot(tg, dp_st)< 0)
+ dp_st *= -1;
+ float3 dp_en = (3 * curve_coef[3] * i_en + 2 * curve_coef[2]) * i_en + curve_coef[1];
+ if(dot(tg, dp_en) < 0)
+ dp_en *= -1;
+
+ if(flags & CURVE_KN_BACKFACING && (dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f)) {
+ correction = (-tb + rootd) * 0.5f * invcyla;
+ t = tcentre + correction;
+ }
+
+ if(dot(dp_st, -p_st) + t * dp_st.z < 0 || dot(dp_en, p_en) - t * dp_en.z < 0 || isect->t < t || t <= 0.0f) {
+ tree++;
+ level = tree & -tree;
+ continue;
+ }
+
+ float w = (zcentre + (tg.z * correction)) * invl;
+ w = saturate(w);
+ /* compute u on the curve segment */
+ u = i_st * (1 - w) + i_en * w;
+
+ /* stochastic fade from minimum width */
+ if(difl != 0.0f && lcg_state) {
+ r_curr = r1 + (r2 - r1) * w;
+ r_ext = or1 + (or2 - or1) * w;
+ coverage = r_curr/r_ext;
+
+ if(coverage != 1.0f && (lcg_step_float(lcg_state) > coverage))
+ return hit;
+ }
+ }
+ /* we found a new intersection */
+
+#ifdef __VISIBILITY_FLAG__
+ /* visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags */
+ if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
+#endif
+ {
+ /* record intersection */
+ isect->t = t;
+ isect->u = u;
+ isect->v = gd;
+ isect->prim = curveAddr;
+ isect->object = object;
+ isect->type = type;
+ hit = true;
+ }
+
+ tree++;
+ level = tree & -tree;
+ }
+ else {
+ /* split the curve into two curves and process */
+ level = level >> 1;
+ }
+ }
+
+ return hit;
+}
+
+ccl_device_curveintersect bool curve_intersect(KernelGlobals *kg,
+ Intersection *isect,
+ float3 P,
+ float3 direction,
+ uint visibility,
+ int object,
+ int curveAddr,
+ float time,
+ int type,
+ uint *lcg_state,
+ float difl,
+ float extmax)
+{
+ /* define few macros to minimize code duplication for SSE */
+#ifndef __KERNEL_SSE2__
+# define len3_squared(x) len_squared(x)
+# define len3(x) len(x)
+# define dot3(x, y) dot(x, y)
+#endif
+
+ const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
+
+ if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
+ const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
+ if(time < prim_time.x || time > prim_time.y) {
+ return false;
+ }
+ }
+
+ int segment = PRIMITIVE_UNPACK_SEGMENT(type);
+ /* curve Intersection check */
+ int flags = kernel_data.curve.curveflags;
+
+ int prim = kernel_tex_fetch(__prim_index, curveAddr);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int cnum = __float_as_int(v00.x);
+ int k0 = cnum + segment;
+ int k1 = k0 + 1;
+
+#ifndef __KERNEL_SSE2__
+ float4 P_curve[2];
+
+ if(is_curve_primitive) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_curve_keys(kg, fobject, prim, time, k0, k1, P_curve);
+ }
+
+ float or1 = P_curve[0].w;
+ float or2 = P_curve[1].w;
+ float3 p1 = float4_to_float3(P_curve[0]);
+ float3 p2 = float4_to_float3(P_curve[1]);
+
+ /* minimum width extension */
+ float r1 = or1;
+ float r2 = or2;
+ float3 dif = P - p1;
+ float3 dif_second = P - p2;
+ if(difl != 0.0f) {
+ float pixelsize = min(len3(dif) * difl, extmax);
+ r1 = or1 < pixelsize ? pixelsize : or1;
+ pixelsize = min(len3(dif_second) * difl, extmax);
+ r2 = or2 < pixelsize ? pixelsize : or2;
+ }
+ /* --- */
+
+ float3 p21_diff = p2 - p1;
+ float3 sphere_dif1 = (dif + dif_second) * 0.5f;
+ float3 dir = direction;
+ float sphere_b_tmp = dot3(dir, sphere_dif1);
+ float3 sphere_dif2 = sphere_dif1 - sphere_b_tmp * dir;
+#else
+ ssef P_curve[2];
+
+ if(is_curve_primitive) {
+ P_curve[0] = load4f(&kg->__curve_keys.data[k0].x);
+ P_curve[1] = load4f(&kg->__curve_keys.data[k1].x);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
+ motion_curve_keys(kg, fobject, prim, time, k0, k1, (float4*)&P_curve);
+ }
+
+ const ssef or12 = shuffle<3, 3, 3, 3>(P_curve[0], P_curve[1]);
+
+ ssef r12 = or12;
+ const ssef vP = load4f(P);
+ const ssef dif = vP - P_curve[0];
+ const ssef dif_second = vP - P_curve[1];
+ if(difl != 0.0f) {
+ const ssef len1_sq = len3_squared_splat(dif);
+ const ssef len2_sq = len3_squared_splat(dif_second);
+ const ssef len12 = mm_sqrt(shuffle<0, 0, 0, 0>(len1_sq, len2_sq));
+ const ssef pixelsize12 = min(len12 * difl, ssef(extmax));
+ r12 = max(or12, pixelsize12);
+ }
+ float or1 = extract<0>(or12), or2 = extract<0>(shuffle<2>(or12));
+ float r1 = extract<0>(r12), r2 = extract<0>(shuffle<2>(r12));
+
+ const ssef p21_diff = P_curve[1] - P_curve[0];
+ const ssef sphere_dif1 = (dif + dif_second) * 0.5f;
+ const ssef dir = load4f(direction);
+ const ssef sphere_b_tmp = dot3_splat(dir, sphere_dif1);
+ const ssef sphere_dif2 = nmadd(sphere_b_tmp, dir, sphere_dif1);
+#endif
+
+ float mr = max(r1, r2);
+ float l = len3(p21_diff);
+ float invl = 1.0f / l;
+ float sp_r = mr + 0.5f * l;
+
+ float sphere_b = dot3(dir, sphere_dif2);
+ float sdisc = sphere_b * sphere_b - len3_squared(sphere_dif2) + sp_r * sp_r;
+
+ if(sdisc < 0.0f)
+ return false;
+
+ /* obtain parameters and test midpoint distance for suitable modes */
+#ifndef __KERNEL_SSE2__
+ float3 tg = p21_diff * invl;
+#else
+ const ssef tg = p21_diff * invl;
+#endif
+ float gd = (r2 - r1) * invl;
+
+ float dirz = dot3(dir, tg);
+ float difz = dot3(dif, tg);
+
+ float a = 1.0f - (dirz*dirz*(1 + gd*gd));
+
+ float halfb = dot3(dir, dif) - dirz*(difz + gd*(difz*gd + r1));
+
+ float tcentre = -halfb/a;
+ float zcentre = difz + (dirz * tcentre);
+
+ if((tcentre > isect->t) && !(flags & CURVE_KN_ACCURATE))
+ return false;
+ if((zcentre < 0 || zcentre > l) && !(flags & CURVE_KN_ACCURATE) && !(flags & CURVE_KN_INTERSECTCORRECTION))
+ return false;
+
+ /* test minimum separation */
+#ifndef __KERNEL_SSE2__
+ float3 cprod = cross(tg, dir);
+ float cprod2sq = len3_squared(cross(tg, dif));
+#else
+ const ssef cprod = cross(tg, dir);
+ float cprod2sq = len3_squared(cross_zxy(tg, dif));
+#endif
+ float cprodsq = len3_squared(cprod);
+ float distscaled = dot3(cprod, dif);
+
+ if(cprodsq == 0)
+ distscaled = cprod2sq;
+ else
+ distscaled = (distscaled*distscaled)/cprodsq;
+
+ if(distscaled > mr*mr)
+ return false;
+
+ /* calculate true intersection */
+#ifndef __KERNEL_SSE2__
+ float3 tdif = dif + tcentre * dir;
+#else
+ const ssef tdif = madd(ssef(tcentre), dir, dif);
+#endif
+ float tdifz = dot3(tdif, tg);
+ float tdifma = tdifz*gd + r1;
+ float tb = 2*(dot3(dir, tdif) - dirz*(tdifz + gd*tdifma));
+ float tc = dot3(tdif, tdif) - tdifz*tdifz - tdifma*tdifma;
+ float td = tb*tb - 4*a*tc;
+
+ if(td < 0.0f)
+ return false;
+
+ float rootd = 0.0f;
+ float correction = 0.0f;
+ if(flags & CURVE_KN_ACCURATE) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd)/(2*a));
+ }
+
+ float t = tcentre + correction;
+
+ if(t < isect->t) {
+
+ if(flags & CURVE_KN_INTERSECTCORRECTION) {
+ rootd = sqrtf(td);
+ correction = ((-tb - rootd)/(2*a));
+ t = tcentre + correction;
+ }
+
+ float z = zcentre + (dirz * correction);
+ // bool backface = false;
+
+ if(flags & CURVE_KN_BACKFACING && (t < 0.0f || z < 0 || z > l)) {
+ // backface = true;
+ correction = ((-tb + rootd)/(2*a));
+ t = tcentre + correction;
+ z = zcentre + (dirz * correction);
+ }
+
+ /* stochastic fade from minimum width */
+ float adjradius = or1 + z * (or2 - or1) * invl;
+ adjradius = adjradius / (r1 + z * gd);
+ if(lcg_state && adjradius != 1.0f) {
+ if(lcg_step_float(lcg_state) > adjradius)
+ return false;
+ }
+ /* --- */
+
+ if(t > 0.0f && t < isect->t && z >= 0 && z <= l) {
+
+ if(flags & CURVE_KN_ENCLOSEFILTER) {
+ float enc_ratio = 1.01f;
+ if((difz > -r1 * enc_ratio) && (dot3(dif_second, tg) < r2 * enc_ratio)) {
+ float a2 = 1.0f - (dirz*dirz*(1 + gd*gd*enc_ratio*enc_ratio));
+ float c2 = dot3(dif, dif) - difz * difz * (1 + gd*gd*enc_ratio*enc_ratio) - r1*r1*enc_ratio*enc_ratio - 2*r1*difz*gd*enc_ratio;
+ if(a2*c2 < 0.0f)
+ return false;
+ }
+ }
+
+#ifdef __VISIBILITY_FLAG__
+ /* visibility flag test. we do it here under the assumption
+ * that most triangles are culled by node flags */
+ if(kernel_tex_fetch(__prim_visibility, curveAddr) & visibility)
+#endif
+ {
+ /* record intersection */
+ isect->t = t;
+ isect->u = z*invl;
+ isect->v = gd;
+ isect->prim = curveAddr;
+ isect->object = object;
+ isect->type = type;
+
+ return true;
+ }
+ }
+ }
+
+ return false;
+
+#ifndef __KERNEL_SSE2__
+# undef len3_squared
+# undef len3
+# undef dot3
+#endif
+}
+
+ccl_device_inline float3 curvetangent(float t, float3 p0, float3 p1, float3 p2, float3 p3)
+{
+ float fc = 0.71f;
+ float data[4];
+ float t2 = t * t;
+ data[0] = -3.0f * fc * t2 + 4.0f * fc * t - fc;
+ data[1] = 3.0f * (2.0f - fc) * t2 + 2.0f * (fc - 3.0f) * t;
+ data[2] = 3.0f * (fc - 2.0f) * t2 + 2.0f * (3.0f - 2.0f * fc) * t + fc;
+ data[3] = 3.0f * fc * t2 - 2.0f * fc * t;
+ return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
+}
+
+ccl_device_inline float3 curvepoint(float t, float3 p0, float3 p1, float3 p2, float3 p3)
+{
+ float data[4];
+ float fc = 0.71f;
+ float t2 = t * t;
+ float t3 = t2 * t;
+ data[0] = -fc * t3 + 2.0f * fc * t2 - fc * t;
+ data[1] = (2.0f - fc) * t3 + (fc - 3.0f) * t2 + 1.0f;
+ data[2] = (fc - 2.0f) * t3 + (3.0f - 2.0f * fc) * t2 + fc * t;
+ data[3] = fc * t3 - fc * t2;
+ return data[0] * p0 + data[1] * p1 + data[2] * p2 + data[3] * p3;
+}
+
+ccl_device_inline float3 curve_refine(KernelGlobals *kg,
+ ShaderData *sd,
+ const Intersection *isect,
+ const Ray *ray)
+{
+ int flag = kernel_data.curve.curveflags;
+ float t = isect->t;
+ float3 P = ray->P;
+ float3 D = ray->D;
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_itfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ D = transform_direction(&tfm, D*t);
+ D = normalize_len(D, &t);
+ }
+
+ int prim = kernel_tex_fetch(__prim_index, isect->prim);
+ float4 v00 = kernel_tex_fetch(__curves, prim);
+
+ int k0 = __float_as_int(v00.x) + PRIMITIVE_UNPACK_SEGMENT(sd->type);
+ int k1 = k0 + 1;
+
+ float3 tg;
+
+ if(flag & CURVE_KN_INTERPOLATE) {
+ int ka = max(k0 - 1,__float_as_int(v00.x));
+ int kb = min(k1 + 1,__float_as_int(v00.x) + __float_as_int(v00.y) - 1);
+
+ float4 P_curve[4];
+
+ if(sd->type & PRIMITIVE_CURVE) {
+ P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
+ P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
+ P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
+ P_curve[3] = kernel_tex_fetch(__curve_keys, kb);
+ }
+ else {
+ motion_cardinal_curve_keys(kg, sd->object, sd->prim, sd->time, ka, k0, k1, kb, P_curve);
+ }
+
+ float3 p[4];
+ p[0] = float4_to_float3(P_curve[0]);
+ p[1] = float4_to_float3(P_curve[1]);
+ p[2] = float4_to_float3(P_curve[2]);
+ p[3] = float4_to_float3(P_curve[3]);
+
+ P = P + D*t;
+
+#ifdef __UV__
+ sd->u = isect->u;
+ sd->v = 0.0f;
+#endif
+
+ tg = normalize(curvetangent(isect->u, p[0], p[1], p[2], p[3]));
+
+ if(kernel_data.curve.curveflags & CURVE_KN_RIBBONS) {
+ sd->Ng = normalize(-(D - tg * (dot(tg, D))));
+ }
+ else {
+ /* direction from inside to surface of curve */
+ float3 p_curr = curvepoint(isect->u, p[0], p[1], p[2], p[3]);
+ sd->Ng = normalize(P - p_curr);
+
+ /* adjustment for changing radius */
+ float gd = isect->v;
+
+ if(gd != 0.0f) {
+ sd->Ng = sd->Ng - gd * tg;
+ sd->Ng = normalize(sd->Ng);
+ }
+ }
+
+ /* todo: sometimes the normal is still so that this is detected as
+ * backfacing even if cull backfaces is enabled */
+
+ sd->N = sd->Ng;
+ }
+ else {
+ float4 P_curve[2];
+
+ if(sd->type & PRIMITIVE_CURVE) {
+ P_curve[0]= kernel_tex_fetch(__curve_keys, k0);
+ P_curve[1]= kernel_tex_fetch(__curve_keys, k1);
+ }
+ else {
+ motion_curve_keys(kg, sd->object, sd->prim, sd->time, k0, k1, P_curve);
+ }
+
+ float l = 1.0f;
+ tg = normalize_len(float4_to_float3(P_curve[1] - P_curve[0]), &l);
+
+ P = P + D*t;
+
+ float3 dif = P - float4_to_float3(P_curve[0]);
+
+#ifdef __UV__
+ sd->u = dot(dif,tg)/l;
+ sd->v = 0.0f;
+#endif
+
+ if(flag & CURVE_KN_TRUETANGENTGNORMAL) {
+ sd->Ng = -(D - tg * dot(tg, D));
+ sd->Ng = normalize(sd->Ng);
+ }
+ else {
+ float gd = isect->v;
+
+ /* direction from inside to surface of curve */
+ sd->Ng = (dif - tg * sd->u * l) / (P_curve[0].w + sd->u * l * gd);
+
+ /* adjustment for changing radius */
+ if(gd != 0.0f) {
+ sd->Ng = sd->Ng - gd * tg;
+ sd->Ng = normalize(sd->Ng);
+ }
+ }
+
+ sd->N = sd->Ng;
+ }
+
+#ifdef __DPDU__
+ /* dPdu/dPdv */
+ sd->dPdu = tg;
+ sd->dPdv = cross(tg, sd->Ng);
+#endif
+
+ if(isect->object != OBJECT_NONE) {
+#ifdef __OBJECT_MOTION__
+ Transform tfm = sd->ob_tfm;
+#else
+ Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
+#endif
+
+ P = transform_point(&tfm, P);
+ }
+
+ return P;
+}
+
+#endif
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/geom/geom_object.h b/intern/cycles/kernel/geom/geom_object.h
index 6ecdfe0173a..1ffc143be34 100644
--- a/intern/cycles/kernel/geom/geom_object.h
+++ b/intern/cycles/kernel/geom/geom_object.h
@@ -415,12 +415,7 @@ ccl_device_inline float3 bvh_clamp_direction(float3 dir)
ccl_device_inline float3 bvh_inverse_direction(float3 dir)
{
- /* TODO(sergey): Currently disabled, gives speedup but causes precision issues. */
-#if defined(__KERNEL_SSE__) && 0
return rcp(dir);
-#else
- return 1.0f / dir;
-#endif
}
/* Transform ray into object space to enter static object in BVH */
diff --git a/intern/cycles/kernel/kernel_accumulate.h b/intern/cycles/kernel/kernel_accumulate.h
index 9ed16aceb55..82d3c153bf5 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -21,6 +21,9 @@ CCL_NAMESPACE_BEGIN
* BSDF evaluation result, split per BSDF type. This is used to accumulate
* render passes separately. */
+ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg,
+ const ShaderData *sd);
+
ccl_device_inline void bsdf_eval_init(BsdfEval *eval, ClosureType type, float3 value, int use_light_pass)
{
#ifdef __PASSES__
@@ -205,6 +208,7 @@ ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
L->path_subsurface = make_float3(0.0f, 0.0f, 0.0f);
L->path_scatter = make_float3(0.0f, 0.0f, 0.0f);
+ L->transparent = 0.0f;
L->emission = make_float3(0.0f, 0.0f, 0.0f);
L->background = make_float3(0.0f, 0.0f, 0.0f);
L->ao = make_float3(0.0f, 0.0f, 0.0f);
@@ -214,6 +218,7 @@ ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
else
#endif
{
+ L->transparent = 0.0f;
L->emission = make_float3(0.0f, 0.0f, 0.0f);
}
@@ -223,13 +228,21 @@ ccl_device_inline void path_radiance_init(PathRadiance *L, int use_light_pass)
L->shadow_background_color = make_float3(0.0f, 0.0f, 0.0f);
L->shadow_radiance_sum = make_float3(0.0f, 0.0f, 0.0f);
L->shadow_throughput = 0.0f;
+ L->shadow_transparency = 1.0f;
#endif
#ifdef __DENOISING_FEATURES__
L->denoising_normal = make_float3(0.0f, 0.0f, 0.0f);
L->denoising_albedo = make_float3(0.0f, 0.0f, 0.0f);
L->denoising_depth = 0.0f;
-#endif /* __DENOISING_FEATURES__ */
+#endif
+
+#ifdef __KERNEL_DEBUG__
+ L->debug_data.num_bvh_traversed_nodes = 0;
+ L->debug_data.num_bvh_traversed_instances = 0;
+ L->debug_data.num_bvh_intersections = 0;
+ L->debug_data.num_ray_bounces = 0;
+#endif
}
ccl_device_inline void path_radiance_bsdf_bounce(PathRadiance *L, ccl_addr_space float3 *throughput,
@@ -398,10 +411,11 @@ ccl_device_inline void path_radiance_accum_total_light(
#endif
}
-ccl_device_inline void path_radiance_accum_background(PathRadiance *L,
- ccl_addr_space PathState *state,
- float3 throughput,
- float3 value)
+ccl_device_inline void path_radiance_accum_background(
+ PathRadiance *L,
+ ccl_addr_space PathState *state,
+ float3 throughput,
+ float3 value)
{
#ifdef __PASSES__
if(L->use_light_pass) {
@@ -421,9 +435,7 @@ ccl_device_inline void path_radiance_accum_background(PathRadiance *L,
#ifdef __SHADOW_TRICKS__
if(state->flag & PATH_RAY_STORE_SHADOW_INFO) {
L->path_total += throughput * value;
- if(state->flag & PATH_RAY_SHADOW_CATCHER_ONLY) {
- L->path_total_shaded += throughput * value;
- }
+ L->path_total_shaded += throughput * value * L->shadow_transparency;
}
#endif
@@ -671,7 +683,7 @@ ccl_device_inline float path_radiance_sum_shadow(const PathRadiance *L)
if(path_total != 0.0f) {
return path_total_shaded / path_total;
}
- return 1.0f;
+ return L->shadow_transparency;
}
/* Calculate final light sum and transparency for shadow catcher object. */
diff --git a/intern/cycles/kernel/kernel_compat_cuda.h b/intern/cycles/kernel/kernel_compat_cuda.h
index 38708f7ff0b..6d1cf055f2c 100644
--- a/intern/cycles/kernel/kernel_compat_cuda.h
+++ b/intern/cycles/kernel/kernel_compat_cuda.h
@@ -53,6 +53,10 @@
#define ccl_may_alias
#define ccl_addr_space
#define ccl_restrict __restrict__
+/* TODO(sergey): In theory we might use references with CUDA, however
+ * performance impact yet to be investigated.
+ */
+#define ccl_ref
#define ccl_align(n) __align__(n)
#define ATTR_FALLTHROUGH
diff --git a/intern/cycles/kernel/kernel_compat_opencl.h b/intern/cycles/kernel/kernel_compat_opencl.h
index 4836c290312..36d6031d042 100644
--- a/intern/cycles/kernel/kernel_compat_opencl.h
+++ b/intern/cycles/kernel/kernel_compat_opencl.h
@@ -42,6 +42,7 @@
#define ccl_local_param __local
#define ccl_private __private
#define ccl_restrict restrict
+#define ccl_ref
#define ccl_align(n) __attribute__((aligned(n)))
#ifdef __SPLIT_KERNEL__
@@ -129,6 +130,7 @@
# define expf(x) native_exp(((float)(x)))
# define sqrtf(x) native_sqrt(((float)(x)))
# define logf(x) native_log(((float)(x)))
+# define rcp(x) native_recip(x)
#else
# define sinf(x) sin(((float)(x)))
# define cosf(x) cos(((float)(x)))
@@ -136,11 +138,12 @@
# define expf(x) exp(((float)(x)))
# define sqrtf(x) sqrt(((float)(x)))
# define logf(x) log(((float)(x)))
+# define rcp(x) recip(x))
#endif
/* data lookup defines */
#define kernel_data (*kg->data)
-#define kernel_tex_fetch(t, index) kg->t[index]
+#define kernel_tex_fetch(tex, index) ((ccl_global tex##_t*)(kg->buffers[kg->tex.buffer] + kg->tex.offset))[(index)]
/* define NULL */
#define NULL 0
diff --git a/intern/cycles/kernel/kernel_debug.h b/intern/cycles/kernel/kernel_debug.h
deleted file mode 100644
index 5647bbae5b5..00000000000
--- a/intern/cycles/kernel/kernel_debug.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright 2011-2014 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
-
-ccl_device_inline void debug_data_init(DebugData *debug_data)
-{
- debug_data->num_bvh_traversed_nodes = 0;
- debug_data->num_bvh_traversed_instances = 0;
- debug_data->num_bvh_intersections = 0;
- debug_data->num_ray_bounces = 0;
-}
-
-ccl_device_inline void kernel_write_debug_passes(KernelGlobals *kg,
- ccl_global float *buffer,
- ccl_addr_space PathState *state,
- DebugData *debug_data,
- int sample)
-{
- int flag = kernel_data.film.pass_flag;
- if(flag & PASS_BVH_TRAVERSED_NODES) {
- kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_nodes,
- sample,
- debug_data->num_bvh_traversed_nodes);
- }
- if(flag & PASS_BVH_TRAVERSED_INSTANCES) {
- kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_instances,
- sample,
- debug_data->num_bvh_traversed_instances);
- }
- if(flag & PASS_BVH_INTERSECTIONS) {
- kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_intersections,
- sample,
- debug_data->num_bvh_intersections);
- }
- if(flag & PASS_RAY_BOUNCES) {
- kernel_write_pass_float(buffer + kernel_data.film.pass_ray_bounces,
- sample,
- debug_data->num_ray_bounces);
- }
-}
-
-CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_globals.h b/intern/cycles/kernel/kernel_globals.h
index f95f0d98c52..9d55183d94b 100644
--- a/intern/cycles/kernel/kernel_globals.h
+++ b/intern/cycles/kernel/kernel_globals.h
@@ -23,6 +23,10 @@
# include "util/util_vector.h"
#endif
+#ifdef __KERNEL_OPENCL__
+# include "util/util_atomic.h"
+#endif
+
CCL_NAMESPACE_BEGIN
/* On the CPU, we pass along the struct KernelGlobals to nearly everywhere in
@@ -109,11 +113,22 @@ typedef struct KernelGlobals {
#ifdef __KERNEL_OPENCL__
+# define KERNEL_TEX(type, ttype, name) \
+typedef type name##_t;
+# include "kernel/kernel_textures.h"
+
+typedef struct tex_info_t {
+ uint buffer, padding;
+ uint64_t offset;
+ uint width, height, depth, options;
+} tex_info_t;
+
typedef ccl_addr_space struct KernelGlobals {
ccl_constant KernelData *data;
+ ccl_global char *buffers[8];
# define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name;
+ tex_info_t name;
# include "kernel/kernel_textures.h"
# ifdef __SPLIT_KERNEL__
@@ -122,6 +137,57 @@ typedef ccl_addr_space struct KernelGlobals {
# endif
} KernelGlobals;
+#define KERNEL_BUFFER_PARAMS \
+ ccl_global char *buffer0, \
+ ccl_global char *buffer1, \
+ ccl_global char *buffer2, \
+ ccl_global char *buffer3, \
+ ccl_global char *buffer4, \
+ ccl_global char *buffer5, \
+ ccl_global char *buffer6, \
+ ccl_global char *buffer7
+
+#define KERNEL_BUFFER_ARGS buffer0, buffer1, buffer2, buffer3, buffer4, buffer5, buffer6, buffer7
+
+ccl_device_inline void kernel_set_buffer_pointers(KernelGlobals *kg, KERNEL_BUFFER_PARAMS)
+{
+#ifdef __SPLIT_KERNEL__
+ if(ccl_local_id(0) + ccl_local_id(1) == 0)
+#endif
+ {
+ kg->buffers[0] = buffer0;
+ kg->buffers[1] = buffer1;
+ kg->buffers[2] = buffer2;
+ kg->buffers[3] = buffer3;
+ kg->buffers[4] = buffer4;
+ kg->buffers[5] = buffer5;
+ kg->buffers[6] = buffer6;
+ kg->buffers[7] = buffer7;
+ }
+
+# ifdef __SPLIT_KERNEL__
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+# endif
+}
+
+ccl_device_inline void kernel_set_buffer_info(KernelGlobals *kg)
+{
+# ifdef __SPLIT_KERNEL__
+ if(ccl_local_id(0) + ccl_local_id(1) == 0)
+# endif
+ {
+ ccl_global tex_info_t *info = (ccl_global tex_info_t*)kg->buffers[0];
+
+# define KERNEL_TEX(type, ttype, name) \
+ kg->name = *(info++);
+# include "kernel/kernel_textures.h"
+ }
+
+# ifdef __SPLIT_KERNEL__
+ ccl_barrier(CCL_LOCAL_MEM_FENCE);
+# endif
+}
+
#endif /* __KERNEL_OPENCL__ */
/* Interpolated lookup table access */
diff --git a/intern/cycles/kernel/kernel_image_opencl.h b/intern/cycles/kernel/kernel_image_opencl.h
index 90747e09357..9e3373432ec 100644
--- a/intern/cycles/kernel/kernel_image_opencl.h
+++ b/intern/cycles/kernel/kernel_image_opencl.h
@@ -15,30 +15,42 @@
*/
-/* For OpenCL all images are packed in a single array, and we do manual lookup
- * and interpolation. */
+/* For OpenCL we do manual lookup and interpolation. */
+
+ccl_device_inline ccl_global tex_info_t* kernel_tex_info(KernelGlobals *kg, uint id) {
+ const uint tex_offset = id
+#define KERNEL_TEX(type, ttype, name) + 1
+#include "kernel/kernel_textures.h"
+ ;
+
+ return &((ccl_global tex_info_t*)kg->buffers[0])[tex_offset];
+}
+
+#define tex_fetch(type, info, index) ((ccl_global type*)(kg->buffers[info->buffer] + info->offset))[(index)]
ccl_device_inline float4 svm_image_texture_read(KernelGlobals *kg, int id, int offset)
{
+ const ccl_global tex_info_t *info = kernel_tex_info(kg, id);
const int texture_type = kernel_tex_type(id);
+
/* Float4 */
if(texture_type == IMAGE_DATA_TYPE_FLOAT4) {
- return kernel_tex_fetch(__tex_image_float4_packed, offset);
+ return tex_fetch(float4, info, offset);
}
/* Byte4 */
else if(texture_type == IMAGE_DATA_TYPE_BYTE4) {
- uchar4 r = kernel_tex_fetch(__tex_image_byte4_packed, offset);
+ uchar4 r = tex_fetch(uchar4, info, offset);
float f = 1.0f/255.0f;
return make_float4(r.x*f, r.y*f, r.z*f, r.w*f);
}
/* Float */
else if(texture_type == IMAGE_DATA_TYPE_FLOAT) {
- float f = kernel_tex_fetch(__tex_image_float_packed, offset);
+ float f = tex_fetch(float, info, offset);
return make_float4(f, f, f, 1.0f);
}
/* Byte */
else {
- uchar r = kernel_tex_fetch(__tex_image_byte_packed, offset);
+ uchar r = tex_fetch(uchar, info, offset);
float f = r * (1.0f/255.0f);
return make_float4(f, f, f, 1.0f);
}
@@ -64,17 +76,17 @@ ccl_device_inline float svm_image_texture_frac(float x, int *ix)
return x - (float)i;
}
-ccl_device_inline uint kernel_decode_image_interpolation(uint4 info)
+ccl_device_inline uint kernel_decode_image_interpolation(uint info)
{
- return (info.w & (1 << 0)) ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR;
+ return (info & (1 << 0)) ? INTERPOLATION_CLOSEST : INTERPOLATION_LINEAR;
}
-ccl_device_inline uint kernel_decode_image_extension(uint4 info)
+ccl_device_inline uint kernel_decode_image_extension(uint info)
{
- if(info.w & (1 << 1)) {
+ if(info & (1 << 1)) {
return EXTENSION_REPEAT;
}
- else if(info.w & (1 << 2)) {
+ else if(info & (1 << 2)) {
return EXTENSION_EXTEND;
}
else {
@@ -84,13 +96,16 @@ ccl_device_inline uint kernel_decode_image_extension(uint4 info)
ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, float y)
{
- uint4 info = kernel_tex_fetch(__tex_image_packed_info, id*2);
- uint width = info.x;
- uint height = info.y;
- uint offset = info.z;
+ const ccl_global tex_info_t *info = kernel_tex_info(kg, id);
+
+ uint width = info->width;
+ uint height = info->height;
+ uint offset = 0;
+
/* Decode image options. */
- uint interpolation = kernel_decode_image_interpolation(info);
- uint extension = kernel_decode_image_extension(info);
+ uint interpolation = kernel_decode_image_interpolation(info->options);
+ uint extension = kernel_decode_image_extension(info->options);
+
/* Actual sampling. */
float4 r;
int ix, iy, nix, niy;
@@ -150,14 +165,17 @@ ccl_device float4 kernel_tex_image_interp(KernelGlobals *kg, int id, float x, fl
ccl_device float4 kernel_tex_image_interp_3d(KernelGlobals *kg, int id, float x, float y, float z)
{
- uint4 info = kernel_tex_fetch(__tex_image_packed_info, id*2);
- uint width = info.x;
- uint height = info.y;
- uint offset = info.z;
- uint depth = kernel_tex_fetch(__tex_image_packed_info, id*2+1).x;
+ const ccl_global tex_info_t *info = kernel_tex_info(kg, id);
+
+ uint width = info->width;
+ uint height = info->height;
+ uint offset = 0;
+ uint depth = info->depth;
+
/* Decode image options. */
- uint interpolation = kernel_decode_image_interpolation(info);
- uint extension = kernel_decode_image_extension(info);
+ uint interpolation = kernel_decode_image_interpolation(info->options);
+ uint extension = kernel_decode_image_extension(info->options);
+
/* Actual sampling. */
float4 r;
int ix, iy, iz, nix, niy, niz;
diff --git a/intern/cycles/kernel/kernel_passes.h b/intern/cycles/kernel/kernel_passes.h
index 9cd7ffb181d..de65e8ef27b 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -194,6 +194,36 @@ ccl_device_inline void kernel_update_denoising_features(KernelGlobals *kg,
#endif /* __DENOISING_FEATURES__ */
}
+#ifdef __KERNEL_DEBUG__
+ccl_device_inline void kernel_write_debug_passes(KernelGlobals *kg,
+ ccl_global float *buffer,
+ PathRadiance *L,
+ int sample)
+{
+ int flag = kernel_data.film.pass_flag;
+ if(flag & PASS_BVH_TRAVERSED_NODES) {
+ kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_nodes,
+ sample,
+ L->debug_data.num_bvh_traversed_nodes);
+ }
+ if(flag & PASS_BVH_TRAVERSED_INSTANCES) {
+ kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_traversed_instances,
+ sample,
+ L->debug_data.num_bvh_traversed_instances);
+ }
+ if(flag & PASS_BVH_INTERSECTIONS) {
+ kernel_write_pass_float(buffer + kernel_data.film.pass_bvh_intersections,
+ sample,
+ L->debug_data.num_bvh_intersections);
+ }
+ if(flag & PASS_RAY_BOUNCES) {
+ kernel_write_pass_float(buffer + kernel_data.film.pass_ray_bounces,
+ sample,
+ L->debug_data.num_ray_bounces);
+ }
+}
+#endif /* __KERNEL_DEBUG__ */
+
ccl_device_inline void kernel_write_data_passes(KernelGlobals *kg, ccl_global float *buffer, PathRadiance *L,
ShaderData *sd, int sample, ccl_addr_space PathState *state, float3 throughput)
{
@@ -334,10 +364,12 @@ ccl_device_inline void kernel_write_light_passes(KernelGlobals *kg, ccl_global f
}
ccl_device_inline void kernel_write_result(KernelGlobals *kg, ccl_global float *buffer,
- int sample, PathRadiance *L, float alpha, bool is_shadow_catcher)
+ int sample, PathRadiance *L, bool is_shadow_catcher)
{
if(L) {
float3 L_sum;
+ float alpha = 1.0f - L->transparent;
+
#ifdef __SHADOW_TRICKS__
if(is_shadow_catcher) {
L_sum = path_radiance_sum_shadowcatcher(kg, L, &alpha);
@@ -389,6 +421,11 @@ ccl_device_inline void kernel_write_result(KernelGlobals *kg, ccl_global float *
sample, L->denoising_depth);
}
#endif /* __DENOISING_FEATURES__ */
+
+
+#ifdef __KERNEL_DEBUG__
+ kernel_write_debug_passes(kg, buffer, L, sample);
+#endif
}
else {
kernel_write_pass_float4(buffer, sample, make_float4(0.0f, 0.0f, 0.0f, 0.0f));
diff --git a/intern/cycles/kernel/kernel_path.h b/intern/cycles/kernel/kernel_path.h
index c340b3bc968..c454228eab5 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -48,10 +48,6 @@
#include "kernel/kernel_path_volume.h"
#include "kernel/kernel_path_subsurface.h"
-#ifdef __KERNEL_DEBUG__
-# include "kernel/kernel_debug.h"
-#endif
-
CCL_NAMESPACE_BEGIN
ccl_device_noinline void kernel_path_ao(KernelGlobals *kg,
@@ -100,6 +96,8 @@ ccl_device_noinline void kernel_path_ao(KernelGlobals *kg,
#ifndef __SPLIT_KERNEL__
+#if defined(__BRANCHED_PATH__) || defined(__BAKING__)
+
ccl_device void kernel_path_indirect(KernelGlobals *kg,
ShaderData *sd,
ShaderData *emission_sd,
@@ -318,8 +316,12 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
#endif /* __BRANCHED_PATH__ */
#ifdef __SHADOW_TRICKS__
- if(!(sd->object_flag & SD_OBJECT_SHADOW_CATCHER)) {
- state->flag &= ~PATH_RAY_SHADOW_CATCHER_ONLY;
+ if(!(sd->object_flag & SD_OBJECT_SHADOW_CATCHER) &&
+ (state->flag & PATH_RAY_SHADOW_CATCHER))
+ {
+ /* Only update transparency after shadow catcher bounce. */
+ L->shadow_transparency *=
+ average(shader_bsdf_transparency(kg, sd));
}
#endif /* __SHADOW_TRICKS__ */
@@ -350,7 +352,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
float probability =
- path_state_terminate_probability(kg,
+ path_state_continuation_probability(kg,
state,
throughput*num_samples);
@@ -428,18 +430,18 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
}
}
+#endif /* defined(__BRANCHED_PATH__) || defined(__BAKING__) */
-ccl_device_inline float kernel_path_integrate(KernelGlobals *kg,
- RNG *rng,
- int sample,
- Ray ray,
- ccl_global float *buffer,
- PathRadiance *L,
- bool *is_shadow_catcher)
+ccl_device_inline void kernel_path_integrate(KernelGlobals *kg,
+ RNG *rng,
+ int sample,
+ Ray ray,
+ ccl_global float *buffer,
+ PathRadiance *L,
+ bool *is_shadow_catcher)
{
/* initialize */
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- float L_transparent = 0.0f;
path_radiance_init(L, kernel_data.film.use_light_pass);
@@ -451,11 +453,6 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg,
PathState state;
path_state_init(kg, &emission_sd, &state, rng, sample, &ray);
-#ifdef __KERNEL_DEBUG__
- DebugData debug_data;
- debug_data_init(&debug_data);
-#endif /* __KERNEL_DEBUG__ */
-
#ifdef __SUBSURFACE__
SubsurfaceIndirectRays ss_indirect;
kernel_path_subsurface_init_indirect(&ss_indirect);
@@ -496,11 +493,11 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg,
#ifdef __KERNEL_DEBUG__
if(state.flag & PATH_RAY_CAMERA) {
- debug_data.num_bvh_traversed_nodes += isect.num_traversed_nodes;
- debug_data.num_bvh_traversed_instances += isect.num_traversed_instances;
- debug_data.num_bvh_intersections += isect.num_intersections;
+ L->debug_data.num_bvh_traversed_nodes += isect.num_traversed_nodes;
+ L->debug_data.num_bvh_traversed_instances += isect.num_traversed_instances;
+ L->debug_data.num_bvh_intersections += isect.num_intersections;
}
- debug_data.num_ray_bounces++;
+ L->debug_data.num_ray_bounces++;
#endif /* __KERNEL_DEBUG__ */
#ifdef __LAMP_MIS__
@@ -615,7 +612,7 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg,
if(!hit) {
/* eval background shader if nothing hit */
if(kernel_data.background.transparent && (state.flag & PATH_RAY_CAMERA)) {
- L_transparent += average(throughput);
+ L->transparent += average(throughput);
#ifdef __PASSES__
if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
@@ -644,9 +641,7 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg,
if((sd.object_flag & SD_OBJECT_SHADOW_CATCHER)) {
if(state.flag & PATH_RAY_CAMERA) {
state.flag |= (PATH_RAY_SHADOW_CATCHER |
- PATH_RAY_SHADOW_CATCHER_ONLY |
PATH_RAY_STORE_SHADOW_INFO);
- state.catcher_object = sd.object;
if(!kernel_data.background.transparent) {
L->shadow_background_color =
indirect_background(kg, &emission_sd, &state, &ray);
@@ -655,8 +650,10 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg,
L->shadow_throughput = average(throughput);
}
}
- else {
- state.flag &= ~PATH_RAY_SHADOW_CATCHER_ONLY;
+ else if(state.flag & PATH_RAY_SHADOW_CATCHER) {
+ /* Only update transparency after shadow catcher bounce. */
+ L->shadow_transparency *=
+ average(shader_bsdf_transparency(kg, &sd));
}
#endif /* __SHADOW_TRICKS__ */
@@ -675,7 +672,7 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg,
holdout_weight = shader_holdout_eval(kg, &sd);
}
/* any throughput is ok, should all be identical here */
- L_transparent += average(holdout_weight*throughput);
+ L->transparent += average(holdout_weight*throughput);
}
if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) {
@@ -710,7 +707,7 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg,
/* path termination. this is a strange place to put the termination, it's
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_terminate_probability(kg, &state, throughput);
+ float probability = path_state_continuation_probability(kg, &state, throughput);
if(probability == 0.0f) {
break;
@@ -780,14 +777,8 @@ ccl_device_inline float kernel_path_integrate(KernelGlobals *kg,
#endif /* __SUBSURFACE__ */
#ifdef __SHADOW_TRICKS__
- *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER);
+ *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER) != 0;
#endif /* __SHADOW_TRICKS__ */
-
-#ifdef __KERNEL_DEBUG__
- kernel_write_debug_passes(kg, buffer, &state, &debug_data, sample);
-#endif /* __KERNEL_DEBUG__ */
-
- return 1.0f - L_transparent;
}
ccl_device void kernel_path_trace(KernelGlobals *kg,
@@ -812,14 +803,12 @@ ccl_device void kernel_path_trace(KernelGlobals *kg,
bool is_shadow_catcher;
if(ray.t != 0.0f) {
- float alpha = kernel_path_integrate(kg, &rng, sample, ray, buffer, &L, &is_shadow_catcher);
- kernel_write_result(kg, buffer, sample, &L, alpha, is_shadow_catcher);
+ kernel_path_integrate(kg, &rng, sample, ray, buffer, &L, &is_shadow_catcher);
+ kernel_write_result(kg, buffer, sample, &L, is_shadow_catcher);
}
else {
- kernel_write_result(kg, buffer, sample, NULL, 0.0f, false);
+ kernel_write_result(kg, buffer, sample, NULL, false);
}
-
- path_rng_end(kg, rng_state, rng);
}
#endif /* __SPLIT_KERNEL__ */
diff --git a/intern/cycles/kernel/kernel_path_branched.h b/intern/cycles/kernel/kernel_path_branched.h
index 77d4f1df447..abc291bc7e3 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -119,6 +119,9 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
PathState ps = *state;
float3 tp = throughput;
Ray bsdf_ray;
+#ifdef __SHADOW_TRICKS__
+ float shadow_transparency = L->shadow_transparency;
+#endif
if(!kernel_branched_path_surface_bounce(kg,
&bsdf_rng,
@@ -149,6 +152,10 @@ ccl_device_noinline void kernel_branched_path_surface_indirect_light(KernelGloba
* for the next samples */
path_radiance_sum_indirect(L);
path_radiance_reset_indirect(L);
+
+#ifdef __SHADOW_TRICKS__
+ L->shadow_transparency = shadow_transparency;
+#endif
}
}
}
@@ -262,17 +269,16 @@ ccl_device void kernel_branched_path_subsurface_scatter(KernelGlobals *kg,
}
#endif /* __SUBSURFACE__ */
-ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
- RNG *rng,
- int sample,
- Ray ray,
- ccl_global float *buffer,
- PathRadiance *L,
- bool *is_shadow_catcher)
+ccl_device void kernel_branched_path_integrate(KernelGlobals *kg,
+ RNG *rng,
+ int sample,
+ Ray ray,
+ ccl_global float *buffer,
+ PathRadiance *L,
+ bool *is_shadow_catcher)
{
/* initialize */
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
- float L_transparent = 0.0f;
path_radiance_init(L, kernel_data.film.use_light_pass);
@@ -284,11 +290,6 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
PathState state;
path_state_init(kg, &emission_sd, &state, rng, sample, &ray);
-#ifdef __KERNEL_DEBUG__
- DebugData debug_data;
- debug_data_init(&debug_data);
-#endif /* __KERNEL_DEBUG__ */
-
/* Main Loop
* Here we only handle transparency intersections from the camera ray.
* Indirect bounces are handled in kernel_branched_path_surface_indirect_light().
@@ -319,10 +320,10 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
#endif /* __HAIR__ */
#ifdef __KERNEL_DEBUG__
- debug_data.num_bvh_traversed_nodes += isect.num_traversed_nodes;
- debug_data.num_bvh_traversed_instances += isect.num_traversed_instances;
- debug_data.num_bvh_intersections += isect.num_intersections;
- debug_data.num_ray_bounces++;
+ L->debug_data.num_bvh_traversed_nodes += isect.num_traversed_nodes;
+ L->debug_data.num_bvh_traversed_instances += isect.num_traversed_instances;
+ L->debug_data.num_bvh_intersections += isect.num_intersections;
+ L->debug_data.num_ray_bounces++;
#endif /* __KERNEL_DEBUG__ */
#ifdef __VOLUME__
@@ -475,7 +476,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
if(!hit) {
/* eval background shader if nothing hit */
if(kernel_data.background.transparent) {
- L_transparent += average(throughput);
+ L->transparent += average(throughput);
#ifdef __PASSES__
if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
@@ -500,9 +501,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
#ifdef __SHADOW_TRICKS__
if((sd.object_flag & SD_OBJECT_SHADOW_CATCHER)) {
state.flag |= (PATH_RAY_SHADOW_CATCHER |
- PATH_RAY_SHADOW_CATCHER_ONLY |
PATH_RAY_STORE_SHADOW_INFO);
- state.catcher_object = sd.object;
if(!kernel_data.background.transparent) {
L->shadow_background_color =
indirect_background(kg, &emission_sd, &state, &ray);
@@ -510,8 +509,10 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
L->shadow_radiance_sum = path_radiance_clamp_and_sum(kg, L);
L->shadow_throughput = average(throughput);
}
- else {
- state.flag &= ~PATH_RAY_SHADOW_CATCHER_ONLY;
+ else if(state.flag & PATH_RAY_SHADOW_CATCHER) {
+ /* Only update transparency after shadow catcher bounce. */
+ L->shadow_transparency *=
+ average(shader_bsdf_transparency(kg, &sd));
}
#endif /* __SHADOW_TRICKS__ */
@@ -527,7 +528,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
holdout_weight = shader_holdout_eval(kg, &sd);
}
/* any throughput is ok, should all be identical here */
- L_transparent += average(holdout_weight*throughput);
+ L->transparent += average(holdout_weight*throughput);
}
if(sd.object_flag & SD_OBJECT_HOLDOUT_MASK) {
break;
@@ -551,7 +552,7 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
/* path termination. this is a strange place to put the termination, it's
* mainly due to the mixed in MIS that we use. gives too many unneeded
* shader evaluations, only need emission if we are going to terminate */
- float probability = path_state_terminate_probability(kg, &state, throughput);
+ float probability = path_state_continuation_probability(kg, &state, throughput);
if(probability == 0.0f) {
break;
@@ -628,14 +629,8 @@ ccl_device float kernel_branched_path_integrate(KernelGlobals *kg,
}
#ifdef __SHADOW_TRICKS__
- *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER);
+ *is_shadow_catcher = (state.flag & PATH_RAY_SHADOW_CATCHER) != 0;
#endif /* __SHADOW_TRICKS__ */
-
-#ifdef __KERNEL_DEBUG__
- kernel_write_debug_passes(kg, buffer, &state, &debug_data, sample);
-#endif /* __KERNEL_DEBUG__ */
-
- return 1.0f - L_transparent;
}
ccl_device void kernel_branched_path_trace(KernelGlobals *kg,
@@ -660,14 +655,12 @@ ccl_device void kernel_branched_path_trace(KernelGlobals *kg,
bool is_shadow_catcher;
if(ray.t != 0.0f) {
- float alpha = kernel_branched_path_integrate(kg, &rng, sample, ray, buffer, &L, &is_shadow_catcher);
- kernel_write_result(kg, buffer, sample, &L, alpha, is_shadow_catcher);
+ kernel_branched_path_integrate(kg, &rng, sample, ray, buffer, &L, &is_shadow_catcher);
+ kernel_write_result(kg, buffer, sample, &L, is_shadow_catcher);
}
else {
- kernel_write_result(kg, buffer, sample, NULL, 0.0f, false);
+ kernel_write_result(kg, buffer, sample, NULL, false);
}
-
- path_rng_end(kg, rng_state, rng);
}
#endif /* __SPLIT_KERNEL__ */
diff --git a/intern/cycles/kernel/kernel_path_state.h b/intern/cycles/kernel/kernel_path_state.h
index a96ffe07718..28582de979d 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -64,10 +64,6 @@ ccl_device_inline void path_state_init(KernelGlobals *kg,
state->volume_stack[0].shader = SHADER_NONE;
}
#endif
-
-#ifdef __SHADOW_TRICKS__
- state->catcher_object = OBJECT_NONE;
-#endif
}
ccl_device_inline void path_state_next(KernelGlobals *kg, ccl_addr_space PathState *state, int label)
@@ -160,7 +156,7 @@ ccl_device_inline uint path_state_ray_visibility(KernelGlobals *kg, PathState *s
return flag;
}
-ccl_device_inline float path_state_terminate_probability(KernelGlobals *kg, ccl_addr_space PathState *state, const float3 throughput)
+ccl_device_inline float path_state_continuation_probability(KernelGlobals *kg, ccl_addr_space PathState *state, const float3 throughput)
{
if(state->flag & PATH_RAY_TRANSPARENT) {
/* Transparent rays are treated separately with own max bounces. */
@@ -173,7 +169,7 @@ ccl_device_inline float path_state_terminate_probability(KernelGlobals *kg, ccl_
}
#ifdef __SHADOW_TRICKS__
/* Exception for shadow catcher not working correctly with RR. */
- else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->transparent_bounce <= 8)) {
+ else if((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->transparent_bounce <= 8)) {
return 1.0f;
}
#endif
@@ -196,7 +192,7 @@ ccl_device_inline float path_state_terminate_probability(KernelGlobals *kg, ccl_
}
#ifdef __SHADOW_TRICKS__
/* Exception for shadow catcher not working correctly with RR. */
- else if ((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->bounce <= 3)) {
+ else if((state->flag & PATH_RAY_SHADOW_CATCHER) && (state->bounce <= 3)) {
return 1.0f;
}
#endif
diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h
index e8a912ccc0b..073011ace31 100644
--- a/intern/cycles/kernel/kernel_random.h
+++ b/intern/cycles/kernel/kernel_random.h
@@ -18,6 +18,16 @@
CCL_NAMESPACE_BEGIN
+/* Pseudo random numbers, uncomment this for debugging correlations. Only run
+ * this single threaded on a CPU for repeatable resutls. */
+//#define __DEBUG_CORRELATION__
+
+
+/* High Dimensional Sobol.
+ *
+ * Multidimensional sobol with generator matrices. Dimension 0 and 1 are equal
+ * to classic Van der Corput and Sobol sequences. */
+
#ifdef __SOBOL__
/* Skip initial numbers that are not as well distributed, especially the
@@ -26,47 +36,6 @@ CCL_NAMESPACE_BEGIN
*/
#define SOBOL_SKIP 64
-/* High Dimensional Sobol. */
-
-/* Van der Corput radical inverse. */
-ccl_device uint van_der_corput(uint bits)
-{
- bits = (bits << 16) | (bits >> 16);
- bits = ((bits & 0x00ff00ff) << 8) | ((bits & 0xff00ff00) >> 8);
- bits = ((bits & 0x0f0f0f0f) << 4) | ((bits & 0xf0f0f0f0) >> 4);
- bits = ((bits & 0x33333333) << 2) | ((bits & 0xcccccccc) >> 2);
- bits = ((bits & 0x55555555) << 1) | ((bits & 0xaaaaaaaa) >> 1);
- return bits;
-}
-
-/* Sobol radical inverse. */
-ccl_device uint sobol(uint i)
-{
- uint r = 0;
- for(uint v = 1U << 31; i; i >>= 1, v ^= v >> 1) {
- if(i & 1) {
- r ^= v;
- }
- }
- return r;
-}
-
-/* Inverse of sobol radical inverse. */
-ccl_device uint sobol_inverse(uint i)
-{
- const uint msb = 1U << 31;
- uint r = 0;
- for(uint v = 1; i; i <<= 1, v ^= v << 1) {
- if(i & msb) {
- r ^= v;
- }
- }
- return r;
-}
-
-/* Multidimensional sobol with generator matrices
- * dimension 0 and 1 are equal to van_der_corput() and sobol() respectively.
- */
ccl_device uint sobol_dimension(KernelGlobals *kg, int index, int dimension)
{
uint result = 0;
@@ -79,50 +48,31 @@ ccl_device uint sobol_dimension(KernelGlobals *kg, int index, int dimension)
return result;
}
-/* Lookup index and x/y coordinate, assumes m is a power of two. */
-ccl_device uint sobol_lookup(const uint m,
- const uint frame,
- const uint ex,
- const uint ey,
- uint *x, uint *y)
-{
- /* Shift is constant per frame. */
- const uint shift = frame << (m << 1);
- const uint sobol_shift = sobol(shift);
- /* Van der Corput is its own inverse. */
- const uint lower = van_der_corput(ex << (32 - m));
- /* Need to compensate for ey difference and shift. */
- const uint sobol_lower = sobol(lower);
- const uint mask = ~-(1 << m) << (32 - m); /* Only m upper bits. */
- const uint delta = ((ey << (32 - m)) ^ sobol_lower ^ sobol_shift) & mask;
- /* Only use m upper bits for the index (m is a power of two). */
- const uint sobol_result = delta | (delta >> m);
- const uint upper = sobol_inverse(sobol_result);
- const uint index = shift | upper | lower;
- *x = van_der_corput(index);
- *y = sobol_shift ^ sobol_result ^ sobol_lower;
- return index;
-}
+#endif /* __SOBOL__ */
+
ccl_device_forceinline float path_rng_1D(KernelGlobals *kg,
RNG *rng,
int sample, int num_samples,
int dimension)
{
+#ifdef __DEBUG_CORRELATION__
+ return (float)drand48();
+#endif
+
#ifdef __CMJ__
- if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) {
+# ifdef __SOBOL__
+ if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ)
+# endif
+ {
/* Correlated multi-jitter. */
int p = *rng + dimension;
return cmj_sample_1D(sample, num_samples, p);
}
#endif
-#ifdef __SOBOL_FULL_SCREEN__
- uint result = sobol_dimension(kg, *rng, dimension);
- float r = (float)result * (1.0f/(float)0xFFFFFFFF);
- return r;
-#else
- /* Compute sobol sequence value using direction vectors. */
+#ifdef __SOBOL__
+ /* Sobol sequence value using direction vectors. */
uint result = sobol_dimension(kg, sample + SOBOL_SKIP, dimension);
float r = (float)result * (1.0f/(float)0xFFFFFFFF);
@@ -145,19 +95,29 @@ ccl_device_forceinline void path_rng_2D(KernelGlobals *kg,
int dimension,
float *fx, float *fy)
{
+#ifdef __DEBUG_CORRELATION__
+ *fx = (float)drand48();
+ *fy = (float)drand48();
+ return;
+#endif
+
#ifdef __CMJ__
- if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ) {
+# ifdef __SOBOL__
+ if(kernel_data.integrator.sampling_pattern == SAMPLING_PATTERN_CMJ)
+# endif
+ {
/* Correlated multi-jitter. */
int p = *rng + dimension;
cmj_sample_2D(sample, num_samples, p, fx, fy);
+ return;
}
- else
#endif
- {
- /* Sobol. */
- *fx = path_rng_1D(kg, rng, sample, num_samples, dimension);
- *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1);
- }
+
+#ifdef __SOBOL__
+ /* Sobol. */
+ *fx = path_rng_1D(kg, rng, sample, num_samples, dimension);
+ *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1);
+#endif
}
ccl_device_inline void path_rng_init(KernelGlobals *kg,
@@ -167,81 +127,13 @@ ccl_device_inline void path_rng_init(KernelGlobals *kg,
int x, int y,
float *fx, float *fy)
{
-#ifdef __SOBOL_FULL_SCREEN__
- uint px, py;
- uint bits = 16; /* limits us to 65536x65536 and 65536 samples */
- uint size = 1 << bits;
- uint frame = sample;
-
- *rng = sobol_lookup(bits, frame, x, y, &px, &py);
-
- *rng ^= kernel_data.integrator.seed;
-
- if(sample == 0) {
- *fx = 0.5f;
- *fy = 0.5f;
- }
- else {
- *fx = size * (float)px * (1.0f/(float)0xFFFFFFFF) - x;
- *fy = size * (float)py * (1.0f/(float)0xFFFFFFFF) - y;
- }
-#else
+ /* load state */
*rng = *rng_state;
-
*rng ^= kernel_data.integrator.seed;
- if(sample == 0) {
- *fx = 0.5f;
- *fy = 0.5f;
- }
- else {
- path_rng_2D(kg, rng, sample, num_samples, PRNG_FILTER_U, fx, fy);
- }
+#ifdef __DEBUG_CORRELATION__
+ srand48(*rng + sample);
#endif
-}
-
-ccl_device void path_rng_end(KernelGlobals *kg,
- ccl_global uint *rng_state,
- RNG rng)
-{
- /* nothing to do */
-}
-
-#else /* __SOBOL__ */
-
-/* Linear Congruential Generator */
-
-ccl_device_forceinline float path_rng_1D(KernelGlobals *kg,
- RNG *rng,
- int sample, int num_samples,
- int dimension)
-{
- /* implicit mod 2^32 */
- *rng = (1103515245*(*rng) + 12345);
- return (float)*rng * (1.0f/(float)0xFFFFFFFF);
-}
-
-ccl_device_inline void path_rng_2D(KernelGlobals *kg,
- RNG *rng,
- int sample, int num_samples,
- int dimension,
- float *fx, float *fy)
-{
- *fx = path_rng_1D(kg, rng, sample, num_samples, dimension);
- *fy = path_rng_1D(kg, rng, sample, num_samples, dimension + 1);
-}
-
-ccl_device void path_rng_init(KernelGlobals *kg,
- ccl_global uint *rng_state,
- int sample, int num_samples,
- RNG *rng,
- int x, int y,
- float *fx, float *fy)
-{
- /* load state */
- *rng = *rng_state;
-
- *rng ^= kernel_data.integrator.seed;
if(sample == 0) {
*fx = 0.5f;
@@ -252,16 +144,6 @@ ccl_device void path_rng_init(KernelGlobals *kg,
}
}
-ccl_device void path_rng_end(KernelGlobals *kg,
- ccl_global uint *rng_state,
- RNG rng)
-{
- /* store state for next sample */
- *rng_state = rng;
-}
-
-#endif /* __SOBOL__ */
-
/* Linear Congruential Generator */
ccl_device uint lcg_step_uint(uint *rng)
diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h
index c66f52255f0..f553599a2e4 100644
--- a/intern/cycles/kernel/kernel_shader.h
+++ b/intern/cycles/kernel/kernel_shader.h
@@ -83,7 +83,7 @@ ccl_device_noinline void shader_setup_from_ray(KernelGlobals *kg,
float4 curvedata = kernel_tex_fetch(__curves, sd->prim);
sd->shader = __float_as_int(curvedata.z);
- sd->P = bvh_curve_refine(kg, sd, isect, ray);
+ sd->P = curve_refine(kg, sd, isect, ray);
}
else
#endif
@@ -669,7 +669,7 @@ ccl_device void shader_bsdf_blur(KernelGlobals *kg, ShaderData *sd, float roughn
}
}
-ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
+ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, const ShaderData *sd)
{
if(sd->flag & SD_HAS_ONLY_VOLUME)
return make_float3(1.0f, 1.0f, 1.0f);
@@ -677,7 +677,7 @@ ccl_device float3 shader_bsdf_transparency(KernelGlobals *kg, ShaderData *sd)
float3 eval = make_float3(0.0f, 0.0f, 0.0f);
for(int i = 0; i < sd->num_closure; i++) {
- ShaderClosure *sc = &sd->closure[i];
+ const ShaderClosure *sc = &sd->closure[i];
if(sc->type == CLOSURE_BSDF_TRANSPARENT_ID) // todo: make this work for osl
eval += sc->weight;
diff --git a/intern/cycles/kernel/kernel_shadow.h b/intern/cycles/kernel/kernel_shadow.h
index fab5946970d..10e9083551e 100644
--- a/intern/cycles/kernel/kernel_shadow.h
+++ b/intern/cycles/kernel/kernel_shadow.h
@@ -72,13 +72,14 @@ ccl_device_forceinline bool shadow_handle_transparent_isect(
ccl_device bool shadow_blocked_opaque(KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
+ const uint visibility,
Ray *ray,
Intersection *isect,
float3 *shadow)
{
const bool blocked = scene_intersect(kg,
*ray,
- PATH_RAY_SHADOW_OPAQUE,
+ visibility & PATH_RAY_SHADOW_OPAQUE,
isect,
NULL,
0.0f, 0.0f);
@@ -128,7 +129,7 @@ ccl_device bool shadow_blocked_opaque(KernelGlobals *kg,
ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
- const int skip_object,
+ const uint visibility,
Ray *ray,
Intersection *hits,
uint max_hits,
@@ -141,7 +142,7 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
const bool blocked = scene_intersect_shadow_all(kg,
ray,
hits,
- skip_object,
+ visibility,
max_hits,
&num_hits);
/* If no opaque surface found but we did find transparent hits,
@@ -218,7 +219,7 @@ ccl_device bool shadow_blocked_transparent_all_loop(KernelGlobals *kg,
ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
- const int skip_object,
+ const uint visibility,
Ray *ray,
uint max_hits,
float3 *shadow)
@@ -253,7 +254,7 @@ ccl_device bool shadow_blocked_transparent_all(KernelGlobals *kg,
return shadow_blocked_transparent_all_loop(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
hits,
max_hits,
@@ -278,14 +279,14 @@ ccl_device bool shadow_blocked_transparent_stepped_loop(
KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
- const int skip_object,
+ const uint visibility,
Ray *ray,
Intersection *isect,
const bool blocked,
const bool is_transparent_isect,
float3 *shadow)
{
- if((blocked && is_transparent_isect) || skip_object != OBJECT_NONE) {
+ if(blocked && is_transparent_isect) {
float3 throughput = make_float3(1.0f, 1.0f, 1.0f);
float3 Pend = ray->P + ray->D*ray->t;
int bounce = state->transparent_bounce;
@@ -304,30 +305,13 @@ ccl_device bool shadow_blocked_transparent_stepped_loop(
}
if(!scene_intersect(kg,
*ray,
- PATH_RAY_SHADOW_TRANSPARENT,
+ visibility & PATH_RAY_SHADOW_TRANSPARENT,
isect,
NULL,
0.0f, 0.0f))
{
break;
}
-#ifdef __SHADOW_TRICKS__
- if(skip_object != OBJECT_NONE) {
- const int isect_object = (isect->object == PRIM_NONE)
- ? kernel_tex_fetch(__prim_object, isect->prim)
- : isect->object;
- if(isect_object == skip_object) {
- shader_setup_from_ray(kg, shadow_sd, isect, ray);
- /* Move ray forward. */
- ray->P = ray_offset(shadow_sd->P, -shadow_sd->Ng);
- if(ray->t != FLT_MAX) {
- ray->D = normalize_len(Pend - ray->P, &ray->t);
- }
- bounce++;
- continue;
- }
- }
-#endif
if(!shader_transparent_shadow(kg, isect)) {
return true;
}
@@ -373,31 +357,24 @@ ccl_device bool shadow_blocked_transparent_stepped(
KernelGlobals *kg,
ShaderData *shadow_sd,
ccl_addr_space PathState *state,
- const int skip_object,
+ const uint visibility,
Ray *ray,
Intersection *isect,
float3 *shadow)
{
- bool blocked, is_transparent_isect;
- if(skip_object == OBJECT_NONE) {
- blocked = scene_intersect(kg,
- *ray,
- PATH_RAY_SHADOW_OPAQUE,
- isect,
- NULL,
- 0.0f, 0.0f);
- is_transparent_isect = blocked
- ? shader_transparent_shadow(kg, isect)
- : false;
- }
- else {
- blocked = false;
- is_transparent_isect = false;
- }
+ bool blocked = scene_intersect(kg,
+ *ray,
+ visibility & PATH_RAY_SHADOW_OPAQUE,
+ isect,
+ NULL,
+ 0.0f, 0.0f);
+ bool is_transparent_isect = blocked
+ ? shader_transparent_shadow(kg, isect)
+ : false;
return shadow_blocked_transparent_stepped_loop(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
isect,
blocked,
@@ -422,25 +399,24 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
return false;
}
#ifdef __SHADOW_TRICKS__
- const int skip_object = state->catcher_object;
+ const uint visibility = (state->flag & PATH_RAY_SHADOW_CATCHER)
+ ? PATH_RAY_SHADOW_NON_CATCHER
+ : PATH_RAY_SHADOW;
#else
- const int skip_object = OBJECT_NONE;
+ const uint visibility = PATH_RAY_SHADOW;
#endif
/* Do actual shadow shading. */
/* First of all, we check if integrator requires transparent shadows.
* if not, we use simplest and fastest ever way to calculate occlusion.
- *
- * NOTE: We can't do quick opaque test here if we are on shadow-catcher
- * path because we don't want catcher object to be casting shadow here.
*/
#ifdef __TRANSPARENT_SHADOWS__
- if(!kernel_data.integrator.transparent_shadows &&
- skip_object == OBJECT_NONE)
+ if(!kernel_data.integrator.transparent_shadows)
#endif
{
return shadow_blocked_opaque(kg,
shadow_sd,
state,
+ visibility,
ray,
&isect,
shadow);
@@ -467,7 +443,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
*/
const bool blocked = scene_intersect(kg,
*ray,
- PATH_RAY_SHADOW_OPAQUE,
+ visibility & PATH_RAY_SHADOW_OPAQUE,
&isect,
NULL,
0.0f, 0.0f);
@@ -480,7 +456,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
return shadow_blocked_transparent_stepped_loop(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
&isect,
blocked,
@@ -491,7 +467,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
return shadow_blocked_transparent_all(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
max_hits,
shadow);
@@ -500,7 +476,7 @@ ccl_device_inline bool shadow_blocked(KernelGlobals *kg,
return shadow_blocked_transparent_stepped(kg,
shadow_sd,
state,
- skip_object,
+ visibility,
ray,
&isect,
shadow);
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index aa5b32803a5..dc6bbbb9924 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -184,15 +184,8 @@ KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_665)
# else
/* bindless textures */
KERNEL_TEX(uint, texture_uint, __bindless_mapping)
-# endif
-#endif
-
-/* packed image (opencl) */
-KERNEL_TEX(uchar4, texture_uchar4, __tex_image_byte4_packed)
-KERNEL_TEX(float4, texture_float4, __tex_image_float4_packed)
-KERNEL_TEX(uchar, texture_uchar, __tex_image_byte_packed)
-KERNEL_TEX(float, texture_float, __tex_image_float_packed)
-KERNEL_TEX(uint4, texture_uint4, __tex_image_packed_info)
+# endif /* __CUDA_ARCH__ */
+#endif /* __KERNEL_CUDA__ */
#undef KERNEL_TEX
#undef KERNEL_IMAGE_TEX
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 557ce5804f8..f1b82eee352 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -330,24 +330,28 @@ enum PathRayFlag {
PATH_RAY_SINGULAR = (1 << 5),
PATH_RAY_TRANSPARENT = (1 << 6),
- PATH_RAY_SHADOW_OPAQUE = (1 << 7),
- PATH_RAY_SHADOW_TRANSPARENT = (1 << 8),
- PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE|PATH_RAY_SHADOW_TRANSPARENT),
-
- PATH_RAY_CURVE = (1 << 9), /* visibility flag to define curve segments */
- PATH_RAY_VOLUME_SCATTER = (1 << 10), /* volume scattering */
+ PATH_RAY_SHADOW_OPAQUE_NON_CATCHER = (1 << 7),
+ PATH_RAY_SHADOW_OPAQUE_CATCHER = (1 << 8),
+ PATH_RAY_SHADOW_OPAQUE = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER|PATH_RAY_SHADOW_OPAQUE_CATCHER),
+ PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER = (1 << 9),
+ PATH_RAY_SHADOW_TRANSPARENT_CATCHER = (1 << 10),
+ PATH_RAY_SHADOW_TRANSPARENT = (PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER|PATH_RAY_SHADOW_TRANSPARENT_CATCHER),
+ PATH_RAY_SHADOW_NON_CATCHER = (PATH_RAY_SHADOW_OPAQUE_NON_CATCHER|PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER),
+ PATH_RAY_SHADOW = (PATH_RAY_SHADOW_OPAQUE|PATH_RAY_SHADOW_TRANSPARENT),
+
+ PATH_RAY_CURVE = (1 << 11), /* visibility flag to define curve segments */
+ PATH_RAY_VOLUME_SCATTER = (1 << 12), /* volume scattering */
/* Special flag to tag unaligned BVH nodes. */
- PATH_RAY_NODE_UNALIGNED = (1 << 11),
+ PATH_RAY_NODE_UNALIGNED = (1 << 13),
- PATH_RAY_ALL_VISIBILITY = ((1 << 12)-1),
+ PATH_RAY_ALL_VISIBILITY = ((1 << 14)-1),
- PATH_RAY_MIS_SKIP = (1 << 12),
- PATH_RAY_DIFFUSE_ANCESTOR = (1 << 13),
- PATH_RAY_SINGLE_PASS_DONE = (1 << 14),
- PATH_RAY_SHADOW_CATCHER = (1 << 15),
- PATH_RAY_SHADOW_CATCHER_ONLY = (1 << 16),
- PATH_RAY_STORE_SHADOW_INFO = (1 << 17),
+ PATH_RAY_MIS_SKIP = (1 << 15),
+ PATH_RAY_DIFFUSE_ANCESTOR = (1 << 16),
+ PATH_RAY_SINGLE_PASS_DONE = (1 << 17),
+ PATH_RAY_SHADOW_CATCHER = (1 << 18),
+ PATH_RAY_STORE_SHADOW_INFO = (1 << 19),
};
/* Closure Label */
@@ -464,11 +468,24 @@ typedef enum DenoiseFlag {
DENOISING_CLEAN_ALL_PASSES = (1 << 8)-1,
} DenoiseFlag;
+#ifdef __KERNEL_DEBUG__
+/* NOTE: This is a runtime-only struct, alignment is not
+ * really important here.
+ */
+typedef struct DebugData {
+ int num_bvh_traversed_nodes;
+ int num_bvh_traversed_instances;
+ int num_bvh_intersections;
+ int num_ray_bounces;
+} DebugData;
+#endif
+
typedef ccl_addr_space struct PathRadiance {
#ifdef __PASSES__
int use_light_pass;
#endif
+ float transparent;
float3 emission;
#ifdef __PASSES__
float3 background;
@@ -524,6 +541,9 @@ typedef ccl_addr_space struct PathRadiance {
*/
float3 shadow_radiance_sum;
float shadow_throughput;
+
+ /* Accumulated transparency along the path after shadow catcher bounce. */
+ float shadow_transparency;
#endif
#ifdef __DENOISING_FEATURES__
@@ -531,6 +551,10 @@ typedef ccl_addr_space struct PathRadiance {
float3 denoising_albedo;
float denoising_depth;
#endif /* __DENOISING_FEATURES__ */
+
+#ifdef __KERNEL_DEBUG__
+ DebugData debug_data;
+#endif /* __KERNEL_DEBUG__ */
} PathRadiance;
typedef struct BsdfEval {
@@ -1027,10 +1051,6 @@ typedef struct PathState {
RNG rng_congruential;
VolumeStack volume_stack[VOLUME_STACK_SIZE];
#endif
-
-#ifdef __SHADOW_TRICKS__
- int catcher_object;
-#endif
} PathState;
/* Subsurface */
@@ -1342,18 +1362,6 @@ typedef struct KernelData {
} KernelData;
static_assert_align(KernelData, 16);
-#ifdef __KERNEL_DEBUG__
-/* NOTE: This is a runtime-only struct, alignment is not
- * really important here.
- */
-typedef ccl_addr_space struct DebugData {
- int num_bvh_traversed_nodes;
- int num_bvh_traversed_instances;
- int num_bvh_intersections;
- int num_ray_bounces;
-} DebugData;
-#endif
-
/* Declarations required for split kernel */
/* Macro for queues */
diff --git a/intern/cycles/kernel/kernels/cpu/filter_sse41.cpp b/intern/cycles/kernel/kernels/cpu/filter_sse41.cpp
index 1a7b2040da1..254025be4e2 100644
--- a/intern/cycles/kernel/kernels/cpu/filter_sse41.cpp
+++ b/intern/cycles/kernel/kernels/cpu/filter_sse41.cpp
@@ -25,6 +25,7 @@
#else
/* SSE optimization disabled for now on 32 bit, see bug #36316 */
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
+# define __KERNEL_SSE__
# define __KERNEL_SSE2__
# define __KERNEL_SSE3__
# define __KERNEL_SSSE3__
diff --git a/intern/cycles/kernel/kernels/cuda/kernel_config.h b/intern/cycles/kernel/kernels/cuda/kernel_config.h
index 9fa39dc9ebb..7ae205b7e14 100644
--- a/intern/cycles/kernel/kernels/cuda/kernel_config.h
+++ b/intern/cycles/kernel/kernels/cuda/kernel_config.h
@@ -81,8 +81,13 @@
# error "Unknown or unsupported CUDA architecture, can't determine launch bounds"
#endif
-/* compute number of threads per block and minimum blocks per multiprocessor
- * given the maximum number of registers per thread */
+/* For split kernel using all registers seems fastest for now, but this
+ * is unlikely to be optimal once we resolve other bottlenecks. */
+
+#define CUDA_KERNEL_SPLIT_MAX_REGISTERS CUDA_THREAD_MAX_REGISTERS
+
+/* Compute number of threads per block and minimum blocks per multiprocessor
+ * given the maximum number of registers per thread. */
#define CUDA_LAUNCH_BOUNDS(threads_block_width, thread_num_registers) \
__launch_bounds__( \
diff --git a/intern/cycles/kernel/kernels/cuda/kernel_split.cu b/intern/cycles/kernel/kernels/cuda/kernel_split.cu
index 628891b1458..e97e87285a5 100644
--- a/intern/cycles/kernel/kernels/cuda/kernel_split.cu
+++ b/intern/cycles/kernel/kernels/cuda/kernel_split.cu
@@ -90,7 +90,7 @@ kernel_cuda_path_trace_data_init(
#define DEFINE_SPLIT_KERNEL_FUNCTION(name) \
extern "C" __global__ void \
- CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS) \
+ CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_SPLIT_MAX_REGISTERS) \
kernel_cuda_##name() \
{ \
kernel_##name(NULL); \
@@ -98,7 +98,7 @@ kernel_cuda_path_trace_data_init(
#define DEFINE_SPLIT_KERNEL_FUNCTION_LOCALS(name, type) \
extern "C" __global__ void \
- CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_MAX_REGISTERS) \
+ CUDA_LAUNCH_BOUNDS(CUDA_THREADS_BLOCK_WIDTH, CUDA_KERNEL_SPLIT_MAX_REGISTERS) \
kernel_cuda_##name() \
{ \
ccl_local type locals; \
diff --git a/intern/cycles/kernel/kernels/opencl/kernel.cl b/intern/cycles/kernel/kernels/opencl/kernel.cl
index 078acc1631e..b7108f3d0f8 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel.cl
+++ b/intern/cycles/kernel/kernels/opencl/kernel.cl
@@ -52,9 +52,7 @@ __kernel void kernel_ocl_path_trace(
ccl_global float *buffer,
ccl_global uint *rng_state,
-#define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name,
-#include "kernel/kernel_textures.h"
+ KERNEL_BUFFER_PARAMS,
int sample,
int sx, int sy, int sw, int sh, int offset, int stride)
@@ -63,9 +61,8 @@ __kernel void kernel_ocl_path_trace(
kg->data = data;
-#define KERNEL_TEX(type, ttype, name) \
- kg->name = name;
-#include "kernel/kernel_textures.h"
+ kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
+ kernel_set_buffer_info(kg);
int x = sx + ccl_global_id(0);
int y = sy + ccl_global_id(1);
@@ -82,9 +79,7 @@ __kernel void kernel_ocl_shader(
ccl_global float4 *output,
ccl_global float *output_luma,
-#define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name,
-#include "kernel/kernel_textures.h"
+ KERNEL_BUFFER_PARAMS,
int type, int sx, int sw, int offset, int sample)
{
@@ -92,9 +87,8 @@ __kernel void kernel_ocl_shader(
kg->data = data;
-#define KERNEL_TEX(type, ttype, name) \
- kg->name = name;
-#include "kernel/kernel_textures.h"
+ kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
+ kernel_set_buffer_info(kg);
int x = sx + ccl_global_id(0);
@@ -114,9 +108,7 @@ __kernel void kernel_ocl_bake(
ccl_global uint4 *input,
ccl_global float4 *output,
-#define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name,
-#include "kernel/kernel_textures.h"
+ KERNEL_BUFFER_PARAMS,
int type, int filter, int sx, int sw, int offset, int sample)
{
@@ -124,9 +116,8 @@ __kernel void kernel_ocl_bake(
kg->data = data;
-#define KERNEL_TEX(type, ttype, name) \
- kg->name = name;
-#include "kernel/kernel_textures.h"
+ kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
+ kernel_set_buffer_info(kg);
int x = sx + ccl_global_id(0);
@@ -144,9 +135,7 @@ __kernel void kernel_ocl_convert_to_byte(
ccl_global uchar4 *rgba,
ccl_global float *buffer,
-#define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name,
-#include "kernel/kernel_textures.h"
+ KERNEL_BUFFER_PARAMS,
float sample_scale,
int sx, int sy, int sw, int sh, int offset, int stride)
@@ -155,9 +144,8 @@ __kernel void kernel_ocl_convert_to_byte(
kg->data = data;
-#define KERNEL_TEX(type, ttype, name) \
- kg->name = name;
-#include "kernel/kernel_textures.h"
+ kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
+ kernel_set_buffer_info(kg);
int x = sx + ccl_global_id(0);
int y = sy + ccl_global_id(1);
@@ -171,9 +159,7 @@ __kernel void kernel_ocl_convert_to_half_float(
ccl_global uchar4 *rgba,
ccl_global float *buffer,
-#define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name,
-#include "kernel/kernel_textures.h"
+ KERNEL_BUFFER_PARAMS,
float sample_scale,
int sx, int sy, int sw, int sh, int offset, int stride)
@@ -182,9 +168,8 @@ __kernel void kernel_ocl_convert_to_half_float(
kg->data = data;
-#define KERNEL_TEX(type, ttype, name) \
- kg->name = name;
-#include "kernel/kernel_textures.h"
+ kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
+ kernel_set_buffer_info(kg);
int x = sx + ccl_global_id(0);
int y = sy + ccl_global_id(1);
@@ -193,7 +178,7 @@ __kernel void kernel_ocl_convert_to_half_float(
kernel_film_convert_to_half_float(kg, rgba, buffer, sample_scale, x, y, offset, stride);
}
-__kernel void kernel_ocl_zero_buffer(ccl_global float4 *buffer, ulong size, ulong offset)
+__kernel void kernel_ocl_zero_buffer(ccl_global float4 *buffer, uint64_t size, uint64_t offset)
{
size_t i = ccl_global_id(0) + ccl_global_id(1) * ccl_global_size(0);
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_data_init.cl b/intern/cycles/kernel/kernels/opencl/kernel_data_init.cl
index 8b85d362f8a..95b35e40a45 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_data_init.cl
+++ b/intern/cycles/kernel/kernels/opencl/kernel_data_init.cl
@@ -25,11 +25,7 @@ __kernel void kernel_ocl_path_trace_data_init(
int num_elements,
ccl_global char *ray_state,
ccl_global uint *rng_state,
-
-#define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name,
-#include "kernel/kernel_textures.h"
-
+ KERNEL_BUFFER_PARAMS,
int start_sample,
int end_sample,
int sx, int sy, int sw, int sh, int offset, int stride,
@@ -46,10 +42,7 @@ __kernel void kernel_ocl_path_trace_data_init(
num_elements,
ray_state,
rng_state,
-
-#define KERNEL_TEX(type, ttype, name) name,
-#include "kernel/kernel_textures.h"
-
+ KERNEL_BUFFER_ARGS,
start_sample,
end_sample,
sx, sy, sw, sh, offset, stride,
diff --git a/intern/cycles/kernel/kernels/opencl/kernel_split_function.h b/intern/cycles/kernel/kernels/opencl/kernel_split_function.h
index f1e914a70d4..591c3846ef2 100644
--- a/intern/cycles/kernel/kernels/opencl/kernel_split_function.h
+++ b/intern/cycles/kernel/kernels/opencl/kernel_split_function.h
@@ -25,9 +25,7 @@ __kernel void KERNEL_NAME_EVAL(kernel_ocl_path_trace, KERNEL_NAME)(
ccl_global char *ray_state,
ccl_global uint *rng_state,
-#define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name,
-#include "kernel/kernel_textures.h"
+ KERNEL_BUFFER_PARAMS,
ccl_global int *queue_index,
ccl_global char *use_queues_flag,
@@ -52,12 +50,9 @@ __kernel void KERNEL_NAME_EVAL(kernel_ocl_path_trace, KERNEL_NAME)(
split_data_init(kg, &kernel_split_state, ccl_global_size(0)*ccl_global_size(1), split_data_buffer, ray_state);
-#define KERNEL_TEX(type, ttype, name) \
- kg->name = name;
-#include "kernel/kernel_textures.h"
}
- ccl_barrier(CCL_LOCAL_MEM_FENCE);
+ kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
KERNEL_NAME_EVAL(kernel, KERNEL_NAME)(
kg
diff --git a/intern/cycles/kernel/split/kernel_buffer_update.h b/intern/cycles/kernel/split/kernel_buffer_update.h
index 4c1fdd2d69c..6aa0d6948d0 100644
--- a/intern/cycles/kernel/split/kernel_buffer_update.h
+++ b/intern/cycles/kernel/split/kernel_buffer_update.h
@@ -79,14 +79,10 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
int stride = kernel_split_params.stride;
ccl_global char *ray_state = kernel_split_state.ray_state;
-#ifdef __KERNEL_DEBUG__
- DebugData *debug_data = &kernel_split_state.debug_data[ray_index];
-#endif
ccl_global PathState *state = &kernel_split_state.path_state[ray_index];
PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
- ccl_global float *L_transparent = &kernel_split_state.L_transparent[ray_index];
RNG rng = kernel_split_state.rng[ray_index];
ccl_global float *buffer = kernel_split_params.buffer;
@@ -111,15 +107,9 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
buffer += (kernel_split_params.offset + pixel_x + pixel_y*stride) * kernel_data.film.pass_stride;
if(IS_STATE(ray_state, ray_index, RAY_UPDATE_BUFFER)) {
-#ifdef __KERNEL_DEBUG__
- kernel_write_debug_passes(kg, buffer, state, debug_data, sample);
-#endif
-
/* accumulate result in output buffer */
bool is_shadow_catcher = (state->flag & PATH_RAY_SHADOW_CATCHER);
- kernel_write_result(kg, buffer, sample, L, 1.0f - (*L_transparent), is_shadow_catcher);
-
- path_rng_end(kg, rng_state, rng);
+ kernel_write_result(kg, buffer, sample, L, is_shadow_catcher);
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_TO_REGENERATE);
}
@@ -148,19 +138,15 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
kernel_path_trace_setup(kg, rng_state, sample, pixel_x, pixel_y, &rng, ray);
if(ray->t != 0.0f) {
- /* Initialize throughput, L_transparent, Ray, PathState;
+ /* Initialize throughput, path radiance, Ray, PathState;
* These rays proceed with path-iteration.
*/
*throughput = make_float3(1.0f, 1.0f, 1.0f);
- *L_transparent = 0.0f;
path_radiance_init(L, kernel_data.film.use_light_pass);
path_state_init(kg, &kernel_split_state.sd_DL_shadow[ray_index], state, &rng, sample, ray);
#ifdef __SUBSURFACE__
kernel_path_subsurface_init_indirect(&kernel_split_state.ss_rays[ray_index]);
#endif
-#ifdef __KERNEL_DEBUG__
- debug_data_init(debug_data);
-#endif
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_REGENERATED);
enqueue_flag = 1;
}
@@ -169,7 +155,6 @@ ccl_device void kernel_buffer_update(KernelGlobals *kg,
float4 L_rad = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
/* Accumulate result in output buffer. */
kernel_write_pass_float4(buffer, sample, L_rad);
- path_rng_end(kg, rng_state, rng);
ASSIGN_RAY_STATE(ray_state, ray_index, RAY_TO_REGENERATE);
}
diff --git a/intern/cycles/kernel/split/kernel_data_init.h b/intern/cycles/kernel/split/kernel_data_init.h
index e4545d66eff..2c042dfde6f 100644
--- a/intern/cycles/kernel/split/kernel_data_init.h
+++ b/intern/cycles/kernel/split/kernel_data_init.h
@@ -52,9 +52,7 @@ void KERNEL_FUNCTION_FULL_NAME(data_init)(
ccl_global uint *rng_state,
#ifdef __KERNEL_OPENCL__
-#define KERNEL_TEX(type, ttype, name) \
- ccl_global type *name,
-#include "kernel/kernel_textures.h"
+ KERNEL_BUFFER_PARAMS,
#endif
int start_sample,
@@ -100,9 +98,8 @@ void KERNEL_FUNCTION_FULL_NAME(data_init)(
split_data_init(kg, &kernel_split_state, num_elements, split_data_buffer, ray_state);
#ifdef __KERNEL_OPENCL__
-#define KERNEL_TEX(type, ttype, name) \
- kg->name = name;
-#include "kernel/kernel_textures.h"
+ kernel_set_buffer_pointers(kg, KERNEL_BUFFER_ARGS);
+ kernel_set_buffer_info(kg);
#endif
int thread_index = ccl_global_id(1) * ccl_global_size(0) + ccl_global_id(0);
@@ -127,14 +124,25 @@ void KERNEL_FUNCTION_FULL_NAME(data_init)(
/* zero the tiles pixels and initialize rng_state if this is the first sample */
if(start_sample == 0) {
- parallel_for(kg, i, sw * sh * kernel_data.film.pass_stride) {
- int pixel = i / kernel_data.film.pass_stride;
- int pass = i % kernel_data.film.pass_stride;
+ int pass_stride = kernel_data.film.pass_stride;
+
+#ifdef __KERNEL_CPU__
+ for(int y = sy; y < sy + sh; y++) {
+ int index = offset + y * stride;
+ memset(buffer + (sx + index) * pass_stride, 0, sizeof(float) * pass_stride * sw);
+ for(int x = sx; x < sx + sw; x++) {
+ rng_state[index + x] = hash_int_2d(x, y);
+ }
+ }
+#else
+ parallel_for(kg, i, sw * sh * pass_stride) {
+ int pixel = i / pass_stride;
+ int pass = i % pass_stride;
int x = sx + pixel % sw;
int y = sy + pixel / sw;
- int index = (offset + x + y*stride) * kernel_data.film.pass_stride + pass;
+ int index = (offset + x + y*stride) * pass_stride + pass;
*(buffer + index) = 0.0f;
}
@@ -146,6 +154,7 @@ void KERNEL_FUNCTION_FULL_NAME(data_init)(
int index = (offset + x + y*stride);
*(rng_state + index) = hash_int_2d(x, y);
}
+#endif
}
#endif /* KERENL_STUB */
diff --git a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
index fec671be016..95f57fbff57 100644
--- a/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
+++ b/intern/cycles/kernel/split/kernel_holdout_emission_blurring_pathtermination_ao.h
@@ -127,9 +127,7 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
if(state->flag & PATH_RAY_CAMERA) {
PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
state->flag |= (PATH_RAY_SHADOW_CATCHER |
- PATH_RAY_SHADOW_CATCHER_ONLY |
PATH_RAY_STORE_SHADOW_INFO);
- state->catcher_object = sd->object;
if(!kernel_data.background.transparent) {
ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
L->shadow_background_color = indirect_background(
@@ -142,8 +140,10 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
L->shadow_throughput = average(throughput);
}
}
- else {
- state->flag &= ~PATH_RAY_SHADOW_CATCHER_ONLY;
+ else if(state->flag & PATH_RAY_SHADOW_CATCHER) {
+ /* Only update transparency after shadow catcher bounce. */
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ L->shadow_transparency *= average(shader_bsdf_transparency(kg, sd));
}
#endif /* __SHADOW_TRICKS__ */
@@ -162,7 +162,8 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
holdout_weight = shader_holdout_eval(kg, sd);
}
/* any throughput is ok, should all be identical here */
- kernel_split_state.L_transparent[ray_index] += average(holdout_weight*throughput);
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+ L->transparent += average(holdout_weight*throughput);
}
if(sd->object_flag & SD_OBJECT_HOLDOUT_MASK) {
kernel_split_path_end(kg, ray_index);
@@ -224,19 +225,19 @@ ccl_device void kernel_holdout_emission_blurring_pathtermination_ao(
* shader evaluations, only need emission if we are going to terminate.
*/
#ifndef __BRANCHED_PATH__
- float probability = path_state_terminate_probability(kg, state, throughput);
+ float probability = path_state_continuation_probability(kg, state, throughput);
#else
float probability = 1.0f;
if(!kernel_data.integrator.branched) {
- probability = path_state_terminate_probability(kg, state, throughput);
+ probability = path_state_continuation_probability(kg, state, throughput);
}
else if(IS_FLAG(ray_state, ray_index, RAY_BRANCHED_INDIRECT)) {
int num_samples = kernel_split_state.branched_state[ray_index].num_samples;
- probability = path_state_terminate_probability(kg, state, throughput*num_samples);
+ probability = path_state_continuation_probability(kg, state, throughput*num_samples);
}
else if(state->flag & PATH_RAY_TRANSPARENT) {
- probability = path_state_terminate_probability(kg, state, throughput);
+ probability = path_state_continuation_probability(kg, state, throughput);
}
#endif
diff --git a/intern/cycles/kernel/split/kernel_indirect_background.h b/intern/cycles/kernel/split/kernel_indirect_background.h
index f0ebb90f60a..04d5769ef0d 100644
--- a/intern/cycles/kernel/split/kernel_indirect_background.h
+++ b/intern/cycles/kernel/split/kernel_indirect_background.h
@@ -54,12 +54,11 @@ ccl_device void kernel_indirect_background(KernelGlobals *kg)
PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
ccl_global Ray *ray = &kernel_split_state.ray[ray_index];
ccl_global float3 *throughput = &kernel_split_state.throughput[ray_index];
- ccl_global float *L_transparent = &kernel_split_state.L_transparent[ray_index];
if(IS_STATE(ray_state, ray_index, RAY_HIT_BACKGROUND)) {
/* eval background shader if nothing hit */
if(kernel_data.background.transparent && (state->flag & PATH_RAY_CAMERA)) {
- *L_transparent = (*L_transparent) + average((*throughput));
+ L->transparent += average((*throughput));
#ifdef __PASSES__
if(!(kernel_data.film.pass_flag & PASS_BACKGROUND))
#endif
diff --git a/intern/cycles/kernel/split/kernel_path_init.h b/intern/cycles/kernel/split/kernel_path_init.h
index a7ecde7c80d..8315b0b2bd3 100644
--- a/intern/cycles/kernel/split/kernel_path_init.h
+++ b/intern/cycles/kernel/split/kernel_path_init.h
@@ -71,11 +71,10 @@ ccl_device void kernel_path_init(KernelGlobals *kg) {
&kernel_split_state.ray[ray_index]);
if(kernel_split_state.ray[ray_index].t != 0.0f) {
- /* Initialize throughput, L_transparent, Ray, PathState;
+ /* Initialize throughput, path radiance, Ray, PathState;
* These rays proceed with path-iteration.
*/
kernel_split_state.throughput[ray_index] = make_float3(1.0f, 1.0f, 1.0f);
- kernel_split_state.L_transparent[ray_index] = 0.0f;
path_radiance_init(&kernel_split_state.path_radiance[ray_index], kernel_data.film.use_light_pass);
path_state_init(kg,
&kernel_split_state.sd_DL_shadow[ray_index],
@@ -86,17 +85,12 @@ ccl_device void kernel_path_init(KernelGlobals *kg) {
#ifdef __SUBSURFACE__
kernel_path_subsurface_init_indirect(&kernel_split_state.ss_rays[ray_index]);
#endif
-
-#ifdef __KERNEL_DEBUG__
- debug_data_init(&kernel_split_state.debug_data[ray_index]);
-#endif
}
else {
/* These rays do not participate in path-iteration. */
float4 L_rad = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
/* Accumulate result in output buffer. */
kernel_write_pass_float4(buffer, my_sample, L_rad);
- path_rng_end(kg, rng_state, kernel_split_state.rng[ray_index]);
ASSIGN_RAY_STATE(kernel_split_state.ray_state, ray_index, RAY_TO_REGENERATE);
}
kernel_split_state.rng[ray_index] = rng;
diff --git a/intern/cycles/kernel/split/kernel_scene_intersect.h b/intern/cycles/kernel/split/kernel_scene_intersect.h
index 45984ca509b..5c6d90eecc4 100644
--- a/intern/cycles/kernel/split/kernel_scene_intersect.h
+++ b/intern/cycles/kernel/split/kernel_scene_intersect.h
@@ -59,9 +59,6 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg)
return;
}
-#ifdef __KERNEL_DEBUG__
- DebugData *debug_data = &kernel_split_state.debug_data[ray_index];
-#endif
Intersection isect;
PathState state = kernel_split_state.path_state[ray_index];
Ray ray = kernel_split_state.ray[ray_index];
@@ -97,12 +94,14 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg)
kernel_split_state.isect[ray_index] = isect;
#ifdef __KERNEL_DEBUG__
+ PathRadiance *L = &kernel_split_state.path_radiance[ray_index];
+
if(state.flag & PATH_RAY_CAMERA) {
- debug_data->num_bvh_traversed_nodes += isect.num_traversed_nodes;
- debug_data->num_bvh_traversed_instances += isect.num_traversed_instances;
- debug_data->num_bvh_intersections += isect.num_intersections;
+ L->debug_data.num_bvh_traversed_nodes += isect.num_traversed_nodes;
+ L->debug_data.num_bvh_traversed_instances += isect.num_traversed_instances;
+ L->debug_data.num_bvh_intersections += isect.num_intersections;
}
- debug_data->num_ray_bounces++;
+ L->debug_data.num_ray_bounces++;
#endif
if(!hit) {
diff --git a/intern/cycles/kernel/split/kernel_shader_sort.h b/intern/cycles/kernel/split/kernel_shader_sort.h
index 297decb0bc2..5a55b680695 100644
--- a/intern/cycles/kernel/split/kernel_shader_sort.h
+++ b/intern/cycles/kernel/split/kernel_shader_sort.h
@@ -39,7 +39,7 @@ ccl_device void kernel_shader_sort(KernelGlobals *kg,
ccl_local ushort *local_index = &locals->local_index[0];
/* copy to local memory */
- for (uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
+ for(uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
uint idx = offset + i + lid;
uint add = input + idx;
uint value = (~0);
@@ -59,9 +59,9 @@ ccl_device void kernel_shader_sort(KernelGlobals *kg,
# ifdef __KERNEL_OPENCL__
/* bitonic sort */
- for (uint length = 1; length < SHADER_SORT_BLOCK_SIZE; length <<= 1) {
- for (uint inc = length; inc > 0; inc >>= 1) {
- for (uint ii = 0; ii < SHADER_SORT_BLOCK_SIZE; ii += SHADER_SORT_LOCAL_SIZE) {
+ for(uint length = 1; length < SHADER_SORT_BLOCK_SIZE; length <<= 1) {
+ for(uint inc = length; inc > 0; inc >>= 1) {
+ for(uint ii = 0; ii < SHADER_SORT_BLOCK_SIZE; ii += SHADER_SORT_LOCAL_SIZE) {
uint i = lid + ii;
bool direction = ((i & (length << 1)) != 0);
uint j = i ^ inc;
@@ -81,7 +81,7 @@ ccl_device void kernel_shader_sort(KernelGlobals *kg,
# endif /* __KERNEL_OPENCL__ */
/* copy to destination */
- for (uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
+ for(uint i = 0; i < SHADER_SORT_BLOCK_SIZE; i += SHADER_SORT_LOCAL_SIZE) {
uint idx = offset + i + lid;
uint lidx = local_index[i + lid];
uint outi = output + idx;
diff --git a/intern/cycles/kernel/split/kernel_split_data_types.h b/intern/cycles/kernel/split/kernel_split_data_types.h
index 4bb2f0d3d80..4f32c68d630 100644
--- a/intern/cycles/kernel/split/kernel_split_data_types.h
+++ b/intern/cycles/kernel/split/kernel_split_data_types.h
@@ -56,14 +56,6 @@ typedef struct SplitParams {
/* SPLIT_DATA_ENTRY(type, name, num) */
-#if defined(WITH_CYCLES_DEBUG) || defined(__KERNEL_DEBUG__)
-/* DebugData memory */
-# define SPLIT_DATA_DEBUG_ENTRIES \
- SPLIT_DATA_ENTRY(DebugData, debug_data, 1)
-#else
-# define SPLIT_DATA_DEBUG_ENTRIES
-#endif /* DEBUG */
-
#ifdef __BRANCHED_PATH__
typedef ccl_global struct SplitBranchedState {
@@ -124,7 +116,6 @@ typedef ccl_global struct SplitBranchedState {
#define SPLIT_DATA_ENTRIES \
SPLIT_DATA_ENTRY(ccl_global RNG, rng, 1) \
SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \
- SPLIT_DATA_ENTRY(ccl_global float, L_transparent, 1) \
SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \
SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \
SPLIT_DATA_ENTRY(ccl_global PathState, path_state, 1) \
@@ -139,13 +130,11 @@ typedef ccl_global struct SplitBranchedState {
SPLIT_DATA_SUBSURFACE_ENTRIES \
SPLIT_DATA_VOLUME_ENTRIES \
SPLIT_DATA_BRANCHED_ENTRIES \
- SPLIT_DATA_DEBUG_ENTRIES \
/* entries to be copied to inactive rays when sharing branched samples (TODO: which are actually needed?) */
#define SPLIT_DATA_ENTRIES_BRANCHED_SHARED \
SPLIT_DATA_ENTRY(ccl_global RNG, rng, 1) \
SPLIT_DATA_ENTRY(ccl_global float3, throughput, 1) \
- SPLIT_DATA_ENTRY(ccl_global float, L_transparent, 1) \
SPLIT_DATA_ENTRY(PathRadiance, path_radiance, 1) \
SPLIT_DATA_ENTRY(ccl_global Ray, ray, 1) \
SPLIT_DATA_ENTRY(ccl_global PathState, path_state, 1) \
@@ -158,7 +147,6 @@ typedef ccl_global struct SplitBranchedState {
SPLIT_DATA_SUBSURFACE_ENTRIES \
SPLIT_DATA_VOLUME_ENTRIES \
SPLIT_DATA_BRANCHED_ENTRIES \
- SPLIT_DATA_DEBUG_ENTRIES \
/* struct that holds pointers to data in the shared state buffer */
typedef struct SplitData {
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 02b65440154..80ec77f8b4a 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -43,7 +43,6 @@ static bool isfinite(half /*value*/)
ImageManager::ImageManager(const DeviceInfo& info)
{
need_update = true;
- pack_images = false;
osl_texture_system = NULL;
animation_frame = 0;
@@ -87,11 +86,6 @@ ImageManager::~ImageManager()
}
}
-void ImageManager::set_pack_images(bool pack_images_)
-{
- pack_images = pack_images_;
-}
-
void ImageManager::set_osl_texture_system(void *texture_system)
{
osl_texture_system = texture_system;
@@ -344,7 +338,7 @@ int ImageManager::add_image(const string& filename,
else {
/* Very unlikely, since max_num_images is insanely big. But better safe than sorry. */
int tex_count = 0;
- for (int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
+ for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
tex_count += tex_num_images[type];
}
if(tex_count > max_num_images) {
@@ -742,7 +736,7 @@ void ImageManager::device_load_image(Device *device,
pixels[3] = TEX_IMAGE_MISSING_A;
}
- if(!pack_images) {
+ {
thread_scoped_lock device_lock(device_mutex);
device->tex_alloc(name.c_str(),
tex_img,
@@ -771,7 +765,7 @@ void ImageManager::device_load_image(Device *device,
pixels[0] = TEX_IMAGE_MISSING_R;
}
- if(!pack_images) {
+ {
thread_scoped_lock device_lock(device_mutex);
device->tex_alloc(name.c_str(),
tex_img,
@@ -803,7 +797,7 @@ void ImageManager::device_load_image(Device *device,
pixels[3] = (TEX_IMAGE_MISSING_A * 255);
}
- if(!pack_images) {
+ {
thread_scoped_lock device_lock(device_mutex);
device->tex_alloc(name.c_str(),
tex_img,
@@ -831,7 +825,7 @@ void ImageManager::device_load_image(Device *device,
pixels[0] = (TEX_IMAGE_MISSING_R * 255);
}
- if(!pack_images) {
+ {
thread_scoped_lock device_lock(device_mutex);
device->tex_alloc(name.c_str(),
tex_img,
@@ -862,7 +856,7 @@ void ImageManager::device_load_image(Device *device,
pixels[3] = TEX_IMAGE_MISSING_A;
}
- if(!pack_images) {
+ {
thread_scoped_lock device_lock(device_mutex);
device->tex_alloc(name.c_str(),
tex_img,
@@ -890,7 +884,7 @@ void ImageManager::device_load_image(Device *device,
pixels[0] = TEX_IMAGE_MISSING_R;
}
- if(!pack_images) {
+ {
thread_scoped_lock device_lock(device_mutex);
device->tex_alloc(name.c_str(),
tex_img,
@@ -1047,9 +1041,6 @@ void ImageManager::device_update(Device *device,
pool.wait_work();
- if(pack_images)
- device_pack_images(device, dscene, progress);
-
need_update = false;
}
@@ -1079,141 +1070,6 @@ void ImageManager::device_update_slot(Device *device,
}
}
-uint8_t ImageManager::pack_image_options(ImageDataType type, size_t slot)
-{
- uint8_t options = 0;
- /* Image Options are packed into one uint:
- * bit 0 -> Interpolation
- * bit 1 + 2 + 3 -> Extension
- */
- if(images[type][slot]->interpolation == INTERPOLATION_CLOSEST) {
- options |= (1 << 0);
- }
- if(images[type][slot]->extension == EXTENSION_REPEAT) {
- options |= (1 << 1);
- }
- else if(images[type][slot]->extension == EXTENSION_EXTEND) {
- options |= (1 << 2);
- }
- else /* EXTENSION_CLIP */ {
- options |= (1 << 3);
- }
- return options;
-}
-
-template<typename T>
-void ImageManager::device_pack_images_type(
- ImageDataType type,
- const vector<device_vector<T>*>& cpu_textures,
- device_vector<T> *device_image,
- uint4 *info)
-{
- size_t size = 0, offset = 0;
- /* First step is to calculate size of the texture we need. */
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] == NULL) {
- continue;
- }
- device_vector<T>& tex_img = *cpu_textures[slot];
- size += tex_img.size();
- }
- /* Now we know how much memory we need, so we can allocate and fill. */
- T *pixels = device_image->resize(size);
- for(size_t slot = 0; slot < images[type].size(); slot++) {
- if(images[type][slot] == NULL) {
- continue;
- }
- device_vector<T>& tex_img = *cpu_textures[slot];
- uint8_t options = pack_image_options(type, slot);
- const int index = type_index_to_flattened_slot(slot, type) * 2;
- info[index] = make_uint4(tex_img.data_width,
- tex_img.data_height,
- offset,
- options);
- info[index+1] = make_uint4(tex_img.data_depth, 0, 0, 0);
- memcpy(pixels + offset,
- (void*)tex_img.data_pointer,
- tex_img.memory_size());
- offset += tex_img.size();
- }
-}
-
-void ImageManager::device_pack_images(Device *device,
- DeviceScene *dscene,
- Progress& /*progess*/)
-{
- /* For OpenCL, we pack all image textures into a single large texture, and
- * do our own interpolation in the kernel.
- */
-
- /* TODO(sergey): This will over-allocate a bit, but this is constant memory
- * so should be fine for a short term.
- */
- const size_t info_size = max4(max_flattened_slot(IMAGE_DATA_TYPE_FLOAT4),
- max_flattened_slot(IMAGE_DATA_TYPE_BYTE4),
- max_flattened_slot(IMAGE_DATA_TYPE_FLOAT),
- max_flattened_slot(IMAGE_DATA_TYPE_BYTE));
- uint4 *info = dscene->tex_image_packed_info.resize(info_size*2);
-
- /* Pack byte4 textures. */
- device_pack_images_type(IMAGE_DATA_TYPE_BYTE4,
- dscene->tex_byte4_image,
- &dscene->tex_image_byte4_packed,
- info);
- /* Pack float4 textures. */
- device_pack_images_type(IMAGE_DATA_TYPE_FLOAT4,
- dscene->tex_float4_image,
- &dscene->tex_image_float4_packed,
- info);
- /* Pack byte textures. */
- device_pack_images_type(IMAGE_DATA_TYPE_BYTE,
- dscene->tex_byte_image,
- &dscene->tex_image_byte_packed,
- info);
- /* Pack float textures. */
- device_pack_images_type(IMAGE_DATA_TYPE_FLOAT,
- dscene->tex_float_image,
- &dscene->tex_image_float_packed,
- info);
-
- /* Push textures to the device. */
- if(dscene->tex_image_byte4_packed.size()) {
- if(dscene->tex_image_byte4_packed.device_pointer) {
- thread_scoped_lock device_lock(device_mutex);
- device->tex_free(dscene->tex_image_byte4_packed);
- }
- device->tex_alloc("__tex_image_byte4_packed", dscene->tex_image_byte4_packed);
- }
- if(dscene->tex_image_float4_packed.size()) {
- if(dscene->tex_image_float4_packed.device_pointer) {
- thread_scoped_lock device_lock(device_mutex);
- device->tex_free(dscene->tex_image_float4_packed);
- }
- device->tex_alloc("__tex_image_float4_packed", dscene->tex_image_float4_packed);
- }
- if(dscene->tex_image_byte_packed.size()) {
- if(dscene->tex_image_byte_packed.device_pointer) {
- thread_scoped_lock device_lock(device_mutex);
- device->tex_free(dscene->tex_image_byte_packed);
- }
- device->tex_alloc("__tex_image_byte_packed", dscene->tex_image_byte_packed);
- }
- if(dscene->tex_image_float_packed.size()) {
- if(dscene->tex_image_float_packed.device_pointer) {
- thread_scoped_lock device_lock(device_mutex);
- device->tex_free(dscene->tex_image_float_packed);
- }
- device->tex_alloc("__tex_image_float_packed", dscene->tex_image_float_packed);
- }
- if(dscene->tex_image_packed_info.size()) {
- if(dscene->tex_image_packed_info.device_pointer) {
- thread_scoped_lock device_lock(device_mutex);
- device->tex_free(dscene->tex_image_packed_info);
- }
- device->tex_alloc("__tex_image_packed_info", dscene->tex_image_packed_info);
- }
-}
-
void ImageManager::device_free_builtin(Device *device, DeviceScene *dscene)
{
for(int type = 0; type < IMAGE_DATA_NUM_TYPES; type++) {
@@ -1239,18 +1095,6 @@ void ImageManager::device_free(Device *device, DeviceScene *dscene)
dscene->tex_float_image.clear();
dscene->tex_byte_image.clear();
dscene->tex_half_image.clear();
-
- device->tex_free(dscene->tex_image_float4_packed);
- device->tex_free(dscene->tex_image_byte4_packed);
- device->tex_free(dscene->tex_image_float_packed);
- device->tex_free(dscene->tex_image_byte_packed);
- device->tex_free(dscene->tex_image_packed_info);
-
- dscene->tex_image_float4_packed.clear();
- dscene->tex_image_byte4_packed.clear();
- dscene->tex_image_float_packed.clear();
- dscene->tex_image_byte_packed.clear();
- dscene->tex_image_packed_info.clear();
}
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index db7e28a5e44..c86d1cbedbf 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -76,7 +76,6 @@ public:
void device_free_builtin(Device *device, DeviceScene *dscene);
void set_osl_texture_system(void *texture_system);
- void set_pack_images(bool pack_images_);
bool set_animation_frame_update(int frame);
bool need_update;
@@ -130,7 +129,6 @@ private:
vector<Image*> images[IMAGE_DATA_NUM_TYPES];
void *osl_texture_system;
- bool pack_images;
bool file_load_image_generic(Image *img,
ImageInput **in,
@@ -152,8 +150,6 @@ private:
int flattened_slot_to_type_index(int flat_slot, ImageDataType *type);
string name_from_type(int type);
- uint8_t pack_image_options(ImageDataType type, size_t slot);
-
void device_load_image(Device *device,
DeviceScene *dscene,
Scene *scene,
@@ -164,17 +160,6 @@ private:
DeviceScene *dscene,
ImageDataType type,
int slot);
-
- template<typename T>
- void device_pack_images_type(
- ImageDataType type,
- const vector<device_vector<T>*>& cpu_textures,
- device_vector<T> *device_image,
- uint4 *info);
-
- void device_pack_images(Device *device,
- DeviceScene *dscene,
- Progress& progess);
};
CCL_NAMESPACE_END
diff --git a/intern/cycles/render/integrator.cpp b/intern/cycles/render/integrator.cpp
index b9b8c681a26..15b728d6e02 100644
--- a/intern/cycles/render/integrator.cpp
+++ b/intern/cycles/render/integrator.cpp
@@ -39,7 +39,6 @@ NODE_DEFINE(Integrator)
SOCKET_INT(max_volume_bounce, "Max Volume Bounce", 7);
SOCKET_INT(transparent_max_bounce, "Transparent Max Bounce", 7);
- SOCKET_BOOLEAN(transparent_shadows, "Transparent Shadows", false);
SOCKET_INT(ao_bounces, "AO Bounces", 0);
@@ -121,19 +120,14 @@ void Integrator::device_update(Device *device, DeviceScene *dscene, Scene *scene
* We only need to enable transparent shadows, if we actually have
* transparent shaders in the scene. Otherwise we can disable it
* to improve performance a bit. */
- if(transparent_shadows) {
- kintegrator->transparent_shadows = false;
- foreach(Shader *shader, scene->shaders) {
- /* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */
- if((shader->has_surface_transparent && shader->use_transparent_shadow) || shader->has_volume) {
- kintegrator->transparent_shadows = true;
- break;
- }
+ kintegrator->transparent_shadows = false;
+ foreach(Shader *shader, scene->shaders) {
+ /* keep this in sync with SD_HAS_TRANSPARENT_SHADOW in shader.cpp */
+ if((shader->has_surface_transparent && shader->use_transparent_shadow) || shader->has_volume) {
+ kintegrator->transparent_shadows = true;
+ break;
}
}
- else {
- kintegrator->transparent_shadows = false;
- }
kintegrator->volume_max_steps = volume_max_steps;
kintegrator->volume_step_size = volume_step_size;
diff --git a/intern/cycles/render/integrator.h b/intern/cycles/render/integrator.h
index ce5651ec823..3cb430d72b4 100644
--- a/intern/cycles/render/integrator.h
+++ b/intern/cycles/render/integrator.h
@@ -39,7 +39,6 @@ public:
int max_volume_bounce;
int transparent_max_bounce;
- bool transparent_shadows;
int ao_bounces;
diff --git a/intern/cycles/render/light.cpp b/intern/cycles/render/light.cpp
index 93d88c5642c..371ea54ef11 100644
--- a/intern/cycles/render/light.cpp
+++ b/intern/cycles/render/light.cpp
@@ -225,7 +225,7 @@ void LightManager::disable_ineffective_light(Device *device, Scene *scene)
bool LightManager::object_usable_as_light(Object *object) {
Mesh *mesh = object->mesh;
/* Skip objects with NaNs */
- if (!object->bounds.valid()) {
+ if(!object->bounds.valid()) {
return false;
}
/* Skip if we are not visible for BSDFs. */
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index 03825f780e0..84537bf5993 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1925,16 +1925,7 @@ void MeshManager::device_update_displacement_images(Device *device,
if(node->special_type != SHADER_SPECIAL_TYPE_IMAGE_SLOT) {
continue;
}
- if(device->info.pack_images) {
- /* If device requires packed images we need to update all
- * images now, even if they're not used for displacement.
- */
- image_manager->device_update(device,
- dscene,
- scene,
- progress);
- return;
- }
+
ImageSlotTextureNode *image_node = static_cast<ImageSlotTextureNode*>(node);
int slot = image_node->slot;
if(slot != -1) {
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 375abfeb27a..b00e5624266 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -262,6 +262,17 @@ bool Object::is_traceable()
return true;
}
+uint Object::visibility_for_tracing() const {
+ uint trace_visibility = visibility;
+ if (is_shadow_catcher) {
+ trace_visibility &= ~PATH_RAY_SHADOW_NON_CATCHER;
+ }
+ else {
+ trace_visibility &= ~PATH_RAY_SHADOW_CATCHER;
+ }
+ return trace_visibility;
+}
+
/* Object Manager */
ObjectManager::ObjectManager()
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 12d7b2c81cf..6927bbfe4c7 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -60,7 +60,7 @@ public:
ParticleSystem *particle_system;
int particle_index;
-
+
Object();
~Object();
@@ -75,6 +75,11 @@ public:
* kernel scene.
*/
bool is_traceable();
+
+ /* Combine object's visibility with all possible internal run-time
+ * determined flags which denotes trace-time visibility.
+ */
+ uint visibility_for_tracing() const;
};
/* Object Manager */
diff --git a/intern/cycles/render/osl.cpp b/intern/cycles/render/osl.cpp
index a794f233718..c337079b09f 100644
--- a/intern/cycles/render/osl.cpp
+++ b/intern/cycles/render/osl.cpp
@@ -233,8 +233,10 @@ void OSLShaderManager::shading_system_init()
"glossy", /* PATH_RAY_GLOSSY */
"singular", /* PATH_RAY_SINGULAR */
"transparent", /* PATH_RAY_TRANSPARENT */
- "shadow", /* PATH_RAY_SHADOW_OPAQUE */
- "shadow", /* PATH_RAY_SHADOW_TRANSPARENT */
+ "shadow", /* PATH_RAY_SHADOW_OPAQUE_NON_CATCHER */
+ "shadow", /* PATH_RAY_SHADOW_OPAQUE_CATCHER */
+ "shadow", /* PATH_RAY_SHADOW_TRANSPARENT_NON_CATCHER */
+ "shadow", /* PATH_RAY_SHADOW_TRANSPARENT_CATCHER */
"__unused__",
"__unused__",
diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp
index 4db20338744..c59a5d97df5 100644
--- a/intern/cycles/render/scene.cpp
+++ b/intern/cycles/render/scene.cpp
@@ -148,8 +148,6 @@ void Scene::device_update(Device *device_, Progress& progress)
* - Film needs light manager to run for use_light_visibility
* - Lookup tables are done a second time to handle film tables
*/
-
- image_manager->set_pack_images(device->info.pack_images);
progress.set_status("Updating Shaders");
shader_manager->device_update(device, &dscene, this, progress);
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 4c2c4f5fcc3..0194327f567 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -121,13 +121,6 @@ public:
vector<device_vector<uchar>* > tex_byte_image;
vector<device_vector<half>* > tex_half_image;
- /* opencl images */
- device_vector<float4> tex_image_float4_packed;
- device_vector<uchar4> tex_image_byte4_packed;
- device_vector<float> tex_image_float_packed;
- device_vector<uchar> tex_image_byte_packed;
- device_vector<uint4> tex_image_packed_info;
-
KernelData data;
};
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 8622318858e..3798483aa9c 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -46,7 +46,7 @@ Session::Session(const SessionParams& params_)
: params(params_),
tile_manager(params.progressive, params.samples, params.tile_size, params.start_resolution,
params.background == false || params.progressive_refine, params.background, params.tile_order,
- max(params.device.multi_devices.size(), 1)),
+ max(params.device.multi_devices.size(), 1), params.pixel_size),
stats()
{
device_use_gl = ((params.device.type != DEVICE_CPU) && !params.background);
@@ -721,7 +721,6 @@ DeviceRequestedFeatures Session::get_requested_device_features()
BakeManager *bake_manager = scene->bake_manager;
requested_features.use_baking = bake_manager->get_baking();
requested_features.use_integrator_branched = (scene->integrator->method == Integrator::BRANCHED_PATH);
- requested_features.use_transparent &= scene->integrator->transparent_shadows;
requested_features.use_denoising = params.use_denoising;
return requested_features;
diff --git a/intern/cycles/render/session.h b/intern/cycles/render/session.h
index 9f8bb8c42fa..980eda0876d 100644
--- a/intern/cycles/render/session.h
+++ b/intern/cycles/render/session.h
@@ -53,6 +53,7 @@ public:
int2 tile_size;
TileOrder tile_order;
int start_resolution;
+ int pixel_size;
int threads;
bool display_buffer_linear;
@@ -81,6 +82,7 @@ public:
samples = INT_MAX;
tile_size = make_int2(64, 64);
start_resolution = INT_MAX;
+ pixel_size = 1;
threads = 0;
use_denoising = false;
@@ -110,6 +112,7 @@ public:
&& experimental == params.experimental
&& tile_size == params.tile_size
&& start_resolution == params.start_resolution
+ && pixel_size == params.pixel_size
&& threads == params.threads
&& display_buffer_linear == params.display_buffer_linear
&& cancel_timeout == params.cancel_timeout
diff --git a/intern/cycles/render/shader.cpp b/intern/cycles/render/shader.cpp
index 44a266dfe18..493e01de363 100644
--- a/intern/cycles/render/shader.cpp
+++ b/intern/cycles/render/shader.cpp
@@ -503,9 +503,7 @@ void ShaderManager::device_update_common(Device *device,
KernelIntegrator *kintegrator = &dscene->data.integrator;
kintegrator->use_volumes = has_volumes;
/* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
- if(scene->integrator->transparent_shadows) {
- kintegrator->transparent_shadows = has_transparent_shadow;
- }
+ kintegrator->transparent_shadows = has_transparent_shadow;
}
void ShaderManager::device_free_common(Device *device, DeviceScene *dscene, Scene *scene)
diff --git a/intern/cycles/render/tile.cpp b/intern/cycles/render/tile.cpp
index 176a1f4f0f3..4f3479c52ae 100644
--- a/intern/cycles/render/tile.cpp
+++ b/intern/cycles/render/tile.cpp
@@ -88,12 +88,14 @@ enum SpiralDirection {
} /* namespace */
TileManager::TileManager(bool progressive_, int num_samples_, int2 tile_size_, int start_resolution_,
- bool preserve_tile_device_, bool background_, TileOrder tile_order_, int num_devices_)
+ bool preserve_tile_device_, bool background_, TileOrder tile_order_,
+ int num_devices_, int pixel_size_)
{
progressive = progressive_;
tile_size = tile_size_;
tile_order = tile_order_;
start_resolution = start_resolution_;
+ pixel_size = pixel_size_;
num_samples = num_samples_;
num_devices = num_devices_;
preserve_tile_device = preserve_tile_device_;
@@ -471,7 +473,7 @@ bool TileManager::done()
int end_sample = (range_num_samples == -1)
? num_samples
: range_start_sample + range_num_samples;
- return (state.resolution_divider == 1) &&
+ return (state.resolution_divider == pixel_size) &&
(state.sample+state.num_samples >= end_sample);
}
@@ -480,9 +482,9 @@ bool TileManager::next()
if(done())
return false;
- if(progressive && state.resolution_divider > 1) {
+ if(progressive && state.resolution_divider > pixel_size) {
state.sample = 0;
- state.resolution_divider /= 2;
+ state.resolution_divider = max(state.resolution_divider/2, pixel_size);
state.num_samples = 1;
set_tiles();
}
@@ -496,7 +498,7 @@ bool TileManager::next()
else
state.num_samples = range_num_samples;
- state.resolution_divider = 1;
+ state.resolution_divider = pixel_size;
set_tiles();
}
diff --git a/intern/cycles/render/tile.h b/intern/cycles/render/tile.h
index e39a8f0627a..4cd57b7b30c 100644
--- a/intern/cycles/render/tile.h
+++ b/intern/cycles/render/tile.h
@@ -88,7 +88,7 @@ public:
int num_samples;
TileManager(bool progressive, int num_samples, int2 tile_size, int start_resolution,
- bool preserve_tile_device, bool background, TileOrder tile_order, int num_devices = 1);
+ bool preserve_tile_device, bool background, TileOrder tile_order, int num_devices = 1, int pixel_size = 1);
~TileManager();
void free_device();
@@ -122,6 +122,7 @@ protected:
int2 tile_size;
TileOrder tile_order;
int start_resolution;
+ int pixel_size;
int num_devices;
/* in some cases it is important that the same tile will be returned for the same
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index 43f9a57d099..7f3747a0f58 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -38,6 +38,7 @@ set(SRC_HEADERS
util_atomic.h
util_boundbox.h
util_debug.h
+ util_defines.h
util_guarded_allocator.cpp
util_foreach.h
util_function.h
diff --git a/intern/cycles/util/util_defines.h b/intern/cycles/util/util_defines.h
new file mode 100644
index 00000000000..ae654092c87
--- /dev/null
+++ b/intern/cycles/util/util_defines.h
@@ -0,0 +1,135 @@
+
+/*
+ * Copyright 2011-2017 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.
+ */
+
+#ifndef __UTIL_DEFINES_H__
+#define __UTIL_DEFINES_H__
+
+/* Bitness */
+
+#if defined(__ppc64__) || defined(__PPC64__) || defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)
+# define __KERNEL_64_BIT__
+#endif
+
+/* Qualifiers for kernel code shared by CPU and GPU */
+
+#ifndef __KERNEL_GPU__
+# define ccl_device static inline
+# define ccl_device_noinline static
+# define ccl_global
+# define ccl_constant
+# define ccl_local
+# define ccl_local_param
+# define ccl_private
+# define ccl_restrict __restrict
+# define ccl_ref &
+# define __KERNEL_WITH_SSE_ALIGN__
+
+# if defined(_WIN32) && !defined(FREE_WINDOWS)
+# define ccl_device_inline static __forceinline
+# define ccl_device_forceinline static __forceinline
+# define ccl_align(...) __declspec(align(__VA_ARGS__))
+# ifdef __KERNEL_64_BIT__
+# define ccl_try_align(...) __declspec(align(__VA_ARGS__))
+# else /* __KERNEL_64_BIT__ */
+# undef __KERNEL_WITH_SSE_ALIGN__
+/* No support for function arguments (error C2719). */
+# define ccl_try_align(...)
+# endif /* __KERNEL_64_BIT__ */
+# define ccl_may_alias
+# define ccl_always_inline __forceinline
+# define ccl_never_inline __declspec(noinline)
+# define ccl_maybe_unused
+# else /* _WIN32 && !FREE_WINDOWS */
+# define ccl_device_inline static inline __attribute__((always_inline))
+# define ccl_device_forceinline static inline __attribute__((always_inline))
+# define ccl_align(...) __attribute__((aligned(__VA_ARGS__)))
+# ifndef FREE_WINDOWS64
+# define __forceinline inline __attribute__((always_inline))
+# endif
+# define ccl_try_align(...) __attribute__((aligned(__VA_ARGS__)))
+# define ccl_may_alias __attribute__((__may_alias__))
+# define ccl_always_inline __attribute__((always_inline))
+# define ccl_never_inline __attribute__((noinline))
+# define ccl_maybe_unused __attribute__((used))
+# endif /* _WIN32 && !FREE_WINDOWS */
+
+/* Use to suppress '-Wimplicit-fallthrough' (in place of 'break'). */
+# if defined(__GNUC__) && (__GNUC__ >= 7) /* gcc7.0+ only */
+# define ATTR_FALLTHROUGH __attribute__((fallthrough))
+# else
+# define ATTR_FALLTHROUGH ((void)0)
+# endif
+#endif /* __KERNEL_GPU__ */
+
+/* macros */
+
+/* hints for branch prediction, only use in code that runs a _lot_ */
+#if defined(__GNUC__) && defined(__KERNEL_CPU__)
+# define LIKELY(x) __builtin_expect(!!(x), 1)
+# define UNLIKELY(x) __builtin_expect(!!(x), 0)
+#else
+# define LIKELY(x) (x)
+# define UNLIKELY(x) (x)
+#endif
+
+#if defined(__cplusplus) && ((__cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1800))
+# define HAS_CPP11_FEATURES
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+# if defined(HAS_CPP11_FEATURES)
+/* Some magic to be sure we don't have reference in the type. */
+template<typename T> static inline T decltype_helper(T x) { return x; }
+# define TYPEOF(x) decltype(decltype_helper(x))
+# else
+# define TYPEOF(x) typeof(x)
+# endif
+#endif
+
+/* Causes warning:
+ * incompatible types when assigning to type 'Foo' from type 'Bar'
+ * ... the compiler optimizes away the temp var */
+#ifdef __GNUC__
+#define CHECK_TYPE(var, type) { \
+ TYPEOF(var) *__tmp; \
+ __tmp = (type *)NULL; \
+ (void)__tmp; \
+} (void)0
+
+#define CHECK_TYPE_PAIR(var_a, var_b) { \
+ TYPEOF(var_a) *__tmp; \
+ __tmp = (typeof(var_b) *)NULL; \
+ (void)__tmp; \
+} (void)0
+#else
+# define CHECK_TYPE(var, type)
+# define CHECK_TYPE_PAIR(var_a, var_b)
+#endif
+
+/* can be used in simple macros */
+#define CHECK_TYPE_INLINE(val, type) \
+ ((void)(((type)0) != (val)))
+
+#ifndef __KERNEL_GPU__
+# include <cassert>
+# define util_assert(statement) assert(statement)
+#else
+# define util_assert(statement)
+#endif
+
+#endif /* __UTIL_DEFINES_H__ */
+
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index b719640b19c..4d51ec5570a 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -94,6 +94,7 @@ ccl_device_inline float fminf(float a, float b)
#ifndef __KERNEL_GPU__
using std::isfinite;
using std::isnan;
+using std::sqrt;
ccl_device_inline int abs(int x)
{
diff --git a/intern/cycles/util/util_math_float3.h b/intern/cycles/util/util_math_float3.h
index bb04c4aa2d9..e73e5bc17a2 100644
--- a/intern/cycles/util/util_math_float3.h
+++ b/intern/cycles/util/util_math_float3.h
@@ -108,8 +108,7 @@ ccl_device_inline float3 operator*(const float3& a, const float f)
ccl_device_inline float3 operator*(const float f, const float3& a)
{
- /* TODO(sergey): Currently disabled, gives speedup but causes precision issues. */
-#if defined(__KERNEL_SSE__) && 0
+#if defined(__KERNEL_SSE__)
return float3(_mm_mul_ps(_mm_set1_ps(f), a.m128));
#else
return make_float3(a.x*f, a.y*f, a.z*f);
@@ -118,10 +117,8 @@ ccl_device_inline float3 operator*(const float f, const float3& a)
ccl_device_inline float3 operator/(const float f, const float3& a)
{
- /* TODO(sergey): Currently disabled, gives speedup but causes precision issues. */
-#if defined(__KERNEL_SSE__) && 0
- __m128 rc = _mm_rcp_ps(a.m128);
- return float3(_mm_mul_ps(_mm_set1_ps(f),rc));
+#if defined(__KERNEL_SSE__)
+ return float3(_mm_div_ps(_mm_set1_ps(f), a.m128));
#else
return make_float3(f / a.x, f / a.y, f / a.z);
#endif
@@ -135,10 +132,8 @@ ccl_device_inline float3 operator/(const float3& a, const float f)
ccl_device_inline float3 operator/(const float3& a, const float3& b)
{
- /* TODO(sergey): Currently disabled, gives speedup but causes precision issues. */
-#if defined(__KERNEL_SSE__) && 0
- __m128 rc = _mm_rcp_ps(b.m128);
- return float3(_mm_mul_ps(a, rc));
+#if defined(__KERNEL_SSE__)
+ return float3(_mm_div_ps(a.m128, b.m128));
#else
return make_float3(a.x / b.x, a.y / b.y, a.z / b.z);
#endif
@@ -282,9 +277,8 @@ ccl_device_inline float3 mix(const float3& a, const float3& b, float t)
ccl_device_inline float3 rcp(const float3& a)
{
#ifdef __KERNEL_SSE__
- const float4 r(_mm_rcp_ps(a.m128));
- return float3(_mm_sub_ps(_mm_add_ps(r, r),
- _mm_mul_ps(_mm_mul_ps(r, r), a)));
+ /* Don't use _mm_rcp_ps due to poor precision. */
+ return float3(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
#else
return make_float3(1.0f/a.x, 1.0f/a.y, 1.0f/a.z);
#endif
diff --git a/intern/cycles/util/util_math_float4.h b/intern/cycles/util/util_math_float4.h
index d89121b3a1d..aa7e56fefe9 100644
--- a/intern/cycles/util/util_math_float4.h
+++ b/intern/cycles/util/util_math_float4.h
@@ -48,23 +48,30 @@ ccl_device_inline bool operator==(const float4& a, const float4& b);
ccl_device_inline float dot(const float4& a, const float4& b);
ccl_device_inline float len_squared(const float4& a);
ccl_device_inline float4 rcp(const float4& a);
+ccl_device_inline float4 sqrt(const float4& a);
+ccl_device_inline float4 sqr(const float4& a);
ccl_device_inline float4 cross(const float4& a, const float4& b);
ccl_device_inline bool is_zero(const float4& a);
-ccl_device_inline float reduce_add(const float4& a);
ccl_device_inline float average(const float4& a);
ccl_device_inline float len(const float4& a);
ccl_device_inline float4 normalize(const float4& a);
ccl_device_inline float4 safe_normalize(const float4& a);
ccl_device_inline float4 min(const float4& a, const float4& b);
ccl_device_inline float4 max(const float4& a, const float4& b);
+ccl_device_inline float4 fabs(const float4& a);
#endif /* !__KERNEL_OPENCL__*/
#ifdef __KERNEL_SSE__
template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
__forceinline const float4 shuffle(const float4& b);
+template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
+__forceinline const float4 shuffle(const float4& a, const float4& b);
template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4& b);
+template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4& a, const float4& b);
+template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4& a, const float4& b);
+
# ifdef __KERNEL_SSE3__
template<> __forceinline const float4 shuffle<0, 0, 2, 2>(const float4& b);
template<> __forceinline const float4 shuffle<1, 1, 3, 3>(const float4& b);
@@ -77,9 +84,7 @@ ccl_device_inline float4 select(const int4& mask,
const float4& b);
ccl_device_inline float4 reduce_min(const float4& a);
ccl_device_inline float4 reduce_max(const float4& a);
-# if 0
ccl_device_inline float4 reduce_add(const float4& a);
-# endif
#endif /* !__KERNEL_GPU__ */
/*******************************************************************************
@@ -128,7 +133,7 @@ ccl_device_inline float4 operator/(const float4& a, float f)
ccl_device_inline float4 operator/(const float4& a, const float4& b)
{
#ifdef __KERNEL_SSE__
- return a * rcp(b);
+ return float4(_mm_div_ps(a.m128, b.m128));
#else
return make_float4(a.x/b.x, a.y/b.y, a.z/b.z, a.w/b.w);
#endif
@@ -171,8 +176,7 @@ ccl_device_inline float4 operator/=(float4& a, float f)
ccl_device_inline int4 operator<(const float4& a, const float4& b)
{
#ifdef __KERNEL_SSE__
- /* TODO(sergey): avoid cvt. */
- return int4(_mm_cvtps_epi32(_mm_cmplt_ps(a.m128, b.m128)));
+ return int4(_mm_castps_si128(_mm_cmplt_ps(a.m128, b.m128)));
#else
return make_int4(a.x < b.x, a.y < b.y, a.z < b.z, a.w < b.w);
#endif
@@ -181,8 +185,7 @@ ccl_device_inline int4 operator<(const float4& a, const float4& b)
ccl_device_inline int4 operator>=(const float4& a, const float4& b)
{
#ifdef __KERNEL_SSE__
- /* TODO(sergey): avoid cvt. */
- return int4(_mm_cvtps_epi32(_mm_cmpge_ps(a.m128, b.m128)));
+ return int4(_mm_castps_si128(_mm_cmpge_ps(a.m128, b.m128)));
#else
return make_int4(a.x >= b.x, a.y >= b.y, a.z >= b.z, a.w >= b.w);
#endif
@@ -191,8 +194,7 @@ ccl_device_inline int4 operator>=(const float4& a, const float4& b)
ccl_device_inline int4 operator<=(const float4& a, const float4& b)
{
#ifdef __KERNEL_SSE__
- /* TODO(sergey): avoid cvt. */
- return int4(_mm_cvtps_epi32(_mm_cmple_ps(a.m128, b.m128)));
+ return int4(_mm_castps_si128(_mm_cmple_ps(a.m128, b.m128)));
#else
return make_int4(a.x <= b.x, a.y <= b.y, a.z <= b.z, a.w <= b.w);
#endif
@@ -224,14 +226,30 @@ ccl_device_inline float len_squared(const float4& a)
ccl_device_inline float4 rcp(const float4& a)
{
#ifdef __KERNEL_SSE__
- float4 r(_mm_rcp_ps(a.m128));
- return float4(_mm_sub_ps(_mm_add_ps(r, r),
- _mm_mul_ps(_mm_mul_ps(r, r), a)));
+ /* Don't use _mm_rcp_ps due to poor precision. */
+ return float4(_mm_div_ps(_mm_set_ps1(1.0f), a.m128));
#else
return make_float4(1.0f/a.x, 1.0f/a.y, 1.0f/a.z, 1.0f/a.w);
#endif
}
+ccl_device_inline float4 sqrt(const float4& a)
+{
+#ifdef __KERNEL_SSE__
+ return float4(_mm_sqrt_ps(a.m128));
+#else
+ return make_float4(sqrtf(a.x),
+ sqrtf(a.y),
+ sqrtf(a.z),
+ sqrtf(a.w));
+#endif
+}
+
+ccl_device_inline float4 sqr(const float4& a)
+{
+ return a * a;
+}
+
ccl_device_inline float4 cross(const float4& a, const float4& b)
{
#ifdef __KERNEL_SSE__
@@ -254,20 +272,25 @@ ccl_device_inline bool is_zero(const float4& a)
#endif
}
-ccl_device_inline float reduce_add(const float4& a)
+ccl_device_inline float4 reduce_add(const float4& a)
{
#ifdef __KERNEL_SSE__
+# ifdef __KERNEL_SSE3__
+ float4 h(_mm_hadd_ps(a.m128, a.m128));
+ return float4( _mm_hadd_ps(h.m128, h.m128));
+# else
float4 h(shuffle<1,0,3,2>(a) + a);
- /* TODO(sergey): Investigate efficiency. */
- return _mm_cvtss_f32(shuffle<2,3,0,1>(h) + h);
+ return shuffle<2,3,0,1>(h) + h;
+# endif
#else
- return ((a.x + a.y) + (a.z + a.w));
+ float sum = (a.x + a.y) + (a.z + a.w);
+ return make_float4(sum, sum, sum, sum);
#endif
}
ccl_device_inline float average(const float4& a)
{
- return reduce_add(a) * 0.25f;
+ return reduce_add(a).x * 0.25f;
}
ccl_device_inline float len(const float4& a)
@@ -309,6 +332,18 @@ ccl_device_inline float4 max(const float4& a, const float4& b)
max(a.w, b.w));
#endif
}
+
+ccl_device_inline float4 fabs(const float4& a)
+{
+#ifdef __KERNEL_SSE__
+ return float4(_mm_and_ps(a.m128, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))));
+#else
+ return make_float4(fabsf(a.x),
+ fabsf(a.y),
+ fabsf(a.z),
+ fabsf(a.w));
+#endif
+}
#endif /* !__KERNEL_OPENCL__*/
#ifdef __KERNEL_SSE__
@@ -320,11 +355,28 @@ __forceinline const float4 shuffle(const float4& b)
_MM_SHUFFLE(index_3, index_2, index_1, index_0))));
}
+template<size_t index_0, size_t index_1, size_t index_2, size_t index_3>
+__forceinline const float4 shuffle(const float4& a, const float4& b)
+{
+ return float4(_mm_shuffle_ps(a.m128, b.m128,
+ _MM_SHUFFLE(index_3, index_2, index_1, index_0)));
+}
+
template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4& b)
{
return float4(_mm_castpd_ps(_mm_movedup_pd(_mm_castps_pd(b))));
}
+template<> __forceinline const float4 shuffle<0, 1, 0, 1>(const float4& a, const float4& b)
+{
+ return float4(_mm_movelh_ps(a.m128, b.m128));
+}
+
+template<> __forceinline const float4 shuffle<2, 3, 2, 3>(const float4& a, const float4& b)
+{
+ return float4(_mm_movehl_ps(b.m128, a.m128));
+}
+
# ifdef __KERNEL_SSE3__
template<> __forceinline const float4 shuffle<0, 0, 2, 2>(const float4& b)
{
@@ -344,9 +396,7 @@ ccl_device_inline float4 select(const int4& mask,
const float4& b)
{
#ifdef __KERNEL_SSE__
- /* TODO(sergey): avoid cvt. */
- return float4(_mm_or_ps(_mm_and_ps(_mm_cvtepi32_ps(mask), a),
- _mm_andnot_ps(_mm_cvtepi32_ps(mask), b)));
+ return float4(_mm_blendv_ps(b.m128, a.m128, _mm_castsi128_ps(mask.m128)));
#else
return make_float4((mask.x)? a.x: b.x,
(mask.y)? a.y: b.y,
@@ -355,6 +405,13 @@ ccl_device_inline float4 select(const int4& mask,
#endif
}
+ccl_device_inline float4 mask(const int4& mask,
+ const float4& a)
+{
+ /* Replace elements of x with zero where mask isn't set. */
+ return select(mask, a, make_float4(0.0f));
+}
+
ccl_device_inline float4 reduce_min(const float4& a)
{
#ifdef __KERNEL_SSE__
@@ -375,17 +432,15 @@ ccl_device_inline float4 reduce_max(const float4& a)
#endif
}
-#if 0
-ccl_device_inline float4 reduce_add(const float4& a)
+ccl_device_inline float4 load_float4(const float *v)
{
#ifdef __KERNEL_SSE__
- float4 h = shuffle<1,0,3,2>(a) + a;
- return shuffle<2,3,0,1>(h) + h;
+ return float4(_mm_loadu_ps(v));
#else
- return make_float4((a.x + a.y) + (a.z + a.w));
+ return make_float4(v[0], v[1], v[2], v[3]);
#endif
}
-#endif
+
#endif /* !__KERNEL_GPU__ */
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_math_matrix.h b/intern/cycles/util/util_math_matrix.h
index c7511f8306e..b31dbe4fc67 100644
--- a/intern/cycles/util/util_math_matrix.h
+++ b/intern/cycles/util/util_math_matrix.h
@@ -223,20 +223,20 @@ ccl_device void math_matrix_jacobi_eigendecomposition(float *A, ccl_global float
{
const float singular_epsilon = 1e-9f;
- for (int row = 0; row < n; row++) {
- for (int col = 0; col < n; col++) {
+ for(int row = 0; row < n; row++) {
+ for(int col = 0; col < n; col++) {
MATS(V, n, row, col, v_stride) = (col == row) ? 1.0f : 0.0f;
}
}
- for (int sweep = 0; sweep < 8; sweep++) {
+ for(int sweep = 0; sweep < 8; sweep++) {
float off_diagonal = 0.0f;
- for (int row = 1; row < n; row++) {
- for (int col = 0; col < row; col++) {
+ for(int row = 1; row < n; row++) {
+ for(int col = 0; col < row; col++) {
off_diagonal += fabsf(MAT(A, n, row, col));
}
}
- if (off_diagonal < 1e-7f) {
+ if(off_diagonal < 1e-7f) {
/* The matrix has nearly reached diagonal form.
* Since the eigenvalues are only used to determine truncation, their exact values aren't required - a relative error of a few ULPs won't matter at all. */
break;
@@ -253,7 +253,7 @@ ccl_device void math_matrix_jacobi_eigendecomposition(float *A, ccl_global float
float abs_element = fabsf(element);
/* If we're in a later sweep and the element already is very small, just set it to zero and skip the rotation. */
- if (sweep > 3 && abs_element <= singular_epsilon*fabsf(MAT(A, n, row, row)) && abs_element <= singular_epsilon*fabsf(MAT(A, n, col, col))) {
+ if(sweep > 3 && abs_element <= singular_epsilon*fabsf(MAT(A, n, row, row)) && abs_element <= singular_epsilon*fabsf(MAT(A, n, col, col))) {
MAT(A, n, row, col) = 0.0f;
continue;
}
@@ -272,10 +272,10 @@ ccl_device void math_matrix_jacobi_eigendecomposition(float *A, ccl_global float
* Then, we compute sin(phi) and cos(phi) themselves. */
float singular_diff = MAT(A, n, row, row) - MAT(A, n, col, col);
float ratio;
- if (abs_element > singular_epsilon*fabsf(singular_diff)) {
+ if(abs_element > singular_epsilon*fabsf(singular_diff)) {
float cot_2phi = 0.5f*singular_diff / element;
ratio = 1.0f / (fabsf(cot_2phi) + sqrtf(1.0f + cot_2phi*cot_2phi));
- if (cot_2phi < 0.0f) ratio = -ratio; /* Copy sign. */
+ if(cot_2phi < 0.0f) ratio = -ratio; /* Copy sign. */
}
else {
ratio = element / singular_diff;
@@ -315,21 +315,21 @@ ccl_device void math_matrix_jacobi_eigendecomposition(float *A, ccl_global float
}
/* Sort eigenvalues and the associated eigenvectors. */
- for (int i = 0; i < n - 1; i++) {
+ for(int i = 0; i < n - 1; i++) {
float v = MAT(A, n, i, i);
int k = i;
- for (int j = i; j < n; j++) {
- if (MAT(A, n, j, j) >= v) {
+ for(int j = i; j < n; j++) {
+ if(MAT(A, n, j, j) >= v) {
v = MAT(A, n, j, j);
k = j;
}
}
- if (k != i) {
+ if(k != i) {
/* Swap eigenvalues. */
MAT(A, n, k, k) = MAT(A, n, i, i);
MAT(A, n, i, i) = v;
/* Swap eigenvectors. */
- for (int j = 0; j < n; j++) {
+ for(int j = 0; j < n; j++) {
float v = MATS(V, n, i, j, v_stride);
MATS(V, n, i, j, v_stride) = MATS(V, n, k, j, v_stride);
MATS(V, n, k, j, v_stride) = v;
@@ -339,59 +339,59 @@ ccl_device void math_matrix_jacobi_eigendecomposition(float *A, ccl_global float
}
#ifdef __KERNEL_SSE3__
-ccl_device_inline void math_vector_zero_sse(__m128 *A, int n)
+ccl_device_inline void math_vector_zero_sse(float4 *A, int n)
{
for(int i = 0; i < n; i++) {
- A[i] = _mm_setzero_ps();
+ A[i] = make_float4(0.0f);
}
}
-ccl_device_inline void math_matrix_zero_sse(__m128 *A, int n)
+ccl_device_inline void math_matrix_zero_sse(float4 *A, int n)
{
for(int row = 0; row < n; row++) {
for(int col = 0; col <= row; col++) {
- MAT(A, n, row, col) = _mm_setzero_ps();
+ MAT(A, n, row, col) = make_float4(0.0f);
}
}
}
/* Add Gramian matrix of v to A.
* The Gramian matrix of v is v^T*v, so element (i,j) is v[i]*v[j]. */
-ccl_device_inline void math_matrix_add_gramian_sse(__m128 *A, int n, const __m128 *ccl_restrict v, __m128 weight)
+ccl_device_inline void math_matrix_add_gramian_sse(float4 *A, int n, const float4 *ccl_restrict v, float4 weight)
{
for(int row = 0; row < n; row++) {
for(int col = 0; col <= row; col++) {
- MAT(A, n, row, col) = _mm_add_ps(MAT(A, n, row, col), _mm_mul_ps(_mm_mul_ps(v[row], v[col]), weight));
+ MAT(A, n, row, col) = MAT(A, n, row, col) + v[row] * v[col] * weight;
}
}
}
-ccl_device_inline void math_vector_add_sse(__m128 *V, int n, const __m128 *ccl_restrict a)
+ccl_device_inline void math_vector_add_sse(float4 *V, int n, const float4 *ccl_restrict a)
{
for(int i = 0; i < n; i++) {
- V[i] = _mm_add_ps(V[i], a[i]);
+ V[i] += a[i];
}
}
-ccl_device_inline void math_vector_mul_sse(__m128 *V, int n, const __m128 *ccl_restrict a)
+ccl_device_inline void math_vector_mul_sse(float4 *V, int n, const float4 *ccl_restrict a)
{
for(int i = 0; i < n; i++) {
- V[i] = _mm_mul_ps(V[i], a[i]);
+ V[i] *= a[i];
}
}
-ccl_device_inline void math_vector_max_sse(__m128 *a, const __m128 *ccl_restrict b, int n)
+ccl_device_inline void math_vector_max_sse(float4 *a, const float4 *ccl_restrict b, int n)
{
for(int i = 0; i < n; i++) {
- a[i] = _mm_max_ps(a[i], b[i]);
+ a[i] = max(a[i], b[i]);
}
}
-ccl_device_inline void math_matrix_hsum(float *A, int n, const __m128 *ccl_restrict B)
+ccl_device_inline void math_matrix_hsum(float *A, int n, const float4 *ccl_restrict B)
{
for(int row = 0; row < n; row++) {
for(int col = 0; col <= row; col++) {
- MAT(A, n, row, col) = _mm_hsum_ss(MAT(B, n, row, col));
+ MAT(A, n, row, col) = reduce_add(MAT(B, n, row, col))[0];
}
}
}
diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h
index 6f70a474fe7..0382c0811dd 100644
--- a/intern/cycles/util/util_optimization.h
+++ b/intern/cycles/util/util_optimization.h
@@ -19,16 +19,6 @@
#ifndef __KERNEL_GPU__
-/* quiet unused define warnings */
-#if defined(__KERNEL_SSE2__) || \
- defined(__KERNEL_SSE3__) || \
- defined(__KERNEL_SSSE3__) || \
- defined(__KERNEL_SSE41__) || \
- defined(__KERNEL_AVX__) || \
- defined(__KERNEL_AVX2__)
- /* do nothing */
-#endif
-
/* x86
*
* Compile a regular, SSE2 and SSE3 kernel. */
@@ -73,48 +63,6 @@
#endif /* defined(__x86_64__) || defined(_M_X64) */
-/* SSE Experiment
- *
- * This is disabled code for an experiment to use SSE types globally for types
- * such as float3 and float4. Currently this gives an overall slowdown. */
-
-#if 0
-# define __KERNEL_SSE__
-# ifndef __KERNEL_SSE2__
-# define __KERNEL_SSE2__
-# endif
-# ifndef __KERNEL_SSE3__
-# define __KERNEL_SSE3__
-# endif
-# ifndef __KERNEL_SSSE3__
-# define __KERNEL_SSSE3__
-# endif
-# ifndef __KERNEL_SSE4__
-# define __KERNEL_SSE4__
-# endif
-#endif
-
-/* SSE Intrinsics includes
- *
- * We assume __KERNEL_SSEX__ flags to have been defined at this point */
-
-/* SSE intrinsics headers */
-#ifndef FREE_WINDOWS64
-
-#ifdef _MSC_VER
-# include <intrin.h>
-#elif (defined(__x86_64__) || defined(__i386__))
-# include <x86intrin.h>
-#endif
-
-#else
-
-/* MinGW64 has conflicting declarations for these SSE headers in <windows.h>.
- * Since we can't avoid including <windows.h>, better only include that */
-#include "util/util_windows.h"
-
-#endif
-
#endif
#endif /* __UTIL_OPTIMIZATION_H__ */
diff --git a/intern/cycles/util/util_simd.h b/intern/cycles/util/util_simd.h
index 587febe3e52..1a26ca697dd 100644
--- a/intern/cycles/util/util_simd.h
+++ b/intern/cycles/util/util_simd.h
@@ -18,19 +18,38 @@
#ifndef __UTIL_SIMD_TYPES_H__
#define __UTIL_SIMD_TYPES_H__
+#ifndef __KERNEL_GPU__
+
#include <limits>
#include "util/util_debug.h"
-#include "util/util_types.h"
+#include "util/util_defines.h"
+
+/* SSE Intrinsics includes
+ *
+ * We assume __KERNEL_SSEX__ flags to have been defined at this point */
+
+/* SSE intrinsics headers */
+#ifndef FREE_WINDOWS64
+
+#ifdef _MSC_VER
+# include <intrin.h>
+#elif (defined(__x86_64__) || defined(__i386__))
+# include <x86intrin.h>
+#endif
+
+#else
+
+/* MinGW64 has conflicting declarations for these SSE headers in <windows.h>.
+ * Since we can't avoid including <windows.h>, better only include that */
+#include "util/util_windows.h"
+
+#endif
CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_SSE2__
-struct sseb;
-struct ssei;
-struct ssef;
-
extern const __m128 _mm_lookupmask_ps[16];
/* Special Types */
@@ -328,12 +347,9 @@ __forceinline size_t __bscf(size_t& v)
#endif /* _WIN32 */
-static const unsigned int BITSCAN_NO_BIT_SET_32 = 32;
-static const size_t BITSCAN_NO_BIT_SET_64 = 64;
+#if !(defined(__SSE4_1__) || defined(__SSE4_2__))
-#ifdef __KERNEL_SSE3__
-/* Emulation of SSE4 functions with SSE3 */
-# ifndef __KERNEL_SSE41__
+/* Emulation of SSE4 functions with SSE2 */
#define _MM_FROUND_TO_NEAREST_INT 0x00
#define _MM_FROUND_TO_NEG_INF 0x01
@@ -342,50 +358,45 @@ static const size_t BITSCAN_NO_BIT_SET_64 = 64;
#define _MM_FROUND_CUR_DIRECTION 0x04
#undef _mm_blendv_ps
-#define _mm_blendv_ps __emu_mm_blendv_ps
-__forceinline __m128 _mm_blendv_ps( __m128 value, __m128 input, __m128 mask ) {
+#define _mm_blendv_ps _mm_blendv_ps_emu
+__forceinline __m128 _mm_blendv_ps_emu( __m128 value, __m128 input, __m128 mask)
+{
return _mm_or_ps(_mm_and_ps(mask, input), _mm_andnot_ps(mask, value));
}
#undef _mm_blend_ps
-#define _mm_blend_ps __emu_mm_blend_ps
-__forceinline __m128 _mm_blend_ps( __m128 value, __m128 input, const int mask ) {
+#define _mm_blend_ps _mm_blend_ps_emu
+__forceinline __m128 _mm_blend_ps_emu( __m128 value, __m128 input, const int mask)
+{
assert(mask < 0x10); return _mm_blendv_ps(value, input, _mm_lookupmask_ps[mask]);
}
#undef _mm_blendv_epi8
-#define _mm_blendv_epi8 __emu_mm_blendv_epi8
-__forceinline __m128i _mm_blendv_epi8( __m128i value, __m128i input, __m128i mask ) {
+#define _mm_blendv_epi8 _mm_blendv_epi8_emu
+__forceinline __m128i _mm_blendv_epi8_emu( __m128i value, __m128i input, __m128i mask)
+{
return _mm_or_si128(_mm_and_si128(mask, input), _mm_andnot_si128(mask, value));
}
-#undef _mm_mullo_epi32
-#define _mm_mullo_epi32 __emu_mm_mullo_epi32
-__forceinline __m128i _mm_mullo_epi32( __m128i value, __m128i input ) {
- __m128i rvalue;
- char* _r = (char*)(&rvalue + 1);
- char* _v = (char*)(& value + 1);
- char* _i = (char*)(& input + 1);
- for( ssize_t i = -16 ; i != 0 ; i += 4 ) *((int32_t*)(_r + i)) = *((int32_t*)(_v + i))* *((int32_t*)(_i + i));
- return rvalue;
-}
-
#undef _mm_min_epi32
-#define _mm_min_epi32 __emu_mm_min_epi32
-__forceinline __m128i _mm_min_epi32( __m128i value, __m128i input ) {
+#define _mm_min_epi32 _mm_min_epi32_emu
+__forceinline __m128i _mm_min_epi32_emu( __m128i value, __m128i input)
+{
return _mm_blendv_epi8(input, value, _mm_cmplt_epi32(value, input));
}
#undef _mm_max_epi32
-#define _mm_max_epi32 __emu_mm_max_epi32
-__forceinline __m128i _mm_max_epi32( __m128i value, __m128i input ) {
+#define _mm_max_epi32 _mm_max_epi32_emu
+__forceinline __m128i _mm_max_epi32_emu( __m128i value, __m128i input)
+{
return _mm_blendv_epi8(value, input, _mm_cmplt_epi32(value, input));
}
#undef _mm_extract_epi32
-#define _mm_extract_epi32 __emu_mm_extract_epi32
-__forceinline int _mm_extract_epi32( __m128i input, const int index ) {
- switch ( index ) {
+#define _mm_extract_epi32 _mm_extract_epi32_emu
+__forceinline int _mm_extract_epi32_emu( __m128i input, const int index)
+{
+ switch(index) {
case 0: return _mm_cvtsi128_si32(input);
case 1: return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(1, 1, 1, 1)));
case 2: return _mm_cvtsi128_si32(_mm_shuffle_epi32(input, _MM_SHUFFLE(2, 2, 2, 2)));
@@ -395,27 +406,26 @@ __forceinline int _mm_extract_epi32( __m128i input, const int index ) {
}
#undef _mm_insert_epi32
-#define _mm_insert_epi32 __emu_mm_insert_epi32
-__forceinline __m128i _mm_insert_epi32( __m128i value, int input, const int index ) {
+#define _mm_insert_epi32 _mm_insert_epi32_emu
+__forceinline __m128i _mm_insert_epi32_emu( __m128i value, int input, const int index)
+{
assert(index >= 0 && index < 4); ((int*)&value)[index] = input; return value;
}
-#undef _mm_extract_ps
-#define _mm_extract_ps __emu_mm_extract_ps
-__forceinline int _mm_extract_ps( __m128 input, const int index ) {
- int32_t* ptr = (int32_t*)&input; return ptr[index];
-}
-
#undef _mm_insert_ps
-#define _mm_insert_ps __emu_mm_insert_ps
-__forceinline __m128 _mm_insert_ps( __m128 value, __m128 input, const int index )
-{ assert(index < 0x100); ((float*)&value)[(index >> 4)&0x3] = ((float*)&input)[index >> 6]; return _mm_andnot_ps(_mm_lookupmask_ps[index&0xf], value); }
+#define _mm_insert_ps _mm_insert_ps_emu
+__forceinline __m128 _mm_insert_ps_emu( __m128 value, __m128 input, const int index)
+{
+ assert(index < 0x100);
+ ((float*)&value)[(index >> 4)&0x3] = ((float*)&input)[index >> 6];
+ return _mm_andnot_ps(_mm_lookupmask_ps[index&0xf], value);
+}
#undef _mm_round_ps
-#define _mm_round_ps __emu_mm_round_ps
-__forceinline __m128 _mm_round_ps( __m128 value, const int flags )
+#define _mm_round_ps _mm_round_ps_emu
+__forceinline __m128 _mm_round_ps_emu( __m128 value, const int flags)
{
- switch ( flags )
+ switch(flags)
{
case _MM_FROUND_TO_NEAREST_INT: return _mm_cvtepi32_ps(_mm_cvtps_epi32(value));
case _MM_FROUND_TO_NEG_INF : return _mm_cvtepi32_ps(_mm_cvtps_epi32(_mm_add_ps(value, _mm_set1_ps(-0.5f))));
@@ -425,57 +435,7 @@ __forceinline __m128 _mm_round_ps( __m128 value, const int flags )
return value;
}
-# ifdef _M_X64
-#undef _mm_insert_epi64
-#define _mm_insert_epi64 __emu_mm_insert_epi64
-__forceinline __m128i _mm_insert_epi64( __m128i value, __int64 input, const int index ) {
- assert(size_t(index) < 4); ((__int64*)&value)[index] = input; return value;
-}
-
-#undef _mm_extract_epi64
-#define _mm_extract_epi64 __emu_mm_extract_epi64
-__forceinline __int64 _mm_extract_epi64( __m128i input, const int index ) {
- assert(size_t(index) < 2);
- return index == 0 ? _mm_cvtsi128_si64x(input) : _mm_cvtsi128_si64x(_mm_unpackhi_epi64(input, input));
-}
-# endif
-
-# endif
-
-#undef _mm_fabs_ps
-#define _mm_fabs_ps(x) _mm_and_ps(x, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff)))
-
-/* Return a __m128 with every element set to the largest element of v. */
-ccl_device_inline __m128 _mm_hmax_ps(__m128 v)
-{
- /* v[0, 1, 2, 3] => [0, 1, 0, 1] and [2, 3, 2, 3] => v[max(0, 2), max(1, 3), max(0, 2), max(1, 3)] */
- v = _mm_max_ps(_mm_movehl_ps(v, v), _mm_movelh_ps(v, v));
- /* v[max(0, 2), max(1, 3), max(0, 2), max(1, 3)] => [4 times max(1, 3)] and [4 times max(0, 2)] => v[4 times max(0, 1, 2, 3)] */
- v = _mm_max_ps(_mm_movehdup_ps(v), _mm_moveldup_ps(v));
- return v;
-}
-
-/* Return the sum of the four elements of x. */
-ccl_device_inline float _mm_hsum_ss(__m128 x)
-{
- __m128 a = _mm_movehdup_ps(x);
- __m128 b = _mm_add_ps(x, a);
- return _mm_cvtss_f32(_mm_add_ss(_mm_movehl_ps(a, b), b));
-}
-
-/* Return a __m128 with every element set to the sum of the four elements of x. */
-ccl_device_inline __m128 _mm_hsum_ps(__m128 x)
-{
- x = _mm_hadd_ps(x, x);
- x = _mm_hadd_ps(x, x);
- return x;
-}
-
-/* Replace elements of x with zero where mask isn't set. */
-#undef _mm_mask_ps
-#define _mm_mask_ps(x, mask) _mm_blendv_ps(_mm_setzero_ps(), x, mask)
-
-#endif
+#endif /* !(defined(__SSE4_1__) || defined(__SSE4_2__)) */
#else /* __KERNEL_SSE2__ */
@@ -496,13 +456,19 @@ ccl_device_inline int bitscan(int value)
#endif /* __KERNEL_SSE2__ */
+/* quiet unused define warnings */
+#if defined(__KERNEL_SSE2__) || \
+ defined(__KERNEL_SSE3__) || \
+ defined(__KERNEL_SSSE3__) || \
+ defined(__KERNEL_SSE41__) || \
+ defined(__KERNEL_AVX__) || \
+ defined(__KERNEL_AVX2__)
+ /* do nothing */
+#endif
+
CCL_NAMESPACE_END
-#include "util/util_math.h"
-#include "util/util_sseb.h"
-#include "util/util_ssei.h"
-#include "util/util_ssef.h"
-#include "util/util_avxf.h"
+#endif /* __KERNEL_GPU__ */
#endif /* __UTIL_SIMD_TYPES_H__ */
diff --git a/intern/cycles/util/util_sseb.h b/intern/cycles/util/util_sseb.h
index 6e669701f3b..93c22aafdcd 100644
--- a/intern/cycles/util/util_sseb.h
+++ b/intern/cycles/util/util_sseb.h
@@ -22,6 +22,9 @@ CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_SSE2__
+struct ssei;
+struct ssef;
+
/*! 4-wide SSE bool type. */
struct sseb
{
diff --git a/intern/cycles/util/util_ssef.h b/intern/cycles/util/util_ssef.h
index cf99a08efae..bb007ff84a9 100644
--- a/intern/cycles/util/util_ssef.h
+++ b/intern/cycles/util/util_ssef.h
@@ -22,6 +22,9 @@ CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_SSE2__
+struct sseb;
+struct ssef;
+
/*! 4-wide SSE float type. */
struct ssef
{
diff --git a/intern/cycles/util/util_ssei.h b/intern/cycles/util/util_ssei.h
index 5f62569268c..ef2a9e68b7d 100644
--- a/intern/cycles/util/util_ssei.h
+++ b/intern/cycles/util/util_ssei.h
@@ -22,6 +22,9 @@ CCL_NAMESPACE_BEGIN
#ifdef __KERNEL_SSE2__
+struct sseb;
+struct ssef;
+
/*! 4-wide SSE integer type. */
struct ssei
{
@@ -234,8 +237,10 @@ __forceinline size_t select_max(const sseb& valid, const ssei& v) { const ssei a
#else
-__forceinline int reduce_min(const ssei& v) { return min(min(v[0],v[1]),min(v[2],v[3])); }
-__forceinline int reduce_max(const ssei& v) { return max(max(v[0],v[1]),max(v[2],v[3])); }
+__forceinline int ssei_min(int a, int b) { return (a < b)? a: b; }
+__forceinline int ssei_max(int a, int b) { return (a > b)? a: b; }
+__forceinline int reduce_min(const ssei& v) { return ssei_min(ssei_min(v[0],v[1]),ssei_min(v[2],v[3])); }
+__forceinline int reduce_max(const ssei& v) { return ssei_max(ssei_max(v[0],v[1]),ssei_max(v[2],v[3])); }
__forceinline int reduce_add(const ssei& v) { return v[0]+v[1]+v[2]+v[3]; }
#endif
diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h
index a5d1d7152d5..aabca6c81fc 100644
--- a/intern/cycles/util/util_types.h
+++ b/intern/cycles/util/util_types.h
@@ -21,72 +21,18 @@
# include <stdlib.h>
#endif
-/* Bitness */
+/* Standard Integer Types */
-#if defined(__ppc64__) || defined(__PPC64__) || defined(__x86_64__) || defined(__ia64__) || defined(_M_X64)
-# define __KERNEL_64_BIT__
+#if !defined(__KERNEL_GPU__) && !defined(_WIN32)
+# include <stdint.h>
#endif
-/* Qualifiers for kernel code shared by CPU and GPU */
-
-#ifndef __KERNEL_GPU__
-# define ccl_device static inline
-# define ccl_device_noinline static
-# define ccl_global
-# define ccl_constant
-# define ccl_local
-# define ccl_local_param
-# define ccl_private
-# define ccl_restrict __restrict
-# define __KERNEL_WITH_SSE_ALIGN__
-
-# if defined(_WIN32) && !defined(FREE_WINDOWS)
-# define ccl_device_inline static __forceinline
-# define ccl_device_forceinline static __forceinline
-# define ccl_align(...) __declspec(align(__VA_ARGS__))
-# ifdef __KERNEL_64_BIT__
-# define ccl_try_align(...) __declspec(align(__VA_ARGS__))
-# else /* __KERNEL_64_BIT__ */
-# undef __KERNEL_WITH_SSE_ALIGN__
-/* No support for function arguments (error C2719). */
-# define ccl_try_align(...)
-# endif /* __KERNEL_64_BIT__ */
-# define ccl_may_alias
-# define ccl_always_inline __forceinline
-# define ccl_never_inline __declspec(noinline)
-# define ccl_maybe_unused
-# else /* _WIN32 && !FREE_WINDOWS */
-# define ccl_device_inline static inline __attribute__((always_inline))
-# define ccl_device_forceinline static inline __attribute__((always_inline))
-# define ccl_align(...) __attribute__((aligned(__VA_ARGS__)))
-# ifndef FREE_WINDOWS64
-# define __forceinline inline __attribute__((always_inline))
-# endif
-# define ccl_try_align(...) __attribute__((aligned(__VA_ARGS__)))
-# define ccl_may_alias __attribute__((__may_alias__))
-# define ccl_always_inline __attribute__((always_inline))
-# define ccl_never_inline __attribute__((noinline))
-# define ccl_maybe_unused __attribute__((used))
-# endif /* _WIN32 && !FREE_WINDOWS */
-
-/* Use to suppress '-Wimplicit-fallthrough' (in place of 'break'). */
-# if defined(__GNUC__) && (__GNUC__ >= 7) /* gcc7.0+ only */
-# define ATTR_FALLTHROUGH __attribute__((fallthrough))
-# else
-# define ATTR_FALLTHROUGH ((void)0)
-# endif
-#endif /* __KERNEL_GPU__ */
-
-/* Standard Integer Types */
+#include "util/util_defines.h"
#ifndef __KERNEL_GPU__
-/* int8_t, uint16_t, and friends */
-# ifndef _WIN32
-# include <stdint.h>
-# endif
-/* SIMD Types */
# include "util/util_optimization.h"
-#endif /* __KERNEL_GPU__ */
+# include "util/util_simd.h"
+#endif
CCL_NAMESPACE_BEGIN
@@ -201,65 +147,8 @@ enum ExtensionType {
EXTENSION_NUM_TYPES,
};
-/* macros */
-
-/* hints for branch prediction, only use in code that runs a _lot_ */
-#if defined(__GNUC__) && defined(__KERNEL_CPU__)
-# define LIKELY(x) __builtin_expect(!!(x), 1)
-# define UNLIKELY(x) __builtin_expect(!!(x), 0)
-#else
-# define LIKELY(x) (x)
-# define UNLIKELY(x) (x)
-#endif
-
-#if defined(__cplusplus) && ((__cplusplus >= 201103L) || (defined(_MSC_VER) && _MSC_VER >= 1800))
-# define HAS_CPP11_FEATURES
-#endif
-
-#if defined(__GNUC__) || defined(__clang__)
-# if defined(HAS_CPP11_FEATURES)
-/* Some magic to be sure we don't have reference in the type. */
-template<typename T> static inline T decltype_helper(T x) { return x; }
-# define TYPEOF(x) decltype(decltype_helper(x))
-# else
-# define TYPEOF(x) typeof(x)
-# endif
-#endif
-
-/* Causes warning:
- * incompatible types when assigning to type 'Foo' from type 'Bar'
- * ... the compiler optimizes away the temp var */
-#ifdef __GNUC__
-#define CHECK_TYPE(var, type) { \
- TYPEOF(var) *__tmp; \
- __tmp = (type *)NULL; \
- (void)__tmp; \
-} (void)0
-
-#define CHECK_TYPE_PAIR(var_a, var_b) { \
- TYPEOF(var_a) *__tmp; \
- __tmp = (typeof(var_b) *)NULL; \
- (void)__tmp; \
-} (void)0
-#else
-# define CHECK_TYPE(var, type)
-# define CHECK_TYPE_PAIR(var_a, var_b)
-#endif
-
-/* can be used in simple macros */
-#define CHECK_TYPE_INLINE(val, type) \
- ((void)(((type)0) != (val)))
-
-
CCL_NAMESPACE_END
-#ifndef __KERNEL_GPU__
-# include <cassert>
-# define util_assert(statement) assert(statement)
-#else
-# define util_assert(statement)
-#endif
-
/* Vectorized types declaration. */
#include "util/util_types_uchar2.h"
#include "util/util_types_uchar3.h"
@@ -298,5 +187,13 @@ CCL_NAMESPACE_END
#include "util/util_types_vector3_impl.h"
+/* SSE types. */
+#ifndef __KERNEL_GPU__
+# include "util/util_sseb.h"
+# include "util/util_ssei.h"
+# include "util/util_ssef.h"
+# include "util/util_avxf.h"
+#endif
+
#endif /* __UTIL_TYPES_H__ */
diff --git a/intern/gawain/CMakeLists.txt b/intern/gawain/CMakeLists.txt
index 48392012176..9924daa8cd1 100644
--- a/intern/gawain/CMakeLists.txt
+++ b/intern/gawain/CMakeLists.txt
@@ -8,31 +8,31 @@ set(INC_SYS
)
set(SRC
- src/attrib_binding.c
- src/batch.c
- src/element.c
- src/buffer_id.cpp
- src/immediate.c
- src/imm_util.c
- src/primitive.c
- src/shader_interface.c
- src/vertex_buffer.c
- src/vertex_format.c
+ src/gwn_attr_binding.c
+ src/gwn_batch.c
+ src/gwn_element.c
+ src/gwn_buffer_id.cpp
+ src/gwn_immediate.c
+ src/gwn_imm_util.c
+ src/gwn_primitive.c
+ src/gwn_shader_interface.c
+ src/gwn_vertex_buffer.c
+ src/gwn_vertex_format.c
- gawain/attrib_binding.h
- gawain/attrib_binding_private.h
- gawain/batch.h
- gawain/buffer_id.h
- gawain/common.h
- gawain/element.h
- gawain/imm_util.h
- gawain/immediate.h
- gawain/primitive.h
- gawain/primitive_private.h
- gawain/shader_interface.h
- gawain/vertex_buffer.h
- gawain/vertex_format.h
- gawain/vertex_format_private.h
+ gawain/gwn_attr_binding.h
+ gawain/gwn_attr_binding_private.h
+ gawain/gwn_batch.h
+ gawain/gwn_buffer_id.h
+ gawain/gwn_common.h
+ gawain/gwn_element.h
+ gawain/gwn_imm_util.h
+ gawain/gwn_immediate.h
+ gawain/gwn_primitive.h
+ gawain/gwn_primitive_private.h
+ gawain/gwn_shader_interface.h
+ gawain/gwn_vertex_buffer.h
+ gawain/gwn_vertex_format.h
+ gawain/gwn_vertex_format_private.h
)
add_definitions(${GL_DEFINITIONS})
diff --git a/intern/gawain/gawain/attrib_binding.h b/intern/gawain/gawain/gwn_attr_binding.h
index a254f05dc05..a209e1c4f0f 100644
--- a/intern/gawain/gawain/attrib_binding.h
+++ b/intern/gawain/gawain/gwn_attr_binding.h
@@ -11,9 +11,9 @@
#pragma once
-#include "common.h"
+#include "gwn_common.h"
-typedef struct {
+typedef struct Gwn_AttrBinding {
uint64_t loc_bits; // store 4 bits for each of the 16 attribs
uint16_t enabled_bits; // 1 bit for each attrib
} Gwn_AttrBinding;
diff --git a/intern/gawain/gawain/attrib_binding_private.h b/intern/gawain/gawain/gwn_attr_binding_private.h
index 53fdecff9ce..300945d464b 100644
--- a/intern/gawain/gawain/attrib_binding_private.h
+++ b/intern/gawain/gawain/gwn_attr_binding_private.h
@@ -11,8 +11,8 @@
#pragma once
-#include "vertex_format.h"
-#include "shader_interface.h"
+#include "gwn_vertex_format.h"
+#include "gwn_shader_interface.h"
void AttribBinding_clear(Gwn_AttrBinding*);
diff --git a/intern/gawain/gawain/batch.h b/intern/gawain/gawain/gwn_batch.h
index 6e2f32c1996..9bcb7437163 100644
--- a/intern/gawain/gawain/batch.h
+++ b/intern/gawain/gawain/gwn_batch.h
@@ -11,9 +11,9 @@
#pragma once
-#include "vertex_buffer.h"
-#include "element.h"
-#include "shader_interface.h"
+#include "gwn_vertex_buffer.h"
+#include "gwn_element.h"
+#include "gwn_shader_interface.h"
typedef enum {
GWN_BATCH_READY_TO_FORMAT,
@@ -36,19 +36,33 @@ typedef struct Gwn_Batch {
Gwn_BatchPhase phase;
bool program_dirty;
bool program_in_use;
+ unsigned owns_flag;
// state
GLuint program;
const Gwn_ShaderInterface* interface;
} Gwn_Batch;
-Gwn_Batch* GWN_batch_create(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*);
-void GWN_batch_init(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*);
+enum {
+ GWN_BATCH_OWNS_VBO = (1 << 0),
+ /* each vbo index gets bit-shifted */
+ GWN_BATCH_OWNS_INDEX = (1 << 31),
+};
+
+Gwn_Batch* GWN_batch_create_ex(Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, unsigned owns_flag);
+void GWN_batch_init_ex(Gwn_Batch*, Gwn_PrimType, Gwn_VertBuf*, Gwn_IndexBuf*, unsigned owns_flag);
+
+#define GWN_batch_create(prim, verts, elem) \
+ GWN_batch_create_ex(prim, verts, elem, 0)
+#define GWN_batch_init(batch, prim, verts, elem) \
+ GWN_batch_init_ex(batch, prim, verts, elem, 0)
void GWN_batch_discard(Gwn_Batch*); // verts & elem are not discarded
-void GWN_batch_discard_all(Gwn_Batch*); // including verts & elem
-int GWN_batch_vertbuf_add(Gwn_Batch*, Gwn_VertBuf*);
+int GWN_batch_vertbuf_add_ex(Gwn_Batch*, Gwn_VertBuf*, bool own_vbo);
+
+#define GWN_batch_vertbuf_add(batch, verts) \
+ GWN_batch_vertbuf_add_ex(batch, verts, false)
void GWN_batch_program_set(Gwn_Batch*, GLuint program, const Gwn_ShaderInterface*);
// Entire batch draws with one shader program, but can be redrawn later with another program.
@@ -63,6 +77,7 @@ void GWN_batch_uniform_1f(Gwn_Batch*, const char* name, float value);
void GWN_batch_uniform_2f(Gwn_Batch*, const char* name, float x, float y);
void GWN_batch_uniform_3f(Gwn_Batch*, const char* name, float x, float y, float z);
void GWN_batch_uniform_4f(Gwn_Batch*, const char* name, float x, float y, float z, float w);
+void GWN_batch_uniform_2fv(Gwn_Batch*, const char* name, const float data[2]);
void GWN_batch_uniform_3fv(Gwn_Batch*, const char* name, const float data[3]);
void GWN_batch_uniform_4fv(Gwn_Batch*, const char* name, const float data[4]);
@@ -87,17 +102,17 @@ void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch*, Gwn_Batch*);
// We often need a batch with its own data, to be created and discarded together.
// WithOwn variants reduce number of system allocations.
-typedef struct {
+typedef struct BatchWithOwnVertexBuffer {
Gwn_Batch batch;
Gwn_VertBuf verts; // link batch.verts to this
} BatchWithOwnVertexBuffer;
-typedef struct {
+typedef struct BatchWithOwnElementList {
Gwn_Batch batch;
Gwn_IndexBuf elem; // link batch.elem to this
} BatchWithOwnElementList;
-typedef struct {
+typedef struct BatchWithOwnVertexBufferAndElementList {
Gwn_Batch batch;
Gwn_IndexBuf elem; // link batch.elem to this
Gwn_VertBuf verts; // link batch.verts to this
@@ -121,9 +136,3 @@ Gwn_Batch* create_BatchInGeneral(Gwn_PrimType, VertexBufferStuff, ElementListStu
batch = NULL; \
} \
} while (0)
-#define BATCH_DISCARD_ALL_SAFE(batch) do { \
- if (batch != NULL) { \
- GWN_batch_discard_all(batch); \
- batch = NULL; \
- } \
-} while (0)
diff --git a/intern/gawain/gawain/buffer_id.h b/intern/gawain/gawain/gwn_buffer_id.h
index e978eec67d8..db5df99f526 100644
--- a/intern/gawain/gawain/buffer_id.h
+++ b/intern/gawain/gawain/gwn_buffer_id.h
@@ -20,7 +20,7 @@
extern "C" {
#endif
-#include "common.h"
+#include "gwn_common.h"
GLuint GWN_buf_id_alloc(void);
void GWN_buf_id_free(GLuint buffer_id);
diff --git a/intern/gawain/gawain/common.h b/intern/gawain/gawain/gwn_common.h
index e96a3b5c2a2..e96a3b5c2a2 100644
--- a/intern/gawain/gawain/common.h
+++ b/intern/gawain/gawain/gwn_common.h
diff --git a/intern/gawain/gawain/element.h b/intern/gawain/gawain/gwn_element.h
index 771462be7c5..3081305769f 100644
--- a/intern/gawain/gawain/element.h
+++ b/intern/gawain/gawain/gwn_element.h
@@ -11,7 +11,7 @@
#pragma once
-#include "primitive.h"
+#include "gwn_primitive.h"
#define GWN_TRACK_INDEX_RANGE 1
@@ -21,7 +21,7 @@ typedef enum {
GWN_INDEX_U32
} Gwn_IndexBufType;
-typedef struct {
+typedef struct Gwn_IndexBuf {
unsigned index_ct;
#if GWN_TRACK_INDEX_RANGE
Gwn_IndexBufType index_type;
@@ -37,7 +37,7 @@ typedef struct {
void GWN_indexbuf_use(Gwn_IndexBuf*);
unsigned GWN_indexbuf_size_get(const Gwn_IndexBuf*);
-typedef struct {
+typedef struct Gwn_IndexBufBuilder {
unsigned max_allowed_index;
unsigned max_index_ct;
unsigned index_ct;
diff --git a/intern/gawain/gawain/imm_util.h b/intern/gawain/gawain/gwn_imm_util.h
index 730bd7c1a3c..730bd7c1a3c 100644
--- a/intern/gawain/gawain/imm_util.h
+++ b/intern/gawain/gawain/gwn_imm_util.h
diff --git a/intern/gawain/gawain/immediate.h b/intern/gawain/gawain/gwn_immediate.h
index 39ba76db931..386b26b63b1 100644
--- a/intern/gawain/gawain/immediate.h
+++ b/intern/gawain/gawain/gwn_immediate.h
@@ -11,9 +11,9 @@
#pragma once
-#include "vertex_format.h"
-#include "primitive.h"
-#include "shader_interface.h"
+#include "gwn_vertex_format.h"
+#include "gwn_primitive.h"
+#include "gwn_shader_interface.h"
#define IMM_BATCH_COMBO 1
@@ -28,7 +28,7 @@ void immBeginAtMost(Gwn_PrimType, unsigned max_vertex_ct); // can supply fewer v
void immEnd(void); // finishes and draws
#if IMM_BATCH_COMBO
-#include "batch.h"
+#include "gwn_batch.h"
// immBegin a batch, then use standard immFunctions as usual.
// immEnd will finalize the batch instead of drawing.
// Then you can draw it as many times as you like! Partially replaces the need for display lists.
diff --git a/intern/gawain/gawain/primitive.h b/intern/gawain/gawain/gwn_primitive.h
index c6786dc1993..5e5b8019889 100644
--- a/intern/gawain/gawain/primitive.h
+++ b/intern/gawain/gawain/gwn_primitive.h
@@ -11,7 +11,7 @@
#pragma once
-#include "common.h"
+#include "gwn_common.h"
typedef enum {
GWN_PRIM_POINTS,
diff --git a/intern/gawain/gawain/primitive_private.h b/intern/gawain/gawain/gwn_primitive_private.h
index d959cd89852..d959cd89852 100644
--- a/intern/gawain/gawain/primitive_private.h
+++ b/intern/gawain/gawain/gwn_primitive_private.h
diff --git a/intern/gawain/gawain/shader_interface.h b/intern/gawain/gawain/gwn_shader_interface.h
index 5304cc9fa51..cb3aeb84239 100644
--- a/intern/gawain/gawain/shader_interface.h
+++ b/intern/gawain/gawain/gwn_shader_interface.h
@@ -11,7 +11,7 @@
#pragma once
-#include "common.h"
+#include "gwn_common.h"
typedef enum {
GWN_UNIFORM_NONE, // uninitialized/unknown
@@ -30,7 +30,7 @@ typedef enum {
GWN_UNIFORM_CUSTOM // custom uniform, not one of the above built-ins
} Gwn_UniformBuiltin;
-typedef struct {
+typedef struct Gwn_ShaderInput {
const char* name;
unsigned name_hash;
GLenum gl_type;
@@ -39,7 +39,7 @@ typedef struct {
GLint location;
} Gwn_ShaderInput;
-typedef struct {
+typedef struct Gwn_ShaderInterface {
uint16_t uniform_ct;
uint16_t attrib_ct;
Gwn_ShaderInput inputs[0]; // dynamic size, uniforms followed by attribs
diff --git a/intern/gawain/gawain/vertex_buffer.h b/intern/gawain/gawain/gwn_vertex_buffer.h
index 9aee8e05877..5ad82251e79 100644
--- a/intern/gawain/gawain/vertex_buffer.h
+++ b/intern/gawain/gawain/gwn_vertex_buffer.h
@@ -11,7 +11,7 @@
#pragma once
-#include "vertex_format.h"
+#include "gwn_vertex_format.h"
// How to create a Gwn_VertBuf:
// 1) verts = GWN_vertbuf_create() or GWN_vertbuf_init(verts)
@@ -21,7 +21,7 @@
// Is Gwn_VertBuf always used as part of a Gwn_Batch?
-typedef struct {
+typedef struct Gwn_VertBuf {
Gwn_VertFormat format;
unsigned vertex_ct;
GLubyte* data; // NULL indicates data in VRAM (unmapped) or not yet allocated
@@ -51,7 +51,7 @@ void GWN_vertbuf_attr_fill(Gwn_VertBuf*, unsigned a_idx, const void* data); // t
void GWN_vertbuf_attr_fill_stride(Gwn_VertBuf*, unsigned a_idx, unsigned stride, const void* data);
// For low level access only
-typedef struct {
+typedef struct Gwn_VertBufRaw {
unsigned size;
unsigned stride;
GLubyte* data;
diff --git a/intern/gawain/gawain/vertex_format.h b/intern/gawain/gawain/gwn_vertex_format.h
index ab61722db60..348e6399afa 100644
--- a/intern/gawain/gawain/vertex_format.h
+++ b/intern/gawain/gawain/gwn_vertex_format.h
@@ -11,7 +11,7 @@
#pragma once
-#include "common.h"
+#include "gwn_common.h"
#define GWN_VERT_ATTR_MAX_LEN 16
#define MAX_ATTRIB_NAMES 3
@@ -38,7 +38,7 @@ typedef enum {
GWN_FETCH_INT_TO_FLOAT // 127 (any int type) -> 127.0
} Gwn_VertFetchMode;
-typedef struct {
+typedef struct Gwn_VertAttr {
Gwn_VertCompType comp_type;
unsigned gl_comp_type;
unsigned comp_ct; // 1 to 4
@@ -49,7 +49,7 @@ typedef struct {
unsigned name_ct;
} Gwn_VertAttr;
-typedef struct {
+typedef struct Gwn_VertFormat {
unsigned attrib_ct; // 0 to 16 (GWN_VERT_ATTR_MAX_LEN)
unsigned name_ct; // total count of active vertex attrib
unsigned stride; // stride in bytes, 1 to 256
@@ -67,7 +67,7 @@ void GWN_vertformat_alias_add(Gwn_VertFormat*, const char* alias);
// format conversion
-typedef struct {
+typedef struct Gwn_PackedNormal {
int x : 10;
int y : 10;
int z : 10;
diff --git a/intern/gawain/gawain/vertex_format_private.h b/intern/gawain/gawain/gwn_vertex_format_private.h
index c1a0f734eda..c1a0f734eda 100644
--- a/intern/gawain/gawain/vertex_format_private.h
+++ b/intern/gawain/gawain/gwn_vertex_format_private.h
diff --git a/intern/gawain/src/attrib_binding.c b/intern/gawain/src/gwn_attr_binding.c
index 6cdb8a0e542..7647a927b1e 100644
--- a/intern/gawain/src/attrib_binding.c
+++ b/intern/gawain/src/gwn_attr_binding.c
@@ -9,8 +9,8 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-#include "attrib_binding.h"
-#include "attrib_binding_private.h"
+#include "gwn_attr_binding.h"
+#include "gwn_attr_binding_private.h"
#include <stddef.h>
#if GWN_VERT_ATTR_MAX_LEN != 16
diff --git a/intern/gawain/src/batch.c b/intern/gawain/src/gwn_batch.c
index 22a5aab48b4..359ca956495 100644
--- a/intern/gawain/src/batch.c
+++ b/intern/gawain/src/gwn_batch.c
@@ -9,25 +9,29 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-#include "batch.h"
-#include "buffer_id.h"
-#include "primitive_private.h"
+#include "gwn_batch.h"
+#include "gwn_buffer_id.h"
+#include "gwn_primitive_private.h"
#include <stdlib.h>
// necessary functions from matrix API
extern void gpuBindMatrices(const Gwn_ShaderInterface* shaderface);
extern bool gpuMatricesDirty(void); // how best to use this here?
-Gwn_Batch* GWN_batch_create(Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem)
+Gwn_Batch* GWN_batch_create_ex(
+ Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem,
+ unsigned owns_flag)
{
Gwn_Batch* batch = calloc(1, sizeof(Gwn_Batch));
- GWN_batch_init(batch, prim_type, verts, elem);
+ GWN_batch_init_ex(batch, prim_type, verts, elem, owns_flag);
return batch;
}
-void GWN_batch_init(Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem)
+void GWN_batch_init_ex(
+ Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts, Gwn_IndexBuf* elem,
+ unsigned owns_flag)
{
#if TRUST_NO_ONE
assert(verts != NULL);
@@ -40,32 +44,34 @@ void GWN_batch_init(Gwn_Batch* batch, Gwn_PrimType prim_type, Gwn_VertBuf* verts
batch->prim_type = prim_type;
batch->gl_prim_type = convert_prim_type_to_gl(prim_type);
batch->phase = GWN_BATCH_READY_TO_DRAW;
+ batch->owns_flag = owns_flag;
}
void GWN_batch_discard(Gwn_Batch* batch)
{
- if (batch->vao_id)
- GWN_vao_free(batch->vao_id);
-
- free(batch);
- }
+ if (batch->owns_flag & GWN_BATCH_OWNS_INDEX)
+ GWN_indexbuf_discard(batch->elem);
-void GWN_batch_discard_all(Gwn_Batch* batch)
- {
- for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v)
+ if ((batch->owns_flag & ~GWN_BATCH_OWNS_INDEX) != 0)
{
- if (batch->verts[v] == NULL)
- break;
- GWN_vertbuf_discard(batch->verts[v]);
+ for (int v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v)
+ {
+ if (batch->verts[v] == NULL)
+ break;
+ if (batch->owns_flag & (1 << v))
+ GWN_vertbuf_discard(batch->verts[v]);
+ }
}
- if (batch->elem)
- GWN_indexbuf_discard(batch->elem);
+ if (batch->vao_id)
+ GWN_vao_free(batch->vao_id);
- GWN_batch_discard(batch);
+ free(batch);
}
-int GWN_batch_vertbuf_add(Gwn_Batch* batch, Gwn_VertBuf* verts)
+int GWN_batch_vertbuf_add_ex(
+ Gwn_Batch* batch, Gwn_VertBuf* verts,
+ bool own_vbo)
{
for (unsigned v = 0; v < GWN_BATCH_VBO_MAX_LEN; ++v)
{
@@ -78,6 +84,8 @@ int GWN_batch_vertbuf_add(Gwn_Batch* batch, Gwn_VertBuf* verts)
#endif
batch->verts[v] = verts;
// TODO: mark dirty so we can keep attrib bindings up-to-date
+ if (own_vbo)
+ batch->owns_flag |= (1 << v);
return v;
}
}
@@ -219,6 +227,12 @@ void GWN_batch_uniform_1f(Gwn_Batch* batch, const char* name, float x)
glUniform1f(uniform->location, x);
}
+void GWN_batch_uniform_2fv(Gwn_Batch* batch, const char* name, const float data[2])
+ {
+ GET_UNIFORM
+ glUniform2fv(uniform->location, 1, data);
+ }
+
void GWN_batch_uniform_3fv(Gwn_Batch* batch, const char* name, const float data[3])
{
GET_UNIFORM
@@ -446,4 +460,4 @@ void GWN_batch_draw_stupid_instanced_with_batch(Gwn_Batch* batch_instanced, Gwn_
// GWN_batch_program_use_end(batch);
glBindVertexArray(0);
- } \ No newline at end of file
+ }
diff --git a/intern/gawain/src/buffer_id.cpp b/intern/gawain/src/gwn_buffer_id.cpp
index 59a6b9c89e7..a93c3950d29 100644
--- a/intern/gawain/src/buffer_id.cpp
+++ b/intern/gawain/src/gwn_buffer_id.cpp
@@ -9,7 +9,7 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.#include "buffer_id.h"
-#include "buffer_id.h"
+#include "gwn_buffer_id.h"
#include <mutex>
#include <vector>
diff --git a/intern/gawain/src/element.c b/intern/gawain/src/gwn_element.c
index ecf555fbfe8..f31b64fa232 100644
--- a/intern/gawain/src/element.c
+++ b/intern/gawain/src/gwn_element.c
@@ -9,8 +9,8 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-#include "element.h"
-#include "buffer_id.h"
+#include "gwn_element.h"
+#include "gwn_buffer_id.h"
#include <stdlib.h>
#define KEEP_SINGLE_COPY 1
diff --git a/intern/gawain/src/imm_util.c b/intern/gawain/src/gwn_imm_util.c
index b06778c9045..45d8a7036e8 100644
--- a/intern/gawain/src/imm_util.c
+++ b/intern/gawain/src/gwn_imm_util.c
@@ -9,8 +9,8 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-#include "imm_util.h"
-#include "immediate.h"
+#include "gwn_imm_util.h"
+#include "gwn_immediate.h"
void immRectf(unsigned pos, float x1, float y1, float x2, float y2)
diff --git a/intern/gawain/src/immediate.c b/intern/gawain/src/gwn_immediate.c
index 5eb5ebb8336..1c0776d1bbf 100644
--- a/intern/gawain/src/immediate.c
+++ b/intern/gawain/src/gwn_immediate.c
@@ -9,12 +9,12 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-#include "immediate.h"
-#include "buffer_id.h"
-#include "attrib_binding.h"
-#include "attrib_binding_private.h"
-#include "vertex_format_private.h"
-#include "primitive_private.h"
+#include "gwn_immediate.h"
+#include "gwn_buffer_id.h"
+#include "gwn_attr_binding.h"
+#include "gwn_attr_binding_private.h"
+#include "gwn_vertex_format_private.h"
+#include "gwn_primitive_private.h"
#include <string.h>
// necessary functions from matrix API
diff --git a/intern/gawain/src/primitive.c b/intern/gawain/src/gwn_primitive.c
index b9d92a6bdf8..b206b3ae1b3 100644
--- a/intern/gawain/src/primitive.c
+++ b/intern/gawain/src/gwn_primitive.c
@@ -9,8 +9,8 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-#include "primitive.h"
-#include "primitive_private.h"
+#include "gwn_primitive.h"
+#include "gwn_primitive_private.h"
Gwn_PrimClass GWN_primtype_class(Gwn_PrimType prim_type)
{
diff --git a/intern/gawain/src/shader_interface.c b/intern/gawain/src/gwn_shader_interface.c
index dff2c06f531..e06fde6ad14 100644
--- a/intern/gawain/src/shader_interface.c
+++ b/intern/gawain/src/gwn_shader_interface.c
@@ -9,7 +9,7 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-#include "shader_interface.h"
+#include "gwn_shader_interface.h"
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
diff --git a/intern/gawain/src/vertex_buffer.c b/intern/gawain/src/gwn_vertex_buffer.c
index 364e16a1a68..2019d7d50bc 100644
--- a/intern/gawain/src/vertex_buffer.c
+++ b/intern/gawain/src/gwn_vertex_buffer.c
@@ -9,9 +9,9 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-#include "vertex_buffer.h"
-#include "buffer_id.h"
-#include "vertex_format_private.h"
+#include "gwn_vertex_buffer.h"
+#include "gwn_buffer_id.h"
+#include "gwn_vertex_format_private.h"
#include <stdlib.h>
#include <string.h>
diff --git a/intern/gawain/src/vertex_format.c b/intern/gawain/src/gwn_vertex_format.c
index 34704db3359..d6367935703 100644
--- a/intern/gawain/src/vertex_format.c
+++ b/intern/gawain/src/gwn_vertex_format.c
@@ -9,8 +9,8 @@
// This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of
// the MPL was not distributed with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
-#include "vertex_format.h"
-#include "vertex_format_private.h"
+#include "gwn_vertex_format.h"
+#include "gwn_vertex_format_private.h"
#include <stddef.h>
#include <string.h>
diff --git a/intern/ghost/intern/GHOST_ContextGLX.cpp b/intern/ghost/intern/GHOST_ContextGLX.cpp
index 0a9dc900aed..061ac29945b 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.cpp
+++ b/intern/ghost/intern/GHOST_ContextGLX.cpp
@@ -57,7 +57,6 @@ GHOST_ContextGLX::GHOST_ContextGLX(
GHOST_TUns16 numOfAASamples,
Window window,
Display *display,
- XVisualInfo *visualInfo,
GLXFBConfig fbconfig,
int contextProfileMask,
int contextMajorVersion,
@@ -66,7 +65,6 @@ GHOST_ContextGLX::GHOST_ContextGLX(
int contextResetNotificationStrategy)
: GHOST_Context(stereoVisual, numOfAASamples),
m_display(display),
- m_visualInfo(visualInfo),
m_fbconfig(fbconfig),
m_window(window),
m_contextProfileMask(contextProfileMask),
diff --git a/intern/ghost/intern/GHOST_ContextGLX.h b/intern/ghost/intern/GHOST_ContextGLX.h
index 6547a0bd00a..51fb1dd57dc 100644
--- a/intern/ghost/intern/GHOST_ContextGLX.h
+++ b/intern/ghost/intern/GHOST_ContextGLX.h
@@ -57,7 +57,6 @@ public:
GHOST_TUns16 numOfAASamples,
Window window,
Display *display,
- XVisualInfo *visualInfo,
GLXFBConfig fbconfig,
int contextProfileMask,
int contextMajorVersion,
@@ -113,7 +112,6 @@ private:
void initContextGLXEW();
Display *m_display;
- XVisualInfo *m_visualInfo;
GLXFBConfig m_fbconfig;
Window m_window;
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 450fe568814..12355cb6aab 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -1356,7 +1356,6 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
m_wantNumOfAASamples,
m_window,
m_display,
- m_visualInfo,
(GLXFBConfig)m_fbconfig,
profile_mask,
4, minor,
@@ -1374,7 +1373,6 @@ GHOST_Context *GHOST_WindowX11::newDrawingContext(GHOST_TDrawingContextType type
m_wantNumOfAASamples,
m_window,
m_display,
- m_visualInfo,
(GLXFBConfig)m_fbconfig,
profile_mask,
3, 3,
diff --git a/intern/itasc/FixedObject.hpp b/intern/itasc/FixedObject.hpp
index 02c1804073c..e768157ed2b 100644
--- a/intern/itasc/FixedObject.hpp
+++ b/intern/itasc/FixedObject.hpp
@@ -21,7 +21,7 @@ public:
int addFrame(const std::string& name, const Frame& frame);
- virtual void updateCoordinates(struct EvaluationContext *eval_ctx, const Timestamp& timestamp) {};
+ virtual void updateCoordinates(const struct EvaluationContext *eval_ctx, const Timestamp& timestamp) {};
virtual int addEndEffector(const std::string& name);
virtual bool finalize();
virtual const Frame& getPose(const unsigned int frameIndex);
diff --git a/intern/itasc/MovingFrame.cpp b/intern/itasc/MovingFrame.cpp
index b1815ddd0de..83e15bb59d9 100644
--- a/intern/itasc/MovingFrame.cpp
+++ b/intern/itasc/MovingFrame.cpp
@@ -90,7 +90,7 @@ bool MovingFrame::setCallback(MovingFrameCallback _function, void* _param)
return true;
}
-void MovingFrame::updateCoordinates(struct EvaluationContext *eval_ctx, const Timestamp& timestamp)
+void MovingFrame::updateCoordinates(const struct EvaluationContext *eval_ctx, const Timestamp& timestamp)
{
// don't compute the velocity during substepping, it is assumed constant.
if (!timestamp.substep) {
diff --git a/intern/itasc/MovingFrame.hpp b/intern/itasc/MovingFrame.hpp
index 89519832840..719e06b4bf7 100644
--- a/intern/itasc/MovingFrame.hpp
+++ b/intern/itasc/MovingFrame.hpp
@@ -15,7 +15,12 @@ struct EvaluationContext;
namespace iTaSC{
-typedef bool (*MovingFrameCallback)(struct EvaluationContext *eval_ctx, const Timestamp& timestamp, const Frame& _current, Frame& _next, void *param);
+typedef bool (*MovingFrameCallback)(
+ const struct EvaluationContext *eval_ctx,
+ const Timestamp& timestamp,
+ const Frame& _current,
+ Frame& _next,
+ void *param);
class MovingFrame: public UncontrolledObject {
public:
@@ -25,7 +30,7 @@ public:
bool setFrame(const Frame& frame);
bool setCallback(MovingFrameCallback _function, void* _param);
- virtual void updateCoordinates(struct EvaluationContext *eval_ctx, const Timestamp& timestamp);
+ virtual void updateCoordinates(const struct EvaluationContext *eval_ctx, const Timestamp& timestamp);
virtual void updateKinematics(const Timestamp& timestamp);
virtual void pushCache(const Timestamp& timestamp);
virtual void initCache(Cache *_cache);
diff --git a/intern/itasc/Scene.cpp b/intern/itasc/Scene.cpp
index fd8b006d19c..93f316783ba 100644
--- a/intern/itasc/Scene.cpp
+++ b/intern/itasc/Scene.cpp
@@ -257,7 +257,7 @@ bool Scene::getConstraintPose(ConstraintSet* constraint, void *_param, KDL::Fram
return true;
}
-bool Scene::update(struct EvaluationContext *eval_ctx, double timestamp, double timestep, unsigned int numsubstep, bool reiterate, bool cache, bool interpolate)
+bool Scene::update(const struct EvaluationContext *eval_ctx, double timestamp, double timestep, unsigned int numsubstep, bool reiterate, bool cache, bool interpolate)
{
// we must have valid timestep and timestamp
if (timestamp < KDL::epsilon || timestep < 0.0)
diff --git a/intern/itasc/Scene.hpp b/intern/itasc/Scene.hpp
index 0039be07584..ebbec561a6e 100644
--- a/intern/itasc/Scene.hpp
+++ b/intern/itasc/Scene.hpp
@@ -39,7 +39,7 @@ public:
bool addSolver(Solver* _solver);
bool addCache(Cache* _cache);
bool initialize();
- bool update(struct EvaluationContext *eval_ctx, double timestamp, double timestep, unsigned int numsubstep=1, bool reiterate=false, bool cache=true, bool interpolate=true);
+ bool update(const struct EvaluationContext *eval_ctx, double timestamp, double timestep, unsigned int numsubstep=1, bool reiterate=false, bool cache=true, bool interpolate=true);
bool setParam(SceneParam paramId, double value);
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
diff --git a/intern/itasc/UncontrolledObject.hpp b/intern/itasc/UncontrolledObject.hpp
index 889bc742c6d..d932974a24d 100644
--- a/intern/itasc/UncontrolledObject.hpp
+++ b/intern/itasc/UncontrolledObject.hpp
@@ -29,7 +29,7 @@ public:
virtual void initialize(unsigned int _nu, unsigned int _nf);
virtual const e_matrix& getJu(unsigned int frameIndex) const;
virtual const e_vector& getXudot() const {return m_xudot;}
- virtual void updateCoordinates(struct EvaluationContext *eval_ctx, const Timestamp& timestamp)=0;
+ virtual void updateCoordinates(const struct EvaluationContext *eval_ctx, const Timestamp& timestamp)=0;
virtual const unsigned int getNrOfCoordinates(){return m_nu;};
virtual const unsigned int getNrOfFrames(){return m_nf;};
diff --git a/intern/itasc/WorldObject.hpp b/intern/itasc/WorldObject.hpp
index b992445ab10..9876090e128 100644
--- a/intern/itasc/WorldObject.hpp
+++ b/intern/itasc/WorldObject.hpp
@@ -16,7 +16,7 @@ public:
WorldObject();
virtual ~WorldObject();
- virtual void updateCoordinates(struct EvaluationContext *eval_ctx, const Timestamp& timestamp) {};
+ virtual void updateCoordinates(const struct EvaluationContext *eval_ctx, const Timestamp& timestamp) {};
virtual void updateKinematics(const Timestamp& timestamp) {};
virtual void pushCache(const Timestamp& timestamp) {};
virtual void initCache(Cache *_cache) {};
diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc
index b89221c36da..d3de306edc8 100644
--- a/intern/opencolorio/ocio_impl_glsl.cc
+++ b/intern/opencolorio/ocio_impl_glsl.cc
@@ -49,7 +49,7 @@
#endif
extern "C" {
-#include "gawain/immediate.h"
+#include "gawain/gwn_immediate.h"
}
using namespace OCIO_NAMESPACE;
diff --git a/intern/opensubdiv/opensubdiv_gpu_capi.cc b/intern/opensubdiv/opensubdiv_gpu_capi.cc
index 811cd18745e..7d8085c1ff5 100644
--- a/intern/opensubdiv/opensubdiv_gpu_capi.cc
+++ b/intern/opensubdiv/opensubdiv_gpu_capi.cc
@@ -616,7 +616,7 @@ static GLuint prepare_patchDraw(OpenSubdiv_GLMesh *gl_mesh,
if (fill_quads) {
int model;
- GLboolean use_texture_2d, use_lighting;
+ GLboolean use_texture_2d;
glGetIntegerv(GL_SHADE_MODEL, &model);
glGetBooleanv(GL_TEXTURE_2D, &use_texture_2d);
diff --git a/release/scripts/presets/cycles/integrator/direct_light.py b/release/scripts/presets/cycles/integrator/direct_light.py
index 12b332cb431..701aa10d556 100644
--- a/release/scripts/presets/cycles/integrator/direct_light.py
+++ b/release/scripts/presets/cycles/integrator/direct_light.py
@@ -2,12 +2,10 @@ import bpy
cycles = bpy.context.scene.cycles
cycles.max_bounces = 8
-cycles.min_bounces = 8
cycles.caustics_reflective = False
cycles.caustics_refractive = False
cycles.diffuse_bounces = 0
cycles.glossy_bounces = 1
cycles.transmission_bounces = 2
cycles.volume_bounces = 0
-cycles.transparent_min_bounces = 8
cycles.transparent_max_bounces = 8
diff --git a/release/scripts/presets/cycles/integrator/full_global_illumination.py b/release/scripts/presets/cycles/integrator/full_global_illumination.py
index 69fa6e735bd..a03c6c8bd64 100644
--- a/release/scripts/presets/cycles/integrator/full_global_illumination.py
+++ b/release/scripts/presets/cycles/integrator/full_global_illumination.py
@@ -2,12 +2,10 @@ import bpy
cycles = bpy.context.scene.cycles
cycles.max_bounces = 128
-cycles.min_bounces = 3
cycles.caustics_reflective = True
cycles.caustics_refractive = True
cycles.diffuse_bounces = 128
cycles.glossy_bounces = 128
cycles.transmission_bounces = 128
cycles.volume_bounces = 128
-cycles.transparent_min_bounces = 8
cycles.transparent_max_bounces = 128
diff --git a/release/scripts/presets/cycles/integrator/limited_global_illumination.py b/release/scripts/presets/cycles/integrator/limited_global_illumination.py
index 22a8478d23b..d37bf46c705 100644
--- a/release/scripts/presets/cycles/integrator/limited_global_illumination.py
+++ b/release/scripts/presets/cycles/integrator/limited_global_illumination.py
@@ -2,12 +2,10 @@ import bpy
cycles = bpy.context.scene.cycles
cycles.max_bounces = 8
-cycles.min_bounces = 3
cycles.caustics_reflective = False
cycles.caustics_refractive = False
cycles.diffuse_bounces = 1
cycles.glossy_bounces = 4
cycles.transmission_bounces = 8
cycles.volume_bounces = 2
-cycles.transparent_min_bounces = 8
cycles.transparent_max_bounces = 8
diff --git a/release/scripts/presets/cycles/sampling/final.py b/release/scripts/presets/cycles/sampling/final.py
index d03423b6c2e..f1222d927c1 100644
--- a/release/scripts/presets/cycles/sampling/final.py
+++ b/release/scripts/presets/cycles/sampling/final.py
@@ -1,20 +1,18 @@
import bpy
cycles = bpy.context.scene.cycles
-cycles.use_square_samples = True
-
# Path Trace
-cycles.samples = 24
-cycles.preview_samples = 12
+cycles.samples = 512
+cycles.preview_samples = 128
# Branched Path Trace
-cycles.aa_samples = 8
-cycles.preview_aa_samples = 4
+cycles.aa_samples = 128
+cycles.preview_aa_samples = 32
-cycles.diffuse_samples = 3
-cycles.glossy_samples = 2
-cycles.transmission_samples = 2
+cycles.diffuse_samples = 4
+cycles.glossy_samples = 4
+cycles.transmission_samples = 4
cycles.ao_samples = 1
-cycles.mesh_light_samples = 2
-cycles.subsurface_samples = 2
-cycles.volume_samples = 2
+cycles.mesh_light_samples = 4
+cycles.subsurface_samples = 4
+cycles.volume_samples = 4
diff --git a/release/scripts/presets/cycles/sampling/preview.py b/release/scripts/presets/cycles/sampling/preview.py
index 5f071c7474d..c16449e2c8f 100644
--- a/release/scripts/presets/cycles/sampling/preview.py
+++ b/release/scripts/presets/cycles/sampling/preview.py
@@ -1,20 +1,18 @@
import bpy
cycles = bpy.context.scene.cycles
-cycles.use_square_samples = True
-
# Path Trace
-cycles.samples = 12
-cycles.preview_samples = 6
+cycles.samples = 128
+cycles.preview_samples = 32
# Branched Path Trace
-cycles.aa_samples = 4
-cycles.preview_aa_samples = 2
+cycles.aa_samples = 32
+cycles.preview_aa_samples = 4
-cycles.diffuse_samples = 3
-cycles.glossy_samples = 2
-cycles.transmission_samples = 2
+cycles.diffuse_samples = 4
+cycles.glossy_samples = 4
+cycles.transmission_samples = 4
cycles.ao_samples = 1
-cycles.mesh_light_samples = 2
-cycles.subsurface_samples = 2
-cycles.volume_samples = 2
+cycles.mesh_light_samples = 4
+cycles.subsurface_samples = 4
+cycles.volume_samples = 4
diff --git a/release/scripts/startup/bl_operators/clip.py b/release/scripts/startup/bl_operators/clip.py
index d0e55159733..ea68641f68b 100644
--- a/release/scripts/startup/bl_operators/clip.py
+++ b/release/scripts/startup/bl_operators/clip.py
@@ -210,7 +210,7 @@ class CLIP_OT_set_active_clip(bpy.types.Operator):
@classmethod
def poll(cls, context):
space = context.space_data
- return space.type == 'CLIP_EDITOR'
+ return space.type == 'CLIP_EDITOR' and space.clip
def execute(self, context):
clip = context.space_data.clip
@@ -254,6 +254,11 @@ class CLIP_OT_track_to_empty(Operator):
constraint.object = tracking_object.name
constraint.camera = CLIP_camera_for_clip(context, clip)
+ @classmethod
+ def poll(cls, context):
+ space = context.space_data
+ return space.type == 'CLIP_EDITOR' and space.clip
+
def execute(self, context):
sc = context.space_data
clip = sc.clip
diff --git a/release/scripts/startup/bl_ui/properties_material.py b/release/scripts/startup/bl_ui/properties_material.py
index e513fb1b7a2..29cb2466ee5 100644
--- a/release/scripts/startup/bl_ui/properties_material.py
+++ b/release/scripts/startup/bl_ui/properties_material.py
@@ -1183,6 +1183,8 @@ class EEVEE_MATERIAL_PT_options(MaterialButtonsPanel, Panel):
if mat.blend_method not in {"OPAQUE", "CLIP", "HASHED"}:
layout.prop(mat, "transparent_hide_backside")
+ layout.prop(mat, "use_screen_refraction")
+ layout.prop(mat, "refraction_depth")
classes = (
diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py
index 0b98d8738dc..73d3d5fc755 100644
--- a/release/scripts/startup/bl_ui/properties_physics_common.py
+++ b/release/scripts/startup/bl_ui/properties_physics_common.py
@@ -79,7 +79,7 @@ class PHYSICS_PT_add(PhysicButtonsPanel, Panel):
col = split.column()
- if obj.type in {'MESH', 'LATTICE', 'CURVE'}:
+ if obj.type in {'MESH', 'LATTICE', 'CURVE', 'SURFACE', 'FONT'}:
physics_add(self, col, context.soft_body, "Soft Body", 'SOFT_BODY', 'MOD_SOFT', True)
if obj.type == 'MESH':
diff --git a/release/scripts/startup/bl_ui/properties_physics_softbody.py b/release/scripts/startup/bl_ui/properties_physics_softbody.py
index 5ce4302891d..5efe105e7d8 100644
--- a/release/scripts/startup/bl_ui/properties_physics_softbody.py
+++ b/release/scripts/startup/bl_ui/properties_physics_softbody.py
@@ -26,6 +26,9 @@ from bl_ui.properties_physics_common import (
)
+COMPAT_OB_TYPES = {'MESH', 'LATTICE', 'CURVE', 'SURFACE', 'FONT'}
+
+
def softbody_panel_enabled(md):
return (md.point_cache.is_baked is False)
@@ -39,7 +42,7 @@ class PhysicButtonsPanel:
def poll(cls, context):
ob = context.object
rd = context.scene.render
- return (ob and (ob.type == 'MESH' or ob.type == 'LATTICE'or ob.type == 'CURVE')) and (rd.engine in cls.COMPAT_ENGINES) and (context.soft_body)
+ return ob and ob.type in COMPAT_OB_TYPES and rd.engine in cls.COMPAT_ENGINES and context.soft_body
class PHYSICS_PT_softbody(PhysicButtonsPanel, Panel):
diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py
index fdc98e4ad25..1c3ea6a5ee7 100644
--- a/release/scripts/startup/bl_ui/properties_render.py
+++ b/release/scripts/startup/bl_ui/properties_render.py
@@ -275,6 +275,7 @@ class RENDER_PT_performance(RenderButtonsPanel, Panel):
col.separator()
col.prop(rd, "preview_start_resolution")
+ col.prop(rd, "preview_pixel_size", text="")
col = split.column()
col.label(text="Memory:")
@@ -656,9 +657,12 @@ class RENDER_PT_eevee_postprocess_settings(RenderButtonsPanel, Panel):
col.label("Ambient Occlusion:")
col.prop(props, "gtao_use_bent_normals")
+ col.prop(props, "gtao_denoise")
+ col.prop(props, "gtao_bounce")
col.prop(props, "gtao_samples")
col.prop(props, "gtao_distance")
col.prop(props, "gtao_factor")
+ col.prop(props, "gtao_quality")
col.separator()
col.label("Motion Blur:")
@@ -675,7 +679,9 @@ class RENDER_PT_eevee_postprocess_settings(RenderButtonsPanel, Panel):
col.prop(props, "bloom_threshold")
col.prop(props, "bloom_knee")
col.prop(props, "bloom_radius")
+ col.prop(props, "bloom_color")
col.prop(props, "bloom_intensity")
+ col.prop(props, "bloom_clamp")
class RENDER_PT_eevee_volumetric(RenderButtonsPanel, Panel):
@@ -730,6 +736,7 @@ class RENDER_PT_eevee_screen_space_reflections(RenderButtonsPanel, Panel):
props = scene.layer_properties['BLENDER_EEVEE']
col = layout.column()
+ col.prop(props, "ssr_refraction")
col.prop(props, "ssr_halfres")
col.prop(props, "ssr_ray_count")
col.prop(props, "ssr_quality")
diff --git a/release/scripts/startup/bl_ui/properties_render_layer.py b/release/scripts/startup/bl_ui/properties_render_layer.py
index 168d1dcb242..e4315717157 100644
--- a/release/scripts/startup/bl_ui/properties_render_layer.py
+++ b/release/scripts/startup/bl_ui/properties_render_layer.py
@@ -192,9 +192,12 @@ class RENDERLAYER_PT_eevee_postprocess_settings(RenderLayerButtonsPanel, Panel):
col = layout.column()
col.label("Ambient Occlusion:")
col.template_override_property(layer_props, scene_props, "gtao_use_bent_normals")
+ col.template_override_property(layer_props, scene_props, "gtao_denoise")
+ col.template_override_property(layer_props, scene_props, "gtao_bounce")
col.template_override_property(layer_props, scene_props, "gtao_samples")
col.template_override_property(layer_props, scene_props, "gtao_distance")
col.template_override_property(layer_props, scene_props, "gtao_factor")
+ col.template_override_property(layer_props, scene_props, "gtao_quality")
col.separator()
col.label("Motion Blur:")
@@ -211,7 +214,9 @@ class RENDERLAYER_PT_eevee_postprocess_settings(RenderLayerButtonsPanel, Panel):
col.template_override_property(layer_props, scene_props, "bloom_threshold")
col.template_override_property(layer_props, scene_props, "bloom_knee")
col.template_override_property(layer_props, scene_props, "bloom_radius")
+ col.template_override_property(layer_props, scene_props, "bloom_color")
col.template_override_property(layer_props, scene_props, "bloom_intensity")
+ col.template_override_property(layer_props, scene_props, "bloom_clamp")
class RENDERLAYER_PT_eevee_volumetric(RenderLayerButtonsPanel, Panel):
@@ -276,6 +281,7 @@ class RENDERLAYER_PT_eevee_screen_space_reflections(RenderLayerButtonsPanel, Pan
col = layout.column()
col.template_override_property(layer_props, scene_props, "ssr_halfres")
+ col.template_override_property(layer_props, scene_props, "ssr_refraction")
col.template_override_property(layer_props, scene_props, "ssr_ray_count")
col.template_override_property(layer_props, scene_props, "ssr_quality")
col.template_override_property(layer_props, scene_props, "ssr_max_roughness")
diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py
index 79bb10cefeb..d155f5868f4 100644
--- a/release/scripts/startup/bl_ui/space_sequencer.py
+++ b/release/scripts/startup/bl_ui/space_sequencer.py
@@ -1101,9 +1101,6 @@ class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel):
render = context.scene.render
col = layout.column()
- col.prop(render, "use_sequencer_gl_preview", text="OpenGL Preview")
- col = layout.column()
- #col.active = render.use_sequencer_gl_preview
col.prop(render, "sequencer_gl_preview", text="")
row = col.row()
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 7a777194d83..8fecb042a1c 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -220,6 +220,7 @@ class USERPREF_PT_interface(Panel):
col = row.column()
col.label(text="Display:")
col.prop(view, "ui_scale", text="Scale")
+ col.prop(view, "ui_line_width", text="Line Width")
col.prop(view, "show_tooltips")
col.prop(view, "show_tooltips_python")
col.prop(view, "show_object_info", text="Object Info")
@@ -909,7 +910,7 @@ class USERPREF_PT_theme(Panel):
col.separator()
col.separator()
- col.label("Axis Colors:")
+ col.label("Axis & Manipulator Colors:")
row = col.row()
@@ -927,9 +928,13 @@ class USERPREF_PT_theme(Panel):
padding = subsplit.split(percentage=0.15)
colsub = padding.column()
colsub = padding.column()
+ colsub.row().prop(ui, "manipulator_primary")
+ colsub.row().prop(ui, "manipulator_secondary")
+ colsub.row().prop(ui, "manipulator_a")
+ colsub.row().prop(ui, "manipulator_b")
- layout.separator()
- layout.separator()
+ col.separator()
+ col.separator()
elif theme.theme_area == 'BONE_COLOR_SETS':
col = split.column()
diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py
index 6f226e8cf87..341efd78f5e 100644
--- a/release/scripts/startup/nodeitems_builtins.py
+++ b/release/scripts/startup/nodeitems_builtins.py
@@ -251,8 +251,7 @@ shader_node_categories = [
NodeItem("NodeGroupInput", poll=group_input_output_item_poll),
]),
ShaderNewNodeCategory("SH_NEW_OUTPUT", "Output", items=[
- NodeItem("ShaderNodeOutputMaterial", poll=object_cycles_shader_nodes_poll),
- NodeItem("ShaderNodeOutputEeveeMaterial", poll=object_eevee_shader_nodes_poll),
+ NodeItem("ShaderNodeOutputMaterial", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeOutputLamp", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeOutputWorld", poll=world_shader_nodes_poll),
NodeItem("ShaderNodeOutputLineStyle", poll=line_style_shader_nodes_poll),
@@ -264,9 +263,9 @@ shader_node_categories = [
NodeItem("ShaderNodeBsdfDiffuse", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfPrincipled", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfGlossy", poll=object_eevee_cycles_shader_nodes_poll),
- NodeItem("ShaderNodeBsdfTransparent", poll=object_cycles_shader_nodes_poll),
- NodeItem("ShaderNodeBsdfRefraction", poll=object_cycles_shader_nodes_poll),
- NodeItem("ShaderNodeBsdfGlass", poll=object_cycles_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfTransparent", poll=object_eevee_cycles_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfRefraction", poll=object_eevee_cycles_shader_nodes_poll),
+ NodeItem("ShaderNodeBsdfGlass", poll=object_eevee_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfTranslucent", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfAnisotropic", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeBsdfVelvet", poll=object_cycles_shader_nodes_poll),
@@ -279,7 +278,6 @@ shader_node_categories = [
NodeItem("ShaderNodeHoldout", poll=object_cycles_shader_nodes_poll),
NodeItem("ShaderNodeVolumeAbsorption", poll=volume_shader_nodes_poll),
NodeItem("ShaderNodeVolumeScatter", poll=volume_shader_nodes_poll),
- NodeItem("ShaderNodeEeveeMetallic", poll=object_eevee_shader_nodes_poll),
NodeItem("ShaderNodeEeveeSpecular", poll=object_eevee_shader_nodes_poll),
]),
ShaderNewNodeCategory("SH_NEW_TEXTURE", "Texture", items=[
diff --git a/release/windows/blendthumb/CMakeLists.txt b/release/windows/blendthumb/CMakeLists.txt
new file mode 100644
index 00000000000..1e5f5131a36
--- /dev/null
+++ b/release/windows/blendthumb/CMakeLists.txt
@@ -0,0 +1,42 @@
+# ***** 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 *****
+
+#-----------------------------------------------------------------------------
+cmake_minimum_required(VERSION 2.8)
+project(BlendThumb)
+
+#Bring the headers, such as Student.h into the project
+include_directories(${ZLIB_INCLUDE})
+
+#Can manually add the sources using the set command as follows:
+set(SOURCES src/BlenderThumb.cpp
+ src/BlendThumb.def
+ src/BlendThumb.rc
+ src/Dll.cpp
+)
+
+add_library(BlendThumb SHARED ${SOURCES})
+target_link_libraries(BlendThumb ${ZLIB_LIBS})
+install (TARGETS BlendThumb DESTINATION bin)
diff --git a/release/windows/blendthumb/src/BlendThumb.def b/release/windows/blendthumb/src/BlendThumb.def
new file mode 100644
index 00000000000..71f9236735f
--- /dev/null
+++ b/release/windows/blendthumb/src/BlendThumb.def
@@ -0,0 +1,5 @@
+EXPORTS
+ DllGetClassObject PRIVATE
+ DllCanUnloadNow PRIVATE
+ DllRegisterServer PRIVATE
+ DllUnregisterServer PRIVATE \ No newline at end of file
diff --git a/release/windows/blendthumb/src/BlendThumb.rc b/release/windows/blendthumb/src/BlendThumb.rc
new file mode 100644
index 00000000000..5dfd416b0c5
--- /dev/null
+++ b/release/windows/blendthumb/src/BlendThumb.rc
@@ -0,0 +1,26 @@
+#define IDR_VERSION1 1
+
+IDR_VERSION1 VERSIONINFO
+FILEVERSION 1,4,0,0
+PRODUCTVERSION 2,78,0,0
+FILEOS 0x00000004
+FILETYPE 0x00000002
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "FFFF04B0"
+ BEGIN
+ VALUE "FileVersion", "1.4\0"
+ VALUE "ProductVersion", "2.78\0"
+ VALUE "FileDescription", "Blender Thumbnail Handler\0"
+ VALUE "OriginalFilename", "BlendThumb.dll\0"
+ VALUE "ProductName", "Blender\0"
+ VALUE "LegalCopyright", "GPL2, 2016\0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x0409, 0x04B0
+ END
+END
+
diff --git a/release/windows/blendthumb/src/BlenderThumb.cpp b/release/windows/blendthumb/src/BlenderThumb.cpp
new file mode 100644
index 00000000000..508b9f74852
--- /dev/null
+++ b/release/windows/blendthumb/src/BlenderThumb.cpp
@@ -0,0 +1,324 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <shlwapi.h>
+#include <thumbcache.h> // For IThumbnailProvider.
+#include <new>
+
+#pragma comment(lib, "shlwapi.lib")
+
+// this thumbnail provider implements IInitializeWithStream to enable being hosted
+// in an isolated process for robustness
+
+class CBlendThumb : public IInitializeWithStream, public IThumbnailProvider
+{
+public:
+ CBlendThumb() : _cRef(1), _pStream(NULL) {}
+
+ virtual ~CBlendThumb()
+ {
+ if (_pStream)
+ {
+ _pStream->Release();
+ }
+ }
+
+ // IUnknown
+ IFACEMETHODIMP QueryInterface(REFIID riid, void **ppv)
+ {
+ static const QITAB qit[] =
+ {
+ QITABENT(CBlendThumb, IInitializeWithStream),
+ QITABENT(CBlendThumb, IThumbnailProvider),
+ { 0 },
+ };
+ return QISearch(this, qit, riid, ppv);
+ }
+
+ IFACEMETHODIMP_(ULONG) AddRef()
+ {
+ return InterlockedIncrement(&_cRef);
+ }
+
+ IFACEMETHODIMP_(ULONG) Release()
+ {
+ ULONG cRef = InterlockedDecrement(&_cRef);
+ if (!cRef)
+ {
+ delete this;
+ }
+ return cRef;
+ }
+
+ // IInitializeWithStream
+ IFACEMETHODIMP Initialize(IStream *pStream, DWORD grfMode);
+
+ // IThumbnailProvider
+ IFACEMETHODIMP GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha);
+
+private:
+ long _cRef;
+ IStream *_pStream; // provided during initialization.
+};
+
+HRESULT CBlendThumb_CreateInstance(REFIID riid, void **ppv)
+{
+ CBlendThumb *pNew = new (std::nothrow) CBlendThumb();
+ HRESULT hr = pNew ? S_OK : E_OUTOFMEMORY;
+ if (SUCCEEDED(hr))
+ {
+ hr = pNew->QueryInterface(riid, ppv);
+ pNew->Release();
+ }
+ return hr;
+}
+
+// IInitializeWithStream
+IFACEMETHODIMP CBlendThumb::Initialize(IStream *pStream, DWORD)
+{
+ HRESULT hr = E_UNEXPECTED; // can only be inited once
+ if (_pStream == NULL)
+ {
+ // take a reference to the stream if we have not been inited yet
+ hr = pStream->QueryInterface(&_pStream);
+ }
+ return hr;
+}
+
+#include <math.h>
+#include <zlib.h>
+#include "Wincodec.h"
+const unsigned char gzip_magic[3] = { 0x1f, 0x8b, 0x08 };
+
+// IThumbnailProvider
+IFACEMETHODIMP CBlendThumb::GetThumbnail(UINT cx, HBITMAP *phbmp, WTS_ALPHATYPE *pdwAlpha)
+{
+ ULONG BytesRead;
+ HRESULT hr = S_FALSE;
+ LARGE_INTEGER SeekPos;
+
+ // Compressed?
+ unsigned char in_magic[3];
+ _pStream->Read(&in_magic,3,&BytesRead);
+ bool gzipped = true;
+ for ( int i=0; i < 3; i++ )
+ if ( in_magic[i] != gzip_magic[i] )
+ {
+ gzipped = false;
+ break;
+ }
+
+ if (gzipped)
+ {
+ // Zlib inflate
+ z_stream stream;
+ stream.zalloc = Z_NULL;
+ stream.zfree = Z_NULL;
+ stream.opaque = Z_NULL;
+
+ // Get compressed file length
+ SeekPos.QuadPart = 0;
+ _pStream->Seek(SeekPos,STREAM_SEEK_END,NULL);
+
+ // Get compressed and uncompressed size
+ uLong source_size;
+ uLongf dest_size;
+ //SeekPos.QuadPart = -4; // last 4 bytes define size of uncompressed file
+ //ULARGE_INTEGER Tell;
+ //_pStream->Seek(SeekPos,STREAM_SEEK_END,&Tell);
+ //source_size = (uLong)Tell.QuadPart + 4; // src
+ //_pStream->Read(&dest_size,4,&BytesRead); // dest
+ dest_size = 1024*70; // thumbnail is currently always inside the first 65KB...if it moves or enlargens this line will have to change or go!
+ source_size = (uLong)max(SeekPos.QuadPart,dest_size); // for safety, assume no compression
+
+ // Input
+ Bytef* src = new Bytef[source_size];
+ stream.next_in = (Bytef*)src;
+ stream.avail_in = (uInt)source_size;
+
+ // Output
+ Bytef* dest = new Bytef[dest_size];
+ stream.next_out = (Bytef*)dest;
+ stream.avail_out = dest_size;
+
+ // IStream to src
+ SeekPos.QuadPart = 0;
+ _pStream->Seek(SeekPos,STREAM_SEEK_SET,NULL);
+ _pStream->Read(src,source_size,&BytesRead);
+
+ // Do the inflation
+ int err;
+ err = inflateInit2(&stream,16); // 16 means "gzip"...nice!
+ err = inflate(&stream, Z_FINISH);
+ err = inflateEnd(&stream);
+
+ // Replace the IStream, which is read-only
+ _pStream->Release();
+ _pStream = SHCreateMemStream(dest,dest_size);
+
+ delete[] src;
+ delete[] dest;
+ }
+
+ // Blender version, early out if sub 2.5
+ SeekPos.QuadPart = 9;
+ _pStream->Seek(SeekPos,STREAM_SEEK_SET,NULL);
+ char version[4];
+ version[3] = '\0';
+ _pStream->Read(&version,3,&BytesRead);
+ if ( BytesRead != 3)
+ return E_UNEXPECTED;
+ int iVersion = atoi(version);
+ if ( iVersion < 250 )
+ return S_FALSE;
+
+ // 32 or 64 bit blend?
+ SeekPos.QuadPart = 7;
+ _pStream->Seek(SeekPos,STREAM_SEEK_SET,NULL);
+
+ char _PointerSize;
+ _pStream->Read(&_PointerSize,1,&BytesRead);
+
+ int PointerSize = _PointerSize == '_' ? 4 : 8;
+ int HeaderSize = 16 + PointerSize;
+
+ // Find and read thumbnail ("TEST") block
+ SeekPos.QuadPart = 12;
+ _pStream->Seek(SeekPos,STREAM_SEEK_SET,NULL);
+ int BlockOffset = 12;
+ while ( _pStream )
+ {
+ // Scan current block
+ char BlockName[5];
+ BlockName[4] = '\0';
+ int BlockSize = 0;
+
+ if (_pStream->Read(BlockName,4,&BytesRead) == S_OK && _pStream->Read((void*)&BlockSize,4,&BytesRead) == S_OK)
+ {
+ if ( strcmp (BlockName,"TEST") != 0 )
+ {
+ SeekPos.QuadPart = BlockOffset += HeaderSize + BlockSize;
+ _pStream->Seek(SeekPos,STREAM_SEEK_SET,NULL);
+ continue;
+ }
+ }
+ else break; // eof
+
+ // Found the block
+ SeekPos.QuadPart = BlockOffset + HeaderSize;
+ _pStream->Seek(SeekPos,STREAM_SEEK_SET,NULL);
+
+ int width, height;
+ _pStream->Read((char*)&width,4,&BytesRead);
+ _pStream->Read((char*)&height,4,&BytesRead);
+ BlockSize -= 8;
+
+ // Isolate RGBA data
+ char* pRGBA = new char[BlockSize];
+ _pStream->Read(pRGBA,BlockSize,&BytesRead);
+
+ if (BytesRead != (ULONG)BlockSize)
+ return E_UNEXPECTED;
+
+ // Convert to BGRA for Windows
+ for (int i=0; i < BlockSize; i+=4 )
+ {
+ #define RED_BYTE pRGBA[i]
+ #define BLUE_BYTE pRGBA[i+2]
+
+ char red = RED_BYTE;
+ RED_BYTE = BLUE_BYTE;
+ BLUE_BYTE = red;
+ }
+
+ // Flip vertically (Blender stores it upside-down)
+ unsigned int LineSize = width*4;
+ char* FlippedImage = new char[BlockSize];
+ for (int i=0; i<height; i++)
+ {
+ if ( 0 != memcpy_s(&FlippedImage[ (height - i - 1)*LineSize ],LineSize,&pRGBA[ i*LineSize ],LineSize))
+ return E_UNEXPECTED;
+ }
+ delete[] pRGBA;
+ pRGBA = FlippedImage;
+
+ // Create image
+ *phbmp = CreateBitmap(width,height,1,32,pRGBA);
+ if (!*phbmp)
+ return E_FAIL;
+ *pdwAlpha = WTSAT_ARGB; // it's actually BGRA, not sure why this works
+
+ // Scale down if required
+ if ( (unsigned)width > cx || (unsigned)height > cx )
+ {
+ float scale = 1.0f / (max(width,height) / (float)cx);
+ LONG NewWidth = (LONG)(width *scale);
+ LONG NewHeight = (LONG)(height *scale);
+
+#ifdef _DEBUG
+#if 1
+ MessageBox(0,L"Attach now",L"Debugging",MB_OK);
+#endif
+#endif
+ IWICImagingFactory *pImgFac;
+ hr = CoCreateInstance(CLSID_WICImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pImgFac));
+
+ IWICBitmap* WICBmp;
+ hr = pImgFac->CreateBitmapFromHBITMAP(*phbmp,0,WICBitmapUseAlpha,&WICBmp);
+
+ BITMAPINFO bmi = {};
+ bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
+ bmi.bmiHeader.biWidth = NewWidth;
+ bmi.bmiHeader.biHeight = -NewHeight;
+ bmi.bmiHeader.biPlanes = 1;
+ bmi.bmiHeader.biBitCount = 32;
+ bmi.bmiHeader.biCompression = BI_RGB;
+
+ BYTE *pBits;
+ HBITMAP ResizedHBmp = CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, (void**)&pBits, NULL, 0);
+ hr = ResizedHBmp ? S_OK : E_OUTOFMEMORY;
+ if (SUCCEEDED(hr))
+ {
+ IWICBitmapScaler* pIScaler;
+ hr = pImgFac->CreateBitmapScaler(&pIScaler);
+ hr = pIScaler->Initialize(WICBmp,NewWidth,NewHeight,WICBitmapInterpolationModeFant);
+
+ WICRect rect = {0, 0, NewWidth, NewHeight};
+ hr = pIScaler->CopyPixels(&rect, NewWidth * 4, NewWidth * NewHeight * 4, pBits);
+
+ if (SUCCEEDED(hr))
+ {
+ DeleteObject(*phbmp);
+ *phbmp = ResizedHBmp;
+ }
+ else
+ DeleteObject(ResizedHBmp);
+
+ pIScaler->Release();
+ }
+ WICBmp->Release();
+ pImgFac->Release();
+ }
+ else
+ hr = S_OK;
+ break;
+ }
+ return hr;
+}
diff --git a/release/windows/blendthumb/src/Dll.cpp b/release/windows/blendthumb/src/Dll.cpp
new file mode 100644
index 00000000000..09ccd34ff8e
--- /dev/null
+++ b/release/windows/blendthumb/src/Dll.cpp
@@ -0,0 +1,277 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <objbase.h>
+#include <shlwapi.h>
+#include <thumbcache.h> // For IThumbnailProvider.
+#include <shlobj.h> // For SHChangeNotify
+#include <new>
+
+extern HRESULT CBlendThumb_CreateInstance(REFIID riid, void **ppv);
+
+#define SZ_CLSID_BLENDTHUMBHANDLER L"{D45F043D-F17F-4e8a-8435-70971D9FA46D}"
+#define SZ_BLENDTHUMBHANDLER L"Blender Thumbnail Handler"
+const CLSID CLSID_BlendThumbHandler = { 0xd45f043d, 0xf17f, 0x4e8a, { 0x84, 0x35, 0x70, 0x97, 0x1d, 0x9f, 0xa4, 0x6d } };
+
+typedef HRESULT (*PFNCREATEINSTANCE)(REFIID riid, void **ppvObject);
+struct CLASS_OBJECT_INIT
+{
+ const CLSID *pClsid;
+ PFNCREATEINSTANCE pfnCreate;
+};
+
+// add classes supported by this module here
+const CLASS_OBJECT_INIT c_rgClassObjectInit[] =
+{
+ { &CLSID_BlendThumbHandler, CBlendThumb_CreateInstance }
+};
+
+
+long g_cRefModule = 0;
+
+// Handle the the DLL's module
+HINSTANCE g_hInst = NULL;
+
+// Standard DLL functions
+STDAPI_(BOOL) DllMain(HINSTANCE hInstance, DWORD dwReason, void *)
+{
+ if (dwReason == DLL_PROCESS_ATTACH)
+ {
+ g_hInst = hInstance;
+ DisableThreadLibraryCalls(hInstance);
+ }
+ return TRUE;
+}
+
+STDAPI DllCanUnloadNow()
+{
+ // Only allow the DLL to be unloaded after all outstanding references have been released
+ return (g_cRefModule == 0) ? S_OK : S_FALSE;
+}
+
+void DllAddRef()
+{
+ InterlockedIncrement(&g_cRefModule);
+}
+
+void DllRelease()
+{
+ InterlockedDecrement(&g_cRefModule);
+}
+
+class CClassFactory : public IClassFactory
+{
+public:
+ static HRESULT CreateInstance(REFCLSID clsid, const CLASS_OBJECT_INIT *pClassObjectInits, size_t cClassObjectInits, REFIID riid, void **ppv)
+ {
+ *ppv = NULL;
+ HRESULT hr = CLASS_E_CLASSNOTAVAILABLE;
+ for (size_t i = 0; i < cClassObjectInits; i++)
+ {
+ if (clsid == *pClassObjectInits[i].pClsid)
+ {
+ IClassFactory *pClassFactory = new (std::nothrow) CClassFactory(pClassObjectInits[i].pfnCreate);
+ hr = pClassFactory ? S_OK : E_OUTOFMEMORY;
+ if (SUCCEEDED(hr))
+ {
+ hr = pClassFactory->QueryInterface(riid, ppv);
+ pClassFactory->Release();
+ }
+ break; // match found
+ }
+ }
+ return hr;
+ }
+
+ CClassFactory(PFNCREATEINSTANCE pfnCreate) : _cRef(1), _pfnCreate(pfnCreate)
+ {
+ DllAddRef();
+ }
+
+ // IUnknown
+ IFACEMETHODIMP QueryInterface(REFIID riid, void ** ppv)
+ {
+ static const QITAB qit[] =
+ {
+ QITABENT(CClassFactory, IClassFactory),
+ { 0 }
+ };
+ return QISearch(this, qit, riid, ppv);
+ }
+
+ IFACEMETHODIMP_(ULONG) AddRef()
+ {
+ return InterlockedIncrement(&_cRef);
+ }
+
+ IFACEMETHODIMP_(ULONG) Release()
+ {
+ long cRef = InterlockedDecrement(&_cRef);
+ if (cRef == 0)
+ {
+ delete this;
+ }
+ return cRef;
+ }
+
+ // IClassFactory
+ IFACEMETHODIMP CreateInstance(IUnknown *punkOuter, REFIID riid, void **ppv)
+ {
+ return punkOuter ? CLASS_E_NOAGGREGATION : _pfnCreate(riid, ppv);
+ }
+
+ IFACEMETHODIMP LockServer(BOOL fLock)
+ {
+ if (fLock)
+ {
+ DllAddRef();
+ }
+ else
+ {
+ DllRelease();
+ }
+ return S_OK;
+ }
+
+private:
+ ~CClassFactory()
+ {
+ DllRelease();
+ }
+
+ long _cRef;
+ PFNCREATEINSTANCE _pfnCreate;
+};
+
+STDAPI DllGetClassObject(REFCLSID clsid, REFIID riid, void **ppv)
+{
+ return CClassFactory::CreateInstance(clsid, c_rgClassObjectInit, ARRAYSIZE(c_rgClassObjectInit), riid, ppv);
+}
+
+// A struct to hold the information required for a registry entry
+
+struct REGISTRY_ENTRY
+{
+ HKEY hkeyRoot;
+ PCWSTR pszKeyName;
+ PCWSTR pszValueName;
+ DWORD dwValueType;
+ PCWSTR pszData;
+};
+
+// Creates a registry key (if needed) and sets the default value of the key
+
+HRESULT CreateRegKeyAndSetValue(const REGISTRY_ENTRY *pRegistryEntry)
+{
+ HKEY hKey;
+ HRESULT hr = HRESULT_FROM_WIN32(RegCreateKeyExW(pRegistryEntry->hkeyRoot, pRegistryEntry->pszKeyName,
+ 0, NULL, REG_OPTION_NON_VOLATILE, KEY_SET_VALUE, NULL, &hKey, NULL));
+ if (SUCCEEDED(hr))
+ {
+ // All this just to support REG_DWORD...
+ DWORD size;
+ DWORD data;
+ BYTE* lpData = (LPBYTE) pRegistryEntry->pszData;
+ switch (pRegistryEntry->dwValueType)
+ {
+ case REG_SZ:
+ size = ((DWORD) wcslen(pRegistryEntry->pszData) + 1) * sizeof(WCHAR);
+ break;
+ case REG_DWORD:
+ size = sizeof(DWORD);
+ data = (DWORD)pRegistryEntry->pszData;
+ lpData = (BYTE*)&data;
+ break;
+ default:
+ return E_INVALIDARG;
+ }
+
+ hr = HRESULT_FROM_WIN32(RegSetValueExW(hKey, pRegistryEntry->pszValueName, 0, pRegistryEntry->dwValueType,
+ lpData, size ));
+ RegCloseKey(hKey);
+ }
+ return hr;
+}
+
+//
+// Registers this COM server
+//
+STDAPI DllRegisterServer()
+{
+ HRESULT hr;
+
+ WCHAR szModuleName[MAX_PATH];
+
+ if (!GetModuleFileNameW(g_hInst, szModuleName, ARRAYSIZE(szModuleName)))
+ {
+ hr = HRESULT_FROM_WIN32(GetLastError());
+ }
+ else
+ {
+ const REGISTRY_ENTRY rgRegistryEntries[] =
+ {
+ // RootKey KeyName ValueName ValueType Data
+ {HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_BLENDTHUMBHANDLER, NULL, REG_SZ, SZ_BLENDTHUMBHANDLER},
+ {HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_BLENDTHUMBHANDLER L"\\InProcServer32", NULL, REG_SZ, szModuleName},
+ {HKEY_CURRENT_USER, L"Software\\Classes\\CLSID\\" SZ_CLSID_BLENDTHUMBHANDLER L"\\InProcServer32", L"ThreadingModel", REG_SZ, L"Apartment"},
+ {HKEY_CURRENT_USER, L"Software\\Classes\\.blend\\", L"Treatment", REG_DWORD, 0}, // doesn't appear to do anything...
+ {HKEY_CURRENT_USER, L"Software\\Classes\\.blend\\ShellEx\\{e357fccd-a995-4576-b01f-234630154e96}", NULL, REG_SZ, SZ_CLSID_BLENDTHUMBHANDLER},
+ };
+
+ hr = S_OK;
+ for (int i = 0; i < ARRAYSIZE(rgRegistryEntries) && SUCCEEDED(hr); i++)
+ {
+ hr = CreateRegKeyAndSetValue(&rgRegistryEntries[i]);
+ }
+ }
+ if (SUCCEEDED(hr))
+ {
+ // This tells the shell to invalidate the thumbnail cache. This is important because any .blend files
+ // viewed before registering this handler would otherwise show cached blank thumbnails.
+ SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, NULL, NULL);
+ }
+ return hr;
+}
+
+//
+// Unregisters this COM server
+//
+STDAPI DllUnregisterServer()
+{
+ HRESULT hr = S_OK;
+
+ const PCWSTR rgpszKeys[] =
+ {
+ L"Software\\Classes\\CLSID\\" SZ_CLSID_BLENDTHUMBHANDLER,
+ L"Software\\Classes\\.blend\\ShellEx\\{e357fccd-a995-4576-b01f-234630154e96}"
+ };
+
+ // Delete the registry entries
+ for (int i = 0; i < ARRAYSIZE(rgpszKeys) && SUCCEEDED(hr); i++)
+ {
+ hr = HRESULT_FROM_WIN32(RegDeleteTreeW(HKEY_CURRENT_USER, rgpszKeys[i]));
+ if (hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND))
+ {
+ // If the registry entry has already been deleted, say S_OK.
+ hr = S_OK;
+ }
+ }
+ return hr;
+}
diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc
index 1d2bc689027..d6e7a80d174 100644
--- a/source/blender/alembic/intern/abc_customdata.cc
+++ b/source/blender/alembic/intern/abc_customdata.cc
@@ -252,7 +252,31 @@ static void read_uvs(const CDStreamConfig &config, void *data,
}
}
-static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams,
+static size_t mcols_out_of_bounds_check(
+ const size_t color_index,
+ const size_t array_size,
+ const std::string & iobject_full_name,
+ const PropertyHeader &prop_header,
+ bool &r_bounds_warning_given)
+{
+ if (color_index < array_size) {
+ return color_index;
+ }
+
+ if (!r_bounds_warning_given) {
+ std::cerr << "Alembic: color index out of bounds "
+ "reading face colors for object "
+ << iobject_full_name
+ << ", property "
+ << prop_header.getName() << std::endl;
+ r_bounds_warning_given = true;
+ }
+
+ return 0;
+}
+
+static void read_custom_data_mcols(const std::string & iobject_full_name,
+ const ICompoundProperty &arbGeomParams,
const PropertyHeader &prop_header,
const CDStreamConfig &config,
const Alembic::Abc::ISampleSelector &iss)
@@ -303,6 +327,8 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams,
size_t face_index = 0;
size_t color_index;
+ bool bounds_warning_given = false;
+
for (int i = 0; i < config.totpoly; ++i) {
MPoly *poly = &mpolys[i];
MCol *cface = &cfaces[poly->loopstart + poly->totloop];
@@ -311,9 +337,14 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams,
for (int j = 0; j < poly->totloop; ++j, ++face_index) {
--cface;
--mloop;
- color_index = is_facevarying ? face_index : mloop->v;
if (use_c3f_ptr) {
+ color_index = mcols_out_of_bounds_check(
+ is_facevarying ? face_index : mloop->v,
+ c3f_ptr->size(),
+ iobject_full_name, prop_header,
+ bounds_warning_given);
+
const Imath::C3f &color = (*c3f_ptr)[color_index];
cface->a = FTOCHAR(color[0]);
cface->r = FTOCHAR(color[1]);
@@ -321,6 +352,12 @@ static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams,
cface->b = 255;
}
else {
+ color_index = mcols_out_of_bounds_check(
+ is_facevarying ? face_index : mloop->v,
+ c4f_ptr->size(),
+ iobject_full_name, prop_header,
+ bounds_warning_given);
+
const Imath::C4f &color = (*c4f_ptr)[color_index];
cface->a = FTOCHAR(color[0]);
cface->r = FTOCHAR(color[1]);
@@ -356,7 +393,10 @@ static void read_custom_data_uvs(const ICompoundProperty &prop,
read_uvs(config, cd_data, sample.getVals(), sample.getIndices());
}
-void read_custom_data(const ICompoundProperty &prop, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss)
+void read_custom_data(const std::string & iobject_full_name,
+ const ICompoundProperty &prop,
+ const CDStreamConfig &config,
+ const Alembic::Abc::ISampleSelector &iss)
{
if (!prop.valid()) {
return;
@@ -386,7 +426,7 @@ void read_custom_data(const ICompoundProperty &prop, const CDStreamConfig &confi
continue;
}
- read_custom_data_mcols(prop, prop_header, config, iss);
+ read_custom_data_mcols(iobject_full_name, prop, prop_header, config, iss);
continue;
}
}
diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h
index 9e671fde386..b3072a2c9f7 100644
--- a/source/blender/alembic/intern/abc_customdata.h
+++ b/source/blender/alembic/intern/abc_customdata.h
@@ -96,7 +96,8 @@ void write_custom_data(const OCompoundProperty &prop,
CustomData *data,
int data_type);
-void read_custom_data(const ICompoundProperty &prop,
+void read_custom_data(const std::string & iobject_full_name,
+ const ICompoundProperty &prop,
const CDStreamConfig &config,
const Alembic::Abc::ISampleSelector &iss);
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 25cf5f49b14..de0ed421eb7 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -681,17 +681,17 @@ static void assign_materials(Main *bmain, Object *ob, const std::map<std::string
std::string mat_name = it->first;
mat_iter = mat_map.find(mat_name.c_str());
- Material *assigned_name;
+ Material *assigned_mat;
if (mat_iter == mat_map.end()) {
- assigned_name = BKE_material_add(bmain, mat_name.c_str());
- mat_map[mat_name] = assigned_name;
+ assigned_mat = BKE_material_add(bmain, mat_name.c_str());
+ mat_map[mat_name] = assigned_mat;
}
else {
- assigned_name = mat_iter->second;
+ assigned_mat = mat_iter->second;
}
- assign_material(ob, assigned_name, it->second, BKE_MAT_ASSIGN_OBDATA);
+ assign_material(ob, assigned_mat, it->second, BKE_MAT_ASSIGN_OBDATA);
}
}
}
@@ -937,7 +937,8 @@ static void get_weight_and_index(CDStreamConfig &config,
config.ceil_index = i1;
}
-static void read_mesh_sample(ImportSettings *settings,
+static void read_mesh_sample(const std::string & iobject_full_name,
+ ImportSettings *settings,
const IPolyMeshSchema &schema,
const ISampleSelector &selector,
CDStreamConfig &config,
@@ -975,10 +976,9 @@ static void read_mesh_sample(ImportSettings *settings,
}
if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
- read_custom_data(schema.getArbGeomParams(), config, selector);
+ read_custom_data(iobject_full_name,
+ schema.getArbGeomParams(), config, selector);
}
-
- /* TODO: face sets */
}
CDStreamConfig get_config(DerivedMesh *dm)
@@ -1106,7 +1106,8 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm,
config.time = sample_sel.getRequestedTime();
bool do_normals = false;
- read_mesh_sample(&settings, m_schema, sample_sel, config, do_normals);
+ read_mesh_sample(m_iobject.getFullName(),
+ &settings, m_schema, sample_sel, config, do_normals);
if (new_dm) {
/* Check if we had ME_SMOOTH flag set to restore it. */
@@ -1117,6 +1118,16 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm,
CDDM_calc_normals(new_dm);
CDDM_calc_edges(new_dm);
+ /* Here we assume that the number of materials doesn't change, i.e. that
+ * the material slots that were created when the object was loaded from
+ * Alembic are still valid now. */
+ size_t num_polys = new_dm->getNumPolys(new_dm);
+ if (num_polys > 0) {
+ MPoly *dmpolies = new_dm->getPolyArray(new_dm);
+ std::map<std::string, int> mat_map;
+ assign_facesets_to_mpoly(sample_sel, 0, dmpolies, num_polys, mat_map);
+ }
+
return new_dm;
}
@@ -1127,8 +1138,11 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm,
return dm;
}
-void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
- const ISampleSelector &sample_sel)
+void AbcMeshReader::assign_facesets_to_mpoly(
+ const ISampleSelector &sample_sel,
+ size_t poly_start,
+ MPoly *mpoly, int totpoly,
+ std::map<std::string, int> & r_mat_map)
{
std::vector<std::string> face_sets;
m_schema.getFaceSetNames(face_sets);
@@ -1137,21 +1151,21 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star
return;
}
- std::map<std::string, int> mat_map;
int current_mat = 0;
for (int i = 0; i < face_sets.size(); ++i) {
const std::string &grp_name = face_sets[i];
- if (mat_map.find(grp_name) == mat_map.end()) {
- mat_map[grp_name] = 1 + current_mat++;
+ if (r_mat_map.find(grp_name) == r_mat_map.end()) {
+ r_mat_map[grp_name] = 1 + current_mat++;
}
- const int assigned_mat = mat_map[grp_name];
+ const int assigned_mat = r_mat_map[grp_name];
const IFaceSet faceset = m_schema.getFaceSet(grp_name);
if (!faceset.valid()) {
+ std::cerr << " Face set " << grp_name << " invalid for " << m_object_name << "\n";
continue;
}
@@ -1163,16 +1177,25 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star
for (size_t l = 0; l < num_group_faces; l++) {
size_t pos = (*group_faces)[l] + poly_start;
- if (pos >= mesh->totpoly) {
+ if (pos >= totpoly) {
std::cerr << "Faceset overflow on " << faceset.getName() << '\n';
break;
}
- MPoly &poly = mesh->mpoly[pos];
+ MPoly &poly = mpoly[pos];
poly.mat_nr = assigned_mat - 1;
}
}
+}
+
+void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
+ const ISampleSelector &sample_sel)
+{
+ std::map<std::string, int> mat_map;
+ assign_facesets_to_mpoly(sample_sel,
+ poly_start, mesh->mpoly, mesh->totpoly,
+ mat_map);
utils::assign_materials(bmain, m_object, mat_map);
}
@@ -1191,7 +1214,8 @@ ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2)
return NULL;
}
-static void read_subd_sample(ImportSettings *settings,
+static void read_subd_sample(const std::string & iobject_full_name,
+ ImportSettings *settings,
const ISubDSchema &schema,
const ISampleSelector &selector,
CDStreamConfig &config)
@@ -1226,10 +1250,9 @@ static void read_subd_sample(ImportSettings *settings,
}
if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
- read_custom_data(schema.getArbGeomParams(), config, selector);
+ read_custom_data(iobject_full_name,
+ schema.getArbGeomParams(), config, selector);
}
-
- /* TODO: face sets */
}
/* ************************************************************************** */
@@ -1358,7 +1381,8 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm,
/* Only read point data when streaming meshes, unless we need to create new ones. */
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
config.time = sample_sel.getRequestedTime();
- read_subd_sample(&settings, m_schema, sample_sel, config);
+ read_subd_sample(m_iobject.getFullName(),
+ &settings, m_schema, sample_sel, config);
if (new_dm) {
/* Check if we had ME_SMOOTH flag set to restore it. */
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index 941407d2208..e0b2365e134 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -113,6 +113,11 @@ public:
private:
void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
const Alembic::AbcGeom::ISampleSelector &sample_sel);
+
+ void assign_facesets_to_mpoly(const Alembic::Abc::ISampleSelector &sample_sel,
+ size_t poly_start,
+ MPoly *mpoly, int totpoly,
+ std::map<std::string, int> & r_mat_map);
};
/* ************************************************************************** */
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 63b5dc68875..c86595cd509 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -219,7 +219,7 @@ struct DerivedMesh {
/** Recalculates mesh tessellation */
void (*recalcTessellation)(DerivedMesh *dm);
- /** Loop tessellation cache */
+ /** Loop tessellation cache (WARNING! Only call inside threading-protected code!) */
void (*recalcLoopTri)(DerivedMesh *dm);
/** accessor functions */
const struct MLoopTri *(*getLoopTriArray)(DerivedMesh * dm);
@@ -605,7 +605,6 @@ void DM_ensure_normals(DerivedMesh *dm);
void DM_ensure_tessface(DerivedMesh *dm);
void DM_ensure_looptri_data(DerivedMesh *dm);
-void DM_ensure_looptri(DerivedMesh *dm);
void DM_verttri_from_looptri(MVertTri *verttri, const MLoop *mloop, const MLoopTri *looptri, int looptri_num);
void DM_update_tessface_data(DerivedMesh *dm);
@@ -659,18 +658,18 @@ void mesh_get_mapped_verts_coords(DerivedMesh *dm, float (*r_cos)[3], const int
/* */
DerivedMesh *mesh_get_derived_final(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob, CustomDataMask dataMask);
DerivedMesh *mesh_get_derived_deform(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob, CustomDataMask dataMask);
DerivedMesh *mesh_create_derived_for_modifier(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
struct ModifierData *md, int build_shapekey_layers);
DerivedMesh *mesh_create_derived_render(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob, CustomDataMask dataMask);
DerivedMesh *getEditDerivedBMesh(
@@ -678,37 +677,37 @@ DerivedMesh *getEditDerivedBMesh(
float (*vertexCos)[3]);
DerivedMesh *mesh_create_derived_index_render(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob, CustomDataMask dataMask, int index);
/* same as above but wont use render settings */
DerivedMesh *mesh_create_derived(struct Mesh *me, float (*vertCos)[3]);
DerivedMesh *mesh_create_derived_view(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob, CustomDataMask dataMask);
DerivedMesh *mesh_create_derived_no_deform(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob, float (*vertCos)[3],
CustomDataMask dataMask);
DerivedMesh *mesh_create_derived_no_deform_render(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob, float (*vertCos)[3],
CustomDataMask dataMask);
/* for gameengine */
DerivedMesh *mesh_create_derived_no_virtual(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
float (*vertCos)[3], CustomDataMask dataMask);
DerivedMesh *mesh_create_derived_physics(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
float (*vertCos)[3], CustomDataMask dataMask);
DerivedMesh *editbmesh_get_derived_base(
struct Object *ob, struct BMEditMesh *em, CustomDataMask data_mask);
DerivedMesh *editbmesh_get_derived_cage(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *,
struct BMEditMesh *em, CustomDataMask dataMask);
DerivedMesh *editbmesh_get_derived_cage_and_final(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *,
struct BMEditMesh *em, CustomDataMask dataMask,
DerivedMesh **r_final);
@@ -717,7 +716,7 @@ DerivedMesh *object_get_derived_final(struct Object *ob, const bool for_render);
float (*editbmesh_get_vertex_cos(struct BMEditMesh *em, int *r_numVerts))[3];
bool editbmesh_modifier_is_enabled(struct Scene *scene, struct ModifierData *md, DerivedMesh *dm);
void makeDerivedMesh(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct BMEditMesh *em,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct BMEditMesh *em,
CustomDataMask dataMask, const bool build_shapekey_layers);
void weight_to_rgb(float r_rgb[3], const float weight);
@@ -808,11 +807,5 @@ struct MEdge *DM_get_edge_array(struct DerivedMesh *dm, bool *r_allocated);
struct MLoop *DM_get_loop_array(struct DerivedMesh *dm, bool *r_allocated);
struct MPoly *DM_get_poly_array(struct DerivedMesh *dm, bool *r_allocated);
struct MFace *DM_get_tessface_array(struct DerivedMesh *dm, bool *r_allocated);
-const MLoopTri *DM_get_looptri_array(
- DerivedMesh *dm,
- const MVert *mvert,
- const MPoly *mpoly, int mpoly_len,
- const MLoop *mloop, int mloop_len,
- bool *r_allocated);
#endif /* __BKE_DERIVEDMESH_H__ */
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 5db0c3c9130..28be2b04c71 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -57,8 +57,9 @@ extern "C" {
/* Allocate a new bAction with the given name */
struct bAction *add_empty_action(struct Main *bmain, const char name[]);
-/* Allocate a copy of the given Action and all its data */
-struct bAction *BKE_action_copy(struct Main *bmain, const struct bAction *src);
+void BKE_action_copy_data(struct Main *bmain, struct bAction *act_dst, const struct bAction *act_src, const int flag);
+/* Allocate a copy of the given Action and all its data */
+struct bAction *BKE_action_copy(struct Main *bmain, const struct bAction *act_src);
/* Deallocate all of the Action's data, but not the Action itself */
void BKE_action_free(struct bAction *act);
@@ -150,6 +151,7 @@ void BKE_pose_free_data_ex(struct bPose *pose, bool do_id_user);
void BKE_pose_free_data(struct bPose *pose);
void BKE_pose_free(struct bPose *pose);
void BKE_pose_free_ex(struct bPose *pose, bool do_id_user);
+void BKE_pose_copy_data_ex(struct bPose **dst, const struct bPose *src, const int flag, const bool copy_constraints);
void BKE_pose_copy_data(struct bPose **dst, const struct bPose *src, const bool copy_constraints);
void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from);
struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name);
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index ef8a1c7e417..9beff85b87c 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -66,8 +66,8 @@ int where_on_path(struct Object *ob, float ctime, float vec[4], float dir[3], fl
/* ---------------------------------------------------- */
/* Dupli-Geometry */
-struct ListBase *object_duplilist_ex(struct EvaluationContext *eval_ctx, struct Scene *sce, struct Object *ob, bool update);
-struct ListBase *object_duplilist(struct EvaluationContext *eval_ctx, struct Scene *sce, struct Object *ob);
+struct ListBase *object_duplilist_ex(const struct EvaluationContext *eval_ctx, struct Scene *sce, struct Object *ob, bool update);
+struct ListBase *object_duplilist(const struct EvaluationContext *eval_ctx, struct Scene *sce, struct Object *ob);
void free_object_duplilist(struct ListBase *lb);
int count_duplilist(struct Object *ob);
@@ -81,7 +81,7 @@ typedef struct DupliApplyData {
DupliExtraData *extra;
} DupliApplyData;
-DupliApplyData *duplilist_apply(struct EvaluationContext *eval_ctx, struct Object *ob, struct Scene *scene, struct ListBase *duplilist);
+DupliApplyData *duplilist_apply(const struct EvaluationContext *eval_ctx, struct Object *ob, struct Scene *scene, struct ListBase *duplilist);
void duplilist_restore(struct ListBase *duplilist, DupliApplyData *apply_data);
void duplilist_free_apply_data(DupliApplyData *apply_data);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 3e6e24a28b0..622767baa10 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -67,10 +67,10 @@ bool BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct b
void BKE_animdata_free(struct ID *id, const bool do_id_user);
/* Copy AnimData */
-struct AnimData *BKE_animdata_copy(struct AnimData *adt, const bool do_action);
+struct AnimData *BKE_animdata_copy(struct Main *bmain, struct AnimData *adt, const bool do_action);
/* Copy AnimData */
-bool BKE_animdata_copy_id(struct ID *id_to, struct ID *id_from, const bool do_action);
+bool BKE_animdata_copy_id(struct Main *bmain, struct ID *id_to, struct ID *id_from, const bool do_action);
/* Copy AnimData Actions */
void BKE_animdata_copy_id_action(struct ID *id, const bool set_newid);
@@ -102,7 +102,7 @@ struct KS_Path *BKE_keyingset_add_path(struct KeyingSet *ks, struct ID *id, cons
struct KS_Path *BKE_keyingset_find_path(struct KeyingSet *ks, struct ID *id, const char group_name[], const char rna_path[], int array_index, int group_mode);
/* Copy all KeyingSets in the given list */
-void BKE_keyingsets_copy(struct ListBase *newlist, struct ListBase *list);
+void BKE_keyingsets_copy(struct ListBase *newlist, const struct ListBase *list);
/* Free the given Keying Set path */
void BKE_keyingset_free_path(struct KeyingSet *ks, struct KS_Path *ksp);
@@ -195,8 +195,8 @@ void animsys_evaluate_action_group(struct PointerRNA *ptr, struct bAction *act,
struct EvaluationContext;
-void BKE_animsys_eval_animdata(struct EvaluationContext *eval_ctx, struct ID *id);
-void BKE_animsys_eval_driver(struct EvaluationContext *eval_ctx, struct ID *id, struct FCurve *fcurve);
+void BKE_animsys_eval_animdata(const struct EvaluationContext *eval_ctx, struct ID *id);
+void BKE_animsys_eval_driver(const struct EvaluationContext *eval_ctx, struct ID *id, struct FCurve *fcurve);
/* ************************************* */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 41783700bf6..453a6432d83 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -79,6 +79,7 @@ int BKE_armature_bonelist_count(struct ListBase *lb);
void BKE_armature_bonelist_free(struct ListBase *lb);
void BKE_armature_free(struct bArmature *arm);
void BKE_armature_make_local(struct Main *bmain, struct bArmature *arm, const bool lib_local);
+void BKE_armature_copy_data(struct Main *bmain, struct bArmature *arm_dst, const struct bArmature *arm_src, const int flag);
struct bArmature *BKE_armature_copy(struct Main *bmain, const struct bArmature *arm);
/* Bounding box. */
@@ -99,8 +100,8 @@ void BKE_armature_where_is(struct bArmature *arm);
void BKE_armature_where_is_bone(struct Bone *bone, struct Bone *prevbone, const bool use_recursion);
void BKE_pose_clear_pointers(struct bPose *pose);
void BKE_pose_rebuild(struct Object *ob, struct bArmature *arm);
-void BKE_pose_where_is(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
-void BKE_pose_where_is_bone(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra);
+void BKE_pose_where_is(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
+void BKE_pose_where_is_bone(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime, bool do_extra);
void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan);
/* get_objectspace_bone_matrix has to be removed still */
@@ -117,7 +118,7 @@ void BKE_armature_loc_pose_to_bone(struct bPoseChannel *pchan, const float inloc
void BKE_armature_mat_bone_to_pose(struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
void BKE_armature_mat_pose_to_delta(float delta_mat[4][4], float pose_mat[4][4], float arm_mat[4][4]);
-void BKE_armature_mat_pose_to_bone_ex(struct EvaluationContext *eval_ctx, struct Object *ob, struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
+void BKE_armature_mat_pose_to_bone_ex(const struct EvaluationContext *eval_ctx, struct Object *ob, struct bPoseChannel *pchan, float inmat[4][4], float outmat[4][4]);
void BKE_pchan_mat3_to_rot(struct bPoseChannel *pchan, float mat[3][3], bool use_compat);
void BKE_pchan_apply_mat4(struct bPoseChannel *pchan, float mat[4][4], bool use_comat);
@@ -164,42 +165,44 @@ struct bPoseChannel *BKE_armature_splineik_solver_find_root(
struct bSplineIKConstraint *data);
void BKE_pose_splineik_init_tree(struct Scene *scene, struct Object *ob, float ctime);
-void BKE_splineik_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan_root, float ctime);
+void BKE_splineik_execute_tree(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
+ struct Object *ob, struct bPoseChannel *pchan_root, float ctime);
-void BKE_pose_eval_init(struct EvaluationContext *eval_ctx,
+void BKE_pose_eval_init(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
struct bPose *pose);
-void BKE_pose_eval_bone(struct EvaluationContext *eval_ctx,
+void BKE_pose_eval_bone(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
struct bPoseChannel *pchan);
-void BKE_pose_constraints_evaluate(struct EvaluationContext *eval_ctx,
+void BKE_pose_constraints_evaluate(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
struct bPoseChannel *pchan);
-void BKE_pose_bone_done(struct EvaluationContext *eval_ctx,
+void BKE_pose_bone_done(const struct EvaluationContext *eval_ctx,
struct bPoseChannel *pchan);
-void BKE_pose_iktree_evaluate(struct EvaluationContext *eval_ctx,
+void BKE_pose_iktree_evaluate(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
struct bPoseChannel *rootchan);
-void BKE_pose_splineik_evaluate(struct EvaluationContext *eval_ctx,
+void BKE_pose_splineik_evaluate(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
struct bPoseChannel *rootchan);
-void BKE_pose_eval_flush(struct EvaluationContext *eval_ctx,
+void BKE_pose_eval_flush(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob,
struct bPose *pose);
-void BKE_pose_eval_proxy_copy(struct EvaluationContext *eval_ctx,
+void BKE_pose_eval_proxy_copy(const struct EvaluationContext *eval_ctx,
struct Object *ob);
#ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 42e4e73f2d5..dedb75a080a 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -44,6 +44,7 @@ void BKE_brush_system_exit(void);
void BKE_brush_init(struct Brush *brush);
struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode);
struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode);
+void BKE_brush_copy_data(struct Main *bmain, struct Brush *brush_dst, const struct Brush *brush_src, const int flag);
struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush);
void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local);
void BKE_brush_unlink(struct Main *bmain, struct Brush *brush);
diff --git a/source/blender/blenkernel/BKE_cachefile.h b/source/blender/blenkernel/BKE_cachefile.h
index db8ddb2ba68..e0419d0e749 100644
--- a/source/blender/blenkernel/BKE_cachefile.h
+++ b/source/blender/blenkernel/BKE_cachefile.h
@@ -47,6 +47,8 @@ void BKE_cachefile_init(struct CacheFile *cache_file);
void BKE_cachefile_free(struct CacheFile *cache_file);
+void BKE_cachefile_copy_data(
+ struct Main *bmain, struct CacheFile *cache_file_dst, const struct CacheFile *cache_file_src, const int flag);
struct CacheFile *BKE_cachefile_copy(struct Main *bmain, const struct CacheFile *cache_file);
void BKE_cachefile_make_local(struct Main *bmain, struct CacheFile *cache_file, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 22165212ed8..2234cee0e0d 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -53,6 +53,7 @@ struct GPUFXSettings;
void BKE_camera_init(struct Camera *cam);
void *BKE_camera_add(struct Main *bmain, const char *name);
+void BKE_camera_copy_data(struct Main *bmain, struct Camera *cam_dst, const struct Camera *cam_src, const int flag);
struct Camera *BKE_camera_copy(struct Main *bmain, const struct Camera *cam);
void BKE_camera_make_local(struct Main *bmain, struct Camera *cam, const bool lib_local);
void BKE_camera_free(struct Camera *ca);
diff --git a/source/blender/blenkernel/BKE_cloth.h b/source/blender/blenkernel/BKE_cloth.h
index 67723209e75..7f7cbd678e2 100644
--- a/source/blender/blenkernel/BKE_cloth.h
+++ b/source/blender/blenkernel/BKE_cloth.h
@@ -227,7 +227,7 @@ void cloth_free_contacts(ColliderContacts *collider_contacts, int totcolliders);
void cloth_free_modifier_extern (struct ClothModifierData *clmd );
void cloth_free_modifier (struct ClothModifierData *clmd );
void cloth_init (struct ClothModifierData *clmd );
-void clothModifier_do (struct ClothModifierData *clmd, struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3]);
+void clothModifier_do(struct ClothModifierData *clmd, const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm, float (*vertexCos)[3]);
int cloth_uses_vgroup(struct ClothModifierData *clmd);
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 6490418edbe..cf7e2908360 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -103,7 +103,7 @@ typedef struct bConstraintTypeInfo {
/* evaluation */
/* set the ct->matrix for the given constraint target (at the given ctime) */
- void (*get_target_matrix)(struct EvaluationContext *eval_ctx, struct bConstraint *con, struct bConstraintOb *cob, struct bConstraintTarget *ct, float ctime);
+ void (*get_target_matrix)(const struct EvaluationContext *eval_ctx, struct bConstraint *con, struct bConstraintOb *cob, struct bConstraintTarget *ct, float ctime);
/* evaluate the constraint for the given time */
void (*evaluate_constraint)(struct bConstraint *con, struct bConstraintOb *cob, struct ListBase *targets);
} bConstraintTypeInfo;
@@ -121,6 +121,7 @@ void BKE_constraint_unique_name(struct bConstraint *con, struct ListBase *list);
void BKE_constraints_free(struct ListBase *list);
void BKE_constraints_free_ex(struct ListBase *list, bool do_id_user);
void BKE_constraints_copy(struct ListBase *dst, const struct ListBase *src, bool do_extern);
+void BKE_constraints_copy_ex(struct ListBase *dst, const struct ListBase *src, const int flag, bool do_extern);
void BKE_constraints_id_loop(struct ListBase *list, ConstraintIDFunc func, void *userdata);
void BKE_constraint_free_data(struct bConstraint *con);
void BKE_constraint_free_data_ex(struct bConstraint *con, bool do_id_user);
@@ -147,10 +148,10 @@ void BKE_constraints_clear_evalob(struct bConstraintOb *cob);
void BKE_constraint_mat_convertspace(
struct Object *ob, struct bPoseChannel *pchan, float mat[4][4], short from, short to, const bool keep_scale);
-void BKE_constraint_target_matrix_get(struct EvaluationContext *eval_ctx, struct Scene *scene, struct bConstraint *con,
+void BKE_constraint_target_matrix_get(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct bConstraint *con,
int n, short ownertype, void *ownerdata, float mat[4][4], float ctime);
-void BKE_constraint_targets_for_solving_get(struct EvaluationContext *eval_ctx, struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
-void BKE_constraints_solve(struct EvaluationContext *eval_ctx, struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
+void BKE_constraint_targets_for_solving_get(const struct EvaluationContext *eval_ctx, struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
+void BKE_constraints_solve(const struct EvaluationContext *eval_ctx, struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_crazyspace.h b/source/blender/blenkernel/BKE_crazyspace.h
index 4fe52370f47..31542cd6f8a 100644
--- a/source/blender/blenkernel/BKE_crazyspace.h
+++ b/source/blender/blenkernel/BKE_crazyspace.h
@@ -42,20 +42,20 @@ struct EvaluationContext;
/* crazyspace.c */
float (*BKE_crazyspace_get_mapped_editverts(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *obedit))[3];
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *obedit))[3];
void BKE_crazyspace_set_quats_editmesh(
struct BMEditMesh *em, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4],
const bool use_select);
void BKE_crazyspace_set_quats_mesh(
struct Mesh *me, float (*origcos)[3], float (*mappedcos)[3], float (*quats)[4]);
int BKE_crazyspace_get_first_deform_matrices_editbmesh(
- struct EvaluationContext *eval_ctx, struct Scene *, struct Object *, struct BMEditMesh *em,
+ const struct EvaluationContext *eval_ctx, struct Scene *, struct Object *, struct BMEditMesh *em,
float (**deformmats)[3][3], float (**deformcos)[3]);
int BKE_sculpt_get_first_deform_matrices(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
float (**deformmats)[3][3], float (**deformcos)[3]);
void BKE_crazyspace_build_sculpt(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
float (**deformmats)[3][3], float (**deformcos)[3]);
#ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index 501a623acea..1ebb092a939 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -79,6 +79,7 @@ void BKE_curve_free(struct Curve *cu);
void BKE_curve_editfont_free(struct Curve *cu);
void BKE_curve_init(struct Curve *cu);
struct Curve *BKE_curve_add(struct Main *bmain, const char *name, int type);
+void BKE_curve_copy_data(struct Main *bmain, struct Curve *cu_dst, const struct Curve *cu_src, const int flag);
struct Curve *BKE_curve_copy(struct Main *bmain, const struct Curve *cu);
void BKE_curve_make_local(struct Main *bmain, struct Curve *cu, const bool lib_local);
short BKE_curve_type_get(struct Curve *cu);
@@ -93,8 +94,8 @@ void BKE_curve_texspace_get(struct Curve *cu, float r_loc[3], float r_rot[3], fl
bool BKE_curve_minmax(struct Curve *cu, bool use_radius, float min[3], float max[3]);
bool BKE_curve_center_median(struct Curve *cu, float cent[3]);
bool BKE_curve_center_bounds(struct Curve *cu, float cent[3]);
-void BKE_curve_transform_ex(struct Curve *cu, float mat[4][4], const bool do_keys, const float unit_scale);
-void BKE_curve_transform(struct Curve *cu, float mat[4][4], const bool do_keys);
+void BKE_curve_transform_ex(struct Curve *cu, float mat[4][4], const bool do_keys, const bool do_props, const float unit_scale);
+void BKE_curve_transform(struct Curve *cu, float mat[4][4], const bool do_keys, const bool do_props);
void BKE_curve_translate(struct Curve *cu, float offset[3], const bool do_keys);
void BKE_curve_material_index_remove(struct Curve *cu, int index);
void BKE_curve_material_index_clear(struct Curve *cu);
@@ -122,13 +123,14 @@ void BKE_curve_editNurb_keyIndex_free(struct GHash **keyindex);
void BKE_curve_editNurb_free(struct Curve *cu);
struct ListBase *BKE_curve_editNurbs_get(struct Curve *cu);
-float *BKE_curve_make_orco(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, int *r_numVerts);
+float *BKE_curve_make_orco(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, int *r_numVerts);
float *BKE_curve_surf_make_orco(struct Object *ob);
void BKE_curve_bevelList_free(struct ListBase *bev);
void BKE_curve_bevelList_make(struct Object *ob, struct ListBase *nurbs, bool for_render);
-void BKE_curve_bevel_make(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *disp,
- const bool for_render, const bool use_render_resolution);
+void BKE_curve_bevel_make(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *disp,
+ const bool for_render, const bool use_render_resolution);
void BKE_curve_forward_diff_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride);
void BKE_curve_forward_diff_tangent_bezier(float q0, float q1, float q2, float q3, float *p, int it, int stride);
@@ -213,11 +215,13 @@ void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles);
/* **** Depsgraph evaluation **** */
-void BKE_curve_eval_geometry(struct EvaluationContext *eval_ctx,
- struct Curve *curve);
+void BKE_curve_eval_geometry(
+ const struct EvaluationContext *eval_ctx,
+ struct Curve *curve);
-void BKE_curve_eval_path(struct EvaluationContext *eval_ctx,
- struct Curve *curve);
+void BKE_curve_eval_path(
+ const struct EvaluationContext *eval_ctx,
+ struct Curve *curve);
/* Draw Cache */
enum {
diff --git a/source/blender/blenkernel/BKE_data_transfer.h b/source/blender/blenkernel/BKE_data_transfer.h
index 497319819de..d5f0313ca64 100644
--- a/source/blender/blenkernel/BKE_data_transfer.h
+++ b/source/blender/blenkernel/BKE_data_transfer.h
@@ -130,12 +130,12 @@ enum {
};
void BKE_object_data_transfer_layout(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob_src,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob_src,
struct Object *ob_dst, const int data_types, const bool use_delete,
const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX]);
bool BKE_object_data_transfer_mesh(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob_src, struct Object *ob_dst, const int data_types, const bool use_create,
const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode,
struct SpaceTransform *space_transform, const bool auto_transform,
@@ -144,7 +144,7 @@ bool BKE_object_data_transfer_mesh(
const int mix_mode, const float mix_factor, const char *vgroup_name, const bool invert_vgroup,
struct ReportList *reports);
bool BKE_object_data_transfer_dm(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob_src, struct Object *ob_dst, struct DerivedMesh *dm_dst,
const int data_types, bool use_create,
const int map_vert_mode, const int map_edge_mode, const int map_loop_mode, const int map_poly_mode,
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 641abc54216..c2229976dd9 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -86,23 +86,30 @@ void BKE_displist_count(struct ListBase *lb, int *totvert, int *totface, int *to
void BKE_displist_free(struct ListBase *lb);
bool BKE_displist_has_faces(struct ListBase *lb);
-void BKE_displist_make_surf(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase,
- struct DerivedMesh **r_dm_final, const bool for_render, const bool for_orco, const bool use_render_resolution);
-void BKE_displist_make_curveTypes(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, const bool for_orco);
-void BKE_displist_make_curveTypes_forRender(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase,
- struct DerivedMesh **r_dm_final, const bool for_orco, const bool use_render_resolution);
-void BKE_displist_make_curveTypes_forOrco(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
-void BKE_displist_make_mball(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
-void BKE_displist_make_mball_forRender(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
+void BKE_displist_make_surf(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase,
+ struct DerivedMesh **r_dm_final, const bool for_render, const bool for_orco, const bool use_render_resolution);
+void BKE_displist_make_curveTypes(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, const bool for_orco);
+void BKE_displist_make_curveTypes_forRender(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase,
+ struct DerivedMesh **r_dm_final, const bool for_orco, const bool use_render_resolution);
+void BKE_displist_make_curveTypes_forOrco(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
+void BKE_displist_make_mball(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
+void BKE_displist_make_mball_forRender(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ListBase *dispbase);
bool BKE_displist_surfindex_get(DispList *dl, int a, int *b, int *p1, int *p2, int *p3, int *p4);
void BKE_displist_fill(struct ListBase *dispbase, struct ListBase *to, const float normal_proj[3], const bool flipnormal);
-float BKE_displist_calc_taper(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *taperobj, int cur, int tot);
+float BKE_displist_calc_taper(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *taperobj, int cur, int tot);
/* add Orco layer to the displist object which has got derived mesh and return orco */
-float *BKE_displist_make_orco(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm_final,
- const bool for_render, const bool use_render_resolution);
+float *BKE_displist_make_orco(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm_final,
+ const bool for_render, const bool use_render_resolution);
void BKE_displist_minmax(struct ListBase *dispbase, float min[3], float max[3]);
diff --git a/source/blender/blenkernel/BKE_dynamicpaint.h b/source/blender/blenkernel/BKE_dynamicpaint.h
index 1360d0c730f..cee10d2bd56 100644
--- a/source/blender/blenkernel/BKE_dynamicpaint.h
+++ b/source/blender/blenkernel/BKE_dynamicpaint.h
@@ -62,7 +62,7 @@ typedef struct PaintWavePoint {
short state;
} PaintWavePoint;
-struct DerivedMesh *dynamicPaint_Modifier_do(struct DynamicPaintModifierData *pmd, struct EvaluationContext *eval_ctx, struct Scene *scene,
+struct DerivedMesh *dynamicPaint_Modifier_do(struct DynamicPaintModifierData *pmd, const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob, struct DerivedMesh *dm);
void dynamicPaint_Modifier_free(struct DynamicPaintModifierData *pmd);
void dynamicPaint_Modifier_copy(struct DynamicPaintModifierData *pmd, struct DynamicPaintModifierData *tsmd);
@@ -86,7 +86,7 @@ struct DynamicPaintSurface *get_activeSurface(struct DynamicPaintCanvasSettings
/* image sequence baking */
int dynamicPaint_createUVSurface(struct Scene *scene, struct DynamicPaintSurface *surface, float *progress, short *do_update);
-int dynamicPaint_calculateFrame(struct DynamicPaintSurface *surface, struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *cObject, int frame);
+int dynamicPaint_calculateFrame(struct DynamicPaintSurface *surface, const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *cObject, int frame);
void dynamicPaint_outputSurfaceImage(struct DynamicPaintSurface *surface, char *filename, short output_layer);
/* PaintPoint state */
diff --git a/source/blender/blenkernel/BKE_editmesh.h b/source/blender/blenkernel/BKE_editmesh.h
index 02ad8777e60..af1aeff230f 100644
--- a/source/blender/blenkernel/BKE_editmesh.h
+++ b/source/blender/blenkernel/BKE_editmesh.h
@@ -99,6 +99,7 @@ float (*BKE_editmesh_vertexCos_get_orco(BMEditMesh *em, int *r_numVerts))[3]
void BKE_editmesh_statvis_calc(BMEditMesh *em, struct DerivedMesh *dm,
const struct MeshStatVis *statvis);
-float (*BKE_editmesh_vertexCos_get(struct EvaluationContext *eval_ctx, struct BMEditMesh *em, struct Scene *scene, int *r_numVerts))[3];
+float (*BKE_editmesh_vertexCos_get(
+ const struct EvaluationContext *eval_ctx, struct BMEditMesh *em, struct Scene *scene, int *r_numVerts))[3];
#endif /* __BKE_EDITMESH_H__ */
diff --git a/source/blender/blenkernel/BKE_effect.h b/source/blender/blenkernel/BKE_effect.h
index 383e6d0cb62..6fa19d4aaf6 100644
--- a/source/blender/blenkernel/BKE_effect.h
+++ b/source/blender/blenkernel/BKE_effect.h
@@ -94,7 +94,7 @@ typedef struct EffectorData {
typedef struct EffectorCache {
struct EffectorCache *next, *prev;
- struct EvaluationContext *eval_ctx;
+ const struct EvaluationContext *eval_ctx;
struct Scene *scene;
struct Object *ob;
struct ParticleSystem *psys;
@@ -112,10 +112,11 @@ typedef struct EffectorCache {
} EffectorCache;
void free_partdeflect(struct PartDeflect *pd);
-struct ListBase *pdInitEffectors(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src,
- struct EffectorWeights *weights, bool for_simulation);
+struct ListBase *pdInitEffectors(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob_src, struct ParticleSystem *psys_src,
+ struct EffectorWeights *weights, bool for_simulation);
void pdEndEffectors(struct ListBase **effectors);
-void pdPrecalculateEffectors(struct EvaluationContext *eval_ctx, struct ListBase *effectors);
+void pdPrecalculateEffectors(const struct EvaluationContext *eval_ctx, struct ListBase *effectors);
void pdDoEffectors(struct ListBase *effectors, struct ListBase *colliders, struct EffectorWeights *weights, struct EffectedPoint *point, float *force, float *impulse);
void pd_point_from_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, struct EffectedPoint *point);
diff --git a/source/blender/blenkernel/BKE_fluidsim.h b/source/blender/blenkernel/BKE_fluidsim.h
index 0345382271b..4ec58b2a0e5 100644
--- a/source/blender/blenkernel/BKE_fluidsim.h
+++ b/source/blender/blenkernel/BKE_fluidsim.h
@@ -40,7 +40,7 @@ struct EvaluationContext;
/* old interface */
-void initElbeemMesh(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+void initElbeemMesh(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
int *numVertices, float **vertices,
int *numTriangles, int **triangles,
int useGlobalCoords, int modifierIndex);
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index e7ae0f606e7..60ad061bf77 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -78,6 +78,7 @@ void BKE_vfont_builtin_register(void *mem, int size);
void BKE_vfont_free_data(struct VFont *vfont);
void BKE_vfont_free(struct VFont *sc);
void BKE_vfont_init(struct VFont *vfont);
+void BKE_vfont_copy_data(struct Main *bmain, struct VFont *vfont_dst, const struct VFont *vfont_src, const int flag);
struct VFont *BKE_vfont_builtin_get(void);
struct VFont *BKE_vfont_load(struct Main *bmain, const char *filepath);
struct VFont *BKE_vfont_load_exists_ex(struct Main *bmain, const char *filepath, bool *r_exists);
diff --git a/source/blender/blenkernel/BKE_freestyle.h b/source/blender/blenkernel/BKE_freestyle.h
index 50407f3bdfc..1045fde0039 100644
--- a/source/blender/blenkernel/BKE_freestyle.h
+++ b/source/blender/blenkernel/BKE_freestyle.h
@@ -50,7 +50,7 @@ typedef struct FreestyleModuleSettings FreestyleModuleSettings;
/* FreestyleConfig */
void BKE_freestyle_config_init(FreestyleConfig *config);
void BKE_freestyle_config_free(FreestyleConfig *config);
-void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *config);
+void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *config, const int flag);
/* FreestyleConfig.modules */
FreestyleModuleConfig *BKE_freestyle_module_add(FreestyleConfig *config);
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index bdd28baf137..b6de922c245 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -60,6 +60,7 @@ struct bGPdata *BKE_gpencil_data_addnew(const char name[]);
struct bGPDframe *BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src);
struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src);
+void BKE_gpencil_copy_data(struct Main *bmain, struct bGPdata *gpd_dst, const struct bGPdata *gpd_src, const int flag);
struct bGPdata *BKE_gpencil_data_duplicate(struct Main *bmain, const struct bGPdata *gpd, bool internal_copy);
void BKE_gpencil_make_local(struct Main *bmain, struct bGPdata *gpd, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index 4555bbf076d..205f42d6643 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -43,6 +43,7 @@ struct Scene;
void BKE_group_free(struct Group *group);
struct Group *BKE_group_add(struct Main *bmain, const char *name);
+void BKE_group_copy_data(struct Main *bmain, struct Group *group_dst, const struct Group *group_src, const int flag);
struct Group *BKE_group_copy(struct Main *bmain, const struct Group *group);
void BKE_group_make_local(struct Main *bmain, struct Group *group, const bool lib_local);
bool BKE_group_object_add(struct Group *group, struct Object *ob);
@@ -53,6 +54,6 @@ bool BKE_group_object_cyclic_check(struct Main *bmain, struct Object *o
bool BKE_group_is_animated(struct Group *group, struct Object *parent);
void BKE_group_tag_recalc(struct Group *group);
-void BKE_group_handle_recalc_and_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *parent, struct Group *group);
+void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *parent, struct Group *group);
#endif /* __BKE_GROUP_H__ */
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index ab8728faedb..055c530d255 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -58,7 +58,7 @@ typedef union IDPropertyTemplate {
/* ----------- Property Array Type ---------- */
IDProperty *IDP_NewIDPArray(const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-IDProperty *IDP_CopyIDPArray(const IDProperty *array) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+IDProperty *IDP_CopyIDPArray(const IDProperty *array, const int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* shallow copies item */
void IDP_SetIndexArray(struct IDProperty *prop, int index, struct IDProperty *item) ATTR_NONNULL();
@@ -91,6 +91,7 @@ void IDP_ReplaceGroupInGroup(struct IDProperty *dest, const struct IDProperty *s
void IDP_ReplaceInGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL();
void IDP_ReplaceInGroup_ex(struct IDProperty *group, struct IDProperty *prop, struct IDProperty *prop_exist);
void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite) ATTR_NONNULL();
+void IDP_MergeGroup_ex(IDProperty *dest, const IDProperty *src, const bool do_overwrite, const int flag) ATTR_NONNULL();
bool IDP_AddToGroup(struct IDProperty *group, struct IDProperty *prop) ATTR_NONNULL();
bool IDP_InsertToGroup(struct IDProperty *group, struct IDProperty *previous,
struct IDProperty *pnew) ATTR_NONNULL(1 /* group */, 3 /* pnew */);
@@ -103,6 +104,7 @@ IDProperty *IDP_GetPropertyTypeFromGroup(struct IDProperty *prop, const char *na
/*-------- Main Functions --------*/
struct IDProperty *IDP_GetProperties(struct ID *id, const bool create_if_needed) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
struct IDProperty *IDP_CopyProperty(const struct IDProperty *prop) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+struct IDProperty *IDP_CopyProperty_ex(const struct IDProperty *prop, const int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is_strict) ATTR_WARN_UNUSED_RESULT;
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index e155b0719cc..3f8be511212 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -250,6 +250,7 @@ void BKE_image_packfiles_from_mem(struct ReportList *reports, struct Image *ima,
void BKE_image_print_memlist(void);
/* empty image block, of similar type and filename */
+void BKE_image_copy_data(struct Main *bmain, struct Image *ima_dst, const struct Image *ima_src, const int flag);
struct Image *BKE_image_copy(struct Main *bmain, const struct Image *ima);
/* merge source into dest, and free source */
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index 94e8a24fbc5..5eef44ef896 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -51,6 +51,7 @@ extern "C" {
void BKE_key_free(struct Key *sc);
void BKE_key_free_nolib(struct Key *key);
struct Key *BKE_key_add(struct ID *id);
+void BKE_key_copy_data(struct Main *bmain, struct Key *key_dst, const struct Key *key_src, const int flag);
struct Key *BKE_key_copy(struct Main *bmain, const struct Key *key);
struct Key *BKE_key_copy_nolib(struct Key *key);
void BKE_key_sort(struct Key *key);
diff --git a/source/blender/blenkernel/BKE_lamp.h b/source/blender/blenkernel/BKE_lamp.h
index 713ca80fb1a..b68da654520 100644
--- a/source/blender/blenkernel/BKE_lamp.h
+++ b/source/blender/blenkernel/BKE_lamp.h
@@ -44,6 +44,7 @@ struct Scene;
void BKE_lamp_init(struct Lamp *la);
struct Lamp *BKE_lamp_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT;
+void BKE_lamp_copy_data(struct Main *bmain, struct Lamp *la_dst, const struct Lamp *la_src, const int flag);
struct Lamp *BKE_lamp_copy(struct Main *bmain, const struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
struct Lamp *localize_lamp(struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
void BKE_lamp_make_local(struct Main *bmain, struct Lamp *la, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index fe3d388178e..52d6dc53808 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -48,6 +48,7 @@ struct EvaluationContext;
void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb);
void BKE_lattice_init(struct Lattice *lt);
struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name);
+void BKE_lattice_copy_data(struct Main *bmain, struct Lattice *lt_dst, const struct Lattice *lt_src, const int flag);
struct Lattice *BKE_lattice_copy(struct Main *bmain, const struct Lattice *lt);
void BKE_lattice_free(struct Lattice *lt);
void BKE_lattice_make_local(struct Main *bmain, struct Lattice *lt, const bool lib_local);
@@ -61,10 +62,12 @@ void end_latt_deform(struct LatticeDeformData *lattice_deform_data);
bool object_deform_mball(struct Object *ob, struct ListBase *dispbase);
void outside_lattice(struct Lattice *lt);
-void curve_deform_verts(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *cuOb, struct Object *target,
- struct DerivedMesh *dm, float (*vertexCos)[3],
+void curve_deform_verts(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
+ struct Object *cuOb, struct Object *target,
+ struct DerivedMesh *dm, float (*vertexCos)[3],
int numVerts, const char *vgroup, short defaxis);
-void curve_deform_vector(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *cuOb, struct Object *target,
+void curve_deform_vector(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *cuOb, struct Object *target,
float orco[3], float vec[3], float mat[3][3], int no_rot_axis);
void lattice_deform_verts(struct Object *laOb, struct Object *target,
@@ -77,7 +80,7 @@ void armature_deform_verts(struct Object *armOb, struct Object *target,
float (*BKE_lattice_vertexcos_get(struct Object *ob, int *r_numVerts))[3];
void BKE_lattice_vertexcos_apply(struct Object *ob, float (*vertexCos)[3]);
-void BKE_lattice_modifiers_calc(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
+void BKE_lattice_modifiers_calc(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
struct MDeformVert *BKE_lattice_deform_verts_get(struct Object *lattice);
struct BPoint *BKE_lattice_active_point_get(struct Lattice *lt);
@@ -101,7 +104,7 @@ void BKE_lattice_bitmap_from_flag(struct Lattice *lt, unsigned int *bitmap, cons
struct EvaluationContext;
-void BKE_lattice_eval_geometry(struct EvaluationContext *eval_ctx,
+void BKE_lattice_eval_geometry(const struct EvaluationContext *eval_ctx,
struct Lattice *latt);
/* Draw Cache */
diff --git a/source/blender/blenkernel/BKE_layer.h b/source/blender/blenkernel/BKE_layer.h
index 0a26fe08016..5f95a69ed1e 100644
--- a/source/blender/blenkernel/BKE_layer.h
+++ b/source/blender/blenkernel/BKE_layer.h
@@ -144,13 +144,13 @@ void BKE_collection_engine_property_value_set_bool(struct IDProperty *props, con
/* evaluation */
-void BKE_layer_eval_layer_collection_pre(struct EvaluationContext *eval_ctx,
+void BKE_layer_eval_layer_collection_pre(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct SceneLayer *scene_layer);
-void BKE_layer_eval_layer_collection(struct EvaluationContext *eval_ctx,
+void BKE_layer_eval_layer_collection(const struct EvaluationContext *eval_ctx,
struct LayerCollection *layer_collection,
struct LayerCollection *parent_layer_collection);
-void BKE_layer_eval_layer_collection_post(struct EvaluationContext *eval_ctx,
+void BKE_layer_eval_layer_collection_post(const struct EvaluationContext *eval_ctx,
struct SceneLayer *scene_layer);
/* iterators */
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index bfe8cea7519..eac4dc81582 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -52,11 +52,38 @@ struct PropertyRNA;
size_t BKE_libblock_get_alloc_info(short type, const char **name);
void *BKE_libblock_alloc_notest(short type);
-void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name, const int flag) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void BKE_libblock_init_empty(struct ID *id);
+
+/**
+ * New ID creation/copying options.
+ */
+enum {
+ /* *** Generic options (should be handled by all ID types copying, ID creation, etc.). *** */
+ /* Create datablock outside of any main database - similar to 'localize' functions of materials etc. */
+ LIB_ID_CREATE_NO_MAIN = 1 << 0,
+ /* Do not affect user refcount of datablocks used by new one (which also gets zero usercount then).
+ * Implies LIB_ID_CREATE_NO_MAIN. */
+ LIB_ID_CREATE_NO_USER_REFCOUNT = 1 << 1,
+ /* Assume given 'newid' already points to allocated memory for whole datablock (ID + data) - USE WITH CAUTION!
+ * Implies LIB_ID_CREATE_NO_MAIN. */
+ LIB_ID_CREATE_NO_ALLOCATE = 1 << 2,
+
+ LIB_ID_CREATE_NO_DEG_TAG = 1 << 8, /* Do not tag new ID for update in depsgraph. */
+
+ /* Specific options to some ID types or usages, may be ignored by unrelated ID copying functions. */
+ LIB_ID_COPY_NO_PROXY_CLEAR = 1 << 16, /* Object only, needed by make_local code. */
+ LIB_ID_COPY_NO_PREVIEW = 1 << 17, /* Do not copy preview data, when supported. */
+ LIB_ID_COPY_CACHES = 1 << 18, /* Copy runtime data caches. */
+ /* XXX TODO Do we want to keep that? would rather try to get rid of it... */
+ LIB_ID_COPY_ACTIONS = 1 << 19, /* EXCEPTION! Deep-copy actions used by animdata of copied ID. */
+};
+
+void BKE_libblock_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag);
void *BKE_libblock_copy(struct Main *bmain, const struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+/* "Deprecated" old API. */
void *BKE_libblock_copy_nolib(const struct ID *id, const bool do_action) ATTR_NONNULL();
-void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
+
void BKE_libblock_rename(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL();
void BLI_libblock_ensure_unique_name(struct Main *bmain, const char *name) ATTR_NONNULL();
@@ -64,13 +91,45 @@ struct ID *BKE_libblock_find_name_ex(struct Main *bmain, const short type, const
struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
/* library_remap.c (keep here since they're general functions) */
-void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
-void BKE_libblock_free_datablock(struct ID *id) ATTR_NONNULL();
+/**
+ * New freeing logic options.
+ */
+enum {
+ /* *** Generic options (should be handled by all ID types freeing). *** */
+ /* Do not try to remove freed ID from given Main (passed Main may be NULL). */
+ LIB_ID_FREE_NO_MAIN = 1 << 0,
+ /* Do not affect user refcount of datablocks used by freed one.
+ * Implies LIB_ID_FREE_NO_MAIN. */
+ LIB_ID_FREE_NO_USER_REFCOUNT = 1 << 1,
+ /* Assume freed ID datablock memory is managed elsewhere, do not free it
+ * (still calls relevant ID type's freeing function though) - USE WITH CAUTION!
+ * Implies LIB_ID_FREE_NO_MAIN. */
+ LIB_ID_FREE_NOT_ALLOCATED = 1 << 2,
+
+ LIB_ID_FREE_NO_DEG_TAG = 1 << 8, /* Do not tag freed ID for update in depsgraph. */
+ LIB_ID_FREE_NO_UI_USER = 1 << 9, /* Do not attempt to remove freed ID from UI data/notifiers/... */
+};
+
+void BKE_id_free_ex(struct Main *bmain, void *idv, int flag, const bool use_flag_from_idtag);
+void BKE_id_free(struct Main *bmain, void *idv);
+/* Those three naming are bad actually, should be BKE_id_free... (since it goes beyond mere datablock). */
+/* "Deprecated" old API */
void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) ATTR_NONNULL();
+void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
void BKE_libblock_free_us(struct Main *bmain, void *idv) ATTR_NONNULL();
-void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL();
+
+void BKE_libblock_management_main_add(struct Main *bmain, void *idv);
+void BKE_libblock_management_main_remove(struct Main *bmain, void *idv);
+
+void BKE_libblock_management_usercounts_set(struct Main *bmain, void *idv);
+void BKE_libblock_management_usercounts_clear(struct Main *bmain, void *idv);
+
+/* TODO should be named "BKE_id_delete()". */
void BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
+void BKE_libblock_free_datablock(struct ID *id, const int flag) ATTR_NONNULL();
+void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL();
+
void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
void id_lib_extern(struct ID *id);
void BKE_library_filepath_set(struct Library *lib, const char *filepath);
@@ -87,6 +146,7 @@ void BKE_id_make_local_generic(struct Main *bmain, struct ID *id, const bool id_
bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const bool force_local);
bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
bool id_copy(struct Main *bmain, const struct ID *id, struct ID **newid, bool test);
+bool BKE_id_copy_ex(struct Main *bmain, const struct ID *id, struct ID **r_newid, const int flag, const bool test);
void id_sort_by_name(struct ListBase *lb, struct ID *id);
void BKE_id_expand_local(struct Main *bmain, struct ID *id);
void BKE_id_copy_ensure_local(struct Main *bmain, const struct ID *old_id, struct ID *new_id);
diff --git a/source/blender/blenkernel/BKE_lightprobe.h b/source/blender/blenkernel/BKE_lightprobe.h
index ae7df75345d..a769b6653d7 100644
--- a/source/blender/blenkernel/BKE_lightprobe.h
+++ b/source/blender/blenkernel/BKE_lightprobe.h
@@ -38,7 +38,8 @@ struct LightProbe;
void BKE_lightprobe_init(struct LightProbe *probe);
void *BKE_lightprobe_add(struct Main *bmain, const char *name);
-struct LightProbe *BKE_lightprobe_copy(struct Main *bmain, struct LightProbe *probe);
+void BKE_lightprobe_copy_data(struct Main *bmain, struct LightProbe *probe_dst, const struct LightProbe *probe_src, const int flag);
+struct LightProbe *BKE_lightprobe_copy(struct Main *bmain, const struct LightProbe *probe);
void BKE_lightprobe_make_local(struct Main *bmain, struct LightProbe *probe, const bool lib_local);
void BKE_lightprobe_free(struct LightProbe *probe);
diff --git a/source/blender/blenkernel/BKE_linestyle.h b/source/blender/blenkernel/BKE_linestyle.h
index c7b323d0f6e..3ba4fbe0338 100644
--- a/source/blender/blenkernel/BKE_linestyle.h
+++ b/source/blender/blenkernel/BKE_linestyle.h
@@ -52,6 +52,9 @@ struct bContext;
void BKE_linestyle_init(struct FreestyleLineStyle *linestyle);
FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name);
void BKE_linestyle_free(FreestyleLineStyle *linestyle);
+void BKE_linestyle_copy_data(
+ struct Main *bmain, struct FreestyleLineStyle *linestyle_dst, const struct FreestyleLineStyle *linestyle_src,
+ const int flag);
FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle);
void BKE_linestyle_make_local(struct Main *bmain, struct FreestyleLineStyle *linestyle, const bool lib_local);
@@ -63,10 +66,14 @@ LineStyleModifier *BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyl
LineStyleModifier *BKE_linestyle_thickness_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type);
LineStyleModifier *BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type);
-LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
-LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
-LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
-LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
+LineStyleModifier *BKE_linestyle_color_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag);
+LineStyleModifier *BKE_linestyle_alpha_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag);
+LineStyleModifier *BKE_linestyle_thickness_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag);
+LineStyleModifier *BKE_linestyle_geometry_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag);
int BKE_linestyle_color_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier);
int BKE_linestyle_alpha_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier);
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index 0735d2d97a1..6e154241af7 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -122,6 +122,7 @@ void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const eMask
/* general */
struct Mask *BKE_mask_new(struct Main *bmain, const char *name);
+void BKE_mask_copy_data(struct Main *bmain, struct Mask *mask_dst, const struct Mask *mask_src, const int flag);
struct Mask *BKE_mask_copy_nolib(struct Mask *mask);
struct Mask *BKE_mask_copy(struct Main *bmain, const struct Mask *mask);
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 14820587200..49fb128417e 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -54,6 +54,7 @@ void BKE_material_init(struct Material *ma);
void BKE_material_remap_object(struct Object *ob, const unsigned int *remap);
void BKE_material_remap_object_calc(struct Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst);
struct Material *BKE_material_add(struct Main *bmain, const char *name);
+void BKE_material_copy_data(struct Main *bmain, struct Material *ma_dst, const struct Material *ma_src, const int flag);
struct Material *BKE_material_copy(struct Main *bmain, const struct Material *ma);
struct Material *localize_material(struct Material *ma);
struct Material *give_node_material(struct Material *ma); /* returns node material or self */
@@ -122,7 +123,7 @@ void paste_matcopybuf(struct Material *ma);
struct EvaluationContext;
-void BKE_material_eval(struct EvaluationContext *eval_ctx, struct Material *material);
+void BKE_material_eval(const struct EvaluationContext *eval_ctx, struct Material *material);
#ifdef __cplusplus
}
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index c00a0743ebb..0c07ce55781 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -41,6 +41,7 @@ struct MetaElem;
void BKE_mball_free(struct MetaBall *mb);
void BKE_mball_init(struct MetaBall *mb);
struct MetaBall *BKE_mball_add(struct Main *bmain, const char *name);
+void BKE_mball_copy_data(struct Main *bmain, struct MetaBall *mb_dst, const struct MetaBall *mb_src, const int flag);
struct MetaBall *BKE_mball_copy(struct Main *bmain, const struct MetaBall *mb);
void BKE_mball_make_local(struct Main *bmain, struct MetaBall *mb, const bool lib_local);
@@ -59,7 +60,7 @@ bool BKE_mball_minmax_ex(struct MetaBall *mb, float min[3], float max[3],
float obmat[4][4], const short flag);
bool BKE_mball_center_median(struct MetaBall *mb, float r_cent[3]);
bool BKE_mball_center_bounds(struct MetaBall *mb, float r_cent[3]);
-void BKE_mball_transform(struct MetaBall *mb, float mat[4][4]);
+void BKE_mball_transform(struct MetaBall *mb, float mat[4][4], const bool do_props);
void BKE_mball_translate(struct MetaBall *mb, const float offset[3]);
struct MetaElem *BKE_mball_element_add(struct MetaBall *mb, const int type);
@@ -72,7 +73,7 @@ void BKE_mball_select_swap(struct MetaBall *mb);
struct EvaluationContext;
-void BKE_mball_eval_geometry(struct EvaluationContext *eval_ctx,
+void BKE_mball_eval_geometry(const struct EvaluationContext *eval_ctx,
struct MetaBall *mball);
#endif
diff --git a/source/blender/blenkernel/BKE_mball_tessellate.h b/source/blender/blenkernel/BKE_mball_tessellate.h
index 361f31b704c..40cdc80e280 100644
--- a/source/blender/blenkernel/BKE_mball_tessellate.h
+++ b/source/blender/blenkernel/BKE_mball_tessellate.h
@@ -28,7 +28,7 @@ struct Object;
struct Scene;
void BKE_mball_polygonize(
- struct EvaluationContext *eval_ctx, struct Scene *scene,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
struct Object *ob, struct ListBase *dispbase);
void BKE_mball_cubeTable_free(void);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index 4766f1d37eb..d68712202c9 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -88,6 +88,7 @@ int BKE_mesh_edge_other_vert(const struct MEdge *e, int v);
void BKE_mesh_free(struct Mesh *me);
void BKE_mesh_init(struct Mesh *me);
struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name);
+void BKE_mesh_copy_data(struct Main *bmain, struct Mesh *me_dst, const struct Mesh *me_src, const int flag);
struct Mesh *BKE_mesh_copy(struct Main *bmain, const struct Mesh *me);
void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd);
void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
@@ -118,7 +119,7 @@ void BKE_mesh_from_nurbs_displist(
struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv, const char *obdata_name);
void BKE_mesh_from_nurbs(struct Object *ob);
void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblist, const int edge_users_test);
-void BKE_mesh_to_curve(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
+void BKE_mesh_to_curve(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
void BKE_mesh_material_index_remove(struct Mesh *me, short index);
void BKE_mesh_material_index_clear(struct Mesh *me);
void BKE_mesh_material_remap(struct Mesh *me, const unsigned int *remap, unsigned int remap_len);
@@ -139,7 +140,7 @@ float (*BKE_mesh_vertexCos_get(const struct Mesh *me, int *r_numVerts))[3];
void BKE_mesh_split_faces(struct Mesh *mesh, bool free_loop_normals);
-struct Mesh *BKE_mesh_new_from_object(struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, struct Object *ob,
+struct Mesh *BKE_mesh_new_from_object(const struct EvaluationContext *eval_ctx, struct Main *bmain, struct Scene *sce, struct Object *ob,
int apply_modifiers, int settings, int calc_tessface, int calc_undeformed);
/* vertex level transformations & checks (no derived mesh) */
@@ -400,7 +401,7 @@ void BKE_mesh_calc_edges(struct Mesh *mesh, bool update, const bool select);
/* **** Depsgraph evaluation **** */
-void BKE_mesh_eval_geometry(struct EvaluationContext *eval_ctx,
+void BKE_mesh_eval_geometry(const struct EvaluationContext *eval_ctx,
struct Mesh *mesh);
/* Draw Cache */
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index ca74993156d..76a36bdf3ff 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -159,25 +159,25 @@ typedef struct ModifierTypeInfo {
* the object it can obtain it from the derivedData argument if non-NULL,
* and otherwise the ob argument.
*/
- void (*deformVerts)(struct ModifierData *md, struct EvaluationContext *eval_ctx,
+ void (*deformVerts)(struct ModifierData *md, const struct EvaluationContext *eval_ctx,
struct Object *ob, struct DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts,
ModifierApplyFlag flag);
/* Like deformMatricesEM but called from object mode (for supporting modifiers in sculpt mode) */
- void (*deformMatrices)(struct ModifierData *md, struct EvaluationContext *eval_ctx,
+ void (*deformMatrices)(struct ModifierData *md, const struct EvaluationContext *eval_ctx,
struct Object *ob, struct DerivedMesh *derivedData,
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
/* Like deformVerts but called during editmode (for supporting modifiers)
*/
- void (*deformVertsEM)(struct ModifierData *md, struct EvaluationContext *eval_ctx,
+ void (*deformVertsEM)(struct ModifierData *md, const struct EvaluationContext *eval_ctx,
struct Object *ob, struct BMEditMesh *editData,
struct DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts);
/* Set deform matrix per vertex for crazyspace correction */
- void (*deformMatricesEM)(struct ModifierData *md, struct EvaluationContext *eval_ctx,
+ void (*deformMatricesEM)(struct ModifierData *md, const struct EvaluationContext *eval_ctx,
struct Object *ob, struct BMEditMesh *editData,
struct DerivedMesh *derivedData,
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts);
@@ -203,7 +203,7 @@ typedef struct ModifierTypeInfo {
* The modifier may reuse the derivedData argument (i.e. return it in
* modified form), but must not release it.
*/
- struct DerivedMesh *(*applyModifier)(struct ModifierData *md, struct EvaluationContext *eval_ctx,
+ struct DerivedMesh *(*applyModifier)(struct ModifierData *md, const struct EvaluationContext *eval_ctx,
struct Object *ob, struct DerivedMesh *derivedData,
ModifierApplyFlag flag);
@@ -214,7 +214,7 @@ typedef struct ModifierTypeInfo {
* are expected from editmode objects. The same qualifications regarding
* derivedData apply as for applyModifier.
*/
- struct DerivedMesh *(*applyModifierEM)(struct ModifierData *md, struct EvaluationContext *eval_ctx,
+ struct DerivedMesh *(*applyModifierEM)(struct ModifierData *md, const struct EvaluationContext *eval_ctx,
struct Object *ob, struct BMEditMesh *editData,
struct DerivedMesh *derivedData, ModifierApplyFlag flag);
@@ -337,6 +337,7 @@ bool modifier_unique_name(struct ListBase *modifiers, struct ModifierDa
void modifier_copyData_generic(const struct ModifierData *md, struct ModifierData *target);
void modifier_copyData(struct ModifierData *md, struct ModifierData *target);
+void modifier_copyData_ex(struct ModifierData *md, struct ModifierData *target, const int flag);
bool modifier_dependsOnTime(struct ModifierData *md);
bool modifier_supportsMapping(struct ModifierData *md);
bool modifier_supportsCage(struct Scene *scene, struct ModifierData *md);
@@ -419,24 +420,24 @@ const char *modifier_path_relbase(struct Object *ob);
/* wrappers for modifier callbacks */
struct DerivedMesh *modwrap_applyModifier(
- ModifierData *md, struct EvaluationContext *eval_ctx,
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
struct Object *ob, struct DerivedMesh *dm,
ModifierApplyFlag flag);
struct DerivedMesh *modwrap_applyModifierEM(
- ModifierData *md, struct EvaluationContext *eval_ctx,
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
struct Object *ob, struct BMEditMesh *em,
struct DerivedMesh *dm,
ModifierApplyFlag flag);
void modwrap_deformVerts(
- ModifierData *md, struct EvaluationContext *eval_ctx,
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
struct Object *ob, struct DerivedMesh *dm,
float (*vertexCos)[3], int numVerts,
ModifierApplyFlag flag);
void modwrap_deformVertsEM(
- ModifierData *md, struct EvaluationContext *eval_ctx, struct Object *ob,
+ ModifierData *md, const struct EvaluationContext *eval_ctx, struct Object *ob,
struct BMEditMesh *em, struct DerivedMesh *dm,
float (*vertexCos)[3], int numVerts);
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 69fdad5ef7b..3ddf75f204e 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -41,6 +41,7 @@ struct MovieDistortion;
void BKE_movieclip_free(struct MovieClip *clip);
+void BKE_movieclip_copy_data(struct Main *bmain, struct MovieClip *clip_dst, const struct MovieClip *clip_src, const int flag);
struct MovieClip *BKE_movieclip_copy(struct Main *bmain, const struct MovieClip *clip);
void BKE_movieclip_make_local(struct Main *bmain, struct MovieClip *clip, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h
index 5ddc67b7a8c..761bb7e8acb 100644
--- a/source/blender/blenkernel/BKE_multires.h
+++ b/source/blender/blenkernel/BKE_multires.h
@@ -81,18 +81,18 @@ struct DerivedMesh *multires_make_derived_from_derived(struct DerivedMesh *dm,
struct MultiresModifierData *find_multires_modifier_before(struct Scene *scene,
struct ModifierData *lastmd);
struct MultiresModifierData *get_multires_modifier(struct Scene *scene, struct Object *ob, bool use_first);
-struct DerivedMesh *get_multires_dm(struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
+struct DerivedMesh *get_multires_dm(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
struct Object *ob);
void multiresModifier_del_levels(struct MultiresModifierData *, struct Object *, int direction);
void multiresModifier_base_apply(struct MultiresModifierData *mmd, struct Object *ob);
void multiresModifier_subdivide(struct MultiresModifierData *mmd, struct Object *ob, int updateblock, int simple);
void multiresModifier_sync_levels_ex(
struct Object *ob_dst, struct MultiresModifierData *mmd_src, struct MultiresModifierData *mmd_dst);
-int multiresModifier_reshape(struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
+int multiresModifier_reshape(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
struct Object *dst, struct Object *src);
-int multiresModifier_reshapeFromDM(struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
+int multiresModifier_reshapeFromDM(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
struct Object *ob, struct DerivedMesh *srcdm);
-int multiresModifier_reshapeFromDeformMod(struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
+int multiresModifier_reshapeFromDeformMod(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct MultiresModifierData *mmd,
struct Object *ob, struct ModifierData *md);
void multires_stitch_grids(struct Object *);
@@ -110,8 +110,8 @@ void multires_free(struct Multires *mr);
void multires_load_old(struct Object *ob, struct Mesh *me);
void multires_load_old_250(struct Mesh *);
-void multiresModifier_scale_disp(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
-void multiresModifier_prepare_join(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct Object *to_ob);
+void multiresModifier_scale_disp(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
+void multiresModifier_prepare_join(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct Object *to_ob);
int multires_mdisp_corners(struct MDisps *s);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index a668ae9a7af..5e50d37e145 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -336,6 +336,7 @@ struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, const char
/* copy/free funcs, need to manage ID users */
void ntreeFreeTree(struct bNodeTree *ntree);
+void BKE_node_tree_copy_data(struct Main *bmain, struct bNodeTree *ntree_dst, const struct bNodeTree *ntree_src, const int flag);
struct bNodeTree *ntreeCopyTree_ex(const struct bNodeTree *ntree, struct Main *bmain, const bool do_id_user);
struct bNodeTree *ntreeCopyTree(struct Main *bmain, const struct bNodeTree *ntree);
/* node->id user count */
@@ -453,6 +454,7 @@ void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node);
void nodeUniqueName(struct bNodeTree *ntree, struct bNode *node);
void nodeFreeNode(struct bNodeTree *ntree, struct bNode *node);
+struct bNode *BKE_node_copy_ex(struct bNodeTree *ntree, struct bNode *node_src, const int flag);
struct bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node);
struct bNodeLink *nodeAddLink(struct bNodeTree *ntree, struct bNode *fromnode, struct bNodeSocket *fromsock, struct bNode *tonode, struct bNodeSocket *tosock);
@@ -794,9 +796,7 @@ struct ShadeResult;
#define SH_NODE_UVALONGSTROKE 191
#define SH_NODE_TEX_POINTDENSITY 192
#define SH_NODE_BSDF_PRINCIPLED 193
-#define SH_NODE_EEVEE_METALLIC 194
#define SH_NODE_EEVEE_SPECULAR 195
-#define SH_NODE_OUTPUT_EEVEE_MATERIAL 196
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index d763b33b88f..35cde742ff0 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -51,13 +51,13 @@ struct HookModifierData;
struct ModifierData;
void BKE_object_workob_clear(struct Object *workob);
-void BKE_object_workob_calc_parent(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct Object *workob);
+void BKE_object_workob_calc_parent(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct Object *workob);
void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src);
-struct SoftBody *copy_softbody(const struct SoftBody *sb, bool copy_caches);
-struct BulletSoftBody *copy_bulletsoftbody(const struct BulletSoftBody *sb);
-struct ParticleSystem *BKE_object_copy_particlesystem(struct ParticleSystem *psys);
-void BKE_object_copy_particlesystems(struct Object *ob_dst, const struct Object *ob_src);
+struct SoftBody *copy_softbody(const struct SoftBody *sb, const int flag);
+struct BulletSoftBody *copy_bulletsoftbody(const struct BulletSoftBody *sb, const int flag);
+struct ParticleSystem *BKE_object_copy_particlesystem(struct ParticleSystem *psys, const int flag);
+void BKE_object_copy_particlesystems(struct Object *ob_dst, const struct Object *ob_src, const int flag);
void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src);
void BKE_object_free_particlesystems(struct Object *ob);
void BKE_object_free_softbody(struct Object *ob);
@@ -106,7 +106,7 @@ bool BKE_object_lod_is_usable(struct Object *ob, struct SceneLayer *sl);
struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct SceneLayer *sl);
struct Object *BKE_object_lod_matob_get(struct Object *ob, struct SceneLayer *sl);
-struct Object *BKE_object_copy_ex(struct Main *bmain, const struct Object *ob, bool copy_caches);
+void BKE_object_copy_data(struct Main *bmain, struct Object *ob_dst, const struct Object *ob_src, const int flag);
struct Object *BKE_object_copy(struct Main *bmain, const struct Object *ob);
void BKE_object_make_local(struct Main *bmain, struct Object *ob, const bool lib_local);
void BKE_object_make_local_ex(struct Main *bmain, struct Object *ob, const bool lib_local, const bool clear_proxy);
@@ -128,10 +128,10 @@ struct Object *BKE_object_pose_armature_get(struct Object *ob);
void BKE_object_get_parent_matrix(struct Scene *scene, struct Object *ob,
struct Object *par, float parentmat[4][4]);
-void BKE_object_where_is_calc(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
-void BKE_object_where_is_calc_ex(struct EvaluationContext *eval_ctx, struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob, float r_originmat[3][3]);
-void BKE_object_where_is_calc_time(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
-void BKE_object_where_is_calc_time_ex(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime,
+void BKE_object_where_is_calc(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
+void BKE_object_where_is_calc_ex(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct RigidBodyWorld *rbw, struct Object *ob, float r_originmat[3][3]);
+void BKE_object_where_is_calc_time(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
+void BKE_object_where_is_calc_time_ex(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime,
struct RigidBodyWorld *rbw, float r_originmat[3][3]);
void BKE_object_where_is_calc_mat4(struct Scene *scene, struct Object *ob, float obmat[4][4]);
@@ -179,39 +179,43 @@ void BKE_object_tfm_protected_restore(struct Object *ob,
const short protectflag);
/* Dependency graph evaluation callbacks. */
-void BKE_object_eval_local_transform(struct EvaluationContext *eval_ctx,
+void BKE_object_eval_local_transform(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
-void BKE_object_eval_parent(struct EvaluationContext *eval_ctx,
+void BKE_object_eval_parent(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
-void BKE_object_eval_constraints(struct EvaluationContext *eval_ctx,
+void BKE_object_eval_constraints(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
-void BKE_object_eval_done(struct EvaluationContext *eval_ctx, struct Object *ob);
+void BKE_object_eval_done(const struct EvaluationContext *eval_ctx, struct Object *ob);
-void BKE_object_eval_uber_transform(struct EvaluationContext *eval_ctx,
+void BKE_object_eval_uber_transform(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
-void BKE_object_eval_uber_data(struct EvaluationContext *eval_ctx,
+void BKE_object_eval_uber_data(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
-void BKE_object_eval_cloth(struct EvaluationContext *eval_ctx,
+void BKE_object_eval_cloth(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *object);
-void BKE_object_eval_update_shading(struct EvaluationContext *eval_ctx,
+void BKE_object_eval_update_shading(const struct EvaluationContext *eval_ctx,
struct Object *object);
-void BKE_object_handle_data_update(struct EvaluationContext *eval_ctx,
- struct Scene *scene,
- struct Object *ob);
-void BKE_object_handle_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
-void BKE_object_handle_update_ex(struct EvaluationContext *eval_ctx,
- struct Scene *scene, struct Object *ob,
- struct RigidBodyWorld *rbw,
- const bool do_proxy_update);
+void BKE_object_handle_data_update(
+ const struct EvaluationContext *eval_ctx,
+ struct Scene *scene,
+ struct Object *ob);
+void BKE_object_handle_update(
+ const struct EvaluationContext *eval_ctx,
+ struct Scene *scene, struct Object *ob);
+void BKE_object_handle_update_ex(
+ const struct EvaluationContext *eval_ctx,
+ struct Scene *scene, struct Object *ob,
+ struct RigidBodyWorld *rbw,
+ const bool do_proxy_update);
void BKE_object_sculpt_modifiers_changed(struct Object *ob);
int BKE_object_obdata_texspace_get(struct Object *ob, short **r_texflag, float **r_loc, float **r_size, float **r_rot);
@@ -262,7 +266,7 @@ struct KDTree *BKE_object_as_kdtree(struct Object *ob, int *r_tot);
bool BKE_object_modifier_use_time(struct Object *ob, struct ModifierData *md);
-bool BKE_object_modifier_update_subframe(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+bool BKE_object_modifier_update_subframe(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
bool update_mesh, int parent_recursion, float frame, int type);
#ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index e9287465528..3f4941f222e 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -101,6 +101,8 @@ void BKE_paint_set_overlay_override(enum OverlayFlags flag);
/* palettes */
void BKE_palette_free(struct Palette *palette);
struct Palette *BKE_palette_add(struct Main *bmain, const char *name);
+void BKE_palette_copy_data(
+ struct Main *bmain, struct Palette *palette_dst, const struct Palette *palette_src, const int flag);
struct Palette *BKE_palette_copy(struct Main *bmain, const struct Palette *palette);
void BKE_palette_make_local(struct Main *bmain, struct Palette *palette, const bool lib_local);
struct PaletteColor *BKE_palette_color_add(struct Palette *palette);
@@ -111,12 +113,14 @@ void BKE_palette_clear(struct Palette *palette);
/* paint curves */
struct PaintCurve *BKE_paint_curve_add(struct Main *bmain, const char *name);
void BKE_paint_curve_free(struct PaintCurve *pc);
+void BKE_paint_curve_copy_data(
+ struct Main *bmain, struct PaintCurve *pc_dst, const struct PaintCurve *pc_src, const int flag);
struct PaintCurve *BKE_paint_curve_copy(struct Main *bmain, const struct PaintCurve *pc);
void BKE_paint_curve_make_local(struct Main *bmain, struct PaintCurve *pc, const bool lib_local);
void BKE_paint_init(struct Scene *sce, PaintMode mode, const char col[3]);
void BKE_paint_free(struct Paint *p);
-void BKE_paint_copy(struct Paint *src, struct Paint *tar);
+void BKE_paint_copy(struct Paint *src, struct Paint *tar, const int flag);
void BKE_paint_cavity_curve_preset(struct Paint *p, int preset);
@@ -209,8 +213,9 @@ void BKE_sculptsession_free(struct Object *ob);
void BKE_sculptsession_free_deformMats(struct SculptSession *ss);
void BKE_sculptsession_bm_to_me(struct Object *ob, bool reorder);
void BKE_sculptsession_bm_to_me_for_render(struct Object *object);
-void BKE_sculpt_update_mesh_elements(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Sculpt *sd, struct Object *ob,
- bool need_pmap, bool need_mask);
+void BKE_sculpt_update_mesh_elements(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Sculpt *sd, struct Object *ob,
+ bool need_pmap, bool need_mask);
struct MultiresModifierData *BKE_sculpt_multires_active(struct Scene *scene, struct Object *ob);
int BKE_sculpt_mask_layers_ensure(struct Object *ob,
struct MultiresModifierData *mmd);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 52922271689..ae103e613a4 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -78,7 +78,7 @@ struct EvaluationContext;
/* common stuff that many particle functions need */
typedef struct ParticleSimulationData {
- struct EvaluationContext *eval_ctx;
+ const struct EvaluationContext *eval_ctx;
struct Scene *scene;
struct Object *ob;
struct ParticleSystem *psys;
@@ -326,6 +326,9 @@ struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct P
struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name);
void object_remove_particle_system(struct Scene *scene, struct Object *ob);
struct ParticleSettings *psys_new_settings(const char *name, struct Main *main);
+void BKE_particlesettings_copy_data(
+ struct Main *bmain, struct ParticleSettings *part_dst, const struct ParticleSettings *part_src,
+ const int flag);
struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain, const struct ParticleSettings *part);
void BKE_particlesettings_make_local(struct Main *bmain, struct ParticleSettings *part, const bool lib_local);
@@ -334,9 +337,9 @@ void psys_reset(struct ParticleSystem *psys, int mode);
void psys_find_parents(struct ParticleSimulationData *sim, const bool use_render_params);
void psys_cache_paths(struct ParticleSimulationData *sim, float cfra, const bool use_render_params);
-void psys_cache_edit_paths(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra, const bool use_render_params);
+void psys_cache_edit_paths(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct PTCacheEdit *edit, float cfra, const bool use_render_params);
void psys_cache_child_paths(struct ParticleSimulationData *sim, float cfra, const bool editupdate, const bool use_render_params);
-int do_guides(struct EvaluationContext *eval_ctx, struct ParticleSettings *part, struct ListBase *effectors, ParticleKey *state, int pa_num, float time);
+int do_guides(const struct EvaluationContext *eval_ctx, struct ParticleSettings *part, struct ListBase *effectors, ParticleKey *state, int pa_num, float time);
void precalc_guides(struct ParticleSimulationData *sim, struct ListBase *effectors);
float psys_get_timestep(struct ParticleSimulationData *sim);
float psys_get_child_time(struct ParticleSystem *psys, struct ChildParticle *cpa, float cfra, float *birthtime, float *dietime);
@@ -368,7 +371,7 @@ void psys_tasks_create(struct ParticleThreadContext *ctx, int startpart, int end
void psys_tasks_free(struct ParticleTask *tasks, int numtasks);
void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3], float zvec[3], float center[3]);
-void psys_apply_hair_lattice(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
+void psys_apply_hair_lattice(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys);
/* particle_system.c */
struct ParticleSystem *psys_get_target_system(struct Object *ob, struct ParticleTarget *pt);
@@ -383,7 +386,7 @@ void psys_check_boid_data(struct ParticleSystem *psys);
void psys_get_birth_coords(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleKey *state, float dtime, float cfra);
-void particle_system_update(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, const bool use_render_params);
+void particle_system_update(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct ParticleSystem *psys, const bool use_render_params);
/* Callback format for performing operations on ID-pointers for particle systems */
typedef void (*ParticleSystemIDFunc)(struct ParticleSystem *psys, struct ID **idpoin, void *userdata, int cb_flag);
@@ -476,12 +479,12 @@ typedef struct ParticleRenderData {
struct EvaluationContext;
-void BKE_particle_system_settings_eval(struct EvaluationContext *eval_ctx,
+void BKE_particle_system_settings_eval(const struct EvaluationContext *eval_ctx,
struct ParticleSystem *psys);
void BKE_particle_system_settings_recalc_clear(struct EvaluationContext *UNUSED(eval_ctx),
struct ParticleSettings *particle_settings);
-void BKE_particle_system_eval_init(struct EvaluationContext *eval_ctx,
+void BKE_particle_system_eval_init(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_pointcache.h b/source/blender/blenkernel/BKE_pointcache.h
index 02f6c435ee2..f0819c8d79d 100644
--- a/source/blender/blenkernel/BKE_pointcache.h
+++ b/source/blender/blenkernel/BKE_pointcache.h
@@ -314,7 +314,7 @@ struct PointCache *BKE_ptcache_add(struct ListBase *ptcaches);
void BKE_ptcache_free_mem(struct ListBase *mem_cache);
void BKE_ptcache_free(struct PointCache *cache);
void BKE_ptcache_free_list(struct ListBase *ptcaches);
-struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const struct ListBase *ptcaches_old, bool copy_data);
+struct PointCache *BKE_ptcache_copy_list(struct ListBase *ptcaches_new, const struct ListBase *ptcaches_old, const int flag);
/********************** Baking *********************/
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index 41e2a117eeb..6aa43665427 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -50,8 +50,8 @@ void BKE_rigidbody_free_constraint(struct Object *ob);
/* ...... */
-struct RigidBodyOb *BKE_rigidbody_copy_object(const struct Object *ob);
-struct RigidBodyCon *BKE_rigidbody_copy_constraint(const struct Object *ob);
+struct RigidBodyOb *BKE_rigidbody_copy_object(const struct Object *ob, const int flag);
+struct RigidBodyCon *BKE_rigidbody_copy_constraint(const struct Object *ob, const int flag);
/* Callback format for performing operations on ID-pointers for rigidbody world. */
typedef void (*RigidbodyWorldIDFunc)(struct RigidBodyWorld *rbw, struct ID **idpoin, void *userdata, int cb_flag);
@@ -67,7 +67,7 @@ struct RigidBodyOb *BKE_rigidbody_create_object(struct Scene *scene, struct Obje
struct RigidBodyCon *BKE_rigidbody_create_constraint(struct Scene *scene, struct Object *ob, short type);
/* copy */
-struct RigidBodyWorld *BKE_rigidbody_world_copy(struct RigidBodyWorld *rbw);
+struct RigidBodyWorld *BKE_rigidbody_world_copy(struct RigidBodyWorld *rbw, const int flag);
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw);
/* 'validate' (i.e. make new or replace old) Physics-Engine objects */
@@ -100,19 +100,19 @@ void BKE_rigidbody_aftertrans_update(struct Object *ob, float loc[3], float rot[
void BKE_rigidbody_sync_transforms(struct RigidBodyWorld *rbw, struct Object *ob, float ctime);
bool BKE_rigidbody_check_sim_running(struct RigidBodyWorld *rbw, float ctime);
void BKE_rigidbody_cache_reset(struct RigidBodyWorld *rbw);
-void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, struct Scene *scene, float ctime);
-void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, struct Scene *scene, float ctime);
+void BKE_rigidbody_rebuild_world(const struct EvaluationContext *eval_ctx, struct Scene *scene, float ctime);
+void BKE_rigidbody_do_simulation(const struct EvaluationContext *eval_ctx, struct Scene *scene, float ctime);
/* -------------------- */
/* Depsgraph evaluation */
-void BKE_rigidbody_rebuild_sim(struct EvaluationContext *eval_ctx,
+void BKE_rigidbody_rebuild_sim(const struct EvaluationContext *eval_ctx,
struct Scene *scene);
-void BKE_rigidbody_eval_simulation(struct EvaluationContext *eval_ctx,
+void BKE_rigidbody_eval_simulation(const struct EvaluationContext *eval_ctx,
struct Scene *scene);
-void BKE_rigidbody_object_sync_transforms(struct EvaluationContext *eval_ctx,
+void BKE_rigidbody_object_sync_transforms(const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_sca.h b/source/blender/blenkernel/BKE_sca.h
index 10cddd7b454..35bcd91a9b1 100644
--- a/source/blender/blenkernel/BKE_sca.h
+++ b/source/blender/blenkernel/BKE_sca.h
@@ -52,16 +52,16 @@ void free_actuators(struct ListBase *lb);
void free_sensor(struct bSensor *sens);
void free_sensors(struct ListBase *lb);
-struct bSensor *copy_sensor(struct bSensor *sens);
-void copy_sensors(struct ListBase *lbn, const struct ListBase *lbo);
+struct bSensor *copy_sensor(struct bSensor *sens, const int flag);
+void copy_sensors(struct ListBase *lbn, const struct ListBase *lbo, const int flag);
void init_sensor(struct bSensor *sens);
struct bSensor *new_sensor(int type);
-struct bController *copy_controller(struct bController *cont);
-void copy_controllers(struct ListBase *lbn, const struct ListBase *lbo);
+struct bController *copy_controller(struct bController *cont, const int flag);
+void copy_controllers(struct ListBase *lbn, const struct ListBase *lbo, const int flag);
void init_controller(struct bController *cont);
struct bController *new_controller(int type);
-struct bActuator *copy_actuator(struct bActuator *act);
-void copy_actuators(struct ListBase *lbn, const struct ListBase *lbo);
+struct bActuator *copy_actuator(struct bActuator *act, const int flag);
+void copy_actuators(struct ListBase *lbn, const struct ListBase *lbo, const int flag);
void init_actuator(struct bActuator *act);
struct bActuator *new_actuator(int type);
void clear_sca_new_poins_ob(struct Object *ob);
@@ -70,7 +70,7 @@ void set_sca_new_poins_ob(struct Object *ob);
void set_sca_new_poins(void);
void BKE_sca_logic_links_remap(struct Main *bmain, struct Object *ob_old, struct Object *ob_new);
-void BKE_sca_logic_copy(struct Object *ob_new, const struct Object *ob);
+void BKE_sca_logic_copy(struct Object *ob_new, const struct Object *ob, const int flag);
void sca_move_sensor(struct bSensor *sens_to_move, struct Object *ob, int move_up);
void sca_move_controller(struct bController *cont_to_move, struct Object *ob, int move_up);
diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h
index 6ca79d8c7cd..d0c913d7235 100644
--- a/source/blender/blenkernel/BKE_scene.h
+++ b/source/blender/blenkernel/BKE_scene.h
@@ -99,8 +99,9 @@ typedef struct SceneBaseIter {
int phase;
} SceneBaseIter;
-int BKE_scene_base_iter_next(struct EvaluationContext *eval_ctx, struct SceneBaseIter *iter,
- struct Scene **scene, int val, struct BaseLegacy **base, struct Object **ob);
+int BKE_scene_base_iter_next(
+ const struct EvaluationContext *eval_ctx, struct SceneBaseIter *iter,
+ struct Scene **scene, int val, struct BaseLegacy **base, struct Object **ob);
void BKE_scene_base_flag_to_objects(struct SceneLayer *sl);
void BKE_scene_base_flag_from_objects(struct Scene *scene);
@@ -112,6 +113,7 @@ void BKE_scene_object_base_flag_sync_from_object(struct Base *base);
void BKE_scene_set_background(struct Main *bmain, struct Scene *sce);
struct Scene *BKE_scene_set_name(struct Main *bmain, const char *name);
+void BKE_scene_copy_data(struct Main *bmain, struct Scene *sce_dst, const struct Scene *sce_src, const int flag);
struct Scene *BKE_scene_copy(struct Main *bmain, struct Scene *sce, int type);
void BKE_scene_groups_relink(struct Scene *sce);
@@ -167,6 +169,8 @@ bool BKE_scene_check_rigidbody_active(const struct Scene *scene);
int BKE_scene_num_threads(const struct Scene *scene);
int BKE_render_num_threads(const struct RenderData *r);
+int BKE_render_preview_pixel_size(const struct RenderData *r);
+
double BKE_scene_unit_scale(const struct UnitSettings *unit, const int unit_type, double value);
/* multiview */
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index 5a2c49f5527..bcc06a4ab25 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -335,7 +335,8 @@ bool BKE_sequence_base_shuffle(
bool BKE_sequence_base_shuffle_time(ListBase *seqbasep, struct Scene *evil_scene);
bool BKE_sequence_base_isolated_sel_check(struct ListBase *seqbase);
void BKE_sequencer_free_imbuf(struct Scene *scene, struct ListBase *seqbasep, bool for_render);
-struct Sequence *BKE_sequence_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence *seq, int dupe_flag);
+struct Sequence *BKE_sequence_dupli_recursive(
+ const struct Scene *scene_src, struct Scene *scene_dst, struct Sequence *seq, int dupe_flag);
int BKE_sequence_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
bool BKE_sequence_check_depend(struct Sequence *seq, struct Sequence *cur);
@@ -352,8 +353,8 @@ void BKE_sequencer_refresh_sound_length(struct Scene *scene);
void BKE_sequence_base_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq);
void BKE_sequence_base_dupli_recursive(
- struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase,
- int dupe_flag);
+ const struct Scene *scene_src, struct Scene *scene_dst, struct ListBase *nseqbase, const struct ListBase *seqbase,
+ int dupe_flag, const int flag);
bool BKE_sequence_is_valid_check(struct Sequence *seq);
void BKE_sequencer_clear_scene_in_allseqs(struct Main *bmain, struct Scene *sce);
@@ -421,7 +422,7 @@ struct Sequence *BKE_sequencer_add_movie_strip(struct bContext *C, ListBase *seq
/* view3d draw callback, run when not in background view */
typedef struct ImBuf *(*SequencerDrawView)(
- struct EvaluationContext *eval_ctx, struct Scene *, struct SceneLayer *sl, struct Object *, int, int,
+ const struct EvaluationContext *eval_ctx, struct Scene *, struct SceneLayer *sl, struct Object *, int, int,
unsigned int, int, bool, bool, bool,
int, int, bool, const char *,
struct GPUFX *, struct GPUOffScreen *, char[256]);
diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h
index 40b349c9cbc..64d70e8e209 100644
--- a/source/blender/blenkernel/BKE_smoke.h
+++ b/source/blender/blenkernel/BKE_smoke.h
@@ -35,7 +35,7 @@
typedef float (*bresenham_callback)(float *result, float *input, int res[3], int *pixel, float *tRay, float correct);
-struct DerivedMesh *smokeModifier_do(struct SmokeModifierData *smd, struct EvaluationContext *eval_ctx,
+struct DerivedMesh *smokeModifier_do(struct SmokeModifierData *smd, const struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob, struct DerivedMesh *dm);
diff --git a/source/blender/blenkernel/BKE_softbody.h b/source/blender/blenkernel/BKE_softbody.h
index 89aaf4b39ec..e2255bdb779 100644
--- a/source/blender/blenkernel/BKE_softbody.h
+++ b/source/blender/blenkernel/BKE_softbody.h
@@ -60,7 +60,7 @@ extern void sbFree(struct SoftBody *sb);
extern void sbFreeSimulation(struct SoftBody *sb);
/* do one simul step, reading and writing vertex locs from given array */
-extern void sbObjectStep(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+extern void sbObjectStep(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
float framnr, float (*vertexCos)[3], int numVerts);
/* makes totally fresh start situation, resets time */
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index a5c626e74d7..98fb4f47339 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -35,8 +35,8 @@
#define SOUND_WAVE_SAMPLES_PER_SECOND 250
-#ifdef WITH_SYSTEM_AUDASPACE
-# include AUD_DEVICE_H
+#if defined(WITH_AUDASPACE)
+# include <AUD_Device.h>
#endif
struct bSound;
@@ -80,9 +80,11 @@ void BKE_sound_load(struct Main *main, struct bSound *sound);
void BKE_sound_free(struct bSound *sound);
+void BKE_sound_copy_data(struct Main *bmain, struct bSound *sound_dst, const struct bSound *sound_src, const int flag);
+
void BKE_sound_make_local(struct Main *bmain, struct bSound *sound, const bool lib_local);
-#if defined(__AUD_C_API_H__) || defined(WITH_SYSTEM_AUDASPACE)
+#if defined(WITH_AUDASPACE)
AUD_Device *BKE_sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume);
#endif
@@ -147,6 +149,4 @@ float BKE_sound_get_length(struct bSound *sound);
char **BKE_sound_get_device_names(void);
-bool BKE_sound_is_jack_supported(void);
-
#endif /* __BKE_SOUND_H__ */
diff --git a/source/blender/blenkernel/BKE_speaker.h b/source/blender/blenkernel/BKE_speaker.h
index 907558f9203..57f4c37f129 100644
--- a/source/blender/blenkernel/BKE_speaker.h
+++ b/source/blender/blenkernel/BKE_speaker.h
@@ -33,6 +33,7 @@ struct Speaker;
void BKE_speaker_init(struct Speaker *spk);
void *BKE_speaker_add(struct Main *bmain, const char *name);
+void BKE_speaker_copy_data(struct Main *bmain, struct Speaker *spk_dst, const struct Speaker *spk_src, const int flag);
struct Speaker *BKE_speaker_copy(struct Main *bmain, const struct Speaker *spk);
void BKE_speaker_make_local(struct Main *bmain, struct Speaker *spk, const bool lib_local);
void BKE_speaker_free(struct Speaker *spk);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index c8fb483cdf2..14d3318e059 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -52,6 +52,7 @@ bool BKE_text_reload(struct Text *text);
struct Text *BKE_text_load_ex(struct Main *bmain, const char *file, const char *relpath,
const bool is_internal);
struct Text *BKE_text_load (struct Main *bmain, const char *file, const char *relpath);
+void BKE_text_copy_data(struct Main *bmain, struct Text *ta_dst, const struct Text *ta_src, const int flag);
struct Text *BKE_text_copy (struct Main *bmain, const struct Text *ta);
void BKE_text_make_local (struct Main *bmain, struct Text *text, const bool lib_local);
void BKE_text_clear (struct Text *text);
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 190fdeafaec..8a9171673ea 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -70,6 +70,7 @@ void colorband_update_sort(struct ColorBand *coba);
void BKE_texture_free(struct Tex *tex);
void BKE_texture_default(struct Tex *tex);
+void BKE_texture_copy_data(struct Main *bmain, struct Tex *tex_dst, const struct Tex *tex_src, const int flag);
struct Tex *BKE_texture_copy(struct Main *bmain, const struct Tex *tex);
struct Tex *BKE_texture_add(struct Main *bmain, const char *name);
struct Tex *BKE_texture_localize(struct Tex *tex);
@@ -114,13 +115,13 @@ void BKE_texture_colormapping_default(struct ColorMapping *color
void BKE_texture_envmap_free_data(struct EnvMap *env);
void BKE_texture_envmap_free(struct EnvMap *env);
struct EnvMap *BKE_texture_envmap_add(void);
-struct EnvMap *BKE_texture_envmap_copy(const struct EnvMap *env);
+struct EnvMap *BKE_texture_envmap_copy(const struct EnvMap *env, const int flag);
void BKE_texture_pointdensity_init_data(struct PointDensity *pd);
void BKE_texture_pointdensity_free_data(struct PointDensity *pd);
void BKE_texture_pointdensity_free(struct PointDensity *pd);
struct PointDensity *BKE_texture_pointdensity_add(void);
-struct PointDensity *BKE_texture_pointdensity_copy(const struct PointDensity *pd);
+struct PointDensity *BKE_texture_pointdensity_copy(const struct PointDensity *pd, const int flag);
void BKE_texture_voxeldata_free_data(struct VoxelData *vd);
void BKE_texture_voxeldata_free(struct VoxelData *vd);
@@ -129,7 +130,7 @@ struct VoxelData *BKE_texture_voxeldata_copy(struct VoxelData *vd);
void BKE_texture_ocean_free(struct OceanTex *ot);
struct OceanTex *BKE_texture_ocean_add(void);
-struct OceanTex *BKE_texture_ocean_copy(const struct OceanTex *ot);
+struct OceanTex *BKE_texture_ocean_copy(const struct OceanTex *ot, const int flag);
bool BKE_texture_dependsOnTime(const struct Tex *texture);
bool BKE_texture_is_image_user(const struct Tex *tex);
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index d149654fc82..b4ca1b79238 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -53,7 +53,7 @@ struct rcti;
/* **** Common functions **** */
void BKE_tracking_free(struct MovieTracking *tracking);
-void BKE_tracking_copy(struct MovieTracking *tracking_dst, const struct MovieTracking *tracking_src);
+void BKE_tracking_copy(struct MovieTracking *tracking_dst, const struct MovieTracking *tracking_src, const int flag);
void BKE_tracking_settings_init(struct MovieTracking *tracking);
diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h
index 5175edcd3d6..ea0cd125b06 100644
--- a/source/blender/blenkernel/BKE_world.h
+++ b/source/blender/blenkernel/BKE_world.h
@@ -39,6 +39,7 @@ struct World;
void BKE_world_free(struct World *sc);
void BKE_world_init(struct World *wrld);
struct World *add_world(struct Main *bmian, const char *name);
+void BKE_world_copy_data(struct Main *bmain, struct World *wrld_dst, const struct World *wrld_src, const int flag);
struct World *BKE_world_copy(struct Main *bmain, const struct World *wrld);
struct World *localize_world(struct World *wrld);
void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local);
@@ -47,7 +48,7 @@ void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib
struct EvaluationContext;
-void BKE_world_eval(struct EvaluationContext *eval_ctx, struct World *world);
+void BKE_world_eval(const struct EvaluationContext *eval_ctx, struct World *world);
#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index 7fbf33fb255..55fbb9d0c38 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -340,7 +340,7 @@ if(WIN32)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 7b3eebb45dc..309fcad0d0a 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -96,6 +96,10 @@ static DerivedMesh *navmesh_dm_createNavMeshForVisualization(DerivedMesh *dm);
# define ASSERT_IS_VALID_DM(dm)
#endif
+
+static ThreadMutex loops_cache_lock = BLI_MUTEX_INITIALIZER;
+
+
static void add_shapekey_layers(DerivedMesh *dm, Mesh *me, Object *ob);
static void shapekey_layers_to_keyblocks(DerivedMesh *dm, Mesh *me, int actshape_uid);
@@ -238,6 +242,23 @@ static int dm_getNumLoopTri(DerivedMesh *dm)
return numlooptris;
}
+static const MLoopTri *dm_getLoopTriArray(DerivedMesh *dm)
+{
+ if (dm->looptris.array) {
+ BLI_assert(dm->getNumLoopTri(dm) == dm->looptris.num);
+ }
+ else {
+ BLI_mutex_lock(&loops_cache_lock);
+ /* We need to ensure array is still NULL inside mutex-protected code, some other thread might have already
+ * recomputed those looptris. */
+ if (dm->looptris.array == NULL) {
+ dm->recalcLoopTri(dm);
+ }
+ BLI_mutex_unlock(&loops_cache_lock);
+ }
+ return dm->looptris.array;
+}
+
static CustomData *dm_getVertCData(DerivedMesh *dm)
{
return &dm->vertData;
@@ -281,6 +302,8 @@ void DM_init_funcs(DerivedMesh *dm)
dm->dupLoopArray = dm_dupLoopArray;
dm->dupPolyArray = dm_dupPolyArray;
+ dm->getLoopTriArray = dm_getLoopTriArray;
+
/* subtypes handle getting actual data */
dm->getNumLoopTri = dm_getNumLoopTri;
@@ -501,19 +524,6 @@ void DM_ensure_looptri_data(DerivedMesh *dm)
}
}
-/**
- * The purpose of this function is that we can call:
- * `dm->getLoopTriArray(dm)` and get the array returned.
- */
-void DM_ensure_looptri(DerivedMesh *dm)
-{
- const int numPolys = dm->getNumPolys(dm);
-
- if ((dm->looptris.num == 0) && (numPolys != 0)) {
- dm->recalcLoopTri(dm);
- }
-}
-
void DM_verttri_from_looptri(MVertTri *verttri, const MLoop *mloop, const MLoopTri *looptri, int looptri_num)
{
int i;
@@ -1126,7 +1136,7 @@ DerivedMesh *mesh_create_derived(Mesh *me, float (*vertCos)[3])
}
DerivedMesh *mesh_create_derived_for_modifier(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
ModifierData *md, int build_shapekey_layers)
{
Mesh *me = ob->data;
@@ -1732,7 +1742,7 @@ static void dm_ensure_display_normals(DerivedMesh *dm)
* - apply deform modifiers and input vertexco
*/
static void mesh_calc_modifiers(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (*inputVertexCos)[3],
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (*inputVertexCos)[3],
const bool useRenderParams, int useDeform,
const bool need_mapping, CustomDataMask dataMask,
const int index, const bool useCache, const bool build_shapekey_layers,
@@ -2203,7 +2213,6 @@ static void mesh_calc_modifiers(
if (dataMask & CD_MASK_MFACE) {
DM_ensure_tessface(finaldm);
}
- DM_ensure_looptri(finaldm);
/* without this, drawing ngon tri's faces will show ugly tessellated face
* normals and will also have to calculate normals on the fly, try avoid
@@ -2288,7 +2297,7 @@ bool editbmesh_modifier_is_enabled(Scene *scene, ModifierData *md, DerivedMesh *
}
static void editbmesh_calc_modifiers(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
BMEditMesh *em, CustomDataMask dataMask,
/* return args */
DerivedMesh **r_cage, DerivedMesh **r_final)
@@ -2618,7 +2627,7 @@ static bool calc_modifiers_skip_orco(Scene *scene,
#endif
static void mesh_build_data(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask,
const bool build_shapekey_layers, const bool need_mapping)
{
BLI_assert(ob->type == OB_MESH);
@@ -2654,7 +2663,9 @@ static void mesh_build_data(
BLI_assert(!(ob->derivedFinal->dirty & DM_DIRTY_NORMALS));
}
-static void editbmesh_build_data(struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
+static void editbmesh_build_data(
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
{
BKE_object_free_derived_caches(obedit);
BKE_object_sculpt_modifiers_changed(obedit);
@@ -2721,7 +2732,7 @@ static CustomDataMask object_get_datamask(const Scene *scene, Object *ob, bool *
}
void makeDerivedMesh(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em,
CustomDataMask dataMask, const bool build_shapekey_layers)
{
bool need_mapping;
@@ -2737,7 +2748,8 @@ void makeDerivedMesh(
/***/
-DerivedMesh *mesh_get_derived_final(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
+DerivedMesh *mesh_get_derived_final(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
@@ -2756,7 +2768,7 @@ DerivedMesh *mesh_get_derived_final(struct EvaluationContext *eval_ctx, Scene *s
return ob->derivedFinal;
}
-DerivedMesh *mesh_get_derived_deform(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
+DerivedMesh *mesh_get_derived_deform(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
@@ -2775,7 +2787,7 @@ DerivedMesh *mesh_get_derived_deform(struct EvaluationContext *eval_ctx, Scene *
return ob->derivedDeform;
}
-DerivedMesh *mesh_create_derived_render(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
+DerivedMesh *mesh_create_derived_render(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2786,7 +2798,7 @@ DerivedMesh *mesh_create_derived_render(struct EvaluationContext *eval_ctx, Scen
return final;
}
-DerivedMesh *mesh_create_derived_index_render(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask, int index)
+DerivedMesh *mesh_create_derived_index_render(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, CustomDataMask dataMask, int index)
{
DerivedMesh *final;
@@ -2798,7 +2810,7 @@ DerivedMesh *mesh_create_derived_index_render(struct EvaluationContext *eval_ctx
}
DerivedMesh *mesh_create_derived_view(
- struct EvaluationContext *eval_ctx, Scene *scene,
+ const struct EvaluationContext *eval_ctx, Scene *scene,
Object *ob, CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2819,7 +2831,7 @@ DerivedMesh *mesh_create_derived_view(
}
DerivedMesh *mesh_create_derived_no_deform(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
float (*vertCos)[3], CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2832,7 +2844,7 @@ DerivedMesh *mesh_create_derived_no_deform(
}
DerivedMesh *mesh_create_derived_no_virtual(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
float (*vertCos)[3], CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2845,7 +2857,7 @@ DerivedMesh *mesh_create_derived_no_virtual(
}
DerivedMesh *mesh_create_derived_physics(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob,
float (*vertCos)[3], CustomDataMask dataMask)
{
DerivedMesh *final;
@@ -2858,7 +2870,7 @@ DerivedMesh *mesh_create_derived_physics(
}
DerivedMesh *mesh_create_derived_no_deform_render(
- struct EvaluationContext *eval_ctx, Scene *scene,
+ const struct EvaluationContext *eval_ctx, Scene *scene,
Object *ob, float (*vertCos)[3],
CustomDataMask dataMask)
{
@@ -2874,7 +2886,7 @@ DerivedMesh *mesh_create_derived_no_deform_render(
/***/
DerivedMesh *editbmesh_get_derived_cage_and_final(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em,
CustomDataMask dataMask,
/* return args */
DerivedMesh **r_final)
@@ -2895,7 +2907,9 @@ DerivedMesh *editbmesh_get_derived_cage_and_final(
return em->derivedCage;
}
-DerivedMesh *editbmesh_get_derived_cage(struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em, CustomDataMask dataMask)
+DerivedMesh *editbmesh_get_derived_cage(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit, BMEditMesh *em,
+ CustomDataMask dataMask)
{
/* if there's no derived mesh or the last data mask used doesn't include
* the data we need, rebuild the derived mesh
@@ -3951,35 +3965,3 @@ MFace *DM_get_tessface_array(DerivedMesh *dm, bool *r_allocated)
return mface;
}
-
-const MLoopTri *DM_get_looptri_array(
- DerivedMesh *dm,
- const MVert *mvert,
- const MPoly *mpoly, int mpoly_len,
- const MLoop *mloop, int mloop_len,
- bool *r_allocated)
-{
- const MLoopTri *looptri = dm->getLoopTriArray(dm);
- *r_allocated = false;
-
- if (looptri == NULL) {
- if (mpoly_len > 0) {
- const int looptris_num = poly_to_tri_count(mpoly_len, mloop_len);
- MLoopTri *looptri_data;
-
- looptri_data = MEM_mallocN(sizeof(MLoopTri) * looptris_num, __func__);
-
- BKE_mesh_recalc_looptri(
- mloop, mpoly,
- mvert,
- mloop_len, mpoly_len,
- looptri_data);
-
- looptri = looptri_data;
-
- *r_allocated = true;
- }
- }
-
- return looptri;
-}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 8a94d4b8666..00b9e0a283b 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -89,7 +89,7 @@ bAction *add_empty_action(Main *bmain, const char name[])
{
bAction *act;
- act = BKE_libblock_alloc(bmain, ID_AC, name);
+ act = BKE_libblock_alloc(bmain, ID_AC, name, 0);
return act;
}
@@ -121,46 +121,56 @@ void BKE_action_free(bAction *act)
/* .................................. */
-bAction *BKE_action_copy(Main *bmain, const bAction *src)
+/**
+ * Only copy internal data of Action ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_action_copy_data(Main *UNUSED(bmain), bAction *act_dst, const bAction *act_src, const int UNUSED(flag))
{
- bAction *dst = NULL;
- bActionGroup *dgrp, *sgrp;
- FCurve *dfcu, *sfcu;
-
- if (src == NULL)
- return NULL;
- dst = BKE_libblock_copy(bmain, &src->id);
-
+ bActionGroup *grp_dst, *grp_src;
+ FCurve *fcu_dst, *fcu_src;
+
/* duplicate the lists of groups and markers */
- BLI_duplicatelist(&dst->groups, &src->groups);
- BLI_duplicatelist(&dst->markers, &src->markers);
-
+ BLI_duplicatelist(&act_dst->groups, &act_src->groups);
+ BLI_duplicatelist(&act_dst->markers, &act_src->markers);
+
/* copy F-Curves, fixing up the links as we go */
- BLI_listbase_clear(&dst->curves);
-
- for (sfcu = src->curves.first; sfcu; sfcu = sfcu->next) {
+ BLI_listbase_clear(&act_dst->curves);
+
+ for (fcu_src = act_src->curves.first; fcu_src; fcu_src = fcu_src->next) {
/* duplicate F-Curve */
- dfcu = copy_fcurve(sfcu);
- BLI_addtail(&dst->curves, dfcu);
-
+ fcu_dst = copy_fcurve(fcu_src); /* XXX TODO pass subdata flag? But surprisingly does not seem to be doing any ID refcounting... */
+ BLI_addtail(&act_dst->curves, fcu_dst);
+
/* fix group links (kindof bad list-in-list search, but this is the most reliable way) */
- for (dgrp = dst->groups.first, sgrp = src->groups.first; dgrp && sgrp; dgrp = dgrp->next, sgrp = sgrp->next) {
- if (sfcu->grp == sgrp) {
- dfcu->grp = dgrp;
-
- if (dgrp->channels.first == sfcu)
- dgrp->channels.first = dfcu;
- if (dgrp->channels.last == sfcu)
- dgrp->channels.last = dfcu;
-
+ for (grp_dst = act_dst->groups.first, grp_src = act_src->groups.first;
+ grp_dst && grp_src;
+ grp_dst = grp_dst->next, grp_src = grp_src->next)
+ {
+ if (fcu_src->grp == grp_src) {
+ fcu_dst->grp = grp_dst;
+
+ if (grp_dst->channels.first == fcu_src) {
+ grp_dst->channels.first = fcu_dst;
+ }
+ if (grp_dst->channels.last == fcu_src) {
+ grp_dst->channels.last = fcu_dst;
+ }
break;
}
}
}
-
- BKE_id_copy_ensure_local(bmain, &src->id, &dst->id);
+}
- return dst;
+bAction *BKE_action_copy(Main *bmain, const bAction *act_src)
+{
+ bAction *act_copy;
+ BKE_id_copy_ex(bmain, &act_src->id, (ID **)&act_copy, 0, false);
+ return act_copy;
}
/* *************** Action Groups *************** */
@@ -524,7 +534,7 @@ const char *BKE_pose_ikparam_get_name(bPose *pose)
*
* \param dst Should be freed already, makes entire duplicate.
*/
-void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constraints)
+void BKE_pose_copy_data_ex(bPose **dst, const bPose *src, const int flag, const bool copy_constraints)
{
bPose *outPose;
bPoseChannel *pchan;
@@ -554,9 +564,8 @@ void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constrain
outPose->avs = src->avs;
for (pchan = outPose->chanbase.first; pchan; pchan = pchan->next) {
-
- if (pchan->custom) {
- id_us_plus(&pchan->custom->id);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)pchan->custom);
}
/* warning, O(n2) here, if done without the hash, but these are rarely used features. */
@@ -571,13 +580,13 @@ void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constrain
}
if (copy_constraints) {
- BKE_constraints_copy(&listb, &pchan->constraints, true); // BKE_constraints_copy NULLs listb
+ BKE_constraints_copy_ex(&listb, &pchan->constraints, flag, true); // BKE_constraints_copy NULLs listb
pchan->constraints = listb;
pchan->mpath = NULL; /* motion paths should not get copied yet... */
}
if (pchan->prop) {
- pchan->prop = IDP_CopyProperty(pchan->prop);
+ pchan->prop = IDP_CopyProperty_ex(pchan->prop, flag);
}
pchan->draw_data = NULL; /* Drawing cache, no need to copy. */
@@ -591,6 +600,11 @@ void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constrain
*dst = outPose;
}
+void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constraints)
+{
+ BKE_pose_copy_data_ex(dst, src, 0, copy_constraints);
+}
+
void BKE_pose_itasc_init(bItasc *itasc)
{
if (itasc) {
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 3b3dff21206..f71238031a2 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -261,7 +261,7 @@ void BKE_animdata_free(ID *id, const bool do_id_user)
/* Copying -------------------------------------------- */
/* Make a copy of the given AnimData - to be used when copying datablocks */
-AnimData *BKE_animdata_copy(AnimData *adt, const bool do_action)
+AnimData *BKE_animdata_copy(Main *bmain, AnimData *adt, const bool do_action)
{
AnimData *dadt;
@@ -272,8 +272,9 @@ AnimData *BKE_animdata_copy(AnimData *adt, const bool do_action)
/* make a copy of action - at worst, user has to delete copies... */
if (do_action) {
- dadt->action = BKE_action_copy(G.main, adt->action);
- dadt->tmpact = BKE_action_copy(G.main, adt->tmpact);
+ BLI_assert(bmain != NULL);
+ BKE_id_copy_ex(bmain, (ID *)dadt->action, (ID **)&dadt->action, 0, false);
+ BKE_id_copy_ex(bmain, (ID *)dadt->tmpact, (ID **)&dadt->tmpact, 0, false);
}
else {
id_us_plus((ID *)dadt->action);
@@ -293,7 +294,7 @@ AnimData *BKE_animdata_copy(AnimData *adt, const bool do_action)
return dadt;
}
-bool BKE_animdata_copy_id(ID *id_to, ID *id_from, const bool do_action)
+bool BKE_animdata_copy_id(Main *bmain, ID *id_to, ID *id_from, const bool do_action)
{
AnimData *adt;
@@ -305,7 +306,7 @@ bool BKE_animdata_copy_id(ID *id_to, ID *id_from, const bool do_action)
adt = BKE_animdata_from_id(id_from);
if (adt) {
IdAdtTemplate *iat = (IdAdtTemplate *)id_to;
- iat->adt = BKE_animdata_copy(adt, do_action);
+ iat->adt = BKE_animdata_copy(bmain, adt, do_action);
}
return true;
@@ -1349,7 +1350,7 @@ void BKE_keyingset_free_path(KeyingSet *ks, KS_Path *ksp)
}
/* Copy all KeyingSets in the given list */
-void BKE_keyingsets_copy(ListBase *newlist, ListBase *list)
+void BKE_keyingsets_copy(ListBase *newlist, const ListBase *list)
{
KeyingSet *ksn;
KS_Path *kspn;
@@ -2849,7 +2850,7 @@ void BKE_animsys_evaluate_all_animation(Main *main, Scene *scene, float ctime)
#define DEBUG_PRINT if (G.debug & G_DEBUG_DEPSGRAPH) printf
-void BKE_animsys_eval_animdata(EvaluationContext *eval_ctx, ID *id)
+void BKE_animsys_eval_animdata(const EvaluationContext *eval_ctx, ID *id)
{
AnimData *adt = BKE_animdata_from_id(id);
Scene *scene = NULL; /* XXX: this is only needed for flushing RNA updates,
@@ -2859,7 +2860,7 @@ void BKE_animsys_eval_animdata(EvaluationContext *eval_ctx, ID *id)
BKE_animsys_evaluate_animdata(scene, id, adt, eval_ctx->ctime, ADT_RECALC_ANIM);
}
-void BKE_animsys_eval_driver(EvaluationContext *eval_ctx,
+void BKE_animsys_eval_driver(const EvaluationContext *eval_ctx,
ID *id,
FCurve *fcu)
{
diff --git a/source/blender/blenkernel/intern/appdir.c b/source/blender/blenkernel/intern/appdir.c
index 43fd47981b1..f39d8006f76 100644
--- a/source/blender/blenkernel/intern/appdir.c
+++ b/source/blender/blenkernel/intern/appdir.c
@@ -106,7 +106,8 @@ const char *BKE_appdir_folder_default(void)
static char *blender_version_decimal(const int ver)
{
static char version_str[5];
- sprintf(version_str, "%d.%02d", ver / 100, ver % 100);
+ BLI_assert(ver < 1000);
+ BLI_snprintf(version_str, sizeof(version_str), "%d.%02d", ver / 100, ver % 100);
return version_str;
}
@@ -212,8 +213,10 @@ static bool get_path_local(
/* try EXECUTABLE_DIR/2.5x/folder_name - new default directory for local blender installed files */
#ifdef __APPLE__
/* due new codesign situation in OSX > 10.9.5 we must move the blender_version dir with contents to Resources */
- static char osx_resourses[FILE_MAX];
- sprintf(osx_resourses, "%s../Resources", bprogdir);
+ char osx_resourses[FILE_MAX];
+ BLI_snprintf(osx_resourses, sizeof(osx_resourses), "%s../Resources", bprogdir);
+ /* Remove the '/../' added above. */
+ BLI_cleanup_path(NULL, osx_resourses);
return test_path(targetpath, targetpath_len, osx_resourses, blender_version_decimal(ver), relfolder);
#else
return test_path(targetpath, targetpath_len, bprogdir, blender_version_decimal(ver), relfolder);
@@ -591,6 +594,9 @@ static void where_am_i(char *fullname, const size_t maxlen, const char *name)
else {
BLI_path_program_search(fullname, maxlen, name);
}
+ /* Remove "/./" and "/../" so string comparisons can be used on the path. */
+ BLI_cleanup_path(NULL, fullname);
+
#if defined(DEBUG)
if (!STREQ(name, fullname)) {
printf("guessing '%s' == '%s'\n", name, fullname);
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 81796683761..7dfc4df114c 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -82,7 +82,7 @@ bArmature *BKE_armature_add(Main *bmain, const char *name)
{
bArmature *arm;
- arm = BKE_libblock_alloc(bmain, ID_AR, name);
+ arm = BKE_libblock_alloc(bmain, ID_AR, name, 0);
arm->deformflag = ARM_DEF_VGROUP | ARM_DEF_ENVELOPE;
arm->flag = ARM_COL_CUSTOM; /* custom bone-group colors */
arm->layer = 1;
@@ -149,54 +149,70 @@ void BKE_armature_make_local(Main *bmain, bArmature *arm, const bool lib_local)
BKE_id_make_local_generic(bmain, &arm->id, true, lib_local);
}
-static void copy_bonechildren(Bone *newBone, const Bone *oldBone, const Bone *actBone, Bone **newActBone)
+static void copy_bonechildren(
+ Bone *bone_dst, const Bone *bone_src, const Bone *bone_src_act, Bone **r_bone_dst_act, const int flag)
{
- Bone *curBone, *newChildBone;
+ Bone *bone_src_child, *bone_dst_child;
- if (oldBone == actBone)
- *newActBone = newBone;
+ if (bone_src == bone_src_act) {
+ *r_bone_dst_act = bone_dst;
+ }
- if (oldBone->prop)
- newBone->prop = IDP_CopyProperty(oldBone->prop);
+ if (bone_src->prop) {
+ bone_dst->prop = IDP_CopyProperty_ex(bone_src->prop, flag);
+ }
/* Copy this bone's list */
- BLI_duplicatelist(&newBone->childbase, &oldBone->childbase);
+ BLI_duplicatelist(&bone_dst->childbase, &bone_src->childbase);
/* For each child in the list, update it's children */
- newChildBone = newBone->childbase.first;
- for (curBone = oldBone->childbase.first; curBone; curBone = curBone->next) {
- newChildBone->parent = newBone;
- copy_bonechildren(newChildBone, curBone, actBone, newActBone);
- newChildBone = newChildBone->next;
+ for (bone_src_child = bone_src->childbase.first, bone_dst_child = bone_dst->childbase.first;
+ bone_src_child;
+ bone_src_child = bone_src_child->next, bone_dst_child = bone_dst_child->next)
+ {
+ bone_dst_child->parent = bone_dst;
+ copy_bonechildren(bone_dst_child, bone_src_child, bone_src_act, r_bone_dst_act, flag);
}
}
-bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm)
+/**
+ * Only copy internal data of Armature ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_armature_copy_data(Main *UNUSED(bmain), bArmature *arm_dst, const bArmature *arm_src, const int flag)
{
- bArmature *newArm;
- Bone *oldBone, *newBone;
- Bone *newActBone = NULL;
+ Bone *bone_src, *bone_dst;
+ Bone *bone_dst_act = NULL;
+
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
- newArm = BKE_libblock_copy(bmain, &arm->id);
- BLI_duplicatelist(&newArm->bonebase, &arm->bonebase);
+ BLI_duplicatelist(&arm_dst->bonebase, &arm_src->bonebase);
/* Duplicate the childrens' lists */
- newBone = newArm->bonebase.first;
- for (oldBone = arm->bonebase.first; oldBone; oldBone = oldBone->next) {
- newBone->parent = NULL;
- copy_bonechildren(newBone, oldBone, arm->act_bone, &newActBone);
- newBone = newBone->next;
+ bone_dst = arm_dst->bonebase.first;
+ for (bone_src = arm_src->bonebase.first; bone_src; bone_src = bone_src->next) {
+ bone_dst->parent = NULL;
+ copy_bonechildren(bone_dst, bone_src, arm_src->act_bone, &bone_dst_act, flag_subdata);
+ bone_dst = bone_dst->next;
}
- newArm->act_bone = newActBone;
-
- newArm->edbo = NULL;
- newArm->act_edbone = NULL;
- newArm->sketch = NULL;
+ arm_dst->act_bone = bone_dst_act;
- BKE_id_copy_ensure_local(bmain, &arm->id, &newArm->id);
+ arm_dst->edbo = NULL;
+ arm_dst->act_edbone = NULL;
+ arm_dst->sketch = NULL;
+}
- return newArm;
+bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm)
+{
+ bArmature *arm_copy;
+ BKE_id_copy_ex(bmain, &arm->id, (ID **)&arm_copy, 0, false);
+ return arm_copy;
}
static Bone *get_named_bone_bonechildren(ListBase *lb, const char *name)
@@ -1445,7 +1461,7 @@ void BKE_armature_loc_pose_to_bone(bPoseChannel *pchan, const float inloc[3], fl
copy_v3_v3(outloc, nLocMat[3]);
}
-void BKE_armature_mat_pose_to_bone_ex(struct EvaluationContext *eval_ctx, Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
+void BKE_armature_mat_pose_to_bone_ex(const struct EvaluationContext *eval_ctx, Object *ob, bPoseChannel *pchan, float inmat[4][4], float outmat[4][4])
{
bPoseChannel work_pchan = *pchan;
@@ -2178,7 +2194,9 @@ void BKE_pose_where_is_bone_tail(bPoseChannel *pchan)
/* pchan is validated, as having bone and parent pointer
* 'do_extra': when zero skips loc/size/rot, constraints and strip modifiers.
*/
-void BKE_pose_where_is_bone(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan, float ctime, bool do_extra)
+void BKE_pose_where_is_bone(
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, bPoseChannel *pchan, float ctime, bool do_extra)
{
/* This gives a chan_mat with actions (ipos) results. */
if (do_extra)
@@ -2239,7 +2257,7 @@ void BKE_pose_where_is_bone(struct EvaluationContext *eval_ctx, Scene *scene, Ob
/* This only reads anim data from channels, and writes to channels */
/* This is the only function adding poses */
-void BKE_pose_where_is(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_pose_where_is(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
bArmature *arm;
Bone *bone;
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 5d579b97619..0bd4d3b864f 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -266,8 +266,9 @@ static void splineik_init_tree(Scene *scene, Object *ob, float UNUSED(ctime))
/* ----------- */
/* Evaluate spline IK for a given bone */
-static void splineik_evaluate_bone(struct EvaluationContext *eval_ctx, tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan,
- int index, float ctime)
+static void splineik_evaluate_bone(
+ const struct EvaluationContext *eval_ctx, tSplineIK_Tree *tree, Scene *scene, Object *ob, bPoseChannel *pchan,
+ int index, float ctime)
{
bSplineIKConstraint *ikData = tree->ikData;
float poseHead[3], poseTail[3], poseMat[4][4];
@@ -516,7 +517,7 @@ static void splineik_evaluate_bone(struct EvaluationContext *eval_ctx, tSplineIK
}
/* Evaluate the chain starting from the nominated bone */
-static void splineik_execute_tree(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
+static void splineik_execute_tree(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
{
tSplineIK_Tree *tree;
@@ -549,14 +550,16 @@ void BKE_pose_splineik_init_tree(Scene *scene, Object *ob, float ctime)
splineik_init_tree(scene, ob, ctime);
}
-void BKE_splineik_execute_tree(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
+void BKE_splineik_execute_tree(
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, bPoseChannel *pchan_root, float ctime)
{
splineik_execute_tree(eval_ctx, scene, ob, pchan_root, ctime);
}
/* *************** Depsgraph evaluation callbacks ************ */
-void BKE_pose_eval_init(struct EvaluationContext *eval_ctx,
+void BKE_pose_eval_init(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPose *pose)
@@ -590,7 +593,7 @@ void BKE_pose_eval_init(struct EvaluationContext *eval_ctx,
BKE_pose_splineik_init_tree(scene, ob, ctime);
}
-void BKE_pose_eval_bone(struct EvaluationContext *eval_ctx,
+void BKE_pose_eval_bone(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPoseChannel *pchan)
@@ -625,7 +628,7 @@ void BKE_pose_eval_bone(struct EvaluationContext *eval_ctx,
}
}
-void BKE_pose_constraints_evaluate(struct EvaluationContext *eval_ctx,
+void BKE_pose_constraints_evaluate(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPoseChannel *pchan)
@@ -646,7 +649,7 @@ void BKE_pose_constraints_evaluate(struct EvaluationContext *eval_ctx,
}
}
-void BKE_pose_bone_done(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_bone_done(const struct EvaluationContext *UNUSED(eval_ctx),
bPoseChannel *pchan)
{
float imat[4][4];
@@ -657,7 +660,7 @@ void BKE_pose_bone_done(struct EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_pose_iktree_evaluate(struct EvaluationContext *eval_ctx,
+void BKE_pose_iktree_evaluate(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPoseChannel *rootchan)
@@ -667,7 +670,7 @@ void BKE_pose_iktree_evaluate(struct EvaluationContext *eval_ctx,
BIK_execute_tree(eval_ctx, scene, ob, rootchan, ctime);
}
-void BKE_pose_splineik_evaluate(struct EvaluationContext *eval_ctx,
+void BKE_pose_splineik_evaluate(const struct EvaluationContext *eval_ctx,
Scene *scene,
Object *ob,
bPoseChannel *rootchan)
@@ -677,7 +680,7 @@ void BKE_pose_splineik_evaluate(struct EvaluationContext *eval_ctx,
BKE_splineik_execute_tree(eval_ctx, scene, ob, rootchan, ctime);
}
-void BKE_pose_eval_flush(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_pose_eval_flush(const struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob,
bPose *UNUSED(pose))
@@ -692,7 +695,7 @@ void BKE_pose_eval_flush(struct EvaluationContext *UNUSED(eval_ctx),
ob->recalc &= ~OB_RECALC_ALL;
}
-void BKE_pose_eval_proxy_copy(struct EvaluationContext *UNUSED(eval_ctx), Object *ob)
+void BKE_pose_eval_proxy_copy(const struct EvaluationContext *UNUSED(eval_ctx), Object *ob)
{
BLI_assert(ID_IS_LINKED_DATABLOCK(ob) && ob->proxy_from != NULL);
DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
diff --git a/source/blender/blenkernel/intern/blender_copybuffer.c b/source/blender/blenkernel/intern/blender_copybuffer.c
index 206b0f2a8cc..2d37f3ab0cb 100644
--- a/source/blender/blenkernel/intern/blender_copybuffer.c
+++ b/source/blender/blenkernel/intern/blender_copybuffer.c
@@ -49,6 +49,7 @@
#include "BKE_main.h"
#include "BKE_scene.h"
+#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
#include "BLO_readfile.h"
@@ -160,6 +161,10 @@ bool BKE_copybuffer_paste(bContext *C, const char *libname, const short flag, Re
/* recreate dependency graph to include new objects */
DEG_relations_tag_update(bmain);
+ /* Tag update the scene to flush base collection settings, since the new object is added to a
+ * new (active) collection, not its original collection, thus need recalculation. */
+ DEG_id_tag_update(&scene->id, 0);
+
BLO_blendhandle_close(bh);
/* remove library... */
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index 09760fcc4cb..e1350aa8a46 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -117,6 +117,7 @@ static void setup_app_data(
const char *filepath, ReportList *reports)
{
Scene *curscene = NULL;
+ const bool is_startup = (bfd->filename[0] == '\0');
const bool recover = (G.fileflags & G_FILE_RECOVER) != 0;
enum {
LOAD_UI = 1,
@@ -132,7 +133,7 @@ static void setup_app_data(
else if (BLI_listbase_is_empty(&bfd->main->screen)) {
mode = LOAD_UNDO;
}
- else if (G.fileflags & G_FILE_NO_UI) {
+ else if ((G.fileflags & G_FILE_NO_UI) && (is_startup == false)) {
mode = LOAD_UI_OFF;
}
else {
@@ -264,7 +265,9 @@ static void setup_app_data(
CTX_data_scene_set(C, curscene);
}
else {
- G.fileflags = bfd->fileflags;
+ /* Keep state from preferences. */
+ const int fileflags_skip = G_FILE_FLAGS_RUNTIME;
+ G.fileflags = (G.fileflags & fileflags_skip) | (bfd->fileflags & ~fileflags_skip);
CTX_wm_manager_set(C, G.main->wm.first);
CTX_wm_screen_set(C, bfd->curscreen);
CTX_data_scene_set(C, bfd->curscene);
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 5219148a414..60ea78f3f2b 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -152,7 +152,7 @@ Brush *BKE_brush_add(Main *bmain, const char *name, short ob_mode)
{
Brush *brush;
- brush = BKE_libblock_alloc(bmain, ID_BR, name);
+ brush = BKE_libblock_alloc(bmain, ID_BR, name, 0);
BKE_brush_init(brush);
@@ -172,34 +172,38 @@ struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode)
return NULL;
}
-Brush *BKE_brush_copy(Main *bmain, const Brush *brush)
+/**
+ * Only copy internal data of Brush ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_brush_copy_data(Main *UNUSED(bmain), Brush *brush_dst, const Brush *brush_src, const int flag)
{
- Brush *brushn;
-
- brushn = BKE_libblock_copy(bmain, &brush->id);
-
- if (brush->mtex.tex)
- id_us_plus((ID *)brush->mtex.tex);
-
- if (brush->mask_mtex.tex)
- id_us_plus((ID *)brush->mask_mtex.tex);
-
- if (brush->paint_curve)
- id_us_plus((ID *)brush->paint_curve);
-
- if (brush->icon_imbuf)
- brushn->icon_imbuf = IMB_dupImBuf(brush->icon_imbuf);
+ if (brush_src->icon_imbuf) {
+ brush_dst->icon_imbuf = IMB_dupImBuf(brush_src->icon_imbuf);
+ }
- brushn->preview = NULL;
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&brush_dst->id, &brush_src->id);
+ }
+ else {
+ brush_dst->preview = NULL;
+ }
- brushn->curve = curvemapping_copy(brush->curve);
+ brush_dst->curve = curvemapping_copy(brush_src->curve);
/* enable fake user by default */
- id_fake_user_set(&brushn->id);
-
- BKE_id_copy_ensure_local(bmain, &brush->id, &brushn->id);
+ id_fake_user_set(&brush_dst->id);
+}
- return brushn;
+Brush *BKE_brush_copy(Main *bmain, const Brush *brush)
+{
+ Brush *brush_copy;
+ BKE_id_copy_ex(bmain, &brush->id, (ID **)&brush_copy, 0, false);
+ return brush_copy;
}
/** Free (or release) any data used by this brush (does not free the brush itself). */
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index c1fad4f80c8..775499304d4 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -1137,7 +1137,6 @@ BVHTree *bvhtree_from_mesh_looptri(
const MLoopTri *looptri = NULL;
bool vert_allocated = false;
bool loop_allocated = false;
- bool looptri_allocated = false;
BLI_rw_mutex_lock(&cache_rwlock, THREAD_LOCK_READ);
tree = bvhcache_find(dm->bvhCache, BVHTREE_FROM_LOOPTRI);
@@ -1150,12 +1149,7 @@ BVHTree *bvhtree_from_mesh_looptri(
mpoly = DM_get_poly_array(dm, &poly_allocated);
mloop = DM_get_loop_array(dm, &loop_allocated);
- looptri = DM_get_looptri_array(
- dm,
- mvert,
- mpoly, dm->getNumPolys(dm),
- mloop, dm->getNumLoops(dm),
- &looptri_allocated);
+ looptri = dm->getLoopTriArray(dm);
if (poly_allocated) {
MEM_freeN(mpoly);
@@ -1193,7 +1187,7 @@ BVHTree *bvhtree_from_mesh_looptri(
data, tree, true, epsilon,
mvert, vert_allocated,
mloop, loop_allocated,
- looptri, looptri_allocated);
+ looptri, false);
}
else {
if (vert_allocated) {
@@ -1202,9 +1196,6 @@ BVHTree *bvhtree_from_mesh_looptri(
if (loop_allocated) {
MEM_freeN(mloop);
}
- if (looptri_allocated) {
- MEM_freeN((void *)looptri);
- }
memset(data, 0, sizeof(*data));
}
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 2294e23d4d5..9d02a27187c 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -66,7 +66,7 @@ void BKE_cachefiles_exit(void)
void *BKE_cachefile_add(Main *bmain, const char *name)
{
- CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, name);
+ CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, name, 0);
BKE_cachefile_init(cache_file);
@@ -100,16 +100,26 @@ void BKE_cachefile_free(CacheFile *cache_file)
BLI_freelistN(&cache_file->object_paths);
}
-CacheFile *BKE_cachefile_copy(Main *bmain, const CacheFile *cache_file)
+/**
+ * Only copy internal data of CacheFile ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_cachefile_copy_data(
+ Main *UNUSED(bmain), CacheFile *cache_file_dst, const CacheFile *UNUSED(cache_file_src), const int UNUSED(flag))
{
- CacheFile *new_cache_file = BKE_libblock_copy(bmain, &cache_file->id);
- new_cache_file->handle = NULL;
-
- BLI_listbase_clear(&new_cache_file->object_paths);
-
- BKE_id_copy_ensure_local(bmain, &cache_file->id, &new_cache_file->id);
+ cache_file_dst->handle = NULL;
+ BLI_listbase_clear(&cache_file_dst->object_paths);
+}
- return new_cache_file;
+CacheFile *BKE_cachefile_copy(Main *bmain, const CacheFile *cache_file)
+{
+ CacheFile *cache_file_copy;
+ BKE_id_copy_ex(bmain, &cache_file->id, (ID **)&cache_file_copy, 0, false);
+ return cache_file_copy;
}
void BKE_cachefile_make_local(Main *bmain, CacheFile *cache_file, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 2e36de4e8d4..97bb679f8b0 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -86,22 +86,31 @@ void *BKE_camera_add(Main *bmain, const char *name)
{
Camera *cam;
- cam = BKE_libblock_alloc(bmain, ID_CA, name);
+ cam = BKE_libblock_alloc(bmain, ID_CA, name, 0);
BKE_camera_init(cam);
return cam;
}
-Camera *BKE_camera_copy(Main *bmain, const Camera *cam)
+/**
+ * Only copy internal data of Camera ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_camera_copy_data(Main *UNUSED(bmain), Camera *UNUSED(cam_dst), const Camera *UNUSED(cam_src), const int UNUSED(flag))
{
- Camera *camn;
-
- camn = BKE_libblock_copy(bmain, &cam->id);
-
- BKE_id_copy_ensure_local(bmain, &cam->id, &camn->id);
+ /* Nothing to do! */
+}
- return camn;
+Camera *BKE_camera_copy(Main *bmain, const Camera *cam)
+{
+ Camera *cam_copy;
+ BKE_id_copy_ex(bmain, &cam->id, (ID **)&cam_copy, 0, false);
+ return cam_copy;
}
void BKE_camera_make_local(Main *bmain, Camera *cam, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 155634c9d9c..eb5fc304749 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -1807,19 +1807,6 @@ void CDDM_recalc_looptri(DerivedMesh *dm)
cddm->dm.looptris.array);
}
-static const MLoopTri *cdDM_getLoopTriArray(DerivedMesh *dm)
-{
- if (dm->looptris.array) {
- BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
- }
- else {
- dm->recalcLoopTri(dm);
-
- /* ccdm is an exception here, that recalcLoopTri will fill in the array too */
- }
- return dm->looptris.array;
-}
-
static void cdDM_free_internal(CDDerivedMesh *cddm)
{
if (cddm->pmap) MEM_freeN(cddm->pmap);
@@ -1870,8 +1857,6 @@ static CDDerivedMesh *cdDM_create(const char *desc)
dm->getEdgeDataArray = DM_get_edge_data_layer;
dm->getTessFaceDataArray = DM_get_tessface_data_layer;
- dm->getLoopTriArray = cdDM_getLoopTriArray;
-
dm->calcNormals = CDDM_calc_normals;
dm->calcLoopNormals = CDDM_calc_loop_normals;
dm->calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr;
@@ -3056,7 +3041,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
MPoly *target_poly = cddm->mpoly + *(cddm->pmap[v_target].indices + i_poly);
if (cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, +1) ||
- cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, -1))
+ cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, -1))
{
found = true;
break;
diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c
index 05e92613c62..09b793629f7 100644
--- a/source/blender/blenkernel/intern/cloth.c
+++ b/source/blender/blenkernel/intern/cloth.c
@@ -345,7 +345,7 @@ static int do_init_cloth(Object *ob, ClothModifierData *clmd, DerivedMesh *resul
return 1;
}
-static int do_step_cloth(struct EvaluationContext *eval_ctx, Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
+static int do_step_cloth(const struct EvaluationContext *eval_ctx, Object *ob, ClothModifierData *clmd, DerivedMesh *result, int framenr)
{
ClothVertex *verts = NULL;
Cloth *cloth;
@@ -400,7 +400,7 @@ static int do_step_cloth(struct EvaluationContext *eval_ctx, Object *ob, ClothMo
/************************************************
* clothModifier_do - main simulation function
************************************************/
-void clothModifier_do(ClothModifierData *clmd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3])
+void clothModifier_do(ClothModifierData *clmd, const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm, float (*vertexCos)[3])
{
PointCache *cache;
PTCacheID pid;
@@ -806,7 +806,6 @@ static int cloth_from_object(Object *ob, ClothModifierData *clmd, DerivedMesh *d
if ( !dm )
return 0;
- DM_ensure_looptri(dm);
cloth_from_mesh ( clmd, dm );
// create springs
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index ac7168b6561..e87086380bd 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -689,7 +689,7 @@ static bConstraintTypeInfo CTI_CONSTRNAME = {
/* This function should be used for the get_target_matrix member of all
* constraints that are not picky about what happens to their target matrix.
*/
-static void default_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
+static void default_get_tarmat(const struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *UNUSED(cob), bConstraintTarget *ct, float UNUSED(ctime))
{
if (VALID_CONS_TARGET(ct))
constraint_target_to_mat4(ct->tar, ct->subtarget, ct->matrix, CONSTRAINT_SPACE_WORLD, ct->space, con->flag, con->headtail);
@@ -1155,7 +1155,7 @@ static void kinematic_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void kinematic_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void kinematic_get_tarmat(const struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
bKinematicConstraint *data = con->data;
@@ -1242,7 +1242,7 @@ static void followpath_flush_tars(bConstraint *con, ListBase *list, bool no_copy
}
}
-static void followpath_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void followpath_get_tarmat(const struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
bFollowPathConstraint *data = con->data;
@@ -2024,7 +2024,7 @@ static void pycon_id_looper(bConstraint *con, ConstraintIDFunc func, void *userd
}
/* Whether this approach is maintained remains to be seen (aligorith) */
-static void pycon_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void pycon_get_tarmat(const struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
#ifdef WITH_PYTHON
bPythonConstraint *data = con->data;
@@ -2142,7 +2142,7 @@ static void actcon_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void actcon_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void actcon_get_tarmat(const struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
bActionConstraint *data = con->data;
@@ -3131,7 +3131,7 @@ static void clampto_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void clampto_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void clampto_get_tarmat(const struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
#ifdef CYCLIC_DEPENDENCY_WORKAROUND
if (VALID_CONS_TARGET(ct)) {
@@ -3474,7 +3474,7 @@ static void shrinkwrap_flush_tars(bConstraint *con, ListBase *list, bool no_copy
}
-static void shrinkwrap_get_tarmat(struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void shrinkwrap_get_tarmat(const struct EvaluationContext *UNUSED(eval_ctx), bConstraint *con, bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
bShrinkwrapConstraint *scon = (bShrinkwrapConstraint *) con->data;
@@ -3806,7 +3806,7 @@ static void splineik_flush_tars(bConstraint *con, ListBase *list, bool no_copy)
}
}
-static void splineik_get_tarmat(struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
+static void splineik_get_tarmat(const struct EvaluationContext *eval_ctx, bConstraint *UNUSED(con), bConstraintOb *cob, bConstraintTarget *ct, float UNUSED(ctime))
{
#ifdef CYCLIC_DEPENDENCY_WORKAROUND
if (VALID_CONS_TARGET(ct)) {
@@ -4737,29 +4737,30 @@ static void con_fix_copied_refs_cb(bConstraint *UNUSED(con), ID **idpoin, bool i
}
/* duplicate all of the constraints in a constraint stack */
-void BKE_constraints_copy(ListBase *dst, const ListBase *src, bool do_extern)
+void BKE_constraints_copy_ex(ListBase *dst, const ListBase *src, const int flag, bool do_extern)
{
bConstraint *con, *srccon;
-
+
BLI_listbase_clear(dst);
BLI_duplicatelist(dst, src);
-
+
for (con = dst->first, srccon = src->first; con && srccon; srccon = srccon->next, con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
-
+
/* make a new copy of the constraint's data */
con->data = MEM_dupallocN(con->data);
-
+
/* only do specific constraints if required */
if (cti) {
/* perform custom copying operations if needed */
if (cti->copy_data)
cti->copy_data(con, srccon);
-
- /* fix usercounts for all referenced data in referenced data */
- if (cti->id_looper)
+
+ /* Fix usercounts for all referenced data that need it. */
+ if (cti->id_looper && (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
cti->id_looper(con, con_fix_copied_refs_cb, NULL);
-
+ }
+
/* for proxies we don't want to make extern */
if (do_extern) {
/* go over used ID-links for this constraint to ensure that they are valid for proxies */
@@ -4770,6 +4771,11 @@ void BKE_constraints_copy(ListBase *dst, const ListBase *src, bool do_extern)
}
}
+void BKE_constraints_copy(ListBase *dst, const ListBase *src, bool do_extern)
+{
+ BKE_constraints_copy_ex(dst, src, 0, do_extern);
+}
+
/* ......... */
bConstraint *BKE_constraints_find_name(ListBase *list, const char *name)
@@ -4858,7 +4864,7 @@ bool BKE_constraints_proxylocked_owner(Object *ob, bPoseChannel *pchan)
* None of the actual calculations of the matrices should be done here! Also, this function is
* not to be used by any new constraints, particularly any that have multiple targets.
*/
-void BKE_constraint_target_matrix_get(struct EvaluationContext *eval_ctx, Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
+void BKE_constraint_target_matrix_get(const struct EvaluationContext *eval_ctx, Scene *scene, bConstraint *con, int index, short ownertype, void *ownerdata, float mat[4][4], float ctime)
{
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
@@ -4925,7 +4931,7 @@ void BKE_constraint_target_matrix_get(struct EvaluationContext *eval_ctx, Scene
}
/* Get the list of targets required for solving a constraint */
-void BKE_constraint_targets_for_solving_get(struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
+void BKE_constraint_targets_for_solving_get(const struct EvaluationContext *eval_ctx, bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
{
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
@@ -4960,7 +4966,7 @@ void BKE_constraint_targets_for_solving_get(struct EvaluationContext *eval_ctx,
* BKE_constraints_make_evalob and BKE_constraints_clear_evalob should be called before and
* after running this function, to sort out cob
*/
-void BKE_constraints_solve(struct EvaluationContext *eval_ctx, ListBase *conlist, bConstraintOb *cob, float ctime)
+void BKE_constraints_solve(const struct EvaluationContext *eval_ctx, ListBase *conlist, bConstraintOb *cob, float ctime)
{
bConstraint *con;
float oldmat[4][4];
diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c
index da05c05a694..d2ffbbcf27b 100644
--- a/source/blender/blenkernel/intern/crazyspace.c
+++ b/source/blender/blenkernel/intern/crazyspace.c
@@ -99,7 +99,8 @@ static int modifiers_disable_subsurf_temporary(Object *ob)
}
/* disable subsurf temporal, get mapped cos, and enable it */
-float (*BKE_crazyspace_get_mapped_editverts(struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit))[3]
+float (*BKE_crazyspace_get_mapped_editverts(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *obedit))[3]
{
Mesh *me = obedit->data;
DerivedMesh *dm;
@@ -250,8 +251,9 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, float (*origcos)[3], float (*mapped
/** returns an array of deform matrices for crazyspace correction, and the
* number of modifiers left */
-int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em,
- float (**deformmats)[3][3], float (**deformcos)[3])
+int BKE_crazyspace_get_first_deform_matrices_editbmesh(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BMEditMesh *em,
+ float (**deformmats)[3][3], float (**deformcos)[3])
{
ModifierData *md;
DerivedMesh *dm;
@@ -310,7 +312,9 @@ int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct EvaluationContext
return numleft;
}
-int BKE_sculpt_get_first_deform_matrices(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
+int BKE_sculpt_get_first_deform_matrices(
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
{
ModifierData *md;
DerivedMesh *dm;
@@ -369,7 +373,7 @@ int BKE_sculpt_get_first_deform_matrices(struct EvaluationContext *eval_ctx, Sce
return numleft;
}
-void BKE_crazyspace_build_sculpt(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
+void BKE_crazyspace_build_sculpt(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3])
{
int totleft = BKE_sculpt_get_first_deform_matrices(eval_ctx, scene, ob, deformmats, deformcos);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 6018c07835b..351f443cbc9 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -182,7 +182,7 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type)
{
Curve *cu;
- cu = BKE_libblock_alloc(bmain, ID_CU, name);
+ cu = BKE_libblock_alloc(bmain, ID_CU, name, 0);
cu->type = type;
BKE_curve_init(cu);
@@ -190,43 +190,40 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type)
return cu;
}
-Curve *BKE_curve_copy(Main *bmain, const Curve *cu)
+/**
+ * Only copy internal data of Curve ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_curve_copy_data(Main *bmain, Curve *cu_dst, const Curve *cu_src, const int flag)
{
- Curve *cun;
- int a;
-
- cun = BKE_libblock_copy(bmain, &cu->id);
-
- BLI_listbase_clear(&cun->nurb);
- BKE_nurbList_duplicate(&(cun->nurb), &(cu->nurb));
+ BLI_listbase_clear(&cu_dst->nurb);
+ BKE_nurbList_duplicate(&(cu_dst->nurb), &(cu_src->nurb));
- cun->mat = MEM_dupallocN(cu->mat);
- for (a = 0; a < cun->totcol; a++) {
- id_us_plus((ID *)cun->mat[a]);
- }
+ cu_dst->mat = MEM_dupallocN(cu_src->mat);
- cun->str = MEM_dupallocN(cu->str);
- cun->strinfo = MEM_dupallocN(cu->strinfo);
- cun->tb = MEM_dupallocN(cu->tb);
- cun->bb = MEM_dupallocN(cu->bb);
- cun->batch_cache = NULL;
+ cu_dst->str = MEM_dupallocN(cu_src->str);
+ cu_dst->strinfo = MEM_dupallocN(cu_src->strinfo);
+ cu_dst->tb = MEM_dupallocN(cu_src->tb);
+ cu_dst->bb = MEM_dupallocN(cu_src->bb);
+ cu_dst->batch_cache = NULL;
- if (cu->key) {
- cun->key = BKE_key_copy(bmain, cu->key);
- cun->key->from = (ID *)cun;
+ if (cu_src->key) {
+ BKE_id_copy_ex(bmain, &cu_src->key->id, (ID **)&cu_dst->key, flag, false);
}
- cun->editnurb = NULL;
- cun->editfont = NULL;
-
- id_us_plus((ID *)cun->vfont);
- id_us_plus((ID *)cun->vfontb);
- id_us_plus((ID *)cun->vfonti);
- id_us_plus((ID *)cun->vfontbi);
-
- BKE_id_copy_ensure_local(bmain, &cu->id, &cun->id);
+ cu_dst->editnurb = NULL;
+ cu_dst->editfont = NULL;
+}
- return cun;
+Curve *BKE_curve_copy(Main *bmain, const Curve *cu)
+{
+ Curve *cu_copy;
+ BKE_id_copy_ex(bmain, &cu->id, (ID **)&cu_copy, 0, false);
+ return cu_copy;
}
void BKE_curve_make_local(Main *bmain, Curve *cu, const bool lib_local)
@@ -1625,7 +1622,7 @@ float *BKE_curve_surf_make_orco(Object *ob)
/* NOTE: This routine is tied to the order of vertex
* built by displist and as passed to the renderer.
*/
-float *BKE_curve_make_orco(EvaluationContext *eval_ctx, Scene *scene, Object *ob, int *r_numVerts)
+float *BKE_curve_make_orco(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, int *r_numVerts)
{
Curve *cu = ob->data;
DispList *dl;
@@ -1724,8 +1721,9 @@ float *BKE_curve_make_orco(EvaluationContext *eval_ctx, Scene *scene, Object *ob
/* ***************** BEVEL ****************** */
-void BKE_curve_bevel_make(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *disp,
- const bool for_render, const bool use_render_resolution)
+void BKE_curve_bevel_make(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *disp,
+ const bool for_render, const bool use_render_resolution)
{
DispList *dl, *dlnew;
Curve *bevcu, *cu;
@@ -4449,7 +4447,9 @@ bool BKE_curve_center_bounds(Curve *cu, float cent[3])
}
-void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, const float unit_scale)
+void BKE_curve_transform_ex(
+ Curve *cu, float mat[4][4],
+ const bool do_keys, const bool do_props, const float unit_scale)
{
Nurb *nu;
BPoint *bp;
@@ -4463,7 +4463,9 @@ void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, cons
mul_m4_v3(mat, bezt->vec[0]);
mul_m4_v3(mat, bezt->vec[1]);
mul_m4_v3(mat, bezt->vec[2]);
- bezt->radius *= unit_scale;
+ if (do_props) {
+ bezt->radius *= unit_scale;
+ }
}
BKE_nurb_handles_calc(nu);
}
@@ -4471,7 +4473,9 @@ void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, cons
i = nu->pntsu * nu->pntsv;
for (bp = nu->bp; i--; bp++) {
mul_m4_v3(mat, bp->vec);
- bp->radius *= unit_scale;
+ if (do_props) {
+ bp->radius *= unit_scale;
+ }
}
}
}
@@ -4487,10 +4491,12 @@ void BKE_curve_transform_ex(Curve *cu, float mat[4][4], const bool do_keys, cons
}
}
-void BKE_curve_transform(Curve *cu, float mat[4][4], const bool do_keys)
+void BKE_curve_transform(
+ Curve *cu, float mat[4][4],
+ const bool do_keys, const bool do_props)
{
float unit_scale = mat4_to_scale(mat);
- BKE_curve_transform_ex(cu, mat, do_keys, unit_scale);
+ BKE_curve_transform_ex(cu, mat, do_keys, do_props, unit_scale);
}
void BKE_curve_translate(Curve *cu, float offset[3], const bool do_keys)
@@ -4669,7 +4675,7 @@ void BKE_curve_rect_from_textbox(const struct Curve *cu, const struct TextBox *t
/* **** Depsgraph evaluation **** */
-void BKE_curve_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
+void BKE_curve_eval_geometry(const EvaluationContext *UNUSED(eval_ctx),
Curve *curve)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
@@ -4680,7 +4686,7 @@ void BKE_curve_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_curve_eval_path(EvaluationContext *UNUSED(eval_ctx),
+void BKE_curve_eval_path(const EvaluationContext *UNUSED(eval_ctx),
Curve *curve)
{
/* TODO(sergey): This will probably need to be a part of
diff --git a/source/blender/blenkernel/intern/data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c
index 0b88cc48a96..00b8063110d 100644
--- a/source/blender/blenkernel/intern/data_transfer.c
+++ b/source/blender/blenkernel/intern/data_transfer.c
@@ -1010,7 +1010,8 @@ static bool data_transfer_layersmapping_generate(
* to get (as much as possible) exact copy of source data layout.
*/
void BKE_object_data_transfer_layout(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types, const bool use_delete,
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob_src, Object *ob_dst, const int data_types, const bool use_delete,
const int fromlayers_select[DT_MULTILAYER_INDEX_MAX], const int tolayers_select[DT_MULTILAYER_INDEX_MAX])
{
DerivedMesh *dm_src;
@@ -1085,7 +1086,7 @@ void BKE_object_data_transfer_layout(
}
bool BKE_object_data_transfer_dm(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, DerivedMesh *dm_dst,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, DerivedMesh *dm_dst,
const int data_types, bool use_create, const int map_vert_mode, const int map_edge_mode,
const int map_loop_mode, const int map_poly_mode, SpaceTransform *space_transform, const bool auto_transform,
const float max_distance, const float ray_radius, const float islands_handling_precision,
@@ -1457,7 +1458,7 @@ bool BKE_object_data_transfer_dm(
}
bool BKE_object_data_transfer_mesh(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types,
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, Object *ob_dst, const int data_types,
const bool use_create, const int map_vert_mode, const int map_edge_mode, const int map_loop_mode,
const int map_poly_mode, SpaceTransform *space_transform, const bool auto_transform,
const float max_distance, const float ray_radius, const float islands_handling_precision,
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index fd22aaa291b..8316d68b35c 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -678,7 +678,7 @@ static void curve_to_filledpoly(Curve *cu, ListBase *UNUSED(nurb), ListBase *dis
* - first point left, last point right
* - based on subdivided points in original curve, not on points in taper curve (still)
*/
-static float displist_calc_taper(EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, float fac)
+static float displist_calc_taper(const EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, float fac)
{
DispList *dl;
@@ -718,14 +718,14 @@ static float displist_calc_taper(EvaluationContext *eval_ctx, Scene *scene, Obje
return 1.0;
}
-float BKE_displist_calc_taper(EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, int cur, int tot)
+float BKE_displist_calc_taper(const EvaluationContext *eval_ctx, Scene *scene, Object *taperobj, int cur, int tot)
{
float fac = ((float)cur) / (float)(tot - 1);
return displist_calc_taper(eval_ctx, scene, taperobj, fac);
}
-void BKE_displist_make_mball(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_displist_make_mball(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
if (!ob || ob->type != OB_MBALL)
return;
@@ -748,7 +748,7 @@ void BKE_displist_make_mball(EvaluationContext *eval_ctx, Scene *scene, Object *
}
}
-void BKE_displist_make_mball_forRender(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
+void BKE_displist_make_mball_forRender(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
{
BKE_mball_polygonize(eval_ctx, scene, ob, dispbase);
BKE_mball_texspace_calc(ob);
@@ -798,8 +798,9 @@ static ModifierData *curve_get_tessellate_point(Scene *scene, Object *ob,
return pretessellatePoint;
}
-static void curve_calc_modifiers_pre(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb,
- const bool for_render, const bool use_render_resolution)
+static void curve_calc_modifiers_pre(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb,
+ const bool for_render, const bool use_render_resolution)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -908,9 +909,10 @@ static void displist_apply_allverts(ListBase *dispbase, float (*allverts)[3])
}
}
-static void curve_calc_modifiers_post(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb,
- ListBase *dispbase, DerivedMesh **r_dm_final,
- const bool for_render, const bool use_render_resolution)
+static void curve_calc_modifiers_post(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *nurb,
+ ListBase *dispbase, DerivedMesh **r_dm_final,
+ const bool for_render, const bool use_render_resolution)
{
VirtualModifierData virtualModifierData;
ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
@@ -1090,7 +1092,7 @@ static void displist_surf_indices(DispList *dl)
}
}
-static DerivedMesh *create_orco_dm(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+static DerivedMesh *create_orco_dm(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
DerivedMesh *dm;
ListBase disp = {NULL, NULL};
@@ -1134,8 +1136,9 @@ static void add_orco_dm(Object *ob, DerivedMesh *dm, DerivedMesh *orcodm)
DM_add_vert_layer(dm, CD_ORCO, CD_ASSIGN, orco);
}
-static void curve_calc_orcodm(EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final,
- const bool for_render, const bool use_render_resolution)
+static void curve_calc_orcodm(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final,
+ const bool for_render, const bool use_render_resolution)
{
/* this function represents logic of mesh's orcodm calculation
* for displist-based objects
@@ -1201,9 +1204,10 @@ static void curve_calc_orcodm(EvaluationContext *eval_ctx, Scene *scene, Object
orcodm->release(orcodm);
}
-void BKE_displist_make_surf(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
- DerivedMesh **r_dm_final,
- const bool for_render, const bool for_orco, const bool use_render_resolution)
+void BKE_displist_make_surf(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **r_dm_final,
+ const bool for_render, const bool for_orco, const bool use_render_resolution)
{
ListBase nubase = {NULL, NULL};
Nurb *nu;
@@ -1513,9 +1517,10 @@ static void calc_bevfac_mapping(Curve *cu, BevList *bl, Nurb *nu,
}
}
-static void do_makeDispListCurveTypes(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
- DerivedMesh **r_dm_final,
- const bool for_render, const bool for_orco, const bool use_render_resolution)
+static void do_makeDispListCurveTypes(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **r_dm_final,
+ const bool for_render, const bool for_orco, const bool use_render_resolution)
{
Curve *cu = ob->data;
@@ -1761,7 +1766,7 @@ static void do_makeDispListCurveTypes(EvaluationContext *eval_ctx, Scene *scene,
}
}
-void BKE_displist_make_curveTypes(EvaluationContext *eval_ctx, Scene *scene, Object *ob, const bool for_orco)
+void BKE_displist_make_curveTypes(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, const bool for_orco)
{
ListBase *dispbase;
@@ -1784,9 +1789,10 @@ void BKE_displist_make_curveTypes(EvaluationContext *eval_ctx, Scene *scene, Obj
boundbox_displist_object(ob);
}
-void BKE_displist_make_curveTypes_forRender(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
- DerivedMesh **r_dm_final, const bool for_orco,
- const bool use_render_resolution)
+void BKE_displist_make_curveTypes_forRender(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase,
+ DerivedMesh **r_dm_final, const bool for_orco,
+ const bool use_render_resolution)
{
if (ob->curve_cache == NULL) {
ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve");
@@ -1795,7 +1801,8 @@ void BKE_displist_make_curveTypes_forRender(EvaluationContext *eval_ctx, Scene *
do_makeDispListCurveTypes(eval_ctx, scene, ob, dispbase, r_dm_final, true, for_orco, use_render_resolution);
}
-void BKE_displist_make_curveTypes_forOrco(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
+void BKE_displist_make_curveTypes_forOrco(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
{
if (ob->curve_cache == NULL) {
ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve");
@@ -1805,9 +1812,10 @@ void BKE_displist_make_curveTypes_forOrco(EvaluationContext *eval_ctx, Scene *sc
}
/* add Orco layer to the displist object which has got derived mesh and return orco */
-float *BKE_displist_make_orco(EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final,
- const bool for_render,
- const bool use_render_resolution)
+float *BKE_displist_make_orco(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm_final,
+ const bool for_render,
+ const bool use_render_resolution)
{
float *orco;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 6ac284d6b73..724b30d0cb1 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -500,7 +500,7 @@ static int surface_getBrushFlags(DynamicPaintSurface *surface, const SceneLayer
if (surface->brush_group)
go = surface->brush_group->gobject.first;
else
- base = FIRSTBASE_NEW;
+ base = FIRSTBASE_NEW(sl);
while (base || go) {
brushObj = NULL;
@@ -1975,7 +1975,9 @@ static void canvas_copyDerivedMesh(DynamicPaintCanvasSettings *canvas, DerivedMe
/*
* Updates derived mesh copy and processes dynamic paint step / caches.
*/
-static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
+static void dynamicPaint_frameUpdate(
+ DynamicPaintModifierData *pmd, const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, DerivedMesh *dm)
{
if (pmd->canvas) {
DynamicPaintCanvasSettings *canvas = pmd->canvas;
@@ -2057,14 +2059,13 @@ static void dynamicPaint_frameUpdate(DynamicPaintModifierData *pmd, struct Evalu
}
/* Modifier call. Processes dynamic paint modifier step. */
-DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
+DerivedMesh *dynamicPaint_Modifier_do(
+ DynamicPaintModifierData *pmd, const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, DerivedMesh *dm)
{
if (pmd->canvas) {
DerivedMesh *ret;
- /* For now generate looptris in every case */
- DM_ensure_looptri(dm);
-
/* Update canvas data for a new frame */
dynamicPaint_frameUpdate(pmd, eval_ctx, scene, ob, dm);
@@ -2074,9 +2075,6 @@ DerivedMesh *dynamicPaint_Modifier_do(DynamicPaintModifierData *pmd, struct Eval
return ret;
}
else {
- /* For now generate looptris in every case */
- DM_ensure_looptri(dm);
-
/* Update canvas data for a new frame */
dynamicPaint_frameUpdate(pmd, eval_ctx, scene, ob, dm);
@@ -3584,7 +3582,8 @@ static void dynamic_paint_brush_velocity_compute_cb(void *userdata, const int i)
}
static void dynamicPaint_brushMeshCalculateVelocity(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale)
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, DynamicPaintBrushSettings *brush, Vec3f **brushVel, float timescale)
{
float prev_obmat[4][4];
DerivedMesh *dm_p, *dm_c;
@@ -3642,7 +3641,7 @@ static void dynamicPaint_brushMeshCalculateVelocity(
}
/* calculate velocity for object center point */
-static void dynamicPaint_brushObjectCalculateVelocity(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Vec3f *brushVel, float timescale)
+static void dynamicPaint_brushObjectCalculateVelocity(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Vec3f *brushVel, float timescale)
{
float prev_obmat[4][4];
float cur_loc[3] = {0.0f}, prev_loc[3] = {0.0f};
@@ -4038,7 +4037,7 @@ static void dynamic_paint_paint_mesh_cell_point_cb_ex(
}
}
-static int dynamicPaint_paintMesh(struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface,
+static int dynamicPaint_paintMesh(const struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface,
DynamicPaintBrushSettings *brush,
Object *brushOb,
BrushMaterials *bMats,
@@ -4532,7 +4531,7 @@ static void dynamic_paint_paint_single_point_cb_ex(
}
static int dynamicPaint_paintSinglePoint(
- struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush,
+ const struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush,
Object *brushOb, BrushMaterials *bMats, Scene *scene, float timescale)
{
PaintSurfaceData *sData = surface->data;
@@ -4847,7 +4846,7 @@ static void dynamic_paint_prepare_effect_cb(void *userdata, const int index)
}
static int dynamicPaint_prepareEffectStep(
- struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, Scene *scene, Object *ob, float **force, float timescale)
+ const struct EvaluationContext *eval_ctx, DynamicPaintSurface *surface, Scene *scene, Object *ob, float **force, float timescale)
{
double average_force = 0.0f;
float shrink_speed = 0.0f, spread_speed = 0.0f;
@@ -5760,7 +5759,7 @@ static int dynamicPaint_generateBakeData(DynamicPaintSurface *surface, const Sce
/*
* Do Dynamic Paint step. Paints scene brush objects of current state/frame to the surface.
*/
-static int dynamicPaint_doStep(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe)
+static int dynamicPaint_doStep(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DynamicPaintSurface *surface, float timescale, float subframe)
{
PaintSurfaceData *sData = surface->data;
PaintBakeData *bData = sData->bData;
@@ -5794,7 +5793,7 @@ static int dynamicPaint_doStep(struct EvaluationContext *eval_ctx, Scene *scene,
if (surface->brush_group)
go = surface->brush_group->gobject.first;
else
- base = FIRSTBASE_NEW;
+ base = FIRSTBASE_NEW(sl);
while (base || go) {
brushObj = NULL;
@@ -5931,7 +5930,9 @@ static int dynamicPaint_doStep(struct EvaluationContext *eval_ctx, Scene *scene,
/*
* Calculate a single frame and included subframes for surface
*/
-int dynamicPaint_calculateFrame(DynamicPaintSurface *surface, struct EvaluationContext *eval_ctx, Scene *scene, Object *cObject, int frame)
+int dynamicPaint_calculateFrame(
+ DynamicPaintSurface *surface, const struct EvaluationContext *eval_ctx,
+ Scene *scene, Object *cObject, int frame)
{
float timescale = 1.0f;
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index df3c652ee19..2beb15ed995 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -299,18 +299,6 @@ static void emDM_recalcLoopTri(DerivedMesh *dm)
}
}
-static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
-{
- if (dm->looptris.array) {
- BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
- }
- else {
- dm->recalcLoopTri(dm);
- }
-
- return dm->looptris.array;
-}
-
static void emDM_foreachMappedVert(
DerivedMesh *dm,
void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
@@ -1639,8 +1627,6 @@ DerivedMesh *getEditDerivedBMesh(
bmdm->dm.getNumLoops = emDM_getNumLoops;
bmdm->dm.getNumPolys = emDM_getNumPolys;
- bmdm->dm.getLoopTriArray = emDM_getLoopTriArray;
-
bmdm->dm.getVert = emDM_getVert;
bmdm->dm.getVertCo = emDM_getVertCo;
bmdm->dm.getVertNo = emDM_getVertNo;
@@ -2183,7 +2169,7 @@ static void cage_mapped_verts_callback(
}
}
-float (*BKE_editmesh_vertexCos_get(struct EvaluationContext *eval_ctx, BMEditMesh *em, Scene *scene, int *r_numVerts))[3]
+float (*BKE_editmesh_vertexCos_get(const struct EvaluationContext *eval_ctx, BMEditMesh *em, Scene *scene, int *r_numVerts))[3]
{
DerivedMesh *cage, *final;
BLI_bitmap *visit_bitmap;
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index af1d4cc2e7d..36f7f6d604e 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -147,7 +147,7 @@ void free_partdeflect(PartDeflect *pd)
MEM_freeN(pd);
}
-static EffectorCache *new_effector_cache(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
+static EffectorCache *new_effector_cache(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, PartDeflect *pd)
{
EffectorCache *eff = MEM_callocN(sizeof(EffectorCache), "EffectorCache");
eff->eval_ctx = eval_ctx;
@@ -158,7 +158,7 @@ static EffectorCache *new_effector_cache(struct EvaluationContext *eval_ctx, Sce
eff->frame = -1;
return eff;
}
-static void add_object_to_effectors(ListBase **effectors, struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation)
+static void add_object_to_effectors(ListBase **effectors, const struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, Object *ob_src, bool for_simulation)
{
EffectorCache *eff = NULL;
@@ -183,7 +183,7 @@ static void add_object_to_effectors(ListBase **effectors, struct EvaluationConte
BLI_addtail(*effectors, eff);
}
-static void add_particles_to_effectors(ListBase **effectors, struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
+static void add_particles_to_effectors(ListBase **effectors, const struct EvaluationContext *eval_ctx, Scene *scene, EffectorWeights *weights, Object *ob, ParticleSystem *psys, ParticleSystem *psys_src, bool for_simulation)
{
ParticleSettings *part= psys->part;
@@ -209,8 +209,9 @@ static void add_particles_to_effectors(ListBase **effectors, struct EvaluationCo
}
/* returns ListBase handle with objects taking part in the effecting */
-ListBase *pdInitEffectors(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, ParticleSystem *psys_src,
- EffectorWeights *weights, bool for_simulation)
+ListBase *pdInitEffectors(
+ const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob_src, ParticleSystem *psys_src,
+ EffectorWeights *weights, bool for_simulation)
{
SceneLayer *sl;
Base *base;
@@ -243,7 +244,7 @@ ListBase *pdInitEffectors(struct EvaluationContext *eval_ctx, Scene *scene, Obje
}
}
else {
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if ( base->object->pd && base->object->pd->forcefield )
add_object_to_effectors(&effectors, eval_ctx, scene, weights, base->object, ob_src, for_simulation);
@@ -278,7 +279,7 @@ void pdEndEffectors(ListBase **effectors)
}
}
-static void precalculate_effector(struct EvaluationContext *eval_ctx, EffectorCache *eff)
+static void precalculate_effector(const struct EvaluationContext *eval_ctx, EffectorCache *eff)
{
unsigned int cfra = (unsigned int)(eff->scene->r.cfra >= 0 ? eff->scene->r.cfra : -eff->scene->r.cfra);
if (!eff->pd->rng)
@@ -318,7 +319,7 @@ static void precalculate_effector(struct EvaluationContext *eval_ctx, EffectorCa
}
}
-void pdPrecalculateEffectors(struct EvaluationContext *eval_ctx, ListBase *effectors)
+void pdPrecalculateEffectors(const struct EvaluationContext *eval_ctx, ListBase *effectors)
{
if (effectors) {
EffectorCache *eff = effectors->first;
diff --git a/source/blender/blenkernel/intern/fluidsim.c b/source/blender/blenkernel/intern/fluidsim.c
index 5599190010d..12b9abc6d03 100644
--- a/source/blender/blenkernel/intern/fluidsim.c
+++ b/source/blender/blenkernel/intern/fluidsim.c
@@ -65,7 +65,7 @@
// file handling
//-------------------------------------------------------------------------------
-void initElbeemMesh(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+void initElbeemMesh(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
int *numVertices, float **vertices,
int *numTriangles, int **triangles,
int useGlobalCoords, int modifierIndex)
@@ -80,8 +80,6 @@ void initElbeemMesh(struct EvaluationContext *eval_ctx, struct Scene *scene, str
dm = mesh_create_derived_index_render(eval_ctx, scene, ob, CD_MASK_BAREMESH, modifierIndex);
- DM_ensure_looptri(dm);
-
mvert = dm->getVertArray(dm);
mloop = dm->getLoopArray(dm);
looptri = dm->getLoopTriArray(dm);
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 401fed74c52..d6b28cfaf70 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -106,6 +106,23 @@ void BKE_vfont_free(struct VFont *vf)
}
}
+void BKE_vfont_copy_data(Main *UNUSED(bmain), VFont *vfont_dst, const VFont *UNUSED(vfont_src), const int flag)
+{
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+
+ /* Just to be sure, should not have any value actually after reading time. */
+ vfont_dst->temp_pf = NULL;
+
+ if (vfont_dst->packedfile) {
+ vfont_dst->packedfile = dupPackedFile(vfont_dst->packedfile);
+ }
+
+ if (vfont_dst->data) {
+ vfont_dst->data = BLI_vfontdata_copy(vfont_dst->data, flag_subdata);
+ }
+}
+
static void *builtin_font_data = NULL;
static int builtin_font_size = 0;
@@ -249,7 +266,7 @@ VFont *BKE_vfont_load(Main *bmain, const char *filepath)
vfd = BLI_vfontdata_from_freetypefont(pf);
if (vfd) {
- vfont = BKE_libblock_alloc(bmain, ID_VF, filename);
+ vfont = BKE_libblock_alloc(bmain, ID_VF, filename, 0);
vfont->data = vfd;
/* if there's a font name, use it for the ID name */
diff --git a/source/blender/blenkernel/intern/freestyle.c b/source/blender/blenkernel/intern/freestyle.c
index 0a0b023df82..e45a938a4fc 100644
--- a/source/blender/blenkernel/intern/freestyle.c
+++ b/source/blender/blenkernel/intern/freestyle.c
@@ -44,7 +44,7 @@
// function declarations
static FreestyleLineSet *alloc_lineset(void);
-static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset);
+static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset, const int flag);
static FreestyleModuleConfig *alloc_module(void);
static void copy_module(FreestyleModuleConfig *new_module, FreestyleModuleConfig *module);
@@ -79,7 +79,7 @@ void BKE_freestyle_config_free(FreestyleConfig *config)
BLI_freelistN(&config->modules);
}
-void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *config)
+void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *config, const int flag)
{
FreestyleLineSet *lineset, *new_lineset;
FreestyleModuleConfig *module, *new_module;
@@ -93,7 +93,7 @@ void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *con
BLI_listbase_clear(&new_config->linesets);
for (lineset = (FreestyleLineSet *)config->linesets.first; lineset; lineset = lineset->next) {
new_lineset = alloc_lineset();
- copy_lineset(new_lineset, lineset);
+ copy_lineset(new_lineset, lineset, flag);
BLI_addtail(&new_config->linesets, (void *)new_lineset);
}
@@ -105,11 +105,9 @@ void BKE_freestyle_config_copy(FreestyleConfig *new_config, FreestyleConfig *con
}
}
-static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset)
+static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *lineset, const int flag)
{
new_lineset->linestyle = lineset->linestyle;
- if (new_lineset->linestyle)
- id_us_plus(&new_lineset->linestyle->id);
new_lineset->flags = lineset->flags;
new_lineset->selection = lineset->selection;
new_lineset->qi = lineset->qi;
@@ -118,10 +116,12 @@ static void copy_lineset(FreestyleLineSet *new_lineset, FreestyleLineSet *linese
new_lineset->edge_types = lineset->edge_types;
new_lineset->exclude_edge_types = lineset->exclude_edge_types;
new_lineset->group = lineset->group;
- if (new_lineset->group) {
- id_us_plus(&new_lineset->group->id);
- }
strcpy(new_lineset->name, lineset->name);
+
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)new_lineset->linestyle);
+ id_us_plus((ID *)new_lineset->group);
+ }
}
static FreestyleModuleConfig *alloc_module(void)
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 758438bb051..ee0d0b41898 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -627,7 +627,7 @@ bGPdata *BKE_gpencil_data_addnew(const char name[])
bGPdata *gpd;
/* allocate memory for a new block */
- gpd = BKE_libblock_alloc(G.main, ID_GD, name);
+ gpd = BKE_libblock_alloc(G.main, ID_GD, name, 0);
/* initial settings */
gpd->flag = (GP_DATA_DISPINFO | GP_DATA_EXPAND);
@@ -753,47 +753,62 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src)
return gpl_dst;
}
-/* make a copy of a given gpencil datablock */
-bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy)
+/**
+ * Only copy internal data of GreasePencil ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_gpencil_copy_data(Main *UNUSED(bmain), bGPdata *gpd_dst, const bGPdata *gpd_src, const int UNUSED(flag))
{
- const bGPDlayer *gpl_src;
- bGPDlayer *gpl_dst;
- bGPdata *gpd_dst;
+ /* copy layers */
+ BLI_listbase_clear(&gpd_dst->layers);
+ for (const bGPDlayer *gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
+ /* make a copy of source layer and its data */
+ bGPDlayer *gpl_dst = BKE_gpencil_layer_duplicate(gpl_src); /* TODO here too could add unused flags... */
+ BLI_addtail(&gpd_dst->layers, gpl_dst);
+ }
- /* error checking */
- if (gpd_src == NULL) {
- return NULL;
+ /* copy palettes */
+ BLI_listbase_clear(&gpd_dst->palettes);
+ for (const bGPDpalette *palette_src = gpd_src->palettes.first; palette_src; palette_src = palette_src->next) {
+ bGPDpalette *palette_dst = BKE_gpencil_palette_duplicate(palette_src); /* TODO here too could add unused flags... */
+ BLI_addtail(&gpd_dst->palettes, palette_dst);
}
-
- /* make a copy of the base-data */
+}
+
+/* make a copy of a given gpencil datablock */
+bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy)
+{
+ /* Yuck and super-uber-hyper yuck!!!
+ * Should be replaceable with a no-main copy (LIB_ID_COPY_NO_MAIN etc.), but not sure about it,
+ * so for now keep old code for that one. */
if (internal_copy) {
+ const bGPDlayer *gpl_src;
+ bGPDlayer *gpl_dst;
+ bGPdata *gpd_dst;
+
/* make a straight copy for undo buffers used during stroke drawing */
gpd_dst = MEM_dupallocN(gpd_src);
+
+ /* copy layers */
+ BLI_listbase_clear(&gpd_dst->layers);
+ for (gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
+ /* make a copy of source layer and its data */
+ gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);
+ BLI_addtail(&gpd_dst->layers, gpl_dst);
+ }
+
+ /* return new */
+ return gpd_dst;
}
else {
- /* make a copy when others use this */
- gpd_dst = BKE_libblock_copy(bmain, &gpd_src->id);
- }
-
- /* copy layers */
- BLI_listbase_clear(&gpd_dst->layers);
- for (gpl_src = gpd_src->layers.first; gpl_src; gpl_src = gpl_src->next) {
- /* make a copy of source layer and its data */
- gpl_dst = BKE_gpencil_layer_duplicate(gpl_src);
- BLI_addtail(&gpd_dst->layers, gpl_dst);
- }
- if (!internal_copy) {
- /* copy palettes */
- bGPDpalette *palette_src, *palette_dst;
- BLI_listbase_clear(&gpd_dst->palettes);
- for (palette_src = gpd_src->palettes.first; palette_src; palette_src = palette_src->next) {
- palette_dst = BKE_gpencil_palette_duplicate(palette_src);
- BLI_addtail(&gpd_dst->palettes, palette_dst);
- }
+ bGPdata *gpd_copy;
+ BKE_id_copy_ex(bmain, &gpd_src->id, (ID **)&gpd_copy, 0, false);
+ return gpd_copy;
}
-
- /* return new */
- return gpd_dst;
}
void BKE_gpencil_make_local(Main *bmain, bGPdata *gpd, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 94a341de366..5ccbe9f7054 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -77,7 +77,7 @@ Group *BKE_group_add(Main *bmain, const char *name)
{
Group *group;
- group = BKE_libblock_alloc(bmain, ID_GR, name);
+ group = BKE_libblock_alloc(bmain, ID_GR, name, 0);
id_us_min(&group->id);
id_us_ensure_real(&group->id);
group->layer = (1 << 20) - 1;
@@ -87,19 +87,32 @@ Group *BKE_group_add(Main *bmain, const char *name)
return group;
}
-Group *BKE_group_copy(Main *bmain, const Group *group)
+/**
+ * Only copy internal data of Group ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_group_copy_data(Main *UNUSED(bmain), Group *group_dst, const Group *group_src, const int flag)
{
- Group *groupn;
-
- groupn = BKE_libblock_copy(bmain, &group->id);
- BLI_duplicatelist(&groupn->gobject, &group->gobject);
+ BLI_duplicatelist(&group_dst->gobject, &group_src->gobject);
/* Do not copy group's preview (same behavior as for objects). */
- groupn->preview = NULL;
-
- BKE_id_copy_ensure_local(bmain, &group->id, &groupn->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0 && false) { /* XXX TODO temp hack */
+ BKE_previewimg_id_copy(&group_dst->id, &group_src->id);
+ }
+ else {
+ group_dst->preview = NULL;
+ }
+}
- return groupn;
+Group *BKE_group_copy(Main *bmain, const Group *group)
+{
+ Group *group_copy;
+ BKE_id_copy_ex(bmain, &group->id, (ID **)&group_copy, 0, false);
+ return group_copy;
}
void BKE_group_make_local(Main *bmain, Group *group, const bool lib_local)
@@ -314,7 +327,7 @@ static void group_replaces_nla(Object *parent, Object *target, char mode)
* you can draw everything, leaves tags in objects to signal it needs further updating */
/* note: does not work for derivedmesh and render... it recreates all again in convertblender.c */
-void BKE_group_handle_recalc_and_update(struct EvaluationContext *eval_ctx, Scene *scene, Object *UNUSED(parent), Group *group)
+void BKE_group_handle_recalc_and_update(const struct EvaluationContext *eval_ctx, Scene *scene, Object *UNUSED(parent), Group *group)
{
GroupObject *go;
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index a3bd15252cb..b00a62a1a87 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -90,7 +90,7 @@ IDProperty *IDP_NewIDPArray(const char *name)
return prop;
}
-IDProperty *IDP_CopyIDPArray(const IDProperty *array)
+IDProperty *IDP_CopyIDPArray(const IDProperty *array, const int flag)
{
/* don't use MEM_dupallocN because this may be part of an array */
IDProperty *narray, *tmp;
@@ -109,7 +109,7 @@ IDProperty *IDP_CopyIDPArray(const IDProperty *array)
* then free it. this makes for more maintainable
* code than simply reimplementing the copy functions
* in this loop.*/
- tmp = IDP_CopyProperty(GETPROP(narray, i));
+ tmp = IDP_CopyProperty_ex(GETPROP(narray, i), flag);
memcpy(GETPROP(narray, i), tmp, sizeof(IDProperty));
MEM_freeN(tmp);
}
@@ -285,9 +285,9 @@ void IDP_FreeArray(IDProperty *prop)
}
-static IDProperty *idp_generic_copy(const IDProperty *prop)
+static IDProperty *idp_generic_copy(const IDProperty *prop, const int UNUSED(flag))
{
- IDProperty *newp = MEM_callocN(sizeof(IDProperty), "IDProperty array dup");
+ IDProperty *newp = MEM_callocN(sizeof(IDProperty), __func__);
BLI_strncpy(newp->name, prop->name, MAX_IDPROP_NAME);
newp->type = prop->type;
@@ -298,9 +298,9 @@ static IDProperty *idp_generic_copy(const IDProperty *prop)
return newp;
}
-static IDProperty *IDP_CopyArray(const IDProperty *prop)
+static IDProperty *IDP_CopyArray(const IDProperty *prop, const int flag)
{
- IDProperty *newp = idp_generic_copy(prop);
+ IDProperty *newp = idp_generic_copy(prop, flag);
if (prop->data.pointer) {
newp->data.pointer = MEM_dupallocN(prop->data.pointer);
@@ -310,7 +310,7 @@ static IDProperty *IDP_CopyArray(const IDProperty *prop)
int a;
for (a = 0; a < prop->len; a++)
- array[a] = IDP_CopyProperty(array[a]);
+ array[a] = IDP_CopyProperty_ex(array[a], flag);
}
}
newp->len = prop->len;
@@ -363,12 +363,12 @@ IDProperty *IDP_NewString(const char *st, const char *name, int maxlen)
return prop;
}
-static IDProperty *IDP_CopyString(const IDProperty *prop)
+static IDProperty *IDP_CopyString(const IDProperty *prop, const int flag)
{
IDProperty *newp;
BLI_assert(prop->type == IDP_STRING);
- newp = idp_generic_copy(prop);
+ newp = idp_generic_copy(prop, flag);
if (prop->data.pointer)
newp->data.pointer = MEM_dupallocN(prop->data.pointer);
@@ -442,15 +442,17 @@ void IDP_FreeString(IDProperty *prop)
/** \name IDProperty ID API
* \{ */
-static IDProperty *IDP_CopyID(const IDProperty *prop)
+static IDProperty *IDP_CopyID(const IDProperty *prop, const int flag)
{
IDProperty *newp;
BLI_assert(prop->type == IDP_ID);
- newp = idp_generic_copy(prop);
+ newp = idp_generic_copy(prop, flag);
newp->data.pointer = prop->data.pointer;
- id_us_plus(IDP_Id(newp));
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus(IDP_Id(newp));
+ }
return newp;
}
@@ -467,17 +469,17 @@ static IDProperty *IDP_CopyID(const IDProperty *prop)
/**
* Checks if a property with the same name as prop exists, and if so replaces it.
*/
-static IDProperty *IDP_CopyGroup(const IDProperty *prop)
+static IDProperty *IDP_CopyGroup(const IDProperty *prop, const int flag)
{
IDProperty *newp, *link;
BLI_assert(prop->type == IDP_GROUP);
- newp = idp_generic_copy(prop);
+ newp = idp_generic_copy(prop, flag);
newp->len = prop->len;
newp->subtype = prop->subtype;
for (link = prop->data.group.first; link; link = link->next) {
- BLI_addtail(&newp->data.group, IDP_CopyProperty(link));
+ BLI_addtail(&newp->data.group, IDP_CopyProperty_ex(link, flag));
}
return newp;
@@ -603,7 +605,7 @@ void IDP_ReplaceInGroup(IDProperty *group, IDProperty *prop)
* If a property is missing in \a dest, add it.
* Do it recursively.
*/
-void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite)
+void IDP_MergeGroup_ex(IDProperty *dest, const IDProperty *src, const bool do_overwrite, const int flag)
{
IDProperty *prop;
@@ -616,12 +618,12 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw
IDProperty *prop_exist = IDP_GetPropertyFromGroup(dest, prop->name);
if (prop_exist != NULL) {
- IDP_MergeGroup(prop_exist, prop, do_overwrite);
+ IDP_MergeGroup_ex(prop_exist, prop, do_overwrite, flag);
continue;
}
}
- IDProperty *copy = IDP_CopyProperty(prop);
+ IDProperty *copy = IDP_CopyProperty_ex(prop, flag);
IDP_ReplaceInGroup(dest, copy);
}
}
@@ -630,12 +632,12 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw
IDProperty *prop_exist = IDP_GetPropertyFromGroup(dest, prop->name);
if (prop_exist != NULL) {
if (prop->type == IDP_GROUP) {
- IDP_MergeGroup(prop_exist, prop, do_overwrite);
+ IDP_MergeGroup_ex(prop_exist, prop, do_overwrite, flag);
continue;
}
}
else {
- IDProperty *copy = IDP_CopyProperty(prop);
+ IDProperty *copy = IDP_CopyProperty_ex(prop, flag);
dest->len++;
BLI_addtail(&dest->data.group, copy);
}
@@ -644,6 +646,15 @@ void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overw
}
/**
+ * If a property is missing in \a dest, add it.
+ * Do it recursively.
+ */
+void IDP_MergeGroup(IDProperty *dest, const IDProperty *src, const bool do_overwrite)
+{
+ IDP_MergeGroup_ex(dest, src, do_overwrite, 0);
+}
+
+/**
* This function has a sanity check to make sure ID properties with the same name don't
* get added to the group.
*
@@ -748,18 +759,23 @@ static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user)
/** \name IDProperty Main API
* \{ */
-IDProperty *IDP_CopyProperty(const IDProperty *prop)
+IDProperty *IDP_CopyProperty_ex(const IDProperty *prop, const int flag)
{
switch (prop->type) {
- case IDP_GROUP: return IDP_CopyGroup(prop);
- case IDP_STRING: return IDP_CopyString(prop);
- case IDP_ID: return IDP_CopyID(prop);
- case IDP_ARRAY: return IDP_CopyArray(prop);
- case IDP_IDPARRAY: return IDP_CopyIDPArray(prop);
- default: return idp_generic_copy(prop);
+ case IDP_GROUP: return IDP_CopyGroup(prop, flag);
+ case IDP_STRING: return IDP_CopyString(prop, flag);
+ case IDP_ID: return IDP_CopyID(prop, flag);
+ case IDP_ARRAY: return IDP_CopyArray(prop, flag);
+ case IDP_IDPARRAY: return IDP_CopyIDPArray(prop, flag);
+ default: return idp_generic_copy(prop, flag);
}
}
+IDProperty *IDP_CopyProperty(const IDProperty *prop)
+{
+ return IDP_CopyProperty_ex(prop, 0);
+}
+
/* Updates ID pointers after an object has been copied */
/* TODO Nuke this once its only user has been correctly converted to use generic ID management from BKE_library! */
void IDP_RelinkProperty(struct IDProperty *prop)
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 2915e9d715d..355aa67a947 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -383,7 +383,7 @@ static Image *image_alloc(Main *bmain, const char *name, short source, short typ
{
Image *ima;
- ima = BKE_libblock_alloc(bmain, ID_IM, name);
+ ima = BKE_libblock_alloc(bmain, ID_IM, name, 0);
if (ima) {
image_init(ima, source, type);
}
@@ -434,39 +434,53 @@ static void copy_image_packedfiles(ListBase *lb_dst, const ListBase *lb_src)
}
}
-/* empty image block, of similar type and filename */
-Image *BKE_image_copy(Main *bmain, const Image *ima)
+/**
+ * Only copy internal data of Image ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_image_copy_data(Main *UNUSED(bmain), Image *ima_dst, const Image *ima_src, const int flag)
{
- Image *nima = image_alloc(bmain, ima->id.name + 2, ima->source, ima->type);
-
- BLI_strncpy(nima->name, ima->name, sizeof(ima->name));
-
- nima->flag = ima->flag;
- nima->tpageflag = ima->tpageflag;
-
- nima->gen_x = ima->gen_x;
- nima->gen_y = ima->gen_y;
- nima->gen_type = ima->gen_type;
- copy_v4_v4(nima->gen_color, ima->gen_color);
-
- nima->animspeed = ima->animspeed;
+ BKE_color_managed_colorspace_settings_copy(&ima_dst->colorspace_settings, &ima_src->colorspace_settings);
- nima->aspx = ima->aspx;
- nima->aspy = ima->aspy;
+ copy_image_packedfiles(&ima_dst->packedfiles, &ima_src->packedfiles);
- BKE_color_managed_colorspace_settings_copy(&nima->colorspace_settings, &ima->colorspace_settings);
+ ima_dst->stereo3d_format = MEM_dupallocN(ima_src->stereo3d_format);
+ BLI_duplicatelist(&ima_dst->views, &ima_src->views);
- copy_image_packedfiles(&nima->packedfiles, &ima->packedfiles);
+ /* Cleanup stuff that cannot be copied. */
+ ima_dst->cache = NULL;
+ ima_dst->rr = NULL;
+ for (int i = 0; i < IMA_MAX_RENDER_SLOT; i++) {
+ ima_dst->renders[i] = NULL;
+ }
- /* nima->stere3d_format is already allocated by image_alloc... */
- *nima->stereo3d_format = *ima->stereo3d_format;
- BLI_duplicatelist(&nima->views, &ima->views);
+ BLI_listbase_clear(&ima_dst->anims);
- BKE_previewimg_id_copy(&nima->id, &ima->id);
+ ima_dst->totbind = 0;
+ for (int i = 0; i < TEXTARGET_COUNT; i++) {
+ ima_dst->bindcode[i] = 0;
+ ima_dst->gputexture[i] = NULL;
+ }
+ ima_dst->repbind = NULL;
- BKE_id_copy_ensure_local(bmain, &ima->id, &nima->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&ima_dst->id, &ima_src->id);
+ }
+ else {
+ ima_dst->preview = NULL;
+ }
+}
- return nima;
+/* empty image block, of similar type and filename */
+Image *BKE_image_copy(Main *bmain, const Image *ima)
+{
+ Image *ima_copy;
+ BKE_id_copy_ex(bmain, &ima->id, (ID **)&ima_copy, 0, false);
+ return ima_copy;
}
void BKE_image_make_local(Main *bmain, Image *ima, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 98b251294ae..364817438c5 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -107,7 +107,7 @@ Key *BKE_key_add(ID *id) /* common function */
Key *key;
char *el;
- key = BKE_libblock_alloc(G.main, ID_KE, "Key");
+ key = BKE_libblock_alloc(G.main, ID_KE, "Key", 0);
key->type = KEY_NORMAL;
key->from = id;
@@ -151,31 +151,40 @@ Key *BKE_key_add(ID *id) /* common function */
return key;
}
-Key *BKE_key_copy(Main *bmain, const Key *key)
+/**
+ * Only copy internal data of ShapeKey ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_key_copy_data(Main *UNUSED(bmain), Key *key_dst, const Key *key_src, const int UNUSED(flag))
{
- Key *keyn;
- KeyBlock *kbn, *kb;
-
- keyn = BKE_libblock_copy(bmain, &key->id);
-
- BLI_duplicatelist(&keyn->block, &key->block);
-
- kb = key->block.first;
- kbn = keyn->block.first;
- while (kbn) {
-
- if (kbn->data) kbn->data = MEM_dupallocN(kbn->data);
- if (kb == key->refkey) keyn->refkey = kbn;
-
- kbn = kbn->next;
- kb = kb->next;
- }
+ BLI_duplicatelist(&key_dst->block, &key_src->block);
- BKE_id_copy_ensure_local(bmain, &key->id, &keyn->id);
+ KeyBlock *kb_dst, *kb_src;
+ for (kb_src = key_src->block.first, kb_dst = key_dst->block.first;
+ kb_dst;
+ kb_src = kb_src->next, kb_dst = kb_dst->next)
+ {
+ if (kb_dst->data) {
+ kb_dst->data = MEM_dupallocN(kb_dst->data);
+ }
+ if (kb_src == key_src->refkey) {
+ key_dst->refkey = kb_dst;
+ }
+ }
+}
- return keyn;
+Key *BKE_key_copy(Main *bmain, const Key *key)
+{
+ Key *key_copy;
+ BKE_id_copy_ex(bmain, &key->id, (ID **)&key_copy, 0, false);
+ return key_copy;
}
+/* XXX TODO get rid of this! */
Key *BKE_key_copy_nolib(Key *key)
{
Key *keyn;
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 4a3a1c50195..dc736b3f084 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -110,42 +110,60 @@ Lamp *BKE_lamp_add(Main *bmain, const char *name)
{
Lamp *la;
- la = BKE_libblock_alloc(bmain, ID_LA, name);
+ la = BKE_libblock_alloc(bmain, ID_LA, name, 0);
BKE_lamp_init(la);
return la;
}
-Lamp *BKE_lamp_copy(Main *bmain, const Lamp *la)
+/**
+ * Only copy internal data of Lamp ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_lamp_copy_data(Main *bmain, Lamp *la_dst, const Lamp *la_src, const int flag)
{
- Lamp *lan;
- int a;
-
- lan = BKE_libblock_copy(bmain, &la->id);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (lan->mtex[a]) {
- lan->mtex[a] = MEM_mallocN(sizeof(MTex), "copylamptex");
- memcpy(lan->mtex[a], la->mtex[a], sizeof(MTex));
- id_us_plus((ID *)lan->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (la_dst->mtex[a]) {
+ la_dst->mtex[a] = MEM_mallocN(sizeof(*la_dst->mtex[a]), __func__);
+ *la_dst->mtex[a] = *la_src->mtex[a];
}
}
-
- lan->curfalloff = curvemapping_copy(la->curfalloff);
- if (la->nodetree)
- lan->nodetree = ntreeCopyTree(bmain, la->nodetree);
+ la_dst->curfalloff = curvemapping_copy(la_src->curfalloff);
- BKE_previewimg_id_copy(&lan->id, &la->id);
+ if (la_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)la_src->nodetree, (ID **)&la_dst->nodetree, flag, false);
+ }
- BKE_id_copy_ensure_local(bmain, &la->id, &lan->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&la_dst->id, &la_src->id);
+ }
+ else {
+ la_dst->preview = NULL;
+ }
+}
- return lan;
+Lamp *BKE_lamp_copy(Main *bmain, const Lamp *la)
+{
+ Lamp *la_copy;
+ BKE_id_copy_ex(bmain, &la->id, (ID **)&la_copy, 0, false);
+ return la_copy;
}
Lamp *localize_lamp(Lamp *la)
{
+ /* TODO replace with something like
+ * Lamp *la_copy;
+ * BKE_id_copy_ex(bmain, &la->id, (ID **)&la_copy, LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT, false);
+ * return la_copy;
+ *
+ * ... Once f*** nodes are fully converted to that too :( */
+
Lamp *lan;
int a;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index fd984c17356..0f26f53113f 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -269,39 +269,46 @@ Lattice *BKE_lattice_add(Main *bmain, const char *name)
{
Lattice *lt;
- lt = BKE_libblock_alloc(bmain, ID_LT, name);
+ lt = BKE_libblock_alloc(bmain, ID_LT, name, 0);
BKE_lattice_init(lt);
return lt;
}
-Lattice *BKE_lattice_copy(Main *bmain, const Lattice *lt)
+/**
+ * Only copy internal data of Lattice ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_lattice_copy_data(Main *bmain, Lattice *lt_dst, const Lattice *lt_src, const int flag)
{
- Lattice *ltn;
-
- ltn = BKE_libblock_copy(bmain, &lt->id);
- ltn->def = MEM_dupallocN(lt->def);
+ lt_dst->def = MEM_dupallocN(lt_src->def);
- if (lt->key) {
- ltn->key = BKE_key_copy(bmain, ltn->key);
- ltn->key->from = (ID *)ltn;
- }
-
- if (lt->dvert) {
- int tot = lt->pntsu * lt->pntsv * lt->pntsw;
- ltn->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
- BKE_defvert_array_copy(ltn->dvert, lt->dvert, tot);
+ if (lt_src->key) {
+ BKE_id_copy_ex(bmain, &lt_src->key->id, (ID **)&lt_dst->key, flag, false);
}
- ltn->editlatt = NULL;
+ if (lt_src->dvert) {
+ int tot = lt_src->pntsu * lt_src->pntsv * lt_src->pntsw;
+ lt_dst->dvert = MEM_mallocN(sizeof(MDeformVert) * tot, "Lattice MDeformVert");
+ BKE_defvert_array_copy(lt_dst->dvert, lt_src->dvert, tot);
+ }
- BKE_id_copy_ensure_local(bmain, &lt->id, &ltn->id);
+ lt_dst->editlatt = NULL;
+}
- return ltn;
+Lattice *BKE_lattice_copy(Main *bmain, const Lattice *lt)
+{
+ Lattice *lt_copy;
+ BKE_id_copy_ex(bmain, &lt->id, (ID **)&lt_copy, 0, false);
+ return lt_copy;
}
-/** Free (or release) any data used by this lattice (does not free the lattice itself). */
+ /** Free (or release) any data used by this lattice (does not free the lattice itself). */
void BKE_lattice_free(Lattice *lt)
{
BKE_animdata_free(&lt->id, false);
@@ -596,7 +603,7 @@ static bool where_on_path_deform(Object *ob, float ctime, float vec[4], float di
/* co: local coord, result local too */
/* returns quaternion for rotation, using cd->no_rot_axis */
/* axis is using another define!!! */
-static bool calc_curve_deform(struct EvaluationContext *eval_ctx, Scene *scene, Object *par, float co[3],
+static bool calc_curve_deform(const struct EvaluationContext *eval_ctx, Scene *scene, Object *par, float co[3],
const short axis, CurveDeform *cd, float r_quat[4])
{
Curve *cu = par->data;
@@ -700,7 +707,8 @@ static bool calc_curve_deform(struct EvaluationContext *eval_ctx, Scene *scene,
}
void curve_deform_verts(
- struct EvaluationContext *eval_ctx, Scene *scene, Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
+ const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *cuOb, Object *target, DerivedMesh *dm, float (*vertexCos)[3],
int numVerts, const char *vgroup, short defaxis)
{
Curve *cu;
@@ -818,7 +826,7 @@ void curve_deform_verts(
/* input vec and orco = local coord in armature space */
/* orco is original not-animated or deformed reference point */
/* result written in vec and mat */
-void curve_deform_vector(struct EvaluationContext *eval_ctx, Scene *scene, Object *cuOb, Object *target,
+void curve_deform_vector(const struct EvaluationContext *eval_ctx, Scene *scene, Object *cuOb, Object *target,
float orco[3], float vec[3], float mat[3][3], int no_rot_axis)
{
CurveDeform cd;
@@ -1027,7 +1035,7 @@ void BKE_lattice_vertexcos_apply(struct Object *ob, float (*vertexCos)[3])
}
}
-void BKE_lattice_modifiers_calc(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_lattice_modifiers_calc(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
Lattice *lt = ob->data;
VirtualModifierData virtualModifierData;
@@ -1228,7 +1236,7 @@ void BKE_lattice_translate(Lattice *lt, float offset[3], bool do_keys)
/* **** Depsgraph evaluation **** */
-void BKE_lattice_eval_geometry(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_lattice_eval_geometry(const struct EvaluationContext *UNUSED(eval_ctx),
Lattice *UNUSED(latt))
{
}
diff --git a/source/blender/blenkernel/intern/layer.c b/source/blender/blenkernel/intern/layer.c
index 56b9bd2cc1e..16a4477977f 100644
--- a/source/blender/blenkernel/intern/layer.c
+++ b/source/blender/blenkernel/intern/layer.c
@@ -1734,7 +1734,7 @@ static void idproperty_reset(IDProperty **props, IDProperty *props_ref)
}
}
-void BKE_layer_eval_layer_collection_pre(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_layer_eval_layer_collection_pre(const struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene, SceneLayer *scene_layer)
{
DEBUG_PRINT("%s on %s (%p)\n", __func__, scene_layer->name, scene_layer);
@@ -1751,7 +1751,7 @@ void BKE_layer_eval_layer_collection_pre(struct EvaluationContext *UNUSED(eval_c
scene_layer->flag |= SCENE_LAYER_ENGINE_DIRTY;
}
-void BKE_layer_eval_layer_collection(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_layer_eval_layer_collection(const struct EvaluationContext *UNUSED(eval_ctx),
LayerCollection *layer_collection,
LayerCollection *parent_layer_collection)
{
@@ -1798,7 +1798,7 @@ void BKE_layer_eval_layer_collection(struct EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_layer_eval_layer_collection_post(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_layer_eval_layer_collection_post(const struct EvaluationContext *UNUSED(eval_ctx),
SceneLayer *scene_layer)
{
DEBUG_PRINT("%s on %s (%p)\n", __func__, scene_layer->name, scene_layer);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index ed64de9b1aa..71fbb3d726a 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -385,7 +385,6 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
switch ((ID_Type)GS(id->name)) {
case ID_SCE:
- /* Partially implemented (has no copy...). */
if (!test) BKE_scene_make_local(bmain, (Scene *)id, lib_local);
return true;
case ID_OB:
@@ -428,14 +427,12 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
if (!test) BKE_world_make_local(bmain, (World *)id, lib_local);
return true;
case ID_VF:
- /* Partially implemented (has no copy...). */
if (!test) BKE_vfont_make_local(bmain, (VFont *)id, lib_local);
return true;
case ID_TXT:
if (!test) BKE_text_make_local(bmain, (Text *)id, lib_local);
return true;
case ID_SO:
- /* Partially implemented (has no copy...). */
if (!test) BKE_sound_make_local(bmain, (bSound *)id, lib_local);
return true;
case ID_GR:
@@ -493,118 +490,193 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
return false;
}
+struct IDCopyLibManagementData {
+ const ID *id_src;
+ ID *id_dst;
+ int flag;
+};
+
+/* Increases usercount as required, and remap self ID pointers. */
+static int id_copy_libmanagement_cb(void *user_data, ID *UNUSED(id_self), ID **id_pointer, int cb_flag)
+{
+ struct IDCopyLibManagementData *data = user_data;
+ ID *id = *id_pointer;
+
+ /* Remap self-references to new copied ID. */
+ if (id == data->id_src) {
+ /* We cannot use id_self here, it is not *always* id_dst (thanks to $£!+@#&/? nodetrees). */
+ id = *id_pointer = data->id_dst;
+ }
+
+ /* Increase used IDs refcount if needed and required. */
+ if ((data->flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0 && (cb_flag & IDWALK_CB_USER)) {
+ id_us_plus(id);
+ }
+
+ return IDWALK_RET_NOP;
+}
+
/**
- * Invokes the appropriate copy method for the block and returns the result in
- * newid, unless test. Returns true if the block can be copied.
+ * Generic entry point for copying a datablock (new API).
+ *
+ * \note Copy is only affecting given data-block (no ID used by copied one will be affected, besides usercount).
+ * There is only one exception, if LIB_ID_COPY_ACTIONS is defined, actions used by animdata will be duplicated.
+ *
+ * \note Usercount of new copy is always set to 1.
+ *
+ * \param bmain Main database, may be NULL only if LIB_ID_COPY_NO_MAIN is specified.
+ * \param id Source datablock.
+ * \param r_newid Pointer to new (copied) ID pointer.
+ * \param flag Set of copy options, see DNA_ID.h enum for details (leave to zero for default, full copy).
+ * \param test If set, do not do any copy, just test whether copy is supported.
+ * \return False when copying that ID type is not supported, true otherwise.
*/
-bool id_copy(Main *bmain, const ID *id, ID **newid, bool test)
+/* XXX TODO remove test thing, *all* IDs should be copyable that way! */
+bool BKE_id_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag, const bool test)
{
- if (!test) {
- *newid = NULL;
+#define LIB_ID_TYPES_NOCOPY ID_LI, ID_SCR, ID_WM, /* Not supported */ \
+ ID_IP /* Deprecated */
+
+ BLI_assert(test || (r_newid != NULL));
+ if (r_newid != NULL) {
+ *r_newid = NULL;
+ }
+ if (id == NULL) {
+ return false;
}
- /* conventions:
- * - make shallow copy, only this ID block
- * - id.us of the new ID is set to 1 */
+ if (ELEM(GS(id->name), LIB_ID_TYPES_NOCOPY)) {
+ return false;
+ }
+ else if (test) {
+ return true;
+ }
+
+ BKE_libblock_copy_ex(bmain, id, r_newid, flag);
+
switch ((ID_Type)GS(id->name)) {
+ case ID_SCE:
+ BKE_scene_copy_data(bmain, (Scene *)*r_newid, (Scene *)id, flag);
+ break;
case ID_OB:
- if (!test) *newid = (ID *)BKE_object_copy(bmain, (Object *)id);
- return true;
+ BKE_object_copy_data(bmain, (Object *)*r_newid, (Object *)id, flag);
+ break;
case ID_ME:
- if (!test) *newid = (ID *)BKE_mesh_copy(bmain, (Mesh *)id);
- return true;
+ BKE_mesh_copy_data(bmain, (Mesh *)*r_newid, (Mesh *)id, flag);
+ break;
case ID_CU:
- if (!test) *newid = (ID *)BKE_curve_copy(bmain, (Curve *)id);
- return true;
+ BKE_curve_copy_data(bmain, (Curve *)*r_newid, (Curve *)id, flag);
+ break;
case ID_MB:
- if (!test) *newid = (ID *)BKE_mball_copy(bmain, (MetaBall *)id);
- return true;
+ BKE_mball_copy_data(bmain, (MetaBall *)*r_newid, (MetaBall *)id, flag);
+ break;
case ID_MA:
- if (!test) *newid = (ID *)BKE_material_copy(bmain, (Material *)id);
- return true;
+ BKE_material_copy_data(bmain, (Material *)*r_newid, (Material *)id, flag);
+ break;
case ID_TE:
- if (!test) *newid = (ID *)BKE_texture_copy(bmain, (Tex *)id);
- return true;
+ BKE_texture_copy_data(bmain, (Tex *)*r_newid, (Tex *)id, flag);
+ break;
case ID_IM:
- if (!test) *newid = (ID *)BKE_image_copy(bmain, (Image *)id);
- return true;
+ BKE_image_copy_data(bmain, (Image *)*r_newid, (Image *)id, flag);
+ break;
case ID_LT:
- if (!test) *newid = (ID *)BKE_lattice_copy(bmain, (Lattice *)id);
- return true;
+ BKE_lattice_copy_data(bmain, (Lattice *)*r_newid, (Lattice *)id, flag);
+ break;
case ID_LA:
- if (!test) *newid = (ID *)BKE_lamp_copy(bmain, (Lamp *)id);
- return true;
+ BKE_lamp_copy_data(bmain, (Lamp *)*r_newid, (Lamp *)id, flag);
+ break;
case ID_SPK:
- if (!test) *newid = (ID *)BKE_speaker_copy(bmain, (Speaker *)id);
- return true;
+ BKE_speaker_copy_data(bmain, (Speaker *)*r_newid, (Speaker *)id, flag);
+ break;
case ID_LP:
- if (!test) *newid = (ID *)BKE_lightprobe_copy(bmain, (LightProbe *)id);
- return true;
+ BKE_lightprobe_copy_data(bmain, (LightProbe *)*r_newid, (LightProbe *)id, flag);
+ break;
case ID_CA:
- if (!test) *newid = (ID *)BKE_camera_copy(bmain, (Camera *)id);
- return true;
+ BKE_camera_copy_data(bmain, (Camera *)*r_newid, (Camera *)id, flag);
+ break;
case ID_KE:
- if (!test) *newid = (ID *)BKE_key_copy(bmain, (Key *)id);
- return true;
+ BKE_key_copy_data(bmain, (Key *)*r_newid, (Key *)id, flag);
+ break;
case ID_WO:
- if (!test) *newid = (ID *)BKE_world_copy(bmain, (World *)id);
- return true;
+ BKE_world_copy_data(bmain, (World *)*r_newid, (World *)id, flag);
+ break;
case ID_TXT:
- if (!test) *newid = (ID *)BKE_text_copy(bmain, (Text *)id);
- return true;
+ BKE_text_copy_data(bmain, (Text *)*r_newid, (Text *)id, flag);
+ break;
case ID_GR:
- if (!test) *newid = (ID *)BKE_group_copy(bmain, (Group *)id);
- return true;
+ BKE_group_copy_data(bmain, (Group *)*r_newid, (Group *)id, flag);
+ break;
case ID_AR:
- if (!test) *newid = (ID *)BKE_armature_copy(bmain, (bArmature *)id);
- return true;
+ BKE_armature_copy_data(bmain, (bArmature *)*r_newid, (bArmature *)id, flag);
+ break;
case ID_AC:
- if (!test) *newid = (ID *)BKE_action_copy(bmain, (bAction *)id);
- return true;
+ BKE_action_copy_data(bmain, (bAction *)*r_newid, (bAction *)id, flag);
+ break;
case ID_NT:
- if (!test) *newid = (ID *)ntreeCopyTree(bmain, (bNodeTree *)id);
- return true;
+ BKE_node_tree_copy_data(bmain, (bNodeTree *)*r_newid, (bNodeTree *)id, flag);
+ break;
case ID_BR:
- if (!test) *newid = (ID *)BKE_brush_copy(bmain, (Brush *)id);
- return true;
+ BKE_brush_copy_data(bmain, (Brush *)*r_newid, (Brush *)id, flag);
+ break;
case ID_PA:
- if (!test) *newid = (ID *)BKE_particlesettings_copy(bmain, (ParticleSettings *)id);
- return true;
+ BKE_particlesettings_copy_data(bmain, (ParticleSettings *)*r_newid, (ParticleSettings *)id, flag);
+ break;
case ID_GD:
- if (!test) *newid = (ID *)BKE_gpencil_data_duplicate(bmain, (bGPdata *)id, false);
- return true;
+ BKE_gpencil_copy_data(bmain, (bGPdata *)*r_newid, (bGPdata *)id, flag);
+ break;
case ID_MC:
- if (!test) *newid = (ID *)BKE_movieclip_copy(bmain, (MovieClip *)id);
- return true;
+ BKE_movieclip_copy_data(bmain, (MovieClip *)*r_newid, (MovieClip *)id, flag);
+ break;
case ID_MSK:
- if (!test) *newid = (ID *)BKE_mask_copy(bmain, (Mask *)id);
- return true;
+ BKE_mask_copy_data(bmain, (Mask *)*r_newid, (Mask *)id, flag);
+ break;
case ID_LS:
- if (!test) *newid = (ID *)BKE_linestyle_copy(bmain, (FreestyleLineStyle *)id);
- return true;
+ BKE_linestyle_copy_data(bmain, (FreestyleLineStyle *)*r_newid, (FreestyleLineStyle *)id, flag);
+ break;
case ID_PAL:
- if (!test) *newid = (ID *)BKE_palette_copy(bmain, (Palette *)id);
- return true;
+ BKE_palette_copy_data(bmain, (Palette *)*r_newid, (Palette *)id, flag);
+ break;
case ID_PC:
- if (!test) *newid = (ID *)BKE_paint_curve_copy(bmain, (PaintCurve *)id);
- return true;
+ BKE_paint_curve_copy_data(bmain, (PaintCurve *)*r_newid, (PaintCurve *)id, flag);
+ break;
case ID_CF:
- if (!test) *newid = (ID *)BKE_cachefile_copy(bmain, (CacheFile *)id);
- return true;
- case ID_WS:
- case ID_SCE:
+ BKE_cachefile_copy_data(bmain, (CacheFile *)*r_newid, (CacheFile *)id, flag);
+ break;
+ case ID_SO:
+ BKE_sound_copy_data(bmain, (bSound *)*r_newid, (bSound *)id, flag);
+ break;
+ case ID_VF:
+ BKE_vfont_copy_data(bmain, (VFont *)*r_newid, (VFont *)id, flag);
+ break;
case ID_LI:
case ID_SCR:
case ID_WM:
- return false; /* can't be copied from here */
- case ID_VF:
- case ID_SO:
- return false; /* not implemented */
+ case ID_WS:
case ID_IP:
- return false; /* deprecated */
+ BLI_assert(0); /* Should have been rejected at start of function! */
+ break;
}
-
- return false;
+
+ /* Update ID refcount, remap pointers to self in new ID. */
+ struct IDCopyLibManagementData data = {.id_src = id, .id_dst = *r_newid, .flag = flag};
+ BKE_library_foreach_ID_link(bmain, *r_newid, id_copy_libmanagement_cb, &data, IDWALK_NOP);
+
+ /* Do not make new copy local in case we are copying outside of main...
+ * XXX TODO: is this behavior OK, or should we need own flag to control that? */
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ BKE_id_copy_ensure_local(bmain, id, *r_newid);
+ }
+
+ return true;
+}
+
+/**
+ * Invokes the appropriate copy method for the block and returns the result in
+ * newid, unless test. Returns true if the block can be copied.
+ */
+bool id_copy(Main *bmain, const ID *id, ID **newid, bool test)
+{
+ return BKE_id_copy_ex(bmain, id, newid, 0, test);
}
/** Does *not* set ID->newid pointer. */
@@ -636,6 +708,101 @@ bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
return false;
}
+static int libblock_management_us_plus(void *UNUSED(user_data), ID *UNUSED(id_self), ID **id_pointer, int cb_flag)
+{
+ if (cb_flag & IDWALK_CB_USER) {
+ id_us_plus(*id_pointer);
+ }
+ if (cb_flag & IDWALK_CB_USER_ONE) {
+ id_us_ensure_real(*id_pointer);
+ }
+
+ return IDWALK_RET_NOP;
+}
+
+static int libblock_management_us_min(void *UNUSED(user_data), ID *UNUSED(id_self), ID **id_pointer, int cb_flag)
+{
+ if (cb_flag & IDWALK_CB_USER) {
+ id_us_min(*id_pointer);
+ }
+ /* We can do nothing in IDWALK_CB_USER_ONE case! */
+
+ return IDWALK_RET_NOP;
+}
+
+/** Add a 'NO_MAIN' datablock to given main (also sets usercounts of its IDs if needed). */
+void BKE_libblock_management_main_add(Main *bmain, void *idv)
+{
+ ID *id = idv;
+
+ BLI_assert(bmain != NULL);
+ if ((id->tag & LIB_TAG_NO_MAIN) == 0) {
+ return;
+ }
+
+ if ((id->tag & LIB_TAG_NOT_ALLOCATED) != 0) {
+ /* We cannot add non-allocated ID to Main! */
+ return;
+ }
+
+ /* We cannot allow non-userrefcounting IDs in Main database! */
+ if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0) {
+ BKE_library_foreach_ID_link(bmain, id, libblock_management_us_plus, NULL, IDWALK_NOP);
+ }
+
+ ListBase *lb = which_libbase(bmain, GS(id->name));
+ BKE_main_lock(bmain);
+ BLI_addtail(lb, id);
+ new_id(lb, id, NULL);
+ /* alphabetic insertion: is in new_id */
+ id->tag &= ~(LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT);
+ BKE_main_unlock(bmain);
+}
+
+/** Remove a datablock from given main (set it to 'NO_MAIN' status). */
+void BKE_libblock_management_main_remove(Main *bmain, void *idv)
+{
+ ID *id = idv;
+
+ BLI_assert(bmain != NULL);
+ if ((id->tag & LIB_TAG_NO_MAIN) != 0) {
+ return;
+ }
+
+ /* For now, allow userrefcounting IDs to get out of Main - can be handy in some cases... */
+
+ ListBase *lb = which_libbase(bmain, GS(id->name));
+ BKE_main_lock(bmain);
+ BLI_remlink(lb, id);
+ id->tag |= LIB_TAG_NO_MAIN;
+ BKE_main_unlock(bmain);
+}
+
+void BKE_libblock_management_usercounts_set(Main *bmain, void *idv)
+{
+ ID *id = idv;
+
+ if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) == 0) {
+ return;
+ }
+
+ BKE_library_foreach_ID_link(bmain, id, libblock_management_us_plus, NULL, IDWALK_NOP);
+ id->tag &= ~LIB_TAG_NO_USER_REFCOUNT;
+}
+
+void BKE_libblock_management_usercounts_clear(Main *bmain, void *idv)
+{
+ ID *id = idv;
+
+ /* We do not allow IDs in Main database to not be userrefcounting. */
+ if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0 || (id->tag & LIB_TAG_NO_MAIN) != 0) {
+ return;
+ }
+
+ BKE_library_foreach_ID_link(bmain, id, libblock_management_us_min, NULL, IDWALK_NOP);
+ id->tag |= LIB_TAG_NO_USER_REFCOUNT;
+}
+
ListBase *which_libbase(Main *mainlib, short type)
{
switch ((ID_Type)type) {
@@ -953,23 +1120,44 @@ void *BKE_libblock_alloc_notest(short type)
* The user count is set to 1, all other content (apart from name and links) being
* initialized to zero.
*/
-void *BKE_libblock_alloc(Main *bmain, short type, const char *name)
+void *BKE_libblock_alloc(Main *bmain, short type, const char *name, const int flag)
{
- ID *id = NULL;
- ListBase *lb = which_libbase(bmain, type);
-
- id = BKE_libblock_alloc_notest(type);
+ BLI_assert((flag & LIB_ID_CREATE_NO_ALLOCATE) == 0);
+
+ ID *id = BKE_libblock_alloc_notest(type);
+
if (id) {
- BKE_main_lock(bmain);
- BLI_addtail(lb, id);
- id->us = 1;
+ if ((flag & LIB_ID_CREATE_NO_MAIN) != 0) {
+ id->tag |= LIB_TAG_NO_MAIN;
+ }
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) != 0) {
+ id->tag |= LIB_TAG_NO_USER_REFCOUNT;
+ }
+
id->icon_id = 0;
- *( (short *)id->name) = type;
- new_id(lb, id, name);
- /* alphabetic insertion: is in new_id */
- BKE_main_unlock(bmain);
+ *((short *)id->name) = type;
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id->us = 1;
+ }
+ if ((flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ ListBase *lb = which_libbase(bmain, type);
+
+ BKE_main_lock(bmain);
+ BLI_addtail(lb, id);
+ new_id(lb, id, name);
+ /* alphabetic insertion: is in new_id */
+ BKE_main_unlock(bmain);
+
+ /* TODO to be removed from here! */
+ if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0) {
+ DEG_id_type_tag(bmain, type);
+ }
+ }
+ else {
+ BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2);
+ }
}
- DEG_id_type_tag(bmain, type);
+
return id;
}
@@ -1095,70 +1283,80 @@ void BKE_libblock_init_empty(ID *id)
/* by spec, animdata is first item after ID */
/* and, trust that BKE_animdata_from_id() will only find AnimData for valid ID-types */
-static void id_copy_animdata(ID *id, const bool do_action)
+static void id_copy_animdata(Main *bmain, ID *id, const bool do_action)
{
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
IdAdtTemplate *iat = (IdAdtTemplate *)id;
- iat->adt = BKE_animdata_copy(iat->adt, do_action); /* could be set to false, need to investigate */
+ iat->adt = BKE_animdata_copy(bmain, iat->adt, do_action); /* could be set to false, need to investigate */
}
}
-/* material nodes use this since they are not treated as libdata */
-void BKE_libblock_copy_data(ID *id, const ID *id_from, const bool do_action)
+void BKE_libblock_copy_ex(Main *bmain, const ID *id, ID **r_newid, const int flag)
{
- if (id_from->properties)
- id->properties = IDP_CopyProperty(id_from->properties);
+ ID *new_id = *r_newid;
+
+ /* Grrrrrrrrr... Not adding 'root' nodetrees to bmain.... grrrrrrrrrrrrrrrrrrrr! */
+ /* This is taken from original ntree copy code, might be weak actually? */
+ const bool use_nodetree_alloc_exception = ((GS(id->name) == ID_NT) && (bmain != NULL) &&
+ (BLI_findindex(&bmain->nodetree, id) < 0));
+
+ BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || bmain != NULL);
+ BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) != 0 || (flag & LIB_ID_CREATE_NO_ALLOCATE) == 0);
+ BLI_assert((flag & LIB_ID_CREATE_NO_MAIN) == 0 || (flag & LIB_ID_CREATE_NO_USER_REFCOUNT) != 0);
+
+ if ((flag & LIB_ID_CREATE_NO_ALLOCATE) != 0) {
+ /* r_newid already contains pointer to allocated memory. */
+ /* TODO do we want to memset(0) whole mem before filling it? */
+ BLI_strncpy(new_id->name, id->name, sizeof(new_id->name));
+ new_id->us = 0;
+ new_id->tag |= LIB_TAG_NOT_ALLOCATED | LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT;
+ /* TODO Do we want/need to copy more from ID struct itself? */
+ }
+ else {
+ new_id = BKE_libblock_alloc(bmain, GS(id->name), id->name + 2, flag | (use_nodetree_alloc_exception ? LIB_ID_CREATE_NO_MAIN : 0));
+ }
+ BLI_assert(new_id != NULL);
+
+ const size_t id_len = BKE_libblock_get_alloc_info(GS(new_id->name), NULL);
+ const size_t id_offset = sizeof(ID);
+ if ((int)id_len - (int)id_offset > 0) { /* signed to allow neg result */ /* XXX ????? */
+ const char *cp = (const char *)id;
+ char *cpn = (char *)new_id;
+
+ memcpy(cpn + id_offset, cp + id_offset, id_len - id_offset);
+ }
+
+ if (id->properties) {
+ new_id->properties = IDP_CopyProperty_ex(id->properties, flag);
+ }
/* the duplicate should get a copy of the animdata */
- id_copy_animdata(id, do_action);
+ id_copy_animdata(bmain, new_id, (flag & LIB_ID_COPY_ACTIONS) != 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0);
+
+ if ((flag & LIB_ID_CREATE_NO_DEG_TAG) == 0 && (flag & LIB_ID_CREATE_NO_MAIN) == 0) {
+ DEG_id_type_tag(bmain, GS(new_id->name));
+ }
+
+ *r_newid = new_id;
}
/* used everywhere in blenkernel */
void *BKE_libblock_copy(Main *bmain, const ID *id)
{
ID *idn;
- size_t idn_len;
-
- idn = BKE_libblock_alloc(bmain, GS(id->name), id->name + 2);
- assert(idn != NULL);
+ BKE_libblock_copy_ex(bmain, id, &idn, 0);
- idn_len = MEM_allocN_len(idn);
- if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
- const char *cp = (const char *)id;
- char *cpn = (char *)idn;
-
- memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
- }
-
- BKE_libblock_copy_data(idn, id, false);
-
return idn;
}
void *BKE_libblock_copy_nolib(const ID *id, const bool do_action)
{
ID *idn;
- size_t idn_len;
-
- idn = BKE_libblock_alloc_notest(GS(id->name));
- assert(idn != NULL);
-
- BLI_strncpy(idn->name, id->name, sizeof(idn->name));
-
- idn_len = MEM_allocN_len(idn);
- if ((int)idn_len - (int)sizeof(ID) > 0) { /* signed to allow neg result */
- const char *cp = (const char *)id;
- char *cpn = (char *)idn;
-
- memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
- }
-
- idn->us = 1;
- BKE_libblock_copy_data(idn, id, do_action);
+ BKE_libblock_copy_ex(NULL, id, &idn, LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | (do_action ? LIB_ID_COPY_ACTIONS : 0));
return idn;
}
@@ -1198,41 +1396,41 @@ void BKE_main_free(Main *mainvar)
/* errors freeing ID's can be hard to track down,
* enable this so valgrind will give the line number in its error log */
switch (a) {
- case 0: BKE_libblock_free_ex(mainvar, id, false); break;
- case 1: BKE_libblock_free_ex(mainvar, id, false); break;
- case 2: BKE_libblock_free_ex(mainvar, id, false); break;
- case 3: BKE_libblock_free_ex(mainvar, id, false); break;
- case 4: BKE_libblock_free_ex(mainvar, id, false); break;
- case 5: BKE_libblock_free_ex(mainvar, id, false); break;
- case 6: BKE_libblock_free_ex(mainvar, id, false); break;
- case 7: BKE_libblock_free_ex(mainvar, id, false); break;
- case 8: BKE_libblock_free_ex(mainvar, id, false); break;
- case 9: BKE_libblock_free_ex(mainvar, id, false); break;
- case 10: BKE_libblock_free_ex(mainvar, id, false); break;
- case 11: BKE_libblock_free_ex(mainvar, id, false); break;
- case 12: BKE_libblock_free_ex(mainvar, id, false); break;
- case 13: BKE_libblock_free_ex(mainvar, id, false); break;
- case 14: BKE_libblock_free_ex(mainvar, id, false); break;
- case 15: BKE_libblock_free_ex(mainvar, id, false); break;
- case 16: BKE_libblock_free_ex(mainvar, id, false); break;
- case 17: BKE_libblock_free_ex(mainvar, id, false); break;
- case 18: BKE_libblock_free_ex(mainvar, id, false); break;
- case 19: BKE_libblock_free_ex(mainvar, id, false); break;
- case 20: BKE_libblock_free_ex(mainvar, id, false); break;
- case 21: BKE_libblock_free_ex(mainvar, id, false); break;
- case 22: BKE_libblock_free_ex(mainvar, id, false); break;
- case 23: BKE_libblock_free_ex(mainvar, id, false); break;
- case 24: BKE_libblock_free_ex(mainvar, id, false); break;
- case 25: BKE_libblock_free_ex(mainvar, id, false); break;
- case 26: BKE_libblock_free_ex(mainvar, id, false); break;
- case 27: BKE_libblock_free_ex(mainvar, id, false); break;
- case 28: BKE_libblock_free_ex(mainvar, id, false); break;
- case 29: BKE_libblock_free_ex(mainvar, id, false); break;
- case 30: BKE_libblock_free_ex(mainvar, id, false); break;
- case 31: BKE_libblock_free_ex(mainvar, id, false); break;
- case 32: BKE_libblock_free_ex(mainvar, id, false); break;
- case 33: BKE_libblock_free_ex(mainvar, id, false); break;
- case 34: BKE_libblock_free_ex(mainvar, id, false); break;
+ case 0: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 1: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 2: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 3: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 4: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 5: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 6: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 7: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 8: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 9: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 10: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 11: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 12: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 13: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 14: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 15: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 16: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 17: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 18: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 19: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 20: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 21: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 22: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 23: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 24: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 25: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 26: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 27: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 28: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 29: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 30: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 31: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 32: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 33: BKE_libblock_free_ex(mainvar, id, false, false); break;
+ case 34: BKE_libblock_free_ex(mainvar, id, false, false); break;
default:
BLI_assert(0);
break;
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index 7310370ca10..8f0bb26a0c1 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -248,7 +248,7 @@ static int foreach_libblock_remap_callback(void *user_data, ID *id_self, ID **id
return IDWALK_RET_NOP;
}
-/* Some reamapping unfortunately require extra and/or specific handling, tackle those here. */
+/* Some remapping unfortunately require extra and/or specific handling, tackle those here. */
static void libblock_remap_data_preprocess_scene_base_unlink(
IDRemap *r_id_remap_data, Scene *sce, BaseLegacy *base, const bool skip_indirect, const bool is_indirect)
{
@@ -352,7 +352,7 @@ static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data)
}
}
-static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain, Object *old_ob, Object *new_ob)
+static void libblock_remap_data_postprocess_object_update(Main *bmain, Object *old_ob, Object *new_ob)
{
if (old_ob->flag & OB_FROMGROUP) {
/* Note that for Scene's BaseObject->flag, either we:
@@ -371,6 +371,13 @@ static void libblock_remap_data_postprocess_object_fromgroup_update(Main *bmain,
new_ob->flag |= OB_FROMGROUP;
}
}
+ if (old_ob->type == OB_MBALL) {
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->type == OB_MBALL && BKE_mball_is_basis_for(ob, old_ob)) {
+ DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ }
+ }
+ }
}
static void libblock_remap_data_postprocess_group_scene_unlink(Main *UNUSED(bmain), Scene *sce, ID *old_id)
@@ -575,7 +582,7 @@ void BKE_libblock_remap_locked(
*/
switch (GS(old_id->name)) {
case ID_OB:
- libblock_remap_data_postprocess_object_fromgroup_update(bmain, (Object *)old_id, (Object *)new_id);
+ libblock_remap_data_postprocess_object_update(bmain, (Object *)old_id, (Object *)new_id);
break;
case ID_GR:
if (!new_id) { /* Only affects us in case group was unlinked. */
@@ -605,7 +612,7 @@ void BKE_libblock_remap_locked(
libblock_remap_data_postprocess_nodetree_update(bmain, new_id);
BKE_main_lock(bmain);
- /* Full rebuild of DAG! */
+ /* Full rebuild of DEG! */
DEG_relations_tag_update(bmain);
}
@@ -685,8 +692,7 @@ void BKE_libblock_relink_ex(
switch (GS(old_id->name)) {
case ID_OB:
{
- libblock_remap_data_postprocess_object_fromgroup_update(
- bmain, (Object *)old_id, (Object *)new_id);
+ libblock_remap_data_postprocess_object_update(bmain, (Object *)old_id, (Object *)new_id);
break;
}
case ID_GR:
@@ -701,7 +707,7 @@ void BKE_libblock_relink_ex(
else {
/* No choice but to check whole objects/groups. */
for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
- libblock_remap_data_postprocess_object_fromgroup_update(bmain, ob, NULL);
+ libblock_remap_data_postprocess_object_update(bmain, ob, NULL);
}
for (Group *grp = bmain->group.first; grp; grp = grp->id.next) {
libblock_remap_data_postprocess_group_scene_unlink(bmain, sce, NULL);
@@ -758,9 +764,11 @@ void BKE_libblock_free_data(ID *id, const bool do_id_user)
IDP_FreeProperty_ex(id->properties, do_id_user);
MEM_freeN(id->properties);
}
+
+ /* XXX TODO remove animdata handling from each type's freeing func, and do it here, like for copy! */
}
-void BKE_libblock_free_datablock(ID *id)
+void BKE_libblock_free_datablock(ID *id, const int UNUSED(flag))
{
const short type = GS(id->name);
switch (type) {
@@ -876,6 +884,90 @@ void BKE_libblock_free_datablock(ID *id)
}
}
+
+void BKE_id_free_ex(Main *bmain, void *idv, int flag, const bool use_flag_from_idtag)
+{
+ ID *id = idv;
+
+ if (use_flag_from_idtag) {
+ if ((id->tag & LIB_TAG_NO_MAIN) != 0) {
+ flag |= LIB_ID_FREE_NO_MAIN;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NO_MAIN;
+ }
+
+ if ((id->tag & LIB_TAG_NO_USER_REFCOUNT) != 0) {
+ flag |= LIB_ID_FREE_NO_USER_REFCOUNT;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NO_USER_REFCOUNT;
+ }
+
+ if ((id->tag & LIB_TAG_NOT_ALLOCATED) != 0) {
+ flag |= LIB_ID_FREE_NOT_ALLOCATED;
+ }
+ else {
+ flag &= ~LIB_ID_FREE_NOT_ALLOCATED;
+ }
+ }
+
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || bmain != NULL);
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NOT_ALLOCATED) == 0);
+ BLI_assert((flag & LIB_ID_FREE_NO_MAIN) != 0 || (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
+
+ const short type = GS(id->name);
+
+ if (bmain && (flag & LIB_ID_FREE_NO_DEG_TAG) == 0) {
+ DEG_id_type_tag(bmain, type);
+ }
+
+#ifdef WITH_PYTHON
+ BPY_id_release(id);
+#endif
+
+ if ((flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0) {
+ BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
+ }
+
+ BKE_libblock_free_datablock(id, flag);
+
+ /* avoid notifying on removed data */
+ if (bmain) {
+ BKE_main_lock(bmain);
+ }
+
+ if ((flag & LIB_ID_FREE_NO_UI_USER) == 0) {
+ if (free_notifier_reference_cb) {
+ free_notifier_reference_cb(id);
+ }
+
+ if (remap_editor_id_reference_cb) {
+ remap_editor_id_reference_cb(id, NULL);
+ }
+ }
+
+ if ((flag & LIB_ID_FREE_NO_MAIN) == 0) {
+ ListBase *lb = which_libbase(bmain, type);
+ BLI_remlink(lb, id);
+ }
+
+ BKE_libblock_free_data(id, (flag & LIB_ID_FREE_NO_USER_REFCOUNT) == 0);
+
+ if (bmain) {
+ BKE_main_unlock(bmain);
+ }
+
+ if ((flag & LIB_ID_FREE_NOT_ALLOCATED) == 0) {
+ MEM_freeN(id);
+ }
+}
+
+void BKE_id_free(Main *bmain, void *idv)
+{
+ BKE_id_free_ex(bmain, idv, 0, true);
+}
+
/**
* used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
*
@@ -905,7 +997,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
}
- BKE_libblock_free_datablock(id);
+ BKE_libblock_free_datablock(id, 0);
/* avoid notifying on removed data */
BKE_main_lock(bmain);
diff --git a/source/blender/blenkernel/intern/lightprobe.c b/source/blender/blenkernel/intern/lightprobe.c
index a1fa266512b..5601fa5ad42 100644
--- a/source/blender/blenkernel/intern/lightprobe.c
+++ b/source/blender/blenkernel/intern/lightprobe.c
@@ -59,22 +59,32 @@ void *BKE_lightprobe_add(Main *bmain, const char *name)
{
LightProbe *probe;
- probe = BKE_libblock_alloc(bmain, ID_LP, name);
+ probe = BKE_libblock_alloc(bmain, ID_LP, name, 0);
BKE_lightprobe_init(probe);
return probe;
}
-LightProbe *BKE_lightprobe_copy(Main *bmain, LightProbe *probe)
+/**
+ * Only copy internal data of LightProbe ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_lightprobe_copy_data(
+ Main *UNUSED(bmain), LightProbe *UNUSED(probe_dst), const LightProbe *UNUSED(probe_src), const int UNUSED(flag))
{
- LightProbe *probe_new;
-
- probe_new = BKE_libblock_copy(bmain, &probe->id);
-
- BKE_id_copy_ensure_local(bmain, &probe->id, &probe_new->id);
+ /* Nothing to do here. */
+}
- return probe_new;
+LightProbe *BKE_lightprobe_copy(Main *bmain, const LightProbe *probe)
+{
+ LightProbe *probe_copy;
+ BKE_id_copy_ex(bmain, &probe->id, (ID **)&probe_copy, 0, false);
+ return probe_copy;
}
void BKE_lightprobe_make_local(Main *bmain, LightProbe *probe, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 771e81ddc4f..1b1a12e702a 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -119,7 +119,7 @@ FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name)
{
FreestyleLineStyle *linestyle;
- linestyle = (FreestyleLineStyle *)BKE_libblock_alloc(bmain, ID_LS, name);
+ linestyle = (FreestyleLineStyle *)BKE_libblock_alloc(bmain, ID_LS, name, 0);
BKE_linestyle_init(linestyle);
@@ -155,73 +155,54 @@ void BKE_linestyle_free(FreestyleLineStyle *linestyle)
BKE_linestyle_geometry_modifier_remove(linestyle, m);
}
-FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle)
+/**
+ * Only copy internal data of Linestyle ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_linestyle_copy_data(
+ struct Main *bmain, FreestyleLineStyle *linestyle_dst, const FreestyleLineStyle *linestyle_src, const int flag)
{
- FreestyleLineStyle *new_linestyle;
- LineStyleModifier *m;
- int a;
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
- new_linestyle = BKE_linestyle_new(bmain, linestyle->id.name + 2);
- BKE_linestyle_free(new_linestyle);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (linestyle->mtex[a]) {
- new_linestyle->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_linestyle_copy");
- memcpy(new_linestyle->mtex[a], linestyle->mtex[a], sizeof(MTex));
- id_us_plus((ID *)new_linestyle->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (linestyle_src->mtex[a]) {
+ linestyle_dst->mtex[a] = MEM_mallocN(sizeof(*linestyle_dst->mtex[a]), __func__);
+ *linestyle_dst->mtex[a] = *linestyle_src->mtex[a];
}
}
- if (linestyle->nodetree) {
- new_linestyle->nodetree = ntreeCopyTree(bmain, linestyle->nodetree);
+ if (linestyle_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)linestyle_src->nodetree, (ID **)&linestyle_dst->nodetree, flag, false);
}
- new_linestyle->r = linestyle->r;
- new_linestyle->g = linestyle->g;
- new_linestyle->b = linestyle->b;
- new_linestyle->alpha = linestyle->alpha;
- new_linestyle->thickness = linestyle->thickness;
- new_linestyle->thickness_position = linestyle->thickness_position;
- new_linestyle->thickness_ratio = linestyle->thickness_ratio;
- new_linestyle->flag = linestyle->flag;
- new_linestyle->caps = linestyle->caps;
- new_linestyle->chaining = linestyle->chaining;
- new_linestyle->rounds = linestyle->rounds;
- new_linestyle->split_length = linestyle->split_length;
- new_linestyle->min_angle = linestyle->min_angle;
- new_linestyle->max_angle = linestyle->max_angle;
- new_linestyle->min_length = linestyle->min_length;
- new_linestyle->max_length = linestyle->max_length;
- new_linestyle->chain_count = linestyle->chain_count;
- new_linestyle->split_dash1 = linestyle->split_dash1;
- new_linestyle->split_gap1 = linestyle->split_gap1;
- new_linestyle->split_dash2 = linestyle->split_dash2;
- new_linestyle->split_gap2 = linestyle->split_gap2;
- new_linestyle->split_dash3 = linestyle->split_dash3;
- new_linestyle->split_gap3 = linestyle->split_gap3;
- new_linestyle->dash1 = linestyle->dash1;
- new_linestyle->gap1 = linestyle->gap1;
- new_linestyle->dash2 = linestyle->dash2;
- new_linestyle->gap2 = linestyle->gap2;
- new_linestyle->dash3 = linestyle->dash3;
- new_linestyle->gap3 = linestyle->gap3;
- new_linestyle->panel = linestyle->panel;
- new_linestyle->sort_key = linestyle->sort_key;
- new_linestyle->integration_type = linestyle->integration_type;
- new_linestyle->texstep = linestyle->texstep;
- new_linestyle->pr_texture = linestyle->pr_texture;
- new_linestyle->use_nodes = linestyle->use_nodes;
- for (m = (LineStyleModifier *)linestyle->color_modifiers.first; m; m = m->next)
- BKE_linestyle_color_modifier_copy(new_linestyle, m);
- for (m = (LineStyleModifier *)linestyle->alpha_modifiers.first; m; m = m->next)
- BKE_linestyle_alpha_modifier_copy(new_linestyle, m);
- for (m = (LineStyleModifier *)linestyle->thickness_modifiers.first; m; m = m->next)
- BKE_linestyle_thickness_modifier_copy(new_linestyle, m);
- for (m = (LineStyleModifier *)linestyle->geometry_modifiers.first; m; m = m->next)
- BKE_linestyle_geometry_modifier_copy(new_linestyle, m);
-
- BKE_id_copy_ensure_local(bmain, &linestyle->id, &new_linestyle->id);
-
- return new_linestyle;
+ LineStyleModifier *m;
+ BLI_listbase_clear(&linestyle_dst->color_modifiers);
+ for (m = (LineStyleModifier *)linestyle_src->color_modifiers.first; m; m = m->next) {
+ BKE_linestyle_color_modifier_copy(linestyle_dst, m, flag_subdata);
+ }
+ BLI_listbase_clear(&linestyle_dst->alpha_modifiers);
+ for (m = (LineStyleModifier *)linestyle_src->alpha_modifiers.first; m; m = m->next) {
+ BKE_linestyle_alpha_modifier_copy(linestyle_dst, m, flag_subdata);
+ }
+ BLI_listbase_clear(&linestyle_dst->thickness_modifiers);
+ for (m = (LineStyleModifier *)linestyle_src->thickness_modifiers.first; m; m = m->next) {
+ BKE_linestyle_thickness_modifier_copy(linestyle_dst, m, flag_subdata);
+ }
+ BLI_listbase_clear(&linestyle_dst->geometry_modifiers);
+ for (m = (LineStyleModifier *)linestyle_src->geometry_modifiers.first; m; m = m->next) {
+ BKE_linestyle_geometry_modifier_copy(linestyle_dst, m, flag_subdata);
+ }
+}
+
+FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle)
+{
+ FreestyleLineStyle *linestyle_copy;
+ BKE_id_copy_ex(bmain, &linestyle->id, (ID **)&linestyle_copy, 0, false);
+ return linestyle_copy;
}
void BKE_linestyle_make_local(struct Main *bmain, FreestyleLineStyle *linestyle, const bool lib_local)
@@ -355,7 +336,8 @@ LineStyleModifier *BKE_linestyle_color_modifier_add(FreestyleLineStyle *linestyl
return m;
}
-LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_color_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag)
{
LineStyleModifier *new_m;
@@ -388,9 +370,10 @@ LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linesty
{
LineStyleColorModifier_DistanceFromObject *p = (LineStyleColorModifier_DistanceFromObject *)m;
LineStyleColorModifier_DistanceFromObject *q = (LineStyleColorModifier_DistanceFromObject *)new_m;
- if (p->target)
- id_us_plus(&p->target->id);
q->target = p->target;
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)q->target);
+ }
q->color_ramp = MEM_dupallocN(p->color_ramp);
q->range_min = p->range_min;
q->range_max = p->range_max;
@@ -594,7 +577,8 @@ LineStyleModifier *BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyl
return m;
}
-LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_alpha_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int UNUSED(flag))
{
LineStyleModifier *new_m;
@@ -863,7 +847,8 @@ LineStyleModifier *BKE_linestyle_thickness_modifier_add(FreestyleLineStyle *line
return m;
}
-LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_thickness_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int flag)
{
LineStyleModifier *new_m;
@@ -901,9 +886,10 @@ LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *lin
{
LineStyleThicknessModifier_DistanceFromObject *p = (LineStyleThicknessModifier_DistanceFromObject *)m;
LineStyleThicknessModifier_DistanceFromObject *q = (LineStyleThicknessModifier_DistanceFromObject *)new_m;
- if (p->target)
- id_us_plus(&p->target->id);
q->target = p->target;
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)q->target);
+ }
q->curve = curvemapping_copy(p->curve);
q->flags = p->flags;
q->range_min = p->range_min;
@@ -1195,7 +1181,8 @@ LineStyleModifier *BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *lines
return m;
}
-LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_geometry_modifier_copy(
+ FreestyleLineStyle *linestyle, const LineStyleModifier *m, const int UNUSED(flag))
{
LineStyleModifier *new_m;
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index ae27e9bcd34..435bc949af0 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -794,7 +794,7 @@ static Mask *mask_alloc(Main *bmain, const char *name)
{
Mask *mask;
- mask = BKE_libblock_alloc(bmain, ID_MSK, name);
+ mask = BKE_libblock_alloc(bmain, ID_MSK, name, 0);
id_fake_user_set(&mask->id);
@@ -821,6 +821,7 @@ Mask *BKE_mask_new(Main *bmain, const char *name)
}
/* TODO(sergey): Use generic BKE_libblock_copy_nolib() instead. */
+/* TODO(bastien): Use new super cool & generic BKE_id_copy_ex() instead! */
Mask *BKE_mask_copy_nolib(Mask *mask)
{
Mask *mask_new;
@@ -840,22 +841,29 @@ Mask *BKE_mask_copy_nolib(Mask *mask)
return mask_new;
}
-Mask *BKE_mask_copy(Main *bmain, const Mask *mask)
+/**
+ * Only copy internal data of Mask ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_mask_copy_data(Main *UNUSED(bmain), Mask *mask_dst, const Mask *mask_src, const int UNUSED(flag))
{
- Mask *mask_new;
+ BLI_listbase_clear(&mask_dst->masklayers);
- mask_new = BKE_libblock_copy(bmain, &mask->id);
-
- BLI_listbase_clear(&mask_new->masklayers);
-
- BKE_mask_layer_copy_list(&mask_new->masklayers, &mask->masklayers);
+ BKE_mask_layer_copy_list(&mask_dst->masklayers, &mask_src->masklayers); /* TODO add unused flag to those as well. */
/* enable fake user by default */
- id_fake_user_set(&mask_new->id);
-
- BKE_id_copy_ensure_local(bmain, &mask->id, &mask_new->id);
+ id_fake_user_set(&mask_dst->id);
+}
- return mask_new;
+Mask *BKE_mask_copy(Main *bmain, const Mask *mask)
+{
+ Mask *mask_copy;
+ BKE_id_copy_ex(bmain, &mask->id, (ID **)&mask_copy, 0, false);
+ return mask_copy;
}
void BKE_mask_make_local(Main *bmain, Mask *mask, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 7038fb0ddcf..be3cc288818 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -215,53 +215,70 @@ Material *BKE_material_add(Main *bmain, const char *name)
{
Material *ma;
- ma = BKE_libblock_alloc(bmain, ID_MA, name);
+ ma = BKE_libblock_alloc(bmain, ID_MA, name, 0);
BKE_material_init(ma);
return ma;
}
-/* XXX keep synced with next function */
-Material *BKE_material_copy(Main *bmain, const Material *ma)
+/**
+ * Only copy internal data of Material ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_material_copy_data(Main *bmain, Material *ma_dst, const Material *ma_src, const int flag)
{
- Material *man;
- int a;
-
- man = BKE_libblock_copy(bmain, &ma->id);
-
- id_lib_extern((ID *)man->group);
- id_lib_extern((ID *)man->edit_image);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (ma->mtex[a]) {
- man->mtex[a] = MEM_mallocN(sizeof(MTex), "copymaterial");
- memcpy(man->mtex[a], ma->mtex[a], sizeof(MTex));
- id_us_plus((ID *)man->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (ma_src->mtex[a]) {
+ ma_dst->mtex[a] = MEM_mallocN(sizeof(*ma_dst->mtex[a]), __func__);
+ *ma_dst->mtex[a] = *ma_src->mtex[a];
}
}
-
- if (ma->ramp_col) man->ramp_col = MEM_dupallocN(ma->ramp_col);
- if (ma->ramp_spec) man->ramp_spec = MEM_dupallocN(ma->ramp_spec);
-
- if (ma->nodetree) {
- man->nodetree = ntreeCopyTree(bmain, ma->nodetree);
+
+ if (ma_src->ramp_col) {
+ ma_dst->ramp_col = MEM_dupallocN(ma_src->ramp_col);
+ }
+ if (ma_src->ramp_spec) {
+ ma_dst->ramp_spec = MEM_dupallocN(ma_src->ramp_spec);
}
- BKE_previewimg_id_copy(&man->id, &ma->id);
+ if (ma_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)ma_src->nodetree, (ID **)&ma_dst->nodetree, flag, false);
+ }
- BLI_listbase_clear(&man->gpumaterial);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&ma_dst->id, &ma_src->id);
+ }
+ else {
+ ma_dst->preview = NULL;
+ }
- /* TODO Duplicate Engine Settings and set runtime to NULL */
+ BLI_listbase_clear(&ma_dst->gpumaterial);
- BKE_id_copy_ensure_local(bmain, &ma->id, &man->id);
+ /* TODO Duplicate Engine Settings and set runtime to NULL */
+}
- return man;
+Material *BKE_material_copy(Main *bmain, const Material *ma)
+{
+ Material *ma_copy;
+ BKE_id_copy_ex(bmain, &ma->id, (ID **)&ma_copy, 0, false);
+ return ma_copy;
}
/* XXX (see above) material copy without adding to main dbase */
Material *localize_material(Material *ma)
{
+ /* TODO replace with something like
+ * Material *ma_copy;
+ * BKE_id_copy_ex(bmain, &ma->id, (ID **)&ma_copy, LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT, false);
+ * return ma_copy;
+ *
+ * ... Once f*** nodes are fully converted to that too :( */
+
Material *man;
int a;
@@ -1798,7 +1815,7 @@ bool BKE_object_material_edit_image_set(Object *ob, short mat_nr, Image *image)
return false;
}
-void BKE_material_eval(struct EvaluationContext *UNUSED(eval_ctx), Material *material)
+void BKE_material_eval(const struct EvaluationContext *UNUSED(eval_ctx), Material *material)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
printf("%s on %s (%p)\n", __func__, material->id.name, material);
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 27e2b17b4e2..f1e549b1400 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -97,33 +97,36 @@ MetaBall *BKE_mball_add(Main *bmain, const char *name)
{
MetaBall *mb;
- mb = BKE_libblock_alloc(bmain, ID_MB, name);
+ mb = BKE_libblock_alloc(bmain, ID_MB, name, 0);
BKE_mball_init(mb);
return mb;
}
-MetaBall *BKE_mball_copy(Main *bmain, const MetaBall *mb)
+/**
+ * Only copy internal data of MetaBall ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_mball_copy_data(Main *UNUSED(bmain), MetaBall *mb_dst, const MetaBall *mb_src, const int UNUSED(flag))
{
- MetaBall *mbn;
- int a;
-
- mbn = BKE_libblock_copy(bmain, &mb->id);
+ BLI_duplicatelist(&mb_dst->elems, &mb_src->elems);
- BLI_duplicatelist(&mbn->elems, &mb->elems);
-
- mbn->mat = MEM_dupallocN(mb->mat);
- for (a = 0; a < mbn->totcol; a++) {
- id_us_plus((ID *)mbn->mat[a]);
- }
+ mb_dst->mat = MEM_dupallocN(mb_src->mat);
- mbn->editelems = NULL;
- mbn->lastelem = NULL;
-
- BKE_id_copy_ensure_local(bmain, &mb->id, &mbn->id);
+ mb_dst->editelems = NULL;
+ mb_dst->lastelem = NULL;
+}
- return mbn;
+MetaBall *BKE_mball_copy(Main *bmain, const MetaBall *mb)
+{
+ MetaBall *mb_copy;
+ BKE_id_copy_ex(bmain, &mb->id, (ID **)&mb_copy, 0, false);
+ return mb_copy;
}
void BKE_mball_make_local(Main *bmain, MetaBall *mb, const bool lib_local)
@@ -469,7 +472,7 @@ bool BKE_mball_center_bounds(MetaBall *mb, float r_cent[3])
return false;
}
-void BKE_mball_transform(MetaBall *mb, float mat[4][4])
+void BKE_mball_transform(MetaBall *mb, float mat[4][4], const bool do_props)
{
MetaElem *me;
float quat[4];
@@ -481,14 +484,17 @@ void BKE_mball_transform(MetaBall *mb, float mat[4][4])
for (me = mb->elems.first; me; me = me->next) {
mul_m4_v3(mat, &me->x);
mul_qt_qtqt(me->quat, quat, me->quat);
- me->rad *= scale;
- /* hrmf, probably elems shouldn't be
- * treating scale differently - campbell */
- if (!MB_TYPE_SIZE_SQUARED(me->type)) {
- mul_v3_fl(&me->expx, scale);
- }
- else {
- mul_v3_fl(&me->expx, scale_sqrt);
+
+ if (do_props) {
+ me->rad *= scale;
+ /* hrmf, probably elems shouldn't be
+ * treating scale differently - campbell */
+ if (!MB_TYPE_SIZE_SQUARED(me->type)) {
+ mul_v3_fl(&me->expx, scale);
+ }
+ else {
+ mul_v3_fl(&me->expx, scale_sqrt);
+ }
}
}
}
@@ -532,7 +538,7 @@ void BKE_mball_select_swap(struct MetaBall *mb)
/* **** Depsgraph evaluation **** */
-void BKE_mball_eval_geometry(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_mball_eval_geometry(const struct EvaluationContext *UNUSED(eval_ctx),
MetaBall *UNUSED(mball))
{
}
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index d897213d362..1d9c580d45b 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -1079,7 +1079,7 @@ static void polygonize(PROCESS *process)
* Iterates over ALL objects in the scene and all of its sets, including
* making all duplis(not only metas). Copies metas to mainb array.
* Computes bounding boxes for building BVH. */
-static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scene, Object *ob)
+static void init_meta(const EvaluationContext *eval_ctx, PROCESS *process, Scene *scene, Object *ob)
{
Scene *sce_iter = scene;
BaseLegacy *base;
@@ -1256,7 +1256,7 @@ static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scen
}
}
-void BKE_mball_polygonize(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
+void BKE_mball_polygonize(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ListBase *dispbase)
{
MetaBall *mb;
DispList *dl;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index 9be072f1a21..a0edc75a7b4 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -533,54 +533,57 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name)
{
Mesh *me;
- me = BKE_libblock_alloc(bmain, ID_ME, name);
+ me = BKE_libblock_alloc(bmain, ID_ME, name, 0);
BKE_mesh_init(me);
return me;
}
-Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
+/**
+ * Only copy internal data of Mesh ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_mesh_copy_data(Main *bmain, Mesh *me_dst, const Mesh *me_src, const int flag)
{
- Mesh *men;
- int a;
- const int do_tessface = ((me->totface != 0) && (me->totpoly == 0)); /* only do tessface if we have no polys */
-
- men = BKE_libblock_copy(bmain, &me->id);
-
- men->mat = MEM_dupallocN(me->mat);
- for (a = 0; a < men->totcol; a++) {
- id_us_plus((ID *)men->mat[a]);
- }
- id_us_plus((ID *)men->texcomesh);
+ const bool do_tessface = ((me_src->totface != 0) && (me_src->totpoly == 0)); /* only do tessface if we have no polys */
- CustomData_copy(&me->vdata, &men->vdata, CD_MASK_MESH, CD_DUPLICATE, men->totvert);
- CustomData_copy(&me->edata, &men->edata, CD_MASK_MESH, CD_DUPLICATE, men->totedge);
- CustomData_copy(&me->ldata, &men->ldata, CD_MASK_MESH, CD_DUPLICATE, men->totloop);
- CustomData_copy(&me->pdata, &men->pdata, CD_MASK_MESH, CD_DUPLICATE, men->totpoly);
+ me_dst->mat = MEM_dupallocN(me_src->mat);
+
+ CustomData_copy(&me_src->vdata, &me_dst->vdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totvert);
+ CustomData_copy(&me_src->edata, &me_dst->edata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totedge);
+ CustomData_copy(&me_src->ldata, &me_dst->ldata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totloop);
+ CustomData_copy(&me_src->pdata, &me_dst->pdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totpoly);
if (do_tessface) {
- CustomData_copy(&me->fdata, &men->fdata, CD_MASK_MESH, CD_DUPLICATE, men->totface);
+ CustomData_copy(&me_src->fdata, &me_dst->fdata, CD_MASK_MESH, CD_DUPLICATE, me_dst->totface);
}
else {
- mesh_tessface_clear_intern(men, false);
+ mesh_tessface_clear_intern(me_dst, false);
}
- BKE_mesh_update_customdata_pointers(men, do_tessface);
+ BKE_mesh_update_customdata_pointers(me_dst, do_tessface);
- men->edit_btmesh = NULL;
- men->batch_cache = NULL;
+ me_dst->edit_btmesh = NULL;
+ me_dst->batch_cache = NULL;
- men->mselect = MEM_dupallocN(men->mselect);
- men->bb = MEM_dupallocN(men->bb);
+ me_dst->mselect = MEM_dupallocN(me_dst->mselect);
+ me_dst->bb = MEM_dupallocN(me_dst->bb);
- if (me->key) {
- men->key = BKE_key_copy(bmain, me->key);
- men->key->from = (ID *)men;
+ /* TODO Do we want to add flag to prevent this? */
+ if (me_src->key) {
+ BKE_id_copy_ex(bmain, &me_src->key->id, (ID **)&me_dst->key, flag, false);
}
+}
- BKE_id_copy_ensure_local(bmain, &me->id, &men->id);
-
- return men;
+Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
+{
+ Mesh *me_copy;
+ BKE_id_copy_ex(bmain, &me->id, (ID **)&me_copy, 0, false);
+ return me_copy;
}
BMesh *BKE_mesh_to_bmesh(
@@ -1628,7 +1631,7 @@ void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int e
}
}
-void BKE_mesh_to_curve(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_mesh_to_curve(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
/* make new mesh data from the original copy */
DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_MESH);
@@ -2466,7 +2469,7 @@ void BKE_mesh_split_faces(Mesh *mesh, bool free_loop_normals)
/* settings: 1 - preview, 2 - render */
Mesh *BKE_mesh_new_from_object(
- EvaluationContext *eval_ctx, Main *bmain, Scene *sce, Object *ob,
+ const EvaluationContext *eval_ctx, Main *bmain, Scene *sce, Object *ob,
int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
{
Mesh *tmpmesh;
@@ -2487,7 +2490,9 @@ Mesh *BKE_mesh_new_from_object(
int uv_from_orco;
/* copies object and modifiers (but not the data) */
- Object *tmpobj = BKE_object_copy_ex(bmain, ob, true);
+ Object *tmpobj;
+ /* TODO: make it temp copy outside bmain! */
+ BKE_id_copy_ex(bmain, &ob->id, (ID **)&tmpobj, LIB_ID_COPY_CACHES, false);
tmpcu = (Curve *)tmpobj->data;
id_us_min(&tmpcu->id);
@@ -2701,7 +2706,7 @@ Mesh *BKE_mesh_new_from_object(
/* **** Depsgraph evaluation **** */
-void BKE_mesh_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
+void BKE_mesh_eval_geometry(const EvaluationContext *UNUSED(eval_ctx),
Mesh *mesh)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
diff --git a/source/blender/blenkernel/intern/mesh_remap.c b/source/blender/blenkernel/intern/mesh_remap.c
index c5fa9b15896..d2fe8f27f4a 100644
--- a/source/blender/blenkernel/intern/mesh_remap.c
+++ b/source/blender/blenkernel/intern/mesh_remap.c
@@ -1184,7 +1184,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
bool polys_allocated_src;
MPoly *polys_src = DM_get_poly_array(dm_src, &polys_allocated_src);
const int num_polys_src = dm_src->getNumPolys(dm_src);
- bool looptri_allocated_src = false;
const MLoopTri *looptri_src = NULL;
int num_looptri_src = 0;
@@ -1374,17 +1373,11 @@ void BKE_mesh_remap_calc_loops_from_dm(
if (dirty_tess_flag) {
dm_src->dirty &= ~dirty_tess_flag;
}
- DM_ensure_looptri(dm_src);
if (dirty_tess_flag) {
dm_src->dirty |= dirty_tess_flag;
}
- looptri_src = DM_get_looptri_array(
- dm_src,
- verts_src,
- polys_src, num_polys_src,
- loops_src, num_loops_src,
- &looptri_allocated_src);
+ looptri_src = dm_src->getLoopTriArray(dm_src);
num_looptri_src = dm_src->getNumLoopTri(dm_src);
looptri_active = BLI_BITMAP_NEW((size_t)num_looptri_src, __func__);
@@ -1403,7 +1396,7 @@ void BKE_mesh_remap_calc_loops_from_dm(
&treedata[tindex],
verts_src, verts_allocated_src,
loops_src, loops_allocated_src,
- looptri_src, num_looptri_src, looptri_allocated_src,
+ looptri_src, num_looptri_src, false,
looptri_active, num_looptri_active, bvh_epsilon, 2, 6);
if (verts_allocated_src) {
verts_allocated_src = false; /* Only 'give' our verts once, to first tree! */
@@ -1411,9 +1404,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
if (loops_allocated_src) {
loops_allocated_src = false; /* Only 'give' our loops once, to first tree! */
}
- if (looptri_allocated_src) {
- looptri_allocated_src = false; /* Only 'give' our looptri once, to first tree! */
- }
}
MEM_freeN(looptri_active);
@@ -1928,9 +1918,6 @@ void BKE_mesh_remap_calc_loops_from_dm(
if (polys_allocated_src) {
MEM_freeN(polys_src);
}
- if (looptri_allocated_src) {
- MEM_freeN((void *)looptri_src);
- }
if (vert_to_loop_map_src) {
MEM_freeN(vert_to_loop_map_src);
}
diff --git a/source/blender/blenkernel/intern/mesh_sample.c b/source/blender/blenkernel/intern/mesh_sample.c
index 53d14c9dd16..8e823350fce 100644
--- a/source/blender/blenkernel/intern/mesh_sample.c
+++ b/source/blender/blenkernel/intern/mesh_sample.c
@@ -428,7 +428,7 @@ MeshSampleGenerator *BKE_mesh_sample_gen_surface_random_ex(DerivedMesh *dm, unsi
MSurfaceSampleGenerator_Random *gen;
DM_ensure_normals(dm);
- DM_ensure_looptri(dm);
+ DM_ensure_looptri_data(dm);
gen = MEM_callocN(sizeof(MSurfaceSampleGenerator_Random), "MSurfaceSampleGenerator_Random");
sample_generator_init(&gen->base, (GeneratorFreeFp)generator_random_free, (GeneratorMakeSampleFp)generator_random_make_sample);
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index b4eb132353c..1a146dc67d1 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -59,6 +59,8 @@
#include "BKE_appdir.h"
#include "BKE_key.h"
+#include "BKE_library.h"
+#include "BKE_library_query.h"
#include "BKE_multires.h"
#include "BKE_DerivedMesh.h"
@@ -269,14 +271,37 @@ void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst)
memcpy(md_dst_data, md_src_data, (size_t)mti->structSize - data_size);
}
-void modifier_copyData(ModifierData *md, ModifierData *target)
+static void modifier_copy_data_id_us_cb(void *UNUSED(userData), Object *UNUSED(ob), ID **idpoin, int cb_flag)
+{
+ ID *id = *idpoin;
+ if (id != NULL && (cb_flag & IDWALK_CB_USER) != 0) {
+ id_us_plus(id);
+ }
+}
+
+void modifier_copyData_ex(ModifierData *md, ModifierData *target, const int flag)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
target->mode = md->mode;
- if (mti->copyData)
+ if (mti->copyData) {
mti->copyData(md, target);
+ }
+
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ if (mti->foreachIDLink) {
+ mti->foreachIDLink(target, NULL, modifier_copy_data_id_us_cb, NULL);
+ }
+ else if (mti->foreachObjectLink) {
+ mti->foreachObjectLink(target, NULL, (ObjectWalkFunc)modifier_copy_data_id_us_cb, NULL);
+ }
+ }
+}
+
+void modifier_copyData(ModifierData *md, ModifierData *target)
+{
+ modifier_copyData_ex(md, target, 0);
}
@@ -732,7 +757,7 @@ void modifier_path_init(char *path, int path_maxlen, const char *name)
/* wrapper around ModifierTypeInfo.applyModifier that ensures valid normals */
struct DerivedMesh *modwrap_applyModifier(
- ModifierData *md, struct EvaluationContext *eval_ctx,
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, struct DerivedMesh *dm,
ModifierApplyFlag flag)
{
@@ -746,7 +771,7 @@ struct DerivedMesh *modwrap_applyModifier(
}
struct DerivedMesh *modwrap_applyModifierEM(
- ModifierData *md, struct EvaluationContext *eval_ctx,
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, struct BMEditMesh *em,
DerivedMesh *dm,
ModifierApplyFlag flag)
@@ -761,7 +786,7 @@ struct DerivedMesh *modwrap_applyModifierEM(
}
void modwrap_deformVerts(
- ModifierData *md, struct EvaluationContext *eval_ctx,
+ ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts,
ModifierApplyFlag flag)
@@ -776,7 +801,7 @@ void modwrap_deformVerts(
}
void modwrap_deformVertsEM(
- ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob,
+ ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob,
struct BMEditMesh *em, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts)
{
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index dfa8742a295..16d597e25fa 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -588,7 +588,7 @@ static MovieClip *movieclip_alloc(Main *bmain, const char *name)
{
MovieClip *clip;
- clip = BKE_libblock_alloc(bmain, ID_MC, name);
+ clip = BKE_libblock_alloc(bmain, ID_MC, name, 0);
clip->aspx = clip->aspy = 1.0f;
@@ -1488,25 +1488,33 @@ void BKE_movieclip_free(MovieClip *clip)
BKE_animdata_free((ID *) clip, false);
}
-MovieClip *BKE_movieclip_copy(Main *bmain, const MovieClip *clip)
+/**
+ * Only copy internal data of MovieClip ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_movieclip_copy_data(Main *UNUSED(bmain), MovieClip *clip_dst, const MovieClip *clip_src, const int flag)
{
- MovieClip *clip_new;
-
- clip_new = BKE_libblock_copy(bmain, &clip->id);
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
- clip_new->anim = NULL;
- clip_new->cache = NULL;
+ clip_dst->anim = NULL;
+ clip_dst->cache = NULL;
- BKE_tracking_copy(&clip_new->tracking, &clip->tracking);
- clip_new->tracking_context = NULL;
+ BKE_tracking_copy(&clip_dst->tracking, &clip_src->tracking, flag_subdata);
+ clip_dst->tracking_context = NULL;
- id_us_plus((ID *)clip_new->gpd);
-
- BKE_color_managed_colorspace_settings_copy(&clip_new->colorspace_settings, &clip->colorspace_settings);
-
- BKE_id_copy_ensure_local(bmain, &clip->id, &clip_new->id);
+ BKE_color_managed_colorspace_settings_copy(&clip_dst->colorspace_settings, &clip_src->colorspace_settings);
+}
- return clip_new;
+MovieClip *BKE_movieclip_copy(Main *bmain, const MovieClip *clip)
+{
+ MovieClip *clip_copy;
+ BKE_id_copy_ex(bmain, &clip->id, (ID **)&clip_copy, 0, false);
+ return clip_copy;
}
void BKE_movieclip_make_local(Main *bmain, MovieClip *clip, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c
index 3e4828afb55..7ef4b588dcd 100644
--- a/source/blender/blenkernel/intern/multires.c
+++ b/source/blender/blenkernel/intern/multires.c
@@ -276,7 +276,7 @@ static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
return mdisps;
}
-DerivedMesh *get_multires_dm(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *ob)
+DerivedMesh *get_multires_dm(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *ob)
{
ModifierData *md = (ModifierData *)mmd;
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -397,7 +397,7 @@ void multires_force_render_update(Object *ob)
multires_force_update(ob);
}
-int multiresModifier_reshapeFromDM(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
+int multiresModifier_reshapeFromDM(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
Object *ob, DerivedMesh *srcdm)
{
DerivedMesh *mrdm = get_multires_dm(eval_ctx, scene, mmd, ob);
@@ -419,13 +419,13 @@ int multiresModifier_reshapeFromDM(struct EvaluationContext *eval_ctx, Scene *sc
}
/* Returns 1 on success, 0 if the src's totvert doesn't match */
-int multiresModifier_reshape(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
+int multiresModifier_reshape(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd, Object *dst, Object *src)
{
DerivedMesh *srcdm = mesh_get_derived_final(eval_ctx, scene, src, CD_MASK_BAREMESH);
return multiresModifier_reshapeFromDM(eval_ctx, scene, mmd, dst, srcdm);
}
-int multiresModifier_reshapeFromDeformMod(struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
+int multiresModifier_reshapeFromDeformMod(const struct EvaluationContext *eval_ctx, Scene *scene, MultiresModifierData *mmd,
Object *ob, ModifierData *md)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -2174,7 +2174,7 @@ static void multires_sync_levels(Scene *scene, Object *ob_src, Object *ob_dst)
}
}
-static void multires_apply_smat(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float smat[3][3])
+static void multires_apply_smat(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float smat[3][3])
{
DerivedMesh *dm = NULL, *cddm = NULL, *subdm = NULL;
CCGElem **gridData, **subGridData;
@@ -2276,7 +2276,7 @@ int multires_mdisp_corners(MDisps *s)
return 0;
}
-void multiresModifier_scale_disp(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void multiresModifier_scale_disp(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
float smat[3][3];
@@ -2286,7 +2286,7 @@ void multiresModifier_scale_disp(struct EvaluationContext *eval_ctx, Scene *scen
multires_apply_smat(eval_ctx, scene, ob, smat);
}
-void multiresModifier_prepare_join(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *to_ob)
+void multiresModifier_prepare_join(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *to_ob)
{
float smat[3][3], tmat[3][3], mat[3][3];
multires_sync_levels(scene, to_ob, ob);
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index 148fc3827e0..478b854c4df 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -59,7 +59,7 @@
#include "BKE_library.h"
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
#include "RNA_access.h"
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 05d6b981dc1..ed1e2fe1c19 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -902,80 +902,100 @@ bNode *nodeAddStaticNode(const struct bContext *C, bNodeTree *ntree, int type)
return nodeAddNode(C, ntree, idname);
}
-static void node_socket_copy(bNodeSocket *dst, bNodeSocket *src)
+static void node_socket_copy(bNodeSocket *sock_dst, bNodeSocket *sock_src, const int flag)
{
- src->new_sock = dst;
-
- if (src->prop)
- dst->prop = IDP_CopyProperty(src->prop);
-
- if (src->default_value)
- dst->default_value = MEM_dupallocN(src->default_value);
-
- dst->stack_index = 0;
+ sock_src->new_sock = sock_dst;
+
+ if (sock_src->prop) {
+ sock_dst->prop = IDP_CopyProperty_ex(sock_src->prop, flag);
+ }
+
+ if (sock_src->default_value) {
+ sock_dst->default_value = MEM_dupallocN(sock_src->default_value);
+ }
+
+ sock_dst->stack_index = 0;
/* XXX some compositor node (e.g. image, render layers) still store
* some persistent buffer data here, need to clear this to avoid dangling pointers.
*/
- dst->cache = NULL;
+ sock_dst->cache = NULL;
}
/* keep socket listorder identical, for copying links */
/* ntree is the target tree */
-bNode *nodeCopyNode(bNodeTree *ntree, bNode *node)
+bNode *BKE_node_copy_ex(bNodeTree *ntree, bNode *node_src, const int flag)
{
- bNode *nnode = MEM_callocN(sizeof(bNode), "dupli node");
- bNodeSocket *sock, *oldsock;
- bNodeLink *link, *oldlink;
+ bNode *node_dst = MEM_callocN(sizeof(bNode), "dupli node");
+ bNodeSocket *sock_dst, *sock_src;
+ bNodeLink *link_dst, *link_src;
- *nnode = *node;
+ *node_dst = *node_src;
/* can be called for nodes outside a node tree (e.g. clipboard) */
if (ntree) {
- nodeUniqueName(ntree, nnode);
+ nodeUniqueName(ntree, node_dst);
- BLI_addtail(&ntree->nodes, nnode);
+ BLI_addtail(&ntree->nodes, node_dst);
}
- BLI_duplicatelist(&nnode->inputs, &node->inputs);
- oldsock = node->inputs.first;
- for (sock = nnode->inputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
- BLI_duplicatelist(&nnode->outputs, &node->outputs);
- oldsock = node->outputs.first;
- for (sock = nnode->outputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
- if (node->prop)
- nnode->prop = IDP_CopyProperty(node->prop);
-
- BLI_duplicatelist(&nnode->internal_links, &node->internal_links);
- oldlink = node->internal_links.first;
- for (link = nnode->internal_links.first; link; link = link->next, oldlink = oldlink->next) {
- link->fromnode = nnode;
- link->tonode = nnode;
- link->fromsock = link->fromsock->new_sock;
- link->tosock = link->tosock->new_sock;
+ BLI_duplicatelist(&node_dst->inputs, &node_src->inputs);
+ for (sock_dst = node_dst->inputs.first, sock_src = node_src->inputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag);
}
-
- /* don't increase node->id users, freenode doesn't decrement either */
-
- if (node->typeinfo->copyfunc)
- node->typeinfo->copyfunc(ntree, nnode, node);
-
- node->new_node = nnode;
- nnode->new_node = NULL;
-
- if (nnode->typeinfo->copyfunc_api) {
+
+ BLI_duplicatelist(&node_dst->outputs, &node_src->outputs);
+ for (sock_dst = node_dst->outputs.first, sock_src = node_src->outputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag);
+ }
+
+ if (node_src->prop) {
+ node_dst->prop = IDP_CopyProperty_ex(node_src->prop, flag);
+ }
+
+ BLI_duplicatelist(&node_dst->internal_links, &node_src->internal_links);
+ for (link_dst = node_dst->internal_links.first, link_src = node_src->internal_links.first;
+ link_dst != NULL;
+ link_dst = link_dst->next, link_src = link_src->next)
+ {
+ link_dst->fromnode = node_dst;
+ link_dst->tonode = node_dst;
+ link_dst->fromsock = link_dst->fromsock->new_sock;
+ link_dst->tosock = link_dst->tosock->new_sock;
+ }
+
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus(node_dst->id);
+ }
+
+ if (node_src->typeinfo->copyfunc) {
+ node_src->typeinfo->copyfunc(ntree, node_dst, node_src);
+ }
+
+ node_src->new_node = node_dst;
+ node_dst->new_node = NULL;
+
+ if (node_dst->typeinfo->copyfunc_api) {
PointerRNA ptr;
- RNA_pointer_create((ID *)ntree, &RNA_Node, nnode, &ptr);
-
- nnode->typeinfo->copyfunc_api(&ptr, node);
+ RNA_pointer_create((ID *)ntree, &RNA_Node, node_dst, &ptr);
+
+ node_dst->typeinfo->copyfunc_api(&ptr, node_src);
}
-
- if (ntree)
+
+ if (ntree) {
ntree->update |= NTREE_UPDATE_NODES;
-
- return nnode;
+ }
+
+ return node_dst;
+}
+
+bNode *nodeCopyNode(bNodeTree *ntree, bNode *node)
+{
+ return BKE_node_copy_ex(ntree, node, LIB_ID_CREATE_NO_USER_REFCOUNT);
}
/* also used via rna api, so we check for proper input output direction */
@@ -1172,7 +1192,7 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
* node groups and other tree types are created as library data.
*/
if (bmain) {
- ntree = BKE_libblock_alloc(bmain, ID_NT, name);
+ ntree = BKE_libblock_alloc(bmain, ID_NT, name, 0);
}
else {
ntree = MEM_callocN(sizeof(bNodeTree), "new node tree");
@@ -1191,119 +1211,96 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
return ntree;
}
-/* Warning: this function gets called during some rather unexpected times
- * - this gets called when executing compositing updates (for threaded previews)
- * - when the nodetree datablock needs to be copied (i.e. when users get copied)
- * - for scene duplication use ntreeSwapID() after so we don't have stale pointers.
+/**
+ * Only copy internal data of NodeTree ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
*
- * do_make_extern: keep enabled for general use, only reason _not_ to enable is when
- * copying for internal use (threads for eg), where you wont want it to modify the
- * scene data.
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
*/
-static bNodeTree *ntreeCopyTree_internal(
- const bNodeTree *ntree, Main *bmain,
- bool skip_database, bool do_id_user, bool do_make_extern, bool copy_previews)
+void BKE_node_tree_copy_data(Main *UNUSED(bmain), bNodeTree *ntree_dst, const bNodeTree *ntree_src, const int flag)
{
- bNodeTree *newtree;
- bNode *node /*, *nnode */ /* UNUSED */, *last;
- bNodeSocket *sock, *oldsock;
- bNodeLink *link;
-
- if (ntree == NULL) return NULL;
-
- /* is ntree part of library? */
- if (bmain && !skip_database && BLI_findindex(&bmain->nodetree, ntree) >= 0) {
- newtree = BKE_libblock_copy(bmain, &ntree->id);
- }
- else {
- newtree = BKE_libblock_copy_nolib(&ntree->id, true);
- }
+ bNodeSocket *sock_dst, *sock_src;
+ bNodeLink *link_dst;
- id_us_plus((ID *)newtree->gpd);
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
/* in case a running nodetree is copied */
- newtree->execdata = NULL;
-
- newtree->duplilock = NULL;
-
- BLI_listbase_clear(&newtree->nodes);
- BLI_listbase_clear(&newtree->links);
-
- last = ntree->nodes.last;
- for (node = ntree->nodes.first; node; node = node->next) {
+ ntree_dst->execdata = NULL;
- /* ntreeUserDecrefID inline */
- if (do_id_user) {
- id_us_plus(node->id);
- }
+ ntree_dst->duplilock = NULL;
- if (do_make_extern) {
- id_lib_extern(node->id);
- }
+ BLI_listbase_clear(&ntree_dst->nodes);
+ BLI_listbase_clear(&ntree_dst->links);
- node->new_node = NULL;
- /* nnode = */ nodeCopyNode(newtree, node); /* sets node->new */
-
- /* make sure we don't copy new nodes again! */
- if (node == last)
- break;
+ for (bNode *node_src = ntree_src->nodes.first; node_src; node_src = node_src->next) {
+ BKE_node_copy_ex(ntree_dst, node_src, flag_subdata);
}
-
+
/* copy links */
- BLI_duplicatelist(&newtree->links, &ntree->links);
- for (link = newtree->links.first; link; link = link->next) {
- link->fromnode = (link->fromnode ? link->fromnode->new_node : NULL);
- link->fromsock = (link->fromsock ? link->fromsock->new_sock : NULL);
- link->tonode = (link->tonode ? link->tonode->new_node : NULL);
- link->tosock = (link->tosock ? link->tosock->new_sock : NULL);
+ BLI_duplicatelist(&ntree_dst->links, &ntree_src->links);
+ for (link_dst = ntree_dst->links.first; link_dst; link_dst = link_dst->next) {
+ link_dst->fromnode = (link_dst->fromnode ? link_dst->fromnode->new_node : NULL);
+ link_dst->fromsock = (link_dst->fromsock ? link_dst->fromsock->new_sock : NULL);
+ link_dst->tonode = (link_dst->tonode ? link_dst->tonode->new_node : NULL);
+ link_dst->tosock = (link_dst->tosock ? link_dst->tosock->new_sock : NULL);
/* update the link socket's pointer */
- if (link->tosock)
- link->tosock->link = link;
+ if (link_dst->tosock) {
+ link_dst->tosock->link = link_dst;
+ }
}
-
+
/* copy interface sockets */
- BLI_duplicatelist(&newtree->inputs, &ntree->inputs);
- oldsock = ntree->inputs.first;
- for (sock = newtree->inputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
- BLI_duplicatelist(&newtree->outputs, &ntree->outputs);
- oldsock = ntree->outputs.first;
- for (sock = newtree->outputs.first; sock; sock = sock->next, oldsock = oldsock->next)
- node_socket_copy(sock, oldsock);
-
+ BLI_duplicatelist(&ntree_dst->inputs, &ntree_src->inputs);
+ for (sock_dst = ntree_dst->inputs.first, sock_src = ntree_src->inputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag_subdata);
+ }
+
+ BLI_duplicatelist(&ntree_dst->outputs, &ntree_src->outputs);
+ for (sock_dst = ntree_dst->outputs.first, sock_src = ntree_src->outputs.first;
+ sock_dst != NULL;
+ sock_dst = sock_dst->next, sock_src = sock_src->next)
+ {
+ node_socket_copy(sock_dst, sock_src, flag_subdata);
+ }
+
/* copy preview hash */
- if (ntree->previews && copy_previews) {
+ if (ntree_src->previews && (flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
bNodeInstanceHashIterator iter;
-
- newtree->previews = BKE_node_instance_hash_new("node previews");
-
- NODE_INSTANCE_HASH_ITER(iter, ntree->previews) {
+
+ ntree_dst->previews = BKE_node_instance_hash_new("node previews");
+
+ NODE_INSTANCE_HASH_ITER(iter, ntree_src->previews) {
bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
- BKE_node_instance_hash_insert(newtree->previews, key, BKE_node_preview_copy(preview));
+ BKE_node_instance_hash_insert(ntree_dst->previews, key, BKE_node_preview_copy(preview));
}
}
- else
- newtree->previews = NULL;
-
+ else {
+ ntree_dst->previews = NULL;
+ }
+
/* update node->parent pointers */
- for (node = newtree->nodes.first; node; node = node->next) {
- if (node->parent)
- node->parent = node->parent->new_node;
+ for (bNode *node_dst = ntree_dst->nodes.first, *node_src = ntree_src->nodes.first; node_dst; node_dst = node_dst->next, node_src = node_src->next) {
+ if (node_dst->parent) {
+ node_dst->parent = node_dst->parent->new_node;
+ }
}
-
- /* node tree will generate its own interface type */
- newtree->interface_type = NULL;
-
- BKE_id_copy_ensure_local(bmain, &ntree->id, &newtree->id);
- return newtree;
+ /* node tree will generate its own interface type */
+ ntree_dst->interface_type = NULL;
}
bNodeTree *ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_id_user)
{
- return ntreeCopyTree_internal(ntree, bmain, false, do_id_user, true, true);
+ bNodeTree *ntree_copy;
+ BKE_id_copy_ex(bmain, (ID *)ntree, (ID **)&ntree_copy, do_id_user ? 0 : LIB_ID_CREATE_NO_USER_REFCOUNT, false);
+ return ntree_copy;
}
bNodeTree *ntreeCopyTree(Main *bmain, const bNodeTree *ntree)
{
@@ -1994,10 +1991,11 @@ bNodeTree *ntreeLocalize(bNodeTree *ntree)
adt->tmpact = NULL;
}
- /* Make full copy.
+ /* Make full copy outside of Main database.
* Note: previews are not copied here.
*/
- ltree = ntreeCopyTree_internal(ntree, G.main, true, false, false, false);
+ BKE_id_copy_ex(G.main, (ID *)ntree, (ID **)&ltree,
+ LIB_ID_CREATE_NO_MAIN | LIB_ID_CREATE_NO_USER_REFCOUNT | LIB_ID_COPY_NO_PREVIEW, false);
ltree->flag |= NTREE_IS_LOCALIZED;
for (node = ltree->nodes.first; node; node = node->next) {
@@ -2277,7 +2275,7 @@ StructRNA *ntreeInterfaceTypeGet(bNodeTree *ntree, int create)
/* rename the RNA type */
RNA_def_struct_free_pointers(srna);
- RNA_def_struct_identifier(srna, identifier);
+ RNA_def_struct_identifier(&BLENDER_RNA, srna, identifier);
RNA_def_struct_ui_text(srna, name, description);
RNA_def_struct_duplicate_pointers(srna);
}
@@ -3596,12 +3594,10 @@ static void registerShaderNodes(void)
register_node_type_sh_add_shader();
register_node_type_sh_uvmap();
register_node_type_sh_uvalongstroke();
- register_node_type_sh_eevee_metallic();
register_node_type_sh_eevee_specular();
register_node_type_sh_output_lamp();
register_node_type_sh_output_material();
- register_node_type_sh_output_eevee_material();
register_node_type_sh_output_world();
register_node_type_sh_output_linestyle();
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index d7c60f67c05..07de120ff48 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -319,7 +319,7 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr
modifier_unique_name(&ob_dst->modifiers, nmd);
}
- BKE_object_copy_particlesystems(ob_dst, ob_src);
+ BKE_object_copy_particlesystems(ob_dst, ob_src, 0);
/* TODO: smoke?, cloth? */
}
@@ -337,14 +337,14 @@ void BKE_object_free_derived_caches(Object *ob)
Mesh *me = ob->data;
if (me && me->bb) {
- atomic_fetch_and_or_uint32((uint*)&me->bb->flag, BOUNDBOX_DIRTY);
+ atomic_fetch_and_or_uint32((uint *)&me->bb->flag, BOUNDBOX_DIRTY);
}
}
else if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
Curve *cu = ob->data;
if (cu && cu->bb) {
- atomic_fetch_and_or_uint32((uint*)&cu->bb->flag, BOUNDBOX_DIRTY);
+ atomic_fetch_and_or_uint32((uint *)&cu->bb->flag, BOUNDBOX_DIRTY);
}
}
@@ -705,7 +705,7 @@ Object *BKE_object_add_only_object(Main *bmain, int type, const char *name)
if (!name)
name = get_obdata_defname(type);
- ob = BKE_libblock_alloc(bmain, ID_OB, name);
+ ob = BKE_libblock_alloc(bmain, ID_OB, name, 0);
/* default object vars */
ob->type = type;
@@ -834,7 +834,7 @@ static LodLevel *lod_level_select(Object *ob, const float camera_position[3])
bool BKE_object_lod_is_usable(Object *ob, SceneLayer *sl)
{
- bool active = (sl) ? ob == OBACT_NEW : false;
+ bool active = (sl) ? ob == OBACT_NEW(sl) : false;
return (ob->mode == OB_MODE_OBJECT || !active);
}
@@ -875,7 +875,7 @@ struct Object *BKE_object_lod_matob_get(Object *ob, SceneLayer *sl)
#endif /* WITH_GAMEENGINE */
-SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
+SoftBody *copy_softbody(const SoftBody *sb, const int flag)
{
SoftBody *sbn;
@@ -883,7 +883,7 @@ SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
sbn = MEM_dupallocN(sb);
- if (copy_caches == false) {
+ if ((flag & LIB_ID_COPY_CACHES) == 0) {
sbn->totspring = sbn->totpoint = 0;
sbn->bpoint = NULL;
sbn->bspring = NULL;
@@ -912,7 +912,7 @@ SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
sbn->scratch = NULL;
- sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, copy_caches);
+ sbn->pointcache = BKE_ptcache_copy_list(&sbn->ptcaches, &sb->ptcaches, flag);
if (sb->effector_weights)
sbn->effector_weights = MEM_dupallocN(sb->effector_weights);
@@ -920,7 +920,7 @@ SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
return sbn;
}
-BulletSoftBody *copy_bulletsoftbody(const BulletSoftBody *bsb)
+BulletSoftBody *copy_bulletsoftbody(const BulletSoftBody *bsb, const int UNUSED(flag))
{
BulletSoftBody *bsbn;
@@ -931,7 +931,7 @@ BulletSoftBody *copy_bulletsoftbody(const BulletSoftBody *bsb)
return bsbn;
}
-ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
+ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys, const int flag)
{
ParticleSystem *psysn;
ParticleData *pa;
@@ -968,7 +968,7 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
if (psys->clmd) {
psysn->clmd = (ClothModifierData *)modifier_new(eModifierType_Cloth);
- modifier_copyData((ModifierData *)psys->clmd, (ModifierData *)psysn->clmd);
+ modifier_copyData_ex((ModifierData *)psys->clmd, (ModifierData *)psysn->clmd, flag);
psys->hair_in_dm = psys->hair_out_dm = NULL;
}
@@ -988,7 +988,8 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
BLI_listbase_clear(&psysn->childcachebufs);
psysn->renderdata = NULL;
- psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, false);
+ /* XXX Never copy caches here? */
+ psysn->pointcache = BKE_ptcache_copy_list(&psysn->ptcaches, &psys->ptcaches, flag & ~LIB_ID_COPY_CACHES);
/* XXX - from reading existing code this seems correct but intended usage of
* pointcache should /w cloth should be added in 'ParticleSystem' - campbell */
@@ -996,12 +997,14 @@ ParticleSystem *BKE_object_copy_particlesystem(ParticleSystem *psys)
psysn->clmd->point_cache = psysn->pointcache;
}
- id_us_plus((ID *)psysn->part);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)psysn->part);
+ }
return psysn;
}
-void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src)
+void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src, const int flag)
{
ParticleSystem *psys, *npsys;
ModifierData *md;
@@ -1013,7 +1016,7 @@ void BKE_object_copy_particlesystems(Object *ob_dst, const Object *ob_src)
BLI_listbase_clear(&ob_dst->particlesystem);
for (psys = ob_src->particlesystem.first; psys; psys = psys->next) {
- npsys = BKE_object_copy_particlesystem(psys);
+ npsys = BKE_object_copy_particlesystem(psys, flag);
BLI_addtail(&ob_dst->particlesystem, npsys);
@@ -1050,23 +1053,25 @@ void BKE_object_copy_softbody(Object *ob_dst, const Object *ob_src)
{
if (ob_src->soft) {
ob_dst->softflag = ob_src->softflag;
- ob_dst->soft = copy_softbody(ob_src->soft, false);
+ ob_dst->soft = copy_softbody(ob_src->soft, 0);
}
}
-static void copy_object_pose(Object *obn, const Object *ob)
+static void copy_object_pose(Object *obn, const Object *ob, const int flag)
{
bPoseChannel *chan;
/* note: need to clear obn->pose pointer first, so that BKE_pose_copy_data works (otherwise there's a crash) */
obn->pose = NULL;
- BKE_pose_copy_data(&obn->pose, ob->pose, 1); /* 1 = copy constraints */
+ BKE_pose_copy_data_ex(&obn->pose, ob->pose, flag, true); /* true = copy constraints */
for (chan = obn->pose->chanbase.first; chan; chan = chan->next) {
bConstraint *con;
chan->flag &= ~(POSE_LOC | POSE_ROT | POSE_SIZE);
+ /* XXX Remapping object pointing onto itself should be handled by generic BKE_library_remap stuff, but...
+ * the flush_constraint_targets callback am not sure about, so will delay that for now. */
for (con = chan->constraints.first; con; con = con->next) {
const bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con);
ListBase targets = {NULL, NULL};
@@ -1087,13 +1092,10 @@ static void copy_object_pose(Object *obn, const Object *ob)
}
}
-static void copy_object_lod(Object *obn, const Object *ob)
+static void copy_object_lod(Object *obn, const Object *ob, const int UNUSED(flag))
{
BLI_duplicatelist(&obn->lodlevels, &ob->lodlevels);
- if (obn->lodlevels.first)
- ((LodLevel *)obn->lodlevels.first)->source = obn;
-
obn->currentlod = (LodLevel *)obn->lodlevels.first;
}
@@ -1138,100 +1140,101 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
copy_v3_v3(ob_tar->size, ob_src->size);
}
-Object *BKE_object_copy_ex(Main *bmain, const Object *ob, bool copy_caches)
+/**
+ * Only copy internal data of Object ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_object_copy_data(Main *UNUSED(bmain), Object *ob_dst, const Object *ob_src, const int flag)
{
- Object *obn;
ModifierData *md;
- int a;
- obn = BKE_libblock_copy(bmain, &ob->id);
-
- if (ob->totcol) {
- obn->mat = MEM_dupallocN(ob->mat);
- obn->matbits = MEM_dupallocN(ob->matbits);
- obn->totcol = ob->totcol;
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+
+ if (ob_src->totcol) {
+ ob_dst->mat = MEM_dupallocN(ob_src->mat);
+ ob_dst->matbits = MEM_dupallocN(ob_src->matbits);
+ ob_dst->totcol = ob_src->totcol;
}
- if (ob->iuser) obn->iuser = MEM_dupallocN(ob->iuser);
+ if (ob_src->iuser) ob_dst->iuser = MEM_dupallocN(ob_src->iuser);
- if (ob->bb) obn->bb = MEM_dupallocN(ob->bb);
- obn->flag &= ~OB_FROMGROUP;
+ if (ob_src->bb) ob_dst->bb = MEM_dupallocN(ob_src->bb);
+ ob_dst->flag &= ~OB_FROMGROUP;
- BLI_listbase_clear(&obn->modifiers);
+ BLI_listbase_clear(&ob_dst->modifiers);
- for (md = ob->modifiers.first; md; md = md->next) {
+ for (md = ob_src->modifiers.first; md; md = md->next) {
ModifierData *nmd = modifier_new(md->type);
BLI_strncpy(nmd->name, md->name, sizeof(nmd->name));
- modifier_copyData(md, nmd);
- BLI_addtail(&obn->modifiers, nmd);
+ modifier_copyData_ex(md, nmd, flag_subdata);
+ BLI_addtail(&ob_dst->modifiers, nmd);
}
- BLI_listbase_clear(&obn->prop);
- BKE_bproperty_copy_list(&obn->prop, &ob->prop);
+ BLI_listbase_clear(&ob_dst->prop);
+ BKE_bproperty_copy_list(&ob_dst->prop, &ob_src->prop);
- BKE_sca_logic_copy(obn, ob);
+ BKE_sca_logic_copy(ob_dst, ob_src, flag_subdata);
- if (ob->pose) {
- copy_object_pose(obn, ob);
+ if (ob_src->pose) {
+ copy_object_pose(ob_dst, ob_src, flag_subdata);
/* backwards compat... non-armatures can get poses in older files? */
- if (ob->type == OB_ARMATURE)
- BKE_pose_rebuild(obn, obn->data);
+ if (ob_src->type == OB_ARMATURE)
+ BKE_pose_rebuild(ob_dst, ob_dst->data);
}
- defgroup_copy_list(&obn->defbase, &ob->defbase);
- BKE_object_facemap_copy_list(&obn->fmaps, &ob->fmaps);
- BKE_constraints_copy(&obn->constraints, &ob->constraints, true);
+ defgroup_copy_list(&ob_dst->defbase, &ob_src->defbase);
+ BKE_object_facemap_copy_list(&ob_dst->fmaps, &ob_src->fmaps);
+ BKE_constraints_copy_ex(&ob_dst->constraints, &ob_src->constraints, flag_subdata, true);
- obn->mode = OB_MODE_OBJECT;
- obn->sculpt = NULL;
+ ob_dst->mode = OB_MODE_OBJECT;
+ ob_dst->sculpt = NULL;
- /* increase user numbers */
- id_us_plus((ID *)obn->data);
- id_us_plus((ID *)obn->poselib);
- id_us_plus((ID *)obn->gpd);
- id_us_plus((ID *)obn->dup_group);
+ if (ob_src->pd) {
+ ob_dst->pd = MEM_dupallocN(ob_src->pd);
+ if (ob_dst->pd->rng) {
+ ob_dst->pd->rng = MEM_dupallocN(ob_src->pd->rng);
+ }
+ }
+ ob_dst->soft = copy_softbody(ob_src->soft, flag_subdata);
+ ob_dst->bsoft = copy_bulletsoftbody(ob_src->bsoft, flag_subdata);
+ ob_dst->rigidbody_object = BKE_rigidbody_copy_object(ob_src, flag_subdata);
+ ob_dst->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob_src, flag_subdata);
- for (a = 0; a < obn->totcol; a++) id_us_plus((ID *)obn->mat[a]);
+ BKE_object_copy_particlesystems(ob_dst, ob_src, flag_subdata);
- if (ob->pd) {
- obn->pd = MEM_dupallocN(ob->pd);
- if (obn->pd->tex)
- id_us_plus(&(obn->pd->tex->id));
- if (obn->pd->rng)
- obn->pd->rng = MEM_dupallocN(ob->pd->rng);
- }
- obn->soft = copy_softbody(ob->soft, copy_caches);
- obn->bsoft = copy_bulletsoftbody(ob->bsoft);
- obn->rigidbody_object = BKE_rigidbody_copy_object(ob);
- obn->rigidbody_constraint = BKE_rigidbody_copy_constraint(ob);
-
- BKE_object_copy_particlesystems(obn, ob);
-
- obn->derivedDeform = NULL;
- obn->derivedFinal = NULL;
+ ob_dst->derivedDeform = NULL;
+ ob_dst->derivedFinal = NULL;
- BLI_listbase_clear(&obn->gpulamp);
- BLI_listbase_clear(&obn->pc_ids);
- BLI_listbase_clear(&obn->drawdata);
+ BLI_listbase_clear(&ob_dst->gpulamp);
+ BLI_listbase_clear(&ob_dst->drawdata);
+ BLI_listbase_clear(&ob_dst->pc_ids);
- obn->mpath = NULL;
+ ob_dst->mpath = NULL;
- copy_object_lod(obn, ob);
+ copy_object_lod(ob_dst, ob_src, flag_subdata);
- /* Copy runtime surve data. */
- obn->curve_cache = NULL;
-
- BKE_id_copy_ensure_local(bmain, &ob->id, &obn->id);
+ /* Do not copy runtime curve data. */
+ ob_dst->curve_cache = NULL;
/* Do not copy object's preview (mostly due to the fact renderers create temp copy of objects). */
- obn->preview = NULL;
-
- return obn;
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0 && false) { /* XXX TODO temp hack */
+ BKE_previewimg_id_copy(&ob_dst->id, &ob_src->id);
+ }
+ else {
+ ob_dst->preview = NULL;
+ }
}
/* copy objects, will re-initialize cached simulation data */
Object *BKE_object_copy(Main *bmain, const Object *ob)
{
- return BKE_object_copy_ex(bmain, ob, false);
+ Object *ob_copy;
+ BKE_id_copy_ex(bmain, &ob->id, (ID **)&ob_copy, 0, false);
+ return ob_copy;
}
void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, const bool clear_proxy)
@@ -1307,10 +1310,10 @@ static void armature_set_id_extern(Object *ob)
unsigned int lay = arm->layer_protected;
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if (!(pchan->bone->layer & lay)) {
+ if (!(pchan->bone->layer & lay))
id_lib_extern((ID *)pchan->custom);
- }
}
+
}
void BKE_object_copy_proxy_drivers(Object *ob, Object *target)
@@ -1429,7 +1432,7 @@ void BKE_object_make_proxy(Object *ob, Object *target, Object *gob)
/* type conversions */
if (target->type == OB_ARMATURE) {
- copy_object_pose(ob, target); /* data copy, object pointers in constraints */
+ copy_object_pose(ob, target, 0); /* data copy, object pointers in constraints */
BKE_pose_rest(ob->pose); /* clear all transforms in channels */
BKE_pose_rebuild(ob, ob->data); /* set all internal links */
@@ -2102,8 +2105,9 @@ static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat
}
/* note, scene is the active scene while actual_scene is the scene the object resides in */
-void BKE_object_where_is_calc_time_ex(EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime,
- RigidBodyWorld *rbw, float r_originmat[3][3])
+void BKE_object_where_is_calc_time_ex(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime,
+ RigidBodyWorld *rbw, float r_originmat[3][3])
{
if (ob == NULL) return;
@@ -2147,7 +2151,7 @@ void BKE_object_where_is_calc_time_ex(EvaluationContext *eval_ctx, Scene *scene,
else ob->transflag &= ~OB_NEG_SCALE;
}
-void BKE_object_where_is_calc_time(EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime)
+void BKE_object_where_is_calc_time(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime)
{
BKE_object_where_is_calc_time_ex(eval_ctx, scene, ob, ctime, NULL, NULL);
}
@@ -2174,17 +2178,17 @@ void BKE_object_where_is_calc_mat4(Scene *scene, Object *ob, float obmat[4][4])
}
}
-void BKE_object_where_is_calc_ex(EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
+void BKE_object_where_is_calc_ex(const EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3])
{
BKE_object_where_is_calc_time_ex(eval_ctx, scene, ob, BKE_scene_frame_get(scene), rbw, r_originmat);
}
-void BKE_object_where_is_calc(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_object_where_is_calc(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
BKE_object_where_is_calc_time_ex(eval_ctx, scene, ob, BKE_scene_frame_get(scene), NULL, NULL);
}
/* for calculation of the inverse parent transform, only used for editor */
-void BKE_object_workob_calc_parent(EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *workob)
+void BKE_object_workob_calc_parent(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, Object *workob)
{
BKE_object_workob_clear(workob);
@@ -2537,7 +2541,7 @@ void BKE_scene_foreach_display_point(
Base *base;
Object *ob;
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (((base->flag & BASE_VISIBLED) != 0) && ((base->flag & BASE_SELECTED) != 0)) {
ob = base->object;
@@ -2636,7 +2640,7 @@ bool BKE_object_parent_loop_check(const Object *par, const Object *ob)
/* the main object update call, for object matrix, constraints, keys and displist (modifiers) */
/* requires flags to be set! */
/* Ideally we shouldn't have to pass the rigid body world, but need bigger restructuring to avoid id */
-void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
+void BKE_object_handle_update_ex(const EvaluationContext *eval_ctx,
Scene *scene, Object *ob,
RigidBodyWorld *rbw,
const bool do_proxy_update)
@@ -2715,7 +2719,7 @@ void BKE_object_handle_update_ex(EvaluationContext *eval_ctx,
* e.g. "scene" <-- set 1 <-- set 2 ("ob" lives here) <-- set 3 <-- ... <-- set n
* rigid bodies depend on their world so use BKE_object_handle_update_ex() to also pass along the corrent rigid body world
*/
-void BKE_object_handle_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+void BKE_object_handle_update(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
BKE_object_handle_update_ex(eval_ctx, scene, ob, NULL, true);
}
@@ -3631,9 +3635,9 @@ static void object_cacheIgnoreClear(Object *ob, int state)
/* Note: this function should eventually be replaced by depsgraph functionality.
* Avoid calling this in new code unless there is a very good reason for it!
*/
-bool BKE_object_modifier_update_subframe(EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update_mesh,
- int parent_recursion, float frame,
- int type)
+bool BKE_object_modifier_update_subframe(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update_mesh,
+ int parent_recursion, float frame, int type)
{
ModifierData *md = modifiers_findByType(ob, (ModifierType)type);
bConstraint *con;
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index 66cacd67a85..c25207d81bf 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -69,7 +69,7 @@
/* Dupli-Geometry */
typedef struct DupliContext {
- EvaluationContext *eval_ctx;
+ const EvaluationContext *eval_ctx;
bool do_update;
bool animated;
Group *group; /* XXX child objects are selected from this group if set, could be nicer */
@@ -95,7 +95,7 @@ typedef struct DupliGenerator {
static const DupliGenerator *get_dupli_generator(const DupliContext *ctx);
/* create initial context for root object */
-static void init_context(DupliContext *r_ctx, EvaluationContext *eval_ctx, Scene *scene, Object *ob, float space_mat[4][4], bool update)
+static void init_context(DupliContext *r_ctx, const EvaluationContext *eval_ctx, Scene *scene, Object *ob, float space_mat[4][4], bool update)
{
r_ctx->eval_ctx = eval_ctx;
r_ctx->scene = scene;
@@ -1216,7 +1216,7 @@ static const DupliGenerator *get_dupli_generator(const DupliContext *ctx)
/* ---- ListBase dupli container implementation ---- */
/* Returns a list of DupliObject */
-ListBase *object_duplilist_ex(EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update)
+ListBase *object_duplilist_ex(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, bool update)
{
ListBase *duplilist = MEM_callocN(sizeof(ListBase), "duplilist");
DupliContext ctx;
@@ -1231,7 +1231,7 @@ ListBase *object_duplilist_ex(EvaluationContext *eval_ctx, Scene *scene, Object
/* note: previously updating was always done, this is why it defaults to be on
* but there are likely places it can be called without updating */
-ListBase *object_duplilist(EvaluationContext *eval_ctx, Scene *sce, Object *ob)
+ListBase *object_duplilist(const EvaluationContext *eval_ctx, Scene *sce, Object *ob)
{
return object_duplilist_ex(eval_ctx, sce, ob, true);
}
@@ -1272,7 +1272,7 @@ int count_duplilist(Object *ob)
return 1;
}
-DupliApplyData *duplilist_apply(EvaluationContext *eval_ctx, Object *ob, Scene *scene, ListBase *duplilist)
+DupliApplyData *duplilist_apply(const EvaluationContext *eval_ctx, Object *ob, Scene *scene, ListBase *duplilist)
{
DupliApplyData *apply_data = NULL;
int num_objects = BLI_listbase_count(duplilist);
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index 0bbfbb8a4e7..c5d267ace9d 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -69,7 +69,7 @@
static ThreadMutex material_lock = BLI_MUTEX_INITIALIZER;
-void BKE_object_eval_local_transform(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_local_transform(const EvaluationContext *UNUSED(eval_ctx),
Scene *UNUSED(scene),
Object *ob)
{
@@ -81,7 +81,7 @@ void BKE_object_eval_local_transform(EvaluationContext *UNUSED(eval_ctx),
/* Evaluate parent */
/* NOTE: based on solve_parenting(), but with the cruft stripped out */
-void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_parent(const EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob)
{
@@ -113,7 +113,7 @@ void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_object_eval_constraints(EvaluationContext *eval_ctx,
+void BKE_object_eval_constraints(const EvaluationContext *eval_ctx,
Scene *scene,
Object *ob)
{
@@ -136,7 +136,7 @@ void BKE_object_eval_constraints(EvaluationContext *eval_ctx,
BKE_constraints_clear_evalob(cob);
}
-void BKE_object_eval_done(EvaluationContext *UNUSED(eval_ctx), Object *ob)
+void BKE_object_eval_done(const EvaluationContext *UNUSED(eval_ctx), Object *ob)
{
DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
@@ -145,9 +145,10 @@ void BKE_object_eval_done(EvaluationContext *UNUSED(eval_ctx), Object *ob)
else ob->transflag &= ~OB_NEG_SCALE;
}
-void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
- Scene *scene,
- Object *ob)
+void BKE_object_handle_data_update(
+ const EvaluationContext *eval_ctx,
+ Scene *scene,
+ Object *ob)
{
ID *data_id = (ID *)ob->data;
AnimData *adt = BKE_animdata_from_id(data_id);
@@ -296,7 +297,7 @@ void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
/* quick cache removed */
}
-void BKE_object_eval_uber_transform(EvaluationContext *UNUSED(eval_ctx),
+void BKE_object_eval_uber_transform(const EvaluationContext *UNUSED(eval_ctx),
Scene *UNUSED(scene),
Object *ob)
{
@@ -326,7 +327,7 @@ void BKE_object_eval_uber_transform(EvaluationContext *UNUSED(eval_ctx),
}
}
-void BKE_object_eval_uber_data(EvaluationContext *eval_ctx,
+void BKE_object_eval_uber_data(const EvaluationContext *eval_ctx,
Scene *scene,
Object *ob)
{
@@ -401,13 +402,13 @@ void BKE_object_eval_uber_data(EvaluationContext *eval_ctx,
ob->recalc &= ~(OB_RECALC_DATA | OB_RECALC_TIME);
}
-void BKE_object_eval_cloth(EvaluationContext *UNUSED(eval_ctx), Scene *scene, Object *object)
+void BKE_object_eval_cloth(const EvaluationContext *UNUSED(eval_ctx), Scene *scene, Object *object)
{
DEBUG_PRINT("%s on %s\n", __func__, object->id.name);
BKE_ptcache_object_reset(scene, object, PTCACHE_RESET_DEPSGRAPH);
}
-void BKE_object_eval_update_shading(EvaluationContext *UNUSED(eval_ctx), Object *object)
+void BKE_object_eval_update_shading(const EvaluationContext *UNUSED(eval_ctx), Object *object)
{
DEBUG_PRINT("%s on %s\n", __func__, object->id.name);
if (object->type == OB_MESH) {
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index eebe514c7ca..81b26f13a9f 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -312,24 +312,31 @@ PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name)
{
PaintCurve *pc;
- pc = BKE_libblock_alloc(bmain, ID_PC, name);
+ pc = BKE_libblock_alloc(bmain, ID_PC, name, 0);
return pc;
}
-PaintCurve *BKE_paint_curve_copy(Main *bmain, const PaintCurve *pc)
+/**
+ * Only copy internal data of PaintCurve ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_paint_curve_copy_data(Main *UNUSED(bmain), PaintCurve *pc_dst, const PaintCurve *pc_src, const int UNUSED(flag))
{
- PaintCurve *pc_new;
-
- pc_new = BKE_libblock_copy(bmain, &pc->id);
-
- if (pc->tot_points != 0) {
- pc_new->points = MEM_dupallocN(pc->points);
+ if (pc_src->tot_points != 0) {
+ pc_dst->points = MEM_dupallocN(pc_src->points);
}
+}
- BKE_id_copy_ensure_local(bmain, &pc->id, &pc_new->id);
-
- return pc_new;
+PaintCurve *BKE_paint_curve_copy(Main *bmain, const PaintCurve *pc)
+{
+ PaintCurve *pc_copy;
+ BKE_id_copy_ex(bmain, &pc->id, (ID **)&pc_copy, 0, false);
+ return pc_copy;
}
void BKE_paint_curve_make_local(Main *bmain, PaintCurve *pc, const bool lib_local)
@@ -391,7 +398,7 @@ Palette *BKE_palette_add(Main *bmain, const char *name)
{
Palette *palette;
- palette = BKE_libblock_alloc(bmain, ID_PAL, name);
+ palette = BKE_libblock_alloc(bmain, ID_PAL, name, 0);
/* enable fake user by default */
id_fake_user_set(&palette->id);
@@ -399,17 +406,24 @@ Palette *BKE_palette_add(Main *bmain, const char *name)
return palette;
}
-Palette *BKE_palette_copy(Main *bmain, const Palette *palette)
+/**
+ * Only copy internal data of Palette ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_palette_copy_data(Main *UNUSED(bmain), Palette *palette_dst, const Palette *palette_src, const int UNUSED(flag))
{
- Palette *palette_new;
-
- palette_new = BKE_libblock_copy(bmain, &palette->id);
-
- BLI_duplicatelist(&palette_new->colors, &palette->colors);
-
- BKE_id_copy_ensure_local(bmain, &palette->id, &palette_new->id);
+ BLI_duplicatelist(&palette_dst->colors, &palette_src->colors);
+}
- return palette_new;
+Palette *BKE_palette_copy(Main *bmain, const Palette *palette)
+{
+ Palette *palette_copy;
+ BKE_id_copy_ex(bmain, &palette->id, (ID **)&palette_copy, 0, false);
+ return palette_copy;
}
void BKE_palette_make_local(Main *bmain, Palette *palette, const bool lib_local)
@@ -540,12 +554,15 @@ void BKE_paint_free(Paint *paint)
* still do a id_us_plus(), rather then if we were copying between 2 existing
* scenes where a matching value should decrease the existing user count as
* with paint_brush_set() */
-void BKE_paint_copy(Paint *src, Paint *tar)
+void BKE_paint_copy(Paint *src, Paint *tar, const int flag)
{
tar->brush = src->brush;
- id_us_plus((ID *)tar->brush);
- id_us_plus((ID *)tar->palette);
tar->cavity_curve = curvemapping_copy(src->cavity_curve);
+
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)tar->brush);
+ id_us_plus((ID *)tar->palette);
+ }
}
void BKE_paint_stroke_get_average(Scene *scene, Object *ob, float stroke[3])
@@ -694,7 +711,7 @@ void BKE_sculptsession_bm_to_me_for_render(Object *object)
if (object->sculpt->bm) {
/* Ensure no points to old arrays are stored in DM
*
- * Apparently, we could not use DAG_id_tag_update
+ * Apparently, we could not use DEG_id_tag_update
* here because this will lead to the while object
* surface to disappear, so we'll release DM in place.
*/
@@ -823,8 +840,9 @@ static bool sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
/**
* \param need_mask So the DerivedMesh thats returned has mask data
*/
-void BKE_sculpt_update_mesh_elements(EvaluationContext *eval_ctx, Scene *scene, Sculpt *sd, Object *ob,
- bool need_pmap, bool need_mask)
+void BKE_sculpt_update_mesh_elements(
+ const EvaluationContext *eval_ctx, Scene *scene, Sculpt *sd, Object *ob,
+ bool need_pmap, bool need_mask)
{
DerivedMesh *dm;
SculptSession *ss = ob->sculpt;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index baa4214123e..79c4ad6e618 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -1856,7 +1856,7 @@ void precalc_guides(ParticleSimulationData *sim, ListBase *effectors)
}
}
-int do_guides(EvaluationContext *eval_ctx, ParticleSettings *part, ListBase *effectors, ParticleKey *state, int index, float time)
+int do_guides(const EvaluationContext *eval_ctx, ParticleSettings *part, ListBase *effectors, ParticleKey *state, int index, float time)
{
CurveMapping *clumpcurve = (part->child_flag & PART_CHILD_USE_CLUMP_CURVE) ? part->clumpcurve : NULL;
CurveMapping *roughcurve = (part->child_flag & PART_CHILD_USE_ROUGH_CURVE) ? part->roughcurve : NULL;
@@ -2768,7 +2768,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
if (vg_length)
MEM_freeN(vg_length);
}
-void psys_cache_edit_paths(EvaluationContext *eval_ctx, Scene *scene, Object *ob, PTCacheEdit *edit, float cfra, const bool use_render_params)
+void psys_cache_edit_paths(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, PTCacheEdit *edit, float cfra, const bool use_render_params)
{
ParticleCacheKey *ca, **cache = edit->pathcache;
ParticleEditSettings *pset = &scene->toolsettings->particle;
@@ -3317,7 +3317,7 @@ ParticleSettings *psys_new_settings(const char *name, Main *main)
if (main == NULL)
main = G.main;
- part = BKE_libblock_alloc(main, ID_PA, name);
+ part = BKE_libblock_alloc(main, ID_PA, name, 0);
default_particle_settings(part);
@@ -3348,38 +3348,45 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
part->roughcurve = cumap;
}
-ParticleSettings *BKE_particlesettings_copy(Main *bmain, const ParticleSettings *part)
+/**
+ * Only copy internal data of ParticleSettings ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_particlesettings_copy_data(
+ Main *UNUSED(bmain), ParticleSettings *part_dst, const ParticleSettings *part_src, const int UNUSED(flag))
{
- ParticleSettings *partn;
- int a;
+ part_dst->pd = MEM_dupallocN(part_src->pd);
+ part_dst->pd2 = MEM_dupallocN(part_src->pd2);
+ part_dst->effector_weights = MEM_dupallocN(part_src->effector_weights);
+ part_dst->fluid = MEM_dupallocN(part_src->fluid);
- partn = BKE_libblock_copy(bmain, &part->id);
+ if (part_src->clumpcurve) {
+ part_dst->clumpcurve = curvemapping_copy(part_src->clumpcurve);
+ }
+ if (part_src->roughcurve) {
+ part_dst->roughcurve = curvemapping_copy(part_src->roughcurve);
+ }
- partn->pd = MEM_dupallocN(part->pd);
- partn->pd2 = MEM_dupallocN(part->pd2);
- partn->effector_weights = MEM_dupallocN(part->effector_weights);
- partn->fluid = MEM_dupallocN(part->fluid);
+ part_dst->boids = boid_copy_settings(part_src->boids);
- if (part->clumpcurve)
- partn->clumpcurve = curvemapping_copy(part->clumpcurve);
- if (part->roughcurve)
- partn->roughcurve = curvemapping_copy(part->roughcurve);
-
- partn->boids = boid_copy_settings(part->boids);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (part->mtex[a]) {
- partn->mtex[a] = MEM_mallocN(sizeof(MTex), "psys_copy_tex");
- memcpy(partn->mtex[a], part->mtex[a], sizeof(MTex));
- id_us_plus((ID *)partn->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (part_src->mtex[a]) {
+ part_dst->mtex[a] = MEM_dupallocN(part_src->mtex[a]);
}
}
- BLI_duplicatelist(&partn->dupliweights, &part->dupliweights);
-
- BKE_id_copy_ensure_local(bmain, &part->id, &partn->id);
+ BLI_duplicatelist(&part_dst->dupliweights, &part_src->dupliweights);
+}
- return partn;
+ParticleSettings *BKE_particlesettings_copy(Main *bmain, const ParticleSettings *part)
+{
+ ParticleSettings *part_copy;
+ BKE_id_copy_ex(bmain, &part->id, (ID **)&part_copy, 0, false);
+ return part_copy;
}
void BKE_particlesettings_make_local(Main *bmain, ParticleSettings *part, const bool lib_local)
@@ -4318,7 +4325,7 @@ void psys_make_billboard(ParticleBillboardData *bb, float xvec[3], float yvec[3]
madd_v3_v3fl(center, yvec, bb->offset[1]);
}
-void psys_apply_hair_lattice(EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys)
+void psys_apply_hair_lattice(const EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys)
{
ParticleSimulationData sim = {0};
sim.eval_ctx = eval_ctx;
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 044f52832e6..0591ea073cc 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -980,7 +980,7 @@ void psys_get_birth_coords(ParticleSimulationData *sim, ParticleData *pa, Partic
}
/* recursively evaluate emitter parent anim at cfra */
-static void evaluate_emitter_anim(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra)
+static void evaluate_emitter_anim(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra)
{
if (ob->parent)
evaluate_emitter_anim(eval_ctx, scene, ob->parent, cfra);
@@ -4158,7 +4158,7 @@ static int hair_needs_recalc(ParticleSystem *psys)
/* main particle update call, checks that things are ok on the large scale and
* then advances in to actual particle calculations depending on particle type */
-void particle_system_update(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, const bool use_render_params)
+void particle_system_update(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, ParticleSystem *psys, const bool use_render_params)
{
ParticleSimulationData sim= {0};
ParticleSettings *part = psys->part;
@@ -4361,7 +4361,7 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func,
/* **** Depsgraph evaluation **** */
-void BKE_particle_system_settings_eval(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_particle_system_settings_eval(const struct EvaluationContext *UNUSED(eval_ctx),
ParticleSystem *psys)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
@@ -4379,7 +4379,7 @@ void BKE_particle_system_settings_recalc_clear(struct EvaluationContext *UNUSED(
particle_settings->recalc = 0;
}
-void BKE_particle_system_eval_init(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_particle_system_eval_init(const struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob)
{
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 0b152534dcb..341a4d1fde5 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -3449,7 +3449,7 @@ void BKE_ptcache_free_list(ListBase *ptcaches)
}
}
-static PointCache *ptcache_copy(PointCache *cache, bool copy_data)
+static PointCache *ptcache_copy(PointCache *cache, const bool copy_data)
{
PointCache *ncache;
@@ -3492,14 +3492,15 @@ static PointCache *ptcache_copy(PointCache *cache, bool copy_data)
}
/* returns first point cache */
-PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, const ListBase *ptcaches_old, bool copy_data)
+PointCache *BKE_ptcache_copy_list(ListBase *ptcaches_new, const ListBase *ptcaches_old, const int flag)
{
PointCache *cache = ptcaches_old->first;
BLI_listbase_clear(ptcaches_new);
- for (; cache; cache=cache->next)
- BLI_addtail(ptcaches_new, ptcache_copy(cache, copy_data));
+ for (; cache; cache=cache->next) {
+ BLI_addtail(ptcaches_new, ptcache_copy(cache, (flag & LIB_ID_COPY_CACHES) != 0));
+ }
return ptcaches_new->first;
}
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index ee78bc4d678..df048ce5036 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -183,7 +183,7 @@ void BKE_rigidbody_free_constraint(Object *ob)
* be added to relevant groups later...
*/
-RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob)
+RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int UNUSED(flag))
{
RigidBodyOb *rboN = NULL;
@@ -203,7 +203,7 @@ RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob)
return rboN;
}
-RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob)
+RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int UNUSED(flag))
{
RigidBodyCon *rbcN = NULL;
@@ -290,8 +290,6 @@ static rbCollisionShape *rigidbody_get_shape_trimesh_from_mesh(Object *ob)
if (dm == NULL)
return NULL;
- DM_ensure_looptri(dm);
-
mvert = dm->getVertArray(dm);
totvert = dm->getNumVerts(dm);
looptri = dm->getLoopTriArray(dm);
@@ -523,8 +521,6 @@ void BKE_rigidbody_calc_volume(Object *ob, float *r_vol)
if (dm == NULL)
return;
- DM_ensure_looptri(dm);
-
mvert = dm->getVertArray(dm);
totvert = dm->getNumVerts(dm);
lt = dm->getLoopTriArray(dm);
@@ -608,8 +604,6 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
if (dm == NULL)
return;
- DM_ensure_looptri(dm);
-
mvert = dm->getVertArray(dm);
totvert = dm->getNumVerts(dm);
looptri = dm->getLoopTriArray(dm);
@@ -944,24 +938,26 @@ RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
return rbw;
}
-RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw)
+RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
{
- RigidBodyWorld *rbwn = MEM_dupallocN(rbw);
+ RigidBodyWorld *rbw_copy = MEM_dupallocN(rbw);
- if (rbw->effector_weights)
- rbwn->effector_weights = MEM_dupallocN(rbw->effector_weights);
- if (rbwn->group)
- id_us_plus(&rbwn->group->id);
- if (rbwn->constraints)
- id_us_plus(&rbwn->constraints->id);
+ if (rbw->effector_weights) {
+ rbw_copy->effector_weights = MEM_dupallocN(rbw->effector_weights);
+ }
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)rbw_copy->group);
+ id_us_plus((ID *)rbw_copy->constraints);
+ }
- rbwn->pointcache = BKE_ptcache_copy_list(&rbwn->ptcaches, &rbw->ptcaches, false);
+ /* XXX Never copy caches here? */
+ rbw_copy->pointcache = BKE_ptcache_copy_list(&rbw_copy->ptcaches, &rbw->ptcaches, flag & ~LIB_ID_COPY_CACHES);
- rbwn->objects = NULL;
- rbwn->physics_world = NULL;
- rbwn->numbodies = 0;
+ rbw_copy->objects = NULL;
+ rbw_copy->physics_world = NULL;
+ rbw_copy->numbodies = 0;
- return rbwn;
+ return rbw_copy;
}
void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw)
@@ -1226,7 +1222,7 @@ static void rigidbody_update_sim_world(Scene *scene, RigidBodyWorld *rbw)
rigidbody_update_ob_array(rbw);
}
-static void rigidbody_update_sim_ob(struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
+static void rigidbody_update_sim_ob(const struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, Object *ob, RigidBodyOb *rbo)
{
float loc[3];
float rot[4];
@@ -1315,7 +1311,7 @@ static void rigidbody_update_sim_ob(struct EvaluationContext *eval_ctx, Scene *s
*
* \param rebuild Rebuild entire simulation
*/
-static void rigidbody_update_simulation(struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
+static void rigidbody_update_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, RigidBodyWorld *rbw, bool rebuild)
{
GroupObject *go;
@@ -1559,7 +1555,7 @@ void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
/* Rebuild rigid body world */
/* NOTE: this needs to be called before frame update to work correctly */
-void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, Scene *scene, float ctime)
+void BKE_rigidbody_rebuild_world(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime)
{
RigidBodyWorld *rbw = scene->rigidbody_world;
PointCache *cache;
@@ -1587,7 +1583,7 @@ void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, Scene *scen
}
/* Run RigidBody simulation for the specified physics world */
-void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scene, float ctime)
+void BKE_rigidbody_do_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime)
{
float timestep;
RigidBodyWorld *rbw = scene->rigidbody_world;
@@ -1657,13 +1653,13 @@ void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scen
# pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
-struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob) { return NULL; }
-struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob) { return NULL; }
+struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob, const int flag) { return NULL; }
+struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob, const int flag) { return NULL; }
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) {}
void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) { if (r_vol) *r_vol = 0.0f; }
void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) { zero_v3(r_center); }
struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene) { return NULL; }
-struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw) { return NULL; }
+struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag) { return NULL; }
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {}
void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata) {}
struct RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type) { return NULL; }
@@ -1675,8 +1671,8 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle) {}
bool BKE_rigidbody_check_sim_running(RigidBodyWorld *rbw, float ctime) { return false; }
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw) {}
-void BKE_rigidbody_rebuild_world(struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {}
-void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {}
+void BKE_rigidbody_rebuild_world(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {}
+void BKE_rigidbody_do_simulation(const struct EvaluationContext *eval_ctx, Scene *scene, float ctime) {}
#ifdef __GNUC__
# pragma GCC diagnostic pop
@@ -1687,7 +1683,7 @@ void BKE_rigidbody_do_simulation(struct EvaluationContext *eval_ctx, Scene *scen
/* -------------------- */
/* Depsgraph evaluation */
-void BKE_rigidbody_rebuild_sim(struct EvaluationContext *eval_ctx,
+void BKE_rigidbody_rebuild_sim(const struct EvaluationContext *eval_ctx,
Scene *scene)
{
float ctime = BKE_scene_frame_get(scene);
@@ -1702,7 +1698,7 @@ void BKE_rigidbody_rebuild_sim(struct EvaluationContext *eval_ctx,
}
}
-void BKE_rigidbody_eval_simulation(struct EvaluationContext *eval_ctx,
+void BKE_rigidbody_eval_simulation(const struct EvaluationContext *eval_ctx,
Scene *scene)
{
float ctime = BKE_scene_frame_get(scene);
@@ -1717,7 +1713,7 @@ void BKE_rigidbody_eval_simulation(struct EvaluationContext *eval_ctx,
}
}
-void BKE_rigidbody_object_sync_transforms(struct EvaluationContext *UNUSED(eval_ctx),
+void BKE_rigidbody_object_sync_transforms(const struct EvaluationContext *UNUSED(eval_ctx),
Scene *scene,
Object *ob)
{
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 19d646daf9f..fb81ed4d47f 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -72,7 +72,7 @@ void free_sensors(ListBase *lb)
}
}
-bSensor *copy_sensor(bSensor *sens)
+bSensor *copy_sensor(bSensor *sens, const int UNUSED(flag))
{
bSensor *sensn;
@@ -87,14 +87,14 @@ bSensor *copy_sensor(bSensor *sens)
return sensn;
}
-void copy_sensors(ListBase *lbn, const ListBase *lbo)
+void copy_sensors(ListBase *lbn, const ListBase *lbo, const int flag)
{
bSensor *sens, *sensn;
lbn->first= lbn->last= NULL;
sens= lbo->first;
while (sens) {
- sensn= copy_sensor(sens);
+ sensn= copy_sensor(sens, flag);
BLI_addtail(lbn, sensn);
sens= sens->next;
}
@@ -234,7 +234,7 @@ void free_controllers(ListBase *lb)
}
}
-bController *copy_controller(bController *cont)
+bController *copy_controller(bController *cont, const int UNUSED(flag))
{
bController *contn;
@@ -251,14 +251,14 @@ bController *copy_controller(bController *cont)
return contn;
}
-void copy_controllers(ListBase *lbn, const ListBase *lbo)
+void copy_controllers(ListBase *lbn, const ListBase *lbo, const int flag)
{
bController *cont, *contn;
lbn->first= lbn->last= NULL;
cont= lbo->first;
while (cont) {
- contn= copy_controller(cont);
+ contn= copy_controller(cont, flag);
BLI_addtail(lbn, contn);
cont= cont->next;
}
@@ -359,7 +359,7 @@ void free_actuators(ListBase *lb)
}
}
-bActuator *copy_actuator(bActuator *act)
+bActuator *copy_actuator(bActuator *act, const int flag)
{
bActuator *actn;
@@ -374,29 +374,31 @@ bActuator *copy_actuator(bActuator *act)
case ACT_SHAPEACTION:
{
bActionActuator *aa = (bActionActuator *)act->data;
- if (aa->act)
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus((ID *)aa->act);
+ }
break;
}
case ACT_SOUND:
{
bSoundActuator *sa = (bSoundActuator *)act->data;
- if (sa->sound)
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
id_us_plus((ID *)sa->sound);
+ }
break;
}
}
return actn;
}
-void copy_actuators(ListBase *lbn, const ListBase *lbo)
+void copy_actuators(ListBase *lbn, const ListBase *lbo, const int flag)
{
bActuator *act, *actn;
lbn->first= lbn->last= NULL;
act= lbo->first;
while (act) {
- actn= copy_actuator(act);
+ actn= copy_actuator(act, flag);
BLI_addtail(lbn, actn);
act= act->next;
}
@@ -783,11 +785,11 @@ void BKE_sca_logic_links_remap(Main *bmain, Object *ob_old, Object *ob_new)
* Handle the copying of logic data into a new object, including internal logic links update.
* External links (links between logic bricks of different objects) must be handled separately.
*/
-void BKE_sca_logic_copy(Object *ob_new, const Object *ob)
+void BKE_sca_logic_copy(Object *ob_new, const Object *ob, const int flag)
{
- copy_sensors(&ob_new->sensors, &ob->sensors);
- copy_controllers(&ob_new->controllers, &ob->controllers);
- copy_actuators(&ob_new->actuators, &ob->actuators);
+ copy_sensors(&ob_new->sensors, &ob->sensors, flag);
+ copy_controllers(&ob_new->controllers, &ob->controllers, flag);
+ copy_actuators(&ob_new->actuators, &ob->actuators, flag);
for (bSensor *sens = ob_new->sensors.first; sens; sens = sens->next) {
if (sens->flag & SENS_NEW) {
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index eada47fbb5f..b380a98932d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -161,324 +161,438 @@ static void remove_sequencer_fcurves(Scene *sce)
}
/* copy SceneCollection tree but keep pointing to the same objects */
-static void scene_collection_copy(SceneCollection *scn, SceneCollection *sc)
+static void scene_collection_copy(SceneCollection *sc_dst, SceneCollection *sc_src, const int flag)
{
- BLI_duplicatelist(&scn->objects, &sc->objects);
- for (LinkData *link = scn->objects.first; link; link = link->next) {
- id_us_plus(link->data);
+ BLI_duplicatelist(&sc_dst->objects, &sc_src->objects);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ for (LinkData *link = sc_dst->objects.first; link; link = link->next) {
+ id_us_plus(link->data);
+ }
}
- BLI_duplicatelist(&scn->filter_objects, &sc->filter_objects);
- for (LinkData *link = scn->filter_objects.first; link; link = link->next) {
- id_us_plus(link->data);
+ BLI_duplicatelist(&sc_dst->filter_objects, &sc_src->filter_objects);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ for (LinkData *link = sc_dst->filter_objects.first; link; link = link->next) {
+ id_us_plus(link->data);
+ }
}
- BLI_duplicatelist(&scn->scene_collections, &sc->scene_collections);
- SceneCollection *nscn = scn->scene_collections.first; /* nested SceneCollection new */
- for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
- scene_collection_copy(nscn, nsc);
- nscn = nscn->next;
+ BLI_duplicatelist(&sc_dst->scene_collections, &sc_src->scene_collections);
+ for (SceneCollection *nsc_src = sc_src->scene_collections.first, *nsc_dst = sc_dst->scene_collections.first;
+ nsc_src;
+ nsc_src = nsc_src->next, nsc_dst = nsc_dst->next) {
+ scene_collection_copy(nsc_dst, nsc_src, flag);
}
}
/* Find the equivalent SceneCollection in the new tree */
-static SceneCollection *scene_collection_from_new_tree(SceneCollection *sc_reference, SceneCollection *scn, SceneCollection *sc)
+static SceneCollection *scene_collection_from_new_tree(SceneCollection *sc_reference, SceneCollection *sc_dst, SceneCollection *sc_src)
{
- if (sc == sc_reference) {
- return scn;
+ if (sc_src == sc_reference) {
+ return sc_dst;
}
- SceneCollection *nscn = scn->scene_collections.first; /* nested master collection new */
- for (SceneCollection *nsc = sc->scene_collections.first; nsc; nsc = nsc->next) {
-
- SceneCollection *found = scene_collection_from_new_tree(sc_reference, nscn, nsc);
- if (found) {
+ for (SceneCollection *nsc_src = sc_src->scene_collections.first, *nsc_dst = sc_dst->scene_collections.first;
+ nsc_src;
+ nsc_src = nsc_src->next, nsc_dst = nsc_dst->next)
+ {
+ SceneCollection *found = scene_collection_from_new_tree(sc_reference, nsc_dst, nsc_src);
+ if (found != NULL) {
return found;
}
- nscn = nscn->next;
}
return NULL;
}
-/* recreate the LayerCollection tree */
-static void layer_collections_recreate(SceneLayer *sl, ListBase *lb, SceneCollection *mcn, SceneCollection *mc)
+static void layer_collections_sync_flags(ListBase *layer_collections_dst, const ListBase *layer_collections_src)
{
- for (LayerCollection *lc = lb->first; lc; lc = lc->next) {
+ LayerCollection *layer_collection_dst = (LayerCollection *)layer_collections_dst->first;
+ const LayerCollection *layer_collection_src = (const LayerCollection *)layer_collections_src->first;
+ while (layer_collection_dst != NULL) {
+ layer_collection_dst->flag = layer_collection_src->flag;
+ layer_collections_sync_flags(&layer_collection_dst->layer_collections,
+ &layer_collection_src->layer_collections);
+ /* TODO(sergey/dfelinto): Overrides. */
+ layer_collection_dst = layer_collection_dst->next;
+ layer_collection_src = layer_collection_src->next;
+ }
+}
+
- SceneCollection *sc = scene_collection_from_new_tree(lc->scene_collection, mcn, mc);
- BLI_assert(sc);
+/* recreate the LayerCollection tree */
+static void layer_collections_recreate(
+ SceneLayer *sl_dst, ListBase *lb_src, SceneCollection *mc_dst, SceneCollection *mc_src)
+{
+ for (LayerCollection *lc_src = lb_src->first; lc_src; lc_src = lc_src->next) {
+ SceneCollection *sc_dst = scene_collection_from_new_tree(lc_src->scene_collection, mc_dst, mc_src);
+ BLI_assert(sc_dst);
- /* instead of syncronizing both trees we simply re-create it */
- BKE_collection_link(sl, sc);
+ /* instead of synchronizing both trees we simply re-create it */
+ BKE_collection_link(sl_dst, sc_dst);
}
}
-Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
+/**
+ * Only copy internal data of Scene ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_scene_copy_data(Main *bmain, Scene *sce_dst, const Scene *sce_src, const int flag)
{
- Scene *scen;
- SceneRenderLayer *srl, *new_srl;
- FreestyleLineSet *lineset;
- ToolSettings *ts;
- BaseLegacy *legacy_base, *olegacy_base;
-
- if (type == SCE_COPY_EMPTY) {
- ListBase rl, rv;
- scen = BKE_scene_add(bmain, sce->id.name + 2);
-
- rl = scen->r.layers;
- rv = scen->r.views;
- curvemapping_free_data(&scen->r.mblur_shutter_curve);
- scen->r = sce->r;
- scen->r.layers = rl;
- scen->r.actlay = 0;
- scen->r.views = rv;
- scen->unit = sce->unit;
- scen->physics_settings = sce->physics_settings;
- scen->gm = sce->gm;
- scen->audio = sce->audio;
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
- if (sce->id.properties)
- scen->id.properties = IDP_CopyProperty(sce->id.properties);
+ sce_dst->ed = NULL;
+ sce_dst->theDag = NULL;
+ sce_dst->depsgraph_legacy = NULL;
+ sce_dst->obedit = NULL;
+ sce_dst->fps_info = NULL;
- MEM_freeN(scen->toolsettings);
- BKE_sound_destroy_scene(scen);
- }
- else {
- scen = BKE_libblock_copy(bmain, &sce->id);
- BLI_duplicatelist(&(scen->base), &(sce->base));
-
- if (type != SCE_COPY_FULL) {
- id_us_plus((ID *)scen->world);
+ BLI_duplicatelist(&(sce_dst->base), &(sce_src->base));
+ for (BaseLegacy *base_dst = sce_dst->base.first, *base_src = sce_src->base.first;
+ base_dst;
+ base_dst = base_dst->next, base_src = base_src->next)
+ {
+ if (base_src == sce_src->basact) {
+ sce_dst->basact = base_dst;
}
- id_us_plus((ID *)scen->set);
- /* id_us_plus((ID *)scen->gm.dome.warptext); */ /* XXX Not refcounted? see readfile.c */
-
- scen->ed = NULL;
- scen->theDag = NULL;
- scen->depsgraph_legacy = NULL;
- scen->obedit = NULL;
- scen->fps_info = NULL;
+ }
- if (sce->rigidbody_world)
- scen->rigidbody_world = BKE_rigidbody_world_copy(sce->rigidbody_world);
+ /* layers and collections */
+ sce_dst->collection = MEM_dupallocN(sce_src->collection);
+ SceneCollection *mc_src = BKE_collection_master(sce_src);
+ SceneCollection *mc_dst = BKE_collection_master(sce_dst);
- BLI_duplicatelist(&(scen->markers), &(sce->markers));
- BLI_duplicatelist(&(scen->r.layers), &(sce->r.layers));
- BLI_duplicatelist(&(scen->r.views), &(sce->r.views));
- BKE_keyingsets_copy(&(scen->keyingsets), &(sce->keyingsets));
+ /* recursively creates a new SceneCollection tree */
+ scene_collection_copy(mc_dst, mc_src, flag_subdata);
- if (sce->nodetree) {
- /* ID's are managed on both copy and switch */
- scen->nodetree = ntreeCopyTree(bmain, sce->nodetree);
- BKE_libblock_relink_ex(bmain, scen->nodetree, &sce->id, &scen->id, false);
- }
+ IDPropertyTemplate val = {0};
+ BLI_duplicatelist(&sce_dst->render_layers, &sce_src->render_layers);
+ for (SceneLayer *sl_src = sce_src->render_layers.first, *sl_dst = sce_dst->render_layers.first;
+ sl_src;
+ sl_src = sl_src->next, sl_dst = sl_dst->next)
+ {
+ sl_dst->stats = NULL;
+ sl_dst->properties_evaluated = NULL;
+ sl_dst->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ IDP_MergeGroup_ex(sl_dst->properties, sl_src->properties, true, flag_subdata);
+
+ /* we start fresh with no overrides and no visibility flags set
+ * instead of syncing both trees we simply unlink and relink the scene collection */
+ BLI_listbase_clear(&sl_dst->layer_collections);
+ BLI_listbase_clear(&sl_dst->object_bases);
+ BLI_listbase_clear(&sl_dst->drawdata);
+
+ layer_collections_recreate(sl_dst, &sl_src->layer_collections, mc_dst, mc_src);
+
+ /* Now we handle the syncing for visibility, selectability, ... */
+ layer_collections_sync_flags(&sl_dst->layer_collections, &sl_src->layer_collections);
+
+ Object *active_ob = OBACT_NEW(sl_src);
+ for (Base *base_src = sl_src->object_bases.first, *base_dst = sl_dst->object_bases.first;
+ base_src;
+ base_src = base_src->next, base_dst = base_dst->next)
+ {
+ base_dst->flag = base_src->flag;
+ base_dst->flag_legacy = base_src->flag_legacy;
- olegacy_base = sce->base.first;
- legacy_base = scen->base.first;
- while (legacy_base) {
- id_us_plus(&legacy_base->object->id);
- if (olegacy_base == sce->basact) scen->basact = legacy_base;
-
- olegacy_base = olegacy_base->next;
- legacy_base = legacy_base->next;
+ if (base_dst->object == active_ob) {
+ sl_dst->basact = base_dst;
+ }
}
+ }
- /* copy action and remove animation used by sequencer */
- BKE_animdata_copy_id_action(&scen->id, false);
+ sce_dst->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ if (sce_src->collection_properties) {
+ IDP_MergeGroup_ex(sce_dst->collection_properties, sce_src->collection_properties, true, flag_subdata);
+ }
+ sce_dst->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ if (sce_src->layer_properties) {
+ IDP_MergeGroup_ex(sce_dst->layer_properties, sce_src->layer_properties, true, flag_subdata);
+ }
- if (type != SCE_COPY_FULL)
- remove_sequencer_fcurves(scen);
+ BLI_duplicatelist(&(sce_dst->markers), &(sce_src->markers));
+ BLI_duplicatelist(&(sce_dst->r.layers), &(sce_src->r.layers));
+ BLI_duplicatelist(&(sce_dst->r.views), &(sce_src->r.views));
+ BKE_keyingsets_copy(&(sce_dst->keyingsets), &(sce_src->keyingsets));
- /* copy Freestyle settings */
- new_srl = scen->r.layers.first;
- for (srl = sce->r.layers.first; srl; srl = srl->next) {
- if (new_srl->prop != NULL) {
- new_srl->prop = IDP_CopyProperty(new_srl->prop);
- }
- BKE_freestyle_config_copy(&new_srl->freestyleConfig, &srl->freestyleConfig);
- if (type == SCE_COPY_FULL) {
- for (lineset = new_srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
- if (lineset->linestyle) {
- /* Has been incremented by BKE_freestyle_config_copy(). */
- id_us_min(&lineset->linestyle->id);
- lineset->linestyle = BKE_linestyle_copy(bmain, lineset->linestyle);
- }
- }
- }
- new_srl = new_srl->next;
- }
+ if (sce_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)sce_src->nodetree, (ID **)&sce_dst->nodetree, flag, false);
+ BKE_libblock_relink_ex(bmain, sce_dst->nodetree, (void *)(&sce_src->id), &sce_dst->id, false);
+ }
- /* layers and collections */
- scen->collection = MEM_dupallocN(sce->collection);
- SceneCollection *mcn = BKE_collection_master(scen);
- SceneCollection *mc = BKE_collection_master(sce);
-
- /* recursively creates a new SceneCollection tree */
- scene_collection_copy(mcn, mc);
-
- IDPropertyTemplate val = {0};
- BLI_duplicatelist(&scen->render_layers, &sce->render_layers);
- SceneLayer *new_sl = scen->render_layers.first;
- for (SceneLayer *sl = sce->render_layers.first; sl; sl = sl->next) {
- new_sl->stats = NULL;
- new_sl->properties_evaluated = NULL;
- new_sl->properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
- IDP_MergeGroup(new_sl->properties, sl->properties, true);
-
- /* we start fresh with no overrides and no visibility flags set
- * instead of syncing both trees we simply unlink and relink the scene collection */
- BLI_listbase_clear(&new_sl->layer_collections);
- BLI_listbase_clear(&new_sl->object_bases);
- BLI_listbase_clear(&new_sl->drawdata);
- layer_collections_recreate(new_sl, &sl->layer_collections, mcn, mc);
-
- Object *active_ob = OBACT_NEW;
- Base *new_base = new_sl->object_bases.first;
- for (Base *base = sl->object_bases.first; base; base = base->next) {
- new_base->flag = base->flag;
- new_base->flag_legacy = base->flag_legacy;
-
- if (new_base->object == active_ob) {
- new_sl->basact = new_base;
- }
+ if (sce_src->rigidbody_world) {
+ sce_dst->rigidbody_world = BKE_rigidbody_world_copy(sce_src->rigidbody_world, flag_subdata);
+ }
- new_base = new_base->next;
- }
- new_sl = new_sl->next;
+ /* copy Freestyle settings */
+ for (SceneRenderLayer *srl_dst = sce_dst->r.layers.first, *srl_src = sce_src->r.layers.first;
+ srl_src;
+ srl_dst = srl_dst->next, srl_src = srl_src->next)
+ {
+ if (srl_dst->prop != NULL) {
+ srl_dst->prop = IDP_CopyProperty_ex(srl_dst->prop, flag_subdata);
}
-
- scen->collection_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
- scen->layer_properties = IDP_New(IDP_GROUP, &val, ROOT_PROP);
+ BKE_freestyle_config_copy(&srl_dst->freestyleConfig, &srl_src->freestyleConfig, flag_subdata);
}
/* copy color management settings */
- BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings);
- BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings);
- BKE_color_managed_colorspace_settings_copy(&scen->sequencer_colorspace_settings, &sce->sequencer_colorspace_settings);
+ BKE_color_managed_display_settings_copy(&sce_dst->display_settings, &sce_src->display_settings);
+ BKE_color_managed_view_settings_copy(&sce_dst->view_settings, &sce_src->view_settings);
+ BKE_color_managed_colorspace_settings_copy(&sce_dst->sequencer_colorspace_settings, &sce_src->sequencer_colorspace_settings);
- BKE_color_managed_display_settings_copy(&scen->r.im_format.display_settings, &sce->r.im_format.display_settings);
- BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings);
+ BKE_color_managed_display_settings_copy(&sce_dst->r.im_format.display_settings, &sce_src->r.im_format.display_settings);
+ BKE_color_managed_view_settings_copy(&sce_dst->r.im_format.view_settings, &sce_src->r.im_format.view_settings);
- BKE_color_managed_display_settings_copy(&scen->r.bake.im_format.display_settings, &sce->r.bake.im_format.display_settings);
- BKE_color_managed_view_settings_copy(&scen->r.bake.im_format.view_settings, &sce->r.bake.im_format.view_settings);
+ BKE_color_managed_display_settings_copy(&sce_dst->r.bake.im_format.display_settings, &sce_src->r.bake.im_format.display_settings);
+ BKE_color_managed_view_settings_copy(&sce_dst->r.bake.im_format.view_settings, &sce_src->r.bake.im_format.view_settings);
- curvemapping_copy_data(&scen->r.mblur_shutter_curve, &sce->r.mblur_shutter_curve);
+ curvemapping_copy_data(&sce_dst->r.mblur_shutter_curve, &sce_src->r.mblur_shutter_curve);
/* tool settings */
- scen->toolsettings = MEM_dupallocN(sce->toolsettings);
-
- ts = scen->toolsettings;
- if (ts) {
+ if (sce_dst->toolsettings != NULL) {
+ ToolSettings *ts = sce_dst->toolsettings = MEM_dupallocN(sce_dst->toolsettings);
if (ts->vpaint) {
ts->vpaint = MEM_dupallocN(ts->vpaint);
ts->vpaint->paintcursor = NULL;
ts->vpaint->vpaint_prev = NULL;
ts->vpaint->wpaint_prev = NULL;
- BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint);
+ BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, flag_subdata);
}
if (ts->wpaint) {
ts->wpaint = MEM_dupallocN(ts->wpaint);
ts->wpaint->paintcursor = NULL;
ts->wpaint->vpaint_prev = NULL;
ts->wpaint->wpaint_prev = NULL;
- BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint);
+ BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, flag_subdata);
}
if (ts->sculpt) {
ts->sculpt = MEM_dupallocN(ts->sculpt);
- BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint);
+ BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, flag_subdata);
}
if (ts->uvsculpt) {
ts->uvsculpt = MEM_dupallocN(ts->uvsculpt);
- BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint);
+ BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint, flag_subdata);
}
- BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint);
+ BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint, flag_subdata);
ts->imapaint.paintcursor = NULL;
- id_us_plus((ID *)ts->imapaint.stencil);
- id_us_plus((ID *)ts->imapaint.clone);
- id_us_plus((ID *)ts->imapaint.canvas);
ts->particle.paintcursor = NULL;
ts->particle.scene = NULL;
ts->particle.object = NULL;
-
+
/* duplicate Grease Pencil Drawing Brushes */
BLI_listbase_clear(&ts->gp_brushes);
- for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) {
+ for (bGPDbrush *brush = sce_src->toolsettings->gp_brushes.first; brush; brush = brush->next) {
bGPDbrush *newbrush = BKE_gpencil_brush_duplicate(brush);
BLI_addtail(&ts->gp_brushes, newbrush);
}
-
+
/* duplicate Grease Pencil interpolation curve */
ts->gp_interpolate.custom_ipo = curvemapping_copy(ts->gp_interpolate.custom_ipo);
}
-
+
/* make a private copy of the avicodecdata */
- if (sce->r.avicodecdata) {
- scen->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
- scen->r.avicodecdata->lpFormat = MEM_dupallocN(scen->r.avicodecdata->lpFormat);
- scen->r.avicodecdata->lpParms = MEM_dupallocN(scen->r.avicodecdata->lpParms);
+ if (sce_src->r.avicodecdata) {
+ sce_dst->r.avicodecdata = MEM_dupallocN(sce_src->r.avicodecdata);
+ sce_dst->r.avicodecdata->lpFormat = MEM_dupallocN(sce_dst->r.avicodecdata->lpFormat);
+ sce_dst->r.avicodecdata->lpParms = MEM_dupallocN(sce_dst->r.avicodecdata->lpParms);
}
-
+
/* make a private copy of the qtcodecdata */
- if (sce->r.qtcodecdata) {
- scen->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
- scen->r.qtcodecdata->cdParms = MEM_dupallocN(scen->r.qtcodecdata->cdParms);
+ if (sce_src->r.qtcodecdata) {
+ sce_dst->r.qtcodecdata = MEM_dupallocN(sce_src->r.qtcodecdata);
+ sce_dst->r.qtcodecdata->cdParms = MEM_dupallocN(sce_dst->r.qtcodecdata->cdParms);
}
-
- if (sce->r.ffcodecdata.properties) { /* intentionally check scen not sce. */
- scen->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
+
+ if (sce_src->r.ffcodecdata.properties) { /* intentionally check sce_dst not sce_src. */ /* XXX ??? comment outdated... */
+ sce_dst->r.ffcodecdata.properties = IDP_CopyProperty_ex(sce_src->r.ffcodecdata.properties, flag_subdata);
}
- /* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
- * are done outside of blenkernel with ED_objects_single_users! */
+ /* before scene copy */
+ BKE_sound_create_scene(sce_dst);
- /* camera */
- if (type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
- ID_NEW_REMAP(scen->camera);
+ /* Copy sequencer, this is local data! */
+ if (sce_src->ed) {
+ sce_dst->ed = MEM_callocN(sizeof(*sce_dst->ed), __func__);
+ sce_dst->ed->seqbasep = &sce_dst->ed->seqbase;
+ BKE_sequence_base_dupli_recursive(
+ sce_src, sce_dst, &sce_dst->ed->seqbase, &sce_src->ed->seqbase, SEQ_DUPE_ALL, flag_subdata);
}
-
- /* before scene copy */
- BKE_sound_create_scene(scen);
- /* world */
- if (type == SCE_COPY_FULL) {
- if (scen->world) {
- scen->world = BKE_world_copy(bmain, scen->world);
- BKE_animdata_copy_id_action((ID *)scen->world, false);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&sce_dst->id, &sce_src->id);
+ }
+ else {
+ sce_dst->preview = NULL;
+ }
+}
+
+Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
+{
+ Scene *sce_copy;
+
+ /* TODO this should/could most likely be replaced by call to more generic code at some point...
+ * But for now, let's keep it well isolated here. */
+ if (type == SCE_COPY_EMPTY) {
+ ToolSettings *ts;
+ ListBase rl, rv;
+
+ sce_copy = BKE_scene_add(bmain, sce->id.name + 2);
+
+ rl = sce_copy->r.layers;
+ rv = sce_copy->r.views;
+ curvemapping_free_data(&sce_copy->r.mblur_shutter_curve);
+ sce_copy->r = sce->r;
+ sce_copy->r.layers = rl;
+ sce_copy->r.actlay = 0;
+ sce_copy->r.views = rv;
+ sce_copy->unit = sce->unit;
+ sce_copy->physics_settings = sce->physics_settings;
+ sce_copy->gm = sce->gm;
+ sce_copy->audio = sce->audio;
+
+ if (sce->id.properties)
+ sce_copy->id.properties = IDP_CopyProperty(sce->id.properties);
+
+ MEM_freeN(sce_copy->toolsettings);
+ BKE_sound_destroy_scene(sce_copy);
+
+ /* copy color management settings */
+ BKE_color_managed_display_settings_copy(&sce_copy->display_settings, &sce->display_settings);
+ BKE_color_managed_view_settings_copy(&sce_copy->view_settings, &sce->view_settings);
+ BKE_color_managed_colorspace_settings_copy(&sce_copy->sequencer_colorspace_settings, &sce->sequencer_colorspace_settings);
+
+ BKE_color_managed_display_settings_copy(&sce_copy->r.im_format.display_settings, &sce->r.im_format.display_settings);
+ BKE_color_managed_view_settings_copy(&sce_copy->r.im_format.view_settings, &sce->r.im_format.view_settings);
+
+ BKE_color_managed_display_settings_copy(&sce_copy->r.bake.im_format.display_settings, &sce->r.bake.im_format.display_settings);
+ BKE_color_managed_view_settings_copy(&sce_copy->r.bake.im_format.view_settings, &sce->r.bake.im_format.view_settings);
+
+ curvemapping_copy_data(&sce_copy->r.mblur_shutter_curve, &sce->r.mblur_shutter_curve);
+
+ /* tool settings */
+ sce_copy->toolsettings = MEM_dupallocN(sce->toolsettings);
+
+ ts = sce_copy->toolsettings;
+ if (ts) {
+ if (ts->vpaint) {
+ ts->vpaint = MEM_dupallocN(ts->vpaint);
+ ts->vpaint->paintcursor = NULL;
+ ts->vpaint->vpaint_prev = NULL;
+ ts->vpaint->wpaint_prev = NULL;
+ BKE_paint_copy(&ts->vpaint->paint, &ts->vpaint->paint, 0);
+ }
+ if (ts->wpaint) {
+ ts->wpaint = MEM_dupallocN(ts->wpaint);
+ ts->wpaint->paintcursor = NULL;
+ ts->wpaint->vpaint_prev = NULL;
+ ts->wpaint->wpaint_prev = NULL;
+ BKE_paint_copy(&ts->wpaint->paint, &ts->wpaint->paint, 0);
+ }
+ if (ts->sculpt) {
+ ts->sculpt = MEM_dupallocN(ts->sculpt);
+ BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint, 0);
+ }
+ if (ts->uvsculpt) {
+ ts->uvsculpt = MEM_dupallocN(ts->uvsculpt);
+ BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint, 0);
+ }
+
+ BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint, 0);
+ ts->imapaint.paintcursor = NULL;
+ id_us_plus((ID *)ts->imapaint.stencil);
+ id_us_plus((ID *)ts->imapaint.clone);
+ id_us_plus((ID *)ts->imapaint.canvas);
+ ts->particle.paintcursor = NULL;
+ ts->particle.scene = NULL;
+ ts->particle.object = NULL;
+
+ /* duplicate Grease Pencil Drawing Brushes */
+ BLI_listbase_clear(&ts->gp_brushes);
+ for (bGPDbrush *brush = sce->toolsettings->gp_brushes.first; brush; brush = brush->next) {
+ bGPDbrush *newbrush = BKE_gpencil_brush_duplicate(brush);
+ BLI_addtail(&ts->gp_brushes, newbrush);
+ }
+
+ /* duplicate Grease Pencil interpolation curve */
+ ts->gp_interpolate.custom_ipo = curvemapping_copy(ts->gp_interpolate.custom_ipo);
+ }
+
+ /* make a private copy of the avicodecdata */
+ if (sce->r.avicodecdata) {
+ sce_copy->r.avicodecdata = MEM_dupallocN(sce->r.avicodecdata);
+ sce_copy->r.avicodecdata->lpFormat = MEM_dupallocN(sce_copy->r.avicodecdata->lpFormat);
+ sce_copy->r.avicodecdata->lpParms = MEM_dupallocN(sce_copy->r.avicodecdata->lpParms);
}
- if (sce->ed) {
- scen->ed = MEM_callocN(sizeof(Editing), "addseq");
- scen->ed->seqbasep = &scen->ed->seqbase;
- BKE_sequence_base_dupli_recursive(sce, scen, &scen->ed->seqbase, &sce->ed->seqbase, SEQ_DUPE_ALL);
+ /* make a private copy of the qtcodecdata */
+ if (sce->r.qtcodecdata) {
+ sce_copy->r.qtcodecdata = MEM_dupallocN(sce->r.qtcodecdata);
+ sce_copy->r.qtcodecdata->cdParms = MEM_dupallocN(sce_copy->r.qtcodecdata->cdParms);
}
+
+ if (sce->r.ffcodecdata.properties) { /* intentionally check scen not sce. */
+ sce_copy->r.ffcodecdata.properties = IDP_CopyProperty(sce->r.ffcodecdata.properties);
+ }
+
+ /* before scene copy */
+ BKE_sound_create_scene(sce_copy);
+
+ /* grease pencil */
+ sce_copy->gpd = NULL;
+
+ sce_copy->preview = NULL;
+
+ return sce_copy;
}
-
- /* grease pencil */
- if (scen->gpd) {
+ else {
+ BKE_id_copy_ex(bmain, (ID *)sce, (ID **)&sce_copy, LIB_ID_COPY_ACTIONS, false);
+
+ /* Extra actions, most notably SCE_FULL_COPY also duplicates several 'children' datablocks... */
+
if (type == SCE_COPY_FULL) {
- scen->gpd = BKE_gpencil_data_duplicate(bmain, scen->gpd, false);
- }
- else if (type == SCE_COPY_EMPTY) {
- scen->gpd = NULL;
+ /* Copy Freestyle LineStyle datablocks. */
+ for (SceneRenderLayer *srl_dst = sce_copy->r.layers.first; srl_dst; srl_dst = srl_dst->next) {
+ for (FreestyleLineSet *lineset = srl_dst->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
+ if (lineset->linestyle) {
+ /* XXX Not copying anim/actions here? */
+ BKE_id_copy_ex(bmain, (ID *)lineset->linestyle, (ID **)&lineset->linestyle, 0, false);
+ }
+ }
+ }
+
+ /* Full copy of world (included animations) */
+ if (sce_copy->world) {
+ BKE_id_copy_ex(bmain, (ID *)sce_copy->world, (ID **)&sce_copy->world, LIB_ID_COPY_ACTIONS, false);
+ }
+
+ /* Full copy of GreasePencil. */
+ /* XXX Not copying anim/actions here? */
+ if (sce_copy->gpd) {
+ BKE_id_copy_ex(bmain, (ID *)sce_copy->gpd, (ID **)&sce_copy->gpd, 0, false);
+ }
}
else {
- id_us_plus((ID *)scen->gpd);
+ /* Remove sequencer if not full copy */
+ /* XXX Why in Hell? :/ */
+ remove_sequencer_fcurves(sce_copy);
+ BKE_sequencer_editing_free(sce_copy);
}
- }
- BKE_previewimg_id_copy(&scen->id, &sce->id);
+ /* NOTE: part of SCE_COPY_LINK_DATA and SCE_COPY_FULL operations
+ * are done outside of blenkernel with ED_objects_single_users! */
- if (type != SCE_COPY_NEW) {
- if (sce->collection_properties) {
- IDP_MergeGroup(scen->collection_properties, sce->collection_properties, true);
+ /* camera */
+ if (ELEM(type, SCE_COPY_LINK_DATA, SCE_COPY_FULL)) {
+ ID_NEW_REMAP(sce_copy->camera);
}
- if (sce->layer_properties) {
- IDP_MergeGroup(scen->layer_properties, sce->layer_properties, true);
- }
- }
- return scen;
+ return sce_copy;
+ }
}
void BKE_scene_groups_relink(Scene *sce)
@@ -549,7 +663,7 @@ void BKE_scene_free_ex(Scene *sce, const bool do_id_user)
BLI_freelistN(&sce->markers);
BLI_freelistN(&sce->r.layers);
BLI_freelistN(&sce->r.views);
-
+
if (sce->toolsettings) {
if (sce->toolsettings->vpaint) {
BKE_paint_free(&sce->toolsettings->vpaint->paint);
@@ -720,7 +834,7 @@ void BKE_scene_init(Scene *sce)
sce->r.seq_prev_type = OB_SOLID;
sce->r.seq_rend_type = OB_SOLID;
- sce->r.seq_flag = R_SEQ_GL_PREV;
+ sce->r.seq_flag = 0;
sce->r.threads = 1;
@@ -999,7 +1113,7 @@ Scene *BKE_scene_add(Main *bmain, const char *name)
{
Scene *sce;
- sce = BKE_libblock_alloc(bmain, ID_SCE, name);
+ sce = BKE_libblock_alloc(bmain, ID_SCE, name, 0);
id_us_min(&sce->id);
id_us_ensure_real(&sce->id);
@@ -1089,8 +1203,9 @@ Scene *BKE_scene_set_name(Main *bmain, const char *name)
}
/* Used by metaballs, return *all* objects (including duplis) existing in the scene (including scene's sets) */
-int BKE_scene_base_iter_next(EvaluationContext *eval_ctx, SceneBaseIter *iter,
- Scene **scene, int val, BaseLegacy **base, Object **ob)
+int BKE_scene_base_iter_next(
+ const EvaluationContext *eval_ctx, SceneBaseIter *iter,
+ Scene **scene, int val, BaseLegacy **base, Object **ob)
{
bool run_again = true;
@@ -1586,7 +1701,7 @@ void BKE_scene_update_for_newframe(EvaluationContext *eval_ctx, Main *bmain, Sce
BKE_image_update_frame(bmain, sce->r.cfra);
BKE_sound_set_cfra(sce->r.cfra);
-
+
/* clear animation overrides */
/* XXX TODO... */
@@ -1950,6 +2065,14 @@ int BKE_scene_num_threads(const Scene *scene)
return BKE_render_num_threads(&scene->r);
}
+int BKE_render_preview_pixel_size(const RenderData *r)
+{
+ if (r->preview_pixel_size == 0) {
+ return (U.pixelsize > 1.5f)? 2 : 1;
+ }
+ return r->preview_pixel_size;
+}
+
/* Apply the needed correction factor to value, based on unit_type (only length-related are affected currently)
* and unit->scale_length.
*/
diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c
index a07abe166f0..6bd88099792 100644
--- a/source/blender/blenkernel/intern/screen.c
+++ b/source/blender/blenkernel/intern/screen.c
@@ -185,6 +185,7 @@ ARegion *BKE_area_region_copy(SpaceType *st, ARegion *ar)
newar->swinid = 0;
newar->manipulator_map = NULL;
newar->regiontimer = NULL;
+ newar->headerstr = NULL;
/* use optional regiondata callback */
if (ar->regiondata) {
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 0c384f8b8c8..18c721c8e3f 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -91,7 +91,7 @@
#include "BKE_sound.h"
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
/* mutable state for sequencer */
@@ -3235,7 +3235,7 @@ static ImBuf *seq_render_scene_strip(const SeqRenderData *context, Sequence *seq
const bool is_background = G.background;
const bool do_seq_gl = is_rendering ?
0 /* (context->scene->r.seq_flag & R_SEQ_GL_REND) */ :
- (context->scene->r.seq_flag & R_SEQ_GL_PREV) != 0;
+ (context->scene->r.seq_prev_type) != OB_RENDER;
// bool have_seq = false; /* UNUSED */
bool have_comp = false;
bool use_gpencil = true;
@@ -5373,9 +5373,8 @@ Sequence *BKE_sequencer_add_movie_strip(bContext *C, ListBase *seqbasep, SeqLoad
return seq;
}
-static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dupe_flag)
+static Sequence *seq_dupli(const Scene *scene_src, Scene *scene_dst, Sequence *seq, int dupe_flag, const int flag)
{
- Scene *sce_audio = scene_to ? scene_to : scene;
Sequence *seqn = MEM_dupallocN(seq);
seq->tmp = seqn;
@@ -5399,7 +5398,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
}
if (seq->prop) {
- seqn->prop = IDP_CopyProperty(seq->prop);
+ seqn->prop = IDP_CopyProperty_ex(seq->prop, flag);
}
if (seqn->modifiers.first) {
@@ -5418,7 +5417,7 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
else if (seq->type == SEQ_TYPE_SCENE) {
seqn->strip->stripdata = NULL;
if (seq->scene_sound)
- seqn->scene_sound = BKE_sound_scene_add_scene_sound_defaults(sce_audio, seqn);
+ seqn->scene_sound = BKE_sound_scene_add_scene_sound_defaults(scene_dst, seqn);
}
else if (seq->type == SEQ_TYPE_MOVIECLIP) {
/* avoid assert */
@@ -5435,9 +5434,11 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
seqn->strip->stripdata =
MEM_dupallocN(seq->strip->stripdata);
if (seq->scene_sound)
- seqn->scene_sound = BKE_sound_add_scene_sound_defaults(sce_audio, seqn);
+ seqn->scene_sound = BKE_sound_add_scene_sound_defaults(scene_dst, seqn);
- id_us_plus((ID *)seqn->sound);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)seqn->sound);
+ }
}
else if (seq->type == SEQ_TYPE_IMAGE) {
seqn->strip->stripdata =
@@ -5457,11 +5458,15 @@ static Sequence *seq_dupli(Scene *scene, Scene *scene_to, Sequence *seq, int dup
BLI_assert(0);
}
- if (dupe_flag & SEQ_DUPE_UNIQUE_NAME)
- BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seqn);
+ if (scene_src == scene_dst) {
+ if (dupe_flag & SEQ_DUPE_UNIQUE_NAME) {
+ BKE_sequence_base_unique_name_recursive(&scene_dst->ed->seqbase, seqn);
+ }
- if (dupe_flag & SEQ_DUPE_ANIM)
- BKE_sequencer_dupe_animdata(scene, seq->name + 2, seqn->name + 2);
+ if (dupe_flag & SEQ_DUPE_ANIM) {
+ BKE_sequencer_dupe_animdata(scene_dst, seq->name + 2, seqn->name + 2);
+ }
+ }
return seqn;
}
@@ -5488,16 +5493,16 @@ static void seq_new_fix_links_recursive(Sequence *seq)
}
}
-Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence *seq, int dupe_flag)
+Sequence *BKE_sequence_dupli_recursive(const Scene *scene_src, Scene *scene_dst, Sequence *seq, int dupe_flag)
{
Sequence *seqn;
seq->tmp = NULL;
- seqn = seq_dupli(scene, scene_to, seq, dupe_flag);
+ seqn = seq_dupli(scene_src, scene_dst, seq, dupe_flag, 0);
if (seq->type == SEQ_TYPE_META) {
Sequence *s;
for (s = seq->seqbase.first; s; s = s->next) {
- Sequence *n = BKE_sequence_dupli_recursive(scene, scene_to, s, dupe_flag);
+ Sequence *n = BKE_sequence_dupli_recursive(scene_src, scene_dst, s, dupe_flag);
if (n) {
BLI_addtail(&seqn->seqbase, n);
}
@@ -5510,19 +5515,19 @@ Sequence *BKE_sequence_dupli_recursive(Scene *scene, Scene *scene_to, Sequence *
}
void BKE_sequence_base_dupli_recursive(
- Scene *scene, Scene *scene_to, ListBase *nseqbase, ListBase *seqbase,
- int dupe_flag)
+ const Scene *scene_src, Scene *scene_dst, ListBase *nseqbase, const ListBase *seqbase,
+ int dupe_flag, const int flag)
{
Sequence *seq;
Sequence *seqn = NULL;
- Sequence *last_seq = BKE_sequencer_active_get(scene);
+ Sequence *last_seq = BKE_sequencer_active_get((Scene *)scene_src);
/* always include meta's strips */
int dupe_flag_recursive = dupe_flag | SEQ_DUPE_ALL;
for (seq = seqbase->first; seq; seq = seq->next) {
seq->tmp = NULL;
if ((seq->flag & SELECT) || (dupe_flag & SEQ_DUPE_ALL)) {
- seqn = seq_dupli(scene, scene_to, seq, dupe_flag);
+ seqn = seq_dupli(scene_src, scene_dst, seq, dupe_flag, flag);
if (seqn) { /*should never fail */
if (dupe_flag & SEQ_DUPE_CONTEXT) {
seq->flag &= ~SEQ_ALLSEL;
@@ -5532,13 +5537,13 @@ void BKE_sequence_base_dupli_recursive(
BLI_addtail(nseqbase, seqn);
if (seq->type == SEQ_TYPE_META) {
BKE_sequence_base_dupli_recursive(
- scene, scene_to, &seqn->seqbase, &seq->seqbase,
- dupe_flag_recursive);
+ scene_src, scene_dst, &seqn->seqbase, &seq->seqbase,
+ dupe_flag_recursive, flag);
}
if (dupe_flag & SEQ_DUPE_CONTEXT) {
if (seq == last_seq) {
- BKE_sequencer_active_set(scene, seqn);
+ BKE_sequencer_active_set(scene_dst, seqn);
}
}
}
diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c
index 664305ac715..218ac64f3e0 100644
--- a/source/blender/blenkernel/intern/smoke.c
+++ b/source/blender/blenkernel/intern/smoke.c
@@ -128,7 +128,7 @@ void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(s
void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity),
int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color),
float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {}
-struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), struct EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; }
+struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), const struct EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; }
float smoke_get_velocity_at(struct Object *UNUSED(ob), float UNUSED(position[3]), float UNUSED(velocity[3])) { return 0.0f; }
#endif /* WITH_SMOKE */
@@ -704,7 +704,7 @@ static int get_lamp(SceneLayer *sl, float *light)
int found_lamp = 0;
// try to find a lamp, preferably local
- for (base_tmp = FIRSTBASE_NEW; base_tmp; base_tmp = base_tmp->next) {
+ for (base_tmp = FIRSTBASE_NEW(sl); base_tmp; base_tmp = base_tmp->next) {
if (base_tmp->object->type == OB_LAMP) {
Lamp *la = base_tmp->object->data;
@@ -2073,7 +2073,7 @@ BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value
}
}
-static void update_flowsfluids(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt)
+static void update_flowsfluids(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt)
{
Object **flowobjs = NULL;
EmissionMap *emaps = NULL;
@@ -2489,7 +2489,7 @@ static void update_effectors_task_cb(void *userdata, const int x)
}
}
-static void update_effectors(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt))
+static void update_effectors(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt))
{
ListBase *effectors;
/* make sure smoke flow influence is 0.0f */
@@ -2518,7 +2518,7 @@ static void update_effectors(struct EvaluationContext *eval_ctx, Scene *scene, O
pdEndEffectors(&effectors);
}
-static void step(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps)
+static void step(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps)
{
SmokeDomainSettings *sds = smd->domain;
/* stability values copied from wturbulence.cpp */
@@ -2685,7 +2685,8 @@ static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob)
return result;
}
-static void smokeModifier_process(SmokeModifierData *smd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
+static void smokeModifier_process(
+ SmokeModifierData *smd, const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
{
if ((smd->type & MOD_SMOKE_TYPE_FLOW))
{
@@ -2694,7 +2695,6 @@ static void smokeModifier_process(SmokeModifierData *smd, struct EvaluationConte
if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm);
smd->flow->dm = CDDM_copy(dm);
- DM_ensure_looptri(smd->flow->dm);
if (scene->r.cfra > smd->time)
{
@@ -2717,7 +2717,6 @@ static void smokeModifier_process(SmokeModifierData *smd, struct EvaluationConte
smd->coll->dm->release(smd->coll->dm);
smd->coll->dm = CDDM_copy(dm);
- DM_ensure_looptri(smd->coll->dm);
}
smd->time = scene->r.cfra;
@@ -2829,7 +2828,8 @@ static void smokeModifier_process(SmokeModifierData *smd, struct EvaluationConte
}
}
-struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
+struct DerivedMesh *smokeModifier_do(
+ SmokeModifierData *smd, const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, DerivedMesh *dm)
{
/* lock so preview render does not read smoke data while it gets modified */
if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain)
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 4d8270568ba..7cea1e4940f 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -532,7 +532,7 @@ static void ccd_build_deflector_hash(SceneLayer *sl, Group *group, Object *verte
}
}
else {
- for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW(sl); base; base = base->next) {
/*Only proceed for mesh object in same layer */
if (base->object->type == OB_MESH) {
ob = base->object;
@@ -578,7 +578,7 @@ static void ccd_update_deflector_hash(SceneLayer *sl, Group *group, Object *vert
}
}
else {
- for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW(sl); base; base = base->next) {
/*Only proceed for mesh object in same layer */
if (base->object->type == OB_MESH) {
ob = base->object;
@@ -988,7 +988,7 @@ static bool are_there_deflectors(SceneLayer *sl, Group *group)
}
}
else {
- for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (base->object->pd) {
if (base->object->pd->deflect)
return 1;
@@ -1546,7 +1546,7 @@ static void _scan_for_ext_spring_forces(Scene *scene, Object *ob, float timenow,
}
-static void scan_for_ext_spring_forces(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float timenow)
+static void scan_for_ext_spring_forces(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float timenow)
{
SoftBody *sb = ob->soft;
ListBase *do_effector = NULL;
@@ -1563,7 +1563,7 @@ static void *exec_scan_for_ext_spring_forces(void *data)
return NULL;
}
-static void sb_sfesf_threads_run(struct EvaluationContext *eval_ctx, Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void)))
+static void sb_sfesf_threads_run(const struct EvaluationContext *eval_ctx, Scene *scene, struct Object *ob, float timenow, int totsprings, int *UNUSED(ptr_to_break_func(void)))
{
ListBase *do_effector = NULL;
ListBase threads;
@@ -2235,7 +2235,7 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
MEM_freeN(sb_threads);
}
-static void softbody_calc_forcesEx(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow)
+static void softbody_calc_forcesEx(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow)
{
/* rule we never alter free variables :bp->vec bp->pos in here !
* this will ruin adaptive stepsize AKA heun! (BM)
@@ -2280,7 +2280,7 @@ static void softbody_calc_forcesEx(struct EvaluationContext *eval_ctx, Scene *sc
}
-static void softbody_calc_forces(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow)
+static void softbody_calc_forces(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float forcetime, float timenow)
{
/* redirection to the new threaded Version */
if (!(G.debug_value & 0x10)) { // 16
@@ -3512,7 +3512,7 @@ static void softbody_reset(Object *ob, SoftBody *sb, float (*vertexCos)[3], int
}
}
-static void softbody_step(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SoftBody *sb, float dtime)
+static void softbody_step(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, SoftBody *sb, float dtime)
{
/* the simulator */
float forcetime;
@@ -3646,7 +3646,7 @@ static void softbody_step(struct EvaluationContext *eval_ctx, Scene *scene, Obje
}
/* simulates one step. framenr is in frames */
-void sbObjectStep(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts)
+void sbObjectStep(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float cfra, float (*vertexCos)[3], int numVerts)
{
SoftBody *sb= ob->soft;
PointCache *cache;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 8469351c54a..94fa81308fe 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -48,13 +48,11 @@
#include "DNA_speaker_types.h"
#ifdef WITH_AUDASPACE
-# include AUD_SOUND_H
-# include AUD_SEQUENCE_H
-# include AUD_HANDLE_H
-# include AUD_SPECIAL_H
-# ifdef WITH_SYSTEM_AUDASPACE
-# include "../../../intern/audaspace/intern/AUD_Set.h"
-# endif
+# include <AUD_Sound.h>
+# include <AUD_Sequence.h>
+# include <AUD_Handle.h>
+# include <AUD_Special.h>
+# include "../../../intern/audaspace/intern/AUD_Set.h"
#endif
#include "BKE_global.h"
@@ -83,7 +81,7 @@ bSound *BKE_sound_new_file(struct Main *bmain, const char *filepath)
BLI_path_abs(str, path);
- sound = BKE_libblock_alloc(bmain, ID_SO, BLI_path_basename(filepath));
+ sound = BKE_libblock_alloc(bmain, ID_SO, BLI_path_basename(filepath), 0);
BLI_strncpy(sound->name, filepath, FILE_MAX);
/* sound->type = SOUND_TYPE_FILE; */ /* XXX unused currently */
@@ -155,6 +153,34 @@ void BKE_sound_free(bSound *sound)
}
}
+/**
+ * Only copy internal data of Sound ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_sound_copy_data(Main *bmain, bSound *sound_dst, const bSound *UNUSED(sound_src), const int UNUSED(flag))
+{
+ sound_dst->handle = NULL;
+ sound_dst->cache = NULL;
+ sound_dst->waveform = NULL;
+ sound_dst->playback_handle = NULL;
+ sound_dst->spinlock = NULL; /* Think this is OK? Otherwise, easy to create new spinlock here... */
+
+ /* Just to be sure, should not have any value actually after reading time. */
+ sound_dst->ipo = NULL;
+ sound_dst->newpackedfile = NULL;
+
+ if (sound_dst->packedfile) {
+ sound_dst->packedfile = dupPackedFile(sound_dst->packedfile);
+ }
+
+ /* Initialize whole runtime (audaspace) stuff. */
+ BKE_sound_load(bmain, sound_dst);
+}
+
void BKE_sound_make_local(Main *bmain, bSound *sound, const bool lib_local)
{
BKE_id_make_local_generic(bmain, &sound->id, true, lib_local);
@@ -274,7 +300,6 @@ void BKE_sound_exit_once(void)
sound_device = NULL;
AUD_exitOnce();
-#ifdef WITH_SYSTEM_AUDASPACE
if (audio_device_names != NULL) {
int i;
for (i = 0; audio_device_names[i]; i++) {
@@ -283,7 +308,6 @@ void BKE_sound_exit_once(void)
free(audio_device_names);
audio_device_names = NULL;
}
-#endif
}
/* XXX unused currently */
@@ -879,28 +903,12 @@ float BKE_sound_get_length(bSound *sound)
char **BKE_sound_get_device_names(void)
{
if (audio_device_names == NULL) {
-#ifdef WITH_SYSTEM_AUDASPACE
audio_device_names = AUD_getDeviceNames();
-#else
- static const char *names[] = {
- "Null", "SDL", "OpenAL", "JACK", NULL
- };
- audio_device_names = (char **)names;
-#endif
}
return audio_device_names;
}
-bool BKE_sound_is_jack_supported(void)
-{
-#ifdef WITH_SYSTEM_AUDASPACE
- return 1;
-#else
- return (bool)AUD_isJackSupported();
-#endif
-}
-
#else /* WITH_AUDASPACE */
#include "BLI_utildefines.h"
@@ -947,5 +955,6 @@ void BKE_sound_set_scene_sound_pan(void *UNUSED(handle), float UNUSED(pan), char
void BKE_sound_set_scene_volume(struct Scene *UNUSED(scene), float UNUSED(volume)) {}
void BKE_sound_set_scene_sound_pitch(void *UNUSED(handle), float UNUSED(pitch), char UNUSED(animated)) {}
float BKE_sound_get_length(struct bSound *UNUSED(sound)) { return 0; }
-bool BKE_sound_is_jack_supported(void) { return false; }
+char **BKE_sound_get_device_names(void) { static char *names[1] = {NULL}; return names; }
+
#endif /* WITH_AUDASPACE */
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index d00e4b1a0d2..9d604a9382a 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -61,25 +61,31 @@ void *BKE_speaker_add(Main *bmain, const char *name)
{
Speaker *spk;
- spk = BKE_libblock_alloc(bmain, ID_SPK, name);
+ spk = BKE_libblock_alloc(bmain, ID_SPK, name, 0);
BKE_speaker_init(spk);
return spk;
}
-Speaker *BKE_speaker_copy(Main *bmain, const Speaker *spk)
+/**
+ * Only copy internal data of Speaker ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_speaker_copy_data(Main *UNUSED(bmain), Speaker *UNUSED(spk_dst), const Speaker *UNUSED(spk_src), const int UNUSED(flag))
{
- Speaker *spkn;
-
- spkn = BKE_libblock_copy(bmain, &spk->id);
-
- if (spkn->sound)
- id_us_plus(&spkn->sound->id);
-
- BKE_id_copy_ensure_local(bmain, &spk->id, &spkn->id);
+ /* Nothing to do! */
+}
- return spkn;
+Speaker *BKE_speaker_copy(Main *bmain, const Speaker *spk)
+{
+ Speaker *spk_copy;
+ BKE_id_copy_ex(bmain, &spk->id, (ID **)&spk_copy, 0, false);
+ return spk_copy;
}
void BKE_speaker_make_local(Main *bmain, Speaker *spk, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 1f72744bdee..d4280205cfb 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -4220,10 +4220,10 @@ static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm))
/* Nothing to do: CCG handles creating its own tessfaces */
}
+/* WARNING! *MUST* be called in an 'loops_cache_rwlock' protected thread context! */
static void ccgDM_recalcLoopTri(DerivedMesh *dm)
{
- BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
- MLoopTri *mlooptri;
+ MLoopTri *mlooptri = dm->looptris.array;
const int tottri = dm->numPolyData * 2;
int i, poly_index;
@@ -4248,19 +4248,6 @@ static void ccgDM_recalcLoopTri(DerivedMesh *dm)
lt->tri[2] = (poly_index * 4) + 2;
lt->poly = poly_index;
}
- BLI_rw_mutex_unlock(&loops_cache_rwlock);
-}
-
-static const MLoopTri *ccgDM_getLoopTriArray(DerivedMesh *dm)
-{
- if (dm->looptris.array) {
- BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
- }
- else {
- dm->recalcLoopTri(dm);
- }
-
- return dm->looptris.array;
}
static void ccgDM_calcNormals(DerivedMesh *dm)
@@ -4279,8 +4266,6 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm)
ccgdm->dm.getNumPolys = ccgDM_getNumPolys;
ccgdm->dm.getNumTessFaces = ccgDM_getNumTessFaces;
- ccgdm->dm.getLoopTriArray = ccgDM_getLoopTriArray;
-
ccgdm->dm.getVert = ccgDM_getFinalVert;
ccgdm->dm.getEdge = ccgDM_getFinalEdge;
ccgdm->dm.getTessFace = ccgDM_getFinalFace;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 9444e605e6d..4ae9818f891 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -223,7 +223,7 @@ Text *BKE_text_add(Main *bmain, const char *name)
{
Text *ta;
- ta = BKE_libblock_alloc(bmain, ID_TXT, name);
+ ta = BKE_libblock_alloc(bmain, ID_TXT, name, 0);
BKE_text_init(ta);
@@ -409,7 +409,7 @@ Text *BKE_text_load_ex(Main *bmain, const char *file, const char *relpath, const
return false;
}
- ta = BKE_libblock_alloc(bmain, ID_TXT, BLI_path_basename(filepath_abs));
+ ta = BKE_libblock_alloc(bmain, ID_TXT, BLI_path_basename(filepath_abs), 0);
ta->id.us = 0;
BLI_listbase_clear(&ta->lines);
@@ -448,53 +448,49 @@ Text *BKE_text_load(Main *bmain, const char *file, const char *relpath)
return BKE_text_load_ex(bmain, file, relpath, false);
}
-Text *BKE_text_copy(Main *bmain, const Text *ta)
+/**
+ * Only copy internal data of Text ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_text_copy_data(Main *UNUSED(bmain), Text *ta_dst, const Text *ta_src, const int UNUSED(flag))
{
- Text *tan;
- TextLine *line, *tmp;
-
- tan = BKE_libblock_copy(bmain, &ta->id);
-
/* file name can be NULL */
- if (ta->name) {
- tan->name = BLI_strdup(ta->name);
- }
- else {
- tan->name = NULL;
+ if (ta_src->name) {
+ ta_dst->name = BLI_strdup(ta_src->name);
}
- tan->flags = ta->flags | TXT_ISDIRTY;
-
- BLI_listbase_clear(&tan->lines);
- tan->curl = tan->sell = NULL;
- tan->compiled = NULL;
-
- tan->nlines = ta->nlines;
+ ta_dst->flags |= TXT_ISDIRTY;
+
+ BLI_listbase_clear(&ta_dst->lines);
+ ta_dst->curl = ta_dst->sell = NULL;
+ ta_dst->compiled = NULL;
- line = ta->lines.first;
/* Walk down, reconstructing */
- while (line) {
- tmp = (TextLine *) MEM_mallocN(sizeof(TextLine), "textline");
- tmp->line = MEM_mallocN(line->len + 1, "textline_string");
- tmp->format = NULL;
-
- strcpy(tmp->line, line->line);
+ for (TextLine *line_src = ta_src->lines.first; line_src; line_src = line_src->next) {
+ TextLine *line_dst = MEM_mallocN(sizeof(*line_dst), __func__);
- tmp->len = line->len;
-
- BLI_addtail(&tan->lines, tmp);
-
- line = line->next;
- }
+ line_dst->line = BLI_strdup(line_src->line);
+ line_dst->format = NULL;
+ line_dst->len = line_src->len;
- tan->curl = tan->sell = tan->lines.first;
- tan->curc = tan->selc = 0;
+ BLI_addtail(&ta_dst->lines, line_dst);
+ }
- init_undo_text(tan);
+ ta_dst->curl = ta_dst->sell = ta_dst->lines.first;
+ ta_dst->curc = ta_dst->selc = 0;
- BKE_id_copy_ensure_local(bmain, &ta->id, &tan->id);
+ init_undo_text(ta_dst);
+}
- return tan;
+Text *BKE_text_copy(Main *bmain, const Text *ta)
+{
+ Text *ta_copy;
+ BKE_id_copy_ex(bmain, &ta->id, (ID **)&ta_copy, 0, false);
+ return ta_copy;
}
void BKE_text_make_local(Main *bmain, Text *text, const bool lib_local)
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 1e0659d3d67..89a3842a230 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -707,7 +707,7 @@ Tex *BKE_texture_add(Main *bmain, const char *name)
{
Tex *tex;
- tex = BKE_libblock_alloc(bmain, ID_TE, name);
+ tex = BKE_libblock_alloc(bmain, ID_TE, name, 0);
BKE_texture_default(tex);
@@ -846,41 +846,71 @@ MTex *BKE_texture_mtex_add_id(ID *id, int slot)
/* ------------------------------------------------------------------------- */
-Tex *BKE_texture_copy(Main *bmain, const Tex *tex)
+/**
+ * Only copy internal data of Texture ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_texture_copy_data(Main *bmain, Tex *tex_dst, const Tex *tex_src, const int flag)
{
- Tex *texn;
-
- texn = BKE_libblock_copy(bmain, &tex->id);
- if (BKE_texture_is_image_user(tex)) {
- id_us_plus((ID *)texn->ima);
+ /* We never handle usercount here for own data. */
+ const int flag_subdata = flag | LIB_ID_CREATE_NO_USER_REFCOUNT;
+
+ if (!BKE_texture_is_image_user(tex_src)) {
+ tex_dst->ima = NULL;
}
- else {
- texn->ima = NULL;
+
+ if (tex_dst->coba) {
+ tex_dst->coba = MEM_dupallocN(tex_dst->coba);
+ }
+ if (tex_dst->env) {
+ tex_dst->env = BKE_texture_envmap_copy(tex_dst->env, flag_subdata);
+ }
+ if (tex_dst->pd) {
+ tex_dst->pd = BKE_texture_pointdensity_copy(tex_dst->pd, flag_subdata);
+ }
+ if (tex_dst->vd) {
+ tex_dst->vd = MEM_dupallocN(tex_dst->vd);
+ }
+ if (tex_dst->ot) {
+ tex_dst->ot = BKE_texture_ocean_copy(tex_dst->ot, flag_subdata);
}
-
- if (texn->coba) texn->coba = MEM_dupallocN(texn->coba);
- if (texn->env) texn->env = BKE_texture_envmap_copy(texn->env);
- if (texn->pd) texn->pd = BKE_texture_pointdensity_copy(texn->pd);
- if (texn->vd) texn->vd = MEM_dupallocN(texn->vd);
- if (texn->ot) texn->ot = BKE_texture_ocean_copy(texn->ot);
- if (tex->nodetree) {
- if (tex->nodetree->execdata) {
- ntreeTexEndExecTree(tex->nodetree->execdata);
+ if (tex_src->nodetree) {
+ if (tex_src->nodetree->execdata) {
+ ntreeTexEndExecTree(tex_src->nodetree->execdata);
}
- texn->nodetree = ntreeCopyTree(bmain, tex->nodetree);
+ BKE_id_copy_ex(bmain, (ID *)tex_src->nodetree, (ID **)&tex_dst->nodetree, flag, false);
}
- BKE_previewimg_id_copy(&texn->id, &tex->id);
-
- BKE_id_copy_ensure_local(bmain, &tex->id, &texn->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&tex_dst->id, &tex_src->id);
+ }
+ else {
+ tex_dst->preview = NULL;
+ }
+}
- return texn;
+Tex *BKE_texture_copy(Main *bmain, const Tex *tex)
+{
+ Tex *tex_copy;
+ BKE_id_copy_ex(bmain, &tex->id, (ID **)&tex_copy, 0, false);
+ return tex_copy;
}
/* texture copy without adding to main dbase */
Tex *BKE_texture_localize(Tex *tex)
{
+ /* TODO replace with something like
+ * Tex *tex_copy;
+ * BKE_id_copy_ex(bmain, &tex->id, (ID **)&tex_copy, LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT, false);
+ * return tex_copy;
+ *
+ * ... Once f*** nodes are fully converted to that too :( */
+
Tex *texn;
texn = BKE_libblock_copy_nolib(&tex->id, false);
@@ -889,17 +919,17 @@ Tex *BKE_texture_localize(Tex *tex)
if (texn->coba) texn->coba = MEM_dupallocN(texn->coba);
if (texn->env) {
- texn->env = BKE_texture_envmap_copy(texn->env);
+ texn->env = BKE_texture_envmap_copy(texn->env, LIB_ID_CREATE_NO_USER_REFCOUNT);
id_us_min(&texn->env->ima->id);
}
- if (texn->pd) texn->pd = BKE_texture_pointdensity_copy(texn->pd);
+ if (texn->pd) texn->pd = BKE_texture_pointdensity_copy(texn->pd, LIB_ID_CREATE_NO_USER_REFCOUNT);
if (texn->vd) {
texn->vd = MEM_dupallocN(texn->vd);
if (texn->vd->dataset)
texn->vd->dataset = MEM_dupallocN(texn->vd->dataset);
}
if (texn->ot) {
- texn->ot = BKE_texture_ocean_copy(tex->ot);
+ texn->ot = BKE_texture_ocean_copy(tex->ot, LIB_ID_CREATE_NO_USER_REFCOUNT);
}
texn->preview = NULL;
@@ -1263,16 +1293,20 @@ EnvMap *BKE_texture_envmap_add(void)
/* ------------------------------------------------------------------------- */
-EnvMap *BKE_texture_envmap_copy(const EnvMap *env)
+EnvMap *BKE_texture_envmap_copy(const EnvMap *env, const int flag)
{
EnvMap *envn;
int a;
envn = MEM_dupallocN(env);
envn->ok = 0;
- for (a = 0; a < 6; a++) envn->cube[a] = NULL;
- if (envn->ima) id_us_plus((ID *)envn->ima);
-
+ for (a = 0; a < 6; a++) {
+ envn->cube[a] = NULL;
+ }
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus((ID *)envn->ima);
+ }
+
return envn;
}
@@ -1336,14 +1370,16 @@ PointDensity *BKE_texture_pointdensity_add(void)
return pd;
}
-PointDensity *BKE_texture_pointdensity_copy(const PointDensity *pd)
+PointDensity *BKE_texture_pointdensity_copy(const PointDensity *pd, const int UNUSED(flag))
{
PointDensity *pdn;
pdn = MEM_dupallocN(pd);
pdn->point_tree = NULL;
pdn->point_data = NULL;
- if (pdn->coba) pdn->coba = MEM_dupallocN(pdn->coba);
+ if (pdn->coba) {
+ pdn->coba = MEM_dupallocN(pdn->coba);
+ }
pdn->falloff_curve = curvemapping_copy(pdn->falloff_curve); /* can be NULL */
return pdn;
}
@@ -1430,7 +1466,7 @@ OceanTex *BKE_texture_ocean_add(void)
return ot;
}
-OceanTex *BKE_texture_ocean_copy(const OceanTex *ot)
+OceanTex *BKE_texture_ocean_copy(const OceanTex *ot, const int UNUSED(flag))
{
OceanTex *otn = MEM_dupallocN(ot);
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 9120d384a16..b4ef381534f 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -190,7 +190,7 @@ void BKE_tracking_free(MovieTracking *tracking)
}
/* Copy the whole list of tracks. */
-static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_src, GHash *tracks_mapping)
+static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_src, GHash *tracks_mapping, const int flag)
{
MovieTrackingTrack *track_dst, *track_src;
@@ -202,7 +202,9 @@ static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_sr
if (track_src->markers) {
track_dst->markers = MEM_dupallocN(track_src->markers);
}
- id_us_plus(&track_dst->gpd->id);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus(&track_dst->gpd->id);
+ }
BLI_addtail(tracks_dst, track_dst);
BLI_ghash_insert(tracks_mapping, track_src, track_dst);
}
@@ -210,7 +212,8 @@ static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_sr
/* copy the whole list of plane tracks (need whole MovieTracking structures due to embedded pointers to tracks).
* WARNING: implies tracking_[dst/src] and their tracks have already been copied. */
-static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, const ListBase *plane_tracks_src, GHash *tracks_mapping)
+static void tracking_plane_tracks_copy(
+ ListBase *plane_tracks_dst, const ListBase *plane_tracks_src, GHash *tracks_mapping, const int flag)
{
MovieTrackingPlaneTrack *plane_track_dst, *plane_track_src;
@@ -225,14 +228,17 @@ static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, const ListBas
for (int i = 0; i < plane_track_dst->point_tracksnr; i++) {
plane_track_dst->point_tracks[i] = BLI_ghash_lookup(tracks_mapping, plane_track_src->point_tracks[i]);
}
- id_us_plus(&plane_track_dst->image->id);
+ if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
+ id_us_plus(&plane_track_dst->image->id);
+ }
BLI_addtail(plane_tracks_dst, plane_track_dst);
}
}
/* Copy reconstruction structure. */
static void tracking_reconstruction_copy(
- MovieTrackingReconstruction *reconstruction_dst, const MovieTrackingReconstruction *reconstruction_src)
+ MovieTrackingReconstruction *reconstruction_dst, const MovieTrackingReconstruction *reconstruction_src,
+ const int UNUSED(flag))
{
*reconstruction_dst = *reconstruction_src;
if (reconstruction_src->cameras) {
@@ -242,23 +248,25 @@ static void tracking_reconstruction_copy(
/* Copy stabilization structure. */
static void tracking_stabilization_copy(
- MovieTrackingStabilization *stabilization_dst, const MovieTrackingStabilization *stabilization_src)
+ MovieTrackingStabilization *stabilization_dst, const MovieTrackingStabilization *stabilization_src,
+ const int UNUSED(flag))
{
*stabilization_dst = *stabilization_src;
}
/* Copy tracking object. */
static void tracking_object_copy(
- MovieTrackingObject *object_dst, const MovieTrackingObject *object_src, GHash *tracks_mapping)
+ MovieTrackingObject *object_dst, const MovieTrackingObject *object_src, GHash *tracks_mapping, const int flag)
{
*object_dst = *object_src;
- tracking_tracks_copy(&object_dst->tracks, &object_src->tracks, tracks_mapping);
- tracking_plane_tracks_copy(&object_dst->plane_tracks, &object_src->plane_tracks, tracks_mapping);
- tracking_reconstruction_copy(&object_dst->reconstruction, &object_src->reconstruction);
+ tracking_tracks_copy(&object_dst->tracks, &object_src->tracks, tracks_mapping, flag);
+ tracking_plane_tracks_copy(&object_dst->plane_tracks, &object_src->plane_tracks, tracks_mapping, flag);
+ tracking_reconstruction_copy(&object_dst->reconstruction, &object_src->reconstruction, flag);
}
/* Copy list of tracking objects. */
-static void tracking_objects_copy(ListBase *objects_dst, const ListBase *objects_src, GHash *tracks_mapping)
+static void tracking_objects_copy(
+ ListBase *objects_dst, const ListBase *objects_src, GHash *tracks_mapping, const int flag)
{
MovieTrackingObject *object_dst, *object_src;
@@ -266,22 +274,22 @@ static void tracking_objects_copy(ListBase *objects_dst, const ListBase *objects
for (object_src = objects_src->first; object_src != NULL; object_src = object_src->next) {
object_dst = MEM_mallocN(sizeof(*object_dst), __func__);
- tracking_object_copy(object_dst, object_src, tracks_mapping);
+ tracking_object_copy(object_dst, object_src, tracks_mapping, flag);
BLI_addtail(objects_dst, object_dst);
}
}
/* Copy tracking structure content. */
-void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *tracking_src)
+void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *tracking_src, const int flag)
{
GHash *tracks_mapping = BLI_ghash_ptr_new(__func__);
*tracking_dst = *tracking_src;
- tracking_tracks_copy(&tracking_dst->tracks, &tracking_src->tracks, tracks_mapping);
- tracking_plane_tracks_copy(&tracking_dst->plane_tracks, &tracking_src->plane_tracks, tracks_mapping);
- tracking_reconstruction_copy(&tracking_dst->reconstruction, &tracking_src->reconstruction);
- tracking_stabilization_copy(&tracking_dst->stabilization, &tracking_src->stabilization);
+ tracking_tracks_copy(&tracking_dst->tracks, &tracking_src->tracks, tracks_mapping, flag);
+ tracking_plane_tracks_copy(&tracking_dst->plane_tracks, &tracking_src->plane_tracks, tracks_mapping, flag);
+ tracking_reconstruction_copy(&tracking_dst->reconstruction, &tracking_src->reconstruction, flag);
+ tracking_stabilization_copy(&tracking_dst->stabilization, &tracking_src->stabilization, flag);
if (tracking_src->act_track) {
tracking_dst->act_track = BLI_ghash_lookup(tracks_mapping, tracking_src->act_track);
}
@@ -299,7 +307,7 @@ void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *trackin
}
/* Warning! Will override tracks_mapping. */
- tracking_objects_copy(&tracking_dst->objects, &tracking_src->objects, tracks_mapping);
+ tracking_objects_copy(&tracking_dst->objects, &tracking_src->objects, tracks_mapping, flag);
/* Those remaining are runtime data, they will be reconstructed as needed, do not bother copying them. */
tracking_dst->dopesheet.ok = false;
diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c
index 9475925cdda..30981ed8f23 100644
--- a/source/blender/blenkernel/intern/tracking_auto.c
+++ b/source/blender/blenkernel/intern/tracking_auto.c
@@ -312,7 +312,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
int num_total_tracks = BLI_listbase_count(tracksbase);
context->tracks =
- MEM_callocN(sizeof(MovieTrackingTrack*) * num_total_tracks,
+ MEM_callocN(sizeof(MovieTrackingTrack *) * num_total_tracks,
"auto track pointers");
context->image_accessor =
@@ -381,7 +381,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
bool BKE_autotrack_context_step(AutoTrackContext *context)
{
- int frame_delta = context->backwards ? -1 : 1;
+ const int frame_delta = context->backwards ? -1 : 1;
bool ok = false;
int track;
@@ -395,67 +395,64 @@ bool BKE_autotrack_context_step(AutoTrackContext *context)
libmv_reference_marker,
libmv_tracked_marker;
libmv_TrackRegionResult libmv_result;
- int frame = BKE_movieclip_remap_scene_to_clip_frame(
- context->clips[options->clip_index],
- context->user.framenr);
- bool has_marker;
-
+ const int frame = BKE_movieclip_remap_scene_to_clip_frame(
+ context->clips[options->clip_index],
+ context->user.framenr);
BLI_spin_lock(&context->spin_lock);
- has_marker = libmv_autoTrackGetMarker(context->autotrack,
- options->clip_index,
- frame,
- options->track_index,
- &libmv_current_marker);
+ const bool has_marker = libmv_autoTrackGetMarker(context->autotrack,
+ options->clip_index,
+ frame,
+ options->track_index,
+ &libmv_current_marker);
BLI_spin_unlock(&context->spin_lock);
-
- if (has_marker) {
- if (!tracking_check_marker_margin(&libmv_current_marker,
- options->track->margin,
- context->frame_width,
- context->frame_height))
- {
- continue;
- }
-
- libmv_tracked_marker = libmv_current_marker;
- libmv_tracked_marker.frame = frame + frame_delta;
-
- if (options->use_keyframe_match) {
- libmv_tracked_marker.reference_frame =
- libmv_current_marker.reference_frame;
- libmv_autoTrackGetMarker(context->autotrack,
- options->clip_index,
- libmv_tracked_marker.reference_frame,
- options->track_index,
- &libmv_reference_marker);
- }
- else {
- libmv_tracked_marker.reference_frame = frame;
- libmv_reference_marker = libmv_current_marker;
- }
-
- if (libmv_autoTrackMarker(context->autotrack,
- &options->track_region_options,
- &libmv_tracked_marker,
- &libmv_result))
- {
- BLI_spin_lock(&context->spin_lock);
- libmv_autoTrackAddMarker(context->autotrack,
- &libmv_tracked_marker);
- BLI_spin_unlock(&context->spin_lock);
- }
- else {
- options->is_failed = true;
- options->failed_frame = frame + frame_delta;
- }
- ok = true;
+ /* Check whether we've got marker to sync with. */
+ if (!has_marker) {
+ continue;
+ }
+ /* Check whether marker is going outside of allowed frame margin. */
+ if (!tracking_check_marker_margin(&libmv_current_marker,
+ options->track->margin,
+ context->frame_width,
+ context->frame_height))
+ {
+ continue;
+ }
+ libmv_tracked_marker = libmv_current_marker;
+ libmv_tracked_marker.frame = frame + frame_delta;
+ /* Update reference frame. */
+ if (options->use_keyframe_match) {
+ libmv_tracked_marker.reference_frame =
+ libmv_current_marker.reference_frame;
+ libmv_autoTrackGetMarker(context->autotrack,
+ options->clip_index,
+ libmv_tracked_marker.reference_frame,
+ options->track_index,
+ &libmv_reference_marker);
}
+ else {
+ libmv_tracked_marker.reference_frame = frame;
+ libmv_reference_marker = libmv_current_marker;
+ }
+ /* Perform actual tracking. */
+ if (libmv_autoTrackMarker(context->autotrack,
+ &options->track_region_options,
+ &libmv_tracked_marker,
+ &libmv_result))
+ {
+ BLI_spin_lock(&context->spin_lock);
+ libmv_autoTrackAddMarker(context->autotrack, &libmv_tracked_marker);
+ BLI_spin_unlock(&context->spin_lock);
+ }
+ else {
+ options->is_failed = true;
+ options->failed_frame = frame + frame_delta;
+ }
+ ok = true;
}
-
+ /* Advance the frame. */
BLI_spin_lock(&context->spin_lock);
context->user.framenr += frame_delta;
BLI_spin_unlock(&context->spin_lock);
-
return ok;
}
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index a95399562d5..b1a092517de 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -58,6 +58,15 @@
#include "libmv-capi.h"
+/* Uncomment this to have caching-specific debug prints. */
+// #define DEBUG_CACHE
+
+#ifdef DEBUG_CACHE
+# define CACHE_PRINTF(...) printf(__VA_ARGS__)
+#else
+# define CACHE_PRINTF(...)
+#endif
+
/*********************** Tracks map *************************/
TracksMap *tracks_map_new(const char *object_name, bool is_camera, int num_tracks, int customdata_size)
@@ -523,6 +532,8 @@ typedef struct AccessCacheKey {
int frame;
int downscale;
libmv_InputMode input_mode;
+ bool has_region;
+ float region_min[2], region_max[2];
int64_t transform_key;
} AccessCacheKey;
@@ -537,23 +548,44 @@ static bool accesscache_hashcmp(const void *a_v, const void *b_v)
{
const AccessCacheKey *a = (const AccessCacheKey *) a_v;
const AccessCacheKey *b = (const AccessCacheKey *) b_v;
-
-#define COMPARE_FIELD(field)
- { \
- if (a->clip_index != b->clip_index) { \
- return false; \
- } \
- } (void) 0
-
- COMPARE_FIELD(clip_index);
- COMPARE_FIELD(frame);
- COMPARE_FIELD(downscale);
- COMPARE_FIELD(input_mode);
- COMPARE_FIELD(transform_key);
-
-#undef COMPARE_FIELD
-
- return true;
+ if (a->clip_index != b->clip_index ||
+ a->frame != b->frame ||
+ a->downscale != b->downscale ||
+ a->input_mode != b->input_mode ||
+ a->has_region != b->has_region ||
+ a->transform_key != b->transform_key)
+ {
+ return true;
+ }
+ /* If there is region applied, compare it. */
+ if (a->has_region) {
+ if (!equals_v2v2(a->region_min, b->region_min) ||
+ !equals_v2v2(a->region_max, b->region_max))
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+static void accesscache_construct_key(AccessCacheKey *key,
+ int clip_index,
+ int frame,
+ libmv_InputMode input_mode,
+ int downscale,
+ const libmv_Region *region,
+ int64_t transform_key)
+{
+ key->clip_index = clip_index;
+ key->frame = frame;
+ key->input_mode = input_mode;
+ key->downscale = downscale;
+ key->has_region = (region != NULL);
+ if (key->has_region) {
+ copy_v2_v2(key->region_min, region->min);
+ copy_v2_v2(key->region_max, region->max);
+ }
+ key->transform_key = transform_key;
}
static void accesscache_put(TrackingImageAccessor *accessor,
@@ -561,15 +593,13 @@ static void accesscache_put(TrackingImageAccessor *accessor,
int frame,
libmv_InputMode input_mode,
int downscale,
+ const libmv_Region *region,
int64_t transform_key,
ImBuf *ibuf)
{
AccessCacheKey key;
- key.clip_index = clip_index;
- key.frame = frame;
- key.input_mode = input_mode;
- key.downscale = downscale;
- key.transform_key = transform_key;
+ accesscache_construct_key(&key, clip_index, frame, input_mode, downscale,
+ region, transform_key);
IMB_moviecache_put(accessor->cache, &key, ibuf);
}
@@ -578,14 +608,12 @@ static ImBuf *accesscache_get(TrackingImageAccessor *accessor,
int frame,
libmv_InputMode input_mode,
int downscale,
+ const libmv_Region *region,
int64_t transform_key)
{
AccessCacheKey key;
- key.clip_index = clip_index;
- key.frame = frame;
- key.input_mode = input_mode;
- key.downscale = downscale;
- key.transform_key = transform_key;
+ accesscache_construct_key(&key, clip_index, frame, input_mode, downscale,
+ region, transform_key);
return IMB_moviecache_get(accessor->cache, &key);
}
@@ -674,29 +702,37 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
{
ImBuf *ibuf, *orig_ibuf, *final_ibuf;
int64_t transform_key = 0;
-
if (transform != NULL) {
transform_key = libmv_frameAccessorgetTransformKey(transform);
}
-
/* First try to get fully processed image from the cache. */
+ BLI_spin_lock(&accessor->cache_lock);
ibuf = accesscache_get(accessor,
clip_index,
frame,
input_mode,
downscale,
+ region,
transform_key);
+ BLI_spin_unlock(&accessor->cache_lock);
if (ibuf != NULL) {
+ CACHE_PRINTF("Used cached buffer for frame %d\n", frame);
+ /* This is a little heuristic here: if we re-used image once, this is
+ * a high probability of the image to be related to a keyframe matched
+ * reference image. Those images we don't want to be thrown away because
+ * if we toss them out we'll be re-calculating them at the next
+ * iteration.
+ */
+ ibuf->userflags |= IB_PERSISTENT;
return ibuf;
}
-
+ CACHE_PRINTF("Calculate new buffer for frame %d\n", frame);
/* And now we do postprocessing of the original frame. */
orig_ibuf = accessor_get_preprocessed_ibuf(accessor, clip_index, frame);
-
if (orig_ibuf == NULL) {
return NULL;
}
-
+ /* Cut a region if requested. */
if (region != NULL) {
int width = region->max[0] - region->min[0],
height = region->max[1] - region->min[1];
@@ -756,7 +792,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
BLI_unlock_thread(LOCK_MOVIECLIP);
final_ibuf = orig_ibuf;
}
-
+ /* Downscale if needed. */
if (downscale > 0) {
if (final_ibuf == orig_ibuf) {
final_ibuf = IMB_dupImBuf(orig_ibuf);
@@ -765,7 +801,7 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
orig_ibuf->x / (1 << downscale),
orig_ibuf->y / (1 << downscale));
}
-
+ /* Apply possible transformation. */
if (transform != NULL) {
libmv_FloatImage input_image, output_image;
ibuf_to_float_image(final_ibuf, &input_image);
@@ -778,12 +814,13 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
final_ibuf = float_image_to_ibuf(&output_image);
libmv_floatImageDestroy(&output_image);
}
-
+ /* Transform number of channels. */
if (input_mode == LIBMV_IMAGE_MODE_RGBA) {
BLI_assert(orig_ibuf->channels == 3 || orig_ibuf->channels == 4);
/* pass */
}
else /* if (input_mode == LIBMV_IMAGE_MODE_MONO) */ {
+ BLI_assert(input_mode == LIBMV_IMAGE_MODE_MONO);
if (final_ibuf->channels != 1) {
ImBuf *grayscale_ibuf = make_grayscale_ibuf_copy(final_ibuf);
if (final_ibuf != orig_ibuf) {
@@ -793,37 +830,24 @@ static ImBuf *accessor_get_ibuf(TrackingImageAccessor *accessor,
final_ibuf = grayscale_ibuf;
}
}
-
- /* it's possible processing still didn't happen at this point,
+ /* It's possible processing still didn't happen at this point,
* but we really need a copy of the buffer to be transformed
* and to be put to the cache.
*/
if (final_ibuf == orig_ibuf) {
final_ibuf = IMB_dupImBuf(orig_ibuf);
}
-
IMB_freeImBuf(orig_ibuf);
-
- /* We put postprocessed frame to the cache always for now,
- * not the smartest thing in the world, but who cares at this point.
- */
-
- /* TODO(sergey): Disable cache for now, because we don't store region
- * in the cache key and can't check whether cached version is usable for
- * us or not.
- *
- * Need to think better about what to cache and when.
- */
- if (false) {
- accesscache_put(accessor,
- clip_index,
- frame,
- input_mode,
- downscale,
- transform_key,
- final_ibuf);
- }
-
+ BLI_spin_lock(&accessor->cache_lock);
+ /* Put final buffer to cache. */
+ accesscache_put(accessor,
+ clip_index,
+ frame,
+ input_mode,
+ downscale,
+ region,
+ transform_key,
+ final_ibuf);
return final_ibuf;
}
@@ -876,7 +900,7 @@ static void accessor_release_image_callback(libmv_CacheKey cache_key)
}
static libmv_CacheKey accessor_get_mask_for_track_callback(
- libmv_FrameAccessorUserData* user_data,
+ libmv_FrameAccessorUserData *user_data,
int clip_index,
int frame,
int track_index,
@@ -958,6 +982,8 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR
accessor_get_mask_for_track_callback,
accessor_release_mask_callback);
+ BLI_spin_init(&accessor->cache_lock);
+
return accessor;
}
diff --git a/source/blender/blenkernel/intern/workspace.c b/source/blender/blenkernel/intern/workspace.c
index 82fface7d06..65eb08aba27 100644
--- a/source/blender/blenkernel/intern/workspace.c
+++ b/source/blender/blenkernel/intern/workspace.c
@@ -137,7 +137,7 @@ static bool UNUSED_FUNCTION(workspaces_is_screen_used)(
WorkSpace *BKE_workspace_add(Main *bmain, const char *name)
{
- WorkSpace *new_workspace = BKE_libblock_alloc(bmain, ID_WS, name);
+ WorkSpace *new_workspace = BKE_libblock_alloc(bmain, ID_WS, name, 0);
return new_workspace;
}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index 2adbdc83a36..cbe00e3bbc6 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -112,43 +112,59 @@ World *add_world(Main *bmain, const char *name)
{
World *wrld;
- wrld = BKE_libblock_alloc(bmain, ID_WO, name);
+ wrld = BKE_libblock_alloc(bmain, ID_WO, name, 0);
BKE_world_init(wrld);
return wrld;
}
-World *BKE_world_copy(Main *bmain, const World *wrld)
+/**
+ * Only copy internal data of World ID from source to already allocated/initialized destination.
+ * You probably nerver want to use that directly, use id_copy or BKE_id_copy_ex for typical needs.
+ *
+ * WARNING! This function will not handle ID user count!
+ *
+ * \param flag Copying options (see BKE_library.h's LIB_ID_COPY_... flags for more).
+ */
+void BKE_world_copy_data(Main *bmain, World *wrld_dst, const World *wrld_src, const int flag)
{
- World *wrldn;
- int a;
-
- wrldn = BKE_libblock_copy(bmain, &wrld->id);
-
- for (a = 0; a < MAX_MTEX; a++) {
- if (wrld->mtex[a]) {
- wrldn->mtex[a] = MEM_mallocN(sizeof(MTex), "BKE_world_copy");
- memcpy(wrldn->mtex[a], wrld->mtex[a], sizeof(MTex));
- id_us_plus((ID *)wrldn->mtex[a]->tex);
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (wrld_src->mtex[a]) {
+ wrld_dst->mtex[a] = MEM_dupallocN(wrld_src->mtex[a]);
}
}
- if (wrld->nodetree) {
- wrldn->nodetree = ntreeCopyTree(bmain, wrld->nodetree);
+ if (wrld_src->nodetree) {
+ BKE_id_copy_ex(bmain, (ID *)wrld_src->nodetree, (ID **)&wrld_dst->nodetree, flag, false);
}
-
- BKE_previewimg_id_copy(&wrldn->id, &wrld->id);
- BLI_listbase_clear(&wrldn->gpumaterial);
+ BLI_listbase_clear(&wrld_dst->gpumaterial);
- BKE_id_copy_ensure_local(bmain, &wrld->id, &wrldn->id);
+ if ((flag & LIB_ID_COPY_NO_PREVIEW) == 0) {
+ BKE_previewimg_id_copy(&wrld_dst->id, &wrld_src->id);
+ }
+ else {
+ wrld_dst->preview = NULL;
+ }
+}
- return wrldn;
+World *BKE_world_copy(Main *bmain, const World *wrld)
+{
+ World *wrld_copy;
+ BKE_id_copy_ex(bmain, &wrld->id, (ID **)&wrld_copy, 0, false);
+ return wrld_copy;
}
World *localize_world(World *wrld)
{
+ /* TODO replace with something like
+ * World *wrld_copy;
+ * BKE_id_copy_ex(bmain, &wrld->id, (ID **)&wrld_copy, LIB_ID_COPY_NO_MAIN | LIB_ID_COPY_NO_PREVIEW | LIB_ID_COPY_NO_USER_REFCOUNT, false);
+ * return wrld_copy;
+ *
+ * ... Once f*** nodes are fully converted to that too :( */
+
World *wrldn;
int a;
@@ -176,7 +192,7 @@ void BKE_world_make_local(Main *bmain, World *wrld, const bool lib_local)
BKE_id_make_local_generic(bmain, &wrld->id, true, lib_local);
}
-void BKE_world_eval(struct EvaluationContext *UNUSED(eval_ctx), World *world)
+void BKE_world_eval(const struct EvaluationContext *UNUSED(eval_ctx), World *world)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
printf("%s on %s (%p)\n", __func__, world->id.name, world);
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 156b74f5c3d..4a226dbda11 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -45,8 +45,8 @@
#include "BLI_blenlib.h"
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
-# include AUD_SPECIAL_H
+# include <AUD_Device.h>
+# include <AUD_Special.h>
#endif
#include "BLI_utildefines.h"
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index 1a68a1cac6a..07236fb2096 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -125,6 +125,7 @@ typedef struct TrackingImageAccessor {
int num_tracks;
int start_frame;
struct libmv_FrameAccessor *libmv_accessor;
+ SpinLock cache_lock;
} TrackingImageAccessor;
TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 8bf5c3da90d..72be3c05251 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -44,7 +44,7 @@ extern "C" {
#ifndef GHASH_INTERNAL_API
# ifdef __GNUC__
# undef _GHASH_INTERNAL_ATTR
-# define _GHASH_INTERNAL_ATTR __attribute__ ((deprecated))
+# define _GHASH_INTERNAL_ATTR __attribute__ ((deprecated)) /* not deprecated, just private. */
# endif
#endif
diff --git a/source/blender/blenlib/BLI_math_geom.h b/source/blender/blenlib/BLI_math_geom.h
index 0afb7aa9990..e1bccc2d0a2 100644
--- a/source/blender/blenlib/BLI_math_geom.h
+++ b/source/blender/blenlib/BLI_math_geom.h
@@ -166,8 +166,14 @@ void limit_dist_v3(float v1[3], float v2[3], const float dist);
int isect_seg_seg_v2(const float a1[2], const float a2[2], const float b1[2], const float b2[2]);
int isect_seg_seg_v2_int(const int a1[2], const int a2[2], const int b1[2], const int b2[2]);
-int isect_seg_seg_v2_point(const float v0[2], const float v1[2], const float v2[2], const float v3[2], float vi[2]);
-bool isect_seg_seg_v2_simple(const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
+int isect_seg_seg_v2_point_ex(
+ const float v0[2], const float v1[2], const float v2[2], const float v3[2], const float endpoint_bias,
+ float vi[2]);
+int isect_seg_seg_v2_point(
+ const float v0[2], const float v1[2], const float v2[2], const float v3[2],
+ float vi[2]);
+bool isect_seg_seg_v2_simple(
+ const float v1[2], const float v2[2], const float v3[2], const float v4[2]);
int isect_line_sphere_v3(const float l1[3], const float l2[3], const float sp[3], const float r, float r_p1[3], float r_p2[3]);
int isect_line_sphere_v2(const float l1[2], const float l2[2], const float sp[2], const float r, float r_p1[2], float r_p2[2]);
diff --git a/source/blender/blenlib/BLI_vfontdata.h b/source/blender/blenlib/BLI_vfontdata.h
index 8a7079b6c5f..0cd50319a33 100644
--- a/source/blender/blenlib/BLI_vfontdata.h
+++ b/source/blender/blenlib/BLI_vfontdata.h
@@ -52,8 +52,10 @@ typedef struct VChar {
} VChar;
VFontData *BLI_vfontdata_from_freetypefont(struct PackedFile *pf);
+VFontData *BLI_vfontdata_copy(const VFontData *vfont_src, const int flag);
VChar *BLI_vfontchar_from_freetypefont(struct VFont *vfont, unsigned long character);
+VChar *BLI_vfontchar_copy(const VChar *vchar_src, const int flag);
#endif
diff --git a/source/blender/blenlib/intern/BLI_memiter.c b/source/blender/blenlib/intern/BLI_memiter.c
index c86c26f578a..9c5f026f836 100644
--- a/source/blender/blenlib/intern/BLI_memiter.c
+++ b/source/blender/blenlib/intern/BLI_memiter.c
@@ -147,7 +147,7 @@ BLI_memiter *BLI_memiter_create(uint chunk_size_min)
chunk_size_min -= slop_space;
}
- mi->chunk_size_in_bytes_min = (offset_t)chunk_size_min;
+ mi->chunk_size_in_bytes_min = chunk_size_min;
return mi;
}
@@ -192,7 +192,7 @@ void *BLI_memiter_alloc(BLI_memiter *mi, uint elem_size)
BLI_assert(data_curr_next <= mi->data_last);
BLI_memiter_elem *elem = (BLI_memiter_elem *)mi->data_curr;
- elem->size = elem_size;
+ elem->size = (offset_t)elem_size;
mi->data_curr = data_curr_next;
#ifdef USE_TERMINATE_PARANOID
diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c
index 8719c92a2a6..e990f0b663c 100644
--- a/source/blender/blenlib/intern/freetypefont.c
+++ b/source/blender/blenlib/intern/freetypefont.c
@@ -481,6 +481,22 @@ VFontData *BLI_vfontdata_from_freetypefont(PackedFile *pf)
return vfd;
}
+static void *vfontdata_copy_characters_value_cb(const void *src)
+{
+ return BLI_vfontchar_copy(src, 0);
+}
+
+VFontData *BLI_vfontdata_copy(const VFontData *vfont_src, const int UNUSED(flag))
+{
+ VFontData *vfont_dst = MEM_dupallocN(vfont_src);
+
+ if (vfont_src->characters != NULL) {
+ vfont_dst->characters = BLI_ghash_copy(vfont_src->characters, NULL, vfontdata_copy_characters_value_cb);
+ }
+
+ return vfont_dst;
+}
+
VChar *BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character)
{
VChar *che = NULL;
@@ -503,6 +519,20 @@ VChar *BLI_vfontchar_from_freetypefont(VFont *vfont, unsigned long character)
return che;
}
+/* Yeah, this is very bad... But why is this in BLI in the first place, since it uses Nurb data?
+ * Anyway, do not feel like duplicating whole Nurb copy code here, so unless someone has a better idea... */
+#include "../../blenkernel/BKE_curve.h"
+
+VChar *BLI_vfontchar_copy(const VChar *vchar_src, const int UNUSED(flag))
+{
+ VChar *vchar_dst = MEM_dupallocN(vchar_src);
+
+ BLI_listbase_clear(&vchar_dst->nurbsbase);
+ BKE_nurbList_duplicate(&vchar_dst->nurbsbase, &vchar_src->nurbsbase);
+
+ return vchar_dst;
+}
+
#if 0
/* Freetype2 Outline struct */
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 7e26a99c93d..86045b40811 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -765,18 +765,29 @@ int isect_seg_seg_v2(const float v1[2], const float v2[2], const float v3[2], co
return ISECT_LINE_LINE_NONE;
}
-/* get intersection point of two 2D segments and return intersection type:
- * -1: collinear
- * 1: intersection
+/**
+ * Get intersection point of two 2D segments.
+ *
+ * \param endpoint_bias: Bias to use when testing for end-point overlap.
+ * A positive value considers intersections that extend past the endpoints,
+ * negative values contract the endpoints.
+ * Note the bias is applied to a 0-1 factor, not scaled to the length of segments.
+ *
+ * \returns intersection type:
+ * - -1: collinear.
+ * - 1: intersection.
+ * - 0: no intersection.
*/
-int isect_seg_seg_v2_point(
+int isect_seg_seg_v2_point_ex(
const float v0[2], const float v1[2],
const float v2[2], const float v3[2],
+ const float endpoint_bias,
float r_vi[2])
{
float s10[2], s32[2], s30[2], d;
const float eps = 1e-6f;
- const float eps_sq = eps * eps;
+ const float endpoint_min = -endpoint_bias;
+ const float endpoint_max = endpoint_bias + 1.0f;
sub_v2_v2v2(s10, v1, v0);
sub_v2_v2v2(s32, v3, v2);
@@ -790,8 +801,8 @@ int isect_seg_seg_v2_point(
u = cross_v2v2(s30, s32) / d;
v = cross_v2v2(s10, s30) / d;
- if ((u >= -eps && u <= 1.0f + eps) &&
- (v >= -eps && v <= 1.0f + eps))
+ if ((u >= endpoint_min && u <= endpoint_max) &&
+ (v >= endpoint_min && v <= endpoint_max))
{
/* intersection */
float vi_test[2];
@@ -810,7 +821,7 @@ int isect_seg_seg_v2_point(
sub_v2_v2v2(s_vi_v2, vi_test, v2);
v = (dot_v2v2(s32, s_vi_v2) / dot_v2v2(s32, s32));
#endif
- if (v >= -eps && v <= 1.0f + eps) {
+ if (v >= endpoint_min && v <= endpoint_max) {
copy_v2_v2(r_vi, vi_test);
return 1;
}
@@ -828,7 +839,7 @@ int isect_seg_seg_v2_point(
float u_a, u_b;
if (equals_v2v2(v0, v1)) {
- if (len_squared_v2v2(v2, v3) > eps_sq) {
+ if (len_squared_v2v2(v2, v3) > SQUARE(eps)) {
/* use non-point segment as basis */
SWAP(const float *, v0, v2);
SWAP(const float *, v1, v3);
@@ -855,7 +866,7 @@ int isect_seg_seg_v2_point(
if (u_a > u_b)
SWAP(float, u_a, u_b);
- if (u_a > 1.0f + eps || u_b < -eps) {
+ if (u_a > endpoint_max || u_b < endpoint_min) {
/* non-overlapping segments */
return -1;
}
@@ -871,6 +882,15 @@ int isect_seg_seg_v2_point(
}
}
+int isect_seg_seg_v2_point(
+ const float v0[2], const float v1[2],
+ const float v2[2], const float v3[2],
+ float r_vi[2])
+{
+ const float endpoint_bias = 1e-6f;
+ return isect_seg_seg_v2_point_ex(v0, v1, v2, v3, endpoint_bias, r_vi);
+}
+
bool isect_seg_seg_v2_simple(const float v1[2], const float v2[2], const float v3[2], const float v4[2])
{
#define CCW(A, B, C) \
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index c1d9777d555..336b7b58afe 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -650,7 +650,7 @@ static Main *blo_find_main(FileData *fd, const char *filepath, const char *relab
/* Add library datablock itself to 'main' Main, since libraries are **never** linked data.
* Fixes bug where you could end with all ID_LI datablocks having the same name... */
- lib = BKE_libblock_alloc(mainlist->first, ID_LI, "Lib");
+ lib = BKE_libblock_alloc(mainlist->first, ID_LI, "Lib", 0);
lib->id.us = ID_FAKE_USERS(lib); /* Important, consistency with main ID reading code from read_libblock(). */
BLI_strncpy(lib->name, filepath, sizeof(lib->name));
BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath));
diff --git a/source/blender/blenloader/intern/versioning_280.c b/source/blender/blenloader/intern/versioning_280.c
index 1c7ecc9ce3b..810bf5a3a46 100644
--- a/source/blender/blenloader/intern/versioning_280.c
+++ b/source/blender/blenloader/intern/versioning_280.c
@@ -433,30 +433,61 @@ void blo_do_versions_280(FileData *fd, Library *UNUSED(lib), Main *main)
}
{
- {
- /* Eevee shader nodes renamed because of the output node system.
- * Note that a new output node is not being added here, because it would be overkill
- * to handle this case in lib_verify_nodetree. */
- bool error = false;
- FOREACH_NODETREE(main, ntree, id) {
- if (ntree->type == NTREE_SHADER) {
- for (bNode *node = ntree->nodes.first; node; node = node->next) {
- if (node->type == SH_NODE_EEVEE_METALLIC && STREQ(node->idname, "ShaderNodeOutputMetallic")) {
- BLI_strncpy(node->idname, "ShaderNodeEeveeMetallic", sizeof(node->idname));
- error = true;
- }
+ typedef enum eNTreeDoVersionErrors {
+ NTREE_DOVERSION_NO_ERROR = 0,
+ NTREE_DOVERSION_NEED_OUTPUT = (1 << 0),
+ NTREE_DOVERSION_TRANSPARENCY_EMISSION = (1 << 1),
+ } eNTreeDoVersionErrors;
+
+ /* Eevee shader nodes renamed because of the output node system.
+ * Note that a new output node is not being added here, because it would be overkill
+ * to handle this case in lib_verify_nodetree.
+ *
+ * Also, metallic node is now unified into the principled node. */
+ eNTreeDoVersionErrors error = NTREE_DOVERSION_NO_ERROR;
+
+ FOREACH_NODETREE(main, ntree, id) {
+ if (ntree->type == NTREE_SHADER) {
+ for (bNode *node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ &&
+ STREQ(node->idname, "ShaderNodeOutputMetallic"))
+ {
+ BLI_strncpy(node->idname, "ShaderNodeEeveeMetallic", sizeof(node->idname));
+ error |= NTREE_DOVERSION_NEED_OUTPUT;
+ }
- if (node->type == SH_NODE_EEVEE_SPECULAR && STREQ(node->idname, "ShaderNodeOutputSpecular")) {
- BLI_strncpy(node->idname, "ShaderNodeEeveeSpecular", sizeof(node->idname));
- error = true;
- }
+ else if (node->type == SH_NODE_EEVEE_SPECULAR && STREQ(node->idname, "ShaderNodeOutputSpecular")) {
+ BLI_strncpy(node->idname, "ShaderNodeEeveeSpecular", sizeof(node->idname));
+ error |= NTREE_DOVERSION_NEED_OUTPUT;
+ }
+
+ else if (node->type == 196 /* SH_NODE_OUTPUT_EEVEE_MATERIAL */ &&
+ STREQ(node->idname, "ShaderNodeOutputEeveeMaterial"))
+ {
+ node->type = SH_NODE_OUTPUT_MATERIAL;
+ BLI_strncpy(node->idname, "ShaderNodeOutputMaterial", sizeof(node->idname));
+ }
+
+ else if (node->type == 194 /* SH_NODE_EEVEE_METALLIC */ &&
+ STREQ(node->idname, "ShaderNodeEeveeMetallic"))
+ {
+ node->type = SH_NODE_BSDF_PRINCIPLED;
+ BLI_strncpy(node->idname, "ShaderNodeBsdfPrincipled", sizeof(node->idname));
+ node->custom1 = SHD_GLOSSY_MULTI_GGX;
+ error |= NTREE_DOVERSION_TRANSPARENCY_EMISSION;
}
}
- } FOREACH_NODETREE_END
- if (error) {
- BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console");
- printf("You need to connect Eevee Metallic and Specular shader nodes to new material output nodes.\n");
}
+ } FOREACH_NODETREE_END
+
+ if (error & NTREE_DOVERSION_NEED_OUTPUT) {
+ BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console");
+ printf("You need to connect Principled and Eevee Specular shader nodes to new material output nodes.\n");
+ }
+
+ if (error & NTREE_DOVERSION_TRANSPARENCY_EMISSION) {
+ BKE_report(fd->reports, RPT_ERROR, "Eevee material conversion problem. Error in console");
+ printf("You need to combine transparency and emission shaders to the converted Principled shader nodes.\n");
}
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 10c202a0d19..7939d9107bc 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -3973,6 +3973,9 @@ static bool write_file_handle(
}
for (; id; id = id->next) {
+ /* We should never attempt to write non-regular IDs (i.e. all kind of temp/runtime ones). */
+ BLI_assert((id->tag & (LIB_TAG_NO_MAIN | LIB_TAG_NO_USER_REFCOUNT | LIB_TAG_NOT_ALLOCATED)) == 0);
+
switch ((ID_Type)GS(id->name)) {
case ID_WM:
write_windowmanager(wd, (wmWindowManager *)id);
diff --git a/source/blender/blentranslation/CMakeLists.txt b/source/blender/blentranslation/CMakeLists.txt
index c0dce5b4f0d..320a784ea25 100644
--- a/source/blender/blentranslation/CMakeLists.txt
+++ b/source/blender/blentranslation/CMakeLists.txt
@@ -61,4 +61,6 @@ endif()
blender_add_lib(bf_blentranslation "${SRC}" "${INC}" "${INC_SYS}")
-add_subdirectory(msgfmt)
+if(WITH_INTERNATIONAL)
+ add_subdirectory(msgfmt)
+endif()
diff --git a/source/blender/blentranslation/msgfmt/msgfmt.c b/source/blender/blentranslation/msgfmt/msgfmt.c
index 487d9fee7b4..3abce7b1d3f 100644
--- a/source/blender/blentranslation/msgfmt/msgfmt.c
+++ b/source/blender/blentranslation/msgfmt/msgfmt.c
@@ -160,7 +160,8 @@ static char **get_keys_sorted(GHash *messages, const uint32_t num_keys)
return keys;
}
-BLI_INLINE size_t uint32_to_bytes(const int value, char *bytes) {
+BLI_INLINE size_t uint32_to_bytes(const int value, char *bytes)
+{
size_t i;
for (i = 0; i < sizeof(value); i++) {
bytes[i] = (char) ((value >> ((int)i * 8)) & 0xff);
@@ -168,7 +169,8 @@ BLI_INLINE size_t uint32_to_bytes(const int value, char *bytes) {
return i;
}
-BLI_INLINE size_t msg_to_bytes(char *msg, char *bytes, uint32_t size) {
+BLI_INLINE size_t msg_to_bytes(char *msg, char *bytes, uint32_t size)
+{
/* Note that we also perform replacing of our NULLSEP placeholder by real NULL char... */
size_t i;
for (i = 0; i < size; i++, msg++, bytes++) {
@@ -452,7 +454,8 @@ static int make(const char *input_file_name, const char *output_file_name)
return EXIT_SUCCESS;
}
-int main(int argc, char **argv) {
+int main(int argc, char **argv)
+{
if (argc != 3) {
printf("Usage: %s <input.po> <output.mo>\n", argv[0]);
return EXIT_FAILURE;
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index e515f9af63f..1b35f049838 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -725,10 +725,30 @@ BLI_INLINE bool edge_isect_verts_point_2d(
const BMEdge *e, const BMVert *v_a, const BMVert *v_b,
float r_isect[2])
{
- return ((isect_seg_seg_v2_point(v_a->co, v_b->co, e->v1->co, e->v2->co, r_isect) == 1) &&
+ /* This bias seems like it could be too large,
+ * mostly its not needed, see T52329 for example where it is. */
+ const float endpoint_bias = 1e-4f;
+ return ((isect_seg_seg_v2_point_ex(v_a->co, v_b->co, e->v1->co, e->v2->co, endpoint_bias, r_isect) == 1) &&
((e->v1 != v_a) && (e->v2 != v_a) && (e->v1 != v_b) && (e->v2 != v_b)));
}
+BLI_INLINE int axis_pt_cmp(const float pt_a[2], const float pt_b[2])
+{
+ if (pt_a[0] < pt_b[0]) {
+ return -1;
+ }
+ if (pt_a[0] > pt_b[0]) {
+ return 1;
+ }
+ if (pt_a[1] < pt_b[1]) {
+ return -1;
+ }
+ if (pt_a[1] > pt_b[1]) {
+ return 1;
+ }
+ return 0;
+}
+
/**
* Represents isolated edge-links,
* each island owns contiguous slices of the vert array.
@@ -749,7 +769,8 @@ struct EdgeGroupIsland {
struct {
BMVert *min, *max;
/* used for sorting only */
- float min_axis;
+ float min_axis[2];
+ float max_axis[2];
} vert_span;
};
@@ -758,12 +779,11 @@ static int group_min_cmp_fn(const void *p1, const void *p2)
const struct EdgeGroupIsland *g1 = *(struct EdgeGroupIsland **)p1;
const struct EdgeGroupIsland *g2 = *(struct EdgeGroupIsland **)p2;
/* min->co[SORT_AXIS] hasn't been applied yet */
- const float f1 = g1->vert_span.min_axis;
- const float f2 = g2->vert_span.min_axis;
-
- if (f1 < f2) return -1;
- if (f1 > f2) return 1;
- else return 0;
+ int test = axis_pt_cmp(g1->vert_span.min_axis, g2->vert_span.min_axis);
+ if (UNLIKELY(test == 0)) {
+ test = axis_pt_cmp(g1->vert_span.max_axis, g2->vert_span.max_axis);
+ }
+ return test;
}
struct Edges_VertVert_BVHTreeTest {
@@ -993,8 +1013,8 @@ static int bm_face_split_edgenet_find_connection(
for (int j = 0; j < 2; j++) {
BMVert *v_iter = v_pair[j];
if (BM_elem_flag_test(v_iter, VERT_IS_VALID)) {
- if (direction_sign ? (v_iter->co[SORT_AXIS] >= v_origin->co[SORT_AXIS]) :
- (v_iter->co[SORT_AXIS] <= v_origin->co[SORT_AXIS]))
+ if (direction_sign ? (v_iter->co[SORT_AXIS] > v_origin->co[SORT_AXIS]) :
+ (v_iter->co[SORT_AXIS] < v_origin->co[SORT_AXIS]))
{
BLI_SMALLSTACK_PUSH(vert_search, v_iter);
BLI_SMALLSTACK_PUSH(vert_blacklist, v_iter);
@@ -1360,8 +1380,8 @@ bool BM_face_split_edgenet_connect_islands(
/* init with *any* different verts */
g->vert_span.min = ((BMEdge *)edge_links->link)->v1;
g->vert_span.max = ((BMEdge *)edge_links->link)->v2;
- float min_axis = FLT_MAX;
- float max_axis = -FLT_MAX;
+ float min_axis[2] = {FLT_MAX, FLT_MAX};
+ float max_axis[2] = {-FLT_MAX, -FLT_MAX};
do {
BMEdge *e = edge_links->link;
@@ -1372,24 +1392,29 @@ bool BM_face_split_edgenet_connect_islands(
BLI_assert(v_iter->head.htype == BM_VERT);
/* ideally we could use 'v_iter->co[SORT_AXIS]' here,
* but we need to sort the groups before setting the vertex array order */
+ const float axis_value[2] = {
#if SORT_AXIS == 0
- const float axis_value = dot_m3_v3_row_x(axis_mat, v_iter->co);
+ dot_m3_v3_row_x(axis_mat, v_iter->co),
+ dot_m3_v3_row_y(axis_mat, v_iter->co),
#else
- const float axis_value = dot_m3_v3_row_y(axis_mat, v_iter->co);
+ dot_m3_v3_row_y(axis_mat, v_iter->co),
+ dot_m3_v3_row_x(axis_mat, v_iter->co),
#endif
+ };
- if (axis_value < min_axis) {
+ if (axis_pt_cmp(axis_value, min_axis) == -1) {
g->vert_span.min = v_iter;
- min_axis = axis_value;
+ copy_v2_v2(min_axis, axis_value);
}
- if (axis_value > max_axis ) {
+ if (axis_pt_cmp(axis_value, max_axis) == 1) {
g->vert_span.max = v_iter;
- max_axis = axis_value;
+ copy_v2_v2(max_axis, axis_value);
}
}
} while ((edge_links = edge_links->next));
- g->vert_span.min_axis = min_axis;
+ copy_v2_v2(g->vert_span.min_axis, min_axis);
+ copy_v2_v2(g->vert_span.max_axis, max_axis);
g->has_prev_edge = false;
@@ -1449,8 +1474,10 @@ bool BM_face_split_edgenet_connect_islands(
bm->elem_index_dirty |= BM_VERT;
- /* Now create bvh tree*/
- BVHTree *bvhtree = BLI_bvhtree_new(edge_arr_len, 0.0f, 8, 8);
+ /* Now create bvh tree
+ *
+ * Note that a large epsilon is used because meshes with dimensions of around 100+ need it. see T52329. */
+ BVHTree *bvhtree = BLI_bvhtree_new(edge_arr_len, 1e-4f, 8, 8);
for (uint i = 0; i < edge_arr_len; i++) {
const float e_cos[2][3] = {
{UNPACK2(edge_arr[i]->v1->co), 0.0f},
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 92b65b94fb8..51a0fa4b2cc 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -4531,53 +4531,198 @@ static void set_profile_spacing(BevelParams *bp)
}
/*
- * Calculate and return an offset that is the lesser of the current
+ * Assume we have a situation like:
+ *
+ * a d
+ * \ /
+ * A \ / C
+ * \ th1 th2/
+ * b---------c
+ * B
+ *
+ * where edges are A, B, and C,
+ * following a face around vertices a, b, c, d;
+ * th1 is angle abc and th2 is angle bcd;
+ * and the argument EdgeHalf eb is B, going from b to c.
+ * In general case, edge offset specs for A, B, C have
+ * the form ka*t, kb*t, kc*t where ka, kb, kc are some factors
+ * (may be 0) and t is the current bp->offset.
+ * We want to calculate t at which the clone of B parallel
+ * to it collapses. This can be calculated using trig.
+ * Another case of geometry collision that can happen is
+ * When B slides along A because A is unbeveled.
+ * Then it might collide with a. Similarly for B sliding along C.
+ */
+static float geometry_collide_offset(BevelParams *bp, EdgeHalf *eb)
+{
+ EdgeHalf *ea, *ec, *ebother;
+ BevVert *bvc;
+ BMLoop *lb;
+ BMVert *va, *vb, *vc, *vd;
+ float ka, kb, kc, g, h, t, den, no_collide_offset, th1, th2, sin1, sin2, tan1, tan2, limit;
+
+ limit = no_collide_offset = bp->offset + 1e6;
+ if (bp->offset == 0.0f)
+ return no_collide_offset;
+ kb = eb->offset_l_spec;
+ ea = eb->next; /* note: this is in direction b --> a */
+ ka = ea->offset_r_spec;
+ if (eb->is_rev) {
+ vc = eb->e->v1;
+ vb = eb->e->v2;
+ }
+ else {
+ vb = eb->e->v1;
+ vc = eb->e->v2;
+ }
+ va = ea->is_rev ? ea->e->v1 : ea->e->v2;
+ bvc = NULL;
+ ebother = find_other_end_edge_half(bp, eb, &bvc);
+ if (ebother != NULL) {
+ ec = ebother->prev; /* note: this is in direction c --> d*/
+ vc = bvc->v;
+ kc = ec->offset_l_spec;
+ vd = ec->is_rev ? ec->e->v1 : ec->e->v2;
+ }
+ else {
+ /* No bevvert for w, so C can't be beveled */
+ kc = 0.0f;
+ ec = NULL;
+ /* Find an edge from c that has same face */
+ lb = BM_face_edge_share_loop(eb->fnext, eb->e);
+ if (!lb) {
+ return no_collide_offset;
+ }
+ if (lb->next->v == vc)
+ vd = lb->next->next->v;
+ else if (lb->v == vc)
+ vd = lb->prev->v;
+ else {
+ return no_collide_offset;
+ }
+ }
+ if (ea->e == eb->e || (ec && ec->e == eb->e))
+ return no_collide_offset;
+ ka = ka / bp->offset;
+ kb = kb / bp->offset;
+ kc = kc / bp->offset;
+ th1 = angle_v3v3v3(va->co, vb->co, vc->co);
+ th2 = angle_v3v3v3(vb->co, vc->co, vd->co);
+
+ /* First calculate offset at which edge B collapses, which happens
+ * when advancing clones of A, B, C all meet at a point.
+ * This only happens if at least two of those three edges have non-zero k's */
+ sin1 = sinf(th1);
+ sin2 = sinf(th2);
+ if ((ka > 0.0f) + (kb > 0.0f) + (kc > 0.0f) >= 2) {
+ tan1 = tanf(th1);
+ tan2 = tanf(th2);
+ g = tan1 * tan2;
+ h = sin1 * sin2;
+ den = g * (ka * sin2 + kc * sin1) + kb * h * (tan1 + tan2);
+ if (den != 0.0f) {
+ t = BM_edge_calc_length(eb->e);
+ t *= g * h / den;
+ if (t >= 0.0f)
+ limit = t;
+ }
+ }
+
+ /* Now check edge slide cases */
+ if (kb > 0.0f && ka == 0.0f /*&& bvb->selcount == 1 && bvb->edgecount > 2*/) {
+ t = BM_edge_calc_length(ea->e);
+ t *= sin1 / kb;
+ if (t >= 0.0f && t < limit)
+ limit = t;
+ }
+ if (kb > 0.0f && kc == 0.0f /* && bvc && ec && bvc->selcount == 1 && bvc->edgecount > 2 */) {
+ t = BM_edge_calc_length(ec->e);
+ t *= sin2 / kb;
+ if (t >= 0.0f && t < limit)
+ limit = t;
+ }
+ return limit;
+}
+
+/*
+ * We have an edge A between vertices a and b,
+ * where EdgeHalf ea is the half of A that starts at a.
+ * For vertex-only bevels, the new vertices slide from a at a rate ka*t
+ * and from b at a rate kb*t.
+ * We want to calculate the t at which the two meet.
+ */
+static float vertex_collide_offset(BevelParams *bp, EdgeHalf *ea)
+{
+ float limit, ka, kb, no_collide_offset, la, kab;
+ EdgeHalf *eb;
+
+ limit = no_collide_offset = bp->offset + 1e6;
+ if (bp->offset == 0.0f)
+ return no_collide_offset;
+ ka = ea->offset_l_spec / bp->offset;
+ eb = find_other_end_edge_half(bp, ea, NULL);
+ kb = eb ? eb->offset_l_spec / bp->offset : 0.0f;
+ kab = ka + kb;
+ la = BM_edge_calc_length(ea->e);
+ if (kab <= 0.0f)
+ return no_collide_offset;
+ limit = la / kab;
+ return limit;
+}
+
+/*
+ * Calculate an offset that is the lesser of the current
* bp.offset and the maximum possible offset before geometry
* collisions happen.
- * Currently this is a quick and dirty estimate of the max
- * possible: half the minimum edge length of any vertex involved
- * in a bevel. This is usually conservative.
- * The correct calculation is quite complicated.
- * TODO: implement this correctly.
+ * If the offset changes as a result of this, adjust the
+ * current edge offset specs to reflect this clamping,
+ * and store the new offset in bp.offset.
*/
-static float bevel_limit_offset(BMesh *bm, BevelParams *bp)
+static void bevel_limit_offset(BevelParams *bp)
{
- BMVert *v;
- BMEdge *e;
- BMIter v_iter, e_iter;
- float limited_offset, half_elen;
- bool vbeveled;
+ BevVert *bv;
+ EdgeHalf *eh;
+ GHashIterator giter;
+ float limited_offset, offset_factor, collision_offset;
+ int i;
limited_offset = bp->offset;
- if (bp->offset_type == BEVEL_AMT_PERCENT) {
- if (limited_offset > 50.0f)
- limited_offset = 50.0f;
- return limited_offset;
- }
- BM_ITER_MESH (v, &v_iter, bm, BM_VERTS_OF_MESH) {
- if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
+ GHASH_ITER(giter, bp->vert_hash) {
+ bv = BLI_ghashIterator_getValue(&giter);
+ for (i = 0; i < bv->edgecount; i++) {
+ eh = &bv->edges[i];
if (bp->vertex_only) {
- vbeveled = true;
+ collision_offset = vertex_collide_offset(bp, eh);
+ if (collision_offset < limited_offset)
+ limited_offset = collision_offset;
}
else {
- vbeveled = false;
- BM_ITER_ELEM (e, &e_iter, v, BM_EDGES_OF_VERT) {
- if (BM_elem_flag_test(BM_edge_other_vert(e, v), BM_ELEM_TAG)) {
- vbeveled = true;
- break;
- }
- }
+ collision_offset = geometry_collide_offset(bp, eh);
+ if (collision_offset < limited_offset)
+ limited_offset = collision_offset;
}
- if (vbeveled) {
- BM_ITER_ELEM (e, &e_iter, v, BM_EDGES_OF_VERT) {
- half_elen = 0.5f * BM_edge_calc_length(e);
- if (half_elen < limited_offset)
- limited_offset = half_elen;
- }
+ }
+ }
+
+ if (limited_offset < bp->offset) {
+ /* All current offset specs have some number times bp->offset,
+ * so we can just multiply them all by the reduction factor
+ * of the offset to have the effect of recalculating the specs
+ * with the new limited_offset.
+ */
+ offset_factor = limited_offset / bp->offset;
+ GHASH_ITER(giter, bp->vert_hash) {
+ bv = BLI_ghashIterator_getValue(&giter);
+ for (i = 0; i < bv->edgecount; i++) {
+ eh = &bv->edges[i];
+ eh->offset_l_spec *= offset_factor;
+ eh->offset_r_spec *= offset_factor;
+ eh->offset_l *= offset_factor;
+ eh->offset_r *= offset_factor;
}
}
+ bp->offset = limited_offset;
}
- return limited_offset;
}
/**
@@ -4604,6 +4749,7 @@ void BM_mesh_bevel(
BMEdge *e;
BevVert *bv;
BevelParams bp = {NULL};
+ GHashIterator giter;
bp.offset = offset;
bp.offset_type = offset_type;
@@ -4627,24 +4773,33 @@ void BM_mesh_bevel(
BLI_memarena_use_calloc(bp.mem_arena);
set_profile_spacing(&bp);
- if (limit_offset)
- bp.offset = bevel_limit_offset(bm, &bp);
-
/* Analyze input vertices, sorting edges and assigning initial new vertex positions */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
bv = bevel_vert_construct(bm, &bp, v);
- if (bv)
+ if (!limit_offset && bv)
build_boundary(&bp, bv, true);
}
}
+ /* Perhaps clamp offset to avoid geometry colliisions */
+ if (limit_offset) {
+ bevel_limit_offset(&bp);
+
+ /* Assign initial new vertex positions */
+ GHASH_ITER(giter, bp.vert_hash) {
+ bv = BLI_ghashIterator_getValue(&giter);
+ build_boundary(&bp, bv, true);
+ }
+ }
+
/* Perhaps do a pass to try to even out widths */
if (!bp.vertex_only) {
adjust_offsets(&bp);
}
/* Build the meshes around vertices, now that positions are final */
+ /* Note: could use GHASH_ITER over bp.vert_hash when backward compatibility no longer matters */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
bv = find_bevvert(&bp, v);
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index 42dde0be266..ffd11514ea0 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -34,7 +34,7 @@ void forEachObjectInExportSet(Scene *sce, Functor &f, LinkNode *export_set)
}
}
-bool AnimationExporter::exportAnimations(struct EvaluationContext *eval_ctx, Scene *sce)
+bool AnimationExporter::exportAnimations(const struct EvaluationContext *eval_ctx, Scene *sce)
{
bool has_animations = hasAnimations(sce);
if (has_animations) {
diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h
index d21f3a74ceb..5af5d884455 100644
--- a/source/blender/collada/AnimationExporter.h
+++ b/source/blender/collada/AnimationExporter.h
@@ -85,7 +85,7 @@ class AnimationExporter: COLLADASW::LibraryAnimations
{
private:
Scene *scene;
- struct EvaluationContext *eval_ctx;
+ const struct EvaluationContext *eval_ctx;
COLLADASW::StreamWriter *sw;
public:
@@ -95,7 +95,7 @@ public:
{ this->sw = sw; }
- bool exportAnimations(struct EvaluationContext *eval_ctx, Scene *sce);
+ bool exportAnimations(const struct EvaluationContext *eval_ctx, Scene *sce);
// called for each exported object
void operator() (Object *ob);
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index ad5ffadebc5..844be2dd60b 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -62,7 +62,7 @@ ArmatureExporter::ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSett
}
// write bone nodes
-void ArmatureExporter::add_armature_bones(EvaluationContext *eval_ctx, Object *ob_arm,
+void ArmatureExporter::add_armature_bones(const EvaluationContext *eval_ctx, Object *ob_arm,
Scene *sce, SceneExporter *se,
std::list<Object *>& child_objects)
{
@@ -157,7 +157,7 @@ void ArmatureExporter::find_objects_using_armature(Object *ob_arm, std::vector<O
#endif
// parent_mat is armature-space
-void ArmatureExporter::add_bone_node(EvaluationContext *eval_ctx, Bone *bone, Object *ob_arm, Scene *sce,
+void ArmatureExporter::add_bone_node(const EvaluationContext *eval_ctx, Bone *bone, Object *ob_arm, Scene *sce,
SceneExporter *se,
std::list<Object *>& child_objects)
{
diff --git a/source/blender/collada/ArmatureExporter.h b/source/blender/collada/ArmatureExporter.h
index f0582e97643..a3ed97c3a43 100644
--- a/source/blender/collada/ArmatureExporter.h
+++ b/source/blender/collada/ArmatureExporter.h
@@ -60,7 +60,7 @@ public:
ArmatureExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
// write bone nodes
- void add_armature_bones(struct EvaluationContext *eval_ctx, Object *ob_arm, Scene *sce, SceneExporter *se,
+ void add_armature_bones(const struct EvaluationContext *eval_ctx, Object *ob_arm, Scene *sce, SceneExporter *se,
std::list<Object *>& child_objects);
bool add_instance_controller(Object *ob);
@@ -85,7 +85,7 @@ private:
// Scene, SceneExporter and the list of child_objects
// are required for writing bone parented objects
- void add_bone_node(struct EvaluationContext *eval_ctx, Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se,
+ void add_bone_node(const struct EvaluationContext *eval_ctx, Bone *bone, Object *ob_arm, Scene *sce, SceneExporter *se,
std::list<Object *>& child_objects);
void add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node& node);
diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp
index 3dd2490edfc..f413651167c 100644
--- a/source/blender/collada/ControllerExporter.cpp
+++ b/source/blender/collada/ControllerExporter.cpp
@@ -104,7 +104,7 @@ bool ControllerExporter::add_instance_controller(Object *ob)
return true;
}
-void ControllerExporter::export_controllers(struct EvaluationContext *eval_ctx, Scene *sce)
+void ControllerExporter::export_controllers(const struct EvaluationContext *eval_ctx, Scene *sce)
{
this->eval_ctx = eval_ctx;
scene = sce;
diff --git a/source/blender/collada/ControllerExporter.h b/source/blender/collada/ControllerExporter.h
index c96015c7817..a1d46c5aafb 100644
--- a/source/blender/collada/ControllerExporter.h
+++ b/source/blender/collada/ControllerExporter.h
@@ -66,12 +66,12 @@ public:
bool add_instance_controller(Object *ob);
- void export_controllers(struct EvaluationContext *eval_ctx, Scene *sce);
+ void export_controllers(const struct EvaluationContext *eval_ctx, Scene *sce);
void operator()(Object *ob);
private:
- struct EvaluationContext *eval_ctx;
+ const struct EvaluationContext *eval_ctx;
Scene *scene;
UnitConverter converter;
const ExportSettings *export_settings;
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index 46628ed028e..24a09562a7b 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -179,7 +179,7 @@ static COLLADABU::NativeString make_temp_filepath(const char *name, const char *
// COLLADA allows this through multiple <channel>s in <animation>.
// For this to work, we need to know objects that use a certain action.
-int DocumentExporter::exportCurrentScene(EvaluationContext *eval_ctx, Scene *sce)
+int DocumentExporter::exportCurrentScene(const EvaluationContext *eval_ctx, Scene *sce)
{
PointerRNA sceneptr, unit_settings;
PropertyRNA *system; /* unused , *scale; */
diff --git a/source/blender/collada/DocumentExporter.h b/source/blender/collada/DocumentExporter.h
index 1d32c87610e..895787c7bbc 100644
--- a/source/blender/collada/DocumentExporter.h
+++ b/source/blender/collada/DocumentExporter.h
@@ -39,7 +39,7 @@ class DocumentExporter
{
public:
DocumentExporter(const ExportSettings *export_settings);
- int exportCurrentScene(struct EvaluationContext *eval_ctx, Scene *sce);
+ int exportCurrentScene(const struct EvaluationContext *eval_ctx, Scene *sce);
void exportScenes(const char *filename);
private:
const ExportSettings *export_settings;
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index 715f0ab5370..4365c70b910 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -57,7 +57,7 @@ GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSett
{
}
-void GeometryExporter::exportGeom(struct EvaluationContext *eval_ctx, Scene *sce)
+void GeometryExporter::exportGeom(const struct EvaluationContext *eval_ctx, Scene *sce)
{
openLibrary();
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index 91062ef8f19..7527195fdd8 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -74,13 +74,13 @@ class GeometryExporter : COLLADASW::LibraryGeometries
Normal n;
- struct EvaluationContext *mEvalCtx;
+ const struct EvaluationContext *mEvalCtx;
Scene *mScene;
public:
GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
- void exportGeom(struct EvaluationContext *eval_ctx, Scene *sce);
+ void exportGeom(const struct EvaluationContext *eval_ctx, Scene *sce);
void operator()(Object *ob);
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index 1447cd7f72f..aa98f2ee96c 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -43,7 +43,7 @@ void SceneExporter::setExportTransformationType(BC_export_transformation_type tr
this->transformation_type = transformation_type;
}
-void SceneExporter::exportScene(EvaluationContext *eval_ctx, Scene *sce)
+void SceneExporter::exportScene(const EvaluationContext *eval_ctx, Scene *sce)
{
// <library_visual_scenes> <visual_scene>
std::string id_naming = id_name(sce);
@@ -53,7 +53,7 @@ void SceneExporter::exportScene(EvaluationContext *eval_ctx, Scene *sce)
closeLibrary();
}
-void SceneExporter::exportHierarchy(EvaluationContext *eval_ctx, Scene *sce)
+void SceneExporter::exportHierarchy(const EvaluationContext *eval_ctx, Scene *sce)
{
LinkNode *node;
std::vector<Object *> base_objects;
@@ -91,7 +91,7 @@ void SceneExporter::exportHierarchy(EvaluationContext *eval_ctx, Scene *sce)
}
-void SceneExporter::writeNodes(EvaluationContext *eval_ctx, Object *ob, Scene *sce)
+void SceneExporter::writeNodes(const EvaluationContext *eval_ctx, Object *ob, Scene *sce)
{
// Add associated armature first if available
bool armature_exported = false;
diff --git a/source/blender/collada/SceneExporter.h b/source/blender/collada/SceneExporter.h
index 8dd6da4db05..ded48983bd9 100644
--- a/source/blender/collada/SceneExporter.h
+++ b/source/blender/collada/SceneExporter.h
@@ -96,15 +96,15 @@ class SceneExporter: COLLADASW::LibraryVisualScenes, protected TransformWriter,
{
public:
SceneExporter(COLLADASW::StreamWriter *sw, ArmatureExporter *arm, const ExportSettings *export_settings);
- void exportScene(struct EvaluationContext *eval_ctx, Scene *sce);
+ void exportScene(const struct EvaluationContext *eval_ctx, Scene *sce);
void setExportTransformationType(BC_export_transformation_type transformation_type);
private:
BC_export_transformation_type transformation_type;
// required for writeNodes() for bone-parented objects
friend class ArmatureExporter;
- void exportHierarchy(struct EvaluationContext *eval_ctx, Scene *sce);
- void writeNodes(struct EvaluationContext *eval_ctx, Object *ob, Scene *sce);
+ void exportHierarchy(const struct EvaluationContext *eval_ctx, Scene *sce);
+ void writeNodes(const struct EvaluationContext *eval_ctx, Object *ob, Scene *sce);
ArmatureExporter *arm_exporter;
const ExportSettings *export_settings;
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index 5c5b2ec2dc2..e9285bf24ff 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -67,7 +67,7 @@ int collada_import(bContext *C,
return 0;
}
-int collada_export(EvaluationContext *eval_ctx,
+int collada_export(const EvaluationContext *eval_ctx,
Scene *sce,
SceneLayer *scene_layer,
const char *filepath,
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index c42338002cd..1cec6a53922 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -64,7 +64,7 @@ int collada_import(struct bContext *C,
int keep_bind_info);
-int collada_export(struct EvaluationContext *eval_ctx,
+int collada_export(const struct EvaluationContext *eval_ctx,
struct Scene *sce,
struct SceneLayer *scene_layer,
const char *filepath,
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index 85ac0eb8d3d..3bdd22a53f8 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -147,7 +147,7 @@ Object *bc_add_object(Scene *scene, int type, const char *name)
return ob;
}
-Mesh *bc_get_mesh_copy(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate)
+Mesh *bc_get_mesh_copy(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate)
{
Mesh *tmpmesh;
CustomDataMask mask = CD_MASK_MESH;
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index df972c5b89c..75e9fb5dcea 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -68,7 +68,7 @@ extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsi
extern int bc_test_parent_loop(Object *par, Object *ob);
extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space = true);
extern Object *bc_add_object(Scene *scene, int type, const char *name);
-extern Mesh *bc_get_mesh_copy(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate);
+extern Mesh *bc_get_mesh_copy(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate);
extern Object *bc_get_assigned_armature(Object *ob);
extern Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 81bb8454976..b8aeaac64a1 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -198,6 +198,7 @@ IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id, bool do_tag)
}
#else
IDDepsNode *id_node = m_graph->add_id_node(id);
+ UNUSED_VARS(do_tag);
#endif
return id_node;
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 861aa9521c0..d3304109673 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -932,16 +932,20 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
const short id_type = GS(id->name);
- /* create dependency between driver and data affected by it */
+ /* Create dependency between driver and data affected by it. */
/* - direct property relationship... */
//RNAPathKey affected_key(id, fcu->rna_path);
//add_relation(driver_key, affected_key, "[Driver -> Data] DepsRel");
- /* driver -> data components (for interleaved evaluation - bones/constraints/modifiers) */
- // XXX: this probably should probably be moved out into a separate function
+ /* Driver -> data components (for interleaved evaluation
+ * bones/constraints/modifiers).
+ */
+ // XXX: this probably should probably be moved out into a separate function.
if (strstr(rna_path, "pose.bones[") != NULL) {
/* interleaved drivers during bone eval */
- // TODO: ideally, if this is for a constraint, it goes to said constraint
+ /* TODO: ideally, if this is for a constraint, it goes to said
+ * constraint.
+ */
Object *ob = (Object *)id;
char *bone_name = BLI_str_quoted_substrN(rna_path, "pose.bones[");
pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
@@ -991,7 +995,7 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
}
}
}
- /* Free temp data/ */
+ /* Free temp data. */
MEM_freeN(bone_name);
bone_name = NULL;
}
@@ -1056,25 +1060,30 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
}
}
}
-
- /* ensure that affected prop's update callbacks will be triggered once done */
- // TODO: implement this once the functionality to add these links exists in RNA
- // XXX: the data itself could also set this, if it were to be truly initialised later?
-
- /* loop over variables to get the target relationships */
+ /* Ensure that affected prop's update callbacks will be triggered once
+ * done.
+ */
+ /* TODO: Implement this once the functionality to add these links exists
+ * RNA.
+ */
+ /* XXX: the data itself could also set this, if it were to be truly
+ * initialised later?
+ */
+ /* Loop over variables to get the target relationships. */
LINKLIST_FOREACH (DriverVar *, dvar, &driver->variables) {
- /* only used targets */
+ /* Only used targets. */
DRIVER_TARGETS_USED_LOOPER(dvar)
{
- if (dtar->id == NULL)
+ if (dtar->id == NULL) {
continue;
-
- /* special handling for directly-named bones */
+ }
+ /* Special handling for directly-named bones. */
if ((dtar->flag & DTAR_FLAG_STRUCT_REF) && (dtar->pchan_name[0])) {
Object *ob = (Object *)dtar->id;
- bPoseChannel *target_pchan = BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
+ bPoseChannel *target_pchan =
+ BKE_pose_channel_find_name(ob->pose, dtar->pchan_name);
if (target_pchan != NULL) {
- /* get node associated with bone */
+ /* Get node associated with bone. */
// XXX: watch the space!
/* Some cases can't use final bone transform, for example:
* - Driving the bone with itself (addressed here)
@@ -1086,55 +1095,75 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
{
continue;
}
- OperationKey target_key(dtar->id, DEG_NODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_DONE);
- add_relation(target_key, driver_key, "[Bone Target -> Driver]");
+ OperationKey target_key(dtar->id,
+ DEG_NODE_TYPE_BONE,
+ target_pchan->name,
+ DEG_OPCODE_BONE_DONE);
+ add_relation(target_key,
+ driver_key,
+ "[Bone Target -> Driver]");
}
}
else if (dtar->flag & DTAR_FLAG_STRUCT_REF) {
- /* get node associated with the object's transforms */
- OperationKey target_key(dtar->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
+ /* Get node associated with the object's transforms. */
+ if (dtar->id == id) {
+ /* Ignore input dependency if we're driving properties of
+ * the same ID, otherwise we'll be ending up in a cyclic
+ * dependency here.
+ */
+ continue;
+ }
+ OperationKey target_key(dtar->id,
+ DEG_NODE_TYPE_TRANSFORM,
+ DEG_OPCODE_TRANSFORM_FINAL);
add_relation(target_key, driver_key, "[Target -> Driver]");
}
else if (dtar->rna_path && strstr(dtar->rna_path, "pose.bones[")) {
- /* workaround for ensuring that local bone transforms don't end up
- * having to wait for pose eval to finish (to prevent cycles)
+ /* Workaround for ensuring that local bone transforms don't end
+ * up having to wait for pose eval to finish (to prevent cycles).
*/
Object *ob = (Object *)dtar->id;
- char *bone_name = BLI_str_quoted_substrN(dtar->rna_path, "pose.bones[");
- bPoseChannel *target_pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- if (bone_name) {
+ char *bone_name = BLI_str_quoted_substrN(dtar->rna_path,
+ "pose.bones[");
+ bPoseChannel *target_pchan =
+ BKE_pose_channel_find_name(ob->pose, bone_name);
+ if (bone_name != NULL) {
MEM_freeN(bone_name);
bone_name = NULL;
}
- if (target_pchan) {
+ if (target_pchan != NULL) {
if (dtar->id == id &&
pchan != NULL &&
STREQ(pchan->name, target_pchan->name))
{
continue;
}
- OperationKey bone_key(dtar->id, DEG_NODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_LOCAL);
+ OperationKey bone_key(dtar->id,
+ DEG_NODE_TYPE_BONE,
+ target_pchan->name,
+ DEG_OPCODE_BONE_LOCAL);
add_relation(bone_key, driver_key, "[RNA Bone -> Driver]");
}
}
else {
if (dtar->id == id) {
- /* Ignore input dependency if we're driving properties of the same ID,
- * otherwise we'll be ending up in a cyclic dependency here.
+ /* Ignore input dependency if we're driving properties of
+ * the same ID, otherwise we'll be ending up in a cyclic
+ * dependency here.
*/
continue;
}
- /* resolve path to get node */
- RNAPathKey target_key(dtar->id, dtar->rna_path ? dtar->rna_path : "");
+ /* Resolve path to get node. */
+ RNAPathKey target_key(dtar->id,
+ dtar->rna_path ? dtar->rna_path : "");
add_relation(target_key, driver_key, "[RNA Target -> Driver]");
}
}
DRIVER_TARGETS_LOOPER_END
}
-
- /* It's quite tricky to detect if the driver actually depends on time or not,
- * so for now we'll be quite conservative here about optimization and consider
- * all python drivers to be depending on time.
+ /* It's quite tricky to detect if the driver actually depends on time or
+ * not, so for now we'll be quite conservative here about optimization and
+ * consider all python drivers to be depending on time.
*/
if ((driver->type == DRIVER_TYPE_PYTHON) &&
python_driver_depends_on_time(driver))
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 0dd3cfaa783..7d0ac47e6fd 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -222,7 +222,7 @@ void DEG_objects_iterator_next(BLI_Iterator *iter)
/* Make sure we have the base collection settings is already populated.
* This will fail when BKE_layer_eval_layer_collection_pre hasn't run yet
- * Which usually means a missing call to DAG_id_tag_update(). */
+ * Which usually means a missing call to DEG_id_tag_update(). */
BLI_assert(!BLI_listbase_is_empty(&base->collection_properties->data.group));
/* Flushing depsgraph data. */
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
index 3ed93ea5677..3184c7c9066 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_copy_on_write.cc
@@ -279,21 +279,6 @@ bool id_copy_no_main(const ID *id, ID **newid)
return result;
}
-void layer_collections_sync_flags(ListBase *layer_collections_dst,
- const ListBase *layer_collections_src)
-{
- LayerCollection *layer_collection_dst = (LayerCollection *)layer_collections_dst->first;
- const LayerCollection *layer_collection_src = (const LayerCollection *)layer_collections_src->first;
- while (layer_collection_dst != NULL) {
- layer_collection_dst->flag = layer_collection_src->flag;
- layer_collections_sync_flags(&layer_collection_dst->layer_collections,
- &layer_collection_src->layer_collections);
- /* TODO(sergey): Overrides. */
- layer_collection_dst = layer_collection_dst->next;
- layer_collection_src = layer_collection_src->next;
- }
-}
-
/* Similar to BKE_scene_copy() but does not require main.
*
* TODO(sergey): Get rid of this once T51804 is handled.
@@ -316,18 +301,6 @@ Scene *scene_copy_no_main(Scene *scene)
(Scene *)id_for_copy,
SCE_COPY_LINK_OB);
- /* TODO(sergey): Make this part of BKE_scene_copy(). */
- {
- SceneLayer *new_scene_layer = (SceneLayer *)new_scene->render_layers.first;
- const SceneLayer *scene_layer = (const SceneLayer *)scene->render_layers.first;
- while (new_scene_layer != NULL) {
- layer_collections_sync_flags(&new_scene_layer->layer_collections,
- &scene_layer->layer_collections);
- new_scene_layer = new_scene_layer->next;
- scene_layer = scene_layer->next;
- }
- }
-
#ifdef NESTED_ID_NASTY_WORKAROUND
nested_id_hack_restore_pointers(&scene->id, &new_scene->id);
#endif
@@ -918,7 +891,7 @@ void deg_free_copy_on_write_datablock(ID *id_cow)
return;
}
}
- BKE_libblock_free_datablock(id_cow);
+ BKE_libblock_free_datablock(id_cow, 0);
BKE_libblock_free_data(id_cow, false);
/* Signal datablock as not being expanded. */
id_cow->name[0] = '\0';
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc
index cc305665594..0f28be1aaf4 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node.cc
@@ -201,6 +201,7 @@ void IDDepsNode::init_copy_on_write(ID *id_cow_hint)
id_cow = id_orig;
}
#else
+ UNUSED_VARS(id_cow_hint);
id_cow = id_orig;
#endif
}
diff --git a/source/blender/draw/CMakeLists.txt b/source/blender/draw/CMakeLists.txt
index 5b39779035d..c5ae2dadd6c 100644
--- a/source/blender/draw/CMakeLists.txt
+++ b/source/blender/draw/CMakeLists.txt
@@ -146,6 +146,8 @@ data_to_c_simple(engines/eevee/shaders/effect_dof_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_geom.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_dof_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_downsample_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_downsample_cube_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/effect_gtao_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_motion_blur_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/effect_ssr_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl SRC)
@@ -160,6 +162,7 @@ data_to_c_simple(engines/eevee/shaders/shadow_store_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_store_geom.glsl SRC)
data_to_c_simple(engines/eevee/shaders/shadow_store_vert.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_lut_frag.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/btdf_lut_frag.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_direct_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_common_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/irradiance_lib.glsl SRC)
@@ -167,6 +170,7 @@ data_to_c_simple(engines/eevee/shaders/octahedron_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/bsdf_sampling_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/raytrace_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/ltc_lib.glsl SRC)
+data_to_c_simple(engines/eevee/shaders/ssr_lib.glsl SRC)
data_to_c_simple(engines/eevee/shaders/volumetric_frag.glsl SRC)
data_to_c_simple(modes/shaders/common_globals_lib.glsl SRC)
diff --git a/source/blender/draw/engines/clay/clay_engine.c b/source/blender/draw/engines/clay/clay_engine.c
index a9192a30412..44178f66563 100644
--- a/source/blender/draw/engines/clay/clay_engine.c
+++ b/source/blender/draw/engines/clay/clay_engine.c
@@ -326,7 +326,7 @@ static struct GPUTexture *create_jitter_texture(int num_samples)
jitter[i][2] = bn * num_samples_inv;
}
- UNUSED_VARS(bsdf_split_sum_ggx, ltc_mag_ggx, ltc_mat_ggx);
+ UNUSED_VARS(bsdf_split_sum_ggx, btdf_split_sum_ggx, ltc_mag_ggx, ltc_mat_ggx);
return DRW_texture_create_2D(64, 64, DRW_TEX_RGB_16, DRW_TEX_FILTER | DRW_TEX_WRAP, &jitter[0][0]);
}
diff --git a/source/blender/draw/engines/eevee/eevee_effects.c b/source/blender/draw/engines/eevee/eevee_effects.c
index 7592e5c08d9..0f61b6e967c 100644
--- a/source/blender/draw/engines/eevee/eevee_effects.c
+++ b/source/blender/draw/engines/eevee/eevee_effects.c
@@ -98,12 +98,19 @@ static struct {
/* Simple Downsample */
struct GPUShader *downsample_sh;
+ struct GPUShader *downsample_cube_sh;
+
+ /* Ground Truth Ambient Occlusion */
+ struct GPUShader *gtao_sh;
+ struct GPUShader *gtao_debug_sh;
struct GPUTexture *depth_src;
struct GPUTexture *color_src;
int depth_src_layer;
+ float cube_texel_size;
} e_data = {NULL}; /* Engine data */
+extern char datatoc_ambient_occlusion_lib_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
@@ -115,7 +122,11 @@ extern char datatoc_effect_dof_vert_glsl[];
extern char datatoc_effect_dof_geom_glsl[];
extern char datatoc_effect_dof_frag_glsl[];
extern char datatoc_effect_downsample_frag_glsl[];
+extern char datatoc_effect_downsample_cube_frag_glsl[];
+extern char datatoc_effect_gtao_frag_glsl[];
extern char datatoc_lightprobe_lib_glsl[];
+extern char datatoc_lightprobe_vert_glsl[];
+extern char datatoc_lightprobe_geom_glsl[];
extern char datatoc_raytrace_lib_glsl[];
extern char datatoc_tonemap_frag_glsl[];
extern char datatoc_volumetric_frag_glsl[];
@@ -229,7 +240,22 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
/* Shaders */
if (!e_data.motion_blur_sh) {
+ DynStr *ds_frag = BLI_dynstr_new();
+ BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_ambient_occlusion_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_effect_gtao_frag_glsl);
+ char *frag_str = BLI_dynstr_get_cstring(ds_frag);
+ BLI_dynstr_free(ds_frag);
+
+ e_data.gtao_sh = DRW_shader_create_fullscreen(frag_str, NULL);
+ e_data.gtao_debug_sh = DRW_shader_create_fullscreen(frag_str, "#define DEBUG_AO\n");
+
+ MEM_freeN(frag_str);
+
e_data.downsample_sh = DRW_shader_create_fullscreen(datatoc_effect_downsample_frag_glsl, NULL);
+ e_data.downsample_cube_sh = DRW_shader_create(datatoc_lightprobe_vert_glsl,
+ datatoc_lightprobe_geom_glsl,
+ datatoc_effect_downsample_cube_frag_glsl, NULL);
e_data.volumetric_upsample_sh = DRW_shader_create_fullscreen(datatoc_volumetric_frag_glsl, "#define STEP_UPSAMPLE\n");
@@ -340,7 +366,9 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
float threshold = BKE_collection_engine_property_value_get_float(props, "bloom_threshold");
float knee = BKE_collection_engine_property_value_get_float(props, "bloom_knee");
float intensity = BKE_collection_engine_property_value_get_float(props, "bloom_intensity");
+ const float *color = BKE_collection_engine_property_value_get_float_array(props, "bloom_color");
float radius = BKE_collection_engine_property_value_get_float(props, "bloom_radius");
+ effects->bloom_clamp = BKE_collection_engine_property_value_get_float(props, "bloom_clamp");
/* determine the iteration count */
const float minDim = (float)MIN2(blitsize[0], blitsize[1]);
@@ -354,7 +382,8 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
effects->bloom_curve_threshold[1] = knee * 2.0f;
effects->bloom_curve_threshold[2] = 0.25f / max_ff(1e-5f, knee);
effects->bloom_curve_threshold[3] = threshold;
- effects->bloom_intensity = intensity;
+
+ mul_v3_v3fl(effects->bloom_color, color, intensity);
/* Downsample buffers */
copy_v2_v2_int(texsize, blitsize);
@@ -479,11 +508,68 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
&tex, 1);
}
- {
+ if (BKE_collection_engine_property_value_get_bool(props, "gtao_enable")) {
/* Ambient Occlusion*/
- stl->effects->ao_dist = BKE_collection_engine_property_value_get_float(props, "gtao_distance");
- stl->effects->ao_samples = BKE_collection_engine_property_value_get_int(props, "gtao_samples");
- stl->effects->ao_factor = BKE_collection_engine_property_value_get_float(props, "gtao_factor");
+ effects->enabled_effects |= EFFECT_GTAO;
+
+ effects->ao_dist = BKE_collection_engine_property_value_get_float(props, "gtao_distance");
+ effects->ao_factor = BKE_collection_engine_property_value_get_float(props, "gtao_factor");
+ effects->ao_quality = 1.0f - BKE_collection_engine_property_value_get_float(props, "gtao_quality");
+ effects->ao_samples = BKE_collection_engine_property_value_get_int(props, "gtao_samples");
+ effects->ao_samples_inv = 1.0f / effects->ao_samples;
+
+ effects->ao_settings = 1.0; /* USE_AO */
+ if (BKE_collection_engine_property_value_get_bool(props, "gtao_use_bent_normals")) {
+ effects->ao_settings += 2.0; /* USE_BENT_NORMAL */
+ }
+ if (BKE_collection_engine_property_value_get_bool(props, "gtao_denoise")) {
+ effects->ao_settings += 4.0; /* USE_DENOISE */
+ }
+
+ effects->ao_offset = 0.0f;
+ effects->ao_bounce_fac = (float)BKE_collection_engine_property_value_get_bool(props, "gtao_bounce");
+
+ effects->ao_texsize[0] = ((int)viewport_size[0]);
+ effects->ao_texsize[1] = ((int)viewport_size[1]);
+
+ /* Round up to multiple of 2 */
+ if ((effects->ao_texsize[0] & 0x1) != 0) {
+ effects->ao_texsize[0] += 1;
+ }
+ if ((effects->ao_texsize[1] & 0x1) != 0) {
+ effects->ao_texsize[1] += 1;
+ }
+
+ CLAMP(effects->ao_samples, 1, 32);
+
+ if (effects->hori_tex_layers != effects->ao_samples) {
+ DRW_TEXTURE_FREE_SAFE(txl->gtao_horizons);
+ }
+
+ if (txl->gtao_horizons == NULL) {
+ effects->hori_tex_layers = effects->ao_samples;
+ txl->gtao_horizons = DRW_texture_create_2D_array((int)viewport_size[0], (int)viewport_size[1], effects->hori_tex_layers, DRW_TEX_RG_8, 0, NULL);
+ }
+
+ DRWFboTexture tex = {&txl->gtao_horizons, DRW_TEX_RG_8, 0};
+
+ DRW_framebuffer_init(&fbl->gtao_fb, &draw_engine_eevee_type,
+ effects->ao_texsize[0], effects->ao_texsize[1],
+ &tex, 1);
+
+ if (G.debug_value == 6) {
+ DRWFboTexture tex_debug = {&stl->g_data->gtao_horizons_debug, DRW_TEX_RGBA_8, DRW_TEX_TEMP};
+
+ DRW_framebuffer_init(&fbl->gtao_debug_fb, &draw_engine_eevee_type,
+ (int)viewport_size[0], (int)viewport_size[1],
+ &tex_debug, 1);
+ }
+ }
+ else {
+ /* Cleanup */
+ DRW_TEXTURE_FREE_SAFE(txl->gtao_horizons);
+ DRW_FRAMEBUFFER_FREE_SAFE(fbl->gtao_fb);
+ effects->ao_settings = 0.0f;
}
/* MinMax Pyramid */
@@ -498,6 +584,17 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
txl->maxzbuffer = DRW_texture_create_2D((int)viewport_size[0] / 2, (int)viewport_size[1] / 2, DRW_TEX_DEPTH_24, DRW_TEX_MIPMAP, NULL);
}
+ /* Compute Mipmap texel alignement. */
+ for (int i = 0; i < 10; ++i) {
+ float mip_size[2] = {viewport_size[0], viewport_size[1]};
+ for (int j = 0; j < i; ++j) {
+ mip_size[0] = floorf(fmaxf(1.0f, mip_size[0] / 2.0f));
+ mip_size[1] = floorf(fmaxf(1.0f, mip_size[1] / 2.0f));
+ }
+ stl->g_data->mip_ratio[i][0] = viewport_size[0] / (mip_size[0] * powf(2.0f, floorf(log2f(floorf(viewport_size[0] / mip_size[0])))));
+ stl->g_data->mip_ratio[i][1] = viewport_size[1] / (mip_size[1] * powf(2.0f, floorf(log2f(floorf(viewport_size[1] / mip_size[1])))));
+ }
+
if (BKE_collection_engine_property_value_get_bool(props, "volumetric_enable")) {
World *wo = scene->world;
@@ -573,6 +670,14 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
if (BKE_collection_engine_property_value_get_bool(props, "ssr_enable")) {
effects->enabled_effects |= EFFECT_SSR;
+ if (BKE_collection_engine_property_value_get_bool(props, "ssr_refraction")) {
+ effects->enabled_effects |= EFFECT_REFRACT;
+
+ DRWFboTexture tex = {&txl->refract_color, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
+
+ DRW_framebuffer_init(&fbl->refract_fb, &draw_engine_eevee_type, (int)viewport_size[0], (int)viewport_size[1], &tex, 1);
+ }
+
/* Enable double buffering to be able to read previous frame color */
effects->enabled_effects |= EFFECT_DOUBLE_BUFFER;
@@ -598,11 +703,6 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
/* MRT for the shading pass in order to output needed data for the SSR pass. */
/* TODO create one texture layer per lobe */
- if (txl->ssr_normal_input == NULL) {
- DRWTextureFormat nor_format = DRW_TEX_RG_16;
- txl->ssr_normal_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], nor_format, 0, NULL);
- }
-
if (txl->ssr_specrough_input == NULL) {
DRWTextureFormat specrough_format = (high_qual_input) ? DRW_TEX_RGBA_16 : DRW_TEX_RGBA_8;
txl->ssr_specrough_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], specrough_format, 0, NULL);
@@ -610,9 +710,7 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
/* Reattach textures to the right buffer (because we are alternating between buffers) */
/* TODO multiple FBO per texture!!!! */
- DRW_framebuffer_texture_detach(txl->ssr_normal_input);
DRW_framebuffer_texture_detach(txl->ssr_specrough_input);
- DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
/* Raytracing output */
@@ -630,7 +728,6 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
}
else {
/* Cleanup to release memory */
- DRW_TEXTURE_FREE_SAFE(txl->ssr_normal_input);
DRW_TEXTURE_FREE_SAFE(txl->ssr_specrough_input);
DRW_FRAMEBUFFER_FREE_SAFE(fbl->screen_tracing_fb);
for (int i = 0; i < 4; ++i) {
@@ -638,6 +735,25 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
}
}
+ /* Normal buffer for deferred passes. */
+ if ((((effects->enabled_effects & EFFECT_GTAO) != 0) && G.debug_value == 6) ||
+ ((effects->enabled_effects & EFFECT_SSR) != 0))
+ {
+ if (txl->ssr_normal_input == NULL) {
+ DRWTextureFormat nor_format = DRW_TEX_RG_16;
+ txl->ssr_normal_input = DRW_texture_create_2D((int)viewport_size[0], (int)viewport_size[1], nor_format, 0, NULL);
+ }
+
+ /* Reattach textures to the right buffer (because we are alternating between buffers) */
+ /* TODO multiple FBO per texture!!!! */
+ DRW_framebuffer_texture_detach(txl->ssr_normal_input);
+ DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
+ }
+ else {
+ /* Cleanup to release memory */
+ DRW_TEXTURE_FREE_SAFE(txl->ssr_normal_input);
+ }
+
/* Setup double buffer so we can access last frame as it was before post processes */
if ((effects->enabled_effects & EFFECT_DOUBLE_BUFFER) != 0) {
DRWFboTexture tex_double_buffer = {&txl->color_double_buffer, DRW_TEX_RGB_11_11_10, DRW_TEX_FILTER | DRW_TEX_MIPMAP};
@@ -754,6 +870,7 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
DRW_shgroup_uniform_buffer(grp, "minzBuffer", &stl->g_data->minzbuffer);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
+ DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
DRW_shgroup_uniform_vec4(grp, "ssrParameters", &effects->ssr_quality, 1);
DRW_shgroup_uniform_int(grp, "rayCount", &effects->ssr_ray_count, 1);
DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
@@ -768,11 +885,12 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
DRW_shgroup_uniform_buffer(grp, "specroughBuffer", &txl->ssr_specrough_input);
DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
- DRW_shgroup_uniform_buffer(grp, "colorBuffer", &txl->color_double_buffer);
+ DRW_shgroup_uniform_buffer(grp, "prevColorBuffer", &txl->color_double_buffer);
DRW_shgroup_uniform_mat4(grp, "PastViewProjectionMatrix", (float *)stl->g_data->prev_persmat);
DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
DRW_shgroup_uniform_int(grp, "planar_count", &sldata->probes->num_planar, 1);
DRW_shgroup_uniform_int(grp, "probe_count", &sldata->probes->num_render_cube, 1);
+ DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
DRW_shgroup_uniform_float(grp, "borderFadeFactor", &effects->ssr_border_fac, 1);
DRW_shgroup_uniform_float(grp, "maxRoughness", &effects->ssr_max_roughness, 1);
DRW_shgroup_uniform_float(grp, "lodCubeMax", &sldata->probes->lod_cube_max, 1);
@@ -794,10 +912,22 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
psl->color_downsample_ps = DRW_pass_create("Downsample", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.downsample_sh, psl->color_downsample_ps);
DRW_shgroup_uniform_buffer(grp, "source", &e_data.color_src);
+ DRW_shgroup_uniform_float(grp, "fireflyFactor", &effects->ssr_firefly_fac, 1);
DRW_shgroup_call_add(grp, quad, NULL);
}
{
+ static int zero = 0;
+ psl->color_downsample_cube_ps = DRW_pass_create("Downsample Cube", DRW_STATE_WRITE_COLOR);
+ DRWShadingGroup *grp = DRW_shgroup_instance_create(e_data.downsample_cube_sh, psl->color_downsample_cube_ps, quad);
+ DRW_shgroup_uniform_buffer(grp, "source", &e_data.color_src);
+ DRW_shgroup_uniform_float(grp, "texelSize", &e_data.cube_texel_size, 1);
+ DRW_shgroup_uniform_int(grp, "Layer", &zero, 1);
+ for (int i = 0; i < 6; ++i)
+ DRW_shgroup_call_dynamic_add_empty(grp);
+ }
+
+ {
/* Perform min/max downsample */
psl->minz_downlevel_ps = DRW_pass_create("HiZ Min Down Level", DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_ALWAYS);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.minz_downlevel_sh, psl->minz_downlevel_ps);
@@ -845,6 +975,33 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
}
{
+ psl->ao_horizon_search = DRW_pass_create("GTAO Horizon Search", DRW_STATE_WRITE_COLOR);
+ DRWShadingGroup *grp = DRW_shgroup_create(e_data.gtao_sh, psl->ao_horizon_search);
+ DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
+ DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
+ DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
+ DRW_shgroup_uniform_vec4(grp, "aoParameters[0]", &stl->effects->ao_dist, 2);
+ DRW_shgroup_uniform_float(grp, "sampleNbr", &stl->effects->ao_sample_nbr, 1);
+ DRW_shgroup_uniform_ivec2(grp, "aoHorizonTexSize", (int *)stl->effects->ao_texsize, 1);
+ DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
+ DRW_shgroup_call_add(grp, quad, NULL);
+
+ psl->ao_horizon_debug = DRW_pass_create("GTAO Horizon Debug", DRW_STATE_WRITE_COLOR);
+ grp = DRW_shgroup_create(e_data.gtao_debug_sh, psl->ao_horizon_debug);
+ DRW_shgroup_uniform_buffer(grp, "maxzBuffer", &txl->maxzbuffer);
+ DRW_shgroup_uniform_buffer(grp, "depthBuffer", &e_data.depth_src);
+ DRW_shgroup_uniform_buffer(grp, "normalBuffer", &txl->ssr_normal_input);
+ DRW_shgroup_uniform_buffer(grp, "horizonBuffer", &txl->gtao_horizons);
+ DRW_shgroup_uniform_vec4(grp, "viewvecs[0]", (float *)stl->g_data->viewvecs, 2);
+ DRW_shgroup_uniform_vec2(grp, "mipRatio[0]", (float *)stl->g_data->mip_ratio, 10);
+ DRW_shgroup_uniform_vec4(grp, "aoParameters[0]", &stl->effects->ao_dist, 2);
+ DRW_shgroup_uniform_ivec2(grp, "aoHorizonTexSize", (int *)stl->effects->ao_texsize, 1);
+ DRW_shgroup_uniform_texture(grp, "utilTex", EEVEE_materials_get_util_tex());
+ DRW_shgroup_call_add(grp, quad, NULL);
+ }
+
+ {
psl->motion_blur = DRW_pass_create("Motion Blur", DRW_STATE_WRITE_COLOR);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.motion_blur_sh, psl->motion_blur);
@@ -893,8 +1050,9 @@ void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
eevee_create_bloom_pass("Bloom Upsample", effects, e_data.bloom_upsample_sh[use_highres], &psl->bloom_upsample, true);
grp = eevee_create_bloom_pass("Bloom Blit", effects, e_data.bloom_blit_sh[use_antiflicker], &psl->bloom_blit, false);
DRW_shgroup_uniform_vec4(grp, "curveThreshold", effects->bloom_curve_threshold, 1);
+ DRW_shgroup_uniform_float(grp, "clampIntensity", &effects->bloom_clamp, 1);
grp = eevee_create_bloom_pass("Bloom Resolve", effects, e_data.bloom_resolve_sh[use_highres], &psl->bloom_resolve, true);
- DRW_shgroup_uniform_float(grp, "bloomIntensity", &effects->bloom_intensity, 1);
+ DRW_shgroup_uniform_vec3(grp, "bloomColor", effects->bloom_color, 1);
}
{
@@ -962,6 +1120,13 @@ static void simple_downsample_cb(void *vedata, int UNUSED(level))
DRW_draw_pass(psl->color_downsample_ps);
}
+static void simple_downsample_cube_cb(void *vedata, int level)
+{
+ EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ e_data.cube_texel_size = (float)(1 << level) / (float)GPU_texture_width(e_data.color_src);
+ DRW_draw_pass(psl->color_downsample_cube_ps);
+}
+
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int layer)
{
EEVEE_PassList *psl = vedata->psl;
@@ -970,13 +1135,13 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int l
EEVEE_TextureList *txl = vedata->txl;
e_data.depth_src = depth_src;
+ e_data.depth_src_layer = layer;
DRW_stats_group_start("Min buffer");
/* Copy depth buffer to min texture top level */
DRW_framebuffer_texture_attach(fbl->downsample_fb, stl->g_data->minzbuffer, 0, 0);
DRW_framebuffer_bind(fbl->downsample_fb);
if (layer >= 0) {
- e_data.depth_src_layer = layer;
DRW_draw_pass(psl->minz_downdepth_layer_ps);
}
else {
@@ -993,7 +1158,6 @@ void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, GPUTexture *depth_src, int l
DRW_framebuffer_texture_attach(fbl->downsample_fb, txl->maxzbuffer, 0, 0);
DRW_framebuffer_bind(fbl->downsample_fb);
if (layer >= 0) {
- e_data.depth_src_layer = layer;
DRW_draw_pass(psl->maxz_downdepth_layer_ps);
}
else {
@@ -1019,6 +1183,19 @@ void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src,
DRW_stats_group_end();
}
+/**
+ * Simple downsampling algorithm for cubemap. Reconstruct mip chain up to mip level.
+ **/
+void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, GPUTexture *texture_src, int level)
+{
+ e_data.color_src = texture_src;
+
+ DRW_stats_group_start("Downsample Cube buffer");
+ /* Create lower levels */
+ DRW_framebuffer_recursive_downsample(fb_src, texture_src, level, &simple_downsample_cube_cb, vedata);
+ DRW_stats_group_end();
+}
+
void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
@@ -1059,6 +1236,20 @@ void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *veda
}
}
+void EEVEE_effects_do_refraction(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ if ((effects->enabled_effects & EFFECT_REFRACT) != 0) {
+ DRW_framebuffer_texture_attach(fbl->refract_fb, txl->refract_color, 0, 0);
+ DRW_framebuffer_blit(fbl->main, fbl->refract_fb, false);
+ EEVEE_downsample_buffer(vedata, fbl->downsample_fb, txl->refract_color, 9);
+ }
+}
+
void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *vedata)
{
EEVEE_PassList *psl = vedata->psl;
@@ -1103,6 +1294,49 @@ void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *veda
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_normal_input, 1, 0);
DRW_framebuffer_texture_attach(fbl->main, txl->ssr_specrough_input, 2, 0);
}
+
+ if ((effects->enabled_effects & EFFECT_GTAO) != 0 && G.debug_value == 6) {
+ /* GTAO Debug */
+ DRW_framebuffer_texture_attach(fbl->gtao_debug_fb, stl->g_data->gtao_horizons_debug, 0, 0);
+ DRW_framebuffer_bind(fbl->gtao_debug_fb);
+
+ DRW_draw_pass(psl->ao_horizon_debug);
+
+ /* Restore */
+ DRW_framebuffer_texture_detach(stl->g_data->gtao_horizons_debug);
+ }
+
+ DRW_framebuffer_bind(fbl->main);
+}
+
+void EEVEE_effects_do_gtao(EEVEE_SceneLayerData *UNUSED(sldata), EEVEE_Data *vedata)
+{
+ EEVEE_PassList *psl = vedata->psl;
+ EEVEE_TextureList *txl = vedata->txl;
+ EEVEE_FramebufferList *fbl = vedata->fbl;
+ EEVEE_StorageList *stl = vedata->stl;
+ EEVEE_EffectsInfo *effects = stl->effects;
+
+ if ((effects->enabled_effects & EFFECT_GTAO) != 0) {
+ DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
+ e_data.depth_src = dtxl->depth;
+
+ DRW_stats_group_start("GTAO Horizon Scan");
+ for (effects->ao_sample_nbr = 0.0;
+ effects->ao_sample_nbr < effects->ao_samples;
+ ++effects->ao_sample_nbr)
+ {
+ DRW_framebuffer_texture_detach(txl->gtao_horizons);
+ DRW_framebuffer_texture_layer_attach(fbl->gtao_fb, txl->gtao_horizons, 0, (int)effects->ao_sample_nbr, 0);
+ DRW_framebuffer_bind(fbl->gtao_fb);
+
+ DRW_draw_pass(psl->ao_horizon_search);
+ }
+ DRW_stats_group_end();
+
+ /* Restore */
+ DRW_framebuffer_bind(fbl->main);
+ }
}
#define SWAP_DOUBLE_BUFFERS() { \
@@ -1250,10 +1484,10 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
DRW_transform_to_display(effects->source_buffer);
/* Debug : Ouput buffer to view. */
- if ((G.debug_value > 0) && (G.debug_value <= 5)) {
+ if ((G.debug_value > 0) && (G.debug_value <= 6)) {
switch (G.debug_value) {
case 1:
- if (stl->g_data->minzbuffer) DRW_transform_to_display(stl->g_data->minzbuffer);
+ if (txl->maxzbuffer) DRW_transform_to_display(txl->maxzbuffer);
break;
case 2:
if (stl->g_data->ssr_hit_output[0]) DRW_transform_to_display(stl->g_data->ssr_hit_output[0]);
@@ -1267,6 +1501,9 @@ void EEVEE_draw_effects(EEVEE_Data *vedata)
case 5:
if (txl->color_double_buffer) DRW_transform_to_display(txl->color_double_buffer);
break;
+ case 6:
+ if (stl->g_data->gtao_horizons_debug) DRW_transform_to_display(stl->g_data->gtao_horizons_debug);
+ break;
default:
break;
}
@@ -1299,6 +1536,10 @@ void EEVEE_effects_free(void)
DRW_SHADER_FREE_SAFE(e_data.ssr_sh[i]);
}
DRW_SHADER_FREE_SAFE(e_data.downsample_sh);
+ DRW_SHADER_FREE_SAFE(e_data.downsample_cube_sh);
+
+ DRW_SHADER_FREE_SAFE(e_data.gtao_sh);
+ DRW_SHADER_FREE_SAFE(e_data.gtao_debug_sh);
DRW_SHADER_FREE_SAFE(e_data.volumetric_upsample_sh);
diff --git a/source/blender/draw/engines/eevee/eevee_engine.c b/source/blender/draw/engines/eevee/eevee_engine.c
index f2af9c53aa8..6ea717a0471 100644
--- a/source/blender/draw/engines/eevee/eevee_engine.c
+++ b/source/blender/draw/engines/eevee/eevee_engine.c
@@ -138,6 +138,7 @@ static void EEVEE_cache_finish(void *vedata)
static void EEVEE_draw_scene(void *vedata)
{
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_FramebufferList *fbl = ((EEVEE_Data *)vedata)->fbl;
EEVEE_SceneLayerData *sldata = EEVEE_scene_layer_data_get();
@@ -148,7 +149,18 @@ static void EEVEE_draw_scene(void *vedata)
* when using opengl render. */
int loop_ct = DRW_state_is_image_render() ? 4 : 1;
+ static float rand = 0.0f;
+
+ /* XXX temp for denoising render. TODO plug number of samples here */
+ if (DRW_state_is_image_render()) {
+ rand += 1.0f / 8.0f;
+ rand = rand - floorf(rand);
+ /* Set jitter offset */
+ stl->effects->ao_offset = rand * stl->effects->ao_samples_inv;
+ }
+
while (loop_ct--) {
+
/* Refresh shadows */
DRW_stats_group_start("Shadows");
EEVEE_draw_shadows(sldata, psl);
@@ -171,18 +183,20 @@ static void EEVEE_draw_scene(void *vedata)
DRW_draw_pass(psl->depth_pass_cull);
DRW_stats_group_end();
- DRW_draw_pass(psl->background_pass);
-
/* Create minmax texture */
DRW_stats_group_start("Main MinMax buffer");
EEVEE_create_minmax_buffer(vedata, dtxl->depth, -1);
DRW_stats_group_end();
+ /* Compute GTAO Horizons */
+ EEVEE_effects_do_gtao(sldata, vedata);
+
/* Restore main FB */
DRW_framebuffer_bind(fbl->main);
/* Shading pass */
DRW_stats_group_start("Shading");
+ DRW_draw_pass(psl->background_pass);
EEVEE_draw_default_passes(psl);
DRW_draw_pass(psl->material_pass);
DRW_stats_group_end();
@@ -194,9 +208,17 @@ static void EEVEE_draw_scene(void *vedata)
DRW_draw_pass(psl->probe_display);
- /* Volumetrics */
- DRW_stats_group_start("Volumetrics");
- EEVEE_effects_do_volumetrics(sldata, vedata);
+ /* Prepare Refraction */
+ EEVEE_effects_do_refraction(sldata, vedata);
+
+ /* Restore main FB */
+ DRW_framebuffer_bind(fbl->main);
+
+ /* Opaque refraction */
+ DRW_stats_group_start("Opaque Refraction");
+ DRW_draw_pass(psl->refract_depth_pass);
+ DRW_draw_pass(psl->refract_depth_pass_cull);
+ DRW_draw_pass(psl->refract_pass);
DRW_stats_group_end();
/* Transparent */
@@ -205,6 +227,11 @@ static void EEVEE_draw_scene(void *vedata)
DRW_draw_pass(psl->transparent_pass);
DRW_stats_group_end();
+ /* Volumetrics */
+ DRW_stats_group_start("Volumetrics");
+ EEVEE_effects_do_volumetrics(sldata, vedata);
+ DRW_stats_group_end();
+
/* Post Process */
DRW_stats_group_start("Post FX");
EEVEE_draw_effects(vedata);
@@ -235,14 +262,16 @@ static void EEVEE_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDPr
props->type == IDP_GROUP &&
props->subtype == IDP_GROUP_SUB_ENGINE_RENDER);
+
BKE_collection_engine_property_add_bool(props, "ssr_enable", false);
+ BKE_collection_engine_property_add_bool(props, "ssr_refraction", false);
BKE_collection_engine_property_add_bool(props, "ssr_halfres", true);
BKE_collection_engine_property_add_int(props, "ssr_ray_count", 1);
BKE_collection_engine_property_add_float(props, "ssr_quality", 0.25f);
BKE_collection_engine_property_add_float(props, "ssr_max_roughness", 0.5f);
BKE_collection_engine_property_add_float(props, "ssr_thickness", 0.2f);
BKE_collection_engine_property_add_float(props, "ssr_border_fade", 0.075f);
- BKE_collection_engine_property_add_float(props, "ssr_firefly_fac", 0.0f);
+ BKE_collection_engine_property_add_float(props, "ssr_firefly_fac", 10.0f);
BKE_collection_engine_property_add_bool(props, "volumetric_enable", false);
BKE_collection_engine_property_add_float(props, "volumetric_start", 0.1f);
@@ -257,19 +286,25 @@ static void EEVEE_scene_layer_settings_create(RenderEngine *UNUSED(engine), IDPr
BKE_collection_engine_property_add_bool(props, "gtao_enable", false);
BKE_collection_engine_property_add_bool(props, "gtao_use_bent_normals", true);
+ BKE_collection_engine_property_add_bool(props, "gtao_denoise", true);
+ BKE_collection_engine_property_add_bool(props, "gtao_bounce", true);
BKE_collection_engine_property_add_float(props, "gtao_distance", 0.2f);
BKE_collection_engine_property_add_float(props, "gtao_factor", 1.0f);
+ BKE_collection_engine_property_add_float(props, "gtao_quality", 0.25f);
BKE_collection_engine_property_add_int(props, "gtao_samples", 2);
BKE_collection_engine_property_add_bool(props, "dof_enable", false);
BKE_collection_engine_property_add_float(props, "bokeh_max_size", 100.0f);
BKE_collection_engine_property_add_float(props, "bokeh_threshold", 1.0f);
+ float default_bloom_color[3] = {1.0f, 1.0f, 1.0f};
BKE_collection_engine_property_add_bool(props, "bloom_enable", false);
+ BKE_collection_engine_property_add_float_array(props, "bloom_color", default_bloom_color, 3);
BKE_collection_engine_property_add_float(props, "bloom_threshold", 0.8f);
BKE_collection_engine_property_add_float(props, "bloom_knee", 0.5f);
BKE_collection_engine_property_add_float(props, "bloom_intensity", 0.8f);
BKE_collection_engine_property_add_float(props, "bloom_radius", 6.5f);
+ BKE_collection_engine_property_add_float(props, "bloom_clamp", 1.0f);
BKE_collection_engine_property_add_bool(props, "motion_blur_enable", false);
BKE_collection_engine_property_add_int(props, "motion_blur_samples", 8);
diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c
index 7a446d221fa..a20b373d3b1 100644
--- a/source/blender/draw/engines/eevee/eevee_lightprobes.c
+++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c
@@ -434,6 +434,7 @@ void EEVEE_lightprobes_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *veda
struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
DRWShadingGroup *grp = stl->g_data->planar_downsample = DRW_shgroup_instance_create(e_data.probe_planar_downsample_sh, psl->probe_planar_downsample_ps, geom);
DRW_shgroup_uniform_buffer(grp, "source", &txl->planar_pool);
+ DRW_shgroup_uniform_float(grp, "fireflyFactor", &stl->effects->ssr_firefly_fac, 1);
DRW_shgroup_uniform_vec2(grp, "texelSize", stl->g_data->texel_size, 1);
}
}
@@ -826,14 +827,17 @@ static void downsample_planar(void *vedata, int level)
}
/* Glossy filter probe_rt to probe_pool at index probe_idx */
-static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, int probe_idx)
+static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl, int probe_idx)
{
EEVEE_LightProbesInfo *pinfo = sldata->probes;
+ /* Max lod used from the render target probe */
+ pinfo->lod_rt_max = floorf(log2f(PROBE_RT_SIZE)) - 2.0f;
+
/* 2 - Let gpu create Mipmaps for Filtered Importance Sampling. */
/* Bind next framebuffer to be able to gen. mips for probe_rt. */
DRW_framebuffer_bind(sldata->probe_filter_fb);
- DRW_texture_generate_mipmaps(sldata->probe_rt);
+ EEVEE_downsample_cube_buffer(vedata, sldata->probe_filter_fb, sldata->probe_rt, (int)(pinfo->lod_rt_max));
/* 3 - Render to probe array to the specified layer, do prefiltering. */
/* Detach to rebind the right mipmap. */
@@ -842,7 +846,7 @@ static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *ps
const int maxlevel = (int)floorf(log2f(PROBE_OCTAHEDRON_SIZE));
const int min_lod_level = 3;
for (int i = 0; i < maxlevel - min_lod_level; i++) {
- float bias = (i == 0) ? 0.0f : 1.0f;
+ float bias = (i == 0) ? -1.0f : 1.0f;
pinfo->texel_size = 1.0f / mipsize;
pinfo->padding_size = powf(2.0f, (float)(maxlevel - min_lod_level - 1 - i));
/* XXX : WHY THE HECK DO WE NEED THIS ??? */
@@ -879,7 +883,6 @@ static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *ps
pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
pinfo->lodfactor = bias + 0.5f * log((float)(PROBE_RT_SIZE * PROBE_RT_SIZE) * pinfo->invsamples_ct) / log(2);
- pinfo->lod_rt_max = floorf(log2f(PROBE_RT_SIZE)) - 2.0f;
DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->probe_pool, 0, i);
DRW_framebuffer_viewport_size(sldata->probe_filter_fb, 0, 0, mipsize, mipsize);
@@ -897,19 +900,10 @@ static void glossy_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *ps
}
/* Diffuse filter probe_rt to irradiance_pool at index probe_idx */
-static void diffuse_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *psl, int offset)
+static void diffuse_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, EEVEE_PassList *psl, int offset)
{
EEVEE_LightProbesInfo *pinfo = sldata->probes;
- /* 4 - Compute spherical harmonics */
- /* Tweaking parameters to balance perf. vs precision */
- DRW_framebuffer_bind(sldata->probe_filter_fb);
- DRW_texture_generate_mipmaps(sldata->probe_rt);
-
- /* Bind the right texture layer (one layer per irradiance grid) */
- DRW_framebuffer_texture_detach(sldata->probe_pool);
- DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
-
/* find cell position on the virtual 3D texture */
/* NOTE : Keep in sync with load_irradiance_cell() */
#if defined(IRRADIANCE_SH_L2)
@@ -927,6 +921,7 @@ static void diffuse_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *p
int y = size[1] * (offset / cell_per_row);
#ifndef IRRADIANCE_SH_L2
+ /* Tweaking parameters to balance perf. vs precision */
const float bias = 0.0f;
pinfo->invsamples_ct = 1.0f / pinfo->samples_ct;
pinfo->lodfactor = bias + 0.5f * log((float)(PROBE_RT_SIZE * PROBE_RT_SIZE) * pinfo->invsamples_ct) / log(2);
@@ -936,6 +931,14 @@ static void diffuse_filter_probe(EEVEE_SceneLayerData *sldata, EEVEE_PassList *p
pinfo->lod_rt_max = 2.0f; /* Improve cache reuse */
#endif
+ /* 4 - Compute spherical harmonics */
+ DRW_framebuffer_bind(sldata->probe_filter_fb);
+ EEVEE_downsample_cube_buffer(vedata, sldata->probe_filter_fb, sldata->probe_rt, (int)(pinfo->lod_rt_max));
+
+ /* Bind the right texture layer (one layer per irradiance grid) */
+ DRW_framebuffer_texture_detach(sldata->probe_pool);
+ DRW_framebuffer_texture_attach(sldata->probe_filter_fb, sldata->irradiance_rt, 0, 0);
+
DRW_framebuffer_viewport_size(sldata->probe_filter_fb, x, y, size[0], size[1]);
DRW_draw_pass(psl->probe_diffuse_compute);
@@ -968,8 +971,7 @@ static void render_scene_to_probe(
/* Disable AO until we find a way to hide really bad discontinuities between cubefaces. */
tmp_ao_dist = stl->effects->ao_dist;
tmp_ao_samples = stl->effects->ao_samples;
- stl->effects->ao_dist = 0.0f;
- stl->effects->ao_samples = 0.0f;
+ stl->effects->ao_settings = 0.0f; /* Disable AO */
/* 1 - Render to each cubeface individually.
* We do this instead of using geometry shader because a) it's faster,
@@ -1098,6 +1100,9 @@ static void render_scene_to_planar(
EEVEE_create_minmax_buffer(vedata, tmp_planar_depth, layer);
+ /* Compute GTAO Horizons */
+ EEVEE_effects_do_gtao(sldata, vedata);
+
/* Rebind Planar FB */
DRW_framebuffer_bind(fbl->planarref_fb);
@@ -1196,13 +1201,13 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
/* Render world in priority */
if (e_data.update_world) {
render_world_to_probe(sldata, psl);
- glossy_filter_probe(sldata, psl, 0);
- diffuse_filter_probe(sldata, psl, 0);
+ glossy_filter_probe(sldata, vedata, psl, 0);
+ diffuse_filter_probe(sldata, vedata, psl, 0);
/* Swap and redo prefiltering for other rendertarget.
* This way we have world lighting waiting for irradiance grids to catch up. */
SWAP(GPUTexture *, sldata->irradiance_pool, sldata->irradiance_rt);
- diffuse_filter_probe(sldata, psl, 0);
+ diffuse_filter_probe(sldata, vedata, psl, 0);
e_data.update_world = false;
@@ -1255,7 +1260,7 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
lightprobe_cell_location_get(egrid, cell_id, pos);
render_scene_to_probe(sldata, vedata, pos, prb->clipsta, prb->clipend);
- diffuse_filter_probe(sldata, psl, egrid->offset + cell_id);
+ diffuse_filter_probe(sldata, vedata, psl, egrid->offset + cell_id);
/* Restore */
pinfo->num_render_grid = tmp_num_render_grid;
@@ -1300,7 +1305,7 @@ void EEVEE_lightprobes_refresh(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata)
LightProbe *prb = (LightProbe *)ob->data;
render_scene_to_probe(sldata, vedata, ob->obmat[3], prb->clipsta, prb->clipend);
- glossy_filter_probe(sldata, psl, i);
+ glossy_filter_probe(sldata, vedata, psl, i);
ped->need_update = false;
ped->probe_id = i;
diff --git a/source/blender/draw/engines/eevee/eevee_lut.h b/source/blender/draw/engines/eevee/eevee_lut.h
index 711defee35d..37306dbc87a 100644
--- a/source/blender/draw/engines/eevee/eevee_lut.h
+++ b/source/blender/draw/engines/eevee/eevee_lut.h
@@ -3345,6 +3345,11017 @@ static float bsdf_split_sum_ggx[64 * 64 * 2] = {
0.626953f, 0.023544f, 0.616699f, 0.022186f, 0.605957f, 0.020920f, 0.594727f, 0.019730f
};
+static float btdf_split_sum_ggx[32][64 * 64] = {
+ {
+ 0.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f,
+ 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 0.999512f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.999512f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.039917f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f,
+ 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.999512f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.999512f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ },
+ {
+ 0.000122f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000122f, 0.004147f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.897949f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000732f, 0.996094f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.002439f,
+ 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000366f, 0.078308f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.001098f, 0.992188f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.999512f,
+ 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.005001f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.999512f,
+ 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000732f, 0.902344f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.002928f, 0.997070f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 1.000000f, 0.999512f, 0.999512f, 1.000000f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000732f, 0.301758f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.999512f, 1.000000f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.002562f, 0.996094f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000732f, 0.433594f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000244f, 0.004021f, 0.996582f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.001098f, 0.949219f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000610f,
+ 0.012039f, 0.998047f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.002073f, 0.993652f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000854f, 0.725586f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000610f, 0.011856f, 0.998047f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.002905f, 0.995117f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.001098f, 0.978027f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000732f, 0.314941f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000731f, 0.017670f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000366f, 0.005852f, 0.997559f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.003050f,
+ 0.996094f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.001957f, 0.993652f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.001586f, 0.990234f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.001220f, 0.986816f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.001220f, 0.984375f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f,
+ 0.001098f, 0.985352f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.001220f, 0.989258f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.001341f, 0.993652f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.001586f, 0.996094f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.002802f, 0.997559f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000117f, 0.000122f, 0.000122f,
+ 0.000243f, 0.006088f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000366f, 0.026321f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000732f, 0.892578f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000975f, 0.993652f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.002317f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.017944f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000731f, 0.983887f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000119f, 0.000122f, 0.000122f, 0.001653f, 0.998535f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.026108f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000732f, 0.995605f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.003777f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000365f, 0.991211f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.002195f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000364f, 0.993164f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.002672f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000360f, 0.998047f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.017075f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000731f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.997070f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.006874f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000480f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.996582f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000067f, 0.005440f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000365f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.995605f, 0.995117f,
+ 0.995117f, 0.995605f, 0.995117f, 0.995117f,
+ },
+ {
+ 0.003168f, 0.995605f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.999512f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000976f, 0.053314f, 0.994629f, 0.998535f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000122f, 0.000122f, 0.000732f, 0.003660f,
+ 0.653809f, 0.995117f, 0.998047f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000488f, 0.001463f, 0.010452f, 0.947266f, 0.995605f, 0.998535f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000365f, 0.000853f, 0.002928f, 0.037750f,
+ 0.980957f, 0.996582f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000243f, 0.000610f, 0.001342f, 0.006100f, 0.314453f, 0.989746f, 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000487f, 0.001091f, 0.002317f, 0.015839f, 0.910645f,
+ 0.993652f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000366f, 0.000732f, 0.001463f, 0.005302f, 0.068909f, 0.977539f, 0.995605f, 0.998047f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000244f, 0.000732f, 0.001098f, 0.002560f, 0.011551f, 0.658691f, 0.989746f,
+ 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000366f,
+ 0.000732f, 0.001585f, 0.004868f, 0.041077f, 0.958984f, 0.994141f, 0.997559f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000244f, 0.000732f, 0.001215f, 0.002802f, 0.010834f, 0.441895f, 0.987305f, 0.996094f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000242f, 0.000488f, 0.000850f,
+ 0.001586f, 0.004753f, 0.039154f, 0.948242f, 0.993652f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000366f, 0.000732f, 0.001220f, 0.003159f, 0.012032f, 0.480713f, 0.985840f, 0.996094f, 0.998047f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000240f, 0.000731f, 0.001097f, 0.001950f,
+ 0.005966f, 0.054413f, 0.957520f, 0.994141f, 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000486f, 0.000732f, 0.001534f, 0.003536f, 0.016937f, 0.726562f, 0.988281f, 0.996582f, 0.998047f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000365f, 0.000732f, 0.001098f, 0.002192f, 0.008278f,
+ 0.125244f, 0.974121f, 0.994629f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000365f, 0.000731f, 0.000947f, 0.001828f, 0.005314f, 0.031677f, 0.916016f, 0.991699f, 0.997070f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000488f, 0.000732f, 0.001339f, 0.003294f, 0.014389f, 0.562012f,
+ 0.985840f, 0.996094f, 0.998047f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000487f,
+ 0.000732f, 0.001098f, 0.002310f, 0.008163f, 0.123779f, 0.973633f, 0.994629f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000365f, 0.000732f, 0.001097f, 0.002071f, 0.005669f, 0.041199f, 0.937988f, 0.992676f,
+ 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000118f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000366f, 0.000728f, 0.000732f,
+ 0.001585f, 0.004143f, 0.020813f, 0.813965f, 0.989746f, 0.996582f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000116f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000488f, 0.000732f, 0.001220f, 0.003292f, 0.012581f, 0.446533f, 0.984863f, 0.996094f, 0.998047f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000471f, 0.000732f, 0.001220f, 0.002796f,
+ 0.009338f, 0.161865f, 0.977051f, 0.995117f, 0.997559f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000365f, 0.000732f, 0.001098f, 0.002285f, 0.006870f, 0.074097f, 0.965820f, 0.994141f, 0.997559f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000366f, 0.000731f, 0.001086f, 0.001945f, 0.005238f, 0.043732f,
+ 0.947754f, 0.993652f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000366f,
+ 0.000730f, 0.000893f, 0.001826f, 0.004871f, 0.030411f, 0.922852f, 0.992188f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.000609f, 0.000732f, 0.001407f, 0.004375f, 0.023758f, 0.892090f, 0.992188f,
+ 0.997070f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000605f, 0.000732f,
+ 0.001579f, 0.003941f, 0.020767f, 0.862793f, 0.991699f, 0.997559f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000238f, 0.000483f, 0.000732f, 0.001449f, 0.003654f, 0.018951f, 0.847656f, 0.991699f, 0.997559f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000233f, 0.000485f, 0.000732f, 0.001308f, 0.003353f,
+ 0.018997f, 0.855469f, 0.991699f, 0.997559f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000118f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000487f, 0.000732f, 0.001292f, 0.003649f, 0.019791f, 0.881836f, 0.992188f, 0.997559f, 0.998535f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000432f, 0.000732f, 0.001220f, 0.003635f, 0.021912f, 0.916992f,
+ 0.993652f, 0.997559f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000116f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000487f,
+ 0.000732f, 0.001245f, 0.004002f, 0.028107f, 0.946289f, 0.994141f, 0.998047f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000085f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000475f, 0.000732f, 0.001611f, 0.004581f, 0.040466f, 0.966309f, 0.995605f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000487f, 0.000732f, 0.001703f,
+ 0.005589f, 0.073486f, 0.979980f, 0.996094f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000475f, 0.000732f, 0.001706f, 0.006809f, 0.198730f, 0.987305f, 0.997559f, 0.998535f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000488f, 0.000732f, 0.002071f, 0.009590f, 0.647949f,
+ 0.992188f, 0.997559f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000710f, 0.001093f, 0.002541f, 0.015533f, 0.922852f, 0.995117f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000116f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000242f, 0.000728f, 0.001218f, 0.003387f, 0.034454f, 0.975586f, 0.996582f, 0.998535f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000365f, 0.000731f, 0.001219f,
+ 0.004959f, 0.161865f, 0.989746f, 0.998047f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000366f, 0.000731f, 0.001767f, 0.009331f, 0.849121f, 0.994629f, 0.998535f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000487f, 0.000732f, 0.002644f, 0.024231f, 0.977051f,
+ 0.997559f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000685f, 0.001217f, 0.004139f, 0.195435f, 0.992676f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000362f, 0.000731f, 0.001570f, 0.010086f, 0.944824f, 0.997070f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000365f, 0.000745f, 0.002781f,
+ 0.051758f, 0.990723f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000599f, 0.001176f, 0.006641f, 0.899414f, 0.997070f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000731f, 0.002066f, 0.032654f, 0.991211f, 0.998535f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000119f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000448f,
+ 0.001088f, 0.005440f, 0.918457f, 0.997070f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000119f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000725f, 0.001822f, 0.038452f, 0.994141f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000329f, 0.000848f, 0.005672f, 0.972168f,
+ 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000581f, 0.001982f, 0.155273f, 0.997070f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000330f, 0.000848f, 0.009247f, 0.992676f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000589f, 0.002625f,
+ 0.958496f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.001199f, 0.083374f, 0.998047f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000716f, 0.007244f, 0.996582f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f,
+ 0.002277f, 0.991211f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000070f, 0.000121f, 0.000122f, 0.000122f, 0.000854f, 0.950684f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000111f, 0.000121f, 0.000122f, 0.000475f, 0.067139f, 0.999512f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000118f, 0.000122f,
+ 0.000002f, 0.005859f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000014f, 0.001376f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000572f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000077f, 0.000002f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000103f, 0.992188f, 0.991699f, 0.991699f, 0.992188f, 0.992188f, 0.991699f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.940430f, 0.940430f,
+ 0.940918f, 0.940918f, 0.940430f, 0.940430f,
+ },
+ {
+ 0.014023f, 0.979492f, 0.994629f, 0.997070f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000488f, 0.004757f, 0.163330f, 0.975098f, 0.993164f, 0.996582f, 0.997559f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000610f, 0.002928f, 0.017166f,
+ 0.563965f, 0.978027f, 0.992676f, 0.996094f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000364f, 0.000732f, 0.002192f, 0.006573f, 0.044952f, 0.830566f, 0.980957f, 0.992676f, 0.996094f, 0.997070f, 0.998047f,
+ 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 1.000000f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000366f, 0.000854f, 0.001586f, 0.004253f, 0.014313f, 0.130371f,
+ 0.919922f, 0.984375f, 0.993652f, 0.996094f, 0.997070f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000488f,
+ 0.000854f, 0.001342f, 0.003025f, 0.007305f, 0.028870f, 0.407715f, 0.954590f, 0.987305f, 0.993652f, 0.996094f, 0.997070f, 0.998047f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000609f, 0.000842f, 0.000976f, 0.002193f, 0.005112f, 0.012505f, 0.066589f, 0.768066f,
+ 0.970703f, 0.989746f, 0.994629f, 0.996582f, 0.997070f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000244f, 0.000599f, 0.000609f, 0.000976f,
+ 0.001829f, 0.003046f, 0.007256f, 0.023499f, 0.194946f, 0.908691f, 0.979980f, 0.991699f, 0.995117f, 0.996582f, 0.997559f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000244f, 0.000488f, 0.000609f, 0.000976f, 0.001583f, 0.002647f, 0.004726f, 0.012169f, 0.050537f, 0.568359f, 0.954102f,
+ 0.985840f, 0.993164f, 0.995605f, 0.997070f, 0.998047f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000244f, 0.000488f, 0.000610f, 0.000975f, 0.001211f, 0.001946f,
+ 0.003532f, 0.007793f, 0.022446f, 0.139648f, 0.856445f, 0.974121f, 0.989746f, 0.994141f, 0.996094f, 0.997559f, 0.998047f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000241f,
+ 0.000310f, 0.000609f, 0.000807f, 0.001098f, 0.001822f, 0.002794f, 0.005699f, 0.012878f, 0.047821f, 0.469238f, 0.941406f, 0.982910f,
+ 0.991699f, 0.995117f, 0.996582f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000244f, 0.000244f, 0.000609f, 0.000732f, 0.001098f, 0.001461f, 0.002274f, 0.004025f,
+ 0.008247f, 0.023254f, 0.135254f, 0.833984f, 0.969727f, 0.987793f, 0.993652f, 0.995605f, 0.997070f, 0.998047f, 0.998535f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000207f, 0.000244f, 0.000609f,
+ 0.000610f, 0.001096f, 0.001098f, 0.002071f, 0.003370f, 0.006172f, 0.014442f, 0.052795f, 0.486572f, 0.940430f, 0.981934f, 0.991699f,
+ 0.994629f, 0.996582f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000244f, 0.000485f, 0.000610f, 0.001080f, 0.001098f, 0.001742f, 0.002668f, 0.004692f, 0.010147f,
+ 0.028076f, 0.168701f, 0.854004f, 0.970703f, 0.988770f, 0.993652f, 0.996094f, 0.997070f, 0.998047f, 0.998047f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000244f, 0.000487f, 0.000610f, 0.000731f,
+ 0.001098f, 0.001413f, 0.002411f, 0.003895f, 0.007072f, 0.017242f, 0.069580f, 0.605957f, 0.948730f, 0.983398f, 0.992188f, 0.995117f,
+ 0.996582f, 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000244f, 0.000244f, 0.000609f, 0.000610f, 0.001094f, 0.001337f, 0.001828f, 0.003275f, 0.005814f, 0.012054f, 0.036987f,
+ 0.270752f, 0.899414f, 0.975586f, 0.989746f, 0.993652f, 0.996094f, 0.997070f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000241f, 0.000365f, 0.000597f, 0.000610f, 0.000970f, 0.001098f,
+ 0.001815f, 0.002771f, 0.005009f, 0.008888f, 0.023804f, 0.115845f, 0.775879f, 0.962891f, 0.986328f, 0.993164f, 0.995605f, 0.997070f,
+ 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000244f, 0.000536f, 0.000731f, 0.000937f, 0.001203f, 0.001581f, 0.002186f, 0.004005f, 0.007061f, 0.016830f, 0.061218f, 0.522949f,
+ 0.940430f, 0.981934f, 0.991211f, 0.994629f, 0.996582f, 0.997559f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000363f, 0.000487f, 0.000731f, 0.000732f, 0.001097f, 0.001339f, 0.002071f,
+ 0.003498f, 0.005947f, 0.012390f, 0.037964f, 0.268799f, 0.896973f, 0.975586f, 0.989258f, 0.994141f, 0.996094f, 0.997070f, 0.998047f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000244f, 0.000366f,
+ 0.000609f, 0.000610f, 0.001094f, 0.001215f, 0.002056f, 0.003183f, 0.004742f, 0.009880f, 0.026337f, 0.139526f, 0.813477f, 0.966309f,
+ 0.986816f, 0.993164f, 0.996094f, 0.997070f, 0.997559f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000163f, 0.000363f, 0.000600f, 0.000731f, 0.001088f, 0.001216f, 0.001616f, 0.002640f, 0.004402f,
+ 0.008156f, 0.019669f, 0.083191f, 0.664062f, 0.953125f, 0.984375f, 0.992188f, 0.995117f, 0.997070f, 0.998047f, 0.998535f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.000244f, 0.000523f, 0.000731f,
+ 0.000732f, 0.001097f, 0.001690f, 0.002169f, 0.003998f, 0.006939f, 0.015808f, 0.055634f, 0.471191f, 0.935059f, 0.980957f, 0.991211f,
+ 0.995117f, 0.996582f, 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000336f, 0.000486f, 0.000731f, 0.000732f, 0.001097f, 0.001558f, 0.002069f, 0.003525f, 0.006058f, 0.013062f,
+ 0.040894f, 0.306396f, 0.910156f, 0.978027f, 0.990234f, 0.994141f, 0.996582f, 0.997559f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000113f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000360f, 0.000515f, 0.000731f, 0.000731f, 0.001094f,
+ 0.001219f, 0.002148f, 0.003159f, 0.005577f, 0.011360f, 0.031952f, 0.203979f, 0.874512f, 0.973633f, 0.989258f, 0.994141f, 0.996582f,
+ 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000325f, 0.000366f, 0.000731f, 0.000731f, 0.001093f, 0.001219f, 0.001820f, 0.002916f, 0.005291f, 0.009758f, 0.026352f, 0.145020f,
+ 0.832520f, 0.969238f, 0.988281f, 0.993652f, 0.996094f, 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000244f, 0.000440f, 0.000605f, 0.000731f, 0.001086f, 0.001097f, 0.001646f,
+ 0.002670f, 0.004230f, 0.008835f, 0.022415f, 0.112183f, 0.786133f, 0.966309f, 0.987793f, 0.993652f, 0.996094f, 0.997559f, 0.998047f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000272f, 0.000358f,
+ 0.000565f, 0.000731f, 0.000790f, 0.001210f, 0.001573f, 0.002434f, 0.004360f, 0.008102f, 0.020660f, 0.092896f, 0.741699f, 0.962891f,
+ 0.987305f, 0.993164f, 0.996094f, 0.997070f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000364f, 0.000723f, 0.000731f, 0.000731f, 0.001216f, 0.001698f, 0.002510f, 0.003998f,
+ 0.007484f, 0.018463f, 0.082336f, 0.709961f, 0.961426f, 0.986816f, 0.993652f, 0.996094f, 0.997559f, 0.998535f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000242f, 0.000362f, 0.000704f, 0.000730f,
+ 0.000845f, 0.001096f, 0.001513f, 0.002302f, 0.003941f, 0.007168f, 0.017746f, 0.076782f, 0.693848f, 0.961426f, 0.987305f, 0.993652f,
+ 0.996094f, 0.997559f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000364f, 0.000579f, 0.000728f, 0.000731f, 0.001096f, 0.001491f, 0.002069f, 0.003899f, 0.007195f, 0.017059f,
+ 0.075439f, 0.701172f, 0.962402f, 0.987793f, 0.993652f, 0.996094f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000119f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000357f, 0.000482f, 0.000730f, 0.000731f, 0.001094f,
+ 0.001334f, 0.002230f, 0.003708f, 0.007217f, 0.017410f, 0.079163f, 0.730469f, 0.965820f, 0.988281f, 0.994141f, 0.996582f, 0.998047f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000112f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000238f,
+ 0.000243f, 0.000365f, 0.000729f, 0.000731f, 0.001095f, 0.001330f, 0.002066f, 0.003637f, 0.007118f, 0.018112f, 0.087708f, 0.775391f,
+ 0.969238f, 0.989258f, 0.994629f, 0.997070f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000073f, 0.000121f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000323f, 0.000390f, 0.000729f, 0.000731f, 0.001094f, 0.001332f, 0.002275f,
+ 0.003782f, 0.007252f, 0.019379f, 0.105042f, 0.827637f, 0.973145f, 0.990723f, 0.994629f, 0.997070f, 0.998047f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000114f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000240f, 0.000369f,
+ 0.000729f, 0.000731f, 0.001093f, 0.001330f, 0.002209f, 0.003937f, 0.007896f, 0.021805f, 0.137207f, 0.876953f, 0.979004f, 0.991699f,
+ 0.995605f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000119f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000272f, 0.000479f, 0.000727f, 0.000731f, 0.001085f, 0.001331f, 0.002291f, 0.004105f, 0.008446f,
+ 0.025024f, 0.202271f, 0.916504f, 0.982910f, 0.993164f, 0.996094f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000120f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000360f, 0.000469f, 0.000681f, 0.000731f,
+ 0.001092f, 0.001331f, 0.002184f, 0.004227f, 0.009521f, 0.030899f, 0.335205f, 0.945312f, 0.986816f, 0.993652f, 0.996582f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000116f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000241f, 0.000429f, 0.000726f, 0.000731f, 0.001091f, 0.001649f, 0.002464f, 0.004810f, 0.010895f, 0.041931f, 0.563477f,
+ 0.963867f, 0.989746f, 0.995117f, 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000101f, 0.000120f,
+ 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000288f, 0.000481f, 0.000720f, 0.000731f, 0.001093f, 0.001571f,
+ 0.002735f, 0.005405f, 0.013199f, 0.064880f, 0.786133f, 0.976562f, 0.992188f, 0.995605f, 0.997559f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000112f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000240f,
+ 0.000481f, 0.000727f, 0.000731f, 0.001093f, 0.001655f, 0.003132f, 0.005909f, 0.017181f, 0.123169f, 0.904297f, 0.984375f, 0.993652f,
+ 0.996582f, 0.998047f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000110f, 0.000120f, 0.000121f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000264f, 0.000392f, 0.000727f, 0.000835f, 0.001196f, 0.001765f, 0.003252f, 0.007343f,
+ 0.024521f, 0.304199f, 0.954102f, 0.989258f, 0.995605f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000034f, 0.000119f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000235f, 0.000375f, 0.000728f,
+ 0.000822f, 0.001095f, 0.002024f, 0.003952f, 0.009193f, 0.040894f, 0.694824f, 0.975586f, 0.992676f, 0.996582f, 0.998047f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000112f, 0.000121f, 0.000121f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000307f, 0.000475f, 0.000728f, 0.000943f, 0.001216f, 0.002283f, 0.004829f, 0.013008f, 0.092224f, 0.908203f,
+ 0.986328f, 0.995117f, 0.997559f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000073f, 0.000118f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000240f, 0.000576f, 0.000728f, 0.001073f, 0.001569f,
+ 0.002668f, 0.005947f, 0.020889f, 0.331543f, 0.965820f, 0.992188f, 0.996582f, 0.998047f, 0.998535f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000100f, 0.000120f, 0.000121f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000362f, 0.000630f, 0.000729f, 0.001087f, 0.001567f, 0.003241f, 0.008240f, 0.043793f, 0.824219f, 0.984375f, 0.994629f, 0.997559f,
+ 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000075f, 0.000119f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000363f, 0.000689f, 0.000730f, 0.001185f, 0.002022f, 0.004108f, 0.013702f,
+ 0.161011f, 0.957031f, 0.991699f, 0.996582f, 0.998047f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000105f, 0.000120f, 0.000121f, 0.000121f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000156f, 0.000372f, 0.000689f,
+ 0.000730f, 0.001198f, 0.002651f, 0.006214f, 0.028854f, 0.750000f, 0.984375f, 0.995605f, 0.998047f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000102f,
+ 0.000118f, 0.000120f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000472f, 0.000724f, 0.000966f, 0.001658f, 0.003397f, 0.010582f, 0.116028f, 0.959473f, 0.993164f,
+ 0.997559f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000111f, 0.000119f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000130f, 0.000479f, 0.000726f, 0.001163f, 0.002157f,
+ 0.004829f, 0.024338f, 0.776855f, 0.987793f, 0.996582f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000097f, 0.000117f,
+ 0.000120f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000219f, 0.000580f, 0.000728f, 0.001203f, 0.002872f, 0.009109f, 0.130371f, 0.972168f, 0.995117f, 0.998047f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000112f, 0.000118f, 0.000121f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000333f, 0.000681f, 0.000940f, 0.001629f, 0.004120f, 0.025467f, 0.890625f,
+ 0.991699f, 0.997559f, 0.999512f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000083f, 0.000116f, 0.000120f,
+ 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000353f, 0.000722f,
+ 0.000961f, 0.002403f, 0.009354f, 0.295166f, 0.985840f, 0.997070f, 0.999512f, 0.999023f, 0.999512f, 0.999023f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000105f, 0.000118f, 0.000120f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000130f, 0.000427f, 0.000605f, 0.001345f, 0.004620f, 0.041229f, 0.966797f, 0.996094f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000074f, 0.000114f, 0.000119f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000089f, 0.000562f, 0.000942f, 0.002352f, 0.012459f,
+ 0.854004f, 0.994141f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000103f, 0.000117f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000007f, 0.000002f,
+ 0.000231f, 0.000596f, 0.001180f, 0.005474f, 0.211426f, 0.991211f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000111f, 0.000118f, 0.000120f, 0.000121f,
+ 0.000121f, 0.000122f, 0.000029f, 0.000004f, 0.000001f, 0.000348f, 0.000896f, 0.002764f, 0.032562f, 0.984375f, 0.998535f, 0.998535f,
+ 0.999023f, 0.998535f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000089f, 0.000116f, 0.000119f, 0.000121f, 0.000121f, 0.000121f, 0.000013f, 0.000003f, 0.000075f, 0.000586f, 0.001508f,
+ 0.010292f, 0.963379f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000107f, 0.000118f, 0.000120f, 0.000121f, 0.000116f,
+ 0.000008f, 0.000002f, 0.000233f, 0.000857f, 0.004566f, 0.834961f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000083f, 0.000114f, 0.000119f, 0.000120f, 0.000060f, 0.000005f, 0.000001f, 0.000557f, 0.002064f, 0.182373f, 0.997559f, 0.997559f,
+ 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000103f, 0.000117f, 0.000120f, 0.000024f, 0.000003f, 0.000168f,
+ 0.000968f, 0.026428f, 0.996582f, 0.997070f, 0.996582f, 0.996582f, 0.996582f, 0.997070f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000047f,
+ 0.000110f, 0.000118f, 0.000017f, 0.000002f, 0.000513f, 0.006870f, 0.995605f, 0.995605f, 0.995117f, 0.995117f, 0.995117f, 0.995117f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000096f, 0.000115f, 0.000011f, 0.000042f, 0.001919f, 0.992676f, 0.992676f,
+ 0.992676f, 0.992676f, 0.992676f, 0.992676f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000044f, 0.000109f,
+ 0.000008f, 0.000314f, 0.985840f, 0.985840f, 0.985840f, 0.985840f, 0.986328f, 0.985840f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000089f, 0.000060f, 0.964355f, 0.964355f, 0.963867f, 0.963867f, 0.963379f, 0.964355f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000022f, 0.818848f, 0.819824f,
+ 0.819336f, 0.819824f, 0.819824f, 0.819824f,
+ },
+ {
+ 0.038849f, 0.941406f, 0.984375f, 0.992188f, 0.994141f, 0.996094f, 0.996582f, 0.997070f, 0.998047f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 1.000000f, 1.000000f, 1.000000f, 0.999512f, 0.001582f, 0.014984f, 0.262451f, 0.930664f, 0.979980f, 0.989258f, 0.993164f, 0.995117f,
+ 0.996094f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.999512f, 0.000244f, 0.002317f, 0.009003f, 0.047180f,
+ 0.524902f, 0.936523f, 0.978027f, 0.988281f, 0.992188f, 0.994629f, 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 1.000000f,
+ 0.000122f, 0.001098f, 0.002560f, 0.006824f, 0.020493f, 0.108826f, 0.715820f, 0.946289f, 0.978516f, 0.988281f, 0.992188f, 0.994141f,
+ 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000607f, 0.001098f, 0.002310f, 0.005646f, 0.012825f, 0.040131f, 0.231201f,
+ 0.825195f, 0.954590f, 0.979980f, 0.988281f, 0.992188f, 0.994141f, 0.995117f, 0.996582f, 0.996582f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000244f, 0.000609f, 0.001341f,
+ 0.002310f, 0.004208f, 0.008865f, 0.021591f, 0.074585f, 0.439209f, 0.885742f, 0.962402f, 0.981934f, 0.989258f, 0.992676f, 0.994141f,
+ 0.995605f, 0.996582f, 0.997070f, 0.997070f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.999512f,
+ 0.000000f, 0.000122f, 0.000483f, 0.000610f, 0.001460f, 0.002192f, 0.003994f, 0.007030f, 0.013847f, 0.036316f, 0.146362f, 0.661621f,
+ 0.921875f, 0.969238f, 0.983398f, 0.989746f, 0.993164f, 0.994141f, 0.995605f, 0.996582f, 0.996582f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000243f, 0.000604f, 0.000730f, 0.001307f, 0.001944f, 0.003017f,
+ 0.004997f, 0.009834f, 0.021606f, 0.063416f, 0.295410f, 0.808594f, 0.944336f, 0.974609f, 0.985352f, 0.990234f, 0.993652f, 0.995117f,
+ 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 1.000000f, 0.000000f, 0.000000f, 0.000119f, 0.000366f,
+ 0.000495f, 0.000731f, 0.001217f, 0.001823f, 0.002796f, 0.004398f, 0.007656f, 0.015366f, 0.035828f, 0.119263f, 0.531738f, 0.886230f,
+ 0.958496f, 0.979004f, 0.986816f, 0.991699f, 0.993652f, 0.995117f, 0.996094f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000244f, 0.000366f, 0.000607f, 0.000731f, 0.001211f, 0.001650f, 0.002441f, 0.003975f, 0.006207f,
+ 0.011536f, 0.023315f, 0.060822f, 0.242798f, 0.744141f, 0.927734f, 0.969238f, 0.982422f, 0.989258f, 0.992188f, 0.994141f, 0.995605f,
+ 0.996094f, 0.996582f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.998535f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000211f, 0.000455f, 0.000486f, 0.000853f,
+ 0.001081f, 0.001810f, 0.002426f, 0.003759f, 0.005501f, 0.009094f, 0.016876f, 0.037109f, 0.114075f, 0.475586f, 0.862305f, 0.951172f,
+ 0.975586f, 0.985840f, 0.990234f, 0.992676f, 0.995117f, 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000364f, 0.000366f, 0.000464f, 0.000731f, 0.001093f, 0.001577f, 0.002235f, 0.002798f, 0.004841f, 0.007637f, 0.013008f,
+ 0.025635f, 0.063965f, 0.238403f, 0.720215f, 0.919434f, 0.965820f, 0.981445f, 0.987793f, 0.991211f, 0.993652f, 0.995117f, 0.996094f,
+ 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000238f, 0.000609f, 0.000712f, 0.000974f, 0.000976f, 0.001507f,
+ 0.002031f, 0.002680f, 0.004066f, 0.006294f, 0.010284f, 0.018326f, 0.040924f, 0.124146f, 0.485596f, 0.859375f, 0.949707f, 0.975586f,
+ 0.984375f, 0.989746f, 0.992676f, 0.994629f, 0.995605f, 0.996582f, 0.997070f, 0.997070f, 0.998047f, 0.998047f, 0.998535f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000113f, 0.000487f,
+ 0.000488f, 0.000610f, 0.000961f, 0.000976f, 0.001337f, 0.001705f, 0.002663f, 0.003521f, 0.005417f, 0.008408f, 0.014809f, 0.028793f,
+ 0.073120f, 0.270996f, 0.741699f, 0.922363f, 0.965332f, 0.980957f, 0.987793f, 0.991699f, 0.993652f, 0.995117f, 0.996094f, 0.997070f,
+ 0.997070f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000244f, 0.000224f, 0.000486f, 0.000609f, 0.000610f, 0.000973f, 0.000975f, 0.001306f, 0.001703f, 0.002350f,
+ 0.003239f, 0.004848f, 0.007122f, 0.011955f, 0.021820f, 0.048859f, 0.152710f, 0.554199f, 0.875977f, 0.953125f, 0.976562f, 0.985352f,
+ 0.990234f, 0.993164f, 0.994629f, 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000234f, 0.000244f, 0.000485f, 0.000488f, 0.000610f,
+ 0.000969f, 0.000975f, 0.001335f, 0.001693f, 0.001991f, 0.002811f, 0.004097f, 0.006397f, 0.009903f, 0.017303f, 0.035034f, 0.094421f,
+ 0.354736f, 0.795898f, 0.933594f, 0.969238f, 0.981934f, 0.988281f, 0.991699f, 0.993652f, 0.995117f, 0.996094f, 0.997070f, 0.997559f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000244f, 0.000244f, 0.000480f, 0.000608f, 0.000488f, 0.000922f, 0.000975f, 0.000976f, 0.001339f, 0.001827f, 0.002674f, 0.003891f,
+ 0.005688f, 0.008324f, 0.014320f, 0.026917f, 0.064392f, 0.216431f, 0.668945f, 0.904785f, 0.959961f, 0.978516f, 0.986816f, 0.990723f,
+ 0.993652f, 0.994141f, 0.996094f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 1.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000188f, 0.000220f, 0.000480f, 0.000608f, 0.000609f, 0.000876f, 0.000975f,
+ 0.000976f, 0.001454f, 0.002068f, 0.002649f, 0.003481f, 0.004757f, 0.007801f, 0.012230f, 0.021698f, 0.046814f, 0.138306f, 0.506348f,
+ 0.859375f, 0.947754f, 0.974121f, 0.984375f, 0.989746f, 0.992188f, 0.994141f, 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000244f,
+ 0.000446f, 0.000487f, 0.000609f, 0.000731f, 0.000973f, 0.000975f, 0.001310f, 0.001823f, 0.002304f, 0.002869f, 0.004890f, 0.006813f,
+ 0.010475f, 0.017731f, 0.036163f, 0.095337f, 0.353516f, 0.792480f, 0.932129f, 0.968262f, 0.982422f, 0.988770f, 0.992188f, 0.993652f,
+ 0.995605f, 0.996094f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.000241f, 0.000362f, 0.000487f, 0.000609f, 0.000609f, 0.000973f, 0.001213f, 0.001419f,
+ 0.001807f, 0.002068f, 0.002794f, 0.004070f, 0.005917f, 0.009140f, 0.015129f, 0.029053f, 0.070068f, 0.242554f, 0.700684f, 0.911621f,
+ 0.961914f, 0.979492f, 0.987305f, 0.991211f, 0.993164f, 0.995117f, 0.995605f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.000243f, 0.000483f, 0.000603f,
+ 0.000609f, 0.000730f, 0.001076f, 0.000975f, 0.001327f, 0.001598f, 0.002056f, 0.002848f, 0.003519f, 0.005589f, 0.008041f, 0.013321f,
+ 0.024155f, 0.054718f, 0.171875f, 0.590332f, 0.885742f, 0.955566f, 0.977051f, 0.985840f, 0.990723f, 0.993164f, 0.994629f, 0.995605f,
+ 0.997070f, 0.997070f, 0.997559f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000192f, 0.000122f, 0.000244f, 0.000483f, 0.000606f, 0.000608f, 0.000731f, 0.000953f, 0.001095f, 0.001258f, 0.001575f, 0.002066f,
+ 0.002594f, 0.003857f, 0.004734f, 0.007683f, 0.011642f, 0.021179f, 0.044464f, 0.127930f, 0.476807f, 0.850586f, 0.947266f, 0.974121f,
+ 0.984375f, 0.989746f, 0.992676f, 0.994141f, 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000229f, 0.000239f, 0.000244f, 0.000343f, 0.000483f, 0.000608f, 0.000609f,
+ 0.000857f, 0.000973f, 0.001097f, 0.001571f, 0.002041f, 0.002399f, 0.002922f, 0.004471f, 0.006836f, 0.010643f, 0.018661f, 0.037354f,
+ 0.100037f, 0.378418f, 0.810547f, 0.937988f, 0.971191f, 0.983887f, 0.989258f, 0.992188f, 0.994141f, 0.995605f, 0.996582f, 0.997070f,
+ 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000161f,
+ 0.000230f, 0.000244f, 0.000486f, 0.000607f, 0.000609f, 0.000819f, 0.000972f, 0.000975f, 0.001431f, 0.001945f, 0.002283f, 0.003031f,
+ 0.004238f, 0.006424f, 0.009995f, 0.016068f, 0.032104f, 0.081360f, 0.302246f, 0.765625f, 0.928223f, 0.968750f, 0.982422f, 0.988770f,
+ 0.992676f, 0.994629f, 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000240f, 0.000240f, 0.000244f, 0.000450f, 0.000607f, 0.000609f, 0.000731f, 0.001084f,
+ 0.000974f, 0.001341f, 0.001910f, 0.002254f, 0.003216f, 0.004017f, 0.005692f, 0.008980f, 0.014832f, 0.028854f, 0.069641f, 0.248657f,
+ 0.719238f, 0.918945f, 0.965820f, 0.981445f, 0.988770f, 0.992188f, 0.994629f, 0.995605f, 0.996094f, 0.997070f, 0.997559f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.000360f,
+ 0.000461f, 0.000607f, 0.000608f, 0.000731f, 0.001086f, 0.001202f, 0.001307f, 0.001592f, 0.002066f, 0.003134f, 0.003990f, 0.005611f,
+ 0.008133f, 0.013680f, 0.025986f, 0.061462f, 0.211670f, 0.676758f, 0.910156f, 0.963867f, 0.980957f, 0.988281f, 0.991699f, 0.994629f,
+ 0.995605f, 0.996582f, 0.997070f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000240f, 0.000243f, 0.000482f, 0.000604f, 0.000608f, 0.000730f, 0.001040f, 0.001188f, 0.001287f,
+ 0.001574f, 0.002064f, 0.002613f, 0.003721f, 0.005428f, 0.008018f, 0.013161f, 0.024200f, 0.055573f, 0.186401f, 0.642578f, 0.904785f,
+ 0.962402f, 0.980469f, 0.987793f, 0.991699f, 0.994141f, 0.995605f, 0.996582f, 0.997070f, 0.998047f, 0.998535f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.000480f, 0.000602f,
+ 0.000721f, 0.000705f, 0.000907f, 0.001094f, 0.001096f, 0.001493f, 0.002058f, 0.002607f, 0.003639f, 0.004826f, 0.007595f, 0.012413f,
+ 0.022171f, 0.051697f, 0.171143f, 0.619629f, 0.899414f, 0.961426f, 0.980957f, 0.987793f, 0.992188f, 0.994629f, 0.995605f, 0.996582f,
+ 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000172f, 0.000232f, 0.000243f, 0.000244f, 0.000576f, 0.000711f, 0.000608f, 0.000767f, 0.001089f, 0.001213f, 0.001509f, 0.002029f,
+ 0.002684f, 0.003550f, 0.005161f, 0.007107f, 0.011871f, 0.021545f, 0.049347f, 0.163086f, 0.609863f, 0.900391f, 0.962891f, 0.980957f,
+ 0.988281f, 0.992676f, 0.994629f, 0.996094f, 0.996582f, 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000210f, 0.000122f, 0.000337f, 0.000290f, 0.000594f, 0.000726f, 0.000730f,
+ 0.000731f, 0.001090f, 0.001212f, 0.001506f, 0.002029f, 0.002335f, 0.003489f, 0.005077f, 0.007000f, 0.011398f, 0.021027f, 0.048218f,
+ 0.161133f, 0.614258f, 0.903809f, 0.963379f, 0.981934f, 0.988770f, 0.992188f, 0.994629f, 0.996094f, 0.997070f, 0.997559f, 0.998047f,
+ 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000281f, 0.000440f, 0.000683f, 0.000726f, 0.000730f, 0.000731f, 0.001087f, 0.001095f, 0.001485f, 0.001793f, 0.002214f, 0.002991f,
+ 0.004951f, 0.006912f, 0.011162f, 0.020905f, 0.048187f, 0.165527f, 0.633789f, 0.910156f, 0.965820f, 0.982422f, 0.989746f, 0.993164f,
+ 0.995117f, 0.996094f, 0.997070f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000241f, 0.000243f, 0.000480f, 0.000725f, 0.000697f, 0.000731f, 0.001007f,
+ 0.001094f, 0.001360f, 0.001795f, 0.002161f, 0.003244f, 0.004871f, 0.006966f, 0.011330f, 0.020706f, 0.049591f, 0.178345f, 0.667969f,
+ 0.918457f, 0.968262f, 0.983887f, 0.990234f, 0.993652f, 0.995605f, 0.996582f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000086f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.000243f,
+ 0.000465f, 0.000592f, 0.000729f, 0.000730f, 0.001079f, 0.001093f, 0.001332f, 0.001885f, 0.002129f, 0.003254f, 0.004818f, 0.006889f,
+ 0.011429f, 0.021957f, 0.052521f, 0.201294f, 0.714355f, 0.929199f, 0.972168f, 0.985352f, 0.991211f, 0.994141f, 0.995605f, 0.997070f,
+ 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000115f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000184f, 0.000241f, 0.000347f, 0.000453f, 0.000579f, 0.000728f, 0.000729f, 0.001034f, 0.001093f, 0.001292f,
+ 0.001857f, 0.002131f, 0.003296f, 0.004826f, 0.006958f, 0.011726f, 0.023071f, 0.057983f, 0.239258f, 0.767578f, 0.939453f, 0.976074f,
+ 0.987305f, 0.992676f, 0.994629f, 0.996094f, 0.997070f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000088f, 0.000119f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000191f, 0.000242f, 0.000425f, 0.000558f,
+ 0.000723f, 0.000730f, 0.001058f, 0.001092f, 0.001297f, 0.001653f, 0.002352f, 0.003124f, 0.004860f, 0.007072f, 0.012131f, 0.024551f,
+ 0.066406f, 0.300537f, 0.820312f, 0.951172f, 0.979492f, 0.988281f, 0.993164f, 0.995117f, 0.996582f, 0.997070f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000119f,
+ 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000227f, 0.000239f, 0.000341f, 0.000359f, 0.000587f, 0.000605f, 0.000729f, 0.001040f, 0.001185f, 0.001275f, 0.001849f, 0.002390f,
+ 0.003399f, 0.005001f, 0.007404f, 0.012871f, 0.027237f, 0.079529f, 0.395264f, 0.868164f, 0.960938f, 0.982910f, 0.990234f, 0.993164f,
+ 0.995605f, 0.997070f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000119f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000211f, 0.000239f, 0.000307f, 0.000394f, 0.000704f, 0.000711f, 0.000728f,
+ 0.001001f, 0.001088f, 0.001204f, 0.001713f, 0.002367f, 0.003151f, 0.004639f, 0.007820f, 0.014084f, 0.030609f, 0.102722f, 0.527344f,
+ 0.906250f, 0.969727f, 0.985840f, 0.991699f, 0.994629f, 0.996094f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000117f, 0.000115f, 0.000121f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000196f,
+ 0.000332f, 0.000363f, 0.000686f, 0.000719f, 0.000723f, 0.000963f, 0.001089f, 0.001290f, 0.001849f, 0.002394f, 0.003458f, 0.004833f,
+ 0.008301f, 0.015579f, 0.036926f, 0.143188f, 0.676270f, 0.934570f, 0.976562f, 0.988281f, 0.992676f, 0.995605f, 0.996582f, 0.998047f,
+ 0.998047f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000102f, 0.000120f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000311f, 0.000345f, 0.000479f, 0.000723f, 0.000728f, 0.000934f, 0.001085f,
+ 0.001282f, 0.001821f, 0.002399f, 0.003355f, 0.005524f, 0.008881f, 0.017807f, 0.047058f, 0.222046f, 0.803223f, 0.954102f, 0.981445f,
+ 0.990723f, 0.994141f, 0.996582f, 0.997559f, 0.998047f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000090f, 0.000116f, 0.000121f, 0.000121f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000201f, 0.000239f, 0.000358f,
+ 0.000618f, 0.000719f, 0.000727f, 0.000863f, 0.001087f, 0.001350f, 0.001945f, 0.002689f, 0.003731f, 0.005817f, 0.010033f, 0.021332f,
+ 0.064514f, 0.374512f, 0.885254f, 0.969238f, 0.986328f, 0.992676f, 0.995605f, 0.996582f, 0.998047f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000086f, 0.000117f, 0.000121f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000164f, 0.000238f, 0.000353f, 0.000596f, 0.000591f, 0.000727f, 0.000901f, 0.001085f, 0.001266f, 0.001767f,
+ 0.002663f, 0.003914f, 0.006153f, 0.011612f, 0.026871f, 0.100525f, 0.605957f, 0.934082f, 0.978027f, 0.989746f, 0.994141f, 0.996094f,
+ 0.997559f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999023f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000107f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000195f, 0.000323f, 0.000339f, 0.000461f, 0.000706f,
+ 0.000726f, 0.000845f, 0.001086f, 0.001298f, 0.001843f, 0.003027f, 0.004387f, 0.007011f, 0.013832f, 0.036530f, 0.183228f, 0.805664f,
+ 0.959961f, 0.984863f, 0.991699f, 0.995605f, 0.997070f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000117f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000224f, 0.000336f, 0.000464f, 0.000708f, 0.000726f, 0.000965f, 0.001083f, 0.001458f, 0.002180f, 0.003096f, 0.004425f,
+ 0.008377f, 0.017639f, 0.056610f, 0.390869f, 0.909180f, 0.975586f, 0.989746f, 0.994141f, 0.996582f, 0.998047f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000110f, 0.000113f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000135f, 0.000336f, 0.000467f, 0.000713f, 0.000725f, 0.000959f,
+ 0.001191f, 0.001287f, 0.001939f, 0.003231f, 0.005306f, 0.009888f, 0.024414f, 0.105835f, 0.709961f, 0.955078f, 0.984863f, 0.993164f,
+ 0.996094f, 0.997559f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000061f, 0.000089f,
+ 0.000118f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000309f,
+ 0.000299f, 0.000460f, 0.000710f, 0.000724f, 0.000997f, 0.001073f, 0.001410f, 0.002117f, 0.003506f, 0.006031f, 0.012863f, 0.038391f,
+ 0.260742f, 0.892090f, 0.975098f, 0.990723f, 0.995117f, 0.997559f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000085f, 0.000110f, 0.000118f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000317f, 0.000499f, 0.000706f, 0.000599f, 0.000851f, 0.001069f, 0.001633f,
+ 0.002367f, 0.003918f, 0.007580f, 0.017929f, 0.074646f, 0.645508f, 0.956055f, 0.986328f, 0.994141f, 0.996582f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000099f, 0.000113f,
+ 0.000119f, 0.000119f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000160f, 0.000326f, 0.000308f,
+ 0.000578f, 0.000602f, 0.000921f, 0.001071f, 0.001807f, 0.002783f, 0.004620f, 0.010017f, 0.029465f, 0.211792f, 0.896484f, 0.979004f,
+ 0.992188f, 0.996094f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000027f, 0.000103f, 0.000114f, 0.000118f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000090f, 0.000212f, 0.000309f, 0.000586f, 0.000602f, 0.000937f, 0.001147f, 0.002031f, 0.003237f, 0.006134f,
+ 0.014969f, 0.063171f, 0.665527f, 0.964355f, 0.989258f, 0.995117f, 0.999023f, 0.998535f, 0.999023f, 0.999023f, 0.998535f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000018f, 0.000103f, 0.000113f,
+ 0.000117f, 0.000119f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000004f, 0.000002f, 0.000199f, 0.000390f, 0.000586f, 0.000665f,
+ 0.000946f, 0.001365f, 0.002207f, 0.003767f, 0.008308f, 0.025955f, 0.227661f, 0.924316f, 0.984863f, 0.994141f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000098f, 0.000109f, 0.000117f, 0.000119f, 0.000120f, 0.000120f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000011f, 0.000005f, 0.000003f,
+ 0.000002f, 0.000193f, 0.000388f, 0.000586f, 0.000659f, 0.000952f, 0.001580f, 0.002762f, 0.005363f, 0.013153f, 0.066589f, 0.781738f,
+ 0.977051f, 0.993164f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000075f, 0.000112f,
+ 0.000116f, 0.000118f, 0.000119f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000122f,
+ 0.000088f, 0.000026f, 0.000010f, 0.000005f, 0.000003f, 0.000002f, 0.000186f, 0.000407f, 0.000586f, 0.000760f, 0.000986f, 0.001796f,
+ 0.003275f, 0.007565f, 0.026794f, 0.363281f, 0.959473f, 0.990723f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000010f, 0.000090f, 0.000110f, 0.000115f, 0.000117f, 0.000119f, 0.000120f, 0.000120f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000077f, 0.000023f, 0.000011f, 0.000005f, 0.000003f, 0.000002f, 0.000158f,
+ 0.000407f, 0.000587f, 0.000826f, 0.001264f, 0.002174f, 0.004894f, 0.013359f, 0.098511f, 0.911133f, 0.987793f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000084f, 0.000107f,
+ 0.000114f, 0.000117f, 0.000119f, 0.000119f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000093f, 0.000024f,
+ 0.000011f, 0.000005f, 0.000003f, 0.000002f, 0.000220f, 0.000476f, 0.000585f, 0.000913f, 0.001374f, 0.002951f, 0.007511f, 0.034973f,
+ 0.736328f, 0.982910f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000056f, 0.000102f, 0.000112f, 0.000116f, 0.000117f, 0.000119f, 0.000120f, 0.000120f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000075f, 0.000025f, 0.000010f, 0.000005f, 0.000003f, 0.000034f, 0.000222f, 0.000491f, 0.000589f,
+ 0.001020f, 0.001881f, 0.004669f, 0.015717f, 0.298340f, 0.974609f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000048f, 0.000095f,
+ 0.000106f, 0.000114f, 0.000117f, 0.000118f, 0.000119f, 0.000120f, 0.000120f, 0.000121f, 0.000089f, 0.000029f, 0.000012f, 0.000006f,
+ 0.000003f, 0.000002f, 0.000223f, 0.000525f, 0.000687f, 0.001122f, 0.002672f, 0.008255f, 0.079590f, 0.954590f, 0.996582f, 0.996582f,
+ 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000077f, 0.000104f, 0.000112f, 0.000115f, 0.000117f, 0.000119f, 0.000119f,
+ 0.000120f, 0.000109f, 0.000031f, 0.000013f, 0.000006f, 0.000003f, 0.000002f, 0.000254f, 0.000550f, 0.000846f, 0.001545f, 0.004223f,
+ 0.027771f, 0.901855f, 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000037f,
+ 0.000090f, 0.000107f, 0.000113f, 0.000116f, 0.000118f, 0.000119f, 0.000120f, 0.000041f, 0.000015f, 0.000007f, 0.000004f, 0.000002f,
+ 0.000271f, 0.000563f, 0.000786f, 0.002211f, 0.012207f, 0.711426f, 0.994629f, 0.994629f, 0.995117f, 0.994629f, 0.994629f, 0.994629f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000028f, 0.000083f, 0.000102f, 0.000110f, 0.000114f, 0.000117f, 0.000118f,
+ 0.000052f, 0.000019f, 0.000008f, 0.000004f, 0.000002f, 0.000314f, 0.000444f, 0.001049f, 0.005669f, 0.266846f, 0.993164f, 0.993652f,
+ 0.993164f, 0.993652f, 0.993164f, 0.993164f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000048f, 0.000089f, 0.000106f, 0.000112f, 0.000115f, 0.000077f, 0.000026f, 0.000010f, 0.000005f, 0.000079f, 0.000425f, 0.000405f,
+ 0.002468f, 0.064209f, 0.990234f, 0.990723f, 0.990234f, 0.990234f, 0.990234f, 0.991211f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000020f, 0.000075f, 0.000098f, 0.000108f, 0.000113f, 0.000044f,
+ 0.000016f, 0.000006f, 0.000027f, 0.000270f, 0.000825f, 0.018448f, 0.986328f, 0.986328f, 0.986328f, 0.986328f, 0.986328f, 0.986328f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000049f, 0.000085f, 0.000102f, 0.000070f, 0.000022f, 0.000008f, 0.000133f, 0.000295f, 0.005318f, 0.978516f, 0.979004f,
+ 0.977539f, 0.977539f, 0.978027f, 0.978516f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000066f, 0.000092f, 0.000036f, 0.000011f,
+ 0.000135f, 0.000925f, 0.959473f, 0.959961f, 0.959961f, 0.959473f, 0.959961f, 0.959473f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000027f, 0.000065f, 0.000016f, 0.000109f, 0.907715f, 0.907227f, 0.907715f, 0.907227f, 0.907715f, 0.907715f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000017f, 0.711914f, 0.712402f,
+ 0.711426f, 0.711426f, 0.711914f, 0.712402f,
+ },
+ {
+ 0.076172f, 0.877441f, 0.964355f, 0.980957f, 0.987305f, 0.990723f, 0.992676f, 0.993652f, 0.994629f, 0.995605f, 0.996094f, 0.996582f,
+ 0.997070f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.003897f, 0.033173f, 0.320557f, 0.863770f, 0.953613f, 0.975586f, 0.984863f, 0.988770f,
+ 0.991211f, 0.992676f, 0.994141f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997559f, 0.997559f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000975f, 0.005951f, 0.020935f, 0.093140f,
+ 0.501465f, 0.873047f, 0.950684f, 0.973145f, 0.981934f, 0.986816f, 0.990234f, 0.992188f, 0.993164f, 0.994629f, 0.995605f, 0.996094f,
+ 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.998047f, 0.998535f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000610f, 0.002430f, 0.006081f, 0.015915f, 0.045593f, 0.179810f, 0.635254f, 0.889648f, 0.951172f, 0.972168f, 0.981445f, 0.986328f,
+ 0.989746f, 0.991699f, 0.993652f, 0.994629f, 0.995117f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.997559f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000244f, 0.001219f, 0.002796f, 0.006172f, 0.012848f, 0.028458f, 0.081177f, 0.301758f,
+ 0.733398f, 0.905273f, 0.953613f, 0.972168f, 0.981445f, 0.986328f, 0.989258f, 0.991699f, 0.993652f, 0.994141f, 0.995117f, 0.996094f,
+ 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000244f, 0.000731f, 0.001706f, 0.003166f,
+ 0.005470f, 0.010406f, 0.020813f, 0.047089f, 0.136719f, 0.449951f, 0.803223f, 0.919434f, 0.957520f, 0.973633f, 0.981934f, 0.986328f,
+ 0.989746f, 0.991699f, 0.993164f, 0.994629f, 0.995117f, 0.995605f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000244f, 0.000366f, 0.001214f, 0.001894f, 0.003159f, 0.005108f, 0.008720f, 0.015839f, 0.031586f, 0.074951f, 0.224121f, 0.596680f,
+ 0.851074f, 0.932617f, 0.962402f, 0.975586f, 0.982910f, 0.987305f, 0.989746f, 0.991699f, 0.993164f, 0.994141f, 0.995117f, 0.995605f,
+ 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000366f, 0.000731f, 0.000976f, 0.001827f, 0.002987f, 0.004757f, 0.007988f,
+ 0.013023f, 0.023544f, 0.048431f, 0.120239f, 0.352783f, 0.717285f, 0.887207f, 0.943848f, 0.966309f, 0.978027f, 0.983887f, 0.987305f,
+ 0.990234f, 0.992188f, 0.993652f, 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000434f, 0.000488f, 0.000704f,
+ 0.001218f, 0.002190f, 0.002783f, 0.004723f, 0.006878f, 0.011040f, 0.018372f, 0.034241f, 0.073242f, 0.194336f, 0.510742f, 0.803711f,
+ 0.912598f, 0.952637f, 0.970703f, 0.979004f, 0.984863f, 0.988281f, 0.991211f, 0.992676f, 0.994141f, 0.994629f, 0.995605f, 0.996094f,
+ 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000243f, 0.000488f, 0.000488f, 0.000916f, 0.001219f, 0.002308f, 0.002914f, 0.004124f, 0.006523f, 0.009537f, 0.014793f,
+ 0.025833f, 0.050446f, 0.116089f, 0.312744f, 0.661133f, 0.860840f, 0.931641f, 0.960449f, 0.974121f, 0.981445f, 0.986328f, 0.989258f,
+ 0.991211f, 0.992676f, 0.994141f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000121f, 0.000356f, 0.000488f, 0.000609f, 0.000944f, 0.001339f, 0.002296f,
+ 0.002964f, 0.003880f, 0.005676f, 0.008476f, 0.012909f, 0.020874f, 0.036926f, 0.075500f, 0.187988f, 0.474854f, 0.774414f, 0.900391f,
+ 0.946289f, 0.966309f, 0.978027f, 0.983887f, 0.987793f, 0.990234f, 0.991699f, 0.993164f, 0.994141f, 0.995117f, 0.995605f, 0.996094f,
+ 0.997070f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000244f, 0.000483f,
+ 0.000488f, 0.000731f, 0.001070f, 0.001551f, 0.002024f, 0.002520f, 0.003990f, 0.004738f, 0.007584f, 0.010834f, 0.016800f, 0.028763f,
+ 0.054535f, 0.120728f, 0.309082f, 0.642090f, 0.848145f, 0.926270f, 0.957031f, 0.971191f, 0.980469f, 0.985352f, 0.988770f, 0.990723f,
+ 0.992188f, 0.993652f, 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998047f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000242f, 0.000485f, 0.000608f, 0.000731f, 0.001091f, 0.001339f, 0.001943f, 0.002602f, 0.003466f,
+ 0.004845f, 0.006649f, 0.009529f, 0.014824f, 0.023407f, 0.041351f, 0.083496f, 0.199951f, 0.482422f, 0.770996f, 0.896484f, 0.944336f,
+ 0.965332f, 0.976562f, 0.982910f, 0.986816f, 0.990234f, 0.991699f, 0.993164f, 0.994141f, 0.995117f, 0.995117f, 0.996094f, 0.996582f,
+ 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000121f, 0.000243f, 0.000243f, 0.000602f, 0.000609f, 0.000799f,
+ 0.001088f, 0.001459f, 0.001822f, 0.002432f, 0.003033f, 0.004375f, 0.006042f, 0.008560f, 0.012810f, 0.019791f, 0.032715f, 0.061584f,
+ 0.135254f, 0.335693f, 0.660156f, 0.853027f, 0.926758f, 0.956543f, 0.972168f, 0.980469f, 0.984863f, 0.988281f, 0.991211f, 0.992676f,
+ 0.993652f, 0.994141f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000119f,
+ 0.000243f, 0.000366f, 0.000605f, 0.000730f, 0.000731f, 0.001201f, 0.001458f, 0.001804f, 0.002428f, 0.003593f, 0.004234f, 0.005745f,
+ 0.007755f, 0.011139f, 0.016754f, 0.027054f, 0.047424f, 0.097107f, 0.231323f, 0.525879f, 0.791016f, 0.902832f, 0.945801f, 0.966797f,
+ 0.977051f, 0.982910f, 0.987793f, 0.990234f, 0.991699f, 0.993164f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f,
+ 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000116f, 0.000122f, 0.000365f, 0.000244f, 0.000602f, 0.000721f, 0.000730f, 0.000852f, 0.001451f,
+ 0.001842f, 0.002518f, 0.002993f, 0.004097f, 0.005253f, 0.007099f, 0.009865f, 0.014908f, 0.022827f, 0.038879f, 0.072815f, 0.163940f,
+ 0.396484f, 0.707031f, 0.869141f, 0.932129f, 0.960449f, 0.973145f, 0.980957f, 0.986328f, 0.988770f, 0.991211f, 0.992676f, 0.993652f,
+ 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000110f, 0.000361f, 0.000242f, 0.000244f,
+ 0.000602f, 0.000728f, 0.000853f, 0.001260f, 0.001569f, 0.001704f, 0.002287f, 0.003103f, 0.003857f, 0.004848f, 0.006680f, 0.009003f,
+ 0.012978f, 0.019897f, 0.032135f, 0.057983f, 0.121033f, 0.291504f, 0.604980f, 0.827148f, 0.915039f, 0.953125f, 0.969238f, 0.978516f,
+ 0.984375f, 0.988281f, 0.991211f, 0.992188f, 0.993652f, 0.994141f, 0.995117f, 0.995605f, 0.996582f, 0.996582f, 0.997070f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000241f, 0.000241f, 0.000365f, 0.000365f, 0.000589f, 0.000852f, 0.000852f, 0.001246f, 0.001562f, 0.001812f, 0.002241f,
+ 0.002794f, 0.003633f, 0.004669f, 0.006069f, 0.008202f, 0.011772f, 0.016891f, 0.027618f, 0.047089f, 0.093506f, 0.216309f, 0.495605f,
+ 0.771484f, 0.894531f, 0.942383f, 0.965332f, 0.976074f, 0.982910f, 0.987305f, 0.989746f, 0.991699f, 0.993164f, 0.994629f, 0.995117f,
+ 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000364f, 0.000242f, 0.000487f, 0.000737f, 0.000730f,
+ 0.000974f, 0.001083f, 0.001520f, 0.001701f, 0.001938f, 0.002768f, 0.003658f, 0.004227f, 0.005741f, 0.007671f, 0.010796f, 0.015511f,
+ 0.023529f, 0.040009f, 0.074158f, 0.165405f, 0.395264f, 0.703613f, 0.868164f, 0.932129f, 0.959473f, 0.973633f, 0.980957f, 0.985840f,
+ 0.988770f, 0.991699f, 0.992676f, 0.994141f, 0.995117f, 0.995117f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000100f, 0.000000f, 0.000241f,
+ 0.000224f, 0.000487f, 0.000488f, 0.000710f, 0.000972f, 0.000848f, 0.001181f, 0.001333f, 0.001910f, 0.001830f, 0.002661f, 0.003298f,
+ 0.004154f, 0.005386f, 0.007271f, 0.009735f, 0.013908f, 0.021149f, 0.034149f, 0.062042f, 0.130371f, 0.313477f, 0.627930f, 0.837402f,
+ 0.919922f, 0.954590f, 0.970215f, 0.979492f, 0.985352f, 0.988770f, 0.991211f, 0.992676f, 0.993652f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996582f, 0.996582f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000049f, 0.000242f, 0.000483f, 0.000606f, 0.000487f, 0.000695f, 0.000970f, 0.000974f, 0.001136f,
+ 0.001328f, 0.001694f, 0.002028f, 0.002617f, 0.002953f, 0.003847f, 0.004951f, 0.006653f, 0.009193f, 0.012672f, 0.018661f, 0.029968f,
+ 0.052673f, 0.106689f, 0.250977f, 0.549805f, 0.801758f, 0.907227f, 0.948242f, 0.967773f, 0.978027f, 0.984375f, 0.987793f, 0.990723f,
+ 0.992188f, 0.993652f, 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000166f, 0.000243f, 0.000485f, 0.000487f,
+ 0.000487f, 0.000945f, 0.000834f, 0.000974f, 0.000974f, 0.001300f, 0.001810f, 0.002058f, 0.002573f, 0.002703f, 0.003761f, 0.004887f,
+ 0.006393f, 0.008514f, 0.011818f, 0.016937f, 0.026672f, 0.046051f, 0.089478f, 0.204712f, 0.476807f, 0.762207f, 0.891602f, 0.942383f,
+ 0.965820f, 0.976562f, 0.983398f, 0.987793f, 0.990234f, 0.992188f, 0.993652f, 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.997070f,
+ 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000224f, 0.000358f, 0.000477f, 0.000486f, 0.000487f, 0.000580f, 0.000841f, 0.000973f, 0.001079f, 0.001255f, 0.001649f,
+ 0.002045f, 0.002241f, 0.002995f, 0.003841f, 0.004826f, 0.005920f, 0.007866f, 0.010925f, 0.015930f, 0.024109f, 0.040619f, 0.077454f,
+ 0.171509f, 0.412354f, 0.720215f, 0.876953f, 0.936035f, 0.962402f, 0.975098f, 0.982422f, 0.987305f, 0.990234f, 0.992188f, 0.993164f,
+ 0.994629f, 0.995117f, 0.996094f, 0.996582f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000165f, 0.000205f, 0.000411f, 0.000480f, 0.000486f, 0.000608f, 0.000688f,
+ 0.000966f, 0.000968f, 0.000974f, 0.001421f, 0.001489f, 0.001695f, 0.002090f, 0.002886f, 0.003326f, 0.004608f, 0.005604f, 0.007317f,
+ 0.010414f, 0.014862f, 0.022232f, 0.036469f, 0.067810f, 0.146973f, 0.359375f, 0.680664f, 0.861816f, 0.931152f, 0.959961f, 0.974609f,
+ 0.981934f, 0.986816f, 0.989746f, 0.991699f, 0.993652f, 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000242f,
+ 0.000453f, 0.000539f, 0.000486f, 0.000487f, 0.000487f, 0.000957f, 0.000969f, 0.001202f, 0.001139f, 0.001393f, 0.001986f, 0.002045f,
+ 0.002863f, 0.003216f, 0.004128f, 0.005417f, 0.007378f, 0.009689f, 0.013466f, 0.020432f, 0.033722f, 0.060883f, 0.129395f, 0.318115f,
+ 0.642090f, 0.847656f, 0.926270f, 0.958008f, 0.973145f, 0.981934f, 0.986328f, 0.989746f, 0.992188f, 0.993164f, 0.994629f, 0.995605f,
+ 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.000380f, 0.000482f, 0.000606f, 0.000607f, 0.000608f, 0.000829f, 0.000970f,
+ 0.000972f, 0.001070f, 0.001402f, 0.001812f, 0.002138f, 0.002619f, 0.003246f, 0.004082f, 0.005318f, 0.006699f, 0.009262f, 0.012764f,
+ 0.019318f, 0.031052f, 0.055878f, 0.116821f, 0.286621f, 0.610352f, 0.835938f, 0.922852f, 0.956543f, 0.973145f, 0.981445f, 0.986328f,
+ 0.989746f, 0.991699f, 0.993652f, 0.995117f, 0.995605f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000243f, 0.000350f, 0.000480f,
+ 0.000605f, 0.000596f, 0.000608f, 0.000890f, 0.000963f, 0.000972f, 0.000974f, 0.001316f, 0.001798f, 0.002058f, 0.002560f, 0.002811f,
+ 0.003983f, 0.005108f, 0.006489f, 0.008888f, 0.012314f, 0.018021f, 0.029495f, 0.051941f, 0.107422f, 0.263428f, 0.585449f, 0.827148f,
+ 0.919434f, 0.956055f, 0.971680f, 0.981445f, 0.986816f, 0.989746f, 0.992188f, 0.994141f, 0.995117f, 0.995605f, 0.996582f, 0.996582f,
+ 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000130f, 0.000176f, 0.000462f, 0.000483f, 0.000604f, 0.000607f, 0.000638f, 0.000922f, 0.000965f, 0.000971f, 0.001235f,
+ 0.001376f, 0.001769f, 0.002041f, 0.002575f, 0.003130f, 0.003487f, 0.004936f, 0.006264f, 0.008415f, 0.012047f, 0.017517f, 0.027786f,
+ 0.049164f, 0.101257f, 0.249512f, 0.568848f, 0.821777f, 0.918945f, 0.956055f, 0.972168f, 0.981445f, 0.986816f, 0.990234f, 0.992188f,
+ 0.993652f, 0.995117f, 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000130f, 0.000122f, 0.000242f, 0.000352f, 0.000560f, 0.000602f, 0.000604f,
+ 0.000606f, 0.000767f, 0.001046f, 0.001089f, 0.000973f, 0.001327f, 0.001583f, 0.002033f, 0.002272f, 0.002657f, 0.003563f, 0.004589f,
+ 0.006138f, 0.008194f, 0.011299f, 0.016861f, 0.026718f, 0.047119f, 0.097656f, 0.240967f, 0.562500f, 0.821289f, 0.919922f, 0.957031f,
+ 0.973145f, 0.981934f, 0.987305f, 0.990234f, 0.992676f, 0.994141f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.998047f, 0.998047f,
+ 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000241f, 0.000314f, 0.000459f, 0.000600f, 0.000605f, 0.000598f, 0.000804f, 0.000958f, 0.001084f, 0.001104f, 0.001389f, 0.001709f,
+ 0.002041f, 0.002211f, 0.002645f, 0.003635f, 0.004467f, 0.005718f, 0.008072f, 0.011185f, 0.016846f, 0.026184f, 0.046112f, 0.094971f,
+ 0.239014f, 0.565430f, 0.825684f, 0.922363f, 0.958496f, 0.973633f, 0.983398f, 0.987793f, 0.990723f, 0.992676f, 0.994141f, 0.995605f,
+ 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000238f, 0.000122f, 0.000173f, 0.000246f, 0.000387f, 0.000480f, 0.000604f, 0.000604f, 0.000701f,
+ 0.000951f, 0.000968f, 0.001184f, 0.001315f, 0.001597f, 0.001899f, 0.002268f, 0.002813f, 0.003716f, 0.004372f, 0.005886f, 0.007759f,
+ 0.010918f, 0.015915f, 0.025726f, 0.045685f, 0.095459f, 0.243774f, 0.579102f, 0.833984f, 0.926270f, 0.960449f, 0.976074f, 0.983887f,
+ 0.988770f, 0.991211f, 0.993164f, 0.994629f, 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999023f, 0.999512f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000238f, 0.000237f, 0.000242f,
+ 0.000463f, 0.000585f, 0.000587f, 0.000718f, 0.000607f, 0.000885f, 0.001081f, 0.001087f, 0.001299f, 0.001553f, 0.001982f, 0.002104f,
+ 0.002777f, 0.003494f, 0.004406f, 0.005798f, 0.007645f, 0.010750f, 0.016159f, 0.025467f, 0.045959f, 0.097778f, 0.256104f, 0.603516f,
+ 0.847168f, 0.931152f, 0.963379f, 0.977539f, 0.985352f, 0.989258f, 0.991699f, 0.993652f, 0.995117f, 0.996094f, 0.996582f, 0.997559f,
+ 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000231f, 0.000122f, 0.000242f, 0.000242f, 0.000400f, 0.000525f, 0.000495f, 0.000605f, 0.000607f, 0.000898f, 0.001075f,
+ 0.001191f, 0.001133f, 0.001420f, 0.001794f, 0.002041f, 0.002733f, 0.003548f, 0.004448f, 0.005585f, 0.007656f, 0.010735f, 0.015671f,
+ 0.025589f, 0.047363f, 0.102783f, 0.276855f, 0.637695f, 0.862793f, 0.938477f, 0.966797f, 0.979004f, 0.985840f, 0.990234f, 0.992676f,
+ 0.994141f, 0.995117f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000226f, 0.000242f, 0.000470f, 0.000469f,
+ 0.000547f, 0.000711f, 0.000723f, 0.000829f, 0.001024f, 0.001188f, 0.001081f, 0.001415f, 0.001765f, 0.002048f, 0.002708f, 0.003252f,
+ 0.004448f, 0.005711f, 0.007557f, 0.010780f, 0.016220f, 0.026398f, 0.048950f, 0.111267f, 0.309082f, 0.680664f, 0.880371f, 0.945801f,
+ 0.970703f, 0.980957f, 0.986816f, 0.990723f, 0.993164f, 0.994629f, 0.995605f, 0.996582f, 0.997559f, 0.998047f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000204f, 0.000239f, 0.000242f, 0.000283f, 0.000479f, 0.000594f, 0.000603f, 0.000606f, 0.000779f, 0.001068f, 0.001084f, 0.001118f,
+ 0.001515f, 0.001926f, 0.002098f, 0.002674f, 0.002975f, 0.004040f, 0.005478f, 0.007488f, 0.010651f, 0.016327f, 0.027222f, 0.052460f,
+ 0.123718f, 0.355713f, 0.729980f, 0.899902f, 0.952637f, 0.973145f, 0.983887f, 0.988770f, 0.991699f, 0.994141f, 0.995117f, 0.996094f,
+ 0.997070f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000122f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000236f, 0.000207f, 0.000240f, 0.000435f, 0.000534f, 0.000594f, 0.000602f,
+ 0.000722f, 0.000727f, 0.000947f, 0.001081f, 0.001090f, 0.001471f, 0.001829f, 0.002010f, 0.002478f, 0.002956f, 0.004051f, 0.005753f,
+ 0.007717f, 0.011040f, 0.017105f, 0.028748f, 0.057159f, 0.142944f, 0.421387f, 0.780762f, 0.916992f, 0.960449f, 0.976562f, 0.985352f,
+ 0.989746f, 0.992676f, 0.994629f, 0.996094f, 0.997070f, 0.997559f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000224f, 0.000232f,
+ 0.000230f, 0.000382f, 0.000472f, 0.000576f, 0.000715f, 0.000721f, 0.000727f, 0.001046f, 0.001078f, 0.001186f, 0.001434f, 0.001674f,
+ 0.002066f, 0.002546f, 0.003407f, 0.004181f, 0.005634f, 0.007542f, 0.011330f, 0.017609f, 0.031189f, 0.064392f, 0.172729f, 0.506836f,
+ 0.828125f, 0.933105f, 0.966309f, 0.980469f, 0.987305f, 0.991211f, 0.993652f, 0.995117f, 0.996582f, 0.997070f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000232f, 0.000234f, 0.000352f, 0.000461f, 0.000535f, 0.000594f, 0.000722f, 0.000725f,
+ 0.000921f, 0.001116f, 0.001192f, 0.001416f, 0.001637f, 0.001911f, 0.002380f, 0.002949f, 0.003948f, 0.005589f, 0.007942f, 0.011650f,
+ 0.018631f, 0.034302f, 0.075867f, 0.219238f, 0.607422f, 0.870605f, 0.946777f, 0.972656f, 0.983887f, 0.989258f, 0.992676f, 0.995117f,
+ 0.996094f, 0.997070f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000239f, 0.000302f,
+ 0.000396f, 0.000564f, 0.000674f, 0.000617f, 0.000722f, 0.001003f, 0.001068f, 0.001084f, 0.001302f, 0.001598f, 0.001929f, 0.002375f,
+ 0.002935f, 0.004349f, 0.005714f, 0.007957f, 0.012306f, 0.020493f, 0.039001f, 0.092590f, 0.293213f, 0.711426f, 0.905762f, 0.958984f,
+ 0.978027f, 0.986328f, 0.990723f, 0.994141f, 0.995605f, 0.996582f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000232f, 0.000227f, 0.000240f, 0.000282f, 0.000542f, 0.000703f, 0.000718f, 0.000724f, 0.000833f, 0.001069f,
+ 0.001184f, 0.001346f, 0.001464f, 0.001898f, 0.002649f, 0.003164f, 0.004467f, 0.005863f, 0.008400f, 0.013199f, 0.022614f, 0.046051f,
+ 0.120605f, 0.406738f, 0.801270f, 0.931641f, 0.968262f, 0.982422f, 0.988770f, 0.992676f, 0.994629f, 0.996094f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000120f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000219f, 0.000237f, 0.000235f, 0.000241f, 0.000480f,
+ 0.000584f, 0.000715f, 0.000723f, 0.000775f, 0.001061f, 0.000959f, 0.001139f, 0.001526f, 0.001770f, 0.002546f, 0.003151f, 0.004250f,
+ 0.006195f, 0.009071f, 0.014595f, 0.026413f, 0.056763f, 0.169067f, 0.557617f, 0.869141f, 0.951172f, 0.976074f, 0.986328f, 0.990723f,
+ 0.994141f, 0.995605f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000120f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000216f, 0.000228f, 0.000285f, 0.000339f, 0.000454f, 0.000572f, 0.000595f, 0.000721f, 0.000604f, 0.000930f, 0.000958f, 0.001171f,
+ 0.001431f, 0.001888f, 0.002663f, 0.003256f, 0.004402f, 0.006527f, 0.009964f, 0.016281f, 0.031189f, 0.074524f, 0.258301f, 0.714355f,
+ 0.916016f, 0.965332f, 0.982422f, 0.989746f, 0.992676f, 0.995117f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000000f, 0.000063f, 0.000120f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000194f, 0.000184f, 0.000228f, 0.000340f, 0.000396f, 0.000668f, 0.000571f,
+ 0.000478f, 0.000602f, 0.000919f, 0.000956f, 0.001061f, 0.001497f, 0.001888f, 0.002565f, 0.003523f, 0.004578f, 0.006935f, 0.010765f,
+ 0.018417f, 0.038635f, 0.107727f, 0.416260f, 0.832520f, 0.946289f, 0.975586f, 0.986328f, 0.991699f, 0.994629f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000045f, 0.000118f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000234f, 0.000294f, 0.000220f, 0.000486f, 0.000579f, 0.000588f, 0.000669f, 0.000878f, 0.001038f, 0.001135f, 0.001451f, 0.001820f,
+ 0.002529f, 0.003551f, 0.005199f, 0.007542f, 0.012230f, 0.022369f, 0.051910f, 0.174927f, 0.630859f, 0.905273f, 0.965332f, 0.982910f,
+ 0.990234f, 0.993652f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000091f,
+ 0.000117f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000171f, 0.000151f, 0.000166f, 0.000195f, 0.000342f, 0.000452f, 0.000594f, 0.000599f,
+ 0.000862f, 0.001019f, 0.001135f, 0.001465f, 0.002031f, 0.002676f, 0.003714f, 0.005497f, 0.008286f, 0.014320f, 0.028854f, 0.077332f,
+ 0.322754f, 0.809082f, 0.946289f, 0.977051f, 0.987793f, 0.993164f, 0.998047f, 0.998535f, 0.998047f, 0.998047f, 0.998535f, 0.998047f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000079f, 0.000105f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000008f, 0.000006f, 0.000098f, 0.000137f,
+ 0.000233f, 0.000324f, 0.000566f, 0.000589f, 0.000618f, 0.000874f, 0.000941f, 0.001108f, 0.001621f, 0.001880f, 0.002726f, 0.003788f,
+ 0.005840f, 0.009583f, 0.017563f, 0.039368f, 0.133545f, 0.582520f, 0.906738f, 0.968262f, 0.984863f, 0.992188f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000069f, 0.000114f,
+ 0.000117f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000021f,
+ 0.000013f, 0.000009f, 0.000006f, 0.000004f, 0.000090f, 0.000206f, 0.000305f, 0.000538f, 0.000585f, 0.000596f, 0.000869f, 0.000941f,
+ 0.001149f, 0.001516f, 0.002150f, 0.002729f, 0.004475f, 0.006660f, 0.011360f, 0.022690f, 0.061401f, 0.281494f, 0.813965f, 0.952148f,
+ 0.980957f, 0.990723f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000085f, 0.000114f, 0.000117f, 0.000119f, 0.000119f, 0.000120f, 0.000120f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000122f, 0.000122f, 0.000077f, 0.000041f, 0.000022f, 0.000013f, 0.000009f, 0.000006f, 0.000066f, 0.000107f, 0.000223f, 0.000250f,
+ 0.000532f, 0.000576f, 0.000593f, 0.000784f, 0.000937f, 0.001126f, 0.001523f, 0.002306f, 0.003193f, 0.004574f, 0.007717f, 0.014191f,
+ 0.032410f, 0.116577f, 0.595215f, 0.921875f, 0.974609f, 0.988770f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000056f, 0.000112f,
+ 0.000114f, 0.000118f, 0.000119f, 0.000120f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000074f, 0.000038f, 0.000021f, 0.000013f, 0.000009f,
+ 0.000006f, 0.000004f, 0.000003f, 0.000179f, 0.000258f, 0.000367f, 0.000469f, 0.000583f, 0.000770f, 0.000932f, 0.001131f, 0.001758f,
+ 0.002483f, 0.003517f, 0.005432f, 0.009232f, 0.019302f, 0.054504f, 0.293457f, 0.853516f, 0.964844f, 0.986816f, 0.997070f, 0.997070f,
+ 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000015f, 0.000084f, 0.000107f, 0.000113f, 0.000117f, 0.000118f, 0.000119f, 0.000120f, 0.000120f,
+ 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000076f, 0.000042f, 0.000023f, 0.000015f, 0.000009f, 0.000007f, 0.000005f, 0.000004f, 0.000147f, 0.000238f, 0.000457f, 0.000545f,
+ 0.000586f, 0.000821f, 0.000936f, 0.001139f, 0.001849f, 0.002665f, 0.003687f, 0.006367f, 0.011810f, 0.028931f, 0.120605f, 0.687988f,
+ 0.947754f, 0.982910f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000082f, 0.000095f,
+ 0.000111f, 0.000115f, 0.000117f, 0.000118f, 0.000119f, 0.000119f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000083f, 0.000042f, 0.000026f, 0.000015f, 0.000010f, 0.000007f, 0.000005f,
+ 0.000013f, 0.000086f, 0.000185f, 0.000309f, 0.000552f, 0.000577f, 0.000796f, 0.000925f, 0.001251f, 0.001838f, 0.002878f, 0.004509f,
+ 0.007572f, 0.016617f, 0.054932f, 0.391602f, 0.912109f, 0.978516f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.996094f, 0.996094f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000095f, 0.000106f, 0.000112f, 0.000113f, 0.000115f, 0.000118f, 0.000118f,
+ 0.000119f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000099f, 0.000048f,
+ 0.000027f, 0.000017f, 0.000011f, 0.000008f, 0.000006f, 0.000004f, 0.000089f, 0.000182f, 0.000347f, 0.000495f, 0.000570f, 0.000777f,
+ 0.000922f, 0.001316f, 0.001831f, 0.003004f, 0.005028f, 0.010078f, 0.028183f, 0.161865f, 0.833496f, 0.972168f, 0.995117f, 0.995605f,
+ 0.995605f, 0.995117f, 0.995117f, 0.995605f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000074f,
+ 0.000093f, 0.000107f, 0.000111f, 0.000115f, 0.000116f, 0.000117f, 0.000118f, 0.000119f, 0.000119f, 0.000119f, 0.000120f, 0.000120f,
+ 0.000120f, 0.000120f, 0.000120f, 0.000121f, 0.000057f, 0.000032f, 0.000021f, 0.000013f, 0.000008f, 0.000006f, 0.000005f, 0.000034f,
+ 0.000159f, 0.000267f, 0.000514f, 0.000566f, 0.000714f, 0.000888f, 0.001348f, 0.001995f, 0.003302f, 0.006447f, 0.015945f, 0.069153f,
+ 0.646484f, 0.960449f, 0.994629f, 0.995117f, 0.994629f, 0.995117f, 0.994629f, 0.995117f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000080f, 0.000095f, 0.000102f, 0.000109f, 0.000114f, 0.000115f,
+ 0.000116f, 0.000118f, 0.000118f, 0.000119f, 0.000119f, 0.000119f, 0.000120f, 0.000120f, 0.000120f, 0.000077f, 0.000044f, 0.000025f,
+ 0.000015f, 0.000011f, 0.000007f, 0.000005f, 0.000004f, 0.000106f, 0.000244f, 0.000476f, 0.000561f, 0.000622f, 0.000893f, 0.001266f,
+ 0.001968f, 0.003990f, 0.009476f, 0.033234f, 0.342529f, 0.940918f, 0.993652f, 0.993652f, 0.993652f, 0.993652f, 0.993652f, 0.993652f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000046f, 0.000079f, 0.000093f, 0.000104f, 0.000110f, 0.000111f, 0.000113f, 0.000116f, 0.000117f, 0.000118f, 0.000118f, 0.000119f,
+ 0.000119f, 0.000119f, 0.000092f, 0.000050f, 0.000029f, 0.000019f, 0.000012f, 0.000009f, 0.000006f, 0.000004f, 0.000061f, 0.000188f,
+ 0.000324f, 0.000456f, 0.000525f, 0.000657f, 0.001371f, 0.002445f, 0.005634f, 0.017563f, 0.135986f, 0.902832f, 0.992188f, 0.992188f,
+ 0.992676f, 0.992188f, 0.992676f, 0.992188f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000038f, 0.000075f, 0.000092f, 0.000100f, 0.000105f,
+ 0.000111f, 0.000112f, 0.000114f, 0.000116f, 0.000117f, 0.000117f, 0.000118f, 0.000118f, 0.000074f, 0.000041f, 0.000024f, 0.000016f,
+ 0.000010f, 0.000007f, 0.000005f, 0.000033f, 0.000167f, 0.000423f, 0.000410f, 0.000413f, 0.000575f, 0.001446f, 0.003387f, 0.009644f,
+ 0.056183f, 0.817383f, 0.990234f, 0.990234f, 0.990234f, 0.990723f, 0.990234f, 0.990723f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000011f, 0.000067f, 0.000084f, 0.000096f, 0.000103f, 0.000108f, 0.000110f, 0.000113f, 0.000115f, 0.000115f,
+ 0.000116f, 0.000104f, 0.000057f, 0.000035f, 0.000021f, 0.000013f, 0.000009f, 0.000006f, 0.000054f, 0.000161f, 0.000317f, 0.000332f,
+ 0.000393f, 0.000723f, 0.001760f, 0.005203f, 0.025345f, 0.617676f, 0.987793f, 0.987793f, 0.987793f, 0.988281f, 0.988281f, 0.988281f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000017f, 0.000052f, 0.000075f,
+ 0.000091f, 0.000097f, 0.000105f, 0.000108f, 0.000111f, 0.000113f, 0.000114f, 0.000085f, 0.000050f, 0.000031f, 0.000018f, 0.000012f,
+ 0.000008f, 0.000005f, 0.000095f, 0.000314f, 0.000306f, 0.000363f, 0.000813f, 0.002583f, 0.011734f, 0.308105f, 0.983887f, 0.984375f,
+ 0.984375f, 0.984375f, 0.983887f, 0.983887f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000037f, 0.000065f, 0.000083f, 0.000093f, 0.000099f, 0.000105f, 0.000108f,
+ 0.000110f, 0.000082f, 0.000045f, 0.000027f, 0.000017f, 0.000011f, 0.000007f, 0.000114f, 0.000245f, 0.000209f, 0.000379f, 0.001151f,
+ 0.005260f, 0.107971f, 0.977539f, 0.979004f, 0.978027f, 0.978027f, 0.978027f, 0.978027f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000007f, 0.000045f, 0.000069f, 0.000084f, 0.000093f, 0.000099f, 0.000104f, 0.000076f, 0.000044f, 0.000026f, 0.000016f, 0.000010f,
+ 0.000012f, 0.000152f, 0.000179f, 0.000373f, 0.001760f, 0.035522f, 0.969238f, 0.968750f, 0.968750f, 0.968750f, 0.968750f, 0.968750f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000014f, 0.000050f, 0.000070f, 0.000082f,
+ 0.000092f, 0.000075f, 0.000044f, 0.000026f, 0.000015f, 0.000009f, 0.000121f, 0.000117f, 0.000611f, 0.010231f, 0.951172f, 0.951172f,
+ 0.951172f, 0.951172f, 0.950684f, 0.951660f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000020f, 0.000047f, 0.000069f, 0.000077f, 0.000042f, 0.000024f, 0.000013f, 0.000078f,
+ 0.000130f, 0.001914f, 0.915039f, 0.915527f, 0.915039f, 0.915527f, 0.916016f, 0.915039f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000017f, 0.000047f, 0.000040f, 0.000019f, 0.000035f, 0.000188f, 0.833984f, 0.833496f, 0.833496f, 0.834473f, 0.834473f, 0.833984f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000014f, 0.000007f, 0.642578f, 0.643555f,
+ 0.643066f, 0.643555f, 0.642578f, 0.642578f,
+ },
+ {
+ 0.113464f, 0.797852f, 0.930176f, 0.961914f, 0.974609f, 0.980469f, 0.984863f, 0.987793f, 0.989258f, 0.991211f, 0.992188f, 0.993164f,
+ 0.993652f, 0.994141f, 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.997559f,
+ 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.007183f, 0.058716f, 0.349609f, 0.784668f, 0.912598f, 0.952148f, 0.968262f, 0.977539f,
+ 0.981934f, 0.985352f, 0.988281f, 0.990234f, 0.991211f, 0.992188f, 0.993652f, 0.993652f, 0.994141f, 0.995117f, 0.995605f, 0.995605f,
+ 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.002432f, 0.011818f, 0.039581f, 0.143677f,
+ 0.482910f, 0.800293f, 0.908691f, 0.947266f, 0.964844f, 0.974609f, 0.980469f, 0.984375f, 0.987305f, 0.989258f, 0.990723f, 0.991699f,
+ 0.992676f, 0.993652f, 0.994141f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f,
+ 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.001096f, 0.005062f, 0.012482f, 0.030151f, 0.079956f, 0.239014f, 0.581055f, 0.819824f, 0.909180f, 0.946289f, 0.963379f, 0.973145f,
+ 0.979492f, 0.983398f, 0.986328f, 0.988281f, 0.990234f, 0.991699f, 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995605f, 0.996094f,
+ 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000610f, 0.002434f, 0.005779f, 0.012207f, 0.023972f, 0.052765f, 0.129883f, 0.342773f,
+ 0.660156f, 0.841309f, 0.914062f, 0.947266f, 0.963379f, 0.973145f, 0.979004f, 0.982910f, 0.985840f, 0.987793f, 0.989746f, 0.991211f,
+ 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995605f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f,
+ 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000397f, 0.001559f, 0.003397f, 0.006058f,
+ 0.011177f, 0.020355f, 0.039307f, 0.083130f, 0.196777f, 0.452148f, 0.724121f, 0.862305f, 0.920410f, 0.949219f, 0.964355f, 0.973145f,
+ 0.979004f, 0.982910f, 0.985840f, 0.988770f, 0.989258f, 0.991211f, 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995605f, 0.995605f,
+ 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000366f, 0.001097f, 0.002163f, 0.003523f, 0.006268f, 0.010941f, 0.017487f, 0.030930f, 0.058411f, 0.122925f, 0.281738f, 0.556152f,
+ 0.776367f, 0.881348f, 0.928223f, 0.951660f, 0.966309f, 0.973633f, 0.979492f, 0.983398f, 0.986328f, 0.988281f, 0.989746f, 0.991211f,
+ 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995605f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000244f, 0.000728f, 0.001340f, 0.002533f, 0.003813f, 0.006081f, 0.009750f, 0.015419f,
+ 0.025177f, 0.044067f, 0.084473f, 0.179077f, 0.384033f, 0.649902f, 0.818848f, 0.897949f, 0.935547f, 0.956055f, 0.967285f, 0.975098f,
+ 0.980957f, 0.983887f, 0.986328f, 0.988281f, 0.990234f, 0.991699f, 0.992676f, 0.993652f, 0.994141f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000244f, 0.000609f, 0.000854f, 0.001898f,
+ 0.002781f, 0.004246f, 0.006218f, 0.008835f, 0.013504f, 0.021362f, 0.035400f, 0.062347f, 0.121460f, 0.255127f, 0.495361f, 0.726562f,
+ 0.852539f, 0.912598f, 0.943359f, 0.959473f, 0.969238f, 0.976562f, 0.981445f, 0.984375f, 0.987305f, 0.988770f, 0.990234f, 0.991699f,
+ 0.992676f, 0.993652f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000244f, 0.000244f, 0.000731f, 0.001295f, 0.002159f, 0.003092f, 0.004051f, 0.005836f, 0.008560f, 0.011925f, 0.018585f, 0.029373f,
+ 0.048950f, 0.088013f, 0.174194f, 0.354980f, 0.604492f, 0.788086f, 0.880371f, 0.925293f, 0.950195f, 0.963867f, 0.972168f, 0.978027f,
+ 0.982422f, 0.985840f, 0.987793f, 0.990234f, 0.991699f, 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000114f, 0.000244f, 0.000709f, 0.001089f, 0.001580f, 0.002100f, 0.002848f, 0.004028f,
+ 0.005646f, 0.008232f, 0.011276f, 0.016647f, 0.024948f, 0.039215f, 0.067566f, 0.125244f, 0.249878f, 0.471436f, 0.698242f, 0.834961f,
+ 0.902344f, 0.937012f, 0.955078f, 0.967773f, 0.974609f, 0.979492f, 0.983887f, 0.987305f, 0.988770f, 0.990723f, 0.991699f, 0.992676f,
+ 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f,
+ 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000244f, 0.000480f, 0.001081f,
+ 0.001216f, 0.001684f, 0.002287f, 0.003113f, 0.004246f, 0.005711f, 0.007412f, 0.010658f, 0.014900f, 0.021408f, 0.033173f, 0.053711f,
+ 0.094299f, 0.179688f, 0.351807f, 0.591309f, 0.774902f, 0.871582f, 0.919922f, 0.946289f, 0.961426f, 0.971191f, 0.977051f, 0.981934f,
+ 0.984863f, 0.987305f, 0.989258f, 0.991211f, 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000364f, 0.000366f, 0.000729f, 0.001195f, 0.001218f, 0.001693f, 0.002209f, 0.003038f, 0.004192f, 0.005249f, 0.006981f,
+ 0.009926f, 0.013405f, 0.019165f, 0.028473f, 0.044250f, 0.073975f, 0.134521f, 0.260010f, 0.476562f, 0.696289f, 0.830566f, 0.898438f,
+ 0.933594f, 0.954102f, 0.966309f, 0.974609f, 0.979492f, 0.982910f, 0.986328f, 0.988281f, 0.989746f, 0.991699f, 0.992676f, 0.993652f,
+ 0.994141f, 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000226f, 0.000365f, 0.000488f, 0.000731f, 0.001090f, 0.001245f, 0.002028f,
+ 0.002169f, 0.003023f, 0.003952f, 0.005043f, 0.006790f, 0.009026f, 0.012276f, 0.016754f, 0.024628f, 0.037384f, 0.060120f, 0.104431f,
+ 0.196045f, 0.372803f, 0.604980f, 0.779785f, 0.872070f, 0.919922f, 0.945312f, 0.960938f, 0.970703f, 0.977539f, 0.980957f, 0.984863f,
+ 0.987305f, 0.989258f, 0.991211f, 0.992188f, 0.993164f, 0.993652f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.996582f,
+ 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000364f, 0.000487f,
+ 0.000488f, 0.000608f, 0.001092f, 0.001323f, 0.001909f, 0.002028f, 0.002829f, 0.003754f, 0.004940f, 0.006329f, 0.008850f, 0.011353f,
+ 0.015572f, 0.022110f, 0.032196f, 0.050293f, 0.083984f, 0.151978f, 0.288574f, 0.507812f, 0.715332f, 0.839844f, 0.902832f, 0.936035f,
+ 0.955566f, 0.966797f, 0.974609f, 0.979492f, 0.983887f, 0.986816f, 0.988281f, 0.989746f, 0.991699f, 0.992676f, 0.993652f, 0.994141f,
+ 0.994629f, 0.995605f, 0.995605f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000341f, 0.000486f, 0.000487f, 0.000591f, 0.000846f, 0.001213f, 0.001407f, 0.002018f, 0.002306f, 0.003119f,
+ 0.003736f, 0.004700f, 0.005936f, 0.007858f, 0.010498f, 0.013939f, 0.019913f, 0.028564f, 0.043060f, 0.069275f, 0.120972f, 0.225830f,
+ 0.416748f, 0.642090f, 0.798828f, 0.881836f, 0.924805f, 0.948730f, 0.962891f, 0.971191f, 0.978516f, 0.982422f, 0.985352f, 0.987793f,
+ 0.989746f, 0.991211f, 0.992676f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996582f, 0.996582f, 0.996582f, 0.997070f,
+ 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000121f, 0.000122f, 0.000475f, 0.000486f, 0.000487f, 0.000714f, 0.000913f,
+ 0.001296f, 0.001350f, 0.001884f, 0.002163f, 0.002871f, 0.003702f, 0.004578f, 0.005573f, 0.007278f, 0.009819f, 0.013039f, 0.017883f,
+ 0.025589f, 0.037445f, 0.058655f, 0.099243f, 0.180542f, 0.338867f, 0.563965f, 0.751465f, 0.857422f, 0.912109f, 0.941406f, 0.958496f,
+ 0.968262f, 0.976074f, 0.980957f, 0.984375f, 0.986816f, 0.989258f, 0.990723f, 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995117f,
+ 0.995605f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000122f, 0.000242f,
+ 0.000417f, 0.000607f, 0.000602f, 0.000644f, 0.001016f, 0.001223f, 0.001337f, 0.002010f, 0.002087f, 0.002752f, 0.003380f, 0.004486f,
+ 0.005760f, 0.007523f, 0.009048f, 0.012169f, 0.016312f, 0.022949f, 0.033295f, 0.050812f, 0.082886f, 0.146851f, 0.275635f, 0.486572f,
+ 0.696777f, 0.828613f, 0.896484f, 0.933594f, 0.953613f, 0.965820f, 0.973633f, 0.979980f, 0.983887f, 0.986328f, 0.988770f, 0.990723f,
+ 0.992188f, 0.993164f, 0.993652f, 0.994141f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997559f, 0.997559f, 0.997559f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000262f, 0.000463f, 0.000603f, 0.000665f, 0.000716f, 0.001069f, 0.001322f, 0.001538f,
+ 0.001895f, 0.002293f, 0.003120f, 0.003323f, 0.004166f, 0.005638f, 0.006828f, 0.008942f, 0.011368f, 0.015465f, 0.021057f, 0.029663f,
+ 0.044861f, 0.070923f, 0.123169f, 0.228149f, 0.416504f, 0.640137f, 0.797363f, 0.880859f, 0.924805f, 0.948730f, 0.963379f, 0.971680f,
+ 0.978516f, 0.982422f, 0.985840f, 0.988281f, 0.990723f, 0.991699f, 0.992676f, 0.993652f, 0.994141f, 0.995117f, 0.995117f, 0.996094f,
+ 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000120f, 0.000172f, 0.000243f, 0.000365f, 0.000475f, 0.000607f,
+ 0.000608f, 0.000609f, 0.001013f, 0.001424f, 0.001456f, 0.001904f, 0.002411f, 0.002903f, 0.003145f, 0.004314f, 0.004944f, 0.006607f,
+ 0.008156f, 0.010719f, 0.014297f, 0.018906f, 0.027069f, 0.040070f, 0.062103f, 0.104858f, 0.191162f, 0.355469f, 0.581543f, 0.762695f,
+ 0.863281f, 0.915039f, 0.943848f, 0.960449f, 0.970703f, 0.977051f, 0.981445f, 0.985840f, 0.987793f, 0.989746f, 0.991211f, 0.992676f,
+ 0.993652f, 0.994141f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.997070f, 0.997070f, 0.998047f, 0.997559f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000000f, 0.000000f, 0.000096f,
+ 0.000239f, 0.000241f, 0.000336f, 0.000482f, 0.000719f, 0.000729f, 0.000831f, 0.001049f, 0.001552f, 0.001576f, 0.001710f, 0.002373f,
+ 0.002846f, 0.003254f, 0.004051f, 0.005035f, 0.006405f, 0.007706f, 0.009987f, 0.013092f, 0.017715f, 0.024872f, 0.035980f, 0.055328f,
+ 0.091248f, 0.163330f, 0.305664f, 0.524902f, 0.726562f, 0.845215f, 0.906250f, 0.938965f, 0.957031f, 0.969238f, 0.976074f, 0.981445f,
+ 0.984863f, 0.987305f, 0.989258f, 0.991211f, 0.992188f, 0.993164f, 0.994141f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.996582f,
+ 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000118f, 0.000120f, 0.000351f, 0.000364f, 0.000421f, 0.000480f, 0.000606f, 0.000728f, 0.000852f,
+ 0.001175f, 0.001535f, 0.001673f, 0.001671f, 0.002277f, 0.002743f, 0.003220f, 0.003922f, 0.004868f, 0.005951f, 0.007488f, 0.009430f,
+ 0.012527f, 0.016266f, 0.022964f, 0.033142f, 0.049805f, 0.080688f, 0.141846f, 0.265625f, 0.473145f, 0.688477f, 0.825684f, 0.897949f,
+ 0.934082f, 0.954102f, 0.966797f, 0.975098f, 0.980469f, 0.984375f, 0.987305f, 0.989258f, 0.991211f, 0.992676f, 0.993164f, 0.993652f,
+ 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000058f, 0.000235f, 0.000360f, 0.000243f,
+ 0.000440f, 0.000583f, 0.000847f, 0.000851f, 0.000852f, 0.001189f, 0.001411f, 0.001645f, 0.001898f, 0.002417f, 0.002617f, 0.003435f,
+ 0.003695f, 0.004616f, 0.005733f, 0.007278f, 0.009216f, 0.012016f, 0.015701f, 0.021561f, 0.030396f, 0.045746f, 0.073120f, 0.125732f,
+ 0.233521f, 0.428223f, 0.653320f, 0.807617f, 0.887695f, 0.929688f, 0.951660f, 0.965820f, 0.974121f, 0.980469f, 0.984375f, 0.986816f,
+ 0.989746f, 0.991211f, 0.992676f, 0.993164f, 0.994141f, 0.995117f, 0.995605f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000237f, 0.000237f, 0.000362f, 0.000365f, 0.000558f, 0.000814f, 0.000727f, 0.000729f, 0.000935f, 0.001189f, 0.001403f,
+ 0.001569f, 0.001989f, 0.002216f, 0.002533f, 0.003307f, 0.003906f, 0.004463f, 0.005646f, 0.006908f, 0.008980f, 0.011230f, 0.014755f,
+ 0.020020f, 0.028320f, 0.041931f, 0.065979f, 0.113098f, 0.209229f, 0.389648f, 0.620605f, 0.789551f, 0.879395f, 0.924805f, 0.950684f,
+ 0.964844f, 0.974121f, 0.979980f, 0.983398f, 0.987305f, 0.989258f, 0.991211f, 0.992676f, 0.993652f, 0.993652f, 0.995117f, 0.995605f,
+ 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000121f, 0.000241f, 0.000486f, 0.000575f, 0.000707f,
+ 0.000726f, 0.000971f, 0.000849f, 0.000966f, 0.001350f, 0.001660f, 0.001678f, 0.002224f, 0.002483f, 0.003197f, 0.003611f, 0.004200f,
+ 0.005318f, 0.006744f, 0.008476f, 0.010506f, 0.014145f, 0.019089f, 0.026627f, 0.039001f, 0.061096f, 0.103333f, 0.189819f, 0.358887f,
+ 0.591309f, 0.773438f, 0.872559f, 0.922363f, 0.948730f, 0.963867f, 0.973145f, 0.979492f, 0.983887f, 0.986816f, 0.989258f, 0.991211f,
+ 0.992188f, 0.993164f, 0.994629f, 0.995117f, 0.995605f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000175f, 0.000361f,
+ 0.000481f, 0.000485f, 0.000364f, 0.000562f, 0.000703f, 0.000827f, 0.000842f, 0.000972f, 0.001172f, 0.001321f, 0.001675f, 0.001684f,
+ 0.002153f, 0.002455f, 0.003122f, 0.003391f, 0.004177f, 0.005314f, 0.006325f, 0.007896f, 0.010368f, 0.013527f, 0.018082f, 0.025162f,
+ 0.037140f, 0.057343f, 0.095886f, 0.175659f, 0.334473f, 0.567871f, 0.760742f, 0.866699f, 0.919922f, 0.947754f, 0.963379f, 0.972656f,
+ 0.979492f, 0.984375f, 0.987305f, 0.989258f, 0.991211f, 0.992676f, 0.993652f, 0.994629f, 0.995117f, 0.996094f, 0.996582f, 0.997070f,
+ 0.998047f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000325f, 0.000311f, 0.000243f, 0.000484f, 0.000486f, 0.000536f, 0.000698f, 0.000723f, 0.000844f,
+ 0.000972f, 0.001081f, 0.001312f, 0.001658f, 0.001914f, 0.001932f, 0.002390f, 0.003017f, 0.003668f, 0.004353f, 0.005199f, 0.006336f,
+ 0.007812f, 0.009972f, 0.012802f, 0.017029f, 0.024200f, 0.035034f, 0.053833f, 0.090027f, 0.164185f, 0.316162f, 0.549805f, 0.751465f,
+ 0.863281f, 0.918457f, 0.947266f, 0.963379f, 0.974121f, 0.979492f, 0.984375f, 0.987793f, 0.989746f, 0.991699f, 0.993164f, 0.994141f,
+ 0.995117f, 0.995605f, 0.996094f, 0.997070f, 0.997559f, 0.997559f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000231f, 0.000453f, 0.000480f, 0.000484f,
+ 0.000485f, 0.000486f, 0.000917f, 0.000963f, 0.000969f, 0.000970f, 0.001043f, 0.001288f, 0.001523f, 0.001684f, 0.001885f, 0.002464f,
+ 0.002531f, 0.003565f, 0.004124f, 0.004745f, 0.006077f, 0.007580f, 0.009605f, 0.012634f, 0.016953f, 0.023346f, 0.033386f, 0.051697f,
+ 0.085632f, 0.156250f, 0.303955f, 0.537598f, 0.746582f, 0.860840f, 0.918457f, 0.947754f, 0.963867f, 0.973633f, 0.979980f, 0.984863f,
+ 0.987793f, 0.990234f, 0.991699f, 0.993652f, 0.994141f, 0.995117f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000235f, 0.000239f, 0.000359f, 0.000484f, 0.000485f, 0.000486f, 0.000628f, 0.000957f, 0.000967f, 0.000969f, 0.001065f,
+ 0.001288f, 0.001602f, 0.001850f, 0.001995f, 0.002409f, 0.002523f, 0.003462f, 0.003838f, 0.004993f, 0.005917f, 0.007233f, 0.009338f,
+ 0.012230f, 0.015610f, 0.022415f, 0.032288f, 0.049805f, 0.082947f, 0.151489f, 0.296631f, 0.532715f, 0.745117f, 0.862793f, 0.919434f,
+ 0.948242f, 0.964844f, 0.974609f, 0.980957f, 0.985352f, 0.988281f, 0.990723f, 0.992676f, 0.994141f, 0.994629f, 0.995605f, 0.996094f,
+ 0.996582f, 0.997070f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000187f, 0.000437f, 0.000473f, 0.000483f, 0.000485f, 0.000606f,
+ 0.000583f, 0.000711f, 0.000772f, 0.000968f, 0.001107f, 0.001287f, 0.001434f, 0.001662f, 0.001984f, 0.002449f, 0.002634f, 0.003145f,
+ 0.003777f, 0.004410f, 0.005722f, 0.007114f, 0.008926f, 0.011696f, 0.016006f, 0.021683f, 0.031342f, 0.048309f, 0.080750f, 0.149170f,
+ 0.294678f, 0.534668f, 0.749512f, 0.866211f, 0.922363f, 0.950684f, 0.966309f, 0.975586f, 0.981934f, 0.985840f, 0.989258f, 0.991699f,
+ 0.992676f, 0.994141f, 0.994629f, 0.996094f, 0.996582f, 0.997070f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000247f,
+ 0.000238f, 0.000407f, 0.000482f, 0.000484f, 0.000604f, 0.000869f, 0.000909f, 0.000721f, 0.000955f, 0.001000f, 0.001241f, 0.001342f,
+ 0.001655f, 0.001721f, 0.002329f, 0.002623f, 0.003086f, 0.003677f, 0.004349f, 0.005600f, 0.006962f, 0.008835f, 0.011581f, 0.015274f,
+ 0.021286f, 0.030884f, 0.047760f, 0.079895f, 0.148926f, 0.298584f, 0.543945f, 0.758301f, 0.872559f, 0.925781f, 0.953125f, 0.967773f,
+ 0.977051f, 0.982910f, 0.986816f, 0.989258f, 0.991211f, 0.993164f, 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000237f, 0.000410f, 0.000472f, 0.000481f, 0.000483f, 0.000485f, 0.000687f, 0.000913f,
+ 0.000956f, 0.000966f, 0.000997f, 0.001341f, 0.001415f, 0.001813f, 0.002029f, 0.002043f, 0.002594f, 0.003210f, 0.003641f, 0.004734f,
+ 0.005356f, 0.006882f, 0.008675f, 0.011360f, 0.014816f, 0.020920f, 0.030380f, 0.047485f, 0.080200f, 0.151733f, 0.308105f, 0.561523f,
+ 0.772949f, 0.881348f, 0.931152f, 0.956055f, 0.969727f, 0.978516f, 0.983887f, 0.987793f, 0.990234f, 0.992188f, 0.993652f, 0.994629f,
+ 0.995605f, 0.996094f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000254f, 0.000345f, 0.000468f,
+ 0.000585f, 0.000482f, 0.000603f, 0.000485f, 0.000862f, 0.000928f, 0.000965f, 0.001174f, 0.001162f, 0.001405f, 0.001761f, 0.002016f,
+ 0.002182f, 0.002733f, 0.002831f, 0.003504f, 0.004456f, 0.005440f, 0.006775f, 0.008553f, 0.011055f, 0.014694f, 0.020859f, 0.030334f,
+ 0.047852f, 0.081970f, 0.157593f, 0.325439f, 0.586914f, 0.790527f, 0.890137f, 0.936523f, 0.959473f, 0.973145f, 0.980469f, 0.985352f,
+ 0.988770f, 0.990723f, 0.992676f, 0.994141f, 0.995117f, 0.996094f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000241f, 0.000237f, 0.000340f, 0.000457f, 0.000580f, 0.000481f, 0.000601f, 0.000605f, 0.000742f, 0.000951f, 0.000953f,
+ 0.001131f, 0.001257f, 0.001396f, 0.001730f, 0.001936f, 0.002102f, 0.002682f, 0.002762f, 0.003733f, 0.004425f, 0.005344f, 0.006516f,
+ 0.008354f, 0.010971f, 0.014793f, 0.020859f, 0.030640f, 0.048859f, 0.085144f, 0.167358f, 0.350586f, 0.620117f, 0.811035f, 0.900391f,
+ 0.942383f, 0.963379f, 0.975098f, 0.981934f, 0.986816f, 0.989746f, 0.992188f, 0.993164f, 0.994629f, 0.995117f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000131f, 0.000301f, 0.000430f, 0.000470f, 0.000593f,
+ 0.000571f, 0.000587f, 0.000693f, 0.000906f, 0.000959f, 0.000965f, 0.001094f, 0.001364f, 0.001522f, 0.001783f, 0.002094f, 0.002615f,
+ 0.003038f, 0.003365f, 0.004307f, 0.005135f, 0.006493f, 0.008347f, 0.011055f, 0.014824f, 0.020844f, 0.031204f, 0.050507f, 0.090027f,
+ 0.182129f, 0.385498f, 0.659668f, 0.834473f, 0.913086f, 0.949219f, 0.967285f, 0.978027f, 0.983887f, 0.987793f, 0.991211f, 0.992188f,
+ 0.994141f, 0.995117f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000189f, 0.000122f, 0.000122f,
+ 0.000241f, 0.000295f, 0.000425f, 0.000457f, 0.000592f, 0.000481f, 0.000603f, 0.000697f, 0.000926f, 0.000943f, 0.000960f, 0.001022f,
+ 0.001435f, 0.001632f, 0.001658f, 0.002024f, 0.002468f, 0.003010f, 0.003210f, 0.004124f, 0.005219f, 0.006351f, 0.008163f, 0.010933f,
+ 0.015030f, 0.021271f, 0.032257f, 0.053009f, 0.097534f, 0.203003f, 0.432373f, 0.704102f, 0.858887f, 0.924805f, 0.955566f, 0.970703f,
+ 0.979492f, 0.985840f, 0.989258f, 0.991699f, 0.993164f, 0.995117f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000214f, 0.000201f, 0.000239f, 0.000241f, 0.000383f, 0.000461f, 0.000474f, 0.000479f, 0.000598f,
+ 0.000736f, 0.000905f, 0.000947f, 0.001072f, 0.001180f, 0.001376f, 0.001572f, 0.001752f, 0.001900f, 0.002258f, 0.002792f, 0.003487f,
+ 0.004055f, 0.005161f, 0.006424f, 0.008209f, 0.010933f, 0.015030f, 0.021942f, 0.033630f, 0.056671f, 0.107666f, 0.233276f, 0.492188f,
+ 0.752441f, 0.881836f, 0.937012f, 0.961914f, 0.975098f, 0.982910f, 0.987305f, 0.990234f, 0.992676f, 0.994629f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998047f, 0.998535f, 0.998535f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000132f, 0.000224f, 0.000129f, 0.000237f, 0.000240f,
+ 0.000337f, 0.000430f, 0.000468f, 0.000579f, 0.000593f, 0.000602f, 0.000881f, 0.000936f, 0.000956f, 0.000963f, 0.001282f, 0.001519f,
+ 0.001607f, 0.001852f, 0.002150f, 0.002737f, 0.003508f, 0.003990f, 0.005077f, 0.006516f, 0.008179f, 0.011185f, 0.015511f, 0.022446f,
+ 0.035614f, 0.061859f, 0.122681f, 0.275879f, 0.563965f, 0.798828f, 0.903809f, 0.946777f, 0.967773f, 0.978516f, 0.984863f, 0.988770f,
+ 0.991699f, 0.993652f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000149f, 0.000122f, 0.000207f, 0.000371f, 0.000430f, 0.000573f, 0.000591f, 0.000598f, 0.000597f, 0.000804f,
+ 0.000901f, 0.000948f, 0.001053f, 0.001083f, 0.001376f, 0.001584f, 0.001878f, 0.002331f, 0.002529f, 0.003376f, 0.003944f, 0.005230f,
+ 0.006504f, 0.008537f, 0.011459f, 0.015747f, 0.024002f, 0.038361f, 0.069458f, 0.144409f, 0.336914f, 0.644043f, 0.841797f, 0.922363f,
+ 0.957520f, 0.972656f, 0.981934f, 0.987305f, 0.990234f, 0.993164f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998047f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000230f, 0.000234f, 0.000235f, 0.000268f, 0.000400f,
+ 0.000448f, 0.000585f, 0.000590f, 0.000599f, 0.000641f, 0.000788f, 0.000930f, 0.000968f, 0.001107f, 0.001251f, 0.001656f, 0.001701f,
+ 0.002047f, 0.002691f, 0.003437f, 0.003998f, 0.004829f, 0.006329f, 0.008492f, 0.011757f, 0.016525f, 0.025345f, 0.042297f, 0.080200f,
+ 0.177490f, 0.420654f, 0.724121f, 0.878906f, 0.938965f, 0.964355f, 0.977539f, 0.984863f, 0.989746f, 0.992188f, 0.997559f, 0.997559f,
+ 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000214f, 0.000235f, 0.000228f, 0.000240f, 0.000429f, 0.000439f, 0.000574f, 0.000654f, 0.000583f, 0.000493f, 0.000788f, 0.000813f,
+ 0.000947f, 0.001062f, 0.001225f, 0.001569f, 0.001721f, 0.002048f, 0.002844f, 0.002979f, 0.003902f, 0.004997f, 0.006454f, 0.008698f,
+ 0.012192f, 0.018143f, 0.027634f, 0.047913f, 0.095886f, 0.228394f, 0.526855f, 0.796875f, 0.910156f, 0.953125f, 0.973145f, 0.982422f,
+ 0.987793f, 0.991699f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000205f, 0.000236f, 0.000232f, 0.000299f, 0.000446f, 0.000417f,
+ 0.000466f, 0.000580f, 0.000508f, 0.000710f, 0.000800f, 0.000940f, 0.000954f, 0.001228f, 0.001496f, 0.001631f, 0.002043f, 0.002798f,
+ 0.003359f, 0.004139f, 0.004951f, 0.006680f, 0.008995f, 0.012764f, 0.018860f, 0.030823f, 0.056061f, 0.120911f, 0.307617f, 0.645508f,
+ 0.855957f, 0.934082f, 0.964355f, 0.978516f, 0.985840f, 0.990234f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000226f,
+ 0.000122f, 0.000226f, 0.000373f, 0.000272f, 0.000325f, 0.000460f, 0.000471f, 0.000477f, 0.000673f, 0.000877f, 0.000929f, 0.000951f,
+ 0.001129f, 0.001446f, 0.001614f, 0.002096f, 0.002619f, 0.002939f, 0.003941f, 0.005363f, 0.006844f, 0.009491f, 0.013596f, 0.020905f,
+ 0.035370f, 0.068420f, 0.161743f, 0.426270f, 0.755859f, 0.900879f, 0.952148f, 0.973145f, 0.983398f, 0.989746f, 0.997070f, 0.997070f,
+ 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000111f, 0.000236f, 0.000297f, 0.000368f, 0.000449f, 0.000467f,
+ 0.000588f, 0.000641f, 0.000813f, 0.000924f, 0.001035f, 0.001124f, 0.001348f, 0.001764f, 0.001922f, 0.002439f, 0.003160f, 0.004005f,
+ 0.005280f, 0.007107f, 0.010109f, 0.014748f, 0.023148f, 0.041595f, 0.088440f, 0.232910f, 0.578125f, 0.841797f, 0.933594f, 0.965820f,
+ 0.980469f, 0.987305f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000014f, 0.000011f, 0.000116f,
+ 0.000148f, 0.000128f, 0.000369f, 0.000418f, 0.000563f, 0.000470f, 0.000592f, 0.000776f, 0.000901f, 0.000937f, 0.001112f, 0.001348f,
+ 0.001743f, 0.001904f, 0.002470f, 0.003187f, 0.003986f, 0.005360f, 0.007557f, 0.010674f, 0.016068f, 0.026871f, 0.051666f, 0.122925f,
+ 0.356445f, 0.729492f, 0.901855f, 0.955078f, 0.976074f, 0.985840f, 0.996094f, 0.996582f, 0.996094f, 0.996582f, 0.996094f, 0.996582f,
+ 0.000122f, 0.000122f, 0.000121f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000028f, 0.000019f, 0.000014f, 0.000011f, 0.000033f, 0.000118f, 0.000247f, 0.000305f, 0.000412f, 0.000447f, 0.000576f, 0.000587f,
+ 0.000693f, 0.000850f, 0.000949f, 0.001083f, 0.001319f, 0.001557f, 0.001957f, 0.002424f, 0.003340f, 0.004417f, 0.005688f, 0.007774f,
+ 0.011497f, 0.017731f, 0.032257f, 0.068604f, 0.189575f, 0.541992f, 0.843262f, 0.938477f, 0.970703f, 0.983887f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.000121f, 0.000118f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000067f, 0.000042f, 0.000028f, 0.000020f, 0.000015f, 0.000066f, 0.000009f, 0.000101f, 0.000118f,
+ 0.000260f, 0.000358f, 0.000520f, 0.000456f, 0.000563f, 0.000711f, 0.000872f, 0.000980f, 0.001059f, 0.001309f, 0.001699f, 0.002066f,
+ 0.002708f, 0.003248f, 0.004166f, 0.005836f, 0.008224f, 0.012619f, 0.021484f, 0.041260f, 0.101074f, 0.323486f, 0.733887f, 0.912109f,
+ 0.962402f, 0.980957f, 0.995117f, 0.995117f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.000000f, 0.000000f, 0.000119f, 0.000119f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000105f, 0.000067f, 0.000042f, 0.000029f, 0.000022f,
+ 0.000015f, 0.000011f, 0.000040f, 0.000033f, 0.000153f, 0.000204f, 0.000313f, 0.000501f, 0.000554f, 0.000575f, 0.000585f, 0.000778f,
+ 0.000925f, 0.000980f, 0.001245f, 0.001634f, 0.001989f, 0.002413f, 0.003433f, 0.004028f, 0.005989f, 0.008911f, 0.014374f, 0.026443f,
+ 0.057495f, 0.170166f, 0.549805f, 0.864746f, 0.951172f, 0.977051f, 0.994629f, 0.994629f, 0.994629f, 0.994629f, 0.995605f, 0.994629f,
+ 0.000000f, 0.000046f, 0.000088f, 0.000118f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000108f, 0.000069f, 0.000047f, 0.000030f, 0.000022f, 0.000016f, 0.000012f, 0.000052f, 0.000081f, 0.000100f, 0.000184f, 0.000226f,
+ 0.000400f, 0.000467f, 0.000452f, 0.000597f, 0.000807f, 0.000895f, 0.000942f, 0.001219f, 0.001611f, 0.002022f, 0.002352f, 0.003222f,
+ 0.004177f, 0.006481f, 0.009850f, 0.017517f, 0.034668f, 0.090637f, 0.331055f, 0.776367f, 0.932129f, 0.972656f, 0.994141f, 0.994141f,
+ 0.994629f, 0.994141f, 0.994629f, 0.994629f, 0.000000f, 0.000000f, 0.000000f, 0.000107f, 0.000115f, 0.000112f, 0.000119f, 0.000118f,
+ 0.000119f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000117f, 0.000072f, 0.000049f, 0.000032f, 0.000023f, 0.000017f, 0.000013f,
+ 0.000011f, 0.000008f, 0.000075f, 0.000151f, 0.000207f, 0.000305f, 0.000509f, 0.000499f, 0.000560f, 0.000704f, 0.000863f, 0.000917f,
+ 0.001220f, 0.001505f, 0.001740f, 0.002174f, 0.003153f, 0.004559f, 0.007095f, 0.011826f, 0.022247f, 0.051147f, 0.173462f, 0.618652f,
+ 0.902344f, 0.966309f, 0.993164f, 0.993652f, 0.992676f, 0.992676f, 0.993164f, 0.993164f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000060f, 0.000102f, 0.000113f, 0.000117f, 0.000118f, 0.000119f, 0.000119f, 0.000119f, 0.000120f, 0.000120f, 0.000120f,
+ 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000078f,
+ 0.000052f, 0.000038f, 0.000027f, 0.000019f, 0.000015f, 0.000011f, 0.000054f, 0.000007f, 0.000085f, 0.000108f, 0.000258f, 0.000466f,
+ 0.000533f, 0.000560f, 0.000662f, 0.000849f, 0.000856f, 0.000965f, 0.001180f, 0.001678f, 0.002075f, 0.003193f, 0.005016f, 0.008095f,
+ 0.014343f, 0.030899f, 0.090820f, 0.401367f, 0.848145f, 0.956543f, 0.992188f, 0.992188f, 0.992188f, 0.992676f, 0.991699f, 0.992188f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000059f, 0.000096f, 0.000107f, 0.000112f, 0.000115f, 0.000116f,
+ 0.000117f, 0.000118f, 0.000118f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f,
+ 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000088f, 0.000059f, 0.000041f, 0.000031f, 0.000022f, 0.000017f, 0.000013f, 0.000010f,
+ 0.000056f, 0.000091f, 0.000183f, 0.000201f, 0.000309f, 0.000506f, 0.000547f, 0.000525f, 0.000629f, 0.000613f, 0.000817f, 0.001012f,
+ 0.001640f, 0.002420f, 0.003588f, 0.005520f, 0.009453f, 0.019119f, 0.050415f, 0.214722f, 0.751465f, 0.943848f, 0.990723f, 0.990723f,
+ 0.991211f, 0.991211f, 0.991211f, 0.991211f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000055f, 0.000095f, 0.000103f, 0.000105f, 0.000112f, 0.000114f, 0.000115f, 0.000117f, 0.000117f, 0.000117f, 0.000118f,
+ 0.000118f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000120f, 0.000120f, 0.000105f, 0.000069f, 0.000048f,
+ 0.000035f, 0.000025f, 0.000019f, 0.000015f, 0.000011f, 0.000014f, 0.000008f, 0.000071f, 0.000193f, 0.000311f, 0.000315f, 0.000524f,
+ 0.000483f, 0.000558f, 0.000591f, 0.000705f, 0.000950f, 0.001389f, 0.002428f, 0.003494f, 0.006321f, 0.012306f, 0.029480f, 0.108948f,
+ 0.581543f, 0.924316f, 0.989746f, 0.989746f, 0.989258f, 0.989746f, 0.989258f, 0.989746f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000069f, 0.000096f, 0.000103f, 0.000107f,
+ 0.000109f, 0.000112f, 0.000113f, 0.000115f, 0.000115f, 0.000116f, 0.000117f, 0.000117f, 0.000118f, 0.000118f, 0.000118f, 0.000118f,
+ 0.000119f, 0.000119f, 0.000119f, 0.000084f, 0.000061f, 0.000042f, 0.000031f, 0.000023f, 0.000018f, 0.000014f, 0.000011f, 0.000009f,
+ 0.000095f, 0.000127f, 0.000223f, 0.000402f, 0.000432f, 0.000399f, 0.000494f, 0.000535f, 0.000557f, 0.000933f, 0.001474f, 0.002300f,
+ 0.004192f, 0.007919f, 0.017838f, 0.057068f, 0.360840f, 0.890625f, 0.986816f, 0.987793f, 0.987305f, 0.987305f, 0.987793f, 0.987305f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000035f, 0.000041f, 0.000088f, 0.000098f, 0.000103f, 0.000106f, 0.000110f, 0.000110f, 0.000113f, 0.000113f,
+ 0.000115f, 0.000116f, 0.000116f, 0.000117f, 0.000117f, 0.000117f, 0.000117f, 0.000118f, 0.000111f, 0.000074f, 0.000053f, 0.000038f,
+ 0.000029f, 0.000022f, 0.000016f, 0.000013f, 0.000010f, 0.000008f, 0.000073f, 0.000152f, 0.000296f, 0.000369f, 0.000365f, 0.000437f,
+ 0.000507f, 0.000661f, 0.000876f, 0.001451f, 0.002531f, 0.004898f, 0.010384f, 0.031113f, 0.183838f, 0.833008f, 0.984375f, 0.984863f,
+ 0.984863f, 0.984375f, 0.984863f, 0.984863f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000024f, 0.000044f, 0.000073f,
+ 0.000087f, 0.000097f, 0.000102f, 0.000105f, 0.000108f, 0.000110f, 0.000111f, 0.000113f, 0.000114f, 0.000114f, 0.000115f, 0.000115f,
+ 0.000116f, 0.000116f, 0.000101f, 0.000070f, 0.000052f, 0.000037f, 0.000027f, 0.000021f, 0.000016f, 0.000013f, 0.000010f, 0.000008f,
+ 0.000083f, 0.000183f, 0.000352f, 0.000355f, 0.000362f, 0.000365f, 0.000528f, 0.000790f, 0.001469f, 0.003029f, 0.005970f, 0.017242f,
+ 0.089050f, 0.728516f, 0.980957f, 0.981445f, 0.981445f, 0.980957f, 0.980957f, 0.981445f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000033f, 0.000041f, 0.000073f, 0.000083f, 0.000088f, 0.000097f, 0.000102f,
+ 0.000105f, 0.000108f, 0.000108f, 0.000111f, 0.000112f, 0.000113f, 0.000113f, 0.000114f, 0.000097f, 0.000068f, 0.000049f, 0.000038f,
+ 0.000028f, 0.000021f, 0.000016f, 0.000013f, 0.000010f, 0.000056f, 0.000151f, 0.000243f, 0.000264f, 0.000221f, 0.000328f, 0.000449f,
+ 0.000850f, 0.001612f, 0.003340f, 0.009361f, 0.043121f, 0.548340f, 0.976074f, 0.976562f, 0.975586f, 0.976074f, 0.976074f, 0.976562f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000019f, 0.000052f, 0.000065f, 0.000077f, 0.000088f, 0.000094f, 0.000098f, 0.000100f, 0.000104f, 0.000106f, 0.000108f,
+ 0.000109f, 0.000110f, 0.000095f, 0.000069f, 0.000052f, 0.000037f, 0.000028f, 0.000021f, 0.000017f, 0.000013f, 0.000025f, 0.000063f,
+ 0.000195f, 0.000233f, 0.000205f, 0.000264f, 0.000401f, 0.000789f, 0.001532f, 0.004520f, 0.020844f, 0.321289f, 0.969238f, 0.968750f,
+ 0.969238f, 0.968750f, 0.969238f, 0.969238f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000018f, 0.000039f, 0.000053f,
+ 0.000066f, 0.000079f, 0.000086f, 0.000090f, 0.000096f, 0.000100f, 0.000102f, 0.000105f, 0.000098f, 0.000074f, 0.000053f, 0.000041f,
+ 0.000031f, 0.000023f, 0.000017f, 0.000013f, 0.000028f, 0.000139f, 0.000189f, 0.000179f, 0.000219f, 0.000333f, 0.000840f, 0.002119f,
+ 0.009193f, 0.144775f, 0.958496f, 0.958496f, 0.958008f, 0.958496f, 0.958008f, 0.958008f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000025f, 0.000040f, 0.000052f, 0.000067f, 0.000077f, 0.000082f,
+ 0.000089f, 0.000093f, 0.000097f, 0.000079f, 0.000059f, 0.000044f, 0.000033f, 0.000024f, 0.000018f, 0.000014f, 0.000034f, 0.000084f,
+ 0.000157f, 0.000199f, 0.000309f, 0.000817f, 0.003424f, 0.054901f, 0.940918f, 0.940918f, 0.940918f, 0.940918f, 0.941406f, 0.940430f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000021f, 0.000040f, 0.000054f, 0.000063f, 0.000072f, 0.000078f, 0.000085f, 0.000065f, 0.000049f,
+ 0.000036f, 0.000026f, 0.000019f, 0.000014f, 0.000042f, 0.000114f, 0.000122f, 0.000276f, 0.001024f, 0.016357f, 0.912109f, 0.912598f,
+ 0.911621f, 0.912598f, 0.911621f, 0.913086f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000016f, 0.000032f, 0.000045f, 0.000056f, 0.000065f, 0.000054f, 0.000039f, 0.000028f, 0.000019f, 0.000013f, 0.000049f, 0.000079f,
+ 0.000226f, 0.003199f, 0.860840f, 0.859863f, 0.860352f, 0.860840f, 0.860840f, 0.860352f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000021f, 0.000035f,
+ 0.000040f, 0.000027f, 0.000018f, 0.000013f, 0.000033f, 0.000333f, 0.764160f, 0.765137f, 0.764648f, 0.764648f, 0.764648f, 0.765137f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000011f, 0.000009f, 0.600586f, 0.602051f,
+ 0.602051f, 0.601562f, 0.601074f, 0.601074f,
+ },
+ {
+ 0.142456f, 0.713867f, 0.883789f, 0.933105f, 0.953613f, 0.964844f, 0.972168f, 0.977539f, 0.980957f, 0.983398f, 0.985352f, 0.987305f,
+ 0.989258f, 0.989746f, 0.990723f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.993652f, 0.994141f, 0.995117f, 0.995117f, 0.995605f,
+ 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.012886f, 0.087646f, 0.360840f, 0.709473f, 0.859863f, 0.916992f, 0.943848f, 0.958496f,
+ 0.967773f, 0.973633f, 0.978516f, 0.980957f, 0.984375f, 0.986328f, 0.987793f, 0.988770f, 0.990234f, 0.991211f, 0.992188f, 0.993164f,
+ 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.997070f,
+ 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.003895f, 0.020126f, 0.063599f, 0.188721f,
+ 0.464844f, 0.727539f, 0.853027f, 0.909668f, 0.938477f, 0.954590f, 0.965332f, 0.971680f, 0.976562f, 0.979980f, 0.982910f, 0.985840f,
+ 0.986816f, 0.988770f, 0.990234f, 0.990723f, 0.991699f, 0.992188f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f,
+ 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.002062f, 0.008438f, 0.021774f, 0.049713f, 0.117676f, 0.279541f, 0.541016f, 0.751465f, 0.855469f, 0.909180f, 0.936035f, 0.952637f,
+ 0.963379f, 0.970703f, 0.975098f, 0.979492f, 0.982910f, 0.984863f, 0.986328f, 0.987793f, 0.989258f, 0.990234f, 0.990723f, 0.992188f,
+ 0.992676f, 0.993164f, 0.993652f, 0.994629f, 0.995117f, 0.995117f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.997070f,
+ 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.001335f, 0.004597f, 0.010628f, 0.020844f, 0.040283f, 0.082764f, 0.177612f, 0.366211f,
+ 0.605469f, 0.773926f, 0.863281f, 0.910156f, 0.936035f, 0.952148f, 0.962402f, 0.969727f, 0.975098f, 0.979004f, 0.982422f, 0.984863f,
+ 0.986328f, 0.988281f, 0.988770f, 0.989746f, 0.991211f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994629f, 0.995117f, 0.995117f,
+ 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000851f, 0.002769f, 0.006130f, 0.010994f,
+ 0.019394f, 0.034943f, 0.063293f, 0.122253f, 0.244019f, 0.448242f, 0.660156f, 0.798828f, 0.872559f, 0.914062f, 0.937988f, 0.954102f,
+ 0.961914f, 0.970215f, 0.974609f, 0.978516f, 0.981934f, 0.984375f, 0.986328f, 0.987793f, 0.988770f, 0.989746f, 0.991211f, 0.991699f,
+ 0.992676f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f,
+ 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000466f, 0.001933f, 0.003809f, 0.007095f, 0.011353f, 0.018204f, 0.030029f, 0.050568f, 0.090759f, 0.170898f, 0.318848f, 0.526367f,
+ 0.708496f, 0.820801f, 0.884277f, 0.918457f, 0.940918f, 0.954102f, 0.963867f, 0.970215f, 0.975098f, 0.978516f, 0.981934f, 0.984863f,
+ 0.986328f, 0.988281f, 0.988770f, 0.990234f, 0.991211f, 0.991699f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.994629f, 0.995605f,
+ 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000487f, 0.001685f, 0.002766f, 0.004467f, 0.007305f, 0.011215f, 0.017136f, 0.026489f,
+ 0.042419f, 0.071716f, 0.125244f, 0.228271f, 0.399658f, 0.599609f, 0.751953f, 0.842773f, 0.894531f, 0.924805f, 0.943359f, 0.955566f,
+ 0.965820f, 0.971191f, 0.976562f, 0.979980f, 0.981934f, 0.984863f, 0.986816f, 0.988281f, 0.989258f, 0.990723f, 0.991211f, 0.992188f,
+ 0.992676f, 0.993652f, 0.994141f, 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997070f,
+ 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000244f, 0.000965f, 0.002024f, 0.003202f,
+ 0.005009f, 0.007050f, 0.011070f, 0.015869f, 0.023987f, 0.036835f, 0.058563f, 0.097168f, 0.169800f, 0.297852f, 0.484131f, 0.664062f,
+ 0.789062f, 0.861816f, 0.905273f, 0.930176f, 0.947266f, 0.958984f, 0.967285f, 0.972168f, 0.976562f, 0.980469f, 0.982910f, 0.984863f,
+ 0.986816f, 0.988770f, 0.989746f, 0.990723f, 0.992188f, 0.992188f, 0.993652f, 0.993652f, 0.994629f, 0.995117f, 0.995117f, 0.995605f,
+ 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000244f, 0.000974f, 0.001576f, 0.002403f, 0.003510f, 0.005344f, 0.007332f, 0.010567f, 0.015099f, 0.022064f, 0.032104f, 0.048706f,
+ 0.078003f, 0.130249f, 0.224243f, 0.378174f, 0.566406f, 0.720703f, 0.820312f, 0.879883f, 0.915039f, 0.936523f, 0.951660f, 0.961426f,
+ 0.968262f, 0.974121f, 0.978027f, 0.980957f, 0.983887f, 0.985840f, 0.987793f, 0.989258f, 0.990234f, 0.991211f, 0.992188f, 0.992676f,
+ 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997070f,
+ 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000240f, 0.000609f, 0.001096f, 0.001580f, 0.002674f, 0.004131f, 0.005245f, 0.007660f,
+ 0.010757f, 0.014221f, 0.019775f, 0.028381f, 0.041870f, 0.064697f, 0.103638f, 0.173706f, 0.293945f, 0.466553f, 0.642090f, 0.769531f,
+ 0.849121f, 0.895996f, 0.924316f, 0.942871f, 0.956055f, 0.963867f, 0.970703f, 0.975098f, 0.979004f, 0.981934f, 0.984863f, 0.986328f,
+ 0.988770f, 0.989746f, 0.990723f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994629f, 0.995117f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000000f, 0.000608f, 0.001062f, 0.001268f,
+ 0.002001f, 0.003099f, 0.003937f, 0.005379f, 0.007595f, 0.010078f, 0.013176f, 0.018524f, 0.025787f, 0.036896f, 0.054932f, 0.085327f,
+ 0.137573f, 0.229980f, 0.376953f, 0.555664f, 0.708984f, 0.810547f, 0.873047f, 0.909180f, 0.933594f, 0.948730f, 0.959961f, 0.967285f,
+ 0.973145f, 0.977539f, 0.980469f, 0.983398f, 0.985840f, 0.986816f, 0.988770f, 0.989746f, 0.991211f, 0.992188f, 0.993164f, 0.993652f,
+ 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000244f, 0.000606f, 0.000609f, 0.001317f, 0.001564f, 0.002674f, 0.003273f, 0.004402f, 0.005630f, 0.007141f, 0.009514f, 0.012398f,
+ 0.016678f, 0.023331f, 0.032776f, 0.047363f, 0.071594f, 0.112610f, 0.183960f, 0.303711f, 0.470215f, 0.639648f, 0.766113f, 0.844727f,
+ 0.892090f, 0.921875f, 0.941895f, 0.954590f, 0.963379f, 0.970215f, 0.975098f, 0.979004f, 0.981934f, 0.984863f, 0.986328f, 0.987793f,
+ 0.989746f, 0.991211f, 0.991699f, 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996094f, 0.996094f,
+ 0.996582f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000244f, 0.000244f, 0.000727f, 0.000803f, 0.001575f, 0.002035f, 0.002821f, 0.003527f,
+ 0.004475f, 0.005421f, 0.007023f, 0.009491f, 0.011879f, 0.015976f, 0.021530f, 0.029587f, 0.041809f, 0.061737f, 0.094360f, 0.150146f,
+ 0.246460f, 0.393066f, 0.566406f, 0.712891f, 0.812500f, 0.872070f, 0.909180f, 0.933105f, 0.948242f, 0.959961f, 0.967773f, 0.972656f,
+ 0.977539f, 0.980957f, 0.982910f, 0.986328f, 0.987305f, 0.988770f, 0.989746f, 0.991211f, 0.992188f, 0.993164f, 0.993652f, 0.994629f,
+ 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000244f, 0.000244f, 0.000471f, 0.000727f,
+ 0.000967f, 0.001572f, 0.002161f, 0.002680f, 0.003246f, 0.004337f, 0.005241f, 0.006950f, 0.009087f, 0.011497f, 0.015038f, 0.019913f,
+ 0.026688f, 0.037537f, 0.054352f, 0.080383f, 0.125122f, 0.202515f, 0.327148f, 0.493652f, 0.656250f, 0.774414f, 0.849609f, 0.895508f,
+ 0.923828f, 0.942383f, 0.954590f, 0.963867f, 0.971191f, 0.975586f, 0.979004f, 0.982422f, 0.984863f, 0.987305f, 0.988281f, 0.989746f,
+ 0.990723f, 0.992188f, 0.992676f, 0.993652f, 0.994141f, 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f,
+ 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999023f,
+ 0.000121f, 0.000244f, 0.000244f, 0.000715f, 0.001089f, 0.001278f, 0.001781f, 0.002275f, 0.002548f, 0.003334f, 0.004150f, 0.005314f,
+ 0.006824f, 0.008430f, 0.011200f, 0.014145f, 0.018631f, 0.024750f, 0.033905f, 0.047760f, 0.069885f, 0.106445f, 0.169312f, 0.273682f,
+ 0.426270f, 0.596191f, 0.732422f, 0.823242f, 0.879883f, 0.914062f, 0.936035f, 0.950684f, 0.960938f, 0.968750f, 0.973633f, 0.978516f,
+ 0.981934f, 0.984375f, 0.986328f, 0.988281f, 0.989258f, 0.990234f, 0.991699f, 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.995117f,
+ 0.995605f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999512f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999023f, 0.000241f, 0.000244f, 0.000365f, 0.000600f, 0.000961f, 0.000972f, 0.001621f, 0.001697f,
+ 0.002274f, 0.002684f, 0.003359f, 0.004238f, 0.005573f, 0.006691f, 0.008057f, 0.010529f, 0.013832f, 0.017593f, 0.022812f, 0.031174f,
+ 0.042786f, 0.061462f, 0.092407f, 0.143799f, 0.231201f, 0.366943f, 0.535645f, 0.688477f, 0.794922f, 0.861816f, 0.902832f, 0.928711f,
+ 0.945801f, 0.957520f, 0.966797f, 0.972656f, 0.976562f, 0.980469f, 0.983398f, 0.985840f, 0.987793f, 0.989258f, 0.990234f, 0.991699f,
+ 0.992676f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996094f, 0.997070f, 0.997070f, 0.997559f, 0.997559f,
+ 0.998047f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000243f, 0.000365f, 0.000365f,
+ 0.000798f, 0.000968f, 0.001249f, 0.001528f, 0.001798f, 0.002457f, 0.002798f, 0.003494f, 0.004353f, 0.005306f, 0.006363f, 0.008141f,
+ 0.010147f, 0.012596f, 0.016006f, 0.021423f, 0.028503f, 0.039185f, 0.055420f, 0.081116f, 0.124390f, 0.198120f, 0.316895f, 0.478516f,
+ 0.641113f, 0.763672f, 0.842773f, 0.891113f, 0.921387f, 0.941406f, 0.954590f, 0.963867f, 0.970215f, 0.975586f, 0.979492f, 0.982910f,
+ 0.985352f, 0.987305f, 0.988770f, 0.989746f, 0.991211f, 0.992188f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f,
+ 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000238f, 0.000365f, 0.000365f, 0.000598f, 0.000820f, 0.001200f, 0.001279f, 0.001631f, 0.001736f, 0.002172f, 0.002874f,
+ 0.003576f, 0.004391f, 0.005096f, 0.006176f, 0.007545f, 0.009674f, 0.012505f, 0.015945f, 0.020187f, 0.026550f, 0.035706f, 0.049835f,
+ 0.072510f, 0.109253f, 0.171631f, 0.275391f, 0.426514f, 0.594238f, 0.730469f, 0.822754f, 0.877930f, 0.913574f, 0.936523f, 0.951172f,
+ 0.961426f, 0.969727f, 0.974609f, 0.978027f, 0.982422f, 0.984863f, 0.986816f, 0.988770f, 0.989746f, 0.991699f, 0.992188f, 0.993164f,
+ 0.993652f, 0.994629f, 0.994629f, 0.995117f, 0.996094f, 0.996094f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000364f, 0.000486f, 0.000487f, 0.000562f, 0.000822f, 0.000967f,
+ 0.001213f, 0.001871f, 0.001803f, 0.002485f, 0.002796f, 0.003410f, 0.004242f, 0.005070f, 0.006153f, 0.007698f, 0.009262f, 0.011635f,
+ 0.014709f, 0.019104f, 0.024521f, 0.033295f, 0.045746f, 0.065674f, 0.096741f, 0.150635f, 0.241455f, 0.380127f, 0.548828f, 0.698242f,
+ 0.802246f, 0.867188f, 0.906738f, 0.931152f, 0.948242f, 0.959473f, 0.967285f, 0.973633f, 0.978516f, 0.981445f, 0.984375f, 0.986328f,
+ 0.988281f, 0.989258f, 0.990723f, 0.992188f, 0.993164f, 0.993652f, 0.994629f, 0.994629f, 0.995117f, 0.996094f, 0.996582f, 0.996582f,
+ 0.997559f, 0.997559f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000350f, 0.000483f,
+ 0.000486f, 0.000604f, 0.000743f, 0.001093f, 0.001187f, 0.001297f, 0.001601f, 0.001921f, 0.002501f, 0.002922f, 0.003296f, 0.004200f,
+ 0.005211f, 0.006054f, 0.007603f, 0.008904f, 0.011169f, 0.014091f, 0.017685f, 0.023331f, 0.030991f, 0.042358f, 0.059326f, 0.087646f,
+ 0.134521f, 0.213867f, 0.341309f, 0.506348f, 0.665039f, 0.780762f, 0.854492f, 0.899414f, 0.927246f, 0.945312f, 0.957520f, 0.966309f,
+ 0.973145f, 0.977539f, 0.981445f, 0.984375f, 0.986328f, 0.988770f, 0.989746f, 0.991211f, 0.992188f, 0.993164f, 0.993652f, 0.994629f,
+ 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000000f, 0.000120f, 0.000360f, 0.000485f, 0.000486f, 0.000487f, 0.000604f, 0.000947f, 0.001201f, 0.001374f, 0.001715f,
+ 0.002127f, 0.002239f, 0.002876f, 0.003426f, 0.004063f, 0.005276f, 0.005810f, 0.006744f, 0.008713f, 0.010597f, 0.013680f, 0.016754f,
+ 0.021744f, 0.028778f, 0.039093f, 0.054901f, 0.079956f, 0.121399f, 0.191895f, 0.307861f, 0.468262f, 0.633301f, 0.760742f, 0.842285f,
+ 0.892090f, 0.923340f, 0.942383f, 0.956543f, 0.965332f, 0.972168f, 0.977539f, 0.980469f, 0.983887f, 0.985840f, 0.988281f, 0.989746f,
+ 0.990723f, 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000121f, 0.000219f, 0.000474f, 0.000484f, 0.000486f, 0.000487f,
+ 0.000720f, 0.001108f, 0.001199f, 0.001209f, 0.001689f, 0.002253f, 0.002489f, 0.002916f, 0.003714f, 0.004040f, 0.005054f, 0.006001f,
+ 0.006737f, 0.008713f, 0.010376f, 0.012665f, 0.016251f, 0.020615f, 0.027145f, 0.036499f, 0.050720f, 0.073181f, 0.110474f, 0.174072f,
+ 0.280518f, 0.434570f, 0.604980f, 0.742188f, 0.830566f, 0.885742f, 0.918945f, 0.940918f, 0.954102f, 0.964355f, 0.971680f, 0.977051f,
+ 0.980957f, 0.984375f, 0.986816f, 0.988281f, 0.989746f, 0.990723f, 0.992188f, 0.993652f, 0.994141f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996582f, 0.997070f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000000f, 0.000120f, 0.000239f,
+ 0.000319f, 0.000475f, 0.000484f, 0.000485f, 0.000618f, 0.000844f, 0.001094f, 0.001201f, 0.001570f, 0.001782f, 0.002010f, 0.002407f,
+ 0.003046f, 0.003099f, 0.004208f, 0.004700f, 0.005882f, 0.006878f, 0.007980f, 0.009949f, 0.012344f, 0.015358f, 0.019821f, 0.026047f,
+ 0.034271f, 0.047455f, 0.067993f, 0.102112f, 0.160034f, 0.258057f, 0.406494f, 0.578613f, 0.723633f, 0.820312f, 0.880371f, 0.916016f,
+ 0.938965f, 0.953125f, 0.963867f, 0.971191f, 0.976562f, 0.980469f, 0.983887f, 0.985840f, 0.988770f, 0.989746f, 0.991699f, 0.992676f,
+ 0.993652f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.999023f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000242f, 0.000455f, 0.000481f, 0.000583f, 0.000601f, 0.000804f, 0.000912f, 0.001247f,
+ 0.001319f, 0.001571f, 0.001793f, 0.002337f, 0.002464f, 0.003099f, 0.003164f, 0.003809f, 0.004627f, 0.005764f, 0.006397f, 0.008118f,
+ 0.009605f, 0.011917f, 0.015083f, 0.018692f, 0.024384f, 0.032806f, 0.044983f, 0.063477f, 0.095337f, 0.148560f, 0.240112f, 0.382324f,
+ 0.556641f, 0.708984f, 0.812500f, 0.875488f, 0.913574f, 0.937500f, 0.953125f, 0.963867f, 0.971191f, 0.977051f, 0.980957f, 0.983887f,
+ 0.986816f, 0.988281f, 0.990234f, 0.992188f, 0.993164f, 0.993652f, 0.994141f, 0.995605f, 0.995605f, 0.996094f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000240f, 0.000242f, 0.000524f, 0.000597f,
+ 0.000604f, 0.000606f, 0.000674f, 0.001040f, 0.001238f, 0.001427f, 0.001637f, 0.001670f, 0.002104f, 0.002432f, 0.002775f, 0.003416f,
+ 0.003860f, 0.004482f, 0.005573f, 0.006374f, 0.007828f, 0.009384f, 0.011635f, 0.014175f, 0.018219f, 0.023224f, 0.031052f, 0.042603f,
+ 0.060730f, 0.089661f, 0.139526f, 0.225464f, 0.363525f, 0.538574f, 0.696289f, 0.806152f, 0.872559f, 0.912109f, 0.937012f, 0.952637f,
+ 0.963867f, 0.971191f, 0.976562f, 0.981445f, 0.984863f, 0.987305f, 0.988770f, 0.990723f, 0.992188f, 0.993164f, 0.994141f, 0.994629f,
+ 0.995117f, 0.996094f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000119f,
+ 0.000192f, 0.000240f, 0.000242f, 0.000535f, 0.000478f, 0.000600f, 0.000843f, 0.000925f, 0.001027f, 0.001236f, 0.001502f, 0.001490f,
+ 0.001658f, 0.002256f, 0.002430f, 0.002880f, 0.003056f, 0.003983f, 0.004292f, 0.005333f, 0.006264f, 0.007393f, 0.009064f, 0.011131f,
+ 0.013741f, 0.017242f, 0.022690f, 0.029922f, 0.040680f, 0.057831f, 0.085022f, 0.132446f, 0.214844f, 0.349121f, 0.524414f, 0.688477f,
+ 0.801758f, 0.871094f, 0.912109f, 0.937500f, 0.953125f, 0.964355f, 0.971680f, 0.977539f, 0.981445f, 0.985352f, 0.987305f, 0.989258f,
+ 0.991211f, 0.992188f, 0.993652f, 0.994629f, 0.995117f, 0.995605f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000119f, 0.000232f, 0.000233f, 0.000363f, 0.000457f, 0.000714f, 0.000724f, 0.000727f,
+ 0.000847f, 0.000992f, 0.001177f, 0.001525f, 0.001560f, 0.001740f, 0.002090f, 0.002329f, 0.002718f, 0.003372f, 0.003902f, 0.004307f,
+ 0.005184f, 0.005886f, 0.007446f, 0.008667f, 0.010574f, 0.013588f, 0.016556f, 0.021744f, 0.028854f, 0.039124f, 0.055176f, 0.081726f,
+ 0.127075f, 0.206421f, 0.338867f, 0.515625f, 0.683105f, 0.800293f, 0.870605f, 0.912598f, 0.937500f, 0.954590f, 0.965332f, 0.973145f,
+ 0.978516f, 0.982422f, 0.985840f, 0.988281f, 0.989746f, 0.991211f, 0.992676f, 0.993652f, 0.994141f, 0.995117f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000103f, 0.000120f, 0.000240f, 0.000240f,
+ 0.000484f, 0.000574f, 0.000596f, 0.000837f, 0.000820f, 0.000859f, 0.000985f, 0.001070f, 0.001509f, 0.001554f, 0.001785f, 0.002214f,
+ 0.002476f, 0.002754f, 0.002991f, 0.003487f, 0.004303f, 0.005074f, 0.005920f, 0.007126f, 0.008743f, 0.010361f, 0.013023f, 0.016403f,
+ 0.021011f, 0.027817f, 0.037811f, 0.053375f, 0.079041f, 0.123291f, 0.201172f, 0.333252f, 0.511719f, 0.682129f, 0.801270f, 0.872070f,
+ 0.914062f, 0.939941f, 0.955078f, 0.966309f, 0.973633f, 0.979004f, 0.982910f, 0.986328f, 0.988770f, 0.990234f, 0.991699f, 0.992676f,
+ 0.993652f, 0.995117f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000079f, 0.000053f, 0.000118f, 0.000418f, 0.000358f, 0.000363f, 0.000678f, 0.000708f, 0.000825f, 0.000838f, 0.000878f, 0.001146f,
+ 0.000978f, 0.001483f, 0.001541f, 0.001769f, 0.001812f, 0.002434f, 0.002699f, 0.003225f, 0.003298f, 0.004002f, 0.004948f, 0.005932f,
+ 0.007084f, 0.008461f, 0.010414f, 0.012665f, 0.015915f, 0.020615f, 0.027023f, 0.036743f, 0.051941f, 0.077332f, 0.120789f, 0.198608f,
+ 0.331543f, 0.512695f, 0.686523f, 0.805664f, 0.875488f, 0.917480f, 0.941406f, 0.957031f, 0.968262f, 0.975098f, 0.980469f, 0.983887f,
+ 0.986816f, 0.989258f, 0.990723f, 0.992188f, 0.993164f, 0.994629f, 0.998047f, 0.998047f, 0.998535f, 0.998047f, 0.998535f, 0.998535f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000109f, 0.000232f, 0.000349f, 0.000478f, 0.000483f, 0.000483f, 0.000609f,
+ 0.000795f, 0.000835f, 0.000806f, 0.000726f, 0.001022f, 0.001222f, 0.001442f, 0.001536f, 0.001650f, 0.001714f, 0.002377f, 0.002588f,
+ 0.003159f, 0.003643f, 0.004036f, 0.004929f, 0.005718f, 0.006813f, 0.008072f, 0.009880f, 0.012527f, 0.015854f, 0.020035f, 0.026352f,
+ 0.035950f, 0.051178f, 0.076416f, 0.119751f, 0.198730f, 0.334229f, 0.519531f, 0.694824f, 0.812988f, 0.880859f, 0.920898f, 0.944336f,
+ 0.958984f, 0.969727f, 0.976562f, 0.980957f, 0.984863f, 0.987793f, 0.989746f, 0.991211f, 0.992676f, 0.993652f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000068f, 0.000265f,
+ 0.000361f, 0.000478f, 0.000480f, 0.000479f, 0.000568f, 0.000693f, 0.000714f, 0.000806f, 0.000843f, 0.000919f, 0.001222f, 0.001376f,
+ 0.001531f, 0.001554f, 0.001987f, 0.002342f, 0.002558f, 0.002798f, 0.003132f, 0.004021f, 0.004864f, 0.005455f, 0.006664f, 0.008110f,
+ 0.009613f, 0.011955f, 0.015335f, 0.019608f, 0.025879f, 0.035522f, 0.050629f, 0.075623f, 0.120239f, 0.201416f, 0.342041f, 0.533203f,
+ 0.707031f, 0.821777f, 0.887695f, 0.925293f, 0.946777f, 0.961914f, 0.971680f, 0.977539f, 0.982422f, 0.985352f, 0.988281f, 0.989746f,
+ 0.992188f, 0.993164f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000000f, 0.000122f, 0.000322f, 0.000241f, 0.000478f, 0.000480f, 0.000480f, 0.000510f, 0.000695f, 0.000710f,
+ 0.000958f, 0.000765f, 0.001075f, 0.001116f, 0.001318f, 0.001606f, 0.001546f, 0.001916f, 0.002306f, 0.002499f, 0.002905f, 0.003202f,
+ 0.003914f, 0.004498f, 0.005459f, 0.006611f, 0.007687f, 0.009331f, 0.011757f, 0.014923f, 0.019241f, 0.025833f, 0.035492f, 0.050507f,
+ 0.076233f, 0.122131f, 0.207153f, 0.355225f, 0.551758f, 0.724609f, 0.833496f, 0.894531f, 0.930664f, 0.951660f, 0.964844f, 0.973145f,
+ 0.979492f, 0.983887f, 0.986816f, 0.989258f, 0.991211f, 0.993164f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.997559f, 0.997559f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000351f, 0.000458f, 0.000476f,
+ 0.000480f, 0.000482f, 0.000528f, 0.000650f, 0.000704f, 0.000956f, 0.000828f, 0.000963f, 0.001111f, 0.001265f, 0.001474f, 0.001806f,
+ 0.001872f, 0.002308f, 0.002445f, 0.002701f, 0.003229f, 0.003851f, 0.004375f, 0.005356f, 0.006317f, 0.007458f, 0.009300f, 0.011574f,
+ 0.014725f, 0.019165f, 0.025696f, 0.035461f, 0.050812f, 0.077637f, 0.125977f, 0.216797f, 0.374756f, 0.576660f, 0.745117f, 0.848145f,
+ 0.904785f, 0.936523f, 0.956055f, 0.967773f, 0.975586f, 0.980957f, 0.984863f, 0.987793f, 0.990234f, 0.992188f, 0.997070f, 0.997559f,
+ 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000292f, 0.000224f, 0.000452f, 0.000453f, 0.000479f, 0.000480f, 0.000517f, 0.000614f, 0.000902f, 0.000712f, 0.000959f,
+ 0.000978f, 0.001100f, 0.001276f, 0.001461f, 0.001524f, 0.001651f, 0.002041f, 0.002350f, 0.002853f, 0.003433f, 0.003622f, 0.004166f,
+ 0.005043f, 0.006187f, 0.007534f, 0.009209f, 0.011551f, 0.014908f, 0.019012f, 0.025406f, 0.035461f, 0.051575f, 0.079651f, 0.131714f,
+ 0.230957f, 0.401367f, 0.607910f, 0.769531f, 0.863281f, 0.914062f, 0.942871f, 0.959961f, 0.970703f, 0.978027f, 0.982910f, 0.986816f,
+ 0.988770f, 0.991699f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000238f, 0.000355f, 0.000449f, 0.000462f, 0.000474f, 0.000477f,
+ 0.000482f, 0.000846f, 0.000726f, 0.000706f, 0.000953f, 0.000889f, 0.001012f, 0.001259f, 0.001390f, 0.001755f, 0.001658f, 0.002060f,
+ 0.002369f, 0.002539f, 0.003170f, 0.003460f, 0.004131f, 0.004993f, 0.006008f, 0.007431f, 0.009109f, 0.011444f, 0.014252f, 0.019058f,
+ 0.025574f, 0.036011f, 0.053162f, 0.083435f, 0.140381f, 0.250488f, 0.436035f, 0.645996f, 0.795898f, 0.880371f, 0.924316f, 0.949219f,
+ 0.963867f, 0.973145f, 0.980469f, 0.984863f, 0.988281f, 0.990723f, 0.997070f, 0.997559f, 0.997070f, 0.997559f, 0.997559f, 0.997070f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000239f,
+ 0.000306f, 0.000440f, 0.000437f, 0.000474f, 0.000478f, 0.000481f, 0.000523f, 0.000664f, 0.000731f, 0.000802f, 0.000935f, 0.001022f,
+ 0.001173f, 0.001314f, 0.001504f, 0.001831f, 0.001984f, 0.002317f, 0.002472f, 0.003199f, 0.003370f, 0.004189f, 0.004868f, 0.005924f,
+ 0.007320f, 0.008926f, 0.011421f, 0.014595f, 0.019119f, 0.026260f, 0.036987f, 0.055176f, 0.088440f, 0.152466f, 0.277832f, 0.479980f,
+ 0.686523f, 0.823242f, 0.895508f, 0.933105f, 0.955566f, 0.969238f, 0.976562f, 0.982422f, 0.986816f, 0.989746f, 0.996582f, 0.997070f,
+ 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000194f, 0.000280f, 0.000417f, 0.000448f, 0.000468f, 0.000476f, 0.000479f, 0.000490f,
+ 0.000845f, 0.000688f, 0.000740f, 0.000945f, 0.000998f, 0.001148f, 0.001266f, 0.001414f, 0.001475f, 0.001667f, 0.002262f, 0.002537f,
+ 0.003019f, 0.003288f, 0.004223f, 0.004768f, 0.005890f, 0.007259f, 0.009026f, 0.011360f, 0.014297f, 0.019272f, 0.026474f, 0.038116f,
+ 0.058197f, 0.095032f, 0.168945f, 0.313965f, 0.533203f, 0.731445f, 0.850098f, 0.911133f, 0.942871f, 0.961914f, 0.972656f, 0.979980f,
+ 0.984863f, 0.988770f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.000000f, 0.000000f, 0.000122f, 0.000000f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000187f, 0.000233f, 0.000141f, 0.000271f, 0.000341f,
+ 0.000380f, 0.000465f, 0.000473f, 0.000590f, 0.000605f, 0.000798f, 0.000847f, 0.000934f, 0.000946f, 0.000836f, 0.001009f, 0.001142f,
+ 0.001430f, 0.001495f, 0.001850f, 0.002111f, 0.002541f, 0.003035f, 0.003300f, 0.004139f, 0.004913f, 0.005718f, 0.007141f, 0.008934f,
+ 0.011475f, 0.014832f, 0.019653f, 0.027573f, 0.039917f, 0.062225f, 0.104919f, 0.192017f, 0.362305f, 0.594238f, 0.775879f, 0.875977f,
+ 0.925293f, 0.952148f, 0.967773f, 0.977051f, 0.983398f, 0.988281f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.996094f, 0.996582f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000238f, 0.000243f, 0.000238f, 0.000424f, 0.000453f, 0.000467f, 0.000475f, 0.000581f, 0.000689f, 0.000795f,
+ 0.000634f, 0.000823f, 0.001014f, 0.000900f, 0.001083f, 0.001485f, 0.001731f, 0.001851f, 0.002056f, 0.002373f, 0.002621f, 0.003445f,
+ 0.004082f, 0.004578f, 0.005821f, 0.007217f, 0.008881f, 0.011330f, 0.014778f, 0.020416f, 0.028473f, 0.042419f, 0.067993f, 0.118286f,
+ 0.225342f, 0.425293f, 0.661621f, 0.818848f, 0.899902f, 0.939453f, 0.960449f, 0.973145f, 0.980957f, 0.985840f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000205f, 0.000224f, 0.000122f, 0.000231f, 0.000245f, 0.000411f, 0.000520f,
+ 0.000463f, 0.000470f, 0.000587f, 0.000361f, 0.000712f, 0.000694f, 0.000815f, 0.000978f, 0.001055f, 0.001105f, 0.001390f, 0.001438f,
+ 0.001705f, 0.001984f, 0.002333f, 0.002546f, 0.003408f, 0.003876f, 0.004627f, 0.005783f, 0.007198f, 0.008995f, 0.011383f, 0.015396f,
+ 0.020828f, 0.030029f, 0.045654f, 0.075439f, 0.137451f, 0.271973f, 0.503418f, 0.728516f, 0.857910f, 0.920410f, 0.951172f, 0.968262f,
+ 0.977539f, 0.984375f, 0.995117f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000173f, 0.000150f, 0.000278f, 0.000376f, 0.000427f, 0.000470f, 0.000352f, 0.000356f, 0.000475f, 0.000441f, 0.000709f, 0.000774f,
+ 0.000970f, 0.001013f, 0.000998f, 0.001193f, 0.001397f, 0.001677f, 0.001957f, 0.002268f, 0.002529f, 0.003353f, 0.003874f, 0.004555f,
+ 0.005692f, 0.007160f, 0.008987f, 0.011543f, 0.015732f, 0.021896f, 0.032135f, 0.050140f, 0.086548f, 0.165894f, 0.337646f, 0.593750f,
+ 0.791504f, 0.892090f, 0.938477f, 0.961914f, 0.974609f, 0.982422f, 0.994629f, 0.995117f, 0.995117f, 0.995605f, 0.995117f, 0.995605f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000187f, 0.000130f, 0.000231f, 0.000315f, 0.000298f, 0.000332f, 0.000343f,
+ 0.000465f, 0.000472f, 0.000579f, 0.000717f, 0.000839f, 0.000932f, 0.000817f, 0.001086f, 0.001090f, 0.001545f, 0.001735f, 0.001837f,
+ 0.002485f, 0.002493f, 0.003288f, 0.003828f, 0.004520f, 0.005833f, 0.007156f, 0.009193f, 0.012123f, 0.015839f, 0.022934f, 0.034760f,
+ 0.056488f, 0.102600f, 0.208862f, 0.427734f, 0.687988f, 0.846191f, 0.919434f, 0.952637f, 0.969727f, 0.979980f, 0.993652f, 0.994629f,
+ 0.994141f, 0.994629f, 0.994629f, 0.994629f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000133f,
+ 0.000141f, 0.000234f, 0.000300f, 0.000397f, 0.000436f, 0.000456f, 0.000465f, 0.000534f, 0.000663f, 0.000810f, 0.000796f, 0.000812f,
+ 0.001062f, 0.001237f, 0.001428f, 0.001565f, 0.001818f, 0.002182f, 0.002783f, 0.002943f, 0.003773f, 0.004715f, 0.005482f, 0.007195f,
+ 0.009285f, 0.012207f, 0.016922f, 0.024567f, 0.038483f, 0.066101f, 0.127563f, 0.274170f, 0.540527f, 0.774414f, 0.891113f, 0.940430f,
+ 0.965332f, 0.977539f, 0.993652f, 0.994141f, 0.994629f, 0.994141f, 0.994629f, 0.994141f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000124f, 0.000116f, 0.000119f, 0.000125f, 0.000121f, 0.000197f, 0.000323f, 0.000418f, 0.000446f, 0.000433f,
+ 0.000467f, 0.000612f, 0.000710f, 0.000783f, 0.000911f, 0.000817f, 0.001161f, 0.001343f, 0.001514f, 0.001707f, 0.002081f, 0.002386f,
+ 0.002882f, 0.003609f, 0.004627f, 0.005478f, 0.007011f, 0.009384f, 0.012695f, 0.017960f, 0.026901f, 0.044067f, 0.080078f, 0.167114f,
+ 0.374023f, 0.664062f, 0.845703f, 0.923340f, 0.957031f, 0.974121f, 0.992676f, 0.993652f, 0.993164f, 0.993652f, 0.993652f, 0.993164f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000121f, 0.000121f, 0.000052f, 0.000039f, 0.000029f, 0.000054f, 0.000045f, 0.000118f,
+ 0.000128f, 0.000231f, 0.000387f, 0.000429f, 0.000446f, 0.000544f, 0.000539f, 0.000648f, 0.000749f, 0.000790f, 0.000978f, 0.001102f,
+ 0.001195f, 0.001501f, 0.001761f, 0.001978f, 0.002661f, 0.003170f, 0.003519f, 0.004509f, 0.005344f, 0.007004f, 0.009361f, 0.013229f,
+ 0.019196f, 0.030258f, 0.052002f, 0.102661f, 0.234131f, 0.511230f, 0.774902f, 0.898438f, 0.947754f, 0.970215f, 0.992188f, 0.992676f,
+ 0.993164f, 0.992676f, 0.992188f, 0.992188f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000070f, 0.000052f,
+ 0.000038f, 0.000030f, 0.000023f, 0.000060f, 0.000116f, 0.000121f, 0.000252f, 0.000337f, 0.000306f, 0.000435f, 0.000450f, 0.000562f,
+ 0.000584f, 0.000722f, 0.000858f, 0.000888f, 0.000969f, 0.001230f, 0.001429f, 0.001576f, 0.001827f, 0.002361f, 0.002863f, 0.003267f,
+ 0.004047f, 0.005394f, 0.007256f, 0.009781f, 0.013855f, 0.021439f, 0.035034f, 0.065063f, 0.141724f, 0.346680f, 0.665527f, 0.859375f,
+ 0.934570f, 0.965820f, 0.991699f, 0.991699f, 0.991699f, 0.992188f, 0.991699f, 0.991699f, 0.000000f, 0.000000f, 0.000122f, 0.000121f,
+ 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000099f, 0.000069f, 0.000051f, 0.000039f, 0.000030f, 0.000023f, 0.000024f, 0.000115f, 0.000103f, 0.000224f,
+ 0.000204f, 0.000339f, 0.000407f, 0.000437f, 0.000452f, 0.000489f, 0.000663f, 0.000821f, 0.000922f, 0.001004f, 0.001086f, 0.001279f,
+ 0.001554f, 0.001651f, 0.001997f, 0.002390f, 0.003136f, 0.004223f, 0.005508f, 0.007339f, 0.010094f, 0.014854f, 0.024048f, 0.042664f,
+ 0.087036f, 0.213867f, 0.516113f, 0.799805f, 0.915527f, 0.958984f, 0.990723f, 0.991211f, 0.990723f, 0.990723f, 0.990723f, 0.991211f,
+ 0.000000f, 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000096f, 0.000073f, 0.000053f, 0.000040f, 0.000031f,
+ 0.000025f, 0.000020f, 0.000017f, 0.000105f, 0.000110f, 0.000135f, 0.000235f, 0.000380f, 0.000462f, 0.000513f, 0.000556f, 0.000638f,
+ 0.000804f, 0.000868f, 0.000897f, 0.001002f, 0.001079f, 0.001246f, 0.001596f, 0.002153f, 0.002213f, 0.003094f, 0.004158f, 0.005306f,
+ 0.007458f, 0.010887f, 0.017166f, 0.028748f, 0.055176f, 0.128174f, 0.350586f, 0.703613f, 0.888184f, 0.951172f, 0.988770f, 0.989746f,
+ 0.989746f, 0.989746f, 0.989746f, 0.989746f, 0.000122f, 0.000120f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000101f, 0.000073f, 0.000057f, 0.000043f, 0.000033f, 0.000027f, 0.000021f, 0.000018f, 0.000105f, 0.000112f, 0.000111f, 0.000161f,
+ 0.000320f, 0.000390f, 0.000421f, 0.000438f, 0.000559f, 0.000665f, 0.000735f, 0.000719f, 0.000704f, 0.000887f, 0.001223f, 0.001384f,
+ 0.001867f, 0.002462f, 0.003216f, 0.004032f, 0.005367f, 0.007988f, 0.012054f, 0.019943f, 0.035919f, 0.078064f, 0.215332f, 0.566895f,
+ 0.845703f, 0.939941f, 0.987793f, 0.988281f, 0.987793f, 0.987793f, 0.988281f, 0.988281f, 0.000000f, 0.000120f, 0.000120f, 0.000120f,
+ 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f,
+ 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000103f, 0.000077f, 0.000061f, 0.000046f, 0.000037f, 0.000030f, 0.000023f,
+ 0.000019f, 0.000016f, 0.000039f, 0.000094f, 0.000181f, 0.000205f, 0.000350f, 0.000392f, 0.000423f, 0.000510f, 0.000619f, 0.000672f,
+ 0.000705f, 0.000632f, 0.000807f, 0.001038f, 0.001278f, 0.001894f, 0.002245f, 0.002758f, 0.003883f, 0.005863f, 0.008636f, 0.013672f,
+ 0.023880f, 0.048828f, 0.127441f, 0.400879f, 0.779297f, 0.925781f, 0.985840f, 0.986328f, 0.986328f, 0.985840f, 0.986328f, 0.986328f,
+ 0.000000f, 0.000100f, 0.000108f, 0.000118f, 0.000119f, 0.000118f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000120f, 0.000120f,
+ 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000111f, 0.000086f,
+ 0.000066f, 0.000051f, 0.000041f, 0.000032f, 0.000026f, 0.000021f, 0.000018f, 0.000015f, 0.000086f, 0.000131f, 0.000190f, 0.000293f,
+ 0.000419f, 0.000481f, 0.000477f, 0.000438f, 0.000542f, 0.000564f, 0.000599f, 0.000700f, 0.000916f, 0.001122f, 0.001589f, 0.001997f,
+ 0.002678f, 0.004017f, 0.005814f, 0.009361f, 0.015808f, 0.031250f, 0.075989f, 0.250732f, 0.676758f, 0.904297f, 0.983887f, 0.983887f,
+ 0.983887f, 0.984375f, 0.984375f, 0.983887f, 0.000000f, 0.000000f, 0.000077f, 0.000112f, 0.000104f, 0.000115f, 0.000115f, 0.000117f,
+ 0.000117f, 0.000117f, 0.000118f, 0.000118f, 0.000118f, 0.000118f, 0.000119f, 0.000118f, 0.000119f, 0.000119f, 0.000119f, 0.000119f,
+ 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000097f, 0.000076f, 0.000060f, 0.000046f, 0.000037f, 0.000030f, 0.000024f, 0.000020f,
+ 0.000045f, 0.000063f, 0.000091f, 0.000140f, 0.000202f, 0.000333f, 0.000305f, 0.000399f, 0.000462f, 0.000452f, 0.000535f, 0.000531f,
+ 0.000631f, 0.000866f, 0.000858f, 0.001307f, 0.001844f, 0.002823f, 0.004070f, 0.006264f, 0.010536f, 0.020035f, 0.045990f, 0.145996f,
+ 0.532227f, 0.874023f, 0.980957f, 0.981445f, 0.980957f, 0.981445f, 0.980957f, 0.981445f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000091f, 0.000103f, 0.000105f, 0.000106f, 0.000111f, 0.000113f, 0.000115f, 0.000114f, 0.000116f, 0.000116f, 0.000117f, 0.000117f,
+ 0.000117f, 0.000117f, 0.000117f, 0.000118f, 0.000118f, 0.000118f, 0.000118f, 0.000118f, 0.000118f, 0.000112f, 0.000084f, 0.000069f,
+ 0.000055f, 0.000043f, 0.000036f, 0.000028f, 0.000024f, 0.000020f, 0.000028f, 0.000039f, 0.000083f, 0.000141f, 0.000211f, 0.000262f,
+ 0.000413f, 0.000305f, 0.000370f, 0.000358f, 0.000489f, 0.000564f, 0.000599f, 0.000893f, 0.001084f, 0.001696f, 0.002697f, 0.004074f,
+ 0.006836f, 0.012878f, 0.028122f, 0.083496f, 0.364014f, 0.826660f, 0.976562f, 0.977539f, 0.977051f, 0.977539f, 0.978027f, 0.977051f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000015f, 0.000086f, 0.000077f, 0.000103f, 0.000100f, 0.000109f,
+ 0.000110f, 0.000111f, 0.000112f, 0.000112f, 0.000114f, 0.000114f, 0.000115f, 0.000115f, 0.000116f, 0.000115f, 0.000116f, 0.000116f,
+ 0.000117f, 0.000117f, 0.000117f, 0.000100f, 0.000079f, 0.000066f, 0.000053f, 0.000041f, 0.000035f, 0.000028f, 0.000023f, 0.000019f,
+ 0.000017f, 0.000034f, 0.000113f, 0.000174f, 0.000257f, 0.000325f, 0.000356f, 0.000324f, 0.000409f, 0.000454f, 0.000474f, 0.000659f,
+ 0.000778f, 0.001243f, 0.001575f, 0.002472f, 0.004105f, 0.007957f, 0.016800f, 0.047852f, 0.217529f, 0.755371f, 0.972656f, 0.973145f,
+ 0.973145f, 0.973145f, 0.973145f, 0.973145f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000028f, 0.000049f, 0.000085f, 0.000081f, 0.000096f, 0.000101f, 0.000104f, 0.000106f, 0.000108f, 0.000109f, 0.000110f,
+ 0.000111f, 0.000112f, 0.000113f, 0.000113f, 0.000114f, 0.000114f, 0.000114f, 0.000115f, 0.000115f, 0.000096f, 0.000078f, 0.000064f,
+ 0.000051f, 0.000043f, 0.000035f, 0.000029f, 0.000024f, 0.000020f, 0.000026f, 0.000055f, 0.000087f, 0.000135f, 0.000248f, 0.000261f,
+ 0.000274f, 0.000258f, 0.000296f, 0.000359f, 0.000474f, 0.000627f, 0.001012f, 0.001484f, 0.002630f, 0.004536f, 0.010277f, 0.027405f,
+ 0.119507f, 0.645996f, 0.966797f, 0.967285f, 0.967285f, 0.967285f, 0.966797f, 0.966797f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000014f, 0.000021f, 0.000065f, 0.000074f,
+ 0.000077f, 0.000091f, 0.000091f, 0.000099f, 0.000098f, 0.000103f, 0.000103f, 0.000106f, 0.000107f, 0.000108f, 0.000109f, 0.000110f,
+ 0.000111f, 0.000111f, 0.000112f, 0.000096f, 0.000079f, 0.000064f, 0.000053f, 0.000043f, 0.000036f, 0.000030f, 0.000024f, 0.000021f,
+ 0.000018f, 0.000028f, 0.000072f, 0.000125f, 0.000233f, 0.000243f, 0.000220f, 0.000258f, 0.000320f, 0.000353f, 0.000630f, 0.000932f,
+ 0.001324f, 0.002357f, 0.005402f, 0.014534f, 0.062561f, 0.493164f, 0.958008f, 0.958008f, 0.958984f, 0.958496f, 0.958496f, 0.958008f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000011f, 0.000035f, 0.000041f, 0.000064f, 0.000074f, 0.000081f, 0.000082f, 0.000090f,
+ 0.000092f, 0.000096f, 0.000099f, 0.000100f, 0.000102f, 0.000104f, 0.000105f, 0.000106f, 0.000107f, 0.000099f, 0.000082f, 0.000067f,
+ 0.000055f, 0.000047f, 0.000038f, 0.000031f, 0.000026f, 0.000022f, 0.000018f, 0.000037f, 0.000071f, 0.000111f, 0.000190f, 0.000204f,
+ 0.000153f, 0.000245f, 0.000299f, 0.000482f, 0.000790f, 0.001330f, 0.002619f, 0.007282f, 0.031097f, 0.318115f, 0.946289f, 0.946777f,
+ 0.946777f, 0.946777f, 0.946777f, 0.946777f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000008f, 0.000029f, 0.000044f, 0.000055f, 0.000063f, 0.000073f, 0.000075f, 0.000081f, 0.000087f, 0.000090f, 0.000092f,
+ 0.000094f, 0.000097f, 0.000099f, 0.000100f, 0.000087f, 0.000071f, 0.000059f, 0.000049f, 0.000040f, 0.000034f, 0.000028f, 0.000024f,
+ 0.000020f, 0.000016f, 0.000072f, 0.000114f, 0.000169f, 0.000147f, 0.000181f, 0.000246f, 0.000367f, 0.000626f, 0.001325f, 0.003117f,
+ 0.013741f, 0.167480f, 0.929688f, 0.929688f, 0.929688f, 0.930176f, 0.930664f, 0.930176f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000019f,
+ 0.000030f, 0.000044f, 0.000049f, 0.000062f, 0.000068f, 0.000072f, 0.000078f, 0.000081f, 0.000084f, 0.000087f, 0.000090f, 0.000079f,
+ 0.000065f, 0.000054f, 0.000044f, 0.000037f, 0.000030f, 0.000025f, 0.000021f, 0.000017f, 0.000052f, 0.000100f, 0.000132f, 0.000130f,
+ 0.000164f, 0.000297f, 0.000552f, 0.001273f, 0.005009f, 0.071594f, 0.903809f, 0.905273f, 0.904297f, 0.904785f, 0.904785f, 0.904785f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000013f, 0.000028f, 0.000036f,
+ 0.000045f, 0.000053f, 0.000060f, 0.000066f, 0.000071f, 0.000075f, 0.000071f, 0.000058f, 0.000049f, 0.000040f, 0.000033f, 0.000027f,
+ 0.000022f, 0.000018f, 0.000032f, 0.000078f, 0.000090f, 0.000123f, 0.000175f, 0.000441f, 0.001637f, 0.022537f, 0.865234f, 0.865234f,
+ 0.865723f, 0.865723f, 0.865234f, 0.864746f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000017f, 0.000027f, 0.000036f, 0.000042f,
+ 0.000050f, 0.000056f, 0.000052f, 0.000043f, 0.000035f, 0.000028f, 0.000022f, 0.000018f, 0.000049f, 0.000055f, 0.000047f, 0.000108f,
+ 0.000342f, 0.004566f, 0.802734f, 0.803711f, 0.803711f, 0.803711f, 0.803711f, 0.803711f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000013f, 0.000022f, 0.000030f, 0.000033f, 0.000027f,
+ 0.000021f, 0.000015f, 0.000011f, 0.000031f, 0.000045f, 0.000449f, 0.708496f, 0.707520f, 0.708984f, 0.708496f, 0.707520f, 0.708008f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000011f, 0.000006f, 0.000007f, 0.575195f, 0.575195f,
+ 0.575195f, 0.575195f, 0.575195f, 0.575195f,
+ },
+ {
+ 0.158813f, 0.632812f, 0.824219f, 0.891602f, 0.924805f, 0.942383f, 0.954102f, 0.962402f, 0.968262f, 0.972656f, 0.976074f, 0.978516f,
+ 0.980957f, 0.982910f, 0.984375f, 0.985840f, 0.986816f, 0.988770f, 0.989746f, 0.989746f, 0.990234f, 0.991211f, 0.992188f, 0.992676f,
+ 0.993652f, 0.993652f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.996582f,
+ 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.019775f, 0.115845f, 0.361084f, 0.642578f, 0.798340f, 0.872559f, 0.911133f, 0.933594f,
+ 0.947266f, 0.957031f, 0.964355f, 0.968750f, 0.973145f, 0.976562f, 0.979492f, 0.981934f, 0.983398f, 0.984863f, 0.986816f, 0.987793f,
+ 0.988770f, 0.989258f, 0.990234f, 0.991211f, 0.991699f, 0.992676f, 0.993164f, 0.993164f, 0.993652f, 0.994141f, 0.995117f, 0.995117f,
+ 0.995605f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.006638f, 0.031082f, 0.089661f, 0.222168f,
+ 0.448242f, 0.663086f, 0.794434f, 0.864258f, 0.903320f, 0.926758f, 0.942383f, 0.953613f, 0.961426f, 0.966797f, 0.972168f, 0.975586f,
+ 0.978027f, 0.980469f, 0.982910f, 0.984375f, 0.985840f, 0.986816f, 0.988281f, 0.989258f, 0.990234f, 0.991211f, 0.991699f, 0.992188f,
+ 0.992676f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.996582f,
+ 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.003246f, 0.013367f, 0.032806f, 0.072754f, 0.152954f, 0.304199f, 0.509766f, 0.687500f, 0.797852f, 0.862305f, 0.900391f, 0.923828f,
+ 0.940430f, 0.950684f, 0.959473f, 0.965820f, 0.970703f, 0.974121f, 0.977051f, 0.979492f, 0.981934f, 0.983887f, 0.985840f, 0.987305f,
+ 0.987793f, 0.989258f, 0.989746f, 0.990723f, 0.991211f, 0.992188f, 0.992188f, 0.993164f, 0.993652f, 0.993652f, 0.994629f, 0.995117f,
+ 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.002029f, 0.007267f, 0.016678f, 0.032288f, 0.061462f, 0.115051f, 0.215088f, 0.376709f,
+ 0.562988f, 0.712891f, 0.807617f, 0.865234f, 0.901367f, 0.923828f, 0.939453f, 0.950684f, 0.958984f, 0.965332f, 0.970215f, 0.974609f,
+ 0.977051f, 0.979980f, 0.981934f, 0.983887f, 0.984863f, 0.986328f, 0.988281f, 0.988770f, 0.989746f, 0.990723f, 0.990723f, 0.991699f,
+ 0.992188f, 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995117f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.996582f,
+ 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.001274f, 0.004623f, 0.009880f, 0.017792f,
+ 0.030869f, 0.052673f, 0.091431f, 0.160645f, 0.277832f, 0.442383f, 0.610352f, 0.737793f, 0.819824f, 0.870605f, 0.902832f, 0.924805f,
+ 0.939941f, 0.950195f, 0.958496f, 0.964844f, 0.970215f, 0.973633f, 0.977051f, 0.979980f, 0.981934f, 0.983398f, 0.984863f, 0.986328f,
+ 0.987305f, 0.988770f, 0.989746f, 0.990723f, 0.991211f, 0.992188f, 0.992676f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f,
+ 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000943f, 0.003231f, 0.006317f, 0.011040f, 0.018051f, 0.029190f, 0.046936f, 0.075867f, 0.125488f, 0.210449f, 0.341797f, 0.503906f,
+ 0.652344f, 0.761230f, 0.832031f, 0.877441f, 0.906738f, 0.927734f, 0.940918f, 0.951172f, 0.959473f, 0.965820f, 0.970703f, 0.974121f,
+ 0.977051f, 0.979492f, 0.981934f, 0.983398f, 0.985352f, 0.987305f, 0.988281f, 0.989258f, 0.990234f, 0.990723f, 0.991211f, 0.992188f,
+ 0.992676f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.996582f,
+ 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000731f, 0.001970f, 0.004425f, 0.007351f, 0.011627f, 0.017975f, 0.027161f, 0.041779f,
+ 0.064270f, 0.101685f, 0.164917f, 0.265137f, 0.406494f, 0.561035f, 0.692383f, 0.785156f, 0.845703f, 0.884766f, 0.911621f, 0.930176f,
+ 0.942871f, 0.953125f, 0.959961f, 0.965332f, 0.970703f, 0.974121f, 0.977539f, 0.979492f, 0.982422f, 0.983887f, 0.985840f, 0.987305f,
+ 0.987793f, 0.989258f, 0.990234f, 0.991211f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994141f, 0.995117f, 0.995117f, 0.995605f,
+ 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.000487f, 0.001872f, 0.003445f, 0.005367f,
+ 0.008400f, 0.012405f, 0.017822f, 0.025345f, 0.037964f, 0.056244f, 0.085327f, 0.132935f, 0.210327f, 0.325928f, 0.471924f, 0.615723f,
+ 0.729004f, 0.807617f, 0.859375f, 0.894043f, 0.916504f, 0.934570f, 0.945801f, 0.955078f, 0.961426f, 0.967285f, 0.972168f, 0.975586f,
+ 0.978516f, 0.980957f, 0.982422f, 0.984863f, 0.985840f, 0.986816f, 0.988770f, 0.989258f, 0.990723f, 0.991699f, 0.992188f, 0.992676f,
+ 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.997070f, 0.997070f, 0.997559f,
+ 0.997559f, 0.998047f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.000363f, 0.001300f, 0.002499f, 0.003784f, 0.006153f, 0.008896f, 0.012367f, 0.017227f, 0.024185f, 0.034241f, 0.049591f, 0.072754f,
+ 0.111023f, 0.170776f, 0.263184f, 0.391113f, 0.535645f, 0.665527f, 0.761719f, 0.828613f, 0.871582f, 0.902344f, 0.922852f, 0.937988f,
+ 0.949219f, 0.957031f, 0.963867f, 0.968750f, 0.972656f, 0.976074f, 0.979004f, 0.981445f, 0.983887f, 0.984863f, 0.986328f, 0.988281f,
+ 0.989258f, 0.990234f, 0.991211f, 0.991699f, 0.992676f, 0.993652f, 0.993652f, 0.994629f, 0.995117f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999023f, 0.999023f, 0.000365f, 0.000972f, 0.001874f, 0.003323f, 0.004669f, 0.006599f, 0.008919f, 0.012360f,
+ 0.016785f, 0.022720f, 0.031616f, 0.044647f, 0.064026f, 0.094055f, 0.141235f, 0.215332f, 0.323486f, 0.459229f, 0.597168f, 0.710449f,
+ 0.791992f, 0.847656f, 0.885254f, 0.910645f, 0.929199f, 0.941895f, 0.952148f, 0.960449f, 0.965332f, 0.970703f, 0.974121f, 0.977539f,
+ 0.979980f, 0.981934f, 0.984375f, 0.985840f, 0.987305f, 0.988770f, 0.989746f, 0.990723f, 0.991211f, 0.992188f, 0.993164f, 0.993164f,
+ 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.997559f,
+ 0.998047f, 0.998535f, 0.999023f, 0.999512f, 0.999023f, 0.999512f, 0.999512f, 0.999023f, 0.000244f, 0.000764f, 0.001375f, 0.002415f,
+ 0.003582f, 0.004963f, 0.006973f, 0.008751f, 0.011726f, 0.016113f, 0.021683f, 0.029129f, 0.040283f, 0.057098f, 0.081421f, 0.119019f,
+ 0.178955f, 0.268311f, 0.390625f, 0.528809f, 0.654785f, 0.751465f, 0.820312f, 0.866211f, 0.896973f, 0.919434f, 0.935547f, 0.946777f,
+ 0.956055f, 0.962402f, 0.968262f, 0.972168f, 0.975098f, 0.979004f, 0.981445f, 0.983398f, 0.985352f, 0.986816f, 0.987793f, 0.989258f,
+ 0.990723f, 0.991211f, 0.992188f, 0.992188f, 0.993164f, 0.993652f, 0.994629f, 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996094f,
+ 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000122f, 0.000606f, 0.001439f, 0.002058f, 0.002743f, 0.004169f, 0.005035f, 0.006775f, 0.009010f, 0.012085f, 0.015717f, 0.020813f,
+ 0.027573f, 0.037170f, 0.050812f, 0.071472f, 0.102905f, 0.151489f, 0.225708f, 0.332031f, 0.463623f, 0.596191f, 0.707031f, 0.787598f,
+ 0.844238f, 0.881348f, 0.908691f, 0.927246f, 0.940918f, 0.951660f, 0.958984f, 0.965820f, 0.970215f, 0.974121f, 0.977539f, 0.979980f,
+ 0.982422f, 0.984375f, 0.985840f, 0.987305f, 0.988281f, 0.990234f, 0.990723f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994141f,
+ 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000118f, 0.000846f, 0.001303f, 0.001593f, 0.002180f, 0.003050f, 0.004353f, 0.005577f,
+ 0.006954f, 0.009331f, 0.011826f, 0.015007f, 0.019653f, 0.025391f, 0.034119f, 0.046112f, 0.063660f, 0.090210f, 0.130737f, 0.192139f,
+ 0.283203f, 0.404053f, 0.537598f, 0.658691f, 0.753418f, 0.818848f, 0.865234f, 0.896973f, 0.918945f, 0.934570f, 0.946289f, 0.955566f,
+ 0.962402f, 0.967285f, 0.972168f, 0.976074f, 0.979004f, 0.981445f, 0.983398f, 0.985840f, 0.986816f, 0.988281f, 0.989258f, 0.990723f,
+ 0.991211f, 0.992676f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f,
+ 0.997559f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000117f, 0.000487f, 0.000957f, 0.001514f,
+ 0.002008f, 0.002619f, 0.003424f, 0.004551f, 0.005836f, 0.007381f, 0.009155f, 0.011459f, 0.014366f, 0.018646f, 0.024017f, 0.031281f,
+ 0.042664f, 0.057068f, 0.080139f, 0.113586f, 0.165894f, 0.243164f, 0.352051f, 0.481934f, 0.610840f, 0.716309f, 0.793945f, 0.847168f,
+ 0.884766f, 0.910645f, 0.928223f, 0.942383f, 0.952637f, 0.959961f, 0.965332f, 0.970703f, 0.975098f, 0.978027f, 0.980957f, 0.983398f,
+ 0.984863f, 0.986816f, 0.988281f, 0.989258f, 0.990723f, 0.991211f, 0.992188f, 0.992676f, 0.993164f, 0.993652f, 0.994629f, 0.995117f,
+ 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.997559f, 0.997070f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000000f, 0.000608f, 0.000952f, 0.001111f, 0.001660f, 0.002102f, 0.002817f, 0.003517f, 0.004742f, 0.005585f, 0.007080f, 0.008980f,
+ 0.011078f, 0.014191f, 0.017838f, 0.022614f, 0.029404f, 0.038940f, 0.052551f, 0.071533f, 0.100769f, 0.145020f, 0.211548f, 0.307373f,
+ 0.430176f, 0.561523f, 0.676758f, 0.764648f, 0.828613f, 0.872070f, 0.900879f, 0.921875f, 0.937012f, 0.948730f, 0.957520f, 0.964355f,
+ 0.969238f, 0.973633f, 0.977539f, 0.979980f, 0.982422f, 0.984863f, 0.986328f, 0.987793f, 0.988770f, 0.990234f, 0.991211f, 0.991699f,
+ 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000244f, 0.000576f, 0.000727f, 0.001083f, 0.001186f, 0.001810f, 0.002558f, 0.002968f,
+ 0.003725f, 0.004913f, 0.005955f, 0.007011f, 0.008759f, 0.010918f, 0.013718f, 0.016953f, 0.021423f, 0.027832f, 0.035980f, 0.047913f,
+ 0.064941f, 0.090332f, 0.128174f, 0.185791f, 0.270264f, 0.384033f, 0.514160f, 0.638184f, 0.736328f, 0.807617f, 0.856934f, 0.891602f,
+ 0.915039f, 0.932617f, 0.945801f, 0.954102f, 0.962402f, 0.968262f, 0.972168f, 0.976562f, 0.979492f, 0.981445f, 0.983887f, 0.985840f,
+ 0.987305f, 0.988281f, 0.990234f, 0.990723f, 0.992188f, 0.992676f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996582f, 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000000f, 0.000244f, 0.000708f, 0.000903f,
+ 0.001129f, 0.001511f, 0.002031f, 0.002565f, 0.003189f, 0.004112f, 0.004696f, 0.005989f, 0.006954f, 0.008865f, 0.010826f, 0.013031f,
+ 0.016312f, 0.020493f, 0.026154f, 0.033966f, 0.044159f, 0.059845f, 0.081665f, 0.114929f, 0.164917f, 0.239624f, 0.343750f, 0.469971f,
+ 0.598145f, 0.706055f, 0.786133f, 0.842773f, 0.881348f, 0.908203f, 0.927246f, 0.941895f, 0.952148f, 0.959961f, 0.966797f, 0.971191f,
+ 0.976074f, 0.978516f, 0.981445f, 0.983887f, 0.985352f, 0.987305f, 0.988281f, 0.989258f, 0.990723f, 0.991699f, 0.992676f, 0.993652f,
+ 0.994141f, 0.994629f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000122f, 0.000244f, 0.000482f, 0.000674f, 0.001029f, 0.001440f, 0.001746f, 0.002153f, 0.002804f, 0.003206f, 0.003859f, 0.004948f,
+ 0.005722f, 0.007206f, 0.008568f, 0.010498f, 0.012413f, 0.015793f, 0.019989f, 0.024826f, 0.031799f, 0.041382f, 0.054932f, 0.074768f,
+ 0.103882f, 0.147949f, 0.213867f, 0.308838f, 0.429932f, 0.560059f, 0.675781f, 0.765625f, 0.827148f, 0.871582f, 0.901367f, 0.923340f,
+ 0.937988f, 0.949707f, 0.958496f, 0.965820f, 0.969727f, 0.974609f, 0.978027f, 0.980469f, 0.983398f, 0.985840f, 0.986816f, 0.988281f,
+ 0.989258f, 0.990723f, 0.992188f, 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996582f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000244f, 0.000244f, 0.000363f, 0.000604f, 0.000834f, 0.001020f, 0.001548f, 0.001970f,
+ 0.002262f, 0.002548f, 0.003157f, 0.003914f, 0.004681f, 0.005962f, 0.006943f, 0.008263f, 0.010277f, 0.012589f, 0.015144f, 0.018951f,
+ 0.023788f, 0.030014f, 0.039001f, 0.051056f, 0.069092f, 0.094666f, 0.133911f, 0.192993f, 0.279053f, 0.394287f, 0.524414f, 0.646484f,
+ 0.743652f, 0.812988f, 0.861328f, 0.895020f, 0.917969f, 0.935547f, 0.947754f, 0.957520f, 0.963867f, 0.969238f, 0.974121f, 0.978027f,
+ 0.980469f, 0.983398f, 0.984863f, 0.987305f, 0.988281f, 0.989258f, 0.990723f, 0.991699f, 0.992676f, 0.993652f, 0.994141f, 0.994629f,
+ 0.995117f, 0.996094f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000118f, 0.000244f, 0.000244f, 0.000584f,
+ 0.000837f, 0.000847f, 0.001295f, 0.001681f, 0.002018f, 0.002348f, 0.003014f, 0.003157f, 0.004124f, 0.004547f, 0.005432f, 0.006607f,
+ 0.008163f, 0.010071f, 0.011925f, 0.014786f, 0.017990f, 0.022659f, 0.028824f, 0.036621f, 0.047882f, 0.063477f, 0.087158f, 0.122559f,
+ 0.175781f, 0.254639f, 0.363037f, 0.492188f, 0.618652f, 0.722168f, 0.799805f, 0.852051f, 0.889648f, 0.914551f, 0.932129f, 0.944824f,
+ 0.955078f, 0.962891f, 0.968262f, 0.973633f, 0.977051f, 0.980469f, 0.982910f, 0.984863f, 0.987305f, 0.988281f, 0.990234f, 0.991211f,
+ 0.992188f, 0.993164f, 0.993652f, 0.994141f, 0.995117f, 0.995605f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000242f, 0.000243f, 0.000243f, 0.000481f, 0.000742f, 0.000843f, 0.000969f, 0.001348f, 0.001726f, 0.001791f, 0.002348f, 0.002853f,
+ 0.003452f, 0.003735f, 0.004757f, 0.005516f, 0.006744f, 0.008102f, 0.009621f, 0.011948f, 0.014320f, 0.017365f, 0.021698f, 0.027298f,
+ 0.034546f, 0.044891f, 0.059875f, 0.081055f, 0.112915f, 0.161255f, 0.234009f, 0.335693f, 0.462646f, 0.592285f, 0.702637f, 0.785645f,
+ 0.843750f, 0.883301f, 0.911133f, 0.929688f, 0.944336f, 0.954590f, 0.961914f, 0.967773f, 0.973633f, 0.977539f, 0.980469f, 0.982910f,
+ 0.985352f, 0.986816f, 0.988770f, 0.990234f, 0.991211f, 0.992188f, 0.993164f, 0.993652f, 0.994629f, 0.995117f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000100f, 0.000216f, 0.000243f, 0.000365f, 0.000517f, 0.000836f, 0.000964f, 0.001148f,
+ 0.001472f, 0.001674f, 0.001785f, 0.002438f, 0.002815f, 0.003490f, 0.004070f, 0.004837f, 0.005608f, 0.006630f, 0.008095f, 0.009483f,
+ 0.011551f, 0.013847f, 0.016953f, 0.020584f, 0.025879f, 0.033051f, 0.042664f, 0.055817f, 0.075500f, 0.105103f, 0.149536f, 0.216553f,
+ 0.312988f, 0.436768f, 0.568359f, 0.685059f, 0.773926f, 0.835449f, 0.878418f, 0.907227f, 0.927734f, 0.943359f, 0.953125f, 0.962402f,
+ 0.967285f, 0.973145f, 0.977051f, 0.980469f, 0.983887f, 0.985352f, 0.987305f, 0.989258f, 0.990234f, 0.991699f, 0.992188f, 0.993164f,
+ 0.994141f, 0.994629f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000150f, 0.000242f, 0.000364f,
+ 0.000441f, 0.000627f, 0.000916f, 0.000959f, 0.000968f, 0.001463f, 0.001671f, 0.002222f, 0.002577f, 0.002714f, 0.003479f, 0.004208f,
+ 0.004723f, 0.005669f, 0.006886f, 0.007637f, 0.009315f, 0.011154f, 0.013596f, 0.016205f, 0.019821f, 0.024963f, 0.031250f, 0.040375f,
+ 0.053009f, 0.071167f, 0.098511f, 0.139648f, 0.202271f, 0.293457f, 0.414307f, 0.548340f, 0.669434f, 0.762695f, 0.829590f, 0.874512f,
+ 0.904785f, 0.926758f, 0.941895f, 0.953613f, 0.961914f, 0.968262f, 0.973633f, 0.977539f, 0.980957f, 0.983398f, 0.985352f, 0.987793f,
+ 0.989258f, 0.990234f, 0.991211f, 0.992188f, 0.993164f, 0.994629f, 0.998047f, 0.998535f, 0.998047f, 0.998047f, 0.998047f, 0.998047f,
+ 0.000000f, 0.000231f, 0.000232f, 0.000363f, 0.000486f, 0.000503f, 0.000724f, 0.001104f, 0.001080f, 0.001271f, 0.001509f, 0.001976f,
+ 0.002247f, 0.002476f, 0.002895f, 0.003553f, 0.004192f, 0.004871f, 0.005623f, 0.006332f, 0.007584f, 0.008957f, 0.010849f, 0.012917f,
+ 0.015396f, 0.019226f, 0.023941f, 0.030060f, 0.038513f, 0.050385f, 0.067627f, 0.093140f, 0.131714f, 0.190674f, 0.278076f, 0.395752f,
+ 0.530273f, 0.655762f, 0.753906f, 0.823242f, 0.870605f, 0.903320f, 0.925781f, 0.941406f, 0.953125f, 0.961914f, 0.969238f, 0.974121f,
+ 0.978027f, 0.980957f, 0.983887f, 0.985840f, 0.988281f, 0.989258f, 0.990723f, 0.991699f, 0.992676f, 0.993652f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.000000f, 0.000009f, 0.000116f, 0.000360f, 0.000484f, 0.000485f, 0.000536f, 0.000827f,
+ 0.000935f, 0.001077f, 0.001204f, 0.001561f, 0.001974f, 0.002136f, 0.002777f, 0.002964f, 0.003517f, 0.004192f, 0.004711f, 0.005505f,
+ 0.006283f, 0.007408f, 0.008713f, 0.010674f, 0.012375f, 0.015099f, 0.018677f, 0.022797f, 0.028732f, 0.036835f, 0.047974f, 0.064270f,
+ 0.088318f, 0.124634f, 0.180664f, 0.264893f, 0.380615f, 0.516113f, 0.645020f, 0.747559f, 0.819824f, 0.870117f, 0.902344f, 0.925293f,
+ 0.941406f, 0.953613f, 0.962402f, 0.969238f, 0.974121f, 0.978027f, 0.981934f, 0.984375f, 0.986328f, 0.988281f, 0.989746f, 0.990723f,
+ 0.992676f, 0.993164f, 0.997559f, 0.998047f, 0.998047f, 0.997559f, 0.998047f, 0.998047f, 0.000000f, 0.000000f, 0.000074f, 0.000337f,
+ 0.000481f, 0.000484f, 0.000485f, 0.000556f, 0.000823f, 0.001143f, 0.001187f, 0.001391f, 0.001781f, 0.002155f, 0.002327f, 0.002760f,
+ 0.003008f, 0.003433f, 0.004101f, 0.004681f, 0.005417f, 0.006443f, 0.007393f, 0.008560f, 0.010345f, 0.012177f, 0.014496f, 0.018127f,
+ 0.022125f, 0.027740f, 0.035736f, 0.046173f, 0.061920f, 0.084717f, 0.119324f, 0.173218f, 0.254883f, 0.368652f, 0.505371f, 0.637207f,
+ 0.742676f, 0.818359f, 0.868164f, 0.902832f, 0.925781f, 0.942383f, 0.953613f, 0.963379f, 0.970215f, 0.975098f, 0.979004f, 0.982422f,
+ 0.984863f, 0.986328f, 0.988770f, 0.990723f, 0.991699f, 0.992676f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000188f, 0.000358f, 0.000481f, 0.000484f, 0.000484f, 0.000704f, 0.000852f, 0.001165f, 0.001316f,
+ 0.001500f, 0.001685f, 0.001933f, 0.002079f, 0.002720f, 0.003136f, 0.003727f, 0.003723f, 0.004513f, 0.005207f, 0.006275f, 0.007236f,
+ 0.008453f, 0.010056f, 0.011848f, 0.014191f, 0.017212f, 0.021652f, 0.026978f, 0.034241f, 0.044678f, 0.058990f, 0.081421f, 0.114929f,
+ 0.167236f, 0.247070f, 0.360596f, 0.498291f, 0.632812f, 0.741211f, 0.818359f, 0.869629f, 0.903809f, 0.927734f, 0.943848f, 0.955566f,
+ 0.964355f, 0.970703f, 0.976074f, 0.979492f, 0.982422f, 0.985840f, 0.987793f, 0.989258f, 0.990723f, 0.992188f, 0.997070f, 0.997559f,
+ 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000000f, 0.000121f, 0.000120f, 0.000288f, 0.000357f, 0.000479f, 0.000483f,
+ 0.000535f, 0.000711f, 0.000862f, 0.001256f, 0.001351f, 0.001502f, 0.001719f, 0.002146f, 0.002037f, 0.002653f, 0.003248f, 0.003222f,
+ 0.003820f, 0.004456f, 0.005173f, 0.006008f, 0.007072f, 0.008247f, 0.009758f, 0.011826f, 0.013771f, 0.016861f, 0.020935f, 0.025986f,
+ 0.032928f, 0.043030f, 0.057587f, 0.078918f, 0.111755f, 0.162964f, 0.241943f, 0.355713f, 0.495117f, 0.632324f, 0.742676f, 0.819336f,
+ 0.871582f, 0.905762f, 0.929688f, 0.945312f, 0.957031f, 0.965332f, 0.972168f, 0.976562f, 0.980957f, 0.983887f, 0.986328f, 0.988281f,
+ 0.990234f, 0.991699f, 0.997070f, 0.997559f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000000f, 0.000000f, 0.000121f,
+ 0.000200f, 0.000412f, 0.000471f, 0.000599f, 0.000598f, 0.000596f, 0.000805f, 0.001099f, 0.001334f, 0.001417f, 0.001456f, 0.001723f,
+ 0.002102f, 0.002283f, 0.002579f, 0.003208f, 0.003233f, 0.003740f, 0.004574f, 0.005287f, 0.006012f, 0.006870f, 0.008018f, 0.009354f,
+ 0.011208f, 0.013542f, 0.016495f, 0.020370f, 0.025284f, 0.032410f, 0.041901f, 0.056183f, 0.077087f, 0.109558f, 0.160278f, 0.239380f,
+ 0.354492f, 0.496094f, 0.635254f, 0.747070f, 0.823730f, 0.875488f, 0.908691f, 0.931641f, 0.947266f, 0.958008f, 0.966309f, 0.972656f,
+ 0.978027f, 0.981445f, 0.984863f, 0.986816f, 0.989258f, 0.990723f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997070f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000117f, 0.000237f, 0.000239f, 0.000430f, 0.000465f, 0.000599f, 0.000724f, 0.000716f, 0.000815f,
+ 0.000981f, 0.001334f, 0.001299f, 0.001545f, 0.001617f, 0.001935f, 0.002110f, 0.002501f, 0.002823f, 0.003408f, 0.003790f, 0.004467f,
+ 0.005112f, 0.005848f, 0.006718f, 0.007942f, 0.009514f, 0.011093f, 0.013092f, 0.015945f, 0.019608f, 0.024689f, 0.031494f, 0.041046f,
+ 0.054901f, 0.075989f, 0.108032f, 0.158936f, 0.239014f, 0.356201f, 0.500488f, 0.642090f, 0.753418f, 0.830566f, 0.880859f, 0.912598f,
+ 0.935059f, 0.950195f, 0.960449f, 0.968262f, 0.975098f, 0.979980f, 0.982910f, 0.985352f, 0.987793f, 0.990234f, 0.996582f, 0.997070f,
+ 0.997070f, 0.996582f, 0.997070f, 0.996582f, 0.000000f, 0.000000f, 0.000000f, 0.000117f, 0.000120f, 0.000121f, 0.000312f, 0.000407f,
+ 0.000707f, 0.000597f, 0.000648f, 0.000720f, 0.000941f, 0.001008f, 0.001229f, 0.001289f, 0.001423f, 0.001726f, 0.002060f, 0.002211f,
+ 0.002506f, 0.002985f, 0.003036f, 0.003683f, 0.004066f, 0.004833f, 0.005592f, 0.006611f, 0.007675f, 0.008965f, 0.010811f, 0.012833f,
+ 0.015854f, 0.019485f, 0.024429f, 0.031036f, 0.040466f, 0.054108f, 0.074890f, 0.107727f, 0.159180f, 0.241699f, 0.362549f, 0.510742f,
+ 0.653809f, 0.763184f, 0.837891f, 0.887207f, 0.917480f, 0.938477f, 0.953613f, 0.962891f, 0.970703f, 0.976562f, 0.980469f, 0.984375f,
+ 0.986816f, 0.988770f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.000000f, 0.000000f, 0.000000f, 0.000117f,
+ 0.000118f, 0.000120f, 0.000129f, 0.000434f, 0.000536f, 0.000613f, 0.000716f, 0.000799f, 0.000720f, 0.000768f, 0.001024f, 0.001202f,
+ 0.001501f, 0.001530f, 0.001568f, 0.001897f, 0.002190f, 0.002502f, 0.002893f, 0.003105f, 0.003551f, 0.004021f, 0.004791f, 0.005405f,
+ 0.006313f, 0.007309f, 0.008720f, 0.010712f, 0.012657f, 0.015472f, 0.018982f, 0.023697f, 0.030579f, 0.040009f, 0.054138f, 0.075012f,
+ 0.107849f, 0.161377f, 0.247070f, 0.373047f, 0.525391f, 0.667969f, 0.776855f, 0.847656f, 0.894043f, 0.923340f, 0.942871f, 0.956543f,
+ 0.965820f, 0.973145f, 0.978027f, 0.982422f, 0.985352f, 0.987793f, 0.996094f, 0.996094f, 0.996582f, 0.996094f, 0.996582f, 0.996094f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000081f, 0.000116f, 0.000227f, 0.000360f, 0.000366f, 0.000642f, 0.000691f, 0.000711f,
+ 0.000806f, 0.000721f, 0.000925f, 0.000947f, 0.001155f, 0.001478f, 0.001554f, 0.001612f, 0.001929f, 0.002354f, 0.002291f, 0.002712f,
+ 0.003029f, 0.003441f, 0.003876f, 0.004452f, 0.005276f, 0.006256f, 0.007149f, 0.008568f, 0.010040f, 0.012566f, 0.015160f, 0.018677f,
+ 0.023376f, 0.030411f, 0.039642f, 0.053986f, 0.075134f, 0.109436f, 0.165527f, 0.255127f, 0.387695f, 0.544434f, 0.686523f, 0.791016f,
+ 0.858398f, 0.901367f, 0.928711f, 0.947266f, 0.959961f, 0.968262f, 0.975098f, 0.980469f, 0.983887f, 0.987305f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000088f, 0.000085f, 0.000338f, 0.000351f,
+ 0.000359f, 0.000480f, 0.000539f, 0.000698f, 0.000798f, 0.000793f, 0.000834f, 0.000891f, 0.000941f, 0.001143f, 0.001422f, 0.001512f,
+ 0.001833f, 0.001955f, 0.002144f, 0.002426f, 0.002716f, 0.003262f, 0.003572f, 0.003860f, 0.004456f, 0.005173f, 0.006191f, 0.006939f,
+ 0.008545f, 0.010162f, 0.012375f, 0.014969f, 0.018555f, 0.023376f, 0.029953f, 0.039673f, 0.054077f, 0.076477f, 0.112000f, 0.171509f,
+ 0.268066f, 0.408203f, 0.569336f, 0.709961f, 0.808105f, 0.872070f, 0.910645f, 0.935059f, 0.951660f, 0.963379f, 0.971680f, 0.977539f,
+ 0.982422f, 0.985840f, 0.995117f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000116f, 0.000340f, 0.000353f, 0.000349f, 0.000480f, 0.000576f, 0.000668f, 0.000700f, 0.000818f, 0.000833f,
+ 0.000787f, 0.001125f, 0.001110f, 0.001407f, 0.001489f, 0.001563f, 0.001804f, 0.002073f, 0.002285f, 0.002409f, 0.002985f, 0.003052f,
+ 0.003853f, 0.004433f, 0.005100f, 0.006046f, 0.007046f, 0.008156f, 0.009827f, 0.012138f, 0.014740f, 0.018311f, 0.023071f, 0.029770f,
+ 0.040009f, 0.054810f, 0.078003f, 0.116150f, 0.180176f, 0.284668f, 0.434570f, 0.599121f, 0.735352f, 0.827637f, 0.885254f, 0.919922f,
+ 0.941895f, 0.957031f, 0.967285f, 0.975098f, 0.979980f, 0.984375f, 0.995117f, 0.995117f, 0.995117f, 0.995117f, 0.995117f, 0.995605f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000000f, 0.000122f, 0.000235f, 0.000320f, 0.000351f, 0.000353f, 0.000478f,
+ 0.000602f, 0.000651f, 0.000793f, 0.000706f, 0.000816f, 0.000814f, 0.000898f, 0.001062f, 0.001259f, 0.001441f, 0.001564f, 0.001772f,
+ 0.001743f, 0.002134f, 0.002512f, 0.002668f, 0.003193f, 0.003746f, 0.004341f, 0.004902f, 0.005909f, 0.006920f, 0.008125f, 0.009605f,
+ 0.011711f, 0.014549f, 0.018280f, 0.023163f, 0.030334f, 0.040375f, 0.055939f, 0.080566f, 0.122070f, 0.192383f, 0.307373f, 0.467773f,
+ 0.634277f, 0.763184f, 0.846191f, 0.897461f, 0.928711f, 0.948730f, 0.962402f, 0.971680f, 0.978516f, 0.982422f, 0.994141f, 0.994629f,
+ 0.994629f, 0.995117f, 0.995117f, 0.995117f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000185f, 0.000190f,
+ 0.000272f, 0.000281f, 0.000464f, 0.000466f, 0.000476f, 0.000521f, 0.000654f, 0.000680f, 0.000699f, 0.000815f, 0.000814f, 0.000890f,
+ 0.001110f, 0.001283f, 0.001311f, 0.001590f, 0.001727f, 0.001801f, 0.002020f, 0.002312f, 0.002897f, 0.003267f, 0.003592f, 0.004143f,
+ 0.004810f, 0.005844f, 0.006618f, 0.008018f, 0.009697f, 0.011597f, 0.014374f, 0.018127f, 0.023056f, 0.030258f, 0.041107f, 0.057373f,
+ 0.084045f, 0.129517f, 0.208618f, 0.337646f, 0.508789f, 0.673828f, 0.793457f, 0.866211f, 0.911133f, 0.938965f, 0.955566f, 0.967285f,
+ 0.975586f, 0.980469f, 0.994141f, 0.994141f, 0.994629f, 0.994629f, 0.994629f, 0.994141f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000226f, 0.000431f, 0.000456f, 0.000467f, 0.000352f, 0.000496f, 0.000588f,
+ 0.000891f, 0.000771f, 0.000803f, 0.000947f, 0.000972f, 0.001078f, 0.001033f, 0.001279f, 0.001436f, 0.001483f, 0.001831f, 0.002033f,
+ 0.002264f, 0.002710f, 0.002996f, 0.003582f, 0.004032f, 0.004665f, 0.005592f, 0.006527f, 0.007820f, 0.009323f, 0.011581f, 0.014328f,
+ 0.018219f, 0.023239f, 0.030777f, 0.042084f, 0.059448f, 0.089233f, 0.140869f, 0.230713f, 0.375977f, 0.556641f, 0.715332f, 0.822266f,
+ 0.885742f, 0.924316f, 0.947266f, 0.962402f, 0.972656f, 0.978516f, 0.993164f, 0.994141f, 0.994141f, 0.994141f, 0.994141f, 0.994141f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000283f, 0.000229f, 0.000425f,
+ 0.000303f, 0.000336f, 0.000469f, 0.000474f, 0.000728f, 0.000663f, 0.000883f, 0.000695f, 0.000679f, 0.000858f, 0.000919f, 0.000980f,
+ 0.001218f, 0.001330f, 0.001665f, 0.001637f, 0.002054f, 0.002335f, 0.002508f, 0.002880f, 0.003323f, 0.004055f, 0.004730f, 0.005463f,
+ 0.006485f, 0.007740f, 0.009293f, 0.011566f, 0.014175f, 0.017944f, 0.023346f, 0.031433f, 0.043304f, 0.063232f, 0.096313f, 0.155518f,
+ 0.260498f, 0.424561f, 0.611328f, 0.758789f, 0.852051f, 0.904785f, 0.937012f, 0.955566f, 0.968262f, 0.977051f, 0.992676f, 0.992676f,
+ 0.993164f, 0.993652f, 0.993164f, 0.993652f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000256f, 0.000216f, 0.000406f, 0.000426f, 0.000457f, 0.000453f, 0.000472f, 0.000651f, 0.000593f, 0.000876f,
+ 0.000571f, 0.000590f, 0.000819f, 0.000809f, 0.001000f, 0.001224f, 0.001293f, 0.001637f, 0.001790f, 0.001863f, 0.002298f, 0.002550f,
+ 0.002995f, 0.003201f, 0.003933f, 0.004677f, 0.005360f, 0.006447f, 0.007763f, 0.009377f, 0.011330f, 0.014420f, 0.017944f, 0.023560f,
+ 0.032196f, 0.045380f, 0.067383f, 0.105469f, 0.175659f, 0.301025f, 0.484375f, 0.669922f, 0.801270f, 0.879395f, 0.922852f, 0.948242f,
+ 0.963379f, 0.974121f, 0.992188f, 0.992188f, 0.992188f, 0.993164f, 0.992188f, 0.993164f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000230f, 0.000206f, 0.000355f, 0.000335f, 0.000305f,
+ 0.000461f, 0.000565f, 0.000474f, 0.000429f, 0.000520f, 0.000758f, 0.000777f, 0.000668f, 0.000821f, 0.001013f, 0.001089f, 0.001325f,
+ 0.001570f, 0.001787f, 0.001707f, 0.002037f, 0.002457f, 0.002892f, 0.003359f, 0.003881f, 0.004616f, 0.005203f, 0.006336f, 0.007477f,
+ 0.009048f, 0.011345f, 0.014015f, 0.018356f, 0.024307f, 0.033661f, 0.048279f, 0.073303f, 0.118774f, 0.204102f, 0.354492f, 0.554688f,
+ 0.729492f, 0.840332f, 0.902832f, 0.937988f, 0.958008f, 0.971191f, 0.991699f, 0.992188f, 0.992188f, 0.991699f, 0.992188f, 0.991699f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000205f, 0.000248f, 0.000213f, 0.000344f, 0.000437f, 0.000351f, 0.000352f, 0.000359f, 0.000389f, 0.000482f, 0.000676f, 0.000560f,
+ 0.000806f, 0.000813f, 0.000927f, 0.001230f, 0.001392f, 0.001526f, 0.001627f, 0.001629f, 0.002047f, 0.002321f, 0.002661f, 0.003317f,
+ 0.003752f, 0.004406f, 0.005119f, 0.005936f, 0.007156f, 0.009003f, 0.010941f, 0.013985f, 0.018539f, 0.025131f, 0.035248f, 0.051880f,
+ 0.081543f, 0.137207f, 0.244507f, 0.424561f, 0.632812f, 0.787598f, 0.876465f, 0.924805f, 0.951172f, 0.966797f, 0.990723f, 0.991211f,
+ 0.991211f, 0.991211f, 0.991211f, 0.991211f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000224f, 0.000171f, 0.000276f, 0.000278f, 0.000288f, 0.000329f, 0.000365f,
+ 0.000459f, 0.000483f, 0.000626f, 0.000716f, 0.000767f, 0.000793f, 0.000800f, 0.000897f, 0.000976f, 0.001156f, 0.001322f, 0.001427f,
+ 0.001799f, 0.001997f, 0.002256f, 0.002773f, 0.002806f, 0.003515f, 0.004040f, 0.004910f, 0.005730f, 0.007046f, 0.008858f, 0.011124f,
+ 0.014374f, 0.018982f, 0.026123f, 0.037659f, 0.057129f, 0.093445f, 0.164062f, 0.301514f, 0.511230f, 0.712402f, 0.838867f, 0.906738f,
+ 0.942383f, 0.961914f, 0.989746f, 0.990234f, 0.989746f, 0.990234f, 0.989746f, 0.990234f, 0.000000f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000173f, 0.000140f,
+ 0.000138f, 0.000232f, 0.000291f, 0.000318f, 0.000338f, 0.000346f, 0.000422f, 0.000368f, 0.000680f, 0.000722f, 0.000765f, 0.000766f,
+ 0.000803f, 0.001069f, 0.001103f, 0.001185f, 0.001611f, 0.001593f, 0.001939f, 0.002211f, 0.002569f, 0.003008f, 0.003239f, 0.003952f,
+ 0.004681f, 0.005630f, 0.007008f, 0.008720f, 0.011200f, 0.014587f, 0.019653f, 0.027527f, 0.040955f, 0.064514f, 0.110413f, 0.204224f,
+ 0.381104f, 0.609863f, 0.785645f, 0.881836f, 0.931152f, 0.956543f, 0.988770f, 0.989258f, 0.989258f, 0.989258f, 0.989258f, 0.988770f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000121f,
+ 0.000121f, 0.000123f, 0.000121f, 0.000090f, 0.000102f, 0.000063f, 0.000156f, 0.000248f, 0.000333f, 0.000321f, 0.000431f, 0.000392f,
+ 0.000349f, 0.000434f, 0.000674f, 0.000741f, 0.000776f, 0.000936f, 0.000888f, 0.001049f, 0.001179f, 0.001326f, 0.001686f, 0.001732f,
+ 0.002050f, 0.002150f, 0.002453f, 0.003016f, 0.003601f, 0.004444f, 0.005692f, 0.006741f, 0.008324f, 0.011093f, 0.014709f, 0.020752f,
+ 0.029800f, 0.045654f, 0.074951f, 0.136108f, 0.264893f, 0.486816f, 0.710938f, 0.848145f, 0.916992f, 0.950684f, 0.987305f, 0.987793f,
+ 0.987793f, 0.988281f, 0.987793f, 0.987793f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000100f, 0.000049f, 0.000039f, 0.000125f, 0.000121f,
+ 0.000184f, 0.000280f, 0.000366f, 0.000392f, 0.000333f, 0.000341f, 0.000477f, 0.000597f, 0.000607f, 0.000747f, 0.000767f, 0.000961f,
+ 0.000936f, 0.001056f, 0.001306f, 0.001388f, 0.001633f, 0.001836f, 0.001997f, 0.002348f, 0.002878f, 0.003332f, 0.004131f, 0.005165f,
+ 0.006519f, 0.008568f, 0.011444f, 0.015419f, 0.021881f, 0.032532f, 0.052032f, 0.091187f, 0.177246f, 0.357910f, 0.610352f, 0.800781f,
+ 0.897461f, 0.942871f, 0.985352f, 0.986328f, 0.986816f, 0.986328f, 0.986328f, 0.986328f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000099f, 0.000076f,
+ 0.000060f, 0.000108f, 0.000040f, 0.000127f, 0.000127f, 0.000121f, 0.000200f, 0.000265f, 0.000360f, 0.000316f, 0.000428f, 0.000455f,
+ 0.000456f, 0.000583f, 0.000682f, 0.000750f, 0.000773f, 0.000824f, 0.000937f, 0.001220f, 0.001262f, 0.001384f, 0.001622f, 0.001862f,
+ 0.002157f, 0.002817f, 0.003414f, 0.004082f, 0.004993f, 0.006561f, 0.008560f, 0.011696f, 0.016022f, 0.023529f, 0.036469f, 0.062286f,
+ 0.117126f, 0.245605f, 0.487549f, 0.732910f, 0.870605f, 0.933105f, 0.983887f, 0.984863f, 0.984863f, 0.984863f, 0.984375f, 0.984863f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000096f, 0.000075f, 0.000061f, 0.000083f, 0.000096f, 0.000034f, 0.000101f, 0.000121f, 0.000137f,
+ 0.000211f, 0.000324f, 0.000381f, 0.000373f, 0.000420f, 0.000472f, 0.000494f, 0.000690f, 0.000793f, 0.000768f, 0.000853f, 0.000867f,
+ 0.000978f, 0.001003f, 0.001145f, 0.001416f, 0.001888f, 0.002125f, 0.002491f, 0.003004f, 0.003864f, 0.005028f, 0.006500f, 0.008682f,
+ 0.011856f, 0.016922f, 0.025757f, 0.042603f, 0.078247f, 0.161743f, 0.358398f, 0.641602f, 0.833496f, 0.920410f, 0.981934f, 0.982910f,
+ 0.982910f, 0.982910f, 0.982910f, 0.982910f, 0.000122f, 0.000000f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000120f, 0.000097f, 0.000078f, 0.000062f, 0.000051f,
+ 0.000043f, 0.000072f, 0.000030f, 0.000060f, 0.000109f, 0.000206f, 0.000216f, 0.000333f, 0.000347f, 0.000395f, 0.000415f, 0.000458f,
+ 0.000568f, 0.000664f, 0.000709f, 0.000598f, 0.000781f, 0.000628f, 0.001053f, 0.001046f, 0.001179f, 0.001579f, 0.001649f, 0.002386f,
+ 0.002857f, 0.003727f, 0.004894f, 0.006363f, 0.008789f, 0.012314f, 0.018616f, 0.029709f, 0.052429f, 0.105652f, 0.244385f, 0.524414f,
+ 0.782715f, 0.904785f, 0.979492f, 0.980957f, 0.979980f, 0.979980f, 0.980469f, 0.980469f, 0.000000f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f,
+ 0.000120f, 0.000097f, 0.000079f, 0.000065f, 0.000054f, 0.000045f, 0.000073f, 0.000032f, 0.000089f, 0.000038f, 0.000134f, 0.000138f,
+ 0.000211f, 0.000333f, 0.000370f, 0.000400f, 0.000420f, 0.000496f, 0.000566f, 0.000494f, 0.000584f, 0.000714f, 0.000708f, 0.000843f,
+ 0.001056f, 0.001019f, 0.001327f, 0.001812f, 0.001908f, 0.002798f, 0.003479f, 0.004578f, 0.006195f, 0.008881f, 0.012901f, 0.020599f,
+ 0.035339f, 0.069214f, 0.159058f, 0.394531f, 0.709961f, 0.882812f, 0.977051f, 0.978027f, 0.977539f, 0.976562f, 0.977051f, 0.977539f,
+ 0.000000f, 0.000121f, 0.000120f, 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f,
+ 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000119f, 0.000120f, 0.000102f, 0.000084f, 0.000071f, 0.000059f, 0.000048f, 0.000041f,
+ 0.000035f, 0.000062f, 0.000026f, 0.000098f, 0.000103f, 0.000136f, 0.000230f, 0.000327f, 0.000356f, 0.000338f, 0.000387f, 0.000499f,
+ 0.000577f, 0.000627f, 0.000669f, 0.000611f, 0.000699f, 0.000904f, 0.000893f, 0.001340f, 0.001666f, 0.002068f, 0.002377f, 0.003105f,
+ 0.004345f, 0.006218f, 0.009178f, 0.013962f, 0.024170f, 0.045441f, 0.101868f, 0.271973f, 0.612305f, 0.853027f, 0.973145f, 0.974121f,
+ 0.973633f, 0.974121f, 0.973633f, 0.974121f, 0.000121f, 0.000120f, 0.000119f, 0.000120f, 0.000119f, 0.000119f, 0.000119f, 0.000119f,
+ 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000108f,
+ 0.000091f, 0.000075f, 0.000063f, 0.000053f, 0.000045f, 0.000039f, 0.000034f, 0.000040f, 0.000090f, 0.000068f, 0.000104f, 0.000127f,
+ 0.000220f, 0.000302f, 0.000412f, 0.000316f, 0.000444f, 0.000495f, 0.000428f, 0.000510f, 0.000463f, 0.000614f, 0.000726f, 0.000719f,
+ 0.001164f, 0.001533f, 0.001707f, 0.002079f, 0.002848f, 0.004189f, 0.006142f, 0.009491f, 0.016113f, 0.029343f, 0.064758f, 0.175415f,
+ 0.490723f, 0.812012f, 0.968750f, 0.969727f, 0.969238f, 0.969727f, 0.969727f, 0.969727f, 0.000000f, 0.000117f, 0.000117f, 0.000115f,
+ 0.000118f, 0.000118f, 0.000117f, 0.000117f, 0.000117f, 0.000117f, 0.000118f, 0.000117f, 0.000117f, 0.000118f, 0.000117f, 0.000117f,
+ 0.000117f, 0.000117f, 0.000117f, 0.000118f, 0.000117f, 0.000100f, 0.000082f, 0.000070f, 0.000060f, 0.000051f, 0.000043f, 0.000038f,
+ 0.000033f, 0.000053f, 0.000027f, 0.000089f, 0.000105f, 0.000137f, 0.000227f, 0.000277f, 0.000293f, 0.000284f, 0.000300f, 0.000420f,
+ 0.000367f, 0.000473f, 0.000467f, 0.000555f, 0.000625f, 0.000870f, 0.001177f, 0.001563f, 0.001982f, 0.002714f, 0.004051f, 0.006134f,
+ 0.010384f, 0.018967f, 0.040314f, 0.108887f, 0.358643f, 0.755859f, 0.962891f, 0.963867f, 0.964355f, 0.963867f, 0.963379f, 0.963379f,
+ 0.000000f, 0.000000f, 0.000098f, 0.000103f, 0.000111f, 0.000112f, 0.000112f, 0.000114f, 0.000113f, 0.000115f, 0.000114f, 0.000115f,
+ 0.000115f, 0.000115f, 0.000115f, 0.000115f, 0.000116f, 0.000116f, 0.000116f, 0.000116f, 0.000116f, 0.000116f, 0.000109f, 0.000094f,
+ 0.000078f, 0.000067f, 0.000058f, 0.000050f, 0.000043f, 0.000038f, 0.000033f, 0.000054f, 0.000025f, 0.000078f, 0.000091f, 0.000173f,
+ 0.000203f, 0.000252f, 0.000331f, 0.000277f, 0.000264f, 0.000407f, 0.000342f, 0.000444f, 0.000470f, 0.000542f, 0.000773f, 0.001081f,
+ 0.001245f, 0.001682f, 0.002602f, 0.003744f, 0.006248f, 0.011566f, 0.025040f, 0.065491f, 0.236938f, 0.678223f, 0.956055f, 0.956543f,
+ 0.956543f, 0.956543f, 0.957031f, 0.957031f, 0.000000f, 0.000000f, 0.000021f, 0.000080f, 0.000072f, 0.000089f, 0.000100f, 0.000099f,
+ 0.000105f, 0.000107f, 0.000107f, 0.000110f, 0.000109f, 0.000110f, 0.000111f, 0.000111f, 0.000112f, 0.000112f, 0.000112f, 0.000113f,
+ 0.000113f, 0.000113f, 0.000113f, 0.000113f, 0.000105f, 0.000090f, 0.000078f, 0.000067f, 0.000057f, 0.000050f, 0.000043f, 0.000038f,
+ 0.000033f, 0.000029f, 0.000025f, 0.000055f, 0.000091f, 0.000130f, 0.000225f, 0.000275f, 0.000254f, 0.000290f, 0.000259f, 0.000378f,
+ 0.000333f, 0.000362f, 0.000458f, 0.000587f, 0.000876f, 0.001062f, 0.001382f, 0.002398f, 0.003763f, 0.006603f, 0.014496f, 0.038300f,
+ 0.143677f, 0.573730f, 0.946777f, 0.947266f, 0.947266f, 0.947266f, 0.948242f, 0.947266f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000014f, 0.000036f, 0.000072f, 0.000082f, 0.000080f, 0.000094f, 0.000096f, 0.000099f, 0.000098f, 0.000103f, 0.000103f,
+ 0.000103f, 0.000106f, 0.000105f, 0.000107f, 0.000107f, 0.000108f, 0.000108f, 0.000109f, 0.000109f, 0.000109f, 0.000105f, 0.000090f,
+ 0.000078f, 0.000067f, 0.000059f, 0.000051f, 0.000045f, 0.000039f, 0.000034f, 0.000030f, 0.000026f, 0.000045f, 0.000086f, 0.000108f,
+ 0.000143f, 0.000212f, 0.000227f, 0.000204f, 0.000231f, 0.000263f, 0.000315f, 0.000354f, 0.000481f, 0.000702f, 0.000888f, 0.001257f,
+ 0.002018f, 0.003738f, 0.007675f, 0.021317f, 0.080933f, 0.444336f, 0.934082f, 0.935059f, 0.935059f, 0.935059f, 0.935059f, 0.935059f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000024f, 0.000038f, 0.000059f,
+ 0.000063f, 0.000076f, 0.000080f, 0.000085f, 0.000089f, 0.000091f, 0.000092f, 0.000095f, 0.000097f, 0.000099f, 0.000098f, 0.000101f,
+ 0.000101f, 0.000102f, 0.000103f, 0.000104f, 0.000104f, 0.000091f, 0.000080f, 0.000069f, 0.000062f, 0.000053f, 0.000046f, 0.000041f,
+ 0.000035f, 0.000032f, 0.000027f, 0.000039f, 0.000052f, 0.000103f, 0.000139f, 0.000178f, 0.000190f, 0.000178f, 0.000185f, 0.000247f,
+ 0.000274f, 0.000368f, 0.000528f, 0.000637f, 0.001027f, 0.001937f, 0.003853f, 0.010445f, 0.041718f, 0.304199f, 0.917480f, 0.917480f,
+ 0.917969f, 0.917480f, 0.918457f, 0.917969f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000023f, 0.000037f, 0.000048f, 0.000048f, 0.000063f, 0.000063f,
+ 0.000074f, 0.000077f, 0.000080f, 0.000083f, 0.000086f, 0.000088f, 0.000090f, 0.000091f, 0.000092f, 0.000094f, 0.000095f, 0.000096f,
+ 0.000084f, 0.000073f, 0.000064f, 0.000057f, 0.000049f, 0.000043f, 0.000037f, 0.000033f, 0.000029f, 0.000025f, 0.000060f, 0.000061f,
+ 0.000087f, 0.000118f, 0.000156f, 0.000131f, 0.000175f, 0.000226f, 0.000230f, 0.000373f, 0.000507f, 0.000992f, 0.001814f, 0.004639f,
+ 0.018799f, 0.176758f, 0.894043f, 0.894531f, 0.895508f, 0.895020f, 0.895020f, 0.895996f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000019f, 0.000028f, 0.000034f, 0.000043f, 0.000052f, 0.000057f, 0.000062f, 0.000067f,
+ 0.000070f, 0.000074f, 0.000075f, 0.000079f, 0.000081f, 0.000083f, 0.000085f, 0.000076f, 0.000068f, 0.000059f, 0.000051f, 0.000046f,
+ 0.000040f, 0.000035f, 0.000030f, 0.000026f, 0.000028f, 0.000038f, 0.000072f, 0.000100f, 0.000120f, 0.000107f, 0.000152f, 0.000156f,
+ 0.000254f, 0.000436f, 0.000722f, 0.001875f, 0.007088f, 0.083069f, 0.863281f, 0.862305f, 0.863281f, 0.862305f, 0.863281f, 0.862793f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000005f, 0.000015f, 0.000022f, 0.000030f, 0.000037f, 0.000042f, 0.000048f, 0.000053f, 0.000058f, 0.000060f,
+ 0.000064f, 0.000067f, 0.000069f, 0.000061f, 0.000053f, 0.000047f, 0.000041f, 0.000036f, 0.000031f, 0.000027f, 0.000023f, 0.000020f,
+ 0.000036f, 0.000063f, 0.000082f, 0.000081f, 0.000104f, 0.000149f, 0.000263f, 0.000616f, 0.002337f, 0.028168f, 0.816406f, 0.816895f,
+ 0.816895f, 0.816895f, 0.817383f, 0.816895f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000003f, 0.000011f, 0.000019f, 0.000026f, 0.000031f, 0.000036f, 0.000041f, 0.000045f, 0.000050f, 0.000047f,
+ 0.000041f, 0.000036f, 0.000031f, 0.000027f, 0.000023f, 0.000019f, 0.000028f, 0.000029f, 0.000053f, 0.000052f, 0.000072f, 0.000165f,
+ 0.000511f, 0.006050f, 0.751465f, 0.752441f, 0.752930f, 0.752441f, 0.752441f, 0.752930f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000011f, 0.000017f, 0.000021f, 0.000027f, 0.000028f, 0.000024f, 0.000020f, 0.000017f,
+ 0.000013f, 0.000020f, 0.000021f, 0.000029f, 0.000057f, 0.000588f, 0.665039f, 0.664551f, 0.665527f, 0.665039f, 0.665039f, 0.665039f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000009f, 0.000006f, 0.000004f, 0.000007f, 0.557129f, 0.558105f,
+ 0.557617f, 0.557617f, 0.558594f, 0.558105f,
+ },
+ {
+ 0.163818f, 0.558105f, 0.755859f, 0.841797f, 0.886230f, 0.912109f, 0.929199f, 0.941406f, 0.950195f, 0.957031f, 0.961914f, 0.966309f,
+ 0.970215f, 0.972656f, 0.975586f, 0.978027f, 0.979492f, 0.981445f, 0.982910f, 0.984375f, 0.985840f, 0.986328f, 0.987305f, 0.988770f,
+ 0.989258f, 0.989746f, 0.990234f, 0.991211f, 0.991699f, 0.992188f, 0.993164f, 0.993652f, 0.993652f, 0.993652f, 0.994141f, 0.995117f,
+ 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.027023f, 0.138184f, 0.353760f, 0.583984f, 0.735352f, 0.819336f, 0.868652f, 0.898926f,
+ 0.918945f, 0.933594f, 0.943848f, 0.952148f, 0.958984f, 0.963867f, 0.967773f, 0.971680f, 0.974121f, 0.976562f, 0.978516f, 0.980469f,
+ 0.982422f, 0.983398f, 0.984863f, 0.986328f, 0.986816f, 0.988281f, 0.989258f, 0.989746f, 0.990723f, 0.990723f, 0.991699f, 0.992676f,
+ 0.993164f, 0.993164f, 0.993652f, 0.994141f, 0.994141f, 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.997070f,
+ 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.009819f, 0.044250f, 0.113525f, 0.244995f,
+ 0.430420f, 0.608887f, 0.733887f, 0.810547f, 0.860352f, 0.892578f, 0.913086f, 0.929688f, 0.940918f, 0.949219f, 0.956055f, 0.961426f,
+ 0.966309f, 0.970215f, 0.972656f, 0.975586f, 0.977539f, 0.979980f, 0.980957f, 0.983398f, 0.983887f, 0.985352f, 0.986328f, 0.987793f,
+ 0.988281f, 0.989746f, 0.989746f, 0.991211f, 0.991699f, 0.992188f, 0.992676f, 0.993164f, 0.993652f, 0.993652f, 0.994141f, 0.995117f,
+ 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.004848f, 0.020447f, 0.046814f, 0.096313f, 0.183228f, 0.319092f, 0.484375f, 0.631836f, 0.739258f, 0.810547f, 0.857422f, 0.888672f,
+ 0.910645f, 0.925781f, 0.938965f, 0.947754f, 0.954590f, 0.960449f, 0.964355f, 0.968750f, 0.971191f, 0.974609f, 0.977051f, 0.979004f,
+ 0.980957f, 0.982422f, 0.983887f, 0.985840f, 0.986816f, 0.987793f, 0.988770f, 0.989258f, 0.990234f, 0.990723f, 0.991211f, 0.991699f,
+ 0.992676f, 0.992676f, 0.993652f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.996582f,
+ 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.003096f, 0.011017f, 0.024399f, 0.046600f, 0.083191f, 0.145386f, 0.243774f, 0.379395f,
+ 0.529297f, 0.656738f, 0.750977f, 0.813965f, 0.857910f, 0.887695f, 0.909668f, 0.925293f, 0.937500f, 0.946289f, 0.953613f, 0.959473f,
+ 0.964355f, 0.968262f, 0.971191f, 0.974121f, 0.976562f, 0.979004f, 0.980957f, 0.982910f, 0.984375f, 0.985840f, 0.986328f, 0.987793f,
+ 0.988281f, 0.989258f, 0.989746f, 0.991211f, 0.991699f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f,
+ 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.998047f,
+ 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.001808f, 0.006992f, 0.014923f, 0.026413f,
+ 0.044403f, 0.073120f, 0.119446f, 0.193115f, 0.300537f, 0.433594f, 0.568848f, 0.680664f, 0.763184f, 0.821289f, 0.860840f, 0.890137f,
+ 0.909668f, 0.925293f, 0.937500f, 0.945801f, 0.953613f, 0.959473f, 0.963867f, 0.968262f, 0.971680f, 0.974609f, 0.977051f, 0.979004f,
+ 0.980957f, 0.982422f, 0.983887f, 0.984863f, 0.986816f, 0.987305f, 0.987793f, 0.989746f, 0.989746f, 0.991211f, 0.991699f, 0.992188f,
+ 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.994629f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997070f,
+ 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.001668f, 0.005253f, 0.010010f, 0.016602f, 0.026459f, 0.042023f, 0.065369f, 0.101868f, 0.158081f, 0.241455f, 0.354248f, 0.483887f,
+ 0.606934f, 0.706055f, 0.777832f, 0.830566f, 0.867188f, 0.893066f, 0.912109f, 0.926270f, 0.938477f, 0.946289f, 0.953125f, 0.959473f,
+ 0.964355f, 0.968750f, 0.971680f, 0.975098f, 0.977051f, 0.979492f, 0.980957f, 0.982910f, 0.984375f, 0.985840f, 0.986328f, 0.987305f,
+ 0.988770f, 0.989746f, 0.990234f, 0.991211f, 0.992188f, 0.993164f, 0.993164f, 0.994141f, 0.994629f, 0.994629f, 0.995117f, 0.995605f,
+ 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998047f, 0.998535f, 0.999023f, 0.999023f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999023f, 0.001086f, 0.003477f, 0.006756f, 0.011604f, 0.018066f, 0.027222f, 0.039978f, 0.059448f,
+ 0.088257f, 0.132690f, 0.198120f, 0.291504f, 0.408447f, 0.531250f, 0.641602f, 0.728516f, 0.793457f, 0.839844f, 0.873047f, 0.896973f,
+ 0.915527f, 0.929199f, 0.939941f, 0.948730f, 0.955566f, 0.960938f, 0.965332f, 0.969238f, 0.972168f, 0.975098f, 0.977539f, 0.979492f,
+ 0.981445f, 0.983398f, 0.984375f, 0.985840f, 0.986816f, 0.988281f, 0.989258f, 0.989746f, 0.990723f, 0.991699f, 0.992188f, 0.993164f,
+ 0.993652f, 0.994141f, 0.994629f, 0.994629f, 0.995605f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.997559f, 0.997559f,
+ 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000982f, 0.002764f, 0.004925f, 0.008194f,
+ 0.012703f, 0.018417f, 0.026154f, 0.037964f, 0.053894f, 0.078552f, 0.113770f, 0.166626f, 0.242310f, 0.343262f, 0.460449f, 0.576660f,
+ 0.675293f, 0.753418f, 0.809570f, 0.851074f, 0.879883f, 0.902344f, 0.919434f, 0.931152f, 0.941895f, 0.950195f, 0.956055f, 0.960938f,
+ 0.965820f, 0.969727f, 0.973145f, 0.976074f, 0.978027f, 0.980469f, 0.981934f, 0.983887f, 0.985352f, 0.986328f, 0.987793f, 0.988770f,
+ 0.989746f, 0.990234f, 0.991211f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996582f, 0.996582f, 0.997559f, 0.997559f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000723f, 0.002268f, 0.003639f, 0.006371f, 0.009392f, 0.013046f, 0.018570f, 0.026016f, 0.035919f, 0.049957f, 0.070618f, 0.099609f,
+ 0.142212f, 0.204590f, 0.290039f, 0.396973f, 0.512207f, 0.619141f, 0.707520f, 0.775391f, 0.825195f, 0.860352f, 0.887207f, 0.907715f,
+ 0.923340f, 0.935547f, 0.944824f, 0.951660f, 0.958496f, 0.963379f, 0.967773f, 0.971191f, 0.974121f, 0.977051f, 0.979492f, 0.980957f,
+ 0.982910f, 0.984375f, 0.985352f, 0.987305f, 0.988281f, 0.989258f, 0.989746f, 0.990723f, 0.991699f, 0.992188f, 0.993164f, 0.993164f,
+ 0.994141f, 0.994629f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000364f, 0.001690f, 0.003056f, 0.004982f, 0.007217f, 0.010124f, 0.013931f, 0.018738f,
+ 0.025177f, 0.034332f, 0.045990f, 0.063599f, 0.088501f, 0.124146f, 0.175781f, 0.248047f, 0.341797f, 0.451416f, 0.562012f, 0.659668f,
+ 0.738281f, 0.797852f, 0.841797f, 0.872559f, 0.896484f, 0.914062f, 0.928711f, 0.938477f, 0.947266f, 0.954590f, 0.959473f, 0.964844f,
+ 0.969238f, 0.972168f, 0.975098f, 0.977539f, 0.979980f, 0.981934f, 0.983398f, 0.985352f, 0.986816f, 0.987793f, 0.988770f, 0.989746f,
+ 0.990723f, 0.991211f, 0.992188f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995117f, 0.995605f, 0.996094f, 0.996582f,
+ 0.997070f, 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000365f, 0.001221f, 0.002531f, 0.003979f,
+ 0.005829f, 0.007874f, 0.010475f, 0.013962f, 0.018402f, 0.024368f, 0.032257f, 0.042847f, 0.057983f, 0.079346f, 0.109375f, 0.153198f,
+ 0.214233f, 0.295898f, 0.397705f, 0.506836f, 0.609863f, 0.698730f, 0.767578f, 0.817871f, 0.854980f, 0.883301f, 0.903809f, 0.920410f,
+ 0.933105f, 0.942871f, 0.950195f, 0.957031f, 0.962402f, 0.966797f, 0.970703f, 0.973633f, 0.976562f, 0.979004f, 0.981445f, 0.982910f,
+ 0.984375f, 0.985840f, 0.986816f, 0.988281f, 0.989746f, 0.989746f, 0.991211f, 0.992188f, 0.992676f, 0.993164f, 0.993652f, 0.994141f,
+ 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.000343f, 0.001357f, 0.002039f, 0.003130f, 0.004398f, 0.006432f, 0.008141f, 0.010925f, 0.014008f, 0.018326f, 0.023331f, 0.030655f,
+ 0.040558f, 0.053680f, 0.071960f, 0.098206f, 0.134644f, 0.187012f, 0.258057f, 0.349854f, 0.455566f, 0.562012f, 0.656738f, 0.734863f,
+ 0.792969f, 0.836914f, 0.868652f, 0.894043f, 0.912598f, 0.926758f, 0.937988f, 0.947266f, 0.954590f, 0.960449f, 0.964355f, 0.968750f,
+ 0.972656f, 0.975586f, 0.978027f, 0.980469f, 0.981934f, 0.983398f, 0.985840f, 0.986816f, 0.988281f, 0.989258f, 0.990723f, 0.990723f,
+ 0.991699f, 0.992676f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000244f, 0.001185f, 0.001561f, 0.002504f, 0.003990f, 0.005272f, 0.006573f, 0.008606f,
+ 0.010933f, 0.013878f, 0.017715f, 0.022415f, 0.029068f, 0.038086f, 0.049774f, 0.066162f, 0.088257f, 0.120361f, 0.164917f, 0.227173f,
+ 0.308838f, 0.407959f, 0.515137f, 0.615723f, 0.700684f, 0.767090f, 0.817383f, 0.854492f, 0.882812f, 0.904297f, 0.920898f, 0.932617f,
+ 0.943359f, 0.951172f, 0.957520f, 0.962891f, 0.967773f, 0.971191f, 0.974121f, 0.977539f, 0.979492f, 0.981445f, 0.983887f, 0.985352f,
+ 0.986816f, 0.988281f, 0.988770f, 0.989258f, 0.990723f, 0.991699f, 0.992188f, 0.993164f, 0.993652f, 0.994141f, 0.995117f, 0.995605f,
+ 0.995605f, 0.996582f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000243f, 0.000847f, 0.001555f, 0.002224f,
+ 0.003141f, 0.004093f, 0.005264f, 0.006817f, 0.008850f, 0.010948f, 0.014053f, 0.017456f, 0.022339f, 0.028351f, 0.036011f, 0.046326f,
+ 0.060791f, 0.080444f, 0.107788f, 0.146851f, 0.201660f, 0.274658f, 0.366699f, 0.470215f, 0.574707f, 0.666016f, 0.740234f, 0.797363f,
+ 0.839355f, 0.871094f, 0.895508f, 0.913574f, 0.927734f, 0.938965f, 0.947754f, 0.955566f, 0.960449f, 0.965332f, 0.969727f, 0.973145f,
+ 0.976074f, 0.979004f, 0.981445f, 0.982910f, 0.984863f, 0.986328f, 0.987305f, 0.988770f, 0.989258f, 0.990723f, 0.991699f, 0.992188f,
+ 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.996094f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000244f, 0.000767f, 0.001042f, 0.001934f, 0.002502f, 0.003588f, 0.004292f, 0.005558f, 0.006824f, 0.008667f, 0.010872f, 0.013802f,
+ 0.017426f, 0.021637f, 0.027176f, 0.033936f, 0.043304f, 0.056549f, 0.073914f, 0.098083f, 0.132446f, 0.180664f, 0.245239f, 0.330078f,
+ 0.429199f, 0.533203f, 0.631348f, 0.711914f, 0.775879f, 0.823242f, 0.860352f, 0.886230f, 0.907227f, 0.923340f, 0.935059f, 0.944824f,
+ 0.952148f, 0.958984f, 0.964844f, 0.968750f, 0.972168f, 0.975586f, 0.978516f, 0.980957f, 0.982422f, 0.983887f, 0.985840f, 0.987305f,
+ 0.988770f, 0.989746f, 0.990234f, 0.992188f, 0.992676f, 0.992676f, 0.994141f, 0.994141f, 0.995117f, 0.995605f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000000f, 0.000485f, 0.001062f, 0.001658f, 0.002398f, 0.002998f, 0.003805f, 0.004723f,
+ 0.006004f, 0.007084f, 0.009102f, 0.011093f, 0.013489f, 0.016876f, 0.020813f, 0.025803f, 0.032257f, 0.040924f, 0.052673f, 0.068298f,
+ 0.090149f, 0.120239f, 0.162598f, 0.221313f, 0.298096f, 0.392822f, 0.496582f, 0.597656f, 0.684082f, 0.754883f, 0.807617f, 0.848145f,
+ 0.877930f, 0.900391f, 0.917969f, 0.931641f, 0.941406f, 0.950684f, 0.957031f, 0.962402f, 0.967773f, 0.971680f, 0.974609f, 0.978027f,
+ 0.980469f, 0.982422f, 0.984375f, 0.985840f, 0.987305f, 0.988281f, 0.989746f, 0.990723f, 0.991699f, 0.992188f, 0.993164f, 0.993652f,
+ 0.994141f, 0.995117f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000244f, 0.000477f, 0.000852f, 0.001439f,
+ 0.002045f, 0.002424f, 0.003101f, 0.004093f, 0.004887f, 0.005989f, 0.007751f, 0.008606f, 0.011002f, 0.013420f, 0.016251f, 0.020035f,
+ 0.024628f, 0.030579f, 0.039093f, 0.049255f, 0.063599f, 0.083191f, 0.109924f, 0.148071f, 0.200928f, 0.270996f, 0.359863f, 0.461670f,
+ 0.564453f, 0.656738f, 0.732910f, 0.791992f, 0.836426f, 0.869629f, 0.894531f, 0.913086f, 0.928223f, 0.939453f, 0.949219f, 0.956055f,
+ 0.961914f, 0.966797f, 0.970703f, 0.975098f, 0.977051f, 0.979492f, 0.982422f, 0.983887f, 0.985352f, 0.987305f, 0.988770f, 0.989746f,
+ 0.990723f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994629f, 0.998047f, 0.998535f, 0.998535f, 0.998047f, 0.998047f, 0.998535f,
+ 0.000242f, 0.000650f, 0.000847f, 0.001138f, 0.001621f, 0.002239f, 0.002527f, 0.003325f, 0.004227f, 0.005165f, 0.006462f, 0.007389f,
+ 0.008904f, 0.011024f, 0.013130f, 0.015915f, 0.019272f, 0.023819f, 0.029205f, 0.036652f, 0.046417f, 0.059418f, 0.077209f, 0.101562f,
+ 0.136230f, 0.183350f, 0.248047f, 0.331055f, 0.429688f, 0.533203f, 0.630859f, 0.711426f, 0.776367f, 0.824219f, 0.861328f, 0.887695f,
+ 0.908691f, 0.924805f, 0.937500f, 0.946777f, 0.954102f, 0.960938f, 0.966309f, 0.970215f, 0.974121f, 0.977539f, 0.979492f, 0.981934f,
+ 0.983887f, 0.985840f, 0.987305f, 0.989258f, 0.989746f, 0.990723f, 0.991211f, 0.992676f, 0.993164f, 0.994141f, 0.997559f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.000089f, 0.000243f, 0.000827f, 0.000964f, 0.001418f, 0.001579f, 0.002296f, 0.002914f,
+ 0.003632f, 0.004280f, 0.005344f, 0.006130f, 0.007545f, 0.008949f, 0.010498f, 0.012733f, 0.015686f, 0.018646f, 0.023010f, 0.028229f,
+ 0.034851f, 0.044098f, 0.056122f, 0.072388f, 0.094788f, 0.125610f, 0.168945f, 0.228271f, 0.306396f, 0.401123f, 0.504883f, 0.604492f,
+ 0.691895f, 0.760742f, 0.813477f, 0.853027f, 0.881836f, 0.904297f, 0.921387f, 0.934570f, 0.944824f, 0.953125f, 0.959961f, 0.964844f,
+ 0.969727f, 0.973633f, 0.976562f, 0.979492f, 0.981934f, 0.983887f, 0.986328f, 0.987305f, 0.988281f, 0.989258f, 0.991211f, 0.992188f,
+ 0.992676f, 0.993652f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.000069f, 0.000461f, 0.000609f, 0.000933f,
+ 0.001088f, 0.001488f, 0.001900f, 0.002378f, 0.003101f, 0.003687f, 0.004547f, 0.005276f, 0.006233f, 0.007282f, 0.008820f, 0.010239f,
+ 0.012581f, 0.015312f, 0.018341f, 0.022095f, 0.027344f, 0.034027f, 0.041687f, 0.053467f, 0.067810f, 0.088440f, 0.117126f, 0.156616f,
+ 0.211426f, 0.284180f, 0.375977f, 0.478760f, 0.581543f, 0.672363f, 0.746094f, 0.802734f, 0.845703f, 0.877441f, 0.900879f, 0.918457f,
+ 0.933105f, 0.943848f, 0.951660f, 0.959473f, 0.964355f, 0.968750f, 0.974121f, 0.977051f, 0.979492f, 0.982422f, 0.984375f, 0.985840f,
+ 0.987305f, 0.988770f, 0.990234f, 0.991211f, 0.992188f, 0.993164f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f,
+ 0.000244f, 0.000348f, 0.000606f, 0.000737f, 0.001079f, 0.001458f, 0.001783f, 0.002192f, 0.002924f, 0.003231f, 0.003862f, 0.004551f,
+ 0.005169f, 0.006367f, 0.007381f, 0.008682f, 0.010590f, 0.012199f, 0.014900f, 0.017761f, 0.021530f, 0.026108f, 0.032349f, 0.039642f,
+ 0.050446f, 0.064392f, 0.083313f, 0.109436f, 0.145996f, 0.197021f, 0.266357f, 0.354248f, 0.455811f, 0.560059f, 0.654785f, 0.732910f,
+ 0.793457f, 0.837891f, 0.873047f, 0.897461f, 0.917480f, 0.931641f, 0.941895f, 0.951172f, 0.958984f, 0.964844f, 0.969727f, 0.973633f,
+ 0.977051f, 0.979980f, 0.981934f, 0.984375f, 0.985840f, 0.988281f, 0.989258f, 0.990234f, 0.991211f, 0.992676f, 0.997070f, 0.997559f,
+ 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000244f, 0.000520f, 0.000592f, 0.000720f, 0.000812f, 0.001174f, 0.001500f, 0.001884f,
+ 0.002178f, 0.002831f, 0.003321f, 0.003885f, 0.004471f, 0.005436f, 0.006275f, 0.007584f, 0.008675f, 0.010521f, 0.012238f, 0.014557f,
+ 0.017197f, 0.020874f, 0.025467f, 0.030960f, 0.038208f, 0.047821f, 0.061249f, 0.078552f, 0.103149f, 0.136841f, 0.184937f, 0.249878f,
+ 0.334473f, 0.435059f, 0.539551f, 0.638184f, 0.720215f, 0.784668f, 0.832031f, 0.868164f, 0.894531f, 0.914062f, 0.929688f, 0.942383f,
+ 0.950684f, 0.958984f, 0.964844f, 0.970215f, 0.974121f, 0.977539f, 0.979980f, 0.982422f, 0.984863f, 0.985840f, 0.988281f, 0.989258f,
+ 0.990723f, 0.992188f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997559f, 0.997559f, 0.000000f, 0.000243f, 0.000351f, 0.000603f,
+ 0.000708f, 0.001079f, 0.001493f, 0.001752f, 0.001936f, 0.002171f, 0.002911f, 0.003382f, 0.003906f, 0.004578f, 0.005222f, 0.006161f,
+ 0.007362f, 0.008850f, 0.010010f, 0.011971f, 0.014145f, 0.016983f, 0.020477f, 0.024582f, 0.029739f, 0.036804f, 0.045837f, 0.057648f,
+ 0.074829f, 0.097534f, 0.130127f, 0.174438f, 0.236572f, 0.318604f, 0.416992f, 0.523926f, 0.624023f, 0.709961f, 0.777344f, 0.827148f,
+ 0.865234f, 0.893066f, 0.914062f, 0.929688f, 0.941406f, 0.951660f, 0.958496f, 0.965820f, 0.969238f, 0.974609f, 0.977539f, 0.980469f,
+ 0.983398f, 0.985352f, 0.986816f, 0.988281f, 0.989746f, 0.990723f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997070f,
+ 0.000243f, 0.000244f, 0.000456f, 0.000592f, 0.000602f, 0.001025f, 0.001282f, 0.001656f, 0.001856f, 0.002073f, 0.002535f, 0.002768f,
+ 0.003487f, 0.003822f, 0.004574f, 0.005589f, 0.006519f, 0.007336f, 0.008453f, 0.009911f, 0.011581f, 0.013985f, 0.016373f, 0.019638f,
+ 0.023819f, 0.028473f, 0.035339f, 0.043945f, 0.055939f, 0.071350f, 0.093140f, 0.123474f, 0.165771f, 0.225342f, 0.304199f, 0.402344f,
+ 0.509277f, 0.612305f, 0.702148f, 0.771973f, 0.824219f, 0.863281f, 0.891113f, 0.913086f, 0.930176f, 0.942383f, 0.951660f, 0.959473f,
+ 0.965820f, 0.970215f, 0.974609f, 0.977539f, 0.980957f, 0.983887f, 0.985352f, 0.987305f, 0.988770f, 0.990723f, 0.996582f, 0.996582f,
+ 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.000000f, 0.000243f, 0.000276f, 0.000557f, 0.000594f, 0.000849f, 0.000845f, 0.001282f,
+ 0.001520f, 0.001774f, 0.002119f, 0.002499f, 0.002840f, 0.003252f, 0.004005f, 0.004555f, 0.005245f, 0.006168f, 0.007233f, 0.008301f,
+ 0.009911f, 0.011330f, 0.013748f, 0.015945f, 0.019089f, 0.023071f, 0.027786f, 0.034058f, 0.042542f, 0.053619f, 0.068237f, 0.089539f,
+ 0.117798f, 0.158325f, 0.215698f, 0.293213f, 0.389893f, 0.498291f, 0.603027f, 0.694824f, 0.767090f, 0.821777f, 0.862305f, 0.891113f,
+ 0.914062f, 0.930176f, 0.942383f, 0.952148f, 0.959473f, 0.965820f, 0.971680f, 0.975098f, 0.978516f, 0.981445f, 0.983887f, 0.985840f,
+ 0.988281f, 0.989258f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.996094f, 0.996582f, 0.000240f, 0.000240f, 0.000242f, 0.000365f,
+ 0.000678f, 0.000779f, 0.000957f, 0.001003f, 0.001390f, 0.001656f, 0.001828f, 0.002274f, 0.002455f, 0.003210f, 0.003704f, 0.004097f,
+ 0.004616f, 0.005409f, 0.006180f, 0.007092f, 0.008453f, 0.009521f, 0.011154f, 0.013397f, 0.015656f, 0.018509f, 0.022247f, 0.026810f,
+ 0.032928f, 0.041046f, 0.051727f, 0.065613f, 0.085205f, 0.113098f, 0.152832f, 0.208496f, 0.284424f, 0.380371f, 0.489258f, 0.596680f,
+ 0.690918f, 0.764648f, 0.821777f, 0.862305f, 0.892578f, 0.914551f, 0.931152f, 0.943848f, 0.953613f, 0.960938f, 0.967773f, 0.971680f,
+ 0.976074f, 0.979492f, 0.982422f, 0.984863f, 0.986816f, 0.988281f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.996094f,
+ 0.000000f, 0.000242f, 0.000242f, 0.000364f, 0.000465f, 0.000803f, 0.000927f, 0.000956f, 0.001275f, 0.001335f, 0.001570f, 0.001968f,
+ 0.002184f, 0.002726f, 0.003069f, 0.003294f, 0.003906f, 0.004662f, 0.005245f, 0.006027f, 0.007191f, 0.008202f, 0.009460f, 0.010735f,
+ 0.012970f, 0.015404f, 0.018051f, 0.021484f, 0.026321f, 0.032135f, 0.039581f, 0.049805f, 0.063538f, 0.082458f, 0.109497f, 0.147827f,
+ 0.202393f, 0.277344f, 0.373535f, 0.483887f, 0.593262f, 0.688477f, 0.764648f, 0.821289f, 0.863281f, 0.894043f, 0.916016f, 0.932129f,
+ 0.944336f, 0.954590f, 0.962402f, 0.968262f, 0.973633f, 0.977051f, 0.980957f, 0.983398f, 0.985352f, 0.987793f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.000000f, 0.000239f, 0.000360f, 0.000362f, 0.000363f, 0.000475f, 0.000767f, 0.000931f,
+ 0.000951f, 0.001211f, 0.001491f, 0.001634f, 0.002129f, 0.002457f, 0.002678f, 0.002995f, 0.003393f, 0.003922f, 0.004711f, 0.005135f,
+ 0.005955f, 0.006935f, 0.008072f, 0.009270f, 0.010841f, 0.012558f, 0.014618f, 0.017502f, 0.020828f, 0.025269f, 0.030884f, 0.038269f,
+ 0.048218f, 0.061554f, 0.080505f, 0.106567f, 0.144287f, 0.197998f, 0.272705f, 0.369141f, 0.480469f, 0.591797f, 0.690430f, 0.767090f,
+ 0.824707f, 0.866699f, 0.896484f, 0.918457f, 0.934570f, 0.946777f, 0.956543f, 0.963379f, 0.969727f, 0.974609f, 0.978027f, 0.981934f,
+ 0.984375f, 0.986328f, 0.995117f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.000000f, 0.000208f, 0.000238f, 0.000362f,
+ 0.000363f, 0.000555f, 0.000600f, 0.000888f, 0.001140f, 0.001140f, 0.001272f, 0.001661f, 0.001811f, 0.002041f, 0.002550f, 0.002636f,
+ 0.002941f, 0.003492f, 0.004032f, 0.004593f, 0.005062f, 0.005875f, 0.007015f, 0.007965f, 0.009079f, 0.010300f, 0.012291f, 0.014229f,
+ 0.016937f, 0.020248f, 0.024689f, 0.030151f, 0.037354f, 0.047028f, 0.060211f, 0.078491f, 0.104431f, 0.141602f, 0.195068f, 0.270264f,
+ 0.367676f, 0.480957f, 0.594238f, 0.693848f, 0.770996f, 0.828613f, 0.869629f, 0.898438f, 0.921875f, 0.937012f, 0.949219f, 0.958008f,
+ 0.964844f, 0.971680f, 0.976074f, 0.979980f, 0.982422f, 0.985840f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.995117f, 0.995117f,
+ 0.000000f, 0.000000f, 0.000229f, 0.000358f, 0.000479f, 0.000362f, 0.000498f, 0.000634f, 0.000836f, 0.000927f, 0.001288f, 0.001244f,
+ 0.001605f, 0.001732f, 0.002106f, 0.002478f, 0.002613f, 0.003183f, 0.003510f, 0.004021f, 0.004528f, 0.005047f, 0.005768f, 0.006859f,
+ 0.007759f, 0.008865f, 0.009933f, 0.011742f, 0.013741f, 0.016678f, 0.019897f, 0.024017f, 0.029297f, 0.036469f, 0.045990f, 0.058990f,
+ 0.077026f, 0.102722f, 0.140015f, 0.193604f, 0.269531f, 0.369141f, 0.485107f, 0.600098f, 0.700195f, 0.777344f, 0.833984f, 0.873535f,
+ 0.903809f, 0.924316f, 0.940430f, 0.951172f, 0.960938f, 0.968262f, 0.973145f, 0.978027f, 0.980957f, 0.983887f, 0.994629f, 0.995117f,
+ 0.995117f, 0.995605f, 0.995117f, 0.995117f, 0.000000f, 0.000000f, 0.000078f, 0.000353f, 0.000354f, 0.000360f, 0.000482f, 0.000573f,
+ 0.000757f, 0.000923f, 0.001230f, 0.001266f, 0.001485f, 0.001679f, 0.001963f, 0.002161f, 0.002235f, 0.002739f, 0.003115f, 0.003563f,
+ 0.003933f, 0.004436f, 0.004917f, 0.005623f, 0.006599f, 0.007469f, 0.008484f, 0.010101f, 0.011665f, 0.013695f, 0.016403f, 0.019531f,
+ 0.023300f, 0.028870f, 0.035889f, 0.045135f, 0.058014f, 0.075928f, 0.101746f, 0.139160f, 0.193848f, 0.271729f, 0.374023f, 0.492920f,
+ 0.609863f, 0.709473f, 0.786133f, 0.842285f, 0.880859f, 0.908691f, 0.928711f, 0.943848f, 0.954102f, 0.963867f, 0.969727f, 0.975098f,
+ 0.979004f, 0.982422f, 0.994141f, 0.994629f, 0.994141f, 0.994141f, 0.994141f, 0.994629f, 0.000000f, 0.000000f, 0.000000f, 0.000330f,
+ 0.000336f, 0.000352f, 0.000478f, 0.000481f, 0.000676f, 0.000822f, 0.001072f, 0.001228f, 0.001283f, 0.001417f, 0.001621f, 0.001938f,
+ 0.001953f, 0.002377f, 0.002737f, 0.002914f, 0.003624f, 0.003721f, 0.004555f, 0.004845f, 0.005531f, 0.006325f, 0.007244f, 0.008255f,
+ 0.009911f, 0.011467f, 0.013496f, 0.016068f, 0.018951f, 0.022888f, 0.028183f, 0.035126f, 0.044617f, 0.057220f, 0.075134f, 0.101501f,
+ 0.139526f, 0.195679f, 0.276123f, 0.381592f, 0.503418f, 0.622070f, 0.721680f, 0.796387f, 0.850098f, 0.887207f, 0.914551f, 0.933594f,
+ 0.947266f, 0.957520f, 0.966797f, 0.972656f, 0.977539f, 0.980957f, 0.993164f, 0.994141f, 0.994141f, 0.994141f, 0.994141f, 0.994141f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000243f, 0.000466f, 0.000474f, 0.000475f, 0.000600f, 0.000740f, 0.000796f, 0.001130f,
+ 0.001333f, 0.001339f, 0.001440f, 0.001575f, 0.001961f, 0.002031f, 0.002388f, 0.002563f, 0.003174f, 0.003345f, 0.003555f, 0.004143f,
+ 0.004681f, 0.005333f, 0.006191f, 0.007111f, 0.008278f, 0.009666f, 0.011177f, 0.013451f, 0.015511f, 0.018707f, 0.022629f, 0.027847f,
+ 0.034515f, 0.043976f, 0.056671f, 0.075012f, 0.101685f, 0.140869f, 0.199341f, 0.282959f, 0.393311f, 0.519043f, 0.639160f, 0.736328f,
+ 0.809082f, 0.860352f, 0.896484f, 0.920898f, 0.939453f, 0.951660f, 0.961914f, 0.969238f, 0.975098f, 0.979492f, 0.993164f, 0.993652f,
+ 0.994141f, 0.993652f, 0.993652f, 0.993652f, 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000120f, 0.000367f, 0.000448f, 0.000589f,
+ 0.000595f, 0.000719f, 0.000707f, 0.000809f, 0.000966f, 0.001217f, 0.001369f, 0.001405f, 0.001579f, 0.001786f, 0.002100f, 0.002260f,
+ 0.002600f, 0.002762f, 0.003023f, 0.003531f, 0.004219f, 0.004810f, 0.005409f, 0.006092f, 0.007053f, 0.008064f, 0.009163f, 0.010941f,
+ 0.012733f, 0.015251f, 0.018280f, 0.022202f, 0.027573f, 0.034271f, 0.043732f, 0.056458f, 0.075134f, 0.102661f, 0.143433f, 0.205078f,
+ 0.293701f, 0.409668f, 0.538574f, 0.658203f, 0.753418f, 0.823242f, 0.870605f, 0.905273f, 0.927734f, 0.943848f, 0.956055f, 0.964844f,
+ 0.972168f, 0.977539f, 0.992188f, 0.992676f, 0.993164f, 0.993652f, 0.993164f, 0.992676f, 0.000000f, 0.000000f, 0.000000f, 0.000111f,
+ 0.000224f, 0.000231f, 0.000314f, 0.000562f, 0.000589f, 0.000699f, 0.000717f, 0.000776f, 0.000926f, 0.000968f, 0.001242f, 0.001360f,
+ 0.001487f, 0.001564f, 0.001713f, 0.002073f, 0.002169f, 0.002380f, 0.002941f, 0.003229f, 0.003534f, 0.003914f, 0.004509f, 0.005127f,
+ 0.005939f, 0.006596f, 0.007812f, 0.009354f, 0.010559f, 0.012581f, 0.015007f, 0.018021f, 0.022079f, 0.027191f, 0.034119f, 0.043427f,
+ 0.057190f, 0.075623f, 0.104492f, 0.147949f, 0.213135f, 0.308105f, 0.430664f, 0.562500f, 0.681641f, 0.772949f, 0.839355f, 0.884277f,
+ 0.913574f, 0.934570f, 0.950195f, 0.961426f, 0.969238f, 0.975098f, 0.991211f, 0.992676f, 0.992676f, 0.992676f, 0.992676f, 0.992188f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000084f, 0.000117f, 0.000119f, 0.000367f, 0.000473f, 0.000555f, 0.000576f, 0.000674f, 0.000713f,
+ 0.000816f, 0.000913f, 0.001049f, 0.001168f, 0.001263f, 0.001473f, 0.001580f, 0.001781f, 0.002005f, 0.002123f, 0.002316f, 0.002674f,
+ 0.003094f, 0.003475f, 0.003967f, 0.004318f, 0.004833f, 0.005798f, 0.006699f, 0.007801f, 0.008888f, 0.010429f, 0.012268f, 0.014824f,
+ 0.017792f, 0.021790f, 0.026978f, 0.033844f, 0.043518f, 0.057068f, 0.077148f, 0.107605f, 0.154053f, 0.224609f, 0.326904f, 0.456543f,
+ 0.591797f, 0.708984f, 0.795410f, 0.855957f, 0.895508f, 0.923340f, 0.942383f, 0.955566f, 0.965332f, 0.973145f, 0.991211f, 0.991699f,
+ 0.992188f, 0.992188f, 0.992188f, 0.991699f, 0.000000f, 0.000000f, 0.000000f, 0.000092f, 0.000070f, 0.000236f, 0.000119f, 0.000376f,
+ 0.000433f, 0.000561f, 0.000688f, 0.000586f, 0.000742f, 0.000842f, 0.000881f, 0.000937f, 0.001141f, 0.001300f, 0.001434f, 0.001464f,
+ 0.001598f, 0.001829f, 0.002062f, 0.002338f, 0.002583f, 0.003036f, 0.003460f, 0.003704f, 0.004383f, 0.004986f, 0.005615f, 0.006439f,
+ 0.007267f, 0.008797f, 0.010330f, 0.012146f, 0.014473f, 0.017532f, 0.021622f, 0.026535f, 0.033539f, 0.043579f, 0.058044f, 0.079041f,
+ 0.111572f, 0.162109f, 0.239746f, 0.350830f, 0.488770f, 0.625000f, 0.737305f, 0.817871f, 0.871582f, 0.908203f, 0.932129f, 0.949219f,
+ 0.961914f, 0.970215f, 0.990234f, 0.991211f, 0.991211f, 0.991211f, 0.991211f, 0.991211f, 0.000000f, 0.000000f, 0.000000f, 0.000080f,
+ 0.000100f, 0.000115f, 0.000335f, 0.000350f, 0.000355f, 0.000473f, 0.000633f, 0.000678f, 0.000695f, 0.000694f, 0.000812f, 0.000733f,
+ 0.001109f, 0.001098f, 0.001260f, 0.001452f, 0.001377f, 0.001534f, 0.001972f, 0.001982f, 0.002232f, 0.002567f, 0.002764f, 0.003273f,
+ 0.003542f, 0.004181f, 0.004738f, 0.005466f, 0.006268f, 0.007126f, 0.008614f, 0.010170f, 0.012093f, 0.014359f, 0.017075f, 0.021042f,
+ 0.026459f, 0.033722f, 0.044159f, 0.059113f, 0.082092f, 0.117249f, 0.173218f, 0.259766f, 0.382080f, 0.526367f, 0.662598f, 0.768066f,
+ 0.840332f, 0.889648f, 0.920410f, 0.940918f, 0.956543f, 0.966309f, 0.989746f, 0.990234f, 0.990723f, 0.990723f, 0.990723f, 0.990723f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000191f, 0.000236f, 0.000335f, 0.000337f, 0.000466f, 0.000399f, 0.000608f,
+ 0.000626f, 0.000669f, 0.000696f, 0.000808f, 0.000859f, 0.000915f, 0.000903f, 0.001168f, 0.001245f, 0.001500f, 0.001525f, 0.001863f,
+ 0.001941f, 0.002121f, 0.002399f, 0.002861f, 0.002953f, 0.003632f, 0.004105f, 0.004745f, 0.005333f, 0.006317f, 0.007236f, 0.008255f,
+ 0.009857f, 0.011414f, 0.014015f, 0.016922f, 0.020828f, 0.026321f, 0.034149f, 0.044861f, 0.061279f, 0.085571f, 0.124878f, 0.187866f,
+ 0.285645f, 0.420654f, 0.570801f, 0.703125f, 0.799805f, 0.864258f, 0.905273f, 0.932129f, 0.950684f, 0.963379f, 0.988770f, 0.989258f,
+ 0.989746f, 0.989746f, 0.989746f, 0.989746f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000000f, 0.000122f, 0.000125f, 0.000232f,
+ 0.000360f, 0.000342f, 0.000463f, 0.000388f, 0.000569f, 0.000638f, 0.000671f, 0.000791f, 0.000774f, 0.000943f, 0.000774f, 0.001018f,
+ 0.001044f, 0.001245f, 0.001377f, 0.001410f, 0.001643f, 0.001970f, 0.002041f, 0.002316f, 0.002758f, 0.003023f, 0.003433f, 0.003859f,
+ 0.004444f, 0.005180f, 0.006134f, 0.006920f, 0.008102f, 0.009354f, 0.011475f, 0.013649f, 0.016739f, 0.021011f, 0.026566f, 0.034454f,
+ 0.046051f, 0.063843f, 0.090942f, 0.135498f, 0.207642f, 0.319580f, 0.467529f, 0.620605f, 0.745605f, 0.830566f, 0.886230f, 0.920898f,
+ 0.943848f, 0.958984f, 0.987793f, 0.988281f, 0.988770f, 0.988770f, 0.988281f, 0.988770f, 0.000000f, 0.000000f, 0.000000f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000188f, 0.000200f, 0.000332f, 0.000417f, 0.000338f, 0.000459f, 0.000349f, 0.000558f, 0.000642f, 0.000636f,
+ 0.000629f, 0.000807f, 0.000695f, 0.000747f, 0.000827f, 0.001058f, 0.001182f, 0.001269f, 0.001422f, 0.001472f, 0.001921f, 0.002100f,
+ 0.002337f, 0.002462f, 0.003073f, 0.003374f, 0.003708f, 0.004265f, 0.004826f, 0.005646f, 0.006596f, 0.007710f, 0.008926f, 0.011063f,
+ 0.013580f, 0.016495f, 0.020737f, 0.026459f, 0.035126f, 0.047791f, 0.066833f, 0.097778f, 0.149170f, 0.233887f, 0.363037f, 0.523438f,
+ 0.674805f, 0.788086f, 0.860352f, 0.906250f, 0.935547f, 0.954102f, 0.986328f, 0.987305f, 0.987305f, 0.987305f, 0.987305f, 0.987793f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000175f, 0.000155f, 0.000319f, 0.000241f, 0.000318f,
+ 0.000455f, 0.000462f, 0.000496f, 0.000593f, 0.000516f, 0.000564f, 0.000667f, 0.000668f, 0.000715f, 0.000749f, 0.000925f, 0.001111f,
+ 0.001246f, 0.001381f, 0.001443f, 0.001856f, 0.001997f, 0.002264f, 0.002363f, 0.002880f, 0.003212f, 0.003727f, 0.004208f, 0.004673f,
+ 0.005394f, 0.006367f, 0.007404f, 0.009003f, 0.010651f, 0.013138f, 0.016312f, 0.020767f, 0.027054f, 0.036377f, 0.050262f, 0.071655f,
+ 0.107361f, 0.167969f, 0.269287f, 0.418457f, 0.587402f, 0.730957f, 0.828125f, 0.888184f, 0.924805f, 0.948242f, 0.984863f, 0.986328f,
+ 0.986328f, 0.985840f, 0.986328f, 0.986328f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f,
+ 0.000202f, 0.000133f, 0.000215f, 0.000263f, 0.000304f, 0.000442f, 0.000332f, 0.000365f, 0.000403f, 0.000549f, 0.000607f, 0.000750f,
+ 0.000788f, 0.000802f, 0.000841f, 0.000958f, 0.001049f, 0.001188f, 0.001354f, 0.001318f, 0.001582f, 0.001928f, 0.002064f, 0.002321f,
+ 0.002594f, 0.003042f, 0.003222f, 0.003796f, 0.004440f, 0.005112f, 0.006081f, 0.007259f, 0.008736f, 0.010612f, 0.013077f, 0.016464f,
+ 0.020950f, 0.027664f, 0.037506f, 0.052795f, 0.077698f, 0.120361f, 0.194336f, 0.317627f, 0.486572f, 0.657227f, 0.785156f, 0.865234f,
+ 0.913086f, 0.942871f, 0.983887f, 0.984863f, 0.984375f, 0.984863f, 0.984375f, 0.984863f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000152f, 0.000257f, 0.000243f, 0.000288f, 0.000345f, 0.000228f,
+ 0.000358f, 0.000363f, 0.000432f, 0.000494f, 0.000530f, 0.000582f, 0.000762f, 0.000771f, 0.000913f, 0.000978f, 0.001100f, 0.001305f,
+ 0.001373f, 0.001706f, 0.001712f, 0.001922f, 0.002155f, 0.002569f, 0.002573f, 0.003094f, 0.003401f, 0.004272f, 0.004978f, 0.005829f,
+ 0.006924f, 0.008453f, 0.010452f, 0.012871f, 0.016617f, 0.021072f, 0.028427f, 0.039429f, 0.056732f, 0.086243f, 0.138916f, 0.231812f,
+ 0.381592f, 0.566406f, 0.726562f, 0.833496f, 0.896973f, 0.933594f, 0.981934f, 0.982910f, 0.982910f, 0.982910f, 0.982910f, 0.982910f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000121f, 0.000127f, 0.000215f,
+ 0.000159f, 0.000233f, 0.000284f, 0.000326f, 0.000339f, 0.000339f, 0.000352f, 0.000394f, 0.000623f, 0.000622f, 0.000731f, 0.000730f,
+ 0.000741f, 0.000829f, 0.000914f, 0.001017f, 0.001151f, 0.001469f, 0.001263f, 0.001480f, 0.001740f, 0.002069f, 0.002104f, 0.002443f,
+ 0.002831f, 0.003519f, 0.003929f, 0.004627f, 0.005455f, 0.006634f, 0.008316f, 0.009949f, 0.012596f, 0.016495f, 0.021729f, 0.029877f,
+ 0.042084f, 0.062805f, 0.098694f, 0.165283f, 0.284668f, 0.465088f, 0.654297f, 0.793945f, 0.877930f, 0.924805f, 0.979980f, 0.980957f,
+ 0.980957f, 0.981445f, 0.981445f, 0.980957f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000150f, 0.000163f, 0.000069f, 0.000057f, 0.000121f, 0.000231f, 0.000291f, 0.000304f, 0.000334f, 0.000339f,
+ 0.000346f, 0.000569f, 0.000648f, 0.000674f, 0.000649f, 0.000697f, 0.000772f, 0.000834f, 0.000972f, 0.001005f, 0.001189f, 0.001359f,
+ 0.001237f, 0.001567f, 0.001794f, 0.001963f, 0.002378f, 0.002712f, 0.002867f, 0.003853f, 0.004330f, 0.005196f, 0.006516f, 0.008026f,
+ 0.009888f, 0.012703f, 0.016479f, 0.022110f, 0.031158f, 0.045746f, 0.070557f, 0.117004f, 0.204956f, 0.360596f, 0.564453f, 0.740723f,
+ 0.852051f, 0.912598f, 0.977539f, 0.979492f, 0.979492f, 0.979004f, 0.979492f, 0.979004f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000098f, 0.000082f, 0.000067f, 0.000056f, 0.000124f,
+ 0.000193f, 0.000240f, 0.000258f, 0.000310f, 0.000326f, 0.000335f, 0.000341f, 0.000471f, 0.000613f, 0.000494f, 0.000716f, 0.000742f,
+ 0.000804f, 0.000873f, 0.000832f, 0.001070f, 0.001120f, 0.001146f, 0.001225f, 0.001696f, 0.001814f, 0.002041f, 0.002419f, 0.002941f,
+ 0.003433f, 0.004154f, 0.004818f, 0.006077f, 0.007652f, 0.009521f, 0.012444f, 0.017029f, 0.023193f, 0.033539f, 0.050690f, 0.082092f,
+ 0.144043f, 0.265869f, 0.463379f, 0.672363f, 0.818848f, 0.898438f, 0.975586f, 0.976562f, 0.976562f, 0.976562f, 0.976074f, 0.976562f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000114f,
+ 0.000096f, 0.000079f, 0.000125f, 0.000056f, 0.000142f, 0.000120f, 0.000195f, 0.000246f, 0.000321f, 0.000305f, 0.000319f, 0.000395f,
+ 0.000442f, 0.000540f, 0.000642f, 0.000638f, 0.000696f, 0.000674f, 0.000687f, 0.000857f, 0.000955f, 0.001128f, 0.001224f, 0.001364f,
+ 0.001347f, 0.001555f, 0.001910f, 0.002245f, 0.002714f, 0.003229f, 0.003824f, 0.004673f, 0.005676f, 0.007225f, 0.009293f, 0.012802f,
+ 0.017273f, 0.024368f, 0.036682f, 0.058075f, 0.100952f, 0.188721f, 0.358154f, 0.587891f, 0.775879f, 0.881348f, 0.972168f, 0.972656f,
+ 0.972656f, 0.973145f, 0.973145f, 0.973633f, 0.000000f, 0.000000f, 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000120f, 0.000112f, 0.000093f, 0.000079f, 0.000067f, 0.000057f, 0.000049f, 0.000133f, 0.000137f,
+ 0.000163f, 0.000244f, 0.000328f, 0.000366f, 0.000356f, 0.000415f, 0.000436f, 0.000543f, 0.000555f, 0.000638f, 0.000597f, 0.000702f,
+ 0.000786f, 0.000648f, 0.000891f, 0.000804f, 0.001218f, 0.001070f, 0.001355f, 0.001731f, 0.002171f, 0.002352f, 0.002796f, 0.003546f,
+ 0.004189f, 0.005558f, 0.006939f, 0.009209f, 0.012337f, 0.017776f, 0.026016f, 0.040833f, 0.069946f, 0.130981f, 0.262207f, 0.489258f,
+ 0.719238f, 0.859375f, 0.968262f, 0.969238f, 0.969727f, 0.969727f, 0.969727f, 0.969727f, 0.000000f, 0.000122f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000110f, 0.000093f, 0.000080f,
+ 0.000068f, 0.000094f, 0.000119f, 0.000117f, 0.000120f, 0.000123f, 0.000173f, 0.000263f, 0.000263f, 0.000359f, 0.000386f, 0.000390f,
+ 0.000401f, 0.000556f, 0.000549f, 0.000573f, 0.000502f, 0.000707f, 0.000789f, 0.000629f, 0.000847f, 0.001003f, 0.001024f, 0.001242f,
+ 0.001423f, 0.001877f, 0.002012f, 0.002571f, 0.003071f, 0.003925f, 0.005131f, 0.006767f, 0.009140f, 0.012672f, 0.018509f, 0.028992f,
+ 0.048309f, 0.089233f, 0.183838f, 0.383545f, 0.646973f, 0.830078f, 0.963867f, 0.964844f, 0.964844f, 0.965820f, 0.965820f, 0.965820f,
+ 0.000000f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000120f,
+ 0.000119f, 0.000119f, 0.000113f, 0.000095f, 0.000083f, 0.000070f, 0.000061f, 0.000054f, 0.000048f, 0.000042f, 0.000115f, 0.000112f,
+ 0.000151f, 0.000213f, 0.000309f, 0.000298f, 0.000359f, 0.000337f, 0.000382f, 0.000440f, 0.000576f, 0.000477f, 0.000453f, 0.000690f,
+ 0.000687f, 0.000795f, 0.000776f, 0.000911f, 0.001117f, 0.001119f, 0.001352f, 0.002001f, 0.002140f, 0.002832f, 0.003609f, 0.004715f,
+ 0.006302f, 0.008835f, 0.013115f, 0.020004f, 0.032867f, 0.060333f, 0.124512f, 0.281982f, 0.557617f, 0.794434f, 0.959473f, 0.959961f,
+ 0.960449f, 0.960449f, 0.960449f, 0.959961f, 0.000122f, 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000119f, 0.000119f,
+ 0.000119f, 0.000119f, 0.000119f, 0.000119f, 0.000118f, 0.000118f, 0.000118f, 0.000116f, 0.000098f, 0.000087f, 0.000076f, 0.000065f,
+ 0.000057f, 0.000050f, 0.000045f, 0.000091f, 0.000074f, 0.000106f, 0.000185f, 0.000193f, 0.000228f, 0.000328f, 0.000323f, 0.000399f,
+ 0.000429f, 0.000498f, 0.000552f, 0.000432f, 0.000542f, 0.000592f, 0.000599f, 0.000729f, 0.000734f, 0.000885f, 0.001304f, 0.001273f,
+ 0.001756f, 0.001931f, 0.002445f, 0.003120f, 0.004456f, 0.006165f, 0.008751f, 0.013466f, 0.022141f, 0.040192f, 0.082397f, 0.195679f,
+ 0.455322f, 0.745117f, 0.952637f, 0.953613f, 0.953613f, 0.954102f, 0.952637f, 0.953613f, 0.000000f, 0.000120f, 0.000120f, 0.000119f,
+ 0.000119f, 0.000119f, 0.000118f, 0.000118f, 0.000118f, 0.000118f, 0.000118f, 0.000117f, 0.000117f, 0.000117f, 0.000117f, 0.000117f,
+ 0.000117f, 0.000104f, 0.000092f, 0.000079f, 0.000071f, 0.000062f, 0.000055f, 0.000049f, 0.000044f, 0.000039f, 0.000099f, 0.000106f,
+ 0.000158f, 0.000169f, 0.000241f, 0.000274f, 0.000293f, 0.000389f, 0.000360f, 0.000399f, 0.000387f, 0.000446f, 0.000401f, 0.000530f,
+ 0.000565f, 0.000691f, 0.000722f, 0.000848f, 0.001147f, 0.001418f, 0.001677f, 0.002087f, 0.002972f, 0.004169f, 0.005623f, 0.008835f,
+ 0.014404f, 0.026077f, 0.053467f, 0.129395f, 0.346924f, 0.685059f, 0.943848f, 0.945801f, 0.945801f, 0.945312f, 0.945801f, 0.945801f,
+ 0.000000f, 0.000000f, 0.000117f, 0.000116f, 0.000117f, 0.000117f, 0.000116f, 0.000116f, 0.000115f, 0.000116f, 0.000115f, 0.000116f,
+ 0.000115f, 0.000115f, 0.000115f, 0.000115f, 0.000115f, 0.000115f, 0.000110f, 0.000097f, 0.000086f, 0.000077f, 0.000067f, 0.000060f,
+ 0.000053f, 0.000048f, 0.000043f, 0.000061f, 0.000090f, 0.000083f, 0.000139f, 0.000139f, 0.000216f, 0.000254f, 0.000307f, 0.000358f,
+ 0.000269f, 0.000377f, 0.000324f, 0.000369f, 0.000405f, 0.000455f, 0.000524f, 0.000706f, 0.000701f, 0.001012f, 0.001206f, 0.001316f,
+ 0.001663f, 0.002350f, 0.003571f, 0.005505f, 0.008873f, 0.016006f, 0.033234f, 0.081848f, 0.244751f, 0.605469f, 0.934082f, 0.935059f,
+ 0.936035f, 0.935547f, 0.935547f, 0.935547f, 0.000105f, 0.000114f, 0.000113f, 0.000113f, 0.000111f, 0.000111f, 0.000112f, 0.000111f,
+ 0.000112f, 0.000112f, 0.000112f, 0.000112f, 0.000111f, 0.000112f, 0.000112f, 0.000112f, 0.000112f, 0.000112f, 0.000112f, 0.000112f,
+ 0.000105f, 0.000093f, 0.000083f, 0.000074f, 0.000066f, 0.000059f, 0.000053f, 0.000048f, 0.000043f, 0.000062f, 0.000052f, 0.000063f,
+ 0.000092f, 0.000146f, 0.000176f, 0.000216f, 0.000227f, 0.000263f, 0.000244f, 0.000267f, 0.000370f, 0.000326f, 0.000360f, 0.000391f,
+ 0.000505f, 0.000618f, 0.000726f, 0.000969f, 0.001117f, 0.001651f, 0.002131f, 0.003090f, 0.005188f, 0.009499f, 0.019836f, 0.049042f,
+ 0.159180f, 0.509766f, 0.921875f, 0.922852f, 0.922852f, 0.922363f, 0.923340f, 0.922852f, 0.000000f, 0.000000f, 0.000065f, 0.000098f,
+ 0.000096f, 0.000101f, 0.000100f, 0.000104f, 0.000104f, 0.000103f, 0.000106f, 0.000106f, 0.000106f, 0.000105f, 0.000107f, 0.000107f,
+ 0.000106f, 0.000107f, 0.000107f, 0.000108f, 0.000107f, 0.000108f, 0.000104f, 0.000092f, 0.000082f, 0.000075f, 0.000067f, 0.000059f,
+ 0.000054f, 0.000048f, 0.000044f, 0.000039f, 0.000037f, 0.000058f, 0.000066f, 0.000122f, 0.000137f, 0.000175f, 0.000208f, 0.000194f,
+ 0.000208f, 0.000240f, 0.000270f, 0.000281f, 0.000323f, 0.000364f, 0.000479f, 0.000591f, 0.000712f, 0.000986f, 0.001224f, 0.001896f,
+ 0.002996f, 0.005196f, 0.010506f, 0.027527f, 0.095581f, 0.399658f, 0.905762f, 0.906738f, 0.906250f, 0.905762f, 0.905762f, 0.907227f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000017f, 0.000030f, 0.000054f, 0.000061f, 0.000081f, 0.000087f, 0.000088f, 0.000089f, 0.000093f,
+ 0.000093f, 0.000096f, 0.000096f, 0.000097f, 0.000098f, 0.000099f, 0.000098f, 0.000100f, 0.000100f, 0.000101f, 0.000100f, 0.000101f,
+ 0.000101f, 0.000092f, 0.000082f, 0.000074f, 0.000067f, 0.000060f, 0.000054f, 0.000049f, 0.000045f, 0.000040f, 0.000036f, 0.000037f,
+ 0.000059f, 0.000077f, 0.000093f, 0.000143f, 0.000155f, 0.000188f, 0.000178f, 0.000184f, 0.000231f, 0.000234f, 0.000272f, 0.000352f,
+ 0.000420f, 0.000525f, 0.000764f, 0.001091f, 0.001653f, 0.002705f, 0.005474f, 0.013939f, 0.051880f, 0.283691f, 0.883789f, 0.884766f,
+ 0.885254f, 0.885254f, 0.885742f, 0.885254f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000013f,
+ 0.000032f, 0.000046f, 0.000050f, 0.000060f, 0.000065f, 0.000065f, 0.000075f, 0.000078f, 0.000080f, 0.000079f, 0.000084f, 0.000083f,
+ 0.000087f, 0.000087f, 0.000089f, 0.000090f, 0.000091f, 0.000091f, 0.000092f, 0.000092f, 0.000083f, 0.000075f, 0.000068f, 0.000062f,
+ 0.000056f, 0.000050f, 0.000046f, 0.000042f, 0.000037f, 0.000039f, 0.000044f, 0.000072f, 0.000068f, 0.000089f, 0.000125f, 0.000124f,
+ 0.000126f, 0.000153f, 0.000183f, 0.000212f, 0.000219f, 0.000311f, 0.000363f, 0.000566f, 0.000846f, 0.001332f, 0.002522f, 0.006252f,
+ 0.023834f, 0.175415f, 0.855957f, 0.856934f, 0.856934f, 0.856934f, 0.857422f, 0.856934f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000024f, 0.000028f,
+ 0.000040f, 0.000044f, 0.000051f, 0.000053f, 0.000060f, 0.000063f, 0.000064f, 0.000067f, 0.000071f, 0.000072f, 0.000074f, 0.000076f,
+ 0.000077f, 0.000079f, 0.000079f, 0.000075f, 0.000068f, 0.000062f, 0.000056f, 0.000051f, 0.000046f, 0.000042f, 0.000038f, 0.000034f,
+ 0.000031f, 0.000030f, 0.000045f, 0.000079f, 0.000081f, 0.000107f, 0.000114f, 0.000106f, 0.000144f, 0.000136f, 0.000171f, 0.000254f,
+ 0.000377f, 0.000531f, 0.001037f, 0.002504f, 0.009140f, 0.088379f, 0.818848f, 0.820801f, 0.819824f, 0.820312f, 0.819336f, 0.820801f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000007f, 0.000014f, 0.000021f, 0.000028f,
+ 0.000034f, 0.000036f, 0.000042f, 0.000046f, 0.000049f, 0.000052f, 0.000054f, 0.000056f, 0.000059f, 0.000061f, 0.000064f, 0.000061f,
+ 0.000055f, 0.000050f, 0.000045f, 0.000041f, 0.000037f, 0.000033f, 0.000030f, 0.000027f, 0.000024f, 0.000033f, 0.000060f, 0.000059f,
+ 0.000075f, 0.000073f, 0.000101f, 0.000089f, 0.000144f, 0.000226f, 0.000384f, 0.000847f, 0.003033f, 0.031860f, 0.770020f, 0.770996f,
+ 0.772461f, 0.771973f, 0.772461f, 0.771973f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000010f, 0.000016f,
+ 0.000021f, 0.000023f, 0.000029f, 0.000032f, 0.000036f, 0.000039f, 0.000042f, 0.000044f, 0.000042f, 0.000038f, 0.000035f, 0.000031f,
+ 0.000028f, 0.000025f, 0.000022f, 0.000020f, 0.000017f, 0.000024f, 0.000040f, 0.000047f, 0.000053f, 0.000063f, 0.000087f, 0.000190f,
+ 0.000666f, 0.007278f, 0.708496f, 0.709961f, 0.710449f, 0.710938f, 0.710938f, 0.710449f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f,
+ 0.000005f, 0.000010f, 0.000014f, 0.000018f, 0.000021f, 0.000024f, 0.000024f, 0.000021f, 0.000018f, 0.000016f, 0.000014f, 0.000012f,
+ 0.000008f, 0.000020f, 0.000022f, 0.000025f, 0.000073f, 0.000744f, 0.632324f, 0.632812f, 0.633789f, 0.633789f, 0.633301f, 0.632812f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000007f, 0.000006f, 0.000004f, 0.000005f, 0.000007f, 0.543945f, 0.545410f,
+ 0.545410f, 0.545410f, 0.546387f, 0.545898f,
+ },
+ {
+ 0.159546f, 0.492676f, 0.684570f, 0.783203f, 0.838379f, 0.873535f, 0.897949f, 0.913574f, 0.926270f, 0.936035f, 0.943359f, 0.950195f,
+ 0.955566f, 0.959473f, 0.963379f, 0.966797f, 0.969238f, 0.972168f, 0.973633f, 0.976562f, 0.978027f, 0.979492f, 0.980957f, 0.982422f,
+ 0.983887f, 0.984863f, 0.985840f, 0.986816f, 0.987793f, 0.988770f, 0.989258f, 0.989746f, 0.990234f, 0.990723f, 0.991699f, 0.992676f,
+ 0.993164f, 0.993652f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995117f, 0.995605f, 0.996582f, 0.996582f, 0.997070f, 0.997070f,
+ 0.997070f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.034119f, 0.154175f, 0.341309f, 0.532227f, 0.672363f, 0.763184f, 0.820801f, 0.858398f,
+ 0.885742f, 0.904297f, 0.918945f, 0.929199f, 0.938965f, 0.945801f, 0.951660f, 0.956543f, 0.961426f, 0.964355f, 0.968262f, 0.970703f,
+ 0.973145f, 0.975586f, 0.977539f, 0.979004f, 0.980469f, 0.981934f, 0.983398f, 0.984375f, 0.985352f, 0.986328f, 0.987305f, 0.988281f,
+ 0.988770f, 0.989746f, 0.990234f, 0.991211f, 0.991699f, 0.992676f, 0.993164f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f,
+ 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.999023f,
+ 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.013390f, 0.056915f, 0.134155f, 0.257080f,
+ 0.412109f, 0.560547f, 0.675781f, 0.755859f, 0.812012f, 0.851074f, 0.877930f, 0.898926f, 0.913574f, 0.925781f, 0.935059f, 0.942871f,
+ 0.949707f, 0.954590f, 0.959473f, 0.963379f, 0.966797f, 0.969238f, 0.971680f, 0.975098f, 0.976562f, 0.978516f, 0.979980f, 0.980957f,
+ 0.982422f, 0.984375f, 0.985352f, 0.985840f, 0.987305f, 0.987793f, 0.988770f, 0.989746f, 0.990723f, 0.991211f, 0.991699f, 0.992188f,
+ 0.992676f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995605f, 0.995605f, 0.995605f, 0.996582f, 0.996582f, 0.997070f, 0.997070f,
+ 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f,
+ 0.006939f, 0.027863f, 0.061951f, 0.117859f, 0.204834f, 0.324707f, 0.460205f, 0.585449f, 0.684570f, 0.757324f, 0.810059f, 0.847168f,
+ 0.874023f, 0.895996f, 0.910645f, 0.922852f, 0.933105f, 0.940918f, 0.947754f, 0.953613f, 0.958496f, 0.961914f, 0.965820f, 0.968750f,
+ 0.971680f, 0.974121f, 0.976074f, 0.978027f, 0.979492f, 0.981445f, 0.982910f, 0.983887f, 0.984863f, 0.986328f, 0.987305f, 0.988281f,
+ 0.988770f, 0.989746f, 0.990234f, 0.990723f, 0.991699f, 0.992188f, 0.993164f, 0.993652f, 0.993652f, 0.994141f, 0.995117f, 0.995605f,
+ 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.998535f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.004211f, 0.016022f, 0.034119f, 0.061432f, 0.104797f, 0.170288f, 0.262695f, 0.377686f,
+ 0.499756f, 0.608887f, 0.696777f, 0.762207f, 0.810547f, 0.847168f, 0.873535f, 0.893066f, 0.910156f, 0.922852f, 0.932617f, 0.939941f,
+ 0.946777f, 0.953125f, 0.958496f, 0.961914f, 0.965332f, 0.968750f, 0.971680f, 0.973633f, 0.975586f, 0.977539f, 0.979492f, 0.981445f,
+ 0.982910f, 0.984375f, 0.985840f, 0.986328f, 0.987793f, 0.987793f, 0.989258f, 0.989746f, 0.990723f, 0.991211f, 0.992188f, 0.992676f,
+ 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f,
+ 0.998047f, 0.998535f, 0.999512f, 0.999512f, 0.999023f, 0.999512f, 0.999023f, 0.999023f, 0.002724f, 0.010384f, 0.020813f, 0.036285f,
+ 0.059784f, 0.093933f, 0.145508f, 0.218018f, 0.313232f, 0.424072f, 0.534180f, 0.632812f, 0.709961f, 0.769531f, 0.815918f, 0.848145f,
+ 0.874512f, 0.894043f, 0.909668f, 0.922363f, 0.932129f, 0.939941f, 0.946777f, 0.953125f, 0.958008f, 0.961914f, 0.965332f, 0.968750f,
+ 0.971680f, 0.973633f, 0.976562f, 0.978516f, 0.979980f, 0.981445f, 0.982910f, 0.984863f, 0.985352f, 0.986816f, 0.987793f, 0.988281f,
+ 0.988770f, 0.989746f, 0.990723f, 0.991211f, 0.992188f, 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996582f, 0.996582f, 0.997559f, 0.997559f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f,
+ 0.002113f, 0.007004f, 0.014091f, 0.023895f, 0.037811f, 0.057373f, 0.085632f, 0.127075f, 0.185425f, 0.263672f, 0.360596f, 0.465576f,
+ 0.566895f, 0.655762f, 0.725586f, 0.779297f, 0.822266f, 0.853516f, 0.877441f, 0.895996f, 0.911621f, 0.923828f, 0.933105f, 0.940918f,
+ 0.947754f, 0.953613f, 0.957520f, 0.962402f, 0.965820f, 0.968750f, 0.972168f, 0.974121f, 0.976074f, 0.978027f, 0.980469f, 0.981934f,
+ 0.983398f, 0.984863f, 0.985352f, 0.986328f, 0.988281f, 0.988281f, 0.989258f, 0.990234f, 0.991211f, 0.992188f, 0.992676f, 0.993164f,
+ 0.993652f, 0.994629f, 0.994629f, 0.995605f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.001575f, 0.005211f, 0.010040f, 0.016220f, 0.025665f, 0.037415f, 0.054138f, 0.078491f,
+ 0.112915f, 0.160156f, 0.225464f, 0.308594f, 0.405029f, 0.506348f, 0.599121f, 0.678711f, 0.743164f, 0.791016f, 0.829590f, 0.859375f,
+ 0.881836f, 0.899414f, 0.913086f, 0.924805f, 0.934570f, 0.942383f, 0.948730f, 0.955078f, 0.958984f, 0.963379f, 0.966797f, 0.970215f,
+ 0.972168f, 0.974609f, 0.977051f, 0.979004f, 0.980957f, 0.981934f, 0.983398f, 0.984863f, 0.986328f, 0.987305f, 0.988281f, 0.989258f,
+ 0.990234f, 0.991211f, 0.991699f, 0.992188f, 0.993164f, 0.993652f, 0.994629f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996094f,
+ 0.996582f, 0.997559f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.000985f, 0.004086f, 0.007362f, 0.011887f,
+ 0.018127f, 0.026199f, 0.036804f, 0.052002f, 0.072754f, 0.101318f, 0.140747f, 0.195190f, 0.266113f, 0.352539f, 0.448730f, 0.543945f,
+ 0.630371f, 0.702637f, 0.759277f, 0.803711f, 0.839355f, 0.865234f, 0.886719f, 0.903320f, 0.916504f, 0.927734f, 0.936523f, 0.944336f,
+ 0.950195f, 0.955566f, 0.959961f, 0.964355f, 0.967773f, 0.970215f, 0.973145f, 0.975586f, 0.978027f, 0.979004f, 0.980957f, 0.982910f,
+ 0.984375f, 0.985352f, 0.987305f, 0.987305f, 0.988770f, 0.990234f, 0.990234f, 0.991699f, 0.991699f, 0.993164f, 0.993164f, 0.993652f,
+ 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.998535f, 0.999023f,
+ 0.000829f, 0.002878f, 0.005596f, 0.009109f, 0.013359f, 0.019089f, 0.026901f, 0.036774f, 0.049347f, 0.067200f, 0.091736f, 0.125854f,
+ 0.171631f, 0.232544f, 0.308594f, 0.397461f, 0.491455f, 0.581055f, 0.659668f, 0.724609f, 0.775879f, 0.817383f, 0.848633f, 0.873047f,
+ 0.892090f, 0.907715f, 0.920410f, 0.930664f, 0.939453f, 0.946289f, 0.951660f, 0.957520f, 0.960938f, 0.965820f, 0.968750f, 0.972168f,
+ 0.974609f, 0.976562f, 0.978516f, 0.980469f, 0.981934f, 0.983887f, 0.984863f, 0.986328f, 0.986816f, 0.988770f, 0.989746f, 0.990234f,
+ 0.991211f, 0.991699f, 0.992676f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996582f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000836f, 0.002403f, 0.004837f, 0.006950f, 0.010269f, 0.014679f, 0.019699f, 0.026291f,
+ 0.035431f, 0.046875f, 0.062744f, 0.084045f, 0.113403f, 0.152588f, 0.204712f, 0.271729f, 0.353271f, 0.443115f, 0.532715f, 0.617188f,
+ 0.688477f, 0.748047f, 0.793945f, 0.829102f, 0.857422f, 0.880371f, 0.898438f, 0.912598f, 0.924316f, 0.934082f, 0.941406f, 0.948242f,
+ 0.954590f, 0.959473f, 0.963379f, 0.967285f, 0.970215f, 0.973145f, 0.975586f, 0.977539f, 0.979980f, 0.981445f, 0.982910f, 0.984375f,
+ 0.985840f, 0.987305f, 0.988281f, 0.988770f, 0.990234f, 0.990723f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994141f, 0.995117f,
+ 0.995605f, 0.996094f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.000698f, 0.002052f, 0.003618f, 0.005703f,
+ 0.008430f, 0.011230f, 0.015083f, 0.019821f, 0.026474f, 0.034393f, 0.044922f, 0.059204f, 0.077698f, 0.102661f, 0.136963f, 0.182373f,
+ 0.241089f, 0.314941f, 0.398926f, 0.489014f, 0.575195f, 0.652344f, 0.717285f, 0.769043f, 0.810059f, 0.842773f, 0.869141f, 0.888672f,
+ 0.904785f, 0.917969f, 0.928711f, 0.936523f, 0.945312f, 0.951660f, 0.957031f, 0.961426f, 0.964844f, 0.968750f, 0.971680f, 0.974121f,
+ 0.976562f, 0.979004f, 0.980469f, 0.982422f, 0.983887f, 0.985352f, 0.986816f, 0.987793f, 0.988770f, 0.990234f, 0.990723f, 0.991699f,
+ 0.992676f, 0.993164f, 0.994141f, 0.994141f, 0.994629f, 0.995605f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f,
+ 0.000244f, 0.001565f, 0.002975f, 0.004433f, 0.006596f, 0.008957f, 0.012215f, 0.015533f, 0.020294f, 0.026062f, 0.033722f, 0.042816f,
+ 0.055237f, 0.071960f, 0.094543f, 0.124023f, 0.164185f, 0.216309f, 0.281738f, 0.360352f, 0.446533f, 0.534180f, 0.615234f, 0.686523f,
+ 0.743652f, 0.790527f, 0.825684f, 0.855957f, 0.878418f, 0.895996f, 0.911133f, 0.923340f, 0.933105f, 0.941406f, 0.948242f, 0.953613f,
+ 0.959473f, 0.963379f, 0.966797f, 0.970703f, 0.973145f, 0.976074f, 0.978516f, 0.980469f, 0.982422f, 0.983398f, 0.984863f, 0.986328f,
+ 0.987305f, 0.989258f, 0.989746f, 0.990723f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994141f, 0.995117f, 0.998047f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998047f, 0.000365f, 0.001394f, 0.002546f, 0.004055f, 0.005394f, 0.007465f, 0.009674f, 0.012070f,
+ 0.015556f, 0.019913f, 0.025696f, 0.032623f, 0.041046f, 0.052643f, 0.067383f, 0.087463f, 0.113708f, 0.148315f, 0.194946f, 0.254395f,
+ 0.326416f, 0.408691f, 0.495117f, 0.579102f, 0.654297f, 0.716797f, 0.768066f, 0.809570f, 0.843262f, 0.868652f, 0.888184f, 0.904785f,
+ 0.918457f, 0.929199f, 0.937500f, 0.945801f, 0.951660f, 0.957520f, 0.961914f, 0.965820f, 0.969238f, 0.972656f, 0.975098f, 0.978027f,
+ 0.979492f, 0.981934f, 0.983398f, 0.984863f, 0.986328f, 0.987793f, 0.989258f, 0.989746f, 0.991211f, 0.991211f, 0.992188f, 0.993164f,
+ 0.993652f, 0.994629f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.000596f, 0.001077f, 0.001882f, 0.003033f,
+ 0.004559f, 0.006241f, 0.007805f, 0.010002f, 0.012840f, 0.015900f, 0.019974f, 0.025131f, 0.031250f, 0.039337f, 0.049988f, 0.063843f,
+ 0.080933f, 0.105164f, 0.135986f, 0.176880f, 0.230103f, 0.296631f, 0.374268f, 0.459961f, 0.544434f, 0.623535f, 0.691895f, 0.748535f,
+ 0.792969f, 0.829102f, 0.857422f, 0.880371f, 0.897949f, 0.913086f, 0.924805f, 0.934570f, 0.942383f, 0.949219f, 0.955566f, 0.960938f,
+ 0.964844f, 0.968750f, 0.971191f, 0.974121f, 0.977051f, 0.979004f, 0.980957f, 0.982910f, 0.984863f, 0.985840f, 0.987305f, 0.989258f,
+ 0.989746f, 0.991211f, 0.991211f, 0.992676f, 0.993164f, 0.993652f, 0.997559f, 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.998047f,
+ 0.000243f, 0.001173f, 0.001889f, 0.002661f, 0.003933f, 0.005131f, 0.006496f, 0.008324f, 0.010574f, 0.013115f, 0.015839f, 0.019913f,
+ 0.024445f, 0.030609f, 0.037781f, 0.047333f, 0.059906f, 0.075928f, 0.097229f, 0.124939f, 0.161743f, 0.209595f, 0.271240f, 0.343994f,
+ 0.426758f, 0.511719f, 0.592773f, 0.666504f, 0.727051f, 0.776855f, 0.815918f, 0.847656f, 0.871582f, 0.892090f, 0.907715f, 0.920898f,
+ 0.931152f, 0.940918f, 0.947754f, 0.953613f, 0.958496f, 0.963867f, 0.967773f, 0.970703f, 0.974121f, 0.976074f, 0.979004f, 0.980469f,
+ 0.982910f, 0.984375f, 0.985840f, 0.987305f, 0.988770f, 0.990234f, 0.990234f, 0.992188f, 0.992188f, 0.993164f, 0.997070f, 0.997559f,
+ 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.000351f, 0.000842f, 0.001560f, 0.002363f, 0.003258f, 0.004131f, 0.005272f, 0.007179f,
+ 0.008682f, 0.010643f, 0.013016f, 0.016037f, 0.019516f, 0.024078f, 0.029602f, 0.036591f, 0.045044f, 0.056641f, 0.071350f, 0.090576f,
+ 0.116211f, 0.149414f, 0.193237f, 0.248779f, 0.317871f, 0.396973f, 0.481201f, 0.564453f, 0.640137f, 0.705566f, 0.759766f, 0.802734f,
+ 0.836914f, 0.863281f, 0.885742f, 0.902832f, 0.916992f, 0.927734f, 0.937012f, 0.945801f, 0.952637f, 0.958008f, 0.961914f, 0.966309f,
+ 0.970703f, 0.974121f, 0.976074f, 0.978516f, 0.980957f, 0.982910f, 0.984863f, 0.985840f, 0.987305f, 0.988281f, 0.989746f, 0.990723f,
+ 0.991211f, 0.992676f, 0.997070f, 0.997559f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.000000f, 0.000886f, 0.001405f, 0.001915f,
+ 0.002651f, 0.003870f, 0.004845f, 0.006035f, 0.006912f, 0.008812f, 0.010887f, 0.013229f, 0.016022f, 0.019196f, 0.023590f, 0.028992f,
+ 0.035248f, 0.043304f, 0.053711f, 0.066956f, 0.085083f, 0.107727f, 0.138428f, 0.178589f, 0.229980f, 0.293945f, 0.370117f, 0.453369f,
+ 0.537109f, 0.616699f, 0.685059f, 0.743164f, 0.790039f, 0.826660f, 0.856445f, 0.878906f, 0.897949f, 0.913574f, 0.925293f, 0.935547f,
+ 0.943848f, 0.951172f, 0.957031f, 0.961914f, 0.966797f, 0.970215f, 0.973145f, 0.976562f, 0.979004f, 0.980469f, 0.982910f, 0.984375f,
+ 0.985840f, 0.987305f, 0.988770f, 0.989746f, 0.991211f, 0.992188f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997070f,
+ 0.000104f, 0.000719f, 0.001065f, 0.001970f, 0.002544f, 0.003149f, 0.004230f, 0.005138f, 0.006119f, 0.007580f, 0.009201f, 0.010902f,
+ 0.013260f, 0.015526f, 0.019272f, 0.022858f, 0.027512f, 0.033569f, 0.041199f, 0.050873f, 0.063782f, 0.079895f, 0.101135f, 0.128906f,
+ 0.165771f, 0.213745f, 0.273193f, 0.345703f, 0.427002f, 0.511719f, 0.592773f, 0.666016f, 0.727051f, 0.776367f, 0.817871f, 0.848633f,
+ 0.875000f, 0.894531f, 0.909668f, 0.922852f, 0.934082f, 0.942383f, 0.949707f, 0.956055f, 0.961914f, 0.966309f, 0.970215f, 0.973145f,
+ 0.976562f, 0.978516f, 0.980957f, 0.982910f, 0.984375f, 0.986328f, 0.987305f, 0.988281f, 0.989746f, 0.991211f, 0.996582f, 0.997070f,
+ 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.000240f, 0.000686f, 0.001052f, 0.001375f, 0.002308f, 0.002735f, 0.003510f, 0.004269f,
+ 0.005173f, 0.006649f, 0.007442f, 0.009109f, 0.011246f, 0.012886f, 0.015732f, 0.018829f, 0.022354f, 0.026672f, 0.032867f, 0.039764f,
+ 0.048492f, 0.060455f, 0.075806f, 0.095276f, 0.121033f, 0.155273f, 0.199097f, 0.255859f, 0.324463f, 0.404053f, 0.488525f, 0.571289f,
+ 0.646484f, 0.711426f, 0.765625f, 0.808105f, 0.841797f, 0.869141f, 0.890137f, 0.907227f, 0.920898f, 0.931641f, 0.940918f, 0.948730f,
+ 0.955078f, 0.960449f, 0.965820f, 0.969727f, 0.972656f, 0.976562f, 0.978516f, 0.980957f, 0.982910f, 0.984863f, 0.986328f, 0.987793f,
+ 0.989746f, 0.990723f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.000244f, 0.000597f, 0.000939f, 0.001369f,
+ 0.001999f, 0.002329f, 0.003105f, 0.003786f, 0.004395f, 0.005413f, 0.006474f, 0.007793f, 0.009254f, 0.010971f, 0.012970f, 0.015526f,
+ 0.018112f, 0.022049f, 0.026581f, 0.031586f, 0.038666f, 0.046967f, 0.057617f, 0.071777f, 0.089783f, 0.113953f, 0.145264f, 0.186646f,
+ 0.239990f, 0.305908f, 0.383301f, 0.467285f, 0.551270f, 0.629883f, 0.697266f, 0.754883f, 0.799805f, 0.835938f, 0.864258f, 0.886719f,
+ 0.905273f, 0.918945f, 0.931152f, 0.940918f, 0.948242f, 0.955078f, 0.961426f, 0.965332f, 0.969727f, 0.973633f, 0.976074f, 0.979004f,
+ 0.980957f, 0.983398f, 0.984863f, 0.987305f, 0.988281f, 0.989258f, 0.996094f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.996582f,
+ 0.000000f, 0.000475f, 0.000891f, 0.001390f, 0.001730f, 0.002060f, 0.002501f, 0.003109f, 0.003836f, 0.004837f, 0.005852f, 0.006859f,
+ 0.007740f, 0.009216f, 0.010918f, 0.012863f, 0.014915f, 0.017731f, 0.021317f, 0.025482f, 0.030930f, 0.037262f, 0.044891f, 0.055115f,
+ 0.068298f, 0.085510f, 0.107910f, 0.137207f, 0.176025f, 0.226929f, 0.289551f, 0.364746f, 0.447998f, 0.532715f, 0.613770f, 0.685547f,
+ 0.744629f, 0.791992f, 0.830078f, 0.860352f, 0.884277f, 0.903320f, 0.917969f, 0.930176f, 0.939941f, 0.947754f, 0.954590f, 0.961426f,
+ 0.966309f, 0.970215f, 0.973145f, 0.976562f, 0.979492f, 0.981445f, 0.983398f, 0.985352f, 0.987793f, 0.988281f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996582f, 0.996094f, 0.996094f, 0.000102f, 0.000243f, 0.000844f, 0.001124f, 0.001554f, 0.002077f, 0.002098f, 0.002682f,
+ 0.003357f, 0.004280f, 0.005035f, 0.005764f, 0.006805f, 0.007633f, 0.009354f, 0.010872f, 0.012665f, 0.015099f, 0.017258f, 0.020599f,
+ 0.024887f, 0.029495f, 0.035522f, 0.042999f, 0.053070f, 0.065125f, 0.081299f, 0.102661f, 0.130371f, 0.166992f, 0.215088f, 0.275635f,
+ 0.348877f, 0.431641f, 0.517578f, 0.600098f, 0.672852f, 0.735352f, 0.785645f, 0.826172f, 0.856934f, 0.881836f, 0.900879f, 0.916992f,
+ 0.930176f, 0.940430f, 0.947754f, 0.955078f, 0.960938f, 0.966309f, 0.969238f, 0.973633f, 0.977051f, 0.979492f, 0.981934f, 0.983887f,
+ 0.986328f, 0.987793f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.000241f, 0.000242f, 0.000823f, 0.000956f,
+ 0.001225f, 0.001549f, 0.002031f, 0.002613f, 0.003124f, 0.003574f, 0.004467f, 0.004955f, 0.005672f, 0.006752f, 0.007603f, 0.009186f,
+ 0.010704f, 0.012741f, 0.014366f, 0.017487f, 0.020142f, 0.024002f, 0.028915f, 0.034943f, 0.041656f, 0.050964f, 0.062622f, 0.077881f,
+ 0.097961f, 0.124207f, 0.158936f, 0.204590f, 0.263184f, 0.334961f, 0.416748f, 0.502930f, 0.587891f, 0.664062f, 0.728516f, 0.780762f,
+ 0.822266f, 0.854492f, 0.879395f, 0.900879f, 0.916504f, 0.928711f, 0.940430f, 0.948730f, 0.955566f, 0.961914f, 0.967285f, 0.970215f,
+ 0.974121f, 0.977539f, 0.979980f, 0.982422f, 0.984863f, 0.986816f, 0.994629f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.995605f,
+ 0.000000f, 0.000473f, 0.000607f, 0.000921f, 0.000957f, 0.001448f, 0.001884f, 0.002270f, 0.002703f, 0.002998f, 0.003862f, 0.004307f,
+ 0.005074f, 0.005665f, 0.006737f, 0.007851f, 0.009216f, 0.010735f, 0.012459f, 0.014572f, 0.016998f, 0.019821f, 0.023605f, 0.027969f,
+ 0.033783f, 0.040192f, 0.049286f, 0.060303f, 0.074829f, 0.093750f, 0.118774f, 0.152222f, 0.195801f, 0.252441f, 0.322754f, 0.404053f,
+ 0.491943f, 0.577637f, 0.655273f, 0.722168f, 0.776367f, 0.820312f, 0.854004f, 0.878906f, 0.900879f, 0.916992f, 0.929688f, 0.940430f,
+ 0.949707f, 0.956055f, 0.962402f, 0.967285f, 0.971191f, 0.975586f, 0.978516f, 0.980957f, 0.983398f, 0.985352f, 0.994141f, 0.995117f,
+ 0.995117f, 0.995605f, 0.995117f, 0.995605f, 0.000000f, 0.000444f, 0.000605f, 0.000649f, 0.000926f, 0.001096f, 0.001624f, 0.001669f,
+ 0.002373f, 0.002716f, 0.003231f, 0.003769f, 0.004395f, 0.005005f, 0.005878f, 0.006710f, 0.007793f, 0.008957f, 0.010712f, 0.012230f,
+ 0.014244f, 0.016693f, 0.019531f, 0.022827f, 0.027100f, 0.032318f, 0.038971f, 0.047302f, 0.058105f, 0.072021f, 0.089966f, 0.114319f,
+ 0.146362f, 0.188965f, 0.244019f, 0.312988f, 0.394287f, 0.482178f, 0.569824f, 0.650391f, 0.718262f, 0.774414f, 0.819336f, 0.853027f,
+ 0.880371f, 0.900879f, 0.917969f, 0.930664f, 0.940918f, 0.950684f, 0.957031f, 0.962891f, 0.968262f, 0.972656f, 0.976562f, 0.979004f,
+ 0.981934f, 0.984375f, 0.994141f, 0.994629f, 0.994629f, 0.995117f, 0.994629f, 0.995117f, 0.000000f, 0.000336f, 0.000601f, 0.000712f,
+ 0.000810f, 0.001174f, 0.001286f, 0.001618f, 0.002037f, 0.002592f, 0.002920f, 0.003223f, 0.003847f, 0.004463f, 0.005119f, 0.006020f,
+ 0.006783f, 0.007957f, 0.008888f, 0.010590f, 0.012230f, 0.013885f, 0.016220f, 0.019318f, 0.022278f, 0.026474f, 0.031403f, 0.037781f,
+ 0.046021f, 0.055969f, 0.069397f, 0.086975f, 0.110413f, 0.140991f, 0.182739f, 0.236694f, 0.304932f, 0.385986f, 0.475586f, 0.563965f,
+ 0.646484f, 0.716797f, 0.772461f, 0.818359f, 0.853027f, 0.880859f, 0.901855f, 0.918945f, 0.932129f, 0.942383f, 0.951172f, 0.958496f,
+ 0.964355f, 0.969238f, 0.973633f, 0.977051f, 0.979980f, 0.982910f, 0.993652f, 0.994141f, 0.994629f, 0.994141f, 0.994141f, 0.994629f,
+ 0.000000f, 0.000244f, 0.000418f, 0.000597f, 0.000600f, 0.001085f, 0.001236f, 0.001535f, 0.001970f, 0.002096f, 0.002354f, 0.002834f,
+ 0.003323f, 0.003822f, 0.004463f, 0.005146f, 0.005798f, 0.006859f, 0.007587f, 0.008827f, 0.009956f, 0.011833f, 0.013725f, 0.015945f,
+ 0.018585f, 0.021988f, 0.025665f, 0.030807f, 0.036774f, 0.044373f, 0.054108f, 0.067383f, 0.084229f, 0.106812f, 0.137207f, 0.177734f,
+ 0.230835f, 0.299072f, 0.380127f, 0.470215f, 0.560547f, 0.644531f, 0.715820f, 0.774414f, 0.820312f, 0.854980f, 0.882324f, 0.903809f,
+ 0.921387f, 0.933594f, 0.944824f, 0.952637f, 0.960449f, 0.965820f, 0.971191f, 0.974609f, 0.978027f, 0.981934f, 0.993164f, 0.994629f,
+ 0.994141f, 0.994141f, 0.994141f, 0.994141f, 0.000000f, 0.000244f, 0.000411f, 0.000589f, 0.000820f, 0.000729f, 0.001086f, 0.001301f,
+ 0.001677f, 0.001935f, 0.002312f, 0.002678f, 0.002846f, 0.003590f, 0.003914f, 0.004578f, 0.005020f, 0.005753f, 0.006706f, 0.007710f,
+ 0.008911f, 0.010155f, 0.011528f, 0.013504f, 0.015747f, 0.018036f, 0.021408f, 0.024994f, 0.029816f, 0.035858f, 0.043152f, 0.053009f,
+ 0.065491f, 0.082031f, 0.104065f, 0.133789f, 0.174072f, 0.226929f, 0.294434f, 0.376465f, 0.467773f, 0.560059f, 0.644531f, 0.717285f,
+ 0.777344f, 0.823242f, 0.857910f, 0.885742f, 0.906738f, 0.922852f, 0.936523f, 0.947266f, 0.955078f, 0.961426f, 0.967285f, 0.972656f,
+ 0.976562f, 0.979980f, 0.992676f, 0.993164f, 0.993652f, 0.993652f, 0.993652f, 0.993652f, 0.000000f, 0.000243f, 0.000243f, 0.000442f,
+ 0.000695f, 0.000759f, 0.000837f, 0.001089f, 0.001625f, 0.001702f, 0.002045f, 0.002176f, 0.002756f, 0.003063f, 0.003687f, 0.003893f,
+ 0.004456f, 0.005337f, 0.006062f, 0.006523f, 0.007572f, 0.008430f, 0.009880f, 0.011612f, 0.013237f, 0.015114f, 0.017487f, 0.020584f,
+ 0.024445f, 0.028931f, 0.034729f, 0.042023f, 0.051788f, 0.063843f, 0.079956f, 0.102295f, 0.131592f, 0.171021f, 0.223877f, 0.292236f,
+ 0.375000f, 0.468018f, 0.562012f, 0.648438f, 0.721191f, 0.781250f, 0.826660f, 0.862305f, 0.888672f, 0.909668f, 0.926270f, 0.938965f,
+ 0.949707f, 0.957520f, 0.964355f, 0.969727f, 0.974121f, 0.978027f, 0.992676f, 0.993164f, 0.993164f, 0.992676f, 0.993164f, 0.993164f,
+ 0.000000f, 0.000242f, 0.000242f, 0.000242f, 0.000564f, 0.000692f, 0.000826f, 0.001094f, 0.001280f, 0.001457f, 0.001673f, 0.002232f,
+ 0.002411f, 0.002789f, 0.003174f, 0.003649f, 0.003859f, 0.004349f, 0.004990f, 0.005898f, 0.006622f, 0.007496f, 0.008209f, 0.009583f,
+ 0.011284f, 0.013062f, 0.014763f, 0.017120f, 0.020020f, 0.023804f, 0.028412f, 0.033905f, 0.041016f, 0.050140f, 0.062469f, 0.078552f,
+ 0.100159f, 0.129272f, 0.169067f, 0.222290f, 0.291504f, 0.376465f, 0.470703f, 0.566406f, 0.653320f, 0.728027f, 0.786621f, 0.832031f,
+ 0.866699f, 0.893555f, 0.914062f, 0.929688f, 0.942383f, 0.952148f, 0.959961f, 0.966797f, 0.972168f, 0.976074f, 0.991211f, 0.992188f,
+ 0.992676f, 0.992188f, 0.992676f, 0.992676f, 0.000241f, 0.000241f, 0.000240f, 0.000242f, 0.000486f, 0.000637f, 0.000916f, 0.000933f,
+ 0.001003f, 0.001284f, 0.001584f, 0.001925f, 0.002134f, 0.002502f, 0.002731f, 0.003134f, 0.003435f, 0.004036f, 0.004379f, 0.005077f,
+ 0.005688f, 0.006557f, 0.007347f, 0.007942f, 0.009506f, 0.010712f, 0.012527f, 0.014603f, 0.016693f, 0.019592f, 0.023285f, 0.027512f,
+ 0.033173f, 0.040283f, 0.049347f, 0.061432f, 0.077271f, 0.098938f, 0.128052f, 0.168091f, 0.222168f, 0.292725f, 0.379150f, 0.476807f,
+ 0.573730f, 0.662598f, 0.735840f, 0.794434f, 0.839844f, 0.873535f, 0.898926f, 0.918945f, 0.934082f, 0.945312f, 0.955566f, 0.962402f,
+ 0.969238f, 0.974609f, 0.990723f, 0.991699f, 0.992188f, 0.992188f, 0.992188f, 0.992188f, 0.000000f, 0.000238f, 0.000240f, 0.000362f,
+ 0.000362f, 0.000521f, 0.000631f, 0.000909f, 0.000937f, 0.001249f, 0.001373f, 0.001693f, 0.001746f, 0.002184f, 0.002436f, 0.002680f,
+ 0.003094f, 0.003576f, 0.003828f, 0.004463f, 0.004990f, 0.005589f, 0.006439f, 0.006943f, 0.008217f, 0.009384f, 0.010719f, 0.012184f,
+ 0.014130f, 0.016373f, 0.019241f, 0.022675f, 0.027161f, 0.032379f, 0.039307f, 0.048645f, 0.060455f, 0.076416f, 0.097778f, 0.127441f,
+ 0.168213f, 0.223633f, 0.296387f, 0.385986f, 0.485107f, 0.583984f, 0.673340f, 0.746582f, 0.804199f, 0.848633f, 0.880371f, 0.905273f,
+ 0.923828f, 0.938477f, 0.949707f, 0.958984f, 0.965820f, 0.972656f, 0.990234f, 0.991211f, 0.991211f, 0.991211f, 0.991211f, 0.991211f,
+ 0.000000f, 0.000234f, 0.000238f, 0.000236f, 0.000360f, 0.000482f, 0.000614f, 0.000786f, 0.000900f, 0.001056f, 0.001336f, 0.001466f,
+ 0.001671f, 0.001907f, 0.002333f, 0.002546f, 0.002871f, 0.003067f, 0.003500f, 0.003813f, 0.004425f, 0.004574f, 0.005459f, 0.006092f,
+ 0.006660f, 0.007660f, 0.008987f, 0.010071f, 0.011841f, 0.013847f, 0.016022f, 0.018829f, 0.022339f, 0.026779f, 0.031677f, 0.038910f,
+ 0.047913f, 0.059601f, 0.075684f, 0.097290f, 0.127319f, 0.169189f, 0.226807f, 0.302490f, 0.394775f, 0.497314f, 0.598633f, 0.686523f,
+ 0.759766f, 0.814941f, 0.857422f, 0.888672f, 0.912109f, 0.930176f, 0.943359f, 0.954102f, 0.962402f, 0.968750f, 0.988770f, 0.990234f,
+ 0.990234f, 0.990234f, 0.991211f, 0.990723f, 0.000000f, 0.000036f, 0.000166f, 0.000357f, 0.000356f, 0.000478f, 0.000566f, 0.000638f,
+ 0.000893f, 0.001146f, 0.001242f, 0.001330f, 0.001502f, 0.001773f, 0.001918f, 0.002024f, 0.002501f, 0.002604f, 0.003067f, 0.003334f,
+ 0.003708f, 0.004044f, 0.004646f, 0.005268f, 0.006241f, 0.006931f, 0.007774f, 0.008911f, 0.010277f, 0.011475f, 0.013542f, 0.015732f,
+ 0.018417f, 0.022049f, 0.026154f, 0.031189f, 0.038269f, 0.047119f, 0.059265f, 0.075256f, 0.097534f, 0.128906f, 0.172119f, 0.231934f,
+ 0.311035f, 0.407715f, 0.513184f, 0.615723f, 0.703613f, 0.773926f, 0.827637f, 0.867188f, 0.897461f, 0.919434f, 0.936035f, 0.948730f,
+ 0.958984f, 0.966309f, 0.988770f, 0.989746f, 0.989746f, 0.990234f, 0.989746f, 0.989746f, 0.000000f, 0.000028f, 0.000093f, 0.000334f,
+ 0.000465f, 0.000472f, 0.000373f, 0.000685f, 0.000695f, 0.001027f, 0.001128f, 0.001155f, 0.001419f, 0.001435f, 0.001760f, 0.001850f,
+ 0.002241f, 0.002373f, 0.002604f, 0.002821f, 0.003334f, 0.003666f, 0.004139f, 0.004627f, 0.005207f, 0.005886f, 0.006596f, 0.007580f,
+ 0.008705f, 0.009911f, 0.011520f, 0.013237f, 0.015427f, 0.017944f, 0.021423f, 0.025497f, 0.030945f, 0.037537f, 0.046692f, 0.058624f,
+ 0.075317f, 0.098267f, 0.130493f, 0.176025f, 0.239136f, 0.323242f, 0.424561f, 0.533691f, 0.636230f, 0.723145f, 0.790039f, 0.841797f,
+ 0.880371f, 0.906738f, 0.926758f, 0.941406f, 0.953613f, 0.963379f, 0.987793f, 0.988770f, 0.988770f, 0.989258f, 0.989258f, 0.989258f,
+ 0.000000f, 0.000000f, 0.000047f, 0.000321f, 0.000332f, 0.000351f, 0.000470f, 0.000596f, 0.000655f, 0.000727f, 0.001008f, 0.001112f,
+ 0.001350f, 0.001379f, 0.001380f, 0.001751f, 0.002008f, 0.002151f, 0.002327f, 0.002548f, 0.002691f, 0.003056f, 0.003475f, 0.003925f,
+ 0.004749f, 0.005161f, 0.005863f, 0.006538f, 0.007153f, 0.008453f, 0.009789f, 0.010986f, 0.013168f, 0.015121f, 0.017563f, 0.020966f,
+ 0.025009f, 0.030151f, 0.037048f, 0.046570f, 0.058624f, 0.075623f, 0.099243f, 0.133667f, 0.181641f, 0.249756f, 0.338623f, 0.445312f,
+ 0.556641f, 0.659180f, 0.744141f, 0.808594f, 0.855957f, 0.890137f, 0.916992f, 0.934570f, 0.949219f, 0.959473f, 0.986816f, 0.987793f,
+ 0.987793f, 0.987793f, 0.987793f, 0.988281f, 0.000000f, 0.000000f, 0.000000f, 0.000244f, 0.000429f, 0.000440f, 0.000348f, 0.000592f,
+ 0.000606f, 0.000755f, 0.000690f, 0.000935f, 0.001172f, 0.001257f, 0.001368f, 0.001458f, 0.001786f, 0.001809f, 0.002060f, 0.002274f,
+ 0.002478f, 0.002642f, 0.002987f, 0.003435f, 0.003866f, 0.004337f, 0.005066f, 0.005409f, 0.006355f, 0.007111f, 0.008011f, 0.009392f,
+ 0.011032f, 0.012321f, 0.014717f, 0.017319f, 0.020432f, 0.024551f, 0.029953f, 0.036835f, 0.045929f, 0.058716f, 0.076416f, 0.101562f,
+ 0.137695f, 0.189453f, 0.262451f, 0.358154f, 0.470215f, 0.584961f, 0.686523f, 0.767578f, 0.828125f, 0.871582f, 0.903809f, 0.926270f,
+ 0.941895f, 0.956055f, 0.985352f, 0.986328f, 0.986816f, 0.986816f, 0.986816f, 0.986816f, 0.000000f, 0.000000f, 0.000000f, 0.000119f,
+ 0.000237f, 0.000314f, 0.000570f, 0.000575f, 0.000583f, 0.000632f, 0.000651f, 0.000789f, 0.000947f, 0.001097f, 0.001300f, 0.001320f,
+ 0.001384f, 0.001443f, 0.001641f, 0.001869f, 0.002047f, 0.002396f, 0.002634f, 0.003025f, 0.003412f, 0.003757f, 0.004238f, 0.004620f,
+ 0.005463f, 0.006168f, 0.007072f, 0.008080f, 0.009155f, 0.010590f, 0.012306f, 0.014175f, 0.016769f, 0.020081f, 0.023972f, 0.029495f,
+ 0.036560f, 0.045959f, 0.059265f, 0.078125f, 0.104797f, 0.143677f, 0.199951f, 0.279785f, 0.382812f, 0.500977f, 0.616699f, 0.716309f,
+ 0.791992f, 0.847168f, 0.887207f, 0.915527f, 0.936523f, 0.950684f, 0.984375f, 0.985352f, 0.986328f, 0.985840f, 0.986328f, 0.985840f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000205f, 0.000239f, 0.000299f, 0.000537f, 0.000574f, 0.000696f, 0.000583f, 0.000740f,
+ 0.000778f, 0.000867f, 0.001013f, 0.001257f, 0.001325f, 0.001277f, 0.001416f, 0.001718f, 0.001965f, 0.002079f, 0.002356f, 0.002577f,
+ 0.002771f, 0.003305f, 0.003693f, 0.004028f, 0.004593f, 0.005234f, 0.005905f, 0.006802f, 0.007698f, 0.008553f, 0.009995f, 0.011635f,
+ 0.013824f, 0.016174f, 0.019547f, 0.023544f, 0.029114f, 0.036377f, 0.046417f, 0.060211f, 0.080017f, 0.108643f, 0.151611f, 0.213379f,
+ 0.301758f, 0.414062f, 0.537598f, 0.653320f, 0.748047f, 0.817871f, 0.868164f, 0.903320f, 0.928711f, 0.945801f, 0.982910f, 0.983887f,
+ 0.984375f, 0.984375f, 0.984863f, 0.984375f, 0.000000f, 0.000000f, 0.000045f, 0.000105f, 0.000114f, 0.000340f, 0.000371f, 0.000501f,
+ 0.000639f, 0.000554f, 0.000687f, 0.000675f, 0.000711f, 0.000738f, 0.000824f, 0.001092f, 0.001040f, 0.001185f, 0.001212f, 0.001408f,
+ 0.001624f, 0.001813f, 0.001982f, 0.002182f, 0.002634f, 0.002748f, 0.003252f, 0.003540f, 0.004089f, 0.004505f, 0.005001f, 0.005657f,
+ 0.006500f, 0.007195f, 0.008286f, 0.009750f, 0.011208f, 0.013420f, 0.015762f, 0.019226f, 0.023209f, 0.029144f, 0.036591f, 0.047150f,
+ 0.061615f, 0.082947f, 0.114014f, 0.161621f, 0.231323f, 0.329834f, 0.451416f, 0.579590f, 0.692871f, 0.780273f, 0.844238f, 0.888184f,
+ 0.917969f, 0.939453f, 0.981445f, 0.982422f, 0.982910f, 0.982910f, 0.982910f, 0.982910f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000208f, 0.000311f, 0.000238f, 0.000337f, 0.000524f, 0.000617f, 0.000533f, 0.000675f, 0.000665f, 0.000776f, 0.000840f, 0.000819f,
+ 0.000902f, 0.001169f, 0.001130f, 0.001178f, 0.001382f, 0.001571f, 0.001941f, 0.001932f, 0.002138f, 0.002306f, 0.002586f, 0.002937f,
+ 0.003468f, 0.003740f, 0.004292f, 0.004704f, 0.005444f, 0.006081f, 0.007019f, 0.008255f, 0.009521f, 0.010796f, 0.012840f, 0.015503f,
+ 0.018784f, 0.023178f, 0.029129f, 0.036774f, 0.047699f, 0.063416f, 0.086548f, 0.121399f, 0.175293f, 0.254883f, 0.365234f, 0.496582f,
+ 0.626953f, 0.733398f, 0.813477f, 0.869629f, 0.906738f, 0.933105f, 0.979980f, 0.980957f, 0.981445f, 0.981445f, 0.980957f, 0.981445f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000208f, 0.000312f, 0.000236f, 0.000343f, 0.000475f, 0.000496f, 0.000528f,
+ 0.000659f, 0.000582f, 0.000685f, 0.000710f, 0.000761f, 0.000784f, 0.000941f, 0.001013f, 0.001117f, 0.001339f, 0.001500f, 0.001623f,
+ 0.001769f, 0.002039f, 0.002298f, 0.002565f, 0.002802f, 0.003119f, 0.003471f, 0.003857f, 0.004658f, 0.005177f, 0.005836f, 0.006752f,
+ 0.007324f, 0.008911f, 0.010422f, 0.012527f, 0.015373f, 0.018585f, 0.022964f, 0.029037f, 0.037231f, 0.049072f, 0.066345f, 0.091492f,
+ 0.131470f, 0.193359f, 0.285645f, 0.409912f, 0.548828f, 0.676758f, 0.776367f, 0.845703f, 0.893066f, 0.924805f, 0.978027f, 0.979492f,
+ 0.979492f, 0.979004f, 0.979492f, 0.979492f, 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000166f, 0.000228f, 0.000227f,
+ 0.000369f, 0.000337f, 0.000368f, 0.000452f, 0.000500f, 0.000547f, 0.000543f, 0.000575f, 0.000623f, 0.000723f, 0.000783f, 0.000874f,
+ 0.001141f, 0.001226f, 0.001279f, 0.001336f, 0.001499f, 0.001655f, 0.001922f, 0.002090f, 0.002453f, 0.002298f, 0.003139f, 0.003181f,
+ 0.003674f, 0.004166f, 0.004814f, 0.005447f, 0.006348f, 0.007179f, 0.008736f, 0.010406f, 0.012321f, 0.014984f, 0.018219f, 0.022934f,
+ 0.028824f, 0.037598f, 0.050476f, 0.069397f, 0.098694f, 0.144775f, 0.218018f, 0.325439f, 0.464111f, 0.607910f, 0.729492f, 0.817383f,
+ 0.876953f, 0.915527f, 0.976562f, 0.977539f, 0.977539f, 0.977051f, 0.977051f, 0.977539f, 0.000000f, 0.000000f, 0.000000f, 0.000122f,
+ 0.000122f, 0.000122f, 0.000154f, 0.000200f, 0.000267f, 0.000316f, 0.000324f, 0.000449f, 0.000319f, 0.000379f, 0.000515f, 0.000519f,
+ 0.000558f, 0.000628f, 0.000645f, 0.000690f, 0.000777f, 0.000940f, 0.001096f, 0.001204f, 0.001278f, 0.001485f, 0.001670f, 0.001929f,
+ 0.001961f, 0.002016f, 0.002367f, 0.002785f, 0.003025f, 0.003248f, 0.003805f, 0.004539f, 0.004845f, 0.005733f, 0.006851f, 0.008278f,
+ 0.010017f, 0.011841f, 0.014542f, 0.017807f, 0.022705f, 0.029190f, 0.038544f, 0.052612f, 0.073853f, 0.108093f, 0.162842f, 0.250977f,
+ 0.377930f, 0.529785f, 0.672363f, 0.782715f, 0.855957f, 0.904297f, 0.973145f, 0.974121f, 0.974609f, 0.975586f, 0.974609f, 0.975098f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000158f, 0.000121f, 0.000190f, 0.000238f, 0.000397f, 0.000354f,
+ 0.000364f, 0.000365f, 0.000440f, 0.000474f, 0.000509f, 0.000612f, 0.000611f, 0.000648f, 0.000804f, 0.000755f, 0.000943f, 0.001050f,
+ 0.001221f, 0.001340f, 0.001338f, 0.001443f, 0.001635f, 0.001822f, 0.002083f, 0.002226f, 0.002480f, 0.002682f, 0.003185f, 0.003609f,
+ 0.003948f, 0.005074f, 0.005558f, 0.006741f, 0.007904f, 0.009384f, 0.011360f, 0.014000f, 0.017883f, 0.022675f, 0.029648f, 0.039917f,
+ 0.055695f, 0.080261f, 0.120728f, 0.188354f, 0.296143f, 0.443848f, 0.603027f, 0.737793f, 0.831055f, 0.891113f, 0.970703f, 0.971680f,
+ 0.972168f, 0.972656f, 0.971680f, 0.972168f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000122f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000251f, 0.000260f, 0.000278f, 0.000315f, 0.000334f, 0.000235f, 0.000357f, 0.000442f, 0.000513f, 0.000504f, 0.000598f,
+ 0.000556f, 0.000771f, 0.000831f, 0.000886f, 0.000977f, 0.001145f, 0.001105f, 0.001244f, 0.001281f, 0.001431f, 0.001544f, 0.001850f,
+ 0.001986f, 0.002131f, 0.002537f, 0.002737f, 0.003252f, 0.003826f, 0.004555f, 0.005184f, 0.006199f, 0.007195f, 0.009041f, 0.011337f,
+ 0.013878f, 0.017395f, 0.022552f, 0.030502f, 0.041962f, 0.059875f, 0.089111f, 0.139404f, 0.224609f, 0.357910f, 0.524902f, 0.684082f,
+ 0.800781f, 0.875977f, 0.967773f, 0.968750f, 0.968262f, 0.968750f, 0.969238f, 0.969238f, 0.000000f, 0.000000f, 0.000122f, 0.000122f,
+ 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000095f, 0.000081f, 0.000217f, 0.000149f, 0.000204f, 0.000212f, 0.000338f,
+ 0.000345f, 0.000348f, 0.000456f, 0.000463f, 0.000495f, 0.000570f, 0.000583f, 0.000748f, 0.000799f, 0.000731f, 0.000965f, 0.001041f,
+ 0.001071f, 0.001210f, 0.001318f, 0.001238f, 0.001410f, 0.001631f, 0.001932f, 0.002327f, 0.002577f, 0.003057f, 0.003452f, 0.003956f,
+ 0.004639f, 0.005714f, 0.006817f, 0.008446f, 0.010605f, 0.013443f, 0.017319f, 0.022964f, 0.031021f, 0.044281f, 0.065857f, 0.102112f,
+ 0.166504f, 0.277344f, 0.439941f, 0.617188f, 0.762207f, 0.856445f, 0.963379f, 0.964355f, 0.965332f, 0.964844f, 0.965332f, 0.965332f,
+ 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000107f, 0.000091f, 0.000161f,
+ 0.000119f, 0.000184f, 0.000266f, 0.000284f, 0.000314f, 0.000319f, 0.000334f, 0.000344f, 0.000565f, 0.000455f, 0.000488f, 0.000667f,
+ 0.000710f, 0.000713f, 0.000787f, 0.000755f, 0.000849f, 0.000972f, 0.001097f, 0.001286f, 0.001427f, 0.001556f, 0.001667f, 0.001687f,
+ 0.002155f, 0.002369f, 0.002674f, 0.003086f, 0.003710f, 0.004536f, 0.005585f, 0.006783f, 0.007957f, 0.010262f, 0.013115f, 0.017212f,
+ 0.023102f, 0.032715f, 0.047943f, 0.074158f, 0.121155f, 0.207520f, 0.353027f, 0.541504f, 0.715332f, 0.834473f, 0.959473f, 0.960449f,
+ 0.960938f, 0.960938f, 0.960938f, 0.961426f, 0.000000f, 0.000000f, 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000121f,
+ 0.000120f, 0.000120f, 0.000103f, 0.000089f, 0.000077f, 0.000080f, 0.000121f, 0.000218f, 0.000209f, 0.000245f, 0.000303f, 0.000316f,
+ 0.000388f, 0.000341f, 0.000549f, 0.000594f, 0.000604f, 0.000679f, 0.000625f, 0.000628f, 0.000795f, 0.000883f, 0.000857f, 0.000991f,
+ 0.001166f, 0.000955f, 0.001194f, 0.001347f, 0.001548f, 0.001804f, 0.002048f, 0.002388f, 0.002911f, 0.003130f, 0.003933f, 0.004845f,
+ 0.006031f, 0.007385f, 0.009705f, 0.012688f, 0.017044f, 0.023788f, 0.034882f, 0.053284f, 0.086670f, 0.151123f, 0.271484f, 0.457031f,
+ 0.658203f, 0.805176f, 0.954102f, 0.955078f, 0.956055f, 0.956055f, 0.956055f, 0.955566f, 0.000000f, 0.000122f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000116f, 0.000101f, 0.000088f, 0.000077f, 0.000131f, 0.000071f,
+ 0.000146f, 0.000200f, 0.000237f, 0.000270f, 0.000289f, 0.000302f, 0.000311f, 0.000441f, 0.000396f, 0.000588f, 0.000630f, 0.000570f,
+ 0.000575f, 0.000537f, 0.000589f, 0.000750f, 0.000721f, 0.001048f, 0.001122f, 0.000951f, 0.001243f, 0.001346f, 0.001703f, 0.001592f,
+ 0.001880f, 0.002340f, 0.002804f, 0.003637f, 0.004356f, 0.005329f, 0.006805f, 0.009094f, 0.012566f, 0.017181f, 0.025040f, 0.038147f,
+ 0.061249f, 0.107788f, 0.200195f, 0.369629f, 0.587891f, 0.771973f, 0.948242f, 0.949707f, 0.950195f, 0.949707f, 0.950195f, 0.950195f,
+ 0.000000f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000120f, 0.000119f, 0.000119f, 0.000114f,
+ 0.000101f, 0.000088f, 0.000079f, 0.000070f, 0.000063f, 0.000136f, 0.000136f, 0.000183f, 0.000207f, 0.000277f, 0.000271f, 0.000291f,
+ 0.000369f, 0.000344f, 0.000494f, 0.000459f, 0.000515f, 0.000509f, 0.000532f, 0.000504f, 0.000716f, 0.000589f, 0.000691f, 0.000902f,
+ 0.000972f, 0.000968f, 0.001067f, 0.001483f, 0.001780f, 0.001652f, 0.002090f, 0.002602f, 0.003113f, 0.003738f, 0.004738f, 0.006420f,
+ 0.008522f, 0.012100f, 0.017334f, 0.026489f, 0.042786f, 0.074524f, 0.142578f, 0.283936f, 0.509277f, 0.729492f, 0.940918f, 0.941895f,
+ 0.942383f, 0.942383f, 0.942383f, 0.942871f, 0.000122f, 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000119f, 0.000119f,
+ 0.000119f, 0.000118f, 0.000118f, 0.000118f, 0.000116f, 0.000102f, 0.000090f, 0.000081f, 0.000091f, 0.000066f, 0.000059f, 0.000110f,
+ 0.000109f, 0.000155f, 0.000184f, 0.000227f, 0.000297f, 0.000333f, 0.000355f, 0.000349f, 0.000344f, 0.000421f, 0.000459f, 0.000561f,
+ 0.000600f, 0.000563f, 0.000630f, 0.000563f, 0.000682f, 0.000737f, 0.000892f, 0.001037f, 0.001026f, 0.001163f, 0.001743f, 0.001782f,
+ 0.002117f, 0.002573f, 0.003389f, 0.004429f, 0.005871f, 0.007942f, 0.011841f, 0.018066f, 0.029190f, 0.050842f, 0.098511f, 0.207397f,
+ 0.422363f, 0.677734f, 0.932129f, 0.933594f, 0.933594f, 0.934082f, 0.934082f, 0.934082f, 0.000000f, 0.000121f, 0.000120f, 0.000119f,
+ 0.000119f, 0.000119f, 0.000118f, 0.000118f, 0.000118f, 0.000117f, 0.000117f, 0.000117f, 0.000117f, 0.000116f, 0.000104f, 0.000093f,
+ 0.000084f, 0.000076f, 0.000069f, 0.000091f, 0.000057f, 0.000051f, 0.000112f, 0.000120f, 0.000179f, 0.000232f, 0.000225f, 0.000283f,
+ 0.000301f, 0.000308f, 0.000353f, 0.000437f, 0.000395f, 0.000523f, 0.000486f, 0.000504f, 0.000469f, 0.000614f, 0.000581f, 0.000755f,
+ 0.000789f, 0.001121f, 0.000981f, 0.001218f, 0.001565f, 0.001795f, 0.002296f, 0.002958f, 0.003866f, 0.005329f, 0.007675f, 0.011658f,
+ 0.019043f, 0.033478f, 0.065430f, 0.144043f, 0.331299f, 0.613770f, 0.921387f, 0.922852f, 0.923340f, 0.923340f, 0.923340f, 0.923340f,
+ 0.000000f, 0.000000f, 0.000119f, 0.000118f, 0.000118f, 0.000117f, 0.000116f, 0.000116f, 0.000116f, 0.000116f, 0.000115f, 0.000115f,
+ 0.000115f, 0.000115f, 0.000114f, 0.000108f, 0.000097f, 0.000087f, 0.000079f, 0.000072f, 0.000065f, 0.000060f, 0.000094f, 0.000050f,
+ 0.000104f, 0.000104f, 0.000121f, 0.000164f, 0.000195f, 0.000247f, 0.000265f, 0.000328f, 0.000290f, 0.000355f, 0.000395f, 0.000356f,
+ 0.000361f, 0.000459f, 0.000470f, 0.000515f, 0.000580f, 0.000624f, 0.000751f, 0.000964f, 0.001105f, 0.001279f, 0.001413f, 0.001823f,
+ 0.002441f, 0.003407f, 0.004852f, 0.007210f, 0.011803f, 0.021225f, 0.041473f, 0.095032f, 0.244019f, 0.537598f, 0.907715f, 0.910156f,
+ 0.910156f, 0.909180f, 0.909668f, 0.911133f, 0.000120f, 0.000118f, 0.000117f, 0.000116f, 0.000114f, 0.000114f, 0.000114f, 0.000113f,
+ 0.000113f, 0.000112f, 0.000112f, 0.000112f, 0.000111f, 0.000112f, 0.000111f, 0.000111f, 0.000111f, 0.000101f, 0.000093f, 0.000084f,
+ 0.000077f, 0.000070f, 0.000064f, 0.000059f, 0.000074f, 0.000079f, 0.000059f, 0.000087f, 0.000097f, 0.000128f, 0.000185f, 0.000213f,
+ 0.000265f, 0.000235f, 0.000239f, 0.000288f, 0.000299f, 0.000371f, 0.000341f, 0.000369f, 0.000460f, 0.000446f, 0.000490f, 0.000602f,
+ 0.000694f, 0.000904f, 0.001012f, 0.001234f, 0.001544f, 0.002096f, 0.002989f, 0.004299f, 0.006840f, 0.012383f, 0.024948f, 0.059204f,
+ 0.166626f, 0.452637f, 0.892578f, 0.894043f, 0.894043f, 0.894531f, 0.894531f, 0.894043f, 0.000115f, 0.000107f, 0.000108f, 0.000111f,
+ 0.000108f, 0.000109f, 0.000108f, 0.000108f, 0.000108f, 0.000107f, 0.000108f, 0.000107f, 0.000107f, 0.000106f, 0.000107f, 0.000107f,
+ 0.000106f, 0.000107f, 0.000106f, 0.000097f, 0.000090f, 0.000082f, 0.000075f, 0.000069f, 0.000063f, 0.000058f, 0.000053f, 0.000070f,
+ 0.000073f, 0.000085f, 0.000077f, 0.000088f, 0.000136f, 0.000168f, 0.000190f, 0.000204f, 0.000199f, 0.000252f, 0.000233f, 0.000270f,
+ 0.000325f, 0.000295f, 0.000348f, 0.000383f, 0.000435f, 0.000534f, 0.000581f, 0.000803f, 0.001004f, 0.001330f, 0.001812f, 0.002489f,
+ 0.003944f, 0.006832f, 0.013748f, 0.033997f, 0.104858f, 0.356689f, 0.873047f, 0.873047f, 0.875000f, 0.874023f, 0.874023f, 0.874023f,
+ 0.000000f, 0.000071f, 0.000063f, 0.000094f, 0.000092f, 0.000094f, 0.000093f, 0.000098f, 0.000098f, 0.000098f, 0.000098f, 0.000099f,
+ 0.000098f, 0.000099f, 0.000099f, 0.000099f, 0.000099f, 0.000099f, 0.000099f, 0.000100f, 0.000100f, 0.000094f, 0.000087f, 0.000080f,
+ 0.000074f, 0.000068f, 0.000062f, 0.000058f, 0.000053f, 0.000049f, 0.000059f, 0.000059f, 0.000045f, 0.000078f, 0.000082f, 0.000118f,
+ 0.000155f, 0.000160f, 0.000174f, 0.000180f, 0.000226f, 0.000213f, 0.000248f, 0.000258f, 0.000288f, 0.000352f, 0.000396f, 0.000465f,
+ 0.000566f, 0.000789f, 0.000941f, 0.001343f, 0.002199f, 0.003616f, 0.006912f, 0.017380f, 0.058960f, 0.259521f, 0.847656f, 0.849121f,
+ 0.850586f, 0.850098f, 0.849121f, 0.850586f, 0.000000f, 0.000000f, 0.000019f, 0.000044f, 0.000048f, 0.000061f, 0.000071f, 0.000073f,
+ 0.000076f, 0.000079f, 0.000079f, 0.000082f, 0.000082f, 0.000082f, 0.000085f, 0.000086f, 0.000087f, 0.000086f, 0.000088f, 0.000087f,
+ 0.000089f, 0.000089f, 0.000089f, 0.000090f, 0.000084f, 0.000078f, 0.000072f, 0.000067f, 0.000062f, 0.000057f, 0.000052f, 0.000049f,
+ 0.000045f, 0.000041f, 0.000038f, 0.000040f, 0.000062f, 0.000092f, 0.000100f, 0.000121f, 0.000144f, 0.000133f, 0.000137f, 0.000170f,
+ 0.000181f, 0.000168f, 0.000215f, 0.000286f, 0.000327f, 0.000397f, 0.000504f, 0.000738f, 0.001039f, 0.001729f, 0.003317f, 0.007721f,
+ 0.028458f, 0.166626f, 0.815430f, 0.818359f, 0.818359f, 0.817383f, 0.818848f, 0.818359f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000008f, 0.000016f, 0.000031f, 0.000035f, 0.000048f, 0.000050f, 0.000053f, 0.000058f, 0.000059f,
+ 0.000063f, 0.000064f, 0.000067f, 0.000067f, 0.000070f, 0.000071f, 0.000072f, 0.000073f, 0.000075f, 0.000075f, 0.000076f, 0.000075f,
+ 0.000069f, 0.000064f, 0.000060f, 0.000055f, 0.000051f, 0.000047f, 0.000043f, 0.000040f, 0.000037f, 0.000034f, 0.000040f, 0.000041f,
+ 0.000054f, 0.000069f, 0.000096f, 0.000111f, 0.000109f, 0.000113f, 0.000142f, 0.000136f, 0.000158f, 0.000196f, 0.000237f, 0.000349f,
+ 0.000423f, 0.000744f, 0.001380f, 0.003214f, 0.011124f, 0.088135f, 0.777344f, 0.779297f, 0.780273f, 0.779785f, 0.779785f, 0.779785f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000003f, 0.000007f, 0.000021f, 0.000023f, 0.000031f, 0.000034f, 0.000038f, 0.000041f, 0.000043f, 0.000047f,
+ 0.000049f, 0.000050f, 0.000053f, 0.000055f, 0.000056f, 0.000057f, 0.000059f, 0.000060f, 0.000055f, 0.000051f, 0.000048f, 0.000044f,
+ 0.000041f, 0.000038f, 0.000035f, 0.000032f, 0.000029f, 0.000028f, 0.000028f, 0.000037f, 0.000044f, 0.000064f, 0.000078f, 0.000072f,
+ 0.000089f, 0.000098f, 0.000104f, 0.000146f, 0.000200f, 0.000272f, 0.000479f, 0.001077f, 0.003733f, 0.033752f, 0.729492f, 0.730957f,
+ 0.732422f, 0.731934f, 0.732422f, 0.732422f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000006f, 0.000009f, 0.000013f, 0.000019f, 0.000021f, 0.000025f, 0.000027f, 0.000030f,
+ 0.000033f, 0.000034f, 0.000037f, 0.000039f, 0.000041f, 0.000039f, 0.000036f, 0.000033f, 0.000031f, 0.000028f, 0.000026f, 0.000024f,
+ 0.000021f, 0.000019f, 0.000017f, 0.000023f, 0.000033f, 0.000041f, 0.000043f, 0.000058f, 0.000061f, 0.000081f, 0.000121f, 0.000248f,
+ 0.000821f, 0.008255f, 0.673340f, 0.674805f, 0.674316f, 0.674805f, 0.674805f, 0.673828f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000006f, 0.000010f, 0.000013f,
+ 0.000015f, 0.000017f, 0.000020f, 0.000022f, 0.000021f, 0.000019f, 0.000017f, 0.000015f, 0.000013f, 0.000012f, 0.000010f, 0.000011f,
+ 0.000016f, 0.000019f, 0.000019f, 0.000036f, 0.000090f, 0.000897f, 0.606934f, 0.609863f, 0.609375f, 0.609863f, 0.609863f, 0.610352f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000006f, 0.000005f, 0.000004f, 0.000003f, 0.000004f, 0.000008f, 0.534668f, 0.536621f,
+ 0.537109f, 0.537109f, 0.536621f, 0.536621f,
+ },
+ {
+ 0.149292f, 0.432373f, 0.614258f, 0.719238f, 0.784180f, 0.826660f, 0.856934f, 0.879883f, 0.896484f, 0.909180f, 0.919922f, 0.928711f,
+ 0.936035f, 0.942383f, 0.947266f, 0.952148f, 0.956055f, 0.959473f, 0.962891f, 0.965820f, 0.968262f, 0.970703f, 0.972656f, 0.974609f,
+ 0.976562f, 0.978027f, 0.979492f, 0.980469f, 0.981934f, 0.983398f, 0.984863f, 0.985352f, 0.986328f, 0.987305f, 0.988281f, 0.989258f,
+ 0.989746f, 0.990234f, 0.990723f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.993652f, 0.994629f, 0.995117f, 0.995117f, 0.996094f,
+ 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.998047f, 0.998047f, 0.998535f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999512f, 0.999512f, 0.999512f, 0.999023f, 0.040161f, 0.161255f, 0.324951f, 0.486572f, 0.612305f, 0.704590f, 0.767090f, 0.811523f,
+ 0.844238f, 0.868652f, 0.887695f, 0.902344f, 0.913574f, 0.924316f, 0.932129f, 0.937988f, 0.944336f, 0.949707f, 0.954102f, 0.957520f,
+ 0.960938f, 0.964355f, 0.966797f, 0.969727f, 0.971191f, 0.973633f, 0.975586f, 0.977539f, 0.979004f, 0.980469f, 0.981445f, 0.982910f,
+ 0.983887f, 0.985352f, 0.985840f, 0.987305f, 0.987793f, 0.988770f, 0.989258f, 0.990234f, 0.991211f, 0.992188f, 0.992676f, 0.993164f,
+ 0.993164f, 0.993652f, 0.994141f, 0.995117f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998535f,
+ 0.999023f, 0.999023f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999023f, 0.017395f, 0.068542f, 0.149292f, 0.262451f,
+ 0.392822f, 0.518066f, 0.621582f, 0.700195f, 0.759766f, 0.803711f, 0.836426f, 0.862305f, 0.880859f, 0.896484f, 0.909668f, 0.919434f,
+ 0.929199f, 0.935547f, 0.941895f, 0.947754f, 0.952637f, 0.956055f, 0.959961f, 0.963867f, 0.965820f, 0.968750f, 0.970703f, 0.973145f,
+ 0.975098f, 0.977051f, 0.979004f, 0.979980f, 0.981934f, 0.983398f, 0.983887f, 0.984863f, 0.985840f, 0.986816f, 0.987793f, 0.989258f,
+ 0.989746f, 0.990234f, 0.991211f, 0.991699f, 0.992188f, 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.995605f, 0.996094f, 0.996094f,
+ 0.996582f, 0.997070f, 0.997559f, 0.997559f, 0.998047f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999512f, 0.999023f,
+ 0.009125f, 0.035492f, 0.075806f, 0.135864f, 0.219971f, 0.324707f, 0.437012f, 0.543457f, 0.633789f, 0.704102f, 0.758789f, 0.802246f,
+ 0.833496f, 0.857910f, 0.878418f, 0.894043f, 0.906738f, 0.917480f, 0.925781f, 0.933594f, 0.940918f, 0.946777f, 0.951172f, 0.954590f,
+ 0.959473f, 0.962891f, 0.965820f, 0.968262f, 0.971191f, 0.973145f, 0.975098f, 0.976562f, 0.978516f, 0.979980f, 0.981445f, 0.982422f,
+ 0.983887f, 0.985840f, 0.986328f, 0.987305f, 0.988281f, 0.988770f, 0.989746f, 0.990234f, 0.991699f, 0.992188f, 0.992676f, 0.993652f,
+ 0.994141f, 0.994629f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996582f, 0.997559f, 0.997559f, 0.998047f, 0.999023f, 0.999023f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.005848f, 0.021225f, 0.043640f, 0.076782f, 0.124084f, 0.189575f, 0.274414f, 0.372559f,
+ 0.473633f, 0.567383f, 0.646973f, 0.711426f, 0.761230f, 0.801758f, 0.833496f, 0.857422f, 0.876953f, 0.893066f, 0.905273f, 0.916504f,
+ 0.925293f, 0.932617f, 0.939941f, 0.945801f, 0.950684f, 0.955566f, 0.958984f, 0.962402f, 0.965820f, 0.968262f, 0.970703f, 0.972656f,
+ 0.975098f, 0.977051f, 0.978516f, 0.980469f, 0.981934f, 0.982422f, 0.983887f, 0.985840f, 0.986328f, 0.987305f, 0.988281f, 0.989258f,
+ 0.989746f, 0.990723f, 0.991211f, 0.992188f, 0.993164f, 0.993652f, 0.994629f, 0.995117f, 0.995117f, 0.996094f, 0.996094f, 0.997070f,
+ 0.997559f, 0.997559f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.998535f, 0.998535f, 0.003937f, 0.014107f, 0.027664f, 0.047211f,
+ 0.075195f, 0.113953f, 0.166748f, 0.236328f, 0.320312f, 0.412354f, 0.504395f, 0.589844f, 0.661621f, 0.719727f, 0.768066f, 0.805664f,
+ 0.834961f, 0.858398f, 0.877441f, 0.893066f, 0.906738f, 0.916992f, 0.926270f, 0.933105f, 0.940430f, 0.946289f, 0.951172f, 0.955566f,
+ 0.959473f, 0.962891f, 0.965820f, 0.968262f, 0.970703f, 0.973145f, 0.975098f, 0.977051f, 0.979004f, 0.980469f, 0.981934f, 0.983398f,
+ 0.984375f, 0.985840f, 0.986328f, 0.987305f, 0.988770f, 0.989746f, 0.990723f, 0.991211f, 0.992188f, 0.992676f, 0.993652f, 0.994629f,
+ 0.994629f, 0.995117f, 0.995605f, 0.995605f, 0.996582f, 0.997070f, 0.998535f, 0.999023f, 0.999023f, 0.999023f, 0.998535f, 0.998535f,
+ 0.002962f, 0.009674f, 0.019348f, 0.031708f, 0.049255f, 0.072754f, 0.105164f, 0.149048f, 0.206665f, 0.278076f, 0.361572f, 0.448730f,
+ 0.534668f, 0.611816f, 0.677734f, 0.730957f, 0.775879f, 0.809570f, 0.837891f, 0.861328f, 0.879395f, 0.894531f, 0.907227f, 0.916992f,
+ 0.926270f, 0.934082f, 0.940918f, 0.946289f, 0.951172f, 0.956055f, 0.959473f, 0.962891f, 0.966797f, 0.969238f, 0.971191f, 0.973633f,
+ 0.976074f, 0.977539f, 0.979492f, 0.980957f, 0.982422f, 0.983398f, 0.984863f, 0.986328f, 0.986816f, 0.988281f, 0.989746f, 0.989746f,
+ 0.991211f, 0.991699f, 0.992676f, 0.993164f, 0.994141f, 0.994629f, 0.994629f, 0.995605f, 0.996094f, 0.997070f, 0.998535f, 0.999023f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.001900f, 0.007225f, 0.013733f, 0.022552f, 0.033661f, 0.049164f, 0.070374f, 0.097534f,
+ 0.135132f, 0.183350f, 0.244507f, 0.317871f, 0.400146f, 0.483643f, 0.562988f, 0.633301f, 0.693848f, 0.743652f, 0.784180f, 0.816895f,
+ 0.842773f, 0.865234f, 0.882812f, 0.896973f, 0.908691f, 0.919434f, 0.927734f, 0.935547f, 0.942383f, 0.947266f, 0.952637f, 0.957031f,
+ 0.960938f, 0.964355f, 0.967285f, 0.969727f, 0.971680f, 0.974609f, 0.976074f, 0.978027f, 0.979980f, 0.981445f, 0.982910f, 0.984375f,
+ 0.985840f, 0.986328f, 0.988281f, 0.988770f, 0.989746f, 0.990723f, 0.991699f, 0.992188f, 0.993164f, 0.993652f, 0.994629f, 0.995117f,
+ 0.995605f, 0.996094f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998047f, 0.001921f, 0.005543f, 0.010223f, 0.016312f,
+ 0.024918f, 0.035217f, 0.049164f, 0.067017f, 0.091125f, 0.122986f, 0.164673f, 0.217896f, 0.282471f, 0.356934f, 0.436768f, 0.516602f,
+ 0.590820f, 0.656250f, 0.711426f, 0.757812f, 0.794922f, 0.825684f, 0.850098f, 0.870605f, 0.885742f, 0.900879f, 0.912109f, 0.921387f,
+ 0.929688f, 0.937500f, 0.943848f, 0.949219f, 0.953125f, 0.958496f, 0.961426f, 0.964844f, 0.967773f, 0.970703f, 0.973145f, 0.975098f,
+ 0.977539f, 0.979004f, 0.980957f, 0.982422f, 0.983887f, 0.985352f, 0.986328f, 0.987793f, 0.988770f, 0.989258f, 0.990723f, 0.991211f,
+ 0.992188f, 0.993164f, 0.993652f, 0.994141f, 0.994629f, 0.995117f, 0.998047f, 0.998535f, 0.998535f, 0.998535f, 0.998047f, 0.998047f,
+ 0.001360f, 0.004257f, 0.007988f, 0.013092f, 0.018753f, 0.026352f, 0.035645f, 0.048096f, 0.064270f, 0.085449f, 0.113770f, 0.149292f,
+ 0.195190f, 0.251953f, 0.320557f, 0.395020f, 0.474121f, 0.549316f, 0.618652f, 0.678223f, 0.729492f, 0.770996f, 0.805176f, 0.833496f,
+ 0.855957f, 0.875977f, 0.891113f, 0.904785f, 0.915039f, 0.924316f, 0.933105f, 0.939453f, 0.945312f, 0.950684f, 0.955078f, 0.959473f,
+ 0.962891f, 0.966309f, 0.969727f, 0.972168f, 0.974121f, 0.976562f, 0.978516f, 0.979980f, 0.981934f, 0.983398f, 0.984375f, 0.986328f,
+ 0.986816f, 0.988281f, 0.989746f, 0.990234f, 0.991699f, 0.992188f, 0.992676f, 0.994141f, 0.994141f, 0.994629f, 0.998047f, 0.998047f,
+ 0.998535f, 0.998047f, 0.998047f, 0.998047f, 0.001075f, 0.003492f, 0.006275f, 0.010223f, 0.014473f, 0.019821f, 0.026581f, 0.035492f,
+ 0.046967f, 0.061829f, 0.080750f, 0.105164f, 0.136475f, 0.177246f, 0.227783f, 0.288818f, 0.358154f, 0.433594f, 0.509277f, 0.581543f,
+ 0.645508f, 0.701172f, 0.747070f, 0.783691f, 0.817383f, 0.842773f, 0.864258f, 0.881836f, 0.896484f, 0.908691f, 0.918945f, 0.928223f,
+ 0.935547f, 0.941895f, 0.948730f, 0.952637f, 0.957031f, 0.962402f, 0.964844f, 0.967773f, 0.970703f, 0.973633f, 0.975586f, 0.977539f,
+ 0.979492f, 0.981445f, 0.982910f, 0.984375f, 0.985840f, 0.986816f, 0.988281f, 0.988770f, 0.990234f, 0.991211f, 0.992188f, 0.992676f,
+ 0.993164f, 0.994141f, 0.997559f, 0.997559f, 0.998047f, 0.997559f, 0.997559f, 0.998047f, 0.000967f, 0.002928f, 0.005283f, 0.007759f,
+ 0.011612f, 0.015823f, 0.020966f, 0.027802f, 0.035461f, 0.045959f, 0.059235f, 0.075928f, 0.097778f, 0.126099f, 0.162598f, 0.207153f,
+ 0.261963f, 0.326416f, 0.398193f, 0.471680f, 0.543945f, 0.612305f, 0.671875f, 0.722656f, 0.765137f, 0.799805f, 0.828125f, 0.854004f,
+ 0.872070f, 0.888184f, 0.902344f, 0.914062f, 0.923340f, 0.931641f, 0.938965f, 0.945312f, 0.950684f, 0.955566f, 0.958984f, 0.962891f,
+ 0.966309f, 0.969727f, 0.972168f, 0.974609f, 0.977051f, 0.978516f, 0.980469f, 0.982422f, 0.984375f, 0.985352f, 0.987305f, 0.987793f,
+ 0.988770f, 0.990234f, 0.991211f, 0.992188f, 0.992676f, 0.993164f, 0.997559f, 0.997559f, 0.997559f, 0.998047f, 0.997559f, 0.998047f,
+ 0.000602f, 0.002605f, 0.004345f, 0.006706f, 0.009590f, 0.012650f, 0.016617f, 0.021423f, 0.027893f, 0.035004f, 0.044495f, 0.056610f,
+ 0.072327f, 0.092285f, 0.116821f, 0.148926f, 0.189697f, 0.238892f, 0.298340f, 0.365723f, 0.437988f, 0.511230f, 0.579590f, 0.642090f,
+ 0.698242f, 0.744141f, 0.781738f, 0.814453f, 0.840332f, 0.861816f, 0.880371f, 0.895996f, 0.907715f, 0.918945f, 0.928223f, 0.935547f,
+ 0.942871f, 0.948730f, 0.953125f, 0.958008f, 0.961914f, 0.965332f, 0.968750f, 0.971680f, 0.973633f, 0.976562f, 0.978516f, 0.979980f,
+ 0.981934f, 0.983398f, 0.985352f, 0.986816f, 0.988281f, 0.988770f, 0.989746f, 0.990723f, 0.991699f, 0.992676f, 0.997070f, 0.997559f,
+ 0.997559f, 0.997070f, 0.997070f, 0.997070f, 0.000607f, 0.001955f, 0.003616f, 0.005772f, 0.007656f, 0.010269f, 0.013496f, 0.017273f,
+ 0.022018f, 0.027466f, 0.034729f, 0.043488f, 0.054932f, 0.068359f, 0.086365f, 0.108765f, 0.137939f, 0.174316f, 0.219360f, 0.273926f,
+ 0.336670f, 0.406494f, 0.478516f, 0.549316f, 0.614746f, 0.673340f, 0.722656f, 0.765137f, 0.800293f, 0.828125f, 0.853516f, 0.872070f,
+ 0.888672f, 0.902832f, 0.914551f, 0.924316f, 0.932129f, 0.940430f, 0.946289f, 0.951660f, 0.956055f, 0.960449f, 0.964355f, 0.967773f,
+ 0.970703f, 0.972656f, 0.975586f, 0.978027f, 0.980469f, 0.981934f, 0.983398f, 0.985352f, 0.986328f, 0.988281f, 0.988770f, 0.990234f,
+ 0.990723f, 0.992188f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.000600f, 0.001813f, 0.003101f, 0.004559f,
+ 0.006580f, 0.008873f, 0.011047f, 0.014091f, 0.017639f, 0.022049f, 0.027557f, 0.033997f, 0.042297f, 0.052704f, 0.065369f, 0.081238f,
+ 0.101929f, 0.127930f, 0.161255f, 0.202515f, 0.252686f, 0.311523f, 0.378174f, 0.449707f, 0.519531f, 0.587891f, 0.647949f, 0.701660f,
+ 0.746582f, 0.784668f, 0.817383f, 0.843262f, 0.864746f, 0.882324f, 0.896973f, 0.910156f, 0.920898f, 0.929688f, 0.937012f, 0.943848f,
+ 0.949707f, 0.955078f, 0.959473f, 0.963379f, 0.966797f, 0.970215f, 0.973145f, 0.975098f, 0.978027f, 0.980469f, 0.982422f, 0.983887f,
+ 0.984863f, 0.986328f, 0.987793f, 0.988770f, 0.989746f, 0.991211f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.997070f,
+ 0.000604f, 0.001429f, 0.002676f, 0.003708f, 0.005745f, 0.006973f, 0.009270f, 0.011452f, 0.014503f, 0.018295f, 0.022369f, 0.027222f,
+ 0.033417f, 0.040833f, 0.050171f, 0.062744f, 0.077454f, 0.095886f, 0.119995f, 0.150391f, 0.187622f, 0.234253f, 0.289307f, 0.353027f,
+ 0.421631f, 0.492676f, 0.561523f, 0.625488f, 0.681152f, 0.730469f, 0.770996f, 0.806152f, 0.833984f, 0.857422f, 0.876465f, 0.893066f,
+ 0.906250f, 0.916992f, 0.926758f, 0.935059f, 0.942871f, 0.948242f, 0.954102f, 0.958496f, 0.962891f, 0.966309f, 0.969727f, 0.972168f,
+ 0.975098f, 0.977539f, 0.979492f, 0.981934f, 0.983398f, 0.984863f, 0.986328f, 0.987793f, 0.989258f, 0.990234f, 0.996094f, 0.996582f,
+ 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.000365f, 0.001367f, 0.002123f, 0.003353f, 0.004692f, 0.006054f, 0.007675f, 0.009819f,
+ 0.012314f, 0.014862f, 0.018066f, 0.022064f, 0.026901f, 0.032471f, 0.039764f, 0.048584f, 0.060089f, 0.073730f, 0.090698f, 0.112854f,
+ 0.140381f, 0.175415f, 0.218018f, 0.269775f, 0.329834f, 0.396240f, 0.467285f, 0.537598f, 0.603516f, 0.662109f, 0.712891f, 0.757324f,
+ 0.793945f, 0.823730f, 0.849121f, 0.869629f, 0.887695f, 0.902344f, 0.914062f, 0.924805f, 0.932129f, 0.940430f, 0.947266f, 0.952148f,
+ 0.957031f, 0.962402f, 0.966309f, 0.969238f, 0.972656f, 0.975586f, 0.977051f, 0.979492f, 0.981934f, 0.983398f, 0.984863f, 0.986328f,
+ 0.988281f, 0.988770f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.000356f, 0.001341f, 0.001913f, 0.002897f,
+ 0.003983f, 0.005322f, 0.006607f, 0.008514f, 0.010399f, 0.012451f, 0.015282f, 0.018356f, 0.021912f, 0.026443f, 0.031982f, 0.038635f,
+ 0.047150f, 0.057495f, 0.070007f, 0.086609f, 0.106689f, 0.131714f, 0.164429f, 0.203613f, 0.252441f, 0.310059f, 0.374512f, 0.444092f,
+ 0.514160f, 0.582031f, 0.643066f, 0.697266f, 0.743652f, 0.783691f, 0.814941f, 0.842773f, 0.865234f, 0.882812f, 0.897949f, 0.910645f,
+ 0.922363f, 0.931152f, 0.938965f, 0.945801f, 0.952148f, 0.957520f, 0.961426f, 0.965820f, 0.969727f, 0.972168f, 0.975098f, 0.977539f,
+ 0.979980f, 0.981934f, 0.983887f, 0.985352f, 0.986816f, 0.988281f, 0.995117f, 0.995605f, 0.996094f, 0.996094f, 0.996094f, 0.996094f,
+ 0.000243f, 0.000937f, 0.001662f, 0.002617f, 0.003527f, 0.004555f, 0.005642f, 0.007217f, 0.008820f, 0.010483f, 0.012383f, 0.015175f,
+ 0.018341f, 0.022049f, 0.026245f, 0.031067f, 0.037903f, 0.045563f, 0.054962f, 0.066956f, 0.082092f, 0.101074f, 0.124939f, 0.154663f,
+ 0.191528f, 0.237305f, 0.291992f, 0.354492f, 0.422852f, 0.492676f, 0.562012f, 0.625488f, 0.682617f, 0.731934f, 0.772949f, 0.807129f,
+ 0.835449f, 0.859863f, 0.878906f, 0.895020f, 0.908203f, 0.920898f, 0.929199f, 0.937988f, 0.945312f, 0.951660f, 0.957031f, 0.961914f,
+ 0.965332f, 0.968750f, 0.972656f, 0.975098f, 0.977539f, 0.979980f, 0.982422f, 0.983887f, 0.986328f, 0.987793f, 0.995117f, 0.995605f,
+ 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.000362f, 0.000970f, 0.001489f, 0.002251f, 0.002892f, 0.003727f, 0.004978f, 0.006264f,
+ 0.007530f, 0.009125f, 0.010551f, 0.012756f, 0.015259f, 0.018097f, 0.021637f, 0.025986f, 0.030594f, 0.036804f, 0.044006f, 0.053162f,
+ 0.064148f, 0.078003f, 0.096130f, 0.118042f, 0.146118f, 0.181030f, 0.224487f, 0.276123f, 0.336670f, 0.403320f, 0.473633f, 0.543457f,
+ 0.609375f, 0.667480f, 0.719238f, 0.763184f, 0.799316f, 0.829590f, 0.854492f, 0.875488f, 0.892578f, 0.906738f, 0.918945f, 0.928711f,
+ 0.937012f, 0.944336f, 0.951172f, 0.956543f, 0.961426f, 0.965820f, 0.968750f, 0.972656f, 0.975098f, 0.978027f, 0.980469f, 0.982910f,
+ 0.984375f, 0.985840f, 0.994629f, 0.995117f, 0.995117f, 0.995117f, 0.995117f, 0.995117f, 0.000346f, 0.000923f, 0.001273f, 0.002010f,
+ 0.002619f, 0.003689f, 0.004452f, 0.005177f, 0.006290f, 0.007561f, 0.009033f, 0.010902f, 0.012970f, 0.015495f, 0.018280f, 0.021576f,
+ 0.024948f, 0.030304f, 0.035400f, 0.042480f, 0.051086f, 0.061401f, 0.074890f, 0.091187f, 0.112427f, 0.138794f, 0.171631f, 0.212158f,
+ 0.262451f, 0.320557f, 0.385986f, 0.456055f, 0.525391f, 0.593262f, 0.654297f, 0.708984f, 0.754883f, 0.792969f, 0.824707f, 0.850098f,
+ 0.872070f, 0.890137f, 0.904785f, 0.917480f, 0.927734f, 0.937012f, 0.944336f, 0.951172f, 0.956055f, 0.961914f, 0.966309f, 0.969727f,
+ 0.973145f, 0.976074f, 0.978516f, 0.980469f, 0.982910f, 0.984863f, 0.993652f, 0.995117f, 0.994629f, 0.994629f, 0.994629f, 0.994629f,
+ 0.000242f, 0.000666f, 0.001081f, 0.001806f, 0.002512f, 0.003397f, 0.003866f, 0.004894f, 0.005566f, 0.006859f, 0.007957f, 0.009506f,
+ 0.011009f, 0.013046f, 0.015266f, 0.018173f, 0.021027f, 0.024811f, 0.029526f, 0.034790f, 0.041443f, 0.049835f, 0.059265f, 0.071899f,
+ 0.087769f, 0.107422f, 0.132202f, 0.163208f, 0.201782f, 0.249512f, 0.305908f, 0.370361f, 0.440430f, 0.511230f, 0.578613f, 0.642090f,
+ 0.698730f, 0.746582f, 0.787109f, 0.819824f, 0.848145f, 0.869141f, 0.888672f, 0.903809f, 0.916992f, 0.927246f, 0.936523f, 0.943848f,
+ 0.951660f, 0.957031f, 0.961426f, 0.965820f, 0.970215f, 0.973145f, 0.976074f, 0.979004f, 0.981445f, 0.983398f, 0.994141f, 0.994141f,
+ 0.994629f, 0.994141f, 0.994629f, 0.994141f, 0.000242f, 0.000709f, 0.000917f, 0.001194f, 0.002018f, 0.002634f, 0.003504f, 0.003918f,
+ 0.005020f, 0.005726f, 0.006935f, 0.008141f, 0.009666f, 0.011040f, 0.012848f, 0.014961f, 0.017624f, 0.020660f, 0.024368f, 0.028381f,
+ 0.033905f, 0.040283f, 0.047760f, 0.057312f, 0.069214f, 0.083984f, 0.102539f, 0.126221f, 0.155640f, 0.193359f, 0.238892f, 0.293701f,
+ 0.356689f, 0.425537f, 0.497070f, 0.568359f, 0.632812f, 0.690918f, 0.739746f, 0.782227f, 0.816406f, 0.845703f, 0.868652f, 0.887695f,
+ 0.903320f, 0.916992f, 0.927734f, 0.937012f, 0.944824f, 0.951660f, 0.957031f, 0.962891f, 0.966797f, 0.971191f, 0.973633f, 0.976562f,
+ 0.979492f, 0.981934f, 0.992676f, 0.993652f, 0.994141f, 0.993652f, 0.993652f, 0.994141f, 0.000244f, 0.000660f, 0.000918f, 0.001343f,
+ 0.002117f, 0.002407f, 0.002779f, 0.003626f, 0.004246f, 0.005207f, 0.005913f, 0.007145f, 0.008163f, 0.009438f, 0.011101f, 0.012871f,
+ 0.014999f, 0.017426f, 0.020096f, 0.024185f, 0.027725f, 0.032623f, 0.038910f, 0.046387f, 0.055298f, 0.066467f, 0.080627f, 0.098328f,
+ 0.120972f, 0.149658f, 0.184814f, 0.229492f, 0.282715f, 0.344727f, 0.414062f, 0.486084f, 0.556641f, 0.624023f, 0.683594f, 0.735352f,
+ 0.778320f, 0.814453f, 0.843750f, 0.867188f, 0.887207f, 0.903320f, 0.916504f, 0.928223f, 0.937500f, 0.945312f, 0.953125f, 0.958008f,
+ 0.964355f, 0.967285f, 0.971680f, 0.975098f, 0.978516f, 0.980957f, 0.992676f, 0.993652f, 0.994141f, 0.993652f, 0.993652f, 0.993164f,
+ 0.000200f, 0.000480f, 0.000808f, 0.001303f, 0.001680f, 0.002104f, 0.002510f, 0.002934f, 0.003468f, 0.004429f, 0.005539f, 0.006046f,
+ 0.006889f, 0.008438f, 0.009415f, 0.011108f, 0.012787f, 0.014572f, 0.017517f, 0.020279f, 0.023483f, 0.027359f, 0.031860f, 0.037964f,
+ 0.045227f, 0.053711f, 0.064148f, 0.077759f, 0.095093f, 0.116272f, 0.143311f, 0.177856f, 0.221191f, 0.273193f, 0.334473f, 0.403320f,
+ 0.476318f, 0.548828f, 0.617188f, 0.677734f, 0.730957f, 0.775879f, 0.812500f, 0.842285f, 0.866699f, 0.887695f, 0.903809f, 0.916992f,
+ 0.928711f, 0.938477f, 0.946777f, 0.953125f, 0.959473f, 0.963867f, 0.968750f, 0.972656f, 0.976074f, 0.979004f, 0.992188f, 0.992676f,
+ 0.993164f, 0.993164f, 0.992676f, 0.993164f, 0.000243f, 0.000469f, 0.000878f, 0.001158f, 0.001382f, 0.001801f, 0.002220f, 0.002699f,
+ 0.003273f, 0.004063f, 0.004715f, 0.005447f, 0.005917f, 0.007099f, 0.008385f, 0.009521f, 0.011032f, 0.012627f, 0.014870f, 0.016922f,
+ 0.019836f, 0.023010f, 0.026642f, 0.031174f, 0.036926f, 0.043549f, 0.051941f, 0.062561f, 0.075317f, 0.091553f, 0.112427f, 0.138428f,
+ 0.172485f, 0.213867f, 0.265381f, 0.326172f, 0.394775f, 0.467773f, 0.541504f, 0.610840f, 0.673340f, 0.728516f, 0.774414f, 0.812012f,
+ 0.842773f, 0.867676f, 0.887695f, 0.904297f, 0.918457f, 0.929688f, 0.939453f, 0.948242f, 0.955078f, 0.959961f, 0.965820f, 0.970215f,
+ 0.974121f, 0.977051f, 0.991211f, 0.993164f, 0.993164f, 0.992188f, 0.993164f, 0.992188f, 0.000000f, 0.000242f, 0.000799f, 0.000998f,
+ 0.001273f, 0.001671f, 0.002069f, 0.002485f, 0.003212f, 0.003578f, 0.003948f, 0.004559f, 0.005524f, 0.006321f, 0.007046f, 0.008438f,
+ 0.009438f, 0.010986f, 0.012390f, 0.014320f, 0.016663f, 0.019165f, 0.022476f, 0.025833f, 0.030487f, 0.035675f, 0.042358f, 0.050018f,
+ 0.060211f, 0.072693f, 0.088379f, 0.108948f, 0.134766f, 0.166626f, 0.208008f, 0.258545f, 0.318848f, 0.387451f, 0.461670f, 0.536621f,
+ 0.606934f, 0.671387f, 0.727539f, 0.773438f, 0.811523f, 0.843750f, 0.868164f, 0.889160f, 0.906250f, 0.920410f, 0.932617f, 0.941895f,
+ 0.949707f, 0.956055f, 0.962402f, 0.967285f, 0.971680f, 0.975586f, 0.990723f, 0.991699f, 0.991699f, 0.992188f, 0.992188f, 0.991699f,
+ 0.000237f, 0.000482f, 0.000772f, 0.000877f, 0.001109f, 0.001494f, 0.001991f, 0.002041f, 0.002537f, 0.002975f, 0.003469f, 0.004128f,
+ 0.004841f, 0.005550f, 0.006306f, 0.007359f, 0.008369f, 0.009415f, 0.010788f, 0.012306f, 0.014160f, 0.016571f, 0.018921f, 0.021896f,
+ 0.025497f, 0.029587f, 0.034576f, 0.041260f, 0.049011f, 0.058319f, 0.070557f, 0.086060f, 0.105774f, 0.130737f, 0.162720f, 0.203247f,
+ 0.252930f, 0.313477f, 0.382568f, 0.457275f, 0.532715f, 0.605469f, 0.671387f, 0.728027f, 0.774902f, 0.814453f, 0.844727f, 0.870605f,
+ 0.891113f, 0.909180f, 0.922852f, 0.934082f, 0.943359f, 0.951660f, 0.958008f, 0.964355f, 0.968750f, 0.973145f, 0.990234f, 0.990723f,
+ 0.991699f, 0.991211f, 0.991211f, 0.991211f, 0.000235f, 0.000461f, 0.000484f, 0.000891f, 0.001105f, 0.001346f, 0.001634f, 0.001936f,
+ 0.002438f, 0.002874f, 0.003353f, 0.003925f, 0.004189f, 0.004887f, 0.005684f, 0.006279f, 0.007298f, 0.008339f, 0.009384f, 0.010674f,
+ 0.012360f, 0.013901f, 0.016113f, 0.018677f, 0.021469f, 0.024841f, 0.029144f, 0.033783f, 0.039948f, 0.047272f, 0.056915f, 0.068726f,
+ 0.083801f, 0.102905f, 0.127563f, 0.159058f, 0.199341f, 0.248901f, 0.309570f, 0.379395f, 0.454834f, 0.532715f, 0.606934f, 0.672852f,
+ 0.729980f, 0.778320f, 0.817383f, 0.849121f, 0.874512f, 0.895020f, 0.911621f, 0.924805f, 0.937012f, 0.946289f, 0.954102f, 0.960938f,
+ 0.965820f, 0.971191f, 0.989258f, 0.990234f, 0.990723f, 0.991211f, 0.990723f, 0.990723f, 0.000000f, 0.000360f, 0.000477f, 0.000756f,
+ 0.000896f, 0.001065f, 0.001570f, 0.001622f, 0.002064f, 0.002525f, 0.002819f, 0.003004f, 0.003700f, 0.004356f, 0.005077f, 0.005428f,
+ 0.006283f, 0.007370f, 0.008339f, 0.009323f, 0.010567f, 0.012070f, 0.013672f, 0.015839f, 0.018066f, 0.020844f, 0.024002f, 0.028183f,
+ 0.033051f, 0.039246f, 0.046417f, 0.055450f, 0.067200f, 0.082031f, 0.100586f, 0.125122f, 0.156250f, 0.196167f, 0.245972f, 0.307129f,
+ 0.378174f, 0.454834f, 0.533203f, 0.608398f, 0.675781f, 0.734375f, 0.782715f, 0.821777f, 0.853516f, 0.878906f, 0.898926f, 0.915039f,
+ 0.929199f, 0.939941f, 0.948730f, 0.956055f, 0.963379f, 0.968262f, 0.988770f, 0.989746f, 0.990234f, 0.989746f, 0.989746f, 0.990234f,
+ 0.000000f, 0.000256f, 0.000467f, 0.000590f, 0.000772f, 0.001095f, 0.001356f, 0.001781f, 0.001984f, 0.002161f, 0.002546f, 0.002956f,
+ 0.003338f, 0.003899f, 0.004440f, 0.004986f, 0.005486f, 0.006310f, 0.006969f, 0.008148f, 0.009148f, 0.010284f, 0.011902f, 0.013573f,
+ 0.015465f, 0.017853f, 0.020340f, 0.023590f, 0.027298f, 0.032227f, 0.038208f, 0.045563f, 0.054047f, 0.065796f, 0.080322f, 0.098999f,
+ 0.122864f, 0.153809f, 0.193970f, 0.244629f, 0.306396f, 0.378662f, 0.457031f, 0.536621f, 0.613770f, 0.681641f, 0.740723f, 0.788574f,
+ 0.827637f, 0.858398f, 0.884277f, 0.903320f, 0.919922f, 0.932129f, 0.942871f, 0.951660f, 0.959961f, 0.965820f, 0.987305f, 0.988281f,
+ 0.989258f, 0.989258f, 0.989258f, 0.989258f, 0.000244f, 0.000243f, 0.000583f, 0.000585f, 0.000822f, 0.001073f, 0.001159f, 0.001452f,
+ 0.001525f, 0.002001f, 0.002201f, 0.002714f, 0.002932f, 0.003525f, 0.003904f, 0.004482f, 0.004997f, 0.005581f, 0.006233f, 0.006954f,
+ 0.007820f, 0.008949f, 0.009941f, 0.011482f, 0.013168f, 0.015099f, 0.017151f, 0.020111f, 0.022949f, 0.026947f, 0.031647f, 0.037354f,
+ 0.044342f, 0.053375f, 0.064331f, 0.078857f, 0.097351f, 0.121033f, 0.152588f, 0.192749f, 0.244263f, 0.307129f, 0.380615f, 0.461426f,
+ 0.543457f, 0.621582f, 0.690430f, 0.748047f, 0.796387f, 0.834961f, 0.865723f, 0.889160f, 0.908691f, 0.924316f, 0.937500f, 0.946777f,
+ 0.955078f, 0.962891f, 0.986328f, 0.987793f, 0.988770f, 0.988770f, 0.988770f, 0.988770f, 0.000000f, 0.000243f, 0.000308f, 0.000541f,
+ 0.000801f, 0.000827f, 0.001057f, 0.001280f, 0.001460f, 0.001781f, 0.002090f, 0.002481f, 0.002756f, 0.003054f, 0.003321f, 0.003948f,
+ 0.004303f, 0.004898f, 0.005306f, 0.006405f, 0.006954f, 0.007851f, 0.008537f, 0.009918f, 0.011208f, 0.012825f, 0.014534f, 0.016861f,
+ 0.019379f, 0.022629f, 0.026276f, 0.030838f, 0.036407f, 0.043488f, 0.051819f, 0.063416f, 0.077209f, 0.095825f, 0.119812f, 0.151489f,
+ 0.192749f, 0.245361f, 0.309814f, 0.385986f, 0.469238f, 0.552246f, 0.630859f, 0.699707f, 0.757324f, 0.805176f, 0.842773f, 0.873047f,
+ 0.895508f, 0.914062f, 0.929688f, 0.941406f, 0.952148f, 0.959473f, 0.985840f, 0.986816f, 0.987305f, 0.987305f, 0.987305f, 0.987305f,
+ 0.000000f, 0.000243f, 0.000242f, 0.000548f, 0.000695f, 0.000803f, 0.001053f, 0.001198f, 0.001363f, 0.001513f, 0.001886f, 0.002069f,
+ 0.002447f, 0.002676f, 0.003138f, 0.003551f, 0.003868f, 0.004261f, 0.004936f, 0.005337f, 0.005852f, 0.006615f, 0.007519f, 0.008575f,
+ 0.009705f, 0.010872f, 0.012688f, 0.014397f, 0.016479f, 0.019119f, 0.022064f, 0.025589f, 0.030304f, 0.035828f, 0.042603f, 0.050812f,
+ 0.062012f, 0.076355f, 0.094971f, 0.119263f, 0.151367f, 0.193726f, 0.247925f, 0.314941f, 0.393311f, 0.478271f, 0.563965f, 0.642578f,
+ 0.711914f, 0.769043f, 0.815430f, 0.851562f, 0.881348f, 0.902832f, 0.921387f, 0.934570f, 0.945801f, 0.955078f, 0.984375f, 0.986328f,
+ 0.986328f, 0.986328f, 0.986328f, 0.986328f, 0.000000f, 0.000234f, 0.000239f, 0.000308f, 0.000597f, 0.000690f, 0.000868f, 0.000937f,
+ 0.001189f, 0.001404f, 0.001696f, 0.001854f, 0.002180f, 0.002249f, 0.002672f, 0.002979f, 0.003494f, 0.003761f, 0.004257f, 0.004745f,
+ 0.005154f, 0.005821f, 0.006561f, 0.007557f, 0.008575f, 0.009575f, 0.010963f, 0.012238f, 0.014130f, 0.016113f, 0.018539f, 0.021545f,
+ 0.025162f, 0.029404f, 0.034851f, 0.041626f, 0.050354f, 0.061218f, 0.075562f, 0.094482f, 0.119507f, 0.152344f, 0.196167f, 0.252197f,
+ 0.322266f, 0.404053f, 0.490967f, 0.577637f, 0.658203f, 0.726074f, 0.782715f, 0.827637f, 0.861816f, 0.889648f, 0.910645f, 0.926758f,
+ 0.940918f, 0.950684f, 0.983398f, 0.985352f, 0.984863f, 0.985352f, 0.985840f, 0.985352f, 0.000000f, 0.000240f, 0.000237f, 0.000239f,
+ 0.000436f, 0.000648f, 0.000661f, 0.000892f, 0.001089f, 0.001484f, 0.001446f, 0.001586f, 0.001896f, 0.002176f, 0.002325f, 0.002634f,
+ 0.003057f, 0.003315f, 0.003561f, 0.004150f, 0.004578f, 0.005180f, 0.005768f, 0.006485f, 0.007286f, 0.008400f, 0.009453f, 0.010429f,
+ 0.011795f, 0.013680f, 0.015671f, 0.018005f, 0.020981f, 0.024521f, 0.028748f, 0.034119f, 0.040863f, 0.049622f, 0.060303f, 0.074829f,
+ 0.094116f, 0.119995f, 0.154297f, 0.199341f, 0.258301f, 0.331787f, 0.416504f, 0.507812f, 0.595703f, 0.675781f, 0.743164f, 0.797852f,
+ 0.840820f, 0.873535f, 0.899414f, 0.919434f, 0.934082f, 0.947266f, 0.982422f, 0.983887f, 0.983887f, 0.984375f, 0.984375f, 0.983887f,
+ 0.000136f, 0.000115f, 0.000237f, 0.000238f, 0.000358f, 0.000452f, 0.000759f, 0.000961f, 0.001026f, 0.001113f, 0.001433f, 0.001564f,
+ 0.001659f, 0.001955f, 0.002024f, 0.002384f, 0.002647f, 0.002974f, 0.003267f, 0.003611f, 0.003971f, 0.004498f, 0.005043f, 0.005539f,
+ 0.006344f, 0.007168f, 0.007942f, 0.009010f, 0.010353f, 0.011711f, 0.013458f, 0.015213f, 0.017548f, 0.020279f, 0.023926f, 0.028061f,
+ 0.033356f, 0.040283f, 0.048615f, 0.060455f, 0.074890f, 0.094727f, 0.121216f, 0.156860f, 0.204102f, 0.266846f, 0.344238f, 0.433105f,
+ 0.526855f, 0.616699f, 0.696289f, 0.761230f, 0.813965f, 0.854492f, 0.884766f, 0.909180f, 0.927734f, 0.941895f, 0.980957f, 0.982422f,
+ 0.982910f, 0.982422f, 0.982422f, 0.982910f, 0.000000f, 0.000103f, 0.000208f, 0.000356f, 0.000355f, 0.000400f, 0.000454f, 0.000861f,
+ 0.000922f, 0.001202f, 0.001088f, 0.001401f, 0.001493f, 0.001779f, 0.001881f, 0.002180f, 0.002329f, 0.002483f, 0.002846f, 0.003178f,
+ 0.003542f, 0.003914f, 0.004406f, 0.004871f, 0.005352f, 0.006119f, 0.006927f, 0.007904f, 0.008759f, 0.009972f, 0.011284f, 0.013046f,
+ 0.014938f, 0.016998f, 0.019943f, 0.023224f, 0.027161f, 0.032776f, 0.039917f, 0.048218f, 0.059937f, 0.075134f, 0.095642f, 0.123169f,
+ 0.160767f, 0.211670f, 0.278320f, 0.360352f, 0.454102f, 0.550293f, 0.640625f, 0.718262f, 0.781738f, 0.831055f, 0.869141f, 0.897461f,
+ 0.919434f, 0.936035f, 0.979492f, 0.980957f, 0.980957f, 0.981934f, 0.981445f, 0.981445f, 0.000000f, 0.000192f, 0.000191f, 0.000350f,
+ 0.000352f, 0.000354f, 0.000599f, 0.000721f, 0.000835f, 0.001044f, 0.000988f, 0.001141f, 0.001255f, 0.001479f, 0.001705f, 0.001815f,
+ 0.001843f, 0.002151f, 0.002369f, 0.002831f, 0.003067f, 0.003431f, 0.003698f, 0.004295f, 0.004738f, 0.005352f, 0.005859f, 0.006615f,
+ 0.007587f, 0.008583f, 0.009682f, 0.010735f, 0.012405f, 0.014381f, 0.016708f, 0.018921f, 0.022736f, 0.026947f, 0.032104f, 0.039032f,
+ 0.048004f, 0.059784f, 0.075500f, 0.096924f, 0.125977f, 0.166626f, 0.221069f, 0.292969f, 0.380371f, 0.479004f, 0.577637f, 0.667969f,
+ 0.743164f, 0.803711f, 0.849609f, 0.883789f, 0.910645f, 0.930176f, 0.977539f, 0.979492f, 0.979492f, 0.979492f, 0.979980f, 0.979492f,
+ 0.000000f, 0.000000f, 0.000191f, 0.000214f, 0.000441f, 0.000465f, 0.000351f, 0.000656f, 0.000672f, 0.000957f, 0.000881f, 0.001092f,
+ 0.001209f, 0.001259f, 0.001315f, 0.001583f, 0.001630f, 0.001834f, 0.002033f, 0.002367f, 0.002596f, 0.002924f, 0.003387f, 0.003693f,
+ 0.004063f, 0.004601f, 0.004986f, 0.005676f, 0.006557f, 0.006973f, 0.007801f, 0.008781f, 0.010475f, 0.012100f, 0.013817f, 0.015625f,
+ 0.018784f, 0.021927f, 0.026260f, 0.031677f, 0.038879f, 0.048004f, 0.059845f, 0.076233f, 0.098633f, 0.130005f, 0.173950f, 0.233032f,
+ 0.311035f, 0.405518f, 0.507812f, 0.608887f, 0.698242f, 0.769531f, 0.826172f, 0.868164f, 0.899414f, 0.922852f, 0.976074f, 0.977539f,
+ 0.977539f, 0.977051f, 0.978027f, 0.978027f, 0.000000f, 0.000000f, 0.000117f, 0.000211f, 0.000326f, 0.000573f, 0.000574f, 0.000583f,
+ 0.000584f, 0.000659f, 0.000901f, 0.001014f, 0.001064f, 0.001033f, 0.001163f, 0.001234f, 0.001546f, 0.001585f, 0.001894f, 0.002085f,
+ 0.002361f, 0.002504f, 0.003023f, 0.003147f, 0.003580f, 0.004032f, 0.004314f, 0.004936f, 0.005215f, 0.006081f, 0.006725f, 0.007927f,
+ 0.008743f, 0.009918f, 0.011642f, 0.013367f, 0.015404f, 0.018219f, 0.021545f, 0.025787f, 0.031174f, 0.038361f, 0.047577f, 0.060425f,
+ 0.077881f, 0.102051f, 0.135376f, 0.182861f, 0.249023f, 0.333984f, 0.436035f, 0.542969f, 0.644043f, 0.730469f, 0.798340f, 0.848633f,
+ 0.886719f, 0.914062f, 0.973633f, 0.974609f, 0.975098f, 0.976074f, 0.975098f, 0.976074f, 0.000000f, 0.000000f, 0.000114f, 0.000112f,
+ 0.000271f, 0.000510f, 0.000450f, 0.000565f, 0.000572f, 0.000581f, 0.000654f, 0.000825f, 0.000954f, 0.001085f, 0.001050f, 0.001087f,
+ 0.001282f, 0.001547f, 0.001585f, 0.001825f, 0.002066f, 0.002182f, 0.002384f, 0.002659f, 0.003172f, 0.003357f, 0.003721f, 0.004238f,
+ 0.004505f, 0.005024f, 0.005878f, 0.006512f, 0.007324f, 0.008293f, 0.009201f, 0.011040f, 0.012993f, 0.015007f, 0.017639f, 0.020920f,
+ 0.025131f, 0.030899f, 0.038269f, 0.047760f, 0.061188f, 0.079651f, 0.105469f, 0.142944f, 0.195801f, 0.268799f, 0.363525f, 0.472168f,
+ 0.582520f, 0.683594f, 0.765137f, 0.826660f, 0.872070f, 0.905273f, 0.972168f, 0.973633f, 0.973145f, 0.973633f, 0.973633f, 0.973633f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000111f, 0.000224f, 0.000412f, 0.000494f, 0.000543f, 0.000561f, 0.000680f, 0.000665f, 0.000675f,
+ 0.000679f, 0.000797f, 0.000926f, 0.001122f, 0.001132f, 0.001207f, 0.001375f, 0.001606f, 0.001838f, 0.001963f, 0.002163f, 0.002314f,
+ 0.002480f, 0.002956f, 0.003189f, 0.003489f, 0.003744f, 0.004311f, 0.004749f, 0.005276f, 0.005867f, 0.006962f, 0.008186f, 0.008987f,
+ 0.010498f, 0.012283f, 0.014374f, 0.017075f, 0.020355f, 0.024719f, 0.030640f, 0.037720f, 0.048309f, 0.062134f, 0.082336f, 0.110840f,
+ 0.151978f, 0.212891f, 0.294922f, 0.399170f, 0.515137f, 0.628418f, 0.724609f, 0.799805f, 0.854980f, 0.894043f, 0.968750f, 0.970215f,
+ 0.970703f, 0.971191f, 0.970703f, 0.970703f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000228f, 0.000233f, 0.000436f, 0.000457f,
+ 0.000621f, 0.000546f, 0.000622f, 0.000633f, 0.000576f, 0.000644f, 0.000717f, 0.000909f, 0.000994f, 0.001127f, 0.001179f, 0.001267f,
+ 0.001513f, 0.001628f, 0.001742f, 0.001974f, 0.002111f, 0.002403f, 0.002810f, 0.003139f, 0.003231f, 0.003466f, 0.004021f, 0.004459f,
+ 0.004971f, 0.005581f, 0.006809f, 0.007568f, 0.008759f, 0.010002f, 0.011665f, 0.013847f, 0.016342f, 0.019714f, 0.024368f, 0.030106f,
+ 0.037811f, 0.048706f, 0.063843f, 0.085327f, 0.118042f, 0.164917f, 0.234131f, 0.328125f, 0.443359f, 0.565430f, 0.677246f, 0.767578f,
+ 0.833496f, 0.882812f, 0.965820f, 0.967285f, 0.967773f, 0.968262f, 0.967773f, 0.968262f, 0.000000f, 0.000000f, 0.000000f, 0.000214f,
+ 0.000210f, 0.000296f, 0.000309f, 0.000386f, 0.000462f, 0.000482f, 0.000525f, 0.000572f, 0.000525f, 0.000558f, 0.000689f, 0.000685f,
+ 0.000841f, 0.000934f, 0.001008f, 0.001182f, 0.001271f, 0.001412f, 0.001757f, 0.001787f, 0.001769f, 0.002110f, 0.002321f, 0.002331f,
+ 0.002737f, 0.002951f, 0.003189f, 0.003588f, 0.004253f, 0.004627f, 0.005505f, 0.006119f, 0.006969f, 0.008018f, 0.009583f, 0.010971f,
+ 0.013245f, 0.015915f, 0.019257f, 0.023651f, 0.030014f, 0.038086f, 0.049683f, 0.066406f, 0.091125f, 0.127441f, 0.182617f, 0.262939f,
+ 0.370605f, 0.497070f, 0.623047f, 0.729004f, 0.810547f, 0.867188f, 0.962891f, 0.963867f, 0.964844f, 0.964844f, 0.964355f, 0.964355f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000200f, 0.000215f, 0.000229f, 0.000319f, 0.000330f, 0.000411f, 0.000491f, 0.000527f,
+ 0.000547f, 0.000560f, 0.000634f, 0.000648f, 0.000716f, 0.000778f, 0.000855f, 0.000998f, 0.001182f, 0.001111f, 0.001274f, 0.001625f,
+ 0.001584f, 0.001559f, 0.001864f, 0.002037f, 0.002296f, 0.002438f, 0.002600f, 0.002993f, 0.003290f, 0.003801f, 0.004467f, 0.005085f,
+ 0.005508f, 0.006519f, 0.007645f, 0.008743f, 0.010757f, 0.012558f, 0.014946f, 0.018661f, 0.023422f, 0.029556f, 0.038574f, 0.050964f,
+ 0.069702f, 0.097351f, 0.140015f, 0.205566f, 0.301025f, 0.424561f, 0.559082f, 0.683594f, 0.781250f, 0.852051f, 0.958496f, 0.960449f,
+ 0.960938f, 0.960938f, 0.960938f, 0.960449f, 0.000000f, 0.000000f, 0.000122f, 0.000122f, 0.000122f, 0.000194f, 0.000214f, 0.000251f,
+ 0.000302f, 0.000365f, 0.000370f, 0.000429f, 0.000495f, 0.000521f, 0.000504f, 0.000547f, 0.000632f, 0.000656f, 0.000695f, 0.000795f,
+ 0.000922f, 0.001074f, 0.001125f, 0.001192f, 0.001166f, 0.001303f, 0.001555f, 0.001575f, 0.001763f, 0.001970f, 0.002232f, 0.002560f,
+ 0.002657f, 0.003082f, 0.003559f, 0.003799f, 0.004620f, 0.005241f, 0.006081f, 0.007103f, 0.008385f, 0.009796f, 0.012192f, 0.014702f,
+ 0.018234f, 0.022934f, 0.029556f, 0.039307f, 0.053009f, 0.073547f, 0.106628f, 0.157715f, 0.237793f, 0.351318f, 0.490479f, 0.629883f,
+ 0.746094f, 0.832031f, 0.954590f, 0.956055f, 0.956055f, 0.957031f, 0.956543f, 0.956055f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000121f, 0.000146f, 0.000191f, 0.000200f, 0.000255f, 0.000232f, 0.000252f, 0.000359f, 0.000291f, 0.000342f, 0.000406f, 0.000498f,
+ 0.000520f, 0.000533f, 0.000632f, 0.000605f, 0.000689f, 0.000768f, 0.000908f, 0.001013f, 0.001087f, 0.001030f, 0.001211f, 0.001318f,
+ 0.001497f, 0.001609f, 0.001753f, 0.001957f, 0.002234f, 0.002352f, 0.002663f, 0.003040f, 0.003635f, 0.004082f, 0.004723f, 0.005516f,
+ 0.006367f, 0.007675f, 0.009224f, 0.011360f, 0.013695f, 0.017868f, 0.022598f, 0.029724f, 0.040222f, 0.055542f, 0.080078f, 0.119202f,
+ 0.182617f, 0.281738f, 0.417725f, 0.568848f, 0.705566f, 0.807129f, 0.948730f, 0.951172f, 0.951172f, 0.951172f, 0.951660f, 0.951660f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000203f, 0.000186f, 0.000184f, 0.000321f,
+ 0.000231f, 0.000337f, 0.000359f, 0.000430f, 0.000455f, 0.000531f, 0.000502f, 0.000517f, 0.000728f, 0.000643f, 0.000673f, 0.000816f,
+ 0.000930f, 0.000991f, 0.001028f, 0.001161f, 0.001284f, 0.001369f, 0.001474f, 0.001719f, 0.001781f, 0.001883f, 0.002258f, 0.002518f,
+ 0.002831f, 0.003201f, 0.003744f, 0.004349f, 0.005127f, 0.006130f, 0.007210f, 0.008423f, 0.010696f, 0.013405f, 0.017136f, 0.022522f,
+ 0.030029f, 0.041321f, 0.059631f, 0.089050f, 0.138062f, 0.218994f, 0.343750f, 0.500488f, 0.657227f, 0.780762f, 0.943848f, 0.945312f,
+ 0.945312f, 0.945801f, 0.945801f, 0.946289f, 0.000000f, 0.000000f, 0.000122f, 0.000121f, 0.000121f, 0.000121f, 0.000121f, 0.000120f,
+ 0.000118f, 0.000137f, 0.000139f, 0.000241f, 0.000202f, 0.000304f, 0.000313f, 0.000332f, 0.000357f, 0.000420f, 0.000435f, 0.000463f,
+ 0.000645f, 0.000544f, 0.000700f, 0.000717f, 0.000669f, 0.000834f, 0.000865f, 0.000916f, 0.001109f, 0.001193f, 0.001246f, 0.001300f,
+ 0.001488f, 0.001538f, 0.001806f, 0.001929f, 0.002001f, 0.002462f, 0.002666f, 0.003260f, 0.003904f, 0.004364f, 0.005325f, 0.006306f,
+ 0.008041f, 0.009720f, 0.012718f, 0.016525f, 0.022217f, 0.030579f, 0.043854f, 0.065247f, 0.101929f, 0.166016f, 0.273193f, 0.428223f,
+ 0.600586f, 0.748047f, 0.936523f, 0.938477f, 0.938965f, 0.939453f, 0.938965f, 0.938965f, 0.000000f, 0.000122f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000114f, 0.000102f, 0.000090f, 0.000096f, 0.000131f, 0.000245f, 0.000276f, 0.000257f,
+ 0.000307f, 0.000316f, 0.000322f, 0.000373f, 0.000411f, 0.000440f, 0.000433f, 0.000650f, 0.000578f, 0.000704f, 0.000746f, 0.000723f,
+ 0.000819f, 0.000756f, 0.000758f, 0.000878f, 0.001009f, 0.001270f, 0.001399f, 0.001530f, 0.001798f, 0.001803f, 0.002151f, 0.002317f,
+ 0.002728f, 0.003222f, 0.003782f, 0.004612f, 0.005951f, 0.006985f, 0.009308f, 0.011955f, 0.016052f, 0.022324f, 0.031525f, 0.047272f,
+ 0.073853f, 0.122192f, 0.209717f, 0.352783f, 0.537109f, 0.709473f, 0.928223f, 0.930664f, 0.931152f, 0.930664f, 0.931641f, 0.931152f,
+ 0.000000f, 0.000000f, 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000120f, 0.000119f, 0.000119f, 0.000111f, 0.000100f, 0.000139f,
+ 0.000082f, 0.000154f, 0.000121f, 0.000216f, 0.000147f, 0.000271f, 0.000288f, 0.000298f, 0.000386f, 0.000463f, 0.000370f, 0.000485f,
+ 0.000555f, 0.000530f, 0.000578f, 0.000574f, 0.000612f, 0.000712f, 0.000776f, 0.000716f, 0.000931f, 0.000831f, 0.000967f, 0.001154f,
+ 0.001176f, 0.001284f, 0.001497f, 0.001884f, 0.002270f, 0.002415f, 0.002947f, 0.003412f, 0.004032f, 0.005066f, 0.006485f, 0.008400f,
+ 0.011215f, 0.015404f, 0.022079f, 0.033264f, 0.052124f, 0.087646f, 0.155029f, 0.279297f, 0.465820f, 0.664062f, 0.918945f, 0.921387f,
+ 0.921875f, 0.922363f, 0.922363f, 0.921875f, 0.000000f, 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000119f, 0.000119f, 0.000119f,
+ 0.000118f, 0.000118f, 0.000110f, 0.000100f, 0.000091f, 0.000082f, 0.000075f, 0.000095f, 0.000166f, 0.000113f, 0.000163f, 0.000248f,
+ 0.000258f, 0.000277f, 0.000336f, 0.000301f, 0.000445f, 0.000495f, 0.000473f, 0.000505f, 0.000494f, 0.000470f, 0.000584f, 0.000752f,
+ 0.000821f, 0.000814f, 0.000845f, 0.000807f, 0.000932f, 0.000996f, 0.001380f, 0.001481f, 0.001507f, 0.001757f, 0.002146f, 0.002443f,
+ 0.002869f, 0.003546f, 0.004559f, 0.005878f, 0.007561f, 0.010475f, 0.015320f, 0.022675f, 0.036133f, 0.060883f, 0.110352f, 0.211670f,
+ 0.389160f, 0.610352f, 0.908691f, 0.909180f, 0.910645f, 0.912109f, 0.909668f, 0.910156f, 0.000000f, 0.000121f, 0.000120f, 0.000119f,
+ 0.000119f, 0.000118f, 0.000118f, 0.000117f, 0.000117f, 0.000117f, 0.000116f, 0.000110f, 0.000100f, 0.000099f, 0.000083f, 0.000077f,
+ 0.000071f, 0.000081f, 0.000087f, 0.000166f, 0.000177f, 0.000233f, 0.000238f, 0.000273f, 0.000325f, 0.000357f, 0.000292f, 0.000406f,
+ 0.000418f, 0.000440f, 0.000428f, 0.000568f, 0.000459f, 0.000628f, 0.000678f, 0.000688f, 0.000647f, 0.000830f, 0.000925f, 0.001111f,
+ 0.001011f, 0.001420f, 0.001504f, 0.001771f, 0.001997f, 0.002495f, 0.003147f, 0.003944f, 0.005077f, 0.006958f, 0.010040f, 0.015053f,
+ 0.023727f, 0.040680f, 0.075989f, 0.153076f, 0.312012f, 0.547363f, 0.894531f, 0.897461f, 0.897949f, 0.897949f, 0.897949f, 0.898438f,
+ 0.000000f, 0.000000f, 0.000119f, 0.000118f, 0.000118f, 0.000117f, 0.000116f, 0.000116f, 0.000115f, 0.000115f, 0.000114f, 0.000114f,
+ 0.000111f, 0.000101f, 0.000093f, 0.000086f, 0.000079f, 0.000095f, 0.000095f, 0.000090f, 0.000117f, 0.000109f, 0.000158f, 0.000199f,
+ 0.000207f, 0.000223f, 0.000286f, 0.000288f, 0.000267f, 0.000347f, 0.000368f, 0.000450f, 0.000377f, 0.000460f, 0.000504f, 0.000498f,
+ 0.000494f, 0.000616f, 0.000632f, 0.000699f, 0.000755f, 0.000938f, 0.000978f, 0.001222f, 0.001355f, 0.001673f, 0.002016f, 0.002539f,
+ 0.003258f, 0.004410f, 0.006332f, 0.009285f, 0.014847f, 0.025864f, 0.049042f, 0.104736f, 0.236572f, 0.477295f, 0.879395f, 0.881348f,
+ 0.882324f, 0.881836f, 0.882324f, 0.882324f, 0.000000f, 0.000119f, 0.000118f, 0.000116f, 0.000115f, 0.000114f, 0.000114f, 0.000113f,
+ 0.000112f, 0.000112f, 0.000111f, 0.000111f, 0.000110f, 0.000110f, 0.000103f, 0.000095f, 0.000088f, 0.000081f, 0.000076f, 0.000070f,
+ 0.000065f, 0.000100f, 0.000104f, 0.000099f, 0.000120f, 0.000145f, 0.000190f, 0.000204f, 0.000213f, 0.000230f, 0.000241f, 0.000279f,
+ 0.000325f, 0.000322f, 0.000328f, 0.000381f, 0.000351f, 0.000466f, 0.000452f, 0.000516f, 0.000591f, 0.000622f, 0.000733f, 0.000882f,
+ 0.000895f, 0.001092f, 0.001456f, 0.001765f, 0.002069f, 0.002821f, 0.003851f, 0.005558f, 0.008865f, 0.015579f, 0.029999f, 0.066895f,
+ 0.167480f, 0.400391f, 0.860352f, 0.862793f, 0.863281f, 0.864258f, 0.863281f, 0.863770f, 0.000119f, 0.000114f, 0.000113f, 0.000113f,
+ 0.000111f, 0.000110f, 0.000109f, 0.000109f, 0.000108f, 0.000107f, 0.000107f, 0.000107f, 0.000106f, 0.000105f, 0.000106f, 0.000105f,
+ 0.000098f, 0.000090f, 0.000084f, 0.000078f, 0.000073f, 0.000068f, 0.000063f, 0.000063f, 0.000066f, 0.000053f, 0.000080f, 0.000107f,
+ 0.000126f, 0.000150f, 0.000188f, 0.000187f, 0.000206f, 0.000205f, 0.000235f, 0.000242f, 0.000277f, 0.000340f, 0.000323f, 0.000308f,
+ 0.000417f, 0.000411f, 0.000445f, 0.000536f, 0.000622f, 0.000673f, 0.000887f, 0.000985f, 0.001289f, 0.001623f, 0.002337f, 0.003241f,
+ 0.004929f, 0.008560f, 0.016739f, 0.039307f, 0.109619f, 0.317383f, 0.837402f, 0.840332f, 0.841309f, 0.840820f, 0.840820f, 0.841309f,
+ 0.000000f, 0.000106f, 0.000099f, 0.000104f, 0.000102f, 0.000101f, 0.000100f, 0.000101f, 0.000101f, 0.000100f, 0.000099f, 0.000100f,
+ 0.000099f, 0.000099f, 0.000099f, 0.000098f, 0.000098f, 0.000098f, 0.000093f, 0.000086f, 0.000080f, 0.000075f, 0.000070f, 0.000065f,
+ 0.000061f, 0.000057f, 0.000059f, 0.000054f, 0.000061f, 0.000080f, 0.000087f, 0.000101f, 0.000136f, 0.000147f, 0.000163f, 0.000171f,
+ 0.000179f, 0.000205f, 0.000223f, 0.000237f, 0.000281f, 0.000272f, 0.000299f, 0.000364f, 0.000373f, 0.000448f, 0.000507f, 0.000643f,
+ 0.000801f, 0.001000f, 0.001276f, 0.001765f, 0.002712f, 0.004585f, 0.008492f, 0.020462f, 0.063721f, 0.233643f, 0.811035f, 0.813477f,
+ 0.814453f, 0.813965f, 0.813965f, 0.814453f, 0.000000f, 0.000057f, 0.000085f, 0.000085f, 0.000083f, 0.000085f, 0.000087f, 0.000086f,
+ 0.000087f, 0.000087f, 0.000086f, 0.000087f, 0.000087f, 0.000086f, 0.000087f, 0.000087f, 0.000088f, 0.000086f, 0.000088f, 0.000087f,
+ 0.000087f, 0.000081f, 0.000076f, 0.000071f, 0.000067f, 0.000063f, 0.000058f, 0.000055f, 0.000051f, 0.000048f, 0.000046f, 0.000042f,
+ 0.000051f, 0.000063f, 0.000081f, 0.000101f, 0.000122f, 0.000137f, 0.000147f, 0.000143f, 0.000157f, 0.000183f, 0.000205f, 0.000188f,
+ 0.000196f, 0.000249f, 0.000310f, 0.000329f, 0.000413f, 0.000534f, 0.000679f, 0.000944f, 0.001365f, 0.002199f, 0.004150f, 0.009369f,
+ 0.031677f, 0.153564f, 0.779297f, 0.781250f, 0.782227f, 0.782715f, 0.781738f, 0.781250f, 0.000000f, 0.000000f, 0.000000f, 0.000009f,
+ 0.000030f, 0.000048f, 0.000051f, 0.000054f, 0.000055f, 0.000059f, 0.000060f, 0.000065f, 0.000065f, 0.000066f, 0.000068f, 0.000068f,
+ 0.000070f, 0.000070f, 0.000071f, 0.000071f, 0.000072f, 0.000073f, 0.000073f, 0.000073f, 0.000071f, 0.000066f, 0.000062f, 0.000058f,
+ 0.000055f, 0.000051f, 0.000048f, 0.000045f, 0.000042f, 0.000039f, 0.000044f, 0.000036f, 0.000046f, 0.000056f, 0.000067f, 0.000085f,
+ 0.000099f, 0.000108f, 0.000107f, 0.000113f, 0.000139f, 0.000144f, 0.000165f, 0.000169f, 0.000196f, 0.000266f, 0.000311f, 0.000426f,
+ 0.000598f, 0.000948f, 0.001744f, 0.003975f, 0.012856f, 0.084351f, 0.739746f, 0.743164f, 0.743652f, 0.743652f, 0.743652f, 0.743164f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000012f, 0.000012f, 0.000020f,
+ 0.000028f, 0.000030f, 0.000033f, 0.000034f, 0.000041f, 0.000041f, 0.000045f, 0.000047f, 0.000048f, 0.000049f, 0.000051f, 0.000052f,
+ 0.000054f, 0.000054f, 0.000056f, 0.000057f, 0.000056f, 0.000052f, 0.000049f, 0.000046f, 0.000043f, 0.000041f, 0.000038f, 0.000035f,
+ 0.000033f, 0.000031f, 0.000029f, 0.000029f, 0.000036f, 0.000055f, 0.000048f, 0.000067f, 0.000067f, 0.000073f, 0.000075f, 0.000097f,
+ 0.000085f, 0.000111f, 0.000137f, 0.000191f, 0.000233f, 0.000371f, 0.000609f, 0.001319f, 0.004341f, 0.033844f, 0.696289f, 0.698730f,
+ 0.699219f, 0.698242f, 0.698730f, 0.698730f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000007f,
+ 0.000009f, 0.000012f, 0.000015f, 0.000020f, 0.000022f, 0.000023f, 0.000026f, 0.000029f, 0.000030f, 0.000032f, 0.000033f, 0.000035f,
+ 0.000037f, 0.000037f, 0.000036f, 0.000034f, 0.000032f, 0.000030f, 0.000028f, 0.000026f, 0.000024f, 0.000022f, 0.000021f, 0.000019f,
+ 0.000024f, 0.000024f, 0.000029f, 0.000037f, 0.000043f, 0.000046f, 0.000059f, 0.000058f, 0.000075f, 0.000095f, 0.000160f, 0.000306f,
+ 0.001006f, 0.008865f, 0.643066f, 0.647461f, 0.647949f, 0.647461f, 0.647949f, 0.648438f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000003f, 0.000005f, 0.000007f, 0.000010f, 0.000012f, 0.000013f, 0.000015f, 0.000017f,
+ 0.000019f, 0.000020f, 0.000018f, 0.000017f, 0.000015f, 0.000014f, 0.000013f, 0.000012f, 0.000010f, 0.000012f, 0.000014f, 0.000018f,
+ 0.000018f, 0.000025f, 0.000028f, 0.000045f, 0.000110f, 0.001030f, 0.586914f, 0.589844f, 0.590820f, 0.591309f, 0.591309f, 0.590820f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000002f, 0.000004f, 0.000005f, 0.000004f, 0.000004f, 0.000003f, 0.000003f, 0.000004f, 0.000009f, 0.527344f, 0.529785f,
+ 0.529785f, 0.530273f, 0.530762f, 0.530762f,
+ },
+ {
+ 0.135132f, 0.377441f, 0.544434f, 0.653320f, 0.724609f, 0.773926f, 0.811035f, 0.838867f, 0.860840f, 0.876465f, 0.891113f, 0.902832f,
+ 0.912109f, 0.920898f, 0.928223f, 0.934082f, 0.938965f, 0.943848f, 0.948242f, 0.952637f, 0.955566f, 0.958984f, 0.961914f, 0.964844f,
+ 0.966797f, 0.969238f, 0.971191f, 0.973145f, 0.975098f, 0.976562f, 0.978027f, 0.979492f, 0.980469f, 0.982422f, 0.983398f, 0.984863f,
+ 0.985840f, 0.986328f, 0.987793f, 0.988770f, 0.989746f, 0.989746f, 0.990234f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994141f,
+ 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999512f, 0.999512f, 0.999512f,
+ 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.044891f, 0.163330f, 0.306885f, 0.444336f, 0.559570f, 0.645020f, 0.710938f, 0.760742f,
+ 0.797852f, 0.827148f, 0.850098f, 0.868652f, 0.883789f, 0.895996f, 0.907227f, 0.916016f, 0.923340f, 0.930176f, 0.936523f, 0.941406f,
+ 0.946777f, 0.950684f, 0.954102f, 0.957031f, 0.960938f, 0.963379f, 0.965820f, 0.968262f, 0.970703f, 0.972168f, 0.974609f, 0.976562f,
+ 0.977539f, 0.979492f, 0.980469f, 0.981934f, 0.982910f, 0.984375f, 0.985840f, 0.986816f, 0.987793f, 0.988770f, 0.988770f, 0.990234f,
+ 0.991211f, 0.991699f, 0.992676f, 0.993164f, 0.993164f, 0.994141f, 0.995605f, 0.995605f, 0.996094f, 0.996582f, 0.997070f, 0.997559f,
+ 0.998047f, 0.998535f, 0.999512f, 0.999512f, 0.999512f, 0.999023f, 0.999023f, 0.999023f, 0.020325f, 0.077820f, 0.158936f, 0.260498f,
+ 0.372314f, 0.479736f, 0.572754f, 0.648438f, 0.707520f, 0.754883f, 0.791016f, 0.820312f, 0.843750f, 0.862793f, 0.878906f, 0.891602f,
+ 0.903320f, 0.912598f, 0.920898f, 0.928223f, 0.933594f, 0.939941f, 0.944824f, 0.949219f, 0.952637f, 0.956543f, 0.959961f, 0.962402f,
+ 0.965332f, 0.967773f, 0.970215f, 0.971680f, 0.974121f, 0.976074f, 0.977539f, 0.979004f, 0.980957f, 0.981445f, 0.983398f, 0.984375f,
+ 0.985352f, 0.986328f, 0.987793f, 0.988770f, 0.989746f, 0.990234f, 0.991211f, 0.992188f, 0.992676f, 0.993164f, 0.994141f, 0.994629f,
+ 0.995605f, 0.996094f, 0.996582f, 0.996582f, 0.997559f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.999023f, 0.998535f, 0.998535f,
+ 0.012032f, 0.042908f, 0.088196f, 0.149292f, 0.228027f, 0.319824f, 0.415527f, 0.506348f, 0.586914f, 0.653809f, 0.709473f, 0.752441f,
+ 0.787598f, 0.817383f, 0.840820f, 0.860352f, 0.876465f, 0.889648f, 0.900879f, 0.910156f, 0.918945f, 0.926270f, 0.933105f, 0.938965f,
+ 0.944336f, 0.948730f, 0.952637f, 0.956055f, 0.958984f, 0.962402f, 0.965332f, 0.967773f, 0.970215f, 0.972656f, 0.974609f, 0.976562f,
+ 0.978027f, 0.979492f, 0.980957f, 0.982422f, 0.983887f, 0.984375f, 0.985352f, 0.986816f, 0.987793f, 0.988770f, 0.989746f, 0.990234f,
+ 0.991211f, 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.996094f, 0.996094f, 0.996582f, 0.997559f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.007637f, 0.026825f, 0.053436f, 0.090759f, 0.140137f, 0.203125f, 0.279053f, 0.363281f,
+ 0.449463f, 0.529785f, 0.601562f, 0.663574f, 0.713379f, 0.756348f, 0.789551f, 0.816895f, 0.840332f, 0.858887f, 0.875488f, 0.887695f,
+ 0.900391f, 0.909668f, 0.918945f, 0.926270f, 0.932617f, 0.938477f, 0.943848f, 0.948242f, 0.952148f, 0.955566f, 0.959473f, 0.962402f,
+ 0.965332f, 0.967773f, 0.970215f, 0.972168f, 0.974121f, 0.976562f, 0.978516f, 0.979492f, 0.980957f, 0.981934f, 0.984375f, 0.985352f,
+ 0.985840f, 0.987793f, 0.988281f, 0.989258f, 0.990723f, 0.991211f, 0.991699f, 0.992676f, 0.993652f, 0.994141f, 0.994629f, 0.995605f,
+ 0.996094f, 0.997070f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998535f, 0.998047f, 0.004784f, 0.018082f, 0.035400f, 0.058868f,
+ 0.089783f, 0.130981f, 0.183716f, 0.248047f, 0.321289f, 0.400391f, 0.478760f, 0.552734f, 0.617188f, 0.673828f, 0.720703f, 0.759766f,
+ 0.792480f, 0.818359f, 0.840820f, 0.859863f, 0.875000f, 0.888184f, 0.899902f, 0.910645f, 0.918945f, 0.926270f, 0.931641f, 0.938965f,
+ 0.943848f, 0.948242f, 0.952148f, 0.957031f, 0.959473f, 0.962891f, 0.965332f, 0.968262f, 0.970215f, 0.972656f, 0.975098f, 0.977051f,
+ 0.978516f, 0.979980f, 0.981445f, 0.982910f, 0.984863f, 0.985352f, 0.986328f, 0.987305f, 0.988770f, 0.989746f, 0.990723f, 0.991699f,
+ 0.992676f, 0.993164f, 0.994141f, 0.994629f, 0.995605f, 0.996094f, 0.998047f, 0.998535f, 0.998047f, 0.998047f, 0.998047f, 0.998047f,
+ 0.004044f, 0.012550f, 0.024628f, 0.040466f, 0.060760f, 0.087708f, 0.122742f, 0.167236f, 0.222534f, 0.287109f, 0.358643f, 0.432617f,
+ 0.506348f, 0.573242f, 0.632812f, 0.685059f, 0.728516f, 0.766602f, 0.797363f, 0.822266f, 0.843750f, 0.861328f, 0.877441f, 0.890625f,
+ 0.901367f, 0.910645f, 0.919434f, 0.926758f, 0.933105f, 0.940430f, 0.944824f, 0.948730f, 0.953125f, 0.957520f, 0.960449f, 0.963867f,
+ 0.966309f, 0.969238f, 0.970703f, 0.973633f, 0.976074f, 0.977539f, 0.979004f, 0.980469f, 0.982422f, 0.983398f, 0.984863f, 0.986816f,
+ 0.986816f, 0.988281f, 0.989746f, 0.990723f, 0.991211f, 0.992188f, 0.993164f, 0.994141f, 0.994629f, 0.995117f, 0.998047f, 0.998047f,
+ 0.998047f, 0.998047f, 0.998047f, 0.998047f, 0.002975f, 0.009315f, 0.017868f, 0.029129f, 0.043243f, 0.062012f, 0.084961f, 0.115540f,
+ 0.154419f, 0.201660f, 0.257812f, 0.322754f, 0.391846f, 0.463135f, 0.530762f, 0.594727f, 0.650391f, 0.698730f, 0.739258f, 0.773926f,
+ 0.803711f, 0.826660f, 0.847656f, 0.865723f, 0.879883f, 0.892090f, 0.903809f, 0.913086f, 0.921387f, 0.928223f, 0.935059f, 0.940918f,
+ 0.945801f, 0.950684f, 0.954102f, 0.958008f, 0.961426f, 0.964844f, 0.967285f, 0.970215f, 0.972168f, 0.974609f, 0.976074f, 0.978027f,
+ 0.979980f, 0.981934f, 0.983398f, 0.984375f, 0.985352f, 0.987305f, 0.988281f, 0.989258f, 0.990234f, 0.991211f, 0.992188f, 0.993164f,
+ 0.993652f, 0.994629f, 0.997559f, 0.998047f, 0.998047f, 0.997559f, 0.997559f, 0.997559f, 0.002329f, 0.007256f, 0.013611f, 0.021790f,
+ 0.032043f, 0.044617f, 0.061554f, 0.082336f, 0.108765f, 0.142578f, 0.184448f, 0.234375f, 0.292725f, 0.357422f, 0.424805f, 0.493164f,
+ 0.556641f, 0.615723f, 0.666504f, 0.711914f, 0.750977f, 0.782715f, 0.809570f, 0.832520f, 0.853516f, 0.868652f, 0.882812f, 0.895508f,
+ 0.905762f, 0.916016f, 0.923340f, 0.931152f, 0.936523f, 0.942383f, 0.947266f, 0.951172f, 0.956055f, 0.958984f, 0.962402f, 0.965820f,
+ 0.968750f, 0.971191f, 0.973633f, 0.975586f, 0.977539f, 0.979980f, 0.980957f, 0.982422f, 0.983887f, 0.985352f, 0.985840f, 0.988281f,
+ 0.989746f, 0.990234f, 0.991211f, 0.991699f, 0.993164f, 0.993652f, 0.997070f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f,
+ 0.001871f, 0.006084f, 0.010963f, 0.016953f, 0.024277f, 0.033722f, 0.046234f, 0.060669f, 0.079224f, 0.103638f, 0.132812f, 0.169678f,
+ 0.214478f, 0.267090f, 0.326172f, 0.390137f, 0.456543f, 0.519531f, 0.581543f, 0.636230f, 0.685547f, 0.726562f, 0.762207f, 0.792969f,
+ 0.818359f, 0.839844f, 0.858398f, 0.874023f, 0.887695f, 0.898926f, 0.909668f, 0.918945f, 0.926270f, 0.933105f, 0.938965f, 0.944336f,
+ 0.949219f, 0.953613f, 0.958008f, 0.961426f, 0.964844f, 0.967773f, 0.969727f, 0.972168f, 0.974609f, 0.976074f, 0.979004f, 0.979980f,
+ 0.981934f, 0.983887f, 0.985352f, 0.986328f, 0.987793f, 0.989746f, 0.989746f, 0.990723f, 0.991211f, 0.992676f, 0.996582f, 0.997070f,
+ 0.997559f, 0.997070f, 0.997070f, 0.997070f, 0.001322f, 0.004795f, 0.008530f, 0.013504f, 0.018921f, 0.026154f, 0.035065f, 0.045807f,
+ 0.059662f, 0.076416f, 0.098267f, 0.124512f, 0.157715f, 0.197388f, 0.244873f, 0.299805f, 0.359619f, 0.423096f, 0.487549f, 0.549316f,
+ 0.605957f, 0.657715f, 0.703125f, 0.741211f, 0.774902f, 0.802734f, 0.827148f, 0.847656f, 0.865234f, 0.879883f, 0.893066f, 0.903320f,
+ 0.913086f, 0.920898f, 0.929199f, 0.935547f, 0.941406f, 0.947266f, 0.951172f, 0.956055f, 0.959473f, 0.962891f, 0.965332f, 0.969238f,
+ 0.971191f, 0.974121f, 0.976562f, 0.977539f, 0.979980f, 0.981445f, 0.982910f, 0.984863f, 0.986328f, 0.988281f, 0.988281f, 0.989746f,
+ 0.990723f, 0.991699f, 0.996582f, 0.996582f, 0.997070f, 0.997070f, 0.997070f, 0.996582f, 0.001077f, 0.003971f, 0.006985f, 0.010750f,
+ 0.015579f, 0.020920f, 0.027420f, 0.035522f, 0.045776f, 0.058228f, 0.074097f, 0.093140f, 0.117310f, 0.146851f, 0.182495f, 0.225952f,
+ 0.276611f, 0.332764f, 0.394287f, 0.456543f, 0.518555f, 0.577637f, 0.630371f, 0.679199f, 0.720703f, 0.756836f, 0.787598f, 0.813477f,
+ 0.836426f, 0.855469f, 0.872070f, 0.885742f, 0.897949f, 0.908203f, 0.917480f, 0.925293f, 0.933105f, 0.939453f, 0.944336f, 0.949219f,
+ 0.954590f, 0.957520f, 0.961426f, 0.964844f, 0.968262f, 0.970703f, 0.974121f, 0.975586f, 0.978027f, 0.979492f, 0.981445f, 0.983398f,
+ 0.984863f, 0.986328f, 0.987793f, 0.988770f, 0.989746f, 0.991211f, 0.996094f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.996582f,
+ 0.000954f, 0.003330f, 0.005733f, 0.008904f, 0.012505f, 0.016617f, 0.022446f, 0.028351f, 0.036041f, 0.045807f, 0.056854f, 0.071350f,
+ 0.088867f, 0.110596f, 0.137451f, 0.170654f, 0.209717f, 0.256592f, 0.309326f, 0.366943f, 0.427979f, 0.489502f, 0.549316f, 0.604980f,
+ 0.655762f, 0.700195f, 0.738770f, 0.772461f, 0.801270f, 0.825195f, 0.845703f, 0.864258f, 0.879395f, 0.893066f, 0.903809f, 0.914062f,
+ 0.922363f, 0.929688f, 0.936523f, 0.942871f, 0.947266f, 0.952148f, 0.956055f, 0.960449f, 0.963867f, 0.966797f, 0.969727f, 0.972656f,
+ 0.975586f, 0.976562f, 0.979004f, 0.981445f, 0.982910f, 0.984375f, 0.985840f, 0.986816f, 0.988770f, 0.989746f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996094f, 0.996094f, 0.996094f, 0.000949f, 0.002804f, 0.004730f, 0.007236f, 0.010384f, 0.014160f, 0.018478f, 0.023102f,
+ 0.028992f, 0.036346f, 0.044647f, 0.055542f, 0.068481f, 0.085144f, 0.105286f, 0.130005f, 0.159668f, 0.195557f, 0.238647f, 0.287842f,
+ 0.343018f, 0.402588f, 0.463135f, 0.522949f, 0.580566f, 0.632812f, 0.680664f, 0.721680f, 0.757812f, 0.788574f, 0.814453f, 0.836914f,
+ 0.856934f, 0.872070f, 0.887207f, 0.899414f, 0.909668f, 0.918945f, 0.926758f, 0.933594f, 0.940430f, 0.946289f, 0.950684f, 0.954590f,
+ 0.959473f, 0.963379f, 0.966797f, 0.969238f, 0.972168f, 0.975098f, 0.977051f, 0.979492f, 0.980957f, 0.982910f, 0.984375f, 0.986328f,
+ 0.987793f, 0.988770f, 0.995117f, 0.996094f, 0.995605f, 0.996094f, 0.996094f, 0.995605f, 0.000828f, 0.002361f, 0.004116f, 0.006119f,
+ 0.008797f, 0.011391f, 0.014854f, 0.018890f, 0.023666f, 0.029083f, 0.036011f, 0.044434f, 0.053986f, 0.066589f, 0.081543f, 0.100159f,
+ 0.122314f, 0.149536f, 0.183350f, 0.222900f, 0.269043f, 0.321533f, 0.378418f, 0.438477f, 0.499023f, 0.556641f, 0.611328f, 0.661133f,
+ 0.703613f, 0.742188f, 0.775391f, 0.804199f, 0.828613f, 0.849121f, 0.866211f, 0.881348f, 0.894043f, 0.905762f, 0.916016f, 0.924316f,
+ 0.931641f, 0.938477f, 0.944336f, 0.949707f, 0.954590f, 0.958496f, 0.962402f, 0.966309f, 0.969238f, 0.972168f, 0.974121f, 0.977051f,
+ 0.979004f, 0.980957f, 0.982910f, 0.984863f, 0.985840f, 0.987793f, 0.995117f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.995605f,
+ 0.000606f, 0.001948f, 0.003483f, 0.005394f, 0.007290f, 0.009735f, 0.012352f, 0.015747f, 0.019485f, 0.023788f, 0.029358f, 0.035706f,
+ 0.043732f, 0.053162f, 0.064331f, 0.077942f, 0.094971f, 0.116089f, 0.140991f, 0.172485f, 0.209473f, 0.252686f, 0.302002f, 0.356934f,
+ 0.415283f, 0.475830f, 0.534180f, 0.589844f, 0.641602f, 0.687500f, 0.728516f, 0.763184f, 0.792969f, 0.819336f, 0.841309f, 0.860840f,
+ 0.876953f, 0.890625f, 0.902344f, 0.913086f, 0.921875f, 0.930176f, 0.937012f, 0.943359f, 0.948242f, 0.954102f, 0.958008f, 0.961914f,
+ 0.965820f, 0.969238f, 0.971680f, 0.974609f, 0.977051f, 0.979004f, 0.981445f, 0.983398f, 0.984863f, 0.986816f, 0.994141f, 0.994629f,
+ 0.995117f, 0.995117f, 0.995117f, 0.994629f, 0.000672f, 0.001569f, 0.002895f, 0.004528f, 0.006180f, 0.008324f, 0.010864f, 0.013161f,
+ 0.016357f, 0.020096f, 0.024216f, 0.029327f, 0.035583f, 0.042664f, 0.051453f, 0.062073f, 0.075012f, 0.091125f, 0.110291f, 0.134155f,
+ 0.162476f, 0.197266f, 0.238037f, 0.285156f, 0.337646f, 0.395020f, 0.454590f, 0.513672f, 0.570312f, 0.624023f, 0.672363f, 0.714844f,
+ 0.750977f, 0.783691f, 0.811035f, 0.834473f, 0.854004f, 0.872070f, 0.886230f, 0.899414f, 0.911133f, 0.918945f, 0.928223f, 0.936035f,
+ 0.942871f, 0.948242f, 0.953613f, 0.957031f, 0.961426f, 0.965820f, 0.968750f, 0.972168f, 0.974121f, 0.976562f, 0.979492f, 0.981445f,
+ 0.983398f, 0.985352f, 0.994141f, 0.994629f, 0.995117f, 0.995117f, 0.995117f, 0.994629f, 0.000413f, 0.001430f, 0.002577f, 0.004269f,
+ 0.005703f, 0.007137f, 0.008888f, 0.011124f, 0.013885f, 0.016891f, 0.020355f, 0.024384f, 0.029221f, 0.035217f, 0.041748f, 0.049988f,
+ 0.060059f, 0.072083f, 0.086914f, 0.105286f, 0.126953f, 0.154175f, 0.186523f, 0.224731f, 0.269287f, 0.320557f, 0.375732f, 0.434570f,
+ 0.493896f, 0.552246f, 0.606934f, 0.655762f, 0.701660f, 0.740723f, 0.774902f, 0.803711f, 0.827637f, 0.848633f, 0.867188f, 0.882812f,
+ 0.895996f, 0.908203f, 0.917969f, 0.926758f, 0.934570f, 0.941895f, 0.947266f, 0.952637f, 0.957520f, 0.960938f, 0.965820f, 0.968750f,
+ 0.971680f, 0.974609f, 0.977051f, 0.979980f, 0.981934f, 0.983887f, 0.993652f, 0.994629f, 0.994141f, 0.994141f, 0.994141f, 0.994141f,
+ 0.000240f, 0.001406f, 0.002373f, 0.003283f, 0.004620f, 0.006264f, 0.007744f, 0.009552f, 0.011711f, 0.014069f, 0.017273f, 0.020584f,
+ 0.024429f, 0.028946f, 0.034393f, 0.041046f, 0.048798f, 0.058289f, 0.070312f, 0.083618f, 0.100403f, 0.121338f, 0.146118f, 0.177002f,
+ 0.213257f, 0.255371f, 0.304443f, 0.358887f, 0.416504f, 0.476562f, 0.534668f, 0.590332f, 0.642090f, 0.688965f, 0.729492f, 0.766113f,
+ 0.796387f, 0.822754f, 0.844727f, 0.862305f, 0.880371f, 0.894043f, 0.905762f, 0.916992f, 0.926270f, 0.934082f, 0.940918f, 0.946777f,
+ 0.953125f, 0.956543f, 0.961426f, 0.964844f, 0.969238f, 0.972656f, 0.974609f, 0.977539f, 0.979980f, 0.982422f, 0.992676f, 0.994141f,
+ 0.993652f, 0.993652f, 0.993652f, 0.993652f, 0.000242f, 0.001257f, 0.001991f, 0.003138f, 0.004299f, 0.005302f, 0.006584f, 0.008308f,
+ 0.010048f, 0.012283f, 0.014526f, 0.017578f, 0.020340f, 0.023972f, 0.028671f, 0.033661f, 0.040161f, 0.047821f, 0.056213f, 0.067261f,
+ 0.080444f, 0.096191f, 0.115784f, 0.139771f, 0.168457f, 0.203125f, 0.243286f, 0.290527f, 0.343506f, 0.400879f, 0.459473f, 0.519043f,
+ 0.576172f, 0.629395f, 0.678223f, 0.721191f, 0.757324f, 0.789062f, 0.816895f, 0.839844f, 0.859863f, 0.877930f, 0.892578f, 0.904297f,
+ 0.915527f, 0.925293f, 0.933105f, 0.940430f, 0.946777f, 0.952148f, 0.957031f, 0.961914f, 0.965820f, 0.969238f, 0.973145f, 0.975586f,
+ 0.978516f, 0.980469f, 0.992188f, 0.993652f, 0.993164f, 0.993164f, 0.993652f, 0.993164f, 0.000434f, 0.001172f, 0.001865f, 0.002825f,
+ 0.003633f, 0.004757f, 0.005722f, 0.007175f, 0.009010f, 0.010651f, 0.012520f, 0.014412f, 0.017532f, 0.020599f, 0.024139f, 0.028488f,
+ 0.033356f, 0.039001f, 0.046295f, 0.054749f, 0.064758f, 0.077209f, 0.092834f, 0.111084f, 0.134033f, 0.160767f, 0.193604f, 0.233032f,
+ 0.278320f, 0.329590f, 0.386230f, 0.445068f, 0.504395f, 0.563477f, 0.617188f, 0.666504f, 0.711426f, 0.750000f, 0.783691f, 0.812500f,
+ 0.836426f, 0.857422f, 0.875488f, 0.891113f, 0.903809f, 0.915039f, 0.924805f, 0.933105f, 0.940430f, 0.947266f, 0.953125f, 0.958496f,
+ 0.962402f, 0.966309f, 0.969727f, 0.973145f, 0.976562f, 0.978516f, 0.991699f, 0.992188f, 0.992676f, 0.993164f, 0.993164f, 0.992676f,
+ 0.000358f, 0.000835f, 0.001738f, 0.002270f, 0.002996f, 0.004078f, 0.005157f, 0.006416f, 0.007904f, 0.009331f, 0.010826f, 0.012245f,
+ 0.014938f, 0.017303f, 0.020233f, 0.023926f, 0.027954f, 0.032715f, 0.038147f, 0.045166f, 0.053070f, 0.062561f, 0.074768f, 0.089661f,
+ 0.106689f, 0.128052f, 0.154175f, 0.185547f, 0.223022f, 0.266846f, 0.317383f, 0.373047f, 0.431152f, 0.491943f, 0.550293f, 0.606445f,
+ 0.658203f, 0.704102f, 0.744141f, 0.779297f, 0.809082f, 0.833984f, 0.855957f, 0.875000f, 0.889648f, 0.903320f, 0.915039f, 0.924805f,
+ 0.933594f, 0.940918f, 0.947754f, 0.954102f, 0.958984f, 0.962402f, 0.966797f, 0.970703f, 0.974121f, 0.977539f, 0.990723f, 0.992188f,
+ 0.992676f, 0.992676f, 0.992188f, 0.992676f, 0.000428f, 0.000789f, 0.001460f, 0.002172f, 0.002695f, 0.003561f, 0.004608f, 0.005848f,
+ 0.006886f, 0.007736f, 0.009560f, 0.011078f, 0.012817f, 0.015015f, 0.017563f, 0.020157f, 0.023666f, 0.027145f, 0.031891f, 0.037384f,
+ 0.044189f, 0.051788f, 0.061188f, 0.072327f, 0.085999f, 0.102966f, 0.123413f, 0.148071f, 0.178101f, 0.214478f, 0.256836f, 0.306396f,
+ 0.360840f, 0.419678f, 0.479736f, 0.540527f, 0.597656f, 0.649902f, 0.697754f, 0.738770f, 0.775391f, 0.805664f, 0.831543f, 0.854004f,
+ 0.873535f, 0.889160f, 0.902832f, 0.915039f, 0.925293f, 0.934082f, 0.941895f, 0.948730f, 0.954102f, 0.959961f, 0.963867f, 0.968262f,
+ 0.971680f, 0.975586f, 0.990723f, 0.991699f, 0.991699f, 0.991699f, 0.991699f, 0.991211f, 0.000237f, 0.000782f, 0.001245f, 0.001923f,
+ 0.002417f, 0.003225f, 0.004101f, 0.005062f, 0.005920f, 0.007030f, 0.008102f, 0.009743f, 0.011009f, 0.013054f, 0.015190f, 0.017380f,
+ 0.020126f, 0.023346f, 0.027161f, 0.031464f, 0.036316f, 0.042664f, 0.050110f, 0.058807f, 0.069946f, 0.083191f, 0.099121f, 0.118835f,
+ 0.142822f, 0.171997f, 0.206665f, 0.248413f, 0.296143f, 0.350586f, 0.408936f, 0.469727f, 0.530762f, 0.589844f, 0.643555f, 0.691895f,
+ 0.734375f, 0.772461f, 0.803223f, 0.830566f, 0.854492f, 0.873047f, 0.889648f, 0.903809f, 0.916016f, 0.926270f, 0.935059f, 0.943359f,
+ 0.949219f, 0.955566f, 0.960938f, 0.965332f, 0.969727f, 0.973145f, 0.989746f, 0.990723f, 0.990723f, 0.990723f, 0.991211f, 0.990723f,
+ 0.000243f, 0.000793f, 0.001210f, 0.001616f, 0.002260f, 0.003069f, 0.003649f, 0.004444f, 0.005322f, 0.006088f, 0.006954f, 0.008278f,
+ 0.009766f, 0.011139f, 0.012970f, 0.014908f, 0.016968f, 0.019897f, 0.023193f, 0.026962f, 0.030792f, 0.035522f, 0.041931f, 0.048920f,
+ 0.057404f, 0.067993f, 0.080383f, 0.095825f, 0.114929f, 0.137695f, 0.165771f, 0.199585f, 0.241089f, 0.287842f, 0.341553f, 0.400391f,
+ 0.462402f, 0.523438f, 0.583008f, 0.638184f, 0.687988f, 0.732422f, 0.770020f, 0.802246f, 0.830566f, 0.854004f, 0.873047f, 0.891113f,
+ 0.904785f, 0.916992f, 0.926758f, 0.936523f, 0.943848f, 0.951172f, 0.956543f, 0.961914f, 0.966797f, 0.971191f, 0.989258f, 0.990234f,
+ 0.990234f, 0.990234f, 0.990234f, 0.989746f, 0.000000f, 0.000484f, 0.000973f, 0.001453f, 0.001999f, 0.002689f, 0.003359f, 0.003864f,
+ 0.004726f, 0.005444f, 0.006516f, 0.007404f, 0.008461f, 0.009720f, 0.011261f, 0.012985f, 0.014908f, 0.017120f, 0.019699f, 0.022614f,
+ 0.026093f, 0.030228f, 0.034668f, 0.040619f, 0.047699f, 0.055756f, 0.066284f, 0.078308f, 0.092834f, 0.111328f, 0.133423f, 0.160889f,
+ 0.194214f, 0.233765f, 0.281006f, 0.334473f, 0.392822f, 0.455078f, 0.517090f, 0.578125f, 0.634766f, 0.686035f, 0.730957f, 0.768555f,
+ 0.803223f, 0.831055f, 0.854492f, 0.875488f, 0.892090f, 0.906250f, 0.918457f, 0.929688f, 0.937988f, 0.945801f, 0.952148f, 0.958496f,
+ 0.963867f, 0.968750f, 0.988281f, 0.989258f, 0.989746f, 0.989258f, 0.989746f, 0.989258f, 0.000241f, 0.000699f, 0.000835f, 0.001354f,
+ 0.002066f, 0.002405f, 0.003073f, 0.003466f, 0.003847f, 0.004868f, 0.005798f, 0.006325f, 0.007446f, 0.008553f, 0.009789f, 0.011375f,
+ 0.013031f, 0.014702f, 0.016937f, 0.019455f, 0.022171f, 0.025467f, 0.029541f, 0.034271f, 0.039734f, 0.046295f, 0.054291f, 0.063904f,
+ 0.075745f, 0.089966f, 0.107727f, 0.129395f, 0.156250f, 0.188965f, 0.228394f, 0.274658f, 0.327637f, 0.386963f, 0.449219f, 0.512695f,
+ 0.574707f, 0.632324f, 0.684570f, 0.730469f, 0.770508f, 0.804688f, 0.832520f, 0.857422f, 0.876953f, 0.893066f, 0.908691f, 0.920410f,
+ 0.931152f, 0.940430f, 0.947754f, 0.954590f, 0.960938f, 0.965820f, 0.986816f, 0.988770f, 0.988770f, 0.988770f, 0.988770f, 0.988770f,
+ 0.000122f, 0.000480f, 0.000793f, 0.001184f, 0.001847f, 0.002220f, 0.002459f, 0.003109f, 0.003740f, 0.004234f, 0.005127f, 0.005730f,
+ 0.006557f, 0.007458f, 0.008469f, 0.009911f, 0.011162f, 0.012848f, 0.014519f, 0.016693f, 0.019135f, 0.021820f, 0.025024f, 0.028931f,
+ 0.033508f, 0.038757f, 0.045135f, 0.052856f, 0.062042f, 0.073547f, 0.087646f, 0.104736f, 0.126099f, 0.152588f, 0.184570f, 0.223511f,
+ 0.269775f, 0.323242f, 0.382324f, 0.445801f, 0.510254f, 0.573242f, 0.631348f, 0.685059f, 0.731934f, 0.772461f, 0.806641f, 0.834961f,
+ 0.859375f, 0.879883f, 0.897461f, 0.911133f, 0.923828f, 0.933594f, 0.942383f, 0.950195f, 0.956055f, 0.962402f, 0.985840f, 0.987305f,
+ 0.987793f, 0.987793f, 0.988281f, 0.987793f, 0.000244f, 0.000471f, 0.000666f, 0.001267f, 0.001592f, 0.001838f, 0.002251f, 0.002855f,
+ 0.003225f, 0.003828f, 0.004372f, 0.005112f, 0.005695f, 0.006340f, 0.007534f, 0.008797f, 0.009895f, 0.011215f, 0.012604f, 0.014503f,
+ 0.016602f, 0.018738f, 0.021408f, 0.024567f, 0.028305f, 0.032654f, 0.037872f, 0.043732f, 0.051239f, 0.060669f, 0.071716f, 0.085510f,
+ 0.102356f, 0.123230f, 0.149170f, 0.180664f, 0.219849f, 0.265869f, 0.319092f, 0.379150f, 0.443604f, 0.508789f, 0.572754f, 0.633301f,
+ 0.686523f, 0.734863f, 0.775391f, 0.809570f, 0.838379f, 0.862305f, 0.883301f, 0.900391f, 0.914551f, 0.926270f, 0.937012f, 0.944824f,
+ 0.953125f, 0.959473f, 0.985352f, 0.986816f, 0.986816f, 0.986816f, 0.986816f, 0.986816f, 0.000242f, 0.000346f, 0.000827f, 0.001065f,
+ 0.001428f, 0.001572f, 0.001984f, 0.002367f, 0.002851f, 0.003277f, 0.003786f, 0.004501f, 0.005253f, 0.005955f, 0.006573f, 0.007736f,
+ 0.008659f, 0.009880f, 0.011177f, 0.012459f, 0.014153f, 0.016403f, 0.018173f, 0.020859f, 0.024017f, 0.027496f, 0.031708f, 0.036682f,
+ 0.042877f, 0.050446f, 0.059174f, 0.070068f, 0.083374f, 0.100159f, 0.120728f, 0.145874f, 0.177612f, 0.216187f, 0.262695f, 0.316650f,
+ 0.377686f, 0.443115f, 0.509766f, 0.575195f, 0.635742f, 0.691406f, 0.738281f, 0.779785f, 0.813965f, 0.843750f, 0.866699f, 0.887207f,
+ 0.904297f, 0.918945f, 0.930176f, 0.940918f, 0.948730f, 0.956055f, 0.984375f, 0.985840f, 0.985840f, 0.985840f, 0.986328f, 0.985840f,
+ 0.000242f, 0.000540f, 0.000708f, 0.000830f, 0.001143f, 0.001451f, 0.001861f, 0.002249f, 0.002661f, 0.003010f, 0.003435f, 0.003922f,
+ 0.004707f, 0.005165f, 0.005787f, 0.006840f, 0.007374f, 0.008545f, 0.009651f, 0.011147f, 0.012581f, 0.014084f, 0.015991f, 0.017899f,
+ 0.020325f, 0.023392f, 0.026978f, 0.031113f, 0.035919f, 0.042023f, 0.049103f, 0.057831f, 0.068420f, 0.081543f, 0.098145f, 0.118530f,
+ 0.143921f, 0.175293f, 0.213989f, 0.260742f, 0.316162f, 0.377441f, 0.444336f, 0.512207f, 0.579590f, 0.641113f, 0.696289f, 0.744629f,
+ 0.786621f, 0.820801f, 0.849609f, 0.872559f, 0.892578f, 0.908691f, 0.922363f, 0.934570f, 0.944336f, 0.951660f, 0.982910f, 0.984375f,
+ 0.984863f, 0.984863f, 0.985352f, 0.984863f, 0.000106f, 0.000477f, 0.000649f, 0.000901f, 0.001110f, 0.001206f, 0.001630f, 0.002121f,
+ 0.002192f, 0.002743f, 0.003128f, 0.003538f, 0.003941f, 0.004688f, 0.005276f, 0.005905f, 0.006546f, 0.007568f, 0.008461f, 0.009483f,
+ 0.010674f, 0.011864f, 0.013649f, 0.015549f, 0.017731f, 0.020111f, 0.023010f, 0.026199f, 0.030304f, 0.035278f, 0.040833f, 0.047821f,
+ 0.056580f, 0.066895f, 0.079895f, 0.096191f, 0.116760f, 0.141968f, 0.173584f, 0.212646f, 0.260498f, 0.316162f, 0.379883f, 0.447754f,
+ 0.517578f, 0.584961f, 0.647949f, 0.704102f, 0.752930f, 0.792969f, 0.827148f, 0.855957f, 0.877930f, 0.898438f, 0.914062f, 0.928223f,
+ 0.938965f, 0.948242f, 0.981445f, 0.983398f, 0.983887f, 0.983887f, 0.983887f, 0.983398f, 0.000208f, 0.000456f, 0.000582f, 0.000788f,
+ 0.001016f, 0.001428f, 0.001507f, 0.001769f, 0.002203f, 0.002525f, 0.002718f, 0.003187f, 0.003761f, 0.004238f, 0.004635f, 0.005348f,
+ 0.005901f, 0.006805f, 0.007500f, 0.008545f, 0.009270f, 0.010437f, 0.011742f, 0.013344f, 0.015198f, 0.017242f, 0.019516f, 0.022430f,
+ 0.025665f, 0.029922f, 0.034180f, 0.040161f, 0.046936f, 0.055420f, 0.065735f, 0.078552f, 0.094666f, 0.114563f, 0.140503f, 0.172485f,
+ 0.212646f, 0.260986f, 0.318359f, 0.383545f, 0.453125f, 0.524414f, 0.593750f, 0.656738f, 0.712891f, 0.761230f, 0.801270f, 0.835938f,
+ 0.862305f, 0.885742f, 0.904785f, 0.919922f, 0.933594f, 0.943359f, 0.980469f, 0.982422f, 0.982422f, 0.981934f, 0.982422f, 0.982422f,
+ 0.000170f, 0.000350f, 0.000583f, 0.000682f, 0.000845f, 0.001036f, 0.001265f, 0.001821f, 0.001953f, 0.002163f, 0.002525f, 0.002771f,
+ 0.003418f, 0.003729f, 0.004040f, 0.004871f, 0.005188f, 0.005726f, 0.006512f, 0.007130f, 0.008087f, 0.009018f, 0.010216f, 0.011490f,
+ 0.013084f, 0.014565f, 0.016891f, 0.019073f, 0.021851f, 0.025253f, 0.029022f, 0.033539f, 0.039124f, 0.045563f, 0.054230f, 0.064270f,
+ 0.077271f, 0.093323f, 0.113403f, 0.139648f, 0.172485f, 0.213379f, 0.262939f, 0.322266f, 0.389404f, 0.461426f, 0.534180f, 0.604492f,
+ 0.668457f, 0.724609f, 0.772461f, 0.812500f, 0.845703f, 0.872070f, 0.894043f, 0.911621f, 0.926758f, 0.938477f, 0.979004f, 0.980469f,
+ 0.980957f, 0.980957f, 0.980957f, 0.980957f, 0.000000f, 0.000332f, 0.000583f, 0.000583f, 0.000848f, 0.000959f, 0.001125f, 0.001425f,
+ 0.001810f, 0.001899f, 0.002300f, 0.002529f, 0.002996f, 0.003162f, 0.003607f, 0.004150f, 0.004761f, 0.005146f, 0.005791f, 0.006329f,
+ 0.007099f, 0.008110f, 0.008949f, 0.009941f, 0.011253f, 0.012756f, 0.014565f, 0.016434f, 0.018707f, 0.021271f, 0.024475f, 0.028290f,
+ 0.032745f, 0.037964f, 0.044769f, 0.052795f, 0.063416f, 0.076050f, 0.092102f, 0.113464f, 0.139526f, 0.172974f, 0.214600f, 0.266602f,
+ 0.327637f, 0.397461f, 0.471191f, 0.546387f, 0.617188f, 0.682129f, 0.737793f, 0.784668f, 0.823730f, 0.854980f, 0.881348f, 0.902344f,
+ 0.918945f, 0.933105f, 0.977539f, 0.979492f, 0.979492f, 0.979492f, 0.979492f, 0.979492f, 0.000000f, 0.000243f, 0.000553f, 0.000575f,
+ 0.000591f, 0.000798f, 0.000991f, 0.001234f, 0.001419f, 0.001812f, 0.001935f, 0.002186f, 0.002518f, 0.002975f, 0.003202f, 0.003614f,
+ 0.004047f, 0.004425f, 0.005013f, 0.005718f, 0.006172f, 0.007046f, 0.007740f, 0.008835f, 0.009819f, 0.011192f, 0.012444f, 0.014114f,
+ 0.015884f, 0.018204f, 0.020844f, 0.023392f, 0.027420f, 0.031921f, 0.037170f, 0.043610f, 0.052032f, 0.062408f, 0.075256f, 0.091675f,
+ 0.112610f, 0.140015f, 0.173950f, 0.217651f, 0.271973f, 0.335693f, 0.407715f, 0.484619f, 0.561035f, 0.633789f, 0.698242f, 0.752930f,
+ 0.798828f, 0.836426f, 0.867676f, 0.891602f, 0.911621f, 0.926270f, 0.975098f, 0.977539f, 0.978516f, 0.977539f, 0.977539f, 0.978027f,
+ 0.000121f, 0.000121f, 0.000241f, 0.000385f, 0.000684f, 0.000693f, 0.000932f, 0.001156f, 0.001410f, 0.001648f, 0.001893f, 0.002184f,
+ 0.002367f, 0.002579f, 0.002872f, 0.003319f, 0.003653f, 0.003922f, 0.004425f, 0.004925f, 0.005436f, 0.006180f, 0.006836f, 0.007645f,
+ 0.008278f, 0.009476f, 0.010788f, 0.012169f, 0.013695f, 0.015305f, 0.017319f, 0.020111f, 0.022858f, 0.026718f, 0.030975f, 0.036255f,
+ 0.042938f, 0.051270f, 0.061493f, 0.074768f, 0.091187f, 0.112976f, 0.140747f, 0.176392f, 0.222168f, 0.278809f, 0.345703f, 0.421387f,
+ 0.500488f, 0.578613f, 0.651855f, 0.715820f, 0.769531f, 0.813965f, 0.850586f, 0.878418f, 0.901855f, 0.920410f, 0.973633f, 0.975586f,
+ 0.976074f, 0.976562f, 0.976562f, 0.975098f, 0.000240f, 0.000120f, 0.000281f, 0.000333f, 0.000498f, 0.000680f, 0.000684f, 0.001083f,
+ 0.001312f, 0.001618f, 0.001606f, 0.001834f, 0.002087f, 0.002316f, 0.002735f, 0.002792f, 0.003084f, 0.003386f, 0.003944f, 0.004353f,
+ 0.004761f, 0.005390f, 0.005997f, 0.006615f, 0.007389f, 0.008324f, 0.008987f, 0.010284f, 0.011703f, 0.013382f, 0.014717f, 0.016953f,
+ 0.019424f, 0.022278f, 0.026047f, 0.030029f, 0.035492f, 0.042145f, 0.050446f, 0.060608f, 0.073975f, 0.091187f, 0.113831f, 0.142700f,
+ 0.180176f, 0.228271f, 0.288086f, 0.359131f, 0.437988f, 0.519531f, 0.600098f, 0.673340f, 0.735352f, 0.787598f, 0.830566f, 0.865234f,
+ 0.891602f, 0.913086f, 0.971680f, 0.974121f, 0.974121f, 0.974121f, 0.974121f, 0.974609f, 0.000000f, 0.000239f, 0.000236f, 0.000425f,
+ 0.000487f, 0.000608f, 0.000850f, 0.001012f, 0.001140f, 0.001260f, 0.001410f, 0.001640f, 0.001953f, 0.002003f, 0.002342f, 0.002434f,
+ 0.002686f, 0.002934f, 0.003305f, 0.003771f, 0.004169f, 0.004692f, 0.005028f, 0.005817f, 0.006371f, 0.007179f, 0.007919f, 0.008965f,
+ 0.009857f, 0.011261f, 0.012703f, 0.014229f, 0.016312f, 0.018494f, 0.021744f, 0.025024f, 0.029633f, 0.034790f, 0.041199f, 0.049561f,
+ 0.060242f, 0.073608f, 0.091675f, 0.114502f, 0.144897f, 0.185547f, 0.236328f, 0.300049f, 0.375732f, 0.458496f, 0.542969f, 0.624023f,
+ 0.696289f, 0.758301f, 0.808105f, 0.847656f, 0.879395f, 0.903809f, 0.968750f, 0.971191f, 0.972168f, 0.971680f, 0.972168f, 0.971680f,
+ 0.000000f, 0.000217f, 0.000235f, 0.000235f, 0.000321f, 0.000560f, 0.000588f, 0.000897f, 0.001034f, 0.001040f, 0.001246f, 0.001369f,
+ 0.001611f, 0.001692f, 0.001942f, 0.002153f, 0.002337f, 0.002638f, 0.002878f, 0.003330f, 0.003672f, 0.003986f, 0.004498f, 0.004826f,
+ 0.005535f, 0.006176f, 0.006561f, 0.007538f, 0.008362f, 0.009544f, 0.010612f, 0.011879f, 0.013794f, 0.015839f, 0.018326f, 0.020889f,
+ 0.024567f, 0.028625f, 0.033783f, 0.040527f, 0.049133f, 0.059998f, 0.073608f, 0.092041f, 0.116394f, 0.148682f, 0.191528f, 0.246582f,
+ 0.315186f, 0.395508f, 0.482910f, 0.570312f, 0.651367f, 0.722168f, 0.781738f, 0.828613f, 0.866211f, 0.895508f, 0.966797f, 0.968750f,
+ 0.969238f, 0.969727f, 0.969238f, 0.969238f, 0.000000f, 0.000108f, 0.000215f, 0.000346f, 0.000352f, 0.000501f, 0.000783f, 0.000828f,
+ 0.000954f, 0.000980f, 0.001130f, 0.001353f, 0.001429f, 0.001522f, 0.001690f, 0.001760f, 0.002172f, 0.002363f, 0.002522f, 0.002777f,
+ 0.003202f, 0.003550f, 0.004040f, 0.004364f, 0.004734f, 0.005192f, 0.005909f, 0.006271f, 0.007015f, 0.007957f, 0.008774f, 0.010185f,
+ 0.011681f, 0.013306f, 0.015327f, 0.017517f, 0.020264f, 0.023636f, 0.027740f, 0.033234f, 0.039856f, 0.048340f, 0.059387f, 0.074097f,
+ 0.093567f, 0.118896f, 0.153931f, 0.200073f, 0.260254f, 0.334473f, 0.420410f, 0.511719f, 0.601562f, 0.682129f, 0.750488f, 0.807617f,
+ 0.851074f, 0.884277f, 0.963867f, 0.966309f, 0.966797f, 0.966797f, 0.966797f, 0.966797f, 0.000000f, 0.000059f, 0.000292f, 0.000331f,
+ 0.000344f, 0.000613f, 0.000532f, 0.000703f, 0.000853f, 0.000915f, 0.000936f, 0.001102f, 0.001284f, 0.001430f, 0.001417f, 0.001475f,
+ 0.001791f, 0.001989f, 0.002161f, 0.002388f, 0.002775f, 0.003017f, 0.003357f, 0.003763f, 0.004124f, 0.004383f, 0.004917f, 0.005436f,
+ 0.005840f, 0.006733f, 0.007511f, 0.008667f, 0.009567f, 0.011032f, 0.012474f, 0.014610f, 0.016739f, 0.019379f, 0.022873f, 0.027252f,
+ 0.032410f, 0.039062f, 0.048065f, 0.059296f, 0.074646f, 0.094971f, 0.123108f, 0.161011f, 0.211426f, 0.277344f, 0.358154f, 0.450195f,
+ 0.545410f, 0.636230f, 0.715332f, 0.781250f, 0.832520f, 0.872070f, 0.960449f, 0.962402f, 0.963867f, 0.963379f, 0.962891f, 0.963379f,
+ 0.000000f, 0.000000f, 0.000098f, 0.000301f, 0.000315f, 0.000566f, 0.000587f, 0.000627f, 0.000643f, 0.000795f, 0.000974f, 0.001023f,
+ 0.000987f, 0.001031f, 0.001245f, 0.001470f, 0.001637f, 0.001820f, 0.001884f, 0.002146f, 0.002357f, 0.002630f, 0.002913f, 0.003164f,
+ 0.003380f, 0.003824f, 0.004189f, 0.004353f, 0.004940f, 0.005688f, 0.006409f, 0.007347f, 0.008018f, 0.009163f, 0.010559f, 0.012039f,
+ 0.013695f, 0.016144f, 0.018723f, 0.022354f, 0.026337f, 0.031433f, 0.038818f, 0.047546f, 0.059662f, 0.075623f, 0.097473f, 0.127808f,
+ 0.169556f, 0.225830f, 0.299072f, 0.387451f, 0.486084f, 0.583984f, 0.674805f, 0.751465f, 0.812012f, 0.859375f, 0.957031f, 0.958984f,
+ 0.959473f, 0.959961f, 0.959961f, 0.959961f, 0.000000f, 0.000000f, 0.000004f, 0.000078f, 0.000408f, 0.000432f, 0.000563f, 0.000560f,
+ 0.000566f, 0.000623f, 0.000782f, 0.000829f, 0.000896f, 0.000956f, 0.001056f, 0.001249f, 0.001414f, 0.001473f, 0.001646f, 0.001764f,
+ 0.002066f, 0.002230f, 0.002436f, 0.002651f, 0.003012f, 0.003252f, 0.003414f, 0.004055f, 0.004143f, 0.004784f, 0.005356f, 0.006077f,
+ 0.006870f, 0.007538f, 0.008728f, 0.009834f, 0.011322f, 0.013130f, 0.015427f, 0.017914f, 0.021271f, 0.025436f, 0.030960f, 0.038086f,
+ 0.047485f, 0.060303f, 0.077087f, 0.101196f, 0.134521f, 0.180786f, 0.244507f, 0.326172f, 0.423584f, 0.527832f, 0.628418f, 0.716797f,
+ 0.788086f, 0.843262f, 0.953125f, 0.955566f, 0.955566f, 0.956543f, 0.956055f, 0.956543f, 0.000000f, 0.000000f, 0.000000f, 0.000236f,
+ 0.000320f, 0.000484f, 0.000521f, 0.000549f, 0.000556f, 0.000584f, 0.000574f, 0.000690f, 0.000758f, 0.000841f, 0.001003f, 0.001013f,
+ 0.001169f, 0.001292f, 0.001437f, 0.001658f, 0.001830f, 0.002001f, 0.002081f, 0.002146f, 0.002434f, 0.002712f, 0.002964f, 0.003220f,
+ 0.003513f, 0.003963f, 0.004410f, 0.004875f, 0.005608f, 0.006245f, 0.007179f, 0.008118f, 0.009201f, 0.010582f, 0.012360f, 0.014343f,
+ 0.016968f, 0.020401f, 0.024628f, 0.030365f, 0.037567f, 0.047455f, 0.060913f, 0.079529f, 0.105774f, 0.143555f, 0.196167f, 0.268799f,
+ 0.361084f, 0.467041f, 0.576172f, 0.676758f, 0.760254f, 0.825195f, 0.948242f, 0.951660f, 0.951660f, 0.951660f, 0.951660f, 0.951660f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000122f, 0.000257f, 0.000334f, 0.000390f, 0.000496f, 0.000520f, 0.000539f, 0.000590f, 0.000602f,
+ 0.000646f, 0.000725f, 0.000909f, 0.000949f, 0.001023f, 0.001121f, 0.001181f, 0.001308f, 0.001474f, 0.001457f, 0.001714f, 0.002007f,
+ 0.001929f, 0.002039f, 0.002468f, 0.002672f, 0.003025f, 0.003317f, 0.003635f, 0.004047f, 0.004433f, 0.004864f, 0.005756f, 0.006493f,
+ 0.007515f, 0.008331f, 0.009697f, 0.011383f, 0.014000f, 0.016235f, 0.019653f, 0.024185f, 0.029465f, 0.037109f, 0.047699f, 0.062164f,
+ 0.082642f, 0.112488f, 0.155151f, 0.216919f, 0.300049f, 0.404541f, 0.520020f, 0.631836f, 0.728516f, 0.805664f, 0.943848f, 0.946289f,
+ 0.946777f, 0.946777f, 0.947266f, 0.947266f, 0.000000f, 0.000000f, 0.000122f, 0.000088f, 0.000219f, 0.000229f, 0.000355f, 0.000414f,
+ 0.000482f, 0.000545f, 0.000559f, 0.000568f, 0.000481f, 0.000668f, 0.000636f, 0.000728f, 0.000924f, 0.000980f, 0.001017f, 0.001109f,
+ 0.001258f, 0.001353f, 0.001451f, 0.001564f, 0.001621f, 0.001740f, 0.002066f, 0.002289f, 0.002459f, 0.002621f, 0.002975f, 0.003349f,
+ 0.003588f, 0.003998f, 0.004723f, 0.005116f, 0.006035f, 0.006859f, 0.007957f, 0.009064f, 0.010658f, 0.012711f, 0.015511f, 0.018555f,
+ 0.023026f, 0.028854f, 0.037140f, 0.048035f, 0.064026f, 0.086914f, 0.121033f, 0.171387f, 0.244141f, 0.341797f, 0.458740f, 0.580078f,
+ 0.691895f, 0.780762f, 0.937988f, 0.940430f, 0.941406f, 0.940918f, 0.941895f, 0.941406f, 0.000000f, 0.000000f, 0.000000f, 0.000080f,
+ 0.000211f, 0.000221f, 0.000225f, 0.000192f, 0.000352f, 0.000368f, 0.000397f, 0.000529f, 0.000510f, 0.000504f, 0.000540f, 0.000671f,
+ 0.000694f, 0.000763f, 0.000902f, 0.000998f, 0.001063f, 0.001074f, 0.001128f, 0.001407f, 0.001370f, 0.001449f, 0.001682f, 0.001635f,
+ 0.001976f, 0.002108f, 0.002335f, 0.002558f, 0.002905f, 0.003176f, 0.003637f, 0.003948f, 0.004650f, 0.005341f, 0.006237f, 0.007034f,
+ 0.008415f, 0.009811f, 0.012032f, 0.014565f, 0.017731f, 0.022324f, 0.028427f, 0.036713f, 0.048859f, 0.066406f, 0.092957f, 0.133057f,
+ 0.193848f, 0.281250f, 0.395508f, 0.524902f, 0.648926f, 0.754395f, 0.931152f, 0.934570f, 0.934570f, 0.934570f, 0.935547f, 0.935059f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000181f, 0.000196f, 0.000236f, 0.000250f, 0.000226f, 0.000281f, 0.000335f, 0.000457f,
+ 0.000406f, 0.000511f, 0.000522f, 0.000593f, 0.000539f, 0.000663f, 0.000661f, 0.000779f, 0.000978f, 0.000855f, 0.000937f, 0.001128f,
+ 0.001163f, 0.001253f, 0.001241f, 0.001531f, 0.001595f, 0.001796f, 0.001888f, 0.002226f, 0.002350f, 0.002609f, 0.002787f, 0.003260f,
+ 0.003656f, 0.004303f, 0.004910f, 0.005577f, 0.006683f, 0.007603f, 0.009102f, 0.011017f, 0.013603f, 0.016968f, 0.021652f, 0.027939f,
+ 0.037109f, 0.050262f, 0.070374f, 0.101624f, 0.150391f, 0.225220f, 0.331543f, 0.463867f, 0.601074f, 0.723145f, 0.923828f, 0.927246f,
+ 0.927246f, 0.928223f, 0.927734f, 0.928223f, 0.000000f, 0.000000f, 0.000122f, 0.000121f, 0.000121f, 0.000174f, 0.000156f, 0.000204f,
+ 0.000180f, 0.000221f, 0.000246f, 0.000346f, 0.000313f, 0.000426f, 0.000468f, 0.000482f, 0.000559f, 0.000582f, 0.000536f, 0.000611f,
+ 0.000770f, 0.000666f, 0.000919f, 0.000947f, 0.001013f, 0.000948f, 0.001129f, 0.001169f, 0.001463f, 0.001579f, 0.001540f, 0.001555f,
+ 0.001888f, 0.002007f, 0.002390f, 0.002623f, 0.002708f, 0.003235f, 0.003584f, 0.004223f, 0.005001f, 0.005791f, 0.006905f, 0.008118f,
+ 0.010117f, 0.012512f, 0.015961f, 0.020798f, 0.027374f, 0.037628f, 0.052673f, 0.076172f, 0.114197f, 0.175659f, 0.270752f, 0.399658f,
+ 0.546875f, 0.687012f, 0.915527f, 0.918457f, 0.919434f, 0.919434f, 0.919434f, 0.919434f, 0.000000f, 0.000000f, 0.000121f, 0.000121f,
+ 0.000121f, 0.000120f, 0.000139f, 0.000141f, 0.000152f, 0.000186f, 0.000209f, 0.000222f, 0.000297f, 0.000330f, 0.000367f, 0.000403f,
+ 0.000433f, 0.000456f, 0.000457f, 0.000484f, 0.000521f, 0.000544f, 0.000594f, 0.000807f, 0.000790f, 0.000841f, 0.000784f, 0.001025f,
+ 0.001112f, 0.001014f, 0.001146f, 0.001287f, 0.001485f, 0.001541f, 0.001740f, 0.002014f, 0.002264f, 0.002460f, 0.002825f, 0.003124f,
+ 0.003683f, 0.004177f, 0.005024f, 0.006004f, 0.007454f, 0.009041f, 0.011833f, 0.014839f, 0.019791f, 0.027283f, 0.038361f, 0.055817f,
+ 0.084656f, 0.133057f, 0.213013f, 0.334717f, 0.488770f, 0.645996f, 0.905762f, 0.909668f, 0.909668f, 0.909180f, 0.910645f, 0.908691f,
+ 0.000000f, 0.000000f, 0.000121f, 0.000121f, 0.000120f, 0.000120f, 0.000119f, 0.000115f, 0.000104f, 0.000105f, 0.000203f, 0.000235f,
+ 0.000185f, 0.000290f, 0.000201f, 0.000306f, 0.000259f, 0.000370f, 0.000401f, 0.000428f, 0.000596f, 0.000617f, 0.000474f, 0.000593f,
+ 0.000641f, 0.000676f, 0.000682f, 0.000826f, 0.000897f, 0.000934f, 0.000972f, 0.000972f, 0.001213f, 0.001281f, 0.001410f, 0.001451f,
+ 0.001562f, 0.001786f, 0.002031f, 0.002417f, 0.002764f, 0.003162f, 0.003763f, 0.004406f, 0.005310f, 0.006454f, 0.008156f, 0.010849f,
+ 0.014305f, 0.019318f, 0.027328f, 0.039856f, 0.061310f, 0.097717f, 0.162354f, 0.270752f, 0.424805f, 0.599609f, 0.894043f, 0.897949f,
+ 0.898438f, 0.898438f, 0.898926f, 0.898438f, 0.000000f, 0.000121f, 0.000121f, 0.000120f, 0.000119f, 0.000119f, 0.000118f, 0.000118f,
+ 0.000112f, 0.000102f, 0.000094f, 0.000109f, 0.000131f, 0.000145f, 0.000232f, 0.000171f, 0.000278f, 0.000230f, 0.000347f, 0.000331f,
+ 0.000379f, 0.000381f, 0.000512f, 0.000427f, 0.000541f, 0.000566f, 0.000547f, 0.000613f, 0.000706f, 0.000660f, 0.000809f, 0.000941f,
+ 0.000950f, 0.001035f, 0.001069f, 0.001220f, 0.001149f, 0.001314f, 0.001603f, 0.001801f, 0.002062f, 0.002394f, 0.002737f, 0.003057f,
+ 0.003771f, 0.004471f, 0.005875f, 0.007217f, 0.009651f, 0.013344f, 0.018829f, 0.027710f, 0.043091f, 0.069214f, 0.119141f, 0.210571f,
+ 0.358398f, 0.544922f, 0.881348f, 0.883789f, 0.885254f, 0.885742f, 0.885254f, 0.885254f, 0.000000f, 0.000121f, 0.000120f, 0.000119f,
+ 0.000119f, 0.000118f, 0.000117f, 0.000116f, 0.000116f, 0.000110f, 0.000101f, 0.000094f, 0.000087f, 0.000157f, 0.000151f, 0.000168f,
+ 0.000146f, 0.000219f, 0.000214f, 0.000261f, 0.000313f, 0.000363f, 0.000311f, 0.000415f, 0.000476f, 0.000448f, 0.000429f, 0.000460f,
+ 0.000481f, 0.000560f, 0.000544f, 0.000695f, 0.000626f, 0.000789f, 0.000877f, 0.000894f, 0.000948f, 0.001177f, 0.001175f, 0.001366f,
+ 0.001487f, 0.001738f, 0.002008f, 0.002304f, 0.002663f, 0.003250f, 0.004002f, 0.004932f, 0.006416f, 0.008636f, 0.012344f, 0.018127f,
+ 0.028610f, 0.047150f, 0.083923f, 0.156860f, 0.291260f, 0.487305f, 0.866211f, 0.869141f, 0.870605f, 0.870117f, 0.871094f, 0.870117f,
+ 0.000000f, 0.000000f, 0.000119f, 0.000118f, 0.000117f, 0.000116f, 0.000115f, 0.000115f, 0.000114f, 0.000114f, 0.000109f, 0.000101f,
+ 0.000094f, 0.000087f, 0.000081f, 0.000085f, 0.000129f, 0.000150f, 0.000176f, 0.000193f, 0.000216f, 0.000257f, 0.000241f, 0.000302f,
+ 0.000259f, 0.000299f, 0.000397f, 0.000403f, 0.000384f, 0.000402f, 0.000425f, 0.000582f, 0.000467f, 0.000614f, 0.000660f, 0.000625f,
+ 0.000650f, 0.000819f, 0.000790f, 0.000879f, 0.001001f, 0.001140f, 0.001403f, 0.001555f, 0.001844f, 0.002213f, 0.002636f, 0.003235f,
+ 0.004082f, 0.005604f, 0.007896f, 0.011292f, 0.018005f, 0.030472f, 0.055786f, 0.109985f, 0.224976f, 0.421875f, 0.848145f, 0.852539f,
+ 0.853027f, 0.852539f, 0.852539f, 0.853027f, 0.000000f, 0.000119f, 0.000118f, 0.000116f, 0.000115f, 0.000114f, 0.000113f, 0.000112f,
+ 0.000111f, 0.000111f, 0.000110f, 0.000108f, 0.000101f, 0.000094f, 0.000088f, 0.000082f, 0.000077f, 0.000109f, 0.000068f, 0.000102f,
+ 0.000127f, 0.000158f, 0.000177f, 0.000192f, 0.000207f, 0.000214f, 0.000249f, 0.000278f, 0.000296f, 0.000320f, 0.000330f, 0.000342f,
+ 0.000415f, 0.000371f, 0.000389f, 0.000508f, 0.000463f, 0.000586f, 0.000606f, 0.000649f, 0.000724f, 0.000841f, 0.000910f, 0.001065f,
+ 0.001236f, 0.001475f, 0.001807f, 0.002138f, 0.002716f, 0.003622f, 0.004921f, 0.006950f, 0.010574f, 0.018433f, 0.034607f, 0.072449f,
+ 0.163818f, 0.352295f, 0.827637f, 0.831055f, 0.831543f, 0.832031f, 0.833008f, 0.832520f, 0.000120f, 0.000116f, 0.000114f, 0.000113f,
+ 0.000111f, 0.000110f, 0.000109f, 0.000108f, 0.000107f, 0.000106f, 0.000106f, 0.000105f, 0.000104f, 0.000101f, 0.000094f, 0.000088f,
+ 0.000083f, 0.000078f, 0.000073f, 0.000092f, 0.000064f, 0.000097f, 0.000073f, 0.000105f, 0.000125f, 0.000162f, 0.000179f, 0.000177f,
+ 0.000191f, 0.000221f, 0.000241f, 0.000235f, 0.000270f, 0.000277f, 0.000287f, 0.000329f, 0.000319f, 0.000428f, 0.000417f, 0.000409f,
+ 0.000524f, 0.000537f, 0.000612f, 0.000750f, 0.000770f, 0.000961f, 0.001153f, 0.001347f, 0.001702f, 0.002081f, 0.002903f, 0.003956f,
+ 0.006184f, 0.010368f, 0.019592f, 0.043427f, 0.109924f, 0.280518f, 0.803223f, 0.806152f, 0.807617f, 0.808594f, 0.809082f, 0.808105f,
+ 0.000000f, 0.000111f, 0.000106f, 0.000107f, 0.000104f, 0.000103f, 0.000101f, 0.000101f, 0.000101f, 0.000100f, 0.000099f, 0.000098f,
+ 0.000097f, 0.000097f, 0.000097f, 0.000094f, 0.000088f, 0.000083f, 0.000078f, 0.000073f, 0.000069f, 0.000070f, 0.000061f, 0.000068f,
+ 0.000059f, 0.000067f, 0.000084f, 0.000097f, 0.000128f, 0.000137f, 0.000165f, 0.000160f, 0.000176f, 0.000185f, 0.000217f, 0.000239f,
+ 0.000237f, 0.000238f, 0.000272f, 0.000281f, 0.000314f, 0.000372f, 0.000395f, 0.000430f, 0.000504f, 0.000578f, 0.000665f, 0.000856f,
+ 0.000969f, 0.001210f, 0.001594f, 0.002216f, 0.003370f, 0.005527f, 0.010170f, 0.023239f, 0.066101f, 0.207275f, 0.775391f, 0.779785f,
+ 0.780273f, 0.780762f, 0.780273f, 0.780762f, 0.000000f, 0.000094f, 0.000097f, 0.000095f, 0.000092f, 0.000091f, 0.000091f, 0.000090f,
+ 0.000089f, 0.000089f, 0.000088f, 0.000088f, 0.000087f, 0.000086f, 0.000087f, 0.000086f, 0.000086f, 0.000085f, 0.000081f, 0.000076f,
+ 0.000072f, 0.000068f, 0.000064f, 0.000060f, 0.000057f, 0.000054f, 0.000058f, 0.000048f, 0.000048f, 0.000069f, 0.000068f, 0.000092f,
+ 0.000110f, 0.000122f, 0.000133f, 0.000136f, 0.000146f, 0.000154f, 0.000175f, 0.000194f, 0.000204f, 0.000206f, 0.000238f, 0.000262f,
+ 0.000266f, 0.000338f, 0.000361f, 0.000432f, 0.000527f, 0.000659f, 0.000848f, 0.001183f, 0.001713f, 0.002661f, 0.004921f, 0.010887f,
+ 0.033936f, 0.138428f, 0.743652f, 0.747559f, 0.748047f, 0.748535f, 0.749512f, 0.749023f, 0.000045f, 0.000047f, 0.000059f, 0.000059f,
+ 0.000063f, 0.000068f, 0.000068f, 0.000068f, 0.000067f, 0.000069f, 0.000068f, 0.000070f, 0.000070f, 0.000070f, 0.000071f, 0.000070f,
+ 0.000071f, 0.000071f, 0.000071f, 0.000071f, 0.000071f, 0.000069f, 0.000065f, 0.000062f, 0.000058f, 0.000055f, 0.000052f, 0.000049f,
+ 0.000046f, 0.000044f, 0.000041f, 0.000050f, 0.000051f, 0.000048f, 0.000061f, 0.000070f, 0.000084f, 0.000095f, 0.000107f, 0.000104f,
+ 0.000111f, 0.000128f, 0.000143f, 0.000154f, 0.000157f, 0.000186f, 0.000198f, 0.000216f, 0.000268f, 0.000315f, 0.000414f, 0.000537f,
+ 0.000735f, 0.001149f, 0.002075f, 0.004669f, 0.014175f, 0.077881f, 0.707031f, 0.710449f, 0.712402f, 0.711914f, 0.712891f, 0.712402f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000012f, 0.000013f, 0.000029f, 0.000028f, 0.000037f, 0.000035f, 0.000039f,
+ 0.000043f, 0.000043f, 0.000045f, 0.000045f, 0.000048f, 0.000048f, 0.000050f, 0.000051f, 0.000052f, 0.000052f, 0.000053f, 0.000054f,
+ 0.000054f, 0.000053f, 0.000050f, 0.000048f, 0.000045f, 0.000043f, 0.000040f, 0.000038f, 0.000036f, 0.000034f, 0.000032f, 0.000030f,
+ 0.000028f, 0.000030f, 0.000038f, 0.000043f, 0.000057f, 0.000069f, 0.000072f, 0.000073f, 0.000082f, 0.000095f, 0.000101f, 0.000099f,
+ 0.000116f, 0.000130f, 0.000184f, 0.000211f, 0.000301f, 0.000443f, 0.000737f, 0.001601f, 0.004978f, 0.032593f, 0.666504f, 0.669922f,
+ 0.669922f, 0.672363f, 0.670898f, 0.670410f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000010f, 0.000012f, 0.000015f, 0.000018f, 0.000021f,
+ 0.000022f, 0.000023f, 0.000025f, 0.000028f, 0.000029f, 0.000029f, 0.000031f, 0.000033f, 0.000033f, 0.000035f, 0.000035f, 0.000035f,
+ 0.000033f, 0.000031f, 0.000029f, 0.000028f, 0.000026f, 0.000024f, 0.000023f, 0.000021f, 0.000020f, 0.000019f, 0.000022f, 0.000022f,
+ 0.000030f, 0.000038f, 0.000042f, 0.000041f, 0.000052f, 0.000047f, 0.000064f, 0.000072f, 0.000078f, 0.000129f, 0.000201f, 0.000382f,
+ 0.001180f, 0.009117f, 0.620605f, 0.624512f, 0.625000f, 0.625000f, 0.625000f, 0.625488f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000003f, 0.000005f, 0.000007f, 0.000008f, 0.000010f, 0.000011f, 0.000012f, 0.000014f, 0.000016f, 0.000016f, 0.000018f, 0.000017f,
+ 0.000016f, 0.000015f, 0.000014f, 0.000013f, 0.000012f, 0.000011f, 0.000010f, 0.000009f, 0.000011f, 0.000014f, 0.000018f, 0.000018f,
+ 0.000021f, 0.000028f, 0.000035f, 0.000053f, 0.000136f, 0.001152f, 0.571777f, 0.575684f, 0.575684f, 0.576172f, 0.576660f, 0.576660f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f,
+ 0.000002f, 0.000004f, 0.000004f, 0.000004f, 0.000003f, 0.000003f, 0.000002f, 0.000004f, 0.000003f, 0.000011f, 0.520020f, 0.523926f,
+ 0.524902f, 0.524902f, 0.524902f, 0.524902f,
+ },
+ {
+ 0.119934f, 0.328857f, 0.480713f, 0.586914f, 0.663086f, 0.717773f, 0.759766f, 0.791504f, 0.818359f, 0.838867f, 0.856934f, 0.871094f,
+ 0.883301f, 0.894043f, 0.902832f, 0.911621f, 0.917969f, 0.924805f, 0.930664f, 0.936035f, 0.939941f, 0.944824f, 0.948242f, 0.951660f,
+ 0.954590f, 0.958008f, 0.961426f, 0.962891f, 0.966309f, 0.967285f, 0.970215f, 0.972656f, 0.973633f, 0.975586f, 0.977539f, 0.978516f,
+ 0.979980f, 0.981445f, 0.982910f, 0.984375f, 0.985352f, 0.986328f, 0.987793f, 0.988770f, 0.989746f, 0.990234f, 0.991699f, 0.992676f,
+ 0.993164f, 0.993652f, 0.994629f, 0.995117f, 0.996094f, 0.996582f, 0.997559f, 0.998047f, 0.998535f, 0.999023f, 0.999512f, 0.999023f,
+ 0.999023f, 0.998535f, 0.998535f, 0.998047f, 0.046875f, 0.160400f, 0.286621f, 0.405518f, 0.507812f, 0.590820f, 0.656250f, 0.708008f,
+ 0.748535f, 0.781250f, 0.809082f, 0.830566f, 0.848633f, 0.864258f, 0.877441f, 0.888672f, 0.898926f, 0.906738f, 0.915039f, 0.921387f,
+ 0.928223f, 0.933105f, 0.937988f, 0.942871f, 0.946777f, 0.950684f, 0.954102f, 0.957031f, 0.959961f, 0.962402f, 0.965332f, 0.966797f,
+ 0.969727f, 0.971191f, 0.973145f, 0.975098f, 0.977539f, 0.978027f, 0.980469f, 0.981934f, 0.982910f, 0.984375f, 0.985352f, 0.986816f,
+ 0.987793f, 0.988770f, 0.989258f, 0.990723f, 0.991699f, 0.992676f, 0.993164f, 0.993652f, 0.994629f, 0.995605f, 0.996582f, 0.996582f,
+ 0.997559f, 0.998047f, 0.999023f, 0.999023f, 0.999023f, 0.998535f, 0.998535f, 0.998047f, 0.023788f, 0.084473f, 0.163696f, 0.255615f,
+ 0.351807f, 0.445312f, 0.527832f, 0.597656f, 0.656738f, 0.703613f, 0.742676f, 0.775879f, 0.802734f, 0.824707f, 0.843262f, 0.858887f,
+ 0.873047f, 0.884766f, 0.895508f, 0.903809f, 0.913086f, 0.919434f, 0.925781f, 0.931641f, 0.937012f, 0.941406f, 0.945801f, 0.949707f,
+ 0.953125f, 0.956543f, 0.959473f, 0.962402f, 0.964844f, 0.967285f, 0.969238f, 0.972168f, 0.973633f, 0.975098f, 0.977539f, 0.979492f,
+ 0.980469f, 0.981445f, 0.982910f, 0.984375f, 0.985840f, 0.986816f, 0.988281f, 0.988770f, 0.989746f, 0.990723f, 0.992188f, 0.992676f,
+ 0.993652f, 0.994629f, 0.995605f, 0.996094f, 0.996582f, 0.997559f, 0.998535f, 0.998535f, 0.998535f, 0.998047f, 0.998047f, 0.997559f,
+ 0.014595f, 0.050110f, 0.097717f, 0.158569f, 0.230347f, 0.311523f, 0.394531f, 0.473145f, 0.544922f, 0.606934f, 0.660645f, 0.705566f,
+ 0.743164f, 0.775391f, 0.800781f, 0.822266f, 0.841309f, 0.856934f, 0.870605f, 0.883301f, 0.894043f, 0.902832f, 0.911133f, 0.918945f,
+ 0.925293f, 0.931152f, 0.936035f, 0.941406f, 0.945801f, 0.949707f, 0.953125f, 0.956055f, 0.959473f, 0.962402f, 0.964844f, 0.967285f,
+ 0.970215f, 0.972168f, 0.974121f, 0.975098f, 0.977539f, 0.979004f, 0.980957f, 0.981934f, 0.983398f, 0.984375f, 0.985840f, 0.987305f,
+ 0.988281f, 0.989258f, 0.990723f, 0.991699f, 0.992676f, 0.993652f, 0.994629f, 0.995117f, 0.995605f, 0.996582f, 0.998535f, 0.998535f,
+ 0.998535f, 0.998047f, 0.998047f, 0.997559f, 0.009178f, 0.032379f, 0.062561f, 0.102417f, 0.151611f, 0.210938f, 0.279785f, 0.352783f,
+ 0.426758f, 0.496826f, 0.561035f, 0.618164f, 0.666992f, 0.708496f, 0.744141f, 0.773926f, 0.800781f, 0.821777f, 0.840820f, 0.856445f,
+ 0.870117f, 0.882324f, 0.893066f, 0.901855f, 0.910645f, 0.918457f, 0.925293f, 0.930176f, 0.935547f, 0.941406f, 0.946289f, 0.949707f,
+ 0.953125f, 0.956543f, 0.959961f, 0.962891f, 0.965332f, 0.967773f, 0.969727f, 0.972656f, 0.974121f, 0.976074f, 0.977539f, 0.979492f,
+ 0.981445f, 0.982422f, 0.984375f, 0.985840f, 0.986328f, 0.987793f, 0.989258f, 0.990234f, 0.991211f, 0.992188f, 0.993164f, 0.994141f,
+ 0.994629f, 0.995605f, 0.998047f, 0.998047f, 0.998047f, 0.997559f, 0.997559f, 0.997559f, 0.006382f, 0.022430f, 0.042908f, 0.068970f,
+ 0.102844f, 0.144653f, 0.195557f, 0.253906f, 0.318848f, 0.386230f, 0.454590f, 0.518066f, 0.577148f, 0.628906f, 0.675293f, 0.714844f,
+ 0.748535f, 0.777344f, 0.802246f, 0.823730f, 0.841797f, 0.856934f, 0.871094f, 0.882812f, 0.893555f, 0.902832f, 0.911133f, 0.918457f,
+ 0.925293f, 0.930176f, 0.937012f, 0.940918f, 0.945801f, 0.950195f, 0.953613f, 0.957031f, 0.960449f, 0.963379f, 0.966309f, 0.968262f,
+ 0.970703f, 0.973145f, 0.974609f, 0.976562f, 0.978516f, 0.980469f, 0.981934f, 0.983398f, 0.984375f, 0.985840f, 0.988281f, 0.988770f,
+ 0.989746f, 0.990723f, 0.991699f, 0.992676f, 0.993652f, 0.994629f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997559f, 0.997070f,
+ 0.004585f, 0.015961f, 0.030930f, 0.049133f, 0.072144f, 0.101013f, 0.137451f, 0.181519f, 0.232544f, 0.290039f, 0.352539f, 0.416748f,
+ 0.479736f, 0.538574f, 0.592773f, 0.641602f, 0.684570f, 0.723145f, 0.754395f, 0.782715f, 0.805176f, 0.825195f, 0.843750f, 0.859863f,
+ 0.872559f, 0.884766f, 0.895020f, 0.904297f, 0.912109f, 0.919922f, 0.926270f, 0.932129f, 0.937500f, 0.942383f, 0.946289f, 0.950195f,
+ 0.955078f, 0.958008f, 0.961426f, 0.964355f, 0.967285f, 0.969238f, 0.971680f, 0.974121f, 0.975586f, 0.977539f, 0.979492f, 0.980957f,
+ 0.982910f, 0.984375f, 0.985840f, 0.986328f, 0.988281f, 0.989746f, 0.990723f, 0.992188f, 0.992676f, 0.993164f, 0.997559f, 0.997559f,
+ 0.997070f, 0.997070f, 0.997070f, 0.997070f, 0.003483f, 0.012291f, 0.023209f, 0.036041f, 0.052429f, 0.073486f, 0.099182f, 0.131226f,
+ 0.169678f, 0.214844f, 0.266846f, 0.323242f, 0.383545f, 0.444580f, 0.503418f, 0.559082f, 0.609375f, 0.655762f, 0.695312f, 0.730957f,
+ 0.760254f, 0.788086f, 0.810059f, 0.829590f, 0.847168f, 0.862793f, 0.875488f, 0.886719f, 0.896973f, 0.906250f, 0.914551f, 0.921387f,
+ 0.927734f, 0.933594f, 0.938965f, 0.944336f, 0.948242f, 0.952148f, 0.956543f, 0.958984f, 0.961914f, 0.965332f, 0.968262f, 0.970703f,
+ 0.972656f, 0.974609f, 0.977051f, 0.979004f, 0.980469f, 0.981934f, 0.983887f, 0.985352f, 0.986328f, 0.987793f, 0.989746f, 0.990234f,
+ 0.991699f, 0.992676f, 0.996582f, 0.997070f, 0.997070f, 0.996582f, 0.996582f, 0.996094f, 0.002962f, 0.009613f, 0.017792f, 0.027481f,
+ 0.039429f, 0.055176f, 0.073914f, 0.096985f, 0.125610f, 0.159180f, 0.199707f, 0.246216f, 0.297607f, 0.353760f, 0.412842f, 0.470215f,
+ 0.526367f, 0.578613f, 0.626953f, 0.669434f, 0.707031f, 0.740723f, 0.769043f, 0.794922f, 0.814941f, 0.835449f, 0.851074f, 0.866699f,
+ 0.879395f, 0.890137f, 0.899902f, 0.909180f, 0.916992f, 0.924316f, 0.929688f, 0.936035f, 0.941406f, 0.945312f, 0.950195f, 0.953613f,
+ 0.957520f, 0.960938f, 0.963867f, 0.966797f, 0.969238f, 0.971680f, 0.974121f, 0.976562f, 0.979004f, 0.979980f, 0.981934f, 0.982910f,
+ 0.984375f, 0.986816f, 0.987793f, 0.988770f, 0.990234f, 0.991699f, 0.996582f, 0.996582f, 0.996582f, 0.996582f, 0.996094f, 0.996094f,
+ 0.002077f, 0.007637f, 0.013802f, 0.021606f, 0.031006f, 0.042419f, 0.055969f, 0.073242f, 0.094055f, 0.119446f, 0.150513f, 0.186401f,
+ 0.228638f, 0.276123f, 0.328857f, 0.384277f, 0.440674f, 0.496338f, 0.549805f, 0.598633f, 0.644043f, 0.683594f, 0.719727f, 0.750977f,
+ 0.779297f, 0.802246f, 0.823730f, 0.840820f, 0.855957f, 0.871582f, 0.882324f, 0.893555f, 0.903809f, 0.911621f, 0.920410f, 0.926758f,
+ 0.932617f, 0.938477f, 0.943359f, 0.947754f, 0.953125f, 0.955566f, 0.959473f, 0.962402f, 0.965332f, 0.968262f, 0.970703f, 0.972656f,
+ 0.976074f, 0.977051f, 0.979492f, 0.981445f, 0.983398f, 0.984863f, 0.986328f, 0.987793f, 0.989258f, 0.990723f, 0.995605f, 0.996094f,
+ 0.996094f, 0.996094f, 0.996094f, 0.995605f, 0.002014f, 0.006035f, 0.011299f, 0.017410f, 0.024368f, 0.033020f, 0.043701f, 0.056458f,
+ 0.072205f, 0.091431f, 0.114807f, 0.141968f, 0.174316f, 0.213257f, 0.256836f, 0.306152f, 0.358887f, 0.413330f, 0.468018f, 0.520996f,
+ 0.572266f, 0.618652f, 0.661621f, 0.699707f, 0.732910f, 0.762695f, 0.788574f, 0.810547f, 0.830078f, 0.848145f, 0.862305f, 0.875977f,
+ 0.887695f, 0.898438f, 0.907227f, 0.915527f, 0.922852f, 0.929199f, 0.936035f, 0.940918f, 0.946289f, 0.950684f, 0.953613f, 0.958496f,
+ 0.960938f, 0.964355f, 0.967285f, 0.970215f, 0.972656f, 0.975586f, 0.977539f, 0.979492f, 0.980957f, 0.982910f, 0.984863f, 0.986328f,
+ 0.987793f, 0.988770f, 0.995117f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.001496f, 0.005196f, 0.009201f, 0.013985f,
+ 0.019806f, 0.026413f, 0.034943f, 0.044647f, 0.056641f, 0.070923f, 0.088623f, 0.109680f, 0.135254f, 0.164795f, 0.200073f, 0.240845f,
+ 0.285645f, 0.335449f, 0.387939f, 0.441650f, 0.495850f, 0.546875f, 0.595215f, 0.639160f, 0.679199f, 0.715820f, 0.746582f, 0.774414f,
+ 0.798828f, 0.819824f, 0.837402f, 0.854492f, 0.869629f, 0.881348f, 0.893066f, 0.902832f, 0.912109f, 0.918945f, 0.926758f, 0.933105f,
+ 0.938477f, 0.943359f, 0.948730f, 0.952637f, 0.956055f, 0.960449f, 0.963379f, 0.966797f, 0.969238f, 0.972656f, 0.975098f, 0.977051f,
+ 0.979004f, 0.981445f, 0.982910f, 0.984375f, 0.986328f, 0.987305f, 0.994629f, 0.995605f, 0.995117f, 0.995117f, 0.995117f, 0.994629f,
+ 0.001187f, 0.004314f, 0.007740f, 0.011337f, 0.016373f, 0.021759f, 0.028198f, 0.035889f, 0.045197f, 0.056580f, 0.069946f, 0.085938f,
+ 0.105408f, 0.128784f, 0.155884f, 0.187866f, 0.225830f, 0.268066f, 0.315186f, 0.365479f, 0.418213f, 0.471680f, 0.522949f, 0.572754f,
+ 0.617676f, 0.659668f, 0.697754f, 0.730957f, 0.760742f, 0.787109f, 0.809570f, 0.830078f, 0.846680f, 0.862793f, 0.875488f, 0.888184f,
+ 0.898926f, 0.907715f, 0.916016f, 0.923340f, 0.930664f, 0.936523f, 0.941895f, 0.947754f, 0.951660f, 0.955566f, 0.959473f, 0.963867f,
+ 0.966309f, 0.969238f, 0.972168f, 0.974121f, 0.976562f, 0.979004f, 0.980957f, 0.982910f, 0.984863f, 0.986816f, 0.994141f, 0.994629f,
+ 0.994629f, 0.994629f, 0.994629f, 0.994141f, 0.001187f, 0.003733f, 0.006496f, 0.009918f, 0.013634f, 0.017899f, 0.023026f, 0.029343f,
+ 0.036621f, 0.045227f, 0.055786f, 0.068298f, 0.083740f, 0.101135f, 0.122314f, 0.147827f, 0.177612f, 0.212891f, 0.252686f, 0.297119f,
+ 0.345215f, 0.395996f, 0.448730f, 0.500488f, 0.550781f, 0.597656f, 0.641113f, 0.680664f, 0.716309f, 0.747559f, 0.774414f, 0.799316f,
+ 0.820312f, 0.838867f, 0.855957f, 0.870117f, 0.883301f, 0.894531f, 0.904785f, 0.913086f, 0.920898f, 0.928223f, 0.935059f, 0.940430f,
+ 0.945312f, 0.950684f, 0.955566f, 0.958496f, 0.962891f, 0.965820f, 0.968750f, 0.971680f, 0.974609f, 0.976562f, 0.978516f, 0.980957f,
+ 0.982910f, 0.984863f, 0.994141f, 0.994141f, 0.994629f, 0.994141f, 0.994141f, 0.994629f, 0.000998f, 0.003178f, 0.005444f, 0.008179f,
+ 0.011337f, 0.015091f, 0.019058f, 0.024368f, 0.029587f, 0.037140f, 0.045197f, 0.055115f, 0.066772f, 0.080688f, 0.097229f, 0.117371f,
+ 0.140869f, 0.169312f, 0.201538f, 0.238770f, 0.280762f, 0.326660f, 0.376709f, 0.427490f, 0.479248f, 0.530273f, 0.578613f, 0.623535f,
+ 0.664551f, 0.701660f, 0.733887f, 0.763672f, 0.790039f, 0.812500f, 0.832520f, 0.849121f, 0.865234f, 0.878906f, 0.890625f, 0.901367f,
+ 0.910645f, 0.919434f, 0.926758f, 0.933105f, 0.939453f, 0.944824f, 0.949707f, 0.954590f, 0.958008f, 0.961914f, 0.965332f, 0.968750f,
+ 0.971680f, 0.974121f, 0.977051f, 0.979004f, 0.980957f, 0.982910f, 0.993164f, 0.993164f, 0.994141f, 0.993652f, 0.993652f, 0.993164f,
+ 0.000948f, 0.002638f, 0.004784f, 0.007153f, 0.009590f, 0.012505f, 0.016388f, 0.020599f, 0.025299f, 0.031097f, 0.037323f, 0.045197f,
+ 0.054047f, 0.065002f, 0.078674f, 0.094055f, 0.112305f, 0.134399f, 0.160889f, 0.191040f, 0.226318f, 0.265869f, 0.310303f, 0.358154f,
+ 0.409180f, 0.459473f, 0.510254f, 0.559082f, 0.606445f, 0.648926f, 0.687500f, 0.722168f, 0.753418f, 0.781250f, 0.804199f, 0.825684f,
+ 0.843262f, 0.860840f, 0.874512f, 0.886719f, 0.898926f, 0.907227f, 0.916992f, 0.924805f, 0.932129f, 0.937988f, 0.943848f, 0.949219f,
+ 0.954102f, 0.958496f, 0.961426f, 0.965332f, 0.968750f, 0.972168f, 0.974609f, 0.977051f, 0.979492f, 0.981445f, 0.992188f, 0.993164f,
+ 0.993164f, 0.993164f, 0.993164f, 0.992676f, 0.000696f, 0.002352f, 0.004002f, 0.006138f, 0.008446f, 0.010826f, 0.013840f, 0.017258f,
+ 0.021194f, 0.025970f, 0.031128f, 0.037140f, 0.044281f, 0.053436f, 0.063660f, 0.076050f, 0.090271f, 0.107727f, 0.128662f, 0.152832f,
+ 0.182007f, 0.214111f, 0.252930f, 0.295166f, 0.341553f, 0.390625f, 0.442139f, 0.492676f, 0.541992f, 0.589844f, 0.633301f, 0.674316f,
+ 0.710938f, 0.743652f, 0.772461f, 0.796875f, 0.819824f, 0.839355f, 0.854980f, 0.870605f, 0.884277f, 0.895508f, 0.906738f, 0.915527f,
+ 0.923828f, 0.931152f, 0.937500f, 0.944336f, 0.949219f, 0.953613f, 0.958008f, 0.962402f, 0.965332f, 0.968750f, 0.972168f, 0.974609f,
+ 0.977051f, 0.979980f, 0.991211f, 0.992676f, 0.992188f, 0.992188f, 0.992188f, 0.992676f, 0.000838f, 0.002033f, 0.003664f, 0.005077f,
+ 0.007282f, 0.009415f, 0.011749f, 0.014931f, 0.017853f, 0.021606f, 0.025864f, 0.031219f, 0.037231f, 0.044464f, 0.052338f, 0.062500f,
+ 0.073853f, 0.087463f, 0.104065f, 0.123230f, 0.146362f, 0.173340f, 0.205078f, 0.240845f, 0.281982f, 0.326660f, 0.374756f, 0.425049f,
+ 0.476807f, 0.526855f, 0.574219f, 0.620117f, 0.662598f, 0.699219f, 0.733398f, 0.764160f, 0.791016f, 0.813965f, 0.833984f, 0.851074f,
+ 0.867676f, 0.880859f, 0.893555f, 0.904785f, 0.914062f, 0.922852f, 0.930176f, 0.937012f, 0.942383f, 0.948242f, 0.953125f, 0.957520f,
+ 0.962402f, 0.966309f, 0.969238f, 0.973145f, 0.975098f, 0.978027f, 0.991699f, 0.991699f, 0.992676f, 0.992188f, 0.991699f, 0.992188f,
+ 0.000600f, 0.001687f, 0.003023f, 0.004963f, 0.006405f, 0.008163f, 0.010368f, 0.012718f, 0.015480f, 0.018311f, 0.022064f, 0.026169f,
+ 0.031097f, 0.036926f, 0.043457f, 0.051392f, 0.060669f, 0.071350f, 0.084473f, 0.100220f, 0.118103f, 0.140259f, 0.166016f, 0.195679f,
+ 0.230469f, 0.269531f, 0.313232f, 0.360596f, 0.410156f, 0.460693f, 0.511719f, 0.560547f, 0.607422f, 0.650879f, 0.689941f, 0.724609f,
+ 0.756348f, 0.784180f, 0.808594f, 0.828613f, 0.847656f, 0.864258f, 0.879395f, 0.892090f, 0.903320f, 0.912598f, 0.921875f, 0.929688f,
+ 0.936523f, 0.942871f, 0.947754f, 0.953125f, 0.957520f, 0.961914f, 0.966309f, 0.969238f, 0.972656f, 0.975586f, 0.990234f, 0.991211f,
+ 0.991211f, 0.991699f, 0.991211f, 0.991211f, 0.000269f, 0.001538f, 0.002800f, 0.003868f, 0.005524f, 0.007179f, 0.008987f, 0.011063f,
+ 0.013084f, 0.015747f, 0.019211f, 0.022324f, 0.026474f, 0.031311f, 0.036530f, 0.042969f, 0.050201f, 0.059174f, 0.069641f, 0.081543f,
+ 0.096680f, 0.114075f, 0.134644f, 0.158691f, 0.187622f, 0.220581f, 0.258301f, 0.300781f, 0.347168f, 0.395996f, 0.447266f, 0.498291f,
+ 0.547852f, 0.595215f, 0.640625f, 0.680176f, 0.717285f, 0.749512f, 0.778320f, 0.803223f, 0.825684f, 0.845215f, 0.862793f, 0.877441f,
+ 0.890625f, 0.901855f, 0.912109f, 0.920898f, 0.929688f, 0.937012f, 0.942871f, 0.949707f, 0.954102f, 0.958496f, 0.962402f, 0.966309f,
+ 0.970215f, 0.974121f, 0.989746f, 0.990234f, 0.990723f, 0.990723f, 0.990723f, 0.990234f, 0.000341f, 0.001337f, 0.002573f, 0.003475f,
+ 0.004765f, 0.006329f, 0.007717f, 0.009499f, 0.011642f, 0.014107f, 0.016556f, 0.019470f, 0.022491f, 0.026169f, 0.030945f, 0.036011f,
+ 0.042389f, 0.049042f, 0.057678f, 0.067993f, 0.079468f, 0.093384f, 0.110046f, 0.129883f, 0.152710f, 0.180420f, 0.212158f, 0.248291f,
+ 0.289551f, 0.334961f, 0.383301f, 0.434570f, 0.485596f, 0.536133f, 0.584473f, 0.630371f, 0.671875f, 0.710449f, 0.743652f, 0.773926f,
+ 0.799316f, 0.823242f, 0.843262f, 0.860352f, 0.875977f, 0.889648f, 0.901367f, 0.911621f, 0.921387f, 0.929688f, 0.937012f, 0.943848f,
+ 0.950195f, 0.955078f, 0.959473f, 0.963379f, 0.967773f, 0.971191f, 0.988770f, 0.989746f, 0.990234f, 0.990234f, 0.990234f, 0.990234f,
+ 0.000564f, 0.001324f, 0.002092f, 0.003191f, 0.004471f, 0.005348f, 0.007069f, 0.008438f, 0.010201f, 0.011810f, 0.014297f, 0.016586f,
+ 0.019470f, 0.022644f, 0.026428f, 0.030579f, 0.035797f, 0.041718f, 0.048248f, 0.056213f, 0.065857f, 0.076782f, 0.090271f, 0.106262f,
+ 0.125122f, 0.147095f, 0.173462f, 0.204224f, 0.239746f, 0.279785f, 0.323730f, 0.372314f, 0.422607f, 0.474121f, 0.526367f, 0.575195f,
+ 0.621582f, 0.664062f, 0.703613f, 0.738770f, 0.769043f, 0.796387f, 0.820312f, 0.841797f, 0.858887f, 0.875488f, 0.889648f, 0.900879f,
+ 0.912598f, 0.921875f, 0.930664f, 0.937500f, 0.944336f, 0.950195f, 0.955566f, 0.959961f, 0.964844f, 0.968750f, 0.987305f, 0.989258f,
+ 0.989258f, 0.989258f, 0.989258f, 0.988770f, 0.000369f, 0.001128f, 0.001871f, 0.002792f, 0.003712f, 0.004723f, 0.006016f, 0.007542f,
+ 0.008896f, 0.010773f, 0.012421f, 0.014381f, 0.016632f, 0.019791f, 0.022354f, 0.025955f, 0.030609f, 0.035065f, 0.040924f, 0.047333f,
+ 0.055084f, 0.064209f, 0.075012f, 0.087769f, 0.102966f, 0.120911f, 0.142456f, 0.167358f, 0.197144f, 0.231812f, 0.270752f, 0.314209f,
+ 0.362549f, 0.412598f, 0.464844f, 0.515625f, 0.566895f, 0.614258f, 0.657715f, 0.698730f, 0.734863f, 0.766602f, 0.794922f, 0.818848f,
+ 0.839844f, 0.858887f, 0.875000f, 0.889648f, 0.901855f, 0.912598f, 0.922852f, 0.931152f, 0.938965f, 0.945312f, 0.951660f, 0.957520f,
+ 0.961426f, 0.966309f, 0.986816f, 0.988281f, 0.988281f, 0.988770f, 0.988281f, 0.988281f, 0.000466f, 0.000900f, 0.001792f, 0.002695f,
+ 0.003458f, 0.004204f, 0.005356f, 0.006512f, 0.007896f, 0.009300f, 0.010895f, 0.012459f, 0.014786f, 0.016739f, 0.019424f, 0.022461f,
+ 0.026062f, 0.029831f, 0.034851f, 0.039764f, 0.046417f, 0.053711f, 0.062164f, 0.072388f, 0.085205f, 0.099365f, 0.117004f, 0.137573f,
+ 0.162231f, 0.190674f, 0.224121f, 0.262451f, 0.305664f, 0.353027f, 0.403809f, 0.456055f, 0.508301f, 0.559082f, 0.608398f, 0.652832f,
+ 0.694824f, 0.731445f, 0.764160f, 0.793945f, 0.817871f, 0.839355f, 0.858398f, 0.875488f, 0.890137f, 0.902832f, 0.913574f, 0.923828f,
+ 0.932617f, 0.940918f, 0.946777f, 0.953613f, 0.958984f, 0.963379f, 0.985840f, 0.987305f, 0.987305f, 0.987793f, 0.987305f, 0.987305f,
+ 0.000234f, 0.001040f, 0.001661f, 0.002392f, 0.003101f, 0.003681f, 0.004944f, 0.005844f, 0.007065f, 0.008217f, 0.009247f, 0.010925f,
+ 0.012894f, 0.014549f, 0.017090f, 0.019455f, 0.022385f, 0.025650f, 0.029449f, 0.033936f, 0.039215f, 0.045135f, 0.052612f, 0.060944f,
+ 0.070312f, 0.082397f, 0.096924f, 0.113525f, 0.133179f, 0.156860f, 0.184814f, 0.217773f, 0.255127f, 0.298340f, 0.345215f, 0.395996f,
+ 0.448242f, 0.501953f, 0.553223f, 0.603516f, 0.649414f, 0.691895f, 0.729980f, 0.763184f, 0.792480f, 0.818359f, 0.841309f, 0.858887f,
+ 0.877441f, 0.891113f, 0.904785f, 0.915527f, 0.925781f, 0.933594f, 0.941895f, 0.949219f, 0.955566f, 0.960449f, 0.984863f, 0.985840f,
+ 0.986328f, 0.986816f, 0.986328f, 0.986816f, 0.000241f, 0.000808f, 0.001395f, 0.001986f, 0.002731f, 0.003429f, 0.004131f, 0.005402f,
+ 0.006077f, 0.007347f, 0.008522f, 0.009544f, 0.011345f, 0.013046f, 0.014534f, 0.016953f, 0.019241f, 0.022339f, 0.025208f, 0.029175f,
+ 0.033691f, 0.038300f, 0.044067f, 0.051331f, 0.059143f, 0.068726f, 0.080322f, 0.093567f, 0.109802f, 0.129883f, 0.152466f, 0.179810f,
+ 0.211792f, 0.249390f, 0.291748f, 0.338623f, 0.389404f, 0.442139f, 0.496338f, 0.548340f, 0.599121f, 0.645996f, 0.689941f, 0.728516f,
+ 0.762695f, 0.792969f, 0.818848f, 0.842285f, 0.862793f, 0.878906f, 0.894043f, 0.906250f, 0.917969f, 0.927734f, 0.935547f, 0.944336f,
+ 0.951172f, 0.957031f, 0.983398f, 0.985352f, 0.985840f, 0.985352f, 0.985840f, 0.985352f, 0.000340f, 0.000735f, 0.001377f, 0.001853f,
+ 0.002382f, 0.003159f, 0.004021f, 0.004642f, 0.005604f, 0.006340f, 0.007298f, 0.008591f, 0.009895f, 0.011154f, 0.012871f, 0.014580f,
+ 0.016876f, 0.019180f, 0.022141f, 0.024979f, 0.028748f, 0.032745f, 0.037964f, 0.043213f, 0.050171f, 0.057831f, 0.066833f, 0.078247f,
+ 0.091553f, 0.107178f, 0.125977f, 0.148315f, 0.175415f, 0.207153f, 0.244019f, 0.286377f, 0.333008f, 0.383789f, 0.437744f, 0.491943f,
+ 0.545410f, 0.597168f, 0.645508f, 0.688965f, 0.729004f, 0.764160f, 0.794434f, 0.821289f, 0.843750f, 0.864258f, 0.881348f, 0.895996f,
+ 0.909180f, 0.920898f, 0.929199f, 0.938965f, 0.946777f, 0.952637f, 0.982910f, 0.983887f, 0.984863f, 0.984863f, 0.984375f, 0.984863f,
+ 0.000236f, 0.000605f, 0.001135f, 0.001415f, 0.002329f, 0.002747f, 0.003551f, 0.004158f, 0.004723f, 0.005535f, 0.006687f, 0.007534f,
+ 0.008545f, 0.009979f, 0.011375f, 0.012993f, 0.014656f, 0.016754f, 0.018921f, 0.021759f, 0.024506f, 0.028183f, 0.032043f, 0.036743f,
+ 0.042236f, 0.048645f, 0.056030f, 0.065125f, 0.075928f, 0.089050f, 0.104370f, 0.122681f, 0.145142f, 0.171509f, 0.202759f, 0.239258f,
+ 0.281250f, 0.328369f, 0.379639f, 0.433838f, 0.489014f, 0.543945f, 0.596191f, 0.645020f, 0.690430f, 0.730957f, 0.766113f, 0.797852f,
+ 0.824219f, 0.846680f, 0.867188f, 0.884766f, 0.899414f, 0.912109f, 0.923828f, 0.933105f, 0.942383f, 0.949707f, 0.980957f, 0.982910f,
+ 0.983398f, 0.983398f, 0.983887f, 0.982910f, 0.000214f, 0.000710f, 0.001021f, 0.001429f, 0.001858f, 0.002607f, 0.003220f, 0.003738f,
+ 0.004459f, 0.005032f, 0.005726f, 0.006748f, 0.007748f, 0.008659f, 0.010002f, 0.011368f, 0.012985f, 0.014656f, 0.016525f, 0.018921f,
+ 0.021286f, 0.024231f, 0.027649f, 0.031464f, 0.035858f, 0.041321f, 0.047363f, 0.054840f, 0.063538f, 0.074097f, 0.086609f, 0.101990f,
+ 0.120117f, 0.141846f, 0.168213f, 0.199219f, 0.235352f, 0.277344f, 0.324707f, 0.376953f, 0.432373f, 0.488037f, 0.543457f, 0.597168f,
+ 0.646973f, 0.692871f, 0.732910f, 0.769531f, 0.801270f, 0.828125f, 0.850586f, 0.871582f, 0.888184f, 0.903809f, 0.915527f, 0.927246f,
+ 0.936523f, 0.946289f, 0.979492f, 0.981445f, 0.981934f, 0.982422f, 0.981934f, 0.981934f, 0.000000f, 0.000468f, 0.001076f, 0.001489f,
+ 0.002048f, 0.002413f, 0.002853f, 0.003468f, 0.003952f, 0.004444f, 0.005211f, 0.005917f, 0.006733f, 0.007763f, 0.008713f, 0.010262f,
+ 0.011368f, 0.012733f, 0.014458f, 0.016296f, 0.018478f, 0.021072f, 0.023666f, 0.026810f, 0.030746f, 0.035278f, 0.040131f, 0.046295f,
+ 0.053711f, 0.062195f, 0.072327f, 0.084717f, 0.099487f, 0.117371f, 0.139038f, 0.164795f, 0.195923f, 0.232422f, 0.274414f, 0.322266f,
+ 0.374756f, 0.431641f, 0.488525f, 0.545410f, 0.599121f, 0.650879f, 0.697754f, 0.738770f, 0.774414f, 0.806641f, 0.832520f, 0.856445f,
+ 0.875488f, 0.893555f, 0.907715f, 0.920410f, 0.931152f, 0.940918f, 0.978027f, 0.980469f, 0.980469f, 0.980957f, 0.980957f, 0.980957f,
+ 0.000279f, 0.000497f, 0.000763f, 0.001353f, 0.001794f, 0.002079f, 0.002451f, 0.002956f, 0.003498f, 0.004150f, 0.004589f, 0.005310f,
+ 0.006130f, 0.006958f, 0.007828f, 0.008888f, 0.009895f, 0.011124f, 0.012772f, 0.014282f, 0.016235f, 0.018127f, 0.020630f, 0.022873f,
+ 0.026321f, 0.029938f, 0.034241f, 0.039368f, 0.045319f, 0.052338f, 0.060852f, 0.070801f, 0.082947f, 0.097595f, 0.115051f, 0.136353f,
+ 0.162231f, 0.193481f, 0.229858f, 0.272217f, 0.321777f, 0.375000f, 0.432373f, 0.490479f, 0.548340f, 0.604004f, 0.655762f, 0.702637f,
+ 0.743652f, 0.780273f, 0.812500f, 0.838867f, 0.862305f, 0.881348f, 0.897949f, 0.912598f, 0.925293f, 0.935547f, 0.976562f, 0.978516f,
+ 0.979492f, 0.979980f, 0.979492f, 0.979004f, 0.000110f, 0.000473f, 0.000781f, 0.001262f, 0.001584f, 0.001890f, 0.002270f, 0.002607f,
+ 0.003241f, 0.003704f, 0.004055f, 0.004795f, 0.005356f, 0.005997f, 0.006760f, 0.007896f, 0.008896f, 0.009918f, 0.011200f, 0.012451f,
+ 0.013802f, 0.015556f, 0.017838f, 0.020065f, 0.022751f, 0.025864f, 0.029358f, 0.033600f, 0.038574f, 0.044342f, 0.050995f, 0.059296f,
+ 0.069214f, 0.081116f, 0.095459f, 0.113159f, 0.133911f, 0.160400f, 0.191406f, 0.228638f, 0.272217f, 0.321289f, 0.375732f, 0.434326f,
+ 0.493896f, 0.552734f, 0.609863f, 0.662109f, 0.709961f, 0.750977f, 0.787598f, 0.819336f, 0.846680f, 0.868164f, 0.887695f, 0.904297f,
+ 0.917969f, 0.930176f, 0.975098f, 0.977539f, 0.977051f, 0.977539f, 0.977539f, 0.977539f, 0.000242f, 0.000464f, 0.000831f, 0.001027f,
+ 0.001271f, 0.001722f, 0.001965f, 0.002243f, 0.002714f, 0.003036f, 0.003651f, 0.004025f, 0.004902f, 0.005638f, 0.006176f, 0.006943f,
+ 0.007763f, 0.008789f, 0.009804f, 0.010872f, 0.012070f, 0.013695f, 0.015381f, 0.017395f, 0.019608f, 0.022232f, 0.025009f, 0.028885f,
+ 0.032623f, 0.037659f, 0.043182f, 0.050018f, 0.058167f, 0.067810f, 0.079224f, 0.093811f, 0.111328f, 0.132324f, 0.158569f, 0.190063f,
+ 0.228149f, 0.271973f, 0.322510f, 0.378906f, 0.438477f, 0.499756f, 0.560059f, 0.618164f, 0.671387f, 0.718750f, 0.760742f, 0.796875f,
+ 0.826660f, 0.854492f, 0.875000f, 0.894531f, 0.911133f, 0.923828f, 0.973145f, 0.976074f, 0.975586f, 0.976074f, 0.976074f, 0.977051f,
+ 0.000242f, 0.000552f, 0.000701f, 0.001063f, 0.001186f, 0.001462f, 0.001690f, 0.002340f, 0.002703f, 0.002728f, 0.003325f, 0.003828f,
+ 0.004333f, 0.004913f, 0.005474f, 0.006077f, 0.006943f, 0.007607f, 0.008553f, 0.009460f, 0.010582f, 0.011871f, 0.013451f, 0.015091f,
+ 0.016983f, 0.019165f, 0.021637f, 0.024673f, 0.027863f, 0.031525f, 0.036713f, 0.041962f, 0.048615f, 0.056396f, 0.066162f, 0.077942f,
+ 0.092590f, 0.110046f, 0.130981f, 0.157593f, 0.189331f, 0.228394f, 0.273926f, 0.325684f, 0.383301f, 0.444580f, 0.507324f, 0.569824f,
+ 0.627441f, 0.682129f, 0.729980f, 0.770508f, 0.807129f, 0.837402f, 0.863281f, 0.884766f, 0.902832f, 0.917969f, 0.971191f, 0.973633f,
+ 0.974609f, 0.974121f, 0.974609f, 0.974609f, 0.000239f, 0.000239f, 0.000658f, 0.000899f, 0.001204f, 0.001252f, 0.001629f, 0.001815f,
+ 0.002470f, 0.002430f, 0.003134f, 0.003321f, 0.003925f, 0.004238f, 0.004856f, 0.005341f, 0.006161f, 0.006615f, 0.007511f, 0.008224f,
+ 0.009277f, 0.010445f, 0.011818f, 0.013046f, 0.014473f, 0.016510f, 0.018814f, 0.021057f, 0.023834f, 0.027237f, 0.030853f, 0.035675f,
+ 0.040894f, 0.047241f, 0.055145f, 0.064758f, 0.076782f, 0.090942f, 0.108398f, 0.130371f, 0.157104f, 0.189819f, 0.229248f, 0.276367f,
+ 0.329834f, 0.390137f, 0.453125f, 0.517578f, 0.580566f, 0.640625f, 0.694336f, 0.741699f, 0.782715f, 0.817871f, 0.848145f, 0.872559f,
+ 0.893555f, 0.910645f, 0.969727f, 0.971191f, 0.972656f, 0.972168f, 0.972168f, 0.972168f, 0.000222f, 0.000463f, 0.000620f, 0.000837f,
+ 0.000900f, 0.001048f, 0.001381f, 0.001820f, 0.001957f, 0.002329f, 0.002747f, 0.002964f, 0.003330f, 0.003986f, 0.004322f, 0.004677f,
+ 0.005302f, 0.005760f, 0.006569f, 0.007359f, 0.008141f, 0.009293f, 0.010101f, 0.011452f, 0.012779f, 0.014496f, 0.016144f, 0.018097f,
+ 0.020157f, 0.023148f, 0.026611f, 0.029785f, 0.034515f, 0.039856f, 0.046478f, 0.054016f, 0.063843f, 0.075378f, 0.089233f, 0.107666f,
+ 0.129639f, 0.156860f, 0.190674f, 0.231445f, 0.280518f, 0.336426f, 0.398193f, 0.463379f, 0.530273f, 0.595215f, 0.654785f, 0.708984f,
+ 0.755371f, 0.796875f, 0.831543f, 0.860352f, 0.883789f, 0.903809f, 0.966797f, 0.968750f, 0.969727f, 0.970215f, 0.970215f, 0.969727f,
+ 0.000000f, 0.000345f, 0.000464f, 0.000686f, 0.000782f, 0.001030f, 0.001139f, 0.001598f, 0.001846f, 0.002237f, 0.002489f, 0.002684f,
+ 0.003067f, 0.003344f, 0.003895f, 0.004158f, 0.004845f, 0.005131f, 0.005886f, 0.006561f, 0.007195f, 0.007912f, 0.008965f, 0.009941f,
+ 0.010956f, 0.012383f, 0.013893f, 0.015602f, 0.017303f, 0.019623f, 0.022156f, 0.025452f, 0.028976f, 0.033722f, 0.038910f, 0.045288f,
+ 0.052887f, 0.062561f, 0.074097f, 0.088623f, 0.106812f, 0.129639f, 0.157715f, 0.192261f, 0.235107f, 0.285889f, 0.344482f, 0.408691f,
+ 0.476807f, 0.545410f, 0.610840f, 0.671387f, 0.725098f, 0.771484f, 0.811035f, 0.843750f, 0.871582f, 0.894043f, 0.964355f, 0.967285f,
+ 0.967285f, 0.967773f, 0.967773f, 0.967773f, 0.000000f, 0.000320f, 0.000576f, 0.000572f, 0.000767f, 0.000945f, 0.001066f, 0.001375f,
+ 0.001848f, 0.001980f, 0.002190f, 0.002399f, 0.002695f, 0.002943f, 0.003397f, 0.003664f, 0.004063f, 0.004566f, 0.005119f, 0.005688f,
+ 0.006130f, 0.007057f, 0.007778f, 0.008675f, 0.009590f, 0.010666f, 0.011971f, 0.013443f, 0.015129f, 0.016953f, 0.018875f, 0.021576f,
+ 0.024658f, 0.028488f, 0.032959f, 0.037811f, 0.043793f, 0.051819f, 0.061371f, 0.073181f, 0.088257f, 0.106506f, 0.129883f, 0.159180f,
+ 0.195679f, 0.240479f, 0.293457f, 0.355225f, 0.422852f, 0.492432f, 0.563477f, 0.629883f, 0.690918f, 0.743652f, 0.789062f, 0.827148f,
+ 0.858398f, 0.884277f, 0.961914f, 0.964844f, 0.964355f, 0.964844f, 0.964355f, 0.965332f, 0.000000f, 0.000242f, 0.000435f, 0.000547f,
+ 0.000688f, 0.000803f, 0.001175f, 0.001318f, 0.001593f, 0.001652f, 0.001961f, 0.002209f, 0.002481f, 0.002716f, 0.002911f, 0.003210f,
+ 0.003595f, 0.004005f, 0.004490f, 0.004894f, 0.005508f, 0.006107f, 0.006714f, 0.007462f, 0.008438f, 0.009277f, 0.010170f, 0.011436f,
+ 0.012756f, 0.014145f, 0.016205f, 0.018433f, 0.020966f, 0.023819f, 0.027405f, 0.031464f, 0.036713f, 0.043152f, 0.050842f, 0.060577f,
+ 0.071960f, 0.087219f, 0.106689f, 0.130371f, 0.161377f, 0.199585f, 0.246948f, 0.303467f, 0.367920f, 0.439697f, 0.512207f, 0.584473f,
+ 0.651855f, 0.712402f, 0.764160f, 0.808105f, 0.844727f, 0.875000f, 0.958008f, 0.961426f, 0.961914f, 0.961914f, 0.962402f, 0.961914f,
+ 0.000000f, 0.000237f, 0.000266f, 0.000387f, 0.000557f, 0.000691f, 0.000774f, 0.001221f, 0.001455f, 0.001492f, 0.001769f, 0.001896f,
+ 0.002151f, 0.002386f, 0.002529f, 0.002911f, 0.003147f, 0.003523f, 0.003862f, 0.004311f, 0.004848f, 0.005260f, 0.005795f, 0.006416f,
+ 0.007114f, 0.007942f, 0.008667f, 0.009666f, 0.010818f, 0.012184f, 0.013718f, 0.015541f, 0.017685f, 0.020126f, 0.023056f, 0.026306f,
+ 0.030853f, 0.035797f, 0.042053f, 0.049683f, 0.059784f, 0.072144f, 0.086914f, 0.106873f, 0.132202f, 0.164429f, 0.205200f, 0.255615f,
+ 0.315918f, 0.384521f, 0.458984f, 0.534668f, 0.607910f, 0.676758f, 0.735840f, 0.785645f, 0.828125f, 0.862305f, 0.955566f, 0.958008f,
+ 0.958984f, 0.958496f, 0.958984f, 0.958984f, 0.000000f, 0.000119f, 0.000234f, 0.000484f, 0.000603f, 0.000758f, 0.000934f, 0.000999f,
+ 0.001200f, 0.001343f, 0.001534f, 0.001725f, 0.001860f, 0.002056f, 0.002235f, 0.002445f, 0.002783f, 0.003115f, 0.003448f, 0.003757f,
+ 0.004192f, 0.004723f, 0.005077f, 0.005653f, 0.006172f, 0.006527f, 0.007328f, 0.008247f, 0.009140f, 0.010368f, 0.011711f, 0.013351f,
+ 0.014702f, 0.016937f, 0.019226f, 0.022156f, 0.025604f, 0.029877f, 0.034668f, 0.040710f, 0.048920f, 0.058624f, 0.071289f, 0.087219f,
+ 0.107727f, 0.134521f, 0.168701f, 0.212769f, 0.267090f, 0.331543f, 0.404785f, 0.482910f, 0.561523f, 0.635742f, 0.702637f, 0.760742f,
+ 0.809570f, 0.849121f, 0.951660f, 0.954590f, 0.955566f, 0.955566f, 0.956055f, 0.955566f, 0.000238f, 0.000218f, 0.000229f, 0.000242f,
+ 0.000313f, 0.000859f, 0.000623f, 0.000978f, 0.001021f, 0.001150f, 0.001320f, 0.001431f, 0.001546f, 0.001746f, 0.001895f, 0.002106f,
+ 0.002502f, 0.002630f, 0.002926f, 0.003296f, 0.003651f, 0.003918f, 0.004391f, 0.004910f, 0.005249f, 0.005558f, 0.006413f, 0.007114f,
+ 0.007866f, 0.008789f, 0.009872f, 0.011093f, 0.012413f, 0.013939f, 0.015945f, 0.018692f, 0.021225f, 0.024643f, 0.028687f, 0.033936f,
+ 0.040192f, 0.047791f, 0.058014f, 0.070923f, 0.087585f, 0.109131f, 0.137573f, 0.174683f, 0.222290f, 0.280762f, 0.350830f, 0.428955f,
+ 0.511230f, 0.592285f, 0.666992f, 0.733398f, 0.789062f, 0.834473f, 0.947754f, 0.951172f, 0.951660f, 0.951172f, 0.951660f, 0.951172f,
+ 0.000000f, 0.000205f, 0.000222f, 0.000344f, 0.000301f, 0.000775f, 0.000827f, 0.000719f, 0.000944f, 0.000976f, 0.001306f, 0.001249f,
+ 0.001404f, 0.001569f, 0.001604f, 0.001819f, 0.002182f, 0.002354f, 0.002569f, 0.002857f, 0.003113f, 0.003426f, 0.003649f, 0.004112f,
+ 0.004307f, 0.004925f, 0.005508f, 0.005802f, 0.006565f, 0.007450f, 0.008125f, 0.009079f, 0.010269f, 0.011665f, 0.013565f, 0.015213f,
+ 0.017410f, 0.020203f, 0.023743f, 0.028168f, 0.032684f, 0.039062f, 0.047058f, 0.057404f, 0.070984f, 0.088623f, 0.111389f, 0.142090f,
+ 0.182373f, 0.234253f, 0.298828f, 0.375000f, 0.458008f, 0.543945f, 0.627441f, 0.702148f, 0.765137f, 0.818359f, 0.942871f, 0.946289f,
+ 0.947266f, 0.947266f, 0.946777f, 0.947266f, 0.000064f, 0.000095f, 0.000197f, 0.000213f, 0.000459f, 0.000491f, 0.000647f, 0.000696f,
+ 0.000884f, 0.000911f, 0.001121f, 0.001115f, 0.001234f, 0.001371f, 0.001410f, 0.001743f, 0.001905f, 0.002016f, 0.002207f, 0.002438f,
+ 0.002714f, 0.002939f, 0.003183f, 0.003323f, 0.003727f, 0.004143f, 0.004555f, 0.005276f, 0.005531f, 0.006264f, 0.006702f, 0.007572f,
+ 0.008705f, 0.009712f, 0.011238f, 0.012650f, 0.014320f, 0.016815f, 0.019516f, 0.022400f, 0.026566f, 0.031799f, 0.038055f, 0.046417f,
+ 0.057037f, 0.071350f, 0.089722f, 0.114868f, 0.148193f, 0.192749f, 0.249878f, 0.321045f, 0.404053f, 0.493408f, 0.583008f, 0.666016f,
+ 0.739258f, 0.799316f, 0.937988f, 0.941406f, 0.941895f, 0.942383f, 0.942383f, 0.942383f, 0.000000f, 0.000007f, 0.000144f, 0.000427f,
+ 0.000443f, 0.000566f, 0.000589f, 0.000615f, 0.000725f, 0.000731f, 0.000896f, 0.000953f, 0.001062f, 0.001167f, 0.001344f, 0.001345f,
+ 0.001636f, 0.001774f, 0.001893f, 0.002069f, 0.002350f, 0.002457f, 0.002678f, 0.002743f, 0.003105f, 0.003513f, 0.003830f, 0.004227f,
+ 0.004589f, 0.005047f, 0.005669f, 0.006176f, 0.007153f, 0.007896f, 0.008911f, 0.010231f, 0.011818f, 0.013618f, 0.015465f, 0.018188f,
+ 0.021576f, 0.025452f, 0.030533f, 0.037048f, 0.045685f, 0.056915f, 0.071533f, 0.091675f, 0.118958f, 0.156006f, 0.205444f, 0.270020f,
+ 0.349609f, 0.439941f, 0.533691f, 0.625977f, 0.708984f, 0.778320f, 0.931641f, 0.936035f, 0.936523f, 0.937012f, 0.937012f, 0.937012f,
+ 0.000000f, 0.000000f, 0.000137f, 0.000262f, 0.000432f, 0.000437f, 0.000444f, 0.000590f, 0.000558f, 0.000606f, 0.000817f, 0.000877f,
+ 0.000909f, 0.000951f, 0.001191f, 0.001244f, 0.001373f, 0.001506f, 0.001702f, 0.001690f, 0.001955f, 0.001940f, 0.002283f, 0.002340f,
+ 0.002571f, 0.002871f, 0.003265f, 0.003475f, 0.003910f, 0.004181f, 0.004608f, 0.005112f, 0.005833f, 0.006416f, 0.007145f, 0.008209f,
+ 0.009636f, 0.010750f, 0.012642f, 0.014481f, 0.017197f, 0.020203f, 0.024353f, 0.029694f, 0.036041f, 0.045105f, 0.056702f, 0.072388f,
+ 0.094482f, 0.124329f, 0.166504f, 0.223022f, 0.295898f, 0.384766f, 0.482910f, 0.582031f, 0.675293f, 0.754883f, 0.926270f, 0.929688f,
+ 0.930664f, 0.930664f, 0.931152f, 0.930664f, 0.000000f, 0.000000f, 0.000000f, 0.000232f, 0.000357f, 0.000411f, 0.000513f, 0.000527f,
+ 0.000490f, 0.000504f, 0.000653f, 0.000750f, 0.000780f, 0.000976f, 0.000942f, 0.000967f, 0.001180f, 0.001252f, 0.001385f, 0.001425f,
+ 0.001559f, 0.001801f, 0.001886f, 0.002144f, 0.002111f, 0.002354f, 0.002645f, 0.002827f, 0.003187f, 0.003414f, 0.003792f, 0.004360f,
+ 0.004662f, 0.005146f, 0.005875f, 0.006783f, 0.007610f, 0.008797f, 0.010033f, 0.011566f, 0.013565f, 0.016006f, 0.019165f, 0.023163f,
+ 0.028320f, 0.035400f, 0.044647f, 0.057129f, 0.074402f, 0.098572f, 0.132812f, 0.180542f, 0.245728f, 0.330078f, 0.428955f, 0.535156f,
+ 0.638184f, 0.728516f, 0.919434f, 0.922852f, 0.923828f, 0.923828f, 0.923828f, 0.924316f, 0.000000f, 0.000000f, 0.000000f, 0.000114f,
+ 0.000248f, 0.000359f, 0.000386f, 0.000342f, 0.000465f, 0.000461f, 0.000490f, 0.000609f, 0.000638f, 0.000694f, 0.000807f, 0.000923f,
+ 0.000961f, 0.001074f, 0.001123f, 0.001268f, 0.001311f, 0.001494f, 0.001537f, 0.001754f, 0.001899f, 0.001917f, 0.002199f, 0.002241f,
+ 0.002583f, 0.002769f, 0.003101f, 0.003441f, 0.003775f, 0.004200f, 0.004787f, 0.005272f, 0.006062f, 0.006702f, 0.007732f, 0.009102f,
+ 0.010582f, 0.012466f, 0.014984f, 0.017990f, 0.021957f, 0.027222f, 0.034332f, 0.044128f, 0.057434f, 0.076538f, 0.104126f, 0.143799f,
+ 0.199829f, 0.275879f, 0.373047f, 0.482422f, 0.594727f, 0.698730f, 0.910645f, 0.914551f, 0.916504f, 0.916016f, 0.916504f, 0.915527f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000121f, 0.000221f, 0.000222f, 0.000392f, 0.000402f, 0.000396f, 0.000434f, 0.000476f, 0.000548f,
+ 0.000536f, 0.000644f, 0.000642f, 0.000793f, 0.000795f, 0.000912f, 0.000953f, 0.000989f, 0.001164f, 0.001197f, 0.001285f, 0.001480f,
+ 0.001511f, 0.001674f, 0.001703f, 0.001901f, 0.002075f, 0.002340f, 0.002499f, 0.002800f, 0.003019f, 0.003296f, 0.003695f, 0.004093f,
+ 0.004780f, 0.005260f, 0.006207f, 0.006939f, 0.008034f, 0.009598f, 0.011353f, 0.013702f, 0.016678f, 0.020874f, 0.026062f, 0.033539f,
+ 0.044006f, 0.058746f, 0.080139f, 0.111877f, 0.158447f, 0.226318f, 0.317627f, 0.428711f, 0.548828f, 0.665039f, 0.901367f, 0.907227f,
+ 0.907715f, 0.908203f, 0.908203f, 0.907227f, 0.000000f, 0.000000f, 0.000122f, 0.000173f, 0.000191f, 0.000215f, 0.000224f, 0.000261f,
+ 0.000340f, 0.000374f, 0.000380f, 0.000496f, 0.000416f, 0.000535f, 0.000592f, 0.000622f, 0.000701f, 0.000772f, 0.000742f, 0.000774f,
+ 0.000990f, 0.000945f, 0.001088f, 0.001105f, 0.001348f, 0.001231f, 0.001460f, 0.001620f, 0.001758f, 0.001941f, 0.002008f, 0.002092f,
+ 0.002430f, 0.002615f, 0.002886f, 0.003208f, 0.003519f, 0.004112f, 0.004704f, 0.005371f, 0.006149f, 0.007351f, 0.008659f, 0.010201f,
+ 0.012550f, 0.015549f, 0.019577f, 0.025436f, 0.032928f, 0.044220f, 0.060608f, 0.084961f, 0.123474f, 0.180664f, 0.263184f, 0.372314f,
+ 0.498291f, 0.626465f, 0.892578f, 0.895996f, 0.896973f, 0.896973f, 0.897949f, 0.897949f, 0.000000f, 0.000000f, 0.000121f, 0.000121f,
+ 0.000120f, 0.000192f, 0.000201f, 0.000222f, 0.000222f, 0.000276f, 0.000295f, 0.000344f, 0.000433f, 0.000470f, 0.000485f, 0.000549f,
+ 0.000555f, 0.000558f, 0.000566f, 0.000639f, 0.000678f, 0.000757f, 0.000840f, 0.000905f, 0.000999f, 0.000946f, 0.001018f, 0.001309f,
+ 0.001402f, 0.001417f, 0.001624f, 0.001692f, 0.001869f, 0.002003f, 0.002184f, 0.002602f, 0.002851f, 0.003157f, 0.003595f, 0.004063f,
+ 0.004734f, 0.005398f, 0.006275f, 0.007542f, 0.009148f, 0.011383f, 0.014275f, 0.018250f, 0.024063f, 0.032135f, 0.044922f, 0.063721f,
+ 0.093811f, 0.139648f, 0.211914f, 0.314697f, 0.444092f, 0.584961f, 0.879883f, 0.884766f, 0.885254f, 0.885742f, 0.886230f, 0.885742f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000120f, 0.000154f, 0.000150f, 0.000160f, 0.000202f, 0.000217f, 0.000308f, 0.000319f,
+ 0.000278f, 0.000392f, 0.000362f, 0.000432f, 0.000416f, 0.000448f, 0.000495f, 0.000526f, 0.000710f, 0.000754f, 0.000657f, 0.000755f,
+ 0.000806f, 0.000919f, 0.000815f, 0.001080f, 0.001152f, 0.001207f, 0.001218f, 0.001373f, 0.001320f, 0.001685f, 0.001764f, 0.001819f,
+ 0.002068f, 0.002380f, 0.002668f, 0.003033f, 0.003584f, 0.003979f, 0.004829f, 0.005402f, 0.006630f, 0.008080f, 0.010254f, 0.013069f,
+ 0.017044f, 0.023422f, 0.031647f, 0.046417f, 0.068604f, 0.104919f, 0.165161f, 0.258789f, 0.387207f, 0.537598f, 0.867188f, 0.871582f,
+ 0.872559f, 0.872559f, 0.872559f, 0.873047f, 0.000000f, 0.000121f, 0.000120f, 0.000120f, 0.000119f, 0.000118f, 0.000122f, 0.000108f,
+ 0.000143f, 0.000149f, 0.000184f, 0.000194f, 0.000189f, 0.000210f, 0.000321f, 0.000282f, 0.000376f, 0.000420f, 0.000533f, 0.000437f,
+ 0.000467f, 0.000477f, 0.000587f, 0.000519f, 0.000673f, 0.000662f, 0.000679f, 0.000845f, 0.000881f, 0.000863f, 0.001016f, 0.001093f,
+ 0.001176f, 0.001191f, 0.001336f, 0.001561f, 0.001573f, 0.001754f, 0.001919f, 0.002264f, 0.002596f, 0.002911f, 0.003372f, 0.003870f,
+ 0.004723f, 0.005733f, 0.007092f, 0.008965f, 0.011650f, 0.015701f, 0.022339f, 0.032043f, 0.048370f, 0.076050f, 0.124084f, 0.204834f,
+ 0.328369f, 0.485596f, 0.852539f, 0.856934f, 0.858887f, 0.858887f, 0.858887f, 0.858398f, 0.000000f, 0.000121f, 0.000120f, 0.000119f,
+ 0.000118f, 0.000117f, 0.000116f, 0.000114f, 0.000105f, 0.000110f, 0.000165f, 0.000133f, 0.000157f, 0.000240f, 0.000256f, 0.000257f,
+ 0.000249f, 0.000303f, 0.000342f, 0.000346f, 0.000485f, 0.000510f, 0.000398f, 0.000493f, 0.000492f, 0.000524f, 0.000590f, 0.000585f,
+ 0.000601f, 0.000740f, 0.000647f, 0.000871f, 0.000834f, 0.000969f, 0.001020f, 0.001190f, 0.001244f, 0.001432f, 0.001393f, 0.001702f,
+ 0.001912f, 0.002171f, 0.002445f, 0.002958f, 0.003330f, 0.004025f, 0.004860f, 0.006161f, 0.007896f, 0.010742f, 0.014671f, 0.021378f,
+ 0.032928f, 0.052612f, 0.089050f, 0.155884f, 0.268555f, 0.430664f, 0.836426f, 0.841309f, 0.841309f, 0.842285f, 0.842773f, 0.842285f,
+ 0.000000f, 0.000000f, 0.000119f, 0.000117f, 0.000116f, 0.000115f, 0.000114f, 0.000114f, 0.000111f, 0.000103f, 0.000097f, 0.000118f,
+ 0.000115f, 0.000130f, 0.000176f, 0.000130f, 0.000223f, 0.000235f, 0.000244f, 0.000252f, 0.000274f, 0.000389f, 0.000309f, 0.000430f,
+ 0.000340f, 0.000399f, 0.000408f, 0.000459f, 0.000514f, 0.000501f, 0.000519f, 0.000657f, 0.000588f, 0.000775f, 0.000813f, 0.000789f,
+ 0.000904f, 0.001076f, 0.001027f, 0.001170f, 0.001342f, 0.001425f, 0.001662f, 0.002005f, 0.002298f, 0.002699f, 0.003227f, 0.003990f,
+ 0.005062f, 0.006855f, 0.009415f, 0.013504f, 0.020905f, 0.034424f, 0.060333f, 0.112000f, 0.210693f, 0.371094f, 0.816406f, 0.822754f,
+ 0.822754f, 0.823242f, 0.823242f, 0.823730f, 0.000000f, 0.000119f, 0.000117f, 0.000116f, 0.000114f, 0.000113f, 0.000112f, 0.000111f,
+ 0.000110f, 0.000109f, 0.000102f, 0.000095f, 0.000090f, 0.000084f, 0.000093f, 0.000103f, 0.000118f, 0.000165f, 0.000162f, 0.000190f,
+ 0.000204f, 0.000218f, 0.000223f, 0.000237f, 0.000256f, 0.000272f, 0.000344f, 0.000365f, 0.000365f, 0.000396f, 0.000386f, 0.000412f,
+ 0.000530f, 0.000466f, 0.000492f, 0.000615f, 0.000611f, 0.000748f, 0.000712f, 0.000795f, 0.000908f, 0.000971f, 0.001106f, 0.001353f,
+ 0.001572f, 0.001822f, 0.002251f, 0.002676f, 0.003290f, 0.004349f, 0.005951f, 0.008316f, 0.012543f, 0.021149f, 0.038025f, 0.075500f,
+ 0.156006f, 0.308838f, 0.794922f, 0.800293f, 0.800781f, 0.801270f, 0.801758f, 0.802246f, 0.000121f, 0.000116f, 0.000114f, 0.000113f,
+ 0.000111f, 0.000109f, 0.000108f, 0.000107f, 0.000106f, 0.000104f, 0.000104f, 0.000100f, 0.000094f, 0.000088f, 0.000083f, 0.000078f,
+ 0.000074f, 0.000105f, 0.000078f, 0.000122f, 0.000113f, 0.000153f, 0.000174f, 0.000175f, 0.000207f, 0.000216f, 0.000225f, 0.000215f,
+ 0.000262f, 0.000308f, 0.000297f, 0.000287f, 0.000307f, 0.000342f, 0.000363f, 0.000411f, 0.000401f, 0.000453f, 0.000522f, 0.000555f,
+ 0.000680f, 0.000701f, 0.000751f, 0.000873f, 0.000966f, 0.001181f, 0.001445f, 0.001666f, 0.002077f, 0.002512f, 0.003359f, 0.004856f,
+ 0.007347f, 0.012001f, 0.022049f, 0.046417f, 0.107117f, 0.245361f, 0.770508f, 0.775879f, 0.776367f, 0.776855f, 0.777344f, 0.777832f,
+ 0.000000f, 0.000113f, 0.000108f, 0.000107f, 0.000104f, 0.000103f, 0.000101f, 0.000100f, 0.000099f, 0.000098f, 0.000097f, 0.000096f,
+ 0.000095f, 0.000091f, 0.000086f, 0.000081f, 0.000077f, 0.000073f, 0.000069f, 0.000079f, 0.000084f, 0.000091f, 0.000074f, 0.000100f,
+ 0.000117f, 0.000140f, 0.000144f, 0.000166f, 0.000174f, 0.000178f, 0.000225f, 0.000197f, 0.000234f, 0.000239f, 0.000273f, 0.000289f,
+ 0.000283f, 0.000293f, 0.000338f, 0.000386f, 0.000386f, 0.000432f, 0.000459f, 0.000525f, 0.000625f, 0.000691f, 0.000800f, 0.001004f,
+ 0.001227f, 0.001479f, 0.001984f, 0.002745f, 0.003983f, 0.006413f, 0.011642f, 0.025269f, 0.066040f, 0.182495f, 0.743164f, 0.748535f,
+ 0.749023f, 0.749512f, 0.750000f, 0.749512f, 0.000000f, 0.000102f, 0.000101f, 0.000098f, 0.000094f, 0.000093f, 0.000092f, 0.000090f,
+ 0.000089f, 0.000088f, 0.000087f, 0.000086f, 0.000085f, 0.000084f, 0.000085f, 0.000082f, 0.000078f, 0.000074f, 0.000070f, 0.000066f,
+ 0.000063f, 0.000060f, 0.000057f, 0.000056f, 0.000061f, 0.000060f, 0.000073f, 0.000087f, 0.000100f, 0.000105f, 0.000124f, 0.000136f,
+ 0.000140f, 0.000140f, 0.000159f, 0.000179f, 0.000186f, 0.000205f, 0.000214f, 0.000229f, 0.000248f, 0.000267f, 0.000299f, 0.000344f,
+ 0.000367f, 0.000422f, 0.000496f, 0.000557f, 0.000639f, 0.000837f, 0.001037f, 0.001419f, 0.002081f, 0.003202f, 0.005730f, 0.012199f,
+ 0.034943f, 0.122925f, 0.711426f, 0.716797f, 0.718750f, 0.718262f, 0.718262f, 0.718750f, 0.000094f, 0.000079f, 0.000078f, 0.000074f,
+ 0.000074f, 0.000075f, 0.000074f, 0.000073f, 0.000071f, 0.000072f, 0.000070f, 0.000071f, 0.000071f, 0.000070f, 0.000070f, 0.000069f,
+ 0.000070f, 0.000069f, 0.000068f, 0.000065f, 0.000062f, 0.000059f, 0.000056f, 0.000053f, 0.000050f, 0.000048f, 0.000045f, 0.000044f,
+ 0.000041f, 0.000050f, 0.000050f, 0.000061f, 0.000068f, 0.000085f, 0.000091f, 0.000101f, 0.000102f, 0.000107f, 0.000119f, 0.000129f,
+ 0.000144f, 0.000151f, 0.000160f, 0.000184f, 0.000212f, 0.000213f, 0.000235f, 0.000294f, 0.000315f, 0.000392f, 0.000505f, 0.000637f,
+ 0.000880f, 0.001400f, 0.002462f, 0.005333f, 0.015160f, 0.070312f, 0.678223f, 0.683105f, 0.684082f, 0.684570f, 0.684570f, 0.684570f,
+ 0.000000f, 0.000000f, 0.000023f, 0.000034f, 0.000032f, 0.000038f, 0.000037f, 0.000044f, 0.000043f, 0.000047f, 0.000045f, 0.000047f,
+ 0.000049f, 0.000049f, 0.000049f, 0.000048f, 0.000051f, 0.000050f, 0.000051f, 0.000051f, 0.000052f, 0.000052f, 0.000052f, 0.000049f,
+ 0.000047f, 0.000045f, 0.000042f, 0.000040f, 0.000038f, 0.000036f, 0.000035f, 0.000033f, 0.000031f, 0.000029f, 0.000038f, 0.000037f,
+ 0.000042f, 0.000051f, 0.000055f, 0.000067f, 0.000074f, 0.000073f, 0.000083f, 0.000093f, 0.000088f, 0.000102f, 0.000122f, 0.000122f,
+ 0.000142f, 0.000169f, 0.000206f, 0.000265f, 0.000355f, 0.000531f, 0.000897f, 0.001822f, 0.005493f, 0.030579f, 0.640137f, 0.644531f,
+ 0.647461f, 0.647949f, 0.647461f, 0.648438f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000001f, 0.000000f, 0.000008f, 0.000012f, 0.000014f, 0.000014f, 0.000019f, 0.000021f, 0.000022f, 0.000024f, 0.000026f, 0.000027f,
+ 0.000027f, 0.000028f, 0.000029f, 0.000031f, 0.000031f, 0.000032f, 0.000032f, 0.000033f, 0.000033f, 0.000032f, 0.000030f, 0.000029f,
+ 0.000027f, 0.000026f, 0.000024f, 0.000023f, 0.000022f, 0.000021f, 0.000019f, 0.000018f, 0.000021f, 0.000024f, 0.000028f, 0.000033f,
+ 0.000043f, 0.000041f, 0.000046f, 0.000053f, 0.000050f, 0.000059f, 0.000068f, 0.000094f, 0.000096f, 0.000140f, 0.000239f, 0.000447f,
+ 0.001340f, 0.009087f, 0.600098f, 0.605957f, 0.606934f, 0.606934f, 0.607422f, 0.606934f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000004f, 0.000006f, 0.000006f,
+ 0.000009f, 0.000010f, 0.000011f, 0.000012f, 0.000013f, 0.000014f, 0.000015f, 0.000016f, 0.000017f, 0.000016f, 0.000015f, 0.000014f,
+ 0.000013f, 0.000012f, 0.000012f, 0.000011f, 0.000010f, 0.000009f, 0.000008f, 0.000012f, 0.000014f, 0.000018f, 0.000017f, 0.000022f,
+ 0.000022f, 0.000026f, 0.000040f, 0.000060f, 0.000157f, 0.001244f, 0.557129f, 0.563477f, 0.563477f, 0.564941f, 0.564941f, 0.564941f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000003f,
+ 0.000003f, 0.000004f, 0.000003f, 0.000003f, 0.000003f, 0.000002f, 0.000003f, 0.000003f, 0.000003f, 0.000012f, 0.513672f, 0.520020f,
+ 0.520020f, 0.520508f, 0.521484f, 0.521484f,
+ },
+ {
+ 0.103943f, 0.284912f, 0.422119f, 0.523438f, 0.600586f, 0.659668f, 0.705078f, 0.741699f, 0.771484f, 0.795898f, 0.816895f, 0.834961f,
+ 0.850586f, 0.862793f, 0.874512f, 0.884277f, 0.894043f, 0.901855f, 0.909180f, 0.915039f, 0.921387f, 0.926270f, 0.932129f, 0.936035f,
+ 0.940430f, 0.944336f, 0.948242f, 0.951660f, 0.954590f, 0.957520f, 0.959961f, 0.962891f, 0.965332f, 0.967285f, 0.969727f, 0.971680f,
+ 0.973145f, 0.975586f, 0.977051f, 0.979004f, 0.979980f, 0.981934f, 0.983887f, 0.984375f, 0.985840f, 0.986816f, 0.988770f, 0.989258f,
+ 0.990723f, 0.992188f, 0.992676f, 0.993652f, 0.994629f, 0.995605f, 0.996582f, 0.997559f, 0.998535f, 0.999023f, 0.999512f, 0.999023f,
+ 0.998535f, 0.998047f, 0.997559f, 0.997070f, 0.046997f, 0.153564f, 0.264160f, 0.369385f, 0.460205f, 0.538574f, 0.602051f, 0.654785f,
+ 0.697754f, 0.733398f, 0.762695f, 0.787598f, 0.809082f, 0.827637f, 0.843262f, 0.856934f, 0.868652f, 0.880859f, 0.889648f, 0.898438f,
+ 0.906738f, 0.912598f, 0.918945f, 0.924805f, 0.929688f, 0.935059f, 0.938965f, 0.943359f, 0.947266f, 0.951172f, 0.954102f, 0.956543f,
+ 0.959961f, 0.961914f, 0.964844f, 0.966797f, 0.969727f, 0.971191f, 0.974121f, 0.975098f, 0.977051f, 0.979492f, 0.980469f, 0.981934f,
+ 0.983887f, 0.985352f, 0.985840f, 0.987305f, 0.989258f, 0.990234f, 0.991211f, 0.992188f, 0.993164f, 0.994141f, 0.995117f, 0.996094f,
+ 0.996582f, 0.997559f, 0.999023f, 0.998535f, 0.998047f, 0.997559f, 0.997070f, 0.997070f, 0.025940f, 0.088501f, 0.162964f, 0.246094f,
+ 0.331055f, 0.411865f, 0.486328f, 0.550293f, 0.606934f, 0.655762f, 0.695312f, 0.729980f, 0.758301f, 0.783691f, 0.804199f, 0.823730f,
+ 0.838867f, 0.853027f, 0.865723f, 0.877441f, 0.887207f, 0.895996f, 0.904785f, 0.911133f, 0.916992f, 0.923828f, 0.928223f, 0.933594f,
+ 0.937988f, 0.942871f, 0.946777f, 0.950195f, 0.953613f, 0.956543f, 0.959473f, 0.962402f, 0.964844f, 0.967285f, 0.970215f, 0.971680f,
+ 0.973633f, 0.976074f, 0.977539f, 0.979492f, 0.980469f, 0.982422f, 0.984863f, 0.985352f, 0.986816f, 0.987793f, 0.989258f, 0.990234f,
+ 0.991699f, 0.992676f, 0.994141f, 0.995117f, 0.995605f, 0.996582f, 0.998535f, 0.998047f, 0.998047f, 0.997559f, 0.997070f, 0.996582f,
+ 0.016159f, 0.055176f, 0.104126f, 0.162720f, 0.229126f, 0.300781f, 0.372803f, 0.442871f, 0.506836f, 0.563477f, 0.613281f, 0.657715f,
+ 0.696289f, 0.729004f, 0.757324f, 0.782227f, 0.802734f, 0.821289f, 0.837402f, 0.852539f, 0.865234f, 0.875977f, 0.885742f, 0.895508f,
+ 0.903320f, 0.910156f, 0.917480f, 0.922852f, 0.928711f, 0.934082f, 0.937988f, 0.942871f, 0.947266f, 0.950195f, 0.954102f, 0.957031f,
+ 0.959473f, 0.962402f, 0.964844f, 0.968262f, 0.969727f, 0.972168f, 0.974121f, 0.976562f, 0.978516f, 0.979980f, 0.981934f, 0.982910f,
+ 0.983887f, 0.985840f, 0.986816f, 0.988770f, 0.989746f, 0.991211f, 0.992188f, 0.993652f, 0.994141f, 0.995117f, 0.998047f, 0.997559f,
+ 0.997559f, 0.997070f, 0.996582f, 0.996582f, 0.010841f, 0.036865f, 0.070007f, 0.110962f, 0.159546f, 0.214355f, 0.276367f, 0.340576f,
+ 0.405029f, 0.465820f, 0.523926f, 0.576172f, 0.623535f, 0.664062f, 0.699707f, 0.731445f, 0.758301f, 0.782227f, 0.803223f, 0.821289f,
+ 0.837891f, 0.852051f, 0.864258f, 0.875488f, 0.884766f, 0.894531f, 0.903320f, 0.910156f, 0.916992f, 0.923828f, 0.928223f, 0.933594f,
+ 0.938477f, 0.943359f, 0.947266f, 0.950684f, 0.954102f, 0.957520f, 0.960449f, 0.962891f, 0.965820f, 0.968750f, 0.971191f, 0.973145f,
+ 0.975586f, 0.977539f, 0.978516f, 0.980957f, 0.982422f, 0.984375f, 0.985352f, 0.987305f, 0.988281f, 0.989746f, 0.990723f, 0.992188f,
+ 0.993164f, 0.994141f, 0.997559f, 0.997559f, 0.997070f, 0.996582f, 0.996582f, 0.996094f, 0.007637f, 0.026566f, 0.049896f, 0.078247f,
+ 0.113403f, 0.154663f, 0.202637f, 0.255371f, 0.313232f, 0.372314f, 0.431152f, 0.488037f, 0.540039f, 0.588867f, 0.633301f, 0.670898f,
+ 0.704102f, 0.734375f, 0.761230f, 0.785156f, 0.804688f, 0.822754f, 0.838867f, 0.852539f, 0.864746f, 0.876953f, 0.886230f, 0.895996f,
+ 0.903320f, 0.910645f, 0.917480f, 0.923828f, 0.929199f, 0.935059f, 0.938965f, 0.943359f, 0.948730f, 0.952148f, 0.954590f, 0.958496f,
+ 0.961426f, 0.964355f, 0.966797f, 0.969238f, 0.971680f, 0.974121f, 0.976074f, 0.978027f, 0.979980f, 0.981445f, 0.982910f, 0.984863f,
+ 0.986816f, 0.987793f, 0.989258f, 0.990723f, 0.991699f, 0.993164f, 0.996582f, 0.996582f, 0.996094f, 0.996094f, 0.996094f, 0.995605f,
+ 0.005714f, 0.019485f, 0.036194f, 0.056976f, 0.082336f, 0.113342f, 0.149048f, 0.191284f, 0.238770f, 0.290039f, 0.344727f, 0.400391f,
+ 0.454590f, 0.507324f, 0.557129f, 0.602539f, 0.642578f, 0.679199f, 0.711426f, 0.740234f, 0.766602f, 0.788574f, 0.807617f, 0.825195f,
+ 0.841309f, 0.854980f, 0.867676f, 0.877930f, 0.888184f, 0.896484f, 0.904785f, 0.912109f, 0.918945f, 0.925293f, 0.930176f, 0.935547f,
+ 0.940918f, 0.944336f, 0.948730f, 0.952637f, 0.956055f, 0.959473f, 0.962402f, 0.965332f, 0.967773f, 0.970703f, 0.972656f, 0.975098f,
+ 0.977051f, 0.979004f, 0.981445f, 0.982910f, 0.984375f, 0.985840f, 0.987793f, 0.989258f, 0.990234f, 0.991211f, 0.996094f, 0.996094f,
+ 0.996094f, 0.996094f, 0.995605f, 0.995117f, 0.004505f, 0.014908f, 0.027634f, 0.043274f, 0.061707f, 0.084045f, 0.111694f, 0.143921f,
+ 0.180542f, 0.223877f, 0.270996f, 0.320557f, 0.373291f, 0.425781f, 0.478027f, 0.526855f, 0.573242f, 0.615723f, 0.654785f, 0.688965f,
+ 0.720215f, 0.747559f, 0.771973f, 0.793457f, 0.812500f, 0.829102f, 0.844238f, 0.858398f, 0.870117f, 0.881348f, 0.890625f, 0.898926f,
+ 0.906738f, 0.914062f, 0.921387f, 0.926758f, 0.932617f, 0.937500f, 0.942383f, 0.945801f, 0.950684f, 0.954102f, 0.958008f, 0.960938f,
+ 0.964355f, 0.966797f, 0.969727f, 0.972656f, 0.974609f, 0.976562f, 0.978516f, 0.980469f, 0.981934f, 0.984375f, 0.985840f, 0.987793f,
+ 0.988281f, 0.990234f, 0.995605f, 0.995605f, 0.995605f, 0.995605f, 0.995117f, 0.994629f, 0.003691f, 0.011925f, 0.021622f, 0.033203f,
+ 0.047241f, 0.065247f, 0.085266f, 0.109558f, 0.138550f, 0.172363f, 0.210205f, 0.253418f, 0.299805f, 0.348877f, 0.400146f, 0.450195f,
+ 0.499512f, 0.546387f, 0.589844f, 0.629883f, 0.666016f, 0.700195f, 0.728516f, 0.755371f, 0.778320f, 0.798828f, 0.817383f, 0.833984f,
+ 0.848145f, 0.861816f, 0.874023f, 0.883789f, 0.893555f, 0.902344f, 0.910645f, 0.916992f, 0.922852f, 0.929688f, 0.934570f, 0.938965f,
+ 0.944336f, 0.948730f, 0.951660f, 0.956543f, 0.959473f, 0.962891f, 0.965820f, 0.968262f, 0.970703f, 0.974121f, 0.976074f, 0.978516f,
+ 0.979980f, 0.981934f, 0.983887f, 0.985840f, 0.987305f, 0.988281f, 0.994629f, 0.995117f, 0.995117f, 0.994629f, 0.994629f, 0.994141f,
+ 0.002726f, 0.009560f, 0.017136f, 0.026871f, 0.037415f, 0.050079f, 0.066406f, 0.084717f, 0.107849f, 0.133423f, 0.164062f, 0.198853f,
+ 0.238281f, 0.281250f, 0.327148f, 0.375977f, 0.424805f, 0.473877f, 0.521973f, 0.564941f, 0.606934f, 0.644531f, 0.679199f, 0.710449f,
+ 0.738770f, 0.764160f, 0.786133f, 0.805664f, 0.824219f, 0.838867f, 0.853516f, 0.866211f, 0.876953f, 0.887695f, 0.896484f, 0.905762f,
+ 0.912598f, 0.919922f, 0.925781f, 0.932129f, 0.937500f, 0.942383f, 0.946777f, 0.951660f, 0.955078f, 0.958984f, 0.961426f, 0.965332f,
+ 0.967773f, 0.970703f, 0.972656f, 0.975586f, 0.978027f, 0.979492f, 0.981934f, 0.983887f, 0.984863f, 0.986816f, 0.994629f, 0.994629f,
+ 0.994629f, 0.994141f, 0.994141f, 0.993652f, 0.002487f, 0.007553f, 0.013863f, 0.021439f, 0.029755f, 0.040771f, 0.052643f, 0.067444f,
+ 0.084473f, 0.104980f, 0.128784f, 0.157227f, 0.189087f, 0.224609f, 0.265381f, 0.308838f, 0.354004f, 0.401611f, 0.450439f, 0.496582f,
+ 0.541992f, 0.583984f, 0.623047f, 0.660645f, 0.693359f, 0.722168f, 0.749512f, 0.772949f, 0.793457f, 0.812988f, 0.830078f, 0.845215f,
+ 0.859375f, 0.871094f, 0.882812f, 0.892090f, 0.900879f, 0.908691f, 0.916504f, 0.922852f, 0.930176f, 0.935547f, 0.940430f, 0.944824f,
+ 0.949219f, 0.952637f, 0.956543f, 0.960449f, 0.963867f, 0.967285f, 0.970215f, 0.972656f, 0.974609f, 0.977539f, 0.979492f, 0.981934f,
+ 0.983887f, 0.985352f, 0.993652f, 0.994141f, 0.994141f, 0.993652f, 0.993652f, 0.993164f, 0.001893f, 0.006641f, 0.011551f, 0.017319f,
+ 0.024612f, 0.032959f, 0.042023f, 0.053772f, 0.067444f, 0.083435f, 0.102356f, 0.123840f, 0.150024f, 0.179688f, 0.213501f, 0.250488f,
+ 0.291992f, 0.335938f, 0.381592f, 0.427246f, 0.473877f, 0.518555f, 0.563477f, 0.603027f, 0.640625f, 0.676270f, 0.707031f, 0.735352f,
+ 0.760254f, 0.782715f, 0.802734f, 0.821777f, 0.838379f, 0.851562f, 0.865234f, 0.876953f, 0.886719f, 0.896484f, 0.905273f, 0.913086f,
+ 0.921387f, 0.927734f, 0.933105f, 0.938477f, 0.942871f, 0.948242f, 0.951660f, 0.955566f, 0.959961f, 0.963867f, 0.966309f, 0.969238f,
+ 0.972168f, 0.975098f, 0.977539f, 0.979492f, 0.981934f, 0.983887f, 0.993164f, 0.993652f, 0.993164f, 0.993164f, 0.993164f, 0.992676f,
+ 0.001740f, 0.005634f, 0.009407f, 0.014992f, 0.020157f, 0.026840f, 0.035156f, 0.043793f, 0.054718f, 0.067505f, 0.082092f, 0.099731f,
+ 0.120239f, 0.143921f, 0.171265f, 0.202393f, 0.237915f, 0.276367f, 0.318848f, 0.362793f, 0.407959f, 0.454346f, 0.499023f, 0.542480f,
+ 0.583984f, 0.623535f, 0.659180f, 0.691895f, 0.721680f, 0.748047f, 0.772461f, 0.793457f, 0.812988f, 0.829102f, 0.845215f, 0.859863f,
+ 0.872559f, 0.883789f, 0.893555f, 0.902344f, 0.911133f, 0.918457f, 0.924805f, 0.930664f, 0.937012f, 0.941895f, 0.947266f, 0.951172f,
+ 0.956055f, 0.959473f, 0.962402f, 0.966309f, 0.968750f, 0.972168f, 0.974609f, 0.977051f, 0.979492f, 0.981934f, 0.992188f, 0.992676f,
+ 0.992676f, 0.992676f, 0.992188f, 0.992676f, 0.001502f, 0.004482f, 0.008278f, 0.012276f, 0.016800f, 0.022644f, 0.029129f, 0.036194f,
+ 0.045197f, 0.055298f, 0.067017f, 0.080750f, 0.096863f, 0.115906f, 0.138184f, 0.163940f, 0.192993f, 0.225952f, 0.262695f, 0.302490f,
+ 0.344971f, 0.389648f, 0.434814f, 0.480469f, 0.523926f, 0.566406f, 0.605957f, 0.643066f, 0.677246f, 0.708496f, 0.736816f, 0.761719f,
+ 0.784668f, 0.804688f, 0.823242f, 0.840332f, 0.854004f, 0.867188f, 0.878906f, 0.890137f, 0.898438f, 0.907715f, 0.916016f, 0.922852f,
+ 0.930176f, 0.935547f, 0.940918f, 0.946289f, 0.950684f, 0.955078f, 0.959473f, 0.961914f, 0.966309f, 0.969238f, 0.972168f, 0.974609f,
+ 0.977539f, 0.979492f, 0.991211f, 0.992188f, 0.991699f, 0.992188f, 0.991699f, 0.991211f, 0.001411f, 0.003645f, 0.007160f, 0.010414f,
+ 0.014397f, 0.018677f, 0.024338f, 0.030426f, 0.037384f, 0.045654f, 0.055054f, 0.066101f, 0.079529f, 0.094543f, 0.112793f, 0.133057f,
+ 0.157227f, 0.183960f, 0.215210f, 0.250488f, 0.288086f, 0.329102f, 0.372314f, 0.416992f, 0.461914f, 0.505859f, 0.549316f, 0.589355f,
+ 0.627930f, 0.664062f, 0.695801f, 0.725098f, 0.752441f, 0.775879f, 0.797363f, 0.815918f, 0.833984f, 0.849121f, 0.863281f, 0.875488f,
+ 0.886230f, 0.895996f, 0.904785f, 0.914062f, 0.920898f, 0.928223f, 0.935059f, 0.940918f, 0.945312f, 0.950195f, 0.954102f, 0.958984f,
+ 0.962402f, 0.966309f, 0.969238f, 0.972656f, 0.974609f, 0.977539f, 0.990234f, 0.992188f, 0.991211f, 0.991211f, 0.990723f, 0.991211f,
+ 0.000926f, 0.003523f, 0.006207f, 0.008949f, 0.012718f, 0.016312f, 0.020447f, 0.025467f, 0.031128f, 0.037994f, 0.045532f, 0.054901f,
+ 0.065430f, 0.077576f, 0.091797f, 0.109131f, 0.128418f, 0.151245f, 0.176636f, 0.206055f, 0.238525f, 0.275146f, 0.314697f, 0.357178f,
+ 0.400391f, 0.445312f, 0.489746f, 0.531738f, 0.574219f, 0.613281f, 0.650391f, 0.683594f, 0.714355f, 0.742188f, 0.768066f, 0.790039f,
+ 0.810059f, 0.828125f, 0.843262f, 0.858398f, 0.871582f, 0.883789f, 0.893555f, 0.903809f, 0.912598f, 0.919434f, 0.926758f, 0.933594f,
+ 0.939453f, 0.944336f, 0.950195f, 0.954590f, 0.958008f, 0.962402f, 0.966309f, 0.969727f, 0.972656f, 0.975586f, 0.989746f, 0.990723f,
+ 0.990723f, 0.990234f, 0.990234f, 0.990234f, 0.001140f, 0.003021f, 0.005527f, 0.008102f, 0.010445f, 0.013977f, 0.017349f, 0.021637f,
+ 0.026535f, 0.031677f, 0.038330f, 0.045776f, 0.054382f, 0.064392f, 0.076233f, 0.089844f, 0.105713f, 0.123840f, 0.145020f, 0.169556f,
+ 0.196899f, 0.229248f, 0.263672f, 0.302002f, 0.342529f, 0.385986f, 0.429932f, 0.473877f, 0.517578f, 0.560547f, 0.600586f, 0.638184f,
+ 0.672852f, 0.704590f, 0.733398f, 0.759277f, 0.782715f, 0.803711f, 0.823242f, 0.840820f, 0.854980f, 0.869141f, 0.881348f, 0.892090f,
+ 0.902344f, 0.910645f, 0.919922f, 0.927246f, 0.933105f, 0.938965f, 0.944824f, 0.949707f, 0.954102f, 0.959473f, 0.962891f, 0.966309f,
+ 0.969727f, 0.972168f, 0.988770f, 0.990234f, 0.989746f, 0.989746f, 0.989746f, 0.989258f, 0.000870f, 0.002666f, 0.004578f, 0.006737f,
+ 0.009430f, 0.012077f, 0.015381f, 0.018463f, 0.022293f, 0.027313f, 0.032654f, 0.038727f, 0.045746f, 0.053619f, 0.063232f, 0.074524f,
+ 0.087219f, 0.102356f, 0.119324f, 0.139648f, 0.162842f, 0.189941f, 0.219482f, 0.253174f, 0.289795f, 0.329346f, 0.372070f, 0.415039f,
+ 0.459717f, 0.503418f, 0.546387f, 0.587402f, 0.625977f, 0.661621f, 0.694336f, 0.725586f, 0.752441f, 0.776855f, 0.798828f, 0.818359f,
+ 0.837402f, 0.852539f, 0.866699f, 0.878906f, 0.891113f, 0.900879f, 0.910156f, 0.918457f, 0.926270f, 0.932617f, 0.938965f, 0.944824f,
+ 0.950195f, 0.955078f, 0.958984f, 0.962891f, 0.966797f, 0.970703f, 0.987793f, 0.988770f, 0.989258f, 0.989258f, 0.988770f, 0.988770f,
+ 0.000835f, 0.002302f, 0.004078f, 0.005802f, 0.008026f, 0.010490f, 0.013153f, 0.016235f, 0.019485f, 0.023636f, 0.027847f, 0.033081f,
+ 0.038849f, 0.045441f, 0.053253f, 0.062500f, 0.072571f, 0.085205f, 0.098999f, 0.115662f, 0.135254f, 0.156860f, 0.182373f, 0.211060f,
+ 0.243042f, 0.279053f, 0.318115f, 0.359619f, 0.402832f, 0.447021f, 0.490234f, 0.533691f, 0.575195f, 0.615234f, 0.651855f, 0.686035f,
+ 0.717285f, 0.746094f, 0.771484f, 0.793945f, 0.813965f, 0.833496f, 0.848633f, 0.864258f, 0.877930f, 0.889648f, 0.900391f, 0.909180f,
+ 0.918945f, 0.926270f, 0.932129f, 0.939453f, 0.945312f, 0.950684f, 0.955566f, 0.959473f, 0.963867f, 0.967773f, 0.987305f, 0.988281f,
+ 0.988281f, 0.988281f, 0.988281f, 0.987793f, 0.000815f, 0.001984f, 0.003475f, 0.005302f, 0.007103f, 0.009354f, 0.011528f, 0.013977f,
+ 0.017197f, 0.020111f, 0.023788f, 0.027771f, 0.033447f, 0.038452f, 0.045013f, 0.052704f, 0.061066f, 0.071228f, 0.082886f, 0.096313f,
+ 0.112488f, 0.130737f, 0.151245f, 0.175659f, 0.203125f, 0.234619f, 0.269043f, 0.306885f, 0.347656f, 0.390381f, 0.434570f, 0.478760f,
+ 0.522461f, 0.564453f, 0.605957f, 0.644043f, 0.678223f, 0.710449f, 0.739746f, 0.766602f, 0.791016f, 0.811035f, 0.831055f, 0.847168f,
+ 0.862793f, 0.875977f, 0.888672f, 0.899414f, 0.909180f, 0.917480f, 0.926270f, 0.933105f, 0.939941f, 0.945801f, 0.950684f, 0.955566f,
+ 0.960938f, 0.964844f, 0.985840f, 0.987305f, 0.987793f, 0.987305f, 0.987305f, 0.987305f, 0.000587f, 0.002005f, 0.003122f, 0.004707f,
+ 0.006283f, 0.007778f, 0.009972f, 0.012581f, 0.014435f, 0.017426f, 0.020691f, 0.024475f, 0.028519f, 0.033203f, 0.038513f, 0.044708f,
+ 0.051727f, 0.060028f, 0.069763f, 0.080627f, 0.093506f, 0.109009f, 0.125977f, 0.146362f, 0.169678f, 0.196533f, 0.226685f, 0.259766f,
+ 0.297119f, 0.337646f, 0.380127f, 0.424072f, 0.468018f, 0.512207f, 0.555176f, 0.596680f, 0.635254f, 0.671387f, 0.704590f, 0.734863f,
+ 0.762207f, 0.787109f, 0.809082f, 0.828613f, 0.846191f, 0.860840f, 0.875977f, 0.888184f, 0.899902f, 0.908691f, 0.918457f, 0.926270f,
+ 0.934082f, 0.940430f, 0.947266f, 0.951660f, 0.958008f, 0.961914f, 0.984863f, 0.986328f, 0.986816f, 0.986816f, 0.986328f, 0.986328f,
+ 0.000475f, 0.001671f, 0.003019f, 0.004379f, 0.005592f, 0.006882f, 0.008682f, 0.010757f, 0.012856f, 0.015343f, 0.018112f, 0.021164f,
+ 0.024353f, 0.028595f, 0.033020f, 0.038086f, 0.044006f, 0.050812f, 0.058594f, 0.067993f, 0.078735f, 0.091248f, 0.105530f, 0.122009f,
+ 0.142212f, 0.164062f, 0.189697f, 0.219238f, 0.251953f, 0.288330f, 0.328125f, 0.369629f, 0.413818f, 0.458008f, 0.503418f, 0.547363f,
+ 0.588867f, 0.628418f, 0.665039f, 0.699707f, 0.730469f, 0.758301f, 0.784668f, 0.807129f, 0.826660f, 0.844727f, 0.862305f, 0.875977f,
+ 0.888672f, 0.900879f, 0.910156f, 0.919434f, 0.927734f, 0.935059f, 0.941406f, 0.947754f, 0.953125f, 0.958496f, 0.983887f, 0.985352f,
+ 0.985352f, 0.985352f, 0.984863f, 0.985352f, 0.000325f, 0.001517f, 0.002554f, 0.003811f, 0.004990f, 0.006638f, 0.007706f, 0.009399f,
+ 0.011177f, 0.013580f, 0.015671f, 0.018478f, 0.021393f, 0.024612f, 0.028442f, 0.032990f, 0.037750f, 0.043427f, 0.050354f, 0.057861f,
+ 0.066101f, 0.076294f, 0.088684f, 0.102417f, 0.119080f, 0.137451f, 0.159058f, 0.183838f, 0.212524f, 0.244385f, 0.280273f, 0.319336f,
+ 0.361084f, 0.405029f, 0.449707f, 0.494873f, 0.539551f, 0.582031f, 0.622559f, 0.660156f, 0.695801f, 0.727539f, 0.756348f, 0.782715f,
+ 0.805664f, 0.826172f, 0.845215f, 0.861328f, 0.875977f, 0.889648f, 0.901367f, 0.910645f, 0.920410f, 0.928711f, 0.937012f, 0.942871f,
+ 0.949219f, 0.955078f, 0.982422f, 0.983887f, 0.984375f, 0.984375f, 0.983887f, 0.983887f, 0.000349f, 0.001533f, 0.002413f, 0.003326f,
+ 0.004463f, 0.005524f, 0.006954f, 0.008202f, 0.010025f, 0.011864f, 0.013924f, 0.015884f, 0.018478f, 0.021484f, 0.024658f, 0.028671f,
+ 0.032562f, 0.037170f, 0.042969f, 0.049194f, 0.056641f, 0.065063f, 0.074951f, 0.086182f, 0.099731f, 0.115662f, 0.133789f, 0.154175f,
+ 0.178589f, 0.206421f, 0.237671f, 0.272949f, 0.312012f, 0.352783f, 0.396973f, 0.442627f, 0.487793f, 0.532227f, 0.576660f, 0.617188f,
+ 0.657227f, 0.692383f, 0.725586f, 0.754395f, 0.780762f, 0.805664f, 0.826172f, 0.845215f, 0.861816f, 0.876465f, 0.890137f, 0.902344f,
+ 0.912598f, 0.921875f, 0.930176f, 0.937988f, 0.945312f, 0.952148f, 0.981445f, 0.982910f, 0.982910f, 0.983398f, 0.983398f, 0.983398f,
+ 0.000475f, 0.001141f, 0.002058f, 0.002846f, 0.004120f, 0.005013f, 0.006207f, 0.007664f, 0.009193f, 0.010368f, 0.012222f, 0.014404f,
+ 0.016403f, 0.018799f, 0.021439f, 0.024567f, 0.028076f, 0.032379f, 0.036652f, 0.042145f, 0.048157f, 0.055389f, 0.063660f, 0.073059f,
+ 0.083740f, 0.097046f, 0.112366f, 0.129517f, 0.149780f, 0.173584f, 0.200684f, 0.231812f, 0.266357f, 0.304688f, 0.346680f, 0.390137f,
+ 0.435547f, 0.481445f, 0.526367f, 0.572266f, 0.613770f, 0.653320f, 0.690430f, 0.723633f, 0.754395f, 0.781250f, 0.806152f, 0.826172f,
+ 0.847168f, 0.862793f, 0.878906f, 0.892090f, 0.904297f, 0.914551f, 0.924316f, 0.933105f, 0.940430f, 0.947754f, 0.979492f, 0.981934f,
+ 0.981934f, 0.981934f, 0.981445f, 0.981445f, 0.000239f, 0.000882f, 0.001744f, 0.002878f, 0.003819f, 0.004532f, 0.005550f, 0.006653f,
+ 0.007942f, 0.009277f, 0.010628f, 0.012421f, 0.014397f, 0.016312f, 0.018845f, 0.021576f, 0.024536f, 0.027817f, 0.031860f, 0.036346f,
+ 0.041595f, 0.047333f, 0.054138f, 0.062317f, 0.071350f, 0.081970f, 0.094299f, 0.109070f, 0.126221f, 0.146118f, 0.169067f, 0.195801f,
+ 0.226196f, 0.260742f, 0.298584f, 0.340088f, 0.384277f, 0.429688f, 0.476807f, 0.522461f, 0.568359f, 0.611328f, 0.651855f, 0.689453f,
+ 0.723633f, 0.754395f, 0.782715f, 0.807617f, 0.829590f, 0.848145f, 0.865723f, 0.880859f, 0.894531f, 0.906738f, 0.917969f, 0.927246f,
+ 0.936035f, 0.943359f, 0.978027f, 0.979980f, 0.980469f, 0.980469f, 0.980469f, 0.980469f, 0.000240f, 0.000948f, 0.001495f, 0.002592f,
+ 0.003241f, 0.004055f, 0.004856f, 0.006111f, 0.007133f, 0.008125f, 0.009445f, 0.011108f, 0.012474f, 0.014374f, 0.016586f, 0.018784f,
+ 0.021286f, 0.024475f, 0.027481f, 0.031403f, 0.035828f, 0.040710f, 0.046204f, 0.052704f, 0.060577f, 0.069519f, 0.079651f, 0.092224f,
+ 0.106506f, 0.122986f, 0.142456f, 0.165161f, 0.191284f, 0.221924f, 0.255615f, 0.293457f, 0.335205f, 0.379395f, 0.425537f, 0.472900f,
+ 0.519531f, 0.566406f, 0.610840f, 0.652344f, 0.689941f, 0.724609f, 0.755371f, 0.784180f, 0.808594f, 0.831055f, 0.851562f, 0.869141f,
+ 0.884277f, 0.897461f, 0.909668f, 0.920410f, 0.930176f, 0.937988f, 0.976562f, 0.979004f, 0.979492f, 0.979492f, 0.979492f, 0.979492f,
+ 0.000302f, 0.000863f, 0.001315f, 0.002195f, 0.002905f, 0.003592f, 0.004784f, 0.005478f, 0.006199f, 0.007389f, 0.008545f, 0.009811f,
+ 0.011185f, 0.012787f, 0.014603f, 0.016342f, 0.018784f, 0.021347f, 0.024033f, 0.027496f, 0.031006f, 0.034790f, 0.039856f, 0.045288f,
+ 0.051636f, 0.059052f, 0.067566f, 0.078003f, 0.089905f, 0.103760f, 0.119934f, 0.139282f, 0.161865f, 0.187622f, 0.217407f, 0.251221f,
+ 0.288818f, 0.330811f, 0.375244f, 0.422607f, 0.470703f, 0.518066f, 0.565430f, 0.609863f, 0.651855f, 0.691406f, 0.726562f, 0.758301f,
+ 0.787109f, 0.812500f, 0.835449f, 0.855957f, 0.872559f, 0.887695f, 0.901367f, 0.913574f, 0.923828f, 0.933105f, 0.975098f, 0.977539f,
+ 0.977539f, 0.977539f, 0.978027f, 0.977051f, 0.000240f, 0.000808f, 0.001537f, 0.002106f, 0.002493f, 0.003729f, 0.004036f, 0.004982f,
+ 0.005539f, 0.006454f, 0.007526f, 0.008690f, 0.009987f, 0.011421f, 0.012894f, 0.014618f, 0.016464f, 0.018539f, 0.021118f, 0.023865f,
+ 0.026794f, 0.030487f, 0.034241f, 0.038879f, 0.044067f, 0.050690f, 0.057678f, 0.066040f, 0.076111f, 0.087524f, 0.101379f, 0.117737f,
+ 0.136353f, 0.158325f, 0.183594f, 0.213501f, 0.247192f, 0.284912f, 0.327393f, 0.372803f, 0.420410f, 0.468750f, 0.518066f, 0.565430f,
+ 0.611328f, 0.654297f, 0.694336f, 0.729980f, 0.762207f, 0.791504f, 0.817383f, 0.839844f, 0.859863f, 0.876953f, 0.891602f, 0.905762f,
+ 0.917480f, 0.928711f, 0.973633f, 0.975098f, 0.976562f, 0.975586f, 0.976562f, 0.976562f, 0.000240f, 0.000587f, 0.001223f, 0.001691f,
+ 0.002499f, 0.003008f, 0.003643f, 0.004295f, 0.004795f, 0.005726f, 0.006649f, 0.007671f, 0.008766f, 0.010002f, 0.011307f, 0.012764f,
+ 0.014465f, 0.016388f, 0.018387f, 0.020599f, 0.023453f, 0.026291f, 0.029572f, 0.033417f, 0.037964f, 0.043427f, 0.049316f, 0.056519f,
+ 0.064819f, 0.074219f, 0.085693f, 0.099121f, 0.115112f, 0.133301f, 0.155273f, 0.180420f, 0.210205f, 0.244751f, 0.282715f, 0.324951f,
+ 0.371338f, 0.419434f, 0.468994f, 0.518555f, 0.566895f, 0.613770f, 0.658203f, 0.698242f, 0.735352f, 0.766602f, 0.796875f, 0.821289f,
+ 0.844238f, 0.863770f, 0.881836f, 0.896973f, 0.910156f, 0.922363f, 0.971191f, 0.974121f, 0.974609f, 0.974121f, 0.974609f, 0.974609f,
+ 0.000228f, 0.000671f, 0.001122f, 0.001607f, 0.002291f, 0.002836f, 0.003319f, 0.003817f, 0.004509f, 0.005253f, 0.005894f, 0.006840f,
+ 0.007820f, 0.008972f, 0.010086f, 0.011391f, 0.012848f, 0.014328f, 0.016266f, 0.018158f, 0.020447f, 0.022720f, 0.026031f, 0.029053f,
+ 0.032593f, 0.037109f, 0.042236f, 0.048340f, 0.055115f, 0.063049f, 0.072632f, 0.083801f, 0.097351f, 0.112488f, 0.130493f, 0.152222f,
+ 0.178101f, 0.208008f, 0.241943f, 0.280762f, 0.323730f, 0.370117f, 0.419434f, 0.470459f, 0.520996f, 0.570801f, 0.617676f, 0.663086f,
+ 0.704102f, 0.740234f, 0.773438f, 0.802246f, 0.829102f, 0.850098f, 0.870117f, 0.887695f, 0.902832f, 0.916016f, 0.969238f, 0.972168f,
+ 0.972168f, 0.972656f, 0.972656f, 0.972168f, 0.000121f, 0.000526f, 0.001092f, 0.001670f, 0.001744f, 0.002420f, 0.002945f, 0.003237f,
+ 0.004013f, 0.004894f, 0.005421f, 0.005932f, 0.006996f, 0.007904f, 0.008873f, 0.009995f, 0.011391f, 0.012756f, 0.014053f, 0.015884f,
+ 0.017715f, 0.019775f, 0.022324f, 0.025406f, 0.028290f, 0.032349f, 0.036560f, 0.041412f, 0.047058f, 0.053772f, 0.061493f, 0.070862f,
+ 0.081848f, 0.094666f, 0.110229f, 0.128662f, 0.150024f, 0.175903f, 0.205566f, 0.239990f, 0.279785f, 0.323486f, 0.370850f, 0.421143f,
+ 0.473633f, 0.524902f, 0.576172f, 0.625000f, 0.668457f, 0.710938f, 0.748535f, 0.781250f, 0.810059f, 0.835449f, 0.857910f, 0.877441f,
+ 0.894531f, 0.908691f, 0.966797f, 0.970215f, 0.970703f, 0.970703f, 0.970703f, 0.970215f, 0.000127f, 0.000521f, 0.001083f, 0.001460f,
+ 0.001684f, 0.002111f, 0.002563f, 0.003048f, 0.003618f, 0.004124f, 0.004936f, 0.005543f, 0.006340f, 0.007111f, 0.008049f, 0.008774f,
+ 0.009865f, 0.011162f, 0.012360f, 0.013840f, 0.015465f, 0.017181f, 0.019531f, 0.021973f, 0.024582f, 0.027847f, 0.031342f, 0.035706f,
+ 0.040100f, 0.045990f, 0.052521f, 0.060089f, 0.069214f, 0.080017f, 0.093079f, 0.108521f, 0.126709f, 0.148071f, 0.174072f, 0.204224f,
+ 0.239502f, 0.279541f, 0.324219f, 0.373047f, 0.424805f, 0.477295f, 0.530762f, 0.583008f, 0.632324f, 0.677246f, 0.719727f, 0.756348f,
+ 0.789551f, 0.819336f, 0.842773f, 0.866211f, 0.885742f, 0.901855f, 0.965332f, 0.967773f, 0.968262f, 0.967773f, 0.968750f, 0.968262f,
+ 0.000244f, 0.000397f, 0.001001f, 0.001181f, 0.001642f, 0.001872f, 0.002460f, 0.002712f, 0.003061f, 0.003723f, 0.004520f, 0.005043f,
+ 0.005547f, 0.006451f, 0.007057f, 0.007828f, 0.008942f, 0.009872f, 0.010857f, 0.012131f, 0.013557f, 0.015198f, 0.017059f, 0.019241f,
+ 0.021454f, 0.024048f, 0.027069f, 0.030594f, 0.034332f, 0.039001f, 0.044952f, 0.050873f, 0.058716f, 0.067505f, 0.078369f, 0.091309f,
+ 0.106506f, 0.124695f, 0.146484f, 0.172852f, 0.203369f, 0.239014f, 0.280273f, 0.326172f, 0.376465f, 0.429443f, 0.483643f, 0.538574f,
+ 0.591309f, 0.641602f, 0.687500f, 0.729492f, 0.766602f, 0.800293f, 0.828613f, 0.854004f, 0.874512f, 0.893555f, 0.961914f, 0.965332f,
+ 0.965820f, 0.966309f, 0.966309f, 0.965820f, 0.000243f, 0.000453f, 0.000888f, 0.001245f, 0.001342f, 0.001847f, 0.002060f, 0.002541f,
+ 0.002991f, 0.003355f, 0.003679f, 0.004379f, 0.005177f, 0.005413f, 0.006283f, 0.007038f, 0.007896f, 0.008507f, 0.009552f, 0.010628f,
+ 0.011909f, 0.013306f, 0.015038f, 0.016388f, 0.018433f, 0.020752f, 0.023254f, 0.026413f, 0.029617f, 0.033447f, 0.037842f, 0.043701f,
+ 0.049896f, 0.057190f, 0.066101f, 0.076660f, 0.089600f, 0.104553f, 0.123230f, 0.145386f, 0.171387f, 0.202637f, 0.239624f, 0.281982f,
+ 0.329346f, 0.380859f, 0.436035f, 0.491943f, 0.547852f, 0.602539f, 0.653809f, 0.699707f, 0.741699f, 0.778320f, 0.811035f, 0.838867f,
+ 0.862793f, 0.884766f, 0.959961f, 0.963379f, 0.963379f, 0.963379f, 0.964355f, 0.963379f, 0.000241f, 0.000452f, 0.000798f, 0.001119f,
+ 0.001220f, 0.001430f, 0.001902f, 0.002277f, 0.002737f, 0.002893f, 0.003624f, 0.003937f, 0.004436f, 0.005089f, 0.005669f, 0.006226f,
+ 0.006680f, 0.007519f, 0.008568f, 0.009384f, 0.010422f, 0.011795f, 0.012840f, 0.014526f, 0.016235f, 0.017929f, 0.020218f, 0.022736f,
+ 0.025146f, 0.028580f, 0.032684f, 0.036896f, 0.042511f, 0.048431f, 0.055634f, 0.064453f, 0.075317f, 0.088196f, 0.103333f, 0.121948f,
+ 0.144287f, 0.171143f, 0.203491f, 0.241577f, 0.285156f, 0.334229f, 0.387939f, 0.444580f, 0.501953f, 0.559570f, 0.614746f, 0.666504f,
+ 0.712402f, 0.755371f, 0.791504f, 0.823242f, 0.851074f, 0.875000f, 0.956543f, 0.959961f, 0.960938f, 0.960449f, 0.960449f, 0.960449f,
+ 0.000000f, 0.000263f, 0.000693f, 0.000873f, 0.001183f, 0.001447f, 0.001476f, 0.002068f, 0.002171f, 0.002857f, 0.003164f, 0.003542f,
+ 0.003778f, 0.004326f, 0.004906f, 0.005436f, 0.006126f, 0.006687f, 0.007229f, 0.008377f, 0.009232f, 0.010223f, 0.011436f, 0.012527f,
+ 0.013832f, 0.015747f, 0.017365f, 0.019363f, 0.021667f, 0.024231f, 0.027695f, 0.031769f, 0.035889f, 0.041016f, 0.047028f, 0.054504f,
+ 0.063110f, 0.073975f, 0.086487f, 0.101807f, 0.120972f, 0.143555f, 0.171753f, 0.204956f, 0.244263f, 0.289551f, 0.340576f, 0.396484f,
+ 0.455078f, 0.514648f, 0.573730f, 0.630371f, 0.681152f, 0.729004f, 0.770020f, 0.806641f, 0.837402f, 0.863770f, 0.953613f, 0.956543f,
+ 0.957520f, 0.957031f, 0.957031f, 0.958008f, 0.000000f, 0.000356f, 0.000641f, 0.000870f, 0.000998f, 0.001134f, 0.001495f, 0.001724f,
+ 0.002436f, 0.002478f, 0.002775f, 0.003113f, 0.003435f, 0.003864f, 0.004314f, 0.004704f, 0.005276f, 0.005886f, 0.006599f, 0.007309f,
+ 0.008003f, 0.008987f, 0.009987f, 0.010941f, 0.012192f, 0.013466f, 0.015030f, 0.016708f, 0.018906f, 0.021103f, 0.023788f, 0.026886f,
+ 0.030457f, 0.034943f, 0.040009f, 0.045959f, 0.053162f, 0.061920f, 0.072144f, 0.085205f, 0.101257f, 0.120422f, 0.143555f, 0.172363f,
+ 0.206909f, 0.248047f, 0.295410f, 0.349121f, 0.407715f, 0.468750f, 0.530762f, 0.589844f, 0.647949f, 0.699707f, 0.746094f, 0.786621f,
+ 0.823242f, 0.852051f, 0.950195f, 0.953125f, 0.954102f, 0.954102f, 0.954102f, 0.954102f, 0.000231f, 0.000449f, 0.000516f, 0.000760f,
+ 0.000868f, 0.001152f, 0.001403f, 0.001773f, 0.002165f, 0.002245f, 0.002550f, 0.002783f, 0.003277f, 0.003660f, 0.003782f, 0.004120f,
+ 0.004631f, 0.005268f, 0.005795f, 0.006344f, 0.007053f, 0.007835f, 0.008598f, 0.009460f, 0.010689f, 0.011551f, 0.012726f, 0.014359f,
+ 0.016052f, 0.017975f, 0.020218f, 0.022812f, 0.025803f, 0.029251f, 0.033386f, 0.038574f, 0.044556f, 0.051941f, 0.060577f, 0.071045f,
+ 0.084106f, 0.100342f, 0.119751f, 0.144043f, 0.174194f, 0.209961f, 0.253418f, 0.303467f, 0.359619f, 0.420898f, 0.483887f, 0.547852f,
+ 0.609375f, 0.667480f, 0.719727f, 0.765625f, 0.804688f, 0.839844f, 0.946289f, 0.949707f, 0.950195f, 0.950684f, 0.950684f, 0.950195f,
+ 0.000201f, 0.000336f, 0.000452f, 0.000627f, 0.000793f, 0.000966f, 0.001134f, 0.001578f, 0.001790f, 0.001896f, 0.002254f, 0.002464f,
+ 0.002825f, 0.003012f, 0.003414f, 0.003626f, 0.004131f, 0.004608f, 0.005058f, 0.005642f, 0.006191f, 0.006771f, 0.007378f, 0.008057f,
+ 0.009132f, 0.009918f, 0.010826f, 0.012314f, 0.013794f, 0.015381f, 0.017197f, 0.019257f, 0.021912f, 0.024841f, 0.028259f, 0.032318f,
+ 0.037262f, 0.043427f, 0.050537f, 0.059021f, 0.070007f, 0.083191f, 0.099609f, 0.120239f, 0.145508f, 0.176636f, 0.214600f, 0.260254f,
+ 0.313232f, 0.372803f, 0.437012f, 0.503418f, 0.568359f, 0.631836f, 0.688965f, 0.741211f, 0.786621f, 0.825195f, 0.941406f, 0.946289f,
+ 0.946289f, 0.946777f, 0.946289f, 0.947266f, 0.000000f, 0.000317f, 0.000445f, 0.000453f, 0.000781f, 0.000794f, 0.001183f, 0.001289f,
+ 0.001479f, 0.001832f, 0.001874f, 0.002256f, 0.002270f, 0.002716f, 0.002960f, 0.003273f, 0.003630f, 0.003948f, 0.004467f, 0.004833f,
+ 0.005451f, 0.005962f, 0.006367f, 0.007088f, 0.007717f, 0.008400f, 0.009506f, 0.010445f, 0.011658f, 0.012993f, 0.014618f, 0.016357f,
+ 0.018524f, 0.021210f, 0.023712f, 0.027252f, 0.031219f, 0.036041f, 0.041962f, 0.049194f, 0.057892f, 0.068604f, 0.082642f, 0.099304f,
+ 0.120728f, 0.147217f, 0.180054f, 0.221191f, 0.269287f, 0.325928f, 0.388916f, 0.457275f, 0.525391f, 0.593262f, 0.657715f, 0.714355f,
+ 0.766113f, 0.809082f, 0.937500f, 0.940918f, 0.941895f, 0.941895f, 0.941895f, 0.942383f, 0.000243f, 0.000238f, 0.000411f, 0.000532f,
+ 0.000530f, 0.000764f, 0.000853f, 0.001171f, 0.001417f, 0.001545f, 0.001799f, 0.001900f, 0.002094f, 0.002354f, 0.002577f, 0.002703f,
+ 0.003155f, 0.003428f, 0.003809f, 0.004227f, 0.004677f, 0.004997f, 0.005386f, 0.005913f, 0.006741f, 0.007225f, 0.008057f, 0.008873f,
+ 0.009819f, 0.011101f, 0.012253f, 0.013725f, 0.015488f, 0.017410f, 0.019791f, 0.022598f, 0.025635f, 0.030014f, 0.034973f, 0.040527f,
+ 0.047729f, 0.056702f, 0.067505f, 0.081848f, 0.099609f, 0.121521f, 0.149902f, 0.185181f, 0.228516f, 0.280762f, 0.341553f, 0.408936f,
+ 0.480225f, 0.552246f, 0.622070f, 0.686035f, 0.742188f, 0.792480f, 0.932129f, 0.935547f, 0.937012f, 0.937012f, 0.936523f, 0.937500f,
+ 0.000000f, 0.000232f, 0.000330f, 0.000512f, 0.000523f, 0.000907f, 0.000953f, 0.001018f, 0.001234f, 0.001344f, 0.001610f, 0.001612f,
+ 0.001845f, 0.002054f, 0.002218f, 0.002453f, 0.002829f, 0.003105f, 0.003300f, 0.003712f, 0.003853f, 0.004280f, 0.004631f, 0.005112f,
+ 0.005665f, 0.006279f, 0.006779f, 0.007481f, 0.008362f, 0.009270f, 0.010338f, 0.011505f, 0.012848f, 0.014549f, 0.016403f, 0.018936f,
+ 0.021622f, 0.024750f, 0.028900f, 0.033447f, 0.039185f, 0.046448f, 0.055603f, 0.067078f, 0.081238f, 0.100037f, 0.123230f, 0.153564f,
+ 0.191284f, 0.238525f, 0.295166f, 0.361084f, 0.432861f, 0.507812f, 0.582520f, 0.653320f, 0.717285f, 0.772461f, 0.926270f, 0.931152f,
+ 0.931152f, 0.932129f, 0.932129f, 0.932129f, 0.000118f, 0.000219f, 0.000227f, 0.000405f, 0.000689f, 0.000726f, 0.000910f, 0.000847f,
+ 0.001072f, 0.001114f, 0.001388f, 0.001447f, 0.001656f, 0.001811f, 0.001897f, 0.002253f, 0.002373f, 0.002617f, 0.002796f, 0.003054f,
+ 0.003414f, 0.003681f, 0.003929f, 0.004353f, 0.004902f, 0.005322f, 0.005863f, 0.006424f, 0.007000f, 0.007755f, 0.008675f, 0.009506f,
+ 0.010704f, 0.012215f, 0.013557f, 0.015686f, 0.017807f, 0.020630f, 0.023376f, 0.027328f, 0.032013f, 0.038177f, 0.045288f, 0.054626f,
+ 0.066284f, 0.081543f, 0.100891f, 0.125977f, 0.158447f, 0.199951f, 0.251465f, 0.313965f, 0.384521f, 0.461670f, 0.540527f, 0.617188f,
+ 0.688965f, 0.750977f, 0.920410f, 0.924805f, 0.925781f, 0.926270f, 0.926758f, 0.925781f, 0.000230f, 0.000198f, 0.000217f, 0.000338f,
+ 0.000584f, 0.000786f, 0.000699f, 0.000893f, 0.000954f, 0.000959f, 0.001153f, 0.001165f, 0.001375f, 0.001545f, 0.001752f, 0.001752f,
+ 0.002062f, 0.002235f, 0.002399f, 0.002699f, 0.002853f, 0.002995f, 0.003372f, 0.003603f, 0.003944f, 0.004513f, 0.004704f, 0.005226f,
+ 0.005878f, 0.006527f, 0.006992f, 0.007889f, 0.008919f, 0.010002f, 0.011124f, 0.012604f, 0.014526f, 0.016510f, 0.019104f, 0.022308f,
+ 0.026077f, 0.030701f, 0.036774f, 0.044098f, 0.053558f, 0.065735f, 0.081299f, 0.101990f, 0.129517f, 0.164917f, 0.210938f, 0.268066f,
+ 0.336914f, 0.413818f, 0.496094f, 0.579102f, 0.657227f, 0.727539f, 0.913574f, 0.917969f, 0.918945f, 0.919434f, 0.919922f, 0.919922f,
+ 0.000000f, 0.000101f, 0.000214f, 0.000208f, 0.000339f, 0.000461f, 0.000577f, 0.000780f, 0.000777f, 0.000840f, 0.000853f, 0.001064f,
+ 0.001198f, 0.001327f, 0.001489f, 0.001687f, 0.001809f, 0.001884f, 0.002008f, 0.002129f, 0.002434f, 0.002514f, 0.002949f, 0.003000f,
+ 0.003351f, 0.003674f, 0.003918f, 0.004356f, 0.004875f, 0.005310f, 0.005768f, 0.006458f, 0.007244f, 0.008255f, 0.008949f, 0.010361f,
+ 0.011589f, 0.013290f, 0.015335f, 0.017776f, 0.020828f, 0.024521f, 0.029236f, 0.035431f, 0.042694f, 0.052490f, 0.065369f, 0.082336f,
+ 0.104492f, 0.134277f, 0.173828f, 0.225464f, 0.290039f, 0.365234f, 0.449707f, 0.536133f, 0.623047f, 0.702637f, 0.905273f, 0.911133f,
+ 0.912598f, 0.913086f, 0.913086f, 0.913086f, 0.000000f, 0.000167f, 0.000167f, 0.000316f, 0.000432f, 0.000444f, 0.000608f, 0.000611f,
+ 0.000678f, 0.000750f, 0.000899f, 0.000925f, 0.001043f, 0.001125f, 0.001222f, 0.001343f, 0.001470f, 0.001608f, 0.001679f, 0.001804f,
+ 0.001976f, 0.002234f, 0.002361f, 0.002710f, 0.002748f, 0.003035f, 0.003290f, 0.003647f, 0.003990f, 0.004295f, 0.004745f, 0.005318f,
+ 0.005920f, 0.006618f, 0.007347f, 0.008270f, 0.009361f, 0.010719f, 0.012291f, 0.014221f, 0.016693f, 0.019592f, 0.023239f, 0.027969f,
+ 0.033752f, 0.041534f, 0.051666f, 0.065369f, 0.083618f, 0.108276f, 0.141357f, 0.186035f, 0.244141f, 0.316650f, 0.400635f, 0.491699f,
+ 0.585938f, 0.672852f, 0.897461f, 0.903320f, 0.904297f, 0.903809f, 0.903809f, 0.904297f, 0.000000f, 0.000098f, 0.000145f, 0.000289f,
+ 0.000399f, 0.000424f, 0.000429f, 0.000382f, 0.000529f, 0.000613f, 0.000660f, 0.000836f, 0.000907f, 0.000940f, 0.001005f, 0.001188f,
+ 0.001306f, 0.001451f, 0.001420f, 0.001554f, 0.001667f, 0.001783f, 0.001955f, 0.002125f, 0.002357f, 0.002493f, 0.002760f, 0.002867f,
+ 0.003298f, 0.003626f, 0.003878f, 0.004341f, 0.004704f, 0.005356f, 0.005905f, 0.006512f, 0.007435f, 0.008377f, 0.009598f, 0.011055f,
+ 0.012978f, 0.015388f, 0.018036f, 0.021698f, 0.026337f, 0.032532f, 0.040192f, 0.050995f, 0.065125f, 0.085510f, 0.113037f, 0.150513f,
+ 0.201538f, 0.268799f, 0.351318f, 0.444824f, 0.543457f, 0.641602f, 0.888672f, 0.894043f, 0.894531f, 0.895508f, 0.895020f, 0.895508f,
+ 0.000000f, 0.000000f, 0.000032f, 0.000169f, 0.000338f, 0.000372f, 0.000468f, 0.000471f, 0.000460f, 0.000493f, 0.000588f, 0.000715f,
+ 0.000762f, 0.000912f, 0.000831f, 0.001001f, 0.001043f, 0.001133f, 0.001242f, 0.001312f, 0.001446f, 0.001529f, 0.001647f, 0.001829f,
+ 0.001982f, 0.002121f, 0.002165f, 0.002438f, 0.002628f, 0.002865f, 0.003113f, 0.003424f, 0.003622f, 0.004131f, 0.004639f, 0.005222f,
+ 0.005875f, 0.006622f, 0.007496f, 0.008575f, 0.009987f, 0.011665f, 0.013985f, 0.016617f, 0.019913f, 0.024704f, 0.030960f, 0.039185f,
+ 0.050323f, 0.066284f, 0.088196f, 0.119568f, 0.163208f, 0.223511f, 0.302002f, 0.395752f, 0.499756f, 0.605957f, 0.878418f, 0.883301f,
+ 0.884766f, 0.884766f, 0.885254f, 0.885254f, 0.000000f, 0.000000f, 0.000000f, 0.000216f, 0.000237f, 0.000338f, 0.000387f, 0.000341f,
+ 0.000435f, 0.000441f, 0.000461f, 0.000577f, 0.000544f, 0.000720f, 0.000813f, 0.000823f, 0.000912f, 0.000936f, 0.000994f, 0.001026f,
+ 0.001240f, 0.001268f, 0.001365f, 0.001415f, 0.001590f, 0.001565f, 0.001870f, 0.001929f, 0.002123f, 0.002377f, 0.002430f, 0.002565f,
+ 0.002947f, 0.003384f, 0.003662f, 0.004105f, 0.004513f, 0.005047f, 0.005741f, 0.006550f, 0.007549f, 0.008865f, 0.010612f, 0.012466f,
+ 0.015350f, 0.018677f, 0.023270f, 0.029800f, 0.038361f, 0.050323f, 0.067932f, 0.092590f, 0.129395f, 0.181274f, 0.253418f, 0.345459f,
+ 0.452637f, 0.567383f, 0.866699f, 0.872559f, 0.873047f, 0.873535f, 0.873047f, 0.873535f, 0.000000f, 0.000000f, 0.000121f, 0.000182f,
+ 0.000187f, 0.000237f, 0.000264f, 0.000360f, 0.000360f, 0.000397f, 0.000398f, 0.000412f, 0.000432f, 0.000546f, 0.000575f, 0.000690f,
+ 0.000731f, 0.000727f, 0.000807f, 0.000843f, 0.000924f, 0.001034f, 0.001093f, 0.001111f, 0.001251f, 0.001249f, 0.001334f, 0.001612f,
+ 0.001717f, 0.001820f, 0.002090f, 0.002161f, 0.002354f, 0.002600f, 0.002787f, 0.003119f, 0.003586f, 0.003878f, 0.004452f, 0.004913f,
+ 0.005772f, 0.006508f, 0.007679f, 0.009285f, 0.011086f, 0.013840f, 0.016968f, 0.021820f, 0.028259f, 0.037628f, 0.050812f, 0.070129f,
+ 0.099670f, 0.143433f, 0.207031f, 0.294922f, 0.403076f, 0.525879f, 0.853516f, 0.859375f, 0.860840f, 0.860352f, 0.862305f, 0.861328f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000181f, 0.000198f, 0.000181f, 0.000240f, 0.000275f, 0.000311f, 0.000427f, 0.000447f,
+ 0.000395f, 0.000472f, 0.000456f, 0.000557f, 0.000518f, 0.000562f, 0.000635f, 0.000664f, 0.000868f, 0.000887f, 0.000865f, 0.001025f,
+ 0.001014f, 0.001164f, 0.001096f, 0.001317f, 0.001382f, 0.001432f, 0.001445f, 0.001765f, 0.001744f, 0.002100f, 0.002144f, 0.002350f,
+ 0.002655f, 0.002947f, 0.003294f, 0.003780f, 0.004265f, 0.004971f, 0.005699f, 0.006786f, 0.007957f, 0.009636f, 0.011932f, 0.015823f,
+ 0.020142f, 0.026749f, 0.036530f, 0.051392f, 0.073792f, 0.109375f, 0.164185f, 0.244629f, 0.351562f, 0.479980f, 0.839355f, 0.844727f,
+ 0.846680f, 0.847656f, 0.847168f, 0.846680f, 0.000000f, 0.000121f, 0.000120f, 0.000119f, 0.000162f, 0.000133f, 0.000170f, 0.000201f,
+ 0.000204f, 0.000222f, 0.000258f, 0.000285f, 0.000324f, 0.000327f, 0.000422f, 0.000395f, 0.000431f, 0.000517f, 0.000632f, 0.000529f,
+ 0.000589f, 0.000592f, 0.000735f, 0.000714f, 0.000795f, 0.000778f, 0.000823f, 0.001063f, 0.001080f, 0.001141f, 0.001154f, 0.001308f,
+ 0.001439f, 0.001546f, 0.001689f, 0.001886f, 0.001978f, 0.002174f, 0.002377f, 0.002798f, 0.003277f, 0.003519f, 0.004181f, 0.004780f,
+ 0.005768f, 0.006863f, 0.008644f, 0.010750f, 0.014030f, 0.018448f, 0.025635f, 0.036194f, 0.053223f, 0.080811f, 0.125610f, 0.196533f,
+ 0.299316f, 0.430176f, 0.822754f, 0.830078f, 0.831055f, 0.831543f, 0.832031f, 0.831543f, 0.000000f, 0.000121f, 0.000120f, 0.000118f,
+ 0.000117f, 0.000120f, 0.000123f, 0.000151f, 0.000154f, 0.000175f, 0.000254f, 0.000190f, 0.000211f, 0.000306f, 0.000335f, 0.000358f,
+ 0.000394f, 0.000417f, 0.000443f, 0.000410f, 0.000565f, 0.000565f, 0.000491f, 0.000623f, 0.000616f, 0.000631f, 0.000738f, 0.000676f,
+ 0.000759f, 0.000924f, 0.000895f, 0.001030f, 0.001064f, 0.001176f, 0.001267f, 0.001438f, 0.001518f, 0.001704f, 0.001742f, 0.002028f,
+ 0.002384f, 0.002703f, 0.002972f, 0.003393f, 0.004051f, 0.004959f, 0.005993f, 0.007271f, 0.009277f, 0.012390f, 0.016968f, 0.024368f,
+ 0.036560f, 0.056610f, 0.091797f, 0.151245f, 0.246460f, 0.379639f, 0.805664f, 0.812500f, 0.813477f, 0.813965f, 0.813965f, 0.813965f,
+ 0.000000f, 0.000000f, 0.000118f, 0.000117f, 0.000116f, 0.000114f, 0.000113f, 0.000108f, 0.000127f, 0.000153f, 0.000133f, 0.000202f,
+ 0.000217f, 0.000223f, 0.000242f, 0.000186f, 0.000280f, 0.000304f, 0.000318f, 0.000342f, 0.000338f, 0.000473f, 0.000360f, 0.000484f,
+ 0.000422f, 0.000514f, 0.000527f, 0.000571f, 0.000633f, 0.000568f, 0.000639f, 0.000816f, 0.000789f, 0.000889f, 0.000891f, 0.000966f,
+ 0.001125f, 0.001276f, 0.001316f, 0.001496f, 0.001658f, 0.001818f, 0.002047f, 0.002502f, 0.002781f, 0.003201f, 0.003914f, 0.004795f,
+ 0.006096f, 0.007996f, 0.010918f, 0.015617f, 0.023697f, 0.037567f, 0.063477f, 0.111084f, 0.194824f, 0.324951f, 0.786133f, 0.792969f,
+ 0.794434f, 0.793945f, 0.794922f, 0.794434f, 0.000000f, 0.000119f, 0.000117f, 0.000115f, 0.000113f, 0.000112f, 0.000110f, 0.000109f,
+ 0.000104f, 0.000098f, 0.000099f, 0.000136f, 0.000112f, 0.000126f, 0.000175f, 0.000189f, 0.000196f, 0.000220f, 0.000216f, 0.000247f,
+ 0.000258f, 0.000274f, 0.000285f, 0.000309f, 0.000308f, 0.000321f, 0.000381f, 0.000390f, 0.000475f, 0.000511f, 0.000485f, 0.000501f,
+ 0.000641f, 0.000588f, 0.000652f, 0.000764f, 0.000808f, 0.000952f, 0.000906f, 0.001037f, 0.001110f, 0.001249f, 0.001411f, 0.001647f,
+ 0.001894f, 0.002159f, 0.002687f, 0.003223f, 0.004036f, 0.005150f, 0.006989f, 0.009644f, 0.014420f, 0.023361f, 0.040802f, 0.076050f,
+ 0.146362f, 0.269287f, 0.763184f, 0.770996f, 0.771973f, 0.771973f, 0.772461f, 0.772461f, 0.000121f, 0.000116f, 0.000114f, 0.000112f,
+ 0.000109f, 0.000108f, 0.000106f, 0.000105f, 0.000104f, 0.000101f, 0.000095f, 0.000090f, 0.000085f, 0.000083f, 0.000104f, 0.000097f,
+ 0.000094f, 0.000154f, 0.000127f, 0.000178f, 0.000197f, 0.000194f, 0.000233f, 0.000213f, 0.000279f, 0.000294f, 0.000293f, 0.000258f,
+ 0.000319f, 0.000394f, 0.000344f, 0.000369f, 0.000394f, 0.000410f, 0.000438f, 0.000509f, 0.000514f, 0.000580f, 0.000617f, 0.000684f,
+ 0.000807f, 0.000812f, 0.000914f, 0.001094f, 0.001183f, 0.001436f, 0.001639f, 0.002033f, 0.002523f, 0.003073f, 0.004063f, 0.005680f,
+ 0.008560f, 0.013466f, 0.024109f, 0.047791f, 0.102051f, 0.213867f, 0.740234f, 0.746582f, 0.748047f, 0.748535f, 0.749023f, 0.749023f,
+ 0.000000f, 0.000113f, 0.000108f, 0.000107f, 0.000104f, 0.000102f, 0.000099f, 0.000099f, 0.000097f, 0.000096f, 0.000095f, 0.000091f,
+ 0.000086f, 0.000081f, 0.000077f, 0.000073f, 0.000085f, 0.000091f, 0.000070f, 0.000102f, 0.000117f, 0.000131f, 0.000145f, 0.000148f,
+ 0.000171f, 0.000178f, 0.000178f, 0.000207f, 0.000225f, 0.000209f, 0.000285f, 0.000238f, 0.000260f, 0.000298f, 0.000331f, 0.000360f,
+ 0.000371f, 0.000346f, 0.000407f, 0.000443f, 0.000494f, 0.000516f, 0.000578f, 0.000662f, 0.000767f, 0.000847f, 0.001004f, 0.001149f,
+ 0.001451f, 0.001783f, 0.002310f, 0.003262f, 0.004593f, 0.007309f, 0.012985f, 0.026703f, 0.064026f, 0.158813f, 0.712891f, 0.719238f,
+ 0.722168f, 0.721680f, 0.722168f, 0.722656f, 0.000000f, 0.000105f, 0.000102f, 0.000098f, 0.000094f, 0.000092f, 0.000091f, 0.000089f,
+ 0.000088f, 0.000086f, 0.000085f, 0.000084f, 0.000083f, 0.000080f, 0.000076f, 0.000073f, 0.000069f, 0.000065f, 0.000062f, 0.000059f,
+ 0.000068f, 0.000063f, 0.000069f, 0.000074f, 0.000087f, 0.000102f, 0.000112f, 0.000130f, 0.000137f, 0.000129f, 0.000143f, 0.000168f,
+ 0.000180f, 0.000178f, 0.000189f, 0.000198f, 0.000222f, 0.000240f, 0.000262f, 0.000285f, 0.000304f, 0.000317f, 0.000339f, 0.000399f,
+ 0.000439f, 0.000490f, 0.000570f, 0.000658f, 0.000781f, 0.000988f, 0.001235f, 0.001674f, 0.002407f, 0.003725f, 0.006485f, 0.013199f,
+ 0.034546f, 0.107605f, 0.682129f, 0.691406f, 0.692871f, 0.691406f, 0.692871f, 0.692871f, 0.000105f, 0.000089f, 0.000085f, 0.000080f,
+ 0.000078f, 0.000078f, 0.000075f, 0.000074f, 0.000072f, 0.000072f, 0.000070f, 0.000071f, 0.000069f, 0.000069f, 0.000069f, 0.000068f,
+ 0.000066f, 0.000063f, 0.000060f, 0.000057f, 0.000054f, 0.000052f, 0.000049f, 0.000047f, 0.000046f, 0.000045f, 0.000048f, 0.000055f,
+ 0.000060f, 0.000068f, 0.000083f, 0.000087f, 0.000092f, 0.000103f, 0.000109f, 0.000117f, 0.000130f, 0.000150f, 0.000148f, 0.000142f,
+ 0.000167f, 0.000186f, 0.000210f, 0.000213f, 0.000232f, 0.000280f, 0.000292f, 0.000329f, 0.000391f, 0.000456f, 0.000596f, 0.000764f,
+ 0.001065f, 0.001633f, 0.002806f, 0.005909f, 0.015488f, 0.062378f, 0.651367f, 0.659668f, 0.661133f, 0.661133f, 0.660645f, 0.661621f,
+ 0.000034f, 0.000037f, 0.000048f, 0.000051f, 0.000047f, 0.000049f, 0.000047f, 0.000051f, 0.000049f, 0.000051f, 0.000049f, 0.000050f,
+ 0.000051f, 0.000050f, 0.000050f, 0.000049f, 0.000051f, 0.000050f, 0.000051f, 0.000050f, 0.000049f, 0.000047f, 0.000045f, 0.000043f,
+ 0.000041f, 0.000039f, 0.000037f, 0.000035f, 0.000033f, 0.000032f, 0.000030f, 0.000029f, 0.000034f, 0.000041f, 0.000046f, 0.000057f,
+ 0.000063f, 0.000067f, 0.000065f, 0.000072f, 0.000083f, 0.000093f, 0.000096f, 0.000102f, 0.000102f, 0.000135f, 0.000134f, 0.000151f,
+ 0.000184f, 0.000198f, 0.000245f, 0.000306f, 0.000425f, 0.000607f, 0.001032f, 0.002081f, 0.005886f, 0.027924f, 0.617188f, 0.625977f,
+ 0.627441f, 0.627930f, 0.626953f, 0.628418f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000006f, 0.000010f, 0.000014f,
+ 0.000016f, 0.000014f, 0.000019f, 0.000022f, 0.000022f, 0.000022f, 0.000025f, 0.000026f, 0.000027f, 0.000028f, 0.000029f, 0.000029f,
+ 0.000029f, 0.000030f, 0.000030f, 0.000031f, 0.000032f, 0.000032f, 0.000031f, 0.000030f, 0.000028f, 0.000027f, 0.000026f, 0.000024f,
+ 0.000023f, 0.000022f, 0.000021f, 0.000020f, 0.000019f, 0.000021f, 0.000022f, 0.000024f, 0.000027f, 0.000035f, 0.000041f, 0.000034f,
+ 0.000041f, 0.000052f, 0.000051f, 0.000051f, 0.000058f, 0.000070f, 0.000074f, 0.000103f, 0.000119f, 0.000169f, 0.000277f, 0.000510f,
+ 0.001495f, 0.008766f, 0.583008f, 0.590332f, 0.591797f, 0.591797f, 0.592285f, 0.592285f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000003f, 0.000005f, 0.000006f, 0.000008f, 0.000009f, 0.000010f, 0.000010f,
+ 0.000012f, 0.000012f, 0.000013f, 0.000014f, 0.000015f, 0.000015f, 0.000015f, 0.000015f, 0.000014f, 0.000013f, 0.000013f, 0.000012f,
+ 0.000011f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000014f, 0.000011f, 0.000015f, 0.000017f, 0.000017f, 0.000021f, 0.000020f,
+ 0.000026f, 0.000026f, 0.000042f, 0.000069f, 0.000178f, 0.001302f, 0.544434f, 0.553711f, 0.554688f, 0.554688f, 0.556152f, 0.556641f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000003f, 0.000003f,
+ 0.000003f, 0.000003f, 0.000003f, 0.000002f, 0.000002f, 0.000001f, 0.000003f, 0.000003f, 0.000004f, 0.000014f, 0.506836f, 0.515137f,
+ 0.516113f, 0.516602f, 0.517090f, 0.517578f,
+ },
+ {
+ 0.089539f, 0.244873f, 0.368164f, 0.464355f, 0.539551f, 0.599121f, 0.648438f, 0.688477f, 0.721680f, 0.749512f, 0.772461f, 0.793945f,
+ 0.811523f, 0.826172f, 0.841309f, 0.854004f, 0.863770f, 0.874512f, 0.883301f, 0.891602f, 0.898438f, 0.906250f, 0.912109f, 0.917969f,
+ 0.922852f, 0.928223f, 0.932617f, 0.937012f, 0.940918f, 0.944336f, 0.948242f, 0.951660f, 0.954590f, 0.957520f, 0.960449f, 0.962891f,
+ 0.965820f, 0.967773f, 0.970215f, 0.972656f, 0.974609f, 0.976074f, 0.978516f, 0.979492f, 0.981934f, 0.983398f, 0.984863f, 0.986328f,
+ 0.987793f, 0.988770f, 0.990234f, 0.991699f, 0.993164f, 0.994141f, 0.995117f, 0.996582f, 0.997559f, 0.998535f, 0.999023f, 0.998535f,
+ 0.997559f, 0.997070f, 0.996582f, 0.995605f, 0.045563f, 0.143921f, 0.242798f, 0.334717f, 0.417969f, 0.489258f, 0.550293f, 0.602051f,
+ 0.646484f, 0.683594f, 0.715820f, 0.743652f, 0.767090f, 0.788086f, 0.805664f, 0.822266f, 0.836426f, 0.849609f, 0.861328f, 0.870117f,
+ 0.879883f, 0.889160f, 0.896973f, 0.903320f, 0.909668f, 0.916016f, 0.921875f, 0.926758f, 0.931641f, 0.936523f, 0.940430f, 0.943848f,
+ 0.947266f, 0.951172f, 0.954102f, 0.957520f, 0.960449f, 0.962891f, 0.965820f, 0.968262f, 0.970215f, 0.973145f, 0.974121f, 0.976074f,
+ 0.979004f, 0.980469f, 0.982422f, 0.983887f, 0.985352f, 0.986816f, 0.988281f, 0.989746f, 0.991211f, 0.992188f, 0.994141f, 0.995117f,
+ 0.996094f, 0.997070f, 0.998535f, 0.997559f, 0.997070f, 0.996582f, 0.996094f, 0.995117f, 0.026855f, 0.089233f, 0.159790f, 0.234619f,
+ 0.308838f, 0.381348f, 0.447754f, 0.507812f, 0.561035f, 0.606934f, 0.646484f, 0.683105f, 0.712402f, 0.740234f, 0.763184f, 0.784668f,
+ 0.802246f, 0.819336f, 0.833984f, 0.846680f, 0.857910f, 0.868652f, 0.878418f, 0.886719f, 0.895508f, 0.903320f, 0.909668f, 0.915527f,
+ 0.920410f, 0.926270f, 0.931152f, 0.935547f, 0.940430f, 0.943848f, 0.947754f, 0.951172f, 0.954590f, 0.958008f, 0.960449f, 0.963379f,
+ 0.966309f, 0.968750f, 0.971191f, 0.973145f, 0.975586f, 0.977051f, 0.979004f, 0.981445f, 0.982910f, 0.983887f, 0.985840f, 0.987305f,
+ 0.988770f, 0.990723f, 0.992188f, 0.993164f, 0.994629f, 0.996094f, 0.998047f, 0.997070f, 0.996582f, 0.996094f, 0.995605f, 0.995117f,
+ 0.017746f, 0.058746f, 0.108276f, 0.163818f, 0.224365f, 0.288086f, 0.351562f, 0.413086f, 0.470947f, 0.522949f, 0.569824f, 0.612793f,
+ 0.650879f, 0.684570f, 0.713867f, 0.739258f, 0.762695f, 0.783203f, 0.800781f, 0.817871f, 0.833008f, 0.845215f, 0.857422f, 0.868164f,
+ 0.877441f, 0.886230f, 0.894043f, 0.902832f, 0.908691f, 0.915039f, 0.921387f, 0.925781f, 0.930664f, 0.936035f, 0.939941f, 0.944336f,
+ 0.948242f, 0.951660f, 0.955078f, 0.957520f, 0.961426f, 0.964355f, 0.967285f, 0.968750f, 0.971680f, 0.974121f, 0.975586f, 0.978027f,
+ 0.979980f, 0.981934f, 0.983887f, 0.985352f, 0.987305f, 0.988770f, 0.989746f, 0.991211f, 0.992676f, 0.993652f, 0.997070f, 0.996582f,
+ 0.996582f, 0.996094f, 0.995117f, 0.994629f, 0.012337f, 0.041229f, 0.075928f, 0.117065f, 0.163208f, 0.214478f, 0.270020f, 0.327148f,
+ 0.383301f, 0.437500f, 0.490234f, 0.536621f, 0.581543f, 0.621094f, 0.656250f, 0.688477f, 0.716797f, 0.741699f, 0.763672f, 0.784668f,
+ 0.802246f, 0.818359f, 0.832520f, 0.845703f, 0.857422f, 0.868164f, 0.877930f, 0.886230f, 0.895020f, 0.902344f, 0.909668f, 0.915039f,
+ 0.921875f, 0.926758f, 0.931641f, 0.937012f, 0.940430f, 0.946289f, 0.949219f, 0.952637f, 0.956055f, 0.958984f, 0.961914f, 0.964844f,
+ 0.967773f, 0.970215f, 0.972656f, 0.974609f, 0.976562f, 0.979004f, 0.980957f, 0.982910f, 0.984863f, 0.986816f, 0.987793f, 0.989746f,
+ 0.990723f, 0.992676f, 0.996582f, 0.996094f, 0.995605f, 0.995117f, 0.994629f, 0.994141f, 0.009315f, 0.030411f, 0.055756f, 0.085632f,
+ 0.121094f, 0.160889f, 0.206055f, 0.254150f, 0.305664f, 0.357422f, 0.408447f, 0.459717f, 0.506836f, 0.551270f, 0.592773f, 0.629395f,
+ 0.662598f, 0.692871f, 0.719727f, 0.745117f, 0.767090f, 0.786133f, 0.804688f, 0.819336f, 0.834473f, 0.847168f, 0.858398f, 0.869629f,
+ 0.879395f, 0.888672f, 0.895020f, 0.903320f, 0.910156f, 0.916016f, 0.922363f, 0.928223f, 0.933105f, 0.937012f, 0.941406f, 0.946289f,
+ 0.950195f, 0.954102f, 0.957031f, 0.960449f, 0.963379f, 0.965820f, 0.969238f, 0.971191f, 0.974121f, 0.976074f, 0.978027f, 0.979980f,
+ 0.982422f, 0.984375f, 0.985840f, 0.987793f, 0.989258f, 0.990723f, 0.995605f, 0.995605f, 0.995117f, 0.994629f, 0.994629f, 0.993652f,
+ 0.006634f, 0.022736f, 0.041962f, 0.064026f, 0.090759f, 0.122192f, 0.157593f, 0.197510f, 0.240356f, 0.287354f, 0.335693f, 0.384766f,
+ 0.432373f, 0.479736f, 0.523438f, 0.565430f, 0.604004f, 0.639160f, 0.670898f, 0.699219f, 0.726562f, 0.749023f, 0.770508f, 0.790527f,
+ 0.806641f, 0.822754f, 0.836426f, 0.848633f, 0.859863f, 0.871582f, 0.881348f, 0.889160f, 0.897949f, 0.905273f, 0.912598f, 0.918945f,
+ 0.924316f, 0.929199f, 0.935059f, 0.938965f, 0.943848f, 0.947266f, 0.951660f, 0.955078f, 0.958496f, 0.961914f, 0.964844f, 0.967773f,
+ 0.970703f, 0.973145f, 0.975098f, 0.977539f, 0.979492f, 0.981445f, 0.983887f, 0.985352f, 0.987305f, 0.989258f, 0.995117f, 0.994629f,
+ 0.994141f, 0.994141f, 0.993652f, 0.993164f, 0.005428f, 0.017807f, 0.032166f, 0.049652f, 0.070007f, 0.093811f, 0.121765f, 0.153564f,
+ 0.189087f, 0.228516f, 0.270752f, 0.316162f, 0.362061f, 0.408936f, 0.453857f, 0.498779f, 0.540527f, 0.579590f, 0.615723f, 0.649902f,
+ 0.679688f, 0.707520f, 0.732422f, 0.755371f, 0.775391f, 0.794922f, 0.811035f, 0.826172f, 0.839844f, 0.852051f, 0.864258f, 0.875000f,
+ 0.883301f, 0.892578f, 0.899902f, 0.907715f, 0.914062f, 0.920410f, 0.926270f, 0.931641f, 0.936035f, 0.940918f, 0.945312f, 0.949219f,
+ 0.954102f, 0.957031f, 0.960938f, 0.963379f, 0.966797f, 0.969238f, 0.972168f, 0.974609f, 0.977051f, 0.979492f, 0.980957f, 0.983398f,
+ 0.985352f, 0.987305f, 0.994141f, 0.994141f, 0.994141f, 0.993652f, 0.993164f, 0.992676f, 0.004223f, 0.014046f, 0.025452f, 0.039062f,
+ 0.055115f, 0.073608f, 0.095642f, 0.120239f, 0.149292f, 0.182251f, 0.217529f, 0.257080f, 0.298828f, 0.342773f, 0.387207f, 0.431152f,
+ 0.474609f, 0.516602f, 0.556641f, 0.593750f, 0.628418f, 0.660156f, 0.689453f, 0.715820f, 0.740723f, 0.762207f, 0.782227f, 0.799805f,
+ 0.816406f, 0.830566f, 0.844727f, 0.855469f, 0.867188f, 0.877441f, 0.886230f, 0.895020f, 0.903809f, 0.910645f, 0.917480f, 0.923340f,
+ 0.928711f, 0.934570f, 0.939453f, 0.943848f, 0.948242f, 0.952148f, 0.956055f, 0.959473f, 0.961914f, 0.965820f, 0.968750f, 0.971680f,
+ 0.974121f, 0.975586f, 0.979004f, 0.980957f, 0.983398f, 0.985352f, 0.993652f, 0.993652f, 0.993164f, 0.993164f, 0.992676f, 0.991699f,
+ 0.003532f, 0.011536f, 0.020645f, 0.031342f, 0.044098f, 0.058624f, 0.075989f, 0.096252f, 0.119141f, 0.145386f, 0.175049f, 0.208130f,
+ 0.244385f, 0.283203f, 0.324463f, 0.367432f, 0.410400f, 0.453369f, 0.495361f, 0.534668f, 0.572266f, 0.607910f, 0.641602f, 0.672852f,
+ 0.700195f, 0.725098f, 0.748047f, 0.769531f, 0.789062f, 0.806152f, 0.821777f, 0.835938f, 0.848633f, 0.860352f, 0.872070f, 0.881836f,
+ 0.890625f, 0.898926f, 0.906738f, 0.913086f, 0.919922f, 0.925781f, 0.931641f, 0.936523f, 0.941406f, 0.946289f, 0.950684f, 0.954590f,
+ 0.958008f, 0.961426f, 0.964844f, 0.968262f, 0.970703f, 0.973633f, 0.976074f, 0.978516f, 0.980469f, 0.982910f, 0.992676f, 0.992676f,
+ 0.992188f, 0.992188f, 0.991699f, 0.990723f, 0.002850f, 0.009483f, 0.016647f, 0.025833f, 0.035889f, 0.047424f, 0.061646f, 0.076660f,
+ 0.095642f, 0.117065f, 0.141113f, 0.168457f, 0.198975f, 0.233032f, 0.269775f, 0.308838f, 0.349854f, 0.391357f, 0.432861f, 0.474121f,
+ 0.515625f, 0.552734f, 0.589355f, 0.622559f, 0.654785f, 0.683594f, 0.710938f, 0.735352f, 0.757812f, 0.777344f, 0.795898f, 0.812988f,
+ 0.827637f, 0.842285f, 0.854492f, 0.866211f, 0.876953f, 0.886719f, 0.895508f, 0.902832f, 0.911133f, 0.917969f, 0.924316f, 0.929688f,
+ 0.935059f, 0.940430f, 0.945312f, 0.949219f, 0.953125f, 0.958008f, 0.961426f, 0.964844f, 0.967285f, 0.970703f, 0.973633f, 0.975586f,
+ 0.978516f, 0.981445f, 0.991699f, 0.992188f, 0.991699f, 0.991211f, 0.991211f, 0.990723f, 0.002628f, 0.007713f, 0.014069f, 0.021484f,
+ 0.029709f, 0.038910f, 0.050201f, 0.063171f, 0.078186f, 0.094849f, 0.114563f, 0.137329f, 0.162720f, 0.190918f, 0.222656f, 0.257568f,
+ 0.293945f, 0.332764f, 0.372803f, 0.414551f, 0.455078f, 0.495361f, 0.533691f, 0.571289f, 0.606445f, 0.639160f, 0.668457f, 0.697754f,
+ 0.723633f, 0.746094f, 0.767090f, 0.787598f, 0.804199f, 0.820801f, 0.834473f, 0.848633f, 0.860352f, 0.872559f, 0.882324f, 0.891602f,
+ 0.899902f, 0.907715f, 0.915039f, 0.921387f, 0.927734f, 0.934082f, 0.938965f, 0.944824f, 0.948730f, 0.953125f, 0.956543f, 0.960938f,
+ 0.963867f, 0.967285f, 0.970215f, 0.973145f, 0.976074f, 0.978516f, 0.990234f, 0.990723f, 0.990723f, 0.991211f, 0.990234f, 0.990234f,
+ 0.002131f, 0.006535f, 0.012016f, 0.017670f, 0.024780f, 0.032837f, 0.041199f, 0.051819f, 0.063904f, 0.077759f, 0.093689f, 0.112610f,
+ 0.133057f, 0.156860f, 0.183472f, 0.213257f, 0.245605f, 0.281006f, 0.318115f, 0.357422f, 0.397217f, 0.437500f, 0.478271f, 0.516602f,
+ 0.554688f, 0.589844f, 0.623535f, 0.654785f, 0.684082f, 0.710938f, 0.734375f, 0.757812f, 0.777832f, 0.795898f, 0.813477f, 0.828613f,
+ 0.843262f, 0.855957f, 0.867676f, 0.878906f, 0.888184f, 0.897461f, 0.905273f, 0.912598f, 0.919922f, 0.926758f, 0.932129f, 0.937988f,
+ 0.942871f, 0.947754f, 0.951660f, 0.955566f, 0.960449f, 0.964355f, 0.967285f, 0.970215f, 0.973145f, 0.976074f, 0.989746f, 0.990234f,
+ 0.990234f, 0.990234f, 0.989746f, 0.988770f, 0.001566f, 0.005798f, 0.010231f, 0.015259f, 0.020920f, 0.027176f, 0.034607f, 0.043335f,
+ 0.052887f, 0.064392f, 0.077576f, 0.092712f, 0.109802f, 0.129639f, 0.151611f, 0.176758f, 0.204346f, 0.235474f, 0.269043f, 0.304688f,
+ 0.342529f, 0.381836f, 0.421143f, 0.460449f, 0.500488f, 0.538086f, 0.574219f, 0.608887f, 0.640625f, 0.670898f, 0.699219f, 0.725098f,
+ 0.748535f, 0.769043f, 0.788574f, 0.807129f, 0.823242f, 0.837402f, 0.850586f, 0.863281f, 0.874512f, 0.885254f, 0.894043f, 0.902832f,
+ 0.910645f, 0.917969f, 0.924805f, 0.931152f, 0.936523f, 0.941895f, 0.947266f, 0.951172f, 0.955566f, 0.960449f, 0.963867f, 0.966797f,
+ 0.970703f, 0.973145f, 0.988281f, 0.989258f, 0.989258f, 0.989258f, 0.988770f, 0.988281f, 0.001427f, 0.004749f, 0.008934f, 0.012833f,
+ 0.017670f, 0.023483f, 0.029114f, 0.036438f, 0.044556f, 0.054047f, 0.064453f, 0.077148f, 0.091309f, 0.107544f, 0.125854f, 0.146729f,
+ 0.170776f, 0.197266f, 0.226440f, 0.257568f, 0.292236f, 0.329346f, 0.367188f, 0.405762f, 0.445557f, 0.484619f, 0.522949f, 0.559570f,
+ 0.595215f, 0.627441f, 0.659180f, 0.687012f, 0.714355f, 0.739258f, 0.761719f, 0.781738f, 0.800781f, 0.817383f, 0.833984f, 0.847168f,
+ 0.859375f, 0.872070f, 0.882324f, 0.891602f, 0.900879f, 0.909668f, 0.916504f, 0.923828f, 0.930176f, 0.936523f, 0.941895f, 0.946777f,
+ 0.951172f, 0.956055f, 0.960449f, 0.963867f, 0.967285f, 0.970703f, 0.987305f, 0.988770f, 0.988281f, 0.987793f, 0.987793f, 0.987793f,
+ 0.001357f, 0.004501f, 0.007557f, 0.011284f, 0.015236f, 0.019791f, 0.025101f, 0.030838f, 0.037628f, 0.045532f, 0.054596f, 0.064636f,
+ 0.076355f, 0.089905f, 0.105042f, 0.122498f, 0.142334f, 0.164307f, 0.189697f, 0.217896f, 0.248413f, 0.281494f, 0.316406f, 0.354004f,
+ 0.391846f, 0.430664f, 0.469971f, 0.508301f, 0.545898f, 0.582031f, 0.615723f, 0.647461f, 0.677734f, 0.704590f, 0.731445f, 0.754395f,
+ 0.775391f, 0.794922f, 0.811523f, 0.829102f, 0.842773f, 0.856934f, 0.868652f, 0.880371f, 0.891113f, 0.899414f, 0.908203f, 0.915527f,
+ 0.922852f, 0.930176f, 0.936035f, 0.941406f, 0.947266f, 0.951660f, 0.957031f, 0.960449f, 0.963867f, 0.968262f, 0.986328f, 0.987305f,
+ 0.987793f, 0.987305f, 0.987305f, 0.986816f, 0.001239f, 0.003864f, 0.006699f, 0.009621f, 0.013008f, 0.017059f, 0.021805f, 0.026703f,
+ 0.032562f, 0.039185f, 0.045807f, 0.054352f, 0.064514f, 0.075439f, 0.088257f, 0.102478f, 0.119263f, 0.138306f, 0.159546f, 0.183228f,
+ 0.209961f, 0.239258f, 0.271484f, 0.305176f, 0.341797f, 0.379639f, 0.417480f, 0.456787f, 0.495605f, 0.532227f, 0.570801f, 0.604980f,
+ 0.637207f, 0.666992f, 0.696289f, 0.722656f, 0.746582f, 0.768555f, 0.789062f, 0.808105f, 0.824219f, 0.839844f, 0.854492f, 0.865723f,
+ 0.878418f, 0.888672f, 0.897461f, 0.906738f, 0.915039f, 0.922363f, 0.929199f, 0.935547f, 0.941895f, 0.946289f, 0.952148f, 0.956543f,
+ 0.960449f, 0.964844f, 0.985352f, 0.986816f, 0.986816f, 0.986328f, 0.986328f, 0.985840f, 0.001151f, 0.003429f, 0.005753f, 0.008400f,
+ 0.011391f, 0.014877f, 0.018494f, 0.022858f, 0.028046f, 0.033112f, 0.039642f, 0.046661f, 0.054565f, 0.064026f, 0.074280f, 0.086243f,
+ 0.100403f, 0.116150f, 0.133789f, 0.154053f, 0.176636f, 0.202393f, 0.230957f, 0.261719f, 0.295166f, 0.330322f, 0.367432f, 0.405518f,
+ 0.445312f, 0.483398f, 0.520996f, 0.558105f, 0.594238f, 0.626465f, 0.659668f, 0.688477f, 0.714844f, 0.740723f, 0.763672f, 0.784180f,
+ 0.804199f, 0.821289f, 0.837402f, 0.852051f, 0.864258f, 0.876465f, 0.886719f, 0.897949f, 0.906250f, 0.915039f, 0.922363f, 0.929199f,
+ 0.935547f, 0.941406f, 0.946777f, 0.952637f, 0.958008f, 0.961914f, 0.983887f, 0.985840f, 0.985352f, 0.985352f, 0.984863f, 0.984863f,
+ 0.001000f, 0.002768f, 0.005127f, 0.007515f, 0.010155f, 0.013283f, 0.016205f, 0.019714f, 0.023987f, 0.028854f, 0.033905f, 0.040161f,
+ 0.046814f, 0.054199f, 0.063110f, 0.073303f, 0.084839f, 0.098145f, 0.112854f, 0.129883f, 0.149292f, 0.171387f, 0.195435f, 0.222778f,
+ 0.252686f, 0.285400f, 0.320312f, 0.356689f, 0.394531f, 0.433105f, 0.471924f, 0.510742f, 0.547852f, 0.584473f, 0.617676f, 0.650879f,
+ 0.680664f, 0.708984f, 0.734375f, 0.759277f, 0.780762f, 0.799805f, 0.817383f, 0.834473f, 0.849121f, 0.862793f, 0.875488f, 0.886719f,
+ 0.896484f, 0.906250f, 0.915039f, 0.923828f, 0.930176f, 0.936035f, 0.942871f, 0.948242f, 0.953613f, 0.958008f, 0.982910f, 0.983887f,
+ 0.984375f, 0.983887f, 0.984375f, 0.983398f, 0.000799f, 0.002705f, 0.004459f, 0.006573f, 0.008842f, 0.011375f, 0.014099f, 0.017487f,
+ 0.020798f, 0.024963f, 0.029465f, 0.034637f, 0.039703f, 0.046478f, 0.054047f, 0.062256f, 0.072388f, 0.082947f, 0.095764f, 0.110229f,
+ 0.126099f, 0.144775f, 0.165771f, 0.189697f, 0.216187f, 0.244995f, 0.276123f, 0.310303f, 0.346191f, 0.384521f, 0.422607f, 0.461670f,
+ 0.500000f, 0.538574f, 0.575195f, 0.609863f, 0.643555f, 0.673828f, 0.702637f, 0.730469f, 0.754395f, 0.777344f, 0.797363f, 0.815430f,
+ 0.833008f, 0.848633f, 0.861328f, 0.875000f, 0.886719f, 0.896973f, 0.906738f, 0.915039f, 0.923340f, 0.930176f, 0.936523f, 0.943848f,
+ 0.948730f, 0.954102f, 0.981445f, 0.983398f, 0.982910f, 0.983398f, 0.982910f, 0.982910f, 0.000774f, 0.002554f, 0.003899f, 0.005875f,
+ 0.007759f, 0.009949f, 0.012733f, 0.015060f, 0.018280f, 0.021667f, 0.025574f, 0.029678f, 0.034698f, 0.040405f, 0.046570f, 0.053650f,
+ 0.061462f, 0.071106f, 0.081360f, 0.093323f, 0.107300f, 0.122864f, 0.140747f, 0.160522f, 0.183960f, 0.209229f, 0.237305f, 0.268799f,
+ 0.302002f, 0.337402f, 0.374023f, 0.413330f, 0.451904f, 0.490967f, 0.529785f, 0.567383f, 0.603027f, 0.636719f, 0.668457f, 0.698242f,
+ 0.725586f, 0.750977f, 0.773926f, 0.793945f, 0.813965f, 0.831543f, 0.847656f, 0.861816f, 0.874512f, 0.886719f, 0.897461f, 0.906738f,
+ 0.915527f, 0.923828f, 0.931641f, 0.937988f, 0.944824f, 0.949707f, 0.979980f, 0.981934f, 0.981934f, 0.981934f, 0.981934f, 0.981445f,
+ 0.000657f, 0.001934f, 0.003330f, 0.005280f, 0.006748f, 0.009079f, 0.010994f, 0.013763f, 0.015945f, 0.019150f, 0.022003f, 0.026001f,
+ 0.030350f, 0.034790f, 0.040253f, 0.045898f, 0.052795f, 0.060852f, 0.069641f, 0.079346f, 0.091187f, 0.104492f, 0.119751f, 0.136963f,
+ 0.156372f, 0.178345f, 0.203247f, 0.230957f, 0.260742f, 0.294189f, 0.328613f, 0.365723f, 0.403564f, 0.443115f, 0.482910f, 0.521484f,
+ 0.559570f, 0.596680f, 0.630859f, 0.664062f, 0.694336f, 0.722168f, 0.747559f, 0.771484f, 0.793457f, 0.813477f, 0.830078f, 0.846191f,
+ 0.861816f, 0.874023f, 0.887207f, 0.898438f, 0.908691f, 0.916992f, 0.925293f, 0.933594f, 0.939941f, 0.946777f, 0.978516f, 0.980469f,
+ 0.980469f, 0.980469f, 0.980469f, 0.980469f, 0.000818f, 0.001935f, 0.003246f, 0.004658f, 0.006229f, 0.007912f, 0.010017f, 0.012093f,
+ 0.014259f, 0.016586f, 0.019653f, 0.022659f, 0.026413f, 0.030289f, 0.034790f, 0.039917f, 0.045441f, 0.052338f, 0.059479f, 0.068115f,
+ 0.077759f, 0.089050f, 0.102051f, 0.116272f, 0.133179f, 0.152344f, 0.173340f, 0.197876f, 0.224243f, 0.254150f, 0.286621f, 0.321533f,
+ 0.357666f, 0.396729f, 0.436279f, 0.475830f, 0.514648f, 0.553711f, 0.590332f, 0.626465f, 0.659180f, 0.689941f, 0.719238f, 0.746094f,
+ 0.770020f, 0.792480f, 0.812500f, 0.830566f, 0.846680f, 0.862305f, 0.875977f, 0.888184f, 0.899414f, 0.910156f, 0.918945f, 0.927246f,
+ 0.935059f, 0.941895f, 0.977051f, 0.979004f, 0.979492f, 0.979004f, 0.979492f, 0.979004f, 0.000583f, 0.001696f, 0.003044f, 0.004276f,
+ 0.005394f, 0.007111f, 0.009048f, 0.010727f, 0.012802f, 0.014549f, 0.017319f, 0.019943f, 0.023132f, 0.026459f, 0.030212f, 0.034576f,
+ 0.039612f, 0.045105f, 0.051422f, 0.058594f, 0.066833f, 0.076416f, 0.087341f, 0.099792f, 0.113647f, 0.130005f, 0.147827f, 0.168945f,
+ 0.192261f, 0.218750f, 0.247803f, 0.280029f, 0.314209f, 0.351074f, 0.389404f, 0.429199f, 0.468750f, 0.508301f, 0.547852f, 0.585938f,
+ 0.622070f, 0.655762f, 0.687988f, 0.718262f, 0.744629f, 0.769531f, 0.792480f, 0.812500f, 0.832520f, 0.848633f, 0.863770f, 0.877441f,
+ 0.890137f, 0.901367f, 0.912109f, 0.921387f, 0.929199f, 0.937500f, 0.975586f, 0.978027f, 0.978027f, 0.977539f, 0.977539f, 0.977051f,
+ 0.000463f, 0.001634f, 0.002899f, 0.003574f, 0.004932f, 0.006233f, 0.007866f, 0.009644f, 0.011055f, 0.012894f, 0.015518f, 0.017792f,
+ 0.020279f, 0.023178f, 0.026657f, 0.030136f, 0.034271f, 0.039062f, 0.044586f, 0.050446f, 0.057739f, 0.065613f, 0.074646f, 0.084900f,
+ 0.097107f, 0.111023f, 0.126099f, 0.143921f, 0.164673f, 0.187500f, 0.213257f, 0.242065f, 0.273926f, 0.308594f, 0.344971f, 0.383301f,
+ 0.423340f, 0.463623f, 0.503906f, 0.543945f, 0.582520f, 0.619629f, 0.653809f, 0.686523f, 0.717285f, 0.744629f, 0.770020f, 0.792969f,
+ 0.814453f, 0.833496f, 0.850098f, 0.866211f, 0.879395f, 0.893066f, 0.904297f, 0.914551f, 0.923828f, 0.932129f, 0.973145f, 0.976074f,
+ 0.976562f, 0.976074f, 0.976074f, 0.976074f, 0.000472f, 0.001289f, 0.002508f, 0.003481f, 0.004459f, 0.005894f, 0.007042f, 0.008232f,
+ 0.009972f, 0.011719f, 0.013435f, 0.015884f, 0.017899f, 0.020386f, 0.023422f, 0.026428f, 0.030411f, 0.034180f, 0.038757f, 0.043854f,
+ 0.049652f, 0.056549f, 0.064270f, 0.073303f, 0.083252f, 0.095093f, 0.107910f, 0.123169f, 0.141113f, 0.160645f, 0.183472f, 0.208618f,
+ 0.237305f, 0.268799f, 0.302734f, 0.339600f, 0.377930f, 0.418457f, 0.459473f, 0.500000f, 0.540527f, 0.579102f, 0.617188f, 0.652832f,
+ 0.685547f, 0.716309f, 0.745117f, 0.771484f, 0.794922f, 0.815918f, 0.834961f, 0.853027f, 0.868652f, 0.882324f, 0.895996f, 0.907227f,
+ 0.916992f, 0.927246f, 0.972168f, 0.974121f, 0.975098f, 0.973633f, 0.974609f, 0.973633f, 0.000238f, 0.001453f, 0.002047f, 0.002985f,
+ 0.004227f, 0.005272f, 0.006096f, 0.007309f, 0.008957f, 0.010437f, 0.012184f, 0.014214f, 0.015793f, 0.018082f, 0.020538f, 0.023270f,
+ 0.026505f, 0.029648f, 0.033813f, 0.038300f, 0.043457f, 0.049042f, 0.055298f, 0.062744f, 0.070984f, 0.081299f, 0.092590f, 0.105591f,
+ 0.120361f, 0.137695f, 0.156982f, 0.179443f, 0.204346f, 0.232788f, 0.263672f, 0.297363f, 0.334229f, 0.373047f, 0.414307f, 0.455322f,
+ 0.497314f, 0.538086f, 0.578613f, 0.616211f, 0.653320f, 0.686523f, 0.718262f, 0.747559f, 0.773438f, 0.797363f, 0.818848f, 0.838867f,
+ 0.856934f, 0.871582f, 0.885742f, 0.898926f, 0.910645f, 0.920410f, 0.970215f, 0.971680f, 0.972656f, 0.972656f, 0.972168f, 0.972168f,
+ 0.000376f, 0.001075f, 0.002052f, 0.002823f, 0.003603f, 0.004509f, 0.005619f, 0.007008f, 0.008064f, 0.009132f, 0.010849f, 0.012314f,
+ 0.013817f, 0.015945f, 0.018188f, 0.020676f, 0.022995f, 0.026230f, 0.029587f, 0.033234f, 0.037598f, 0.042328f, 0.048004f, 0.054230f,
+ 0.061188f, 0.069824f, 0.079468f, 0.090454f, 0.103271f, 0.117493f, 0.134644f, 0.153931f, 0.175293f, 0.200806f, 0.228149f, 0.259277f,
+ 0.293945f, 0.330566f, 0.370117f, 0.410889f, 0.453369f, 0.495605f, 0.537109f, 0.578125f, 0.616699f, 0.653809f, 0.689453f, 0.721191f,
+ 0.750000f, 0.776855f, 0.800293f, 0.822754f, 0.841309f, 0.859863f, 0.876465f, 0.890137f, 0.902832f, 0.914062f, 0.967773f, 0.970703f,
+ 0.970703f, 0.970703f, 0.970703f, 0.970703f, 0.000237f, 0.000972f, 0.001674f, 0.002413f, 0.003336f, 0.003956f, 0.005093f, 0.006039f,
+ 0.007069f, 0.008202f, 0.009613f, 0.011017f, 0.012520f, 0.014282f, 0.016068f, 0.017853f, 0.020508f, 0.023117f, 0.025986f, 0.029160f,
+ 0.032898f, 0.036865f, 0.041565f, 0.046997f, 0.052887f, 0.060089f, 0.068176f, 0.077515f, 0.088257f, 0.100586f, 0.114929f, 0.131592f,
+ 0.150635f, 0.172241f, 0.196411f, 0.224731f, 0.255859f, 0.290039f, 0.327393f, 0.367188f, 0.409180f, 0.451172f, 0.493896f, 0.536621f,
+ 0.578613f, 0.618164f, 0.655762f, 0.691406f, 0.724121f, 0.753906f, 0.781738f, 0.805176f, 0.827637f, 0.847656f, 0.864746f, 0.880859f,
+ 0.895508f, 0.907715f, 0.965332f, 0.968262f, 0.968750f, 0.969238f, 0.967773f, 0.967773f, 0.000450f, 0.001033f, 0.001554f, 0.002131f,
+ 0.002939f, 0.003662f, 0.004551f, 0.005722f, 0.006405f, 0.007542f, 0.008484f, 0.009750f, 0.011017f, 0.012596f, 0.014046f, 0.015854f,
+ 0.017975f, 0.020264f, 0.022736f, 0.025497f, 0.028671f, 0.031952f, 0.036011f, 0.040741f, 0.045746f, 0.051910f, 0.058868f, 0.066772f,
+ 0.075867f, 0.086304f, 0.098328f, 0.112244f, 0.128784f, 0.147217f, 0.168945f, 0.193848f, 0.221558f, 0.252441f, 0.287109f, 0.324951f,
+ 0.365234f, 0.407715f, 0.450684f, 0.494629f, 0.539062f, 0.580566f, 0.621094f, 0.659668f, 0.695801f, 0.729004f, 0.758789f, 0.786133f,
+ 0.810547f, 0.833008f, 0.852539f, 0.870117f, 0.886719f, 0.900879f, 0.962891f, 0.966309f, 0.966309f, 0.966797f, 0.966797f, 0.966309f,
+ 0.000304f, 0.001050f, 0.001257f, 0.002295f, 0.002689f, 0.003885f, 0.004284f, 0.004726f, 0.005547f, 0.006721f, 0.007595f, 0.008667f,
+ 0.009811f, 0.011330f, 0.012642f, 0.014130f, 0.016098f, 0.017975f, 0.019867f, 0.022247f, 0.024811f, 0.028030f, 0.031403f, 0.035461f,
+ 0.039642f, 0.044800f, 0.050720f, 0.057495f, 0.065002f, 0.073914f, 0.084290f, 0.095947f, 0.109985f, 0.126343f, 0.144409f, 0.166138f,
+ 0.190918f, 0.218750f, 0.250244f, 0.285400f, 0.323730f, 0.364258f, 0.407471f, 0.452148f, 0.496338f, 0.540527f, 0.584473f, 0.625977f,
+ 0.665039f, 0.701172f, 0.735352f, 0.765137f, 0.792480f, 0.817383f, 0.840332f, 0.859863f, 0.876953f, 0.893066f, 0.959961f, 0.963379f,
+ 0.963867f, 0.964355f, 0.963867f, 0.963867f, 0.000228f, 0.000682f, 0.001293f, 0.001717f, 0.002352f, 0.003160f, 0.003626f, 0.004360f,
+ 0.005348f, 0.005871f, 0.006870f, 0.007660f, 0.008957f, 0.010002f, 0.011299f, 0.012375f, 0.014099f, 0.015900f, 0.017670f, 0.019363f,
+ 0.022034f, 0.024216f, 0.027420f, 0.030930f, 0.034454f, 0.038910f, 0.044006f, 0.049530f, 0.055878f, 0.063477f, 0.072083f, 0.082275f,
+ 0.094177f, 0.107666f, 0.123840f, 0.142090f, 0.163452f, 0.188477f, 0.216919f, 0.248047f, 0.283447f, 0.322754f, 0.364990f, 0.408447f,
+ 0.453613f, 0.500000f, 0.544922f, 0.589355f, 0.631348f, 0.671387f, 0.708008f, 0.742188f, 0.773438f, 0.800781f, 0.824219f, 0.846680f,
+ 0.866699f, 0.884277f, 0.958008f, 0.960938f, 0.961426f, 0.962402f, 0.961914f, 0.960938f, 0.000239f, 0.000731f, 0.001204f, 0.001637f,
+ 0.002144f, 0.002913f, 0.003521f, 0.003828f, 0.004517f, 0.005291f, 0.006203f, 0.006954f, 0.007740f, 0.008911f, 0.010239f, 0.011017f,
+ 0.012413f, 0.013863f, 0.015396f, 0.017181f, 0.019196f, 0.021439f, 0.024078f, 0.026993f, 0.030182f, 0.033752f, 0.038055f, 0.042664f,
+ 0.048004f, 0.054657f, 0.061920f, 0.070312f, 0.080688f, 0.092041f, 0.105774f, 0.121094f, 0.140015f, 0.161255f, 0.186523f, 0.214966f,
+ 0.246948f, 0.283203f, 0.322998f, 0.365967f, 0.410400f, 0.457275f, 0.503906f, 0.550781f, 0.596191f, 0.638672f, 0.678711f, 0.716797f,
+ 0.750488f, 0.781738f, 0.809082f, 0.833496f, 0.855469f, 0.874512f, 0.954590f, 0.958008f, 0.958984f, 0.958984f, 0.958984f, 0.958984f,
+ 0.000226f, 0.000663f, 0.001073f, 0.001420f, 0.002163f, 0.002567f, 0.003052f, 0.003433f, 0.004181f, 0.004734f, 0.005516f, 0.006424f,
+ 0.007050f, 0.008003f, 0.008659f, 0.009827f, 0.011086f, 0.012398f, 0.013649f, 0.015266f, 0.016891f, 0.018921f, 0.021118f, 0.023560f,
+ 0.026505f, 0.029556f, 0.032715f, 0.036865f, 0.041077f, 0.046570f, 0.053314f, 0.060150f, 0.068787f, 0.078552f, 0.090027f, 0.103638f,
+ 0.119690f, 0.138184f, 0.159546f, 0.184692f, 0.213745f, 0.245972f, 0.283203f, 0.324219f, 0.367920f, 0.414062f, 0.461914f, 0.509766f,
+ 0.557129f, 0.604492f, 0.647461f, 0.688965f, 0.727051f, 0.761230f, 0.791504f, 0.819824f, 0.844238f, 0.865234f, 0.951660f, 0.955566f,
+ 0.955566f, 0.956055f, 0.955078f, 0.956543f, 0.000156f, 0.000587f, 0.001056f, 0.001499f, 0.001647f, 0.002380f, 0.002594f, 0.003469f,
+ 0.003777f, 0.004112f, 0.004925f, 0.005699f, 0.006180f, 0.007019f, 0.007957f, 0.008942f, 0.009560f, 0.010727f, 0.011963f, 0.013123f,
+ 0.014885f, 0.016556f, 0.018494f, 0.020355f, 0.022766f, 0.025330f, 0.028320f, 0.031830f, 0.035736f, 0.040161f, 0.045532f, 0.052032f,
+ 0.059113f, 0.066833f, 0.076782f, 0.088501f, 0.101868f, 0.117310f, 0.136108f, 0.157959f, 0.183105f, 0.212769f, 0.247070f, 0.284424f,
+ 0.326660f, 0.371338f, 0.419189f, 0.468994f, 0.518066f, 0.567383f, 0.613770f, 0.658691f, 0.700684f, 0.738770f, 0.771973f, 0.803223f,
+ 0.829590f, 0.854492f, 0.947266f, 0.952637f, 0.952637f, 0.952637f, 0.953125f, 0.952637f, 0.000155f, 0.000358f, 0.000859f, 0.001402f,
+ 0.001830f, 0.002092f, 0.002499f, 0.002672f, 0.003410f, 0.003763f, 0.004375f, 0.005077f, 0.005535f, 0.006554f, 0.007004f, 0.007874f,
+ 0.008537f, 0.009529f, 0.010742f, 0.011749f, 0.013016f, 0.014427f, 0.015945f, 0.017929f, 0.019775f, 0.022018f, 0.024460f, 0.027618f,
+ 0.030640f, 0.034668f, 0.039154f, 0.044250f, 0.050293f, 0.057068f, 0.065491f, 0.074951f, 0.086487f, 0.099670f, 0.115906f, 0.134277f,
+ 0.156860f, 0.182495f, 0.213135f, 0.248047f, 0.286621f, 0.329834f, 0.376709f, 0.426025f, 0.476562f, 0.527832f, 0.577637f, 0.626465f,
+ 0.671387f, 0.713379f, 0.752441f, 0.784668f, 0.815430f, 0.841797f, 0.944336f, 0.948242f, 0.949219f, 0.949219f, 0.949219f, 0.949707f,
+ 0.000233f, 0.000639f, 0.000930f, 0.001277f, 0.001579f, 0.001916f, 0.002041f, 0.002625f, 0.003035f, 0.003571f, 0.004124f, 0.004375f,
+ 0.004978f, 0.005379f, 0.006348f, 0.006886f, 0.007526f, 0.008430f, 0.009216f, 0.010262f, 0.011436f, 0.012779f, 0.014160f, 0.015549f,
+ 0.017120f, 0.019089f, 0.021164f, 0.023621f, 0.026352f, 0.029724f, 0.033447f, 0.037842f, 0.042603f, 0.048737f, 0.055573f, 0.063721f,
+ 0.073364f, 0.084778f, 0.098206f, 0.114197f, 0.133423f, 0.155762f, 0.182739f, 0.213623f, 0.249512f, 0.289795f, 0.335205f, 0.383789f,
+ 0.434814f, 0.487305f, 0.540039f, 0.591797f, 0.640137f, 0.686035f, 0.727539f, 0.765137f, 0.800293f, 0.830078f, 0.940430f, 0.944336f,
+ 0.945312f, 0.946289f, 0.945801f, 0.945312f, 0.000217f, 0.000519f, 0.000848f, 0.001180f, 0.001366f, 0.001589f, 0.001986f, 0.002354f,
+ 0.002987f, 0.003170f, 0.003576f, 0.003901f, 0.004440f, 0.004738f, 0.005543f, 0.006058f, 0.006508f, 0.007511f, 0.008163f, 0.009132f,
+ 0.010078f, 0.011246f, 0.012390f, 0.013412f, 0.014938f, 0.016632f, 0.018433f, 0.020676f, 0.022995f, 0.025726f, 0.028702f, 0.032227f,
+ 0.036377f, 0.041992f, 0.047394f, 0.053986f, 0.062195f, 0.071716f, 0.082825f, 0.096802f, 0.112732f, 0.132202f, 0.155273f, 0.182861f,
+ 0.215210f, 0.252441f, 0.294678f, 0.341553f, 0.392090f, 0.445557f, 0.499512f, 0.553711f, 0.606445f, 0.656250f, 0.703125f, 0.745605f,
+ 0.782715f, 0.816895f, 0.935547f, 0.939941f, 0.941406f, 0.941406f, 0.941406f, 0.940918f, 0.000242f, 0.000678f, 0.000781f, 0.000928f,
+ 0.001200f, 0.001592f, 0.001694f, 0.002096f, 0.002703f, 0.002903f, 0.003170f, 0.003531f, 0.003918f, 0.004433f, 0.004955f, 0.005390f,
+ 0.005939f, 0.006454f, 0.007298f, 0.007782f, 0.008759f, 0.009567f, 0.010559f, 0.011650f, 0.013046f, 0.014420f, 0.015793f, 0.017715f,
+ 0.019699f, 0.021774f, 0.024460f, 0.027481f, 0.031082f, 0.035065f, 0.039917f, 0.045715f, 0.052246f, 0.060486f, 0.070129f, 0.081482f,
+ 0.095093f, 0.111755f, 0.131714f, 0.155273f, 0.183838f, 0.217285f, 0.256348f, 0.300781f, 0.350342f, 0.403076f, 0.458252f, 0.514160f,
+ 0.570312f, 0.624512f, 0.675781f, 0.722168f, 0.763672f, 0.800293f, 0.930664f, 0.935547f, 0.937500f, 0.937012f, 0.937500f, 0.937012f,
+ 0.000239f, 0.000297f, 0.000667f, 0.000785f, 0.001044f, 0.001269f, 0.001569f, 0.001950f, 0.002224f, 0.002419f, 0.002810f, 0.003063f,
+ 0.003626f, 0.003895f, 0.004261f, 0.004749f, 0.005066f, 0.005726f, 0.006260f, 0.007019f, 0.007771f, 0.008369f, 0.008919f, 0.009941f,
+ 0.011101f, 0.012375f, 0.013519f, 0.015190f, 0.016891f, 0.018631f, 0.021011f, 0.023590f, 0.026581f, 0.029892f, 0.033875f, 0.038757f,
+ 0.044281f, 0.051147f, 0.058746f, 0.068481f, 0.079834f, 0.094116f, 0.110779f, 0.131348f, 0.155884f, 0.185669f, 0.220825f, 0.261963f,
+ 0.308594f, 0.360352f, 0.416260f, 0.473877f, 0.532715f, 0.589844f, 0.645508f, 0.696289f, 0.743652f, 0.784668f, 0.925781f, 0.930664f,
+ 0.932129f, 0.932129f, 0.932129f, 0.932129f, 0.000226f, 0.000351f, 0.000434f, 0.000624f, 0.000887f, 0.001040f, 0.001246f, 0.001665f,
+ 0.001856f, 0.002384f, 0.002420f, 0.002842f, 0.002874f, 0.003471f, 0.003735f, 0.004078f, 0.004639f, 0.004910f, 0.005531f, 0.006065f,
+ 0.006664f, 0.007370f, 0.007690f, 0.008690f, 0.009544f, 0.010536f, 0.011795f, 0.012833f, 0.014183f, 0.015900f, 0.017899f, 0.019684f,
+ 0.022430f, 0.025253f, 0.028412f, 0.032410f, 0.037201f, 0.042633f, 0.049316f, 0.057159f, 0.066772f, 0.078186f, 0.092590f, 0.110107f,
+ 0.131348f, 0.156982f, 0.188232f, 0.225342f, 0.269043f, 0.318604f, 0.373535f, 0.431641f, 0.492188f, 0.554199f, 0.613281f, 0.668945f,
+ 0.720703f, 0.766602f, 0.919922f, 0.925781f, 0.926758f, 0.926758f, 0.927246f, 0.926758f, 0.000000f, 0.000340f, 0.000458f, 0.000715f,
+ 0.000823f, 0.000895f, 0.001165f, 0.001518f, 0.001636f, 0.001876f, 0.002190f, 0.002472f, 0.002640f, 0.002964f, 0.003340f, 0.003527f,
+ 0.004005f, 0.004227f, 0.004803f, 0.005260f, 0.005878f, 0.006042f, 0.006805f, 0.007500f, 0.008469f, 0.009132f, 0.009949f, 0.011009f,
+ 0.012077f, 0.013687f, 0.014938f, 0.016785f, 0.018997f, 0.021194f, 0.023895f, 0.027283f, 0.030945f, 0.035583f, 0.040955f, 0.047760f,
+ 0.055573f, 0.065247f, 0.077209f, 0.091736f, 0.109619f, 0.131470f, 0.159058f, 0.192017f, 0.231812f, 0.278076f, 0.331543f, 0.389404f,
+ 0.450928f, 0.513672f, 0.577637f, 0.638672f, 0.695801f, 0.746582f, 0.914062f, 0.919922f, 0.920898f, 0.921387f, 0.921387f, 0.921387f,
+ 0.000146f, 0.000319f, 0.000443f, 0.000458f, 0.000704f, 0.000894f, 0.001199f, 0.001324f, 0.001549f, 0.001592f, 0.002081f, 0.002092f,
+ 0.002237f, 0.002604f, 0.002815f, 0.003159f, 0.003510f, 0.003937f, 0.004147f, 0.004425f, 0.004814f, 0.005318f, 0.005878f, 0.006413f,
+ 0.006924f, 0.007782f, 0.008408f, 0.009239f, 0.010414f, 0.011505f, 0.012642f, 0.014015f, 0.015884f, 0.017563f, 0.019852f, 0.022598f,
+ 0.025650f, 0.029663f, 0.033875f, 0.039307f, 0.045898f, 0.053955f, 0.063782f, 0.075928f, 0.090820f, 0.109497f, 0.132690f, 0.161621f,
+ 0.196777f, 0.239624f, 0.290039f, 0.346436f, 0.408203f, 0.473633f, 0.540527f, 0.605957f, 0.667969f, 0.725586f, 0.907715f, 0.914062f,
+ 0.914062f, 0.915039f, 0.915039f, 0.915039f, 0.000121f, 0.000251f, 0.000506f, 0.000532f, 0.000665f, 0.000830f, 0.001190f, 0.001164f,
+ 0.001290f, 0.001413f, 0.001755f, 0.001900f, 0.002157f, 0.002319f, 0.002422f, 0.002853f, 0.003042f, 0.003254f, 0.003529f, 0.003725f,
+ 0.004288f, 0.004585f, 0.005043f, 0.005539f, 0.005970f, 0.006386f, 0.007126f, 0.007812f, 0.008652f, 0.009598f, 0.010651f, 0.011803f,
+ 0.013130f, 0.014702f, 0.016510f, 0.018814f, 0.021011f, 0.024368f, 0.028122f, 0.032379f, 0.037506f, 0.044128f, 0.052277f, 0.062042f,
+ 0.075073f, 0.090088f, 0.110107f, 0.134766f, 0.165405f, 0.203613f, 0.249268f, 0.303955f, 0.365234f, 0.431396f, 0.501465f, 0.571777f,
+ 0.638672f, 0.702148f, 0.900879f, 0.906738f, 0.907227f, 0.908203f, 0.907227f, 0.908203f, 0.000241f, 0.000122f, 0.000417f, 0.000505f,
+ 0.000741f, 0.000782f, 0.000916f, 0.001145f, 0.001189f, 0.001289f, 0.001331f, 0.001565f, 0.001779f, 0.002020f, 0.002171f, 0.002228f,
+ 0.002623f, 0.002752f, 0.002949f, 0.003157f, 0.003515f, 0.003847f, 0.004082f, 0.004429f, 0.004990f, 0.005405f, 0.006008f, 0.006603f,
+ 0.007103f, 0.007889f, 0.008789f, 0.009766f, 0.010605f, 0.012177f, 0.013672f, 0.015305f, 0.017487f, 0.019913f, 0.022781f, 0.026245f,
+ 0.030670f, 0.035980f, 0.042389f, 0.050812f, 0.060883f, 0.073792f, 0.090088f, 0.111145f, 0.138062f, 0.171143f, 0.212524f, 0.262695f,
+ 0.322266f, 0.388184f, 0.460205f, 0.533203f, 0.606445f, 0.676758f, 0.893066f, 0.898926f, 0.899414f, 0.899414f, 0.900879f, 0.900391f,
+ 0.000000f, 0.000114f, 0.000227f, 0.000407f, 0.000532f, 0.000732f, 0.000714f, 0.000922f, 0.000993f, 0.001072f, 0.001190f, 0.001412f,
+ 0.001569f, 0.001726f, 0.001959f, 0.002071f, 0.002159f, 0.002350f, 0.002565f, 0.002729f, 0.003090f, 0.003248f, 0.003702f, 0.003761f,
+ 0.004192f, 0.004585f, 0.004925f, 0.005272f, 0.005966f, 0.006405f, 0.007275f, 0.007965f, 0.008850f, 0.009872f, 0.011017f, 0.012383f,
+ 0.014275f, 0.015900f, 0.018463f, 0.021194f, 0.024673f, 0.028870f, 0.034271f, 0.040955f, 0.048981f, 0.059723f, 0.073059f, 0.090149f,
+ 0.112549f, 0.141357f, 0.178467f, 0.223755f, 0.280029f, 0.345215f, 0.417969f, 0.494385f, 0.572266f, 0.648438f, 0.884277f, 0.890137f,
+ 0.891602f, 0.891602f, 0.893066f, 0.892090f, 0.000000f, 0.000219f, 0.000211f, 0.000333f, 0.000559f, 0.000609f, 0.000788f, 0.000805f,
+ 0.000869f, 0.000903f, 0.001101f, 0.001166f, 0.001302f, 0.001399f, 0.001456f, 0.001668f, 0.001853f, 0.001999f, 0.002102f, 0.002256f,
+ 0.002447f, 0.002728f, 0.002943f, 0.003178f, 0.003515f, 0.003836f, 0.004074f, 0.004475f, 0.004745f, 0.005325f, 0.005970f, 0.006569f,
+ 0.007248f, 0.008102f, 0.008888f, 0.010132f, 0.011169f, 0.012947f, 0.014763f, 0.016891f, 0.019760f, 0.023087f, 0.027176f, 0.032562f,
+ 0.038940f, 0.047516f, 0.058167f, 0.072754f, 0.090698f, 0.114929f, 0.146851f, 0.187744f, 0.239258f, 0.301514f, 0.373291f, 0.452637f,
+ 0.535645f, 0.617676f, 0.874512f, 0.880859f, 0.882324f, 0.883301f, 0.883301f, 0.882324f, 0.000204f, 0.000207f, 0.000204f, 0.000322f,
+ 0.000435f, 0.000480f, 0.000556f, 0.000615f, 0.000747f, 0.000782f, 0.000844f, 0.001006f, 0.001159f, 0.001191f, 0.001231f, 0.001450f,
+ 0.001585f, 0.001633f, 0.001790f, 0.001919f, 0.002117f, 0.002298f, 0.002432f, 0.002651f, 0.002939f, 0.003172f, 0.003399f, 0.003614f,
+ 0.003944f, 0.004421f, 0.004704f, 0.005203f, 0.005886f, 0.006454f, 0.007160f, 0.008049f, 0.009041f, 0.010201f, 0.011627f, 0.013237f,
+ 0.015404f, 0.018097f, 0.021469f, 0.025284f, 0.030884f, 0.036987f, 0.045990f, 0.056915f, 0.072083f, 0.092163f, 0.119141f, 0.154419f,
+ 0.200928f, 0.259277f, 0.328857f, 0.409424f, 0.495605f, 0.584473f, 0.864258f, 0.871094f, 0.872070f, 0.873047f, 0.872559f, 0.873047f,
+ 0.000000f, 0.000044f, 0.000176f, 0.000290f, 0.000410f, 0.000390f, 0.000513f, 0.000546f, 0.000647f, 0.000680f, 0.000827f, 0.000858f,
+ 0.000958f, 0.001131f, 0.001102f, 0.001223f, 0.001367f, 0.001401f, 0.001525f, 0.001610f, 0.001826f, 0.001821f, 0.002039f, 0.002253f,
+ 0.002459f, 0.002617f, 0.002708f, 0.003036f, 0.003279f, 0.003431f, 0.003805f, 0.004219f, 0.004471f, 0.004929f, 0.005569f, 0.006310f,
+ 0.007107f, 0.007988f, 0.009003f, 0.010384f, 0.011856f, 0.014015f, 0.016418f, 0.019669f, 0.023666f, 0.028809f, 0.035583f, 0.044159f,
+ 0.056458f, 0.072571f, 0.094604f, 0.124329f, 0.164917f, 0.218018f, 0.284912f, 0.364746f, 0.454102f, 0.549316f, 0.853027f, 0.859863f,
+ 0.861328f, 0.861816f, 0.861816f, 0.861816f, 0.000000f, 0.000069f, 0.000120f, 0.000345f, 0.000371f, 0.000398f, 0.000452f, 0.000396f,
+ 0.000498f, 0.000530f, 0.000596f, 0.000648f, 0.000781f, 0.000921f, 0.000995f, 0.001007f, 0.001101f, 0.001146f, 0.001282f, 0.001278f,
+ 0.001471f, 0.001554f, 0.001710f, 0.001811f, 0.001995f, 0.001986f, 0.002314f, 0.002399f, 0.002499f, 0.002903f, 0.002975f, 0.003305f,
+ 0.003605f, 0.004086f, 0.004425f, 0.005081f, 0.005402f, 0.006035f, 0.006889f, 0.007755f, 0.009041f, 0.010422f, 0.012672f, 0.014885f,
+ 0.017746f, 0.021530f, 0.026733f, 0.033691f, 0.043060f, 0.055847f, 0.073181f, 0.097473f, 0.132324f, 0.179077f, 0.241821f, 0.320068f,
+ 0.410400f, 0.510742f, 0.839844f, 0.847656f, 0.849121f, 0.849609f, 0.849121f, 0.849609f, 0.000000f, 0.000000f, 0.000121f, 0.000243f,
+ 0.000321f, 0.000354f, 0.000341f, 0.000431f, 0.000423f, 0.000444f, 0.000473f, 0.000508f, 0.000595f, 0.000706f, 0.000737f, 0.000861f,
+ 0.000869f, 0.000926f, 0.001055f, 0.001104f, 0.001199f, 0.001306f, 0.001360f, 0.001433f, 0.001530f, 0.001555f, 0.001673f, 0.001942f,
+ 0.002138f, 0.002247f, 0.002562f, 0.002609f, 0.002911f, 0.003204f, 0.003466f, 0.003757f, 0.004192f, 0.004845f, 0.005482f, 0.006008f,
+ 0.006874f, 0.007904f, 0.009171f, 0.011124f, 0.013260f, 0.015839f, 0.019821f, 0.024872f, 0.031982f, 0.041534f, 0.055054f, 0.075012f,
+ 0.103516f, 0.143677f, 0.199951f, 0.273438f, 0.364502f, 0.469482f, 0.825684f, 0.834473f, 0.834961f, 0.835938f, 0.835938f, 0.835938f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000120f, 0.000199f, 0.000272f, 0.000265f, 0.000363f, 0.000379f, 0.000388f, 0.000489f, 0.000500f,
+ 0.000488f, 0.000569f, 0.000604f, 0.000700f, 0.000683f, 0.000720f, 0.000784f, 0.000844f, 0.001009f, 0.001047f, 0.001108f, 0.001258f,
+ 0.001276f, 0.001388f, 0.001410f, 0.001565f, 0.001592f, 0.001814f, 0.001800f, 0.002167f, 0.002192f, 0.002556f, 0.002665f, 0.002905f,
+ 0.003195f, 0.003574f, 0.004028f, 0.004513f, 0.005127f, 0.005859f, 0.006847f, 0.008018f, 0.009491f, 0.011452f, 0.014099f, 0.017792f,
+ 0.022995f, 0.030258f, 0.040588f, 0.055878f, 0.078308f, 0.111450f, 0.160278f, 0.229248f, 0.318359f, 0.425781f, 0.810547f, 0.818359f,
+ 0.820312f, 0.821777f, 0.821777f, 0.820801f, 0.000000f, 0.000121f, 0.000120f, 0.000172f, 0.000195f, 0.000171f, 0.000208f, 0.000272f,
+ 0.000316f, 0.000333f, 0.000348f, 0.000355f, 0.000412f, 0.000410f, 0.000515f, 0.000485f, 0.000545f, 0.000656f, 0.000777f, 0.000659f,
+ 0.000705f, 0.000762f, 0.000874f, 0.000927f, 0.000959f, 0.000978f, 0.001045f, 0.001228f, 0.001294f, 0.001398f, 0.001443f, 0.001637f,
+ 0.001752f, 0.001925f, 0.002005f, 0.002230f, 0.002407f, 0.002670f, 0.002895f, 0.003267f, 0.003933f, 0.004280f, 0.005051f, 0.005772f,
+ 0.006718f, 0.008141f, 0.010117f, 0.012383f, 0.015930f, 0.020920f, 0.028671f, 0.039673f, 0.056702f, 0.083313f, 0.124695f, 0.185791f,
+ 0.270996f, 0.379639f, 0.793457f, 0.801270f, 0.803711f, 0.803711f, 0.804688f, 0.804688f, 0.000000f, 0.000121f, 0.000119f, 0.000144f,
+ 0.000149f, 0.000166f, 0.000173f, 0.000167f, 0.000214f, 0.000245f, 0.000334f, 0.000287f, 0.000303f, 0.000391f, 0.000401f, 0.000440f,
+ 0.000469f, 0.000493f, 0.000534f, 0.000513f, 0.000690f, 0.000682f, 0.000645f, 0.000712f, 0.000715f, 0.000747f, 0.000842f, 0.000849f,
+ 0.000967f, 0.000995f, 0.001178f, 0.001167f, 0.001273f, 0.001395f, 0.001586f, 0.001748f, 0.001796f, 0.001986f, 0.002132f, 0.002476f,
+ 0.002893f, 0.003294f, 0.003653f, 0.004086f, 0.004890f, 0.005821f, 0.006927f, 0.008553f, 0.010857f, 0.014137f, 0.019211f, 0.027084f,
+ 0.039642f, 0.059448f, 0.092468f, 0.144775f, 0.224487f, 0.332764f, 0.775391f, 0.784668f, 0.786133f, 0.786133f, 0.787109f, 0.786621f,
+ 0.000000f, 0.000000f, 0.000118f, 0.000116f, 0.000115f, 0.000113f, 0.000140f, 0.000140f, 0.000149f, 0.000220f, 0.000171f, 0.000255f,
+ 0.000274f, 0.000292f, 0.000318f, 0.000295f, 0.000346f, 0.000352f, 0.000380f, 0.000406f, 0.000401f, 0.000533f, 0.000490f, 0.000551f,
+ 0.000558f, 0.000648f, 0.000628f, 0.000723f, 0.000788f, 0.000749f, 0.000836f, 0.000941f, 0.000997f, 0.001065f, 0.001112f, 0.001207f,
+ 0.001328f, 0.001535f, 0.001621f, 0.001840f, 0.002022f, 0.002163f, 0.002522f, 0.002825f, 0.003391f, 0.003830f, 0.004616f, 0.005665f,
+ 0.007172f, 0.009247f, 0.012482f, 0.017532f, 0.025970f, 0.040161f, 0.064941f, 0.107422f, 0.178833f, 0.283447f, 0.754883f, 0.764648f,
+ 0.766113f, 0.767090f, 0.767578f, 0.767090f, 0.000000f, 0.000119f, 0.000116f, 0.000114f, 0.000112f, 0.000110f, 0.000109f, 0.000117f,
+ 0.000114f, 0.000117f, 0.000125f, 0.000193f, 0.000141f, 0.000196f, 0.000221f, 0.000235f, 0.000259f, 0.000278f, 0.000308f, 0.000316f,
+ 0.000323f, 0.000315f, 0.000329f, 0.000351f, 0.000388f, 0.000422f, 0.000465f, 0.000512f, 0.000571f, 0.000568f, 0.000588f, 0.000633f,
+ 0.000747f, 0.000751f, 0.000829f, 0.000958f, 0.000914f, 0.001104f, 0.001145f, 0.001255f, 0.001337f, 0.001499f, 0.001701f, 0.001966f,
+ 0.002275f, 0.002609f, 0.003119f, 0.003773f, 0.004658f, 0.005920f, 0.007935f, 0.010948f, 0.015900f, 0.025284f, 0.042511f, 0.075012f,
+ 0.135010f, 0.234619f, 0.733398f, 0.743164f, 0.744629f, 0.745117f, 0.745605f, 0.745605f, 0.000000f, 0.000116f, 0.000113f, 0.000111f,
+ 0.000108f, 0.000106f, 0.000104f, 0.000103f, 0.000098f, 0.000092f, 0.000099f, 0.000085f, 0.000098f, 0.000105f, 0.000163f, 0.000162f,
+ 0.000128f, 0.000193f, 0.000203f, 0.000214f, 0.000284f, 0.000239f, 0.000303f, 0.000268f, 0.000327f, 0.000326f, 0.000329f, 0.000330f,
+ 0.000407f, 0.000486f, 0.000406f, 0.000454f, 0.000465f, 0.000495f, 0.000535f, 0.000592f, 0.000648f, 0.000727f, 0.000753f, 0.000807f,
+ 0.000956f, 0.000992f, 0.001108f, 0.001294f, 0.001418f, 0.001703f, 0.001978f, 0.002390f, 0.002930f, 0.003643f, 0.004753f, 0.006519f,
+ 0.009499f, 0.014824f, 0.025497f, 0.048065f, 0.095154f, 0.185425f, 0.709961f, 0.719727f, 0.721191f, 0.721191f, 0.721680f, 0.721680f,
+ 0.000000f, 0.000113f, 0.000107f, 0.000106f, 0.000102f, 0.000100f, 0.000097f, 0.000096f, 0.000095f, 0.000092f, 0.000087f, 0.000083f,
+ 0.000078f, 0.000098f, 0.000077f, 0.000091f, 0.000114f, 0.000128f, 0.000114f, 0.000147f, 0.000154f, 0.000162f, 0.000186f, 0.000174f,
+ 0.000220f, 0.000233f, 0.000235f, 0.000245f, 0.000250f, 0.000253f, 0.000321f, 0.000296f, 0.000311f, 0.000354f, 0.000417f, 0.000419f,
+ 0.000438f, 0.000443f, 0.000495f, 0.000513f, 0.000585f, 0.000634f, 0.000705f, 0.000778f, 0.000912f, 0.001002f, 0.001163f, 0.001379f,
+ 0.001745f, 0.002092f, 0.002697f, 0.003721f, 0.005230f, 0.008194f, 0.013870f, 0.027359f, 0.061066f, 0.138062f, 0.685547f, 0.694336f,
+ 0.696777f, 0.696289f, 0.697754f, 0.697754f, 0.000000f, 0.000106f, 0.000102f, 0.000097f, 0.000093f, 0.000091f, 0.000089f, 0.000087f,
+ 0.000085f, 0.000084f, 0.000082f, 0.000080f, 0.000076f, 0.000072f, 0.000069f, 0.000074f, 0.000076f, 0.000059f, 0.000075f, 0.000062f,
+ 0.000085f, 0.000091f, 0.000103f, 0.000111f, 0.000121f, 0.000135f, 0.000128f, 0.000159f, 0.000171f, 0.000160f, 0.000178f, 0.000193f,
+ 0.000196f, 0.000202f, 0.000220f, 0.000230f, 0.000273f, 0.000289f, 0.000312f, 0.000330f, 0.000335f, 0.000397f, 0.000408f, 0.000463f,
+ 0.000517f, 0.000577f, 0.000691f, 0.000771f, 0.000919f, 0.001150f, 0.001436f, 0.001955f, 0.002737f, 0.004185f, 0.007103f, 0.013863f,
+ 0.033661f, 0.093628f, 0.657227f, 0.667480f, 0.668945f, 0.669434f, 0.670898f, 0.669922f, 0.000108f, 0.000093f, 0.000087f, 0.000082f,
+ 0.000079f, 0.000078f, 0.000075f, 0.000073f, 0.000071f, 0.000070f, 0.000069f, 0.000069f, 0.000067f, 0.000066f, 0.000064f, 0.000061f,
+ 0.000059f, 0.000056f, 0.000053f, 0.000051f, 0.000053f, 0.000049f, 0.000044f, 0.000047f, 0.000055f, 0.000058f, 0.000071f, 0.000077f,
+ 0.000093f, 0.000094f, 0.000103f, 0.000102f, 0.000110f, 0.000126f, 0.000130f, 0.000138f, 0.000143f, 0.000166f, 0.000166f, 0.000178f,
+ 0.000194f, 0.000217f, 0.000228f, 0.000231f, 0.000265f, 0.000330f, 0.000341f, 0.000411f, 0.000459f, 0.000549f, 0.000705f, 0.000867f,
+ 0.001228f, 0.001863f, 0.003143f, 0.006283f, 0.015594f, 0.054993f, 0.628418f, 0.638184f, 0.640137f, 0.640137f, 0.641602f, 0.641602f,
+ 0.000071f, 0.000058f, 0.000059f, 0.000058f, 0.000054f, 0.000054f, 0.000051f, 0.000053f, 0.000051f, 0.000052f, 0.000050f, 0.000050f,
+ 0.000051f, 0.000050f, 0.000049f, 0.000049f, 0.000049f, 0.000049f, 0.000047f, 0.000045f, 0.000043f, 0.000041f, 0.000039f, 0.000038f,
+ 0.000036f, 0.000034f, 0.000035f, 0.000037f, 0.000033f, 0.000034f, 0.000038f, 0.000047f, 0.000054f, 0.000061f, 0.000064f, 0.000068f,
+ 0.000069f, 0.000076f, 0.000083f, 0.000092f, 0.000098f, 0.000103f, 0.000112f, 0.000129f, 0.000113f, 0.000139f, 0.000152f, 0.000185f,
+ 0.000204f, 0.000238f, 0.000282f, 0.000365f, 0.000503f, 0.000685f, 0.001178f, 0.002274f, 0.006100f, 0.025162f, 0.597656f, 0.607910f,
+ 0.610840f, 0.611816f, 0.610352f, 0.611328f, 0.000000f, 0.000000f, 0.000004f, 0.000012f, 0.000014f, 0.000020f, 0.000022f, 0.000023f,
+ 0.000024f, 0.000022f, 0.000025f, 0.000027f, 0.000027f, 0.000026f, 0.000028f, 0.000029f, 0.000029f, 0.000029f, 0.000030f, 0.000030f,
+ 0.000030f, 0.000030f, 0.000030f, 0.000030f, 0.000029f, 0.000028f, 0.000027f, 0.000026f, 0.000024f, 0.000023f, 0.000022f, 0.000021f,
+ 0.000020f, 0.000019f, 0.000018f, 0.000019f, 0.000023f, 0.000024f, 0.000027f, 0.000032f, 0.000038f, 0.000040f, 0.000041f, 0.000045f,
+ 0.000054f, 0.000052f, 0.000055f, 0.000060f, 0.000068f, 0.000089f, 0.000089f, 0.000115f, 0.000146f, 0.000198f, 0.000318f, 0.000586f,
+ 0.001614f, 0.008278f, 0.565918f, 0.576660f, 0.578125f, 0.579102f, 0.579590f, 0.580078f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f,
+ 0.000003f, 0.000003f, 0.000005f, 0.000005f, 0.000006f, 0.000007f, 0.000009f, 0.000009f, 0.000010f, 0.000011f, 0.000012f, 0.000012f,
+ 0.000013f, 0.000014f, 0.000014f, 0.000015f, 0.000014f, 0.000014f, 0.000013f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000010f,
+ 0.000009f, 0.000009f, 0.000008f, 0.000010f, 0.000013f, 0.000013f, 0.000013f, 0.000017f, 0.000017f, 0.000022f, 0.000021f, 0.000023f,
+ 0.000031f, 0.000032f, 0.000049f, 0.000079f, 0.000204f, 0.001328f, 0.533203f, 0.543945f, 0.545410f, 0.546387f, 0.546875f, 0.546875f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000003f,
+ 0.000003f, 0.000003f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000016f, 0.499756f, 0.510254f,
+ 0.513184f, 0.513672f, 0.514160f, 0.514160f,
+ },
+ {
+ 0.076172f, 0.209839f, 0.320312f, 0.408691f, 0.481689f, 0.541016f, 0.591309f, 0.633789f, 0.668945f, 0.699707f, 0.727051f, 0.749512f,
+ 0.770020f, 0.788086f, 0.803711f, 0.817871f, 0.832520f, 0.843750f, 0.854492f, 0.864258f, 0.873535f, 0.881836f, 0.889160f, 0.895996f,
+ 0.903320f, 0.909180f, 0.914551f, 0.920410f, 0.925781f, 0.929199f, 0.933594f, 0.938965f, 0.942383f, 0.946289f, 0.949219f, 0.953125f,
+ 0.955566f, 0.959473f, 0.961914f, 0.964355f, 0.967285f, 0.970215f, 0.971680f, 0.974609f, 0.976562f, 0.978516f, 0.980469f, 0.982422f,
+ 0.984375f, 0.986328f, 0.987793f, 0.989746f, 0.990723f, 0.992676f, 0.993652f, 0.995117f, 0.996582f, 0.998047f, 0.999023f, 0.997559f,
+ 0.996582f, 0.995605f, 0.994629f, 0.993652f, 0.043396f, 0.133301f, 0.221313f, 0.303223f, 0.377441f, 0.442871f, 0.500000f, 0.550781f,
+ 0.595215f, 0.632812f, 0.666992f, 0.696777f, 0.723145f, 0.745605f, 0.765137f, 0.783691f, 0.799805f, 0.815430f, 0.828613f, 0.839844f,
+ 0.851562f, 0.861328f, 0.871582f, 0.879395f, 0.887207f, 0.894531f, 0.901855f, 0.907227f, 0.914062f, 0.919434f, 0.924316f, 0.928711f,
+ 0.933594f, 0.937988f, 0.942383f, 0.945801f, 0.949219f, 0.953125f, 0.956055f, 0.959473f, 0.962402f, 0.964355f, 0.967773f, 0.970215f,
+ 0.972656f, 0.975098f, 0.977051f, 0.979492f, 0.980957f, 0.983398f, 0.985352f, 0.986816f, 0.988281f, 0.990234f, 0.991699f, 0.993652f,
+ 0.995117f, 0.996094f, 0.998047f, 0.997070f, 0.996094f, 0.995117f, 0.994141f, 0.993164f, 0.027832f, 0.088440f, 0.153198f, 0.221313f,
+ 0.288086f, 0.352051f, 0.411621f, 0.466797f, 0.515625f, 0.561523f, 0.601074f, 0.637207f, 0.667969f, 0.695312f, 0.721680f, 0.743652f,
+ 0.763184f, 0.781738f, 0.797852f, 0.812500f, 0.826172f, 0.838867f, 0.850098f, 0.859863f, 0.869141f, 0.877930f, 0.886230f, 0.893555f,
+ 0.900879f, 0.907227f, 0.912598f, 0.918457f, 0.922852f, 0.928711f, 0.934082f, 0.938477f, 0.942383f, 0.946289f, 0.950195f, 0.953125f,
+ 0.956543f, 0.959961f, 0.962402f, 0.965820f, 0.968262f, 0.970703f, 0.973145f, 0.975586f, 0.978027f, 0.979980f, 0.982422f, 0.984375f,
+ 0.985840f, 0.987793f, 0.989746f, 0.991211f, 0.993164f, 0.994141f, 0.997559f, 0.996582f, 0.995605f, 0.994629f, 0.993652f, 0.993164f,
+ 0.018921f, 0.061493f, 0.109497f, 0.161987f, 0.217041f, 0.273438f, 0.330811f, 0.384521f, 0.437500f, 0.486084f, 0.530273f, 0.570312f,
+ 0.607910f, 0.640137f, 0.670410f, 0.697266f, 0.722656f, 0.743652f, 0.763672f, 0.781250f, 0.797363f, 0.812012f, 0.825684f, 0.837891f,
+ 0.848633f, 0.859863f, 0.869141f, 0.878418f, 0.886719f, 0.893066f, 0.900879f, 0.906738f, 0.913574f, 0.919434f, 0.924316f, 0.930176f,
+ 0.934082f, 0.939453f, 0.942871f, 0.946777f, 0.950684f, 0.954590f, 0.958008f, 0.960449f, 0.963379f, 0.966797f, 0.969238f, 0.971680f,
+ 0.974121f, 0.977051f, 0.978516f, 0.980957f, 0.983398f, 0.985352f, 0.987305f, 0.989258f, 0.991211f, 0.992676f, 0.996094f, 0.995605f,
+ 0.994629f, 0.993652f, 0.993164f, 0.992188f, 0.013596f, 0.044495f, 0.080017f, 0.119873f, 0.164307f, 0.211670f, 0.261475f, 0.311523f,
+ 0.362793f, 0.410645f, 0.458008f, 0.501953f, 0.542969f, 0.580078f, 0.614746f, 0.645996f, 0.674805f, 0.701172f, 0.723633f, 0.745117f,
+ 0.765625f, 0.782227f, 0.798828f, 0.812988f, 0.826172f, 0.838867f, 0.849609f, 0.861328f, 0.870605f, 0.878906f, 0.887695f, 0.895020f,
+ 0.901855f, 0.907715f, 0.914551f, 0.920898f, 0.925781f, 0.930664f, 0.934570f, 0.940918f, 0.943848f, 0.947754f, 0.951660f, 0.955566f,
+ 0.958984f, 0.961914f, 0.964844f, 0.967773f, 0.970703f, 0.973145f, 0.975586f, 0.978027f, 0.979980f, 0.982422f, 0.984863f, 0.986328f,
+ 0.988770f, 0.990234f, 0.995117f, 0.995117f, 0.994141f, 0.993652f, 0.992676f, 0.991699f, 0.010414f, 0.033203f, 0.060364f, 0.090942f,
+ 0.125610f, 0.163818f, 0.206421f, 0.250488f, 0.295898f, 0.341797f, 0.388428f, 0.433350f, 0.475830f, 0.517090f, 0.555176f, 0.589844f,
+ 0.622559f, 0.652344f, 0.680176f, 0.704590f, 0.729004f, 0.748535f, 0.767578f, 0.784668f, 0.800293f, 0.814941f, 0.828125f, 0.839844f,
+ 0.852051f, 0.861816f, 0.871582f, 0.879883f, 0.888672f, 0.895996f, 0.903320f, 0.909180f, 0.916016f, 0.921387f, 0.927246f, 0.931641f,
+ 0.937012f, 0.940918f, 0.946289f, 0.950195f, 0.953125f, 0.957520f, 0.960449f, 0.963867f, 0.966309f, 0.969238f, 0.972168f, 0.975098f,
+ 0.976562f, 0.979492f, 0.981934f, 0.983887f, 0.985840f, 0.988281f, 0.994629f, 0.994141f, 0.993652f, 0.992676f, 0.991699f, 0.990723f,
+ 0.007889f, 0.025772f, 0.046539f, 0.070312f, 0.097168f, 0.128540f, 0.162354f, 0.200195f, 0.239868f, 0.281738f, 0.325195f, 0.368896f,
+ 0.411621f, 0.453125f, 0.493652f, 0.531738f, 0.566406f, 0.601074f, 0.631836f, 0.659668f, 0.687988f, 0.709961f, 0.732422f, 0.753418f,
+ 0.770996f, 0.788086f, 0.804199f, 0.818359f, 0.831543f, 0.843750f, 0.854492f, 0.864746f, 0.873535f, 0.882812f, 0.890137f, 0.898438f,
+ 0.905273f, 0.912598f, 0.917969f, 0.923828f, 0.929199f, 0.934570f, 0.938477f, 0.942871f, 0.948242f, 0.951660f, 0.955078f, 0.958496f,
+ 0.961914f, 0.965332f, 0.968262f, 0.971680f, 0.973633f, 0.976562f, 0.979492f, 0.981445f, 0.983398f, 0.985352f, 0.993164f, 0.993164f,
+ 0.992676f, 0.991699f, 0.991211f, 0.990234f, 0.006332f, 0.020325f, 0.036438f, 0.055573f, 0.077026f, 0.101562f, 0.129028f, 0.160278f,
+ 0.194458f, 0.230347f, 0.268555f, 0.309326f, 0.350830f, 0.391846f, 0.432373f, 0.472412f, 0.509277f, 0.545410f, 0.579102f, 0.611816f,
+ 0.640625f, 0.668945f, 0.693848f, 0.716797f, 0.739258f, 0.758789f, 0.775879f, 0.793945f, 0.807617f, 0.821777f, 0.834961f, 0.846680f,
+ 0.857422f, 0.867676f, 0.877441f, 0.885742f, 0.893555f, 0.900391f, 0.908203f, 0.915039f, 0.920898f, 0.926270f, 0.931152f, 0.937012f,
+ 0.940918f, 0.946289f, 0.949219f, 0.954102f, 0.958008f, 0.960938f, 0.964355f, 0.967773f, 0.970703f, 0.973145f, 0.975586f, 0.978516f,
+ 0.981445f, 0.983398f, 0.992188f, 0.992188f, 0.991699f, 0.990723f, 0.990723f, 0.989746f, 0.005226f, 0.016647f, 0.029556f, 0.044434f,
+ 0.061523f, 0.081543f, 0.103760f, 0.129150f, 0.157837f, 0.188477f, 0.221924f, 0.257812f, 0.295654f, 0.334473f, 0.374023f, 0.412842f,
+ 0.451904f, 0.489990f, 0.525391f, 0.560059f, 0.593262f, 0.623047f, 0.651855f, 0.678223f, 0.702148f, 0.725098f, 0.745605f, 0.764160f,
+ 0.781738f, 0.799316f, 0.812500f, 0.827148f, 0.838867f, 0.851074f, 0.861328f, 0.871582f, 0.880371f, 0.889648f, 0.896973f, 0.904297f,
+ 0.911621f, 0.917480f, 0.923340f, 0.929688f, 0.934570f, 0.939941f, 0.943848f, 0.948242f, 0.951660f, 0.957031f, 0.959473f, 0.963379f,
+ 0.966797f, 0.969727f, 0.972656f, 0.976074f, 0.979004f, 0.980957f, 0.991699f, 0.991211f, 0.990723f, 0.990234f, 0.989746f, 0.988770f,
+ 0.004108f, 0.013542f, 0.023819f, 0.036194f, 0.050262f, 0.066223f, 0.084717f, 0.104797f, 0.128174f, 0.153809f, 0.182861f, 0.213989f,
+ 0.247437f, 0.282471f, 0.319580f, 0.357422f, 0.395508f, 0.433350f, 0.470947f, 0.506348f, 0.542480f, 0.575684f, 0.605957f, 0.635254f,
+ 0.662109f, 0.687988f, 0.711426f, 0.732910f, 0.753418f, 0.771973f, 0.789062f, 0.804688f, 0.819336f, 0.831543f, 0.843750f, 0.855469f,
+ 0.866211f, 0.875488f, 0.884766f, 0.893066f, 0.901367f, 0.907715f, 0.914062f, 0.921387f, 0.927246f, 0.932129f, 0.937012f, 0.942383f,
+ 0.946777f, 0.951660f, 0.956055f, 0.959473f, 0.962891f, 0.966309f, 0.969238f, 0.972168f, 0.975098f, 0.978027f, 0.989746f, 0.990234f,
+ 0.990234f, 0.989258f, 0.989258f, 0.988281f, 0.003597f, 0.011330f, 0.020065f, 0.029938f, 0.041412f, 0.054504f, 0.068970f, 0.086182f,
+ 0.105469f, 0.126709f, 0.151123f, 0.177612f, 0.206909f, 0.237915f, 0.271484f, 0.305664f, 0.342529f, 0.378906f, 0.416748f, 0.453125f,
+ 0.489502f, 0.524414f, 0.558105f, 0.589844f, 0.619629f, 0.646973f, 0.673828f, 0.698242f, 0.721191f, 0.742676f, 0.761230f, 0.778809f,
+ 0.796387f, 0.810547f, 0.824707f, 0.837891f, 0.850098f, 0.861328f, 0.871094f, 0.881348f, 0.889648f, 0.896973f, 0.904785f, 0.912109f,
+ 0.919434f, 0.924316f, 0.931152f, 0.936523f, 0.941895f, 0.946289f, 0.951172f, 0.955078f, 0.959473f, 0.962402f, 0.965820f, 0.969238f,
+ 0.972656f, 0.975586f, 0.988770f, 0.989258f, 0.989258f, 0.988770f, 0.987793f, 0.987305f, 0.002836f, 0.009857f, 0.016693f, 0.025208f,
+ 0.034668f, 0.045288f, 0.057617f, 0.071106f, 0.087463f, 0.104858f, 0.125000f, 0.147461f, 0.172119f, 0.199829f, 0.229248f, 0.260742f,
+ 0.294434f, 0.329102f, 0.365479f, 0.400879f, 0.437012f, 0.472656f, 0.508301f, 0.541992f, 0.574219f, 0.604980f, 0.634766f, 0.660645f,
+ 0.686523f, 0.709473f, 0.731445f, 0.751953f, 0.770996f, 0.789062f, 0.804199f, 0.817871f, 0.832520f, 0.844727f, 0.856445f, 0.867188f,
+ 0.876953f, 0.886719f, 0.895020f, 0.902832f, 0.909668f, 0.916504f, 0.923340f, 0.929688f, 0.935547f, 0.939941f, 0.944824f, 0.949707f,
+ 0.954102f, 0.958496f, 0.961914f, 0.965820f, 0.969238f, 0.972656f, 0.987793f, 0.988281f, 0.988281f, 0.987793f, 0.986816f, 0.986328f,
+ 0.002541f, 0.008118f, 0.014244f, 0.021194f, 0.029480f, 0.037811f, 0.048584f, 0.060028f, 0.073242f, 0.088196f, 0.104370f, 0.123047f,
+ 0.144531f, 0.167114f, 0.193237f, 0.220947f, 0.250977f, 0.282227f, 0.316162f, 0.351074f, 0.386719f, 0.422119f, 0.457520f, 0.492432f,
+ 0.526367f, 0.559082f, 0.590332f, 0.621094f, 0.648438f, 0.674316f, 0.698730f, 0.721191f, 0.742188f, 0.762207f, 0.780762f, 0.797363f,
+ 0.812500f, 0.826172f, 0.840332f, 0.852051f, 0.863770f, 0.873535f, 0.883301f, 0.892090f, 0.900391f, 0.908203f, 0.915039f, 0.922363f,
+ 0.928711f, 0.933594f, 0.939453f, 0.944824f, 0.950195f, 0.953125f, 0.958008f, 0.962402f, 0.965332f, 0.969238f, 0.986816f, 0.987305f,
+ 0.986816f, 0.986328f, 0.985840f, 0.984863f, 0.002115f, 0.007030f, 0.012138f, 0.017944f, 0.024521f, 0.032318f, 0.040955f, 0.050476f,
+ 0.061676f, 0.073914f, 0.087769f, 0.103271f, 0.121033f, 0.140747f, 0.162598f, 0.187256f, 0.213379f, 0.242065f, 0.272705f, 0.305176f,
+ 0.338623f, 0.373047f, 0.408691f, 0.443848f, 0.478760f, 0.512695f, 0.545898f, 0.577637f, 0.607910f, 0.636719f, 0.663086f, 0.688965f,
+ 0.712402f, 0.734863f, 0.754395f, 0.774414f, 0.791016f, 0.806641f, 0.822266f, 0.835449f, 0.848145f, 0.859863f, 0.870605f, 0.880371f,
+ 0.890137f, 0.898438f, 0.906250f, 0.914551f, 0.921387f, 0.926758f, 0.933594f, 0.938965f, 0.944336f, 0.949219f, 0.954102f, 0.958984f,
+ 0.961914f, 0.965820f, 0.985840f, 0.986328f, 0.985840f, 0.985352f, 0.985352f, 0.984375f, 0.001999f, 0.006226f, 0.010384f, 0.015594f,
+ 0.021027f, 0.027435f, 0.034637f, 0.042969f, 0.052124f, 0.062469f, 0.074097f, 0.087646f, 0.102173f, 0.119141f, 0.137695f, 0.158203f,
+ 0.181396f, 0.206543f, 0.233643f, 0.263184f, 0.295166f, 0.327148f, 0.360596f, 0.395264f, 0.430420f, 0.464600f, 0.499023f, 0.532227f,
+ 0.564941f, 0.595703f, 0.625000f, 0.651855f, 0.679199f, 0.703613f, 0.726074f, 0.747559f, 0.766602f, 0.784668f, 0.801758f, 0.816895f,
+ 0.831055f, 0.843750f, 0.856934f, 0.867188f, 0.878418f, 0.887207f, 0.896484f, 0.904785f, 0.913086f, 0.919922f, 0.926270f, 0.932617f,
+ 0.938477f, 0.944336f, 0.949707f, 0.953613f, 0.958496f, 0.962891f, 0.983887f, 0.984863f, 0.984863f, 0.984375f, 0.983887f, 0.983398f,
+ 0.001891f, 0.004959f, 0.009300f, 0.013786f, 0.018433f, 0.023560f, 0.029892f, 0.037018f, 0.044586f, 0.053284f, 0.062805f, 0.074341f,
+ 0.086975f, 0.100586f, 0.116760f, 0.133789f, 0.154175f, 0.176025f, 0.200317f, 0.226318f, 0.254395f, 0.284424f, 0.316650f, 0.349365f,
+ 0.383301f, 0.418213f, 0.452393f, 0.487061f, 0.520508f, 0.553223f, 0.584473f, 0.613770f, 0.643066f, 0.668945f, 0.695312f, 0.718262f,
+ 0.740234f, 0.761230f, 0.778809f, 0.797363f, 0.812988f, 0.827148f, 0.840332f, 0.854004f, 0.865723f, 0.875977f, 0.886230f, 0.895020f,
+ 0.904297f, 0.912598f, 0.919922f, 0.926270f, 0.932617f, 0.938965f, 0.943359f, 0.949219f, 0.955078f, 0.958984f, 0.982422f, 0.983887f,
+ 0.983398f, 0.982910f, 0.982910f, 0.981934f, 0.001368f, 0.004715f, 0.008041f, 0.011948f, 0.016235f, 0.020889f, 0.025848f, 0.031921f,
+ 0.038391f, 0.045563f, 0.054108f, 0.063477f, 0.074036f, 0.085815f, 0.099304f, 0.114563f, 0.131104f, 0.150146f, 0.170654f, 0.193970f,
+ 0.219360f, 0.246338f, 0.275146f, 0.306396f, 0.338867f, 0.372559f, 0.406494f, 0.440918f, 0.474609f, 0.508789f, 0.541992f, 0.574219f,
+ 0.604492f, 0.634277f, 0.661133f, 0.687500f, 0.710938f, 0.733887f, 0.754883f, 0.774414f, 0.792480f, 0.809570f, 0.824707f, 0.838379f,
+ 0.852051f, 0.862793f, 0.874023f, 0.885254f, 0.895020f, 0.903320f, 0.912109f, 0.919434f, 0.926758f, 0.932617f, 0.939941f, 0.945312f,
+ 0.951172f, 0.955078f, 0.980957f, 0.982910f, 0.982422f, 0.982422f, 0.981445f, 0.981445f, 0.001393f, 0.004227f, 0.007011f, 0.010323f,
+ 0.014107f, 0.018234f, 0.022766f, 0.027649f, 0.032898f, 0.039581f, 0.046539f, 0.054230f, 0.063293f, 0.073608f, 0.085144f, 0.097961f,
+ 0.112305f, 0.127930f, 0.146362f, 0.166260f, 0.188599f, 0.212524f, 0.238647f, 0.266846f, 0.297363f, 0.328369f, 0.361816f, 0.395752f,
+ 0.429932f, 0.464844f, 0.498535f, 0.531250f, 0.564453f, 0.596191f, 0.625488f, 0.653320f, 0.680176f, 0.704590f, 0.728027f, 0.750977f,
+ 0.770020f, 0.788574f, 0.805176f, 0.821289f, 0.835449f, 0.849609f, 0.862793f, 0.874023f, 0.884277f, 0.894043f, 0.903320f, 0.911621f,
+ 0.919434f, 0.926758f, 0.933594f, 0.939453f, 0.945312f, 0.951172f, 0.979492f, 0.980957f, 0.980957f, 0.980957f, 0.980469f, 0.979980f,
+ 0.001163f, 0.003527f, 0.006229f, 0.009323f, 0.012199f, 0.015808f, 0.019928f, 0.024200f, 0.028870f, 0.033997f, 0.040161f, 0.046967f,
+ 0.054871f, 0.063477f, 0.073181f, 0.083618f, 0.096252f, 0.109863f, 0.125122f, 0.142334f, 0.161743f, 0.182739f, 0.206421f, 0.232300f,
+ 0.259277f, 0.288086f, 0.320068f, 0.352783f, 0.386475f, 0.420410f, 0.454590f, 0.489258f, 0.521973f, 0.555176f, 0.586914f, 0.617188f,
+ 0.646484f, 0.673828f, 0.699707f, 0.723633f, 0.746094f, 0.766113f, 0.785645f, 0.803223f, 0.819336f, 0.834961f, 0.848633f, 0.861328f,
+ 0.873535f, 0.884766f, 0.893555f, 0.903809f, 0.911621f, 0.920410f, 0.928223f, 0.934082f, 0.939941f, 0.946777f, 0.978027f, 0.979492f,
+ 0.979492f, 0.979004f, 0.979004f, 0.978516f, 0.000981f, 0.002987f, 0.005329f, 0.008186f, 0.010895f, 0.013832f, 0.017532f, 0.021149f,
+ 0.025253f, 0.029999f, 0.035034f, 0.040985f, 0.047485f, 0.054993f, 0.063049f, 0.072510f, 0.082581f, 0.094421f, 0.107727f, 0.122498f,
+ 0.138794f, 0.157471f, 0.178467f, 0.200562f, 0.225586f, 0.251953f, 0.281250f, 0.311279f, 0.343750f, 0.377197f, 0.411621f, 0.445557f,
+ 0.479736f, 0.513672f, 0.546875f, 0.579590f, 0.610352f, 0.640625f, 0.668457f, 0.694336f, 0.718750f, 0.742188f, 0.762695f, 0.782715f,
+ 0.801270f, 0.817871f, 0.833496f, 0.847168f, 0.860840f, 0.872559f, 0.884277f, 0.894531f, 0.904297f, 0.912598f, 0.920898f, 0.928711f,
+ 0.935547f, 0.942383f, 0.976074f, 0.978027f, 0.978516f, 0.978027f, 0.977539f, 0.977051f, 0.000880f, 0.002707f, 0.005089f, 0.007305f,
+ 0.010147f, 0.012596f, 0.015160f, 0.018616f, 0.022507f, 0.026230f, 0.030777f, 0.035767f, 0.041351f, 0.047455f, 0.054565f, 0.062256f,
+ 0.071289f, 0.081299f, 0.092346f, 0.105408f, 0.119812f, 0.135620f, 0.153320f, 0.173462f, 0.195068f, 0.219482f, 0.245361f, 0.273682f,
+ 0.303711f, 0.335938f, 0.368896f, 0.402588f, 0.437500f, 0.472168f, 0.505859f, 0.539551f, 0.573242f, 0.604492f, 0.634766f, 0.663086f,
+ 0.689453f, 0.714844f, 0.738770f, 0.760254f, 0.780762f, 0.799316f, 0.817383f, 0.833496f, 0.847168f, 0.860840f, 0.873535f, 0.884766f,
+ 0.895508f, 0.905273f, 0.914062f, 0.922363f, 0.930176f, 0.937012f, 0.974609f, 0.976074f, 0.976074f, 0.976562f, 0.976074f, 0.975586f,
+ 0.000851f, 0.002659f, 0.004692f, 0.006466f, 0.008545f, 0.011055f, 0.013649f, 0.016403f, 0.019714f, 0.023056f, 0.026962f, 0.031235f,
+ 0.035828f, 0.041656f, 0.047699f, 0.054077f, 0.061859f, 0.070496f, 0.080200f, 0.091125f, 0.103088f, 0.116882f, 0.132446f, 0.149780f,
+ 0.168701f, 0.190430f, 0.213379f, 0.239258f, 0.267334f, 0.296631f, 0.328369f, 0.360840f, 0.395020f, 0.429932f, 0.464355f, 0.499512f,
+ 0.533203f, 0.566406f, 0.599121f, 0.629883f, 0.658203f, 0.687012f, 0.712402f, 0.735840f, 0.758789f, 0.779297f, 0.798828f, 0.816406f,
+ 0.832520f, 0.847168f, 0.861328f, 0.874023f, 0.886230f, 0.896973f, 0.907227f, 0.915527f, 0.924805f, 0.931641f, 0.972168f, 0.975586f,
+ 0.975586f, 0.974609f, 0.974121f, 0.973633f, 0.000762f, 0.002214f, 0.004040f, 0.005859f, 0.007790f, 0.009689f, 0.012161f, 0.014786f,
+ 0.017441f, 0.020493f, 0.023956f, 0.027618f, 0.031860f, 0.036255f, 0.041595f, 0.047394f, 0.053894f, 0.061188f, 0.069214f, 0.078735f,
+ 0.089050f, 0.101135f, 0.114441f, 0.129150f, 0.145874f, 0.164673f, 0.185303f, 0.208862f, 0.233765f, 0.260742f, 0.290283f, 0.321045f,
+ 0.354248f, 0.388184f, 0.422607f, 0.457764f, 0.493652f, 0.526855f, 0.561523f, 0.594238f, 0.625977f, 0.655273f, 0.683594f, 0.710449f,
+ 0.734863f, 0.758301f, 0.779297f, 0.798828f, 0.817383f, 0.833984f, 0.848145f, 0.862793f, 0.875488f, 0.887207f, 0.899414f, 0.908691f,
+ 0.917969f, 0.926270f, 0.970215f, 0.972656f, 0.974121f, 0.973145f, 0.972656f, 0.972168f, 0.000732f, 0.001928f, 0.003513f, 0.005234f,
+ 0.007042f, 0.008629f, 0.010620f, 0.012985f, 0.015244f, 0.018158f, 0.020935f, 0.024475f, 0.027908f, 0.032013f, 0.036316f, 0.041290f,
+ 0.046661f, 0.053040f, 0.060089f, 0.068115f, 0.077087f, 0.087463f, 0.099121f, 0.111633f, 0.126221f, 0.142578f, 0.160767f, 0.181396f,
+ 0.203003f, 0.228149f, 0.255127f, 0.284180f, 0.315186f, 0.347900f, 0.381836f, 0.416748f, 0.451904f, 0.487549f, 0.522949f, 0.556641f,
+ 0.590332f, 0.623047f, 0.652832f, 0.682129f, 0.708984f, 0.733887f, 0.757324f, 0.779785f, 0.799316f, 0.818359f, 0.835449f, 0.850586f,
+ 0.865234f, 0.877441f, 0.890137f, 0.901367f, 0.912109f, 0.920410f, 0.968262f, 0.970703f, 0.971191f, 0.970703f, 0.971191f, 0.971191f,
+ 0.000524f, 0.001758f, 0.003185f, 0.004864f, 0.006081f, 0.007820f, 0.009705f, 0.011467f, 0.013634f, 0.016068f, 0.018707f, 0.021378f,
+ 0.024597f, 0.028030f, 0.032135f, 0.036224f, 0.041016f, 0.046692f, 0.052399f, 0.059265f, 0.067505f, 0.076050f, 0.085510f, 0.096558f,
+ 0.109253f, 0.123657f, 0.138794f, 0.157227f, 0.176880f, 0.198730f, 0.223267f, 0.250000f, 0.278809f, 0.309326f, 0.342041f, 0.375977f,
+ 0.410889f, 0.447021f, 0.483154f, 0.518555f, 0.554199f, 0.586914f, 0.620117f, 0.650879f, 0.681641f, 0.708496f, 0.734375f, 0.757324f,
+ 0.780762f, 0.801270f, 0.819336f, 0.837891f, 0.852539f, 0.867188f, 0.880371f, 0.893066f, 0.903809f, 0.914551f, 0.966309f, 0.968750f,
+ 0.969238f, 0.969727f, 0.968750f, 0.968750f, 0.000503f, 0.001896f, 0.002653f, 0.004128f, 0.005627f, 0.007004f, 0.008797f, 0.010361f,
+ 0.012230f, 0.014175f, 0.016647f, 0.019348f, 0.021454f, 0.024872f, 0.028290f, 0.031830f, 0.036163f, 0.040649f, 0.045715f, 0.051941f,
+ 0.058319f, 0.065979f, 0.074402f, 0.083618f, 0.094360f, 0.106812f, 0.120239f, 0.135742f, 0.153320f, 0.172974f, 0.194824f, 0.218506f,
+ 0.245117f, 0.273926f, 0.304688f, 0.336426f, 0.371094f, 0.406982f, 0.442627f, 0.479492f, 0.514648f, 0.550781f, 0.584961f, 0.618652f,
+ 0.650879f, 0.681152f, 0.709473f, 0.735352f, 0.760742f, 0.782715f, 0.803711f, 0.821777f, 0.838867f, 0.855957f, 0.870605f, 0.884277f,
+ 0.895996f, 0.906738f, 0.964355f, 0.966309f, 0.967285f, 0.966797f, 0.966309f, 0.966309f, 0.000636f, 0.001421f, 0.002768f, 0.003761f,
+ 0.004944f, 0.006462f, 0.007889f, 0.009262f, 0.010780f, 0.013000f, 0.014946f, 0.017029f, 0.019516f, 0.022049f, 0.024933f, 0.028091f,
+ 0.031616f, 0.035553f, 0.040161f, 0.045380f, 0.051239f, 0.057281f, 0.064270f, 0.072693f, 0.081970f, 0.092468f, 0.104736f, 0.117859f,
+ 0.132690f, 0.150391f, 0.169189f, 0.190796f, 0.214233f, 0.240601f, 0.268555f, 0.299561f, 0.332520f, 0.367188f, 0.402344f, 0.438965f,
+ 0.476074f, 0.512695f, 0.549805f, 0.584473f, 0.619141f, 0.651367f, 0.681152f, 0.709961f, 0.737305f, 0.762695f, 0.785156f, 0.806641f,
+ 0.826172f, 0.843262f, 0.859375f, 0.874023f, 0.888184f, 0.900391f, 0.961426f, 0.964355f, 0.965332f, 0.964844f, 0.964355f, 0.964844f,
+ 0.000295f, 0.001419f, 0.002342f, 0.003471f, 0.004539f, 0.005821f, 0.006882f, 0.008354f, 0.010155f, 0.011574f, 0.013283f, 0.015129f,
+ 0.017090f, 0.019333f, 0.022125f, 0.024643f, 0.028122f, 0.031586f, 0.035522f, 0.039825f, 0.044586f, 0.050110f, 0.056091f, 0.063354f,
+ 0.071045f, 0.080078f, 0.090637f, 0.102112f, 0.115479f, 0.130127f, 0.147217f, 0.165649f, 0.186768f, 0.210571f, 0.236694f, 0.265137f,
+ 0.295654f, 0.328857f, 0.363770f, 0.399902f, 0.436523f, 0.474365f, 0.511230f, 0.548828f, 0.584961f, 0.619141f, 0.652344f, 0.684082f,
+ 0.712891f, 0.741211f, 0.766113f, 0.789062f, 0.810547f, 0.830078f, 0.848633f, 0.864258f, 0.879395f, 0.892578f, 0.958496f, 0.962402f,
+ 0.962402f, 0.962402f, 0.961914f, 0.962402f, 0.000464f, 0.001313f, 0.002159f, 0.003134f, 0.004463f, 0.005001f, 0.006466f, 0.007595f,
+ 0.008842f, 0.010277f, 0.011971f, 0.013550f, 0.015434f, 0.017242f, 0.019348f, 0.021805f, 0.024734f, 0.027817f, 0.031174f, 0.034821f,
+ 0.039124f, 0.043823f, 0.049164f, 0.055237f, 0.062164f, 0.069336f, 0.078430f, 0.088501f, 0.099976f, 0.112854f, 0.127319f, 0.143555f,
+ 0.162354f, 0.183350f, 0.207031f, 0.233032f, 0.260986f, 0.291992f, 0.325195f, 0.361084f, 0.397217f, 0.435059f, 0.473389f, 0.510742f,
+ 0.549316f, 0.586426f, 0.620605f, 0.654785f, 0.686523f, 0.716797f, 0.744629f, 0.769043f, 0.793945f, 0.815918f, 0.834961f, 0.852539f,
+ 0.869141f, 0.884277f, 0.955078f, 0.959473f, 0.959473f, 0.959473f, 0.959961f, 0.959961f, 0.000541f, 0.001223f, 0.002172f, 0.002886f,
+ 0.003679f, 0.004681f, 0.005512f, 0.006683f, 0.008049f, 0.009346f, 0.010704f, 0.012024f, 0.013626f, 0.015213f, 0.017227f, 0.019516f,
+ 0.022079f, 0.024612f, 0.027313f, 0.030731f, 0.034180f, 0.038239f, 0.042969f, 0.048187f, 0.053864f, 0.060516f, 0.068298f, 0.076843f,
+ 0.086670f, 0.097473f, 0.110107f, 0.124268f, 0.140869f, 0.159302f, 0.180420f, 0.203613f, 0.229614f, 0.258057f, 0.289062f, 0.323486f,
+ 0.358398f, 0.395996f, 0.434082f, 0.472900f, 0.511719f, 0.550293f, 0.587402f, 0.624023f, 0.658203f, 0.690918f, 0.721191f, 0.749512f,
+ 0.774902f, 0.799316f, 0.821289f, 0.840820f, 0.859375f, 0.875488f, 0.952637f, 0.956543f, 0.957520f, 0.957520f, 0.957520f, 0.957031f,
+ 0.000252f, 0.001056f, 0.001923f, 0.002523f, 0.003414f, 0.003960f, 0.005146f, 0.006172f, 0.007130f, 0.008179f, 0.009567f, 0.010735f,
+ 0.012077f, 0.013878f, 0.015640f, 0.017456f, 0.019638f, 0.021622f, 0.024170f, 0.026978f, 0.030121f, 0.033630f, 0.037445f, 0.042053f,
+ 0.047119f, 0.052826f, 0.059174f, 0.066711f, 0.075012f, 0.084473f, 0.095276f, 0.107727f, 0.122070f, 0.138184f, 0.156250f, 0.177246f,
+ 0.200928f, 0.226929f, 0.255371f, 0.286865f, 0.321289f, 0.356934f, 0.395264f, 0.434326f, 0.473877f, 0.514160f, 0.553711f, 0.591797f,
+ 0.628418f, 0.663574f, 0.696777f, 0.728027f, 0.755859f, 0.782715f, 0.806152f, 0.829102f, 0.847656f, 0.867188f, 0.949707f, 0.954102f,
+ 0.954590f, 0.954590f, 0.954102f, 0.954590f, 0.000365f, 0.000963f, 0.001581f, 0.002337f, 0.002996f, 0.003952f, 0.004608f, 0.005459f,
+ 0.006489f, 0.007351f, 0.008484f, 0.009544f, 0.011108f, 0.012413f, 0.013901f, 0.015388f, 0.017181f, 0.019012f, 0.021439f, 0.023727f,
+ 0.026520f, 0.029449f, 0.032898f, 0.036835f, 0.041046f, 0.045868f, 0.051575f, 0.058075f, 0.064758f, 0.073120f, 0.082520f, 0.093079f,
+ 0.105652f, 0.119385f, 0.135620f, 0.153687f, 0.174683f, 0.198364f, 0.224365f, 0.253662f, 0.285400f, 0.320557f, 0.357178f, 0.395752f,
+ 0.435791f, 0.476318f, 0.516602f, 0.557129f, 0.596191f, 0.633789f, 0.669434f, 0.703613f, 0.734375f, 0.763672f, 0.790039f, 0.812988f,
+ 0.836914f, 0.855957f, 0.946289f, 0.949707f, 0.951172f, 0.951172f, 0.951172f, 0.951172f, 0.000404f, 0.001028f, 0.001410f, 0.002098f,
+ 0.002657f, 0.003445f, 0.004391f, 0.005039f, 0.005665f, 0.006569f, 0.007549f, 0.008614f, 0.009743f, 0.011108f, 0.012390f, 0.013611f,
+ 0.015396f, 0.017044f, 0.018921f, 0.020874f, 0.023453f, 0.025833f, 0.028809f, 0.032501f, 0.036011f, 0.040161f, 0.044952f, 0.050018f,
+ 0.056091f, 0.063477f, 0.071533f, 0.080200f, 0.091064f, 0.103027f, 0.117065f, 0.133057f, 0.151489f, 0.171997f, 0.196045f, 0.222290f,
+ 0.251709f, 0.284424f, 0.319824f, 0.357422f, 0.397217f, 0.438232f, 0.479492f, 0.521484f, 0.562500f, 0.602051f, 0.641113f, 0.677734f,
+ 0.711914f, 0.743164f, 0.772461f, 0.799316f, 0.822754f, 0.845215f, 0.942383f, 0.946777f, 0.947754f, 0.947754f, 0.948242f, 0.948242f,
+ 0.000406f, 0.000992f, 0.001447f, 0.001986f, 0.002499f, 0.003149f, 0.003769f, 0.004272f, 0.005016f, 0.005981f, 0.006924f, 0.007675f,
+ 0.008766f, 0.009727f, 0.010765f, 0.011986f, 0.013588f, 0.014915f, 0.016724f, 0.018478f, 0.020508f, 0.022873f, 0.025497f, 0.028336f,
+ 0.031525f, 0.034882f, 0.038818f, 0.043243f, 0.048615f, 0.054626f, 0.061707f, 0.069214f, 0.078430f, 0.089111f, 0.101013f, 0.115112f,
+ 0.130859f, 0.148926f, 0.170166f, 0.193604f, 0.220947f, 0.250732f, 0.283936f, 0.320068f, 0.358887f, 0.400391f, 0.442139f, 0.483887f,
+ 0.527344f, 0.569824f, 0.610352f, 0.649414f, 0.686523f, 0.722168f, 0.753906f, 0.782227f, 0.809570f, 0.833496f, 0.938477f, 0.942871f,
+ 0.944824f, 0.944336f, 0.943848f, 0.943848f, 0.000235f, 0.000984f, 0.001204f, 0.001706f, 0.002239f, 0.002998f, 0.003462f, 0.004093f,
+ 0.004372f, 0.005371f, 0.006149f, 0.006962f, 0.007736f, 0.008766f, 0.009804f, 0.010780f, 0.011887f, 0.013336f, 0.014618f, 0.016159f,
+ 0.018158f, 0.020050f, 0.022232f, 0.024597f, 0.027313f, 0.030334f, 0.033752f, 0.037872f, 0.042389f, 0.047516f, 0.053192f, 0.059937f,
+ 0.067749f, 0.076599f, 0.086975f, 0.098755f, 0.112610f, 0.128662f, 0.146973f, 0.168091f, 0.192383f, 0.220215f, 0.250732f, 0.284668f,
+ 0.322021f, 0.361572f, 0.403564f, 0.446777f, 0.490723f, 0.534668f, 0.577637f, 0.619629f, 0.660156f, 0.697754f, 0.731934f, 0.764648f,
+ 0.794922f, 0.820312f, 0.934082f, 0.939453f, 0.939941f, 0.941406f, 0.940430f, 0.940918f, 0.000237f, 0.000591f, 0.001098f, 0.001619f,
+ 0.002241f, 0.002636f, 0.003176f, 0.003521f, 0.004101f, 0.004631f, 0.005398f, 0.006378f, 0.007000f, 0.007767f, 0.008713f, 0.009758f,
+ 0.010475f, 0.011734f, 0.013016f, 0.014404f, 0.015762f, 0.017517f, 0.019440f, 0.021469f, 0.023651f, 0.026199f, 0.029495f, 0.033112f,
+ 0.036499f, 0.040955f, 0.045959f, 0.051849f, 0.058197f, 0.065552f, 0.074585f, 0.085022f, 0.096680f, 0.110535f, 0.126709f, 0.145264f,
+ 0.166626f, 0.191406f, 0.219482f, 0.250488f, 0.286133f, 0.323975f, 0.365723f, 0.408447f, 0.453125f, 0.498779f, 0.542969f, 0.588379f,
+ 0.631836f, 0.671387f, 0.709473f, 0.745117f, 0.777344f, 0.807617f, 0.930176f, 0.935059f, 0.936523f, 0.936523f, 0.936523f, 0.936035f,
+ 0.000242f, 0.000761f, 0.000943f, 0.001624f, 0.001858f, 0.002390f, 0.002638f, 0.003054f, 0.003805f, 0.004559f, 0.005035f, 0.005493f,
+ 0.006157f, 0.006878f, 0.007687f, 0.008530f, 0.009178f, 0.010406f, 0.011406f, 0.012520f, 0.014053f, 0.015579f, 0.017105f, 0.018661f,
+ 0.020737f, 0.022903f, 0.025650f, 0.028259f, 0.031433f, 0.035065f, 0.039581f, 0.044342f, 0.049988f, 0.056366f, 0.064026f, 0.072632f,
+ 0.082825f, 0.094666f, 0.108582f, 0.124634f, 0.143799f, 0.165405f, 0.190796f, 0.219360f, 0.251953f, 0.287842f, 0.328125f, 0.370605f,
+ 0.415283f, 0.461670f, 0.507812f, 0.555176f, 0.600586f, 0.645020f, 0.685547f, 0.724121f, 0.759277f, 0.792969f, 0.924805f, 0.931152f,
+ 0.931641f, 0.932129f, 0.932129f, 0.931641f, 0.000240f, 0.000685f, 0.000955f, 0.001395f, 0.001768f, 0.002157f, 0.002533f, 0.002970f,
+ 0.003223f, 0.003813f, 0.004601f, 0.004993f, 0.005428f, 0.005981f, 0.006878f, 0.007484f, 0.008110f, 0.009132f, 0.009964f, 0.011208f,
+ 0.012138f, 0.013374f, 0.015099f, 0.016190f, 0.018112f, 0.020187f, 0.022202f, 0.024780f, 0.027573f, 0.030411f, 0.034119f, 0.037964f,
+ 0.042755f, 0.048553f, 0.054474f, 0.061890f, 0.070984f, 0.080688f, 0.092590f, 0.106812f, 0.123291f, 0.142456f, 0.164551f, 0.190430f,
+ 0.220459f, 0.253418f, 0.291504f, 0.332520f, 0.376709f, 0.423340f, 0.471436f, 0.520508f, 0.567383f, 0.614746f, 0.660156f, 0.702148f,
+ 0.741211f, 0.776367f, 0.920410f, 0.925293f, 0.926270f, 0.926758f, 0.927246f, 0.926758f, 0.000244f, 0.000431f, 0.000799f, 0.001309f,
+ 0.001587f, 0.001945f, 0.002317f, 0.002514f, 0.003290f, 0.003548f, 0.004082f, 0.004349f, 0.004707f, 0.005348f, 0.006027f, 0.006565f,
+ 0.007141f, 0.008011f, 0.008850f, 0.009552f, 0.010757f, 0.011650f, 0.012794f, 0.014145f, 0.015778f, 0.017303f, 0.019028f, 0.021088f,
+ 0.023575f, 0.026169f, 0.029175f, 0.032562f, 0.036713f, 0.041382f, 0.046448f, 0.052948f, 0.060303f, 0.068787f, 0.079041f, 0.090942f,
+ 0.105103f, 0.121643f, 0.141113f, 0.164185f, 0.190308f, 0.221191f, 0.256836f, 0.295898f, 0.339355f, 0.385010f, 0.433838f, 0.484619f,
+ 0.534668f, 0.583496f, 0.631348f, 0.678223f, 0.719727f, 0.759766f, 0.913574f, 0.920410f, 0.921387f, 0.921875f, 0.921875f, 0.921387f,
+ 0.000243f, 0.000496f, 0.000847f, 0.001157f, 0.001426f, 0.001634f, 0.002020f, 0.002338f, 0.002607f, 0.003035f, 0.003502f, 0.003872f,
+ 0.004459f, 0.004726f, 0.005402f, 0.005779f, 0.006325f, 0.007095f, 0.007767f, 0.008568f, 0.009331f, 0.010086f, 0.011009f, 0.012314f,
+ 0.013611f, 0.015060f, 0.016312f, 0.018158f, 0.020401f, 0.022476f, 0.024979f, 0.027863f, 0.031036f, 0.034943f, 0.039581f, 0.044830f,
+ 0.050903f, 0.058289f, 0.066895f, 0.076782f, 0.088989f, 0.103210f, 0.120422f, 0.140259f, 0.164185f, 0.191772f, 0.223877f, 0.260742f,
+ 0.301758f, 0.347168f, 0.395508f, 0.446533f, 0.497803f, 0.551270f, 0.601562f, 0.651855f, 0.697754f, 0.741211f, 0.908203f, 0.915039f,
+ 0.916016f, 0.916016f, 0.916504f, 0.915527f, 0.000239f, 0.000345f, 0.000690f, 0.000913f, 0.001250f, 0.001343f, 0.001579f, 0.002050f,
+ 0.002331f, 0.002861f, 0.003048f, 0.003616f, 0.003696f, 0.004211f, 0.004723f, 0.005074f, 0.005657f, 0.006100f, 0.006893f, 0.007290f,
+ 0.008118f, 0.008659f, 0.009552f, 0.010704f, 0.011681f, 0.012764f, 0.014114f, 0.015533f, 0.017227f, 0.018982f, 0.021286f, 0.023560f,
+ 0.026489f, 0.029861f, 0.033417f, 0.037933f, 0.043121f, 0.049286f, 0.056519f, 0.065002f, 0.075073f, 0.087158f, 0.101624f, 0.118835f,
+ 0.139648f, 0.164185f, 0.193481f, 0.226929f, 0.265625f, 0.309570f, 0.356934f, 0.408203f, 0.461426f, 0.516113f, 0.569824f, 0.623047f,
+ 0.674316f, 0.720703f, 0.902344f, 0.908203f, 0.909668f, 0.910645f, 0.910645f, 0.911133f, 0.000000f, 0.000281f, 0.000560f, 0.000977f,
+ 0.001063f, 0.001171f, 0.001569f, 0.001903f, 0.002075f, 0.002413f, 0.002695f, 0.003004f, 0.003399f, 0.003553f, 0.003998f, 0.004333f,
+ 0.004971f, 0.005314f, 0.005806f, 0.006340f, 0.007015f, 0.007492f, 0.008377f, 0.009186f, 0.010094f, 0.010910f, 0.012199f, 0.013351f,
+ 0.014618f, 0.016266f, 0.018082f, 0.019852f, 0.022491f, 0.025085f, 0.028168f, 0.031799f, 0.036041f, 0.041107f, 0.047394f, 0.054321f,
+ 0.062866f, 0.073181f, 0.085327f, 0.100525f, 0.118408f, 0.139648f, 0.165527f, 0.196411f, 0.231812f, 0.273193f, 0.318848f, 0.369629f,
+ 0.423828f, 0.480225f, 0.536621f, 0.592773f, 0.647949f, 0.699707f, 0.894043f, 0.900879f, 0.903809f, 0.903320f, 0.903320f, 0.902832f,
+ 0.000232f, 0.000227f, 0.000555f, 0.000656f, 0.000937f, 0.000985f, 0.001351f, 0.001723f, 0.001925f, 0.002010f, 0.002445f, 0.002625f,
+ 0.002760f, 0.003220f, 0.003551f, 0.003870f, 0.004303f, 0.004826f, 0.005028f, 0.005451f, 0.005985f, 0.006523f, 0.007000f, 0.007744f,
+ 0.008499f, 0.009361f, 0.010109f, 0.011185f, 0.012413f, 0.013603f, 0.015121f, 0.016891f, 0.018753f, 0.020920f, 0.023407f, 0.026764f,
+ 0.030197f, 0.034302f, 0.039429f, 0.044891f, 0.052368f, 0.060822f, 0.071167f, 0.083557f, 0.098877f, 0.117493f, 0.139893f, 0.167725f,
+ 0.200195f, 0.238037f, 0.281982f, 0.331543f, 0.385010f, 0.442627f, 0.501465f, 0.561523f, 0.620605f, 0.675781f, 0.887207f, 0.894531f,
+ 0.895020f, 0.896484f, 0.896484f, 0.895996f, 0.000000f, 0.000332f, 0.000577f, 0.000723f, 0.000720f, 0.001210f, 0.001469f, 0.001456f,
+ 0.001546f, 0.001775f, 0.002159f, 0.002291f, 0.002659f, 0.002916f, 0.003046f, 0.003439f, 0.003752f, 0.003883f, 0.004375f, 0.004635f,
+ 0.005241f, 0.005638f, 0.006054f, 0.006630f, 0.007191f, 0.007744f, 0.008545f, 0.009178f, 0.010498f, 0.011536f, 0.012802f, 0.013931f,
+ 0.015808f, 0.017548f, 0.019379f, 0.022110f, 0.025040f, 0.028473f, 0.032471f, 0.037323f, 0.043152f, 0.050476f, 0.058807f, 0.069214f,
+ 0.082520f, 0.098145f, 0.116821f, 0.141602f, 0.170044f, 0.204834f, 0.245728f, 0.293213f, 0.346436f, 0.403564f, 0.464111f, 0.527832f,
+ 0.589844f, 0.650879f, 0.878418f, 0.886719f, 0.888184f, 0.887695f, 0.888672f, 0.888672f, 0.000243f, 0.000307f, 0.000526f, 0.000561f,
+ 0.000923f, 0.000980f, 0.001143f, 0.001386f, 0.001414f, 0.001683f, 0.001735f, 0.001972f, 0.002232f, 0.002481f, 0.002657f, 0.002754f,
+ 0.003193f, 0.003359f, 0.003603f, 0.003956f, 0.004368f, 0.004692f, 0.005119f, 0.005596f, 0.005955f, 0.006634f, 0.007256f, 0.007881f,
+ 0.008652f, 0.009552f, 0.010376f, 0.011719f, 0.012634f, 0.014595f, 0.016113f, 0.018219f, 0.020554f, 0.023254f, 0.026520f, 0.030502f,
+ 0.035553f, 0.041168f, 0.048065f, 0.057190f, 0.067261f, 0.080811f, 0.097107f, 0.117737f, 0.143066f, 0.173950f, 0.211182f, 0.256592f,
+ 0.307129f, 0.364502f, 0.427002f, 0.491943f, 0.557617f, 0.624023f, 0.869629f, 0.877930f, 0.879883f, 0.879883f, 0.879883f, 0.880371f,
+ 0.000000f, 0.000270f, 0.000342f, 0.000509f, 0.000668f, 0.000989f, 0.000945f, 0.001105f, 0.001230f, 0.001335f, 0.001492f, 0.001757f,
+ 0.001917f, 0.002140f, 0.002386f, 0.002501f, 0.002644f, 0.002884f, 0.003199f, 0.003441f, 0.003620f, 0.003891f, 0.004337f, 0.004631f,
+ 0.005119f, 0.005520f, 0.006100f, 0.006504f, 0.007301f, 0.007771f, 0.008751f, 0.009521f, 0.010658f, 0.011765f, 0.013145f, 0.014641f,
+ 0.016785f, 0.018829f, 0.021545f, 0.024719f, 0.028381f, 0.033203f, 0.038849f, 0.046112f, 0.055084f, 0.065552f, 0.079529f, 0.096985f,
+ 0.118530f, 0.145630f, 0.179321f, 0.220337f, 0.269287f, 0.325439f, 0.387207f, 0.454102f, 0.524414f, 0.595215f, 0.859863f, 0.868652f,
+ 0.870605f, 0.869629f, 0.870117f, 0.870605f, 0.000000f, 0.000230f, 0.000334f, 0.000416f, 0.000700f, 0.000726f, 0.000921f, 0.001008f,
+ 0.001065f, 0.001186f, 0.001365f, 0.001471f, 0.001627f, 0.001796f, 0.001843f, 0.002069f, 0.002266f, 0.002438f, 0.002596f, 0.002831f,
+ 0.003000f, 0.003298f, 0.003597f, 0.003887f, 0.004265f, 0.004581f, 0.004986f, 0.005505f, 0.005947f, 0.006454f, 0.007069f, 0.007801f,
+ 0.008621f, 0.009575f, 0.010612f, 0.011848f, 0.013321f, 0.015259f, 0.017410f, 0.019775f, 0.022934f, 0.026550f, 0.031464f, 0.036713f,
+ 0.043945f, 0.052887f, 0.064209f, 0.078735f, 0.096924f, 0.120361f, 0.149536f, 0.186768f, 0.232422f, 0.285889f, 0.347656f, 0.415527f,
+ 0.488281f, 0.563965f, 0.849121f, 0.857910f, 0.859375f, 0.860840f, 0.860840f, 0.860352f, 0.000233f, 0.000225f, 0.000219f, 0.000431f,
+ 0.000579f, 0.000648f, 0.000671f, 0.000744f, 0.000946f, 0.000994f, 0.001091f, 0.001307f, 0.001364f, 0.001490f, 0.001561f, 0.001712f,
+ 0.001892f, 0.001999f, 0.002190f, 0.002369f, 0.002512f, 0.002733f, 0.003014f, 0.003145f, 0.003553f, 0.003822f, 0.004135f, 0.004326f,
+ 0.004799f, 0.005344f, 0.005718f, 0.006378f, 0.007008f, 0.007721f, 0.008400f, 0.009537f, 0.010597f, 0.011917f, 0.013542f, 0.015579f,
+ 0.018051f, 0.020889f, 0.024765f, 0.029236f, 0.034668f, 0.041779f, 0.051056f, 0.062439f, 0.077576f, 0.097595f, 0.122864f, 0.155273f,
+ 0.196655f, 0.247437f, 0.307617f, 0.375977f, 0.450684f, 0.531250f, 0.837891f, 0.847168f, 0.848633f, 0.849609f, 0.849121f, 0.849609f,
+ 0.000202f, 0.000180f, 0.000206f, 0.000339f, 0.000479f, 0.000536f, 0.000687f, 0.000739f, 0.000771f, 0.000849f, 0.001051f, 0.001060f,
+ 0.001154f, 0.001219f, 0.001389f, 0.001505f, 0.001469f, 0.001729f, 0.001858f, 0.001980f, 0.002209f, 0.002243f, 0.002483f, 0.002695f,
+ 0.002951f, 0.003149f, 0.003374f, 0.003654f, 0.004002f, 0.004154f, 0.004539f, 0.005032f, 0.005428f, 0.005989f, 0.006760f, 0.007549f,
+ 0.008423f, 0.009499f, 0.010620f, 0.012016f, 0.013992f, 0.016434f, 0.019135f, 0.022583f, 0.026840f, 0.032501f, 0.039551f, 0.048828f,
+ 0.061066f, 0.077393f, 0.098755f, 0.127075f, 0.163208f, 0.209717f, 0.267578f, 0.334961f, 0.411133f, 0.494629f, 0.825684f, 0.834473f,
+ 0.836426f, 0.837402f, 0.837402f, 0.837402f, 0.000000f, 0.000185f, 0.000184f, 0.000404f, 0.000408f, 0.000454f, 0.000480f, 0.000506f,
+ 0.000660f, 0.000694f, 0.000742f, 0.000801f, 0.000989f, 0.001111f, 0.001167f, 0.001250f, 0.001311f, 0.001424f, 0.001541f, 0.001574f,
+ 0.001712f, 0.001930f, 0.001982f, 0.002201f, 0.002375f, 0.002439f, 0.002792f, 0.002905f, 0.003065f, 0.003412f, 0.003653f, 0.003952f,
+ 0.004463f, 0.004723f, 0.005230f, 0.005936f, 0.006386f, 0.007092f, 0.008240f, 0.009247f, 0.010765f, 0.012344f, 0.014420f, 0.017090f,
+ 0.020493f, 0.024551f, 0.030014f, 0.037689f, 0.047302f, 0.060028f, 0.077820f, 0.100830f, 0.132812f, 0.174561f, 0.228516f, 0.294434f,
+ 0.371582f, 0.457031f, 0.812012f, 0.820801f, 0.823730f, 0.824219f, 0.824707f, 0.824219f, 0.000000f, 0.000053f, 0.000206f, 0.000360f,
+ 0.000379f, 0.000391f, 0.000379f, 0.000478f, 0.000549f, 0.000589f, 0.000626f, 0.000674f, 0.000762f, 0.000832f, 0.000894f, 0.001050f,
+ 0.001111f, 0.001155f, 0.001286f, 0.001345f, 0.001449f, 0.001564f, 0.001666f, 0.001750f, 0.001856f, 0.001925f, 0.002056f, 0.002359f,
+ 0.002542f, 0.002728f, 0.003042f, 0.003164f, 0.003460f, 0.003786f, 0.004116f, 0.004578f, 0.005116f, 0.005688f, 0.006508f, 0.007229f,
+ 0.008125f, 0.009232f, 0.010796f, 0.012741f, 0.015137f, 0.018158f, 0.022186f, 0.028030f, 0.035248f, 0.045593f, 0.059052f, 0.078308f,
+ 0.105042f, 0.141602f, 0.190308f, 0.252930f, 0.329102f, 0.417969f, 0.797852f, 0.807129f, 0.810059f, 0.810547f, 0.811035f, 0.810547f,
+ 0.000000f, 0.000000f, 0.000082f, 0.000195f, 0.000309f, 0.000336f, 0.000324f, 0.000414f, 0.000439f, 0.000460f, 0.000599f, 0.000643f,
+ 0.000637f, 0.000690f, 0.000733f, 0.000834f, 0.000821f, 0.000922f, 0.000989f, 0.001067f, 0.001207f, 0.001293f, 0.001327f, 0.001476f,
+ 0.001581f, 0.001663f, 0.001725f, 0.001906f, 0.001934f, 0.002180f, 0.002258f, 0.002602f, 0.002701f, 0.003019f, 0.003229f, 0.003502f,
+ 0.003847f, 0.004261f, 0.004795f, 0.005318f, 0.006130f, 0.007008f, 0.008118f, 0.009277f, 0.011024f, 0.013229f, 0.016205f, 0.020203f,
+ 0.025620f, 0.033020f, 0.043854f, 0.059021f, 0.080383f, 0.111206f, 0.154419f, 0.212646f, 0.287354f, 0.378418f, 0.781250f, 0.792480f,
+ 0.793457f, 0.795410f, 0.795898f, 0.794922f, 0.000000f, 0.000121f, 0.000120f, 0.000198f, 0.000275f, 0.000249f, 0.000290f, 0.000360f,
+ 0.000375f, 0.000379f, 0.000391f, 0.000438f, 0.000505f, 0.000534f, 0.000669f, 0.000629f, 0.000659f, 0.000754f, 0.000890f, 0.000833f,
+ 0.000849f, 0.000975f, 0.001029f, 0.001117f, 0.001193f, 0.001203f, 0.001269f, 0.001424f, 0.001594f, 0.001675f, 0.001737f, 0.001957f,
+ 0.002094f, 0.002319f, 0.002342f, 0.002609f, 0.002928f, 0.003248f, 0.003523f, 0.003967f, 0.004547f, 0.005138f, 0.005871f, 0.006760f,
+ 0.007912f, 0.009430f, 0.011528f, 0.014236f, 0.017899f, 0.023346f, 0.031235f, 0.042694f, 0.059235f, 0.084229f, 0.120972f, 0.173950f,
+ 0.245239f, 0.334473f, 0.764160f, 0.775391f, 0.777344f, 0.778809f, 0.777832f, 0.778809f, 0.000000f, 0.000121f, 0.000119f, 0.000182f,
+ 0.000177f, 0.000179f, 0.000262f, 0.000239f, 0.000309f, 0.000322f, 0.000404f, 0.000370f, 0.000361f, 0.000430f, 0.000458f, 0.000540f,
+ 0.000589f, 0.000615f, 0.000648f, 0.000632f, 0.000777f, 0.000782f, 0.000798f, 0.000871f, 0.000857f, 0.000925f, 0.001000f, 0.001045f,
+ 0.001191f, 0.001223f, 0.001426f, 0.001419f, 0.001512f, 0.001635f, 0.001884f, 0.002092f, 0.002100f, 0.002293f, 0.002577f, 0.003012f,
+ 0.003258f, 0.003761f, 0.004253f, 0.004814f, 0.005619f, 0.006676f, 0.008064f, 0.009750f, 0.012268f, 0.015854f, 0.021255f, 0.029282f,
+ 0.041687f, 0.061005f, 0.091370f, 0.136230f, 0.202759f, 0.291504f, 0.746582f, 0.757324f, 0.759277f, 0.760254f, 0.760254f, 0.760254f,
+ 0.000000f, 0.000000f, 0.000117f, 0.000126f, 0.000113f, 0.000146f, 0.000158f, 0.000155f, 0.000189f, 0.000288f, 0.000254f, 0.000336f,
+ 0.000347f, 0.000353f, 0.000370f, 0.000355f, 0.000390f, 0.000417f, 0.000456f, 0.000480f, 0.000525f, 0.000587f, 0.000596f, 0.000620f,
+ 0.000676f, 0.000740f, 0.000758f, 0.000852f, 0.000907f, 0.000947f, 0.001057f, 0.001122f, 0.001170f, 0.001293f, 0.001316f, 0.001437f,
+ 0.001531f, 0.001813f, 0.001952f, 0.002090f, 0.002346f, 0.002560f, 0.002974f, 0.003334f, 0.003899f, 0.004547f, 0.005360f, 0.006516f,
+ 0.008179f, 0.010468f, 0.013947f, 0.019241f, 0.027832f, 0.041443f, 0.064941f, 0.102600f, 0.162231f, 0.247437f, 0.726074f, 0.737793f,
+ 0.739258f, 0.740723f, 0.741211f, 0.741211f, 0.000000f, 0.000118f, 0.000115f, 0.000113f, 0.000110f, 0.000126f, 0.000121f, 0.000139f,
+ 0.000147f, 0.000160f, 0.000161f, 0.000233f, 0.000199f, 0.000266f, 0.000286f, 0.000297f, 0.000329f, 0.000313f, 0.000347f, 0.000358f,
+ 0.000364f, 0.000394f, 0.000435f, 0.000446f, 0.000489f, 0.000506f, 0.000546f, 0.000625f, 0.000648f, 0.000674f, 0.000723f, 0.000782f,
+ 0.000865f, 0.000918f, 0.000979f, 0.001104f, 0.001100f, 0.001196f, 0.001352f, 0.001488f, 0.001586f, 0.001749f, 0.001955f, 0.002275f,
+ 0.002644f, 0.003054f, 0.003563f, 0.004322f, 0.005314f, 0.006786f, 0.008980f, 0.012115f, 0.017319f, 0.026520f, 0.043121f, 0.072693f,
+ 0.123535f, 0.203613f, 0.705566f, 0.716797f, 0.719238f, 0.719727f, 0.720703f, 0.721191f, 0.000000f, 0.000000f, 0.000112f, 0.000109f,
+ 0.000106f, 0.000104f, 0.000102f, 0.000096f, 0.000091f, 0.000113f, 0.000147f, 0.000129f, 0.000155f, 0.000134f, 0.000196f, 0.000205f,
+ 0.000181f, 0.000239f, 0.000297f, 0.000255f, 0.000317f, 0.000273f, 0.000335f, 0.000299f, 0.000379f, 0.000385f, 0.000398f, 0.000402f,
+ 0.000473f, 0.000552f, 0.000489f, 0.000543f, 0.000557f, 0.000606f, 0.000662f, 0.000698f, 0.000747f, 0.000810f, 0.000902f, 0.000961f,
+ 0.001063f, 0.001166f, 0.001312f, 0.001523f, 0.001662f, 0.001908f, 0.002298f, 0.002758f, 0.003365f, 0.004135f, 0.005394f, 0.007290f,
+ 0.010490f, 0.015991f, 0.026215f, 0.047180f, 0.087646f, 0.160645f, 0.682617f, 0.695801f, 0.697266f, 0.697266f, 0.697266f, 0.698730f,
+ 0.000000f, 0.000112f, 0.000106f, 0.000104f, 0.000100f, 0.000098f, 0.000095f, 0.000094f, 0.000090f, 0.000085f, 0.000080f, 0.000081f,
+ 0.000085f, 0.000123f, 0.000123f, 0.000138f, 0.000151f, 0.000158f, 0.000147f, 0.000171f, 0.000183f, 0.000192f, 0.000242f, 0.000215f,
+ 0.000253f, 0.000256f, 0.000269f, 0.000278f, 0.000293f, 0.000315f, 0.000377f, 0.000357f, 0.000357f, 0.000423f, 0.000479f, 0.000493f,
+ 0.000489f, 0.000535f, 0.000579f, 0.000628f, 0.000683f, 0.000731f, 0.000833f, 0.000935f, 0.001068f, 0.001200f, 0.001347f, 0.001581f,
+ 0.001995f, 0.002419f, 0.003109f, 0.004147f, 0.005829f, 0.008919f, 0.014641f, 0.027405f, 0.056885f, 0.119385f, 0.658691f, 0.669922f,
+ 0.673828f, 0.673828f, 0.675293f, 0.675293f, 0.000000f, 0.000105f, 0.000101f, 0.000096f, 0.000092f, 0.000089f, 0.000087f, 0.000085f,
+ 0.000083f, 0.000081f, 0.000077f, 0.000073f, 0.000070f, 0.000066f, 0.000080f, 0.000084f, 0.000089f, 0.000068f, 0.000101f, 0.000094f,
+ 0.000116f, 0.000118f, 0.000125f, 0.000129f, 0.000150f, 0.000168f, 0.000153f, 0.000192f, 0.000195f, 0.000185f, 0.000200f, 0.000217f,
+ 0.000226f, 0.000247f, 0.000257f, 0.000262f, 0.000319f, 0.000334f, 0.000347f, 0.000376f, 0.000395f, 0.000447f, 0.000504f, 0.000544f,
+ 0.000590f, 0.000670f, 0.000789f, 0.000887f, 0.001069f, 0.001345f, 0.001670f, 0.002167f, 0.003065f, 0.004562f, 0.007660f, 0.014290f,
+ 0.032135f, 0.081299f, 0.632812f, 0.645996f, 0.648926f, 0.649414f, 0.648926f, 0.649902f, 0.000109f, 0.000094f, 0.000087f, 0.000082f,
+ 0.000078f, 0.000076f, 0.000074f, 0.000071f, 0.000069f, 0.000068f, 0.000067f, 0.000066f, 0.000064f, 0.000061f, 0.000058f, 0.000055f,
+ 0.000053f, 0.000050f, 0.000051f, 0.000046f, 0.000059f, 0.000056f, 0.000057f, 0.000068f, 0.000078f, 0.000088f, 0.000096f, 0.000096f,
+ 0.000105f, 0.000107f, 0.000128f, 0.000121f, 0.000133f, 0.000141f, 0.000156f, 0.000151f, 0.000160f, 0.000200f, 0.000209f, 0.000198f,
+ 0.000222f, 0.000242f, 0.000258f, 0.000275f, 0.000314f, 0.000352f, 0.000410f, 0.000468f, 0.000537f, 0.000639f, 0.000799f, 0.001002f,
+ 0.001390f, 0.002092f, 0.003466f, 0.006653f, 0.015305f, 0.048004f, 0.606934f, 0.618652f, 0.622559f, 0.623047f, 0.623535f, 0.624023f,
+ 0.000084f, 0.000067f, 0.000064f, 0.000062f, 0.000057f, 0.000056f, 0.000053f, 0.000054f, 0.000051f, 0.000052f, 0.000050f, 0.000050f,
+ 0.000050f, 0.000049f, 0.000048f, 0.000047f, 0.000046f, 0.000044f, 0.000042f, 0.000040f, 0.000039f, 0.000037f, 0.000035f, 0.000036f,
+ 0.000037f, 0.000031f, 0.000040f, 0.000041f, 0.000042f, 0.000051f, 0.000058f, 0.000063f, 0.000067f, 0.000069f, 0.000072f, 0.000079f,
+ 0.000085f, 0.000092f, 0.000093f, 0.000101f, 0.000107f, 0.000123f, 0.000125f, 0.000139f, 0.000147f, 0.000154f, 0.000181f, 0.000204f,
+ 0.000229f, 0.000270f, 0.000327f, 0.000425f, 0.000559f, 0.000772f, 0.001265f, 0.002462f, 0.006191f, 0.022415f, 0.578613f, 0.592285f,
+ 0.595215f, 0.596191f, 0.596191f, 0.597656f, 0.000008f, 0.000022f, 0.000022f, 0.000024f, 0.000024f, 0.000027f, 0.000028f, 0.000028f,
+ 0.000028f, 0.000026f, 0.000028f, 0.000029f, 0.000029f, 0.000028f, 0.000029f, 0.000029f, 0.000029f, 0.000029f, 0.000030f, 0.000030f,
+ 0.000030f, 0.000029f, 0.000028f, 0.000027f, 0.000026f, 0.000025f, 0.000024f, 0.000023f, 0.000022f, 0.000021f, 0.000020f, 0.000019f,
+ 0.000021f, 0.000020f, 0.000022f, 0.000026f, 0.000028f, 0.000033f, 0.000037f, 0.000036f, 0.000039f, 0.000045f, 0.000051f, 0.000046f,
+ 0.000056f, 0.000059f, 0.000061f, 0.000071f, 0.000084f, 0.000098f, 0.000110f, 0.000133f, 0.000169f, 0.000223f, 0.000356f, 0.000648f,
+ 0.001702f, 0.007713f, 0.550293f, 0.564453f, 0.566895f, 0.567871f, 0.568359f, 0.568848f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000002f, 0.000003f, 0.000004f, 0.000006f,
+ 0.000007f, 0.000007f, 0.000008f, 0.000008f, 0.000009f, 0.000010f, 0.000011f, 0.000011f, 0.000012f, 0.000012f, 0.000013f, 0.000013f,
+ 0.000013f, 0.000014f, 0.000014f, 0.000013f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000009f, 0.000009f,
+ 0.000008f, 0.000008f, 0.000009f, 0.000011f, 0.000014f, 0.000017f, 0.000015f, 0.000018f, 0.000021f, 0.000022f, 0.000023f, 0.000026f,
+ 0.000035f, 0.000040f, 0.000056f, 0.000089f, 0.000225f, 0.001332f, 0.520996f, 0.535156f, 0.538086f, 0.540039f, 0.540039f, 0.540039f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000003f, 0.000003f,
+ 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000001f, 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000017f, 0.491211f, 0.506348f,
+ 0.508789f, 0.510254f, 0.510254f, 0.510742f,
+ },
+ {
+ 0.064758f, 0.179688f, 0.277344f, 0.358398f, 0.427002f, 0.485107f, 0.535156f, 0.578613f, 0.615234f, 0.647949f, 0.677734f, 0.703125f,
+ 0.725586f, 0.745605f, 0.763672f, 0.780273f, 0.795410f, 0.810059f, 0.821777f, 0.833496f, 0.843750f, 0.854004f, 0.862793f, 0.871582f,
+ 0.879883f, 0.886719f, 0.894043f, 0.900879f, 0.906250f, 0.912109f, 0.917969f, 0.922852f, 0.927246f, 0.932129f, 0.936523f, 0.940918f,
+ 0.944824f, 0.948242f, 0.951660f, 0.955078f, 0.958496f, 0.961426f, 0.964844f, 0.967773f, 0.970215f, 0.973145f, 0.975586f, 0.977539f,
+ 0.979980f, 0.982422f, 0.984863f, 0.986328f, 0.988770f, 0.990234f, 0.992676f, 0.993652f, 0.995605f, 0.997559f, 0.998535f, 0.996582f,
+ 0.995117f, 0.993652f, 0.992188f, 0.990723f, 0.040344f, 0.121460f, 0.199341f, 0.272949f, 0.339600f, 0.401123f, 0.455078f, 0.501953f,
+ 0.546875f, 0.583984f, 0.618164f, 0.648926f, 0.676270f, 0.700195f, 0.723145f, 0.743164f, 0.761230f, 0.776855f, 0.793457f, 0.806641f,
+ 0.819336f, 0.831543f, 0.842285f, 0.852051f, 0.861328f, 0.869629f, 0.877930f, 0.886230f, 0.892578f, 0.899902f, 0.905273f, 0.911621f,
+ 0.917480f, 0.922852f, 0.927246f, 0.932129f, 0.936035f, 0.940430f, 0.945312f, 0.949219f, 0.952148f, 0.956055f, 0.958984f, 0.961914f,
+ 0.965332f, 0.967773f, 0.970703f, 0.973633f, 0.976074f, 0.978516f, 0.980957f, 0.983398f, 0.985840f, 0.987305f, 0.989258f, 0.991699f,
+ 0.993652f, 0.995117f, 0.997070f, 0.995605f, 0.994141f, 0.993164f, 0.991699f, 0.990234f, 0.027191f, 0.084961f, 0.145630f, 0.206177f,
+ 0.266113f, 0.323242f, 0.377930f, 0.428711f, 0.474609f, 0.517090f, 0.554688f, 0.591309f, 0.621582f, 0.650391f, 0.676758f, 0.700684f,
+ 0.723145f, 0.741699f, 0.760254f, 0.776855f, 0.791504f, 0.805664f, 0.818359f, 0.830566f, 0.841309f, 0.851074f, 0.861816f, 0.870117f,
+ 0.878418f, 0.885254f, 0.892090f, 0.899414f, 0.906250f, 0.912598f, 0.916992f, 0.922363f, 0.928223f, 0.932617f, 0.937500f, 0.941895f,
+ 0.945801f, 0.949219f, 0.953613f, 0.957031f, 0.960449f, 0.963379f, 0.966797f, 0.969727f, 0.971680f, 0.974609f, 0.977539f, 0.979980f,
+ 0.981934f, 0.984375f, 0.986328f, 0.989258f, 0.991211f, 0.992676f, 0.996094f, 0.994629f, 0.993652f, 0.992188f, 0.990723f, 0.989746f,
+ 0.019577f, 0.061340f, 0.108337f, 0.156860f, 0.207153f, 0.258789f, 0.310059f, 0.358887f, 0.405762f, 0.450928f, 0.491211f, 0.530273f,
+ 0.565430f, 0.597656f, 0.627441f, 0.654297f, 0.680176f, 0.702637f, 0.724121f, 0.743164f, 0.760742f, 0.776855f, 0.791992f, 0.806152f,
+ 0.817871f, 0.830078f, 0.841797f, 0.852539f, 0.861816f, 0.870117f, 0.878906f, 0.886230f, 0.893066f, 0.900391f, 0.906738f, 0.912598f,
+ 0.918457f, 0.923340f, 0.928223f, 0.933594f, 0.938477f, 0.942871f, 0.946777f, 0.950684f, 0.954590f, 0.958496f, 0.960938f, 0.964844f,
+ 0.967773f, 0.970703f, 0.973633f, 0.976074f, 0.979004f, 0.981445f, 0.983398f, 0.985840f, 0.987793f, 0.990234f, 0.995117f, 0.993652f,
+ 0.992676f, 0.991699f, 0.990234f, 0.989258f, 0.014397f, 0.046295f, 0.081543f, 0.120728f, 0.162842f, 0.206177f, 0.250977f, 0.296143f,
+ 0.342041f, 0.385986f, 0.427979f, 0.468262f, 0.506348f, 0.542480f, 0.575195f, 0.605469f, 0.633789f, 0.660156f, 0.684570f, 0.706543f,
+ 0.727539f, 0.745117f, 0.763184f, 0.778809f, 0.793945f, 0.807617f, 0.820312f, 0.833008f, 0.842773f, 0.852539f, 0.862305f, 0.872070f,
+ 0.879395f, 0.887207f, 0.894531f, 0.900879f, 0.907227f, 0.914551f, 0.919922f, 0.925293f, 0.930176f, 0.935547f, 0.938965f, 0.943359f,
+ 0.948730f, 0.952637f, 0.956055f, 0.959473f, 0.962891f, 0.966309f, 0.969238f, 0.972656f, 0.975098f, 0.977539f, 0.980957f, 0.982910f,
+ 0.984863f, 0.987793f, 0.994141f, 0.993164f, 0.991699f, 0.990723f, 0.989746f, 0.988281f, 0.010925f, 0.035828f, 0.063660f, 0.094360f,
+ 0.128174f, 0.164551f, 0.203247f, 0.244385f, 0.285645f, 0.326416f, 0.367432f, 0.409424f, 0.447998f, 0.484131f, 0.520508f, 0.553711f,
+ 0.584473f, 0.614258f, 0.641113f, 0.666016f, 0.689453f, 0.710938f, 0.730469f, 0.750488f, 0.766602f, 0.781250f, 0.796387f, 0.809570f,
+ 0.822266f, 0.833496f, 0.844727f, 0.854980f, 0.864258f, 0.873047f, 0.881348f, 0.889648f, 0.895996f, 0.903809f, 0.910156f, 0.916504f,
+ 0.921387f, 0.926758f, 0.932129f, 0.937500f, 0.941895f, 0.946777f, 0.950684f, 0.954102f, 0.958008f, 0.960938f, 0.965332f, 0.968262f,
+ 0.971680f, 0.975098f, 0.977539f, 0.979492f, 0.982422f, 0.984863f, 0.992676f, 0.991699f, 0.990723f, 0.989746f, 0.988770f, 0.987793f,
+ 0.008698f, 0.028244f, 0.049866f, 0.074463f, 0.102295f, 0.132935f, 0.165161f, 0.200073f, 0.236206f, 0.275391f, 0.313477f, 0.352051f,
+ 0.391113f, 0.428955f, 0.465088f, 0.500977f, 0.534180f, 0.565430f, 0.593750f, 0.622559f, 0.648438f, 0.671875f, 0.694824f, 0.715820f,
+ 0.734863f, 0.753906f, 0.771484f, 0.784668f, 0.799805f, 0.813477f, 0.825195f, 0.836914f, 0.847656f, 0.857910f, 0.866699f, 0.875488f,
+ 0.884766f, 0.892090f, 0.898438f, 0.906250f, 0.913086f, 0.918457f, 0.923828f, 0.929688f, 0.935059f, 0.939941f, 0.944336f, 0.948730f,
+ 0.952637f, 0.956055f, 0.959961f, 0.963379f, 0.967285f, 0.970703f, 0.973633f, 0.976074f, 0.979492f, 0.982422f, 0.991211f, 0.990723f,
+ 0.990234f, 0.988770f, 0.987793f, 0.986328f, 0.007210f, 0.022797f, 0.040039f, 0.060181f, 0.082153f, 0.107300f, 0.134155f, 0.164673f,
+ 0.196167f, 0.229492f, 0.265381f, 0.301025f, 0.338379f, 0.374756f, 0.411133f, 0.446533f, 0.481201f, 0.515625f, 0.546387f, 0.576660f,
+ 0.605957f, 0.631348f, 0.656738f, 0.681152f, 0.702148f, 0.722168f, 0.741699f, 0.758789f, 0.775391f, 0.791016f, 0.803711f, 0.817383f,
+ 0.829102f, 0.840820f, 0.851562f, 0.860840f, 0.871094f, 0.879395f, 0.887695f, 0.895020f, 0.901855f, 0.909180f, 0.915527f, 0.921387f,
+ 0.927734f, 0.932129f, 0.937500f, 0.941895f, 0.947266f, 0.950684f, 0.955078f, 0.958984f, 0.962891f, 0.966797f, 0.969727f, 0.973145f,
+ 0.976562f, 0.979004f, 0.990234f, 0.989746f, 0.988770f, 0.987793f, 0.986816f, 0.985840f, 0.005863f, 0.018936f, 0.032898f, 0.049377f,
+ 0.067261f, 0.088257f, 0.110535f, 0.135254f, 0.162231f, 0.191895f, 0.223389f, 0.255371f, 0.290039f, 0.324707f, 0.359863f, 0.395996f,
+ 0.429932f, 0.464355f, 0.497314f, 0.529297f, 0.559570f, 0.587891f, 0.616699f, 0.642090f, 0.665527f, 0.688965f, 0.709961f, 0.729492f,
+ 0.747559f, 0.765625f, 0.780762f, 0.794922f, 0.809082f, 0.822754f, 0.833984f, 0.844727f, 0.855957f, 0.864746f, 0.875000f, 0.883789f,
+ 0.891113f, 0.898926f, 0.906250f, 0.912598f, 0.918457f, 0.925293f, 0.930664f, 0.935059f, 0.940918f, 0.945312f, 0.950195f, 0.954590f,
+ 0.958496f, 0.962402f, 0.965820f, 0.969238f, 0.972656f, 0.976074f, 0.988770f, 0.988770f, 0.987793f, 0.986816f, 0.985840f, 0.984863f,
+ 0.004925f, 0.015518f, 0.027451f, 0.041199f, 0.055786f, 0.072998f, 0.091492f, 0.112427f, 0.135254f, 0.160767f, 0.187500f, 0.216919f,
+ 0.247314f, 0.280273f, 0.313477f, 0.346680f, 0.381592f, 0.415283f, 0.448730f, 0.481201f, 0.513184f, 0.543945f, 0.573242f, 0.601562f,
+ 0.627441f, 0.652344f, 0.675293f, 0.697754f, 0.718262f, 0.737793f, 0.754883f, 0.771973f, 0.787109f, 0.800781f, 0.815430f, 0.828125f,
+ 0.839844f, 0.851074f, 0.860840f, 0.870117f, 0.879883f, 0.887695f, 0.896484f, 0.902832f, 0.911133f, 0.916992f, 0.922852f, 0.928711f,
+ 0.934082f, 0.939941f, 0.944336f, 0.948730f, 0.954102f, 0.958008f, 0.961426f, 0.965332f, 0.969238f, 0.972168f, 0.987305f, 0.987305f,
+ 0.986816f, 0.985840f, 0.984863f, 0.983887f, 0.004139f, 0.012955f, 0.022781f, 0.034088f, 0.046997f, 0.061005f, 0.076538f, 0.094360f,
+ 0.113464f, 0.134888f, 0.158203f, 0.183716f, 0.210693f, 0.239990f, 0.270264f, 0.302734f, 0.334961f, 0.367676f, 0.400635f, 0.434082f,
+ 0.467041f, 0.497803f, 0.528809f, 0.558105f, 0.586426f, 0.614258f, 0.638672f, 0.663574f, 0.686035f, 0.707520f, 0.728027f, 0.745605f,
+ 0.762695f, 0.779297f, 0.794434f, 0.808594f, 0.821777f, 0.834473f, 0.845215f, 0.855957f, 0.866699f, 0.876465f, 0.884766f, 0.892090f,
+ 0.900391f, 0.908203f, 0.915039f, 0.920898f, 0.927246f, 0.932617f, 0.937988f, 0.943848f, 0.948730f, 0.952637f, 0.957520f, 0.961426f,
+ 0.965820f, 0.968750f, 0.985840f, 0.985840f, 0.985840f, 0.984375f, 0.983887f, 0.982910f, 0.003492f, 0.011307f, 0.019608f, 0.028793f,
+ 0.039246f, 0.051544f, 0.064392f, 0.078796f, 0.095337f, 0.113953f, 0.134033f, 0.155396f, 0.179688f, 0.205200f, 0.232300f, 0.261475f,
+ 0.291748f, 0.323730f, 0.355225f, 0.387939f, 0.420410f, 0.452637f, 0.483887f, 0.514648f, 0.544922f, 0.573730f, 0.601074f, 0.626953f,
+ 0.651367f, 0.675293f, 0.697266f, 0.717285f, 0.736816f, 0.755371f, 0.771973f, 0.786621f, 0.803223f, 0.815430f, 0.828613f, 0.840820f,
+ 0.851562f, 0.863281f, 0.873047f, 0.880859f, 0.890625f, 0.898438f, 0.905762f, 0.913086f, 0.919434f, 0.925781f, 0.931641f, 0.937500f,
+ 0.942871f, 0.947754f, 0.952637f, 0.957520f, 0.960938f, 0.965820f, 0.984375f, 0.984863f, 0.984375f, 0.983398f, 0.982422f, 0.981445f,
+ 0.002977f, 0.009415f, 0.016708f, 0.024811f, 0.033356f, 0.043457f, 0.054535f, 0.067017f, 0.080322f, 0.096130f, 0.113708f, 0.132080f,
+ 0.152710f, 0.175415f, 0.199829f, 0.226440f, 0.253662f, 0.282959f, 0.313232f, 0.343750f, 0.375000f, 0.406982f, 0.439453f, 0.471191f,
+ 0.501465f, 0.531738f, 0.560547f, 0.587891f, 0.615234f, 0.640625f, 0.664062f, 0.687500f, 0.708496f, 0.728516f, 0.747559f, 0.765137f,
+ 0.781738f, 0.795898f, 0.811523f, 0.824707f, 0.836426f, 0.847656f, 0.858887f, 0.869141f, 0.878906f, 0.887695f, 0.895996f, 0.904297f,
+ 0.911133f, 0.917969f, 0.925293f, 0.931152f, 0.937012f, 0.942383f, 0.947266f, 0.953125f, 0.957031f, 0.961426f, 0.982910f, 0.983398f,
+ 0.982910f, 0.982422f, 0.981445f, 0.980957f, 0.002743f, 0.008568f, 0.014305f, 0.021378f, 0.028732f, 0.037201f, 0.046387f, 0.057068f,
+ 0.068848f, 0.082336f, 0.096924f, 0.113159f, 0.130859f, 0.150146f, 0.171509f, 0.194824f, 0.219482f, 0.246338f, 0.273926f, 0.302734f,
+ 0.333496f, 0.364502f, 0.395752f, 0.426758f, 0.458252f, 0.489990f, 0.519531f, 0.548340f, 0.576660f, 0.604004f, 0.630859f, 0.654297f,
+ 0.678223f, 0.700684f, 0.720215f, 0.740234f, 0.758301f, 0.775391f, 0.790527f, 0.805176f, 0.818848f, 0.833008f, 0.844238f, 0.855469f,
+ 0.866699f, 0.876953f, 0.886230f, 0.894043f, 0.902832f, 0.910645f, 0.917480f, 0.924316f, 0.930664f, 0.937012f, 0.941895f, 0.947266f,
+ 0.952148f, 0.957031f, 0.981445f, 0.982422f, 0.981445f, 0.980957f, 0.980469f, 0.979004f, 0.002504f, 0.007004f, 0.012634f, 0.018555f,
+ 0.024933f, 0.032654f, 0.040283f, 0.048920f, 0.059357f, 0.070007f, 0.082642f, 0.096741f, 0.112122f, 0.128906f, 0.147339f, 0.167603f,
+ 0.189697f, 0.213257f, 0.238770f, 0.265869f, 0.293701f, 0.323242f, 0.354004f, 0.384766f, 0.415283f, 0.447021f, 0.478516f, 0.507812f,
+ 0.536621f, 0.565918f, 0.593750f, 0.620605f, 0.645508f, 0.668945f, 0.692383f, 0.712891f, 0.733398f, 0.751465f, 0.769531f, 0.785156f,
+ 0.801270f, 0.814941f, 0.828125f, 0.841797f, 0.853516f, 0.864746f, 0.874512f, 0.883789f, 0.893555f, 0.900879f, 0.910156f, 0.917480f,
+ 0.923340f, 0.930664f, 0.936523f, 0.942383f, 0.947754f, 0.952637f, 0.979492f, 0.980469f, 0.980469f, 0.979492f, 0.978516f, 0.978027f,
+ 0.002039f, 0.006287f, 0.010864f, 0.016129f, 0.021637f, 0.027786f, 0.034485f, 0.042450f, 0.051331f, 0.060760f, 0.071594f, 0.082886f,
+ 0.096313f, 0.110840f, 0.126587f, 0.145020f, 0.164185f, 0.185181f, 0.207520f, 0.232300f, 0.258301f, 0.285889f, 0.314941f, 0.344238f,
+ 0.374268f, 0.405029f, 0.436035f, 0.466797f, 0.498291f, 0.527344f, 0.555664f, 0.583984f, 0.611328f, 0.636230f, 0.661133f, 0.684082f,
+ 0.705566f, 0.726562f, 0.745605f, 0.764648f, 0.781250f, 0.797852f, 0.812500f, 0.825195f, 0.838867f, 0.851074f, 0.862305f, 0.873535f,
+ 0.883301f, 0.892578f, 0.901367f, 0.908203f, 0.916992f, 0.923828f, 0.931152f, 0.937012f, 0.942383f, 0.947266f, 0.978027f, 0.978516f,
+ 0.979004f, 0.978027f, 0.977051f, 0.977051f, 0.001762f, 0.005489f, 0.009804f, 0.013931f, 0.019028f, 0.024445f, 0.030518f, 0.036865f,
+ 0.044189f, 0.052460f, 0.061432f, 0.071960f, 0.083008f, 0.095642f, 0.109558f, 0.124756f, 0.141602f, 0.160156f, 0.180664f, 0.202148f,
+ 0.225952f, 0.250977f, 0.278076f, 0.305664f, 0.334961f, 0.364990f, 0.394775f, 0.425537f, 0.456543f, 0.487061f, 0.517090f, 0.546387f,
+ 0.575195f, 0.602539f, 0.627930f, 0.653809f, 0.676758f, 0.699707f, 0.721191f, 0.740723f, 0.759766f, 0.777832f, 0.793945f, 0.809082f,
+ 0.823242f, 0.836426f, 0.849609f, 0.861328f, 0.872070f, 0.881836f, 0.892578f, 0.900391f, 0.908691f, 0.916992f, 0.924316f, 0.931152f,
+ 0.937500f, 0.943359f, 0.976074f, 0.977051f, 0.977051f, 0.976562f, 0.976074f, 0.975098f, 0.001675f, 0.005020f, 0.008400f, 0.012253f,
+ 0.016724f, 0.021469f, 0.026428f, 0.032104f, 0.039062f, 0.045563f, 0.053741f, 0.062103f, 0.072205f, 0.082947f, 0.094666f, 0.107727f,
+ 0.122681f, 0.139038f, 0.156250f, 0.176514f, 0.197388f, 0.220581f, 0.244629f, 0.270752f, 0.297607f, 0.326172f, 0.355957f, 0.386475f,
+ 0.416748f, 0.447754f, 0.478027f, 0.507812f, 0.538086f, 0.566406f, 0.594727f, 0.621582f, 0.647461f, 0.671387f, 0.694336f, 0.716797f,
+ 0.737305f, 0.755859f, 0.773438f, 0.791016f, 0.807129f, 0.820801f, 0.834961f, 0.848145f, 0.860352f, 0.871582f, 0.881836f, 0.891602f,
+ 0.901367f, 0.909180f, 0.917480f, 0.925293f, 0.932129f, 0.938965f, 0.974609f, 0.975586f, 0.976074f, 0.974609f, 0.974121f, 0.973633f,
+ 0.001437f, 0.004513f, 0.007427f, 0.010994f, 0.014526f, 0.018829f, 0.023331f, 0.028229f, 0.034058f, 0.040192f, 0.046844f, 0.054321f,
+ 0.062683f, 0.071716f, 0.082397f, 0.093933f, 0.106567f, 0.120728f, 0.136230f, 0.153320f, 0.172485f, 0.192627f, 0.214233f, 0.237915f,
+ 0.263672f, 0.290527f, 0.318115f, 0.347412f, 0.377197f, 0.408203f, 0.438477f, 0.469482f, 0.499512f, 0.529785f, 0.558594f, 0.586914f,
+ 0.614258f, 0.641602f, 0.665527f, 0.689941f, 0.711914f, 0.732422f, 0.752930f, 0.771484f, 0.789062f, 0.805664f, 0.819824f, 0.833984f,
+ 0.847656f, 0.860840f, 0.871094f, 0.881836f, 0.891602f, 0.902344f, 0.910156f, 0.918457f, 0.926270f, 0.932617f, 0.972168f, 0.973633f,
+ 0.973633f, 0.973145f, 0.973145f, 0.971680f, 0.001390f, 0.003952f, 0.006779f, 0.009941f, 0.013062f, 0.017029f, 0.020905f, 0.024994f,
+ 0.029877f, 0.035187f, 0.041077f, 0.047119f, 0.055145f, 0.062500f, 0.071594f, 0.081543f, 0.092712f, 0.104736f, 0.118530f, 0.133179f,
+ 0.150024f, 0.168091f, 0.187378f, 0.209717f, 0.232178f, 0.256836f, 0.283447f, 0.311279f, 0.339844f, 0.369873f, 0.399658f, 0.429932f,
+ 0.461426f, 0.492188f, 0.521973f, 0.551758f, 0.580566f, 0.608887f, 0.635254f, 0.660645f, 0.685059f, 0.708008f, 0.729492f, 0.750488f,
+ 0.769043f, 0.786621f, 0.802734f, 0.818848f, 0.832520f, 0.846680f, 0.860352f, 0.871582f, 0.882324f, 0.892578f, 0.902832f, 0.911133f,
+ 0.919922f, 0.926758f, 0.970703f, 0.971680f, 0.971680f, 0.971680f, 0.971680f, 0.969238f, 0.001328f, 0.003641f, 0.006138f, 0.008690f,
+ 0.011444f, 0.014786f, 0.018311f, 0.022125f, 0.026337f, 0.031403f, 0.036011f, 0.041809f, 0.047943f, 0.054901f, 0.062622f, 0.071106f,
+ 0.081299f, 0.091614f, 0.103455f, 0.116333f, 0.130493f, 0.146484f, 0.164307f, 0.183228f, 0.204224f, 0.226685f, 0.251221f, 0.277100f,
+ 0.303711f, 0.332764f, 0.361572f, 0.391846f, 0.422852f, 0.454102f, 0.485352f, 0.515625f, 0.545410f, 0.574707f, 0.603027f, 0.630371f,
+ 0.656250f, 0.681641f, 0.705078f, 0.726562f, 0.747070f, 0.767578f, 0.784668f, 0.803223f, 0.818848f, 0.833008f, 0.847656f, 0.860352f,
+ 0.872559f, 0.883301f, 0.894043f, 0.903809f, 0.913574f, 0.921387f, 0.967773f, 0.970215f, 0.970215f, 0.968750f, 0.969238f, 0.968750f,
+ 0.001053f, 0.002905f, 0.005432f, 0.007912f, 0.010658f, 0.012901f, 0.016464f, 0.019363f, 0.023376f, 0.027237f, 0.031799f, 0.036346f,
+ 0.042145f, 0.048248f, 0.054871f, 0.062256f, 0.070618f, 0.079834f, 0.089844f, 0.101440f, 0.113831f, 0.128174f, 0.143433f, 0.160156f,
+ 0.179077f, 0.199707f, 0.222046f, 0.245483f, 0.271240f, 0.297363f, 0.325684f, 0.355469f, 0.385254f, 0.416016f, 0.447754f, 0.479004f,
+ 0.508789f, 0.539551f, 0.570312f, 0.598145f, 0.626465f, 0.652344f, 0.678223f, 0.702148f, 0.725098f, 0.746094f, 0.765625f, 0.785645f,
+ 0.803223f, 0.819336f, 0.834961f, 0.848145f, 0.861328f, 0.873535f, 0.884766f, 0.895508f, 0.905762f, 0.915527f, 0.965332f, 0.967773f,
+ 0.968262f, 0.967773f, 0.967285f, 0.966309f, 0.001106f, 0.002684f, 0.004913f, 0.006733f, 0.009300f, 0.011955f, 0.014435f, 0.017700f,
+ 0.020477f, 0.024124f, 0.028091f, 0.032532f, 0.037231f, 0.042511f, 0.048309f, 0.054596f, 0.061798f, 0.069885f, 0.078857f, 0.089050f,
+ 0.099915f, 0.112183f, 0.125488f, 0.140503f, 0.157104f, 0.175293f, 0.195068f, 0.216309f, 0.240356f, 0.265381f, 0.291748f, 0.319580f,
+ 0.348633f, 0.379150f, 0.410156f, 0.441406f, 0.472900f, 0.503418f, 0.534668f, 0.565430f, 0.594727f, 0.622070f, 0.649902f, 0.676270f,
+ 0.700195f, 0.723633f, 0.746094f, 0.766602f, 0.786133f, 0.802734f, 0.819824f, 0.835449f, 0.849609f, 0.863281f, 0.875977f, 0.887695f,
+ 0.898438f, 0.908203f, 0.962891f, 0.965820f, 0.966309f, 0.965332f, 0.964844f, 0.964355f, 0.000782f, 0.002707f, 0.004574f, 0.006184f,
+ 0.008286f, 0.010681f, 0.012878f, 0.015640f, 0.018478f, 0.021912f, 0.025208f, 0.028976f, 0.032867f, 0.037598f, 0.042938f, 0.048370f,
+ 0.054443f, 0.061432f, 0.069214f, 0.077515f, 0.087402f, 0.098145f, 0.109497f, 0.122803f, 0.137329f, 0.153564f, 0.171509f, 0.190918f,
+ 0.212158f, 0.235352f, 0.259766f, 0.286133f, 0.314209f, 0.343262f, 0.373535f, 0.404297f, 0.436279f, 0.467773f, 0.499512f, 0.530273f,
+ 0.561523f, 0.590820f, 0.620117f, 0.647461f, 0.674316f, 0.699219f, 0.722656f, 0.745605f, 0.766602f, 0.785645f, 0.804688f, 0.821777f,
+ 0.836426f, 0.852051f, 0.865234f, 0.878418f, 0.890625f, 0.901855f, 0.959961f, 0.962891f, 0.963867f, 0.963379f, 0.962402f, 0.962402f,
+ 0.000787f, 0.002195f, 0.004250f, 0.005775f, 0.007774f, 0.009445f, 0.011795f, 0.013725f, 0.016678f, 0.019531f, 0.022018f, 0.025665f,
+ 0.029495f, 0.033142f, 0.037598f, 0.042664f, 0.048248f, 0.053772f, 0.060699f, 0.067993f, 0.076416f, 0.085815f, 0.095764f, 0.107422f,
+ 0.120239f, 0.134277f, 0.150269f, 0.167358f, 0.186646f, 0.207764f, 0.230347f, 0.255127f, 0.281250f, 0.308838f, 0.337891f, 0.368408f,
+ 0.399414f, 0.431396f, 0.463135f, 0.495605f, 0.526855f, 0.558594f, 0.588379f, 0.618652f, 0.646973f, 0.673828f, 0.699707f, 0.723633f,
+ 0.746094f, 0.767090f, 0.788086f, 0.806641f, 0.823730f, 0.840332f, 0.854980f, 0.869141f, 0.881836f, 0.893555f, 0.957520f, 0.960938f,
+ 0.960938f, 0.961426f, 0.960449f, 0.959961f, 0.000765f, 0.002207f, 0.003666f, 0.005177f, 0.006973f, 0.008301f, 0.010704f, 0.012794f,
+ 0.015015f, 0.017303f, 0.020309f, 0.022568f, 0.026123f, 0.029587f, 0.033325f, 0.037659f, 0.042206f, 0.047516f, 0.053223f, 0.059814f,
+ 0.067017f, 0.075195f, 0.083801f, 0.094055f, 0.105042f, 0.117737f, 0.131470f, 0.146851f, 0.163940f, 0.182739f, 0.203369f, 0.225952f,
+ 0.250244f, 0.276367f, 0.304199f, 0.333008f, 0.364258f, 0.395264f, 0.427002f, 0.459961f, 0.491699f, 0.524414f, 0.555664f, 0.586914f,
+ 0.617676f, 0.645996f, 0.673340f, 0.699707f, 0.724121f, 0.748047f, 0.770020f, 0.790039f, 0.809082f, 0.827148f, 0.842773f, 0.858398f,
+ 0.873047f, 0.885742f, 0.954102f, 0.958008f, 0.958496f, 0.958496f, 0.958496f, 0.957520f, 0.000586f, 0.001937f, 0.003107f, 0.004745f,
+ 0.006168f, 0.007610f, 0.009590f, 0.011345f, 0.013321f, 0.015587f, 0.017593f, 0.020294f, 0.023346f, 0.026154f, 0.029205f, 0.033234f,
+ 0.037415f, 0.041962f, 0.046906f, 0.052673f, 0.058533f, 0.065796f, 0.073669f, 0.082642f, 0.092346f, 0.103027f, 0.115234f, 0.128784f,
+ 0.143799f, 0.160889f, 0.179199f, 0.199585f, 0.221802f, 0.246094f, 0.271973f, 0.299805f, 0.329102f, 0.359863f, 0.391357f, 0.423340f,
+ 0.456299f, 0.490234f, 0.522949f, 0.555176f, 0.586426f, 0.617188f, 0.645996f, 0.675293f, 0.701660f, 0.726074f, 0.750488f, 0.773926f,
+ 0.793945f, 0.812988f, 0.831543f, 0.847656f, 0.862793f, 0.877441f, 0.951660f, 0.955078f, 0.955566f, 0.955566f, 0.955078f, 0.954590f,
+ 0.000678f, 0.001864f, 0.003138f, 0.004333f, 0.005707f, 0.006893f, 0.008224f, 0.009850f, 0.012215f, 0.013954f, 0.015747f, 0.018219f,
+ 0.020584f, 0.023148f, 0.026047f, 0.029434f, 0.033020f, 0.037018f, 0.041626f, 0.046509f, 0.051910f, 0.058105f, 0.064636f, 0.072510f,
+ 0.080750f, 0.090149f, 0.100891f, 0.112549f, 0.126343f, 0.141113f, 0.157593f, 0.175537f, 0.195801f, 0.218018f, 0.242554f, 0.268311f,
+ 0.295898f, 0.325195f, 0.355713f, 0.388184f, 0.421143f, 0.454834f, 0.488281f, 0.522949f, 0.554199f, 0.587402f, 0.618164f, 0.648438f,
+ 0.676758f, 0.704102f, 0.730957f, 0.754395f, 0.776855f, 0.798340f, 0.817871f, 0.836426f, 0.852051f, 0.868164f, 0.948242f, 0.952637f,
+ 0.953125f, 0.952637f, 0.952148f, 0.951660f, 0.000470f, 0.001578f, 0.002934f, 0.003838f, 0.005032f, 0.006310f, 0.007725f, 0.008972f,
+ 0.010826f, 0.012657f, 0.014359f, 0.015991f, 0.018402f, 0.020721f, 0.023102f, 0.026230f, 0.029495f, 0.032867f, 0.036743f, 0.040680f,
+ 0.045654f, 0.050812f, 0.056763f, 0.063477f, 0.071045f, 0.078918f, 0.088440f, 0.098938f, 0.110657f, 0.123535f, 0.138062f, 0.154175f,
+ 0.172363f, 0.192627f, 0.214478f, 0.238770f, 0.264404f, 0.292236f, 0.322266f, 0.353271f, 0.385742f, 0.419189f, 0.453857f, 0.487549f,
+ 0.521484f, 0.555664f, 0.588867f, 0.621094f, 0.651367f, 0.680176f, 0.708008f, 0.733887f, 0.759766f, 0.780762f, 0.802734f, 0.821289f,
+ 0.840820f, 0.858398f, 0.943848f, 0.949219f, 0.949707f, 0.949707f, 0.949707f, 0.949219f, 0.000485f, 0.001689f, 0.002386f, 0.003698f,
+ 0.004547f, 0.005936f, 0.006851f, 0.008217f, 0.009834f, 0.011055f, 0.012810f, 0.014473f, 0.016449f, 0.018509f, 0.020950f, 0.023209f,
+ 0.025940f, 0.029114f, 0.032410f, 0.036133f, 0.040161f, 0.044861f, 0.050018f, 0.055664f, 0.061859f, 0.069153f, 0.077515f, 0.086365f,
+ 0.096680f, 0.108093f, 0.120605f, 0.135132f, 0.151489f, 0.169556f, 0.189209f, 0.211426f, 0.235352f, 0.261475f, 0.289307f, 0.319580f,
+ 0.351074f, 0.384521f, 0.418701f, 0.452881f, 0.487549f, 0.522461f, 0.556641f, 0.591309f, 0.623535f, 0.653809f, 0.684570f, 0.712891f,
+ 0.739258f, 0.764160f, 0.787109f, 0.809570f, 0.829102f, 0.847168f, 0.940918f, 0.945801f, 0.946289f, 0.946777f, 0.946777f, 0.945312f,
+ 0.000620f, 0.001351f, 0.002413f, 0.003273f, 0.004307f, 0.004971f, 0.006138f, 0.007542f, 0.008835f, 0.009972f, 0.011581f, 0.013069f,
+ 0.014717f, 0.016495f, 0.018738f, 0.020691f, 0.023315f, 0.025879f, 0.028793f, 0.031860f, 0.035309f, 0.039246f, 0.043762f, 0.048950f,
+ 0.054474f, 0.060669f, 0.067932f, 0.075378f, 0.084351f, 0.094055f, 0.105774f, 0.118469f, 0.132690f, 0.148315f, 0.166504f, 0.186401f,
+ 0.208130f, 0.232544f, 0.258789f, 0.287109f, 0.317627f, 0.349854f, 0.383057f, 0.417725f, 0.453125f, 0.488770f, 0.523926f, 0.559082f,
+ 0.594238f, 0.627441f, 0.659180f, 0.689941f, 0.719238f, 0.745117f, 0.770508f, 0.794434f, 0.815430f, 0.836914f, 0.936523f, 0.941895f,
+ 0.942871f, 0.942871f, 0.942871f, 0.942383f, 0.000404f, 0.001095f, 0.002087f, 0.002983f, 0.003986f, 0.004673f, 0.005844f, 0.006878f,
+ 0.007740f, 0.008873f, 0.010323f, 0.011757f, 0.013176f, 0.014915f, 0.016586f, 0.018585f, 0.020523f, 0.022720f, 0.025391f, 0.028244f,
+ 0.031219f, 0.034821f, 0.038788f, 0.042908f, 0.047943f, 0.053040f, 0.058960f, 0.066162f, 0.073547f, 0.082397f, 0.092285f, 0.102844f,
+ 0.115234f, 0.129883f, 0.146118f, 0.163452f, 0.183350f, 0.205688f, 0.229614f, 0.256592f, 0.285156f, 0.316162f, 0.348633f, 0.383057f,
+ 0.418457f, 0.454590f, 0.490967f, 0.526855f, 0.563477f, 0.598633f, 0.632812f, 0.665527f, 0.696777f, 0.726074f, 0.752930f, 0.779297f,
+ 0.803223f, 0.825684f, 0.933105f, 0.938477f, 0.938477f, 0.938965f, 0.938477f, 0.938477f, 0.000415f, 0.000864f, 0.001907f, 0.002775f,
+ 0.003519f, 0.004204f, 0.005352f, 0.006237f, 0.007019f, 0.008064f, 0.009239f, 0.010483f, 0.011742f, 0.013130f, 0.014877f, 0.016571f,
+ 0.018494f, 0.020126f, 0.022537f, 0.024826f, 0.027649f, 0.030701f, 0.033875f, 0.037964f, 0.042114f, 0.046356f, 0.051605f, 0.057587f,
+ 0.064209f, 0.071777f, 0.080261f, 0.089722f, 0.100952f, 0.113220f, 0.127075f, 0.143066f, 0.160767f, 0.180664f, 0.202759f, 0.227417f,
+ 0.254395f, 0.284180f, 0.315674f, 0.348633f, 0.383789f, 0.420166f, 0.457275f, 0.494385f, 0.531250f, 0.569336f, 0.605469f, 0.639160f,
+ 0.672363f, 0.705078f, 0.735352f, 0.762207f, 0.788574f, 0.811523f, 0.928711f, 0.934082f, 0.934570f, 0.935059f, 0.935059f, 0.935059f,
+ 0.000236f, 0.001136f, 0.001664f, 0.002502f, 0.003187f, 0.004082f, 0.004631f, 0.005386f, 0.006275f, 0.007385f, 0.008217f, 0.009453f,
+ 0.010567f, 0.011787f, 0.013115f, 0.014420f, 0.016083f, 0.017944f, 0.019867f, 0.022079f, 0.024414f, 0.026962f, 0.029755f, 0.033112f,
+ 0.036926f, 0.040771f, 0.045258f, 0.050232f, 0.056183f, 0.062500f, 0.069946f, 0.078430f, 0.087708f, 0.098389f, 0.110779f, 0.124634f,
+ 0.140259f, 0.158203f, 0.178223f, 0.200928f, 0.225708f, 0.253174f, 0.282715f, 0.315430f, 0.349365f, 0.385254f, 0.422363f, 0.460938f,
+ 0.499023f, 0.537109f, 0.574707f, 0.612305f, 0.646484f, 0.682129f, 0.713867f, 0.745117f, 0.772461f, 0.799316f, 0.923828f, 0.930176f,
+ 0.930664f, 0.931152f, 0.930664f, 0.930664f, 0.000229f, 0.000964f, 0.001582f, 0.002182f, 0.002838f, 0.003653f, 0.004341f, 0.004921f,
+ 0.005615f, 0.006626f, 0.007423f, 0.008545f, 0.009483f, 0.010666f, 0.011612f, 0.013000f, 0.014275f, 0.015900f, 0.017487f, 0.019333f,
+ 0.021484f, 0.023773f, 0.026276f, 0.028992f, 0.032135f, 0.035492f, 0.039398f, 0.044037f, 0.049072f, 0.054443f, 0.061035f, 0.067871f,
+ 0.076111f, 0.085632f, 0.096252f, 0.108154f, 0.122253f, 0.138306f, 0.156006f, 0.175903f, 0.199219f, 0.224243f, 0.251953f, 0.282715f,
+ 0.315918f, 0.350830f, 0.387451f, 0.425781f, 0.465332f, 0.504395f, 0.544434f, 0.583008f, 0.620117f, 0.657715f, 0.692383f, 0.725098f,
+ 0.755371f, 0.783691f, 0.919434f, 0.925781f, 0.926270f, 0.926758f, 0.926758f, 0.925781f, 0.000410f, 0.000856f, 0.001542f, 0.001844f,
+ 0.002565f, 0.003380f, 0.003971f, 0.004246f, 0.005047f, 0.005863f, 0.006653f, 0.007744f, 0.008568f, 0.009407f, 0.010529f, 0.011482f,
+ 0.012657f, 0.013924f, 0.015602f, 0.017105f, 0.018997f, 0.020859f, 0.022980f, 0.025192f, 0.028030f, 0.031036f, 0.034515f, 0.038300f,
+ 0.042236f, 0.047180f, 0.052795f, 0.059113f, 0.065857f, 0.074097f, 0.083374f, 0.094360f, 0.105896f, 0.119873f, 0.135620f, 0.154175f,
+ 0.174072f, 0.197632f, 0.223267f, 0.251465f, 0.283447f, 0.317139f, 0.353760f, 0.391113f, 0.431152f, 0.470703f, 0.512207f, 0.552734f,
+ 0.592285f, 0.631348f, 0.669434f, 0.704590f, 0.737793f, 0.768555f, 0.913574f, 0.919922f, 0.920898f, 0.920898f, 0.921387f, 0.921387f,
+ 0.000214f, 0.000619f, 0.001172f, 0.001941f, 0.002228f, 0.002960f, 0.003490f, 0.003994f, 0.004761f, 0.005180f, 0.005806f, 0.006622f,
+ 0.007565f, 0.008301f, 0.009262f, 0.010170f, 0.011208f, 0.012482f, 0.013855f, 0.015060f, 0.016739f, 0.018311f, 0.020248f, 0.022034f,
+ 0.024597f, 0.027084f, 0.030045f, 0.033051f, 0.036743f, 0.041016f, 0.045807f, 0.050964f, 0.056946f, 0.063904f, 0.071899f, 0.080994f,
+ 0.091675f, 0.103699f, 0.117920f, 0.133667f, 0.151978f, 0.172729f, 0.196533f, 0.222534f, 0.252197f, 0.284424f, 0.319580f, 0.356689f,
+ 0.396973f, 0.437500f, 0.479492f, 0.521484f, 0.562500f, 0.604004f, 0.644043f, 0.682129f, 0.718262f, 0.751465f, 0.907715f, 0.915039f,
+ 0.916016f, 0.916504f, 0.916504f, 0.916504f, 0.000405f, 0.000760f, 0.001116f, 0.001688f, 0.002180f, 0.002670f, 0.003313f, 0.003569f,
+ 0.003979f, 0.004543f, 0.005466f, 0.005985f, 0.006699f, 0.007359f, 0.008102f, 0.009094f, 0.009949f, 0.011055f, 0.012047f, 0.013412f,
+ 0.014488f, 0.016068f, 0.017532f, 0.019348f, 0.021210f, 0.023834f, 0.025986f, 0.028854f, 0.031891f, 0.035339f, 0.039490f, 0.043976f,
+ 0.049347f, 0.055084f, 0.061951f, 0.069763f, 0.078918f, 0.089478f, 0.101379f, 0.115479f, 0.131592f, 0.150024f, 0.171387f, 0.195068f,
+ 0.222900f, 0.252686f, 0.286621f, 0.323242f, 0.362061f, 0.402588f, 0.445312f, 0.488770f, 0.532715f, 0.575684f, 0.618652f, 0.659180f,
+ 0.698242f, 0.734375f, 0.901367f, 0.909180f, 0.911133f, 0.910645f, 0.911133f, 0.910645f, 0.000218f, 0.000539f, 0.001187f, 0.001617f,
+ 0.001987f, 0.002316f, 0.002666f, 0.003176f, 0.003841f, 0.004425f, 0.004917f, 0.005402f, 0.005768f, 0.006462f, 0.007233f, 0.008018f,
+ 0.008575f, 0.009758f, 0.010582f, 0.011520f, 0.012756f, 0.013832f, 0.015312f, 0.016968f, 0.018509f, 0.020279f, 0.022644f, 0.024857f,
+ 0.027740f, 0.030472f, 0.033783f, 0.037567f, 0.042175f, 0.047150f, 0.052979f, 0.059601f, 0.067505f, 0.076538f, 0.087158f, 0.099243f,
+ 0.113281f, 0.129272f, 0.148315f, 0.170532f, 0.194702f, 0.223267f, 0.254639f, 0.289795f, 0.327393f, 0.368408f, 0.410889f, 0.455322f,
+ 0.499756f, 0.544434f, 0.590332f, 0.633789f, 0.676270f, 0.716309f, 0.895508f, 0.902344f, 0.903809f, 0.905762f, 0.903809f, 0.904297f,
+ 0.000184f, 0.000612f, 0.001122f, 0.001464f, 0.001848f, 0.002150f, 0.002514f, 0.002651f, 0.003391f, 0.003666f, 0.004368f, 0.004677f,
+ 0.005219f, 0.005882f, 0.006531f, 0.007019f, 0.007675f, 0.008530f, 0.009224f, 0.010269f, 0.011017f, 0.012146f, 0.013321f, 0.014626f,
+ 0.016098f, 0.017639f, 0.019440f, 0.021317f, 0.023773f, 0.026123f, 0.029144f, 0.032410f, 0.036072f, 0.040314f, 0.045013f, 0.051086f,
+ 0.057587f, 0.065308f, 0.074402f, 0.084961f, 0.097107f, 0.111267f, 0.127930f, 0.147217f, 0.169556f, 0.195312f, 0.224365f, 0.257568f,
+ 0.294189f, 0.333496f, 0.375977f, 0.420166f, 0.467041f, 0.514160f, 0.561035f, 0.607422f, 0.652344f, 0.695312f, 0.888672f, 0.896484f,
+ 0.897461f, 0.897461f, 0.897949f, 0.897949f, 0.000159f, 0.000537f, 0.000830f, 0.001206f, 0.001578f, 0.001760f, 0.002050f, 0.002504f,
+ 0.002951f, 0.003397f, 0.003674f, 0.004238f, 0.004520f, 0.005245f, 0.005692f, 0.006138f, 0.006748f, 0.007240f, 0.008087f, 0.008728f,
+ 0.009636f, 0.010437f, 0.011543f, 0.012611f, 0.013763f, 0.015266f, 0.016617f, 0.018433f, 0.020248f, 0.022354f, 0.024887f, 0.027390f,
+ 0.030716f, 0.034454f, 0.038422f, 0.043365f, 0.048950f, 0.055511f, 0.062988f, 0.072021f, 0.082336f, 0.094727f, 0.109375f, 0.125977f,
+ 0.145874f, 0.169556f, 0.195679f, 0.226929f, 0.260986f, 0.299805f, 0.341309f, 0.385498f, 0.432129f, 0.480957f, 0.529297f, 0.579102f,
+ 0.627441f, 0.673828f, 0.881348f, 0.889160f, 0.890625f, 0.891113f, 0.891602f, 0.891113f, 0.000204f, 0.000566f, 0.000741f, 0.001033f,
+ 0.001378f, 0.001599f, 0.001961f, 0.002354f, 0.002609f, 0.002974f, 0.003300f, 0.003609f, 0.004101f, 0.004463f, 0.004906f, 0.005337f,
+ 0.006020f, 0.006290f, 0.007023f, 0.007656f, 0.008301f, 0.009140f, 0.009918f, 0.010933f, 0.011940f, 0.013107f, 0.014252f, 0.015656f,
+ 0.017136f, 0.019058f, 0.021057f, 0.023209f, 0.025940f, 0.029190f, 0.032715f, 0.036591f, 0.041138f, 0.046661f, 0.053253f, 0.060944f,
+ 0.069702f, 0.080444f, 0.092651f, 0.107788f, 0.124695f, 0.145630f, 0.169189f, 0.197632f, 0.229736f, 0.266113f, 0.306396f, 0.350586f,
+ 0.397217f, 0.447021f, 0.497803f, 0.549805f, 0.600586f, 0.650391f, 0.872559f, 0.881836f, 0.882812f, 0.883301f, 0.884277f, 0.884277f,
+ 0.000240f, 0.000349f, 0.000795f, 0.000892f, 0.001151f, 0.001377f, 0.001773f, 0.001984f, 0.002415f, 0.002602f, 0.002932f, 0.003168f,
+ 0.003483f, 0.003906f, 0.004257f, 0.004681f, 0.005173f, 0.005596f, 0.006119f, 0.006550f, 0.007126f, 0.007759f, 0.008522f, 0.009270f,
+ 0.010086f, 0.011108f, 0.012138f, 0.013199f, 0.014549f, 0.015884f, 0.017776f, 0.019623f, 0.022003f, 0.024384f, 0.027237f, 0.030624f,
+ 0.034515f, 0.039215f, 0.044342f, 0.050873f, 0.058411f, 0.067017f, 0.078003f, 0.090332f, 0.105530f, 0.123718f, 0.144775f, 0.170410f,
+ 0.200195f, 0.234131f, 0.272461f, 0.315674f, 0.362305f, 0.412354f, 0.465332f, 0.518555f, 0.572754f, 0.626465f, 0.863770f, 0.873047f,
+ 0.875488f, 0.875488f, 0.875977f, 0.875977f, 0.000102f, 0.000298f, 0.000604f, 0.000950f, 0.001089f, 0.001472f, 0.001760f, 0.001823f,
+ 0.001903f, 0.002325f, 0.002611f, 0.002775f, 0.003185f, 0.003405f, 0.003674f, 0.004005f, 0.004406f, 0.004814f, 0.005203f, 0.005665f,
+ 0.006062f, 0.006702f, 0.007317f, 0.007881f, 0.008560f, 0.009239f, 0.010193f, 0.010994f, 0.012161f, 0.013588f, 0.015068f, 0.016479f,
+ 0.018250f, 0.020386f, 0.022781f, 0.025665f, 0.028809f, 0.032501f, 0.037048f, 0.042297f, 0.048553f, 0.055908f, 0.065491f, 0.075378f,
+ 0.088501f, 0.104248f, 0.122742f, 0.145874f, 0.171997f, 0.203247f, 0.239990f, 0.281250f, 0.326904f, 0.376953f, 0.430176f, 0.486328f,
+ 0.542480f, 0.600586f, 0.855469f, 0.864746f, 0.866211f, 0.867188f, 0.867188f, 0.867188f, 0.000000f, 0.000357f, 0.000576f, 0.000692f,
+ 0.001013f, 0.001069f, 0.001383f, 0.001702f, 0.001789f, 0.002102f, 0.002182f, 0.002377f, 0.002686f, 0.002985f, 0.003347f, 0.003359f,
+ 0.003782f, 0.004036f, 0.004436f, 0.004749f, 0.005169f, 0.005672f, 0.006145f, 0.006649f, 0.007187f, 0.007828f, 0.008644f, 0.009529f,
+ 0.010269f, 0.011200f, 0.012337f, 0.013596f, 0.015038f, 0.017044f, 0.018784f, 0.021011f, 0.023727f, 0.026871f, 0.030457f, 0.034637f,
+ 0.039978f, 0.046478f, 0.053436f, 0.062622f, 0.073730f, 0.086792f, 0.102661f, 0.122437f, 0.146240f, 0.174561f, 0.208252f, 0.247437f,
+ 0.291748f, 0.341064f, 0.395020f, 0.451904f, 0.511230f, 0.571777f, 0.844238f, 0.854980f, 0.857422f, 0.858887f, 0.857910f, 0.857910f,
+ 0.000101f, 0.000326f, 0.000535f, 0.000683f, 0.000848f, 0.001161f, 0.001184f, 0.001284f, 0.001576f, 0.001701f, 0.001839f, 0.002167f,
+ 0.002321f, 0.002584f, 0.002645f, 0.002941f, 0.003141f, 0.003538f, 0.003817f, 0.004112f, 0.004395f, 0.004646f, 0.005165f, 0.005531f,
+ 0.006096f, 0.006496f, 0.007217f, 0.007767f, 0.008629f, 0.009163f, 0.010239f, 0.011276f, 0.012611f, 0.013779f, 0.015213f, 0.017120f,
+ 0.019379f, 0.021606f, 0.024994f, 0.028351f, 0.032379f, 0.037201f, 0.043640f, 0.050903f, 0.060120f, 0.071045f, 0.084900f, 0.101868f,
+ 0.122559f, 0.147827f, 0.178223f, 0.214722f, 0.257080f, 0.305664f, 0.358887f, 0.416992f, 0.478027f, 0.542969f, 0.834473f, 0.845215f,
+ 0.847656f, 0.847656f, 0.847656f, 0.848633f, 0.000092f, 0.000316f, 0.000410f, 0.000556f, 0.000808f, 0.000918f, 0.001094f, 0.001287f,
+ 0.001309f, 0.001411f, 0.001671f, 0.001780f, 0.001909f, 0.002092f, 0.002274f, 0.002523f, 0.002733f, 0.002974f, 0.003101f, 0.003401f,
+ 0.003677f, 0.003956f, 0.004311f, 0.004551f, 0.004940f, 0.005444f, 0.005768f, 0.006451f, 0.006977f, 0.007568f, 0.008270f, 0.009201f,
+ 0.010170f, 0.011230f, 0.012566f, 0.013939f, 0.015503f, 0.017761f, 0.020111f, 0.022873f, 0.025940f, 0.029938f, 0.035217f, 0.040985f,
+ 0.048431f, 0.057770f, 0.069092f, 0.083618f, 0.100891f, 0.123047f, 0.150146f, 0.183838f, 0.223633f, 0.269531f, 0.322510f, 0.381348f,
+ 0.444824f, 0.511719f, 0.823730f, 0.834473f, 0.835938f, 0.836914f, 0.836914f, 0.837402f, 0.000240f, 0.000273f, 0.000326f, 0.000564f,
+ 0.000682f, 0.000807f, 0.000854f, 0.000949f, 0.001139f, 0.001238f, 0.001404f, 0.001548f, 0.001637f, 0.001840f, 0.001893f, 0.002077f,
+ 0.002321f, 0.002434f, 0.002642f, 0.002821f, 0.003044f, 0.003271f, 0.003649f, 0.003763f, 0.004208f, 0.004448f, 0.004986f, 0.005169f,
+ 0.005657f, 0.006279f, 0.006680f, 0.007442f, 0.008194f, 0.008881f, 0.009895f, 0.010918f, 0.012138f, 0.013924f, 0.015915f, 0.018112f,
+ 0.020645f, 0.023743f, 0.027817f, 0.032745f, 0.038361f, 0.045990f, 0.055481f, 0.066895f, 0.082031f, 0.100769f, 0.124573f, 0.154541f,
+ 0.190796f, 0.235107f, 0.286133f, 0.344238f, 0.408936f, 0.478271f, 0.810547f, 0.822266f, 0.824707f, 0.825195f, 0.825684f, 0.825684f,
+ 0.000115f, 0.000222f, 0.000252f, 0.000524f, 0.000574f, 0.000673f, 0.000869f, 0.000928f, 0.000963f, 0.001022f, 0.001246f, 0.001292f,
+ 0.001404f, 0.001477f, 0.001652f, 0.001811f, 0.001822f, 0.002058f, 0.002237f, 0.002371f, 0.002588f, 0.002645f, 0.003019f, 0.003080f,
+ 0.003506f, 0.003689f, 0.003904f, 0.004383f, 0.004707f, 0.005020f, 0.005386f, 0.006023f, 0.006451f, 0.007038f, 0.007809f, 0.008911f,
+ 0.009949f, 0.011200f, 0.012222f, 0.014137f, 0.016068f, 0.018692f, 0.021683f, 0.025314f, 0.029861f, 0.035889f, 0.043335f, 0.052582f,
+ 0.065186f, 0.080627f, 0.101501f, 0.127441f, 0.159912f, 0.200806f, 0.250000f, 0.307129f, 0.371582f, 0.444580f, 0.798340f, 0.809570f,
+ 0.811523f, 0.812988f, 0.812988f, 0.812988f, 0.000000f, 0.000211f, 0.000204f, 0.000474f, 0.000555f, 0.000583f, 0.000600f, 0.000593f,
+ 0.000812f, 0.000865f, 0.000941f, 0.001013f, 0.001162f, 0.001348f, 0.001418f, 0.001465f, 0.001616f, 0.001722f, 0.001856f, 0.001888f,
+ 0.002048f, 0.002321f, 0.002396f, 0.002632f, 0.002821f, 0.002974f, 0.003265f, 0.003477f, 0.003632f, 0.004051f, 0.004299f, 0.004700f,
+ 0.005238f, 0.005592f, 0.006199f, 0.006756f, 0.007614f, 0.008324f, 0.009727f, 0.010811f, 0.012337f, 0.014168f, 0.016434f, 0.019257f,
+ 0.022858f, 0.027451f, 0.033295f, 0.040619f, 0.050690f, 0.063416f, 0.080261f, 0.102295f, 0.131104f, 0.168335f, 0.214355f, 0.270508f,
+ 0.334717f, 0.408936f, 0.783691f, 0.795898f, 0.798340f, 0.799316f, 0.800293f, 0.800293f, 0.000174f, 0.000090f, 0.000281f, 0.000397f,
+ 0.000401f, 0.000450f, 0.000488f, 0.000640f, 0.000674f, 0.000713f, 0.000753f, 0.000845f, 0.000872f, 0.001020f, 0.001115f, 0.001264f,
+ 0.001327f, 0.001373f, 0.001520f, 0.001616f, 0.001767f, 0.001875f, 0.001968f, 0.002090f, 0.002232f, 0.002333f, 0.002472f, 0.002802f,
+ 0.002926f, 0.003189f, 0.003569f, 0.003752f, 0.004009f, 0.004513f, 0.004860f, 0.005375f, 0.005997f, 0.006561f, 0.007378f, 0.008347f,
+ 0.009384f, 0.010612f, 0.012466f, 0.014526f, 0.017075f, 0.020447f, 0.024887f, 0.030533f, 0.038300f, 0.048584f, 0.062042f, 0.080383f,
+ 0.104736f, 0.137329f, 0.180176f, 0.232544f, 0.296875f, 0.371338f, 0.769043f, 0.781250f, 0.784180f, 0.784668f, 0.786133f, 0.786133f,
+ 0.000025f, 0.000135f, 0.000154f, 0.000260f, 0.000353f, 0.000364f, 0.000380f, 0.000520f, 0.000548f, 0.000587f, 0.000712f, 0.000735f,
+ 0.000772f, 0.000822f, 0.000886f, 0.001004f, 0.000946f, 0.001115f, 0.001177f, 0.001266f, 0.001454f, 0.001527f, 0.001575f, 0.001680f,
+ 0.001883f, 0.001961f, 0.002043f, 0.002193f, 0.002281f, 0.002520f, 0.002712f, 0.003021f, 0.003147f, 0.003561f, 0.003786f, 0.004116f,
+ 0.004570f, 0.005058f, 0.005634f, 0.006165f, 0.007095f, 0.008049f, 0.009201f, 0.010674f, 0.012550f, 0.014854f, 0.018051f, 0.022385f,
+ 0.027908f, 0.035522f, 0.046295f, 0.061035f, 0.081238f, 0.109131f, 0.146729f, 0.197021f, 0.258301f, 0.333008f, 0.752441f, 0.766113f,
+ 0.768555f, 0.769531f, 0.770020f, 0.769531f, 0.000000f, 0.000121f, 0.000209f, 0.000291f, 0.000337f, 0.000307f, 0.000324f, 0.000415f,
+ 0.000426f, 0.000453f, 0.000491f, 0.000573f, 0.000644f, 0.000650f, 0.000781f, 0.000746f, 0.000830f, 0.000803f, 0.000997f, 0.001017f,
+ 0.001020f, 0.001158f, 0.001241f, 0.001317f, 0.001375f, 0.001432f, 0.001524f, 0.001656f, 0.001858f, 0.001955f, 0.002050f, 0.002274f,
+ 0.002460f, 0.002724f, 0.002831f, 0.003050f, 0.003441f, 0.003790f, 0.004162f, 0.004623f, 0.005219f, 0.005951f, 0.006721f, 0.007729f,
+ 0.008926f, 0.010620f, 0.013000f, 0.015686f, 0.019852f, 0.025436f, 0.033295f, 0.044617f, 0.060608f, 0.083313f, 0.116211f, 0.161499f,
+ 0.220093f, 0.293945f, 0.734863f, 0.749512f, 0.752441f, 0.752930f, 0.753906f, 0.753906f, 0.000000f, 0.000121f, 0.000118f, 0.000246f,
+ 0.000233f, 0.000252f, 0.000338f, 0.000282f, 0.000353f, 0.000355f, 0.000448f, 0.000435f, 0.000464f, 0.000530f, 0.000578f, 0.000649f,
+ 0.000677f, 0.000710f, 0.000749f, 0.000792f, 0.000881f, 0.000903f, 0.000967f, 0.001049f, 0.001041f, 0.001100f, 0.001176f, 0.001254f,
+ 0.001402f, 0.001451f, 0.001697f, 0.001674f, 0.001804f, 0.001914f, 0.002195f, 0.002451f, 0.002474f, 0.002758f, 0.003029f, 0.003483f,
+ 0.003824f, 0.004272f, 0.004833f, 0.005573f, 0.006477f, 0.007629f, 0.009041f, 0.010918f, 0.013573f, 0.017319f, 0.022842f, 0.031036f,
+ 0.043030f, 0.061096f, 0.088440f, 0.127563f, 0.182861f, 0.254395f, 0.717285f, 0.731934f, 0.734863f, 0.735352f, 0.735840f, 0.736328f,
+ 0.000000f, 0.000000f, 0.000117f, 0.000163f, 0.000109f, 0.000208f, 0.000212f, 0.000208f, 0.000270f, 0.000356f, 0.000324f, 0.000377f,
+ 0.000391f, 0.000420f, 0.000449f, 0.000440f, 0.000484f, 0.000504f, 0.000534f, 0.000561f, 0.000639f, 0.000667f, 0.000715f, 0.000722f,
+ 0.000799f, 0.000845f, 0.000939f, 0.000945f, 0.001053f, 0.001149f, 0.001252f, 0.001310f, 0.001392f, 0.001507f, 0.001526f, 0.001710f,
+ 0.001773f, 0.002111f, 0.002300f, 0.002443f, 0.002661f, 0.002996f, 0.003376f, 0.003880f, 0.004482f, 0.005150f, 0.006115f, 0.007401f,
+ 0.009132f, 0.011696f, 0.015076f, 0.020416f, 0.029236f, 0.042389f, 0.063782f, 0.096802f, 0.146362f, 0.215576f, 0.698242f, 0.712891f,
+ 0.715332f, 0.716797f, 0.717285f, 0.717285f, 0.000000f, 0.000118f, 0.000115f, 0.000133f, 0.000144f, 0.000147f, 0.000162f, 0.000150f,
+ 0.000194f, 0.000215f, 0.000228f, 0.000299f, 0.000271f, 0.000313f, 0.000328f, 0.000358f, 0.000378f, 0.000360f, 0.000407f, 0.000438f,
+ 0.000441f, 0.000488f, 0.000515f, 0.000544f, 0.000576f, 0.000617f, 0.000659f, 0.000715f, 0.000741f, 0.000773f, 0.000850f, 0.000921f,
+ 0.000979f, 0.001066f, 0.001128f, 0.001292f, 0.001279f, 0.001400f, 0.001572f, 0.001668f, 0.001869f, 0.002029f, 0.002295f, 0.002607f,
+ 0.002985f, 0.003464f, 0.004066f, 0.004913f, 0.006023f, 0.007519f, 0.009827f, 0.013016f, 0.018524f, 0.027481f, 0.042847f, 0.068970f,
+ 0.111938f, 0.176392f, 0.675781f, 0.692871f, 0.695801f, 0.696777f, 0.698242f, 0.697754f, 0.000000f, 0.000000f, 0.000111f, 0.000108f,
+ 0.000104f, 0.000102f, 0.000118f, 0.000120f, 0.000134f, 0.000128f, 0.000188f, 0.000154f, 0.000197f, 0.000188f, 0.000245f, 0.000256f,
+ 0.000233f, 0.000266f, 0.000345f, 0.000281f, 0.000355f, 0.000322f, 0.000392f, 0.000358f, 0.000437f, 0.000425f, 0.000458f, 0.000477f,
+ 0.000564f, 0.000636f, 0.000578f, 0.000607f, 0.000668f, 0.000719f, 0.000769f, 0.000832f, 0.000880f, 0.000953f, 0.001060f, 0.001116f,
+ 0.001226f, 0.001363f, 0.001486f, 0.001760f, 0.001944f, 0.002216f, 0.002605f, 0.003107f, 0.003778f, 0.004715f, 0.005989f, 0.007942f,
+ 0.011292f, 0.016632f, 0.026550f, 0.045532f, 0.079956f, 0.138550f, 0.655762f, 0.671875f, 0.674805f, 0.675293f, 0.675781f, 0.678223f,
+ 0.000000f, 0.000112f, 0.000105f, 0.000102f, 0.000098f, 0.000095f, 0.000093f, 0.000088f, 0.000089f, 0.000085f, 0.000095f, 0.000126f,
+ 0.000109f, 0.000154f, 0.000153f, 0.000162f, 0.000176f, 0.000190f, 0.000202f, 0.000204f, 0.000212f, 0.000214f, 0.000266f, 0.000239f,
+ 0.000279f, 0.000293f, 0.000329f, 0.000329f, 0.000339f, 0.000365f, 0.000437f, 0.000424f, 0.000429f, 0.000474f, 0.000525f, 0.000596f,
+ 0.000572f, 0.000612f, 0.000666f, 0.000723f, 0.000791f, 0.000850f, 0.000977f, 0.001066f, 0.001225f, 0.001351f, 0.001555f, 0.001837f,
+ 0.002279f, 0.002760f, 0.003445f, 0.004612f, 0.006386f, 0.009438f, 0.015221f, 0.027008f, 0.052551f, 0.102966f, 0.633789f, 0.649414f,
+ 0.652832f, 0.653809f, 0.655273f, 0.655273f, 0.000000f, 0.000105f, 0.000099f, 0.000094f, 0.000090f, 0.000087f, 0.000084f, 0.000082f,
+ 0.000079f, 0.000075f, 0.000071f, 0.000068f, 0.000064f, 0.000072f, 0.000096f, 0.000105f, 0.000112f, 0.000088f, 0.000123f, 0.000129f,
+ 0.000132f, 0.000140f, 0.000147f, 0.000170f, 0.000188f, 0.000192f, 0.000171f, 0.000210f, 0.000217f, 0.000223f, 0.000237f, 0.000251f,
+ 0.000258f, 0.000294f, 0.000298f, 0.000316f, 0.000350f, 0.000382f, 0.000400f, 0.000437f, 0.000479f, 0.000514f, 0.000576f, 0.000620f,
+ 0.000688f, 0.000782f, 0.000916f, 0.001026f, 0.001219f, 0.001502f, 0.001892f, 0.002424f, 0.003359f, 0.004974f, 0.008118f, 0.014343f,
+ 0.030075f, 0.070068f, 0.610352f, 0.626953f, 0.629883f, 0.631348f, 0.632324f, 0.632324f, 0.000110f, 0.000094f, 0.000087f, 0.000081f,
+ 0.000077f, 0.000075f, 0.000072f, 0.000069f, 0.000067f, 0.000066f, 0.000064f, 0.000062f, 0.000058f, 0.000056f, 0.000053f, 0.000051f,
+ 0.000054f, 0.000047f, 0.000057f, 0.000055f, 0.000075f, 0.000078f, 0.000086f, 0.000093f, 0.000093f, 0.000102f, 0.000112f, 0.000113f,
+ 0.000130f, 0.000128f, 0.000142f, 0.000145f, 0.000156f, 0.000153f, 0.000180f, 0.000178f, 0.000183f, 0.000223f, 0.000230f, 0.000240f,
+ 0.000265f, 0.000276f, 0.000300f, 0.000332f, 0.000357f, 0.000411f, 0.000449f, 0.000540f, 0.000615f, 0.000741f, 0.000916f, 0.001144f,
+ 0.001566f, 0.002310f, 0.003731f, 0.006905f, 0.014793f, 0.041779f, 0.585938f, 0.603027f, 0.605957f, 0.608398f, 0.608398f, 0.609375f,
+ 0.000090f, 0.000071f, 0.000066f, 0.000062f, 0.000058f, 0.000056f, 0.000053f, 0.000053f, 0.000051f, 0.000051f, 0.000049f, 0.000048f,
+ 0.000048f, 0.000047f, 0.000045f, 0.000043f, 0.000042f, 0.000040f, 0.000038f, 0.000036f, 0.000036f, 0.000033f, 0.000034f, 0.000040f,
+ 0.000040f, 0.000040f, 0.000048f, 0.000053f, 0.000060f, 0.000064f, 0.000067f, 0.000070f, 0.000075f, 0.000081f, 0.000085f, 0.000090f,
+ 0.000091f, 0.000103f, 0.000106f, 0.000120f, 0.000134f, 0.000138f, 0.000142f, 0.000156f, 0.000174f, 0.000180f, 0.000212f, 0.000239f,
+ 0.000253f, 0.000310f, 0.000377f, 0.000479f, 0.000627f, 0.000875f, 0.001396f, 0.002623f, 0.006184f, 0.019897f, 0.560547f, 0.578125f,
+ 0.581543f, 0.583008f, 0.583984f, 0.583984f, 0.000038f, 0.000035f, 0.000031f, 0.000031f, 0.000030f, 0.000031f, 0.000031f, 0.000030f,
+ 0.000030f, 0.000028f, 0.000029f, 0.000030f, 0.000029f, 0.000028f, 0.000029f, 0.000029f, 0.000029f, 0.000029f, 0.000029f, 0.000028f,
+ 0.000027f, 0.000026f, 0.000025f, 0.000024f, 0.000023f, 0.000022f, 0.000021f, 0.000020f, 0.000019f, 0.000021f, 0.000019f, 0.000022f,
+ 0.000023f, 0.000027f, 0.000031f, 0.000035f, 0.000037f, 0.000039f, 0.000039f, 0.000043f, 0.000049f, 0.000052f, 0.000056f, 0.000050f,
+ 0.000068f, 0.000062f, 0.000070f, 0.000087f, 0.000094f, 0.000107f, 0.000122f, 0.000140f, 0.000191f, 0.000247f, 0.000388f, 0.000710f,
+ 0.001781f, 0.007076f, 0.535156f, 0.553223f, 0.556152f, 0.558105f, 0.559082f, 0.559082f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000003f, 0.000003f, 0.000005f, 0.000006f, 0.000007f, 0.000007f, 0.000009f,
+ 0.000009f, 0.000009f, 0.000010f, 0.000010f, 0.000011f, 0.000011f, 0.000012f, 0.000012f, 0.000012f, 0.000013f, 0.000013f, 0.000013f,
+ 0.000013f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000009f, 0.000008f, 0.000009f,
+ 0.000009f, 0.000010f, 0.000011f, 0.000015f, 0.000017f, 0.000016f, 0.000018f, 0.000021f, 0.000020f, 0.000024f, 0.000024f, 0.000032f,
+ 0.000035f, 0.000045f, 0.000065f, 0.000105f, 0.000246f, 0.001313f, 0.508789f, 0.527344f, 0.530762f, 0.531738f, 0.532715f, 0.533691f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000005f, 0.000018f, 0.481934f, 0.500977f,
+ 0.504883f, 0.505859f, 0.507324f, 0.507812f,
+ },
+ {
+ 0.053833f, 0.152832f, 0.239014f, 0.313477f, 0.377686f, 0.433838f, 0.481689f, 0.524414f, 0.562988f, 0.596680f, 0.626953f, 0.654785f,
+ 0.678711f, 0.700684f, 0.720703f, 0.739746f, 0.755859f, 0.771973f, 0.787109f, 0.798828f, 0.812012f, 0.823730f, 0.833984f, 0.844238f,
+ 0.853027f, 0.862793f, 0.870605f, 0.878418f, 0.885254f, 0.892090f, 0.898926f, 0.904297f, 0.910645f, 0.916504f, 0.921875f, 0.926270f,
+ 0.931641f, 0.936035f, 0.939941f, 0.944336f, 0.948242f, 0.952148f, 0.955566f, 0.959961f, 0.962402f, 0.966309f, 0.969238f, 0.972168f,
+ 0.975098f, 0.978027f, 0.980957f, 0.983398f, 0.985840f, 0.988281f, 0.990723f, 0.992676f, 0.995117f, 0.996582f, 0.998047f, 0.995117f,
+ 0.993164f, 0.990723f, 0.988770f, 0.986816f, 0.036804f, 0.109497f, 0.178589f, 0.244751f, 0.305908f, 0.361084f, 0.411621f, 0.457275f,
+ 0.498535f, 0.536133f, 0.569824f, 0.601562f, 0.629883f, 0.655273f, 0.679688f, 0.700195f, 0.720215f, 0.737793f, 0.755859f, 0.770508f,
+ 0.785645f, 0.798340f, 0.811035f, 0.822754f, 0.833008f, 0.843750f, 0.852539f, 0.861328f, 0.869629f, 0.877441f, 0.885742f, 0.892578f,
+ 0.898926f, 0.905273f, 0.911133f, 0.916504f, 0.921875f, 0.926758f, 0.931641f, 0.936523f, 0.940430f, 0.945312f, 0.949219f, 0.953613f,
+ 0.956543f, 0.960449f, 0.963867f, 0.967285f, 0.970703f, 0.973633f, 0.976562f, 0.979004f, 0.981934f, 0.984375f, 0.986816f, 0.989746f,
+ 0.992188f, 0.994141f, 0.996582f, 0.994141f, 0.992188f, 0.990234f, 0.988281f, 0.986328f, 0.025787f, 0.080383f, 0.136230f, 0.191650f,
+ 0.245239f, 0.297119f, 0.345947f, 0.392822f, 0.436035f, 0.476807f, 0.513184f, 0.547363f, 0.578125f, 0.607910f, 0.634766f, 0.658203f,
+ 0.681152f, 0.702637f, 0.721191f, 0.738770f, 0.755371f, 0.770508f, 0.784668f, 0.798828f, 0.810547f, 0.821777f, 0.833984f, 0.843262f,
+ 0.852539f, 0.861816f, 0.869629f, 0.877930f, 0.885254f, 0.893555f, 0.898926f, 0.906250f, 0.911621f, 0.917969f, 0.923340f, 0.928223f,
+ 0.933105f, 0.937500f, 0.941406f, 0.946289f, 0.950195f, 0.954102f, 0.958496f, 0.961914f, 0.965820f, 0.968750f, 0.971680f, 0.975098f,
+ 0.978027f, 0.980469f, 0.983887f, 0.985840f, 0.988770f, 0.991211f, 0.995117f, 0.993164f, 0.991211f, 0.989258f, 0.987305f, 0.985352f,
+ 0.019455f, 0.060944f, 0.104553f, 0.150513f, 0.196411f, 0.243164f, 0.289062f, 0.333740f, 0.376709f, 0.417725f, 0.454346f, 0.491211f,
+ 0.524414f, 0.556641f, 0.585938f, 0.613770f, 0.639160f, 0.662598f, 0.682617f, 0.703613f, 0.723633f, 0.740723f, 0.756836f, 0.771973f,
+ 0.787109f, 0.798828f, 0.812012f, 0.823242f, 0.833984f, 0.844238f, 0.853516f, 0.863281f, 0.871094f, 0.879395f, 0.886719f, 0.893555f,
+ 0.899902f, 0.907227f, 0.913086f, 0.918945f, 0.924805f, 0.928711f, 0.934082f, 0.938965f, 0.943848f, 0.947754f, 0.952637f, 0.955566f,
+ 0.959961f, 0.963867f, 0.966797f, 0.970215f, 0.973633f, 0.977051f, 0.979004f, 0.982422f, 0.985840f, 0.987793f, 0.993652f, 0.991699f,
+ 0.989746f, 0.988281f, 0.986328f, 0.984375f, 0.015221f, 0.047363f, 0.082092f, 0.119202f, 0.159058f, 0.199219f, 0.239380f, 0.280762f,
+ 0.321533f, 0.362061f, 0.400146f, 0.436768f, 0.472900f, 0.504883f, 0.536621f, 0.566406f, 0.594238f, 0.621094f, 0.645508f, 0.667969f,
+ 0.688477f, 0.707520f, 0.726562f, 0.742676f, 0.759277f, 0.773926f, 0.787598f, 0.800781f, 0.812988f, 0.825195f, 0.835938f, 0.846191f,
+ 0.856445f, 0.865234f, 0.872559f, 0.880859f, 0.888672f, 0.895020f, 0.902832f, 0.908203f, 0.914551f, 0.919922f, 0.926758f, 0.931152f,
+ 0.937012f, 0.941406f, 0.945312f, 0.949707f, 0.954102f, 0.958496f, 0.962402f, 0.965820f, 0.969238f, 0.972168f, 0.976074f, 0.978516f,
+ 0.981934f, 0.984863f, 0.992188f, 0.990723f, 0.988770f, 0.987305f, 0.985352f, 0.983887f, 0.011658f, 0.037170f, 0.065430f, 0.096008f,
+ 0.128784f, 0.162842f, 0.198975f, 0.235596f, 0.273926f, 0.310791f, 0.348145f, 0.385010f, 0.420410f, 0.454834f, 0.488037f, 0.519043f,
+ 0.548828f, 0.577148f, 0.603516f, 0.627441f, 0.650879f, 0.672363f, 0.693848f, 0.712402f, 0.729980f, 0.748535f, 0.762207f, 0.778809f,
+ 0.791504f, 0.804199f, 0.815918f, 0.827637f, 0.838867f, 0.848145f, 0.857910f, 0.866211f, 0.875977f, 0.883301f, 0.891602f, 0.898438f,
+ 0.905273f, 0.911133f, 0.917480f, 0.923340f, 0.928711f, 0.933594f, 0.938477f, 0.942871f, 0.948242f, 0.952637f, 0.956543f, 0.960449f,
+ 0.964355f, 0.968262f, 0.971191f, 0.974609f, 0.978027f, 0.980957f, 0.990723f, 0.989258f, 0.987793f, 0.985840f, 0.984375f, 0.983398f,
+ 0.009758f, 0.030121f, 0.052490f, 0.077576f, 0.104309f, 0.134277f, 0.164917f, 0.197510f, 0.231812f, 0.266113f, 0.301025f, 0.336426f,
+ 0.372070f, 0.405762f, 0.438721f, 0.471436f, 0.502441f, 0.531738f, 0.560059f, 0.587402f, 0.612793f, 0.634766f, 0.658691f, 0.679199f,
+ 0.699219f, 0.718262f, 0.735352f, 0.751953f, 0.767090f, 0.780762f, 0.794922f, 0.808105f, 0.820801f, 0.831055f, 0.842285f, 0.851562f,
+ 0.861328f, 0.870117f, 0.878906f, 0.886719f, 0.893555f, 0.900879f, 0.907715f, 0.913574f, 0.919434f, 0.926270f, 0.932129f, 0.936523f,
+ 0.941895f, 0.945801f, 0.951172f, 0.955078f, 0.959473f, 0.963867f, 0.966797f, 0.970703f, 0.974121f, 0.977539f, 0.989746f, 0.988281f,
+ 0.986328f, 0.984863f, 0.983398f, 0.982422f, 0.007744f, 0.024567f, 0.043365f, 0.063782f, 0.086487f, 0.111389f, 0.137451f, 0.166260f,
+ 0.195435f, 0.226929f, 0.259033f, 0.291748f, 0.324951f, 0.358398f, 0.391113f, 0.424316f, 0.456299f, 0.486328f, 0.516113f, 0.543945f,
+ 0.571289f, 0.597656f, 0.621094f, 0.644531f, 0.666504f, 0.686523f, 0.705078f, 0.724121f, 0.741211f, 0.757324f, 0.773438f, 0.786621f,
+ 0.801270f, 0.812988f, 0.823730f, 0.835938f, 0.846191f, 0.855957f, 0.865723f, 0.873047f, 0.882324f, 0.889648f, 0.897949f, 0.905762f,
+ 0.911133f, 0.917969f, 0.923828f, 0.929199f, 0.934082f, 0.940430f, 0.944824f, 0.949707f, 0.954102f, 0.958008f, 0.962891f, 0.966309f,
+ 0.970215f, 0.974121f, 0.987793f, 0.986816f, 0.985352f, 0.983887f, 0.981934f, 0.980469f, 0.006672f, 0.020828f, 0.035950f, 0.053345f,
+ 0.071594f, 0.092834f, 0.114624f, 0.139282f, 0.165649f, 0.192627f, 0.222290f, 0.252197f, 0.283203f, 0.314941f, 0.346680f, 0.377930f,
+ 0.409668f, 0.441650f, 0.471680f, 0.500977f, 0.529297f, 0.557129f, 0.583008f, 0.607422f, 0.630859f, 0.654297f, 0.674805f, 0.694824f,
+ 0.713867f, 0.731445f, 0.748535f, 0.763672f, 0.778320f, 0.791992f, 0.805664f, 0.817871f, 0.829590f, 0.840332f, 0.850098f, 0.860352f,
+ 0.869141f, 0.878906f, 0.886719f, 0.894043f, 0.901855f, 0.909180f, 0.915527f, 0.920898f, 0.927246f, 0.933105f, 0.938477f, 0.943848f,
+ 0.948730f, 0.953125f, 0.957520f, 0.961914f, 0.965820f, 0.970215f, 0.985840f, 0.985352f, 0.983887f, 0.981934f, 0.980957f, 0.979492f,
+ 0.005592f, 0.017181f, 0.030457f, 0.044739f, 0.060638f, 0.077454f, 0.097046f, 0.117981f, 0.140625f, 0.164673f, 0.190552f, 0.217896f,
+ 0.246582f, 0.275635f, 0.305176f, 0.336426f, 0.366943f, 0.397949f, 0.428711f, 0.457764f, 0.487061f, 0.515137f, 0.542480f, 0.568848f,
+ 0.593750f, 0.619141f, 0.641602f, 0.662598f, 0.683594f, 0.703613f, 0.721191f, 0.738281f, 0.755859f, 0.770996f, 0.784180f, 0.799316f,
+ 0.811035f, 0.823730f, 0.833984f, 0.845703f, 0.855957f, 0.865234f, 0.875000f, 0.883301f, 0.891602f, 0.898926f, 0.906738f, 0.912598f,
+ 0.919922f, 0.926270f, 0.931152f, 0.937988f, 0.942871f, 0.948242f, 0.952148f, 0.957520f, 0.961914f, 0.966309f, 0.984375f, 0.983398f,
+ 0.982422f, 0.981445f, 0.979492f, 0.978027f, 0.004829f, 0.014816f, 0.025711f, 0.037964f, 0.051300f, 0.065796f, 0.082458f, 0.100037f,
+ 0.120178f, 0.141357f, 0.163330f, 0.187622f, 0.213013f, 0.240601f, 0.268311f, 0.296387f, 0.325928f, 0.356445f, 0.385742f, 0.415771f,
+ 0.445557f, 0.474121f, 0.501465f, 0.530762f, 0.556152f, 0.581543f, 0.606445f, 0.630859f, 0.651855f, 0.672852f, 0.693359f, 0.712402f,
+ 0.730469f, 0.746582f, 0.762695f, 0.777832f, 0.791992f, 0.806152f, 0.818359f, 0.830566f, 0.840820f, 0.852051f, 0.862305f, 0.871094f,
+ 0.880371f, 0.888184f, 0.896484f, 0.904297f, 0.910645f, 0.917969f, 0.924316f, 0.931152f, 0.936035f, 0.942383f, 0.947266f, 0.951660f,
+ 0.957031f, 0.960938f, 0.982422f, 0.982422f, 0.981445f, 0.979492f, 0.978516f, 0.977051f, 0.004040f, 0.012436f, 0.022064f, 0.032440f,
+ 0.044006f, 0.056549f, 0.070068f, 0.085999f, 0.102539f, 0.120239f, 0.140625f, 0.161621f, 0.184448f, 0.208496f, 0.234253f, 0.260742f,
+ 0.288086f, 0.316406f, 0.345215f, 0.374512f, 0.404297f, 0.433350f, 0.462402f, 0.490234f, 0.518066f, 0.543945f, 0.570312f, 0.594727f,
+ 0.618652f, 0.642090f, 0.663086f, 0.683594f, 0.703613f, 0.721680f, 0.739258f, 0.755859f, 0.772461f, 0.786621f, 0.798828f, 0.812500f,
+ 0.825195f, 0.836914f, 0.848633f, 0.858887f, 0.869141f, 0.877441f, 0.886230f, 0.894531f, 0.902832f, 0.909668f, 0.916992f, 0.923340f,
+ 0.929688f, 0.935547f, 0.941406f, 0.947266f, 0.951660f, 0.957031f, 0.980469f, 0.980469f, 0.979492f, 0.978516f, 0.977051f, 0.976074f,
+ 0.003536f, 0.010872f, 0.018829f, 0.027893f, 0.037872f, 0.048492f, 0.060883f, 0.073425f, 0.088074f, 0.103638f, 0.120789f, 0.139038f,
+ 0.159912f, 0.181274f, 0.204102f, 0.227905f, 0.253906f, 0.280518f, 0.307861f, 0.335938f, 0.364746f, 0.393311f, 0.421631f, 0.451416f,
+ 0.479004f, 0.505859f, 0.533203f, 0.560059f, 0.584473f, 0.608398f, 0.631836f, 0.653320f, 0.674805f, 0.695801f, 0.714355f, 0.731934f,
+ 0.749512f, 0.765137f, 0.781250f, 0.794434f, 0.808594f, 0.821289f, 0.833496f, 0.844238f, 0.855469f, 0.866211f, 0.875000f, 0.883789f,
+ 0.892578f, 0.901855f, 0.908691f, 0.915527f, 0.922852f, 0.929199f, 0.935059f, 0.941406f, 0.947266f, 0.951172f, 0.978516f, 0.979004f,
+ 0.978027f, 0.977051f, 0.975586f, 0.974121f, 0.002989f, 0.009476f, 0.016785f, 0.024246f, 0.032745f, 0.041809f, 0.052246f, 0.063782f,
+ 0.076111f, 0.089722f, 0.104675f, 0.120605f, 0.138306f, 0.157959f, 0.178101f, 0.200073f, 0.223145f, 0.247192f, 0.273193f, 0.300293f,
+ 0.327148f, 0.354736f, 0.383545f, 0.411621f, 0.439941f, 0.468018f, 0.495605f, 0.522949f, 0.548828f, 0.574219f, 0.598145f, 0.622559f,
+ 0.645508f, 0.666016f, 0.687500f, 0.706543f, 0.725586f, 0.743164f, 0.759766f, 0.775391f, 0.791016f, 0.803711f, 0.817871f, 0.829590f,
+ 0.841797f, 0.852539f, 0.863281f, 0.873047f, 0.882812f, 0.891113f, 0.900391f, 0.906738f, 0.915039f, 0.922852f, 0.929688f, 0.936035f,
+ 0.941895f, 0.946777f, 0.976074f, 0.977051f, 0.976074f, 0.975586f, 0.974121f, 0.972656f, 0.002846f, 0.008568f, 0.014557f, 0.021484f,
+ 0.028442f, 0.036377f, 0.045074f, 0.055054f, 0.066101f, 0.077759f, 0.090759f, 0.104797f, 0.120483f, 0.136719f, 0.155029f, 0.175171f,
+ 0.196045f, 0.218262f, 0.241943f, 0.266357f, 0.292480f, 0.319336f, 0.345703f, 0.373535f, 0.402100f, 0.429932f, 0.457764f, 0.484863f,
+ 0.512207f, 0.539062f, 0.564941f, 0.589844f, 0.613281f, 0.636719f, 0.659180f, 0.680664f, 0.700684f, 0.718750f, 0.736816f, 0.754883f,
+ 0.770508f, 0.785645f, 0.799805f, 0.813965f, 0.826172f, 0.838867f, 0.850586f, 0.861328f, 0.871582f, 0.881836f, 0.890625f, 0.898926f,
+ 0.906738f, 0.915039f, 0.922363f, 0.928711f, 0.936035f, 0.941895f, 0.974609f, 0.975098f, 0.974609f, 0.973633f, 0.972656f, 0.971191f,
+ 0.002285f, 0.007290f, 0.012634f, 0.018280f, 0.024918f, 0.032074f, 0.039673f, 0.048157f, 0.057220f, 0.067810f, 0.078735f, 0.091248f,
+ 0.104370f, 0.119873f, 0.135742f, 0.152344f, 0.171631f, 0.191650f, 0.213501f, 0.236206f, 0.260010f, 0.285156f, 0.310547f, 0.338135f,
+ 0.364746f, 0.392578f, 0.420410f, 0.448242f, 0.476562f, 0.502441f, 0.529785f, 0.555664f, 0.581543f, 0.605469f, 0.629395f, 0.652344f,
+ 0.673340f, 0.693848f, 0.713867f, 0.732910f, 0.750000f, 0.767090f, 0.782715f, 0.797852f, 0.811035f, 0.825195f, 0.836914f, 0.848633f,
+ 0.860840f, 0.870605f, 0.880371f, 0.890137f, 0.898926f, 0.907227f, 0.915527f, 0.923340f, 0.929688f, 0.936523f, 0.972168f, 0.973145f,
+ 0.972656f, 0.972168f, 0.970703f, 0.969727f, 0.002064f, 0.006584f, 0.011154f, 0.016266f, 0.022263f, 0.028397f, 0.034973f, 0.042145f,
+ 0.050232f, 0.059235f, 0.069031f, 0.079346f, 0.091736f, 0.104553f, 0.118652f, 0.133789f, 0.150635f, 0.168457f, 0.188110f, 0.208984f,
+ 0.230225f, 0.253906f, 0.278076f, 0.303955f, 0.329346f, 0.356689f, 0.384033f, 0.411865f, 0.439941f, 0.467285f, 0.493896f, 0.520996f,
+ 0.547363f, 0.573730f, 0.597168f, 0.622559f, 0.645508f, 0.667969f, 0.688965f, 0.709473f, 0.728027f, 0.746094f, 0.762695f, 0.778809f,
+ 0.794922f, 0.809082f, 0.822754f, 0.834961f, 0.847168f, 0.858887f, 0.870117f, 0.880371f, 0.889648f, 0.898926f, 0.907227f, 0.915039f,
+ 0.923828f, 0.930176f, 0.970215f, 0.971680f, 0.970215f, 0.970215f, 0.968750f, 0.968262f, 0.001935f, 0.005634f, 0.010078f, 0.014389f,
+ 0.019669f, 0.024658f, 0.030716f, 0.037201f, 0.044098f, 0.051941f, 0.060333f, 0.070129f, 0.080383f, 0.091370f, 0.103638f, 0.116943f,
+ 0.131714f, 0.148193f, 0.165161f, 0.183838f, 0.203979f, 0.225220f, 0.247803f, 0.271240f, 0.296631f, 0.322510f, 0.349121f, 0.376221f,
+ 0.403076f, 0.431152f, 0.458984f, 0.485596f, 0.513672f, 0.540039f, 0.564941f, 0.590820f, 0.616211f, 0.638672f, 0.662109f, 0.683105f,
+ 0.704102f, 0.723633f, 0.741699f, 0.759766f, 0.776855f, 0.792480f, 0.807617f, 0.821777f, 0.833496f, 0.847168f, 0.858887f, 0.870117f,
+ 0.880859f, 0.889648f, 0.899414f, 0.908203f, 0.916992f, 0.924316f, 0.967285f, 0.968262f, 0.968750f, 0.968262f, 0.967285f, 0.966309f,
+ 0.001805f, 0.005119f, 0.009079f, 0.013023f, 0.017487f, 0.022278f, 0.027130f, 0.032684f, 0.038666f, 0.045959f, 0.052826f, 0.061401f,
+ 0.070801f, 0.080139f, 0.090698f, 0.102844f, 0.115845f, 0.130005f, 0.145264f, 0.162476f, 0.180176f, 0.199951f, 0.220459f, 0.242188f,
+ 0.265869f, 0.290283f, 0.315430f, 0.341309f, 0.368652f, 0.395752f, 0.423584f, 0.451416f, 0.479248f, 0.505859f, 0.532227f, 0.559082f,
+ 0.584961f, 0.609863f, 0.634277f, 0.656738f, 0.678711f, 0.700195f, 0.720703f, 0.738281f, 0.757324f, 0.774414f, 0.790527f, 0.805664f,
+ 0.820312f, 0.834473f, 0.846680f, 0.858887f, 0.869629f, 0.880859f, 0.890625f, 0.899902f, 0.909668f, 0.917969f, 0.964844f, 0.966797f,
+ 0.967285f, 0.965820f, 0.964844f, 0.963867f, 0.001437f, 0.004662f, 0.007919f, 0.011681f, 0.015404f, 0.019272f, 0.024261f, 0.029205f,
+ 0.034515f, 0.040619f, 0.046967f, 0.054138f, 0.061737f, 0.070496f, 0.080200f, 0.090271f, 0.101807f, 0.114136f, 0.127686f, 0.143188f,
+ 0.159058f, 0.176514f, 0.195190f, 0.215454f, 0.237305f, 0.260010f, 0.283936f, 0.309326f, 0.334717f, 0.361328f, 0.389160f, 0.416260f,
+ 0.444336f, 0.471436f, 0.499512f, 0.525879f, 0.552734f, 0.579590f, 0.604004f, 0.628906f, 0.651855f, 0.674805f, 0.696777f, 0.717773f,
+ 0.737305f, 0.755859f, 0.772949f, 0.789551f, 0.805664f, 0.819336f, 0.833984f, 0.847168f, 0.859375f, 0.871094f, 0.881836f, 0.892090f,
+ 0.902344f, 0.910156f, 0.962402f, 0.964355f, 0.964355f, 0.963867f, 0.962891f, 0.961914f, 0.001264f, 0.004036f, 0.007088f, 0.010170f,
+ 0.013672f, 0.017365f, 0.021423f, 0.025955f, 0.030533f, 0.035614f, 0.041321f, 0.047791f, 0.054626f, 0.062195f, 0.070679f, 0.080017f,
+ 0.089600f, 0.100769f, 0.112854f, 0.125977f, 0.139893f, 0.156128f, 0.172852f, 0.191650f, 0.211060f, 0.232056f, 0.254883f, 0.278076f,
+ 0.302979f, 0.328125f, 0.355225f, 0.381836f, 0.409912f, 0.437256f, 0.464844f, 0.492676f, 0.520508f, 0.547852f, 0.573242f, 0.599609f,
+ 0.625000f, 0.649414f, 0.672363f, 0.694336f, 0.714844f, 0.734863f, 0.753418f, 0.771484f, 0.788574f, 0.804688f, 0.820312f, 0.833496f,
+ 0.847656f, 0.859863f, 0.873047f, 0.883301f, 0.894043f, 0.903809f, 0.959961f, 0.961914f, 0.962402f, 0.960938f, 0.960449f, 0.959961f,
+ 0.001297f, 0.003721f, 0.006397f, 0.009308f, 0.012260f, 0.015808f, 0.019302f, 0.023010f, 0.027267f, 0.032013f, 0.037109f, 0.042419f,
+ 0.048523f, 0.054962f, 0.061920f, 0.070435f, 0.079407f, 0.088318f, 0.099121f, 0.111084f, 0.124023f, 0.137695f, 0.152832f, 0.169434f,
+ 0.187378f, 0.206421f, 0.227783f, 0.249268f, 0.272461f, 0.297363f, 0.322754f, 0.348389f, 0.376221f, 0.403809f, 0.431396f, 0.459229f,
+ 0.487305f, 0.515137f, 0.542480f, 0.569336f, 0.595215f, 0.621094f, 0.645996f, 0.669434f, 0.691406f, 0.712891f, 0.733887f, 0.753418f,
+ 0.770996f, 0.789062f, 0.805176f, 0.820801f, 0.835449f, 0.849121f, 0.861328f, 0.874512f, 0.885742f, 0.895508f, 0.956543f, 0.959473f,
+ 0.958984f, 0.958984f, 0.958008f, 0.957031f, 0.001267f, 0.003481f, 0.005955f, 0.008568f, 0.011185f, 0.014030f, 0.017151f, 0.020294f,
+ 0.024246f, 0.028427f, 0.032654f, 0.037476f, 0.042603f, 0.048523f, 0.054871f, 0.062408f, 0.070129f, 0.078552f, 0.087769f, 0.097534f,
+ 0.109192f, 0.121399f, 0.135010f, 0.150513f, 0.165894f, 0.183960f, 0.202881f, 0.222656f, 0.244385f, 0.267334f, 0.291260f, 0.317139f,
+ 0.343506f, 0.370605f, 0.397949f, 0.426025f, 0.454346f, 0.482666f, 0.511230f, 0.538086f, 0.565918f, 0.592285f, 0.618164f, 0.642578f,
+ 0.667480f, 0.690918f, 0.711914f, 0.732910f, 0.752930f, 0.771484f, 0.790039f, 0.806641f, 0.821777f, 0.837402f, 0.850586f, 0.864746f,
+ 0.875977f, 0.887695f, 0.953613f, 0.956543f, 0.957031f, 0.956055f, 0.956055f, 0.955078f, 0.001068f, 0.003025f, 0.005283f, 0.007442f,
+ 0.009857f, 0.012665f, 0.015930f, 0.018570f, 0.021820f, 0.025314f, 0.028931f, 0.033325f, 0.038147f, 0.042908f, 0.049011f, 0.055176f,
+ 0.061859f, 0.069397f, 0.077637f, 0.086792f, 0.096252f, 0.107117f, 0.119385f, 0.132690f, 0.147095f, 0.162720f, 0.180054f, 0.198486f,
+ 0.218384f, 0.239990f, 0.262207f, 0.287109f, 0.311523f, 0.337891f, 0.364990f, 0.392822f, 0.420654f, 0.449219f, 0.478027f, 0.505859f,
+ 0.535156f, 0.562012f, 0.588867f, 0.615723f, 0.641602f, 0.666016f, 0.688965f, 0.711914f, 0.732910f, 0.753906f, 0.773438f, 0.791016f,
+ 0.808594f, 0.823730f, 0.839355f, 0.854004f, 0.867188f, 0.879883f, 0.950195f, 0.954102f, 0.954102f, 0.953125f, 0.952637f, 0.952148f,
+ 0.000884f, 0.003082f, 0.004631f, 0.006931f, 0.008942f, 0.011513f, 0.013779f, 0.016663f, 0.019806f, 0.022934f, 0.026215f, 0.029999f,
+ 0.033813f, 0.038544f, 0.043365f, 0.048615f, 0.054352f, 0.061005f, 0.068420f, 0.076477f, 0.085022f, 0.095032f, 0.105469f, 0.117432f,
+ 0.130127f, 0.143799f, 0.159790f, 0.176270f, 0.194580f, 0.214478f, 0.235229f, 0.257568f, 0.281982f, 0.306641f, 0.332764f, 0.359863f,
+ 0.388184f, 0.416016f, 0.445557f, 0.474854f, 0.502441f, 0.531738f, 0.559570f, 0.586914f, 0.614258f, 0.640625f, 0.665039f, 0.689453f,
+ 0.712891f, 0.734863f, 0.755371f, 0.774902f, 0.793945f, 0.810547f, 0.827637f, 0.842773f, 0.857910f, 0.871094f, 0.946777f, 0.950684f,
+ 0.951172f, 0.950684f, 0.949707f, 0.949707f, 0.000848f, 0.002630f, 0.004330f, 0.006386f, 0.008148f, 0.010437f, 0.012436f, 0.014977f,
+ 0.017731f, 0.020645f, 0.023529f, 0.026413f, 0.030289f, 0.034302f, 0.038391f, 0.043365f, 0.048737f, 0.054413f, 0.060455f, 0.067383f,
+ 0.075134f, 0.083801f, 0.093262f, 0.103821f, 0.114746f, 0.127441f, 0.140991f, 0.156372f, 0.172729f, 0.190918f, 0.210449f, 0.231201f,
+ 0.253662f, 0.277344f, 0.302734f, 0.328857f, 0.355225f, 0.384033f, 0.413086f, 0.440918f, 0.471191f, 0.500488f, 0.529785f, 0.558594f,
+ 0.586426f, 0.613770f, 0.640137f, 0.666016f, 0.689453f, 0.714355f, 0.736328f, 0.757812f, 0.777832f, 0.796875f, 0.813965f, 0.831543f,
+ 0.847168f, 0.860840f, 0.943848f, 0.948242f, 0.947754f, 0.948242f, 0.946777f, 0.946777f, 0.000747f, 0.002462f, 0.004192f, 0.005573f,
+ 0.007454f, 0.009430f, 0.011253f, 0.013588f, 0.015762f, 0.018112f, 0.020859f, 0.023758f, 0.027084f, 0.030426f, 0.034332f, 0.038635f,
+ 0.042999f, 0.048340f, 0.053772f, 0.060028f, 0.066589f, 0.074402f, 0.082764f, 0.091553f, 0.101685f, 0.112854f, 0.125122f, 0.138184f,
+ 0.153320f, 0.169556f, 0.187500f, 0.206543f, 0.227539f, 0.249512f, 0.273193f, 0.298340f, 0.324463f, 0.351562f, 0.379883f, 0.409424f,
+ 0.438477f, 0.468750f, 0.498047f, 0.527832f, 0.556641f, 0.585449f, 0.614258f, 0.641113f, 0.666992f, 0.692383f, 0.716309f, 0.738281f,
+ 0.760742f, 0.780273f, 0.799805f, 0.818848f, 0.834473f, 0.851074f, 0.939941f, 0.944824f, 0.944336f, 0.944336f, 0.944336f, 0.943359f,
+ 0.000670f, 0.002079f, 0.003538f, 0.005146f, 0.006508f, 0.008247f, 0.010223f, 0.012260f, 0.014153f, 0.016479f, 0.018677f, 0.021515f,
+ 0.024323f, 0.027313f, 0.030518f, 0.034302f, 0.038422f, 0.042725f, 0.047760f, 0.053101f, 0.059113f, 0.065613f, 0.072937f, 0.080444f,
+ 0.089722f, 0.099426f, 0.110596f, 0.122314f, 0.135742f, 0.150513f, 0.166260f, 0.183716f, 0.202759f, 0.223633f, 0.245728f, 0.269287f,
+ 0.294189f, 0.320557f, 0.348633f, 0.376709f, 0.406494f, 0.436523f, 0.467285f, 0.497070f, 0.528320f, 0.557129f, 0.586426f, 0.614746f,
+ 0.642090f, 0.668945f, 0.694824f, 0.718750f, 0.742676f, 0.764648f, 0.786133f, 0.805176f, 0.823242f, 0.840820f, 0.936035f, 0.940918f,
+ 0.941406f, 0.941406f, 0.940430f, 0.939941f, 0.000645f, 0.001963f, 0.003384f, 0.004719f, 0.006042f, 0.007614f, 0.009384f, 0.011192f,
+ 0.012665f, 0.015083f, 0.016861f, 0.019165f, 0.021393f, 0.024445f, 0.027451f, 0.030716f, 0.034149f, 0.038116f, 0.042389f, 0.047028f,
+ 0.052277f, 0.058014f, 0.064270f, 0.071289f, 0.079041f, 0.087830f, 0.097351f, 0.108337f, 0.119995f, 0.132812f, 0.147217f, 0.163452f,
+ 0.180420f, 0.199585f, 0.219849f, 0.242065f, 0.265625f, 0.291260f, 0.318115f, 0.345703f, 0.375000f, 0.404541f, 0.434326f, 0.465820f,
+ 0.496582f, 0.526855f, 0.557617f, 0.587402f, 0.616699f, 0.645508f, 0.672363f, 0.698242f, 0.723145f, 0.747559f, 0.770020f, 0.791504f,
+ 0.810059f, 0.828613f, 0.931641f, 0.937012f, 0.937500f, 0.937500f, 0.937012f, 0.936523f, 0.000692f, 0.001705f, 0.003000f, 0.004238f,
+ 0.005798f, 0.006805f, 0.008659f, 0.009933f, 0.011681f, 0.013191f, 0.015259f, 0.017166f, 0.019379f, 0.021729f, 0.024796f, 0.027328f,
+ 0.030380f, 0.033661f, 0.037598f, 0.041718f, 0.046539f, 0.051270f, 0.056946f, 0.062988f, 0.069885f, 0.077271f, 0.085999f, 0.095398f,
+ 0.105652f, 0.117859f, 0.129883f, 0.144409f, 0.159912f, 0.177002f, 0.196045f, 0.216553f, 0.239014f, 0.262451f, 0.288086f, 0.314941f,
+ 0.343262f, 0.372314f, 0.403076f, 0.433594f, 0.465332f, 0.496826f, 0.527832f, 0.559082f, 0.589355f, 0.619629f, 0.648926f, 0.676758f,
+ 0.703125f, 0.728516f, 0.752930f, 0.775391f, 0.797363f, 0.817871f, 0.927246f, 0.933105f, 0.934082f, 0.933594f, 0.933594f, 0.933105f,
+ 0.000460f, 0.001622f, 0.002705f, 0.003983f, 0.004925f, 0.006363f, 0.007652f, 0.008965f, 0.010521f, 0.011963f, 0.013664f, 0.015480f,
+ 0.017258f, 0.019440f, 0.021912f, 0.024338f, 0.027084f, 0.030212f, 0.033356f, 0.037018f, 0.040833f, 0.045380f, 0.050110f, 0.055573f,
+ 0.061829f, 0.068359f, 0.075928f, 0.083984f, 0.093140f, 0.103333f, 0.115112f, 0.127441f, 0.141602f, 0.156982f, 0.174316f, 0.192871f,
+ 0.213257f, 0.235596f, 0.259766f, 0.285400f, 0.312256f, 0.341797f, 0.371094f, 0.402100f, 0.434082f, 0.465332f, 0.497314f, 0.529297f,
+ 0.562012f, 0.592773f, 0.623535f, 0.652832f, 0.681641f, 0.709473f, 0.735352f, 0.759766f, 0.783203f, 0.803711f, 0.922363f, 0.929199f,
+ 0.929688f, 0.929199f, 0.929688f, 0.928711f, 0.000341f, 0.001686f, 0.002537f, 0.003769f, 0.004745f, 0.005764f, 0.007034f, 0.008286f,
+ 0.009369f, 0.010742f, 0.012161f, 0.013931f, 0.015671f, 0.017563f, 0.019440f, 0.021851f, 0.024231f, 0.026672f, 0.029556f, 0.032776f,
+ 0.036255f, 0.040283f, 0.044464f, 0.049194f, 0.054413f, 0.060059f, 0.066589f, 0.074036f, 0.081909f, 0.091187f, 0.100769f, 0.112000f,
+ 0.124512f, 0.139038f, 0.154297f, 0.171265f, 0.189819f, 0.210571f, 0.232788f, 0.257324f, 0.283203f, 0.311035f, 0.339844f, 0.370850f,
+ 0.402100f, 0.433838f, 0.466797f, 0.499268f, 0.532227f, 0.565430f, 0.598145f, 0.628418f, 0.659180f, 0.687988f, 0.715820f, 0.742188f,
+ 0.767090f, 0.791504f, 0.917969f, 0.924805f, 0.925293f, 0.925293f, 0.924805f, 0.924805f, 0.000405f, 0.001282f, 0.002298f, 0.003269f,
+ 0.004448f, 0.005043f, 0.006294f, 0.007233f, 0.008606f, 0.009727f, 0.010849f, 0.012421f, 0.013885f, 0.015465f, 0.017426f, 0.019394f,
+ 0.021667f, 0.023819f, 0.026154f, 0.029175f, 0.032227f, 0.035706f, 0.039062f, 0.043427f, 0.047913f, 0.052856f, 0.058502f, 0.064880f,
+ 0.071960f, 0.079895f, 0.088867f, 0.098633f, 0.109619f, 0.122192f, 0.135742f, 0.151489f, 0.168457f, 0.187134f, 0.207764f, 0.230835f,
+ 0.254883f, 0.281494f, 0.310059f, 0.339355f, 0.370361f, 0.402588f, 0.435547f, 0.468994f, 0.502930f, 0.537109f, 0.569824f, 0.602051f,
+ 0.634766f, 0.665527f, 0.695801f, 0.724121f, 0.750488f, 0.776855f, 0.912598f, 0.919434f, 0.920410f, 0.920410f, 0.919922f, 0.920410f,
+ 0.000529f, 0.001217f, 0.002171f, 0.003035f, 0.003790f, 0.004784f, 0.005711f, 0.006756f, 0.007782f, 0.008987f, 0.009773f, 0.011185f,
+ 0.012650f, 0.013771f, 0.015656f, 0.017181f, 0.018890f, 0.021057f, 0.023239f, 0.025848f, 0.028488f, 0.031525f, 0.034607f, 0.038147f,
+ 0.042023f, 0.046539f, 0.051605f, 0.056793f, 0.063049f, 0.069946f, 0.078064f, 0.086548f, 0.096313f, 0.107117f, 0.119446f, 0.133301f,
+ 0.148560f, 0.165405f, 0.184570f, 0.205811f, 0.228394f, 0.253174f, 0.280029f, 0.308594f, 0.339111f, 0.370605f, 0.404053f, 0.437988f,
+ 0.471680f, 0.506348f, 0.541504f, 0.576172f, 0.609375f, 0.642578f, 0.674316f, 0.705078f, 0.734375f, 0.761719f, 0.907227f, 0.914062f,
+ 0.915527f, 0.915527f, 0.916016f, 0.915039f, 0.000402f, 0.001247f, 0.001841f, 0.002651f, 0.003414f, 0.004200f, 0.005337f, 0.005821f,
+ 0.006733f, 0.008041f, 0.008942f, 0.010201f, 0.011261f, 0.012749f, 0.013893f, 0.015472f, 0.016663f, 0.018829f, 0.020615f, 0.022873f,
+ 0.025299f, 0.027893f, 0.030533f, 0.033600f, 0.037140f, 0.040924f, 0.044983f, 0.049927f, 0.055359f, 0.061340f, 0.068176f, 0.075500f,
+ 0.084106f, 0.093933f, 0.104370f, 0.116638f, 0.130249f, 0.145996f, 0.162842f, 0.181885f, 0.203735f, 0.226562f, 0.251465f, 0.279297f,
+ 0.308594f, 0.339355f, 0.373047f, 0.406982f, 0.440918f, 0.477051f, 0.511719f, 0.548340f, 0.583496f, 0.618164f, 0.652344f, 0.684570f,
+ 0.715332f, 0.745605f, 0.901855f, 0.909180f, 0.910156f, 0.910645f, 0.910156f, 0.910156f, 0.000371f, 0.001090f, 0.001752f, 0.002409f,
+ 0.003042f, 0.003963f, 0.004898f, 0.005295f, 0.006077f, 0.006992f, 0.008102f, 0.009338f, 0.010101f, 0.011078f, 0.012375f, 0.013718f,
+ 0.015099f, 0.016403f, 0.018402f, 0.020203f, 0.022354f, 0.024475f, 0.026825f, 0.029388f, 0.032623f, 0.035522f, 0.039429f, 0.043762f,
+ 0.048462f, 0.053558f, 0.059265f, 0.065552f, 0.073120f, 0.081787f, 0.091431f, 0.102112f, 0.114136f, 0.127930f, 0.143066f, 0.160767f,
+ 0.179810f, 0.200928f, 0.224854f, 0.250732f, 0.279053f, 0.308838f, 0.340820f, 0.374756f, 0.410156f, 0.446045f, 0.482666f, 0.520020f,
+ 0.556152f, 0.593262f, 0.628906f, 0.663574f, 0.695801f, 0.728027f, 0.895508f, 0.903809f, 0.904297f, 0.904297f, 0.904297f, 0.904785f,
+ 0.000425f, 0.000937f, 0.001529f, 0.002129f, 0.002674f, 0.003696f, 0.004257f, 0.004990f, 0.005726f, 0.006161f, 0.007118f, 0.007919f,
+ 0.009109f, 0.009941f, 0.011055f, 0.011993f, 0.013191f, 0.014832f, 0.016281f, 0.017868f, 0.019562f, 0.021362f, 0.023514f, 0.025909f,
+ 0.028549f, 0.031189f, 0.034637f, 0.037994f, 0.042145f, 0.046570f, 0.051453f, 0.057129f, 0.063965f, 0.070984f, 0.079285f, 0.088806f,
+ 0.099426f, 0.111267f, 0.125366f, 0.140747f, 0.158203f, 0.178101f, 0.199585f, 0.223755f, 0.250732f, 0.279297f, 0.310059f, 0.343994f,
+ 0.377686f, 0.414307f, 0.451904f, 0.489258f, 0.527832f, 0.565918f, 0.603027f, 0.640137f, 0.675781f, 0.710449f, 0.888672f, 0.897461f,
+ 0.899902f, 0.900391f, 0.899414f, 0.899414f, 0.000317f, 0.000823f, 0.001386f, 0.002108f, 0.002684f, 0.003239f, 0.003883f, 0.004303f,
+ 0.004730f, 0.005569f, 0.006626f, 0.007214f, 0.008003f, 0.008865f, 0.009590f, 0.010948f, 0.011856f, 0.012871f, 0.014381f, 0.015640f,
+ 0.017075f, 0.018799f, 0.020569f, 0.022537f, 0.024704f, 0.027405f, 0.030090f, 0.033142f, 0.036346f, 0.040436f, 0.044830f, 0.049835f,
+ 0.055450f, 0.061584f, 0.068665f, 0.076904f, 0.086060f, 0.096741f, 0.109192f, 0.122559f, 0.138428f, 0.155762f, 0.176270f, 0.198242f,
+ 0.223145f, 0.250244f, 0.280518f, 0.312500f, 0.346680f, 0.382324f, 0.420410f, 0.458740f, 0.498779f, 0.538086f, 0.577637f, 0.616211f,
+ 0.654297f, 0.690918f, 0.881348f, 0.890625f, 0.892578f, 0.893066f, 0.893066f, 0.892578f, 0.000385f, 0.000766f, 0.001544f, 0.001925f,
+ 0.002359f, 0.002947f, 0.003176f, 0.003691f, 0.004288f, 0.005215f, 0.005917f, 0.006214f, 0.007019f, 0.007843f, 0.008469f, 0.009598f,
+ 0.010345f, 0.011559f, 0.012497f, 0.013634f, 0.014992f, 0.016373f, 0.017853f, 0.019608f, 0.021515f, 0.023788f, 0.026260f, 0.028931f,
+ 0.031860f, 0.034912f, 0.038635f, 0.042633f, 0.047638f, 0.053070f, 0.059540f, 0.066284f, 0.074524f, 0.083679f, 0.094177f, 0.106445f,
+ 0.120361f, 0.135620f, 0.154053f, 0.174072f, 0.197144f, 0.222900f, 0.251221f, 0.281982f, 0.315430f, 0.351318f, 0.388672f, 0.427734f,
+ 0.468506f, 0.508301f, 0.549805f, 0.591309f, 0.631348f, 0.670410f, 0.874512f, 0.884766f, 0.885742f, 0.886230f, 0.886230f, 0.886230f,
+ 0.000230f, 0.000832f, 0.001281f, 0.001865f, 0.002207f, 0.002605f, 0.003212f, 0.003284f, 0.004124f, 0.004597f, 0.005222f, 0.005703f,
+ 0.006260f, 0.007095f, 0.007790f, 0.008377f, 0.009010f, 0.010078f, 0.011009f, 0.011925f, 0.013153f, 0.014282f, 0.015610f, 0.017151f,
+ 0.018951f, 0.020416f, 0.022583f, 0.024826f, 0.027328f, 0.030136f, 0.033508f, 0.036835f, 0.040985f, 0.045410f, 0.050812f, 0.056854f,
+ 0.063965f, 0.071777f, 0.081177f, 0.091858f, 0.103699f, 0.117615f, 0.133423f, 0.152588f, 0.172974f, 0.196777f, 0.222900f, 0.252686f,
+ 0.284912f, 0.319824f, 0.356934f, 0.395996f, 0.436768f, 0.478516f, 0.521484f, 0.564453f, 0.607422f, 0.649414f, 0.866699f, 0.876953f,
+ 0.877930f, 0.879395f, 0.879883f, 0.878418f, 0.000228f, 0.000734f, 0.000993f, 0.001416f, 0.001935f, 0.002293f, 0.002541f, 0.003174f,
+ 0.003508f, 0.004040f, 0.004337f, 0.005039f, 0.005505f, 0.006054f, 0.006840f, 0.007366f, 0.008041f, 0.008644f, 0.009544f, 0.010460f,
+ 0.011238f, 0.012329f, 0.013542f, 0.014755f, 0.016083f, 0.017624f, 0.019424f, 0.021408f, 0.023422f, 0.025803f, 0.028366f, 0.031311f,
+ 0.034912f, 0.039124f, 0.043304f, 0.048492f, 0.054291f, 0.061188f, 0.069397f, 0.078552f, 0.089233f, 0.101074f, 0.115540f, 0.131226f,
+ 0.150757f, 0.172119f, 0.196533f, 0.224243f, 0.254883f, 0.288574f, 0.324707f, 0.364014f, 0.405029f, 0.447510f, 0.491699f, 0.536133f,
+ 0.581543f, 0.627441f, 0.858398f, 0.869141f, 0.870605f, 0.871582f, 0.871094f, 0.871582f, 0.000118f, 0.000713f, 0.000985f, 0.001328f,
+ 0.001612f, 0.001999f, 0.002399f, 0.002913f, 0.003139f, 0.003567f, 0.004055f, 0.004406f, 0.004986f, 0.005226f, 0.005856f, 0.006332f,
+ 0.007042f, 0.007553f, 0.008286f, 0.009064f, 0.009834f, 0.010696f, 0.011658f, 0.012726f, 0.013817f, 0.015289f, 0.016693f, 0.018265f,
+ 0.019699f, 0.021835f, 0.024307f, 0.026642f, 0.029770f, 0.033234f, 0.037048f, 0.041351f, 0.046478f, 0.052032f, 0.058960f, 0.066589f,
+ 0.075745f, 0.086182f, 0.099121f, 0.113037f, 0.129517f, 0.149048f, 0.171387f, 0.196899f, 0.225464f, 0.257812f, 0.293457f, 0.331787f,
+ 0.373291f, 0.416748f, 0.460938f, 0.507812f, 0.554688f, 0.602051f, 0.849609f, 0.859863f, 0.862793f, 0.863281f, 0.862793f, 0.862793f,
+ 0.000211f, 0.000522f, 0.000877f, 0.001204f, 0.001507f, 0.001724f, 0.002062f, 0.002426f, 0.002867f, 0.003157f, 0.003443f, 0.003752f,
+ 0.004192f, 0.004753f, 0.005154f, 0.005428f, 0.006065f, 0.006546f, 0.007210f, 0.007725f, 0.008530f, 0.009247f, 0.010025f, 0.010887f,
+ 0.011909f, 0.012970f, 0.014069f, 0.015335f, 0.017105f, 0.018433f, 0.020554f, 0.022552f, 0.025116f, 0.027802f, 0.031158f, 0.034485f,
+ 0.038971f, 0.044037f, 0.049469f, 0.055847f, 0.063843f, 0.072815f, 0.083618f, 0.095947f, 0.110840f, 0.128174f, 0.147949f, 0.171387f,
+ 0.198242f, 0.228271f, 0.262207f, 0.299805f, 0.340332f, 0.384277f, 0.430176f, 0.477295f, 0.527344f, 0.577637f, 0.839844f, 0.851074f,
+ 0.853516f, 0.854492f, 0.854980f, 0.854980f, 0.000218f, 0.000479f, 0.000706f, 0.001109f, 0.001245f, 0.001763f, 0.001800f, 0.002211f,
+ 0.002377f, 0.002783f, 0.003103f, 0.003223f, 0.003782f, 0.004089f, 0.004326f, 0.004711f, 0.005306f, 0.005569f, 0.006199f, 0.006653f,
+ 0.007168f, 0.007919f, 0.008560f, 0.009254f, 0.009979f, 0.010872f, 0.012054f, 0.012810f, 0.014221f, 0.015793f, 0.017181f, 0.018967f,
+ 0.021088f, 0.023361f, 0.026001f, 0.028915f, 0.032257f, 0.036469f, 0.040924f, 0.046875f, 0.053375f, 0.061218f, 0.070435f, 0.080811f,
+ 0.093628f, 0.108704f, 0.126709f, 0.147461f, 0.172241f, 0.199951f, 0.232788f, 0.268799f, 0.308594f, 0.351562f, 0.397705f, 0.447266f,
+ 0.498291f, 0.550293f, 0.830078f, 0.841797f, 0.843750f, 0.845215f, 0.845215f, 0.845703f, 0.000139f, 0.000379f, 0.000704f, 0.000896f,
+ 0.001095f, 0.001392f, 0.001649f, 0.002058f, 0.002235f, 0.002483f, 0.002621f, 0.002878f, 0.003214f, 0.003580f, 0.003820f, 0.004055f,
+ 0.004498f, 0.004791f, 0.005173f, 0.005692f, 0.006145f, 0.006691f, 0.007175f, 0.007874f, 0.008499f, 0.009239f, 0.010117f, 0.011032f,
+ 0.011864f, 0.012901f, 0.014282f, 0.015701f, 0.017242f, 0.019516f, 0.021469f, 0.024002f, 0.026749f, 0.029953f, 0.034027f, 0.038727f,
+ 0.044250f, 0.050568f, 0.058136f, 0.067139f, 0.078247f, 0.091614f, 0.106689f, 0.125366f, 0.147339f, 0.172974f, 0.202881f, 0.237671f,
+ 0.275879f, 0.318359f, 0.365234f, 0.415283f, 0.468018f, 0.521973f, 0.819336f, 0.832031f, 0.834473f, 0.834961f, 0.835449f, 0.835938f,
+ 0.000115f, 0.000396f, 0.000688f, 0.000885f, 0.000917f, 0.001393f, 0.001478f, 0.001590f, 0.001944f, 0.002123f, 0.002291f, 0.002644f,
+ 0.002666f, 0.003023f, 0.003197f, 0.003546f, 0.003714f, 0.004246f, 0.004551f, 0.004837f, 0.005108f, 0.005577f, 0.006054f, 0.006504f,
+ 0.007023f, 0.007633f, 0.008362f, 0.009148f, 0.009926f, 0.010742f, 0.011917f, 0.013062f, 0.014351f, 0.015991f, 0.017639f, 0.019455f,
+ 0.021729f, 0.024689f, 0.027740f, 0.031708f, 0.036102f, 0.041260f, 0.047882f, 0.055450f, 0.064392f, 0.075500f, 0.088928f, 0.104797f,
+ 0.124756f, 0.147949f, 0.175415f, 0.207275f, 0.244507f, 0.286133f, 0.332520f, 0.381836f, 0.436279f, 0.492432f, 0.808105f, 0.821289f,
+ 0.822754f, 0.824707f, 0.825195f, 0.824219f, 0.000209f, 0.000435f, 0.000493f, 0.000669f, 0.001040f, 0.001076f, 0.001254f, 0.001398f,
+ 0.001603f, 0.001697f, 0.001987f, 0.002140f, 0.002268f, 0.002472f, 0.002769f, 0.002991f, 0.003302f, 0.003572f, 0.003685f, 0.004002f,
+ 0.004337f, 0.004654f, 0.005062f, 0.005379f, 0.005871f, 0.006363f, 0.006733f, 0.007416f, 0.008102f, 0.008812f, 0.009727f, 0.010689f,
+ 0.011566f, 0.013145f, 0.014053f, 0.015762f, 0.017899f, 0.020096f, 0.022552f, 0.025528f, 0.028992f, 0.033325f, 0.038635f, 0.044952f,
+ 0.052582f, 0.061554f, 0.072998f, 0.086670f, 0.103577f, 0.124329f, 0.148804f, 0.178467f, 0.213501f, 0.253174f, 0.298828f, 0.348877f,
+ 0.403076f, 0.461914f, 0.795898f, 0.809570f, 0.812012f, 0.813477f, 0.813477f, 0.814453f, 0.000243f, 0.000322f, 0.000466f, 0.000710f,
+ 0.000863f, 0.000942f, 0.001051f, 0.001182f, 0.001369f, 0.001451f, 0.001716f, 0.001851f, 0.001968f, 0.002192f, 0.002323f, 0.002470f,
+ 0.002773f, 0.002850f, 0.003056f, 0.003399f, 0.003624f, 0.003832f, 0.004192f, 0.004467f, 0.004955f, 0.005276f, 0.005772f, 0.006084f,
+ 0.006672f, 0.007191f, 0.007828f, 0.008720f, 0.009575f, 0.010292f, 0.011505f, 0.012535f, 0.014114f, 0.016006f, 0.017838f, 0.020462f,
+ 0.023193f, 0.026489f, 0.030807f, 0.035858f, 0.041840f, 0.049652f, 0.059174f, 0.070435f, 0.084839f, 0.102783f, 0.124146f, 0.151489f,
+ 0.183472f, 0.221802f, 0.265137f, 0.315186f, 0.369629f, 0.430664f, 0.782715f, 0.796875f, 0.799805f, 0.800293f, 0.801758f, 0.801758f,
+ 0.000119f, 0.000369f, 0.000340f, 0.000595f, 0.000667f, 0.000841f, 0.001010f, 0.001086f, 0.001179f, 0.001225f, 0.001494f, 0.001555f,
+ 0.001654f, 0.001754f, 0.001965f, 0.002142f, 0.002197f, 0.002432f, 0.002619f, 0.002811f, 0.003021f, 0.003139f, 0.003567f, 0.003708f,
+ 0.004066f, 0.004360f, 0.004612f, 0.005123f, 0.005489f, 0.005878f, 0.006306f, 0.006824f, 0.007576f, 0.008286f, 0.008949f, 0.010155f,
+ 0.011322f, 0.012756f, 0.014046f, 0.015976f, 0.018250f, 0.020874f, 0.024094f, 0.027878f, 0.032867f, 0.039154f, 0.046509f, 0.055908f,
+ 0.068054f, 0.082886f, 0.102356f, 0.125732f, 0.155029f, 0.190674f, 0.232422f, 0.281006f, 0.335693f, 0.397949f, 0.770020f, 0.783691f,
+ 0.786621f, 0.787598f, 0.788086f, 0.789551f, 0.000000f, 0.000220f, 0.000275f, 0.000562f, 0.000618f, 0.000683f, 0.000733f, 0.000761f,
+ 0.000966f, 0.001022f, 0.001184f, 0.001237f, 0.001382f, 0.001552f, 0.001688f, 0.001724f, 0.001918f, 0.002024f, 0.002115f, 0.002243f,
+ 0.002403f, 0.002718f, 0.002840f, 0.003052f, 0.003330f, 0.003508f, 0.003860f, 0.004097f, 0.004314f, 0.004719f, 0.005074f, 0.005535f,
+ 0.006058f, 0.006584f, 0.007168f, 0.007874f, 0.008759f, 0.009651f, 0.011086f, 0.012459f, 0.013992f, 0.015945f, 0.018433f, 0.021408f,
+ 0.025192f, 0.029861f, 0.035950f, 0.043396f, 0.053406f, 0.065735f, 0.082031f, 0.102234f, 0.128052f, 0.160645f, 0.200073f, 0.247192f,
+ 0.301025f, 0.363281f, 0.755371f, 0.770996f, 0.772949f, 0.773926f, 0.775879f, 0.775879f, 0.000216f, 0.000102f, 0.000381f, 0.000487f,
+ 0.000429f, 0.000552f, 0.000579f, 0.000788f, 0.000804f, 0.000854f, 0.000937f, 0.000996f, 0.001078f, 0.001218f, 0.001315f, 0.001499f,
+ 0.001532f, 0.001642f, 0.001805f, 0.001825f, 0.002077f, 0.002178f, 0.002312f, 0.002396f, 0.002575f, 0.002735f, 0.002947f, 0.003317f,
+ 0.003428f, 0.003721f, 0.004185f, 0.004379f, 0.004704f, 0.005253f, 0.005650f, 0.006145f, 0.006870f, 0.007515f, 0.008415f, 0.009430f,
+ 0.010612f, 0.012093f, 0.013954f, 0.016052f, 0.018967f, 0.022476f, 0.027115f, 0.032898f, 0.040649f, 0.050690f, 0.063599f, 0.080811f,
+ 0.103210f, 0.132202f, 0.168823f, 0.213501f, 0.266602f, 0.329102f, 0.740234f, 0.756348f, 0.758789f, 0.760254f, 0.761230f, 0.761230f,
+ 0.000179f, 0.000181f, 0.000180f, 0.000289f, 0.000413f, 0.000458f, 0.000497f, 0.000620f, 0.000646f, 0.000688f, 0.000830f, 0.000868f,
+ 0.000904f, 0.000981f, 0.001024f, 0.001178f, 0.001146f, 0.001302f, 0.001382f, 0.001523f, 0.001679f, 0.001737f, 0.001824f, 0.001959f,
+ 0.002195f, 0.002283f, 0.002438f, 0.002579f, 0.002703f, 0.002939f, 0.003181f, 0.003454f, 0.003677f, 0.004051f, 0.004395f, 0.004738f,
+ 0.005283f, 0.005783f, 0.006420f, 0.007095f, 0.007988f, 0.009094f, 0.010384f, 0.011955f, 0.013939f, 0.016434f, 0.019836f, 0.024292f,
+ 0.030029f, 0.037659f, 0.048065f, 0.061890f, 0.080811f, 0.105774f, 0.138672f, 0.180542f, 0.231934f, 0.293213f, 0.724121f, 0.740234f,
+ 0.744141f, 0.745117f, 0.745605f, 0.746094f, 0.000000f, 0.000056f, 0.000263f, 0.000339f, 0.000369f, 0.000357f, 0.000376f, 0.000508f,
+ 0.000519f, 0.000558f, 0.000581f, 0.000678f, 0.000767f, 0.000775f, 0.000905f, 0.000849f, 0.000992f, 0.000942f, 0.001192f, 0.001169f,
+ 0.001204f, 0.001375f, 0.001439f, 0.001532f, 0.001634f, 0.001676f, 0.001799f, 0.001904f, 0.002165f, 0.002262f, 0.002377f, 0.002611f,
+ 0.002836f, 0.003103f, 0.003321f, 0.003550f, 0.004005f, 0.004356f, 0.004772f, 0.005295f, 0.005962f, 0.006756f, 0.007690f, 0.008690f,
+ 0.010078f, 0.011871f, 0.014252f, 0.017242f, 0.021393f, 0.027100f, 0.034851f, 0.046051f, 0.060455f, 0.081848f, 0.110474f, 0.148682f,
+ 0.197632f, 0.257568f, 0.706543f, 0.724121f, 0.727539f, 0.729492f, 0.729980f, 0.729492f, 0.000000f, 0.000130f, 0.000174f, 0.000312f,
+ 0.000290f, 0.000293f, 0.000372f, 0.000319f, 0.000397f, 0.000433f, 0.000550f, 0.000552f, 0.000564f, 0.000593f, 0.000638f, 0.000758f,
+ 0.000784f, 0.000797f, 0.000842f, 0.000937f, 0.001011f, 0.001068f, 0.001125f, 0.001231f, 0.001228f, 0.001288f, 0.001409f, 0.001465f,
+ 0.001644f, 0.001697f, 0.001965f, 0.001924f, 0.002136f, 0.002270f, 0.002436f, 0.002697f, 0.002916f, 0.003202f, 0.003492f, 0.003929f,
+ 0.004391f, 0.004887f, 0.005516f, 0.006233f, 0.007240f, 0.008461f, 0.010094f, 0.012070f, 0.014854f, 0.018585f, 0.024338f, 0.032379f,
+ 0.043884f, 0.060516f, 0.084656f, 0.118469f, 0.164185f, 0.222168f, 0.689941f, 0.708008f, 0.710449f, 0.711914f, 0.712891f, 0.712402f,
+ 0.000000f, 0.000000f, 0.000122f, 0.000226f, 0.000145f, 0.000282f, 0.000255f, 0.000247f, 0.000323f, 0.000389f, 0.000379f, 0.000435f,
+ 0.000461f, 0.000509f, 0.000535f, 0.000517f, 0.000557f, 0.000604f, 0.000649f, 0.000690f, 0.000757f, 0.000773f, 0.000836f, 0.000865f,
+ 0.000924f, 0.000957f, 0.001095f, 0.001104f, 0.001243f, 0.001361f, 0.001458f, 0.001486f, 0.001619f, 0.001745f, 0.001791f, 0.001993f,
+ 0.002100f, 0.002321f, 0.002539f, 0.002771f, 0.003084f, 0.003412f, 0.003866f, 0.004368f, 0.005062f, 0.005821f, 0.006882f, 0.008278f,
+ 0.010071f, 0.012756f, 0.016327f, 0.021774f, 0.029785f, 0.042206f, 0.061462f, 0.090149f, 0.131348f, 0.187378f, 0.669434f, 0.688965f,
+ 0.692383f, 0.694824f, 0.695801f, 0.695312f, 0.000000f, 0.000118f, 0.000113f, 0.000158f, 0.000158f, 0.000176f, 0.000224f, 0.000202f,
+ 0.000251f, 0.000260f, 0.000280f, 0.000332f, 0.000316f, 0.000365f, 0.000389f, 0.000419f, 0.000454f, 0.000435f, 0.000476f, 0.000494f,
+ 0.000516f, 0.000576f, 0.000609f, 0.000656f, 0.000678f, 0.000712f, 0.000792f, 0.000800f, 0.000852f, 0.000919f, 0.000961f, 0.001070f,
+ 0.001120f, 0.001238f, 0.001300f, 0.001480f, 0.001459f, 0.001634f, 0.001798f, 0.001947f, 0.002111f, 0.002377f, 0.002615f, 0.002966f,
+ 0.003410f, 0.003933f, 0.004585f, 0.005489f, 0.006706f, 0.008148f, 0.010757f, 0.013962f, 0.019257f, 0.027771f, 0.041931f, 0.065125f,
+ 0.101135f, 0.152832f, 0.650391f, 0.670898f, 0.674316f, 0.675293f, 0.675781f, 0.677246f, 0.000000f, 0.000000f, 0.000109f, 0.000106f,
+ 0.000121f, 0.000117f, 0.000130f, 0.000151f, 0.000161f, 0.000174f, 0.000234f, 0.000197f, 0.000205f, 0.000236f, 0.000272f, 0.000296f,
+ 0.000267f, 0.000296f, 0.000397f, 0.000344f, 0.000413f, 0.000395f, 0.000433f, 0.000434f, 0.000504f, 0.000488f, 0.000532f, 0.000550f,
+ 0.000602f, 0.000711f, 0.000675f, 0.000704f, 0.000752f, 0.000817f, 0.000896f, 0.000955f, 0.001009f, 0.001091f, 0.001223f, 0.001271f,
+ 0.001415f, 0.001560f, 0.001721f, 0.001989f, 0.002214f, 0.002508f, 0.002930f, 0.003504f, 0.004208f, 0.005169f, 0.006603f, 0.008606f,
+ 0.011864f, 0.017090f, 0.026367f, 0.043396f, 0.072571f, 0.119751f, 0.630859f, 0.650879f, 0.653809f, 0.656250f, 0.657227f, 0.657227f,
+ 0.000000f, 0.000111f, 0.000104f, 0.000100f, 0.000096f, 0.000094f, 0.000105f, 0.000096f, 0.000101f, 0.000115f, 0.000119f, 0.000155f,
+ 0.000129f, 0.000180f, 0.000186f, 0.000199f, 0.000208f, 0.000214f, 0.000232f, 0.000230f, 0.000237f, 0.000247f, 0.000303f, 0.000276f,
+ 0.000324f, 0.000332f, 0.000381f, 0.000371f, 0.000393f, 0.000428f, 0.000490f, 0.000468f, 0.000512f, 0.000540f, 0.000598f, 0.000670f,
+ 0.000673f, 0.000711f, 0.000767f, 0.000842f, 0.000894f, 0.000985f, 0.001120f, 0.001200f, 0.001416f, 0.001544f, 0.001768f, 0.002052f,
+ 0.002510f, 0.003044f, 0.003796f, 0.005016f, 0.006870f, 0.009918f, 0.015335f, 0.026077f, 0.048004f, 0.088745f, 0.610352f, 0.630859f,
+ 0.634277f, 0.636230f, 0.637207f, 0.638184f, 0.000000f, 0.000104f, 0.000098f, 0.000092f, 0.000087f, 0.000084f, 0.000081f, 0.000078f,
+ 0.000074f, 0.000070f, 0.000073f, 0.000075f, 0.000081f, 0.000081f, 0.000119f, 0.000124f, 0.000129f, 0.000115f, 0.000142f, 0.000169f,
+ 0.000155f, 0.000169f, 0.000172f, 0.000196f, 0.000209f, 0.000211f, 0.000203f, 0.000238f, 0.000245f, 0.000260f, 0.000282f, 0.000281f,
+ 0.000297f, 0.000333f, 0.000343f, 0.000374f, 0.000398f, 0.000428f, 0.000473f, 0.000494f, 0.000534f, 0.000591f, 0.000643f, 0.000708f,
+ 0.000790f, 0.000893f, 0.001040f, 0.001169f, 0.001381f, 0.001676f, 0.002123f, 0.002686f, 0.003658f, 0.005329f, 0.008347f, 0.014244f,
+ 0.027954f, 0.060638f, 0.587891f, 0.609375f, 0.613281f, 0.614746f, 0.616699f, 0.616211f, 0.000110f, 0.000094f, 0.000085f, 0.000079f,
+ 0.000075f, 0.000072f, 0.000069f, 0.000067f, 0.000065f, 0.000063f, 0.000059f, 0.000059f, 0.000054f, 0.000051f, 0.000055f, 0.000051f,
+ 0.000066f, 0.000066f, 0.000078f, 0.000074f, 0.000089f, 0.000091f, 0.000102f, 0.000109f, 0.000114f, 0.000126f, 0.000133f, 0.000130f,
+ 0.000141f, 0.000141f, 0.000156f, 0.000172f, 0.000180f, 0.000179f, 0.000206f, 0.000199f, 0.000214f, 0.000254f, 0.000247f, 0.000282f,
+ 0.000300f, 0.000324f, 0.000349f, 0.000374f, 0.000413f, 0.000459f, 0.000513f, 0.000619f, 0.000711f, 0.000823f, 0.001030f, 0.001269f,
+ 0.001724f, 0.002487f, 0.003948f, 0.007015f, 0.014122f, 0.036346f, 0.565430f, 0.586426f, 0.592285f, 0.592773f, 0.594238f, 0.594727f,
+ 0.000092f, 0.000073f, 0.000067f, 0.000062f, 0.000057f, 0.000055f, 0.000052f, 0.000052f, 0.000049f, 0.000049f, 0.000047f, 0.000046f,
+ 0.000046f, 0.000043f, 0.000041f, 0.000039f, 0.000038f, 0.000036f, 0.000039f, 0.000036f, 0.000039f, 0.000037f, 0.000039f, 0.000047f,
+ 0.000051f, 0.000057f, 0.000059f, 0.000060f, 0.000067f, 0.000071f, 0.000078f, 0.000085f, 0.000087f, 0.000091f, 0.000098f, 0.000095f,
+ 0.000102f, 0.000122f, 0.000122f, 0.000137f, 0.000143f, 0.000145f, 0.000168f, 0.000171f, 0.000197f, 0.000209f, 0.000234f, 0.000264f,
+ 0.000295f, 0.000349f, 0.000418f, 0.000520f, 0.000678f, 0.000958f, 0.001512f, 0.002745f, 0.006092f, 0.017456f, 0.542969f, 0.565430f,
+ 0.568848f, 0.569824f, 0.572266f, 0.572266f, 0.000052f, 0.000042f, 0.000037f, 0.000035f, 0.000033f, 0.000033f, 0.000032f, 0.000031f,
+ 0.000031f, 0.000029f, 0.000030f, 0.000030f, 0.000029f, 0.000028f, 0.000028f, 0.000028f, 0.000028f, 0.000028f, 0.000027f, 0.000026f,
+ 0.000024f, 0.000023f, 0.000022f, 0.000022f, 0.000021f, 0.000020f, 0.000019f, 0.000022f, 0.000020f, 0.000023f, 0.000024f, 0.000026f,
+ 0.000028f, 0.000035f, 0.000037f, 0.000038f, 0.000039f, 0.000043f, 0.000048f, 0.000050f, 0.000053f, 0.000055f, 0.000062f, 0.000059f,
+ 0.000072f, 0.000070f, 0.000087f, 0.000099f, 0.000100f, 0.000119f, 0.000142f, 0.000162f, 0.000217f, 0.000283f, 0.000425f, 0.000760f,
+ 0.001818f, 0.006405f, 0.519043f, 0.541504f, 0.546387f, 0.548828f, 0.549316f, 0.550781f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000004f, 0.000004f, 0.000006f, 0.000006f, 0.000008f, 0.000009f, 0.000009f, 0.000009f, 0.000010f,
+ 0.000010f, 0.000010f, 0.000011f, 0.000011f, 0.000011f, 0.000012f, 0.000012f, 0.000012f, 0.000012f, 0.000013f, 0.000012f, 0.000012f,
+ 0.000011f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000008f, 0.000008f, 0.000008f, 0.000008f, 0.000011f,
+ 0.000011f, 0.000012f, 0.000015f, 0.000016f, 0.000016f, 0.000018f, 0.000018f, 0.000020f, 0.000022f, 0.000024f, 0.000028f, 0.000035f,
+ 0.000036f, 0.000052f, 0.000071f, 0.000117f, 0.000260f, 0.001269f, 0.495605f, 0.518555f, 0.523926f, 0.525879f, 0.526855f, 0.527344f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000005f, 0.000021f, 0.473145f, 0.495605f,
+ 0.500000f, 0.502441f, 0.503418f, 0.503906f,
+ },
+ {
+ 0.045868f, 0.130493f, 0.205322f, 0.272705f, 0.331787f, 0.384521f, 0.431885f, 0.473389f, 0.511719f, 0.545898f, 0.576660f, 0.605469f,
+ 0.631348f, 0.654785f, 0.676758f, 0.696289f, 0.714355f, 0.732422f, 0.749023f, 0.763184f, 0.777832f, 0.790527f, 0.802734f, 0.813477f,
+ 0.824219f, 0.834961f, 0.844238f, 0.853027f, 0.862305f, 0.869629f, 0.877441f, 0.884277f, 0.892090f, 0.898926f, 0.904297f, 0.910645f,
+ 0.916992f, 0.921875f, 0.926758f, 0.931641f, 0.937012f, 0.941406f, 0.945801f, 0.950195f, 0.954102f, 0.958496f, 0.962402f, 0.966309f,
+ 0.969238f, 0.973145f, 0.976074f, 0.979492f, 0.982422f, 0.985352f, 0.988281f, 0.991211f, 0.993652f, 0.996094f, 0.997070f, 0.993164f,
+ 0.990234f, 0.987305f, 0.984375f, 0.981445f, 0.033447f, 0.097717f, 0.160400f, 0.219238f, 0.273438f, 0.323486f, 0.371582f, 0.414062f,
+ 0.454834f, 0.491211f, 0.524414f, 0.555176f, 0.583984f, 0.610840f, 0.635254f, 0.658203f, 0.678223f, 0.697754f, 0.716309f, 0.732422f,
+ 0.749023f, 0.763184f, 0.776855f, 0.790527f, 0.802734f, 0.812988f, 0.824707f, 0.834473f, 0.844238f, 0.853516f, 0.862305f, 0.870117f,
+ 0.877930f, 0.884766f, 0.892090f, 0.897949f, 0.905762f, 0.910645f, 0.917480f, 0.923340f, 0.927734f, 0.933105f, 0.937988f, 0.942871f,
+ 0.947266f, 0.951172f, 0.955566f, 0.960449f, 0.963379f, 0.967285f, 0.970703f, 0.974609f, 0.978027f, 0.981445f, 0.984863f, 0.986816f,
+ 0.989746f, 0.993164f, 0.995605f, 0.992188f, 0.988770f, 0.986328f, 0.983398f, 0.980957f, 0.024796f, 0.075195f, 0.126221f, 0.176025f,
+ 0.224976f, 0.271729f, 0.317383f, 0.359375f, 0.399902f, 0.437744f, 0.472656f, 0.505371f, 0.536133f, 0.565430f, 0.591797f, 0.615723f,
+ 0.639648f, 0.660156f, 0.681152f, 0.699219f, 0.718262f, 0.734375f, 0.749512f, 0.764648f, 0.777832f, 0.791016f, 0.802734f, 0.813965f,
+ 0.825195f, 0.835449f, 0.844727f, 0.854004f, 0.862305f, 0.871094f, 0.878418f, 0.886230f, 0.893555f, 0.900391f, 0.906738f, 0.912598f,
+ 0.917969f, 0.923828f, 0.929688f, 0.935059f, 0.939941f, 0.943848f, 0.949219f, 0.953613f, 0.958008f, 0.961914f, 0.965332f, 0.969238f,
+ 0.972656f, 0.976074f, 0.979492f, 0.982910f, 0.986328f, 0.989258f, 0.993652f, 0.990723f, 0.987793f, 0.985352f, 0.982910f, 0.979980f,
+ 0.019119f, 0.058624f, 0.100220f, 0.142578f, 0.185303f, 0.227417f, 0.269287f, 0.310059f, 0.348877f, 0.385254f, 0.421875f, 0.455566f,
+ 0.489014f, 0.518555f, 0.546875f, 0.574707f, 0.598633f, 0.624023f, 0.645508f, 0.666016f, 0.684082f, 0.702637f, 0.720703f, 0.736816f,
+ 0.751465f, 0.766113f, 0.779785f, 0.792969f, 0.804199f, 0.815918f, 0.826660f, 0.836426f, 0.846191f, 0.855957f, 0.864746f, 0.872559f,
+ 0.880371f, 0.888184f, 0.895508f, 0.902344f, 0.908691f, 0.914062f, 0.919922f, 0.925293f, 0.932129f, 0.936035f, 0.941895f, 0.946289f,
+ 0.951172f, 0.955566f, 0.959473f, 0.963867f, 0.967773f, 0.970703f, 0.975586f, 0.978516f, 0.981934f, 0.985352f, 0.991699f, 0.988770f,
+ 0.986328f, 0.983887f, 0.981445f, 0.979004f, 0.015175f, 0.046997f, 0.080688f, 0.116028f, 0.152466f, 0.189819f, 0.227417f, 0.264404f,
+ 0.301758f, 0.338623f, 0.374268f, 0.407471f, 0.439941f, 0.471924f, 0.501465f, 0.529785f, 0.556641f, 0.582031f, 0.606445f, 0.629395f,
+ 0.649902f, 0.670898f, 0.688965f, 0.708496f, 0.725098f, 0.740723f, 0.755371f, 0.769531f, 0.782715f, 0.795410f, 0.807129f, 0.818848f,
+ 0.829590f, 0.839844f, 0.849121f, 0.857910f, 0.866699f, 0.875488f, 0.882812f, 0.890625f, 0.897461f, 0.904297f, 0.910645f, 0.916992f,
+ 0.922363f, 0.928223f, 0.933594f, 0.938477f, 0.944824f, 0.949707f, 0.953613f, 0.958008f, 0.962402f, 0.966309f, 0.970703f, 0.974121f,
+ 0.977539f, 0.981934f, 0.990234f, 0.987793f, 0.984863f, 0.982910f, 0.980469f, 0.978516f, 0.012215f, 0.038452f, 0.066101f, 0.095825f,
+ 0.126831f, 0.159180f, 0.192749f, 0.226685f, 0.260986f, 0.294922f, 0.328857f, 0.363037f, 0.394531f, 0.426270f, 0.457520f, 0.486572f,
+ 0.514648f, 0.541016f, 0.567871f, 0.590820f, 0.614746f, 0.636230f, 0.657227f, 0.676270f, 0.694336f, 0.711914f, 0.729492f, 0.744141f,
+ 0.759277f, 0.773438f, 0.786621f, 0.798340f, 0.811523f, 0.822266f, 0.833496f, 0.842773f, 0.851562f, 0.861816f, 0.869629f, 0.878418f,
+ 0.885742f, 0.893066f, 0.900879f, 0.907715f, 0.913574f, 0.919922f, 0.925781f, 0.932129f, 0.937012f, 0.942871f, 0.946777f, 0.951660f,
+ 0.957031f, 0.960938f, 0.965332f, 0.969727f, 0.973633f, 0.977051f, 0.988281f, 0.986328f, 0.983887f, 0.981445f, 0.979492f, 0.976562f,
+ 0.009903f, 0.031525f, 0.054626f, 0.078979f, 0.105408f, 0.133789f, 0.162720f, 0.192993f, 0.224976f, 0.256592f, 0.288330f, 0.320312f,
+ 0.352295f, 0.383545f, 0.414062f, 0.443848f, 0.473389f, 0.500488f, 0.526367f, 0.553223f, 0.577637f, 0.600586f, 0.622070f, 0.644043f,
+ 0.664551f, 0.683105f, 0.701660f, 0.718262f, 0.734375f, 0.750000f, 0.764648f, 0.778320f, 0.791016f, 0.802734f, 0.815430f, 0.826172f,
+ 0.836426f, 0.845703f, 0.855957f, 0.864258f, 0.874023f, 0.881348f, 0.889648f, 0.896973f, 0.904297f, 0.911621f, 0.917480f, 0.922852f,
+ 0.929199f, 0.935059f, 0.939941f, 0.944824f, 0.950195f, 0.954590f, 0.959961f, 0.964355f, 0.968262f, 0.972656f, 0.986328f, 0.984375f,
+ 0.981934f, 0.979980f, 0.978027f, 0.975586f, 0.008385f, 0.026154f, 0.045319f, 0.066467f, 0.089111f, 0.113220f, 0.138916f, 0.165405f,
+ 0.192871f, 0.222290f, 0.252197f, 0.281494f, 0.311279f, 0.342285f, 0.372314f, 0.402832f, 0.431641f, 0.459473f, 0.486572f, 0.513672f,
+ 0.539062f, 0.562988f, 0.587402f, 0.609863f, 0.631348f, 0.652344f, 0.671875f, 0.689941f, 0.708008f, 0.724609f, 0.740234f, 0.755371f,
+ 0.768066f, 0.783203f, 0.795410f, 0.808105f, 0.819336f, 0.830078f, 0.840332f, 0.851074f, 0.860352f, 0.869141f, 0.877930f, 0.885742f,
+ 0.893555f, 0.900879f, 0.907715f, 0.915039f, 0.920410f, 0.926758f, 0.933105f, 0.938965f, 0.944336f, 0.949707f, 0.953613f, 0.958984f,
+ 0.962891f, 0.967285f, 0.984375f, 0.982910f, 0.980957f, 0.978516f, 0.976562f, 0.974609f, 0.006992f, 0.022324f, 0.038544f, 0.056396f,
+ 0.075317f, 0.095947f, 0.117981f, 0.141968f, 0.166504f, 0.192627f, 0.219238f, 0.246704f, 0.275879f, 0.304443f, 0.333252f, 0.362305f,
+ 0.390869f, 0.419678f, 0.447266f, 0.474121f, 0.500977f, 0.525879f, 0.551270f, 0.574219f, 0.597656f, 0.620117f, 0.641602f, 0.661133f,
+ 0.680664f, 0.698242f, 0.715332f, 0.731934f, 0.746582f, 0.761230f, 0.775391f, 0.789551f, 0.802246f, 0.813477f, 0.825195f, 0.835938f,
+ 0.846191f, 0.855957f, 0.865723f, 0.873535f, 0.882324f, 0.890625f, 0.898438f, 0.905762f, 0.912598f, 0.918945f, 0.925781f, 0.931641f,
+ 0.937012f, 0.943848f, 0.948730f, 0.954102f, 0.957520f, 0.963379f, 0.981934f, 0.980957f, 0.979004f, 0.977051f, 0.975098f, 0.973145f,
+ 0.006260f, 0.018387f, 0.032684f, 0.047821f, 0.064636f, 0.082153f, 0.101318f, 0.122009f, 0.143921f, 0.166870f, 0.191406f, 0.216187f,
+ 0.243164f, 0.269287f, 0.297119f, 0.324951f, 0.352783f, 0.380859f, 0.408691f, 0.435547f, 0.462402f, 0.489258f, 0.514160f, 0.540039f,
+ 0.563965f, 0.585938f, 0.608398f, 0.629395f, 0.649414f, 0.669434f, 0.689453f, 0.705566f, 0.722656f, 0.739258f, 0.753418f, 0.769043f,
+ 0.783203f, 0.795898f, 0.807617f, 0.819824f, 0.830566f, 0.842285f, 0.852051f, 0.862305f, 0.871094f, 0.878906f, 0.888184f, 0.895996f,
+ 0.902832f, 0.910645f, 0.917480f, 0.924316f, 0.930176f, 0.936523f, 0.942383f, 0.946777f, 0.953613f, 0.958496f, 0.979980f, 0.979004f,
+ 0.977539f, 0.975586f, 0.973633f, 0.972168f, 0.005268f, 0.016418f, 0.028091f, 0.041107f, 0.055420f, 0.070435f, 0.087341f, 0.105347f,
+ 0.124512f, 0.144531f, 0.166260f, 0.189453f, 0.213989f, 0.238037f, 0.263184f, 0.290039f, 0.317139f, 0.344238f, 0.370850f, 0.398438f,
+ 0.425293f, 0.451660f, 0.477539f, 0.503418f, 0.528320f, 0.551270f, 0.576172f, 0.598145f, 0.619629f, 0.640137f, 0.659668f, 0.680176f,
+ 0.697754f, 0.714844f, 0.731934f, 0.748047f, 0.762695f, 0.776367f, 0.790039f, 0.803223f, 0.814453f, 0.827148f, 0.837891f, 0.847656f,
+ 0.858398f, 0.868164f, 0.876953f, 0.885742f, 0.893066f, 0.901855f, 0.908691f, 0.916504f, 0.922852f, 0.929199f, 0.935059f, 0.941895f,
+ 0.947754f, 0.953125f, 0.978027f, 0.977539f, 0.975586f, 0.973633f, 0.971680f, 0.969727f, 0.004372f, 0.013802f, 0.024185f, 0.036011f,
+ 0.047729f, 0.060944f, 0.075684f, 0.090820f, 0.107788f, 0.125488f, 0.144653f, 0.165771f, 0.187012f, 0.210205f, 0.233643f, 0.258545f,
+ 0.283447f, 0.309326f, 0.335449f, 0.362305f, 0.388672f, 0.415771f, 0.441650f, 0.468018f, 0.492920f, 0.518066f, 0.542480f, 0.564941f,
+ 0.587891f, 0.609863f, 0.630859f, 0.651855f, 0.670898f, 0.689453f, 0.707520f, 0.724609f, 0.740723f, 0.755859f, 0.770996f, 0.785156f,
+ 0.799316f, 0.809570f, 0.822754f, 0.834473f, 0.845215f, 0.855469f, 0.865723f, 0.874023f, 0.883301f, 0.892090f, 0.899902f, 0.907715f,
+ 0.915039f, 0.922363f, 0.928711f, 0.935059f, 0.941406f, 0.947266f, 0.975586f, 0.975098f, 0.973633f, 0.971680f, 0.969727f, 0.968262f,
+ 0.003809f, 0.012253f, 0.021240f, 0.030884f, 0.041473f, 0.052887f, 0.065308f, 0.079224f, 0.094177f, 0.109558f, 0.126709f, 0.145142f,
+ 0.163940f, 0.184814f, 0.207397f, 0.229736f, 0.252686f, 0.276855f, 0.302246f, 0.327881f, 0.353271f, 0.380127f, 0.405762f, 0.432129f,
+ 0.457520f, 0.482422f, 0.507324f, 0.531250f, 0.556152f, 0.578125f, 0.600586f, 0.622559f, 0.642578f, 0.662109f, 0.681641f, 0.700195f,
+ 0.716797f, 0.734375f, 0.750000f, 0.766113f, 0.779297f, 0.793457f, 0.807129f, 0.819336f, 0.830078f, 0.842285f, 0.853027f, 0.862793f,
+ 0.872559f, 0.881348f, 0.890625f, 0.899414f, 0.907227f, 0.914551f, 0.920898f, 0.928223f, 0.935059f, 0.941406f, 0.973633f, 0.973145f,
+ 0.971680f, 0.970215f, 0.968262f, 0.966797f, 0.003462f, 0.010796f, 0.018646f, 0.026962f, 0.036377f, 0.046173f, 0.057190f, 0.068665f,
+ 0.081726f, 0.095520f, 0.110962f, 0.127563f, 0.144897f, 0.162476f, 0.182373f, 0.202881f, 0.225342f, 0.248291f, 0.271729f, 0.294922f,
+ 0.320312f, 0.345459f, 0.370850f, 0.397217f, 0.422607f, 0.447998f, 0.473145f, 0.498291f, 0.522461f, 0.546875f, 0.569824f, 0.591797f,
+ 0.614258f, 0.635742f, 0.655273f, 0.674805f, 0.693359f, 0.711426f, 0.729492f, 0.745605f, 0.760742f, 0.775391f, 0.789551f, 0.803223f,
+ 0.816406f, 0.828125f, 0.839844f, 0.850586f, 0.861328f, 0.871094f, 0.880371f, 0.889648f, 0.898438f, 0.906250f, 0.915039f, 0.921875f,
+ 0.928223f, 0.935547f, 0.970703f, 0.970215f, 0.970215f, 0.967773f, 0.966309f, 0.965332f, 0.002872f, 0.009338f, 0.016174f, 0.024231f,
+ 0.031525f, 0.040558f, 0.050140f, 0.060455f, 0.071472f, 0.084167f, 0.097168f, 0.111450f, 0.127197f, 0.143433f, 0.160889f, 0.179565f,
+ 0.199463f, 0.220825f, 0.242554f, 0.265625f, 0.288818f, 0.312744f, 0.338135f, 0.362793f, 0.387939f, 0.414307f, 0.439453f, 0.464355f,
+ 0.489014f, 0.514648f, 0.537598f, 0.561523f, 0.583984f, 0.606445f, 0.627930f, 0.648926f, 0.667480f, 0.687988f, 0.705566f, 0.723633f,
+ 0.740234f, 0.756348f, 0.771484f, 0.786621f, 0.799805f, 0.812012f, 0.825195f, 0.836426f, 0.849121f, 0.859375f, 0.870605f, 0.879883f,
+ 0.888672f, 0.897461f, 0.905762f, 0.915039f, 0.921387f, 0.928711f, 0.967773f, 0.969238f, 0.966797f, 0.966797f, 0.964355f, 0.963379f,
+ 0.002750f, 0.008202f, 0.014519f, 0.021301f, 0.028183f, 0.035828f, 0.044342f, 0.053375f, 0.063354f, 0.074219f, 0.085876f, 0.098083f,
+ 0.111938f, 0.126343f, 0.142212f, 0.158936f, 0.177124f, 0.196411f, 0.216553f, 0.237427f, 0.260010f, 0.282715f, 0.306641f, 0.330811f,
+ 0.355957f, 0.381104f, 0.405518f, 0.431152f, 0.456543f, 0.480957f, 0.504883f, 0.529785f, 0.553223f, 0.577148f, 0.599121f, 0.620605f,
+ 0.642090f, 0.662598f, 0.682617f, 0.701172f, 0.718750f, 0.735352f, 0.751953f, 0.768066f, 0.783691f, 0.796875f, 0.810547f, 0.822754f,
+ 0.835938f, 0.847656f, 0.858398f, 0.869141f, 0.879395f, 0.888672f, 0.897949f, 0.906250f, 0.914551f, 0.922363f, 0.965820f, 0.966797f,
+ 0.965820f, 0.963867f, 0.963379f, 0.961426f, 0.002264f, 0.007446f, 0.012741f, 0.018494f, 0.024536f, 0.031769f, 0.039154f, 0.047424f,
+ 0.056122f, 0.065308f, 0.075623f, 0.087219f, 0.098755f, 0.111328f, 0.125854f, 0.140869f, 0.157349f, 0.174805f, 0.193115f, 0.212402f,
+ 0.233643f, 0.254883f, 0.276855f, 0.300293f, 0.324463f, 0.348389f, 0.374023f, 0.398193f, 0.423340f, 0.448242f, 0.473877f, 0.498291f,
+ 0.521973f, 0.545898f, 0.569824f, 0.592773f, 0.614258f, 0.635742f, 0.657227f, 0.676270f, 0.695801f, 0.714844f, 0.731445f, 0.749512f,
+ 0.765137f, 0.779785f, 0.793945f, 0.808594f, 0.821777f, 0.833496f, 0.846191f, 0.858398f, 0.868652f, 0.879395f, 0.888672f, 0.897949f,
+ 0.906738f, 0.916016f, 0.962402f, 0.963867f, 0.962891f, 0.961914f, 0.960938f, 0.958984f, 0.002377f, 0.006668f, 0.011467f, 0.016693f,
+ 0.021820f, 0.028091f, 0.034485f, 0.041748f, 0.049347f, 0.057678f, 0.066589f, 0.076538f, 0.086975f, 0.098816f, 0.111816f, 0.125366f,
+ 0.139404f, 0.155151f, 0.171875f, 0.190186f, 0.208496f, 0.228760f, 0.250244f, 0.271973f, 0.294189f, 0.317871f, 0.341797f, 0.365479f,
+ 0.391357f, 0.415771f, 0.440430f, 0.466797f, 0.491699f, 0.515625f, 0.539551f, 0.563477f, 0.585938f, 0.608887f, 0.630371f, 0.651855f,
+ 0.672363f, 0.692383f, 0.710449f, 0.729492f, 0.745605f, 0.762695f, 0.778320f, 0.792480f, 0.807129f, 0.820801f, 0.833984f, 0.846680f,
+ 0.857910f, 0.869141f, 0.879395f, 0.889648f, 0.899414f, 0.907715f, 0.959473f, 0.961426f, 0.960449f, 0.959961f, 0.958496f, 0.957031f,
+ 0.002062f, 0.006180f, 0.010201f, 0.015053f, 0.019531f, 0.025116f, 0.030960f, 0.037292f, 0.043915f, 0.051117f, 0.059570f, 0.067749f,
+ 0.076843f, 0.087708f, 0.099060f, 0.110352f, 0.123413f, 0.138062f, 0.153198f, 0.169067f, 0.186768f, 0.204956f, 0.224487f, 0.244873f,
+ 0.265625f, 0.288330f, 0.311768f, 0.335205f, 0.359863f, 0.384521f, 0.409668f, 0.434082f, 0.459717f, 0.483887f, 0.508789f, 0.533203f,
+ 0.557617f, 0.580566f, 0.603516f, 0.626465f, 0.646484f, 0.667969f, 0.687500f, 0.708008f, 0.726074f, 0.744141f, 0.760742f, 0.776367f,
+ 0.791504f, 0.806641f, 0.820312f, 0.833496f, 0.846191f, 0.858398f, 0.869629f, 0.879883f, 0.890625f, 0.900879f, 0.956543f, 0.958496f,
+ 0.958008f, 0.956543f, 0.955566f, 0.954102f, 0.001774f, 0.005459f, 0.009155f, 0.013290f, 0.017807f, 0.022537f, 0.027527f, 0.033081f,
+ 0.038818f, 0.045380f, 0.052643f, 0.060516f, 0.068420f, 0.077942f, 0.087952f, 0.098572f, 0.109863f, 0.122925f, 0.136230f, 0.150146f,
+ 0.166382f, 0.183105f, 0.201172f, 0.219482f, 0.240112f, 0.261230f, 0.283203f, 0.305664f, 0.329590f, 0.353027f, 0.377930f, 0.402344f,
+ 0.427490f, 0.453369f, 0.478516f, 0.502930f, 0.527832f, 0.552246f, 0.575684f, 0.598145f, 0.621094f, 0.643555f, 0.664551f, 0.685547f,
+ 0.704590f, 0.723633f, 0.742188f, 0.759277f, 0.775879f, 0.791016f, 0.806152f, 0.820801f, 0.833496f, 0.847168f, 0.859375f, 0.870605f,
+ 0.881348f, 0.893066f, 0.953125f, 0.956055f, 0.955566f, 0.954102f, 0.953125f, 0.951660f, 0.001655f, 0.004757f, 0.008308f, 0.011993f,
+ 0.015808f, 0.020187f, 0.024780f, 0.029434f, 0.034851f, 0.040741f, 0.046997f, 0.053650f, 0.061096f, 0.069397f, 0.078064f, 0.087280f,
+ 0.097351f, 0.108887f, 0.121033f, 0.134277f, 0.148560f, 0.163330f, 0.180054f, 0.197144f, 0.215332f, 0.235718f, 0.255859f, 0.277588f,
+ 0.300049f, 0.323730f, 0.347656f, 0.371826f, 0.396729f, 0.422607f, 0.447021f, 0.472168f, 0.497803f, 0.521973f, 0.547363f, 0.571289f,
+ 0.594238f, 0.618164f, 0.640137f, 0.662109f, 0.682617f, 0.702637f, 0.722168f, 0.739746f, 0.758301f, 0.774902f, 0.790527f, 0.806641f,
+ 0.820801f, 0.834961f, 0.848633f, 0.860352f, 0.872559f, 0.883789f, 0.949707f, 0.953125f, 0.952148f, 0.951172f, 0.950684f, 0.948730f,
+ 0.001418f, 0.004456f, 0.007584f, 0.010803f, 0.014450f, 0.018005f, 0.022186f, 0.026398f, 0.031342f, 0.036224f, 0.041687f, 0.048126f,
+ 0.054382f, 0.061676f, 0.069641f, 0.077759f, 0.086914f, 0.097168f, 0.107910f, 0.119263f, 0.132446f, 0.145752f, 0.161011f, 0.176758f,
+ 0.193726f, 0.211914f, 0.231201f, 0.251709f, 0.272705f, 0.294922f, 0.318604f, 0.342041f, 0.366455f, 0.390869f, 0.416992f, 0.441895f,
+ 0.467285f, 0.493164f, 0.517578f, 0.541992f, 0.566895f, 0.590820f, 0.614746f, 0.637207f, 0.660156f, 0.681152f, 0.701172f, 0.720703f,
+ 0.739746f, 0.758301f, 0.775391f, 0.791992f, 0.807617f, 0.821289f, 0.836426f, 0.850586f, 0.863281f, 0.874512f, 0.946777f, 0.949707f,
+ 0.949707f, 0.948730f, 0.947266f, 0.946289f, 0.001213f, 0.003864f, 0.006721f, 0.009796f, 0.012932f, 0.016037f, 0.020218f, 0.024231f,
+ 0.028275f, 0.032379f, 0.037567f, 0.042603f, 0.048584f, 0.054993f, 0.061798f, 0.069519f, 0.077637f, 0.086182f, 0.095703f, 0.106323f,
+ 0.117676f, 0.130127f, 0.143555f, 0.158203f, 0.173462f, 0.189941f, 0.207886f, 0.226807f, 0.247192f, 0.267822f, 0.290527f, 0.312500f,
+ 0.336670f, 0.360352f, 0.385742f, 0.410889f, 0.437256f, 0.462646f, 0.488281f, 0.513184f, 0.539062f, 0.563477f, 0.588379f, 0.612305f,
+ 0.636230f, 0.657715f, 0.679199f, 0.700195f, 0.720703f, 0.740234f, 0.758301f, 0.775879f, 0.793945f, 0.809082f, 0.824219f, 0.838867f,
+ 0.852539f, 0.865234f, 0.942871f, 0.946777f, 0.946777f, 0.945312f, 0.944824f, 0.943359f, 0.001063f, 0.003754f, 0.005909f, 0.008789f,
+ 0.011780f, 0.014671f, 0.017792f, 0.021378f, 0.025238f, 0.029221f, 0.033417f, 0.038300f, 0.043488f, 0.048828f, 0.054779f, 0.061554f,
+ 0.068604f, 0.076721f, 0.085388f, 0.094482f, 0.104614f, 0.115845f, 0.128296f, 0.141113f, 0.155029f, 0.170044f, 0.186401f, 0.204224f,
+ 0.222778f, 0.242188f, 0.263916f, 0.285156f, 0.308350f, 0.331787f, 0.355957f, 0.381348f, 0.407227f, 0.432617f, 0.459229f, 0.484619f,
+ 0.509277f, 0.536133f, 0.560547f, 0.585938f, 0.609863f, 0.633301f, 0.657715f, 0.678711f, 0.699707f, 0.721191f, 0.740723f, 0.759277f,
+ 0.777344f, 0.794922f, 0.811035f, 0.826660f, 0.841797f, 0.855469f, 0.939453f, 0.943359f, 0.943359f, 0.942871f, 0.941895f, 0.940918f,
+ 0.001175f, 0.003069f, 0.005558f, 0.007912f, 0.010712f, 0.013199f, 0.016235f, 0.019547f, 0.022659f, 0.026138f, 0.030151f, 0.034424f,
+ 0.038940f, 0.044067f, 0.049255f, 0.054993f, 0.061493f, 0.068359f, 0.075928f, 0.084290f, 0.093262f, 0.103760f, 0.114319f, 0.126099f,
+ 0.138550f, 0.152466f, 0.167114f, 0.183472f, 0.200439f, 0.219238f, 0.239014f, 0.259277f, 0.281250f, 0.303711f, 0.327148f, 0.351807f,
+ 0.376709f, 0.402344f, 0.428955f, 0.453857f, 0.480713f, 0.507324f, 0.533203f, 0.558594f, 0.583984f, 0.609375f, 0.633301f, 0.656738f,
+ 0.678711f, 0.700195f, 0.722168f, 0.742188f, 0.761719f, 0.780273f, 0.797852f, 0.813477f, 0.830078f, 0.845703f, 0.935547f, 0.939453f,
+ 0.939453f, 0.938965f, 0.937988f, 0.937012f, 0.001089f, 0.002945f, 0.005066f, 0.007225f, 0.009575f, 0.012016f, 0.014656f, 0.017288f,
+ 0.020142f, 0.023712f, 0.026764f, 0.030640f, 0.034637f, 0.039490f, 0.043854f, 0.048706f, 0.054688f, 0.060913f, 0.067871f, 0.075256f,
+ 0.083191f, 0.092163f, 0.101868f, 0.111938f, 0.123657f, 0.136108f, 0.149658f, 0.164185f, 0.179932f, 0.196777f, 0.215454f, 0.234375f,
+ 0.255371f, 0.276611f, 0.299805f, 0.323486f, 0.347656f, 0.373047f, 0.398682f, 0.425293f, 0.451172f, 0.477783f, 0.504883f, 0.530762f,
+ 0.557617f, 0.583008f, 0.607910f, 0.632812f, 0.657227f, 0.680664f, 0.702637f, 0.724121f, 0.743652f, 0.764160f, 0.783691f, 0.800781f,
+ 0.818848f, 0.833984f, 0.930664f, 0.936035f, 0.936035f, 0.935547f, 0.934570f, 0.933594f, 0.000847f, 0.002800f, 0.004562f, 0.006786f,
+ 0.008804f, 0.011017f, 0.013145f, 0.015640f, 0.018509f, 0.021255f, 0.024277f, 0.027603f, 0.030991f, 0.035248f, 0.039642f, 0.043854f,
+ 0.048798f, 0.054504f, 0.060516f, 0.067017f, 0.073914f, 0.082092f, 0.090515f, 0.099854f, 0.109863f, 0.121521f, 0.133545f, 0.146851f,
+ 0.161133f, 0.176514f, 0.192993f, 0.211426f, 0.230957f, 0.251465f, 0.272705f, 0.295410f, 0.319092f, 0.343994f, 0.369385f, 0.395020f,
+ 0.421631f, 0.448242f, 0.475342f, 0.501953f, 0.529785f, 0.556152f, 0.582031f, 0.608887f, 0.633789f, 0.658203f, 0.681152f, 0.704590f,
+ 0.726074f, 0.748535f, 0.768555f, 0.787109f, 0.804199f, 0.822754f, 0.926758f, 0.931641f, 0.932129f, 0.931641f, 0.931152f, 0.930176f,
+ 0.001035f, 0.002598f, 0.004147f, 0.006062f, 0.007942f, 0.009933f, 0.012405f, 0.014565f, 0.016174f, 0.019135f, 0.021988f, 0.024811f,
+ 0.028259f, 0.031616f, 0.035065f, 0.039429f, 0.043884f, 0.048615f, 0.053833f, 0.059723f, 0.065796f, 0.072693f, 0.080383f, 0.088745f,
+ 0.098206f, 0.107727f, 0.119080f, 0.130981f, 0.143677f, 0.157959f, 0.173218f, 0.189941f, 0.207642f, 0.226929f, 0.247437f, 0.269043f,
+ 0.291748f, 0.315674f, 0.340576f, 0.366211f, 0.392578f, 0.419434f, 0.446533f, 0.473877f, 0.502441f, 0.528320f, 0.556152f, 0.583008f,
+ 0.609375f, 0.635254f, 0.660156f, 0.684082f, 0.706543f, 0.729980f, 0.751953f, 0.771973f, 0.792480f, 0.810547f, 0.922363f, 0.927734f,
+ 0.928223f, 0.928223f, 0.927246f, 0.926758f, 0.000775f, 0.002325f, 0.003843f, 0.005573f, 0.007397f, 0.009163f, 0.010857f, 0.012939f,
+ 0.015312f, 0.017273f, 0.019684f, 0.022537f, 0.025070f, 0.028183f, 0.031616f, 0.035461f, 0.038940f, 0.043671f, 0.048096f, 0.053131f,
+ 0.058411f, 0.064941f, 0.071777f, 0.078857f, 0.086731f, 0.096130f, 0.105835f, 0.116760f, 0.128296f, 0.140747f, 0.154907f, 0.170410f,
+ 0.186646f, 0.204834f, 0.223633f, 0.243896f, 0.265625f, 0.288330f, 0.312012f, 0.337402f, 0.363037f, 0.389648f, 0.417480f, 0.444824f,
+ 0.473633f, 0.500000f, 0.529297f, 0.556641f, 0.583984f, 0.610840f, 0.638184f, 0.662598f, 0.687988f, 0.711914f, 0.734375f, 0.755859f,
+ 0.777832f, 0.798828f, 0.916992f, 0.922852f, 0.923828f, 0.923828f, 0.923340f, 0.922363f, 0.000617f, 0.002234f, 0.003510f, 0.005035f,
+ 0.006397f, 0.008156f, 0.010033f, 0.011665f, 0.013481f, 0.015717f, 0.017700f, 0.020004f, 0.022766f, 0.025391f, 0.028214f, 0.031586f,
+ 0.035217f, 0.038757f, 0.042999f, 0.047668f, 0.052368f, 0.057434f, 0.063538f, 0.070190f, 0.077698f, 0.085449f, 0.094299f, 0.103394f,
+ 0.113953f, 0.125610f, 0.137817f, 0.151855f, 0.167236f, 0.183228f, 0.200806f, 0.219971f, 0.240479f, 0.262451f, 0.285645f, 0.309570f,
+ 0.334961f, 0.360596f, 0.387939f, 0.416016f, 0.444092f, 0.473145f, 0.501465f, 0.529785f, 0.558105f, 0.585938f, 0.614258f, 0.640137f,
+ 0.666992f, 0.692383f, 0.716797f, 0.739746f, 0.763184f, 0.784180f, 0.912109f, 0.918457f, 0.919434f, 0.919434f, 0.918457f, 0.917969f,
+ 0.000665f, 0.002039f, 0.003386f, 0.004520f, 0.005989f, 0.007511f, 0.009262f, 0.010902f, 0.012314f, 0.014320f, 0.015869f, 0.018127f,
+ 0.020248f, 0.022476f, 0.025284f, 0.028122f, 0.030991f, 0.034668f, 0.038239f, 0.042206f, 0.046539f, 0.051361f, 0.056610f, 0.062347f,
+ 0.068604f, 0.075623f, 0.083313f, 0.092041f, 0.101379f, 0.111572f, 0.122986f, 0.135132f, 0.148926f, 0.164062f, 0.180054f, 0.197510f,
+ 0.216797f, 0.237183f, 0.259521f, 0.282227f, 0.307129f, 0.332764f, 0.358887f, 0.386475f, 0.415527f, 0.443604f, 0.473389f, 0.501465f,
+ 0.530762f, 0.560059f, 0.588867f, 0.617676f, 0.645020f, 0.671387f, 0.698242f, 0.722656f, 0.746094f, 0.770020f, 0.906738f, 0.913574f,
+ 0.915039f, 0.914551f, 0.914062f, 0.914062f, 0.000661f, 0.001754f, 0.002831f, 0.004066f, 0.005333f, 0.006668f, 0.008286f, 0.009773f,
+ 0.011124f, 0.012794f, 0.014320f, 0.016357f, 0.018036f, 0.020386f, 0.022766f, 0.025192f, 0.027924f, 0.030807f, 0.034027f, 0.037628f,
+ 0.041321f, 0.045349f, 0.050262f, 0.055328f, 0.060699f, 0.066833f, 0.073669f, 0.081360f, 0.089600f, 0.099060f, 0.108826f, 0.119995f,
+ 0.132324f, 0.145874f, 0.160889f, 0.176880f, 0.194702f, 0.213379f, 0.234497f, 0.256104f, 0.280029f, 0.304688f, 0.330811f, 0.358154f,
+ 0.385986f, 0.415039f, 0.444092f, 0.474609f, 0.503418f, 0.534180f, 0.563965f, 0.592773f, 0.621094f, 0.650391f, 0.678223f, 0.704590f,
+ 0.730469f, 0.754883f, 0.901855f, 0.908691f, 0.910156f, 0.909668f, 0.909668f, 0.908691f, 0.000653f, 0.001667f, 0.002666f, 0.003887f,
+ 0.004986f, 0.006359f, 0.007202f, 0.008751f, 0.010300f, 0.011757f, 0.012939f, 0.014595f, 0.016281f, 0.018234f, 0.020142f, 0.022415f,
+ 0.025101f, 0.027466f, 0.030182f, 0.033539f, 0.036865f, 0.040680f, 0.044342f, 0.048798f, 0.053619f, 0.059479f, 0.065491f, 0.071716f,
+ 0.079285f, 0.087341f, 0.096497f, 0.106445f, 0.117615f, 0.129395f, 0.142822f, 0.157959f, 0.174194f, 0.192139f, 0.210938f, 0.231567f,
+ 0.253906f, 0.277832f, 0.302979f, 0.329590f, 0.357422f, 0.385986f, 0.415283f, 0.446045f, 0.475830f, 0.506348f, 0.537109f, 0.567871f,
+ 0.599121f, 0.628418f, 0.657227f, 0.685547f, 0.712891f, 0.739746f, 0.895508f, 0.902344f, 0.904297f, 0.904785f, 0.904297f, 0.904297f,
+ 0.000372f, 0.001397f, 0.002384f, 0.003529f, 0.004509f, 0.005505f, 0.007015f, 0.008026f, 0.009201f, 0.010292f, 0.011536f, 0.013130f,
+ 0.014915f, 0.016266f, 0.018387f, 0.020218f, 0.022034f, 0.024399f, 0.026901f, 0.029617f, 0.032623f, 0.035950f, 0.039032f, 0.043030f,
+ 0.047577f, 0.052612f, 0.057556f, 0.063477f, 0.070007f, 0.077209f, 0.085083f, 0.094177f, 0.103821f, 0.114563f, 0.126709f, 0.140015f,
+ 0.154785f, 0.171143f, 0.188477f, 0.208252f, 0.229004f, 0.251709f, 0.275879f, 0.302002f, 0.328613f, 0.356445f, 0.385986f, 0.416504f,
+ 0.447510f, 0.478760f, 0.510254f, 0.542480f, 0.573730f, 0.604980f, 0.635742f, 0.665527f, 0.694336f, 0.722656f, 0.887695f, 0.897949f,
+ 0.898926f, 0.899414f, 0.897949f, 0.898438f, 0.000661f, 0.001222f, 0.002275f, 0.003313f, 0.004181f, 0.005119f, 0.006275f, 0.007126f,
+ 0.007988f, 0.009354f, 0.010300f, 0.012062f, 0.013313f, 0.014786f, 0.016251f, 0.018021f, 0.019516f, 0.021896f, 0.024017f, 0.026428f,
+ 0.029022f, 0.031799f, 0.034698f, 0.038422f, 0.042236f, 0.046265f, 0.050598f, 0.055786f, 0.061493f, 0.067871f, 0.074951f, 0.082458f,
+ 0.091187f, 0.101135f, 0.111694f, 0.123779f, 0.137207f, 0.151978f, 0.167969f, 0.186157f, 0.205688f, 0.226929f, 0.249756f, 0.274658f,
+ 0.301025f, 0.328613f, 0.357178f, 0.387207f, 0.418457f, 0.450195f, 0.482422f, 0.516113f, 0.548340f, 0.580566f, 0.612305f, 0.644043f,
+ 0.674805f, 0.705566f, 0.882812f, 0.890625f, 0.892578f, 0.893066f, 0.892578f, 0.893066f, 0.000379f, 0.001211f, 0.002066f, 0.003040f,
+ 0.003834f, 0.004616f, 0.005608f, 0.006550f, 0.007347f, 0.008408f, 0.009529f, 0.010452f, 0.011940f, 0.013039f, 0.014313f, 0.015961f,
+ 0.017746f, 0.019180f, 0.021210f, 0.023239f, 0.025482f, 0.028030f, 0.030640f, 0.033661f, 0.036987f, 0.040466f, 0.044617f, 0.048828f,
+ 0.053894f, 0.059235f, 0.065674f, 0.072632f, 0.079956f, 0.089050f, 0.098267f, 0.109009f, 0.120789f, 0.134521f, 0.148926f, 0.165405f,
+ 0.183228f, 0.202881f, 0.224731f, 0.248779f, 0.273193f, 0.300049f, 0.329346f, 0.358887f, 0.390381f, 0.421387f, 0.454590f, 0.488770f,
+ 0.521484f, 0.555176f, 0.588379f, 0.621582f, 0.654785f, 0.686523f, 0.875488f, 0.885254f, 0.886719f, 0.886230f, 0.886719f, 0.886230f,
+ 0.000282f, 0.001126f, 0.002010f, 0.002661f, 0.003340f, 0.004269f, 0.005192f, 0.005711f, 0.006638f, 0.007278f, 0.008377f, 0.009483f,
+ 0.010567f, 0.011742f, 0.012871f, 0.014061f, 0.015480f, 0.017242f, 0.018799f, 0.020584f, 0.022461f, 0.024490f, 0.027100f, 0.029434f,
+ 0.032532f, 0.035706f, 0.038971f, 0.042969f, 0.047241f, 0.052094f, 0.057373f, 0.063232f, 0.070007f, 0.077637f, 0.086243f, 0.095764f,
+ 0.106323f, 0.118164f, 0.131470f, 0.146118f, 0.162720f, 0.181030f, 0.200928f, 0.223022f, 0.247070f, 0.272705f, 0.300537f, 0.330322f,
+ 0.360107f, 0.393066f, 0.426270f, 0.459473f, 0.494629f, 0.529297f, 0.564453f, 0.598633f, 0.633789f, 0.666504f, 0.868652f, 0.878418f,
+ 0.879395f, 0.880371f, 0.879883f, 0.879395f, 0.000340f, 0.000963f, 0.001826f, 0.002459f, 0.003307f, 0.003847f, 0.004719f, 0.004936f,
+ 0.005802f, 0.006695f, 0.007748f, 0.008522f, 0.009506f, 0.010376f, 0.011383f, 0.012787f, 0.013901f, 0.015182f, 0.016663f, 0.018051f,
+ 0.019821f, 0.021759f, 0.023590f, 0.025818f, 0.028519f, 0.030975f, 0.034210f, 0.037811f, 0.040802f, 0.045349f, 0.050201f, 0.055298f,
+ 0.061310f, 0.067688f, 0.074768f, 0.083557f, 0.092590f, 0.103149f, 0.115479f, 0.128906f, 0.142944f, 0.160278f, 0.178345f, 0.198975f,
+ 0.221802f, 0.246094f, 0.272949f, 0.301514f, 0.331543f, 0.363525f, 0.396729f, 0.430908f, 0.466553f, 0.501953f, 0.538086f, 0.574707f,
+ 0.610840f, 0.646973f, 0.860352f, 0.870605f, 0.873047f, 0.873047f, 0.873535f, 0.872559f, 0.000225f, 0.001021f, 0.001653f, 0.002302f,
+ 0.002827f, 0.003448f, 0.003937f, 0.004486f, 0.004986f, 0.006252f, 0.007000f, 0.007416f, 0.008224f, 0.009300f, 0.009972f, 0.011322f,
+ 0.012115f, 0.013428f, 0.014557f, 0.015991f, 0.017532f, 0.018982f, 0.020706f, 0.022781f, 0.024567f, 0.027161f, 0.029770f, 0.032623f,
+ 0.035828f, 0.039551f, 0.043030f, 0.047852f, 0.052795f, 0.058716f, 0.065125f, 0.072266f, 0.080566f, 0.089661f, 0.100403f, 0.112854f,
+ 0.125732f, 0.140991f, 0.157349f, 0.176514f, 0.197510f, 0.220581f, 0.245850f, 0.273438f, 0.302979f, 0.334717f, 0.367676f, 0.401855f,
+ 0.437256f, 0.474609f, 0.512695f, 0.549316f, 0.588379f, 0.625000f, 0.853027f, 0.863281f, 0.866211f, 0.866211f, 0.866699f, 0.866211f,
+ 0.000324f, 0.000845f, 0.001534f, 0.002172f, 0.002474f, 0.003115f, 0.003824f, 0.003937f, 0.004848f, 0.005417f, 0.006222f, 0.006760f,
+ 0.007446f, 0.008186f, 0.009102f, 0.009888f, 0.010620f, 0.011551f, 0.012878f, 0.013954f, 0.015106f, 0.016495f, 0.018143f, 0.019669f,
+ 0.021713f, 0.023468f, 0.025818f, 0.028183f, 0.031021f, 0.033783f, 0.037445f, 0.041534f, 0.045532f, 0.050598f, 0.056152f, 0.062500f,
+ 0.069580f, 0.077698f, 0.086914f, 0.097717f, 0.108948f, 0.123047f, 0.138184f, 0.155273f, 0.174438f, 0.196167f, 0.219604f, 0.246094f,
+ 0.274902f, 0.305420f, 0.338379f, 0.372314f, 0.408936f, 0.445801f, 0.484131f, 0.523438f, 0.562988f, 0.604492f, 0.843262f, 0.856445f,
+ 0.857422f, 0.857910f, 0.858398f, 0.858398f, 0.000331f, 0.000944f, 0.001288f, 0.001833f, 0.002388f, 0.002769f, 0.003216f, 0.003664f,
+ 0.004276f, 0.004822f, 0.005173f, 0.005951f, 0.006531f, 0.007156f, 0.007896f, 0.008438f, 0.009430f, 0.010117f, 0.011208f, 0.012253f,
+ 0.012970f, 0.014297f, 0.015572f, 0.017059f, 0.018692f, 0.020264f, 0.022125f, 0.024323f, 0.026474f, 0.029343f, 0.032288f, 0.035461f,
+ 0.039062f, 0.043335f, 0.047821f, 0.053558f, 0.059509f, 0.067078f, 0.074341f, 0.083862f, 0.094360f, 0.106323f, 0.120117f, 0.135254f,
+ 0.153442f, 0.172852f, 0.195190f, 0.220337f, 0.246948f, 0.276611f, 0.308594f, 0.343262f, 0.379150f, 0.416992f, 0.455811f, 0.496582f,
+ 0.537598f, 0.579590f, 0.834473f, 0.847656f, 0.850098f, 0.850098f, 0.849609f, 0.850098f, 0.000316f, 0.000824f, 0.001088f, 0.001693f,
+ 0.002062f, 0.002403f, 0.003027f, 0.003460f, 0.003712f, 0.004166f, 0.004765f, 0.005138f, 0.005871f, 0.006218f, 0.006924f, 0.007431f,
+ 0.008255f, 0.008850f, 0.009781f, 0.010590f, 0.011391f, 0.012367f, 0.013474f, 0.014709f, 0.015823f, 0.017685f, 0.018982f, 0.020844f,
+ 0.022629f, 0.025070f, 0.027496f, 0.030380f, 0.033447f, 0.037140f, 0.041168f, 0.045654f, 0.050720f, 0.057251f, 0.063965f, 0.071777f,
+ 0.080811f, 0.091248f, 0.103638f, 0.117126f, 0.133179f, 0.151001f, 0.171631f, 0.194580f, 0.220337f, 0.248413f, 0.279785f, 0.313965f,
+ 0.349365f, 0.386963f, 0.426514f, 0.468262f, 0.510742f, 0.555176f, 0.825684f, 0.838379f, 0.839844f, 0.841309f, 0.841309f, 0.841309f,
+ 0.000210f, 0.000717f, 0.001084f, 0.001454f, 0.001882f, 0.002096f, 0.002468f, 0.002996f, 0.003395f, 0.003632f, 0.004066f, 0.004467f,
+ 0.005020f, 0.005569f, 0.005917f, 0.006474f, 0.006958f, 0.007576f, 0.008453f, 0.009140f, 0.010002f, 0.010689f, 0.011520f, 0.012596f,
+ 0.013695f, 0.014938f, 0.016220f, 0.017593f, 0.019424f, 0.020996f, 0.023331f, 0.025696f, 0.028427f, 0.031067f, 0.034668f, 0.038422f,
+ 0.042908f, 0.048096f, 0.054016f, 0.060699f, 0.068909f, 0.077515f, 0.088501f, 0.100464f, 0.114624f, 0.130615f, 0.149048f, 0.170654f,
+ 0.194214f, 0.222046f, 0.251465f, 0.283936f, 0.319580f, 0.357422f, 0.397461f, 0.440186f, 0.484375f, 0.528320f, 0.814941f, 0.828613f,
+ 0.830078f, 0.832031f, 0.831543f, 0.833008f, 0.000234f, 0.000576f, 0.000939f, 0.001362f, 0.001481f, 0.001999f, 0.002228f, 0.002714f,
+ 0.002846f, 0.003218f, 0.003555f, 0.003933f, 0.004356f, 0.004787f, 0.005169f, 0.005604f, 0.006145f, 0.006554f, 0.007275f, 0.007675f,
+ 0.008293f, 0.009201f, 0.009979f, 0.010651f, 0.011497f, 0.012527f, 0.013893f, 0.014771f, 0.016373f, 0.017975f, 0.019455f, 0.021683f,
+ 0.023895f, 0.026077f, 0.029114f, 0.032257f, 0.036072f, 0.040405f, 0.045197f, 0.050903f, 0.057770f, 0.065613f, 0.074524f, 0.085388f,
+ 0.097656f, 0.111694f, 0.128540f, 0.147949f, 0.170166f, 0.195435f, 0.223389f, 0.255127f, 0.289551f, 0.327393f, 0.367432f, 0.410400f,
+ 0.455078f, 0.502441f, 0.804199f, 0.818848f, 0.821289f, 0.822266f, 0.822754f, 0.822266f, 0.000213f, 0.000506f, 0.000756f, 0.001184f,
+ 0.001396f, 0.001697f, 0.002010f, 0.002474f, 0.002569f, 0.002918f, 0.003090f, 0.003496f, 0.003855f, 0.004139f, 0.004478f, 0.004852f,
+ 0.005253f, 0.005665f, 0.006100f, 0.006638f, 0.007080f, 0.007744f, 0.008293f, 0.009132f, 0.009750f, 0.010658f, 0.011536f, 0.012413f,
+ 0.013779f, 0.014908f, 0.016510f, 0.017990f, 0.019623f, 0.021637f, 0.024109f, 0.026718f, 0.029922f, 0.033539f, 0.037567f, 0.042572f,
+ 0.048279f, 0.054413f, 0.062042f, 0.071472f, 0.081909f, 0.094604f, 0.109436f, 0.127075f, 0.146484f, 0.170044f, 0.196533f, 0.226929f,
+ 0.260254f, 0.296875f, 0.337402f, 0.380615f, 0.426025f, 0.475342f, 0.792969f, 0.807617f, 0.811035f, 0.811523f, 0.812012f, 0.813477f,
+ 0.000119f, 0.000422f, 0.000883f, 0.001027f, 0.001189f, 0.001604f, 0.001783f, 0.001913f, 0.002228f, 0.002522f, 0.002645f, 0.003086f,
+ 0.003199f, 0.003534f, 0.003790f, 0.004105f, 0.004421f, 0.004902f, 0.005283f, 0.005589f, 0.006039f, 0.006401f, 0.007088f, 0.007519f,
+ 0.008217f, 0.008812f, 0.009712f, 0.010460f, 0.011337f, 0.012413f, 0.013596f, 0.014687f, 0.016159f, 0.018051f, 0.019913f, 0.022018f,
+ 0.024551f, 0.027359f, 0.030792f, 0.035065f, 0.039703f, 0.044983f, 0.051392f, 0.059204f, 0.068176f, 0.079102f, 0.092041f, 0.106873f,
+ 0.125000f, 0.145874f, 0.170532f, 0.198975f, 0.230835f, 0.267090f, 0.306641f, 0.349854f, 0.395508f, 0.445801f, 0.780762f, 0.796875f,
+ 0.799805f, 0.801270f, 0.801270f, 0.801270f, 0.000227f, 0.000521f, 0.000698f, 0.000817f, 0.001236f, 0.001359f, 0.001540f, 0.001619f,
+ 0.001940f, 0.002089f, 0.002430f, 0.002552f, 0.002655f, 0.002932f, 0.003241f, 0.003532f, 0.003841f, 0.004120f, 0.004292f, 0.004761f,
+ 0.005051f, 0.005459f, 0.005886f, 0.006290f, 0.006821f, 0.007320f, 0.007889f, 0.008652f, 0.009399f, 0.010063f, 0.010887f, 0.012215f,
+ 0.013206f, 0.014648f, 0.016037f, 0.017853f, 0.019958f, 0.022491f, 0.024994f, 0.028091f, 0.032135f, 0.036530f, 0.041809f, 0.048096f,
+ 0.055908f, 0.064941f, 0.076050f, 0.089050f, 0.104980f, 0.123596f, 0.146118f, 0.172363f, 0.203003f, 0.237183f, 0.276123f, 0.318359f,
+ 0.365479f, 0.416504f, 0.768555f, 0.784668f, 0.788086f, 0.789551f, 0.790039f, 0.790039f, 0.000000f, 0.000448f, 0.000566f, 0.000688f,
+ 0.000985f, 0.001144f, 0.001305f, 0.001437f, 0.001622f, 0.001731f, 0.001989f, 0.002174f, 0.002338f, 0.002552f, 0.002739f, 0.002924f,
+ 0.003239f, 0.003405f, 0.003628f, 0.003933f, 0.004200f, 0.004463f, 0.004948f, 0.005245f, 0.005615f, 0.006138f, 0.006699f, 0.006989f,
+ 0.007793f, 0.008247f, 0.008980f, 0.009918f, 0.010857f, 0.011795f, 0.013016f, 0.014244f, 0.015930f, 0.017868f, 0.019882f, 0.022659f,
+ 0.025543f, 0.029160f, 0.033417f, 0.038635f, 0.044983f, 0.052338f, 0.061859f, 0.072693f, 0.086487f, 0.102966f, 0.122864f, 0.146973f,
+ 0.175049f, 0.207764f, 0.245605f, 0.287842f, 0.334229f, 0.385986f, 0.755371f, 0.771973f, 0.775879f, 0.777344f, 0.777832f, 0.778809f,
+ 0.000000f, 0.000303f, 0.000512f, 0.000752f, 0.000828f, 0.001036f, 0.001184f, 0.001292f, 0.001281f, 0.001460f, 0.001717f, 0.001843f,
+ 0.001955f, 0.002060f, 0.002317f, 0.002476f, 0.002542f, 0.002869f, 0.003088f, 0.003313f, 0.003559f, 0.003693f, 0.004082f, 0.004318f,
+ 0.004696f, 0.005070f, 0.005245f, 0.005741f, 0.006126f, 0.006771f, 0.007298f, 0.007828f, 0.008583f, 0.009338f, 0.010246f, 0.011528f,
+ 0.012794f, 0.014160f, 0.015717f, 0.017853f, 0.019958f, 0.022995f, 0.026291f, 0.030533f, 0.035553f, 0.041565f, 0.048981f, 0.058350f,
+ 0.069824f, 0.083801f, 0.101685f, 0.122437f, 0.148438f, 0.178833f, 0.215454f, 0.256104f, 0.302490f, 0.354736f, 0.741699f, 0.758789f,
+ 0.762695f, 0.763672f, 0.764648f, 0.765625f, 0.000097f, 0.000306f, 0.000370f, 0.000618f, 0.000713f, 0.000810f, 0.000953f, 0.000920f,
+ 0.001167f, 0.001238f, 0.001406f, 0.001483f, 0.001540f, 0.001794f, 0.001970f, 0.002028f, 0.002264f, 0.002354f, 0.002459f, 0.002636f,
+ 0.002827f, 0.003096f, 0.003342f, 0.003544f, 0.003881f, 0.003948f, 0.004459f, 0.004742f, 0.005005f, 0.005394f, 0.005867f, 0.006374f,
+ 0.006901f, 0.007507f, 0.008202f, 0.008881f, 0.010017f, 0.010986f, 0.012451f, 0.013809f, 0.015511f, 0.017776f, 0.020325f, 0.023453f,
+ 0.027390f, 0.032349f, 0.038330f, 0.045624f, 0.055359f, 0.067078f, 0.082275f, 0.101013f, 0.123657f, 0.151611f, 0.185791f, 0.225342f,
+ 0.270752f, 0.322754f, 0.727051f, 0.746094f, 0.749512f, 0.750977f, 0.751953f, 0.751953f, 0.000228f, 0.000211f, 0.000504f, 0.000443f,
+ 0.000523f, 0.000672f, 0.000703f, 0.000902f, 0.000975f, 0.001010f, 0.001122f, 0.001178f, 0.001257f, 0.001424f, 0.001575f, 0.001631f,
+ 0.001789f, 0.001910f, 0.002090f, 0.002144f, 0.002411f, 0.002520f, 0.002703f, 0.002827f, 0.003010f, 0.003195f, 0.003403f, 0.003750f,
+ 0.003960f, 0.004276f, 0.004780f, 0.005005f, 0.005432f, 0.005981f, 0.006428f, 0.007015f, 0.007812f, 0.008537f, 0.009415f, 0.010658f,
+ 0.011963f, 0.013443f, 0.015396f, 0.017731f, 0.020782f, 0.024414f, 0.029083f, 0.034912f, 0.042572f, 0.052216f, 0.064392f, 0.080017f,
+ 0.100220f, 0.126099f, 0.157227f, 0.194946f, 0.239136f, 0.290283f, 0.712402f, 0.731445f, 0.734863f, 0.736816f, 0.737305f, 0.737793f,
+ 0.000211f, 0.000198f, 0.000195f, 0.000413f, 0.000517f, 0.000531f, 0.000586f, 0.000736f, 0.000769f, 0.000809f, 0.000970f, 0.001007f,
+ 0.001067f, 0.001134f, 0.001211f, 0.001348f, 0.001341f, 0.001534f, 0.001617f, 0.001734f, 0.001942f, 0.002010f, 0.002110f, 0.002268f,
+ 0.002523f, 0.002607f, 0.002829f, 0.003004f, 0.003113f, 0.003403f, 0.003681f, 0.003990f, 0.004257f, 0.004601f, 0.005039f, 0.005444f,
+ 0.005993f, 0.006561f, 0.007278f, 0.008026f, 0.009041f, 0.010124f, 0.011513f, 0.013222f, 0.015320f, 0.017914f, 0.021408f, 0.025833f,
+ 0.031433f, 0.039429f, 0.049255f, 0.062286f, 0.079102f, 0.101135f, 0.130005f, 0.164917f, 0.207764f, 0.258057f, 0.696289f, 0.716309f,
+ 0.720215f, 0.722168f, 0.722656f, 0.723145f, 0.000000f, 0.000080f, 0.000286f, 0.000374f, 0.000434f, 0.000457f, 0.000460f, 0.000568f,
+ 0.000610f, 0.000669f, 0.000715f, 0.000773f, 0.000877f, 0.000918f, 0.001030f, 0.000998f, 0.001148f, 0.001134f, 0.001305f, 0.001369f,
+ 0.001410f, 0.001534f, 0.001688f, 0.001780f, 0.001899f, 0.001963f, 0.002081f, 0.002199f, 0.002470f, 0.002563f, 0.002758f, 0.003006f,
+ 0.003273f, 0.003531f, 0.003817f, 0.004093f, 0.004532f, 0.004993f, 0.005463f, 0.006027f, 0.006657f, 0.007492f, 0.008537f, 0.009689f,
+ 0.011246f, 0.012985f, 0.015518f, 0.018539f, 0.022827f, 0.028534f, 0.036072f, 0.046234f, 0.060028f, 0.078918f, 0.103943f, 0.136353f,
+ 0.176514f, 0.225952f, 0.679199f, 0.699707f, 0.703613f, 0.706055f, 0.706543f, 0.708008f, 0.000089f, 0.000176f, 0.000232f, 0.000342f,
+ 0.000317f, 0.000319f, 0.000420f, 0.000382f, 0.000494f, 0.000515f, 0.000612f, 0.000650f, 0.000671f, 0.000701f, 0.000732f, 0.000859f,
+ 0.000888f, 0.000923f, 0.001002f, 0.001048f, 0.001170f, 0.001234f, 0.001292f, 0.001426f, 0.001414f, 0.001476f, 0.001622f, 0.001723f,
+ 0.001892f, 0.001976f, 0.002237f, 0.002239f, 0.002476f, 0.002645f, 0.002817f, 0.003092f, 0.003355f, 0.003626f, 0.003979f, 0.004459f,
+ 0.004948f, 0.005527f, 0.006256f, 0.007027f, 0.008026f, 0.009270f, 0.010918f, 0.013184f, 0.016098f, 0.019913f, 0.025253f, 0.033112f,
+ 0.043762f, 0.059113f, 0.079956f, 0.109009f, 0.146729f, 0.193726f, 0.660645f, 0.682129f, 0.688477f, 0.690430f, 0.689941f, 0.690918f,
+ 0.000000f, 0.000063f, 0.000194f, 0.000281f, 0.000187f, 0.000325f, 0.000278f, 0.000272f, 0.000386f, 0.000466f, 0.000462f, 0.000510f,
+ 0.000519f, 0.000587f, 0.000613f, 0.000603f, 0.000671f, 0.000709f, 0.000744f, 0.000808f, 0.000858f, 0.000913f, 0.000963f, 0.000999f,
+ 0.001062f, 0.001106f, 0.001262f, 0.001266f, 0.001431f, 0.001562f, 0.001672f, 0.001693f, 0.001810f, 0.001976f, 0.002090f, 0.002289f,
+ 0.002422f, 0.002666f, 0.002916f, 0.003166f, 0.003513f, 0.003862f, 0.004318f, 0.004936f, 0.005646f, 0.006493f, 0.007626f, 0.009048f,
+ 0.010826f, 0.013519f, 0.017166f, 0.022476f, 0.030258f, 0.041687f, 0.058807f, 0.083435f, 0.117737f, 0.162598f, 0.644043f, 0.666504f,
+ 0.670410f, 0.673340f, 0.674316f, 0.675293f, 0.000000f, 0.000117f, 0.000112f, 0.000178f, 0.000216f, 0.000222f, 0.000271f, 0.000229f,
+ 0.000280f, 0.000283f, 0.000326f, 0.000376f, 0.000376f, 0.000443f, 0.000456f, 0.000470f, 0.000499f, 0.000507f, 0.000547f, 0.000566f,
+ 0.000613f, 0.000667f, 0.000692f, 0.000749f, 0.000773f, 0.000803f, 0.000917f, 0.000924f, 0.000997f, 0.001055f, 0.001096f, 0.001236f,
+ 0.001261f, 0.001376f, 0.001466f, 0.001693f, 0.001695f, 0.001826f, 0.002077f, 0.002226f, 0.002411f, 0.002686f, 0.002985f, 0.003368f,
+ 0.003801f, 0.004353f, 0.005131f, 0.005974f, 0.007370f, 0.008842f, 0.011345f, 0.014717f, 0.019699f, 0.027893f, 0.040619f, 0.060730f,
+ 0.090454f, 0.132080f, 0.625488f, 0.649414f, 0.653809f, 0.655273f, 0.656250f, 0.658203f, 0.000000f, 0.000000f, 0.000108f, 0.000121f,
+ 0.000136f, 0.000154f, 0.000158f, 0.000191f, 0.000203f, 0.000213f, 0.000270f, 0.000223f, 0.000232f, 0.000270f, 0.000296f, 0.000342f,
+ 0.000324f, 0.000352f, 0.000453f, 0.000407f, 0.000450f, 0.000459f, 0.000486f, 0.000524f, 0.000545f, 0.000565f, 0.000630f, 0.000620f,
+ 0.000678f, 0.000803f, 0.000763f, 0.000813f, 0.000860f, 0.000937f, 0.001035f, 0.001101f, 0.001141f, 0.001254f, 0.001399f, 0.001449f,
+ 0.001616f, 0.001779f, 0.001942f, 0.002220f, 0.002493f, 0.002808f, 0.003258f, 0.003895f, 0.004623f, 0.005714f, 0.007111f, 0.009178f,
+ 0.012367f, 0.017319f, 0.025879f, 0.040741f, 0.065552f, 0.103577f, 0.606934f, 0.630371f, 0.635254f, 0.637695f, 0.638672f, 0.639648f,
+ 0.000000f, 0.000109f, 0.000102f, 0.000098f, 0.000105f, 0.000110f, 0.000113f, 0.000122f, 0.000117f, 0.000132f, 0.000147f, 0.000189f,
+ 0.000163f, 0.000212f, 0.000213f, 0.000222f, 0.000224f, 0.000233f, 0.000258f, 0.000262f, 0.000274f, 0.000305f, 0.000340f, 0.000329f,
+ 0.000358f, 0.000376f, 0.000445f, 0.000418f, 0.000447f, 0.000478f, 0.000546f, 0.000530f, 0.000594f, 0.000626f, 0.000679f, 0.000745f,
+ 0.000763f, 0.000804f, 0.000869f, 0.000952f, 0.001025f, 0.001119f, 0.001254f, 0.001359f, 0.001584f, 0.001728f, 0.001993f, 0.002295f,
+ 0.002790f, 0.003298f, 0.004135f, 0.005363f, 0.007267f, 0.010277f, 0.015350f, 0.024994f, 0.043518f, 0.076599f, 0.585938f, 0.611816f,
+ 0.616211f, 0.619141f, 0.619629f, 0.620605f, 0.000000f, 0.000102f, 0.000095f, 0.000090f, 0.000085f, 0.000081f, 0.000078f, 0.000073f,
+ 0.000075f, 0.000079f, 0.000087f, 0.000092f, 0.000095f, 0.000094f, 0.000133f, 0.000143f, 0.000152f, 0.000155f, 0.000161f, 0.000195f,
+ 0.000174f, 0.000183f, 0.000188f, 0.000216f, 0.000233f, 0.000241f, 0.000241f, 0.000257f, 0.000269f, 0.000302f, 0.000325f, 0.000321f,
+ 0.000350f, 0.000363f, 0.000405f, 0.000426f, 0.000456f, 0.000486f, 0.000539f, 0.000560f, 0.000614f, 0.000671f, 0.000722f, 0.000811f,
+ 0.000891f, 0.000989f, 0.001162f, 0.001312f, 0.001545f, 0.001863f, 0.002340f, 0.002920f, 0.003963f, 0.005615f, 0.008499f, 0.013931f,
+ 0.025833f, 0.052094f, 0.566406f, 0.591797f, 0.597168f, 0.599609f, 0.601074f, 0.601562f, 0.000110f, 0.000092f, 0.000084f, 0.000077f,
+ 0.000073f, 0.000070f, 0.000067f, 0.000064f, 0.000061f, 0.000058f, 0.000055f, 0.000064f, 0.000051f, 0.000054f, 0.000071f, 0.000059f,
+ 0.000082f, 0.000081f, 0.000090f, 0.000087f, 0.000099f, 0.000103f, 0.000127f, 0.000131f, 0.000135f, 0.000139f, 0.000142f, 0.000143f,
+ 0.000156f, 0.000162f, 0.000173f, 0.000194f, 0.000206f, 0.000201f, 0.000233f, 0.000225f, 0.000246f, 0.000294f, 0.000279f, 0.000313f,
+ 0.000333f, 0.000356f, 0.000395f, 0.000432f, 0.000459f, 0.000511f, 0.000577f, 0.000664f, 0.000770f, 0.000916f, 0.001114f, 0.001400f,
+ 0.001881f, 0.002665f, 0.004093f, 0.006966f, 0.013290f, 0.031525f, 0.545410f, 0.571777f, 0.577637f, 0.579102f, 0.580566f, 0.581055f,
+ 0.000093f, 0.000073f, 0.000066f, 0.000061f, 0.000056f, 0.000054f, 0.000051f, 0.000050f, 0.000048f, 0.000047f, 0.000045f, 0.000044f,
+ 0.000042f, 0.000040f, 0.000038f, 0.000036f, 0.000039f, 0.000033f, 0.000041f, 0.000040f, 0.000046f, 0.000048f, 0.000051f, 0.000057f,
+ 0.000060f, 0.000066f, 0.000062f, 0.000067f, 0.000080f, 0.000085f, 0.000088f, 0.000092f, 0.000092f, 0.000097f, 0.000109f, 0.000109f,
+ 0.000117f, 0.000132f, 0.000134f, 0.000147f, 0.000154f, 0.000156f, 0.000188f, 0.000197f, 0.000219f, 0.000234f, 0.000266f, 0.000286f,
+ 0.000335f, 0.000397f, 0.000472f, 0.000566f, 0.000751f, 0.001039f, 0.001626f, 0.002834f, 0.005909f, 0.015411f, 0.524414f, 0.551270f,
+ 0.557129f, 0.559570f, 0.561035f, 0.561523f, 0.000060f, 0.000046f, 0.000039f, 0.000037f, 0.000034f, 0.000034f, 0.000032f, 0.000032f,
+ 0.000031f, 0.000029f, 0.000029f, 0.000029f, 0.000028f, 0.000028f, 0.000028f, 0.000027f, 0.000026f, 0.000025f, 0.000024f, 0.000023f,
+ 0.000022f, 0.000021f, 0.000020f, 0.000021f, 0.000020f, 0.000018f, 0.000018f, 0.000023f, 0.000024f, 0.000028f, 0.000032f, 0.000033f,
+ 0.000032f, 0.000038f, 0.000039f, 0.000043f, 0.000046f, 0.000050f, 0.000052f, 0.000053f, 0.000057f, 0.000067f, 0.000073f, 0.000068f,
+ 0.000076f, 0.000083f, 0.000097f, 0.000110f, 0.000116f, 0.000127f, 0.000157f, 0.000185f, 0.000246f, 0.000319f, 0.000466f, 0.000810f,
+ 0.001841f, 0.005795f, 0.503418f, 0.531250f, 0.536621f, 0.539062f, 0.540039f, 0.540527f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000004f, 0.000005f, 0.000005f, 0.000008f, 0.000008f, 0.000009f, 0.000009f, 0.000010f, 0.000010f, 0.000010f, 0.000010f, 0.000011f,
+ 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000012f, 0.000012f, 0.000012f, 0.000012f, 0.000012f, 0.000012f, 0.000011f, 0.000011f,
+ 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000009f, 0.000008f, 0.000008f, 0.000008f, 0.000009f, 0.000009f, 0.000010f, 0.000012f,
+ 0.000013f, 0.000014f, 0.000015f, 0.000017f, 0.000020f, 0.000021f, 0.000018f, 0.000023f, 0.000023f, 0.000025f, 0.000030f, 0.000038f,
+ 0.000043f, 0.000059f, 0.000079f, 0.000131f, 0.000279f, 0.001210f, 0.481934f, 0.510254f, 0.516113f, 0.518555f, 0.520020f, 0.520508f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000004f, 0.000006f, 0.000022f, 0.460449f, 0.489258f,
+ 0.495850f, 0.498291f, 0.499512f, 0.500000f,
+ },
+ {
+ 0.038544f, 0.111450f, 0.177368f, 0.237061f, 0.290771f, 0.339600f, 0.384277f, 0.425293f, 0.462402f, 0.497070f, 0.527344f, 0.556152f,
+ 0.583496f, 0.607910f, 0.630859f, 0.652344f, 0.672852f, 0.690918f, 0.708496f, 0.724609f, 0.740723f, 0.754883f, 0.768066f, 0.780273f,
+ 0.792480f, 0.803711f, 0.815430f, 0.825684f, 0.835449f, 0.844727f, 0.853516f, 0.861816f, 0.870117f, 0.877930f, 0.885254f, 0.892578f,
+ 0.899414f, 0.905762f, 0.912109f, 0.918945f, 0.923828f, 0.928711f, 0.934082f, 0.939941f, 0.944824f, 0.949707f, 0.953613f, 0.958496f,
+ 0.962402f, 0.967285f, 0.971191f, 0.974609f, 0.979004f, 0.982422f, 0.985352f, 0.989258f, 0.992188f, 0.996094f, 0.996094f, 0.990723f,
+ 0.986328f, 0.982422f, 0.978516f, 0.975098f, 0.029068f, 0.087219f, 0.142578f, 0.195190f, 0.244629f, 0.291016f, 0.334717f, 0.375000f,
+ 0.412842f, 0.446533f, 0.481201f, 0.511230f, 0.539062f, 0.565918f, 0.590820f, 0.614258f, 0.636719f, 0.656250f, 0.675293f, 0.693359f,
+ 0.710449f, 0.726562f, 0.741699f, 0.755371f, 0.769043f, 0.781738f, 0.793457f, 0.805176f, 0.815918f, 0.826660f, 0.835938f, 0.845703f,
+ 0.854980f, 0.862793f, 0.871582f, 0.879395f, 0.885742f, 0.894531f, 0.900879f, 0.907227f, 0.913086f, 0.919434f, 0.925293f, 0.931152f,
+ 0.936523f, 0.941406f, 0.946777f, 0.951172f, 0.956055f, 0.960449f, 0.964355f, 0.968750f, 0.972656f, 0.976562f, 0.980469f, 0.984375f,
+ 0.987793f, 0.991211f, 0.994141f, 0.989258f, 0.984863f, 0.981445f, 0.977539f, 0.974121f, 0.023346f, 0.069641f, 0.115601f, 0.160767f,
+ 0.205078f, 0.248047f, 0.289062f, 0.328125f, 0.365723f, 0.401367f, 0.435059f, 0.466309f, 0.495361f, 0.523926f, 0.550781f, 0.574707f,
+ 0.597168f, 0.620117f, 0.641113f, 0.660156f, 0.679688f, 0.696777f, 0.713379f, 0.728516f, 0.743652f, 0.757324f, 0.770996f, 0.784180f,
+ 0.795410f, 0.806641f, 0.817383f, 0.828125f, 0.837891f, 0.847168f, 0.855957f, 0.864258f, 0.873047f, 0.880859f, 0.888672f, 0.895996f,
+ 0.902832f, 0.909668f, 0.915039f, 0.921875f, 0.927246f, 0.934082f, 0.937988f, 0.943848f, 0.948242f, 0.953613f, 0.958496f, 0.962402f,
+ 0.967285f, 0.971191f, 0.975098f, 0.979492f, 0.983398f, 0.985840f, 0.992188f, 0.987305f, 0.983398f, 0.979980f, 0.977051f, 0.973633f,
+ 0.018600f, 0.056366f, 0.094299f, 0.133545f, 0.172729f, 0.211670f, 0.249756f, 0.285889f, 0.322021f, 0.356934f, 0.390869f, 0.421875f,
+ 0.452148f, 0.481201f, 0.509277f, 0.535156f, 0.560059f, 0.583496f, 0.605957f, 0.626465f, 0.647949f, 0.665527f, 0.684570f, 0.700684f,
+ 0.717285f, 0.731934f, 0.746582f, 0.760254f, 0.773926f, 0.786621f, 0.799316f, 0.809082f, 0.820312f, 0.830566f, 0.840332f, 0.850098f,
+ 0.858887f, 0.867188f, 0.875000f, 0.883789f, 0.890625f, 0.898926f, 0.904297f, 0.912109f, 0.916992f, 0.924316f, 0.930176f, 0.935547f,
+ 0.941406f, 0.945801f, 0.951172f, 0.956055f, 0.960938f, 0.964844f, 0.969727f, 0.974609f, 0.978516f, 0.981934f, 0.989746f, 0.985840f,
+ 0.981934f, 0.978516f, 0.975586f, 0.972168f, 0.015068f, 0.046143f, 0.077881f, 0.111816f, 0.145264f, 0.179688f, 0.214600f, 0.249023f,
+ 0.282715f, 0.316406f, 0.348389f, 0.380615f, 0.411133f, 0.440430f, 0.468018f, 0.494873f, 0.520508f, 0.546387f, 0.568848f, 0.591309f,
+ 0.613281f, 0.634277f, 0.653809f, 0.670898f, 0.688477f, 0.706055f, 0.721191f, 0.736328f, 0.751465f, 0.764648f, 0.776855f, 0.789551f,
+ 0.801270f, 0.812500f, 0.823730f, 0.833496f, 0.843262f, 0.853027f, 0.861328f, 0.869629f, 0.878418f, 0.885742f, 0.893555f, 0.900391f,
+ 0.908203f, 0.914551f, 0.921387f, 0.927246f, 0.932617f, 0.938965f, 0.943848f, 0.949219f, 0.953613f, 0.959473f, 0.963867f, 0.968262f,
+ 0.972656f, 0.977051f, 0.987305f, 0.983887f, 0.980957f, 0.977051f, 0.974121f, 0.970703f, 0.012444f, 0.037933f, 0.065613f, 0.093811f,
+ 0.123474f, 0.153809f, 0.185059f, 0.215820f, 0.247559f, 0.279297f, 0.310547f, 0.341309f, 0.370361f, 0.399658f, 0.428467f, 0.457031f,
+ 0.482910f, 0.507812f, 0.533203f, 0.556152f, 0.579590f, 0.600098f, 0.621094f, 0.641113f, 0.659668f, 0.676270f, 0.695312f, 0.710449f,
+ 0.726074f, 0.740723f, 0.756348f, 0.769043f, 0.780762f, 0.794434f, 0.805176f, 0.816895f, 0.827637f, 0.837891f, 0.847168f, 0.855957f,
+ 0.865723f, 0.873535f, 0.882324f, 0.889648f, 0.897949f, 0.904297f, 0.911133f, 0.917480f, 0.924316f, 0.930176f, 0.936523f, 0.941895f,
+ 0.947266f, 0.952637f, 0.958008f, 0.962891f, 0.967285f, 0.971680f, 0.984863f, 0.981934f, 0.978516f, 0.975586f, 0.972656f, 0.969238f,
+ 0.010353f, 0.032043f, 0.055359f, 0.079529f, 0.104980f, 0.131836f, 0.159424f, 0.187866f, 0.216431f, 0.245239f, 0.275146f, 0.304199f,
+ 0.333496f, 0.362061f, 0.390869f, 0.417969f, 0.445068f, 0.471191f, 0.496582f, 0.520508f, 0.543457f, 0.566895f, 0.588867f, 0.608398f,
+ 0.628906f, 0.648438f, 0.666992f, 0.684570f, 0.701660f, 0.716797f, 0.732422f, 0.746582f, 0.760254f, 0.773438f, 0.786133f, 0.798340f,
+ 0.810547f, 0.821777f, 0.832520f, 0.842773f, 0.851074f, 0.860352f, 0.869629f, 0.878906f, 0.886230f, 0.894043f, 0.901855f, 0.908691f,
+ 0.915527f, 0.922363f, 0.928223f, 0.935059f, 0.939941f, 0.945312f, 0.950684f, 0.956055f, 0.962402f, 0.966797f, 0.982910f, 0.979980f,
+ 0.977051f, 0.973633f, 0.970703f, 0.968262f, 0.008598f, 0.027328f, 0.046417f, 0.067871f, 0.089905f, 0.113220f, 0.137695f, 0.163330f,
+ 0.189087f, 0.216064f, 0.243164f, 0.270752f, 0.298340f, 0.326416f, 0.354004f, 0.381348f, 0.407715f, 0.434082f, 0.460205f, 0.484863f,
+ 0.508789f, 0.532227f, 0.555176f, 0.577637f, 0.598145f, 0.618652f, 0.637695f, 0.657227f, 0.674805f, 0.691406f, 0.708008f, 0.723633f,
+ 0.738770f, 0.751953f, 0.766113f, 0.779785f, 0.791992f, 0.804199f, 0.815918f, 0.825684f, 0.836914f, 0.846680f, 0.856934f, 0.866211f,
+ 0.874512f, 0.882324f, 0.890625f, 0.898438f, 0.905273f, 0.913086f, 0.919922f, 0.926758f, 0.933105f, 0.938477f, 0.944824f, 0.951172f,
+ 0.955566f, 0.960938f, 0.980469f, 0.978027f, 0.974609f, 0.972168f, 0.969238f, 0.966797f, 0.007561f, 0.023315f, 0.040344f, 0.058228f,
+ 0.077148f, 0.097534f, 0.119995f, 0.142212f, 0.165649f, 0.190063f, 0.214722f, 0.240601f, 0.266846f, 0.293457f, 0.319824f, 0.346924f,
+ 0.372314f, 0.398438f, 0.424561f, 0.449463f, 0.474609f, 0.498535f, 0.521973f, 0.544434f, 0.566895f, 0.587402f, 0.608398f, 0.628418f,
+ 0.645996f, 0.665039f, 0.683105f, 0.699219f, 0.716309f, 0.731445f, 0.745117f, 0.760254f, 0.772949f, 0.786133f, 0.799316f, 0.809570f,
+ 0.820801f, 0.832031f, 0.843262f, 0.852051f, 0.861816f, 0.871094f, 0.880371f, 0.887695f, 0.895996f, 0.904297f, 0.911133f, 0.917969f,
+ 0.924805f, 0.931641f, 0.937012f, 0.943848f, 0.949707f, 0.954590f, 0.978027f, 0.976074f, 0.973145f, 0.970215f, 0.967773f, 0.965332f,
+ 0.006416f, 0.020065f, 0.034943f, 0.050537f, 0.067078f, 0.084900f, 0.104065f, 0.123962f, 0.145264f, 0.166748f, 0.189575f, 0.213501f,
+ 0.237305f, 0.262451f, 0.288574f, 0.313477f, 0.338623f, 0.364502f, 0.389893f, 0.414551f, 0.440186f, 0.464600f, 0.487549f, 0.510742f,
+ 0.534668f, 0.556641f, 0.578613f, 0.598145f, 0.618652f, 0.637207f, 0.655273f, 0.674805f, 0.690430f, 0.707031f, 0.724121f, 0.739258f,
+ 0.752930f, 0.767090f, 0.779785f, 0.792969f, 0.805176f, 0.816895f, 0.827637f, 0.838379f, 0.849121f, 0.858398f, 0.868652f, 0.876465f,
+ 0.885742f, 0.894043f, 0.901855f, 0.909180f, 0.916992f, 0.923828f, 0.930176f, 0.937012f, 0.943359f, 0.949707f, 0.975586f, 0.973633f,
+ 0.971191f, 0.968262f, 0.965820f, 0.963379f, 0.005802f, 0.017502f, 0.030045f, 0.043823f, 0.058014f, 0.074280f, 0.090759f, 0.108459f,
+ 0.127197f, 0.146484f, 0.167725f, 0.189087f, 0.211304f, 0.234497f, 0.258301f, 0.282471f, 0.307373f, 0.331299f, 0.356689f, 0.381104f,
+ 0.405762f, 0.430420f, 0.455078f, 0.478516f, 0.502441f, 0.524414f, 0.545898f, 0.568359f, 0.588867f, 0.608887f, 0.628906f, 0.646973f,
+ 0.665527f, 0.684082f, 0.701172f, 0.715820f, 0.731934f, 0.746582f, 0.760742f, 0.774414f, 0.787598f, 0.800781f, 0.812500f, 0.823730f,
+ 0.834961f, 0.845703f, 0.855469f, 0.865234f, 0.874512f, 0.883789f, 0.892090f, 0.899902f, 0.908203f, 0.916016f, 0.922852f, 0.930176f,
+ 0.936523f, 0.942871f, 0.972656f, 0.971191f, 0.968750f, 0.966309f, 0.963867f, 0.961426f, 0.004734f, 0.014984f, 0.026169f, 0.038177f,
+ 0.051208f, 0.065186f, 0.079468f, 0.095276f, 0.111633f, 0.129639f, 0.148071f, 0.167969f, 0.188599f, 0.208984f, 0.231689f, 0.254639f,
+ 0.277832f, 0.301025f, 0.325439f, 0.349854f, 0.373779f, 0.397705f, 0.422607f, 0.446045f, 0.469727f, 0.492676f, 0.514648f, 0.537598f,
+ 0.559570f, 0.580078f, 0.600586f, 0.620117f, 0.639648f, 0.658203f, 0.676758f, 0.692871f, 0.708984f, 0.725586f, 0.740723f, 0.755859f,
+ 0.769531f, 0.783691f, 0.796875f, 0.808594f, 0.820801f, 0.832520f, 0.842285f, 0.852539f, 0.862793f, 0.872070f, 0.881836f, 0.890137f,
+ 0.898926f, 0.906738f, 0.915039f, 0.922363f, 0.929199f, 0.936523f, 0.969727f, 0.968750f, 0.966797f, 0.964355f, 0.961914f, 0.959473f,
+ 0.004055f, 0.013588f, 0.023132f, 0.033722f, 0.044891f, 0.057343f, 0.069763f, 0.083923f, 0.098389f, 0.114441f, 0.131226f, 0.148682f,
+ 0.167603f, 0.186768f, 0.207031f, 0.228516f, 0.250732f, 0.272949f, 0.295410f, 0.318604f, 0.342285f, 0.365967f, 0.390381f, 0.413574f,
+ 0.437744f, 0.460938f, 0.484131f, 0.506348f, 0.528320f, 0.550781f, 0.572266f, 0.592773f, 0.613281f, 0.632812f, 0.651367f, 0.669922f,
+ 0.687500f, 0.704102f, 0.720215f, 0.735840f, 0.751465f, 0.764160f, 0.778809f, 0.792480f, 0.803711f, 0.816895f, 0.829102f, 0.840332f,
+ 0.850586f, 0.860352f, 0.870605f, 0.880371f, 0.889648f, 0.897949f, 0.905762f, 0.914551f, 0.922363f, 0.929199f, 0.967285f, 0.966797f,
+ 0.964844f, 0.961426f, 0.959473f, 0.958008f, 0.003611f, 0.011971f, 0.020401f, 0.030029f, 0.039185f, 0.050415f, 0.061737f, 0.074341f,
+ 0.086975f, 0.101074f, 0.115845f, 0.131958f, 0.148682f, 0.166626f, 0.185059f, 0.205200f, 0.224854f, 0.245483f, 0.267334f, 0.290771f,
+ 0.312988f, 0.335449f, 0.359619f, 0.382080f, 0.406250f, 0.429443f, 0.452881f, 0.475830f, 0.498779f, 0.520996f, 0.542480f, 0.563477f,
+ 0.584473f, 0.604980f, 0.625977f, 0.643555f, 0.663086f, 0.681152f, 0.698242f, 0.714355f, 0.729980f, 0.746582f, 0.760742f, 0.774902f,
+ 0.788086f, 0.801758f, 0.814941f, 0.826660f, 0.838867f, 0.848633f, 0.859863f, 0.869141f, 0.879395f, 0.889160f, 0.897949f, 0.906250f,
+ 0.914551f, 0.922363f, 0.963867f, 0.964355f, 0.961914f, 0.959961f, 0.957520f, 0.955078f, 0.003393f, 0.010361f, 0.018494f, 0.026337f,
+ 0.035187f, 0.044556f, 0.054596f, 0.065186f, 0.077515f, 0.089783f, 0.102783f, 0.117249f, 0.132446f, 0.148071f, 0.165649f, 0.183838f,
+ 0.202026f, 0.221313f, 0.241943f, 0.262939f, 0.285156f, 0.307129f, 0.329102f, 0.352539f, 0.375977f, 0.398438f, 0.421875f, 0.445312f,
+ 0.468750f, 0.490723f, 0.512695f, 0.534668f, 0.556641f, 0.577637f, 0.598633f, 0.619141f, 0.637695f, 0.656738f, 0.674805f, 0.692383f,
+ 0.709473f, 0.726074f, 0.742188f, 0.756836f, 0.771973f, 0.786133f, 0.799316f, 0.812012f, 0.824707f, 0.835938f, 0.848145f, 0.858887f,
+ 0.868164f, 0.878906f, 0.888184f, 0.897949f, 0.906250f, 0.914551f, 0.960938f, 0.960938f, 0.959473f, 0.957520f, 0.955078f, 0.953125f,
+ 0.003084f, 0.009521f, 0.016144f, 0.023346f, 0.031204f, 0.039520f, 0.048523f, 0.057953f, 0.068359f, 0.079895f, 0.091309f, 0.104126f,
+ 0.117920f, 0.132324f, 0.147949f, 0.164062f, 0.181396f, 0.199219f, 0.218872f, 0.238403f, 0.258545f, 0.279541f, 0.301758f, 0.323486f,
+ 0.346191f, 0.368408f, 0.391846f, 0.414795f, 0.437256f, 0.460693f, 0.483643f, 0.505371f, 0.527832f, 0.550293f, 0.571289f, 0.591797f,
+ 0.612305f, 0.632324f, 0.651855f, 0.670898f, 0.687500f, 0.705566f, 0.722168f, 0.737793f, 0.753418f, 0.768555f, 0.783691f, 0.796875f,
+ 0.811035f, 0.823242f, 0.834473f, 0.846191f, 0.857422f, 0.868652f, 0.878418f, 0.887695f, 0.897949f, 0.906250f, 0.958008f, 0.958008f,
+ 0.957031f, 0.954590f, 0.952637f, 0.950684f, 0.002666f, 0.008293f, 0.014297f, 0.021225f, 0.027847f, 0.035156f, 0.043274f, 0.051666f,
+ 0.060791f, 0.070801f, 0.081543f, 0.092407f, 0.104858f, 0.118530f, 0.131836f, 0.146606f, 0.162598f, 0.179443f, 0.196777f, 0.215210f,
+ 0.234375f, 0.254150f, 0.274414f, 0.295898f, 0.317871f, 0.340088f, 0.362549f, 0.385010f, 0.407959f, 0.430664f, 0.454590f, 0.476562f,
+ 0.499268f, 0.521484f, 0.543945f, 0.564941f, 0.585938f, 0.606934f, 0.626465f, 0.646484f, 0.665527f, 0.683594f, 0.701660f, 0.717773f,
+ 0.735352f, 0.751465f, 0.766113f, 0.781738f, 0.794922f, 0.808105f, 0.821289f, 0.833496f, 0.846191f, 0.857910f, 0.868164f, 0.878906f,
+ 0.889160f, 0.899414f, 0.954102f, 0.955566f, 0.953613f, 0.952148f, 0.950195f, 0.948730f, 0.002396f, 0.007427f, 0.012978f, 0.018646f,
+ 0.025024f, 0.031403f, 0.038788f, 0.046112f, 0.054260f, 0.063354f, 0.072693f, 0.082886f, 0.093689f, 0.105469f, 0.118164f, 0.130859f,
+ 0.145996f, 0.161011f, 0.177124f, 0.193359f, 0.211670f, 0.230225f, 0.249634f, 0.270020f, 0.290771f, 0.311768f, 0.333740f, 0.356201f,
+ 0.378906f, 0.401855f, 0.424561f, 0.447754f, 0.470215f, 0.493408f, 0.515137f, 0.537109f, 0.559570f, 0.580078f, 0.601074f, 0.621582f,
+ 0.642090f, 0.661621f, 0.679688f, 0.697754f, 0.715820f, 0.732422f, 0.749512f, 0.765137f, 0.779785f, 0.794434f, 0.808594f, 0.821289f,
+ 0.833496f, 0.846191f, 0.857910f, 0.869141f, 0.879883f, 0.889648f, 0.950195f, 0.952637f, 0.950684f, 0.948730f, 0.947266f, 0.945801f,
+ 0.002029f, 0.006672f, 0.011658f, 0.016937f, 0.022476f, 0.028305f, 0.034332f, 0.041351f, 0.048584f, 0.056671f, 0.064697f, 0.073853f,
+ 0.083923f, 0.094482f, 0.105225f, 0.117798f, 0.130615f, 0.144287f, 0.159302f, 0.174683f, 0.190430f, 0.208740f, 0.226318f, 0.245483f,
+ 0.264893f, 0.285400f, 0.307129f, 0.328369f, 0.350342f, 0.372803f, 0.395264f, 0.418701f, 0.441650f, 0.462891f, 0.486816f, 0.509277f,
+ 0.532227f, 0.553711f, 0.575684f, 0.596680f, 0.617676f, 0.638672f, 0.657715f, 0.676758f, 0.695312f, 0.712402f, 0.729492f, 0.746582f,
+ 0.762695f, 0.778320f, 0.793457f, 0.807129f, 0.820801f, 0.833984f, 0.846191f, 0.858887f, 0.869629f, 0.881836f, 0.947266f, 0.949219f,
+ 0.947754f, 0.946289f, 0.944824f, 0.942871f, 0.002142f, 0.006401f, 0.010841f, 0.015251f, 0.019760f, 0.025055f, 0.031113f, 0.037201f,
+ 0.043671f, 0.050598f, 0.057892f, 0.066101f, 0.075012f, 0.084351f, 0.093994f, 0.105164f, 0.117432f, 0.129517f, 0.142822f, 0.157104f,
+ 0.172119f, 0.188110f, 0.204956f, 0.223145f, 0.241577f, 0.260498f, 0.280762f, 0.301758f, 0.322998f, 0.345215f, 0.366943f, 0.389893f,
+ 0.412842f, 0.435791f, 0.458008f, 0.482178f, 0.504395f, 0.526855f, 0.548828f, 0.571289f, 0.592285f, 0.612793f, 0.634277f, 0.654297f,
+ 0.673340f, 0.692383f, 0.710938f, 0.729004f, 0.745117f, 0.762207f, 0.777832f, 0.792480f, 0.807129f, 0.821289f, 0.834961f, 0.847168f,
+ 0.859863f, 0.871582f, 0.943359f, 0.946289f, 0.944824f, 0.943359f, 0.941895f, 0.940430f, 0.001760f, 0.005562f, 0.009621f, 0.013710f,
+ 0.018417f, 0.022736f, 0.027939f, 0.033264f, 0.039185f, 0.045166f, 0.052460f, 0.059143f, 0.067261f, 0.075745f, 0.084106f, 0.094177f,
+ 0.104980f, 0.116455f, 0.128174f, 0.141113f, 0.155151f, 0.169922f, 0.184937f, 0.201660f, 0.219238f, 0.237549f, 0.256348f, 0.276367f,
+ 0.296875f, 0.317871f, 0.339844f, 0.361572f, 0.383789f, 0.407227f, 0.430908f, 0.453857f, 0.476807f, 0.498779f, 0.521973f, 0.543945f,
+ 0.567383f, 0.589355f, 0.609863f, 0.631348f, 0.651855f, 0.671875f, 0.690918f, 0.709961f, 0.727539f, 0.744141f, 0.761719f, 0.777344f,
+ 0.793457f, 0.808594f, 0.823242f, 0.835449f, 0.848633f, 0.861328f, 0.938965f, 0.941895f, 0.941406f, 0.940430f, 0.938477f, 0.937012f,
+ 0.001594f, 0.005283f, 0.008789f, 0.012383f, 0.016342f, 0.020523f, 0.025284f, 0.029968f, 0.035217f, 0.040741f, 0.046417f, 0.052948f,
+ 0.060120f, 0.067566f, 0.076294f, 0.084534f, 0.093750f, 0.104614f, 0.115173f, 0.126831f, 0.139160f, 0.152832f, 0.166748f, 0.181885f,
+ 0.198853f, 0.215698f, 0.233521f, 0.252197f, 0.271973f, 0.291992f, 0.313477f, 0.334717f, 0.357178f, 0.379395f, 0.401855f, 0.425537f,
+ 0.448242f, 0.471924f, 0.495361f, 0.517578f, 0.541016f, 0.562988f, 0.585938f, 0.607422f, 0.627930f, 0.649414f, 0.670410f, 0.688965f,
+ 0.708496f, 0.727539f, 0.744629f, 0.761719f, 0.778809f, 0.794922f, 0.809082f, 0.824219f, 0.838379f, 0.851074f, 0.935059f, 0.938965f,
+ 0.937988f, 0.937012f, 0.936035f, 0.933594f, 0.001564f, 0.004665f, 0.007973f, 0.011276f, 0.014908f, 0.018600f, 0.022675f, 0.027176f,
+ 0.031464f, 0.036621f, 0.042023f, 0.047974f, 0.054108f, 0.060822f, 0.068237f, 0.075684f, 0.084229f, 0.093567f, 0.103210f, 0.113892f,
+ 0.125000f, 0.137329f, 0.150269f, 0.164307f, 0.179810f, 0.194946f, 0.212158f, 0.229248f, 0.247925f, 0.267578f, 0.287842f, 0.308350f,
+ 0.330322f, 0.352051f, 0.374756f, 0.397461f, 0.420654f, 0.444092f, 0.466797f, 0.490723f, 0.514160f, 0.537109f, 0.560059f, 0.582031f,
+ 0.604980f, 0.626953f, 0.648926f, 0.668457f, 0.688477f, 0.708008f, 0.727539f, 0.745117f, 0.763672f, 0.779297f, 0.795410f, 0.811523f,
+ 0.826660f, 0.840332f, 0.930664f, 0.934570f, 0.934082f, 0.933594f, 0.932129f, 0.930664f, 0.001424f, 0.004261f, 0.007122f, 0.010239f,
+ 0.013374f, 0.016693f, 0.020401f, 0.024368f, 0.028595f, 0.033325f, 0.037964f, 0.043152f, 0.048340f, 0.054962f, 0.060730f, 0.067749f,
+ 0.075684f, 0.083862f, 0.092041f, 0.102051f, 0.112305f, 0.123657f, 0.135376f, 0.148071f, 0.161987f, 0.176270f, 0.192139f, 0.208252f,
+ 0.226196f, 0.244141f, 0.263672f, 0.283447f, 0.304199f, 0.325195f, 0.346924f, 0.370605f, 0.392822f, 0.416260f, 0.439209f, 0.463623f,
+ 0.486084f, 0.511230f, 0.534180f, 0.558105f, 0.580566f, 0.603516f, 0.625000f, 0.647461f, 0.668457f, 0.688965f, 0.708496f, 0.727539f,
+ 0.746582f, 0.764160f, 0.781738f, 0.798340f, 0.813477f, 0.829590f, 0.926758f, 0.931152f, 0.930664f, 0.929199f, 0.928223f, 0.927246f,
+ 0.001294f, 0.004196f, 0.006538f, 0.009346f, 0.012306f, 0.015335f, 0.018845f, 0.022003f, 0.025558f, 0.029816f, 0.034149f, 0.038605f,
+ 0.043915f, 0.049042f, 0.054810f, 0.061188f, 0.067993f, 0.075256f, 0.083130f, 0.091553f, 0.100769f, 0.110779f, 0.121643f, 0.133057f,
+ 0.145630f, 0.159058f, 0.173218f, 0.188721f, 0.204590f, 0.222290f, 0.240234f, 0.259277f, 0.279053f, 0.299561f, 0.321533f, 0.343506f,
+ 0.365723f, 0.389404f, 0.412354f, 0.436035f, 0.459961f, 0.484131f, 0.508301f, 0.532227f, 0.555176f, 0.579102f, 0.601562f, 0.624512f,
+ 0.646484f, 0.668457f, 0.688965f, 0.709473f, 0.729004f, 0.748047f, 0.766602f, 0.784668f, 0.800293f, 0.817383f, 0.921875f, 0.926270f,
+ 0.926270f, 0.925781f, 0.924316f, 0.923340f, 0.001081f, 0.003603f, 0.006027f, 0.008575f, 0.010979f, 0.013847f, 0.016937f, 0.020020f,
+ 0.023315f, 0.026917f, 0.030930f, 0.035156f, 0.039429f, 0.044098f, 0.049622f, 0.054779f, 0.060791f, 0.067566f, 0.074341f, 0.082336f,
+ 0.090515f, 0.099548f, 0.109070f, 0.119263f, 0.130981f, 0.143188f, 0.156250f, 0.170288f, 0.185303f, 0.201294f, 0.218262f, 0.236450f,
+ 0.255615f, 0.275391f, 0.295654f, 0.316895f, 0.339111f, 0.362061f, 0.385498f, 0.408936f, 0.432861f, 0.457275f, 0.481689f, 0.505371f,
+ 0.529785f, 0.553711f, 0.577637f, 0.601074f, 0.624023f, 0.646484f, 0.669434f, 0.689941f, 0.711426f, 0.731445f, 0.750977f, 0.770020f,
+ 0.787598f, 0.804688f, 0.916992f, 0.922363f, 0.922363f, 0.921875f, 0.920898f, 0.918945f, 0.001064f, 0.003231f, 0.005322f, 0.007710f,
+ 0.010323f, 0.012489f, 0.015244f, 0.018051f, 0.020798f, 0.024338f, 0.027893f, 0.031738f, 0.035553f, 0.039795f, 0.044495f, 0.049133f,
+ 0.054657f, 0.060608f, 0.066895f, 0.073792f, 0.081421f, 0.089050f, 0.097717f, 0.106934f, 0.117554f, 0.128540f, 0.140503f, 0.153442f,
+ 0.167236f, 0.182129f, 0.197998f, 0.214966f, 0.232422f, 0.251465f, 0.271240f, 0.291992f, 0.313232f, 0.335693f, 0.358643f, 0.382080f,
+ 0.406006f, 0.430176f, 0.454590f, 0.479004f, 0.503906f, 0.528320f, 0.552734f, 0.577637f, 0.601562f, 0.625000f, 0.648438f, 0.670898f,
+ 0.691895f, 0.713867f, 0.733887f, 0.754883f, 0.774414f, 0.791992f, 0.912109f, 0.917969f, 0.918457f, 0.916992f, 0.916016f, 0.915039f,
+ 0.000998f, 0.003012f, 0.005123f, 0.007114f, 0.009438f, 0.011360f, 0.013763f, 0.016510f, 0.018951f, 0.022171f, 0.025101f, 0.028305f,
+ 0.031830f, 0.035736f, 0.039795f, 0.044067f, 0.048950f, 0.053864f, 0.059601f, 0.066345f, 0.072815f, 0.079956f, 0.087402f, 0.096375f,
+ 0.105835f, 0.115479f, 0.126343f, 0.138184f, 0.150635f, 0.164062f, 0.178711f, 0.194214f, 0.210815f, 0.229004f, 0.247314f, 0.267090f,
+ 0.288330f, 0.309570f, 0.332275f, 0.355469f, 0.378418f, 0.402832f, 0.427490f, 0.452637f, 0.477783f, 0.501953f, 0.527832f, 0.552734f,
+ 0.577637f, 0.602051f, 0.626465f, 0.649902f, 0.672852f, 0.695312f, 0.717773f, 0.737793f, 0.758789f, 0.778809f, 0.906250f, 0.913086f,
+ 0.913574f, 0.912598f, 0.911621f, 0.910645f, 0.001059f, 0.002985f, 0.004475f, 0.006496f, 0.008545f, 0.010300f, 0.012581f, 0.014969f,
+ 0.017471f, 0.019852f, 0.022507f, 0.025864f, 0.028824f, 0.032135f, 0.036041f, 0.039795f, 0.043884f, 0.048706f, 0.053680f, 0.059113f,
+ 0.064819f, 0.071472f, 0.078491f, 0.086365f, 0.094360f, 0.103577f, 0.113403f, 0.124023f, 0.135620f, 0.147705f, 0.160889f, 0.175537f,
+ 0.191284f, 0.207764f, 0.225464f, 0.244263f, 0.264160f, 0.284912f, 0.306641f, 0.329102f, 0.352295f, 0.376465f, 0.400635f, 0.426025f,
+ 0.451416f, 0.476562f, 0.502930f, 0.527344f, 0.553711f, 0.579102f, 0.603027f, 0.627930f, 0.652344f, 0.675781f, 0.700195f, 0.722168f,
+ 0.742676f, 0.764648f, 0.901367f, 0.907715f, 0.908691f, 0.908203f, 0.907227f, 0.906250f, 0.000988f, 0.002577f, 0.004124f, 0.006042f,
+ 0.007603f, 0.009506f, 0.011299f, 0.013680f, 0.015778f, 0.017883f, 0.020554f, 0.023102f, 0.025940f, 0.028946f, 0.031891f, 0.035431f,
+ 0.039825f, 0.043671f, 0.048157f, 0.053009f, 0.058075f, 0.063782f, 0.069885f, 0.077087f, 0.084839f, 0.092712f, 0.101379f, 0.110779f,
+ 0.121155f, 0.132446f, 0.144775f, 0.157837f, 0.172363f, 0.187744f, 0.204590f, 0.222290f, 0.240601f, 0.260254f, 0.281494f, 0.303223f,
+ 0.325439f, 0.349609f, 0.373535f, 0.399170f, 0.424561f, 0.450439f, 0.475586f, 0.501953f, 0.528320f, 0.554688f, 0.580566f, 0.605957f,
+ 0.630859f, 0.656250f, 0.680176f, 0.704102f, 0.727051f, 0.749512f, 0.895508f, 0.902344f, 0.903320f, 0.902832f, 0.901855f, 0.901855f,
+ 0.000842f, 0.002253f, 0.003597f, 0.005352f, 0.007195f, 0.008804f, 0.010460f, 0.012100f, 0.014130f, 0.016281f, 0.018341f, 0.021057f,
+ 0.023193f, 0.025742f, 0.029022f, 0.031830f, 0.035278f, 0.039246f, 0.042999f, 0.047211f, 0.052032f, 0.056946f, 0.062744f, 0.068848f,
+ 0.075195f, 0.082642f, 0.090332f, 0.099060f, 0.108215f, 0.118469f, 0.129517f, 0.141724f, 0.154907f, 0.169434f, 0.184448f, 0.201172f,
+ 0.218506f, 0.237427f, 0.257324f, 0.278320f, 0.300293f, 0.323242f, 0.347412f, 0.372070f, 0.397217f, 0.423340f, 0.449707f, 0.476807f,
+ 0.502930f, 0.529785f, 0.556641f, 0.582520f, 0.609863f, 0.635254f, 0.660645f, 0.686035f, 0.710938f, 0.733887f, 0.889648f, 0.897461f,
+ 0.898926f, 0.896973f, 0.896973f, 0.896484f, 0.000660f, 0.002014f, 0.003531f, 0.004951f, 0.006424f, 0.007935f, 0.009392f, 0.011322f,
+ 0.012924f, 0.014824f, 0.016754f, 0.018906f, 0.020935f, 0.023376f, 0.026245f, 0.028809f, 0.031860f, 0.034821f, 0.038330f, 0.042236f,
+ 0.046387f, 0.050812f, 0.056061f, 0.061279f, 0.066956f, 0.073547f, 0.080566f, 0.088074f, 0.096802f, 0.106079f, 0.116089f, 0.127075f,
+ 0.138672f, 0.151855f, 0.165649f, 0.180908f, 0.197754f, 0.215332f, 0.234375f, 0.254150f, 0.275391f, 0.298096f, 0.321533f, 0.344971f,
+ 0.370361f, 0.396973f, 0.422852f, 0.449219f, 0.477295f, 0.504395f, 0.532227f, 0.558594f, 0.586914f, 0.614258f, 0.640625f, 0.666016f,
+ 0.692871f, 0.718262f, 0.882812f, 0.891602f, 0.892578f, 0.892090f, 0.892090f, 0.890625f, 0.000623f, 0.002073f, 0.003298f, 0.004292f,
+ 0.005589f, 0.007401f, 0.008377f, 0.010315f, 0.011871f, 0.013596f, 0.015213f, 0.016632f, 0.018829f, 0.020920f, 0.023239f, 0.025726f,
+ 0.028381f, 0.031250f, 0.034241f, 0.037781f, 0.041473f, 0.045349f, 0.049469f, 0.054199f, 0.059448f, 0.065186f, 0.071716f, 0.078613f,
+ 0.085999f, 0.093872f, 0.103516f, 0.112976f, 0.123840f, 0.135620f, 0.148804f, 0.162720f, 0.178223f, 0.194824f, 0.212280f, 0.231079f,
+ 0.251953f, 0.273193f, 0.295410f, 0.319580f, 0.343994f, 0.370117f, 0.396729f, 0.422852f, 0.450684f, 0.478516f, 0.507324f, 0.534668f,
+ 0.562988f, 0.591797f, 0.619629f, 0.646484f, 0.674316f, 0.700195f, 0.875488f, 0.885254f, 0.886719f, 0.886719f, 0.885742f, 0.885254f,
+ 0.000583f, 0.001746f, 0.002840f, 0.004143f, 0.005234f, 0.006516f, 0.007835f, 0.009460f, 0.010788f, 0.012062f, 0.013428f, 0.015053f,
+ 0.017349f, 0.018753f, 0.021271f, 0.023163f, 0.025284f, 0.027924f, 0.030655f, 0.033478f, 0.036957f, 0.040527f, 0.044037f, 0.048309f,
+ 0.053223f, 0.058319f, 0.063660f, 0.069763f, 0.076172f, 0.083679f, 0.091431f, 0.100647f, 0.110229f, 0.120667f, 0.132690f, 0.145386f,
+ 0.159668f, 0.174805f, 0.191284f, 0.208984f, 0.228516f, 0.248535f, 0.270996f, 0.293701f, 0.317383f, 0.342529f, 0.369629f, 0.396240f,
+ 0.424072f, 0.452148f, 0.480957f, 0.509277f, 0.539551f, 0.567871f, 0.596680f, 0.625977f, 0.654785f, 0.682129f, 0.868652f, 0.878906f,
+ 0.880371f, 0.879883f, 0.879883f, 0.879395f, 0.000535f, 0.001538f, 0.002930f, 0.003725f, 0.004986f, 0.005920f, 0.006973f, 0.008247f,
+ 0.009575f, 0.010841f, 0.012115f, 0.013550f, 0.015343f, 0.016983f, 0.018814f, 0.020523f, 0.022568f, 0.024887f, 0.027206f, 0.029907f,
+ 0.032959f, 0.035828f, 0.039185f, 0.042877f, 0.046967f, 0.051605f, 0.056213f, 0.061432f, 0.067749f, 0.073730f, 0.081238f, 0.089111f,
+ 0.097656f, 0.107300f, 0.118042f, 0.129883f, 0.142334f, 0.156250f, 0.171875f, 0.187866f, 0.206665f, 0.225708f, 0.246704f, 0.268799f,
+ 0.291992f, 0.316650f, 0.342529f, 0.369629f, 0.397217f, 0.425537f, 0.454590f, 0.484131f, 0.513672f, 0.544434f, 0.574219f, 0.604492f,
+ 0.633789f, 0.664062f, 0.861328f, 0.871582f, 0.873535f, 0.874512f, 0.873047f, 0.872559f, 0.000581f, 0.001668f, 0.002563f, 0.003471f,
+ 0.004494f, 0.005562f, 0.006580f, 0.007782f, 0.008690f, 0.009766f, 0.011261f, 0.012314f, 0.013901f, 0.014969f, 0.016479f, 0.018265f,
+ 0.020294f, 0.022156f, 0.024353f, 0.026505f, 0.029053f, 0.031799f, 0.034607f, 0.037964f, 0.041382f, 0.045471f, 0.049591f, 0.054047f,
+ 0.059326f, 0.065186f, 0.071411f, 0.078735f, 0.086304f, 0.094971f, 0.104126f, 0.114807f, 0.126587f, 0.138916f, 0.153564f, 0.169067f,
+ 0.185669f, 0.203613f, 0.223389f, 0.244629f, 0.266602f, 0.291260f, 0.316406f, 0.342773f, 0.370361f, 0.398926f, 0.427734f, 0.458008f,
+ 0.488770f, 0.520020f, 0.550293f, 0.582031f, 0.613281f, 0.645020f, 0.854004f, 0.865234f, 0.866699f, 0.867188f, 0.866699f, 0.866699f,
+ 0.000571f, 0.001365f, 0.002483f, 0.003033f, 0.004120f, 0.005054f, 0.005981f, 0.006737f, 0.007603f, 0.008675f, 0.009789f, 0.011078f,
+ 0.012413f, 0.013626f, 0.014908f, 0.016174f, 0.017792f, 0.019699f, 0.021591f, 0.023499f, 0.025635f, 0.028000f, 0.030533f, 0.033417f,
+ 0.036499f, 0.039948f, 0.043762f, 0.047943f, 0.052460f, 0.057465f, 0.062622f, 0.068848f, 0.076111f, 0.083557f, 0.092102f, 0.101562f,
+ 0.111816f, 0.123230f, 0.135864f, 0.150024f, 0.165771f, 0.182373f, 0.200806f, 0.221191f, 0.242920f, 0.265869f, 0.290283f, 0.316406f,
+ 0.343262f, 0.371582f, 0.400879f, 0.431396f, 0.463623f, 0.494629f, 0.526367f, 0.558105f, 0.591309f, 0.624023f, 0.845215f, 0.856934f,
+ 0.859375f, 0.859375f, 0.859863f, 0.860352f, 0.000411f, 0.001296f, 0.002012f, 0.002808f, 0.003754f, 0.004543f, 0.005215f, 0.006012f,
+ 0.006725f, 0.007851f, 0.008888f, 0.009979f, 0.010994f, 0.012009f, 0.013062f, 0.014549f, 0.016113f, 0.017441f, 0.019073f, 0.020767f,
+ 0.022598f, 0.024689f, 0.026764f, 0.029358f, 0.032043f, 0.034760f, 0.038391f, 0.041779f, 0.045380f, 0.050110f, 0.055054f, 0.060394f,
+ 0.066650f, 0.073120f, 0.080688f, 0.089233f, 0.098450f, 0.108582f, 0.120178f, 0.133057f, 0.146973f, 0.162354f, 0.179565f, 0.198364f,
+ 0.218750f, 0.240967f, 0.264648f, 0.290039f, 0.316650f, 0.344971f, 0.374023f, 0.404541f, 0.435791f, 0.467773f, 0.500977f, 0.535156f,
+ 0.569336f, 0.601562f, 0.836914f, 0.850098f, 0.852051f, 0.852539f, 0.852539f, 0.852051f, 0.000408f, 0.001071f, 0.001857f, 0.002573f,
+ 0.003338f, 0.004078f, 0.004692f, 0.005379f, 0.006046f, 0.007275f, 0.007957f, 0.008606f, 0.009598f, 0.010864f, 0.011658f, 0.013084f,
+ 0.013977f, 0.015366f, 0.016724f, 0.018402f, 0.019669f, 0.021759f, 0.023697f, 0.025726f, 0.027954f, 0.030640f, 0.033356f, 0.036530f,
+ 0.039948f, 0.043701f, 0.047791f, 0.052704f, 0.057770f, 0.063782f, 0.070129f, 0.077881f, 0.085999f, 0.095337f, 0.105591f, 0.116882f,
+ 0.130005f, 0.143921f, 0.159302f, 0.177246f, 0.196411f, 0.217163f, 0.239746f, 0.263916f, 0.290039f, 0.317871f, 0.346924f, 0.377441f,
+ 0.408936f, 0.442139f, 0.476074f, 0.509766f, 0.545410f, 0.580078f, 0.828613f, 0.841309f, 0.843262f, 0.844238f, 0.843750f, 0.844238f,
+ 0.000322f, 0.001009f, 0.001674f, 0.002262f, 0.002949f, 0.003633f, 0.004250f, 0.004780f, 0.005478f, 0.006256f, 0.007248f, 0.007919f,
+ 0.008720f, 0.009552f, 0.010277f, 0.011391f, 0.012291f, 0.013466f, 0.014786f, 0.015976f, 0.017288f, 0.019043f, 0.020477f, 0.022385f,
+ 0.024292f, 0.026276f, 0.029175f, 0.031769f, 0.034546f, 0.037842f, 0.041626f, 0.045868f, 0.050293f, 0.055084f, 0.060669f, 0.067688f,
+ 0.074585f, 0.083008f, 0.092102f, 0.102234f, 0.113525f, 0.126587f, 0.140869f, 0.156860f, 0.174805f, 0.194214f, 0.215698f, 0.239014f,
+ 0.264404f, 0.291016f, 0.320068f, 0.350098f, 0.382080f, 0.414551f, 0.449463f, 0.485107f, 0.520996f, 0.557617f, 0.818848f, 0.833496f,
+ 0.836426f, 0.836914f, 0.836426f, 0.835938f, 0.000483f, 0.000841f, 0.001632f, 0.002142f, 0.002678f, 0.003359f, 0.003830f, 0.004333f,
+ 0.005077f, 0.005527f, 0.006104f, 0.006908f, 0.007675f, 0.008392f, 0.009216f, 0.009789f, 0.010880f, 0.011719f, 0.012817f, 0.013809f,
+ 0.015068f, 0.016357f, 0.017883f, 0.019485f, 0.021271f, 0.022995f, 0.025162f, 0.027359f, 0.029755f, 0.032806f, 0.036133f, 0.039459f,
+ 0.043091f, 0.047821f, 0.052368f, 0.058258f, 0.064514f, 0.071472f, 0.079224f, 0.088623f, 0.098694f, 0.109924f, 0.123230f, 0.137817f,
+ 0.154053f, 0.172363f, 0.192261f, 0.214478f, 0.238647f, 0.265137f, 0.292725f, 0.322998f, 0.354492f, 0.387695f, 0.422363f, 0.458740f,
+ 0.495605f, 0.533691f, 0.809570f, 0.824219f, 0.826660f, 0.827148f, 0.828125f, 0.827148f, 0.000240f, 0.000906f, 0.001379f, 0.001807f,
+ 0.002495f, 0.002916f, 0.003490f, 0.004139f, 0.004471f, 0.004898f, 0.005638f, 0.005978f, 0.006874f, 0.007313f, 0.007957f, 0.008698f,
+ 0.009560f, 0.010178f, 0.011345f, 0.012177f, 0.012985f, 0.014214f, 0.015274f, 0.016708f, 0.017929f, 0.019882f, 0.021393f, 0.023560f,
+ 0.025406f, 0.028137f, 0.030472f, 0.033752f, 0.036896f, 0.040619f, 0.044952f, 0.049622f, 0.055298f, 0.061249f, 0.068420f, 0.075928f,
+ 0.084900f, 0.095398f, 0.107300f, 0.119934f, 0.134766f, 0.151733f, 0.170410f, 0.191284f, 0.213867f, 0.238647f, 0.265869f, 0.295654f,
+ 0.326660f, 0.359863f, 0.394775f, 0.432129f, 0.469482f, 0.508789f, 0.798340f, 0.814941f, 0.817871f, 0.818359f, 0.818848f, 0.818848f,
+ 0.000376f, 0.000870f, 0.001291f, 0.001619f, 0.002251f, 0.002520f, 0.003016f, 0.003502f, 0.004036f, 0.004299f, 0.004723f, 0.005234f,
+ 0.005840f, 0.006512f, 0.006908f, 0.007595f, 0.008003f, 0.008797f, 0.009773f, 0.010536f, 0.011284f, 0.012161f, 0.013237f, 0.014465f,
+ 0.015579f, 0.016968f, 0.018402f, 0.019882f, 0.021759f, 0.023621f, 0.026138f, 0.028488f, 0.031738f, 0.034668f, 0.038239f, 0.042389f,
+ 0.046783f, 0.052094f, 0.058319f, 0.064941f, 0.072815f, 0.081726f, 0.092102f, 0.103516f, 0.117188f, 0.132202f, 0.149048f, 0.168091f,
+ 0.189941f, 0.213745f, 0.239990f, 0.268311f, 0.299316f, 0.332275f, 0.367188f, 0.403076f, 0.442871f, 0.483398f, 0.788086f, 0.805176f,
+ 0.808105f, 0.808594f, 0.809082f, 0.809082f, 0.000386f, 0.000765f, 0.000998f, 0.001537f, 0.001833f, 0.002407f, 0.002529f, 0.003113f,
+ 0.003334f, 0.003841f, 0.004192f, 0.004585f, 0.005096f, 0.005543f, 0.006073f, 0.006405f, 0.007118f, 0.007641f, 0.008278f, 0.008957f,
+ 0.009651f, 0.010498f, 0.011307f, 0.012184f, 0.013199f, 0.014343f, 0.015671f, 0.016678f, 0.018585f, 0.019852f, 0.021881f, 0.023987f,
+ 0.026398f, 0.029099f, 0.032227f, 0.035339f, 0.039246f, 0.043915f, 0.048859f, 0.054688f, 0.061554f, 0.069519f, 0.078247f, 0.088379f,
+ 0.100037f, 0.113770f, 0.129272f, 0.146606f, 0.166626f, 0.189575f, 0.214111f, 0.241577f, 0.271973f, 0.304199f, 0.339844f, 0.375977f,
+ 0.415527f, 0.457275f, 0.776855f, 0.794434f, 0.797363f, 0.797852f, 0.798828f, 0.799316f, 0.000232f, 0.000636f, 0.000996f, 0.001201f,
+ 0.001721f, 0.002029f, 0.002340f, 0.002802f, 0.003012f, 0.003462f, 0.003693f, 0.004059f, 0.004295f, 0.004822f, 0.005077f, 0.005623f,
+ 0.006126f, 0.006653f, 0.007027f, 0.007561f, 0.008049f, 0.008904f, 0.009399f, 0.010300f, 0.011200f, 0.012115f, 0.013092f, 0.014221f,
+ 0.015671f, 0.016891f, 0.018433f, 0.020294f, 0.022064f, 0.024277f, 0.026688f, 0.029678f, 0.032654f, 0.036499f, 0.040955f, 0.045715f,
+ 0.051514f, 0.058014f, 0.065674f, 0.074707f, 0.084717f, 0.096802f, 0.111023f, 0.126709f, 0.144775f, 0.165771f, 0.189209f, 0.215820f,
+ 0.244385f, 0.275879f, 0.310547f, 0.348145f, 0.387695f, 0.429932f, 0.765137f, 0.783203f, 0.787109f, 0.788574f, 0.788574f, 0.789551f,
+ 0.000171f, 0.000518f, 0.001106f, 0.001242f, 0.001475f, 0.001939f, 0.002092f, 0.002254f, 0.002607f, 0.002930f, 0.003084f, 0.003382f,
+ 0.003674f, 0.004040f, 0.004395f, 0.004780f, 0.005157f, 0.005653f, 0.006088f, 0.006355f, 0.006870f, 0.007420f, 0.008057f, 0.008667f,
+ 0.009361f, 0.010040f, 0.011101f, 0.011803f, 0.012711f, 0.013962f, 0.015343f, 0.016586f, 0.018036f, 0.020142f, 0.022079f, 0.024399f,
+ 0.027023f, 0.030075f, 0.033569f, 0.037750f, 0.042603f, 0.048096f, 0.054718f, 0.062134f, 0.071045f, 0.081299f, 0.093445f, 0.107605f,
+ 0.124268f, 0.142944f, 0.165405f, 0.189941f, 0.218262f, 0.249268f, 0.282227f, 0.319336f, 0.359375f, 0.402832f, 0.752930f, 0.771973f,
+ 0.775879f, 0.776855f, 0.777832f, 0.777832f, 0.000204f, 0.000608f, 0.000865f, 0.001011f, 0.001362f, 0.001632f, 0.001817f, 0.001930f,
+ 0.002274f, 0.002491f, 0.002796f, 0.002932f, 0.003139f, 0.003429f, 0.003736f, 0.004055f, 0.004448f, 0.004829f, 0.004971f, 0.005497f,
+ 0.005859f, 0.006298f, 0.006741f, 0.007080f, 0.007687f, 0.008308f, 0.009087f, 0.009880f, 0.010735f, 0.011528f, 0.012375f, 0.013664f,
+ 0.014862f, 0.016464f, 0.017868f, 0.019852f, 0.022156f, 0.024490f, 0.027435f, 0.030853f, 0.034637f, 0.039154f, 0.044495f, 0.050964f,
+ 0.058441f, 0.067383f, 0.077759f, 0.090332f, 0.104797f, 0.121826f, 0.142334f, 0.164795f, 0.191528f, 0.221313f, 0.254150f, 0.290771f,
+ 0.330078f, 0.374268f, 0.740234f, 0.759277f, 0.763672f, 0.766113f, 0.766602f, 0.766113f, 0.000150f, 0.000514f, 0.000666f, 0.000865f,
+ 0.001163f, 0.001389f, 0.001540f, 0.001672f, 0.001940f, 0.002110f, 0.002302f, 0.002419f, 0.002745f, 0.002974f, 0.003120f, 0.003366f,
+ 0.003695f, 0.003815f, 0.004173f, 0.004574f, 0.004879f, 0.005165f, 0.005646f, 0.006058f, 0.006481f, 0.006969f, 0.007626f, 0.007881f,
+ 0.008751f, 0.009445f, 0.010231f, 0.011246f, 0.012222f, 0.013268f, 0.014641f, 0.015976f, 0.017792f, 0.019867f, 0.021912f, 0.024704f,
+ 0.027786f, 0.031494f, 0.036011f, 0.041229f, 0.047363f, 0.054962f, 0.063904f, 0.074463f, 0.087036f, 0.102295f, 0.120483f, 0.141113f,
+ 0.166260f, 0.194214f, 0.226196f, 0.261719f, 0.301514f, 0.345459f, 0.727051f, 0.747070f, 0.751953f, 0.753418f, 0.754395f, 0.754883f,
+ 0.000103f, 0.000251f, 0.000628f, 0.000912f, 0.000978f, 0.001191f, 0.001365f, 0.001507f, 0.001513f, 0.001757f, 0.001980f, 0.002121f,
+ 0.002316f, 0.002373f, 0.002645f, 0.002909f, 0.003012f, 0.003305f, 0.003538f, 0.003775f, 0.004070f, 0.004246f, 0.004642f, 0.004986f,
+ 0.005394f, 0.005802f, 0.006031f, 0.006565f, 0.006969f, 0.007618f, 0.008293f, 0.008980f, 0.009766f, 0.010612f, 0.011528f, 0.012802f,
+ 0.014198f, 0.015671f, 0.017517f, 0.019592f, 0.021957f, 0.024918f, 0.028442f, 0.032562f, 0.037567f, 0.043762f, 0.051025f, 0.059753f,
+ 0.071045f, 0.084412f, 0.099792f, 0.119385f, 0.141846f, 0.167969f, 0.199341f, 0.233521f, 0.272461f, 0.315674f, 0.712891f, 0.733887f,
+ 0.738770f, 0.740234f, 0.741211f, 0.741699f, 0.000185f, 0.000434f, 0.000489f, 0.000732f, 0.000874f, 0.000968f, 0.001122f, 0.001124f,
+ 0.001371f, 0.001423f, 0.001639f, 0.001693f, 0.001805f, 0.002094f, 0.002241f, 0.002356f, 0.002567f, 0.002691f, 0.002871f, 0.003063f,
+ 0.003195f, 0.003582f, 0.003790f, 0.004089f, 0.004372f, 0.004536f, 0.005085f, 0.005314f, 0.005699f, 0.006153f, 0.006672f, 0.007202f,
+ 0.007805f, 0.008522f, 0.009216f, 0.010071f, 0.011086f, 0.012184f, 0.013596f, 0.015297f, 0.017014f, 0.019363f, 0.021988f, 0.025299f,
+ 0.029282f, 0.033936f, 0.040070f, 0.047028f, 0.056519f, 0.067932f, 0.080872f, 0.098083f, 0.118469f, 0.143188f, 0.171753f, 0.205200f,
+ 0.243286f, 0.286133f, 0.698730f, 0.721680f, 0.725098f, 0.727051f, 0.728027f, 0.728516f, 0.000116f, 0.000267f, 0.000565f, 0.000505f,
+ 0.000648f, 0.000772f, 0.000813f, 0.001031f, 0.001107f, 0.001184f, 0.001335f, 0.001391f, 0.001451f, 0.001633f, 0.001798f, 0.001874f,
+ 0.002090f, 0.002192f, 0.002392f, 0.002464f, 0.002707f, 0.002895f, 0.003044f, 0.003206f, 0.003468f, 0.003666f, 0.003887f, 0.004261f,
+ 0.004524f, 0.004898f, 0.005379f, 0.005711f, 0.006130f, 0.006721f, 0.007267f, 0.007912f, 0.008659f, 0.009575f, 0.010475f, 0.011749f,
+ 0.013252f, 0.014717f, 0.016815f, 0.019302f, 0.022369f, 0.025955f, 0.030502f, 0.036285f, 0.043579f, 0.052795f, 0.064453f, 0.078735f,
+ 0.096497f, 0.118591f, 0.145508f, 0.177368f, 0.213989f, 0.256592f, 0.683105f, 0.707031f, 0.710938f, 0.713379f, 0.714844f, 0.714844f,
+ 0.000223f, 0.000239f, 0.000286f, 0.000476f, 0.000580f, 0.000647f, 0.000715f, 0.000843f, 0.000914f, 0.000950f, 0.001090f, 0.001163f,
+ 0.001259f, 0.001328f, 0.001392f, 0.001560f, 0.001549f, 0.001775f, 0.001868f, 0.001999f, 0.002199f, 0.002235f, 0.002436f, 0.002575f,
+ 0.002842f, 0.002892f, 0.003111f, 0.003401f, 0.003563f, 0.003887f, 0.004196f, 0.004505f, 0.004791f, 0.005142f, 0.005684f, 0.006153f,
+ 0.006710f, 0.007378f, 0.008064f, 0.008881f, 0.009979f, 0.011177f, 0.012779f, 0.014435f, 0.016647f, 0.019150f, 0.022583f, 0.027252f,
+ 0.033051f, 0.040039f, 0.049561f, 0.061340f, 0.076843f, 0.096313f, 0.120544f, 0.150513f, 0.185547f, 0.227173f, 0.668457f, 0.692383f,
+ 0.696289f, 0.698242f, 0.699219f, 0.701172f, 0.000000f, 0.000109f, 0.000315f, 0.000449f, 0.000511f, 0.000507f, 0.000538f, 0.000653f,
+ 0.000724f, 0.000749f, 0.000830f, 0.000893f, 0.001007f, 0.001079f, 0.001189f, 0.001163f, 0.001335f, 0.001307f, 0.001502f, 0.001575f,
+ 0.001627f, 0.001778f, 0.001933f, 0.002029f, 0.002155f, 0.002254f, 0.002401f, 0.002535f, 0.002829f, 0.002943f, 0.003143f, 0.003422f,
+ 0.003710f, 0.003990f, 0.004318f, 0.004627f, 0.005108f, 0.005585f, 0.006142f, 0.006641f, 0.007378f, 0.008354f, 0.009430f, 0.010628f,
+ 0.012123f, 0.014015f, 0.016541f, 0.019836f, 0.023849f, 0.029312f, 0.036774f, 0.046356f, 0.058868f, 0.075562f, 0.097107f, 0.124634f,
+ 0.157837f, 0.197754f, 0.653320f, 0.677734f, 0.682129f, 0.684082f, 0.685547f, 0.684570f, 0.000166f, 0.000195f, 0.000256f, 0.000372f,
+ 0.000386f, 0.000415f, 0.000515f, 0.000432f, 0.000579f, 0.000606f, 0.000706f, 0.000745f, 0.000764f, 0.000837f, 0.000853f, 0.000993f,
+ 0.001034f, 0.001066f, 0.001156f, 0.001203f, 0.001339f, 0.001418f, 0.001470f, 0.001612f, 0.001614f, 0.001707f, 0.001850f, 0.001986f,
+ 0.002151f, 0.002254f, 0.002499f, 0.002560f, 0.002794f, 0.003000f, 0.003212f, 0.003510f, 0.003761f, 0.004086f, 0.004475f, 0.004967f,
+ 0.005428f, 0.006134f, 0.006840f, 0.007786f, 0.008858f, 0.010033f, 0.011909f, 0.014137f, 0.016907f, 0.020767f, 0.025894f, 0.033386f,
+ 0.043274f, 0.056854f, 0.075439f, 0.099548f, 0.130737f, 0.169434f, 0.634277f, 0.661133f, 0.667480f, 0.668945f, 0.669922f, 0.670898f,
+ 0.000115f, 0.000119f, 0.000230f, 0.000304f, 0.000221f, 0.000380f, 0.000322f, 0.000351f, 0.000453f, 0.000527f, 0.000535f, 0.000558f,
+ 0.000595f, 0.000675f, 0.000707f, 0.000670f, 0.000776f, 0.000812f, 0.000839f, 0.000911f, 0.000974f, 0.001033f, 0.001082f, 0.001154f,
+ 0.001209f, 0.001268f, 0.001416f, 0.001432f, 0.001607f, 0.001775f, 0.001877f, 0.001911f, 0.002041f, 0.002207f, 0.002380f, 0.002563f,
+ 0.002741f, 0.002956f, 0.003281f, 0.003513f, 0.003902f, 0.004353f, 0.004803f, 0.005405f, 0.006256f, 0.007072f, 0.008263f, 0.009659f,
+ 0.011627f, 0.014221f, 0.017792f, 0.022919f, 0.030075f, 0.040497f, 0.055878f, 0.076721f, 0.104980f, 0.141357f, 0.618652f, 0.644531f,
+ 0.650391f, 0.652832f, 0.653320f, 0.654785f, 0.000000f, 0.000122f, 0.000142f, 0.000227f, 0.000248f, 0.000246f, 0.000296f, 0.000254f,
+ 0.000308f, 0.000329f, 0.000387f, 0.000437f, 0.000443f, 0.000504f, 0.000515f, 0.000535f, 0.000566f, 0.000592f, 0.000618f, 0.000641f,
+ 0.000706f, 0.000746f, 0.000787f, 0.000839f, 0.000878f, 0.000920f, 0.001043f, 0.001041f, 0.001136f, 0.001199f, 0.001258f, 0.001393f,
+ 0.001428f, 0.001549f, 0.001632f, 0.001856f, 0.001945f, 0.002079f, 0.002310f, 0.002489f, 0.002708f, 0.002996f, 0.003315f, 0.003759f,
+ 0.004177f, 0.004803f, 0.005619f, 0.006527f, 0.007793f, 0.009468f, 0.011917f, 0.015152f, 0.019897f, 0.027298f, 0.038910f, 0.055908f,
+ 0.080811f, 0.114563f, 0.600586f, 0.628906f, 0.634277f, 0.636719f, 0.637207f, 0.638672f, 0.000000f, 0.000000f, 0.000106f, 0.000137f,
+ 0.000172f, 0.000211f, 0.000189f, 0.000226f, 0.000230f, 0.000248f, 0.000293f, 0.000251f, 0.000264f, 0.000321f, 0.000343f, 0.000399f,
+ 0.000368f, 0.000401f, 0.000499f, 0.000479f, 0.000498f, 0.000526f, 0.000550f, 0.000595f, 0.000631f, 0.000645f, 0.000726f, 0.000717f,
+ 0.000786f, 0.000902f, 0.000865f, 0.000916f, 0.000989f, 0.001059f, 0.001165f, 0.001246f, 0.001279f, 0.001408f, 0.001566f, 0.001628f,
+ 0.001808f, 0.001991f, 0.002165f, 0.002466f, 0.002766f, 0.003084f, 0.003534f, 0.004250f, 0.005016f, 0.006130f, 0.007584f, 0.009605f,
+ 0.012718f, 0.017395f, 0.025131f, 0.038269f, 0.058899f, 0.089661f, 0.582031f, 0.611328f, 0.616699f, 0.620117f, 0.621094f, 0.622559f,
+ 0.000000f, 0.000108f, 0.000104f, 0.000095f, 0.000117f, 0.000117f, 0.000122f, 0.000143f, 0.000147f, 0.000164f, 0.000174f, 0.000216f,
+ 0.000191f, 0.000227f, 0.000241f, 0.000250f, 0.000257f, 0.000271f, 0.000301f, 0.000298f, 0.000317f, 0.000344f, 0.000370f, 0.000392f,
+ 0.000404f, 0.000427f, 0.000491f, 0.000491f, 0.000519f, 0.000535f, 0.000611f, 0.000601f, 0.000668f, 0.000698f, 0.000767f, 0.000838f,
+ 0.000865f, 0.000895f, 0.000993f, 0.001066f, 0.001161f, 0.001242f, 0.001415f, 0.001521f, 0.001743f, 0.001901f, 0.002209f, 0.002523f,
+ 0.003038f, 0.003601f, 0.004478f, 0.005699f, 0.007545f, 0.010437f, 0.015175f, 0.023682f, 0.039429f, 0.066406f, 0.563477f, 0.593262f,
+ 0.598633f, 0.602051f, 0.602539f, 0.603516f, 0.000000f, 0.000101f, 0.000093f, 0.000087f, 0.000082f, 0.000078f, 0.000084f, 0.000087f,
+ 0.000093f, 0.000094f, 0.000099f, 0.000104f, 0.000114f, 0.000123f, 0.000158f, 0.000163f, 0.000166f, 0.000178f, 0.000177f, 0.000214f,
+ 0.000191f, 0.000208f, 0.000212f, 0.000247f, 0.000268f, 0.000263f, 0.000272f, 0.000287f, 0.000310f, 0.000336f, 0.000353f, 0.000368f,
+ 0.000396f, 0.000408f, 0.000453f, 0.000476f, 0.000511f, 0.000540f, 0.000615f, 0.000635f, 0.000682f, 0.000751f, 0.000812f, 0.000908f,
+ 0.000987f, 0.001116f, 0.001278f, 0.001431f, 0.001702f, 0.002047f, 0.002512f, 0.003126f, 0.004181f, 0.005817f, 0.008553f, 0.013489f,
+ 0.023697f, 0.045288f, 0.544922f, 0.575684f, 0.581543f, 0.584473f, 0.585938f, 0.587402f, 0.000109f, 0.000091f, 0.000081f, 0.000075f,
+ 0.000070f, 0.000067f, 0.000064f, 0.000061f, 0.000057f, 0.000054f, 0.000058f, 0.000075f, 0.000062f, 0.000064f, 0.000085f, 0.000068f,
+ 0.000092f, 0.000094f, 0.000103f, 0.000110f, 0.000113f, 0.000119f, 0.000141f, 0.000141f, 0.000148f, 0.000152f, 0.000159f, 0.000164f,
+ 0.000175f, 0.000188f, 0.000184f, 0.000218f, 0.000233f, 0.000223f, 0.000253f, 0.000265f, 0.000282f, 0.000321f, 0.000322f, 0.000351f,
+ 0.000371f, 0.000405f, 0.000443f, 0.000478f, 0.000515f, 0.000571f, 0.000652f, 0.000733f, 0.000856f, 0.001011f, 0.001227f, 0.001531f,
+ 0.002029f, 0.002817f, 0.004215f, 0.006874f, 0.012390f, 0.027405f, 0.525879f, 0.557129f, 0.563477f, 0.566895f, 0.568848f, 0.569824f,
+ 0.000094f, 0.000073f, 0.000065f, 0.000060f, 0.000055f, 0.000052f, 0.000049f, 0.000048f, 0.000046f, 0.000045f, 0.000042f, 0.000040f,
+ 0.000040f, 0.000037f, 0.000035f, 0.000035f, 0.000042f, 0.000036f, 0.000049f, 0.000051f, 0.000055f, 0.000056f, 0.000059f, 0.000062f,
+ 0.000064f, 0.000078f, 0.000071f, 0.000079f, 0.000088f, 0.000091f, 0.000093f, 0.000099f, 0.000103f, 0.000110f, 0.000125f, 0.000123f,
+ 0.000127f, 0.000151f, 0.000151f, 0.000161f, 0.000169f, 0.000179f, 0.000204f, 0.000219f, 0.000240f, 0.000267f, 0.000294f, 0.000321f,
+ 0.000378f, 0.000438f, 0.000524f, 0.000628f, 0.000818f, 0.001125f, 0.001693f, 0.002888f, 0.005638f, 0.013580f, 0.505859f, 0.539062f,
+ 0.544922f, 0.548340f, 0.550293f, 0.550781f, 0.000064f, 0.000048f, 0.000041f, 0.000037f, 0.000035f, 0.000034f, 0.000032f, 0.000031f,
+ 0.000030f, 0.000029f, 0.000028f, 0.000028f, 0.000027f, 0.000027f, 0.000026f, 0.000025f, 0.000024f, 0.000023f, 0.000022f, 0.000021f,
+ 0.000020f, 0.000019f, 0.000019f, 0.000023f, 0.000021f, 0.000022f, 0.000026f, 0.000029f, 0.000032f, 0.000031f, 0.000036f, 0.000037f,
+ 0.000036f, 0.000044f, 0.000046f, 0.000048f, 0.000052f, 0.000054f, 0.000056f, 0.000061f, 0.000070f, 0.000073f, 0.000076f, 0.000081f,
+ 0.000082f, 0.000095f, 0.000105f, 0.000120f, 0.000126f, 0.000143f, 0.000173f, 0.000203f, 0.000267f, 0.000346f, 0.000505f, 0.000853f,
+ 0.001829f, 0.005222f, 0.487061f, 0.519531f, 0.527344f, 0.529785f, 0.531738f, 0.532715f, 0.000000f, 0.000002f, 0.000003f, 0.000004f,
+ 0.000008f, 0.000008f, 0.000008f, 0.000010f, 0.000009f, 0.000010f, 0.000010f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f,
+ 0.000012f, 0.000011f, 0.000012f, 0.000011f, 0.000012f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000010f,
+ 0.000009f, 0.000009f, 0.000009f, 0.000008f, 0.000008f, 0.000007f, 0.000008f, 0.000009f, 0.000010f, 0.000012f, 0.000012f, 0.000015f,
+ 0.000013f, 0.000015f, 0.000018f, 0.000020f, 0.000021f, 0.000022f, 0.000022f, 0.000024f, 0.000026f, 0.000027f, 0.000034f, 0.000043f,
+ 0.000049f, 0.000065f, 0.000089f, 0.000138f, 0.000293f, 0.001143f, 0.466553f, 0.500488f, 0.508301f, 0.510742f, 0.512207f, 0.513672f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000004f, 0.000006f, 0.000023f, 0.446777f, 0.482178f,
+ 0.489746f, 0.492676f, 0.494629f, 0.496094f,
+ },
+ {
+ 0.032318f, 0.095032f, 0.152344f, 0.205322f, 0.254883f, 0.299316f, 0.342041f, 0.380859f, 0.416504f, 0.449707f, 0.481201f, 0.508789f,
+ 0.537109f, 0.562012f, 0.584961f, 0.608398f, 0.628418f, 0.648926f, 0.666504f, 0.684570f, 0.701172f, 0.716797f, 0.731934f, 0.746094f,
+ 0.759766f, 0.770996f, 0.784668f, 0.795898f, 0.806641f, 0.817871f, 0.827637f, 0.837402f, 0.846680f, 0.855469f, 0.863770f, 0.872559f,
+ 0.879883f, 0.887695f, 0.895508f, 0.901367f, 0.909180f, 0.915527f, 0.921387f, 0.927734f, 0.934082f, 0.939453f, 0.944824f, 0.950684f,
+ 0.955566f, 0.960449f, 0.965332f, 0.969238f, 0.974121f, 0.978516f, 0.982910f, 0.986816f, 0.990723f, 0.994629f, 0.994629f, 0.987793f,
+ 0.981934f, 0.976562f, 0.971680f, 0.966797f, 0.025833f, 0.076965f, 0.125854f, 0.173096f, 0.217896f, 0.259766f, 0.299561f, 0.338135f,
+ 0.372559f, 0.407471f, 0.437500f, 0.468262f, 0.496582f, 0.522949f, 0.547852f, 0.571289f, 0.593750f, 0.614746f, 0.633789f, 0.652832f,
+ 0.671387f, 0.687988f, 0.705078f, 0.719727f, 0.734863f, 0.749023f, 0.761719f, 0.774414f, 0.786621f, 0.797363f, 0.808594f, 0.818848f,
+ 0.829590f, 0.838867f, 0.848633f, 0.858398f, 0.865723f, 0.874512f, 0.881836f, 0.890137f, 0.897949f, 0.904297f, 0.910645f, 0.917480f,
+ 0.923828f, 0.929688f, 0.935547f, 0.941895f, 0.947266f, 0.952637f, 0.957520f, 0.962402f, 0.967285f, 0.971680f, 0.976562f, 0.980957f,
+ 0.984863f, 0.989258f, 0.992676f, 0.985840f, 0.979980f, 0.975098f, 0.970703f, 0.966309f, 0.020828f, 0.063049f, 0.104797f, 0.146606f,
+ 0.187134f, 0.225464f, 0.263916f, 0.299072f, 0.333252f, 0.366943f, 0.398438f, 0.429199f, 0.457031f, 0.484131f, 0.509766f, 0.534668f,
+ 0.559082f, 0.579590f, 0.600586f, 0.622070f, 0.640625f, 0.659180f, 0.676758f, 0.692383f, 0.708984f, 0.722656f, 0.737793f, 0.751465f,
+ 0.764648f, 0.776367f, 0.789062f, 0.801270f, 0.811523f, 0.821289f, 0.832031f, 0.841309f, 0.850586f, 0.860352f, 0.868652f, 0.876953f,
+ 0.884766f, 0.892090f, 0.899902f, 0.906738f, 0.913086f, 0.920410f, 0.927246f, 0.933105f, 0.938477f, 0.944336f, 0.950195f, 0.955078f,
+ 0.959961f, 0.965332f, 0.970215f, 0.975098f, 0.979492f, 0.983887f, 0.989746f, 0.983398f, 0.978516f, 0.973633f, 0.969238f, 0.964844f,
+ 0.017273f, 0.052429f, 0.088745f, 0.124207f, 0.160034f, 0.195068f, 0.230103f, 0.263916f, 0.297119f, 0.329102f, 0.360596f, 0.390625f,
+ 0.418945f, 0.446289f, 0.472656f, 0.498535f, 0.521973f, 0.545898f, 0.567871f, 0.588867f, 0.609375f, 0.629395f, 0.646973f, 0.664551f,
+ 0.681641f, 0.698242f, 0.712402f, 0.727539f, 0.741699f, 0.755371f, 0.768555f, 0.780762f, 0.792480f, 0.803711f, 0.814941f, 0.825195f,
+ 0.834961f, 0.844727f, 0.854004f, 0.863281f, 0.871094f, 0.879883f, 0.887695f, 0.895508f, 0.902832f, 0.909668f, 0.916504f, 0.923828f,
+ 0.929688f, 0.936035f, 0.941895f, 0.947754f, 0.952637f, 0.958496f, 0.963379f, 0.968750f, 0.973633f, 0.978027f, 0.986816f, 0.980957f,
+ 0.976562f, 0.972168f, 0.967285f, 0.963379f, 0.014076f, 0.043915f, 0.074951f, 0.106140f, 0.137573f, 0.169189f, 0.201416f, 0.233154f,
+ 0.264648f, 0.295166f, 0.324707f, 0.354248f, 0.381836f, 0.410156f, 0.436279f, 0.462891f, 0.487793f, 0.510742f, 0.534180f, 0.556152f,
+ 0.576660f, 0.598145f, 0.616211f, 0.636719f, 0.653320f, 0.670410f, 0.687500f, 0.703125f, 0.718262f, 0.733398f, 0.746582f, 0.760742f,
+ 0.772949f, 0.785156f, 0.796875f, 0.808105f, 0.818848f, 0.829590f, 0.838867f, 0.848145f, 0.857910f, 0.867188f, 0.875977f, 0.883301f,
+ 0.891602f, 0.899414f, 0.906738f, 0.913086f, 0.919922f, 0.926270f, 0.932617f, 0.938477f, 0.944824f, 0.951660f, 0.957520f, 0.961914f,
+ 0.967285f, 0.972168f, 0.984863f, 0.979004f, 0.974609f, 0.970215f, 0.966309f, 0.961914f, 0.012077f, 0.037445f, 0.063660f, 0.090881f,
+ 0.118774f, 0.147827f, 0.176636f, 0.206055f, 0.234253f, 0.262939f, 0.291504f, 0.320312f, 0.347168f, 0.374756f, 0.401367f, 0.427734f,
+ 0.451904f, 0.477051f, 0.500488f, 0.523438f, 0.545898f, 0.566406f, 0.587402f, 0.605957f, 0.624512f, 0.643555f, 0.662109f, 0.676758f,
+ 0.693848f, 0.708984f, 0.724609f, 0.738770f, 0.751465f, 0.765137f, 0.777344f, 0.790039f, 0.800781f, 0.812500f, 0.823242f, 0.833984f,
+ 0.842773f, 0.853027f, 0.861816f, 0.871094f, 0.879395f, 0.887695f, 0.895508f, 0.903320f, 0.910156f, 0.917969f, 0.924316f, 0.931152f,
+ 0.937988f, 0.943848f, 0.949219f, 0.955566f, 0.960449f, 0.966309f, 0.981445f, 0.977051f, 0.972168f, 0.968262f, 0.964355f, 0.960938f,
+ 0.010445f, 0.032562f, 0.054657f, 0.078613f, 0.103333f, 0.128540f, 0.153564f, 0.181274f, 0.207520f, 0.234619f, 0.261475f, 0.288818f,
+ 0.315674f, 0.342041f, 0.368408f, 0.394287f, 0.418945f, 0.443604f, 0.467773f, 0.490479f, 0.512695f, 0.534180f, 0.555664f, 0.575684f,
+ 0.596191f, 0.616211f, 0.633301f, 0.651855f, 0.668457f, 0.685547f, 0.701172f, 0.714844f, 0.729492f, 0.743652f, 0.758301f, 0.770996f,
+ 0.783203f, 0.794922f, 0.806641f, 0.817383f, 0.827637f, 0.838867f, 0.847656f, 0.857422f, 0.866699f, 0.875000f, 0.884277f, 0.892578f,
+ 0.900391f, 0.907227f, 0.914551f, 0.922363f, 0.929199f, 0.935059f, 0.941895f, 0.948242f, 0.953125f, 0.959473f, 0.978516f, 0.974609f,
+ 0.970215f, 0.966309f, 0.962402f, 0.958984f, 0.009117f, 0.027466f, 0.047424f, 0.067871f, 0.089783f, 0.112244f, 0.135376f, 0.159668f,
+ 0.184082f, 0.209106f, 0.233887f, 0.259277f, 0.285400f, 0.311523f, 0.336182f, 0.360840f, 0.385986f, 0.410889f, 0.435059f, 0.458252f,
+ 0.480713f, 0.503418f, 0.524902f, 0.546387f, 0.566895f, 0.586426f, 0.605469f, 0.624512f, 0.642578f, 0.659668f, 0.676758f, 0.692383f,
+ 0.708008f, 0.722168f, 0.736816f, 0.749512f, 0.763184f, 0.776855f, 0.789062f, 0.800781f, 0.812012f, 0.823730f, 0.833496f, 0.843750f,
+ 0.854004f, 0.863281f, 0.872559f, 0.880371f, 0.889648f, 0.896973f, 0.905762f, 0.912598f, 0.919922f, 0.927734f, 0.934082f, 0.940918f,
+ 0.946289f, 0.952637f, 0.976074f, 0.972168f, 0.967773f, 0.963867f, 0.960938f, 0.957031f, 0.007561f, 0.024231f, 0.041077f, 0.059631f,
+ 0.078369f, 0.098145f, 0.119507f, 0.140747f, 0.163208f, 0.185913f, 0.209839f, 0.233154f, 0.257324f, 0.281494f, 0.305908f, 0.330566f,
+ 0.354736f, 0.378906f, 0.402588f, 0.425781f, 0.449219f, 0.471924f, 0.494385f, 0.516602f, 0.536621f, 0.557617f, 0.576660f, 0.596680f,
+ 0.616211f, 0.632812f, 0.650879f, 0.668457f, 0.684082f, 0.700684f, 0.715332f, 0.729492f, 0.744141f, 0.757812f, 0.771973f, 0.783691f,
+ 0.796387f, 0.807129f, 0.818359f, 0.829590f, 0.840820f, 0.850098f, 0.859375f, 0.868652f, 0.877930f, 0.886719f, 0.894531f, 0.903320f,
+ 0.910645f, 0.918945f, 0.925781f, 0.932617f, 0.939453f, 0.945801f, 0.972656f, 0.969727f, 0.965820f, 0.961914f, 0.958496f, 0.955078f,
+ 0.006832f, 0.020676f, 0.036224f, 0.051758f, 0.069214f, 0.086609f, 0.105225f, 0.124146f, 0.144653f, 0.165527f, 0.186646f, 0.209106f,
+ 0.232178f, 0.254883f, 0.277588f, 0.301758f, 0.325195f, 0.348633f, 0.371826f, 0.395264f, 0.418213f, 0.440674f, 0.463135f, 0.485596f,
+ 0.506348f, 0.527832f, 0.548340f, 0.567871f, 0.587891f, 0.606934f, 0.625977f, 0.642578f, 0.660645f, 0.677734f, 0.692871f, 0.708008f,
+ 0.723633f, 0.737793f, 0.752441f, 0.765137f, 0.778320f, 0.791504f, 0.802734f, 0.814453f, 0.825684f, 0.835449f, 0.847168f, 0.856934f,
+ 0.866699f, 0.875488f, 0.884766f, 0.893066f, 0.901367f, 0.910156f, 0.917480f, 0.924805f, 0.932129f, 0.938965f, 0.970215f, 0.966797f,
+ 0.963379f, 0.959961f, 0.956543f, 0.953125f, 0.006050f, 0.018585f, 0.031860f, 0.045807f, 0.060883f, 0.076538f, 0.093323f, 0.109985f,
+ 0.128174f, 0.147949f, 0.167480f, 0.186768f, 0.208496f, 0.230591f, 0.252441f, 0.274170f, 0.297363f, 0.319824f, 0.342773f, 0.365723f,
+ 0.388672f, 0.411133f, 0.433350f, 0.455811f, 0.477295f, 0.498291f, 0.519531f, 0.539551f, 0.560059f, 0.580566f, 0.599121f, 0.617676f,
+ 0.635254f, 0.653320f, 0.669434f, 0.686523f, 0.702148f, 0.717773f, 0.732422f, 0.747070f, 0.760742f, 0.773926f, 0.786621f, 0.798340f,
+ 0.811035f, 0.822754f, 0.833008f, 0.843750f, 0.854004f, 0.863770f, 0.873047f, 0.882812f, 0.891602f, 0.900879f, 0.908691f, 0.916504f,
+ 0.924316f, 0.931152f, 0.966309f, 0.964355f, 0.961426f, 0.957520f, 0.954102f, 0.951172f, 0.005352f, 0.016388f, 0.027985f, 0.040222f,
+ 0.053436f, 0.067261f, 0.082520f, 0.098022f, 0.114319f, 0.131836f, 0.150146f, 0.167969f, 0.187744f, 0.208008f, 0.228271f, 0.249634f,
+ 0.270996f, 0.292969f, 0.314697f, 0.337158f, 0.359375f, 0.380859f, 0.403809f, 0.426025f, 0.447510f, 0.469482f, 0.490967f, 0.511719f,
+ 0.532227f, 0.552734f, 0.571777f, 0.591309f, 0.609375f, 0.628418f, 0.645508f, 0.663086f, 0.680664f, 0.696289f, 0.711426f, 0.727051f,
+ 0.741699f, 0.755859f, 0.768555f, 0.782227f, 0.795410f, 0.807617f, 0.818359f, 0.830078f, 0.841309f, 0.851074f, 0.861816f, 0.871582f,
+ 0.880859f, 0.890625f, 0.898438f, 0.907715f, 0.915527f, 0.923828f, 0.962402f, 0.961914f, 0.958496f, 0.955078f, 0.951172f, 0.948730f,
+ 0.004700f, 0.014397f, 0.025208f, 0.035675f, 0.047485f, 0.060120f, 0.073242f, 0.087097f, 0.102173f, 0.117249f, 0.133789f, 0.150513f,
+ 0.168823f, 0.186890f, 0.206665f, 0.225830f, 0.246216f, 0.267334f, 0.288574f, 0.309814f, 0.331299f, 0.353271f, 0.375244f, 0.396729f,
+ 0.418701f, 0.440674f, 0.461182f, 0.483398f, 0.504883f, 0.524902f, 0.544434f, 0.564941f, 0.584473f, 0.603027f, 0.621582f, 0.639648f,
+ 0.656738f, 0.673828f, 0.690430f, 0.705566f, 0.721680f, 0.736816f, 0.750977f, 0.764648f, 0.778809f, 0.791016f, 0.804688f, 0.815918f,
+ 0.826660f, 0.838867f, 0.850098f, 0.860840f, 0.870605f, 0.879883f, 0.889648f, 0.898438f, 0.907227f, 0.915527f, 0.959961f, 0.958496f,
+ 0.955078f, 0.952148f, 0.949219f, 0.946777f, 0.004238f, 0.013138f, 0.022202f, 0.031769f, 0.042358f, 0.053040f, 0.065613f, 0.077637f,
+ 0.090759f, 0.104980f, 0.119995f, 0.135498f, 0.151855f, 0.167725f, 0.186646f, 0.205078f, 0.224121f, 0.243042f, 0.263672f, 0.283936f,
+ 0.305176f, 0.326416f, 0.347168f, 0.369629f, 0.390625f, 0.411865f, 0.433350f, 0.454590f, 0.475830f, 0.497314f, 0.517578f, 0.537109f,
+ 0.557617f, 0.577637f, 0.596191f, 0.615723f, 0.632812f, 0.651367f, 0.668945f, 0.685059f, 0.701172f, 0.716797f, 0.732422f, 0.747559f,
+ 0.761230f, 0.775391f, 0.788574f, 0.800781f, 0.813965f, 0.824707f, 0.837402f, 0.848145f, 0.859375f, 0.869141f, 0.879395f, 0.889160f,
+ 0.897949f, 0.906250f, 0.956055f, 0.955566f, 0.952148f, 0.950195f, 0.947266f, 0.943848f, 0.003944f, 0.011490f, 0.019943f, 0.028748f,
+ 0.037964f, 0.047485f, 0.058014f, 0.069702f, 0.081360f, 0.093994f, 0.107361f, 0.121277f, 0.136353f, 0.151978f, 0.167480f, 0.185669f,
+ 0.202637f, 0.222168f, 0.240601f, 0.259766f, 0.279541f, 0.300293f, 0.321533f, 0.342285f, 0.362549f, 0.384033f, 0.405762f, 0.427002f,
+ 0.447998f, 0.469238f, 0.490479f, 0.510742f, 0.532227f, 0.551758f, 0.570312f, 0.589844f, 0.609375f, 0.628418f, 0.645508f, 0.662598f,
+ 0.680664f, 0.696777f, 0.712402f, 0.728516f, 0.744141f, 0.757812f, 0.771973f, 0.785156f, 0.798828f, 0.811523f, 0.824707f, 0.835449f,
+ 0.847168f, 0.858887f, 0.869141f, 0.878906f, 0.888672f, 0.897949f, 0.952148f, 0.952148f, 0.949219f, 0.946777f, 0.944336f, 0.941406f,
+ 0.003448f, 0.010574f, 0.017807f, 0.025558f, 0.033875f, 0.042633f, 0.052307f, 0.062134f, 0.073059f, 0.084045f, 0.096375f, 0.109192f,
+ 0.122803f, 0.136475f, 0.151367f, 0.167603f, 0.183960f, 0.201416f, 0.218506f, 0.237427f, 0.256104f, 0.275635f, 0.295410f, 0.315918f,
+ 0.336426f, 0.357178f, 0.378906f, 0.399414f, 0.421143f, 0.442139f, 0.462891f, 0.484375f, 0.504883f, 0.524902f, 0.544922f, 0.564941f,
+ 0.583984f, 0.603516f, 0.622070f, 0.640625f, 0.658691f, 0.675781f, 0.692871f, 0.709473f, 0.725098f, 0.740234f, 0.754883f, 0.769531f,
+ 0.783203f, 0.796875f, 0.809570f, 0.823242f, 0.834473f, 0.846191f, 0.857422f, 0.868164f, 0.878906f, 0.889160f, 0.948730f, 0.948242f,
+ 0.946289f, 0.944336f, 0.940918f, 0.938477f, 0.003017f, 0.009422f, 0.015900f, 0.023041f, 0.030380f, 0.038574f, 0.047150f, 0.055969f,
+ 0.065735f, 0.075684f, 0.086426f, 0.098267f, 0.110535f, 0.123047f, 0.136841f, 0.151489f, 0.166138f, 0.182495f, 0.198975f, 0.216553f,
+ 0.233765f, 0.252930f, 0.271484f, 0.291016f, 0.310547f, 0.331299f, 0.351562f, 0.372559f, 0.393555f, 0.415039f, 0.435059f, 0.457275f,
+ 0.477539f, 0.498047f, 0.519043f, 0.538574f, 0.559570f, 0.579102f, 0.598633f, 0.617188f, 0.635742f, 0.654297f, 0.672363f, 0.688965f,
+ 0.706055f, 0.721191f, 0.737793f, 0.752930f, 0.768066f, 0.782227f, 0.795898f, 0.809082f, 0.821289f, 0.833496f, 0.846191f, 0.857422f,
+ 0.869141f, 0.879883f, 0.944824f, 0.945312f, 0.942871f, 0.940918f, 0.938477f, 0.936035f, 0.002802f, 0.008575f, 0.014763f, 0.020844f,
+ 0.027557f, 0.034576f, 0.042084f, 0.050476f, 0.058990f, 0.067993f, 0.077942f, 0.087952f, 0.098999f, 0.111267f, 0.122803f, 0.136719f,
+ 0.150269f, 0.165527f, 0.180542f, 0.196533f, 0.213257f, 0.230591f, 0.248779f, 0.267334f, 0.286865f, 0.306152f, 0.325928f, 0.346436f,
+ 0.367188f, 0.387695f, 0.409424f, 0.429199f, 0.450195f, 0.471680f, 0.492920f, 0.513184f, 0.534180f, 0.553711f, 0.573730f, 0.593750f,
+ 0.612793f, 0.631836f, 0.649414f, 0.668457f, 0.685059f, 0.703125f, 0.719238f, 0.735352f, 0.750000f, 0.766113f, 0.781738f, 0.794434f,
+ 0.808105f, 0.821777f, 0.833984f, 0.846191f, 0.858398f, 0.870117f, 0.940918f, 0.941895f, 0.939941f, 0.937500f, 0.935059f, 0.932617f,
+ 0.002573f, 0.007603f, 0.013100f, 0.018799f, 0.024719f, 0.031372f, 0.038147f, 0.045105f, 0.052795f, 0.061127f, 0.069519f, 0.079529f,
+ 0.089355f, 0.099976f, 0.111084f, 0.123718f, 0.136353f, 0.148926f, 0.163574f, 0.178345f, 0.194214f, 0.210083f, 0.227783f, 0.245361f,
+ 0.263672f, 0.282471f, 0.301758f, 0.321533f, 0.341797f, 0.361816f, 0.383057f, 0.403320f, 0.424316f, 0.445557f, 0.466797f, 0.487061f,
+ 0.507812f, 0.528809f, 0.549805f, 0.569336f, 0.589844f, 0.608887f, 0.627930f, 0.646973f, 0.665527f, 0.682129f, 0.700195f, 0.717773f,
+ 0.732910f, 0.749512f, 0.765137f, 0.779785f, 0.794434f, 0.808105f, 0.821777f, 0.834473f, 0.847168f, 0.859375f, 0.936523f, 0.937988f,
+ 0.936035f, 0.933594f, 0.932129f, 0.929688f, 0.002409f, 0.007107f, 0.011833f, 0.017075f, 0.022278f, 0.028351f, 0.034088f, 0.040558f,
+ 0.047943f, 0.055389f, 0.063232f, 0.072021f, 0.080322f, 0.090454f, 0.100220f, 0.111389f, 0.122986f, 0.135010f, 0.148438f, 0.162109f,
+ 0.176270f, 0.191772f, 0.207642f, 0.224121f, 0.241699f, 0.259277f, 0.278076f, 0.297363f, 0.316650f, 0.336670f, 0.356934f, 0.377686f,
+ 0.397949f, 0.418701f, 0.439941f, 0.461914f, 0.482178f, 0.502930f, 0.524414f, 0.544922f, 0.565918f, 0.585938f, 0.605957f, 0.625000f,
+ 0.643066f, 0.662109f, 0.680176f, 0.698730f, 0.715820f, 0.731934f, 0.748047f, 0.764648f, 0.780273f, 0.794434f, 0.808594f, 0.821777f,
+ 0.836914f, 0.848145f, 0.932129f, 0.934082f, 0.932617f, 0.930176f, 0.928711f, 0.926270f, 0.002066f, 0.006329f, 0.010986f, 0.015541f,
+ 0.020294f, 0.025452f, 0.030975f, 0.037201f, 0.043152f, 0.049835f, 0.056824f, 0.064331f, 0.072998f, 0.081177f, 0.090637f, 0.100525f,
+ 0.110718f, 0.122131f, 0.134033f, 0.146851f, 0.159912f, 0.173584f, 0.189331f, 0.204468f, 0.221191f, 0.237671f, 0.255615f, 0.273682f,
+ 0.292969f, 0.312012f, 0.331543f, 0.352295f, 0.372314f, 0.393311f, 0.413818f, 0.435547f, 0.456055f, 0.477539f, 0.499023f, 0.520508f,
+ 0.540039f, 0.561523f, 0.581543f, 0.602051f, 0.622070f, 0.641113f, 0.659668f, 0.678223f, 0.697266f, 0.714844f, 0.731445f, 0.748535f,
+ 0.765137f, 0.778809f, 0.794922f, 0.810059f, 0.824219f, 0.837402f, 0.926758f, 0.930176f, 0.928711f, 0.926758f, 0.924805f, 0.922852f,
+ 0.001840f, 0.005703f, 0.009918f, 0.014099f, 0.018311f, 0.023026f, 0.028000f, 0.033508f, 0.038971f, 0.045044f, 0.051880f, 0.058289f,
+ 0.065796f, 0.073425f, 0.081482f, 0.090698f, 0.100464f, 0.110413f, 0.121216f, 0.132812f, 0.145142f, 0.158203f, 0.171997f, 0.186401f,
+ 0.201538f, 0.217651f, 0.234497f, 0.251465f, 0.269287f, 0.288330f, 0.307129f, 0.327148f, 0.346924f, 0.367920f, 0.388428f, 0.409668f,
+ 0.430420f, 0.451416f, 0.474121f, 0.494873f, 0.516113f, 0.537598f, 0.558105f, 0.579102f, 0.598633f, 0.619629f, 0.639160f, 0.657715f,
+ 0.677734f, 0.695801f, 0.713867f, 0.731934f, 0.748047f, 0.764160f, 0.781738f, 0.796875f, 0.810547f, 0.826172f, 0.922363f, 0.925781f,
+ 0.924805f, 0.922852f, 0.921387f, 0.919434f, 0.001621f, 0.005188f, 0.008888f, 0.012939f, 0.016724f, 0.021271f, 0.025772f, 0.029984f,
+ 0.035553f, 0.040741f, 0.046417f, 0.052490f, 0.059265f, 0.066528f, 0.074097f, 0.081482f, 0.090271f, 0.100220f, 0.109741f, 0.120178f,
+ 0.131226f, 0.143188f, 0.156006f, 0.169189f, 0.183716f, 0.198486f, 0.214233f, 0.230713f, 0.247925f, 0.265381f, 0.284424f, 0.303711f,
+ 0.322754f, 0.342773f, 0.363525f, 0.384277f, 0.405518f, 0.427002f, 0.447754f, 0.469727f, 0.491455f, 0.512207f, 0.534180f, 0.554688f,
+ 0.576172f, 0.597168f, 0.617188f, 0.636719f, 0.657227f, 0.677734f, 0.695312f, 0.713379f, 0.731934f, 0.749512f, 0.766113f, 0.782715f,
+ 0.798340f, 0.813477f, 0.917480f, 0.920898f, 0.920410f, 0.919922f, 0.916992f, 0.915039f, 0.001581f, 0.004616f, 0.008049f, 0.011917f,
+ 0.015556f, 0.019547f, 0.023270f, 0.027908f, 0.031860f, 0.036652f, 0.041992f, 0.047577f, 0.053528f, 0.060150f, 0.066772f, 0.073914f,
+ 0.082153f, 0.090088f, 0.099304f, 0.108887f, 0.118835f, 0.129517f, 0.141357f, 0.154297f, 0.166992f, 0.180908f, 0.195557f, 0.210815f,
+ 0.227173f, 0.244141f, 0.261963f, 0.279785f, 0.299072f, 0.318359f, 0.338379f, 0.358887f, 0.380127f, 0.401123f, 0.422607f, 0.443848f,
+ 0.466309f, 0.487793f, 0.509277f, 0.530762f, 0.553223f, 0.573730f, 0.594727f, 0.616699f, 0.636719f, 0.656250f, 0.676270f, 0.695801f,
+ 0.713867f, 0.733398f, 0.750488f, 0.767090f, 0.784180f, 0.801270f, 0.912598f, 0.916992f, 0.916504f, 0.914551f, 0.913086f, 0.911133f,
+ 0.001476f, 0.004410f, 0.007374f, 0.010620f, 0.013931f, 0.017258f, 0.021057f, 0.024979f, 0.029144f, 0.033478f, 0.037872f, 0.042969f,
+ 0.048737f, 0.053986f, 0.060150f, 0.066895f, 0.074036f, 0.081665f, 0.089417f, 0.098083f, 0.107361f, 0.117371f, 0.127930f, 0.139648f,
+ 0.151489f, 0.164062f, 0.178589f, 0.192627f, 0.208130f, 0.223755f, 0.240601f, 0.258057f, 0.275879f, 0.295654f, 0.314697f, 0.334961f,
+ 0.354980f, 0.375977f, 0.396729f, 0.418945f, 0.440430f, 0.462402f, 0.484619f, 0.506348f, 0.528809f, 0.550781f, 0.572266f, 0.593750f,
+ 0.615234f, 0.637207f, 0.656738f, 0.676758f, 0.696289f, 0.716309f, 0.734863f, 0.752930f, 0.770508f, 0.788574f, 0.906738f, 0.911621f,
+ 0.912109f, 0.910156f, 0.908691f, 0.907227f, 0.001204f, 0.003998f, 0.006786f, 0.009850f, 0.012642f, 0.015762f, 0.019226f, 0.022751f,
+ 0.026749f, 0.030502f, 0.034698f, 0.038940f, 0.044006f, 0.048615f, 0.054352f, 0.060608f, 0.066711f, 0.073059f, 0.080505f, 0.088318f,
+ 0.097290f, 0.105835f, 0.115845f, 0.126343f, 0.137085f, 0.148804f, 0.161377f, 0.175049f, 0.189331f, 0.204346f, 0.219604f, 0.236816f,
+ 0.253662f, 0.272217f, 0.291260f, 0.310547f, 0.330811f, 0.350830f, 0.372314f, 0.393799f, 0.415771f, 0.437500f, 0.459717f, 0.481934f,
+ 0.504883f, 0.527344f, 0.549316f, 0.571777f, 0.593750f, 0.615723f, 0.636230f, 0.657715f, 0.678223f, 0.697754f, 0.718262f, 0.737793f,
+ 0.756348f, 0.774902f, 0.900879f, 0.907227f, 0.906738f, 0.905762f, 0.904297f, 0.902832f, 0.001290f, 0.003807f, 0.006207f, 0.008652f,
+ 0.011368f, 0.014618f, 0.017792f, 0.020813f, 0.023849f, 0.027588f, 0.031036f, 0.035400f, 0.039917f, 0.044250f, 0.049408f, 0.054321f,
+ 0.059937f, 0.065918f, 0.072937f, 0.079773f, 0.087463f, 0.095703f, 0.104553f, 0.113892f, 0.124146f, 0.134888f, 0.146606f, 0.159058f,
+ 0.171753f, 0.185913f, 0.201416f, 0.216309f, 0.232910f, 0.250000f, 0.268555f, 0.287354f, 0.306885f, 0.326904f, 0.347412f, 0.369141f,
+ 0.390381f, 0.412842f, 0.434570f, 0.457764f, 0.479736f, 0.502930f, 0.525879f, 0.547852f, 0.570801f, 0.592773f, 0.615723f, 0.637207f,
+ 0.659180f, 0.680176f, 0.700684f, 0.720703f, 0.740234f, 0.759766f, 0.895996f, 0.901855f, 0.901855f, 0.900879f, 0.899414f, 0.897949f,
+ 0.001030f, 0.003561f, 0.005718f, 0.008301f, 0.010582f, 0.013283f, 0.015839f, 0.018753f, 0.022156f, 0.025314f, 0.028427f, 0.032318f,
+ 0.035889f, 0.040039f, 0.044434f, 0.048737f, 0.054077f, 0.059723f, 0.065613f, 0.072083f, 0.079224f, 0.086426f, 0.094238f, 0.102966f,
+ 0.111938f, 0.122253f, 0.132568f, 0.143555f, 0.155884f, 0.168945f, 0.182861f, 0.197510f, 0.213379f, 0.229492f, 0.246948f, 0.264648f,
+ 0.283203f, 0.303467f, 0.322998f, 0.343994f, 0.365479f, 0.387451f, 0.409912f, 0.432129f, 0.455078f, 0.478760f, 0.501465f, 0.523926f,
+ 0.547852f, 0.570801f, 0.593750f, 0.616211f, 0.639160f, 0.661133f, 0.682617f, 0.703613f, 0.725098f, 0.745117f, 0.888672f, 0.896484f,
+ 0.896973f, 0.895020f, 0.895508f, 0.893555f, 0.001051f, 0.002956f, 0.005398f, 0.007523f, 0.009613f, 0.012024f, 0.014725f, 0.017059f,
+ 0.019714f, 0.022537f, 0.025681f, 0.029236f, 0.032715f, 0.036102f, 0.040100f, 0.043945f, 0.048859f, 0.053772f, 0.058838f, 0.064880f,
+ 0.070862f, 0.077576f, 0.084839f, 0.092712f, 0.101013f, 0.110229f, 0.119446f, 0.130005f, 0.141113f, 0.153198f, 0.166016f, 0.179565f,
+ 0.193970f, 0.209351f, 0.225830f, 0.242920f, 0.261230f, 0.280273f, 0.299316f, 0.320068f, 0.341309f, 0.363037f, 0.384521f, 0.407227f,
+ 0.429443f, 0.453369f, 0.477051f, 0.500977f, 0.524414f, 0.547852f, 0.571777f, 0.595215f, 0.619141f, 0.641602f, 0.664062f, 0.686035f,
+ 0.707520f, 0.729004f, 0.882812f, 0.891602f, 0.891113f, 0.890625f, 0.889160f, 0.888184f, 0.000934f, 0.002998f, 0.004883f, 0.006859f,
+ 0.009102f, 0.010925f, 0.012871f, 0.015656f, 0.017853f, 0.020767f, 0.023422f, 0.026413f, 0.029251f, 0.032593f, 0.036011f, 0.039825f,
+ 0.044495f, 0.048645f, 0.053284f, 0.058258f, 0.063782f, 0.069885f, 0.076111f, 0.083313f, 0.090881f, 0.099060f, 0.107788f, 0.117126f,
+ 0.127075f, 0.138428f, 0.150391f, 0.162720f, 0.176270f, 0.190796f, 0.206177f, 0.222290f, 0.239624f, 0.257568f, 0.276367f, 0.296387f,
+ 0.316895f, 0.338623f, 0.360352f, 0.382812f, 0.404785f, 0.428467f, 0.452148f, 0.476562f, 0.500488f, 0.524902f, 0.548828f, 0.572754f,
+ 0.597168f, 0.621094f, 0.644531f, 0.667480f, 0.689941f, 0.712402f, 0.875977f, 0.883789f, 0.884766f, 0.884766f, 0.883301f, 0.883789f,
+ 0.001108f, 0.002474f, 0.004707f, 0.006248f, 0.007744f, 0.009888f, 0.011787f, 0.014244f, 0.016205f, 0.018631f, 0.021286f, 0.023758f,
+ 0.026535f, 0.029510f, 0.032654f, 0.035919f, 0.039825f, 0.043762f, 0.047852f, 0.052368f, 0.057373f, 0.062561f, 0.068604f, 0.074707f,
+ 0.081360f, 0.088623f, 0.096802f, 0.105103f, 0.114624f, 0.124573f, 0.135498f, 0.147217f, 0.159424f, 0.172729f, 0.187378f, 0.202881f,
+ 0.219116f, 0.235962f, 0.254639f, 0.273438f, 0.293945f, 0.314453f, 0.335449f, 0.358154f, 0.380371f, 0.403564f, 0.428223f, 0.452148f,
+ 0.476074f, 0.500977f, 0.525879f, 0.550293f, 0.575195f, 0.599609f, 0.625000f, 0.649414f, 0.672852f, 0.695801f, 0.870117f, 0.879395f,
+ 0.879883f, 0.879395f, 0.878906f, 0.877441f, 0.000877f, 0.002495f, 0.003918f, 0.005669f, 0.007484f, 0.009148f, 0.010895f, 0.012634f,
+ 0.014717f, 0.017014f, 0.019302f, 0.021347f, 0.023849f, 0.026443f, 0.029388f, 0.032532f, 0.035492f, 0.039185f, 0.042816f, 0.046906f,
+ 0.051453f, 0.056122f, 0.061310f, 0.066895f, 0.072937f, 0.079590f, 0.086548f, 0.094360f, 0.103027f, 0.111938f, 0.121643f, 0.132568f,
+ 0.144043f, 0.156006f, 0.169434f, 0.184204f, 0.199341f, 0.215698f, 0.233032f, 0.251221f, 0.269531f, 0.290039f, 0.311768f, 0.333740f,
+ 0.355957f, 0.379395f, 0.402344f, 0.426758f, 0.451172f, 0.476562f, 0.501465f, 0.526855f, 0.552246f, 0.578613f, 0.603516f, 0.629395f,
+ 0.653809f, 0.679199f, 0.863281f, 0.872559f, 0.874023f, 0.873535f, 0.872559f, 0.871094f, 0.000779f, 0.002241f, 0.003813f, 0.005371f,
+ 0.006763f, 0.008186f, 0.009827f, 0.011574f, 0.013260f, 0.015274f, 0.017303f, 0.019119f, 0.021362f, 0.023972f, 0.026505f, 0.029144f,
+ 0.031860f, 0.035126f, 0.038422f, 0.041809f, 0.045929f, 0.050323f, 0.054840f, 0.059631f, 0.065002f, 0.070984f, 0.077759f, 0.084656f,
+ 0.091736f, 0.100037f, 0.109436f, 0.118835f, 0.129272f, 0.140625f, 0.152832f, 0.166138f, 0.180786f, 0.195679f, 0.211914f, 0.229736f,
+ 0.247803f, 0.267822f, 0.287598f, 0.309326f, 0.331055f, 0.354492f, 0.377686f, 0.401855f, 0.426270f, 0.451660f, 0.477051f, 0.503418f,
+ 0.529785f, 0.555664f, 0.583008f, 0.608887f, 0.635254f, 0.661133f, 0.855957f, 0.865234f, 0.866699f, 0.867188f, 0.866211f, 0.865723f,
+ 0.000778f, 0.002155f, 0.003584f, 0.004871f, 0.006149f, 0.007519f, 0.008858f, 0.010498f, 0.012100f, 0.013977f, 0.015511f, 0.017303f,
+ 0.019363f, 0.021515f, 0.023880f, 0.026230f, 0.028564f, 0.031555f, 0.034241f, 0.037476f, 0.041138f, 0.044983f, 0.048859f, 0.053436f,
+ 0.058014f, 0.063232f, 0.069214f, 0.075195f, 0.081848f, 0.089417f, 0.097168f, 0.106201f, 0.115479f, 0.126343f, 0.137695f, 0.149658f,
+ 0.162476f, 0.177002f, 0.192993f, 0.209473f, 0.226440f, 0.245239f, 0.264404f, 0.285156f, 0.306885f, 0.330078f, 0.353271f, 0.376465f,
+ 0.402100f, 0.426758f, 0.453857f, 0.479492f, 0.505859f, 0.532715f, 0.560547f, 0.587402f, 0.614258f, 0.640137f, 0.847168f, 0.858398f,
+ 0.860352f, 0.859863f, 0.859863f, 0.858887f, 0.000673f, 0.002026f, 0.003120f, 0.004242f, 0.005390f, 0.006874f, 0.008087f, 0.009346f,
+ 0.011192f, 0.012642f, 0.013855f, 0.015511f, 0.017502f, 0.019394f, 0.021301f, 0.023331f, 0.025681f, 0.028137f, 0.030792f, 0.033295f,
+ 0.036804f, 0.039917f, 0.043488f, 0.047363f, 0.051880f, 0.056580f, 0.061646f, 0.066956f, 0.072998f, 0.079407f, 0.086609f, 0.094971f,
+ 0.103027f, 0.112793f, 0.122742f, 0.134399f, 0.146118f, 0.159058f, 0.173828f, 0.188599f, 0.205444f, 0.223633f, 0.241943f, 0.262451f,
+ 0.283203f, 0.304932f, 0.328369f, 0.352051f, 0.376953f, 0.402100f, 0.428467f, 0.454834f, 0.481934f, 0.509766f, 0.537598f, 0.566406f,
+ 0.594238f, 0.622559f, 0.838867f, 0.852051f, 0.853516f, 0.853027f, 0.853027f, 0.852051f, 0.000419f, 0.001721f, 0.003044f, 0.003881f,
+ 0.005161f, 0.006329f, 0.007500f, 0.009117f, 0.009941f, 0.011147f, 0.013023f, 0.014053f, 0.015869f, 0.017181f, 0.018906f, 0.020889f,
+ 0.023026f, 0.025085f, 0.027435f, 0.029724f, 0.032440f, 0.035492f, 0.038605f, 0.042175f, 0.045898f, 0.049988f, 0.054504f, 0.059143f,
+ 0.064697f, 0.070435f, 0.076721f, 0.083984f, 0.091675f, 0.100037f, 0.109009f, 0.119629f, 0.130737f, 0.143066f, 0.156250f, 0.170654f,
+ 0.186157f, 0.202393f, 0.220825f, 0.239990f, 0.259521f, 0.281250f, 0.303467f, 0.327148f, 0.351318f, 0.376953f, 0.402832f, 0.430664f,
+ 0.458252f, 0.485596f, 0.514648f, 0.543457f, 0.572754f, 0.602051f, 0.830566f, 0.844238f, 0.845703f, 0.845703f, 0.845703f, 0.845215f,
+ 0.000503f, 0.001644f, 0.002455f, 0.003765f, 0.004906f, 0.005901f, 0.006805f, 0.007744f, 0.008789f, 0.009972f, 0.011314f, 0.012688f,
+ 0.014160f, 0.015480f, 0.016953f, 0.018555f, 0.020325f, 0.022232f, 0.024338f, 0.026535f, 0.028717f, 0.031403f, 0.034119f, 0.037384f,
+ 0.040680f, 0.044128f, 0.047943f, 0.052551f, 0.057098f, 0.062134f, 0.067871f, 0.074158f, 0.081543f, 0.088684f, 0.097107f, 0.106262f,
+ 0.116028f, 0.127563f, 0.139404f, 0.152344f, 0.167358f, 0.182739f, 0.199951f, 0.217773f, 0.237427f, 0.257812f, 0.279541f, 0.303223f,
+ 0.327148f, 0.351807f, 0.377441f, 0.405518f, 0.433105f, 0.460449f, 0.491211f, 0.520020f, 0.550293f, 0.581543f, 0.821777f, 0.835938f,
+ 0.837891f, 0.838867f, 0.838867f, 0.837891f, 0.000649f, 0.001432f, 0.002455f, 0.003469f, 0.004162f, 0.005192f, 0.006046f, 0.007053f,
+ 0.007919f, 0.009148f, 0.010185f, 0.011490f, 0.012558f, 0.013748f, 0.015083f, 0.016663f, 0.018341f, 0.019897f, 0.021561f, 0.023376f,
+ 0.025513f, 0.027725f, 0.030075f, 0.032745f, 0.035583f, 0.038544f, 0.041901f, 0.045898f, 0.049896f, 0.054443f, 0.059784f, 0.065186f,
+ 0.071228f, 0.078247f, 0.085632f, 0.093872f, 0.103088f, 0.113098f, 0.123840f, 0.135986f, 0.148682f, 0.163696f, 0.179321f, 0.196533f,
+ 0.214722f, 0.234985f, 0.256104f, 0.278320f, 0.302246f, 0.326660f, 0.352783f, 0.379395f, 0.406738f, 0.436279f, 0.465820f, 0.496338f,
+ 0.527344f, 0.559082f, 0.813477f, 0.827148f, 0.829590f, 0.830566f, 0.830566f, 0.829590f, 0.000427f, 0.001431f, 0.002077f, 0.002947f,
+ 0.004009f, 0.004860f, 0.005501f, 0.006416f, 0.007008f, 0.008171f, 0.009155f, 0.010063f, 0.011154f, 0.012474f, 0.013336f, 0.014793f,
+ 0.016006f, 0.017471f, 0.019119f, 0.020630f, 0.022079f, 0.024078f, 0.026505f, 0.028687f, 0.031128f, 0.033813f, 0.036804f, 0.040283f,
+ 0.043732f, 0.047882f, 0.052094f, 0.057281f, 0.062500f, 0.068726f, 0.075012f, 0.082581f, 0.090393f, 0.099487f, 0.109375f, 0.120728f,
+ 0.131958f, 0.145508f, 0.160278f, 0.176025f, 0.193848f, 0.212891f, 0.232788f, 0.253906f, 0.277344f, 0.302002f, 0.327637f, 0.354248f,
+ 0.382080f, 0.411621f, 0.441162f, 0.472656f, 0.504395f, 0.536621f, 0.803223f, 0.818359f, 0.821777f, 0.821777f, 0.822266f, 0.821777f,
+ 0.000574f, 0.001416f, 0.001961f, 0.002621f, 0.003527f, 0.004250f, 0.004894f, 0.005653f, 0.006340f, 0.007263f, 0.008255f, 0.008965f,
+ 0.009819f, 0.010857f, 0.011864f, 0.012917f, 0.014114f, 0.015358f, 0.016678f, 0.018005f, 0.019669f, 0.021347f, 0.023239f, 0.025070f,
+ 0.027267f, 0.029434f, 0.032318f, 0.035156f, 0.038269f, 0.041534f, 0.045624f, 0.049469f, 0.054321f, 0.059479f, 0.065369f, 0.071655f,
+ 0.078857f, 0.086853f, 0.095886f, 0.105652f, 0.116943f, 0.128662f, 0.142090f, 0.156860f, 0.173096f, 0.190918f, 0.210327f, 0.231201f,
+ 0.253418f, 0.277100f, 0.302490f, 0.328369f, 0.356445f, 0.385254f, 0.415771f, 0.446533f, 0.479736f, 0.513184f, 0.794434f, 0.810547f,
+ 0.812500f, 0.813477f, 0.812988f, 0.813477f, 0.000417f, 0.001152f, 0.002066f, 0.002480f, 0.003115f, 0.003778f, 0.004543f, 0.005001f,
+ 0.005936f, 0.006420f, 0.007130f, 0.007881f, 0.008789f, 0.009666f, 0.010605f, 0.011276f, 0.012352f, 0.013367f, 0.014626f, 0.015732f,
+ 0.017090f, 0.018509f, 0.020096f, 0.021759f, 0.023895f, 0.025681f, 0.027740f, 0.030121f, 0.032776f, 0.036011f, 0.039276f, 0.042694f,
+ 0.046906f, 0.051575f, 0.056488f, 0.061951f, 0.068481f, 0.075684f, 0.083191f, 0.092102f, 0.101990f, 0.112915f, 0.125122f, 0.138672f,
+ 0.153564f, 0.170410f, 0.188477f, 0.208008f, 0.229980f, 0.252441f, 0.276855f, 0.303711f, 0.331055f, 0.360596f, 0.391357f, 0.422607f,
+ 0.456299f, 0.490234f, 0.783203f, 0.799805f, 0.803223f, 0.804688f, 0.804199f, 0.805176f, 0.000422f, 0.000885f, 0.001743f, 0.002075f,
+ 0.002930f, 0.003460f, 0.004105f, 0.004696f, 0.005257f, 0.005753f, 0.006550f, 0.006916f, 0.007805f, 0.008308f, 0.009109f, 0.010056f,
+ 0.010918f, 0.011627f, 0.012787f, 0.013725f, 0.014732f, 0.016113f, 0.017319f, 0.018906f, 0.020264f, 0.022324f, 0.023911f, 0.026230f,
+ 0.028183f, 0.030884f, 0.033661f, 0.036865f, 0.040314f, 0.044189f, 0.048615f, 0.053284f, 0.058838f, 0.065491f, 0.072205f, 0.079651f,
+ 0.088379f, 0.098389f, 0.109314f, 0.121765f, 0.135010f, 0.150513f, 0.167358f, 0.186035f, 0.206543f, 0.228516f, 0.252197f, 0.278320f,
+ 0.305176f, 0.333496f, 0.364746f, 0.396973f, 0.430176f, 0.465820f, 0.772949f, 0.790527f, 0.794434f, 0.794922f, 0.795410f, 0.794922f,
+ 0.000211f, 0.000970f, 0.001484f, 0.002035f, 0.002586f, 0.003040f, 0.003540f, 0.004086f, 0.004696f, 0.005016f, 0.005508f, 0.006100f,
+ 0.006763f, 0.007401f, 0.008011f, 0.008675f, 0.009247f, 0.010071f, 0.011009f, 0.011940f, 0.012802f, 0.013870f, 0.014771f, 0.016281f,
+ 0.017487f, 0.018890f, 0.020584f, 0.022171f, 0.024200f, 0.026505f, 0.028870f, 0.031372f, 0.034363f, 0.037659f, 0.041412f, 0.045685f,
+ 0.050262f, 0.055664f, 0.061768f, 0.068359f, 0.076172f, 0.084717f, 0.094666f, 0.105835f, 0.117798f, 0.131958f, 0.147095f, 0.164795f,
+ 0.184326f, 0.204956f, 0.228271f, 0.253174f, 0.279785f, 0.307861f, 0.338379f, 0.370361f, 0.404785f, 0.440430f, 0.761230f, 0.780273f,
+ 0.783691f, 0.785645f, 0.786133f, 0.785156f, 0.000281f, 0.000954f, 0.001275f, 0.001745f, 0.002159f, 0.002810f, 0.003002f, 0.003622f,
+ 0.003918f, 0.004471f, 0.004776f, 0.005352f, 0.005852f, 0.006298f, 0.006989f, 0.007339f, 0.008087f, 0.008698f, 0.009499f, 0.010208f,
+ 0.010986f, 0.011871f, 0.012802f, 0.013809f, 0.014923f, 0.016129f, 0.017624f, 0.018753f, 0.020645f, 0.022156f, 0.024399f, 0.026382f,
+ 0.029037f, 0.031769f, 0.034851f, 0.038513f, 0.042542f, 0.047180f, 0.052063f, 0.058136f, 0.064819f, 0.072205f, 0.080933f, 0.090698f,
+ 0.101685f, 0.114441f, 0.128784f, 0.144287f, 0.162476f, 0.182617f, 0.203979f, 0.228149f, 0.253906f, 0.282227f, 0.312744f, 0.344482f,
+ 0.378418f, 0.415039f, 0.749023f, 0.770020f, 0.773438f, 0.774902f, 0.775391f, 0.776367f, 0.000200f, 0.000790f, 0.001209f, 0.001475f,
+ 0.002022f, 0.002375f, 0.002754f, 0.003136f, 0.003532f, 0.003851f, 0.004253f, 0.004719f, 0.004864f, 0.005455f, 0.005749f, 0.006435f,
+ 0.007053f, 0.007557f, 0.007988f, 0.008614f, 0.009216f, 0.010101f, 0.010712f, 0.011604f, 0.012596f, 0.013588f, 0.014877f, 0.016052f,
+ 0.017334f, 0.018753f, 0.020401f, 0.022415f, 0.024338f, 0.026642f, 0.029282f, 0.032196f, 0.035461f, 0.039215f, 0.043854f, 0.048706f,
+ 0.054413f, 0.060913f, 0.068237f, 0.076965f, 0.086792f, 0.097961f, 0.110657f, 0.125488f, 0.141846f, 0.160278f, 0.180542f, 0.203857f,
+ 0.229004f, 0.256348f, 0.286133f, 0.317627f, 0.351807f, 0.388184f, 0.737305f, 0.757812f, 0.762695f, 0.763672f, 0.764160f, 0.764648f,
+ 0.000214f, 0.000700f, 0.001134f, 0.001480f, 0.001724f, 0.002056f, 0.002468f, 0.002672f, 0.003069f, 0.003412f, 0.003618f, 0.003883f,
+ 0.004265f, 0.004627f, 0.004971f, 0.005508f, 0.005817f, 0.006397f, 0.006866f, 0.007244f, 0.007812f, 0.008446f, 0.009003f, 0.009872f,
+ 0.010544f, 0.011345f, 0.012375f, 0.013321f, 0.014275f, 0.015587f, 0.017075f, 0.018372f, 0.020050f, 0.022186f, 0.024246f, 0.026596f,
+ 0.029388f, 0.032562f, 0.036285f, 0.040344f, 0.045197f, 0.050568f, 0.056946f, 0.064514f, 0.072876f, 0.082886f, 0.093933f, 0.107056f,
+ 0.122070f, 0.139404f, 0.158325f, 0.180176f, 0.204590f, 0.231201f, 0.260010f, 0.290771f, 0.325195f, 0.361816f, 0.726074f, 0.747070f,
+ 0.751465f, 0.753418f, 0.753906f, 0.754395f, 0.000187f, 0.000637f, 0.001095f, 0.001133f, 0.001488f, 0.001872f, 0.002007f, 0.002253f,
+ 0.002590f, 0.002880f, 0.003010f, 0.003420f, 0.003593f, 0.003914f, 0.004322f, 0.004650f, 0.005051f, 0.005424f, 0.005733f, 0.006134f,
+ 0.006683f, 0.007183f, 0.007671f, 0.008072f, 0.008720f, 0.009483f, 0.010201f, 0.011070f, 0.011871f, 0.012863f, 0.013924f, 0.015167f,
+ 0.016434f, 0.018143f, 0.019669f, 0.021851f, 0.024109f, 0.026749f, 0.029587f, 0.033020f, 0.037109f, 0.041718f, 0.047119f, 0.053192f,
+ 0.060516f, 0.068848f, 0.078857f, 0.090149f, 0.104004f, 0.119202f, 0.136841f, 0.157471f, 0.180420f, 0.205322f, 0.234009f, 0.264648f,
+ 0.297852f, 0.335449f, 0.711914f, 0.735352f, 0.740234f, 0.741211f, 0.742676f, 0.742676f, 0.000201f, 0.000676f, 0.000884f, 0.001044f,
+ 0.001369f, 0.001633f, 0.001786f, 0.002001f, 0.002237f, 0.002460f, 0.002680f, 0.002777f, 0.003117f, 0.003408f, 0.003632f, 0.003910f,
+ 0.004211f, 0.004375f, 0.004772f, 0.005226f, 0.005520f, 0.005909f, 0.006302f, 0.006882f, 0.007385f, 0.007858f, 0.008553f, 0.008919f,
+ 0.009827f, 0.010582f, 0.011398f, 0.012520f, 0.013611f, 0.014725f, 0.016190f, 0.017593f, 0.019424f, 0.021622f, 0.023941f, 0.026703f,
+ 0.029938f, 0.033539f, 0.038055f, 0.043243f, 0.049408f, 0.056519f, 0.065002f, 0.074951f, 0.086548f, 0.100403f, 0.116394f, 0.135132f,
+ 0.156860f, 0.181030f, 0.208252f, 0.238281f, 0.271240f, 0.307861f, 0.698730f, 0.722656f, 0.727539f, 0.729980f, 0.730957f, 0.730469f,
+ 0.000185f, 0.000371f, 0.000784f, 0.001028f, 0.001153f, 0.001304f, 0.001567f, 0.001792f, 0.001790f, 0.002028f, 0.002283f, 0.002424f,
+ 0.002640f, 0.002764f, 0.003044f, 0.003313f, 0.003445f, 0.003748f, 0.004044f, 0.004337f, 0.004677f, 0.004879f, 0.005207f, 0.005661f,
+ 0.006027f, 0.006481f, 0.006870f, 0.007454f, 0.007874f, 0.008583f, 0.009239f, 0.009880f, 0.010849f, 0.011871f, 0.012833f, 0.014153f,
+ 0.015656f, 0.017151f, 0.018967f, 0.021118f, 0.023621f, 0.026703f, 0.030197f, 0.034576f, 0.039368f, 0.045441f, 0.052460f, 0.061157f,
+ 0.070862f, 0.083069f, 0.097290f, 0.114441f, 0.134155f, 0.157104f, 0.182983f, 0.212158f, 0.244507f, 0.281250f, 0.684570f, 0.710449f,
+ 0.715332f, 0.717285f, 0.717773f, 0.718750f, 0.000109f, 0.000455f, 0.000558f, 0.000757f, 0.000986f, 0.001166f, 0.001298f, 0.001310f,
+ 0.001566f, 0.001614f, 0.001852f, 0.001933f, 0.002062f, 0.002327f, 0.002571f, 0.002699f, 0.002909f, 0.003057f, 0.003254f, 0.003496f,
+ 0.003643f, 0.004066f, 0.004295f, 0.004665f, 0.004822f, 0.005161f, 0.005722f, 0.006008f, 0.006424f, 0.006897f, 0.007435f, 0.008049f,
+ 0.008789f, 0.009529f, 0.010284f, 0.011177f, 0.012321f, 0.013466f, 0.014885f, 0.016586f, 0.018417f, 0.020844f, 0.023575f, 0.026810f,
+ 0.030655f, 0.035400f, 0.041412f, 0.048462f, 0.056976f, 0.067322f, 0.079712f, 0.094543f, 0.112610f, 0.133789f, 0.158691f, 0.186279f,
+ 0.217896f, 0.253418f, 0.670898f, 0.696777f, 0.702148f, 0.704590f, 0.705078f, 0.705566f, 0.000000f, 0.000317f, 0.000556f, 0.000619f,
+ 0.000759f, 0.000889f, 0.001012f, 0.001163f, 0.001282f, 0.001353f, 0.001531f, 0.001621f, 0.001681f, 0.001862f, 0.001976f, 0.002140f,
+ 0.002392f, 0.002502f, 0.002745f, 0.002838f, 0.003019f, 0.003311f, 0.003477f, 0.003639f, 0.003889f, 0.004166f, 0.004429f, 0.004784f,
+ 0.005119f, 0.005547f, 0.006042f, 0.006317f, 0.006901f, 0.007442f, 0.008110f, 0.008751f, 0.009583f, 0.010590f, 0.011566f, 0.012894f,
+ 0.014404f, 0.015930f, 0.018158f, 0.020569f, 0.023697f, 0.027374f, 0.031830f, 0.037567f, 0.044434f, 0.053009f, 0.063599f, 0.076538f,
+ 0.092346f, 0.111511f, 0.134521f, 0.161133f, 0.191772f, 0.227173f, 0.654297f, 0.684082f, 0.687988f, 0.690918f, 0.691895f, 0.691895f,
+ 0.000000f, 0.000275f, 0.000368f, 0.000572f, 0.000683f, 0.000731f, 0.000877f, 0.000979f, 0.001039f, 0.001091f, 0.001234f, 0.001332f,
+ 0.001447f, 0.001547f, 0.001601f, 0.001760f, 0.001790f, 0.002007f, 0.002119f, 0.002245f, 0.002493f, 0.002565f, 0.002747f, 0.002920f,
+ 0.003168f, 0.003235f, 0.003551f, 0.003830f, 0.004040f, 0.004368f, 0.004658f, 0.005001f, 0.005337f, 0.005798f, 0.006287f, 0.006794f,
+ 0.007488f, 0.008087f, 0.008865f, 0.009773f, 0.010963f, 0.012199f, 0.013649f, 0.015610f, 0.017822f, 0.020493f, 0.023849f, 0.028320f,
+ 0.033752f, 0.040466f, 0.049377f, 0.060028f, 0.073853f, 0.090698f, 0.111572f, 0.136841f, 0.166016f, 0.199341f, 0.640137f, 0.667969f,
+ 0.675781f, 0.676758f, 0.678223f, 0.678223f, 0.000017f, 0.000193f, 0.000383f, 0.000487f, 0.000586f, 0.000597f, 0.000618f, 0.000733f,
+ 0.000826f, 0.000863f, 0.000902f, 0.001037f, 0.001121f, 0.001244f, 0.001342f, 0.001329f, 0.001514f, 0.001506f, 0.001719f, 0.001793f,
+ 0.001851f, 0.002016f, 0.002182f, 0.002281f, 0.002432f, 0.002554f, 0.002708f, 0.002859f, 0.003168f, 0.003344f, 0.003563f, 0.003845f,
+ 0.004158f, 0.004478f, 0.004852f, 0.005154f, 0.005714f, 0.006207f, 0.006752f, 0.007370f, 0.008186f, 0.009155f, 0.010193f, 0.011490f,
+ 0.013016f, 0.015144f, 0.017517f, 0.020752f, 0.024811f, 0.029922f, 0.036835f, 0.045593f, 0.056946f, 0.071533f, 0.090576f, 0.113159f,
+ 0.140991f, 0.173340f, 0.624023f, 0.653809f, 0.660156f, 0.663574f, 0.664551f, 0.664062f, 0.000194f, 0.000227f, 0.000316f, 0.000451f,
+ 0.000449f, 0.000482f, 0.000610f, 0.000511f, 0.000654f, 0.000673f, 0.000804f, 0.000844f, 0.000880f, 0.000955f, 0.000961f, 0.001127f,
+ 0.001169f, 0.001210f, 0.001318f, 0.001330f, 0.001507f, 0.001592f, 0.001657f, 0.001771f, 0.001839f, 0.001953f, 0.002083f, 0.002214f,
+ 0.002399f, 0.002518f, 0.002815f, 0.002882f, 0.003132f, 0.003361f, 0.003605f, 0.003925f, 0.004177f, 0.004528f, 0.004963f, 0.005527f,
+ 0.006027f, 0.006783f, 0.007381f, 0.008469f, 0.009644f, 0.010849f, 0.012772f, 0.014748f, 0.017578f, 0.021332f, 0.026367f, 0.033142f,
+ 0.042389f, 0.054413f, 0.070129f, 0.091064f, 0.116943f, 0.147339f, 0.608887f, 0.640137f, 0.645996f, 0.647461f, 0.650391f, 0.651367f,
+ 0.000166f, 0.000146f, 0.000248f, 0.000320f, 0.000288f, 0.000446f, 0.000375f, 0.000407f, 0.000468f, 0.000514f, 0.000629f, 0.000638f,
+ 0.000681f, 0.000773f, 0.000806f, 0.000766f, 0.000883f, 0.000927f, 0.000959f, 0.001036f, 0.001097f, 0.001172f, 0.001224f, 0.001297f,
+ 0.001392f, 0.001425f, 0.001592f, 0.001631f, 0.001793f, 0.001965f, 0.002089f, 0.002157f, 0.002321f, 0.002495f, 0.002680f, 0.002874f,
+ 0.003054f, 0.003305f, 0.003632f, 0.003902f, 0.004314f, 0.004753f, 0.005306f, 0.005901f, 0.006828f, 0.007645f, 0.008896f, 0.010323f,
+ 0.012283f, 0.014816f, 0.018234f, 0.023010f, 0.029678f, 0.039276f, 0.052307f, 0.070190f, 0.093811f, 0.123474f, 0.591797f, 0.623535f,
+ 0.631348f, 0.633301f, 0.634766f, 0.635254f, 0.000000f, 0.000154f, 0.000184f, 0.000257f, 0.000265f, 0.000266f, 0.000323f, 0.000291f,
+ 0.000369f, 0.000384f, 0.000450f, 0.000472f, 0.000505f, 0.000572f, 0.000577f, 0.000604f, 0.000636f, 0.000675f, 0.000699f, 0.000736f,
+ 0.000787f, 0.000840f, 0.000890f, 0.000945f, 0.000988f, 0.001039f, 0.001165f, 0.001165f, 0.001266f, 0.001318f, 0.001410f, 0.001550f,
+ 0.001618f, 0.001743f, 0.001866f, 0.001997f, 0.002151f, 0.002319f, 0.002562f, 0.002779f, 0.002975f, 0.003298f, 0.003674f, 0.004131f,
+ 0.004604f, 0.005268f, 0.006065f, 0.007027f, 0.008316f, 0.009949f, 0.012390f, 0.015526f, 0.019852f, 0.026733f, 0.036682f, 0.051666f,
+ 0.072449f, 0.099792f, 0.574707f, 0.608398f, 0.614746f, 0.618164f, 0.619629f, 0.621094f, 0.000000f, 0.000008f, 0.000146f, 0.000181f,
+ 0.000203f, 0.000243f, 0.000206f, 0.000250f, 0.000257f, 0.000283f, 0.000335f, 0.000293f, 0.000304f, 0.000368f, 0.000373f, 0.000435f,
+ 0.000418f, 0.000468f, 0.000539f, 0.000540f, 0.000564f, 0.000598f, 0.000628f, 0.000657f, 0.000716f, 0.000724f, 0.000797f, 0.000807f,
+ 0.000883f, 0.001002f, 0.000974f, 0.001037f, 0.001104f, 0.001196f, 0.001316f, 0.001394f, 0.001445f, 0.001574f, 0.001746f, 0.001829f,
+ 0.002005f, 0.002222f, 0.002401f, 0.002699f, 0.003057f, 0.003372f, 0.003874f, 0.004505f, 0.005360f, 0.006500f, 0.007927f, 0.009972f,
+ 0.012878f, 0.017258f, 0.024155f, 0.035339f, 0.052795f, 0.077637f, 0.558105f, 0.592285f, 0.600586f, 0.602539f, 0.604004f, 0.605469f,
+ 0.000000f, 0.000107f, 0.000122f, 0.000093f, 0.000133f, 0.000142f, 0.000149f, 0.000174f, 0.000174f, 0.000184f, 0.000190f, 0.000234f,
+ 0.000214f, 0.000250f, 0.000273f, 0.000286f, 0.000292f, 0.000302f, 0.000329f, 0.000336f, 0.000366f, 0.000391f, 0.000408f, 0.000444f,
+ 0.000452f, 0.000495f, 0.000531f, 0.000559f, 0.000578f, 0.000611f, 0.000659f, 0.000675f, 0.000757f, 0.000771f, 0.000854f, 0.000906f,
+ 0.000957f, 0.001004f, 0.001102f, 0.001187f, 0.001267f, 0.001394f, 0.001546f, 0.001683f, 0.001922f, 0.002094f, 0.002420f, 0.002754f,
+ 0.003254f, 0.003878f, 0.004757f, 0.005997f, 0.007812f, 0.010544f, 0.014786f, 0.022324f, 0.035522f, 0.057465f, 0.541504f, 0.576172f,
+ 0.583984f, 0.585938f, 0.588379f, 0.590332f, 0.000000f, 0.000099f, 0.000091f, 0.000084f, 0.000084f, 0.000086f, 0.000089f, 0.000101f,
+ 0.000105f, 0.000109f, 0.000122f, 0.000124f, 0.000132f, 0.000146f, 0.000171f, 0.000172f, 0.000176f, 0.000198f, 0.000197f, 0.000239f,
+ 0.000218f, 0.000235f, 0.000240f, 0.000281f, 0.000309f, 0.000301f, 0.000312f, 0.000321f, 0.000347f, 0.000370f, 0.000387f, 0.000419f,
+ 0.000444f, 0.000458f, 0.000513f, 0.000536f, 0.000570f, 0.000607f, 0.000688f, 0.000703f, 0.000754f, 0.000834f, 0.000890f, 0.000997f,
+ 0.001100f, 0.001238f, 0.001410f, 0.001584f, 0.001859f, 0.002207f, 0.002665f, 0.003323f, 0.004353f, 0.005947f, 0.008492f, 0.012909f,
+ 0.021606f, 0.039368f, 0.522461f, 0.559082f, 0.566406f, 0.569824f, 0.572266f, 0.572754f, 0.000108f, 0.000089f, 0.000079f, 0.000072f,
+ 0.000068f, 0.000065f, 0.000061f, 0.000057f, 0.000061f, 0.000062f, 0.000063f, 0.000086f, 0.000070f, 0.000071f, 0.000095f, 0.000080f,
+ 0.000107f, 0.000113f, 0.000115f, 0.000124f, 0.000121f, 0.000130f, 0.000151f, 0.000154f, 0.000164f, 0.000170f, 0.000176f, 0.000189f,
+ 0.000193f, 0.000215f, 0.000211f, 0.000242f, 0.000252f, 0.000260f, 0.000280f, 0.000293f, 0.000312f, 0.000350f, 0.000359f, 0.000389f,
+ 0.000410f, 0.000452f, 0.000481f, 0.000535f, 0.000578f, 0.000643f, 0.000718f, 0.000812f, 0.000939f, 0.001107f, 0.001329f, 0.001644f,
+ 0.002155f, 0.002930f, 0.004284f, 0.006706f, 0.011452f, 0.023895f, 0.504395f, 0.542480f, 0.550293f, 0.553711f, 0.555664f, 0.557129f,
+ 0.000093f, 0.000072f, 0.000063f, 0.000058f, 0.000053f, 0.000050f, 0.000047f, 0.000046f, 0.000044f, 0.000042f, 0.000039f, 0.000037f,
+ 0.000042f, 0.000035f, 0.000036f, 0.000037f, 0.000051f, 0.000046f, 0.000057f, 0.000058f, 0.000061f, 0.000062f, 0.000066f, 0.000069f,
+ 0.000072f, 0.000087f, 0.000077f, 0.000088f, 0.000093f, 0.000099f, 0.000103f, 0.000109f, 0.000115f, 0.000122f, 0.000139f, 0.000134f,
+ 0.000142f, 0.000170f, 0.000175f, 0.000179f, 0.000192f, 0.000203f, 0.000228f, 0.000245f, 0.000265f, 0.000291f, 0.000326f, 0.000360f,
+ 0.000420f, 0.000481f, 0.000574f, 0.000686f, 0.000887f, 0.001203f, 0.001759f, 0.002892f, 0.005318f, 0.011955f, 0.487305f, 0.524902f,
+ 0.534180f, 0.538086f, 0.539551f, 0.540527f, 0.000066f, 0.000049f, 0.000041f, 0.000037f, 0.000034f, 0.000033f, 0.000032f, 0.000030f,
+ 0.000029f, 0.000028f, 0.000028f, 0.000027f, 0.000026f, 0.000025f, 0.000024f, 0.000023f, 0.000022f, 0.000021f, 0.000022f, 0.000023f,
+ 0.000019f, 0.000018f, 0.000019f, 0.000024f, 0.000026f, 0.000029f, 0.000032f, 0.000032f, 0.000036f, 0.000034f, 0.000040f, 0.000041f,
+ 0.000043f, 0.000049f, 0.000049f, 0.000050f, 0.000056f, 0.000059f, 0.000067f, 0.000067f, 0.000074f, 0.000078f, 0.000082f, 0.000092f,
+ 0.000094f, 0.000103f, 0.000120f, 0.000130f, 0.000141f, 0.000163f, 0.000191f, 0.000230f, 0.000286f, 0.000374f, 0.000543f, 0.000890f,
+ 0.001802f, 0.004650f, 0.468994f, 0.507812f, 0.516602f, 0.520508f, 0.522461f, 0.523926f, 0.000007f, 0.000008f, 0.000008f, 0.000008f,
+ 0.000011f, 0.000010f, 0.000010f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000012f,
+ 0.000012f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000010f, 0.000009f, 0.000009f,
+ 0.000008f, 0.000008f, 0.000009f, 0.000009f, 0.000009f, 0.000009f, 0.000010f, 0.000011f, 0.000012f, 0.000014f, 0.000013f, 0.000016f,
+ 0.000015f, 0.000018f, 0.000020f, 0.000021f, 0.000022f, 0.000025f, 0.000024f, 0.000025f, 0.000030f, 0.000031f, 0.000040f, 0.000046f,
+ 0.000052f, 0.000071f, 0.000099f, 0.000147f, 0.000306f, 0.001072f, 0.450439f, 0.491211f, 0.499756f, 0.503418f, 0.505859f, 0.507324f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000007f, 0.000024f, 0.432129f, 0.474121f,
+ 0.482666f, 0.486572f, 0.489014f, 0.490234f,
+ },
+ {
+ 0.027573f, 0.080750f, 0.130981f, 0.177734f, 0.222290f, 0.263672f, 0.302002f, 0.338623f, 0.373291f, 0.405029f, 0.435791f, 0.464111f,
+ 0.490967f, 0.516602f, 0.540039f, 0.563477f, 0.584961f, 0.605469f, 0.625000f, 0.644043f, 0.660645f, 0.677246f, 0.693848f, 0.708496f,
+ 0.724121f, 0.738281f, 0.751465f, 0.764648f, 0.776855f, 0.789062f, 0.799805f, 0.810547f, 0.821289f, 0.831055f, 0.840820f, 0.850098f,
+ 0.859863f, 0.867676f, 0.876953f, 0.884277f, 0.892578f, 0.900391f, 0.907227f, 0.914551f, 0.921875f, 0.928223f, 0.934082f, 0.940430f,
+ 0.946777f, 0.952637f, 0.957520f, 0.964355f, 0.968262f, 0.974121f, 0.979004f, 0.983887f, 0.989258f, 0.994141f, 0.993164f, 0.983398f,
+ 0.976074f, 0.969238f, 0.962891f, 0.957031f, 0.022873f, 0.067871f, 0.111511f, 0.153809f, 0.193359f, 0.232788f, 0.268799f, 0.303223f,
+ 0.337402f, 0.368652f, 0.399414f, 0.427734f, 0.455078f, 0.481201f, 0.506348f, 0.529785f, 0.552246f, 0.573242f, 0.593750f, 0.613281f,
+ 0.632324f, 0.650391f, 0.667480f, 0.683105f, 0.698730f, 0.713867f, 0.728516f, 0.741211f, 0.755371f, 0.767578f, 0.779785f, 0.791504f,
+ 0.803223f, 0.813477f, 0.823242f, 0.834473f, 0.843750f, 0.853027f, 0.861816f, 0.870605f, 0.878906f, 0.887695f, 0.895996f, 0.901855f,
+ 0.910645f, 0.917480f, 0.923828f, 0.930176f, 0.937012f, 0.943359f, 0.949707f, 0.955078f, 0.960938f, 0.966797f, 0.972656f, 0.977051f,
+ 0.982422f, 0.987305f, 0.989746f, 0.981445f, 0.973633f, 0.967773f, 0.961426f, 0.956055f, 0.019089f, 0.057007f, 0.095215f, 0.132202f,
+ 0.168823f, 0.204712f, 0.238281f, 0.272217f, 0.304688f, 0.334717f, 0.364502f, 0.392822f, 0.420898f, 0.446533f, 0.471924f, 0.495850f,
+ 0.518555f, 0.541992f, 0.562988f, 0.582520f, 0.602539f, 0.621094f, 0.639160f, 0.655762f, 0.672852f, 0.687988f, 0.703613f, 0.718262f,
+ 0.732422f, 0.746094f, 0.758789f, 0.771484f, 0.783203f, 0.795898f, 0.807129f, 0.817383f, 0.827637f, 0.837402f, 0.846680f, 0.856445f,
+ 0.865234f, 0.874023f, 0.882324f, 0.890137f, 0.898438f, 0.905273f, 0.913574f, 0.920410f, 0.927246f, 0.934082f, 0.940918f, 0.946777f,
+ 0.953125f, 0.958496f, 0.964844f, 0.969727f, 0.975586f, 0.980957f, 0.986816f, 0.979004f, 0.971680f, 0.965332f, 0.959961f, 0.954590f,
+ 0.016327f, 0.048676f, 0.081787f, 0.114807f, 0.147705f, 0.180176f, 0.211426f, 0.243652f, 0.273438f, 0.303223f, 0.332031f, 0.360107f,
+ 0.386963f, 0.412598f, 0.438477f, 0.462891f, 0.487305f, 0.510254f, 0.530762f, 0.552246f, 0.572754f, 0.590820f, 0.610352f, 0.629883f,
+ 0.647461f, 0.662598f, 0.679688f, 0.693848f, 0.709961f, 0.723633f, 0.737305f, 0.750977f, 0.763672f, 0.776367f, 0.788086f, 0.799316f,
+ 0.810059f, 0.820801f, 0.832031f, 0.841309f, 0.851074f, 0.860352f, 0.868652f, 0.877930f, 0.886230f, 0.894531f, 0.902832f, 0.910156f,
+ 0.916504f, 0.924316f, 0.930664f, 0.937500f, 0.943848f, 0.950684f, 0.957031f, 0.962891f, 0.968262f, 0.974121f, 0.983887f, 0.976074f,
+ 0.969727f, 0.963867f, 0.958496f, 0.953125f, 0.013573f, 0.041901f, 0.070801f, 0.100098f, 0.129517f, 0.159058f, 0.187866f, 0.217041f,
+ 0.246216f, 0.274414f, 0.302002f, 0.328857f, 0.354980f, 0.381592f, 0.406738f, 0.431641f, 0.455322f, 0.478271f, 0.500000f, 0.521484f,
+ 0.541992f, 0.563477f, 0.583008f, 0.600098f, 0.619141f, 0.636719f, 0.653320f, 0.671387f, 0.684570f, 0.699707f, 0.715332f, 0.729492f,
+ 0.743164f, 0.755371f, 0.768555f, 0.780762f, 0.792480f, 0.804199f, 0.814453f, 0.824707f, 0.835449f, 0.845215f, 0.854980f, 0.864746f,
+ 0.874023f, 0.882812f, 0.890137f, 0.898438f, 0.905762f, 0.914062f, 0.921387f, 0.928223f, 0.935059f, 0.941406f, 0.948242f, 0.955078f,
+ 0.961426f, 0.966797f, 0.980957f, 0.973633f, 0.967773f, 0.961914f, 0.956543f, 0.951660f, 0.011681f, 0.036316f, 0.061584f, 0.087524f,
+ 0.113342f, 0.140259f, 0.167358f, 0.194214f, 0.220947f, 0.247437f, 0.273926f, 0.300537f, 0.325684f, 0.351074f, 0.375732f, 0.400146f,
+ 0.423828f, 0.446533f, 0.469482f, 0.491943f, 0.512695f, 0.532715f, 0.553223f, 0.573242f, 0.592285f, 0.609863f, 0.627930f, 0.644531f,
+ 0.660156f, 0.676758f, 0.691406f, 0.706055f, 0.720215f, 0.734863f, 0.749023f, 0.762207f, 0.774414f, 0.786133f, 0.797852f, 0.809082f,
+ 0.820801f, 0.831055f, 0.840332f, 0.850098f, 0.859863f, 0.869629f, 0.878418f, 0.886719f, 0.895508f, 0.903809f, 0.910645f, 0.918945f,
+ 0.925781f, 0.932617f, 0.939453f, 0.947754f, 0.953613f, 0.958984f, 0.977539f, 0.970703f, 0.964844f, 0.959473f, 0.954102f, 0.949707f,
+ 0.010330f, 0.031525f, 0.053406f, 0.076538f, 0.100159f, 0.124084f, 0.148193f, 0.173096f, 0.197998f, 0.223267f, 0.247681f, 0.273193f,
+ 0.297607f, 0.322021f, 0.346924f, 0.370117f, 0.394043f, 0.417236f, 0.439697f, 0.462158f, 0.483887f, 0.504883f, 0.524902f, 0.545410f,
+ 0.563477f, 0.583008f, 0.602539f, 0.618652f, 0.636230f, 0.652344f, 0.669922f, 0.685059f, 0.699219f, 0.714355f, 0.729004f, 0.741211f,
+ 0.755371f, 0.767578f, 0.780762f, 0.792480f, 0.803711f, 0.815918f, 0.825195f, 0.836914f, 0.846191f, 0.855957f, 0.864746f, 0.874512f,
+ 0.883301f, 0.891602f, 0.900391f, 0.908203f, 0.916016f, 0.923828f, 0.931152f, 0.937988f, 0.945801f, 0.952148f, 0.974121f, 0.967773f,
+ 0.962891f, 0.957520f, 0.952637f, 0.947754f, 0.009186f, 0.027359f, 0.047302f, 0.067505f, 0.088806f, 0.109924f, 0.132202f, 0.154907f,
+ 0.177246f, 0.201050f, 0.224121f, 0.247925f, 0.271240f, 0.295410f, 0.318359f, 0.341797f, 0.365234f, 0.387939f, 0.410156f, 0.432861f,
+ 0.454590f, 0.475586f, 0.495850f, 0.517090f, 0.536621f, 0.556152f, 0.575195f, 0.592773f, 0.609863f, 0.628418f, 0.645020f, 0.661133f,
+ 0.677246f, 0.692383f, 0.707520f, 0.721191f, 0.735352f, 0.748047f, 0.762207f, 0.774414f, 0.786621f, 0.798828f, 0.810547f, 0.820801f,
+ 0.831543f, 0.842285f, 0.852539f, 0.862305f, 0.871094f, 0.880859f, 0.889648f, 0.898438f, 0.906738f, 0.914551f, 0.921875f, 0.929199f,
+ 0.936035f, 0.944824f, 0.971191f, 0.965332f, 0.959473f, 0.955078f, 0.950195f, 0.945801f, 0.008041f, 0.024384f, 0.041321f, 0.059631f,
+ 0.078003f, 0.097656f, 0.117554f, 0.138428f, 0.159912f, 0.181152f, 0.203003f, 0.224976f, 0.247070f, 0.269531f, 0.292480f, 0.314697f,
+ 0.337891f, 0.360352f, 0.382324f, 0.403809f, 0.426025f, 0.447998f, 0.468018f, 0.488770f, 0.508301f, 0.528320f, 0.547852f, 0.567383f,
+ 0.585449f, 0.603516f, 0.620605f, 0.637695f, 0.654297f, 0.670410f, 0.686523f, 0.700195f, 0.715820f, 0.729980f, 0.743164f, 0.756836f,
+ 0.769531f, 0.782715f, 0.794434f, 0.805664f, 0.816895f, 0.827637f, 0.838379f, 0.848633f, 0.859375f, 0.868164f, 0.877930f, 0.887695f,
+ 0.895996f, 0.905273f, 0.912598f, 0.920898f, 0.928711f, 0.936035f, 0.966797f, 0.962402f, 0.957031f, 0.952637f, 0.947754f, 0.943848f,
+ 0.007095f, 0.021515f, 0.036926f, 0.052704f, 0.069641f, 0.087463f, 0.105347f, 0.123413f, 0.143188f, 0.163452f, 0.183105f, 0.204102f,
+ 0.225220f, 0.246704f, 0.268066f, 0.290283f, 0.311768f, 0.333740f, 0.355225f, 0.376465f, 0.397949f, 0.419434f, 0.440430f, 0.461670f,
+ 0.481445f, 0.500977f, 0.520020f, 0.540527f, 0.559570f, 0.578125f, 0.595703f, 0.613770f, 0.630371f, 0.646973f, 0.663086f, 0.678223f,
+ 0.694336f, 0.709473f, 0.723145f, 0.736328f, 0.750000f, 0.764648f, 0.777344f, 0.790039f, 0.801270f, 0.812988f, 0.824707f, 0.834961f,
+ 0.846191f, 0.856934f, 0.865723f, 0.875977f, 0.884766f, 0.894531f, 0.903320f, 0.911621f, 0.919922f, 0.927734f, 0.962891f, 0.959473f,
+ 0.954102f, 0.949219f, 0.945312f, 0.941406f, 0.006138f, 0.019150f, 0.033051f, 0.047089f, 0.061829f, 0.077515f, 0.094299f, 0.111084f,
+ 0.128174f, 0.146729f, 0.165771f, 0.185059f, 0.205200f, 0.224731f, 0.245361f, 0.265625f, 0.286865f, 0.307861f, 0.328857f, 0.350098f,
+ 0.370605f, 0.392090f, 0.413086f, 0.433594f, 0.454346f, 0.474609f, 0.493896f, 0.513672f, 0.532227f, 0.552734f, 0.569824f, 0.588867f,
+ 0.605957f, 0.623047f, 0.640625f, 0.656738f, 0.672852f, 0.688477f, 0.703613f, 0.717773f, 0.732910f, 0.746582f, 0.759766f, 0.772461f,
+ 0.786621f, 0.798340f, 0.810059f, 0.820312f, 0.832520f, 0.842773f, 0.853516f, 0.863770f, 0.873535f, 0.883789f, 0.892578f, 0.901367f,
+ 0.910645f, 0.919434f, 0.958984f, 0.955566f, 0.951172f, 0.946777f, 0.942871f, 0.938965f, 0.005424f, 0.017059f, 0.029541f, 0.042023f,
+ 0.055389f, 0.069397f, 0.083984f, 0.099670f, 0.115601f, 0.132324f, 0.149292f, 0.167114f, 0.185547f, 0.204468f, 0.224121f, 0.243896f,
+ 0.262939f, 0.283691f, 0.304443f, 0.323486f, 0.345459f, 0.365479f, 0.386230f, 0.407471f, 0.426758f, 0.448486f, 0.467529f, 0.487061f,
+ 0.506348f, 0.526367f, 0.545410f, 0.563965f, 0.581543f, 0.600098f, 0.617676f, 0.634277f, 0.650391f, 0.666016f, 0.682617f, 0.697754f,
+ 0.712891f, 0.727539f, 0.741211f, 0.755859f, 0.769043f, 0.782227f, 0.793945f, 0.806152f, 0.818848f, 0.830566f, 0.840332f, 0.851074f,
+ 0.861328f, 0.872070f, 0.881836f, 0.892090f, 0.900879f, 0.910645f, 0.955566f, 0.952637f, 0.948730f, 0.943359f, 0.939941f, 0.935547f,
+ 0.004833f, 0.015442f, 0.026169f, 0.037689f, 0.049683f, 0.062164f, 0.075806f, 0.089539f, 0.103760f, 0.119263f, 0.134888f, 0.151978f,
+ 0.168335f, 0.186646f, 0.204102f, 0.223022f, 0.242065f, 0.260986f, 0.280518f, 0.300537f, 0.320801f, 0.340820f, 0.360107f, 0.381104f,
+ 0.401367f, 0.421387f, 0.441650f, 0.460449f, 0.480957f, 0.500000f, 0.519531f, 0.538574f, 0.557129f, 0.575684f, 0.593262f, 0.610840f,
+ 0.628906f, 0.645508f, 0.662109f, 0.677246f, 0.692871f, 0.708008f, 0.723145f, 0.738281f, 0.751465f, 0.766113f, 0.778320f, 0.791504f,
+ 0.802246f, 0.816406f, 0.827637f, 0.838867f, 0.850098f, 0.860352f, 0.871582f, 0.881348f, 0.890137f, 0.899902f, 0.951660f, 0.948730f,
+ 0.944824f, 0.940918f, 0.937012f, 0.933594f, 0.004269f, 0.013809f, 0.023911f, 0.033569f, 0.044342f, 0.056213f, 0.068054f, 0.080811f,
+ 0.093933f, 0.107910f, 0.122131f, 0.137451f, 0.152710f, 0.169434f, 0.185791f, 0.203979f, 0.221436f, 0.239990f, 0.257812f, 0.277344f,
+ 0.296631f, 0.316162f, 0.335693f, 0.355713f, 0.375244f, 0.395996f, 0.416016f, 0.436035f, 0.455078f, 0.474365f, 0.494629f, 0.513184f,
+ 0.532715f, 0.550781f, 0.569336f, 0.586914f, 0.604980f, 0.622559f, 0.639648f, 0.655762f, 0.672363f, 0.688477f, 0.704102f, 0.718750f,
+ 0.733887f, 0.747559f, 0.761230f, 0.775391f, 0.788574f, 0.800781f, 0.814453f, 0.825684f, 0.837402f, 0.848633f, 0.859375f, 0.870605f,
+ 0.880371f, 0.891113f, 0.947754f, 0.945312f, 0.941895f, 0.937988f, 0.934082f, 0.931152f, 0.004028f, 0.012581f, 0.021133f, 0.030396f,
+ 0.039948f, 0.050323f, 0.061523f, 0.072815f, 0.084961f, 0.096985f, 0.110535f, 0.124756f, 0.138916f, 0.153687f, 0.169800f, 0.185669f,
+ 0.202881f, 0.219116f, 0.237305f, 0.255615f, 0.273926f, 0.293213f, 0.311768f, 0.331055f, 0.351074f, 0.370605f, 0.390381f, 0.409668f,
+ 0.429688f, 0.449707f, 0.468994f, 0.487549f, 0.506836f, 0.526367f, 0.545898f, 0.562988f, 0.581543f, 0.599121f, 0.616699f, 0.634766f,
+ 0.651367f, 0.667480f, 0.683594f, 0.699707f, 0.714844f, 0.730957f, 0.744141f, 0.758789f, 0.772949f, 0.785645f, 0.799316f, 0.812500f,
+ 0.823730f, 0.836914f, 0.847168f, 0.859375f, 0.869629f, 0.880371f, 0.942383f, 0.941406f, 0.937500f, 0.934570f, 0.931152f, 0.927734f,
+ 0.003613f, 0.011391f, 0.018875f, 0.027679f, 0.036133f, 0.045624f, 0.055420f, 0.065491f, 0.076416f, 0.088135f, 0.099487f, 0.112427f,
+ 0.126099f, 0.139771f, 0.154419f, 0.169556f, 0.184814f, 0.201050f, 0.218262f, 0.234985f, 0.252441f, 0.271484f, 0.289062f, 0.308594f,
+ 0.326660f, 0.346924f, 0.365234f, 0.384521f, 0.404541f, 0.424072f, 0.443359f, 0.463135f, 0.482422f, 0.501953f, 0.521484f, 0.539551f,
+ 0.558594f, 0.576660f, 0.595215f, 0.612793f, 0.629883f, 0.647949f, 0.663574f, 0.679688f, 0.695801f, 0.711426f, 0.727539f, 0.741699f,
+ 0.757324f, 0.770996f, 0.785156f, 0.798828f, 0.811035f, 0.823730f, 0.835449f, 0.848145f, 0.858887f, 0.870605f, 0.937988f, 0.937988f,
+ 0.934570f, 0.931152f, 0.927734f, 0.924805f, 0.003248f, 0.010185f, 0.017395f, 0.025055f, 0.032928f, 0.041321f, 0.049957f, 0.059265f,
+ 0.069092f, 0.079407f, 0.090820f, 0.101746f, 0.113770f, 0.126953f, 0.140381f, 0.154053f, 0.168701f, 0.184082f, 0.199951f, 0.216431f,
+ 0.232788f, 0.250000f, 0.267578f, 0.285645f, 0.303955f, 0.322998f, 0.341553f, 0.361084f, 0.379150f, 0.399414f, 0.418701f, 0.437988f,
+ 0.457275f, 0.477051f, 0.496094f, 0.515137f, 0.534180f, 0.553223f, 0.571289f, 0.589844f, 0.606934f, 0.625488f, 0.643066f, 0.659668f,
+ 0.676758f, 0.692871f, 0.708984f, 0.725098f, 0.740234f, 0.753906f, 0.769043f, 0.782227f, 0.796387f, 0.810059f, 0.822266f, 0.834961f,
+ 0.847168f, 0.859375f, 0.933594f, 0.933594f, 0.931152f, 0.927246f, 0.923828f, 0.921387f, 0.002914f, 0.009361f, 0.015793f, 0.022659f,
+ 0.029938f, 0.037354f, 0.045593f, 0.053406f, 0.062988f, 0.072083f, 0.081665f, 0.092712f, 0.103943f, 0.114990f, 0.128174f, 0.140503f,
+ 0.153809f, 0.167725f, 0.182251f, 0.198242f, 0.213623f, 0.230225f, 0.246826f, 0.263672f, 0.281494f, 0.300049f, 0.318604f, 0.337158f,
+ 0.356201f, 0.374756f, 0.394531f, 0.413574f, 0.433105f, 0.451904f, 0.471680f, 0.491211f, 0.509766f, 0.529297f, 0.547852f, 0.566895f,
+ 0.584961f, 0.603516f, 0.621094f, 0.638672f, 0.656738f, 0.673340f, 0.689453f, 0.706543f, 0.722656f, 0.737793f, 0.752930f, 0.767578f,
+ 0.781250f, 0.796875f, 0.809082f, 0.823242f, 0.835449f, 0.847656f, 0.929199f, 0.929199f, 0.927246f, 0.923828f, 0.920898f, 0.917969f,
+ 0.002766f, 0.008736f, 0.014442f, 0.020691f, 0.027054f, 0.033905f, 0.040924f, 0.048645f, 0.056976f, 0.065674f, 0.074951f, 0.084229f,
+ 0.094116f, 0.105225f, 0.116333f, 0.127563f, 0.139771f, 0.153564f, 0.166626f, 0.181030f, 0.196411f, 0.211182f, 0.227417f, 0.243896f,
+ 0.260742f, 0.277588f, 0.295898f, 0.314209f, 0.332031f, 0.351562f, 0.370117f, 0.389404f, 0.408203f, 0.428223f, 0.447266f, 0.467041f,
+ 0.486084f, 0.505859f, 0.524414f, 0.543945f, 0.562012f, 0.581543f, 0.600098f, 0.617676f, 0.636230f, 0.654297f, 0.670898f, 0.687500f,
+ 0.704102f, 0.720703f, 0.736816f, 0.751465f, 0.766113f, 0.781738f, 0.796387f, 0.809082f, 0.823242f, 0.835938f, 0.923828f, 0.925781f,
+ 0.922852f, 0.920410f, 0.916992f, 0.914551f, 0.002483f, 0.007599f, 0.013161f, 0.018555f, 0.024551f, 0.030670f, 0.037476f, 0.044464f,
+ 0.051636f, 0.059174f, 0.067688f, 0.075928f, 0.085693f, 0.095093f, 0.105591f, 0.116394f, 0.127441f, 0.139648f, 0.152344f, 0.165527f,
+ 0.179565f, 0.193970f, 0.208862f, 0.224487f, 0.240356f, 0.256836f, 0.274658f, 0.291748f, 0.310059f, 0.328369f, 0.346680f, 0.365234f,
+ 0.384521f, 0.404297f, 0.423340f, 0.442139f, 0.462646f, 0.481445f, 0.500977f, 0.520020f, 0.540039f, 0.559082f, 0.577148f, 0.596191f,
+ 0.614746f, 0.632812f, 0.651367f, 0.669434f, 0.685059f, 0.702637f, 0.718750f, 0.734375f, 0.750488f, 0.766113f, 0.780762f, 0.795410f,
+ 0.811035f, 0.823730f, 0.919434f, 0.920898f, 0.918457f, 0.916016f, 0.913086f, 0.910645f, 0.002457f, 0.007114f, 0.011757f, 0.016708f,
+ 0.022125f, 0.027786f, 0.033752f, 0.040375f, 0.046661f, 0.053864f, 0.061584f, 0.069336f, 0.077515f, 0.086365f, 0.095947f, 0.105896f,
+ 0.116638f, 0.127075f, 0.138916f, 0.151245f, 0.164062f, 0.177490f, 0.191528f, 0.206177f, 0.221802f, 0.237427f, 0.253906f, 0.270508f,
+ 0.287842f, 0.305664f, 0.323730f, 0.342285f, 0.361572f, 0.379639f, 0.399170f, 0.418457f, 0.438965f, 0.458252f, 0.477295f, 0.497559f,
+ 0.516113f, 0.536133f, 0.554688f, 0.574707f, 0.593750f, 0.612305f, 0.630859f, 0.648926f, 0.666504f, 0.684082f, 0.701660f, 0.717773f,
+ 0.734863f, 0.751465f, 0.766602f, 0.781738f, 0.797852f, 0.812012f, 0.913086f, 0.916016f, 0.913574f, 0.911621f, 0.909180f, 0.906250f,
+ 0.002132f, 0.006493f, 0.010750f, 0.015717f, 0.020569f, 0.025604f, 0.030823f, 0.036682f, 0.043060f, 0.049286f, 0.055786f, 0.062988f,
+ 0.070557f, 0.078918f, 0.086914f, 0.096191f, 0.105530f, 0.116028f, 0.126953f, 0.138306f, 0.149902f, 0.162231f, 0.175537f, 0.189453f,
+ 0.203491f, 0.218628f, 0.234131f, 0.250000f, 0.266602f, 0.284180f, 0.301514f, 0.319580f, 0.338135f, 0.356689f, 0.375977f, 0.395020f,
+ 0.413818f, 0.434082f, 0.452881f, 0.473145f, 0.492920f, 0.512207f, 0.532227f, 0.552246f, 0.570801f, 0.591309f, 0.609375f, 0.629395f,
+ 0.646973f, 0.665527f, 0.683105f, 0.700684f, 0.717773f, 0.734863f, 0.751465f, 0.767578f, 0.782715f, 0.799316f, 0.908203f, 0.911133f,
+ 0.909180f, 0.907227f, 0.904785f, 0.902832f, 0.001891f, 0.006008f, 0.010025f, 0.014122f, 0.018616f, 0.023239f, 0.028442f, 0.033691f,
+ 0.038757f, 0.044556f, 0.050964f, 0.057465f, 0.064087f, 0.071167f, 0.079224f, 0.087463f, 0.096008f, 0.105591f, 0.115356f, 0.125488f,
+ 0.136597f, 0.148193f, 0.160278f, 0.173218f, 0.186768f, 0.200684f, 0.215332f, 0.231323f, 0.246338f, 0.262939f, 0.279785f, 0.297607f,
+ 0.314941f, 0.333984f, 0.353271f, 0.371094f, 0.391357f, 0.409668f, 0.430420f, 0.448975f, 0.469482f, 0.489746f, 0.509277f, 0.528809f,
+ 0.549316f, 0.568848f, 0.588379f, 0.607910f, 0.626953f, 0.645996f, 0.664062f, 0.683105f, 0.700684f, 0.718262f, 0.735840f, 0.751953f,
+ 0.768555f, 0.785645f, 0.902344f, 0.906250f, 0.904785f, 0.902832f, 0.900391f, 0.898438f, 0.001732f, 0.005573f, 0.009193f, 0.012932f,
+ 0.017075f, 0.021286f, 0.025406f, 0.030289f, 0.035675f, 0.040344f, 0.046326f, 0.052032f, 0.058411f, 0.064575f, 0.072205f, 0.079834f,
+ 0.087708f, 0.095947f, 0.104797f, 0.114380f, 0.124451f, 0.134888f, 0.146606f, 0.158691f, 0.170776f, 0.184082f, 0.197510f, 0.212524f,
+ 0.227417f, 0.243164f, 0.259521f, 0.276367f, 0.293457f, 0.311768f, 0.329590f, 0.348633f, 0.367188f, 0.386230f, 0.406006f, 0.425781f,
+ 0.446533f, 0.465332f, 0.486084f, 0.505859f, 0.526367f, 0.545898f, 0.567383f, 0.585938f, 0.605957f, 0.625977f, 0.645508f, 0.664551f,
+ 0.683105f, 0.701172f, 0.718750f, 0.736816f, 0.754395f, 0.770508f, 0.896484f, 0.900879f, 0.900391f, 0.897949f, 0.895996f, 0.894043f,
+ 0.001713f, 0.004684f, 0.008339f, 0.011818f, 0.015450f, 0.019409f, 0.023605f, 0.027832f, 0.032349f, 0.036865f, 0.041809f, 0.047302f,
+ 0.052673f, 0.058838f, 0.065613f, 0.072083f, 0.079407f, 0.087280f, 0.095337f, 0.104126f, 0.113037f, 0.122986f, 0.133667f, 0.144897f,
+ 0.156250f, 0.168579f, 0.181396f, 0.195068f, 0.208984f, 0.224243f, 0.239624f, 0.255859f, 0.272461f, 0.289551f, 0.307617f, 0.326172f,
+ 0.344482f, 0.363770f, 0.383301f, 0.402588f, 0.422607f, 0.443115f, 0.463135f, 0.483154f, 0.503418f, 0.523926f, 0.544434f, 0.564941f,
+ 0.584473f, 0.604980f, 0.624512f, 0.645508f, 0.664551f, 0.683594f, 0.701660f, 0.721191f, 0.738281f, 0.755859f, 0.889648f, 0.895996f,
+ 0.895020f, 0.893066f, 0.891602f, 0.889160f, 0.001545f, 0.004745f, 0.007710f, 0.010979f, 0.014450f, 0.017807f, 0.021469f, 0.025238f,
+ 0.029282f, 0.033661f, 0.038177f, 0.043182f, 0.048157f, 0.053436f, 0.059326f, 0.065674f, 0.072205f, 0.078857f, 0.086548f, 0.094604f,
+ 0.102905f, 0.111816f, 0.121521f, 0.131592f, 0.142334f, 0.153442f, 0.165894f, 0.178345f, 0.192139f, 0.205933f, 0.220703f, 0.236084f,
+ 0.251709f, 0.268555f, 0.285645f, 0.303467f, 0.321777f, 0.340332f, 0.359619f, 0.379150f, 0.398682f, 0.419189f, 0.440430f, 0.460449f,
+ 0.480957f, 0.501465f, 0.521973f, 0.543457f, 0.563477f, 0.584961f, 0.604492f, 0.625488f, 0.645508f, 0.665039f, 0.684082f, 0.704102f,
+ 0.723145f, 0.741211f, 0.885254f, 0.890137f, 0.889160f, 0.887695f, 0.886719f, 0.884277f, 0.001487f, 0.004356f, 0.006828f, 0.010162f,
+ 0.012993f, 0.016022f, 0.019333f, 0.023087f, 0.026886f, 0.030518f, 0.034668f, 0.039062f, 0.043671f, 0.048370f, 0.053741f, 0.059326f,
+ 0.065308f, 0.071655f, 0.078125f, 0.085693f, 0.093323f, 0.101807f, 0.110657f, 0.119507f, 0.129517f, 0.140137f, 0.151367f, 0.163330f,
+ 0.175781f, 0.188843f, 0.202759f, 0.217163f, 0.232666f, 0.248413f, 0.264893f, 0.282227f, 0.299805f, 0.318115f, 0.336914f, 0.356445f,
+ 0.375488f, 0.395996f, 0.416504f, 0.436279f, 0.457520f, 0.479004f, 0.499023f, 0.520508f, 0.541504f, 0.562988f, 0.583984f, 0.604492f,
+ 0.625488f, 0.646973f, 0.666504f, 0.687012f, 0.706055f, 0.725098f, 0.877441f, 0.885254f, 0.884766f, 0.882324f, 0.881836f, 0.880371f,
+ 0.001443f, 0.003807f, 0.006336f, 0.009171f, 0.011909f, 0.015007f, 0.018097f, 0.020905f, 0.024384f, 0.027893f, 0.031555f, 0.035370f,
+ 0.039581f, 0.044128f, 0.048889f, 0.053894f, 0.059174f, 0.065125f, 0.070984f, 0.077698f, 0.084656f, 0.091919f, 0.100037f, 0.108093f,
+ 0.117493f, 0.127563f, 0.137817f, 0.148438f, 0.159912f, 0.172485f, 0.185547f, 0.199585f, 0.213867f, 0.229248f, 0.244995f, 0.261230f,
+ 0.278564f, 0.296387f, 0.314697f, 0.333252f, 0.353271f, 0.372314f, 0.393311f, 0.413330f, 0.433594f, 0.455078f, 0.476318f, 0.497314f,
+ 0.519531f, 0.540527f, 0.562500f, 0.583496f, 0.605469f, 0.626953f, 0.648438f, 0.669434f, 0.689941f, 0.709961f, 0.870605f, 0.878906f,
+ 0.878418f, 0.877441f, 0.875488f, 0.873535f, 0.001302f, 0.003712f, 0.005859f, 0.008286f, 0.010910f, 0.013779f, 0.016235f, 0.019135f,
+ 0.021912f, 0.025345f, 0.029022f, 0.032166f, 0.036011f, 0.040131f, 0.044128f, 0.048492f, 0.053528f, 0.058533f, 0.064209f, 0.070129f,
+ 0.076355f, 0.083191f, 0.090149f, 0.098328f, 0.106628f, 0.115662f, 0.124817f, 0.134766f, 0.145630f, 0.157104f, 0.169678f, 0.182495f,
+ 0.195801f, 0.210205f, 0.225342f, 0.241455f, 0.257812f, 0.274902f, 0.292725f, 0.311035f, 0.330322f, 0.349365f, 0.369873f, 0.390137f,
+ 0.411133f, 0.432373f, 0.453369f, 0.474609f, 0.496826f, 0.519043f, 0.541504f, 0.563477f, 0.585449f, 0.606445f, 0.629395f, 0.650391f,
+ 0.672363f, 0.693848f, 0.863281f, 0.872070f, 0.872070f, 0.871582f, 0.869629f, 0.868164f, 0.001170f, 0.003151f, 0.005295f, 0.007812f,
+ 0.010132f, 0.012466f, 0.015076f, 0.017517f, 0.019943f, 0.023178f, 0.026443f, 0.029312f, 0.032471f, 0.036041f, 0.039978f, 0.044037f,
+ 0.048828f, 0.053070f, 0.057983f, 0.063232f, 0.068909f, 0.075378f, 0.081909f, 0.088745f, 0.096375f, 0.104309f, 0.113281f, 0.122437f,
+ 0.132202f, 0.142944f, 0.154419f, 0.166138f, 0.178955f, 0.192505f, 0.206421f, 0.221558f, 0.237183f, 0.253906f, 0.270996f, 0.289062f,
+ 0.308105f, 0.326904f, 0.346924f, 0.366455f, 0.387695f, 0.408936f, 0.430176f, 0.451416f, 0.474365f, 0.496582f, 0.518066f, 0.541016f,
+ 0.563965f, 0.585938f, 0.608887f, 0.630859f, 0.654297f, 0.675781f, 0.856934f, 0.865234f, 0.866211f, 0.864746f, 0.863281f, 0.862793f,
+ 0.001049f, 0.003254f, 0.005234f, 0.007263f, 0.009270f, 0.011307f, 0.013596f, 0.015869f, 0.018555f, 0.020844f, 0.023972f, 0.026566f,
+ 0.029739f, 0.033020f, 0.036316f, 0.039856f, 0.044159f, 0.048096f, 0.052277f, 0.057281f, 0.062439f, 0.067871f, 0.073792f, 0.079956f,
+ 0.087158f, 0.094055f, 0.102234f, 0.110535f, 0.119934f, 0.129517f, 0.140259f, 0.151245f, 0.162842f, 0.175537f, 0.189209f, 0.203369f,
+ 0.218262f, 0.233643f, 0.250488f, 0.268066f, 0.285645f, 0.304443f, 0.324219f, 0.343750f, 0.364014f, 0.385254f, 0.406494f, 0.428223f,
+ 0.450928f, 0.472656f, 0.495605f, 0.519043f, 0.541504f, 0.565918f, 0.588379f, 0.612305f, 0.635742f, 0.659180f, 0.850098f, 0.859863f,
+ 0.859863f, 0.858398f, 0.857910f, 0.856934f, 0.000914f, 0.002861f, 0.004742f, 0.006569f, 0.008415f, 0.010521f, 0.012596f, 0.014648f,
+ 0.016708f, 0.019089f, 0.021515f, 0.023865f, 0.026688f, 0.029572f, 0.032928f, 0.036377f, 0.039337f, 0.043365f, 0.047333f, 0.051544f,
+ 0.056305f, 0.061066f, 0.066406f, 0.071960f, 0.078247f, 0.084961f, 0.092163f, 0.099426f, 0.108215f, 0.116943f, 0.126831f, 0.136719f,
+ 0.148193f, 0.159302f, 0.171875f, 0.185669f, 0.199585f, 0.214478f, 0.230469f, 0.247070f, 0.264160f, 0.282471f, 0.301270f, 0.321045f,
+ 0.341553f, 0.362061f, 0.383545f, 0.404785f, 0.427734f, 0.449951f, 0.473389f, 0.496582f, 0.520020f, 0.543457f, 0.568359f, 0.592285f,
+ 0.615723f, 0.639648f, 0.840820f, 0.851074f, 0.853027f, 0.853027f, 0.852051f, 0.850586f, 0.000679f, 0.002518f, 0.004173f, 0.006149f,
+ 0.008064f, 0.009369f, 0.011551f, 0.013222f, 0.015175f, 0.017212f, 0.019592f, 0.021835f, 0.024048f, 0.026932f, 0.029846f, 0.032623f,
+ 0.035675f, 0.038940f, 0.042542f, 0.046295f, 0.050354f, 0.055054f, 0.059601f, 0.064880f, 0.070190f, 0.076233f, 0.082703f, 0.089661f,
+ 0.097229f, 0.105103f, 0.113831f, 0.123474f, 0.133423f, 0.144409f, 0.156006f, 0.168335f, 0.182495f, 0.196411f, 0.211304f, 0.227295f,
+ 0.243530f, 0.260986f, 0.279053f, 0.298828f, 0.318359f, 0.339111f, 0.360107f, 0.381348f, 0.403809f, 0.427490f, 0.449463f, 0.473633f,
+ 0.497803f, 0.521484f, 0.546875f, 0.570801f, 0.595703f, 0.620605f, 0.833008f, 0.845215f, 0.845703f, 0.845703f, 0.845215f, 0.843750f,
+ 0.000719f, 0.002470f, 0.003975f, 0.005337f, 0.007275f, 0.008713f, 0.010376f, 0.012032f, 0.013580f, 0.015793f, 0.017609f, 0.019501f,
+ 0.021530f, 0.024277f, 0.026657f, 0.029312f, 0.031982f, 0.035187f, 0.038086f, 0.041565f, 0.045288f, 0.049103f, 0.053436f, 0.058136f,
+ 0.062927f, 0.068054f, 0.073853f, 0.080383f, 0.087341f, 0.094666f, 0.102173f, 0.111084f, 0.120300f, 0.130859f, 0.141235f, 0.152954f,
+ 0.164429f, 0.178223f, 0.192749f, 0.207642f, 0.223145f, 0.239868f, 0.258301f, 0.276611f, 0.295654f, 0.316162f, 0.337402f, 0.358643f,
+ 0.380859f, 0.403320f, 0.427002f, 0.450684f, 0.474609f, 0.499756f, 0.523926f, 0.550781f, 0.575195f, 0.600586f, 0.824707f, 0.836914f,
+ 0.838379f, 0.838867f, 0.837402f, 0.837402f, 0.000683f, 0.002361f, 0.003649f, 0.005116f, 0.006416f, 0.008202f, 0.009460f, 0.010941f,
+ 0.012817f, 0.014099f, 0.015839f, 0.017593f, 0.019867f, 0.021988f, 0.023926f, 0.026276f, 0.028824f, 0.031311f, 0.034363f, 0.036957f,
+ 0.040375f, 0.043823f, 0.047546f, 0.051758f, 0.056183f, 0.061249f, 0.066162f, 0.071777f, 0.077942f, 0.084534f, 0.091553f, 0.099487f,
+ 0.107910f, 0.116882f, 0.127075f, 0.137451f, 0.148804f, 0.161499f, 0.174805f, 0.188721f, 0.203735f, 0.220093f, 0.237427f, 0.254639f,
+ 0.273926f, 0.293457f, 0.313965f, 0.334961f, 0.357666f, 0.379883f, 0.403076f, 0.427002f, 0.451660f, 0.476807f, 0.501953f, 0.527344f,
+ 0.553711f, 0.581055f, 0.815918f, 0.829102f, 0.831055f, 0.831055f, 0.831055f, 0.830566f, 0.000607f, 0.001863f, 0.003416f, 0.004528f,
+ 0.005943f, 0.007191f, 0.008781f, 0.009964f, 0.011337f, 0.012939f, 0.014458f, 0.015808f, 0.018051f, 0.019394f, 0.021332f, 0.023529f,
+ 0.025803f, 0.028168f, 0.030502f, 0.033020f, 0.036072f, 0.039032f, 0.042419f, 0.046082f, 0.049927f, 0.054321f, 0.058411f, 0.063538f,
+ 0.069336f, 0.075684f, 0.081787f, 0.088562f, 0.096436f, 0.104553f, 0.113281f, 0.123596f, 0.133667f, 0.145386f, 0.157471f, 0.171021f,
+ 0.185547f, 0.200562f, 0.216553f, 0.234619f, 0.251709f, 0.271240f, 0.291504f, 0.312012f, 0.333496f, 0.355957f, 0.379395f, 0.403076f,
+ 0.428223f, 0.453857f, 0.479492f, 0.506348f, 0.532715f, 0.560059f, 0.805664f, 0.820801f, 0.823730f, 0.822754f, 0.822754f, 0.822266f,
+ 0.000593f, 0.001862f, 0.002966f, 0.004341f, 0.005600f, 0.006516f, 0.007626f, 0.008995f, 0.010223f, 0.011292f, 0.012848f, 0.014427f,
+ 0.016098f, 0.017532f, 0.019165f, 0.021027f, 0.022842f, 0.024918f, 0.027115f, 0.029739f, 0.032013f, 0.034637f, 0.037506f, 0.040955f,
+ 0.044220f, 0.048065f, 0.051941f, 0.056305f, 0.061768f, 0.066528f, 0.072327f, 0.078979f, 0.085571f, 0.092834f, 0.101135f, 0.110229f,
+ 0.119690f, 0.130127f, 0.141602f, 0.153564f, 0.167114f, 0.181763f, 0.196899f, 0.213623f, 0.230957f, 0.249268f, 0.268555f, 0.289062f,
+ 0.310059f, 0.333252f, 0.355957f, 0.379883f, 0.404541f, 0.430176f, 0.456055f, 0.483887f, 0.510254f, 0.539062f, 0.797852f, 0.812988f,
+ 0.814941f, 0.815430f, 0.815918f, 0.814453f, 0.000556f, 0.001811f, 0.002998f, 0.003815f, 0.004658f, 0.005905f, 0.007099f, 0.008232f,
+ 0.009239f, 0.010483f, 0.011559f, 0.013016f, 0.014305f, 0.015671f, 0.017090f, 0.018646f, 0.020370f, 0.022369f, 0.024124f, 0.026062f,
+ 0.028458f, 0.030624f, 0.033264f, 0.036041f, 0.039307f, 0.042053f, 0.045807f, 0.049530f, 0.054016f, 0.058441f, 0.063904f, 0.069641f,
+ 0.075745f, 0.082520f, 0.089539f, 0.097717f, 0.106750f, 0.116150f, 0.126587f, 0.137817f, 0.150024f, 0.163452f, 0.177490f, 0.193359f,
+ 0.209717f, 0.227539f, 0.246704f, 0.266602f, 0.287598f, 0.309326f, 0.332520f, 0.355713f, 0.380371f, 0.406494f, 0.432861f, 0.459961f,
+ 0.488525f, 0.517090f, 0.787598f, 0.804199f, 0.806641f, 0.807617f, 0.807617f, 0.807129f, 0.000507f, 0.001697f, 0.002468f, 0.003351f,
+ 0.004425f, 0.005486f, 0.006325f, 0.007412f, 0.008156f, 0.009270f, 0.010239f, 0.011497f, 0.012520f, 0.013954f, 0.015182f, 0.016617f,
+ 0.018036f, 0.019714f, 0.021362f, 0.022934f, 0.024704f, 0.026886f, 0.029419f, 0.031525f, 0.034302f, 0.037292f, 0.040558f, 0.043701f,
+ 0.047577f, 0.051849f, 0.056183f, 0.061249f, 0.066467f, 0.072876f, 0.078918f, 0.086548f, 0.094116f, 0.102844f, 0.112427f, 0.122620f,
+ 0.133667f, 0.146362f, 0.159668f, 0.174438f, 0.190063f, 0.207153f, 0.225098f, 0.244263f, 0.264648f, 0.286377f, 0.308350f, 0.332275f,
+ 0.357178f, 0.382080f, 0.408936f, 0.436035f, 0.465820f, 0.495361f, 0.776855f, 0.794922f, 0.797852f, 0.799316f, 0.798828f, 0.798340f,
+ 0.000366f, 0.001644f, 0.002289f, 0.003046f, 0.004082f, 0.005032f, 0.005550f, 0.006599f, 0.007389f, 0.008369f, 0.009201f, 0.010315f,
+ 0.011276f, 0.012405f, 0.013466f, 0.014587f, 0.015991f, 0.017303f, 0.018692f, 0.020081f, 0.021851f, 0.023865f, 0.025726f, 0.027771f,
+ 0.030136f, 0.032532f, 0.035309f, 0.038422f, 0.041626f, 0.045044f, 0.048767f, 0.053375f, 0.057861f, 0.063477f, 0.069031f, 0.075684f,
+ 0.082336f, 0.090515f, 0.099182f, 0.107849f, 0.118958f, 0.130005f, 0.142212f, 0.156128f, 0.170898f, 0.186890f, 0.203857f, 0.222534f,
+ 0.241821f, 0.263428f, 0.285156f, 0.308105f, 0.332275f, 0.359131f, 0.385010f, 0.413086f, 0.441895f, 0.472168f, 0.767090f, 0.785645f,
+ 0.789062f, 0.789551f, 0.790527f, 0.789551f, 0.000340f, 0.001434f, 0.002129f, 0.002827f, 0.003696f, 0.004463f, 0.005112f, 0.005730f,
+ 0.006836f, 0.007465f, 0.008217f, 0.008972f, 0.009972f, 0.010887f, 0.011948f, 0.012794f, 0.013947f, 0.015030f, 0.016266f, 0.017670f,
+ 0.019165f, 0.020813f, 0.022415f, 0.024216f, 0.026047f, 0.028336f, 0.030594f, 0.033142f, 0.035858f, 0.039154f, 0.042328f, 0.046265f,
+ 0.050537f, 0.055237f, 0.059998f, 0.065918f, 0.072083f, 0.078918f, 0.086243f, 0.094788f, 0.104309f, 0.114807f, 0.125854f, 0.138672f,
+ 0.152222f, 0.166992f, 0.183716f, 0.200928f, 0.220459f, 0.240112f, 0.261719f, 0.284668f, 0.308838f, 0.333740f, 0.360840f, 0.388672f,
+ 0.418213f, 0.448730f, 0.756348f, 0.775391f, 0.779297f, 0.780273f, 0.781250f, 0.780273f, 0.000511f, 0.001174f, 0.002163f, 0.002554f,
+ 0.003391f, 0.003990f, 0.004547f, 0.005211f, 0.005993f, 0.006653f, 0.007462f, 0.007942f, 0.008781f, 0.009476f, 0.010323f, 0.011444f,
+ 0.012207f, 0.013062f, 0.014336f, 0.015427f, 0.016464f, 0.017929f, 0.019287f, 0.021164f, 0.022461f, 0.024567f, 0.026474f, 0.028885f,
+ 0.031067f, 0.033630f, 0.036835f, 0.040070f, 0.043488f, 0.047394f, 0.051910f, 0.056732f, 0.062378f, 0.068481f, 0.075073f, 0.082764f,
+ 0.090881f, 0.100403f, 0.110779f, 0.122009f, 0.134399f, 0.148560f, 0.163940f, 0.180298f, 0.198120f, 0.218140f, 0.239014f, 0.260986f,
+ 0.285645f, 0.310059f, 0.336182f, 0.364502f, 0.393311f, 0.424316f, 0.744629f, 0.765137f, 0.769531f, 0.770508f, 0.771484f, 0.771484f,
+ 0.000374f, 0.000983f, 0.001696f, 0.002279f, 0.002924f, 0.003571f, 0.004139f, 0.004742f, 0.005390f, 0.005817f, 0.006371f, 0.006981f,
+ 0.007648f, 0.008354f, 0.009041f, 0.009727f, 0.010536f, 0.011375f, 0.012398f, 0.013535f, 0.014389f, 0.015541f, 0.016602f, 0.018112f,
+ 0.019516f, 0.020996f, 0.022644f, 0.024582f, 0.026627f, 0.028748f, 0.031586f, 0.034210f, 0.037415f, 0.040588f, 0.044464f, 0.048676f,
+ 0.053192f, 0.058472f, 0.064880f, 0.070984f, 0.078674f, 0.086914f, 0.096191f, 0.106445f, 0.117859f, 0.130859f, 0.144775f, 0.160522f,
+ 0.177490f, 0.196411f, 0.215942f, 0.237793f, 0.261475f, 0.285645f, 0.312012f, 0.339111f, 0.368652f, 0.400391f, 0.733887f, 0.755371f,
+ 0.759766f, 0.760742f, 0.761719f, 0.761719f, 0.000298f, 0.000924f, 0.001542f, 0.002125f, 0.002439f, 0.003153f, 0.003502f, 0.004196f,
+ 0.004585f, 0.005039f, 0.005531f, 0.006054f, 0.006531f, 0.007217f, 0.007935f, 0.008362f, 0.009171f, 0.009773f, 0.010704f, 0.011505f,
+ 0.012207f, 0.013321f, 0.014381f, 0.015556f, 0.016586f, 0.017792f, 0.019608f, 0.020844f, 0.022583f, 0.024536f, 0.026566f, 0.028885f,
+ 0.031494f, 0.034332f, 0.037689f, 0.041260f, 0.045258f, 0.049927f, 0.054901f, 0.060699f, 0.067322f, 0.074768f, 0.082764f, 0.091675f,
+ 0.102173f, 0.113831f, 0.126831f, 0.141113f, 0.157104f, 0.175049f, 0.194580f, 0.215210f, 0.237305f, 0.261475f, 0.287598f, 0.314697f,
+ 0.344482f, 0.375977f, 0.721680f, 0.744629f, 0.749512f, 0.751465f, 0.751465f, 0.751465f, 0.000275f, 0.001002f, 0.001335f, 0.001704f,
+ 0.002264f, 0.002790f, 0.003202f, 0.003555f, 0.004017f, 0.004368f, 0.004894f, 0.005318f, 0.005592f, 0.006241f, 0.006611f, 0.007317f,
+ 0.007851f, 0.008560f, 0.009071f, 0.009758f, 0.010429f, 0.011375f, 0.011986f, 0.013130f, 0.013916f, 0.015205f, 0.016403f, 0.017624f,
+ 0.019119f, 0.020660f, 0.022278f, 0.024582f, 0.026474f, 0.029007f, 0.031738f, 0.034668f, 0.038025f, 0.041962f, 0.046417f, 0.051270f,
+ 0.056915f, 0.063110f, 0.070312f, 0.078369f, 0.087769f, 0.098145f, 0.109863f, 0.123352f, 0.137451f, 0.154785f, 0.172363f, 0.192261f,
+ 0.214233f, 0.237793f, 0.262939f, 0.289795f, 0.319336f, 0.351074f, 0.708984f, 0.733398f, 0.738281f, 0.740234f, 0.741211f, 0.740723f,
+ 0.000334f, 0.000805f, 0.001231f, 0.001640f, 0.002033f, 0.002277f, 0.002871f, 0.003115f, 0.003481f, 0.003895f, 0.004147f, 0.004379f,
+ 0.004841f, 0.005306f, 0.005653f, 0.006241f, 0.006630f, 0.007217f, 0.007721f, 0.008133f, 0.008842f, 0.009529f, 0.010010f, 0.011017f,
+ 0.011780f, 0.012733f, 0.013626f, 0.014824f, 0.015656f, 0.017212f, 0.018829f, 0.020248f, 0.021973f, 0.023926f, 0.026306f, 0.028900f,
+ 0.031616f, 0.034973f, 0.038605f, 0.042816f, 0.047424f, 0.052765f, 0.059021f, 0.066162f, 0.074219f, 0.083435f, 0.093994f, 0.105835f,
+ 0.119385f, 0.134277f, 0.151611f, 0.170532f, 0.191284f, 0.214233f, 0.239014f, 0.265381f, 0.293701f, 0.325684f, 0.696289f, 0.722168f,
+ 0.727051f, 0.729004f, 0.729980f, 0.729980f, 0.000215f, 0.000635f, 0.001184f, 0.001348f, 0.001758f, 0.002171f, 0.002249f, 0.002596f,
+ 0.003004f, 0.003325f, 0.003487f, 0.003906f, 0.004108f, 0.004494f, 0.004955f, 0.005241f, 0.005726f, 0.006134f, 0.006485f, 0.006916f,
+ 0.007496f, 0.008072f, 0.008629f, 0.009071f, 0.009857f, 0.010651f, 0.011375f, 0.012283f, 0.013283f, 0.014320f, 0.015350f, 0.016739f,
+ 0.017975f, 0.019852f, 0.021454f, 0.023712f, 0.025925f, 0.028717f, 0.031769f, 0.035217f, 0.038910f, 0.043396f, 0.048767f, 0.054901f,
+ 0.061707f, 0.069824f, 0.078613f, 0.089783f, 0.101685f, 0.115479f, 0.131104f, 0.149292f, 0.168823f, 0.190674f, 0.214844f, 0.241211f,
+ 0.269775f, 0.299561f, 0.683594f, 0.709961f, 0.715332f, 0.717773f, 0.718262f, 0.718750f, 0.000199f, 0.000826f, 0.001047f, 0.001288f,
+ 0.001600f, 0.001857f, 0.002014f, 0.002329f, 0.002535f, 0.002785f, 0.003027f, 0.003210f, 0.003580f, 0.003788f, 0.004025f, 0.004444f,
+ 0.004791f, 0.004974f, 0.005417f, 0.005909f, 0.006248f, 0.006672f, 0.007118f, 0.007664f, 0.008232f, 0.008759f, 0.009598f, 0.009964f,
+ 0.010956f, 0.011650f, 0.012665f, 0.013702f, 0.014832f, 0.016144f, 0.017654f, 0.019211f, 0.021118f, 0.023102f, 0.025681f, 0.028320f,
+ 0.031708f, 0.035370f, 0.039673f, 0.044739f, 0.050812f, 0.057800f, 0.065796f, 0.074768f, 0.085510f, 0.097961f, 0.112000f, 0.128662f,
+ 0.147217f, 0.168213f, 0.190796f, 0.216309f, 0.244751f, 0.274902f, 0.669922f, 0.698730f, 0.703613f, 0.705566f, 0.707031f, 0.707031f,
+ 0.000212f, 0.000458f, 0.000959f, 0.001192f, 0.001321f, 0.001500f, 0.001823f, 0.002064f, 0.002073f, 0.002293f, 0.002512f, 0.002768f,
+ 0.002981f, 0.003138f, 0.003431f, 0.003765f, 0.003918f, 0.004238f, 0.004482f, 0.004814f, 0.005245f, 0.005531f, 0.005871f, 0.006214f,
+ 0.006660f, 0.007236f, 0.007664f, 0.008331f, 0.008812f, 0.009628f, 0.010277f, 0.010979f, 0.012016f, 0.012978f, 0.014084f, 0.015495f,
+ 0.016937f, 0.018494f, 0.020386f, 0.022659f, 0.025208f, 0.028183f, 0.031860f, 0.036072f, 0.040894f, 0.046326f, 0.053009f, 0.061127f,
+ 0.070374f, 0.081238f, 0.094238f, 0.109314f, 0.126343f, 0.145874f, 0.167847f, 0.192505f, 0.219604f, 0.249634f, 0.656738f, 0.686035f,
+ 0.690430f, 0.694336f, 0.694336f, 0.696777f, 0.000151f, 0.000529f, 0.000692f, 0.000883f, 0.001153f, 0.001337f, 0.001380f, 0.001520f,
+ 0.001753f, 0.001886f, 0.002077f, 0.002243f, 0.002386f, 0.002556f, 0.002832f, 0.003029f, 0.003277f, 0.003447f, 0.003683f, 0.003952f,
+ 0.004135f, 0.004578f, 0.004833f, 0.005222f, 0.005417f, 0.005810f, 0.006355f, 0.006718f, 0.007076f, 0.007652f, 0.008293f, 0.008980f,
+ 0.009674f, 0.010422f, 0.011276f, 0.012283f, 0.013443f, 0.014664f, 0.016113f, 0.017853f, 0.019897f, 0.022156f, 0.024826f, 0.028275f,
+ 0.032135f, 0.036865f, 0.042389f, 0.049011f, 0.056732f, 0.066223f, 0.077576f, 0.090820f, 0.106384f, 0.124512f, 0.145264f, 0.169067f,
+ 0.195190f, 0.224976f, 0.642578f, 0.671387f, 0.679688f, 0.682617f, 0.682617f, 0.683594f, 0.000127f, 0.000376f, 0.000600f, 0.000721f,
+ 0.000901f, 0.001066f, 0.001180f, 0.001332f, 0.001455f, 0.001549f, 0.001709f, 0.001831f, 0.001947f, 0.002150f, 0.002245f, 0.002443f,
+ 0.002682f, 0.002844f, 0.002989f, 0.003201f, 0.003403f, 0.003683f, 0.003883f, 0.004097f, 0.004372f, 0.004665f, 0.004963f, 0.005348f,
+ 0.005711f, 0.006165f, 0.006672f, 0.007004f, 0.007610f, 0.008278f, 0.008873f, 0.009636f, 0.010475f, 0.011475f, 0.012634f, 0.014053f,
+ 0.015404f, 0.017242f, 0.019104f, 0.021774f, 0.024750f, 0.028458f, 0.032745f, 0.038391f, 0.044861f, 0.052795f, 0.062103f, 0.073914f,
+ 0.087830f, 0.104553f, 0.123718f, 0.145996f, 0.171509f, 0.200439f, 0.627930f, 0.658691f, 0.666504f, 0.668945f, 0.671387f, 0.671387f,
+ 0.000013f, 0.000374f, 0.000443f, 0.000688f, 0.000819f, 0.000844f, 0.001004f, 0.001132f, 0.001216f, 0.001259f, 0.001405f, 0.001523f,
+ 0.001566f, 0.001753f, 0.001842f, 0.001997f, 0.002022f, 0.002287f, 0.002377f, 0.002541f, 0.002787f, 0.002878f, 0.003096f, 0.003283f,
+ 0.003551f, 0.003651f, 0.003971f, 0.004272f, 0.004524f, 0.004887f, 0.005196f, 0.005527f, 0.005939f, 0.006386f, 0.006977f, 0.007526f,
+ 0.008148f, 0.008835f, 0.009689f, 0.010689f, 0.011810f, 0.013000f, 0.014641f, 0.016388f, 0.018799f, 0.021469f, 0.024734f, 0.029022f,
+ 0.034210f, 0.040588f, 0.048401f, 0.058319f, 0.070435f, 0.085205f, 0.102905f, 0.123901f, 0.147827f, 0.175903f, 0.612793f, 0.645508f,
+ 0.653320f, 0.656250f, 0.657227f, 0.657227f, 0.000113f, 0.000234f, 0.000465f, 0.000547f, 0.000646f, 0.000684f, 0.000711f, 0.000832f,
+ 0.000963f, 0.000999f, 0.001042f, 0.001183f, 0.001279f, 0.001402f, 0.001494f, 0.001513f, 0.001688f, 0.001716f, 0.001919f, 0.001993f,
+ 0.002081f, 0.002253f, 0.002441f, 0.002575f, 0.002714f, 0.002876f, 0.003050f, 0.003214f, 0.003531f, 0.003714f, 0.003956f, 0.004276f,
+ 0.004604f, 0.004967f, 0.005386f, 0.005718f, 0.006283f, 0.006790f, 0.007290f, 0.008133f, 0.008957f, 0.009987f, 0.010956f, 0.012375f,
+ 0.013916f, 0.015991f, 0.018311f, 0.021347f, 0.025253f, 0.030289f, 0.036560f, 0.044586f, 0.054779f, 0.067749f, 0.083252f, 0.102722f,
+ 0.125732f, 0.152100f, 0.597168f, 0.631836f, 0.639160f, 0.643555f, 0.643066f, 0.645508f, 0.000207f, 0.000175f, 0.000364f, 0.000507f,
+ 0.000496f, 0.000569f, 0.000683f, 0.000584f, 0.000737f, 0.000764f, 0.000885f, 0.000964f, 0.000999f, 0.001076f, 0.001085f, 0.001272f,
+ 0.001327f, 0.001354f, 0.001491f, 0.001494f, 0.001677f, 0.001781f, 0.001862f, 0.001976f, 0.002079f, 0.002190f, 0.002338f, 0.002481f,
+ 0.002691f, 0.002811f, 0.003117f, 0.003214f, 0.003422f, 0.003706f, 0.003990f, 0.004314f, 0.004608f, 0.004982f, 0.005379f, 0.006027f,
+ 0.006580f, 0.007351f, 0.008049f, 0.009041f, 0.010323f, 0.011551f, 0.013428f, 0.015419f, 0.018219f, 0.021713f, 0.026550f, 0.032715f,
+ 0.040833f, 0.051605f, 0.065552f, 0.082458f, 0.104004f, 0.129395f, 0.582031f, 0.618652f, 0.625488f, 0.627930f, 0.630859f, 0.631348f,
+ 0.000189f, 0.000160f, 0.000272f, 0.000387f, 0.000335f, 0.000486f, 0.000424f, 0.000469f, 0.000551f, 0.000589f, 0.000700f, 0.000727f,
+ 0.000772f, 0.000859f, 0.000891f, 0.000872f, 0.001000f, 0.001048f, 0.001076f, 0.001172f, 0.001224f, 0.001311f, 0.001376f, 0.001450f,
+ 0.001554f, 0.001591f, 0.001760f, 0.001838f, 0.001999f, 0.002180f, 0.002333f, 0.002388f, 0.002584f, 0.002777f, 0.002907f, 0.003162f,
+ 0.003368f, 0.003677f, 0.003979f, 0.004303f, 0.004715f, 0.005188f, 0.005787f, 0.006378f, 0.007313f, 0.008194f, 0.009407f, 0.010887f,
+ 0.012779f, 0.015198f, 0.018494f, 0.022888f, 0.029037f, 0.037659f, 0.048920f, 0.064270f, 0.083740f, 0.107300f, 0.565918f, 0.603516f,
+ 0.611328f, 0.614746f, 0.617188f, 0.618164f, 0.000000f, 0.000170f, 0.000207f, 0.000274f, 0.000292f, 0.000309f, 0.000381f, 0.000326f,
+ 0.000418f, 0.000439f, 0.000519f, 0.000519f, 0.000560f, 0.000574f, 0.000652f, 0.000678f, 0.000717f, 0.000756f, 0.000782f, 0.000820f,
+ 0.000893f, 0.000937f, 0.000991f, 0.001063f, 0.001112f, 0.001174f, 0.001284f, 0.001302f, 0.001408f, 0.001460f, 0.001586f, 0.001711f,
+ 0.001826f, 0.001959f, 0.002058f, 0.002207f, 0.002388f, 0.002565f, 0.002836f, 0.003046f, 0.003284f, 0.003567f, 0.004009f, 0.004463f,
+ 0.005001f, 0.005661f, 0.006451f, 0.007473f, 0.008751f, 0.010368f, 0.012611f, 0.015587f, 0.019730f, 0.025787f, 0.034729f, 0.047272f,
+ 0.064392f, 0.087097f, 0.550293f, 0.587891f, 0.596680f, 0.600586f, 0.602539f, 0.603516f, 0.000000f, 0.000057f, 0.000175f, 0.000210f,
+ 0.000221f, 0.000261f, 0.000224f, 0.000285f, 0.000296f, 0.000329f, 0.000374f, 0.000329f, 0.000344f, 0.000416f, 0.000421f, 0.000479f,
+ 0.000455f, 0.000530f, 0.000552f, 0.000598f, 0.000640f, 0.000670f, 0.000695f, 0.000740f, 0.000798f, 0.000806f, 0.000883f, 0.000908f,
+ 0.000983f, 0.001094f, 0.001083f, 0.001169f, 0.001242f, 0.001340f, 0.001440f, 0.001536f, 0.001601f, 0.001752f, 0.001893f, 0.002029f,
+ 0.002218f, 0.002424f, 0.002651f, 0.002934f, 0.003294f, 0.003681f, 0.004200f, 0.004833f, 0.005688f, 0.006863f, 0.008202f, 0.010178f,
+ 0.012955f, 0.016846f, 0.023163f, 0.032745f, 0.047150f, 0.067383f, 0.534180f, 0.574219f, 0.582031f, 0.584961f, 0.586914f, 0.589844f,
+ 0.000000f, 0.000105f, 0.000145f, 0.000101f, 0.000161f, 0.000163f, 0.000165f, 0.000193f, 0.000190f, 0.000202f, 0.000205f, 0.000260f,
+ 0.000251f, 0.000281f, 0.000305f, 0.000316f, 0.000323f, 0.000346f, 0.000364f, 0.000383f, 0.000413f, 0.000436f, 0.000461f, 0.000486f,
+ 0.000515f, 0.000564f, 0.000594f, 0.000616f, 0.000639f, 0.000677f, 0.000729f, 0.000748f, 0.000842f, 0.000861f, 0.000943f, 0.000970f,
+ 0.001054f, 0.001120f, 0.001219f, 0.001310f, 0.001398f, 0.001534f, 0.001709f, 0.001852f, 0.002096f, 0.002291f, 0.002594f, 0.002987f,
+ 0.003481f, 0.004128f, 0.004997f, 0.006218f, 0.007950f, 0.010445f, 0.014313f, 0.020874f, 0.032166f, 0.049866f, 0.517578f, 0.558105f,
+ 0.567383f, 0.570801f, 0.573730f, 0.574707f, 0.000000f, 0.000097f, 0.000089f, 0.000082f, 0.000092f, 0.000096f, 0.000092f, 0.000118f,
+ 0.000126f, 0.000130f, 0.000138f, 0.000138f, 0.000143f, 0.000163f, 0.000181f, 0.000187f, 0.000195f, 0.000228f, 0.000221f, 0.000261f,
+ 0.000243f, 0.000254f, 0.000274f, 0.000299f, 0.000334f, 0.000332f, 0.000345f, 0.000362f, 0.000394f, 0.000410f, 0.000433f, 0.000463f,
+ 0.000497f, 0.000510f, 0.000562f, 0.000594f, 0.000636f, 0.000670f, 0.000731f, 0.000777f, 0.000832f, 0.000927f, 0.000991f, 0.001101f,
+ 0.001210f, 0.001350f, 0.001513f, 0.001720f, 0.001999f, 0.002373f, 0.002815f, 0.003498f, 0.004478f, 0.006001f, 0.008347f, 0.012299f,
+ 0.019669f, 0.034210f, 0.501465f, 0.542969f, 0.552246f, 0.556641f, 0.559082f, 0.559570f, 0.000107f, 0.000087f, 0.000077f, 0.000070f,
+ 0.000065f, 0.000066f, 0.000059f, 0.000064f, 0.000065f, 0.000071f, 0.000070f, 0.000095f, 0.000081f, 0.000085f, 0.000110f, 0.000097f,
+ 0.000117f, 0.000126f, 0.000127f, 0.000133f, 0.000132f, 0.000141f, 0.000169f, 0.000173f, 0.000185f, 0.000183f, 0.000192f, 0.000215f,
+ 0.000216f, 0.000235f, 0.000236f, 0.000265f, 0.000278f, 0.000290f, 0.000313f, 0.000317f, 0.000347f, 0.000365f, 0.000400f, 0.000422f,
+ 0.000457f, 0.000494f, 0.000535f, 0.000586f, 0.000639f, 0.000700f, 0.000786f, 0.000888f, 0.001019f, 0.001207f, 0.001435f, 0.001746f,
+ 0.002258f, 0.003019f, 0.004299f, 0.006523f, 0.010612f, 0.020859f, 0.484619f, 0.527344f, 0.536621f, 0.541504f, 0.542969f, 0.544922f,
+ 0.000092f, 0.000070f, 0.000062f, 0.000056f, 0.000051f, 0.000048f, 0.000045f, 0.000044f, 0.000041f, 0.000039f, 0.000038f, 0.000037f,
+ 0.000047f, 0.000039f, 0.000041f, 0.000041f, 0.000058f, 0.000053f, 0.000062f, 0.000064f, 0.000068f, 0.000072f, 0.000076f, 0.000076f,
+ 0.000078f, 0.000092f, 0.000085f, 0.000101f, 0.000104f, 0.000110f, 0.000115f, 0.000118f, 0.000127f, 0.000133f, 0.000152f, 0.000150f,
+ 0.000163f, 0.000190f, 0.000190f, 0.000202f, 0.000213f, 0.000225f, 0.000249f, 0.000268f, 0.000296f, 0.000321f, 0.000354f, 0.000402f,
+ 0.000458f, 0.000520f, 0.000618f, 0.000744f, 0.000950f, 0.001263f, 0.001822f, 0.002865f, 0.005028f, 0.010544f, 0.468018f, 0.511230f,
+ 0.521484f, 0.524902f, 0.529297f, 0.529785f, 0.000067f, 0.000049f, 0.000041f, 0.000037f, 0.000034f, 0.000032f, 0.000031f, 0.000029f,
+ 0.000028f, 0.000027f, 0.000027f, 0.000026f, 0.000025f, 0.000023f, 0.000022f, 0.000021f, 0.000020f, 0.000020f, 0.000023f, 0.000024f,
+ 0.000021f, 0.000022f, 0.000025f, 0.000029f, 0.000030f, 0.000034f, 0.000036f, 0.000034f, 0.000039f, 0.000038f, 0.000045f, 0.000045f,
+ 0.000048f, 0.000051f, 0.000053f, 0.000055f, 0.000063f, 0.000070f, 0.000073f, 0.000073f, 0.000080f, 0.000084f, 0.000089f, 0.000102f,
+ 0.000107f, 0.000115f, 0.000128f, 0.000145f, 0.000156f, 0.000178f, 0.000213f, 0.000253f, 0.000311f, 0.000400f, 0.000572f, 0.000916f,
+ 0.001751f, 0.004158f, 0.450439f, 0.496338f, 0.505859f, 0.510742f, 0.513184f, 0.514648f, 0.000016f, 0.000013f, 0.000011f, 0.000010f,
+ 0.000012f, 0.000012f, 0.000011f, 0.000012f, 0.000011f, 0.000012f, 0.000011f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000011f,
+ 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000009f, 0.000008f, 0.000008f,
+ 0.000008f, 0.000009f, 0.000009f, 0.000009f, 0.000009f, 0.000011f, 0.000012f, 0.000012f, 0.000015f, 0.000014f, 0.000014f, 0.000017f,
+ 0.000018f, 0.000020f, 0.000020f, 0.000022f, 0.000026f, 0.000027f, 0.000028f, 0.000027f, 0.000033f, 0.000036f, 0.000044f, 0.000051f,
+ 0.000057f, 0.000078f, 0.000103f, 0.000159f, 0.000315f, 0.000997f, 0.433350f, 0.479980f, 0.490234f, 0.495605f, 0.498291f, 0.499512f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000004f, 0.000004f, 0.000007f, 0.000025f, 0.416016f, 0.464111f,
+ 0.474854f, 0.479248f, 0.481934f, 0.484375f,
+ },
+ {
+ 0.023209f, 0.069336f, 0.113037f, 0.154663f, 0.193726f, 0.231812f, 0.267578f, 0.301758f, 0.333740f, 0.364258f, 0.393555f, 0.421631f,
+ 0.447510f, 0.473145f, 0.497070f, 0.520020f, 0.541992f, 0.562988f, 0.583008f, 0.602539f, 0.620605f, 0.638184f, 0.655762f, 0.671387f,
+ 0.687500f, 0.702637f, 0.716309f, 0.729980f, 0.744141f, 0.757812f, 0.769531f, 0.782227f, 0.793945f, 0.804688f, 0.815918f, 0.826172f,
+ 0.836426f, 0.846191f, 0.855957f, 0.865234f, 0.874023f, 0.882812f, 0.891113f, 0.898926f, 0.907227f, 0.915039f, 0.922852f, 0.929688f,
+ 0.937012f, 0.943848f, 0.950684f, 0.956543f, 0.963379f, 0.969238f, 0.976074f, 0.981445f, 0.986816f, 0.992676f, 0.991211f, 0.978516f,
+ 0.968750f, 0.960449f, 0.952637f, 0.945312f, 0.019730f, 0.059631f, 0.098206f, 0.135864f, 0.172119f, 0.206421f, 0.239624f, 0.272461f,
+ 0.304932f, 0.333984f, 0.362549f, 0.389648f, 0.416016f, 0.441406f, 0.466309f, 0.489502f, 0.511230f, 0.533203f, 0.554199f, 0.573242f,
+ 0.593262f, 0.611816f, 0.629395f, 0.645508f, 0.662598f, 0.678711f, 0.693359f, 0.708496f, 0.722168f, 0.735840f, 0.750000f, 0.762207f,
+ 0.773926f, 0.786133f, 0.796875f, 0.808594f, 0.818848f, 0.829590f, 0.839355f, 0.850098f, 0.859863f, 0.868652f, 0.877441f, 0.886230f,
+ 0.895020f, 0.903809f, 0.911133f, 0.918457f, 0.925781f, 0.933105f, 0.940430f, 0.946777f, 0.954590f, 0.960938f, 0.966797f, 0.973145f,
+ 0.979004f, 0.984863f, 0.987793f, 0.976074f, 0.966797f, 0.958496f, 0.951172f, 0.943848f, 0.017151f, 0.051636f, 0.085510f, 0.119202f,
+ 0.152466f, 0.184814f, 0.216187f, 0.246582f, 0.276855f, 0.305664f, 0.332764f, 0.360107f, 0.385986f, 0.411621f, 0.435791f, 0.459473f,
+ 0.481445f, 0.502441f, 0.524414f, 0.546387f, 0.565430f, 0.583496f, 0.602051f, 0.619629f, 0.636719f, 0.653320f, 0.669434f, 0.684082f,
+ 0.699707f, 0.713867f, 0.728027f, 0.741211f, 0.754883f, 0.767090f, 0.779297f, 0.791016f, 0.802734f, 0.813965f, 0.824219f, 0.833984f,
+ 0.843750f, 0.854492f, 0.863281f, 0.873535f, 0.882324f, 0.890137f, 0.898926f, 0.906738f, 0.915039f, 0.922852f, 0.930176f, 0.937012f,
+ 0.944336f, 0.951172f, 0.958008f, 0.964844f, 0.970703f, 0.977051f, 0.983887f, 0.972656f, 0.964355f, 0.956543f, 0.949219f, 0.942383f,
+ 0.014885f, 0.044678f, 0.075195f, 0.104919f, 0.135254f, 0.165649f, 0.194702f, 0.223633f, 0.251221f, 0.279053f, 0.305420f, 0.331543f,
+ 0.357422f, 0.382568f, 0.406982f, 0.430420f, 0.453369f, 0.475586f, 0.496582f, 0.517090f, 0.536133f, 0.556641f, 0.575684f, 0.592773f,
+ 0.611328f, 0.628418f, 0.643555f, 0.661621f, 0.676270f, 0.691406f, 0.705566f, 0.720215f, 0.733887f, 0.746582f, 0.759766f, 0.772949f,
+ 0.784668f, 0.795898f, 0.807129f, 0.818359f, 0.828125f, 0.838867f, 0.848633f, 0.858887f, 0.867676f, 0.877441f, 0.886230f, 0.894531f,
+ 0.903320f, 0.911621f, 0.919434f, 0.927734f, 0.934570f, 0.940918f, 0.948730f, 0.956543f, 0.962402f, 0.969238f, 0.979980f, 0.970215f,
+ 0.961914f, 0.954102f, 0.947266f, 0.940918f, 0.013046f, 0.038940f, 0.066162f, 0.093323f, 0.120544f, 0.147583f, 0.174683f, 0.201538f,
+ 0.228516f, 0.254639f, 0.280518f, 0.304932f, 0.330566f, 0.354492f, 0.379395f, 0.402100f, 0.424561f, 0.446533f, 0.467529f, 0.488525f,
+ 0.509277f, 0.529297f, 0.547852f, 0.566895f, 0.585449f, 0.602539f, 0.620605f, 0.636230f, 0.653809f, 0.667480f, 0.684570f, 0.698242f,
+ 0.712891f, 0.726562f, 0.739746f, 0.753418f, 0.765625f, 0.777344f, 0.789551f, 0.801270f, 0.812500f, 0.823730f, 0.833984f, 0.844238f,
+ 0.854004f, 0.863770f, 0.874023f, 0.882324f, 0.891113f, 0.899902f, 0.908203f, 0.916504f, 0.924805f, 0.932129f, 0.939453f, 0.947266f,
+ 0.954102f, 0.960938f, 0.976562f, 0.967285f, 0.958984f, 0.951660f, 0.944824f, 0.938965f, 0.011696f, 0.034698f, 0.058807f, 0.083130f,
+ 0.107727f, 0.132324f, 0.156982f, 0.182251f, 0.207153f, 0.232178f, 0.256836f, 0.280762f, 0.304688f, 0.328369f, 0.352295f, 0.375244f,
+ 0.397461f, 0.419434f, 0.440430f, 0.461914f, 0.482178f, 0.501953f, 0.522461f, 0.540527f, 0.559570f, 0.577148f, 0.595703f, 0.613281f,
+ 0.628418f, 0.644531f, 0.661621f, 0.676270f, 0.691406f, 0.705078f, 0.719727f, 0.733887f, 0.746094f, 0.759766f, 0.771973f, 0.784180f,
+ 0.795898f, 0.807617f, 0.818359f, 0.829102f, 0.839844f, 0.850098f, 0.859375f, 0.869629f, 0.878906f, 0.887695f, 0.896484f, 0.905273f,
+ 0.914062f, 0.921875f, 0.929688f, 0.937988f, 0.944824f, 0.952637f, 0.973145f, 0.963379f, 0.956055f, 0.949219f, 0.942871f, 0.937012f,
+ 0.010094f, 0.030975f, 0.052063f, 0.073975f, 0.096069f, 0.118713f, 0.141479f, 0.164551f, 0.187866f, 0.211182f, 0.234985f, 0.258057f,
+ 0.280518f, 0.303467f, 0.326172f, 0.348145f, 0.370117f, 0.392822f, 0.413574f, 0.434814f, 0.455322f, 0.476074f, 0.495361f, 0.515137f,
+ 0.533203f, 0.551758f, 0.569824f, 0.586426f, 0.604492f, 0.621582f, 0.637695f, 0.654297f, 0.668945f, 0.683594f, 0.699219f, 0.712402f,
+ 0.728516f, 0.741699f, 0.753906f, 0.767090f, 0.778320f, 0.790527f, 0.802246f, 0.813965f, 0.824219f, 0.835449f, 0.846680f, 0.855957f,
+ 0.865723f, 0.875488f, 0.884766f, 0.894043f, 0.902832f, 0.911133f, 0.919434f, 0.927734f, 0.935547f, 0.943359f, 0.968750f, 0.960449f,
+ 0.953125f, 0.946289f, 0.940430f, 0.934570f, 0.008797f, 0.027466f, 0.045959f, 0.066223f, 0.086304f, 0.106506f, 0.127441f, 0.149170f,
+ 0.170532f, 0.192261f, 0.213867f, 0.236206f, 0.258057f, 0.280273f, 0.301758f, 0.323486f, 0.344727f, 0.367188f, 0.388184f, 0.408447f,
+ 0.429443f, 0.450439f, 0.469727f, 0.489014f, 0.508301f, 0.526855f, 0.545410f, 0.562500f, 0.581055f, 0.597656f, 0.613770f, 0.630859f,
+ 0.647461f, 0.663574f, 0.677734f, 0.693359f, 0.707031f, 0.720703f, 0.735352f, 0.748047f, 0.760254f, 0.772461f, 0.785156f, 0.797363f,
+ 0.810059f, 0.819824f, 0.831543f, 0.842285f, 0.852051f, 0.862793f, 0.873047f, 0.882324f, 0.891113f, 0.899902f, 0.909180f, 0.917969f,
+ 0.925781f, 0.934082f, 0.964355f, 0.957031f, 0.949707f, 0.943359f, 0.937988f, 0.932129f, 0.007927f, 0.024414f, 0.041077f, 0.059204f,
+ 0.077148f, 0.095581f, 0.115479f, 0.134644f, 0.154785f, 0.175293f, 0.196045f, 0.216553f, 0.236694f, 0.258057f, 0.278809f, 0.300049f,
+ 0.321289f, 0.342529f, 0.363281f, 0.383545f, 0.403564f, 0.424072f, 0.444092f, 0.463135f, 0.483154f, 0.501953f, 0.519531f, 0.539062f,
+ 0.555664f, 0.574707f, 0.591309f, 0.608398f, 0.624512f, 0.640137f, 0.655762f, 0.671875f, 0.686523f, 0.701172f, 0.715820f, 0.729004f,
+ 0.742676f, 0.755859f, 0.769043f, 0.781738f, 0.792969f, 0.805176f, 0.816895f, 0.827637f, 0.838867f, 0.849121f, 0.859375f, 0.870117f,
+ 0.879395f, 0.889160f, 0.898926f, 0.906738f, 0.916504f, 0.924805f, 0.960938f, 0.953125f, 0.947266f, 0.940430f, 0.935547f, 0.929688f,
+ 0.007080f, 0.022247f, 0.037445f, 0.053070f, 0.069336f, 0.086975f, 0.103577f, 0.121948f, 0.140503f, 0.158936f, 0.178833f, 0.198242f,
+ 0.217651f, 0.237793f, 0.257812f, 0.278076f, 0.297607f, 0.318604f, 0.338623f, 0.358643f, 0.378662f, 0.399170f, 0.418213f, 0.438721f,
+ 0.457520f, 0.477051f, 0.495361f, 0.513672f, 0.531250f, 0.549316f, 0.567383f, 0.583984f, 0.601562f, 0.617676f, 0.634277f, 0.650391f,
+ 0.666016f, 0.680176f, 0.695801f, 0.710449f, 0.723633f, 0.737305f, 0.750977f, 0.764648f, 0.776367f, 0.789551f, 0.802246f, 0.813477f,
+ 0.824219f, 0.835938f, 0.846680f, 0.857422f, 0.867188f, 0.876953f, 0.887207f, 0.895996f, 0.905762f, 0.915527f, 0.955566f, 0.949707f,
+ 0.943359f, 0.937988f, 0.932129f, 0.927246f, 0.006363f, 0.019516f, 0.033691f, 0.047577f, 0.062469f, 0.078186f, 0.093933f, 0.110657f,
+ 0.127563f, 0.144653f, 0.162598f, 0.181152f, 0.199707f, 0.218384f, 0.237427f, 0.257324f, 0.276367f, 0.295166f, 0.315674f, 0.335205f,
+ 0.355225f, 0.374756f, 0.393799f, 0.413574f, 0.432617f, 0.451904f, 0.470459f, 0.489258f, 0.508301f, 0.525879f, 0.543945f, 0.560059f,
+ 0.578613f, 0.595703f, 0.612793f, 0.628418f, 0.644531f, 0.659668f, 0.675293f, 0.689941f, 0.704590f, 0.719238f, 0.732910f, 0.747070f,
+ 0.759766f, 0.773438f, 0.785156f, 0.797852f, 0.809570f, 0.821289f, 0.833008f, 0.843750f, 0.854980f, 0.865723f, 0.875977f, 0.886230f,
+ 0.895508f, 0.904785f, 0.951660f, 0.945801f, 0.939941f, 0.934570f, 0.929199f, 0.924805f, 0.005985f, 0.017776f, 0.030212f, 0.043030f,
+ 0.056488f, 0.070190f, 0.085205f, 0.100342f, 0.115723f, 0.132446f, 0.148438f, 0.165771f, 0.183228f, 0.200684f, 0.218994f, 0.237183f,
+ 0.255859f, 0.274170f, 0.292725f, 0.313477f, 0.331299f, 0.351318f, 0.369873f, 0.389160f, 0.408936f, 0.426758f, 0.446533f, 0.464844f,
+ 0.483154f, 0.501465f, 0.519531f, 0.537598f, 0.555664f, 0.572754f, 0.589844f, 0.605957f, 0.622070f, 0.639648f, 0.654297f, 0.670898f,
+ 0.685059f, 0.700195f, 0.714844f, 0.728516f, 0.742188f, 0.754883f, 0.769043f, 0.781738f, 0.795410f, 0.808105f, 0.818359f, 0.830566f,
+ 0.841797f, 0.853027f, 0.863770f, 0.874023f, 0.884766f, 0.893555f, 0.947266f, 0.942383f, 0.936523f, 0.930664f, 0.926270f, 0.921387f,
+ 0.005173f, 0.016083f, 0.027359f, 0.038849f, 0.051056f, 0.063843f, 0.077026f, 0.091064f, 0.105591f, 0.120422f, 0.135498f, 0.150879f,
+ 0.167480f, 0.184326f, 0.201172f, 0.218384f, 0.236084f, 0.254395f, 0.272949f, 0.291260f, 0.309570f, 0.328125f, 0.346680f, 0.365967f,
+ 0.384766f, 0.403320f, 0.422119f, 0.440918f, 0.458984f, 0.477783f, 0.496094f, 0.513672f, 0.531738f, 0.548828f, 0.566406f, 0.583984f,
+ 0.600098f, 0.617188f, 0.632812f, 0.649902f, 0.665527f, 0.681152f, 0.694824f, 0.709473f, 0.724121f, 0.738770f, 0.752441f, 0.765137f,
+ 0.778809f, 0.791992f, 0.803711f, 0.815918f, 0.828125f, 0.839844f, 0.851562f, 0.862793f, 0.873535f, 0.883789f, 0.941895f, 0.938477f,
+ 0.933105f, 0.927246f, 0.922363f, 0.918457f, 0.004791f, 0.014610f, 0.024475f, 0.035126f, 0.046478f, 0.057922f, 0.069885f, 0.083008f,
+ 0.096069f, 0.109253f, 0.123840f, 0.137939f, 0.153076f, 0.168701f, 0.185059f, 0.200928f, 0.218262f, 0.234985f, 0.252686f, 0.270264f,
+ 0.288086f, 0.306396f, 0.324951f, 0.343018f, 0.362305f, 0.379883f, 0.398926f, 0.417236f, 0.435547f, 0.454346f, 0.472656f, 0.491211f,
+ 0.508301f, 0.526855f, 0.543457f, 0.561523f, 0.578125f, 0.595215f, 0.612305f, 0.628418f, 0.644043f, 0.660645f, 0.675781f, 0.691406f,
+ 0.706055f, 0.720215f, 0.735840f, 0.749023f, 0.762695f, 0.776855f, 0.789551f, 0.800781f, 0.814941f, 0.826172f, 0.838867f, 0.851074f,
+ 0.862305f, 0.872070f, 0.937500f, 0.933594f, 0.929199f, 0.923828f, 0.919434f, 0.915527f, 0.004387f, 0.013268f, 0.022385f, 0.031860f,
+ 0.041962f, 0.052612f, 0.063171f, 0.075073f, 0.086792f, 0.099854f, 0.113037f, 0.125977f, 0.140381f, 0.154663f, 0.169678f, 0.184814f,
+ 0.200562f, 0.217773f, 0.234131f, 0.250732f, 0.268066f, 0.284912f, 0.303223f, 0.321289f, 0.339355f, 0.357666f, 0.375488f, 0.394043f,
+ 0.411865f, 0.430664f, 0.448730f, 0.467041f, 0.485352f, 0.503418f, 0.520508f, 0.539062f, 0.556152f, 0.573242f, 0.590820f, 0.606934f,
+ 0.624512f, 0.640625f, 0.655762f, 0.672363f, 0.687500f, 0.702148f, 0.718750f, 0.731934f, 0.746582f, 0.759766f, 0.772949f, 0.787109f,
+ 0.800781f, 0.813477f, 0.825195f, 0.838379f, 0.850098f, 0.861816f, 0.932617f, 0.929688f, 0.925293f, 0.919922f, 0.915527f, 0.912109f,
+ 0.003941f, 0.011986f, 0.020630f, 0.029144f, 0.038544f, 0.048035f, 0.058075f, 0.068542f, 0.079590f, 0.090942f, 0.102661f, 0.115295f,
+ 0.128296f, 0.141602f, 0.155518f, 0.170654f, 0.185425f, 0.200684f, 0.216309f, 0.231812f, 0.249146f, 0.265137f, 0.282471f, 0.299072f,
+ 0.317139f, 0.334717f, 0.352783f, 0.371338f, 0.388916f, 0.406982f, 0.425537f, 0.443848f, 0.461914f, 0.479980f, 0.498291f, 0.515625f,
+ 0.533203f, 0.550293f, 0.568359f, 0.585449f, 0.603027f, 0.618652f, 0.635742f, 0.652344f, 0.668457f, 0.684082f, 0.699219f, 0.713867f,
+ 0.729004f, 0.743652f, 0.757812f, 0.771484f, 0.785645f, 0.798828f, 0.812012f, 0.824219f, 0.836914f, 0.850098f, 0.927246f, 0.925293f,
+ 0.920410f, 0.916504f, 0.912598f, 0.908203f, 0.003790f, 0.011009f, 0.018829f, 0.026779f, 0.035339f, 0.043762f, 0.053223f, 0.062408f,
+ 0.072693f, 0.082947f, 0.093689f, 0.105469f, 0.117554f, 0.130005f, 0.142822f, 0.156494f, 0.170166f, 0.184448f, 0.198975f, 0.213745f,
+ 0.230469f, 0.246460f, 0.262939f, 0.279541f, 0.296143f, 0.313721f, 0.331299f, 0.348633f, 0.367188f, 0.384521f, 0.402344f, 0.420410f,
+ 0.438965f, 0.457275f, 0.475830f, 0.493164f, 0.510742f, 0.528809f, 0.546387f, 0.564453f, 0.581055f, 0.598145f, 0.615234f, 0.631836f,
+ 0.647461f, 0.665527f, 0.680664f, 0.696289f, 0.711914f, 0.728027f, 0.741211f, 0.756836f, 0.770508f, 0.783691f, 0.798340f, 0.811523f,
+ 0.824219f, 0.837402f, 0.921387f, 0.920410f, 0.916504f, 0.913086f, 0.908691f, 0.904785f, 0.003479f, 0.009949f, 0.016937f, 0.024445f,
+ 0.031708f, 0.039948f, 0.048218f, 0.056793f, 0.066223f, 0.075928f, 0.085632f, 0.096313f, 0.107178f, 0.118958f, 0.130493f, 0.143311f,
+ 0.156494f, 0.170044f, 0.183960f, 0.197876f, 0.213501f, 0.228027f, 0.244019f, 0.260010f, 0.276611f, 0.293213f, 0.309814f, 0.327393f,
+ 0.344482f, 0.363037f, 0.379883f, 0.398438f, 0.416504f, 0.434082f, 0.451904f, 0.470215f, 0.488525f, 0.505859f, 0.523926f, 0.541504f,
+ 0.559570f, 0.577637f, 0.594238f, 0.611328f, 0.628418f, 0.645020f, 0.661133f, 0.677246f, 0.693848f, 0.709961f, 0.725586f, 0.739746f,
+ 0.755371f, 0.769531f, 0.783203f, 0.797852f, 0.810547f, 0.824707f, 0.916016f, 0.915527f, 0.912109f, 0.908691f, 0.904785f, 0.900879f,
+ 0.003014f, 0.008842f, 0.015640f, 0.022018f, 0.028885f, 0.036163f, 0.044250f, 0.051819f, 0.059967f, 0.069031f, 0.078247f, 0.088135f,
+ 0.098267f, 0.108337f, 0.119751f, 0.131470f, 0.143433f, 0.156006f, 0.169189f, 0.183105f, 0.196655f, 0.211304f, 0.226196f, 0.241211f,
+ 0.257080f, 0.273438f, 0.289307f, 0.306396f, 0.323975f, 0.340576f, 0.358398f, 0.375732f, 0.393799f, 0.411133f, 0.429688f, 0.447998f,
+ 0.466064f, 0.483887f, 0.501465f, 0.519531f, 0.537598f, 0.555664f, 0.573242f, 0.590820f, 0.607910f, 0.625000f, 0.642578f, 0.658203f,
+ 0.675293f, 0.691406f, 0.707520f, 0.724121f, 0.738770f, 0.753418f, 0.769531f, 0.783203f, 0.797363f, 0.811523f, 0.910156f, 0.910645f,
+ 0.907715f, 0.904785f, 0.900879f, 0.896973f, 0.002861f, 0.008591f, 0.014000f, 0.020203f, 0.026962f, 0.033203f, 0.040161f, 0.047485f,
+ 0.055237f, 0.062988f, 0.071594f, 0.080750f, 0.089905f, 0.099854f, 0.109741f, 0.120056f, 0.131592f, 0.143311f, 0.155640f, 0.167969f,
+ 0.181763f, 0.195190f, 0.209229f, 0.223877f, 0.238647f, 0.254150f, 0.269531f, 0.285889f, 0.302979f, 0.319824f, 0.336426f, 0.354004f,
+ 0.372070f, 0.389893f, 0.406982f, 0.424805f, 0.443359f, 0.461182f, 0.479492f, 0.498047f, 0.515625f, 0.533691f, 0.551270f, 0.569336f,
+ 0.587402f, 0.604492f, 0.622070f, 0.639160f, 0.656738f, 0.673828f, 0.689941f, 0.705566f, 0.722168f, 0.737793f, 0.753418f, 0.768066f,
+ 0.783203f, 0.798340f, 0.904297f, 0.905762f, 0.902832f, 0.899414f, 0.895996f, 0.893066f, 0.002535f, 0.007812f, 0.013252f, 0.018738f,
+ 0.024384f, 0.030548f, 0.036774f, 0.043427f, 0.050476f, 0.057556f, 0.065491f, 0.073425f, 0.082458f, 0.091370f, 0.100525f, 0.110413f,
+ 0.120605f, 0.131592f, 0.142822f, 0.154663f, 0.166870f, 0.180176f, 0.193237f, 0.207031f, 0.221191f, 0.236084f, 0.250732f, 0.266602f,
+ 0.282959f, 0.299072f, 0.315430f, 0.332520f, 0.350342f, 0.367676f, 0.385010f, 0.403076f, 0.421631f, 0.439209f, 0.457520f, 0.475342f,
+ 0.494141f, 0.512695f, 0.530273f, 0.547852f, 0.565918f, 0.584473f, 0.602051f, 0.619629f, 0.637207f, 0.655273f, 0.671387f, 0.688965f,
+ 0.706055f, 0.721191f, 0.737305f, 0.752930f, 0.769531f, 0.784668f, 0.898438f, 0.900879f, 0.897949f, 0.894531f, 0.891602f, 0.888672f,
+ 0.002411f, 0.007103f, 0.012161f, 0.017105f, 0.022385f, 0.027985f, 0.033203f, 0.039581f, 0.045532f, 0.052521f, 0.059814f, 0.067261f,
+ 0.074768f, 0.083313f, 0.092041f, 0.101013f, 0.110291f, 0.120361f, 0.130615f, 0.141724f, 0.153076f, 0.165283f, 0.177612f, 0.190918f,
+ 0.204346f, 0.218506f, 0.233154f, 0.247559f, 0.263428f, 0.279053f, 0.295166f, 0.312256f, 0.328857f, 0.345947f, 0.363281f, 0.381348f,
+ 0.398926f, 0.417236f, 0.435547f, 0.453369f, 0.471191f, 0.489502f, 0.508301f, 0.525879f, 0.545410f, 0.563477f, 0.581055f, 0.600098f,
+ 0.617676f, 0.635254f, 0.653809f, 0.670410f, 0.687500f, 0.705078f, 0.720703f, 0.736816f, 0.753418f, 0.769531f, 0.892090f, 0.895020f,
+ 0.892578f, 0.889648f, 0.887207f, 0.884277f, 0.002344f, 0.006565f, 0.011322f, 0.015686f, 0.020630f, 0.025574f, 0.030807f, 0.035980f,
+ 0.042084f, 0.048279f, 0.054352f, 0.061432f, 0.068848f, 0.076172f, 0.083618f, 0.092590f, 0.101135f, 0.109619f, 0.120178f, 0.130249f,
+ 0.140991f, 0.151978f, 0.163696f, 0.175781f, 0.188721f, 0.202026f, 0.215820f, 0.230103f, 0.244873f, 0.259766f, 0.275635f, 0.291504f,
+ 0.307617f, 0.324219f, 0.342041f, 0.358887f, 0.376709f, 0.394775f, 0.412354f, 0.431152f, 0.448975f, 0.468018f, 0.486328f, 0.504883f,
+ 0.523438f, 0.541992f, 0.560547f, 0.579102f, 0.597656f, 0.615234f, 0.633789f, 0.651855f, 0.669434f, 0.687500f, 0.704590f, 0.721680f,
+ 0.738770f, 0.755859f, 0.886719f, 0.889648f, 0.887695f, 0.884766f, 0.882812f, 0.879883f, 0.002003f, 0.006268f, 0.009987f, 0.014198f,
+ 0.018875f, 0.023605f, 0.028259f, 0.033203f, 0.038513f, 0.044495f, 0.049866f, 0.056152f, 0.062500f, 0.069458f, 0.076660f, 0.084473f,
+ 0.092163f, 0.100586f, 0.109741f, 0.119324f, 0.128662f, 0.139526f, 0.150146f, 0.161499f, 0.173706f, 0.185791f, 0.199341f, 0.212891f,
+ 0.227051f, 0.241455f, 0.256592f, 0.271729f, 0.288330f, 0.304199f, 0.321045f, 0.337891f, 0.355469f, 0.373291f, 0.391113f, 0.408936f,
+ 0.426758f, 0.446289f, 0.464600f, 0.483643f, 0.500977f, 0.520996f, 0.539551f, 0.558594f, 0.577148f, 0.595703f, 0.614746f, 0.632324f,
+ 0.650879f, 0.669434f, 0.687012f, 0.704590f, 0.722656f, 0.740234f, 0.880371f, 0.883301f, 0.881836f, 0.879883f, 0.877441f, 0.875000f,
+ 0.001739f, 0.005779f, 0.009598f, 0.013245f, 0.017334f, 0.021637f, 0.025955f, 0.030121f, 0.035217f, 0.040131f, 0.045990f, 0.051453f,
+ 0.056915f, 0.063354f, 0.070007f, 0.076965f, 0.084351f, 0.091980f, 0.100281f, 0.108826f, 0.117981f, 0.127441f, 0.137939f, 0.148315f,
+ 0.160034f, 0.171753f, 0.183594f, 0.196167f, 0.209961f, 0.223511f, 0.238037f, 0.252930f, 0.268066f, 0.284180f, 0.300537f, 0.317139f,
+ 0.333740f, 0.351074f, 0.368896f, 0.386719f, 0.405273f, 0.423584f, 0.442871f, 0.460938f, 0.479736f, 0.499512f, 0.517578f, 0.537109f,
+ 0.555664f, 0.575195f, 0.594238f, 0.613770f, 0.632324f, 0.650879f, 0.669922f, 0.687988f, 0.706055f, 0.724121f, 0.873047f, 0.876953f,
+ 0.875488f, 0.874023f, 0.872559f, 0.869141f, 0.001648f, 0.005039f, 0.008675f, 0.012161f, 0.015823f, 0.019760f, 0.023865f, 0.028015f,
+ 0.032318f, 0.036865f, 0.041504f, 0.046906f, 0.051758f, 0.057922f, 0.064087f, 0.070435f, 0.077209f, 0.084290f, 0.091736f, 0.099243f,
+ 0.108215f, 0.117004f, 0.126343f, 0.135620f, 0.146484f, 0.157349f, 0.168823f, 0.180908f, 0.193848f, 0.206909f, 0.220459f, 0.234619f,
+ 0.249634f, 0.264404f, 0.280273f, 0.296631f, 0.313232f, 0.329834f, 0.347412f, 0.365479f, 0.383545f, 0.401855f, 0.420166f, 0.438721f,
+ 0.458252f, 0.477783f, 0.496826f, 0.516602f, 0.535156f, 0.554199f, 0.574219f, 0.593750f, 0.612305f, 0.631836f, 0.651367f, 0.670410f,
+ 0.689453f, 0.708984f, 0.865234f, 0.872070f, 0.870605f, 0.868652f, 0.866699f, 0.863770f, 0.001492f, 0.004704f, 0.007973f, 0.011124f,
+ 0.014603f, 0.017792f, 0.021652f, 0.025314f, 0.029526f, 0.033722f, 0.038147f, 0.042694f, 0.047668f, 0.052673f, 0.057983f, 0.064209f,
+ 0.070068f, 0.076233f, 0.083313f, 0.090942f, 0.098572f, 0.106750f, 0.115295f, 0.124512f, 0.134277f, 0.144287f, 0.154663f, 0.166504f,
+ 0.178345f, 0.190063f, 0.203247f, 0.217041f, 0.231079f, 0.245850f, 0.260986f, 0.276611f, 0.293213f, 0.309570f, 0.326172f, 0.343994f,
+ 0.361816f, 0.379395f, 0.397949f, 0.417480f, 0.436523f, 0.455322f, 0.474854f, 0.493896f, 0.514160f, 0.533691f, 0.553711f, 0.573730f,
+ 0.593262f, 0.612793f, 0.632812f, 0.651855f, 0.672363f, 0.690918f, 0.857910f, 0.865723f, 0.864746f, 0.863281f, 0.860352f, 0.858887f,
+ 0.001657f, 0.004684f, 0.007290f, 0.010201f, 0.013657f, 0.016541f, 0.019989f, 0.023636f, 0.026932f, 0.030548f, 0.034576f, 0.039154f,
+ 0.043793f, 0.048126f, 0.053162f, 0.058319f, 0.063721f, 0.069885f, 0.076355f, 0.082947f, 0.089844f, 0.097046f, 0.105286f, 0.113281f,
+ 0.122559f, 0.131348f, 0.141357f, 0.152100f, 0.163330f, 0.175415f, 0.187256f, 0.199951f, 0.213501f, 0.227051f, 0.241943f, 0.257324f,
+ 0.273193f, 0.288818f, 0.305420f, 0.322754f, 0.340576f, 0.358643f, 0.375732f, 0.394775f, 0.414307f, 0.433105f, 0.453613f, 0.472168f,
+ 0.492188f, 0.512695f, 0.532715f, 0.552246f, 0.573242f, 0.593262f, 0.613770f, 0.632812f, 0.654785f, 0.673828f, 0.851074f, 0.859375f,
+ 0.858398f, 0.856934f, 0.855469f, 0.853027f, 0.001457f, 0.003944f, 0.006870f, 0.009392f, 0.012543f, 0.015190f, 0.018417f, 0.021576f,
+ 0.024811f, 0.028122f, 0.031708f, 0.035278f, 0.039398f, 0.043793f, 0.048218f, 0.052887f, 0.058044f, 0.063477f, 0.069397f, 0.075256f,
+ 0.081360f, 0.088318f, 0.095398f, 0.103210f, 0.111084f, 0.120361f, 0.129150f, 0.139038f, 0.149292f, 0.160645f, 0.172241f, 0.183716f,
+ 0.196533f, 0.209595f, 0.224121f, 0.238647f, 0.253174f, 0.268799f, 0.286133f, 0.302490f, 0.319092f, 0.337158f, 0.355225f, 0.373535f,
+ 0.392090f, 0.411133f, 0.430908f, 0.450928f, 0.470947f, 0.490967f, 0.511719f, 0.531250f, 0.551758f, 0.573730f, 0.594238f, 0.614746f,
+ 0.636230f, 0.656738f, 0.842773f, 0.852051f, 0.851562f, 0.851074f, 0.848633f, 0.846680f, 0.001404f, 0.003891f, 0.006233f, 0.008751f,
+ 0.011353f, 0.014175f, 0.017075f, 0.019592f, 0.022842f, 0.025772f, 0.028839f, 0.032410f, 0.036011f, 0.039764f, 0.043671f, 0.048126f,
+ 0.052704f, 0.057373f, 0.062561f, 0.067688f, 0.074158f, 0.080200f, 0.086853f, 0.093445f, 0.101379f, 0.109192f, 0.117432f, 0.126709f,
+ 0.136353f, 0.146484f, 0.157227f, 0.168823f, 0.180542f, 0.193115f, 0.206299f, 0.219727f, 0.234375f, 0.249756f, 0.265869f, 0.281738f,
+ 0.298096f, 0.315674f, 0.333252f, 0.352051f, 0.370850f, 0.389160f, 0.409180f, 0.428955f, 0.448730f, 0.469971f, 0.489502f, 0.510742f,
+ 0.531738f, 0.552246f, 0.574707f, 0.595215f, 0.617676f, 0.639160f, 0.835449f, 0.845215f, 0.845215f, 0.844238f, 0.843262f, 0.840332f,
+ 0.001275f, 0.003536f, 0.005600f, 0.007881f, 0.010628f, 0.012878f, 0.015610f, 0.018097f, 0.020996f, 0.023376f, 0.026443f, 0.029556f,
+ 0.032867f, 0.036163f, 0.039581f, 0.043915f, 0.047943f, 0.052216f, 0.056763f, 0.061981f, 0.067322f, 0.072449f, 0.078796f, 0.084717f,
+ 0.091919f, 0.098999f, 0.106995f, 0.115417f, 0.124084f, 0.133667f, 0.143433f, 0.154297f, 0.165161f, 0.177124f, 0.189697f, 0.202759f,
+ 0.216309f, 0.230713f, 0.245728f, 0.261719f, 0.278320f, 0.295410f, 0.312256f, 0.330566f, 0.349365f, 0.367676f, 0.386719f, 0.406494f,
+ 0.427246f, 0.447266f, 0.468506f, 0.489746f, 0.510742f, 0.532227f, 0.553711f, 0.575684f, 0.597656f, 0.619141f, 0.826172f, 0.837402f,
+ 0.837891f, 0.837402f, 0.835449f, 0.833984f, 0.001134f, 0.003105f, 0.005337f, 0.007462f, 0.009628f, 0.011833f, 0.014137f, 0.016113f,
+ 0.018875f, 0.021484f, 0.024063f, 0.026581f, 0.029709f, 0.032623f, 0.036194f, 0.039703f, 0.043335f, 0.047058f, 0.051422f, 0.055908f,
+ 0.060608f, 0.065491f, 0.071167f, 0.076843f, 0.083313f, 0.089661f, 0.097168f, 0.104492f, 0.112122f, 0.121155f, 0.130615f, 0.140137f,
+ 0.150757f, 0.161499f, 0.173462f, 0.185547f, 0.199341f, 0.212524f, 0.227051f, 0.242310f, 0.258057f, 0.274414f, 0.291016f, 0.309082f,
+ 0.327148f, 0.345459f, 0.364990f, 0.384521f, 0.404297f, 0.425781f, 0.445801f, 0.467285f, 0.489258f, 0.510254f, 0.533203f, 0.555664f,
+ 0.578125f, 0.601074f, 0.817871f, 0.830078f, 0.831055f, 0.830078f, 0.829102f, 0.828125f, 0.001101f, 0.003019f, 0.004818f, 0.006725f,
+ 0.008781f, 0.010864f, 0.013069f, 0.014801f, 0.017151f, 0.019531f, 0.021973f, 0.024429f, 0.026917f, 0.030121f, 0.033112f, 0.036041f,
+ 0.039337f, 0.042542f, 0.046509f, 0.050537f, 0.054596f, 0.058990f, 0.064209f, 0.069519f, 0.075134f, 0.080994f, 0.087158f, 0.094177f,
+ 0.102051f, 0.109741f, 0.117981f, 0.127319f, 0.136963f, 0.147095f, 0.158081f, 0.169434f, 0.182251f, 0.195557f, 0.208984f, 0.223267f,
+ 0.238281f, 0.254639f, 0.270996f, 0.288330f, 0.305908f, 0.324219f, 0.343018f, 0.362549f, 0.382324f, 0.402832f, 0.424805f, 0.445312f,
+ 0.467529f, 0.489258f, 0.511230f, 0.535645f, 0.558594f, 0.582031f, 0.809082f, 0.822266f, 0.824219f, 0.823242f, 0.821777f, 0.820801f,
+ 0.000987f, 0.002644f, 0.004562f, 0.006344f, 0.008133f, 0.009918f, 0.011696f, 0.013527f, 0.015572f, 0.017746f, 0.019714f, 0.021942f,
+ 0.024155f, 0.027069f, 0.029678f, 0.032288f, 0.035156f, 0.038574f, 0.041779f, 0.045319f, 0.049225f, 0.053284f, 0.057678f, 0.062225f,
+ 0.067505f, 0.072571f, 0.078613f, 0.084961f, 0.092041f, 0.098938f, 0.106506f, 0.115112f, 0.123779f, 0.133667f, 0.143311f, 0.154541f,
+ 0.165894f, 0.178345f, 0.191406f, 0.205200f, 0.219238f, 0.234985f, 0.250977f, 0.267578f, 0.284912f, 0.302734f, 0.321289f, 0.340332f,
+ 0.360352f, 0.380615f, 0.401611f, 0.423340f, 0.445312f, 0.467529f, 0.490967f, 0.514160f, 0.537598f, 0.561035f, 0.800293f, 0.814453f,
+ 0.815918f, 0.815918f, 0.814941f, 0.813965f, 0.000932f, 0.002567f, 0.004009f, 0.005722f, 0.007538f, 0.008812f, 0.010864f, 0.012413f,
+ 0.014290f, 0.015991f, 0.018051f, 0.019836f, 0.022247f, 0.024506f, 0.026520f, 0.029175f, 0.031769f, 0.034332f, 0.037689f, 0.040466f,
+ 0.043945f, 0.047607f, 0.051605f, 0.055817f, 0.060486f, 0.065125f, 0.070557f, 0.076111f, 0.081909f, 0.088806f, 0.095886f, 0.103210f,
+ 0.111755f, 0.120422f, 0.130249f, 0.140137f, 0.150513f, 0.162109f, 0.174561f, 0.187256f, 0.200928f, 0.215698f, 0.231323f, 0.246582f,
+ 0.264160f, 0.281982f, 0.299561f, 0.319092f, 0.338623f, 0.358643f, 0.379883f, 0.400879f, 0.423096f, 0.445557f, 0.468750f, 0.492188f,
+ 0.516113f, 0.541504f, 0.791016f, 0.805664f, 0.808105f, 0.808594f, 0.807129f, 0.806641f, 0.000871f, 0.002337f, 0.003727f, 0.005474f,
+ 0.006641f, 0.008377f, 0.009567f, 0.011154f, 0.012848f, 0.014610f, 0.016235f, 0.017960f, 0.019958f, 0.021729f, 0.023926f, 0.026154f,
+ 0.028351f, 0.030975f, 0.033722f, 0.036407f, 0.039459f, 0.042694f, 0.046082f, 0.049896f, 0.053833f, 0.058167f, 0.062744f, 0.067932f,
+ 0.073608f, 0.079468f, 0.085632f, 0.092651f, 0.100098f, 0.108521f, 0.116699f, 0.126099f, 0.136108f, 0.146606f, 0.157959f, 0.170410f,
+ 0.183594f, 0.197510f, 0.212280f, 0.227295f, 0.243652f, 0.260986f, 0.278564f, 0.297607f, 0.316406f, 0.336426f, 0.357178f, 0.378662f,
+ 0.400146f, 0.422852f, 0.446045f, 0.470215f, 0.494873f, 0.520020f, 0.781250f, 0.796875f, 0.800293f, 0.800781f, 0.799805f, 0.799316f,
+ 0.000782f, 0.002131f, 0.003649f, 0.004715f, 0.006054f, 0.007458f, 0.008759f, 0.010269f, 0.011711f, 0.012970f, 0.014664f, 0.016327f,
+ 0.017914f, 0.019699f, 0.021423f, 0.023499f, 0.025391f, 0.027374f, 0.029999f, 0.032501f, 0.035156f, 0.037872f, 0.040710f, 0.044403f,
+ 0.047791f, 0.051880f, 0.055969f, 0.060364f, 0.065247f, 0.070496f, 0.076172f, 0.082825f, 0.089294f, 0.096497f, 0.104431f, 0.112854f,
+ 0.122375f, 0.132202f, 0.142700f, 0.153931f, 0.166260f, 0.179565f, 0.193481f, 0.208008f, 0.223877f, 0.240479f, 0.257568f, 0.275879f,
+ 0.294922f, 0.314453f, 0.334961f, 0.355957f, 0.377686f, 0.400391f, 0.423828f, 0.448730f, 0.472900f, 0.498535f, 0.771484f, 0.789062f,
+ 0.791504f, 0.792480f, 0.791016f, 0.791016f, 0.000742f, 0.001822f, 0.003183f, 0.004444f, 0.005600f, 0.006550f, 0.008087f, 0.009247f,
+ 0.010559f, 0.011650f, 0.013184f, 0.014565f, 0.016083f, 0.017548f, 0.019119f, 0.020737f, 0.022644f, 0.024597f, 0.026627f, 0.028809f,
+ 0.031281f, 0.033539f, 0.036469f, 0.039429f, 0.042480f, 0.045654f, 0.049561f, 0.053406f, 0.057739f, 0.062469f, 0.067749f, 0.073364f,
+ 0.079773f, 0.086121f, 0.093262f, 0.100647f, 0.109253f, 0.118042f, 0.128174f, 0.138550f, 0.150024f, 0.162231f, 0.175171f, 0.189087f,
+ 0.204468f, 0.220215f, 0.236938f, 0.254639f, 0.273438f, 0.292236f, 0.312012f, 0.333252f, 0.355957f, 0.377686f, 0.401367f, 0.425781f,
+ 0.451416f, 0.476318f, 0.761230f, 0.779785f, 0.782227f, 0.782715f, 0.782715f, 0.782715f, 0.000632f, 0.001970f, 0.003042f, 0.004025f,
+ 0.005173f, 0.006435f, 0.007343f, 0.008522f, 0.009369f, 0.010475f, 0.011726f, 0.012962f, 0.014145f, 0.015411f, 0.016922f, 0.018478f,
+ 0.020111f, 0.021835f, 0.023682f, 0.025253f, 0.027466f, 0.029678f, 0.032196f, 0.034607f, 0.037415f, 0.040497f, 0.043610f, 0.047089f,
+ 0.051178f, 0.055573f, 0.059845f, 0.064758f, 0.070068f, 0.076111f, 0.082275f, 0.089417f, 0.096863f, 0.105286f, 0.114441f, 0.123535f,
+ 0.134399f, 0.145508f, 0.157959f, 0.171387f, 0.185425f, 0.200806f, 0.216919f, 0.233521f, 0.251953f, 0.270508f, 0.290527f, 0.310791f,
+ 0.332275f, 0.355469f, 0.378418f, 0.403564f, 0.428223f, 0.455322f, 0.750977f, 0.770996f, 0.774414f, 0.774414f, 0.774902f, 0.773926f,
+ 0.000517f, 0.001554f, 0.002741f, 0.003695f, 0.004669f, 0.005417f, 0.006466f, 0.007545f, 0.008453f, 0.009499f, 0.010468f, 0.011490f,
+ 0.012718f, 0.013985f, 0.014977f, 0.016235f, 0.017868f, 0.019211f, 0.020630f, 0.022263f, 0.024078f, 0.026291f, 0.028275f, 0.030380f,
+ 0.032928f, 0.035675f, 0.038513f, 0.041656f, 0.044769f, 0.048523f, 0.052216f, 0.057007f, 0.061493f, 0.066711f, 0.072510f, 0.078735f,
+ 0.085327f, 0.093201f, 0.101135f, 0.109619f, 0.119690f, 0.130371f, 0.141602f, 0.154053f, 0.167480f, 0.181396f, 0.197021f, 0.213623f,
+ 0.230835f, 0.248901f, 0.268066f, 0.289062f, 0.310303f, 0.332520f, 0.355225f, 0.379639f, 0.405273f, 0.432373f, 0.740234f, 0.760742f,
+ 0.763672f, 0.765625f, 0.765625f, 0.765625f, 0.000588f, 0.001405f, 0.002306f, 0.003370f, 0.004375f, 0.005116f, 0.005817f, 0.006630f,
+ 0.007797f, 0.008507f, 0.009216f, 0.010254f, 0.011246f, 0.012154f, 0.013191f, 0.014366f, 0.015503f, 0.016785f, 0.018127f, 0.019562f,
+ 0.021072f, 0.022919f, 0.024643f, 0.026749f, 0.028564f, 0.031006f, 0.033203f, 0.036072f, 0.039032f, 0.042114f, 0.045654f, 0.049561f,
+ 0.053650f, 0.058380f, 0.063049f, 0.068848f, 0.075256f, 0.081543f, 0.088562f, 0.096924f, 0.105652f, 0.115173f, 0.125977f, 0.137207f,
+ 0.149902f, 0.163208f, 0.177979f, 0.193726f, 0.210205f, 0.228027f, 0.247070f, 0.266602f, 0.287842f, 0.309326f, 0.333008f, 0.356934f,
+ 0.382568f, 0.408691f, 0.729004f, 0.751953f, 0.755371f, 0.756348f, 0.757324f, 0.756348f, 0.000431f, 0.001562f, 0.002253f, 0.003088f,
+ 0.003944f, 0.004536f, 0.005066f, 0.006020f, 0.006840f, 0.007542f, 0.008347f, 0.008949f, 0.009827f, 0.010719f, 0.011696f, 0.012756f,
+ 0.013649f, 0.014679f, 0.015808f, 0.017288f, 0.018356f, 0.019913f, 0.021332f, 0.023148f, 0.024719f, 0.026840f, 0.029007f, 0.031250f,
+ 0.033661f, 0.036469f, 0.039490f, 0.042969f, 0.046326f, 0.050293f, 0.054901f, 0.059845f, 0.064941f, 0.071289f, 0.077454f, 0.084656f,
+ 0.092529f, 0.101562f, 0.111145f, 0.121460f, 0.132935f, 0.145386f, 0.159302f, 0.174438f, 0.190186f, 0.206909f, 0.225098f, 0.244751f,
+ 0.265381f, 0.287109f, 0.310059f, 0.333984f, 0.359131f, 0.386230f, 0.716797f, 0.740723f, 0.744629f, 0.746582f, 0.747070f, 0.747070f,
+ 0.000576f, 0.001266f, 0.002028f, 0.002766f, 0.003317f, 0.004051f, 0.004742f, 0.005459f, 0.006054f, 0.006641f, 0.007240f, 0.007919f,
+ 0.008644f, 0.009300f, 0.010170f, 0.010925f, 0.011795f, 0.012733f, 0.013855f, 0.014885f, 0.015900f, 0.017212f, 0.018326f, 0.019684f,
+ 0.021469f, 0.023178f, 0.024734f, 0.026794f, 0.028946f, 0.031204f, 0.033844f, 0.036682f, 0.039948f, 0.043335f, 0.047150f, 0.051422f,
+ 0.055969f, 0.061066f, 0.067139f, 0.073242f, 0.080444f, 0.088440f, 0.096985f, 0.106445f, 0.116943f, 0.128906f, 0.141479f, 0.154907f,
+ 0.170410f, 0.186523f, 0.204102f, 0.222900f, 0.243774f, 0.264160f, 0.286865f, 0.310791f, 0.336182f, 0.362793f, 0.705078f, 0.730469f,
+ 0.735352f, 0.736816f, 0.737793f, 0.736816f, 0.000307f, 0.001126f, 0.001758f, 0.002436f, 0.002911f, 0.003540f, 0.004047f, 0.004711f,
+ 0.005245f, 0.005749f, 0.006302f, 0.006844f, 0.007355f, 0.008095f, 0.008835f, 0.009438f, 0.010139f, 0.010941f, 0.011963f, 0.012878f,
+ 0.013519f, 0.014847f, 0.015945f, 0.017029f, 0.018250f, 0.019669f, 0.021362f, 0.022675f, 0.024750f, 0.026657f, 0.028854f, 0.031219f,
+ 0.033844f, 0.036804f, 0.040222f, 0.043793f, 0.047791f, 0.052185f, 0.057251f, 0.062866f, 0.069275f, 0.075867f, 0.083923f, 0.092407f,
+ 0.102295f, 0.112366f, 0.124207f, 0.137085f, 0.151489f, 0.167114f, 0.183838f, 0.202148f, 0.221558f, 0.242065f, 0.263916f, 0.287842f,
+ 0.312256f, 0.339111f, 0.693848f, 0.719727f, 0.724609f, 0.726074f, 0.727539f, 0.727051f, 0.000428f, 0.000939f, 0.001581f, 0.002033f,
+ 0.002665f, 0.003222f, 0.003660f, 0.004059f, 0.004475f, 0.004997f, 0.005554f, 0.006031f, 0.006371f, 0.007080f, 0.007511f, 0.008263f,
+ 0.008820f, 0.009552f, 0.010124f, 0.010948f, 0.011665f, 0.012550f, 0.013397f, 0.014526f, 0.015388f, 0.016754f, 0.017960f, 0.019257f,
+ 0.020844f, 0.022583f, 0.024246f, 0.026642f, 0.028656f, 0.031128f, 0.033783f, 0.036865f, 0.040253f, 0.044312f, 0.048523f, 0.053314f,
+ 0.058655f, 0.064880f, 0.071594f, 0.079102f, 0.087891f, 0.097107f, 0.108276f, 0.119751f, 0.133179f, 0.148071f, 0.163818f, 0.180908f,
+ 0.199951f, 0.219849f, 0.241699f, 0.264160f, 0.288818f, 0.315918f, 0.680176f, 0.708496f, 0.713867f, 0.716309f, 0.716797f, 0.717285f,
+ 0.000467f, 0.001054f, 0.001476f, 0.001825f, 0.002386f, 0.002644f, 0.003218f, 0.003553f, 0.003866f, 0.004433f, 0.004700f, 0.004948f,
+ 0.005505f, 0.006023f, 0.006405f, 0.006920f, 0.007484f, 0.008057f, 0.008598f, 0.009178f, 0.009857f, 0.010551f, 0.011169f, 0.012199f,
+ 0.013092f, 0.014084f, 0.015091f, 0.016205f, 0.017303f, 0.018845f, 0.020538f, 0.021957f, 0.023773f, 0.025833f, 0.028152f, 0.030716f,
+ 0.033661f, 0.036896f, 0.040405f, 0.044708f, 0.049286f, 0.054321f, 0.060333f, 0.067322f, 0.074890f, 0.083435f, 0.092651f, 0.103516f,
+ 0.115784f, 0.129028f, 0.144287f, 0.160278f, 0.178345f, 0.197632f, 0.218994f, 0.241089f, 0.265869f, 0.292725f, 0.667969f, 0.697266f,
+ 0.702637f, 0.704590f, 0.706055f, 0.707031f, 0.000348f, 0.000841f, 0.001292f, 0.001580f, 0.001961f, 0.002508f, 0.002630f, 0.002993f,
+ 0.003458f, 0.003738f, 0.003952f, 0.004425f, 0.004639f, 0.005070f, 0.005547f, 0.005840f, 0.006462f, 0.006844f, 0.007214f, 0.007698f,
+ 0.008339f, 0.008980f, 0.009560f, 0.010094f, 0.010941f, 0.011711f, 0.012550f, 0.013565f, 0.014404f, 0.015579f, 0.016754f, 0.018082f,
+ 0.019592f, 0.021439f, 0.023209f, 0.025375f, 0.027863f, 0.030411f, 0.033478f, 0.037018f, 0.040680f, 0.045105f, 0.050476f, 0.056183f,
+ 0.062805f, 0.070251f, 0.078613f, 0.088196f, 0.099060f, 0.111450f, 0.125122f, 0.140869f, 0.158203f, 0.176880f, 0.197266f, 0.218506f,
+ 0.242798f, 0.268555f, 0.655273f, 0.686035f, 0.691406f, 0.694336f, 0.695312f, 0.695801f, 0.000170f, 0.000976f, 0.001161f, 0.001441f,
+ 0.001846f, 0.002144f, 0.002367f, 0.002632f, 0.002892f, 0.003178f, 0.003435f, 0.003618f, 0.004021f, 0.004292f, 0.004562f, 0.005028f,
+ 0.005405f, 0.005623f, 0.006069f, 0.006577f, 0.006973f, 0.007431f, 0.007904f, 0.008484f, 0.009018f, 0.009659f, 0.010559f, 0.010994f,
+ 0.012009f, 0.012840f, 0.013901f, 0.014915f, 0.016129f, 0.017502f, 0.019089f, 0.020676f, 0.022568f, 0.024673f, 0.027252f, 0.029984f,
+ 0.033234f, 0.037079f, 0.041016f, 0.045868f, 0.051758f, 0.058014f, 0.065613f, 0.073853f, 0.083801f, 0.094727f, 0.107483f, 0.121826f,
+ 0.137573f, 0.156006f, 0.175049f, 0.196167f, 0.219482f, 0.245850f, 0.641113f, 0.673340f, 0.679688f, 0.681641f, 0.683594f, 0.684082f,
+ 0.000293f, 0.000601f, 0.001049f, 0.001358f, 0.001532f, 0.001719f, 0.001882f, 0.002298f, 0.002317f, 0.002628f, 0.002750f, 0.003143f,
+ 0.003363f, 0.003559f, 0.003866f, 0.004204f, 0.004383f, 0.004753f, 0.005028f, 0.005348f, 0.005863f, 0.006176f, 0.006569f, 0.006954f,
+ 0.007401f, 0.008057f, 0.008537f, 0.009178f, 0.009735f, 0.010521f, 0.011208f, 0.011978f, 0.013130f, 0.014099f, 0.015289f, 0.016739f,
+ 0.018219f, 0.019821f, 0.021713f, 0.024200f, 0.026749f, 0.029785f, 0.033386f, 0.036987f, 0.041840f, 0.047089f, 0.053253f, 0.060760f,
+ 0.069214f, 0.079224f, 0.090515f, 0.103638f, 0.118652f, 0.135376f, 0.154175f, 0.174561f, 0.196777f, 0.222534f, 0.628906f, 0.660645f,
+ 0.668457f, 0.670410f, 0.672852f, 0.673340f, 0.000258f, 0.000656f, 0.000811f, 0.001049f, 0.001288f, 0.001462f, 0.001599f, 0.001740f,
+ 0.002012f, 0.002171f, 0.002367f, 0.002535f, 0.002705f, 0.002880f, 0.003115f, 0.003429f, 0.003666f, 0.003897f, 0.004116f, 0.004398f,
+ 0.004635f, 0.005066f, 0.005341f, 0.005779f, 0.006042f, 0.006454f, 0.006954f, 0.007450f, 0.007835f, 0.008400f, 0.009132f, 0.009819f,
+ 0.010536f, 0.011307f, 0.012245f, 0.013229f, 0.014580f, 0.015900f, 0.017303f, 0.019119f, 0.021103f, 0.023468f, 0.026123f, 0.029495f,
+ 0.033112f, 0.037628f, 0.042938f, 0.048859f, 0.056152f, 0.064941f, 0.074829f, 0.086548f, 0.100281f, 0.115967f, 0.133545f, 0.153198f,
+ 0.175171f, 0.199341f, 0.613770f, 0.648926f, 0.655273f, 0.658691f, 0.660645f, 0.662598f, 0.000176f, 0.000474f, 0.000602f, 0.000854f,
+ 0.001030f, 0.001240f, 0.001349f, 0.001505f, 0.001580f, 0.001738f, 0.001957f, 0.002068f, 0.002230f, 0.002420f, 0.002556f, 0.002705f,
+ 0.002998f, 0.003178f, 0.003345f, 0.003567f, 0.003811f, 0.004105f, 0.004284f, 0.004593f, 0.004848f, 0.005173f, 0.005527f, 0.005939f,
+ 0.006306f, 0.006817f, 0.007366f, 0.007729f, 0.008339f, 0.008995f, 0.009644f, 0.010551f, 0.011360f, 0.012344f, 0.013710f, 0.015030f,
+ 0.016510f, 0.018143f, 0.020279f, 0.022751f, 0.025650f, 0.029144f, 0.033508f, 0.038452f, 0.044556f, 0.052032f, 0.060364f, 0.070923f,
+ 0.082642f, 0.097290f, 0.113525f, 0.132446f, 0.153442f, 0.176880f, 0.600586f, 0.636719f, 0.644531f, 0.647461f, 0.648926f, 0.649414f,
+ 0.000121f, 0.000426f, 0.000509f, 0.000778f, 0.000931f, 0.000992f, 0.001135f, 0.001303f, 0.001359f, 0.001410f, 0.001519f, 0.001722f,
+ 0.001751f, 0.001951f, 0.002060f, 0.002218f, 0.002287f, 0.002487f, 0.002670f, 0.002848f, 0.003061f, 0.003233f, 0.003452f, 0.003664f,
+ 0.003883f, 0.004078f, 0.004379f, 0.004692f, 0.004982f, 0.005329f, 0.005756f, 0.006081f, 0.006504f, 0.007019f, 0.007599f, 0.008217f,
+ 0.008850f, 0.009628f, 0.010437f, 0.011597f, 0.012650f, 0.013931f, 0.015480f, 0.017380f, 0.019577f, 0.022247f, 0.025513f, 0.029617f,
+ 0.034363f, 0.040314f, 0.047241f, 0.056274f, 0.066711f, 0.079773f, 0.094482f, 0.112488f, 0.132446f, 0.154907f, 0.585449f, 0.624023f,
+ 0.630371f, 0.634277f, 0.636230f, 0.637207f, 0.000161f, 0.000263f, 0.000526f, 0.000627f, 0.000723f, 0.000775f, 0.000856f, 0.000960f,
+ 0.001079f, 0.001158f, 0.001208f, 0.001272f, 0.001441f, 0.001557f, 0.001657f, 0.001702f, 0.001897f, 0.001918f, 0.002151f, 0.002232f,
+ 0.002337f, 0.002522f, 0.002720f, 0.002865f, 0.003029f, 0.003193f, 0.003387f, 0.003601f, 0.003887f, 0.004124f, 0.004356f, 0.004639f,
+ 0.005070f, 0.005466f, 0.005863f, 0.006298f, 0.006874f, 0.007290f, 0.007965f, 0.008774f, 0.009560f, 0.010666f, 0.011719f, 0.013077f,
+ 0.014679f, 0.016693f, 0.019058f, 0.021881f, 0.025528f, 0.030121f, 0.036011f, 0.043396f, 0.052460f, 0.063477f, 0.076721f, 0.093079f,
+ 0.112305f, 0.133667f, 0.572266f, 0.609375f, 0.618164f, 0.622070f, 0.623535f, 0.625488f, 0.000109f, 0.000212f, 0.000404f, 0.000578f,
+ 0.000567f, 0.000655f, 0.000763f, 0.000676f, 0.000824f, 0.000869f, 0.000971f, 0.001064f, 0.001132f, 0.001210f, 0.001212f, 0.001398f,
+ 0.001486f, 0.001525f, 0.001653f, 0.001676f, 0.001867f, 0.001953f, 0.002062f, 0.002199f, 0.002295f, 0.002443f, 0.002586f, 0.002766f,
+ 0.002979f, 0.003128f, 0.003429f, 0.003551f, 0.003763f, 0.004074f, 0.004349f, 0.004688f, 0.005032f, 0.005470f, 0.005894f, 0.006519f,
+ 0.007092f, 0.007896f, 0.008629f, 0.009659f, 0.010910f, 0.012215f, 0.013962f, 0.015991f, 0.018646f, 0.021881f, 0.026428f, 0.032074f,
+ 0.039276f, 0.048645f, 0.060455f, 0.075256f, 0.092773f, 0.113220f, 0.554688f, 0.596191f, 0.605957f, 0.608887f, 0.610352f, 0.612305f,
+ 0.000202f, 0.000186f, 0.000312f, 0.000433f, 0.000382f, 0.000543f, 0.000482f, 0.000546f, 0.000621f, 0.000666f, 0.000789f, 0.000802f,
+ 0.000859f, 0.000950f, 0.000970f, 0.000975f, 0.001113f, 0.001162f, 0.001207f, 0.001312f, 0.001362f, 0.001433f, 0.001541f, 0.001618f,
+ 0.001720f, 0.001791f, 0.001966f, 0.002035f, 0.002199f, 0.002413f, 0.002546f, 0.002626f, 0.002855f, 0.003063f, 0.003204f, 0.003448f,
+ 0.003693f, 0.003986f, 0.004364f, 0.004684f, 0.005127f, 0.005619f, 0.006271f, 0.006870f, 0.007748f, 0.008713f, 0.009911f, 0.011368f,
+ 0.013191f, 0.015518f, 0.018646f, 0.022644f, 0.028107f, 0.035645f, 0.045471f, 0.058502f, 0.074646f, 0.093994f, 0.541016f, 0.583008f,
+ 0.591797f, 0.596191f, 0.599121f, 0.600098f, 0.000000f, 0.000179f, 0.000242f, 0.000318f, 0.000341f, 0.000345f, 0.000432f, 0.000364f,
+ 0.000475f, 0.000483f, 0.000572f, 0.000576f, 0.000619f, 0.000640f, 0.000716f, 0.000737f, 0.000791f, 0.000845f, 0.000871f, 0.000907f,
+ 0.000998f, 0.001025f, 0.001107f, 0.001181f, 0.001244f, 0.001303f, 0.001391f, 0.001462f, 0.001549f, 0.001631f, 0.001756f, 0.001906f,
+ 0.001984f, 0.002161f, 0.002264f, 0.002419f, 0.002613f, 0.002825f, 0.003103f, 0.003321f, 0.003584f, 0.003893f, 0.004349f, 0.004799f,
+ 0.005383f, 0.006020f, 0.006836f, 0.007858f, 0.009117f, 0.010674f, 0.012825f, 0.015533f, 0.019363f, 0.024780f, 0.032593f, 0.043274f,
+ 0.057770f, 0.076111f, 0.525879f, 0.569336f, 0.578613f, 0.583008f, 0.585449f, 0.586426f, 0.000000f, 0.000088f, 0.000192f, 0.000227f,
+ 0.000230f, 0.000286f, 0.000255f, 0.000317f, 0.000321f, 0.000371f, 0.000401f, 0.000373f, 0.000391f, 0.000457f, 0.000474f, 0.000530f,
+ 0.000509f, 0.000585f, 0.000625f, 0.000664f, 0.000707f, 0.000746f, 0.000772f, 0.000817f, 0.000877f, 0.000887f, 0.000978f, 0.001007f,
+ 0.001069f, 0.001202f, 0.001192f, 0.001290f, 0.001356f, 0.001464f, 0.001583f, 0.001678f, 0.001771f, 0.001929f, 0.002050f, 0.002230f,
+ 0.002424f, 0.002651f, 0.002888f, 0.003176f, 0.003534f, 0.003967f, 0.004475f, 0.005154f, 0.005993f, 0.007118f, 0.008469f, 0.010338f,
+ 0.012794f, 0.016403f, 0.021957f, 0.030090f, 0.042419f, 0.059052f, 0.510254f, 0.554199f, 0.564453f, 0.570312f, 0.572754f, 0.573242f,
+ 0.000000f, 0.000126f, 0.000180f, 0.000121f, 0.000178f, 0.000176f, 0.000177f, 0.000212f, 0.000210f, 0.000228f, 0.000238f, 0.000291f,
+ 0.000280f, 0.000298f, 0.000336f, 0.000350f, 0.000369f, 0.000387f, 0.000395f, 0.000427f, 0.000460f, 0.000476f, 0.000515f, 0.000536f,
+ 0.000573f, 0.000619f, 0.000650f, 0.000670f, 0.000703f, 0.000746f, 0.000798f, 0.000836f, 0.000902f, 0.000949f, 0.001031f, 0.001062f,
+ 0.001162f, 0.001227f, 0.001349f, 0.001442f, 0.001533f, 0.001690f, 0.001865f, 0.001995f, 0.002228f, 0.002495f, 0.002800f, 0.003191f,
+ 0.003653f, 0.004349f, 0.005203f, 0.006393f, 0.008026f, 0.010307f, 0.013710f, 0.019379f, 0.028854f, 0.043457f, 0.494873f, 0.541016f,
+ 0.550781f, 0.555664f, 0.558105f, 0.559570f, 0.000000f, 0.000095f, 0.000086f, 0.000079f, 0.000105f, 0.000124f, 0.000111f, 0.000137f,
+ 0.000141f, 0.000142f, 0.000147f, 0.000151f, 0.000160f, 0.000181f, 0.000202f, 0.000207f, 0.000214f, 0.000248f, 0.000244f, 0.000282f,
+ 0.000273f, 0.000283f, 0.000306f, 0.000334f, 0.000367f, 0.000378f, 0.000376f, 0.000399f, 0.000437f, 0.000459f, 0.000474f, 0.000516f,
+ 0.000552f, 0.000567f, 0.000616f, 0.000649f, 0.000693f, 0.000743f, 0.000805f, 0.000851f, 0.000918f, 0.000999f, 0.001085f, 0.001195f,
+ 0.001309f, 0.001466f, 0.001644f, 0.001850f, 0.002151f, 0.002487f, 0.002974f, 0.003654f, 0.004574f, 0.006001f, 0.008156f, 0.011452f,
+ 0.017853f, 0.029739f, 0.478271f, 0.526367f, 0.537109f, 0.541504f, 0.544434f, 0.545898f, 0.000106f, 0.000085f, 0.000074f, 0.000067f,
+ 0.000066f, 0.000070f, 0.000069f, 0.000073f, 0.000073f, 0.000080f, 0.000084f, 0.000109f, 0.000093f, 0.000098f, 0.000119f, 0.000108f,
+ 0.000128f, 0.000135f, 0.000137f, 0.000149f, 0.000150f, 0.000157f, 0.000182f, 0.000185f, 0.000207f, 0.000206f, 0.000214f, 0.000234f,
+ 0.000237f, 0.000253f, 0.000267f, 0.000289f, 0.000306f, 0.000313f, 0.000344f, 0.000352f, 0.000384f, 0.000406f, 0.000445f, 0.000467f,
+ 0.000503f, 0.000543f, 0.000593f, 0.000634f, 0.000697f, 0.000764f, 0.000850f, 0.000963f, 0.001105f, 0.001298f, 0.001536f, 0.001856f,
+ 0.002333f, 0.003069f, 0.004299f, 0.006271f, 0.009789f, 0.018234f, 0.462402f, 0.511719f, 0.522949f, 0.527344f, 0.530762f, 0.532715f,
+ 0.000091f, 0.000069f, 0.000060f, 0.000054f, 0.000049f, 0.000046f, 0.000043f, 0.000041f, 0.000040f, 0.000044f, 0.000040f, 0.000040f,
+ 0.000054f, 0.000044f, 0.000045f, 0.000044f, 0.000062f, 0.000062f, 0.000069f, 0.000071f, 0.000074f, 0.000079f, 0.000081f, 0.000081f,
+ 0.000085f, 0.000099f, 0.000098f, 0.000115f, 0.000115f, 0.000119f, 0.000125f, 0.000130f, 0.000140f, 0.000144f, 0.000165f, 0.000172f,
+ 0.000178f, 0.000191f, 0.000205f, 0.000222f, 0.000234f, 0.000251f, 0.000276f, 0.000293f, 0.000327f, 0.000354f, 0.000392f, 0.000437f,
+ 0.000494f, 0.000562f, 0.000662f, 0.000800f, 0.001005f, 0.001315f, 0.001852f, 0.002825f, 0.004723f, 0.009285f, 0.446533f, 0.497803f,
+ 0.508301f, 0.514160f, 0.516602f, 0.519043f, 0.000067f, 0.000048f, 0.000040f, 0.000036f, 0.000033f, 0.000031f, 0.000030f, 0.000028f,
+ 0.000027f, 0.000026f, 0.000025f, 0.000024f, 0.000023f, 0.000022f, 0.000021f, 0.000020f, 0.000019f, 0.000020f, 0.000024f, 0.000026f,
+ 0.000025f, 0.000027f, 0.000031f, 0.000032f, 0.000032f, 0.000037f, 0.000041f, 0.000038f, 0.000045f, 0.000042f, 0.000048f, 0.000049f,
+ 0.000053f, 0.000055f, 0.000059f, 0.000062f, 0.000071f, 0.000074f, 0.000077f, 0.000081f, 0.000086f, 0.000091f, 0.000098f, 0.000109f,
+ 0.000116f, 0.000125f, 0.000137f, 0.000158f, 0.000173f, 0.000193f, 0.000230f, 0.000273f, 0.000335f, 0.000425f, 0.000603f, 0.000935f,
+ 0.001694f, 0.003727f, 0.431396f, 0.481934f, 0.493652f, 0.499512f, 0.502930f, 0.504883f, 0.000021f, 0.000016f, 0.000013f, 0.000012f,
+ 0.000013f, 0.000012f, 0.000012f, 0.000012f, 0.000012f, 0.000012f, 0.000011f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000011f,
+ 0.000011f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000009f, 0.000008f, 0.000008f, 0.000008f, 0.000007f,
+ 0.000008f, 0.000009f, 0.000009f, 0.000010f, 0.000010f, 0.000013f, 0.000014f, 0.000013f, 0.000015f, 0.000016f, 0.000017f, 0.000019f,
+ 0.000019f, 0.000020f, 0.000023f, 0.000026f, 0.000027f, 0.000027f, 0.000032f, 0.000030f, 0.000036f, 0.000039f, 0.000050f, 0.000056f,
+ 0.000063f, 0.000082f, 0.000109f, 0.000168f, 0.000317f, 0.000922f, 0.415283f, 0.467773f, 0.479980f, 0.486328f, 0.489014f, 0.490723f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000005f, 0.000008f, 0.000026f, 0.398926f, 0.452881f,
+ 0.465576f, 0.471436f, 0.474854f, 0.477051f,
+ },
+ {
+ 0.019653f, 0.058990f, 0.097473f, 0.134277f, 0.169189f, 0.203491f, 0.236450f, 0.267578f, 0.297852f, 0.326416f, 0.354004f, 0.380859f,
+ 0.406250f, 0.431641f, 0.455078f, 0.477539f, 0.500000f, 0.520996f, 0.541504f, 0.560547f, 0.580566f, 0.598633f, 0.615723f, 0.633301f,
+ 0.649902f, 0.666016f, 0.681641f, 0.695801f, 0.709961f, 0.724609f, 0.738770f, 0.751953f, 0.765137f, 0.775879f, 0.788574f, 0.799805f,
+ 0.812012f, 0.822754f, 0.833496f, 0.844238f, 0.854004f, 0.864258f, 0.874023f, 0.883301f, 0.891602f, 0.900391f, 0.909668f, 0.917969f,
+ 0.925781f, 0.934570f, 0.941895f, 0.949707f, 0.956543f, 0.963379f, 0.970703f, 0.977539f, 0.984863f, 0.991211f, 0.988770f, 0.972656f,
+ 0.960449f, 0.949707f, 0.940430f, 0.931641f, 0.017303f, 0.052399f, 0.086548f, 0.119446f, 0.153076f, 0.183594f, 0.214722f, 0.245117f,
+ 0.273193f, 0.301270f, 0.328613f, 0.354492f, 0.379883f, 0.404541f, 0.427979f, 0.450195f, 0.472656f, 0.494629f, 0.515137f, 0.534668f,
+ 0.554199f, 0.573242f, 0.591309f, 0.608887f, 0.625977f, 0.642578f, 0.658203f, 0.672852f, 0.688477f, 0.704102f, 0.717285f, 0.731445f,
+ 0.744629f, 0.756836f, 0.769531f, 0.782715f, 0.793945f, 0.805664f, 0.816406f, 0.828125f, 0.838379f, 0.849121f, 0.858887f, 0.868652f,
+ 0.877930f, 0.888184f, 0.896973f, 0.905762f, 0.915039f, 0.921875f, 0.930176f, 0.937988f, 0.946777f, 0.954102f, 0.960938f, 0.968750f,
+ 0.975586f, 0.982422f, 0.984375f, 0.969238f, 0.957520f, 0.947754f, 0.938477f, 0.930176f, 0.015221f, 0.045837f, 0.076843f, 0.107666f,
+ 0.136719f, 0.166504f, 0.196045f, 0.223999f, 0.250244f, 0.278320f, 0.303711f, 0.329346f, 0.353271f, 0.378906f, 0.401367f, 0.424316f,
+ 0.447266f, 0.468018f, 0.487793f, 0.508301f, 0.529297f, 0.547363f, 0.566406f, 0.583984f, 0.601562f, 0.618652f, 0.634766f, 0.650879f,
+ 0.666016f, 0.681641f, 0.695801f, 0.710449f, 0.724121f, 0.737305f, 0.750488f, 0.762695f, 0.775391f, 0.788086f, 0.799316f, 0.811035f,
+ 0.821777f, 0.833008f, 0.844238f, 0.854004f, 0.864258f, 0.874023f, 0.882812f, 0.892578f, 0.901367f, 0.910156f, 0.918457f, 0.926758f,
+ 0.936035f, 0.942871f, 0.950684f, 0.958496f, 0.965820f, 0.973145f, 0.980469f, 0.965820f, 0.955078f, 0.945312f, 0.936523f, 0.928223f,
+ 0.013420f, 0.041138f, 0.068359f, 0.096436f, 0.124023f, 0.150879f, 0.177246f, 0.204224f, 0.230103f, 0.255859f, 0.281494f, 0.305420f,
+ 0.329834f, 0.352783f, 0.376709f, 0.398682f, 0.420654f, 0.442627f, 0.462646f, 0.483887f, 0.502441f, 0.521484f, 0.540527f, 0.559082f,
+ 0.576172f, 0.595703f, 0.611328f, 0.627930f, 0.644043f, 0.659668f, 0.674316f, 0.688965f, 0.703613f, 0.717285f, 0.730957f, 0.744629f,
+ 0.756836f, 0.770020f, 0.781738f, 0.793945f, 0.805176f, 0.816895f, 0.828125f, 0.838379f, 0.849121f, 0.859375f, 0.869141f, 0.878418f,
+ 0.888184f, 0.897461f, 0.906738f, 0.915039f, 0.923828f, 0.932129f, 0.940430f, 0.947754f, 0.956543f, 0.963867f, 0.976074f, 0.962402f,
+ 0.951660f, 0.942383f, 0.934082f, 0.926758f, 0.012001f, 0.036591f, 0.061737f, 0.086670f, 0.112000f, 0.136719f, 0.161743f, 0.186768f,
+ 0.211792f, 0.235840f, 0.259521f, 0.283203f, 0.307129f, 0.329590f, 0.352295f, 0.374268f, 0.395996f, 0.416992f, 0.437744f, 0.457520f,
+ 0.477295f, 0.497314f, 0.515625f, 0.534180f, 0.553223f, 0.570312f, 0.588379f, 0.604492f, 0.621582f, 0.636719f, 0.653320f, 0.666992f,
+ 0.683105f, 0.697266f, 0.710449f, 0.724609f, 0.737793f, 0.750977f, 0.764160f, 0.775879f, 0.788086f, 0.799805f, 0.812012f, 0.823242f,
+ 0.833496f, 0.844238f, 0.854492f, 0.864746f, 0.875000f, 0.884277f, 0.894043f, 0.902832f, 0.911621f, 0.920898f, 0.929688f, 0.937500f,
+ 0.945801f, 0.953613f, 0.971191f, 0.958984f, 0.949219f, 0.939941f, 0.932129f, 0.924316f, 0.010612f, 0.032684f, 0.054810f, 0.077759f,
+ 0.100952f, 0.124023f, 0.146851f, 0.171021f, 0.193604f, 0.217163f, 0.239380f, 0.261963f, 0.284424f, 0.307129f, 0.328613f, 0.351318f,
+ 0.371826f, 0.392334f, 0.413574f, 0.432617f, 0.453613f, 0.472656f, 0.491943f, 0.510254f, 0.528320f, 0.546387f, 0.563965f, 0.580078f,
+ 0.598633f, 0.613770f, 0.629883f, 0.645996f, 0.661621f, 0.675293f, 0.688965f, 0.705078f, 0.718262f, 0.731934f, 0.745605f, 0.757812f,
+ 0.770996f, 0.782715f, 0.795410f, 0.807129f, 0.818359f, 0.829102f, 0.839844f, 0.851074f, 0.860840f, 0.871094f, 0.880859f, 0.891113f,
+ 0.900391f, 0.909668f, 0.917969f, 0.927246f, 0.935547f, 0.943848f, 0.966797f, 0.955566f, 0.945801f, 0.937012f, 0.929199f, 0.921875f,
+ 0.009483f, 0.029556f, 0.050140f, 0.070129f, 0.091797f, 0.112549f, 0.134155f, 0.156372f, 0.177368f, 0.198975f, 0.220825f, 0.243286f,
+ 0.263916f, 0.285645f, 0.306885f, 0.327393f, 0.348145f, 0.368896f, 0.389404f, 0.409424f, 0.429199f, 0.448730f, 0.467529f, 0.486572f,
+ 0.505371f, 0.522461f, 0.540039f, 0.558105f, 0.574219f, 0.591309f, 0.607422f, 0.623535f, 0.639648f, 0.654785f, 0.669922f, 0.685547f,
+ 0.698730f, 0.712891f, 0.726074f, 0.740234f, 0.752441f, 0.765625f, 0.778320f, 0.789551f, 0.802246f, 0.813477f, 0.825195f, 0.836426f,
+ 0.847168f, 0.856934f, 0.868164f, 0.877930f, 0.888184f, 0.897461f, 0.906738f, 0.915527f, 0.925293f, 0.935059f, 0.962402f, 0.951660f,
+ 0.942383f, 0.933594f, 0.926270f, 0.919434f, 0.008934f, 0.026581f, 0.044708f, 0.063354f, 0.082825f, 0.102844f, 0.122437f, 0.141968f,
+ 0.162720f, 0.183105f, 0.202515f, 0.224609f, 0.244995f, 0.265381f, 0.285645f, 0.306152f, 0.326416f, 0.346680f, 0.365967f, 0.385498f,
+ 0.406006f, 0.425293f, 0.444092f, 0.461914f, 0.480225f, 0.499268f, 0.517090f, 0.535156f, 0.552246f, 0.568359f, 0.585449f, 0.601562f,
+ 0.616699f, 0.633789f, 0.649414f, 0.663574f, 0.678711f, 0.693848f, 0.706543f, 0.721680f, 0.734375f, 0.746582f, 0.760742f, 0.773438f,
+ 0.786133f, 0.797852f, 0.809082f, 0.821777f, 0.832031f, 0.843262f, 0.854492f, 0.864746f, 0.875000f, 0.884766f, 0.895020f, 0.904785f,
+ 0.914062f, 0.922852f, 0.957520f, 0.947266f, 0.938965f, 0.930664f, 0.923340f, 0.916992f, 0.007668f, 0.024017f, 0.040405f, 0.057831f,
+ 0.075195f, 0.093079f, 0.111694f, 0.130127f, 0.148926f, 0.168213f, 0.187500f, 0.206543f, 0.226440f, 0.246460f, 0.265869f, 0.285400f,
+ 0.305176f, 0.324707f, 0.344238f, 0.363281f, 0.383057f, 0.401123f, 0.420166f, 0.439941f, 0.457764f, 0.475586f, 0.493164f, 0.511719f,
+ 0.528809f, 0.545898f, 0.562988f, 0.579590f, 0.596191f, 0.612305f, 0.627441f, 0.643555f, 0.658203f, 0.672363f, 0.687988f, 0.702637f,
+ 0.715332f, 0.728516f, 0.742676f, 0.756348f, 0.768555f, 0.781250f, 0.794434f, 0.806152f, 0.818359f, 0.828613f, 0.840332f, 0.851074f,
+ 0.861816f, 0.872559f, 0.882812f, 0.892578f, 0.903320f, 0.912598f, 0.952637f, 0.943848f, 0.935059f, 0.927246f, 0.920410f, 0.914062f,
+ 0.007263f, 0.021530f, 0.037048f, 0.052429f, 0.068909f, 0.084961f, 0.102112f, 0.119568f, 0.136475f, 0.154541f, 0.172852f, 0.191528f,
+ 0.209717f, 0.228638f, 0.246948f, 0.265869f, 0.284912f, 0.304199f, 0.322510f, 0.341309f, 0.360596f, 0.379639f, 0.397461f, 0.416504f,
+ 0.434570f, 0.452881f, 0.470947f, 0.489014f, 0.505859f, 0.523438f, 0.541016f, 0.557129f, 0.574219f, 0.590332f, 0.606445f, 0.622070f,
+ 0.637695f, 0.653809f, 0.667969f, 0.682129f, 0.697754f, 0.711426f, 0.724609f, 0.737793f, 0.750977f, 0.765625f, 0.777832f, 0.790039f,
+ 0.801270f, 0.813477f, 0.825684f, 0.837402f, 0.848145f, 0.859375f, 0.870117f, 0.880859f, 0.891602f, 0.900391f, 0.947754f, 0.938965f,
+ 0.931152f, 0.923828f, 0.917480f, 0.911133f, 0.006401f, 0.019730f, 0.033813f, 0.047729f, 0.062561f, 0.077515f, 0.093140f, 0.108948f,
+ 0.125366f, 0.141968f, 0.159058f, 0.175781f, 0.193726f, 0.212036f, 0.229980f, 0.247681f, 0.265869f, 0.284424f, 0.302734f, 0.320557f,
+ 0.339111f, 0.357910f, 0.376221f, 0.394287f, 0.412109f, 0.429688f, 0.448486f, 0.466064f, 0.483398f, 0.500977f, 0.517090f, 0.535156f,
+ 0.552246f, 0.568359f, 0.583984f, 0.600586f, 0.616699f, 0.632324f, 0.647949f, 0.662598f, 0.677246f, 0.692383f, 0.706543f, 0.719727f,
+ 0.734375f, 0.747070f, 0.761230f, 0.773926f, 0.786621f, 0.797852f, 0.811523f, 0.823242f, 0.834961f, 0.846680f, 0.857422f, 0.868652f,
+ 0.879395f, 0.890137f, 0.942383f, 0.934082f, 0.927246f, 0.919922f, 0.913574f, 0.908203f, 0.005836f, 0.018158f, 0.030746f, 0.043335f,
+ 0.057007f, 0.070801f, 0.085754f, 0.099548f, 0.115112f, 0.130127f, 0.146362f, 0.162354f, 0.178711f, 0.195801f, 0.212769f, 0.230103f,
+ 0.247925f, 0.264893f, 0.283203f, 0.300293f, 0.318604f, 0.336426f, 0.354492f, 0.372314f, 0.390137f, 0.408203f, 0.425537f, 0.443848f,
+ 0.461182f, 0.478271f, 0.496094f, 0.513184f, 0.529297f, 0.546387f, 0.563477f, 0.580566f, 0.595703f, 0.611816f, 0.626465f, 0.642090f,
+ 0.658691f, 0.671875f, 0.686523f, 0.702148f, 0.716797f, 0.729980f, 0.744629f, 0.757324f, 0.770020f, 0.783203f, 0.796875f, 0.808105f,
+ 0.820312f, 0.832520f, 0.844727f, 0.855957f, 0.867188f, 0.877930f, 0.937012f, 0.930176f, 0.922852f, 0.916504f, 0.910645f, 0.904785f,
+ 0.005486f, 0.016525f, 0.028030f, 0.039612f, 0.052185f, 0.064636f, 0.077576f, 0.091553f, 0.105347f, 0.119568f, 0.134521f, 0.149536f,
+ 0.164917f, 0.180664f, 0.197388f, 0.213623f, 0.230347f, 0.246826f, 0.264160f, 0.280518f, 0.298584f, 0.315674f, 0.334229f, 0.350830f,
+ 0.369141f, 0.386963f, 0.404053f, 0.422119f, 0.438477f, 0.456299f, 0.474121f, 0.491211f, 0.507812f, 0.524902f, 0.541504f, 0.557617f,
+ 0.574707f, 0.590820f, 0.606934f, 0.622559f, 0.637207f, 0.652832f, 0.668945f, 0.683105f, 0.698730f, 0.711914f, 0.726074f, 0.740723f,
+ 0.753906f, 0.766602f, 0.780273f, 0.792969f, 0.805664f, 0.818848f, 0.830566f, 0.842285f, 0.854492f, 0.866211f, 0.931641f, 0.925781f,
+ 0.918945f, 0.913086f, 0.907227f, 0.900879f, 0.004810f, 0.014847f, 0.025604f, 0.036621f, 0.047577f, 0.059174f, 0.071472f, 0.084106f,
+ 0.096985f, 0.109863f, 0.124146f, 0.137939f, 0.152954f, 0.167358f, 0.182495f, 0.197754f, 0.213745f, 0.230103f, 0.246216f, 0.262939f,
+ 0.279297f, 0.296387f, 0.313477f, 0.329834f, 0.348145f, 0.365479f, 0.382080f, 0.399658f, 0.417480f, 0.434082f, 0.452148f, 0.469238f,
+ 0.486084f, 0.502441f, 0.520020f, 0.536621f, 0.552734f, 0.569336f, 0.585938f, 0.601562f, 0.617676f, 0.632812f, 0.648438f, 0.664062f,
+ 0.679688f, 0.693848f, 0.708008f, 0.722656f, 0.735840f, 0.750488f, 0.765137f, 0.777832f, 0.791016f, 0.803711f, 0.816895f, 0.829102f,
+ 0.841309f, 0.853027f, 0.925781f, 0.921387f, 0.914551f, 0.908203f, 0.903320f, 0.897461f, 0.004494f, 0.013809f, 0.023331f, 0.033264f,
+ 0.043549f, 0.053833f, 0.065369f, 0.076660f, 0.088684f, 0.100708f, 0.113464f, 0.127075f, 0.140381f, 0.154419f, 0.169067f, 0.183472f,
+ 0.198975f, 0.213623f, 0.229370f, 0.245117f, 0.261475f, 0.277832f, 0.294678f, 0.311523f, 0.327148f, 0.344727f, 0.362061f, 0.378418f,
+ 0.395996f, 0.413086f, 0.430176f, 0.447021f, 0.464111f, 0.481689f, 0.498047f, 0.514648f, 0.531738f, 0.547363f, 0.565430f, 0.582031f,
+ 0.597656f, 0.612793f, 0.628418f, 0.644043f, 0.660645f, 0.674805f, 0.689941f, 0.705078f, 0.718750f, 0.734375f, 0.747559f, 0.761719f,
+ 0.775391f, 0.788086f, 0.803223f, 0.814453f, 0.828125f, 0.840332f, 0.919434f, 0.916504f, 0.909668f, 0.904785f, 0.898926f, 0.894043f,
+ 0.004120f, 0.012512f, 0.021423f, 0.030655f, 0.039673f, 0.049500f, 0.059845f, 0.070374f, 0.081543f, 0.093323f, 0.104614f, 0.116577f,
+ 0.129395f, 0.142456f, 0.156250f, 0.169434f, 0.183594f, 0.198364f, 0.213257f, 0.228638f, 0.244141f, 0.259766f, 0.275635f, 0.291748f,
+ 0.308105f, 0.324707f, 0.341309f, 0.359131f, 0.375244f, 0.391846f, 0.408447f, 0.426025f, 0.442871f, 0.459473f, 0.477051f, 0.494141f,
+ 0.510254f, 0.527344f, 0.543457f, 0.560059f, 0.577148f, 0.592773f, 0.608887f, 0.625977f, 0.640625f, 0.656738f, 0.671875f, 0.686523f,
+ 0.702637f, 0.716797f, 0.731445f, 0.746582f, 0.759277f, 0.773926f, 0.787598f, 0.800293f, 0.814453f, 0.827148f, 0.914062f, 0.911133f,
+ 0.905273f, 0.899902f, 0.895508f, 0.890625f, 0.004120f, 0.011566f, 0.019180f, 0.027969f, 0.036255f, 0.045746f, 0.054901f, 0.064941f,
+ 0.074707f, 0.085327f, 0.096436f, 0.107239f, 0.119324f, 0.131470f, 0.144165f, 0.157104f, 0.169922f, 0.183594f, 0.198242f, 0.212769f,
+ 0.227295f, 0.242188f, 0.257568f, 0.273193f, 0.289307f, 0.305420f, 0.321289f, 0.337891f, 0.354492f, 0.371094f, 0.387451f, 0.405029f,
+ 0.421143f, 0.438477f, 0.455322f, 0.472656f, 0.488525f, 0.505859f, 0.521973f, 0.539551f, 0.555664f, 0.572754f, 0.588867f, 0.605469f,
+ 0.621582f, 0.637207f, 0.653320f, 0.668945f, 0.684570f, 0.698242f, 0.714844f, 0.729492f, 0.745117f, 0.758301f, 0.771973f, 0.787109f,
+ 0.800781f, 0.813477f, 0.907715f, 0.905762f, 0.900879f, 0.895508f, 0.890625f, 0.886719f, 0.003464f, 0.010536f, 0.018143f, 0.025604f,
+ 0.033600f, 0.041992f, 0.050659f, 0.059631f, 0.068481f, 0.078552f, 0.088196f, 0.099060f, 0.110107f, 0.121033f, 0.133057f, 0.145020f,
+ 0.157349f, 0.170166f, 0.183838f, 0.197632f, 0.210938f, 0.225464f, 0.241089f, 0.255371f, 0.270508f, 0.286377f, 0.302246f, 0.317871f,
+ 0.334229f, 0.349854f, 0.367188f, 0.383789f, 0.399414f, 0.417236f, 0.433838f, 0.450928f, 0.468018f, 0.484131f, 0.501465f, 0.519043f,
+ 0.535156f, 0.551758f, 0.568359f, 0.585449f, 0.601074f, 0.617676f, 0.634277f, 0.649902f, 0.666016f, 0.681152f, 0.695801f, 0.711914f,
+ 0.727539f, 0.741699f, 0.756836f, 0.770508f, 0.785645f, 0.800293f, 0.901855f, 0.900391f, 0.895996f, 0.891113f, 0.886230f, 0.881836f,
+ 0.003197f, 0.009903f, 0.016525f, 0.023849f, 0.030853f, 0.038605f, 0.046265f, 0.054657f, 0.063232f, 0.072266f, 0.081543f, 0.090881f,
+ 0.100769f, 0.112061f, 0.123047f, 0.134155f, 0.145752f, 0.157471f, 0.170166f, 0.182861f, 0.196289f, 0.210327f, 0.223755f, 0.238525f,
+ 0.253418f, 0.268066f, 0.283203f, 0.299316f, 0.314697f, 0.330811f, 0.346680f, 0.363281f, 0.379639f, 0.396484f, 0.412842f, 0.429443f,
+ 0.446289f, 0.462891f, 0.480225f, 0.497559f, 0.514648f, 0.531250f, 0.547852f, 0.564453f, 0.581055f, 0.598145f, 0.615234f, 0.631836f,
+ 0.646484f, 0.663086f, 0.679199f, 0.694824f, 0.710449f, 0.726074f, 0.740234f, 0.755859f, 0.770508f, 0.784668f, 0.895020f, 0.894531f,
+ 0.890625f, 0.886719f, 0.881836f, 0.877441f, 0.003071f, 0.009163f, 0.015602f, 0.021729f, 0.028412f, 0.035522f, 0.042755f, 0.050598f,
+ 0.057983f, 0.066284f, 0.075317f, 0.083862f, 0.092773f, 0.102905f, 0.113342f, 0.123840f, 0.134399f, 0.145752f, 0.157593f, 0.169556f,
+ 0.182129f, 0.194702f, 0.207886f, 0.222046f, 0.235840f, 0.250977f, 0.265137f, 0.280273f, 0.295898f, 0.311279f, 0.326660f, 0.342773f,
+ 0.359375f, 0.375732f, 0.392090f, 0.409180f, 0.425049f, 0.441895f, 0.459473f, 0.476318f, 0.493652f, 0.510742f, 0.527344f, 0.544434f,
+ 0.561035f, 0.578125f, 0.595215f, 0.611328f, 0.628418f, 0.645020f, 0.661133f, 0.677246f, 0.693359f, 0.708496f, 0.724609f, 0.740723f,
+ 0.755859f, 0.771484f, 0.889160f, 0.889160f, 0.885254f, 0.881348f, 0.876953f, 0.873047f, 0.002748f, 0.008171f, 0.014084f, 0.019638f,
+ 0.026108f, 0.032318f, 0.039154f, 0.045990f, 0.053619f, 0.061066f, 0.068665f, 0.076477f, 0.085632f, 0.094727f, 0.104187f, 0.113831f,
+ 0.123535f, 0.134888f, 0.145508f, 0.157104f, 0.168701f, 0.181030f, 0.193481f, 0.206665f, 0.220093f, 0.233398f, 0.248169f, 0.262695f,
+ 0.277344f, 0.292236f, 0.307617f, 0.322998f, 0.339355f, 0.355469f, 0.371582f, 0.388184f, 0.404541f, 0.420410f, 0.438477f, 0.455322f,
+ 0.472656f, 0.489014f, 0.506348f, 0.523926f, 0.541016f, 0.557617f, 0.575195f, 0.591309f, 0.608887f, 0.625977f, 0.643555f, 0.659180f,
+ 0.674805f, 0.691406f, 0.707520f, 0.724121f, 0.739746f, 0.755371f, 0.882812f, 0.883789f, 0.879883f, 0.875977f, 0.872559f, 0.868652f,
+ 0.002491f, 0.007809f, 0.012764f, 0.018448f, 0.024094f, 0.029861f, 0.036102f, 0.042572f, 0.049500f, 0.056091f, 0.063293f, 0.070984f,
+ 0.079285f, 0.087036f, 0.095825f, 0.104858f, 0.114441f, 0.124084f, 0.133789f, 0.144653f, 0.156250f, 0.167480f, 0.179199f, 0.191650f,
+ 0.204102f, 0.217896f, 0.231445f, 0.245239f, 0.259521f, 0.274170f, 0.289307f, 0.304199f, 0.319580f, 0.334961f, 0.351074f, 0.367676f,
+ 0.384277f, 0.400635f, 0.417480f, 0.434570f, 0.451660f, 0.468994f, 0.485352f, 0.502441f, 0.520508f, 0.537109f, 0.554688f, 0.571777f,
+ 0.588867f, 0.605957f, 0.623047f, 0.639648f, 0.656738f, 0.673828f, 0.690430f, 0.708008f, 0.723633f, 0.739746f, 0.874023f, 0.876953f,
+ 0.874023f, 0.871582f, 0.867188f, 0.862793f, 0.002279f, 0.007130f, 0.012291f, 0.016922f, 0.022171f, 0.027847f, 0.033325f, 0.039185f,
+ 0.045349f, 0.051849f, 0.058411f, 0.064880f, 0.072144f, 0.080017f, 0.087891f, 0.096313f, 0.105103f, 0.114197f, 0.123779f, 0.134155f,
+ 0.144043f, 0.155151f, 0.166016f, 0.177246f, 0.189697f, 0.202271f, 0.214722f, 0.228271f, 0.242310f, 0.256592f, 0.270752f, 0.285400f,
+ 0.300537f, 0.315674f, 0.331543f, 0.347656f, 0.363525f, 0.379639f, 0.396729f, 0.414307f, 0.430908f, 0.447754f, 0.465088f, 0.482178f,
+ 0.499512f, 0.517090f, 0.533203f, 0.552246f, 0.568848f, 0.586426f, 0.603516f, 0.621582f, 0.639648f, 0.656250f, 0.673828f, 0.690918f,
+ 0.707520f, 0.724121f, 0.867676f, 0.870605f, 0.868164f, 0.865723f, 0.861328f, 0.857910f, 0.002220f, 0.006565f, 0.011238f, 0.015961f,
+ 0.020401f, 0.025558f, 0.030853f, 0.036133f, 0.041199f, 0.047180f, 0.053436f, 0.059723f, 0.066162f, 0.073853f, 0.080688f, 0.088440f,
+ 0.096436f, 0.105042f, 0.114319f, 0.123047f, 0.132446f, 0.142822f, 0.153198f, 0.164062f, 0.175659f, 0.187378f, 0.199463f, 0.212402f,
+ 0.225464f, 0.239014f, 0.252686f, 0.266846f, 0.281494f, 0.296631f, 0.312500f, 0.328369f, 0.343750f, 0.359863f, 0.376221f, 0.393066f,
+ 0.409668f, 0.426514f, 0.444336f, 0.461670f, 0.478760f, 0.496826f, 0.513672f, 0.532227f, 0.549316f, 0.567383f, 0.584961f, 0.602051f,
+ 0.620605f, 0.637207f, 0.655273f, 0.672363f, 0.689941f, 0.708008f, 0.860840f, 0.864746f, 0.862793f, 0.859375f, 0.855957f, 0.853027f,
+ 0.002190f, 0.005993f, 0.010117f, 0.014420f, 0.018738f, 0.023361f, 0.028015f, 0.033142f, 0.037781f, 0.043732f, 0.048920f, 0.054840f,
+ 0.061218f, 0.067810f, 0.074219f, 0.081299f, 0.088562f, 0.096130f, 0.104614f, 0.113098f, 0.122253f, 0.131714f, 0.141113f, 0.151245f,
+ 0.162109f, 0.173462f, 0.184692f, 0.196899f, 0.209473f, 0.222534f, 0.236206f, 0.249634f, 0.263672f, 0.277588f, 0.293213f, 0.308350f,
+ 0.323975f, 0.339844f, 0.355957f, 0.372070f, 0.389404f, 0.405762f, 0.422852f, 0.439941f, 0.458008f, 0.475098f, 0.492920f, 0.510742f,
+ 0.528320f, 0.546875f, 0.564453f, 0.583496f, 0.601074f, 0.619141f, 0.636719f, 0.654785f, 0.672852f, 0.691406f, 0.852539f, 0.858398f,
+ 0.856445f, 0.853516f, 0.850586f, 0.847656f, 0.001787f, 0.005753f, 0.009300f, 0.013611f, 0.017410f, 0.021576f, 0.025665f, 0.030533f,
+ 0.035126f, 0.040039f, 0.044952f, 0.050446f, 0.055817f, 0.061890f, 0.068054f, 0.074707f, 0.081482f, 0.088501f, 0.095764f, 0.103943f,
+ 0.112183f, 0.120850f, 0.130249f, 0.139526f, 0.149658f, 0.160400f, 0.171021f, 0.182007f, 0.194336f, 0.206421f, 0.219360f, 0.232666f,
+ 0.245850f, 0.260010f, 0.274170f, 0.289307f, 0.304443f, 0.319580f, 0.335693f, 0.352295f, 0.369141f, 0.385498f, 0.402344f, 0.419189f,
+ 0.437012f, 0.454346f, 0.472412f, 0.490234f, 0.507812f, 0.525879f, 0.545410f, 0.562500f, 0.581055f, 0.600098f, 0.618164f, 0.636719f,
+ 0.655273f, 0.674316f, 0.845703f, 0.852051f, 0.849609f, 0.847168f, 0.845215f, 0.841309f, 0.001766f, 0.005241f, 0.008881f, 0.012024f,
+ 0.016129f, 0.020233f, 0.024124f, 0.027664f, 0.032135f, 0.036835f, 0.041321f, 0.046173f, 0.051392f, 0.056946f, 0.062225f, 0.068604f,
+ 0.074524f, 0.080933f, 0.088135f, 0.095398f, 0.103210f, 0.110779f, 0.119263f, 0.128296f, 0.137695f, 0.147217f, 0.157349f, 0.168091f,
+ 0.179688f, 0.191284f, 0.203613f, 0.215942f, 0.228882f, 0.242554f, 0.255859f, 0.270508f, 0.285400f, 0.300537f, 0.316406f, 0.331787f,
+ 0.348877f, 0.364746f, 0.382080f, 0.398682f, 0.415771f, 0.434082f, 0.451416f, 0.469482f, 0.487793f, 0.505859f, 0.524414f, 0.542969f,
+ 0.562012f, 0.580566f, 0.598145f, 0.618652f, 0.637695f, 0.657227f, 0.837891f, 0.844727f, 0.843750f, 0.841309f, 0.838379f, 0.836426f,
+ 0.001598f, 0.004887f, 0.008217f, 0.011497f, 0.014786f, 0.018326f, 0.021652f, 0.025513f, 0.029541f, 0.033813f, 0.038086f, 0.042236f,
+ 0.046844f, 0.052032f, 0.057251f, 0.062622f, 0.068237f, 0.074280f, 0.080505f, 0.086975f, 0.094116f, 0.101074f, 0.109314f, 0.117554f,
+ 0.126587f, 0.135254f, 0.144775f, 0.155029f, 0.165405f, 0.176392f, 0.187744f, 0.199829f, 0.212646f, 0.224976f, 0.238647f, 0.252441f,
+ 0.267090f, 0.281738f, 0.296631f, 0.312256f, 0.328369f, 0.344971f, 0.361328f, 0.377686f, 0.395264f, 0.412842f, 0.430908f, 0.448730f,
+ 0.467041f, 0.485596f, 0.503906f, 0.522461f, 0.541504f, 0.561523f, 0.580078f, 0.599121f, 0.618164f, 0.639648f, 0.828613f, 0.837891f,
+ 0.836914f, 0.834473f, 0.833008f, 0.830566f, 0.001709f, 0.004494f, 0.007416f, 0.010628f, 0.013680f, 0.016785f, 0.020203f, 0.023712f,
+ 0.027435f, 0.031006f, 0.034424f, 0.038635f, 0.043182f, 0.047668f, 0.052307f, 0.057159f, 0.062042f, 0.067749f, 0.073730f, 0.079956f,
+ 0.086182f, 0.092773f, 0.100159f, 0.107727f, 0.115479f, 0.123962f, 0.132935f, 0.142578f, 0.151978f, 0.162476f, 0.173340f, 0.184570f,
+ 0.196411f, 0.208740f, 0.221436f, 0.235229f, 0.248779f, 0.262939f, 0.277832f, 0.293213f, 0.308105f, 0.324219f, 0.341309f, 0.357178f,
+ 0.374756f, 0.391846f, 0.409424f, 0.427490f, 0.446533f, 0.464844f, 0.483643f, 0.501953f, 0.521484f, 0.541504f, 0.561035f, 0.579590f,
+ 0.599609f, 0.620605f, 0.821289f, 0.830566f, 0.830078f, 0.828125f, 0.825684f, 0.823242f, 0.001367f, 0.004105f, 0.007023f, 0.009552f,
+ 0.012611f, 0.015289f, 0.018341f, 0.021652f, 0.024857f, 0.027878f, 0.031769f, 0.035614f, 0.039276f, 0.043610f, 0.047333f, 0.052155f,
+ 0.056549f, 0.061401f, 0.066895f, 0.072449f, 0.078613f, 0.084778f, 0.091309f, 0.098083f, 0.105774f, 0.113281f, 0.121399f, 0.130371f,
+ 0.139648f, 0.148926f, 0.159546f, 0.169922f, 0.180908f, 0.192749f, 0.204834f, 0.217651f, 0.231567f, 0.244385f, 0.259277f, 0.273926f,
+ 0.289307f, 0.304688f, 0.320557f, 0.336914f, 0.354248f, 0.371338f, 0.388184f, 0.406982f, 0.424316f, 0.443115f, 0.462646f, 0.481445f,
+ 0.501465f, 0.520508f, 0.541016f, 0.559570f, 0.580078f, 0.601074f, 0.812988f, 0.823242f, 0.823242f, 0.821289f, 0.819824f, 0.817383f,
+ 0.001398f, 0.003883f, 0.006351f, 0.008911f, 0.011559f, 0.014343f, 0.017212f, 0.020035f, 0.022797f, 0.026062f, 0.028793f, 0.031891f,
+ 0.035858f, 0.039368f, 0.043213f, 0.047607f, 0.051483f, 0.056030f, 0.060883f, 0.065979f, 0.071350f, 0.076843f, 0.083130f, 0.089172f,
+ 0.096069f, 0.103333f, 0.111023f, 0.119019f, 0.127319f, 0.136719f, 0.145996f, 0.156128f, 0.166138f, 0.177368f, 0.189453f, 0.201416f,
+ 0.213745f, 0.227295f, 0.240601f, 0.255371f, 0.269287f, 0.285400f, 0.301270f, 0.317139f, 0.333740f, 0.350586f, 0.367920f, 0.385986f,
+ 0.404297f, 0.422852f, 0.442383f, 0.460938f, 0.479980f, 0.500488f, 0.520508f, 0.541016f, 0.560547f, 0.582520f, 0.803711f, 0.814941f,
+ 0.815430f, 0.814453f, 0.812500f, 0.810547f, 0.001259f, 0.003464f, 0.006332f, 0.008286f, 0.010384f, 0.013000f, 0.015587f, 0.018234f,
+ 0.021027f, 0.023422f, 0.026566f, 0.029480f, 0.032379f, 0.035919f, 0.039215f, 0.043060f, 0.046997f, 0.050995f, 0.055267f, 0.059998f,
+ 0.065002f, 0.069946f, 0.075317f, 0.081299f, 0.087280f, 0.094116f, 0.101135f, 0.108276f, 0.116150f, 0.124695f, 0.133545f, 0.142700f,
+ 0.152222f, 0.162720f, 0.173950f, 0.185303f, 0.197754f, 0.210205f, 0.223022f, 0.237061f, 0.250732f, 0.265869f, 0.281250f, 0.297119f,
+ 0.313477f, 0.330322f, 0.347656f, 0.364746f, 0.383301f, 0.401367f, 0.420898f, 0.440186f, 0.459229f, 0.479736f, 0.499512f, 0.520996f,
+ 0.541016f, 0.562988f, 0.794434f, 0.807129f, 0.807617f, 0.807129f, 0.805176f, 0.803711f, 0.001070f, 0.003237f, 0.005432f, 0.007359f,
+ 0.009857f, 0.012337f, 0.014191f, 0.016586f, 0.019257f, 0.021561f, 0.024094f, 0.026901f, 0.029724f, 0.032745f, 0.035675f, 0.039368f,
+ 0.042572f, 0.045990f, 0.050354f, 0.054535f, 0.058746f, 0.063232f, 0.068420f, 0.073608f, 0.079529f, 0.085266f, 0.091370f, 0.098083f,
+ 0.105835f, 0.113159f, 0.121094f, 0.129639f, 0.139038f, 0.148926f, 0.159058f, 0.169678f, 0.181274f, 0.193481f, 0.205811f, 0.219482f,
+ 0.233032f, 0.247192f, 0.262207f, 0.277100f, 0.293213f, 0.309814f, 0.326660f, 0.344238f, 0.361816f, 0.380615f, 0.398926f, 0.418945f,
+ 0.438477f, 0.458008f, 0.479004f, 0.499512f, 0.520996f, 0.543945f, 0.784668f, 0.798828f, 0.800293f, 0.799805f, 0.797852f, 0.796875f,
+ 0.001074f, 0.002916f, 0.004955f, 0.007149f, 0.009033f, 0.011055f, 0.013268f, 0.015495f, 0.017365f, 0.019485f, 0.022095f, 0.024002f,
+ 0.026688f, 0.029633f, 0.032593f, 0.035370f, 0.038361f, 0.041870f, 0.045319f, 0.049225f, 0.052948f, 0.057068f, 0.061676f, 0.066345f,
+ 0.071167f, 0.076782f, 0.082581f, 0.088867f, 0.095886f, 0.102539f, 0.109802f, 0.118042f, 0.126709f, 0.135132f, 0.144897f, 0.155151f,
+ 0.165771f, 0.177368f, 0.189209f, 0.201904f, 0.215210f, 0.229370f, 0.242798f, 0.258057f, 0.274170f, 0.290039f, 0.306885f, 0.323242f,
+ 0.341309f, 0.359375f, 0.378418f, 0.397461f, 0.416260f, 0.437500f, 0.457031f, 0.479004f, 0.501465f, 0.522461f, 0.775391f, 0.790527f,
+ 0.791992f, 0.791504f, 0.791016f, 0.789551f, 0.000837f, 0.002916f, 0.004738f, 0.006477f, 0.008575f, 0.010170f, 0.012161f, 0.014023f,
+ 0.015808f, 0.017792f, 0.020111f, 0.022064f, 0.024414f, 0.026794f, 0.029251f, 0.032074f, 0.034698f, 0.037598f, 0.040741f, 0.043915f,
+ 0.047577f, 0.051361f, 0.055389f, 0.059692f, 0.064209f, 0.068787f, 0.074585f, 0.079712f, 0.085632f, 0.092346f, 0.099487f, 0.106323f,
+ 0.114929f, 0.122925f, 0.131958f, 0.141235f, 0.151123f, 0.161865f, 0.172974f, 0.184937f, 0.197632f, 0.210693f, 0.224854f, 0.239136f,
+ 0.254395f, 0.269531f, 0.285889f, 0.302979f, 0.320557f, 0.338623f, 0.356689f, 0.375977f, 0.395752f, 0.415527f, 0.436523f, 0.458252f,
+ 0.479248f, 0.501465f, 0.765137f, 0.781738f, 0.783691f, 0.784180f, 0.783203f, 0.781250f, 0.000854f, 0.002817f, 0.004089f, 0.005684f,
+ 0.007675f, 0.009277f, 0.010864f, 0.012413f, 0.014427f, 0.016235f, 0.017838f, 0.019913f, 0.021805f, 0.023987f, 0.026276f, 0.028915f,
+ 0.030960f, 0.033875f, 0.036652f, 0.039551f, 0.042816f, 0.045837f, 0.049591f, 0.053589f, 0.057526f, 0.061829f, 0.066650f, 0.071655f,
+ 0.077393f, 0.083008f, 0.088989f, 0.096008f, 0.103210f, 0.110657f, 0.119141f, 0.127930f, 0.137085f, 0.146973f, 0.157593f, 0.169312f,
+ 0.181274f, 0.193481f, 0.207031f, 0.220581f, 0.235229f, 0.250732f, 0.266357f, 0.282227f, 0.299805f, 0.317627f, 0.335449f, 0.354736f,
+ 0.374268f, 0.394531f, 0.415527f, 0.436279f, 0.458252f, 0.481689f, 0.754883f, 0.773438f, 0.775391f, 0.775879f, 0.774902f, 0.773926f,
+ 0.000852f, 0.002520f, 0.003937f, 0.005527f, 0.006836f, 0.008408f, 0.009773f, 0.011620f, 0.013039f, 0.014687f, 0.016327f, 0.017944f,
+ 0.019760f, 0.021774f, 0.023697f, 0.025894f, 0.027969f, 0.030121f, 0.032501f, 0.035370f, 0.038208f, 0.041046f, 0.044098f, 0.047791f,
+ 0.051453f, 0.055176f, 0.059570f, 0.064026f, 0.068787f, 0.074158f, 0.079834f, 0.085938f, 0.092590f, 0.099304f, 0.106873f, 0.114990f,
+ 0.124023f, 0.133301f, 0.143066f, 0.153687f, 0.164551f, 0.176392f, 0.189209f, 0.202637f, 0.216553f, 0.231323f, 0.246704f, 0.262451f,
+ 0.279297f, 0.296387f, 0.314697f, 0.333496f, 0.353516f, 0.373047f, 0.394775f, 0.415039f, 0.437500f, 0.460449f, 0.745117f, 0.763672f,
+ 0.766602f, 0.767090f, 0.767090f, 0.765625f, 0.000762f, 0.002342f, 0.003563f, 0.004787f, 0.006447f, 0.007648f, 0.009193f, 0.010353f,
+ 0.012016f, 0.013138f, 0.014557f, 0.016312f, 0.017929f, 0.019470f, 0.021103f, 0.023056f, 0.024918f, 0.026886f, 0.029099f, 0.031586f,
+ 0.034058f, 0.036499f, 0.039307f, 0.042450f, 0.045685f, 0.049072f, 0.052826f, 0.056915f, 0.061096f, 0.065918f, 0.070984f, 0.076538f,
+ 0.082520f, 0.088928f, 0.095520f, 0.102905f, 0.111206f, 0.119629f, 0.128662f, 0.138184f, 0.148682f, 0.160156f, 0.171997f, 0.184937f,
+ 0.198364f, 0.212524f, 0.227173f, 0.243042f, 0.259277f, 0.276611f, 0.294189f, 0.312500f, 0.331055f, 0.350830f, 0.372070f, 0.392334f,
+ 0.415771f, 0.438232f, 0.734375f, 0.754395f, 0.758789f, 0.758789f, 0.758789f, 0.757812f, 0.000848f, 0.002024f, 0.003553f, 0.004646f,
+ 0.005726f, 0.007050f, 0.008362f, 0.009438f, 0.010536f, 0.011810f, 0.013123f, 0.014481f, 0.015778f, 0.017242f, 0.018753f, 0.020447f,
+ 0.022278f, 0.023819f, 0.025940f, 0.027771f, 0.029999f, 0.032410f, 0.034851f, 0.037354f, 0.040375f, 0.043610f, 0.046631f, 0.050354f,
+ 0.054108f, 0.058563f, 0.062805f, 0.067871f, 0.073242f, 0.078796f, 0.085083f, 0.091797f, 0.098816f, 0.106689f, 0.115540f, 0.124207f,
+ 0.134155f, 0.144409f, 0.155762f, 0.167725f, 0.180664f, 0.193848f, 0.208618f, 0.223389f, 0.239746f, 0.256104f, 0.273438f, 0.291260f,
+ 0.310059f, 0.330078f, 0.349854f, 0.370850f, 0.393555f, 0.416992f, 0.724121f, 0.744629f, 0.748535f, 0.750000f, 0.749512f, 0.749512f,
+ 0.000736f, 0.001780f, 0.002937f, 0.004314f, 0.005211f, 0.006214f, 0.007423f, 0.008537f, 0.009392f, 0.010773f, 0.011726f, 0.012970f,
+ 0.014183f, 0.015373f, 0.016724f, 0.017990f, 0.019730f, 0.021194f, 0.022644f, 0.024368f, 0.026443f, 0.028610f, 0.030685f, 0.032898f,
+ 0.035583f, 0.038300f, 0.041351f, 0.044556f, 0.047638f, 0.051422f, 0.055359f, 0.059875f, 0.064392f, 0.069580f, 0.075195f, 0.080872f,
+ 0.087646f, 0.094849f, 0.102173f, 0.110596f, 0.119690f, 0.129761f, 0.139893f, 0.151367f, 0.163452f, 0.176147f, 0.190063f, 0.204590f,
+ 0.219238f, 0.235718f, 0.252441f, 0.270264f, 0.289062f, 0.307861f, 0.328613f, 0.350098f, 0.372314f, 0.395020f, 0.712402f, 0.734863f,
+ 0.739746f, 0.740723f, 0.740723f, 0.740234f, 0.000589f, 0.001616f, 0.002674f, 0.003841f, 0.004940f, 0.005676f, 0.006554f, 0.007442f,
+ 0.008812f, 0.009537f, 0.010277f, 0.011528f, 0.012634f, 0.013527f, 0.014671f, 0.016037f, 0.017136f, 0.018631f, 0.019943f, 0.021530f,
+ 0.023071f, 0.025146f, 0.026825f, 0.029037f, 0.030853f, 0.033447f, 0.035736f, 0.038849f, 0.041656f, 0.044922f, 0.048462f, 0.052277f,
+ 0.056519f, 0.061127f, 0.065796f, 0.071411f, 0.077148f, 0.083435f, 0.090393f, 0.097900f, 0.106079f, 0.115356f, 0.125122f, 0.135132f,
+ 0.146729f, 0.158936f, 0.171509f, 0.185059f, 0.200439f, 0.215576f, 0.232056f, 0.249756f, 0.267822f, 0.286621f, 0.306885f, 0.328125f,
+ 0.349854f, 0.373291f, 0.701172f, 0.725586f, 0.729980f, 0.730957f, 0.731934f, 0.730957f, 0.000547f, 0.001666f, 0.002367f, 0.003559f,
+ 0.004238f, 0.005028f, 0.005852f, 0.006859f, 0.007755f, 0.008530f, 0.009163f, 0.010056f, 0.010956f, 0.011978f, 0.013062f, 0.014076f,
+ 0.015053f, 0.016251f, 0.017471f, 0.018921f, 0.020233f, 0.021774f, 0.023315f, 0.025162f, 0.026871f, 0.029007f, 0.031204f, 0.033661f,
+ 0.036102f, 0.039062f, 0.042053f, 0.045380f, 0.048859f, 0.053040f, 0.057343f, 0.062225f, 0.067261f, 0.073120f, 0.079407f, 0.086243f,
+ 0.093567f, 0.101868f, 0.110596f, 0.120239f, 0.130859f, 0.141968f, 0.154053f, 0.167358f, 0.181274f, 0.196045f, 0.212158f, 0.229248f,
+ 0.247192f, 0.265381f, 0.285400f, 0.305664f, 0.327637f, 0.350586f, 0.689453f, 0.715820f, 0.720215f, 0.722168f, 0.722168f, 0.722168f,
+ 0.000492f, 0.001634f, 0.002342f, 0.003111f, 0.003866f, 0.004574f, 0.005417f, 0.005928f, 0.006588f, 0.007393f, 0.008041f, 0.008873f,
+ 0.009689f, 0.010391f, 0.011375f, 0.012146f, 0.013100f, 0.014183f, 0.015274f, 0.016479f, 0.017456f, 0.018768f, 0.020157f, 0.021606f,
+ 0.023300f, 0.024933f, 0.026855f, 0.028885f, 0.031143f, 0.033417f, 0.036133f, 0.039032f, 0.042236f, 0.045776f, 0.049713f, 0.053680f,
+ 0.058228f, 0.063232f, 0.069092f, 0.074829f, 0.081482f, 0.089050f, 0.096924f, 0.105591f, 0.115417f, 0.126221f, 0.137329f, 0.149658f,
+ 0.162964f, 0.176880f, 0.192505f, 0.208740f, 0.226318f, 0.244873f, 0.263428f, 0.283936f, 0.306396f, 0.329346f, 0.676270f, 0.705078f,
+ 0.709961f, 0.711914f, 0.712891f, 0.711914f, 0.000506f, 0.001342f, 0.002157f, 0.002813f, 0.003353f, 0.004105f, 0.004658f, 0.005344f,
+ 0.005871f, 0.006538f, 0.007050f, 0.007751f, 0.008247f, 0.009109f, 0.009865f, 0.010559f, 0.011269f, 0.012169f, 0.013290f, 0.014191f,
+ 0.015015f, 0.016312f, 0.017395f, 0.018570f, 0.019989f, 0.021439f, 0.023102f, 0.024536f, 0.026535f, 0.028702f, 0.030899f, 0.033356f,
+ 0.035980f, 0.039093f, 0.042328f, 0.046051f, 0.049927f, 0.054199f, 0.059052f, 0.064575f, 0.070496f, 0.076782f, 0.084412f, 0.092285f,
+ 0.100708f, 0.110779f, 0.121399f, 0.132690f, 0.145508f, 0.158813f, 0.173584f, 0.189453f, 0.205688f, 0.223755f, 0.242554f, 0.263184f,
+ 0.284180f, 0.306641f, 0.664551f, 0.693848f, 0.699707f, 0.702148f, 0.702637f, 0.703125f, 0.000500f, 0.001122f, 0.001810f, 0.002363f,
+ 0.002987f, 0.003576f, 0.004158f, 0.004620f, 0.005032f, 0.005627f, 0.006161f, 0.006721f, 0.007179f, 0.007790f, 0.008385f, 0.009163f,
+ 0.009758f, 0.010536f, 0.011284f, 0.011986f, 0.012878f, 0.013710f, 0.014725f, 0.015823f, 0.016937f, 0.018326f, 0.019547f, 0.020874f,
+ 0.022522f, 0.024399f, 0.026077f, 0.028427f, 0.030609f, 0.032990f, 0.035736f, 0.038788f, 0.042236f, 0.045990f, 0.050354f, 0.054901f,
+ 0.059967f, 0.065918f, 0.072205f, 0.079468f, 0.087219f, 0.096252f, 0.105713f, 0.116272f, 0.128174f, 0.140747f, 0.154419f, 0.169556f,
+ 0.186279f, 0.203125f, 0.221313f, 0.240601f, 0.261719f, 0.284424f, 0.652344f, 0.683105f, 0.688965f, 0.691406f, 0.692383f, 0.693359f,
+ 0.000482f, 0.001184f, 0.001604f, 0.002171f, 0.002562f, 0.003029f, 0.003656f, 0.003941f, 0.004410f, 0.004948f, 0.005325f, 0.005577f,
+ 0.006157f, 0.006702f, 0.007172f, 0.007751f, 0.008331f, 0.008904f, 0.009514f, 0.010063f, 0.010925f, 0.011719f, 0.012306f, 0.013321f,
+ 0.014275f, 0.015465f, 0.016510f, 0.017593f, 0.018845f, 0.020401f, 0.022095f, 0.023682f, 0.025513f, 0.027679f, 0.029968f, 0.032593f,
+ 0.035461f, 0.038757f, 0.042175f, 0.046326f, 0.050873f, 0.055939f, 0.061462f, 0.067444f, 0.074402f, 0.082520f, 0.091125f, 0.100830f,
+ 0.111572f, 0.123413f, 0.136719f, 0.150513f, 0.165894f, 0.182251f, 0.200684f, 0.219727f, 0.240234f, 0.261963f, 0.640137f, 0.671387f,
+ 0.679199f, 0.680664f, 0.682617f, 0.683105f, 0.000501f, 0.000919f, 0.001424f, 0.001853f, 0.002266f, 0.002789f, 0.002998f, 0.003397f,
+ 0.003902f, 0.004192f, 0.004417f, 0.004974f, 0.005207f, 0.005676f, 0.006134f, 0.006527f, 0.007179f, 0.007465f, 0.008018f, 0.008537f,
+ 0.009178f, 0.009888f, 0.010544f, 0.011093f, 0.011986f, 0.012794f, 0.013664f, 0.014717f, 0.015747f, 0.016983f, 0.018127f, 0.019470f,
+ 0.021103f, 0.022919f, 0.024826f, 0.026962f, 0.029358f, 0.031769f, 0.035065f, 0.038239f, 0.042297f, 0.046570f, 0.051422f, 0.056671f,
+ 0.062805f, 0.069763f, 0.077698f, 0.086182f, 0.095825f, 0.106812f, 0.119080f, 0.132568f, 0.147217f, 0.162598f, 0.180176f, 0.198730f,
+ 0.218628f, 0.241211f, 0.627441f, 0.660156f, 0.668457f, 0.669922f, 0.672363f, 0.671875f, 0.000235f, 0.001120f, 0.001356f, 0.001651f,
+ 0.002117f, 0.002441f, 0.002678f, 0.002993f, 0.003244f, 0.003519f, 0.003876f, 0.004086f, 0.004505f, 0.004787f, 0.005085f, 0.005604f,
+ 0.005985f, 0.006271f, 0.006783f, 0.007145f, 0.007679f, 0.008217f, 0.008728f, 0.009277f, 0.009956f, 0.010605f, 0.011490f, 0.012062f,
+ 0.013084f, 0.013962f, 0.014984f, 0.016113f, 0.017395f, 0.018829f, 0.020416f, 0.022125f, 0.023972f, 0.025955f, 0.028625f, 0.031616f,
+ 0.034515f, 0.038147f, 0.042114f, 0.046783f, 0.052094f, 0.058075f, 0.065002f, 0.072510f, 0.081604f, 0.091125f, 0.102539f, 0.114807f,
+ 0.128662f, 0.143921f, 0.160034f, 0.178467f, 0.198364f, 0.218750f, 0.613281f, 0.648926f, 0.657227f, 0.659668f, 0.661621f, 0.661621f,
+ 0.000382f, 0.000704f, 0.001099f, 0.001557f, 0.001774f, 0.001976f, 0.002132f, 0.002575f, 0.002634f, 0.002916f, 0.003103f, 0.003494f,
+ 0.003754f, 0.003956f, 0.004269f, 0.004684f, 0.004902f, 0.005234f, 0.005569f, 0.005890f, 0.006416f, 0.006786f, 0.007160f, 0.007645f,
+ 0.008118f, 0.008781f, 0.009346f, 0.010025f, 0.010658f, 0.011475f, 0.012230f, 0.013016f, 0.014122f, 0.015251f, 0.016342f, 0.017807f,
+ 0.019424f, 0.021103f, 0.023026f, 0.025436f, 0.027817f, 0.030914f, 0.034210f, 0.037750f, 0.042450f, 0.047455f, 0.053101f, 0.059998f,
+ 0.067688f, 0.076660f, 0.086670f, 0.097961f, 0.110779f, 0.125366f, 0.140747f, 0.158081f, 0.176880f, 0.197632f, 0.600098f, 0.637207f,
+ 0.644531f, 0.647949f, 0.649414f, 0.651855f, 0.000182f, 0.000738f, 0.000942f, 0.001220f, 0.001469f, 0.001634f, 0.001820f, 0.002005f,
+ 0.002291f, 0.002441f, 0.002636f, 0.002832f, 0.003019f, 0.003242f, 0.003502f, 0.003824f, 0.004017f, 0.004333f, 0.004570f, 0.004883f,
+ 0.005173f, 0.005615f, 0.005909f, 0.006317f, 0.006649f, 0.007160f, 0.007656f, 0.008156f, 0.008583f, 0.009209f, 0.009857f, 0.010696f,
+ 0.011322f, 0.012367f, 0.013229f, 0.014259f, 0.015686f, 0.016815f, 0.018402f, 0.020126f, 0.022095f, 0.024414f, 0.027176f, 0.030273f,
+ 0.033722f, 0.038086f, 0.042969f, 0.048645f, 0.055237f, 0.063171f, 0.071960f, 0.082031f, 0.093994f, 0.107300f, 0.122131f, 0.138550f,
+ 0.156494f, 0.177002f, 0.586426f, 0.625488f, 0.633789f, 0.637207f, 0.638672f, 0.639648f, 0.000199f, 0.000534f, 0.000745f, 0.000995f,
+ 0.001190f, 0.001387f, 0.001516f, 0.001691f, 0.001790f, 0.001941f, 0.002214f, 0.002346f, 0.002449f, 0.002686f, 0.002832f, 0.003042f,
+ 0.003304f, 0.003531f, 0.003662f, 0.003952f, 0.004181f, 0.004517f, 0.004704f, 0.005074f, 0.005352f, 0.005718f, 0.006096f, 0.006481f,
+ 0.006947f, 0.007454f, 0.007988f, 0.008484f, 0.009140f, 0.009804f, 0.010475f, 0.011307f, 0.012299f, 0.013268f, 0.014511f, 0.015823f,
+ 0.017410f, 0.018936f, 0.021225f, 0.023621f, 0.026367f, 0.029770f, 0.033661f, 0.038452f, 0.044067f, 0.050812f, 0.058411f, 0.067444f,
+ 0.077942f, 0.090149f, 0.104187f, 0.119812f, 0.137085f, 0.156372f, 0.572754f, 0.613770f, 0.621582f, 0.625977f, 0.627441f, 0.628906f,
+ 0.000165f, 0.000486f, 0.000618f, 0.000880f, 0.001063f, 0.001140f, 0.001258f, 0.001464f, 0.001498f, 0.001561f, 0.001707f, 0.001899f,
+ 0.001976f, 0.002171f, 0.002285f, 0.002474f, 0.002571f, 0.002764f, 0.002968f, 0.003170f, 0.003389f, 0.003580f, 0.003822f, 0.004036f,
+ 0.004269f, 0.004505f, 0.004738f, 0.005157f, 0.005474f, 0.005821f, 0.006279f, 0.006649f, 0.007107f, 0.007610f, 0.008240f, 0.008835f,
+ 0.009598f, 0.010361f, 0.011276f, 0.012299f, 0.013466f, 0.014740f, 0.016251f, 0.018021f, 0.020294f, 0.022797f, 0.025833f, 0.029739f,
+ 0.034058f, 0.039612f, 0.046021f, 0.053833f, 0.063110f, 0.074158f, 0.086914f, 0.101562f, 0.118164f, 0.136841f, 0.558594f, 0.601074f,
+ 0.608887f, 0.613281f, 0.615234f, 0.617188f, 0.000096f, 0.000348f, 0.000585f, 0.000707f, 0.000837f, 0.000866f, 0.000972f, 0.001095f,
+ 0.001198f, 0.001309f, 0.001355f, 0.001417f, 0.001615f, 0.001740f, 0.001863f, 0.001880f, 0.002048f, 0.002159f, 0.002380f, 0.002487f,
+ 0.002613f, 0.002777f, 0.003000f, 0.003143f, 0.003353f, 0.003521f, 0.003748f, 0.003963f, 0.004265f, 0.004490f, 0.004776f, 0.005093f,
+ 0.005577f, 0.005966f, 0.006321f, 0.006828f, 0.007320f, 0.007904f, 0.008575f, 0.009392f, 0.010231f, 0.011276f, 0.012321f, 0.013832f,
+ 0.015343f, 0.017242f, 0.019501f, 0.022247f, 0.025696f, 0.029922f, 0.035187f, 0.041779f, 0.049683f, 0.059387f, 0.070801f, 0.084106f,
+ 0.100037f, 0.117798f, 0.544434f, 0.588867f, 0.597656f, 0.602539f, 0.604492f, 0.605469f, 0.000123f, 0.000248f, 0.000443f, 0.000625f,
+ 0.000663f, 0.000733f, 0.000843f, 0.000780f, 0.000921f, 0.000986f, 0.001081f, 0.001178f, 0.001254f, 0.001348f, 0.001364f, 0.001515f,
+ 0.001565f, 0.001705f, 0.001824f, 0.001870f, 0.002066f, 0.002155f, 0.002274f, 0.002422f, 0.002525f, 0.002695f, 0.002863f, 0.003038f,
+ 0.003271f, 0.003441f, 0.003736f, 0.003901f, 0.004112f, 0.004478f, 0.004719f, 0.005093f, 0.005482f, 0.005913f, 0.006413f, 0.007019f,
+ 0.007626f, 0.008408f, 0.009201f, 0.010201f, 0.011436f, 0.012749f, 0.014389f, 0.016373f, 0.018906f, 0.022034f, 0.025909f, 0.031082f,
+ 0.037628f, 0.045715f, 0.055939f, 0.068176f, 0.082764f, 0.099365f, 0.529785f, 0.574707f, 0.584961f, 0.589844f, 0.591797f, 0.593750f,
+ 0.000210f, 0.000212f, 0.000365f, 0.000494f, 0.000438f, 0.000597f, 0.000538f, 0.000623f, 0.000638f, 0.000736f, 0.000866f, 0.000882f,
+ 0.000954f, 0.001040f, 0.001070f, 0.001086f, 0.001220f, 0.001274f, 0.001341f, 0.001457f, 0.001513f, 0.001598f, 0.001697f, 0.001781f,
+ 0.001898f, 0.001970f, 0.002131f, 0.002241f, 0.002401f, 0.002645f, 0.002783f, 0.002892f, 0.003120f, 0.003347f, 0.003508f, 0.003757f,
+ 0.004032f, 0.004314f, 0.004688f, 0.005066f, 0.005520f, 0.006012f, 0.006702f, 0.007332f, 0.008171f, 0.009140f, 0.010399f, 0.011787f,
+ 0.013496f, 0.015732f, 0.018509f, 0.022278f, 0.027267f, 0.033813f, 0.042328f, 0.053070f, 0.066406f, 0.082825f, 0.516602f, 0.562500f,
+ 0.573242f, 0.577637f, 0.580078f, 0.581543f, 0.000000f, 0.000216f, 0.000281f, 0.000346f, 0.000374f, 0.000388f, 0.000491f, 0.000416f,
+ 0.000516f, 0.000535f, 0.000635f, 0.000625f, 0.000681f, 0.000719f, 0.000790f, 0.000813f, 0.000879f, 0.000926f, 0.000968f, 0.001004f,
+ 0.001097f, 0.001135f, 0.001229f, 0.001300f, 0.001361f, 0.001431f, 0.001541f, 0.001610f, 0.001711f, 0.001802f, 0.001922f, 0.002094f,
+ 0.002169f, 0.002346f, 0.002468f, 0.002644f, 0.002844f, 0.003094f, 0.003368f, 0.003586f, 0.003883f, 0.004223f, 0.004662f, 0.005093f,
+ 0.005680f, 0.006348f, 0.007206f, 0.008202f, 0.009392f, 0.010895f, 0.012939f, 0.015465f, 0.018906f, 0.023682f, 0.030502f, 0.039825f,
+ 0.051331f, 0.066528f, 0.500977f, 0.548828f, 0.560059f, 0.564453f, 0.567871f, 0.569336f, 0.000000f, 0.000106f, 0.000201f, 0.000252f,
+ 0.000251f, 0.000322f, 0.000281f, 0.000340f, 0.000359f, 0.000428f, 0.000443f, 0.000419f, 0.000444f, 0.000500f, 0.000524f, 0.000590f,
+ 0.000574f, 0.000650f, 0.000693f, 0.000732f, 0.000778f, 0.000821f, 0.000848f, 0.000900f, 0.000965f, 0.000982f, 0.001072f, 0.001109f,
+ 0.001169f, 0.001307f, 0.001301f, 0.001409f, 0.001483f, 0.001610f, 0.001734f, 0.001835f, 0.001940f, 0.002098f, 0.002241f, 0.002426f,
+ 0.002634f, 0.002865f, 0.003136f, 0.003431f, 0.003763f, 0.004211f, 0.004742f, 0.005417f, 0.006229f, 0.007298f, 0.008621f, 0.010330f,
+ 0.012650f, 0.015808f, 0.020569f, 0.027908f, 0.037994f, 0.051514f, 0.485840f, 0.536133f, 0.547363f, 0.551758f, 0.554688f, 0.557617f,
+ 0.000026f, 0.000156f, 0.000201f, 0.000136f, 0.000188f, 0.000187f, 0.000192f, 0.000240f, 0.000245f, 0.000254f, 0.000262f, 0.000311f,
+ 0.000309f, 0.000331f, 0.000374f, 0.000385f, 0.000411f, 0.000431f, 0.000443f, 0.000461f, 0.000507f, 0.000522f, 0.000562f, 0.000596f,
+ 0.000634f, 0.000684f, 0.000718f, 0.000735f, 0.000776f, 0.000815f, 0.000875f, 0.000927f, 0.000982f, 0.001053f, 0.001123f, 0.001162f,
+ 0.001271f, 0.001346f, 0.001473f, 0.001577f, 0.001670f, 0.001838f, 0.002005f, 0.002161f, 0.002405f, 0.002670f, 0.002993f, 0.003399f,
+ 0.003860f, 0.004528f, 0.005386f, 0.006523f, 0.008003f, 0.010063f, 0.013206f, 0.017990f, 0.026031f, 0.038086f, 0.471191f, 0.522949f,
+ 0.534668f, 0.540039f, 0.543457f, 0.544922f, 0.000000f, 0.000093f, 0.000084f, 0.000085f, 0.000124f, 0.000145f, 0.000122f, 0.000149f,
+ 0.000152f, 0.000152f, 0.000158f, 0.000167f, 0.000186f, 0.000209f, 0.000217f, 0.000225f, 0.000231f, 0.000272f, 0.000273f, 0.000301f,
+ 0.000303f, 0.000310f, 0.000338f, 0.000361f, 0.000387f, 0.000423f, 0.000413f, 0.000436f, 0.000478f, 0.000503f, 0.000525f, 0.000570f,
+ 0.000608f, 0.000626f, 0.000677f, 0.000706f, 0.000753f, 0.000813f, 0.000884f, 0.000929f, 0.001000f, 0.001094f, 0.001183f, 0.001302f,
+ 0.001412f, 0.001563f, 0.001769f, 0.001974f, 0.002277f, 0.002626f, 0.003124f, 0.003761f, 0.004665f, 0.005993f, 0.007935f, 0.010818f,
+ 0.016205f, 0.026138f, 0.456299f, 0.509277f, 0.520996f, 0.527344f, 0.530762f, 0.532715f, 0.000105f, 0.000083f, 0.000072f, 0.000065f,
+ 0.000071f, 0.000072f, 0.000077f, 0.000084f, 0.000088f, 0.000093f, 0.000095f, 0.000120f, 0.000100f, 0.000108f, 0.000126f, 0.000118f,
+ 0.000139f, 0.000149f, 0.000153f, 0.000165f, 0.000169f, 0.000172f, 0.000194f, 0.000203f, 0.000233f, 0.000225f, 0.000233f, 0.000253f,
+ 0.000266f, 0.000275f, 0.000299f, 0.000319f, 0.000338f, 0.000345f, 0.000374f, 0.000384f, 0.000415f, 0.000448f, 0.000483f, 0.000511f,
+ 0.000543f, 0.000585f, 0.000647f, 0.000692f, 0.000755f, 0.000827f, 0.000924f, 0.001041f, 0.001186f, 0.001372f, 0.001608f, 0.001953f,
+ 0.002411f, 0.003098f, 0.004238f, 0.005989f, 0.009003f, 0.016006f, 0.441406f, 0.495361f, 0.508301f, 0.514160f, 0.518066f, 0.520508f,
+ 0.000090f, 0.000067f, 0.000058f, 0.000052f, 0.000047f, 0.000044f, 0.000044f, 0.000040f, 0.000042f, 0.000049f, 0.000042f, 0.000045f,
+ 0.000059f, 0.000047f, 0.000050f, 0.000054f, 0.000071f, 0.000073f, 0.000075f, 0.000078f, 0.000079f, 0.000084f, 0.000087f, 0.000090f,
+ 0.000097f, 0.000109f, 0.000108f, 0.000124f, 0.000124f, 0.000131f, 0.000138f, 0.000143f, 0.000155f, 0.000164f, 0.000178f, 0.000182f,
+ 0.000192f, 0.000209f, 0.000225f, 0.000244f, 0.000259f, 0.000274f, 0.000303f, 0.000321f, 0.000357f, 0.000385f, 0.000429f, 0.000470f,
+ 0.000537f, 0.000608f, 0.000710f, 0.000852f, 0.001052f, 0.001371f, 0.001877f, 0.002762f, 0.004406f, 0.008202f, 0.426270f, 0.483154f,
+ 0.495605f, 0.500977f, 0.505371f, 0.507324f, 0.000067f, 0.000047f, 0.000039f, 0.000035f, 0.000032f, 0.000030f, 0.000029f, 0.000027f,
+ 0.000026f, 0.000025f, 0.000024f, 0.000023f, 0.000021f, 0.000020f, 0.000019f, 0.000021f, 0.000020f, 0.000024f, 0.000028f, 0.000030f,
+ 0.000029f, 0.000032f, 0.000035f, 0.000034f, 0.000036f, 0.000044f, 0.000046f, 0.000040f, 0.000048f, 0.000047f, 0.000051f, 0.000053f,
+ 0.000059f, 0.000059f, 0.000064f, 0.000066f, 0.000077f, 0.000079f, 0.000081f, 0.000091f, 0.000094f, 0.000100f, 0.000108f, 0.000119f,
+ 0.000129f, 0.000137f, 0.000148f, 0.000173f, 0.000191f, 0.000210f, 0.000249f, 0.000292f, 0.000357f, 0.000448f, 0.000629f, 0.000943f,
+ 0.001630f, 0.003332f, 0.411377f, 0.468506f, 0.482910f, 0.488770f, 0.492188f, 0.495117f, 0.000025f, 0.000018f, 0.000015f, 0.000013f,
+ 0.000014f, 0.000013f, 0.000012f, 0.000012f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f,
+ 0.000011f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000009f, 0.000008f, 0.000008f, 0.000008f, 0.000008f, 0.000008f, 0.000007f,
+ 0.000008f, 0.000010f, 0.000010f, 0.000010f, 0.000012f, 0.000014f, 0.000014f, 0.000014f, 0.000016f, 0.000018f, 0.000019f, 0.000021f,
+ 0.000020f, 0.000023f, 0.000025f, 0.000027f, 0.000027f, 0.000029f, 0.000035f, 0.000033f, 0.000040f, 0.000044f, 0.000052f, 0.000061f,
+ 0.000069f, 0.000087f, 0.000117f, 0.000174f, 0.000319f, 0.000847f, 0.395996f, 0.454834f, 0.468750f, 0.475586f, 0.479004f, 0.481689f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000002f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000003f, 0.000004f, 0.000004f, 0.000005f, 0.000009f, 0.000027f, 0.381348f, 0.441406f,
+ 0.455566f, 0.462891f, 0.466309f, 0.468994f,
+ },
+ {
+ 0.016769f, 0.050629f, 0.083740f, 0.116638f, 0.148071f, 0.178955f, 0.208374f, 0.236938f, 0.265137f, 0.291992f, 0.317871f, 0.343994f,
+ 0.368164f, 0.391846f, 0.415527f, 0.437988f, 0.459717f, 0.480469f, 0.501465f, 0.520996f, 0.540527f, 0.559082f, 0.577637f, 0.594727f,
+ 0.612305f, 0.628418f, 0.644531f, 0.661133f, 0.676270f, 0.691406f, 0.705566f, 0.719727f, 0.734375f, 0.747070f, 0.760254f, 0.773438f,
+ 0.786133f, 0.798828f, 0.810059f, 0.821777f, 0.833008f, 0.843262f, 0.854492f, 0.865234f, 0.875488f, 0.885254f, 0.895508f, 0.904297f,
+ 0.913574f, 0.923340f, 0.932617f, 0.940918f, 0.949707f, 0.958008f, 0.966309f, 0.974609f, 0.981934f, 0.990234f, 0.985352f, 0.965332f,
+ 0.950195f, 0.937500f, 0.926270f, 0.915527f, 0.015083f, 0.045929f, 0.075806f, 0.105408f, 0.135254f, 0.163208f, 0.191772f, 0.219238f,
+ 0.245239f, 0.271973f, 0.297363f, 0.321045f, 0.345947f, 0.369141f, 0.391846f, 0.414062f, 0.435791f, 0.456787f, 0.477295f, 0.497314f,
+ 0.516113f, 0.535645f, 0.554199f, 0.571777f, 0.588867f, 0.606445f, 0.623047f, 0.639160f, 0.654785f, 0.669434f, 0.685059f, 0.699219f,
+ 0.713379f, 0.728027f, 0.741211f, 0.754883f, 0.767578f, 0.780273f, 0.792480f, 0.804688f, 0.815918f, 0.826660f, 0.838867f, 0.850098f,
+ 0.859863f, 0.871094f, 0.880859f, 0.891113f, 0.900879f, 0.909180f, 0.919434f, 0.929688f, 0.937500f, 0.946289f, 0.954590f, 0.963379f,
+ 0.971191f, 0.979004f, 0.980469f, 0.961426f, 0.947266f, 0.935059f, 0.924316f, 0.914062f, 0.013573f, 0.040955f, 0.068848f, 0.096313f,
+ 0.123169f, 0.150635f, 0.175537f, 0.202026f, 0.228271f, 0.251709f, 0.276367f, 0.300781f, 0.323730f, 0.347168f, 0.369385f, 0.390625f,
+ 0.412354f, 0.433594f, 0.454346f, 0.473145f, 0.491943f, 0.512207f, 0.529785f, 0.549316f, 0.566406f, 0.583008f, 0.600586f, 0.616211f,
+ 0.633301f, 0.648438f, 0.663574f, 0.679199f, 0.693359f, 0.708008f, 0.721680f, 0.735840f, 0.748535f, 0.762207f, 0.773926f, 0.786621f,
+ 0.798340f, 0.811035f, 0.822754f, 0.833984f, 0.845215f, 0.855957f, 0.865723f, 0.876465f, 0.886719f, 0.895508f, 0.906738f, 0.916016f,
+ 0.925293f, 0.934570f, 0.943848f, 0.952148f, 0.960449f, 0.969238f, 0.976074f, 0.958008f, 0.944336f, 0.932617f, 0.921875f, 0.912109f,
+ 0.012329f, 0.037201f, 0.062164f, 0.087646f, 0.112488f, 0.137451f, 0.161865f, 0.187134f, 0.210938f, 0.234253f, 0.258301f, 0.281006f,
+ 0.303467f, 0.325195f, 0.347656f, 0.368652f, 0.389648f, 0.410400f, 0.430664f, 0.450928f, 0.470215f, 0.488770f, 0.507812f, 0.525391f,
+ 0.543457f, 0.560059f, 0.579102f, 0.593750f, 0.611816f, 0.627441f, 0.643066f, 0.658203f, 0.672363f, 0.687500f, 0.702148f, 0.715820f,
+ 0.729004f, 0.742676f, 0.755371f, 0.768066f, 0.781738f, 0.792969f, 0.805176f, 0.816895f, 0.829102f, 0.839844f, 0.850586f, 0.861816f,
+ 0.872559f, 0.882812f, 0.893066f, 0.902832f, 0.912109f, 0.921875f, 0.930664f, 0.940430f, 0.948242f, 0.958008f, 0.970703f, 0.953613f,
+ 0.940430f, 0.929199f, 0.919434f, 0.910156f, 0.010979f, 0.033752f, 0.056763f, 0.080139f, 0.103516f, 0.126221f, 0.149414f, 0.172485f,
+ 0.195435f, 0.218262f, 0.240356f, 0.261719f, 0.284180f, 0.306396f, 0.326416f, 0.347900f, 0.368408f, 0.389160f, 0.408691f, 0.427979f,
+ 0.447754f, 0.467041f, 0.484863f, 0.502441f, 0.520996f, 0.538086f, 0.555664f, 0.573242f, 0.589355f, 0.604980f, 0.622559f, 0.637207f,
+ 0.652832f, 0.666992f, 0.680664f, 0.695801f, 0.710938f, 0.724121f, 0.737305f, 0.750977f, 0.763672f, 0.776855f, 0.789062f, 0.799805f,
+ 0.812012f, 0.824219f, 0.835449f, 0.846680f, 0.857910f, 0.868164f, 0.878418f, 0.889160f, 0.898926f, 0.909180f, 0.917969f, 0.928223f,
+ 0.937012f, 0.946777f, 0.965820f, 0.949707f, 0.937012f, 0.926270f, 0.916504f, 0.907715f, 0.009941f, 0.030746f, 0.051514f, 0.073181f,
+ 0.094116f, 0.116028f, 0.137817f, 0.158691f, 0.180664f, 0.202637f, 0.223511f, 0.244873f, 0.265869f, 0.285889f, 0.307129f, 0.327881f,
+ 0.347412f, 0.367188f, 0.387207f, 0.405762f, 0.425537f, 0.444092f, 0.462646f, 0.481201f, 0.499756f, 0.516602f, 0.533691f, 0.550781f,
+ 0.567383f, 0.583984f, 0.599609f, 0.616211f, 0.630859f, 0.647461f, 0.661621f, 0.676758f, 0.689453f, 0.704590f, 0.718750f, 0.731934f,
+ 0.745117f, 0.757812f, 0.770996f, 0.783691f, 0.796387f, 0.807617f, 0.819824f, 0.831543f, 0.842773f, 0.854004f, 0.864258f, 0.875488f,
+ 0.885742f, 0.895508f, 0.905762f, 0.915527f, 0.925781f, 0.934570f, 0.960449f, 0.945312f, 0.933594f, 0.922852f, 0.913574f, 0.905273f,
+ 0.009003f, 0.027756f, 0.046997f, 0.066711f, 0.085999f, 0.106506f, 0.127075f, 0.146973f, 0.166992f, 0.187500f, 0.207886f, 0.228149f,
+ 0.248169f, 0.268311f, 0.287842f, 0.307861f, 0.327393f, 0.347656f, 0.365967f, 0.385010f, 0.404541f, 0.422363f, 0.441162f, 0.458740f,
+ 0.477783f, 0.495117f, 0.512207f, 0.529297f, 0.546387f, 0.562012f, 0.578613f, 0.595215f, 0.610840f, 0.625977f, 0.641113f, 0.656738f,
+ 0.670410f, 0.685059f, 0.699707f, 0.714355f, 0.727051f, 0.741699f, 0.752441f, 0.767090f, 0.778809f, 0.791504f, 0.803711f, 0.815430f,
+ 0.827148f, 0.838867f, 0.850098f, 0.860840f, 0.872070f, 0.881836f, 0.893066f, 0.903809f, 0.913574f, 0.923828f, 0.955078f, 0.940918f,
+ 0.929199f, 0.919922f, 0.911133f, 0.902344f, 0.008469f, 0.025375f, 0.043121f, 0.060944f, 0.079468f, 0.097961f, 0.116394f, 0.135620f,
+ 0.154541f, 0.174072f, 0.193115f, 0.212280f, 0.231689f, 0.250732f, 0.270264f, 0.289307f, 0.307861f, 0.327148f, 0.345215f, 0.364990f,
+ 0.382812f, 0.401123f, 0.418945f, 0.437012f, 0.455811f, 0.472900f, 0.490234f, 0.507812f, 0.524414f, 0.541016f, 0.558105f, 0.573242f,
+ 0.590332f, 0.605469f, 0.620117f, 0.636230f, 0.651367f, 0.665039f, 0.679688f, 0.694336f, 0.708496f, 0.722168f, 0.735840f, 0.750000f,
+ 0.762695f, 0.774902f, 0.787598f, 0.798828f, 0.811523f, 0.823730f, 0.834473f, 0.846191f, 0.857910f, 0.868652f, 0.879883f, 0.891113f,
+ 0.900391f, 0.911133f, 0.949219f, 0.937012f, 0.925293f, 0.916016f, 0.907227f, 0.899414f, 0.007618f, 0.023178f, 0.039490f, 0.055542f,
+ 0.072937f, 0.090271f, 0.107605f, 0.125122f, 0.142944f, 0.160889f, 0.178955f, 0.197510f, 0.216553f, 0.234497f, 0.252686f, 0.271240f,
+ 0.289795f, 0.307861f, 0.326172f, 0.344238f, 0.362549f, 0.380859f, 0.398438f, 0.416504f, 0.433838f, 0.452393f, 0.468994f, 0.485840f,
+ 0.502930f, 0.519531f, 0.536133f, 0.553223f, 0.569336f, 0.584473f, 0.599609f, 0.615234f, 0.631348f, 0.646484f, 0.659668f, 0.675293f,
+ 0.689941f, 0.703125f, 0.716797f, 0.730957f, 0.744141f, 0.756836f, 0.771484f, 0.782227f, 0.795898f, 0.807617f, 0.819824f, 0.831543f,
+ 0.843750f, 0.854980f, 0.866211f, 0.877441f, 0.888672f, 0.898438f, 0.943359f, 0.931641f, 0.921387f, 0.912109f, 0.903809f, 0.896484f,
+ 0.007118f, 0.021255f, 0.035889f, 0.051514f, 0.066895f, 0.083191f, 0.098999f, 0.115540f, 0.132324f, 0.149292f, 0.166260f, 0.183716f,
+ 0.200928f, 0.218628f, 0.236084f, 0.253906f, 0.272217f, 0.289795f, 0.307617f, 0.325439f, 0.342529f, 0.360596f, 0.378906f, 0.395996f,
+ 0.413330f, 0.430908f, 0.447510f, 0.465332f, 0.481934f, 0.497803f, 0.514648f, 0.531738f, 0.547852f, 0.562988f, 0.579102f, 0.595215f,
+ 0.610840f, 0.625977f, 0.641113f, 0.655273f, 0.670410f, 0.685059f, 0.698730f, 0.712891f, 0.726074f, 0.739258f, 0.753418f, 0.766113f,
+ 0.779785f, 0.791992f, 0.803711f, 0.816406f, 0.829102f, 0.839844f, 0.852539f, 0.863770f, 0.874512f, 0.886719f, 0.937988f, 0.926758f,
+ 0.917480f, 0.908203f, 0.900391f, 0.893066f, 0.006481f, 0.019775f, 0.032928f, 0.047272f, 0.061371f, 0.076233f, 0.091064f, 0.107117f,
+ 0.122559f, 0.138062f, 0.154663f, 0.170532f, 0.187256f, 0.204346f, 0.220947f, 0.237915f, 0.254883f, 0.272217f, 0.289062f, 0.306641f,
+ 0.323730f, 0.341064f, 0.358643f, 0.375732f, 0.393555f, 0.410645f, 0.426758f, 0.444580f, 0.461182f, 0.477783f, 0.494141f, 0.510254f,
+ 0.526855f, 0.543457f, 0.559082f, 0.574219f, 0.590332f, 0.605957f, 0.621094f, 0.634766f, 0.650879f, 0.665039f, 0.679688f, 0.694824f,
+ 0.708008f, 0.722656f, 0.736816f, 0.749023f, 0.762695f, 0.775391f, 0.788086f, 0.801270f, 0.813965f, 0.826172f, 0.838379f, 0.849121f,
+ 0.861328f, 0.873535f, 0.932129f, 0.921875f, 0.912598f, 0.904297f, 0.896484f, 0.889160f, 0.005924f, 0.017899f, 0.030426f, 0.043427f,
+ 0.056824f, 0.070435f, 0.084106f, 0.098755f, 0.112976f, 0.128052f, 0.143311f, 0.158936f, 0.174072f, 0.189575f, 0.206421f, 0.222534f,
+ 0.238403f, 0.255615f, 0.271729f, 0.288818f, 0.305908f, 0.322021f, 0.339355f, 0.356445f, 0.373291f, 0.390137f, 0.407227f, 0.423584f,
+ 0.440430f, 0.457031f, 0.472900f, 0.489502f, 0.506836f, 0.521973f, 0.538574f, 0.554688f, 0.570312f, 0.585449f, 0.601074f, 0.616211f,
+ 0.631348f, 0.646484f, 0.661621f, 0.675781f, 0.690430f, 0.704590f, 0.717285f, 0.731934f, 0.746094f, 0.759277f, 0.771973f, 0.785156f,
+ 0.798340f, 0.810547f, 0.823242f, 0.835938f, 0.848145f, 0.860352f, 0.925781f, 0.916504f, 0.908203f, 0.900391f, 0.893066f, 0.886719f,
+ 0.005573f, 0.016693f, 0.028366f, 0.040192f, 0.052277f, 0.064880f, 0.078064f, 0.090698f, 0.105042f, 0.118591f, 0.133057f, 0.147461f,
+ 0.162231f, 0.177612f, 0.192383f, 0.207886f, 0.223633f, 0.239502f, 0.255615f, 0.272217f, 0.288330f, 0.304932f, 0.320312f, 0.337646f,
+ 0.354004f, 0.369873f, 0.386719f, 0.403320f, 0.419922f, 0.437012f, 0.453369f, 0.469482f, 0.485596f, 0.501465f, 0.517578f, 0.534180f,
+ 0.549316f, 0.565918f, 0.581055f, 0.595703f, 0.611328f, 0.626953f, 0.641602f, 0.657227f, 0.671387f, 0.686523f, 0.699707f, 0.714355f,
+ 0.729004f, 0.742676f, 0.756348f, 0.769043f, 0.782715f, 0.795410f, 0.809082f, 0.821289f, 0.833984f, 0.846680f, 0.919434f, 0.911133f,
+ 0.903320f, 0.895508f, 0.888672f, 0.882324f, 0.005016f, 0.015396f, 0.026169f, 0.037231f, 0.048126f, 0.059937f, 0.071716f, 0.084167f,
+ 0.096680f, 0.109558f, 0.123169f, 0.136719f, 0.150269f, 0.164917f, 0.179077f, 0.194580f, 0.208984f, 0.223877f, 0.239746f, 0.255127f,
+ 0.270996f, 0.286377f, 0.302490f, 0.319336f, 0.335205f, 0.351318f, 0.367432f, 0.383545f, 0.399902f, 0.415771f, 0.432373f, 0.448975f,
+ 0.465088f, 0.481934f, 0.497314f, 0.513672f, 0.529785f, 0.544434f, 0.561035f, 0.576660f, 0.592285f, 0.607422f, 0.622559f, 0.638184f,
+ 0.652344f, 0.667480f, 0.681641f, 0.696777f, 0.711426f, 0.725586f, 0.738770f, 0.753418f, 0.766602f, 0.779297f, 0.793945f, 0.807129f,
+ 0.819824f, 0.833008f, 0.913086f, 0.906738f, 0.898438f, 0.890625f, 0.884277f, 0.878418f, 0.004738f, 0.014053f, 0.024017f, 0.033752f,
+ 0.044495f, 0.055328f, 0.066467f, 0.078064f, 0.089661f, 0.102051f, 0.114258f, 0.126831f, 0.139771f, 0.153564f, 0.167114f, 0.181030f,
+ 0.195190f, 0.209839f, 0.224731f, 0.239136f, 0.253906f, 0.269531f, 0.285156f, 0.300293f, 0.317139f, 0.332520f, 0.348145f, 0.364990f,
+ 0.380859f, 0.396240f, 0.412109f, 0.428711f, 0.444336f, 0.460938f, 0.477295f, 0.492676f, 0.509277f, 0.524902f, 0.540527f, 0.556641f,
+ 0.572266f, 0.587402f, 0.604004f, 0.618164f, 0.633301f, 0.648438f, 0.664062f, 0.678223f, 0.693359f, 0.708008f, 0.722656f, 0.736328f,
+ 0.750000f, 0.764160f, 0.777832f, 0.791016f, 0.805176f, 0.817871f, 0.907227f, 0.900879f, 0.894043f, 0.886719f, 0.880371f, 0.874512f,
+ 0.004105f, 0.012741f, 0.022491f, 0.031769f, 0.041107f, 0.051208f, 0.061249f, 0.071777f, 0.083069f, 0.093811f, 0.105896f, 0.117554f,
+ 0.129761f, 0.142212f, 0.155273f, 0.168579f, 0.182251f, 0.196167f, 0.210449f, 0.223755f, 0.238525f, 0.253662f, 0.268799f, 0.283447f,
+ 0.298828f, 0.313965f, 0.329834f, 0.344971f, 0.361328f, 0.376953f, 0.393066f, 0.408691f, 0.424561f, 0.441406f, 0.457031f, 0.472656f,
+ 0.488770f, 0.504883f, 0.520996f, 0.536133f, 0.551758f, 0.567871f, 0.583496f, 0.599121f, 0.614258f, 0.629395f, 0.645996f, 0.660156f,
+ 0.675781f, 0.689453f, 0.704102f, 0.719727f, 0.733398f, 0.747559f, 0.761719f, 0.776367f, 0.789062f, 0.803223f, 0.899902f, 0.895020f,
+ 0.888184f, 0.881836f, 0.875488f, 0.870117f, 0.003925f, 0.011978f, 0.020538f, 0.028763f, 0.038269f, 0.047028f, 0.056732f, 0.066223f,
+ 0.076904f, 0.086731f, 0.097900f, 0.109314f, 0.120483f, 0.132324f, 0.144653f, 0.156982f, 0.169678f, 0.183228f, 0.196289f, 0.209961f,
+ 0.223633f, 0.237427f, 0.251953f, 0.266602f, 0.281982f, 0.296875f, 0.312012f, 0.326660f, 0.342041f, 0.357910f, 0.373779f, 0.389404f,
+ 0.404785f, 0.420166f, 0.436768f, 0.452637f, 0.468506f, 0.484863f, 0.500977f, 0.516602f, 0.531738f, 0.546875f, 0.563965f, 0.579102f,
+ 0.595215f, 0.610840f, 0.625977f, 0.641602f, 0.657227f, 0.671387f, 0.687500f, 0.702148f, 0.716309f, 0.731445f, 0.746094f, 0.760742f,
+ 0.774414f, 0.788086f, 0.893066f, 0.889648f, 0.882812f, 0.876953f, 0.870605f, 0.865723f, 0.003704f, 0.011169f, 0.019165f, 0.026550f,
+ 0.035339f, 0.043488f, 0.052277f, 0.061066f, 0.071045f, 0.080933f, 0.090576f, 0.101074f, 0.111877f, 0.122925f, 0.134277f, 0.146118f,
+ 0.157837f, 0.170288f, 0.183105f, 0.195557f, 0.209351f, 0.222900f, 0.236328f, 0.250732f, 0.264893f, 0.279297f, 0.294189f, 0.308838f,
+ 0.323975f, 0.339844f, 0.354736f, 0.370117f, 0.385986f, 0.401367f, 0.416504f, 0.432861f, 0.448486f, 0.463867f, 0.480469f, 0.497070f,
+ 0.511719f, 0.527832f, 0.544434f, 0.559570f, 0.575684f, 0.591797f, 0.606934f, 0.623047f, 0.638184f, 0.654297f, 0.668945f, 0.684570f,
+ 0.699219f, 0.714355f, 0.729492f, 0.744629f, 0.758789f, 0.773926f, 0.886230f, 0.883301f, 0.877441f, 0.871582f, 0.866211f, 0.860840f,
+ 0.003500f, 0.010292f, 0.017395f, 0.024963f, 0.032440f, 0.040344f, 0.048462f, 0.057098f, 0.065063f, 0.074646f, 0.083679f, 0.093445f,
+ 0.103882f, 0.114136f, 0.124451f, 0.135498f, 0.146606f, 0.158447f, 0.170410f, 0.182739f, 0.195435f, 0.208008f, 0.221558f, 0.234863f,
+ 0.248657f, 0.262695f, 0.276855f, 0.291748f, 0.306152f, 0.320801f, 0.335693f, 0.350830f, 0.365967f, 0.382080f, 0.396973f, 0.413330f,
+ 0.429199f, 0.444336f, 0.459473f, 0.476074f, 0.492188f, 0.507812f, 0.524414f, 0.540039f, 0.555664f, 0.571777f, 0.586914f, 0.604004f,
+ 0.619629f, 0.635742f, 0.650391f, 0.666504f, 0.682129f, 0.697754f, 0.712891f, 0.728027f, 0.743164f, 0.758301f, 0.878906f, 0.877441f,
+ 0.871582f, 0.866699f, 0.860840f, 0.856445f, 0.003084f, 0.009697f, 0.016403f, 0.022659f, 0.029892f, 0.037354f, 0.044281f, 0.052338f,
+ 0.060516f, 0.068970f, 0.077515f, 0.086243f, 0.096069f, 0.105713f, 0.115356f, 0.125610f, 0.136353f, 0.147339f, 0.158081f, 0.170410f,
+ 0.181396f, 0.194458f, 0.207275f, 0.219482f, 0.232910f, 0.246704f, 0.260010f, 0.274170f, 0.288330f, 0.302979f, 0.317383f, 0.332764f,
+ 0.347656f, 0.363037f, 0.378174f, 0.392578f, 0.408936f, 0.424316f, 0.440430f, 0.456299f, 0.472656f, 0.488525f, 0.503906f, 0.519531f,
+ 0.535645f, 0.552734f, 0.568359f, 0.584961f, 0.600586f, 0.616699f, 0.633301f, 0.648438f, 0.663574f, 0.679199f, 0.694824f, 0.710938f,
+ 0.726074f, 0.742188f, 0.872559f, 0.870605f, 0.865723f, 0.860840f, 0.855957f, 0.851074f, 0.002913f, 0.008781f, 0.014938f, 0.021759f,
+ 0.027878f, 0.034393f, 0.041412f, 0.048737f, 0.055969f, 0.063599f, 0.072021f, 0.080200f, 0.088928f, 0.097839f, 0.106934f, 0.116150f,
+ 0.126587f, 0.136353f, 0.147095f, 0.157715f, 0.169189f, 0.181519f, 0.193481f, 0.205933f, 0.217773f, 0.231323f, 0.244629f, 0.257812f,
+ 0.271240f, 0.285400f, 0.299561f, 0.314453f, 0.329590f, 0.343506f, 0.358887f, 0.373779f, 0.389648f, 0.405029f, 0.420410f, 0.437012f,
+ 0.452393f, 0.468262f, 0.484375f, 0.500000f, 0.516113f, 0.532227f, 0.548828f, 0.564941f, 0.581055f, 0.597168f, 0.612793f, 0.629883f,
+ 0.645508f, 0.662109f, 0.678223f, 0.694336f, 0.709473f, 0.726074f, 0.863770f, 0.864258f, 0.859863f, 0.854980f, 0.850586f, 0.846191f,
+ 0.002815f, 0.008194f, 0.013954f, 0.019653f, 0.025696f, 0.031982f, 0.038177f, 0.044830f, 0.051819f, 0.058502f, 0.066162f, 0.073792f,
+ 0.082031f, 0.090393f, 0.098999f, 0.107605f, 0.117493f, 0.126709f, 0.137207f, 0.146729f, 0.157593f, 0.168579f, 0.179810f, 0.191772f,
+ 0.203369f, 0.215820f, 0.228882f, 0.241455f, 0.254395f, 0.268311f, 0.282227f, 0.296631f, 0.310303f, 0.325439f, 0.339844f, 0.354736f,
+ 0.370361f, 0.385742f, 0.400879f, 0.416504f, 0.432617f, 0.448486f, 0.464355f, 0.479980f, 0.496094f, 0.513184f, 0.528809f, 0.545410f,
+ 0.561035f, 0.578613f, 0.594727f, 0.611328f, 0.626953f, 0.643555f, 0.660156f, 0.676270f, 0.693359f, 0.709473f, 0.856445f, 0.858398f,
+ 0.854492f, 0.849121f, 0.845215f, 0.841309f, 0.002583f, 0.007492f, 0.012878f, 0.018417f, 0.023941f, 0.029495f, 0.035339f, 0.041779f,
+ 0.047577f, 0.054047f, 0.061523f, 0.068787f, 0.075562f, 0.083313f, 0.091858f, 0.099792f, 0.108521f, 0.117615f, 0.126709f, 0.136108f,
+ 0.146851f, 0.156860f, 0.166992f, 0.178345f, 0.189819f, 0.202148f, 0.213623f, 0.225830f, 0.238892f, 0.252197f, 0.265137f, 0.278809f,
+ 0.292480f, 0.306885f, 0.321045f, 0.336914f, 0.350830f, 0.366943f, 0.381348f, 0.396240f, 0.412354f, 0.428223f, 0.444336f, 0.460449f,
+ 0.476318f, 0.493408f, 0.509277f, 0.525879f, 0.542480f, 0.559082f, 0.574707f, 0.591797f, 0.608398f, 0.625488f, 0.642090f, 0.659180f,
+ 0.675781f, 0.691406f, 0.848145f, 0.851562f, 0.848145f, 0.843750f, 0.838867f, 0.835449f, 0.002512f, 0.007374f, 0.012115f, 0.016983f,
+ 0.022064f, 0.027359f, 0.032715f, 0.038147f, 0.044373f, 0.050354f, 0.056641f, 0.063293f, 0.070190f, 0.077026f, 0.084717f, 0.092041f,
+ 0.100342f, 0.108398f, 0.117554f, 0.126221f, 0.135742f, 0.145142f, 0.155151f, 0.165771f, 0.176758f, 0.187988f, 0.199341f, 0.210815f,
+ 0.223389f, 0.236206f, 0.249023f, 0.261719f, 0.275879f, 0.289062f, 0.303467f, 0.317627f, 0.332520f, 0.347412f, 0.361816f, 0.377197f,
+ 0.393066f, 0.407959f, 0.424072f, 0.440186f, 0.457031f, 0.473145f, 0.489502f, 0.505859f, 0.522461f, 0.540039f, 0.555664f, 0.572754f,
+ 0.589844f, 0.606445f, 0.623535f, 0.640625f, 0.658203f, 0.675781f, 0.840820f, 0.843750f, 0.841309f, 0.836914f, 0.833984f, 0.830566f,
+ 0.002369f, 0.006668f, 0.011093f, 0.015778f, 0.020523f, 0.025223f, 0.030701f, 0.035339f, 0.040710f, 0.046600f, 0.051971f, 0.058075f,
+ 0.064819f, 0.071228f, 0.077942f, 0.085205f, 0.092224f, 0.100464f, 0.108398f, 0.116882f, 0.125610f, 0.134155f, 0.143555f, 0.153564f,
+ 0.164062f, 0.174316f, 0.185303f, 0.196899f, 0.208496f, 0.220093f, 0.232666f, 0.245239f, 0.258057f, 0.271729f, 0.285645f, 0.299561f,
+ 0.313721f, 0.328613f, 0.342773f, 0.358154f, 0.373535f, 0.388916f, 0.405518f, 0.419922f, 0.437012f, 0.453125f, 0.469238f, 0.486328f,
+ 0.502930f, 0.519531f, 0.536133f, 0.553223f, 0.571289f, 0.588379f, 0.605469f, 0.623047f, 0.640137f, 0.656250f, 0.833008f, 0.837402f,
+ 0.834473f, 0.831055f, 0.827637f, 0.824219f, 0.002188f, 0.006027f, 0.010582f, 0.014297f, 0.018921f, 0.023270f, 0.028183f, 0.032593f,
+ 0.037781f, 0.042999f, 0.048584f, 0.053650f, 0.059601f, 0.065369f, 0.071899f, 0.078369f, 0.085449f, 0.092407f, 0.099609f, 0.107788f,
+ 0.115601f, 0.124451f, 0.133301f, 0.142212f, 0.151978f, 0.161865f, 0.172363f, 0.182617f, 0.193970f, 0.205566f, 0.217407f, 0.229858f,
+ 0.241943f, 0.254639f, 0.268311f, 0.281494f, 0.295654f, 0.310059f, 0.324219f, 0.339600f, 0.353760f, 0.369629f, 0.385010f, 0.400879f,
+ 0.417725f, 0.433594f, 0.449219f, 0.465820f, 0.482910f, 0.499512f, 0.517090f, 0.534180f, 0.551270f, 0.568848f, 0.586426f, 0.604004f,
+ 0.622559f, 0.639160f, 0.824219f, 0.830078f, 0.827637f, 0.824707f, 0.821777f, 0.818359f, 0.002098f, 0.005634f, 0.009354f, 0.013557f,
+ 0.017685f, 0.021576f, 0.025604f, 0.030380f, 0.034943f, 0.039429f, 0.044281f, 0.049255f, 0.055023f, 0.060577f, 0.066101f, 0.072144f,
+ 0.078491f, 0.085083f, 0.091858f, 0.098999f, 0.106873f, 0.114502f, 0.122498f, 0.131592f, 0.140137f, 0.149536f, 0.159424f, 0.169556f,
+ 0.180054f, 0.191162f, 0.202026f, 0.213989f, 0.226318f, 0.239136f, 0.250977f, 0.264648f, 0.278320f, 0.291748f, 0.305908f, 0.320557f,
+ 0.334961f, 0.350342f, 0.365479f, 0.381592f, 0.397461f, 0.413818f, 0.429199f, 0.446289f, 0.462891f, 0.479736f, 0.496338f, 0.514160f,
+ 0.530762f, 0.548828f, 0.566406f, 0.584473f, 0.602539f, 0.621582f, 0.815918f, 0.823730f, 0.821289f, 0.817871f, 0.815430f, 0.812500f,
+ 0.001772f, 0.005249f, 0.008995f, 0.012260f, 0.016251f, 0.020020f, 0.024216f, 0.027603f, 0.032196f, 0.036377f, 0.041199f, 0.045410f,
+ 0.050110f, 0.055603f, 0.061005f, 0.066406f, 0.072327f, 0.077820f, 0.084290f, 0.090942f, 0.098083f, 0.105164f, 0.113037f, 0.120789f,
+ 0.129272f, 0.138062f, 0.147339f, 0.156982f, 0.166626f, 0.176758f, 0.187866f, 0.199097f, 0.210449f, 0.222412f, 0.234985f, 0.247559f,
+ 0.260742f, 0.273682f, 0.287598f, 0.302002f, 0.316650f, 0.331299f, 0.346191f, 0.362061f, 0.377686f, 0.393066f, 0.409668f, 0.426514f,
+ 0.443115f, 0.459717f, 0.476807f, 0.494629f, 0.511230f, 0.529785f, 0.547852f, 0.565430f, 0.583984f, 0.602539f, 0.806152f, 0.814453f,
+ 0.813965f, 0.811035f, 0.809082f, 0.806641f, 0.001631f, 0.005131f, 0.008186f, 0.011673f, 0.014938f, 0.018463f, 0.021957f, 0.025635f,
+ 0.029083f, 0.033325f, 0.037445f, 0.041840f, 0.046478f, 0.050751f, 0.055634f, 0.060760f, 0.065979f, 0.071472f, 0.077515f, 0.083801f,
+ 0.090027f, 0.096802f, 0.104065f, 0.110840f, 0.119080f, 0.127197f, 0.135498f, 0.144775f, 0.153931f, 0.163574f, 0.173462f, 0.184570f,
+ 0.195312f, 0.207153f, 0.218506f, 0.230591f, 0.243652f, 0.256348f, 0.270020f, 0.283691f, 0.297852f, 0.312744f, 0.326904f, 0.342529f,
+ 0.357910f, 0.373535f, 0.389404f, 0.406494f, 0.421875f, 0.439941f, 0.457275f, 0.474365f, 0.492432f, 0.509766f, 0.527832f, 0.546875f,
+ 0.564941f, 0.584473f, 0.797852f, 0.807129f, 0.807129f, 0.804199f, 0.801758f, 0.799316f, 0.001632f, 0.004704f, 0.007912f, 0.010788f,
+ 0.013870f, 0.017105f, 0.020187f, 0.023483f, 0.026932f, 0.030563f, 0.034332f, 0.038086f, 0.042694f, 0.046631f, 0.050995f, 0.055725f,
+ 0.060486f, 0.065674f, 0.070862f, 0.076721f, 0.082825f, 0.088623f, 0.094910f, 0.102112f, 0.109070f, 0.116516f, 0.124695f, 0.133057f,
+ 0.141968f, 0.151001f, 0.160522f, 0.170776f, 0.181030f, 0.191650f, 0.202881f, 0.214722f, 0.227417f, 0.239624f, 0.252686f, 0.265625f,
+ 0.279785f, 0.293213f, 0.308350f, 0.323242f, 0.338867f, 0.354248f, 0.370117f, 0.386475f, 0.403076f, 0.420410f, 0.437012f, 0.454102f,
+ 0.471924f, 0.490234f, 0.508789f, 0.526855f, 0.545410f, 0.564453f, 0.788086f, 0.799316f, 0.798828f, 0.797852f, 0.794434f, 0.791992f,
+ 0.001594f, 0.004177f, 0.007122f, 0.010201f, 0.012344f, 0.015839f, 0.018372f, 0.021683f, 0.024857f, 0.028534f, 0.031464f, 0.035034f,
+ 0.038879f, 0.042572f, 0.046295f, 0.051056f, 0.055389f, 0.059723f, 0.064697f, 0.069763f, 0.075073f, 0.080750f, 0.087219f, 0.093445f,
+ 0.099548f, 0.107056f, 0.114136f, 0.121887f, 0.130249f, 0.138794f, 0.147217f, 0.157104f, 0.166748f, 0.177124f, 0.187988f, 0.199097f,
+ 0.210693f, 0.222778f, 0.235352f, 0.248169f, 0.261719f, 0.275635f, 0.289062f, 0.303955f, 0.319336f, 0.334717f, 0.350098f, 0.365479f,
+ 0.382324f, 0.398926f, 0.416016f, 0.433594f, 0.451904f, 0.469238f, 0.487549f, 0.506348f, 0.525391f, 0.544922f, 0.779297f, 0.791504f,
+ 0.791504f, 0.789551f, 0.788086f, 0.786133f, 0.001365f, 0.004173f, 0.006222f, 0.008842f, 0.011703f, 0.014366f, 0.017242f, 0.020218f,
+ 0.022903f, 0.025787f, 0.028824f, 0.032227f, 0.035522f, 0.038818f, 0.042511f, 0.046326f, 0.050507f, 0.054657f, 0.058594f, 0.063660f,
+ 0.068359f, 0.073914f, 0.078918f, 0.085083f, 0.091125f, 0.097534f, 0.104126f, 0.111511f, 0.118896f, 0.126831f, 0.135742f, 0.144043f,
+ 0.153564f, 0.163330f, 0.173462f, 0.184082f, 0.195068f, 0.206787f, 0.218628f, 0.231079f, 0.243896f, 0.257080f, 0.270996f, 0.285645f,
+ 0.300049f, 0.314941f, 0.330322f, 0.346191f, 0.362305f, 0.379395f, 0.395508f, 0.412842f, 0.431641f, 0.448975f, 0.468262f, 0.487549f,
+ 0.505371f, 0.525391f, 0.769531f, 0.783691f, 0.783691f, 0.782715f, 0.781250f, 0.778809f, 0.001230f, 0.003925f, 0.006268f, 0.008659f,
+ 0.010796f, 0.013145f, 0.015617f, 0.018234f, 0.021133f, 0.023682f, 0.026215f, 0.029251f, 0.032349f, 0.035400f, 0.038696f, 0.042206f,
+ 0.045807f, 0.049377f, 0.053925f, 0.057953f, 0.062500f, 0.067078f, 0.071777f, 0.077271f, 0.082703f, 0.088806f, 0.094910f, 0.101379f,
+ 0.109192f, 0.115967f, 0.123779f, 0.131470f, 0.140259f, 0.149536f, 0.159302f, 0.169312f, 0.180054f, 0.190674f, 0.202515f, 0.214722f,
+ 0.226562f, 0.239624f, 0.253174f, 0.266602f, 0.281738f, 0.295898f, 0.311035f, 0.326904f, 0.342529f, 0.359131f, 0.375732f, 0.393066f,
+ 0.410400f, 0.428467f, 0.447510f, 0.466064f, 0.485596f, 0.504883f, 0.759277f, 0.774902f, 0.775879f, 0.774902f, 0.773438f, 0.771973f,
+ 0.001031f, 0.003601f, 0.005604f, 0.007858f, 0.009880f, 0.012146f, 0.014549f, 0.016998f, 0.019043f, 0.021362f, 0.024475f, 0.026566f,
+ 0.029358f, 0.032196f, 0.035248f, 0.038391f, 0.041656f, 0.045044f, 0.048553f, 0.052582f, 0.056213f, 0.060669f, 0.065186f, 0.070068f,
+ 0.074768f, 0.080322f, 0.086060f, 0.092102f, 0.098877f, 0.105408f, 0.112366f, 0.120239f, 0.128540f, 0.136597f, 0.145874f, 0.155396f,
+ 0.165283f, 0.175537f, 0.186401f, 0.198120f, 0.210083f, 0.222534f, 0.235229f, 0.248657f, 0.262451f, 0.277344f, 0.291504f, 0.307617f,
+ 0.322998f, 0.339111f, 0.354980f, 0.372559f, 0.390625f, 0.408936f, 0.426758f, 0.445312f, 0.466064f, 0.485840f, 0.749512f, 0.765137f,
+ 0.767578f, 0.767090f, 0.765137f, 0.764648f, 0.001161f, 0.003078f, 0.005310f, 0.007282f, 0.009201f, 0.011330f, 0.013214f, 0.015404f,
+ 0.017273f, 0.019409f, 0.021988f, 0.024078f, 0.026550f, 0.029358f, 0.032043f, 0.034454f, 0.037415f, 0.040710f, 0.043854f, 0.047272f,
+ 0.050659f, 0.054840f, 0.058777f, 0.063293f, 0.067566f, 0.072449f, 0.077759f, 0.083069f, 0.088928f, 0.095886f, 0.102478f, 0.109070f,
+ 0.116760f, 0.124390f, 0.132935f, 0.141479f, 0.151123f, 0.161011f, 0.171143f, 0.182007f, 0.193726f, 0.205688f, 0.218018f, 0.230835f,
+ 0.244507f, 0.258789f, 0.272949f, 0.287109f, 0.303467f, 0.319336f, 0.335449f, 0.352539f, 0.369873f, 0.387939f, 0.406250f, 0.425049f,
+ 0.444824f, 0.464844f, 0.739258f, 0.756348f, 0.758789f, 0.758789f, 0.757324f, 0.756836f, 0.001004f, 0.002939f, 0.005005f, 0.006779f,
+ 0.008453f, 0.010323f, 0.012177f, 0.013870f, 0.016052f, 0.018051f, 0.019638f, 0.022141f, 0.023956f, 0.026413f, 0.028870f, 0.031281f,
+ 0.033661f, 0.036591f, 0.039429f, 0.042542f, 0.045776f, 0.049011f, 0.053009f, 0.056885f, 0.061035f, 0.065186f, 0.069885f, 0.075134f,
+ 0.080505f, 0.085999f, 0.091858f, 0.098633f, 0.105591f, 0.112732f, 0.120667f, 0.128662f, 0.137573f, 0.146729f, 0.156372f, 0.166748f,
+ 0.177490f, 0.189331f, 0.201294f, 0.213501f, 0.226807f, 0.239746f, 0.254150f, 0.268555f, 0.283936f, 0.298828f, 0.316162f, 0.332275f,
+ 0.349609f, 0.367432f, 0.385498f, 0.404053f, 0.423828f, 0.443848f, 0.728516f, 0.747559f, 0.750488f, 0.750488f, 0.749512f, 0.748047f,
+ 0.000970f, 0.002523f, 0.004665f, 0.006203f, 0.007759f, 0.009491f, 0.011070f, 0.012802f, 0.014336f, 0.016266f, 0.017944f, 0.019852f,
+ 0.021805f, 0.023911f, 0.025818f, 0.028137f, 0.030579f, 0.032837f, 0.035248f, 0.038055f, 0.041046f, 0.044189f, 0.047333f, 0.050842f,
+ 0.054504f, 0.058502f, 0.062866f, 0.067383f, 0.071960f, 0.077393f, 0.082642f, 0.088928f, 0.095093f, 0.101685f, 0.108765f, 0.116272f,
+ 0.124451f, 0.133423f, 0.142212f, 0.152100f, 0.162354f, 0.172729f, 0.184692f, 0.196411f, 0.209106f, 0.221802f, 0.235718f, 0.250000f,
+ 0.265137f, 0.280029f, 0.296143f, 0.312012f, 0.329346f, 0.346924f, 0.364990f, 0.384277f, 0.403564f, 0.423340f, 0.718262f, 0.738770f,
+ 0.741211f, 0.742188f, 0.741211f, 0.740234f, 0.000785f, 0.002600f, 0.004028f, 0.005390f, 0.007275f, 0.008774f, 0.010124f, 0.011620f,
+ 0.013306f, 0.014427f, 0.015991f, 0.017838f, 0.019577f, 0.021469f, 0.023254f, 0.024902f, 0.027115f, 0.029190f, 0.031677f, 0.034088f,
+ 0.036682f, 0.039307f, 0.042175f, 0.045410f, 0.048553f, 0.052002f, 0.055908f, 0.060028f, 0.064270f, 0.068909f, 0.074097f, 0.079163f,
+ 0.085022f, 0.091309f, 0.097473f, 0.104797f, 0.112183f, 0.120239f, 0.128662f, 0.137451f, 0.146973f, 0.157471f, 0.168213f, 0.179810f,
+ 0.191650f, 0.204468f, 0.217529f, 0.231201f, 0.245605f, 0.260254f, 0.275879f, 0.292236f, 0.308838f, 0.326416f, 0.344238f, 0.363037f,
+ 0.382080f, 0.403076f, 0.707031f, 0.729980f, 0.732422f, 0.733398f, 0.733398f, 0.732910f, 0.000775f, 0.002190f, 0.003696f, 0.005081f,
+ 0.006397f, 0.007858f, 0.009239f, 0.010323f, 0.011803f, 0.012978f, 0.014328f, 0.015915f, 0.017349f, 0.019058f, 0.020630f, 0.022339f,
+ 0.024445f, 0.025909f, 0.028275f, 0.030151f, 0.032532f, 0.035065f, 0.037476f, 0.040283f, 0.042969f, 0.046448f, 0.049469f, 0.053314f,
+ 0.056976f, 0.061371f, 0.065613f, 0.070435f, 0.075623f, 0.081360f, 0.087341f, 0.093628f, 0.100220f, 0.107788f, 0.115845f, 0.123901f,
+ 0.133057f, 0.142456f, 0.152832f, 0.163574f, 0.174561f, 0.187012f, 0.199463f, 0.212646f, 0.226562f, 0.241455f, 0.256836f, 0.272705f,
+ 0.288818f, 0.305664f, 0.323486f, 0.341797f, 0.362305f, 0.382080f, 0.695312f, 0.719238f, 0.722656f, 0.724121f, 0.724121f, 0.723633f,
+ 0.000906f, 0.002022f, 0.003521f, 0.004963f, 0.005756f, 0.006847f, 0.008446f, 0.009392f, 0.010437f, 0.012039f, 0.012863f, 0.014343f,
+ 0.015457f, 0.016876f, 0.018295f, 0.019730f, 0.021484f, 0.023102f, 0.024689f, 0.026581f, 0.028717f, 0.030945f, 0.032928f, 0.035370f,
+ 0.037872f, 0.040894f, 0.043915f, 0.047028f, 0.050415f, 0.054169f, 0.058167f, 0.062286f, 0.067078f, 0.071960f, 0.077209f, 0.082947f,
+ 0.089417f, 0.096008f, 0.103271f, 0.110718f, 0.119324f, 0.128052f, 0.137817f, 0.147705f, 0.158691f, 0.169922f, 0.181519f, 0.195435f,
+ 0.208496f, 0.222534f, 0.237305f, 0.252441f, 0.268799f, 0.285645f, 0.302979f, 0.322266f, 0.340332f, 0.360840f, 0.683594f, 0.708984f,
+ 0.714355f, 0.715332f, 0.715820f, 0.715332f, 0.000700f, 0.002043f, 0.003139f, 0.004219f, 0.005417f, 0.006477f, 0.007442f, 0.008415f,
+ 0.009499f, 0.010475f, 0.011497f, 0.012619f, 0.013824f, 0.014969f, 0.016190f, 0.017639f, 0.018799f, 0.020386f, 0.021896f, 0.023560f,
+ 0.025131f, 0.027176f, 0.028900f, 0.031067f, 0.033295f, 0.035919f, 0.038239f, 0.041229f, 0.044373f, 0.047394f, 0.050934f, 0.054871f,
+ 0.058838f, 0.063293f, 0.068115f, 0.073303f, 0.078857f, 0.084839f, 0.091309f, 0.098328f, 0.106079f, 0.114136f, 0.123230f, 0.132690f,
+ 0.143066f, 0.153442f, 0.165161f, 0.177368f, 0.190186f, 0.203979f, 0.218262f, 0.232910f, 0.248901f, 0.265381f, 0.282227f, 0.301025f,
+ 0.319580f, 0.339355f, 0.672852f, 0.699707f, 0.704590f, 0.706055f, 0.706543f, 0.706055f, 0.000762f, 0.001804f, 0.002762f, 0.003914f,
+ 0.004791f, 0.005764f, 0.006542f, 0.007622f, 0.008606f, 0.009232f, 0.010178f, 0.011093f, 0.012108f, 0.013191f, 0.014412f, 0.015289f,
+ 0.016510f, 0.017731f, 0.019119f, 0.020615f, 0.022049f, 0.023483f, 0.025345f, 0.027100f, 0.028885f, 0.031067f, 0.033417f, 0.035797f,
+ 0.038422f, 0.041382f, 0.044495f, 0.047638f, 0.051178f, 0.055267f, 0.059387f, 0.064026f, 0.069092f, 0.074585f, 0.080566f, 0.087097f,
+ 0.093811f, 0.101624f, 0.109619f, 0.117798f, 0.127319f, 0.137817f, 0.148682f, 0.160278f, 0.172607f, 0.185669f, 0.199097f, 0.214233f,
+ 0.229492f, 0.245850f, 0.261963f, 0.280273f, 0.299316f, 0.319580f, 0.660645f, 0.689453f, 0.694824f, 0.696777f, 0.697266f, 0.697266f,
+ 0.000499f, 0.001527f, 0.002565f, 0.003622f, 0.004429f, 0.005138f, 0.005955f, 0.006691f, 0.007317f, 0.008156f, 0.008949f, 0.009903f,
+ 0.010635f, 0.011452f, 0.012512f, 0.013451f, 0.014503f, 0.015610f, 0.016632f, 0.017746f, 0.019073f, 0.020355f, 0.021957f, 0.023453f,
+ 0.025208f, 0.026932f, 0.028732f, 0.030945f, 0.033142f, 0.035614f, 0.038300f, 0.041199f, 0.044464f, 0.047760f, 0.051514f, 0.055573f,
+ 0.059998f, 0.064819f, 0.070312f, 0.075867f, 0.082275f, 0.088806f, 0.096436f, 0.104797f, 0.113342f, 0.122559f, 0.132568f, 0.143799f,
+ 0.155396f, 0.167725f, 0.181274f, 0.195068f, 0.209961f, 0.225708f, 0.242310f, 0.259766f, 0.277832f, 0.297363f, 0.648926f, 0.678711f,
+ 0.685059f, 0.687500f, 0.687500f, 0.687988f, 0.000653f, 0.001627f, 0.002562f, 0.003166f, 0.003872f, 0.004562f, 0.005287f, 0.005905f,
+ 0.006557f, 0.007309f, 0.007835f, 0.008621f, 0.009140f, 0.010109f, 0.010773f, 0.011627f, 0.012428f, 0.013351f, 0.014488f, 0.015472f,
+ 0.016479f, 0.017578f, 0.018845f, 0.020157f, 0.021591f, 0.023132f, 0.024765f, 0.026337f, 0.028473f, 0.030594f, 0.032867f, 0.035309f,
+ 0.037933f, 0.041107f, 0.044403f, 0.047852f, 0.051666f, 0.055756f, 0.060455f, 0.065552f, 0.070740f, 0.077454f, 0.083862f, 0.091125f,
+ 0.099304f, 0.107971f, 0.117859f, 0.127808f, 0.139038f, 0.150757f, 0.163574f, 0.176880f, 0.191162f, 0.206665f, 0.222656f, 0.239258f,
+ 0.257568f, 0.277100f, 0.636230f, 0.667969f, 0.675293f, 0.677734f, 0.678223f, 0.678711f, 0.000393f, 0.001375f, 0.002174f, 0.002773f,
+ 0.003334f, 0.004070f, 0.004692f, 0.005047f, 0.005672f, 0.006298f, 0.006893f, 0.007454f, 0.007957f, 0.008636f, 0.009171f, 0.010002f,
+ 0.010674f, 0.011574f, 0.012451f, 0.013145f, 0.014091f, 0.014893f, 0.016083f, 0.017151f, 0.018402f, 0.019714f, 0.021042f, 0.022415f,
+ 0.024155f, 0.026108f, 0.027786f, 0.030212f, 0.032379f, 0.034698f, 0.037415f, 0.040436f, 0.043793f, 0.047455f, 0.051727f, 0.056030f,
+ 0.061218f, 0.066284f, 0.072571f, 0.079041f, 0.086121f, 0.094299f, 0.102844f, 0.112305f, 0.122925f, 0.134033f, 0.145752f, 0.158569f,
+ 0.172729f, 0.187378f, 0.203003f, 0.219238f, 0.237671f, 0.255859f, 0.624023f, 0.657227f, 0.664062f, 0.666992f, 0.668457f, 0.668457f,
+ 0.000379f, 0.001404f, 0.001893f, 0.002403f, 0.002840f, 0.003458f, 0.004021f, 0.004459f, 0.004894f, 0.005527f, 0.005844f, 0.006256f,
+ 0.006866f, 0.007423f, 0.007957f, 0.008476f, 0.009155f, 0.009735f, 0.010422f, 0.011078f, 0.011925f, 0.012787f, 0.013458f, 0.014526f,
+ 0.015541f, 0.016632f, 0.017838f, 0.019028f, 0.020248f, 0.021851f, 0.023514f, 0.024979f, 0.027054f, 0.029236f, 0.031555f, 0.034180f,
+ 0.036713f, 0.040375f, 0.043854f, 0.047607f, 0.051727f, 0.056549f, 0.061768f, 0.067627f, 0.073792f, 0.081116f, 0.089111f, 0.097595f,
+ 0.107056f, 0.117371f, 0.128906f, 0.141113f, 0.154053f, 0.168579f, 0.183960f, 0.199585f, 0.216309f, 0.235352f, 0.612793f, 0.647949f,
+ 0.652832f, 0.656250f, 0.658691f, 0.658203f, 0.000506f, 0.001164f, 0.001575f, 0.002136f, 0.002600f, 0.003054f, 0.003405f, 0.003735f,
+ 0.004364f, 0.004681f, 0.004944f, 0.005569f, 0.005810f, 0.006187f, 0.006813f, 0.007233f, 0.007881f, 0.008217f, 0.008850f, 0.009293f,
+ 0.010109f, 0.010788f, 0.011543f, 0.012161f, 0.012993f, 0.013931f, 0.014809f, 0.015945f, 0.016983f, 0.018234f, 0.019440f, 0.020813f,
+ 0.022491f, 0.024261f, 0.026169f, 0.028458f, 0.030701f, 0.033295f, 0.036560f, 0.039520f, 0.043121f, 0.047333f, 0.052032f, 0.056885f,
+ 0.062561f, 0.068909f, 0.076111f, 0.083496f, 0.092407f, 0.101929f, 0.112671f, 0.124451f, 0.136719f, 0.150146f, 0.165039f, 0.180786f,
+ 0.197510f, 0.215210f, 0.597656f, 0.636230f, 0.642578f, 0.647461f, 0.647949f, 0.649902f, 0.000344f, 0.001057f, 0.001456f, 0.001907f,
+ 0.002377f, 0.002735f, 0.002983f, 0.003359f, 0.003651f, 0.003960f, 0.004311f, 0.004471f, 0.005009f, 0.005283f, 0.005653f, 0.006145f,
+ 0.006592f, 0.006889f, 0.007469f, 0.007889f, 0.008423f, 0.008911f, 0.009567f, 0.010124f, 0.010788f, 0.011574f, 0.012466f, 0.013123f,
+ 0.014053f, 0.015091f, 0.016159f, 0.017288f, 0.018539f, 0.020111f, 0.021698f, 0.023285f, 0.025024f, 0.027405f, 0.029800f, 0.032501f,
+ 0.035583f, 0.039001f, 0.042908f, 0.047302f, 0.052185f, 0.057465f, 0.063843f, 0.070984f, 0.078857f, 0.087463f, 0.097168f, 0.108215f,
+ 0.120117f, 0.132812f, 0.146851f, 0.161865f, 0.177856f, 0.195557f, 0.585449f, 0.624023f, 0.633301f, 0.636230f, 0.637695f, 0.638672f,
+ 0.000516f, 0.000847f, 0.001210f, 0.001663f, 0.002012f, 0.002218f, 0.002424f, 0.002861f, 0.002947f, 0.003275f, 0.003469f, 0.003819f,
+ 0.004169f, 0.004337f, 0.004658f, 0.005169f, 0.005424f, 0.005795f, 0.006138f, 0.006500f, 0.007057f, 0.007458f, 0.007874f, 0.008369f,
+ 0.008888f, 0.009583f, 0.010147f, 0.010864f, 0.011589f, 0.012428f, 0.013161f, 0.013931f, 0.015076f, 0.016266f, 0.017456f, 0.018845f,
+ 0.020432f, 0.022232f, 0.024094f, 0.026459f, 0.028809f, 0.031586f, 0.034973f, 0.038513f, 0.042755f, 0.047485f, 0.052643f, 0.058929f,
+ 0.065796f, 0.073792f, 0.082581f, 0.092407f, 0.103516f, 0.115723f, 0.128906f, 0.142944f, 0.158813f, 0.175781f, 0.572266f, 0.613770f,
+ 0.621094f, 0.625977f, 0.626953f, 0.628418f, 0.000262f, 0.000864f, 0.001096f, 0.001409f, 0.001576f, 0.001852f, 0.002047f, 0.002247f,
+ 0.002518f, 0.002741f, 0.002956f, 0.003157f, 0.003359f, 0.003597f, 0.003872f, 0.004230f, 0.004406f, 0.004772f, 0.005035f, 0.005379f,
+ 0.005695f, 0.006153f, 0.006485f, 0.006935f, 0.007275f, 0.007801f, 0.008301f, 0.008789f, 0.009300f, 0.009949f, 0.010727f, 0.011482f,
+ 0.012245f, 0.013145f, 0.014236f, 0.015236f, 0.016525f, 0.017838f, 0.019348f, 0.021088f, 0.023010f, 0.025253f, 0.027878f, 0.031128f,
+ 0.034149f, 0.038269f, 0.042694f, 0.047852f, 0.053833f, 0.060852f, 0.068665f, 0.077698f, 0.087891f, 0.099182f, 0.111633f, 0.125732f,
+ 0.140381f, 0.157227f, 0.558105f, 0.601562f, 0.610840f, 0.614746f, 0.617188f, 0.619141f, 0.000270f, 0.000683f, 0.000851f, 0.001138f,
+ 0.001346f, 0.001561f, 0.001701f, 0.001884f, 0.001984f, 0.002193f, 0.002455f, 0.002609f, 0.002743f, 0.002993f, 0.003159f, 0.003361f,
+ 0.003593f, 0.003883f, 0.004044f, 0.004360f, 0.004532f, 0.004971f, 0.005169f, 0.005573f, 0.005863f, 0.006252f, 0.006653f, 0.007095f,
+ 0.007572f, 0.008110f, 0.008713f, 0.009056f, 0.009827f, 0.010574f, 0.011307f, 0.012070f, 0.013069f, 0.014122f, 0.015297f, 0.016678f,
+ 0.018234f, 0.019775f, 0.021835f, 0.024216f, 0.026917f, 0.030151f, 0.033875f, 0.038147f, 0.043121f, 0.049408f, 0.056091f, 0.064026f,
+ 0.073059f, 0.083801f, 0.095276f, 0.108459f, 0.122803f, 0.138794f, 0.545410f, 0.590332f, 0.599609f, 0.603516f, 0.606445f, 0.607422f,
+ 0.000190f, 0.000607f, 0.000724f, 0.000989f, 0.001171f, 0.001265f, 0.001416f, 0.001602f, 0.001666f, 0.001761f, 0.001893f, 0.002102f,
+ 0.002199f, 0.002413f, 0.002537f, 0.002743f, 0.002850f, 0.003027f, 0.003258f, 0.003494f, 0.003729f, 0.003937f, 0.004204f, 0.004410f,
+ 0.004616f, 0.004921f, 0.005192f, 0.005604f, 0.005936f, 0.006298f, 0.006836f, 0.007233f, 0.007694f, 0.008224f, 0.008827f, 0.009506f,
+ 0.010262f, 0.011055f, 0.011978f, 0.012955f, 0.014099f, 0.015434f, 0.017029f, 0.018677f, 0.020813f, 0.023193f, 0.026169f, 0.029541f,
+ 0.033783f, 0.038513f, 0.044403f, 0.051208f, 0.059387f, 0.068665f, 0.079468f, 0.091858f, 0.105774f, 0.120728f, 0.530762f, 0.578125f,
+ 0.588379f, 0.592773f, 0.595215f, 0.597168f, 0.000151f, 0.000443f, 0.000673f, 0.000793f, 0.000937f, 0.000987f, 0.001092f, 0.001192f,
+ 0.001324f, 0.001460f, 0.001495f, 0.001565f, 0.001778f, 0.001944f, 0.002054f, 0.002096f, 0.002254f, 0.002338f, 0.002594f, 0.002737f,
+ 0.002886f, 0.003048f, 0.003294f, 0.003460f, 0.003679f, 0.003868f, 0.004086f, 0.004322f, 0.004642f, 0.004894f, 0.005199f, 0.005554f,
+ 0.006035f, 0.006451f, 0.006836f, 0.007359f, 0.007820f, 0.008461f, 0.009163f, 0.009956f, 0.010803f, 0.011871f, 0.012917f, 0.014343f,
+ 0.015900f, 0.017670f, 0.019791f, 0.022400f, 0.025589f, 0.029404f, 0.034210f, 0.039948f, 0.046936f, 0.055298f, 0.064941f, 0.076172f,
+ 0.089172f, 0.103821f, 0.517090f, 0.565918f, 0.576172f, 0.582031f, 0.584961f, 0.586426f, 0.000203f, 0.000287f, 0.000531f, 0.000688f,
+ 0.000738f, 0.000820f, 0.000915f, 0.000875f, 0.001036f, 0.001117f, 0.001215f, 0.001317f, 0.001374f, 0.001476f, 0.001524f, 0.001682f,
+ 0.001726f, 0.001867f, 0.002014f, 0.002056f, 0.002209f, 0.002365f, 0.002495f, 0.002663f, 0.002775f, 0.002953f, 0.003134f, 0.003325f,
+ 0.003567f, 0.003736f, 0.004070f, 0.004261f, 0.004494f, 0.004845f, 0.005116f, 0.005459f, 0.005928f, 0.006329f, 0.006863f, 0.007458f,
+ 0.008087f, 0.008873f, 0.009689f, 0.010651f, 0.011826f, 0.013130f, 0.014732f, 0.016617f, 0.018890f, 0.021912f, 0.025482f, 0.029938f,
+ 0.035736f, 0.042847f, 0.051453f, 0.061615f, 0.074158f, 0.087952f, 0.504395f, 0.554199f, 0.565918f, 0.569336f, 0.573242f, 0.574219f,
+ 0.000215f, 0.000259f, 0.000423f, 0.000534f, 0.000499f, 0.000649f, 0.000622f, 0.000690f, 0.000717f, 0.000817f, 0.000937f, 0.000984f,
+ 0.001045f, 0.001148f, 0.001182f, 0.001211f, 0.001339f, 0.001406f, 0.001463f, 0.001590f, 0.001666f, 0.001759f, 0.001867f, 0.001949f,
+ 0.002064f, 0.002176f, 0.002342f, 0.002453f, 0.002619f, 0.002871f, 0.003033f, 0.003101f, 0.003389f, 0.003620f, 0.003794f, 0.004059f,
+ 0.004368f, 0.004681f, 0.005035f, 0.005466f, 0.005917f, 0.006405f, 0.007092f, 0.007744f, 0.008591f, 0.009506f, 0.010567f, 0.011993f,
+ 0.013710f, 0.015762f, 0.018326f, 0.021759f, 0.026077f, 0.031891f, 0.039124f, 0.048462f, 0.059570f, 0.072571f, 0.489258f, 0.542480f,
+ 0.553223f, 0.558594f, 0.562012f, 0.563965f, 0.000067f, 0.000253f, 0.000305f, 0.000367f, 0.000422f, 0.000431f, 0.000530f, 0.000466f,
+ 0.000565f, 0.000590f, 0.000702f, 0.000690f, 0.000746f, 0.000795f, 0.000859f, 0.000897f, 0.000962f, 0.001021f, 0.001069f, 0.001105f,
+ 0.001207f, 0.001257f, 0.001354f, 0.001424f, 0.001483f, 0.001570f, 0.001687f, 0.001750f, 0.001857f, 0.001982f, 0.002071f, 0.002281f,
+ 0.002361f, 0.002527f, 0.002684f, 0.002846f, 0.003092f, 0.003342f, 0.003622f, 0.003866f, 0.004173f, 0.004520f, 0.004955f, 0.005428f,
+ 0.006023f, 0.006687f, 0.007481f, 0.008446f, 0.009628f, 0.011047f, 0.012840f, 0.015205f, 0.018326f, 0.022629f, 0.028442f, 0.036102f,
+ 0.046051f, 0.058197f, 0.476318f, 0.529785f, 0.541992f, 0.547852f, 0.550293f, 0.553223f, 0.000000f, 0.000118f, 0.000216f, 0.000288f,
+ 0.000272f, 0.000350f, 0.000312f, 0.000374f, 0.000395f, 0.000470f, 0.000488f, 0.000477f, 0.000495f, 0.000548f, 0.000573f, 0.000646f,
+ 0.000636f, 0.000714f, 0.000763f, 0.000803f, 0.000852f, 0.000897f, 0.000930f, 0.000985f, 0.001056f, 0.001089f, 0.001163f, 0.001210f,
+ 0.001281f, 0.001432f, 0.001431f, 0.001548f, 0.001622f, 0.001743f, 0.001869f, 0.001991f, 0.002104f, 0.002262f, 0.002428f, 0.002632f,
+ 0.002815f, 0.003077f, 0.003344f, 0.003656f, 0.004002f, 0.004478f, 0.004974f, 0.005627f, 0.006435f, 0.007481f, 0.008713f, 0.010307f,
+ 0.012291f, 0.015289f, 0.019409f, 0.025497f, 0.033966f, 0.045013f, 0.461914f, 0.517090f, 0.529297f, 0.536133f, 0.539551f, 0.541504f,
+ 0.000073f, 0.000175f, 0.000165f, 0.000149f, 0.000200f, 0.000208f, 0.000215f, 0.000260f, 0.000268f, 0.000277f, 0.000292f, 0.000341f,
+ 0.000334f, 0.000370f, 0.000413f, 0.000424f, 0.000449f, 0.000474f, 0.000488f, 0.000507f, 0.000555f, 0.000574f, 0.000616f, 0.000652f,
+ 0.000696f, 0.000746f, 0.000780f, 0.000804f, 0.000849f, 0.000888f, 0.000949f, 0.001011f, 0.001075f, 0.001151f, 0.001225f, 0.001266f,
+ 0.001385f, 0.001466f, 0.001596f, 0.001699f, 0.001808f, 0.001980f, 0.002157f, 0.002329f, 0.002544f, 0.002850f, 0.003178f, 0.003593f,
+ 0.004047f, 0.004658f, 0.005508f, 0.006565f, 0.007935f, 0.009819f, 0.012527f, 0.016647f, 0.023514f, 0.033173f, 0.447510f, 0.503906f,
+ 0.517578f, 0.523926f, 0.527344f, 0.529297f, 0.000000f, 0.000106f, 0.000097f, 0.000099f, 0.000136f, 0.000157f, 0.000129f, 0.000162f,
+ 0.000167f, 0.000172f, 0.000180f, 0.000186f, 0.000209f, 0.000227f, 0.000232f, 0.000248f, 0.000260f, 0.000291f, 0.000300f, 0.000327f,
+ 0.000335f, 0.000343f, 0.000363f, 0.000395f, 0.000428f, 0.000459f, 0.000458f, 0.000477f, 0.000515f, 0.000549f, 0.000578f, 0.000621f,
+ 0.000659f, 0.000683f, 0.000741f, 0.000767f, 0.000818f, 0.000877f, 0.000952f, 0.001010f, 0.001085f, 0.001177f, 0.001275f, 0.001406f,
+ 0.001516f, 0.001664f, 0.001884f, 0.002096f, 0.002415f, 0.002745f, 0.003231f, 0.003843f, 0.004715f, 0.005936f, 0.007629f, 0.010139f,
+ 0.014763f, 0.022812f, 0.433350f, 0.491455f, 0.506348f, 0.511719f, 0.515625f, 0.518066f, 0.000104f, 0.000080f, 0.000069f, 0.000062f,
+ 0.000074f, 0.000074f, 0.000089f, 0.000097f, 0.000099f, 0.000102f, 0.000105f, 0.000126f, 0.000106f, 0.000119f, 0.000139f, 0.000135f,
+ 0.000154f, 0.000164f, 0.000166f, 0.000175f, 0.000188f, 0.000194f, 0.000211f, 0.000220f, 0.000252f, 0.000248f, 0.000260f, 0.000272f,
+ 0.000293f, 0.000301f, 0.000328f, 0.000347f, 0.000365f, 0.000371f, 0.000401f, 0.000422f, 0.000447f, 0.000489f, 0.000524f, 0.000553f,
+ 0.000588f, 0.000635f, 0.000701f, 0.000751f, 0.000816f, 0.000897f, 0.000997f, 0.001109f, 0.001265f, 0.001460f, 0.001686f, 0.002035f,
+ 0.002457f, 0.003130f, 0.004124f, 0.005676f, 0.008263f, 0.014114f, 0.418945f, 0.479492f, 0.493652f, 0.500000f, 0.503418f, 0.506836f,
+ 0.000089f, 0.000065f, 0.000056f, 0.000050f, 0.000045f, 0.000042f, 0.000046f, 0.000042f, 0.000043f, 0.000055f, 0.000046f, 0.000049f,
+ 0.000065f, 0.000055f, 0.000057f, 0.000063f, 0.000075f, 0.000080f, 0.000078f, 0.000084f, 0.000085f, 0.000092f, 0.000097f, 0.000102f,
+ 0.000108f, 0.000117f, 0.000118f, 0.000138f, 0.000135f, 0.000142f, 0.000151f, 0.000160f, 0.000172f, 0.000180f, 0.000195f, 0.000197f,
+ 0.000210f, 0.000230f, 0.000244f, 0.000266f, 0.000279f, 0.000299f, 0.000324f, 0.000352f, 0.000383f, 0.000414f, 0.000457f, 0.000509f,
+ 0.000575f, 0.000650f, 0.000756f, 0.000904f, 0.001103f, 0.001410f, 0.001880f, 0.002668f, 0.004112f, 0.007290f, 0.404541f, 0.466309f,
+ 0.481201f, 0.488037f, 0.492432f, 0.495361f, 0.000066f, 0.000046f, 0.000038f, 0.000034f, 0.000031f, 0.000029f, 0.000027f, 0.000026f,
+ 0.000025f, 0.000023f, 0.000022f, 0.000024f, 0.000020f, 0.000021f, 0.000021f, 0.000026f, 0.000024f, 0.000028f, 0.000031f, 0.000032f,
+ 0.000032f, 0.000035f, 0.000040f, 0.000038f, 0.000041f, 0.000047f, 0.000049f, 0.000043f, 0.000050f, 0.000052f, 0.000056f, 0.000059f,
+ 0.000066f, 0.000062f, 0.000067f, 0.000071f, 0.000082f, 0.000083f, 0.000089f, 0.000098f, 0.000104f, 0.000107f, 0.000116f, 0.000125f,
+ 0.000141f, 0.000149f, 0.000160f, 0.000183f, 0.000207f, 0.000228f, 0.000264f, 0.000311f, 0.000376f, 0.000469f, 0.000646f, 0.000937f,
+ 0.001554f, 0.002983f, 0.390381f, 0.454346f, 0.469727f, 0.476318f, 0.480713f, 0.484131f, 0.000028f, 0.000019f, 0.000015f, 0.000014f,
+ 0.000014f, 0.000013f, 0.000012f, 0.000012f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000010f,
+ 0.000010f, 0.000009f, 0.000009f, 0.000009f, 0.000008f, 0.000008f, 0.000008f, 0.000007f, 0.000008f, 0.000009f, 0.000009f, 0.000010f,
+ 0.000010f, 0.000011f, 0.000012f, 0.000011f, 0.000014f, 0.000015f, 0.000016f, 0.000016f, 0.000018f, 0.000019f, 0.000019f, 0.000022f,
+ 0.000023f, 0.000024f, 0.000026f, 0.000028f, 0.000029f, 0.000032f, 0.000037f, 0.000037f, 0.000042f, 0.000048f, 0.000056f, 0.000066f,
+ 0.000077f, 0.000091f, 0.000124f, 0.000183f, 0.000318f, 0.000779f, 0.376465f, 0.441406f, 0.457275f, 0.464600f, 0.468994f, 0.471924f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000003f, 0.000004f, 0.000004f, 0.000005f, 0.000010f, 0.000027f, 0.363037f, 0.428223f,
+ 0.444580f, 0.452881f, 0.457031f, 0.459961f,
+ },
+ {
+ 0.014420f, 0.043488f, 0.072388f, 0.100830f, 0.129150f, 0.156494f, 0.183350f, 0.210327f, 0.235352f, 0.260986f, 0.285645f, 0.309082f,
+ 0.332764f, 0.355713f, 0.377441f, 0.399658f, 0.420898f, 0.441650f, 0.461914f, 0.481445f, 0.500977f, 0.520508f, 0.538574f, 0.556641f,
+ 0.574707f, 0.591797f, 0.608398f, 0.624512f, 0.641602f, 0.657227f, 0.672363f, 0.687500f, 0.702148f, 0.717285f, 0.730957f, 0.745117f,
+ 0.758789f, 0.772461f, 0.783203f, 0.797363f, 0.810547f, 0.822266f, 0.833984f, 0.845703f, 0.857422f, 0.868652f, 0.879395f, 0.890625f,
+ 0.901367f, 0.911621f, 0.921875f, 0.932129f, 0.941895f, 0.951660f, 0.960938f, 0.970215f, 0.979492f, 0.987793f, 0.981934f, 0.957031f,
+ 0.938965f, 0.923340f, 0.909668f, 0.897461f, 0.013199f, 0.039978f, 0.066284f, 0.093445f, 0.119324f, 0.145386f, 0.170410f, 0.195801f,
+ 0.220581f, 0.244019f, 0.268066f, 0.291260f, 0.314453f, 0.335938f, 0.358154f, 0.379639f, 0.399902f, 0.420898f, 0.441406f, 0.460938f,
+ 0.480225f, 0.498291f, 0.516602f, 0.535156f, 0.553223f, 0.570312f, 0.587891f, 0.603516f, 0.620117f, 0.636719f, 0.652832f, 0.667480f,
+ 0.682617f, 0.696777f, 0.711914f, 0.726074f, 0.739746f, 0.753418f, 0.766602f, 0.779785f, 0.791992f, 0.804688f, 0.817871f, 0.829102f,
+ 0.841309f, 0.852539f, 0.864258f, 0.875488f, 0.886230f, 0.896973f, 0.907227f, 0.917969f, 0.928223f, 0.937500f, 0.947266f, 0.957520f,
+ 0.966797f, 0.975586f, 0.976562f, 0.952637f, 0.935547f, 0.920898f, 0.907715f, 0.895996f, 0.011932f, 0.036499f, 0.061554f, 0.085999f,
+ 0.110962f, 0.135010f, 0.158813f, 0.182373f, 0.206421f, 0.229004f, 0.251221f, 0.274170f, 0.295654f, 0.317871f, 0.339111f, 0.360107f,
+ 0.379395f, 0.399414f, 0.420654f, 0.440430f, 0.458252f, 0.477295f, 0.496094f, 0.513672f, 0.531738f, 0.549805f, 0.566406f, 0.583984f,
+ 0.599121f, 0.616211f, 0.631348f, 0.647461f, 0.662598f, 0.677734f, 0.692383f, 0.705566f, 0.720703f, 0.734863f, 0.748047f, 0.761230f,
+ 0.774414f, 0.787598f, 0.799805f, 0.812500f, 0.824707f, 0.837402f, 0.848633f, 0.859375f, 0.871094f, 0.882324f, 0.892578f, 0.904297f,
+ 0.913574f, 0.924316f, 0.934570f, 0.943848f, 0.954102f, 0.963867f, 0.970703f, 0.948242f, 0.931641f, 0.917480f, 0.905273f, 0.894043f,
+ 0.011070f, 0.033478f, 0.056396f, 0.079529f, 0.101990f, 0.125244f, 0.147705f, 0.170410f, 0.192139f, 0.214111f, 0.235596f, 0.257812f,
+ 0.279053f, 0.300293f, 0.320557f, 0.340576f, 0.360596f, 0.381104f, 0.400635f, 0.420166f, 0.438965f, 0.458008f, 0.476562f, 0.493652f,
+ 0.511230f, 0.527832f, 0.545898f, 0.562012f, 0.579102f, 0.595703f, 0.610840f, 0.627930f, 0.642578f, 0.657227f, 0.672363f, 0.686523f,
+ 0.701660f, 0.715332f, 0.729492f, 0.742676f, 0.756348f, 0.769531f, 0.782227f, 0.795898f, 0.807617f, 0.820312f, 0.832031f, 0.843262f,
+ 0.855469f, 0.866699f, 0.877441f, 0.889648f, 0.899414f, 0.910156f, 0.920410f, 0.930664f, 0.940430f, 0.950684f, 0.964844f, 0.943848f,
+ 0.927734f, 0.914551f, 0.902344f, 0.891602f, 0.010010f, 0.031067f, 0.051880f, 0.073303f, 0.094421f, 0.116577f, 0.136963f, 0.157959f,
+ 0.180542f, 0.200684f, 0.221436f, 0.242676f, 0.262939f, 0.283447f, 0.303467f, 0.323242f, 0.342529f, 0.362305f, 0.381348f, 0.399414f,
+ 0.418701f, 0.437256f, 0.455322f, 0.472412f, 0.490479f, 0.507812f, 0.524902f, 0.541992f, 0.558105f, 0.574219f, 0.591309f, 0.606445f,
+ 0.622070f, 0.637695f, 0.652344f, 0.666504f, 0.683594f, 0.695801f, 0.710449f, 0.724121f, 0.737305f, 0.751465f, 0.765137f, 0.777344f,
+ 0.790039f, 0.802734f, 0.814941f, 0.827637f, 0.839355f, 0.851074f, 0.862305f, 0.874512f, 0.885254f, 0.895996f, 0.906738f, 0.917480f,
+ 0.927246f, 0.937988f, 0.958984f, 0.939453f, 0.923828f, 0.911133f, 0.899414f, 0.889160f, 0.009491f, 0.028305f, 0.047699f, 0.067810f,
+ 0.087341f, 0.107849f, 0.127686f, 0.147827f, 0.167725f, 0.187744f, 0.207886f, 0.227051f, 0.247314f, 0.266846f, 0.286377f, 0.305908f,
+ 0.324463f, 0.343262f, 0.361572f, 0.380371f, 0.399658f, 0.416748f, 0.435547f, 0.452881f, 0.470703f, 0.488281f, 0.503906f, 0.522461f,
+ 0.538086f, 0.554199f, 0.571289f, 0.586914f, 0.602051f, 0.617676f, 0.633789f, 0.647949f, 0.663086f, 0.677246f, 0.692871f, 0.705078f,
+ 0.718750f, 0.732910f, 0.746582f, 0.759766f, 0.773438f, 0.785645f, 0.798340f, 0.811035f, 0.823242f, 0.834961f, 0.847168f, 0.859863f,
+ 0.870117f, 0.881348f, 0.893066f, 0.903320f, 0.914551f, 0.924316f, 0.953125f, 0.934082f, 0.919434f, 0.906738f, 0.896484f, 0.885742f,
+ 0.008598f, 0.026245f, 0.044495f, 0.062622f, 0.081177f, 0.100098f, 0.119019f, 0.137817f, 0.156616f, 0.175903f, 0.194946f, 0.213745f,
+ 0.232788f, 0.251221f, 0.269775f, 0.288330f, 0.307129f, 0.325928f, 0.344238f, 0.362305f, 0.380371f, 0.397705f, 0.415771f, 0.433105f,
+ 0.450928f, 0.468262f, 0.484863f, 0.501953f, 0.518555f, 0.534668f, 0.550293f, 0.566406f, 0.582520f, 0.598145f, 0.612305f, 0.627930f,
+ 0.643555f, 0.657715f, 0.672852f, 0.687500f, 0.700684f, 0.715332f, 0.728516f, 0.742188f, 0.755371f, 0.769531f, 0.781738f, 0.794434f,
+ 0.807129f, 0.818359f, 0.831543f, 0.843262f, 0.855469f, 0.865723f, 0.877930f, 0.889160f, 0.900391f, 0.911621f, 0.946777f, 0.929199f,
+ 0.915039f, 0.903320f, 0.892578f, 0.883301f, 0.007896f, 0.024490f, 0.041138f, 0.057892f, 0.075439f, 0.092712f, 0.110229f, 0.128296f,
+ 0.146118f, 0.164429f, 0.181885f, 0.200562f, 0.218628f, 0.236572f, 0.255127f, 0.272949f, 0.291016f, 0.308594f, 0.326172f, 0.343994f,
+ 0.361816f, 0.380127f, 0.396973f, 0.414551f, 0.430908f, 0.447998f, 0.465576f, 0.481445f, 0.497559f, 0.514160f, 0.529785f, 0.546387f,
+ 0.562988f, 0.578613f, 0.593262f, 0.609375f, 0.623047f, 0.638672f, 0.653809f, 0.667480f, 0.681641f, 0.697266f, 0.710938f, 0.724121f,
+ 0.737305f, 0.752441f, 0.765625f, 0.776367f, 0.790527f, 0.803223f, 0.815918f, 0.827637f, 0.839844f, 0.851562f, 0.863281f, 0.875000f,
+ 0.886719f, 0.898926f, 0.940430f, 0.923828f, 0.910645f, 0.899414f, 0.889160f, 0.879883f, 0.007320f, 0.022369f, 0.038055f, 0.053925f,
+ 0.070190f, 0.086609f, 0.103027f, 0.119568f, 0.136475f, 0.153320f, 0.170532f, 0.187988f, 0.204834f, 0.223022f, 0.240112f, 0.257324f,
+ 0.275391f, 0.291504f, 0.308838f, 0.326904f, 0.344727f, 0.361572f, 0.378662f, 0.395020f, 0.411865f, 0.428711f, 0.445068f, 0.462646f,
+ 0.478271f, 0.494141f, 0.510254f, 0.525879f, 0.542480f, 0.557129f, 0.573242f, 0.588867f, 0.603516f, 0.618164f, 0.633789f, 0.648438f,
+ 0.663086f, 0.678223f, 0.691895f, 0.706543f, 0.720215f, 0.733398f, 0.746582f, 0.759766f, 0.774414f, 0.786621f, 0.799805f, 0.811523f,
+ 0.823730f, 0.836914f, 0.848145f, 0.860840f, 0.872070f, 0.884277f, 0.933594f, 0.918945f, 0.906250f, 0.895020f, 0.885254f, 0.876953f,
+ 0.006760f, 0.021011f, 0.034973f, 0.050049f, 0.065369f, 0.080261f, 0.095337f, 0.111633f, 0.127319f, 0.142822f, 0.159668f, 0.176514f,
+ 0.192383f, 0.209106f, 0.225586f, 0.242554f, 0.259277f, 0.275635f, 0.292480f, 0.309326f, 0.326904f, 0.343750f, 0.359619f, 0.376465f,
+ 0.393066f, 0.409424f, 0.426514f, 0.442871f, 0.458252f, 0.475586f, 0.490967f, 0.505859f, 0.522461f, 0.539062f, 0.554199f, 0.569336f,
+ 0.583984f, 0.600586f, 0.614258f, 0.630371f, 0.643555f, 0.658691f, 0.673340f, 0.687500f, 0.702148f, 0.715332f, 0.729980f, 0.743652f,
+ 0.756348f, 0.770020f, 0.782715f, 0.796387f, 0.808105f, 0.820801f, 0.833008f, 0.846680f, 0.857910f, 0.870117f, 0.927246f, 0.913574f,
+ 0.901367f, 0.891113f, 0.881348f, 0.873047f, 0.006367f, 0.019165f, 0.032379f, 0.046295f, 0.060089f, 0.074463f, 0.088867f, 0.103821f,
+ 0.118835f, 0.133911f, 0.149048f, 0.164673f, 0.180298f, 0.196289f, 0.212524f, 0.228516f, 0.244385f, 0.260742f, 0.277344f, 0.293213f,
+ 0.309570f, 0.326416f, 0.342773f, 0.358887f, 0.374512f, 0.391113f, 0.406982f, 0.423340f, 0.439453f, 0.455078f, 0.470947f, 0.487793f,
+ 0.502441f, 0.519043f, 0.533691f, 0.550293f, 0.564941f, 0.580078f, 0.595703f, 0.610840f, 0.625488f, 0.640137f, 0.654785f, 0.669434f,
+ 0.683594f, 0.696777f, 0.710938f, 0.725586f, 0.738770f, 0.752441f, 0.766113f, 0.778320f, 0.791016f, 0.805176f, 0.818359f, 0.830566f,
+ 0.842773f, 0.854980f, 0.920410f, 0.908203f, 0.896484f, 0.886230f, 0.877441f, 0.868652f, 0.005981f, 0.017914f, 0.030350f, 0.042908f,
+ 0.056213f, 0.069092f, 0.083008f, 0.096619f, 0.111084f, 0.124634f, 0.139526f, 0.154297f, 0.169312f, 0.184570f, 0.199951f, 0.215454f,
+ 0.230713f, 0.245728f, 0.261963f, 0.277588f, 0.293213f, 0.309326f, 0.325195f, 0.340820f, 0.356934f, 0.373047f, 0.388916f, 0.404785f,
+ 0.420410f, 0.436279f, 0.452148f, 0.468506f, 0.483154f, 0.499756f, 0.515137f, 0.530762f, 0.545898f, 0.560059f, 0.576172f, 0.590820f,
+ 0.606445f, 0.621094f, 0.635254f, 0.649902f, 0.663574f, 0.678223f, 0.692383f, 0.706543f, 0.720703f, 0.733887f, 0.748535f, 0.762695f,
+ 0.775391f, 0.789551f, 0.801758f, 0.814941f, 0.828125f, 0.840332f, 0.913574f, 0.902344f, 0.890625f, 0.881836f, 0.872559f, 0.865234f,
+ 0.005402f, 0.016617f, 0.028061f, 0.039948f, 0.051758f, 0.064270f, 0.076782f, 0.089600f, 0.102600f, 0.116455f, 0.130371f, 0.144165f,
+ 0.158936f, 0.172607f, 0.187744f, 0.201904f, 0.216431f, 0.232422f, 0.247192f, 0.261719f, 0.277100f, 0.292480f, 0.308838f, 0.323975f,
+ 0.339355f, 0.355469f, 0.371338f, 0.386230f, 0.402344f, 0.417725f, 0.433350f, 0.448486f, 0.464600f, 0.480225f, 0.495361f, 0.510742f,
+ 0.525879f, 0.541992f, 0.557129f, 0.571777f, 0.586914f, 0.601562f, 0.616211f, 0.631836f, 0.645508f, 0.661621f, 0.674805f, 0.688965f,
+ 0.703125f, 0.717773f, 0.731934f, 0.745605f, 0.757812f, 0.772949f, 0.785156f, 0.799316f, 0.812012f, 0.826172f, 0.906738f, 0.896484f,
+ 0.886230f, 0.876465f, 0.868164f, 0.860840f, 0.005264f, 0.015457f, 0.026474f, 0.037170f, 0.048157f, 0.059845f, 0.071594f, 0.083984f,
+ 0.096191f, 0.109070f, 0.121887f, 0.134766f, 0.148193f, 0.161255f, 0.175781f, 0.189209f, 0.203369f, 0.218384f, 0.233032f, 0.247681f,
+ 0.261963f, 0.277100f, 0.292480f, 0.307129f, 0.322998f, 0.337891f, 0.352539f, 0.368652f, 0.384033f, 0.399170f, 0.414307f, 0.430420f,
+ 0.445801f, 0.460693f, 0.475342f, 0.491211f, 0.506836f, 0.521973f, 0.537598f, 0.551758f, 0.567383f, 0.582520f, 0.598145f, 0.612305f,
+ 0.627441f, 0.642090f, 0.656738f, 0.670898f, 0.685059f, 0.698730f, 0.713867f, 0.728516f, 0.742188f, 0.755371f, 0.770020f, 0.782715f,
+ 0.796387f, 0.810547f, 0.899414f, 0.889648f, 0.879883f, 0.872070f, 0.863770f, 0.856445f, 0.004719f, 0.014229f, 0.024384f, 0.034607f,
+ 0.044708f, 0.055756f, 0.066895f, 0.077942f, 0.089600f, 0.101624f, 0.113525f, 0.125854f, 0.138428f, 0.151245f, 0.164673f, 0.177734f,
+ 0.191650f, 0.205078f, 0.219360f, 0.233154f, 0.247925f, 0.261475f, 0.276367f, 0.291504f, 0.305908f, 0.320312f, 0.335449f, 0.350098f,
+ 0.365723f, 0.380615f, 0.395996f, 0.411133f, 0.427002f, 0.441895f, 0.456543f, 0.472656f, 0.487793f, 0.502441f, 0.518555f, 0.533203f,
+ 0.547852f, 0.562988f, 0.577637f, 0.593262f, 0.607910f, 0.623535f, 0.638184f, 0.652344f, 0.666992f, 0.681641f, 0.696777f, 0.711426f,
+ 0.725098f, 0.738281f, 0.753418f, 0.766113f, 0.782227f, 0.794922f, 0.892090f, 0.884277f, 0.875000f, 0.866699f, 0.858887f, 0.852539f,
+ 0.004280f, 0.013329f, 0.022476f, 0.031982f, 0.042114f, 0.051849f, 0.062225f, 0.072449f, 0.083679f, 0.095032f, 0.105530f, 0.117676f,
+ 0.129517f, 0.141357f, 0.154297f, 0.166748f, 0.178711f, 0.192505f, 0.205933f, 0.219727f, 0.233521f, 0.247070f, 0.260986f, 0.275391f,
+ 0.290039f, 0.303955f, 0.319580f, 0.333740f, 0.347412f, 0.363037f, 0.377686f, 0.392822f, 0.408203f, 0.422852f, 0.437988f, 0.453125f,
+ 0.468506f, 0.483398f, 0.498779f, 0.514160f, 0.527832f, 0.543945f, 0.559570f, 0.574707f, 0.588867f, 0.604492f, 0.619141f, 0.634277f,
+ 0.648438f, 0.663086f, 0.678223f, 0.692383f, 0.707520f, 0.721680f, 0.735352f, 0.749512f, 0.764648f, 0.778320f, 0.884277f, 0.877441f,
+ 0.868652f, 0.861328f, 0.854492f, 0.847656f, 0.004280f, 0.012138f, 0.021103f, 0.029999f, 0.038940f, 0.048279f, 0.057831f, 0.067566f,
+ 0.077454f, 0.087524f, 0.098816f, 0.109558f, 0.120728f, 0.131958f, 0.143799f, 0.155762f, 0.168091f, 0.180176f, 0.193359f, 0.206177f,
+ 0.219360f, 0.232910f, 0.246338f, 0.260254f, 0.273682f, 0.287598f, 0.302246f, 0.316650f, 0.331299f, 0.344971f, 0.359863f, 0.374268f,
+ 0.389648f, 0.404297f, 0.419434f, 0.434326f, 0.449463f, 0.464844f, 0.479492f, 0.494141f, 0.509766f, 0.524414f, 0.540039f, 0.555176f,
+ 0.569824f, 0.584961f, 0.600098f, 0.615723f, 0.629883f, 0.645508f, 0.659668f, 0.675293f, 0.689453f, 0.704590f, 0.719238f, 0.732422f,
+ 0.748535f, 0.762207f, 0.876953f, 0.871582f, 0.863281f, 0.855957f, 0.849609f, 0.842773f, 0.003744f, 0.011436f, 0.019348f, 0.027893f,
+ 0.036102f, 0.044739f, 0.053711f, 0.063110f, 0.072205f, 0.081970f, 0.091919f, 0.101746f, 0.112732f, 0.122864f, 0.134521f, 0.145996f,
+ 0.157715f, 0.169434f, 0.181519f, 0.193848f, 0.206665f, 0.219360f, 0.231445f, 0.245361f, 0.259033f, 0.272217f, 0.286621f, 0.299805f,
+ 0.314209f, 0.328125f, 0.342285f, 0.357178f, 0.371826f, 0.386475f, 0.400635f, 0.415527f, 0.430420f, 0.445068f, 0.459717f, 0.476074f,
+ 0.490234f, 0.505371f, 0.521484f, 0.536133f, 0.551758f, 0.565430f, 0.581543f, 0.595703f, 0.611816f, 0.626465f, 0.641602f, 0.656738f,
+ 0.671875f, 0.686523f, 0.701172f, 0.715820f, 0.731445f, 0.746582f, 0.868652f, 0.864746f, 0.856934f, 0.851074f, 0.844727f, 0.837891f,
+ 0.003595f, 0.011093f, 0.018265f, 0.025711f, 0.033600f, 0.041656f, 0.050140f, 0.058350f, 0.067505f, 0.076416f, 0.085632f, 0.095093f,
+ 0.104919f, 0.115295f, 0.125610f, 0.136108f, 0.147583f, 0.157959f, 0.169800f, 0.181519f, 0.193359f, 0.205933f, 0.218140f, 0.231323f,
+ 0.243652f, 0.257324f, 0.270508f, 0.283447f, 0.297363f, 0.311523f, 0.325928f, 0.339111f, 0.353516f, 0.367432f, 0.382812f, 0.396973f,
+ 0.412109f, 0.426758f, 0.441406f, 0.456055f, 0.471436f, 0.486328f, 0.501953f, 0.516113f, 0.531738f, 0.546875f, 0.562500f, 0.577637f,
+ 0.592773f, 0.607910f, 0.622559f, 0.638184f, 0.653809f, 0.669434f, 0.684082f, 0.699219f, 0.714355f, 0.729492f, 0.860840f, 0.857422f,
+ 0.852051f, 0.844727f, 0.839355f, 0.832520f, 0.003349f, 0.009933f, 0.016754f, 0.024063f, 0.031204f, 0.038849f, 0.046356f, 0.054413f,
+ 0.062744f, 0.070984f, 0.080017f, 0.088989f, 0.097778f, 0.107361f, 0.117004f, 0.127197f, 0.137451f, 0.148071f, 0.159180f, 0.169922f,
+ 0.181519f, 0.192993f, 0.204956f, 0.217407f, 0.229980f, 0.242188f, 0.254883f, 0.267578f, 0.281494f, 0.294434f, 0.307861f, 0.321533f,
+ 0.335693f, 0.350098f, 0.364258f, 0.379150f, 0.393066f, 0.407715f, 0.422607f, 0.437500f, 0.452148f, 0.467041f, 0.482422f, 0.497314f,
+ 0.512695f, 0.527832f, 0.542969f, 0.558594f, 0.573730f, 0.589844f, 0.604004f, 0.619629f, 0.635254f, 0.651367f, 0.665527f, 0.681152f,
+ 0.696289f, 0.711914f, 0.852539f, 0.851562f, 0.846191f, 0.838867f, 0.832520f, 0.827637f, 0.003290f, 0.009415f, 0.015976f, 0.022095f,
+ 0.028946f, 0.036255f, 0.043396f, 0.050598f, 0.058502f, 0.066284f, 0.074036f, 0.082275f, 0.091187f, 0.099731f, 0.108826f, 0.118652f,
+ 0.128296f, 0.137939f, 0.148193f, 0.159302f, 0.170166f, 0.180786f, 0.191895f, 0.203491f, 0.215210f, 0.227661f, 0.240112f, 0.252686f,
+ 0.265625f, 0.278564f, 0.291748f, 0.305176f, 0.318604f, 0.332764f, 0.346924f, 0.360352f, 0.375000f, 0.389160f, 0.404297f, 0.418213f,
+ 0.433105f, 0.448486f, 0.463135f, 0.477783f, 0.493408f, 0.508301f, 0.523438f, 0.540039f, 0.554199f, 0.570312f, 0.585938f, 0.601074f,
+ 0.617188f, 0.633301f, 0.648926f, 0.664062f, 0.679688f, 0.695312f, 0.844727f, 0.844238f, 0.838867f, 0.833008f, 0.827148f, 0.822266f,
+ 0.002913f, 0.008621f, 0.014595f, 0.020950f, 0.027496f, 0.033600f, 0.040558f, 0.047119f, 0.054260f, 0.061615f, 0.068970f, 0.076782f,
+ 0.084717f, 0.093140f, 0.101562f, 0.109985f, 0.118591f, 0.129150f, 0.138306f, 0.148682f, 0.158447f, 0.169189f, 0.180054f, 0.191162f,
+ 0.202148f, 0.213379f, 0.225586f, 0.237305f, 0.250488f, 0.262939f, 0.275391f, 0.288086f, 0.302490f, 0.315186f, 0.329346f, 0.342529f,
+ 0.356934f, 0.370117f, 0.385742f, 0.400146f, 0.414795f, 0.429199f, 0.444336f, 0.459473f, 0.473389f, 0.489258f, 0.503906f, 0.519531f,
+ 0.535645f, 0.551270f, 0.566895f, 0.582520f, 0.598145f, 0.614258f, 0.629395f, 0.645996f, 0.661621f, 0.677734f, 0.837402f, 0.836914f,
+ 0.832520f, 0.826660f, 0.821777f, 0.816406f, 0.002748f, 0.008018f, 0.014168f, 0.019196f, 0.025040f, 0.031250f, 0.037506f, 0.043732f,
+ 0.050415f, 0.057098f, 0.063721f, 0.071167f, 0.078979f, 0.086609f, 0.094299f, 0.102783f, 0.111145f, 0.119812f, 0.128296f, 0.138306f,
+ 0.147583f, 0.157593f, 0.168213f, 0.178711f, 0.188843f, 0.200317f, 0.211792f, 0.223511f, 0.235352f, 0.247192f, 0.259521f, 0.272461f,
+ 0.285156f, 0.298584f, 0.312012f, 0.324707f, 0.339111f, 0.352783f, 0.366943f, 0.381348f, 0.395996f, 0.410889f, 0.425537f, 0.439941f,
+ 0.454834f, 0.470459f, 0.485352f, 0.501953f, 0.516113f, 0.531738f, 0.547363f, 0.563477f, 0.579102f, 0.595703f, 0.611328f, 0.626953f,
+ 0.642578f, 0.659668f, 0.828125f, 0.830566f, 0.825684f, 0.820801f, 0.815430f, 0.811035f, 0.002630f, 0.007412f, 0.012978f, 0.018356f,
+ 0.023758f, 0.028931f, 0.034729f, 0.040894f, 0.046631f, 0.053101f, 0.059143f, 0.065979f, 0.073669f, 0.080200f, 0.087585f, 0.095276f,
+ 0.102844f, 0.111633f, 0.119812f, 0.128296f, 0.137573f, 0.146729f, 0.156128f, 0.166382f, 0.176880f, 0.187256f, 0.197998f, 0.209351f,
+ 0.220581f, 0.232422f, 0.244385f, 0.256592f, 0.268799f, 0.281982f, 0.294922f, 0.308105f, 0.321045f, 0.334717f, 0.348633f, 0.363525f,
+ 0.378174f, 0.391846f, 0.406006f, 0.420898f, 0.436279f, 0.451660f, 0.466064f, 0.481934f, 0.496826f, 0.513184f, 0.528320f, 0.543945f,
+ 0.560059f, 0.576660f, 0.592285f, 0.608887f, 0.625000f, 0.640625f, 0.819336f, 0.822266f, 0.818848f, 0.813965f, 0.810059f, 0.805664f,
+ 0.002201f, 0.007240f, 0.011803f, 0.016617f, 0.021622f, 0.027344f, 0.032288f, 0.037598f, 0.043427f, 0.049194f, 0.055267f, 0.061462f,
+ 0.067566f, 0.073853f, 0.080872f, 0.088013f, 0.095703f, 0.103821f, 0.111145f, 0.119446f, 0.127563f, 0.136597f, 0.145752f, 0.155273f,
+ 0.165039f, 0.174683f, 0.185181f, 0.195801f, 0.206543f, 0.218140f, 0.229370f, 0.241455f, 0.253174f, 0.265381f, 0.278564f, 0.291504f,
+ 0.304199f, 0.317383f, 0.331299f, 0.344971f, 0.358643f, 0.373291f, 0.386963f, 0.402100f, 0.416016f, 0.431641f, 0.447266f, 0.462646f,
+ 0.477295f, 0.493652f, 0.509277f, 0.524902f, 0.541504f, 0.557617f, 0.574219f, 0.589844f, 0.605957f, 0.623047f, 0.810059f, 0.814453f,
+ 0.811035f, 0.807129f, 0.803223f, 0.798828f, 0.002293f, 0.006927f, 0.010994f, 0.015617f, 0.020584f, 0.025131f, 0.029663f, 0.034760f,
+ 0.040192f, 0.045532f, 0.050964f, 0.056793f, 0.062805f, 0.068726f, 0.074890f, 0.081482f, 0.088806f, 0.096069f, 0.103333f, 0.110535f,
+ 0.118896f, 0.126709f, 0.135254f, 0.144165f, 0.153442f, 0.162720f, 0.172119f, 0.182495f, 0.192749f, 0.203735f, 0.214600f, 0.225952f,
+ 0.237793f, 0.250000f, 0.261719f, 0.274170f, 0.287354f, 0.300293f, 0.313477f, 0.326904f, 0.340820f, 0.354980f, 0.369385f, 0.383545f,
+ 0.396973f, 0.411865f, 0.427734f, 0.442871f, 0.458740f, 0.473633f, 0.489502f, 0.505859f, 0.522461f, 0.537598f, 0.553711f, 0.572754f,
+ 0.588379f, 0.604492f, 0.802246f, 0.807617f, 0.804199f, 0.800781f, 0.797363f, 0.792969f, 0.002081f, 0.006172f, 0.010460f, 0.014503f,
+ 0.019104f, 0.023163f, 0.027832f, 0.032410f, 0.037354f, 0.041992f, 0.047211f, 0.052490f, 0.057831f, 0.063232f, 0.069458f, 0.075317f,
+ 0.082153f, 0.088257f, 0.094910f, 0.102295f, 0.110107f, 0.117554f, 0.125122f, 0.133667f, 0.142456f, 0.151001f, 0.160767f, 0.169922f,
+ 0.179443f, 0.190430f, 0.200562f, 0.211914f, 0.222412f, 0.234009f, 0.245850f, 0.258545f, 0.270752f, 0.283203f, 0.296387f, 0.309082f,
+ 0.322998f, 0.336670f, 0.350098f, 0.364990f, 0.378906f, 0.393311f, 0.408936f, 0.423096f, 0.438965f, 0.454834f, 0.470703f, 0.486572f,
+ 0.502441f, 0.518555f, 0.534668f, 0.551270f, 0.569336f, 0.585938f, 0.792480f, 0.799316f, 0.797363f, 0.793457f, 0.790039f, 0.786621f,
+ 0.002028f, 0.005669f, 0.009705f, 0.013565f, 0.017532f, 0.021286f, 0.025574f, 0.030197f, 0.034180f, 0.038757f, 0.043488f, 0.048737f,
+ 0.053497f, 0.058594f, 0.064026f, 0.070007f, 0.075623f, 0.081360f, 0.088135f, 0.094238f, 0.101379f, 0.108643f, 0.116028f, 0.123718f,
+ 0.131592f, 0.140137f, 0.149048f, 0.157715f, 0.167114f, 0.176636f, 0.187012f, 0.197388f, 0.208130f, 0.219238f, 0.230347f, 0.241943f,
+ 0.254150f, 0.266113f, 0.279053f, 0.291504f, 0.304932f, 0.318848f, 0.332031f, 0.345947f, 0.360107f, 0.375000f, 0.389404f, 0.404541f,
+ 0.419922f, 0.434814f, 0.450684f, 0.466553f, 0.482910f, 0.499023f, 0.516113f, 0.533203f, 0.550293f, 0.567383f, 0.783203f, 0.790527f,
+ 0.789551f, 0.786621f, 0.783691f, 0.780762f, 0.001852f, 0.005554f, 0.008957f, 0.012642f, 0.016296f, 0.020172f, 0.024033f, 0.027878f,
+ 0.031677f, 0.035919f, 0.040253f, 0.044952f, 0.049255f, 0.053955f, 0.058960f, 0.063965f, 0.069336f, 0.074951f, 0.080933f, 0.087219f,
+ 0.093201f, 0.100159f, 0.106689f, 0.114197f, 0.121521f, 0.129517f, 0.137817f, 0.146118f, 0.155151f, 0.164307f, 0.173462f, 0.183472f,
+ 0.193970f, 0.204224f, 0.215210f, 0.226562f, 0.238037f, 0.250244f, 0.262451f, 0.274902f, 0.287598f, 0.301025f, 0.314209f, 0.327393f,
+ 0.342041f, 0.356445f, 0.370850f, 0.385254f, 0.400879f, 0.415771f, 0.431396f, 0.446777f, 0.463379f, 0.480469f, 0.497314f, 0.514160f,
+ 0.530273f, 0.547363f, 0.774414f, 0.783203f, 0.782715f, 0.779297f, 0.776367f, 0.773438f, 0.001690f, 0.005207f, 0.008278f, 0.011696f,
+ 0.015068f, 0.018784f, 0.022186f, 0.025909f, 0.029221f, 0.033508f, 0.037109f, 0.041321f, 0.045471f, 0.049774f, 0.054108f, 0.058838f,
+ 0.063843f, 0.069214f, 0.074280f, 0.080078f, 0.086243f, 0.091980f, 0.098083f, 0.105164f, 0.111877f, 0.119446f, 0.126953f, 0.134888f,
+ 0.143555f, 0.151978f, 0.161133f, 0.170532f, 0.180176f, 0.189697f, 0.200684f, 0.211182f, 0.222412f, 0.234009f, 0.245972f, 0.257568f,
+ 0.270508f, 0.282959f, 0.295898f, 0.309570f, 0.323486f, 0.337158f, 0.351562f, 0.366211f, 0.381104f, 0.396729f, 0.411865f, 0.427490f,
+ 0.443604f, 0.459961f, 0.477051f, 0.494385f, 0.510742f, 0.529297f, 0.763184f, 0.774902f, 0.773438f, 0.771973f, 0.769043f, 0.767578f,
+ 0.001528f, 0.004692f, 0.007587f, 0.010956f, 0.014221f, 0.016907f, 0.020218f, 0.023407f, 0.027283f, 0.030273f, 0.033997f, 0.038055f,
+ 0.041809f, 0.045959f, 0.049683f, 0.053955f, 0.058838f, 0.063171f, 0.068176f, 0.073120f, 0.078491f, 0.084473f, 0.090332f, 0.096619f,
+ 0.102905f, 0.109619f, 0.116699f, 0.124207f, 0.131958f, 0.140503f, 0.148438f, 0.157349f, 0.166626f, 0.176392f, 0.186157f, 0.196045f,
+ 0.207031f, 0.218018f, 0.229736f, 0.241699f, 0.253174f, 0.265381f, 0.278320f, 0.291748f, 0.305176f, 0.318848f, 0.333496f, 0.347412f,
+ 0.362305f, 0.376709f, 0.392822f, 0.407715f, 0.424072f, 0.440430f, 0.457031f, 0.473633f, 0.491211f, 0.508789f, 0.753906f, 0.766602f,
+ 0.767090f, 0.764160f, 0.761719f, 0.759766f, 0.001261f, 0.004250f, 0.007389f, 0.010185f, 0.013023f, 0.015976f, 0.018692f, 0.021713f,
+ 0.024734f, 0.028183f, 0.031464f, 0.034943f, 0.038452f, 0.041870f, 0.045410f, 0.049561f, 0.054047f, 0.058044f, 0.062164f, 0.067017f,
+ 0.071838f, 0.077332f, 0.082581f, 0.088318f, 0.094360f, 0.100525f, 0.107117f, 0.114258f, 0.121643f, 0.128540f, 0.136841f, 0.144897f,
+ 0.153931f, 0.162476f, 0.171875f, 0.182007f, 0.192139f, 0.202637f, 0.213623f, 0.224854f, 0.237183f, 0.248657f, 0.260986f, 0.274170f,
+ 0.287354f, 0.300781f, 0.314453f, 0.328613f, 0.343018f, 0.358643f, 0.373291f, 0.388916f, 0.404785f, 0.420654f, 0.437744f, 0.454590f,
+ 0.471924f, 0.489990f, 0.744629f, 0.757812f, 0.757812f, 0.756836f, 0.754395f, 0.752441f, 0.001527f, 0.004047f, 0.006680f, 0.009369f,
+ 0.012024f, 0.014618f, 0.017288f, 0.020248f, 0.022705f, 0.025803f, 0.028778f, 0.031769f, 0.034912f, 0.038330f, 0.041595f, 0.045166f,
+ 0.048737f, 0.052673f, 0.056885f, 0.061218f, 0.065552f, 0.070251f, 0.075012f, 0.080505f, 0.086060f, 0.091614f, 0.097656f, 0.104065f,
+ 0.110901f, 0.118225f, 0.125366f, 0.133179f, 0.141357f, 0.149902f, 0.158569f, 0.168213f, 0.177734f, 0.187866f, 0.198364f, 0.208984f,
+ 0.220581f, 0.232422f, 0.244019f, 0.256836f, 0.269287f, 0.282471f, 0.296143f, 0.309326f, 0.324463f, 0.338379f, 0.353760f, 0.368652f,
+ 0.385498f, 0.400635f, 0.417725f, 0.434570f, 0.451660f, 0.469482f, 0.733887f, 0.749023f, 0.750977f, 0.749023f, 0.747070f, 0.744629f,
+ 0.001313f, 0.003803f, 0.006126f, 0.008507f, 0.011185f, 0.013550f, 0.015839f, 0.018219f, 0.021027f, 0.023438f, 0.026520f, 0.029129f,
+ 0.031738f, 0.034821f, 0.037964f, 0.041138f, 0.044434f, 0.048035f, 0.051636f, 0.055420f, 0.059540f, 0.063782f, 0.068176f, 0.073181f,
+ 0.077881f, 0.083496f, 0.088989f, 0.094849f, 0.101440f, 0.107849f, 0.114441f, 0.121887f, 0.129395f, 0.137207f, 0.145874f, 0.154419f,
+ 0.163574f, 0.173462f, 0.183228f, 0.193726f, 0.204712f, 0.216064f, 0.227661f, 0.239624f, 0.251709f, 0.264648f, 0.277832f, 0.291504f,
+ 0.305664f, 0.320312f, 0.334473f, 0.349854f, 0.365479f, 0.380615f, 0.397217f, 0.414551f, 0.432129f, 0.449951f, 0.722656f, 0.740234f,
+ 0.741699f, 0.741211f, 0.739746f, 0.737793f, 0.001137f, 0.003654f, 0.005871f, 0.007881f, 0.010262f, 0.012268f, 0.014496f, 0.017059f,
+ 0.018890f, 0.021317f, 0.023605f, 0.026291f, 0.029007f, 0.031494f, 0.034515f, 0.036987f, 0.040375f, 0.043457f, 0.046936f, 0.050385f,
+ 0.053925f, 0.058044f, 0.061981f, 0.066650f, 0.070679f, 0.075562f, 0.080994f, 0.085938f, 0.091919f, 0.098450f, 0.104370f, 0.110840f,
+ 0.118164f, 0.125366f, 0.133301f, 0.141357f, 0.150024f, 0.159546f, 0.168457f, 0.178711f, 0.189453f, 0.199707f, 0.211060f, 0.222656f,
+ 0.234741f, 0.247314f, 0.260010f, 0.272705f, 0.287354f, 0.300781f, 0.315674f, 0.330322f, 0.345947f, 0.362061f, 0.377441f, 0.394775f,
+ 0.412109f, 0.429199f, 0.712891f, 0.730957f, 0.733398f, 0.733398f, 0.731445f, 0.729492f, 0.001163f, 0.003218f, 0.005329f, 0.007542f,
+ 0.009331f, 0.011330f, 0.013367f, 0.015434f, 0.017685f, 0.019714f, 0.021515f, 0.024139f, 0.026062f, 0.028763f, 0.031204f, 0.033722f,
+ 0.036163f, 0.039398f, 0.041992f, 0.045624f, 0.048553f, 0.051971f, 0.056000f, 0.059937f, 0.063904f, 0.068054f, 0.072876f, 0.077820f,
+ 0.083374f, 0.088623f, 0.094116f, 0.100830f, 0.107117f, 0.114197f, 0.121399f, 0.129272f, 0.136963f, 0.145630f, 0.154785f, 0.163696f,
+ 0.173828f, 0.184204f, 0.194946f, 0.205933f, 0.217529f, 0.229614f, 0.242676f, 0.255859f, 0.269043f, 0.282471f, 0.296387f, 0.311523f,
+ 0.326172f, 0.341553f, 0.357910f, 0.374756f, 0.391846f, 0.409180f, 0.701660f, 0.721680f, 0.723633f, 0.724609f, 0.723145f, 0.722656f,
+ 0.001008f, 0.003147f, 0.004818f, 0.006882f, 0.008530f, 0.010468f, 0.012390f, 0.013832f, 0.016006f, 0.017899f, 0.019608f, 0.021866f,
+ 0.023849f, 0.025940f, 0.027847f, 0.030350f, 0.032806f, 0.035187f, 0.037994f, 0.040619f, 0.043732f, 0.046875f, 0.050110f, 0.053833f,
+ 0.057617f, 0.061371f, 0.065613f, 0.070068f, 0.074768f, 0.079895f, 0.085144f, 0.090637f, 0.096863f, 0.103149f, 0.110107f, 0.116943f,
+ 0.124634f, 0.132568f, 0.140991f, 0.149536f, 0.159302f, 0.169189f, 0.179443f, 0.189575f, 0.201538f, 0.213013f, 0.225342f, 0.236938f,
+ 0.250244f, 0.264160f, 0.278320f, 0.292236f, 0.307617f, 0.322021f, 0.337891f, 0.354248f, 0.371582f, 0.389160f, 0.689941f, 0.712891f,
+ 0.715820f, 0.715820f, 0.715820f, 0.714355f, 0.001126f, 0.002708f, 0.004486f, 0.006313f, 0.007927f, 0.009659f, 0.011238f, 0.012833f,
+ 0.014435f, 0.015823f, 0.017670f, 0.019485f, 0.021347f, 0.023453f, 0.025101f, 0.027161f, 0.029160f, 0.031525f, 0.033752f, 0.036560f,
+ 0.039154f, 0.041687f, 0.044891f, 0.047943f, 0.051453f, 0.054871f, 0.058655f, 0.062622f, 0.067078f, 0.071411f, 0.076355f, 0.081665f,
+ 0.086792f, 0.092957f, 0.098877f, 0.105713f, 0.112549f, 0.119995f, 0.127563f, 0.135864f, 0.144897f, 0.154297f, 0.164185f, 0.173828f,
+ 0.185059f, 0.196045f, 0.208008f, 0.219849f, 0.232666f, 0.245483f, 0.259033f, 0.273438f, 0.287842f, 0.302734f, 0.318604f, 0.334473f,
+ 0.351318f, 0.369385f, 0.679688f, 0.702637f, 0.707031f, 0.707031f, 0.707031f, 0.705566f, 0.000980f, 0.002733f, 0.004021f, 0.005688f,
+ 0.007084f, 0.008553f, 0.010345f, 0.011513f, 0.012962f, 0.014297f, 0.015823f, 0.017609f, 0.019119f, 0.020721f, 0.022568f, 0.024200f,
+ 0.026291f, 0.028000f, 0.030457f, 0.032410f, 0.034912f, 0.037476f, 0.039734f, 0.042786f, 0.045563f, 0.048920f, 0.052185f, 0.055817f,
+ 0.059662f, 0.063660f, 0.067993f, 0.072632f, 0.077759f, 0.083191f, 0.088623f, 0.094971f, 0.101135f, 0.107849f, 0.115479f, 0.122864f,
+ 0.131592f, 0.139893f, 0.149414f, 0.158447f, 0.169067f, 0.179443f, 0.191040f, 0.202393f, 0.214478f, 0.227539f, 0.240723f, 0.255127f,
+ 0.268555f, 0.283447f, 0.298828f, 0.315186f, 0.331787f, 0.348389f, 0.667480f, 0.693359f, 0.697754f, 0.698730f, 0.698242f, 0.697754f,
+ 0.000870f, 0.002420f, 0.003994f, 0.005165f, 0.006584f, 0.007763f, 0.009209f, 0.010468f, 0.011604f, 0.013336f, 0.013977f, 0.015442f,
+ 0.016830f, 0.018509f, 0.020065f, 0.021606f, 0.023224f, 0.024933f, 0.026672f, 0.028656f, 0.030914f, 0.033112f, 0.035187f, 0.037689f,
+ 0.040344f, 0.043335f, 0.046234f, 0.049438f, 0.052948f, 0.056427f, 0.060394f, 0.064331f, 0.069031f, 0.073853f, 0.078735f, 0.084412f,
+ 0.090271f, 0.096436f, 0.103455f, 0.110229f, 0.118042f, 0.126099f, 0.134766f, 0.143921f, 0.153198f, 0.163696f, 0.174438f, 0.185913f,
+ 0.197754f, 0.210083f, 0.222778f, 0.235962f, 0.250000f, 0.264648f, 0.279053f, 0.294922f, 0.311279f, 0.328613f, 0.655273f, 0.684082f,
+ 0.688477f, 0.689941f, 0.689941f, 0.689941f, 0.000790f, 0.002153f, 0.003576f, 0.004726f, 0.005966f, 0.007172f, 0.008186f, 0.009453f,
+ 0.010521f, 0.011482f, 0.012772f, 0.013771f, 0.015144f, 0.016434f, 0.017792f, 0.019226f, 0.020355f, 0.022049f, 0.023666f, 0.025375f,
+ 0.027145f, 0.029297f, 0.030975f, 0.033142f, 0.035339f, 0.037964f, 0.040405f, 0.043365f, 0.046478f, 0.049744f, 0.053101f, 0.057068f,
+ 0.060944f, 0.065063f, 0.069763f, 0.074646f, 0.079956f, 0.085938f, 0.091675f, 0.098083f, 0.105164f, 0.112732f, 0.121033f, 0.129395f,
+ 0.138428f, 0.148560f, 0.158325f, 0.169067f, 0.180664f, 0.192139f, 0.205078f, 0.217529f, 0.231934f, 0.246094f, 0.260010f, 0.275391f,
+ 0.292236f, 0.309570f, 0.644043f, 0.673340f, 0.678711f, 0.680664f, 0.680664f, 0.680176f, 0.000538f, 0.002022f, 0.003185f, 0.004456f,
+ 0.005360f, 0.006321f, 0.007286f, 0.008484f, 0.009422f, 0.010185f, 0.011177f, 0.012283f, 0.013191f, 0.014435f, 0.015587f, 0.016769f,
+ 0.017914f, 0.019302f, 0.020584f, 0.022171f, 0.023819f, 0.025391f, 0.027222f, 0.028992f, 0.030914f, 0.033234f, 0.035461f, 0.037903f,
+ 0.040649f, 0.043396f, 0.046326f, 0.049561f, 0.053131f, 0.056946f, 0.061279f, 0.065613f, 0.070374f, 0.075439f, 0.080811f, 0.086731f,
+ 0.093140f, 0.100037f, 0.107544f, 0.115662f, 0.124023f, 0.132935f, 0.143066f, 0.153320f, 0.163696f, 0.175415f, 0.187012f, 0.200195f,
+ 0.213013f, 0.227173f, 0.241455f, 0.256592f, 0.272461f, 0.288330f, 0.632812f, 0.663574f, 0.669434f, 0.670898f, 0.671387f, 0.671875f,
+ 0.000686f, 0.001864f, 0.002884f, 0.003883f, 0.004829f, 0.005592f, 0.006504f, 0.007454f, 0.008064f, 0.008995f, 0.009850f, 0.010948f,
+ 0.011711f, 0.012581f, 0.013763f, 0.014618f, 0.015701f, 0.016953f, 0.018112f, 0.019180f, 0.020691f, 0.021973f, 0.023560f, 0.025192f,
+ 0.026962f, 0.028717f, 0.030624f, 0.032959f, 0.035004f, 0.037567f, 0.040314f, 0.043121f, 0.046204f, 0.049713f, 0.053284f, 0.057129f,
+ 0.061157f, 0.065796f, 0.071167f, 0.076477f, 0.082214f, 0.088379f, 0.095276f, 0.102600f, 0.110596f, 0.118652f, 0.127808f, 0.137817f,
+ 0.147705f, 0.158569f, 0.170166f, 0.182251f, 0.195068f, 0.208008f, 0.222656f, 0.237671f, 0.252686f, 0.269287f, 0.620605f, 0.653320f,
+ 0.659180f, 0.661621f, 0.663086f, 0.663574f, 0.000782f, 0.001828f, 0.002949f, 0.003487f, 0.004421f, 0.005032f, 0.005878f, 0.006557f,
+ 0.007332f, 0.008110f, 0.008591f, 0.009537f, 0.010094f, 0.011147f, 0.011864f, 0.012779f, 0.013573f, 0.014549f, 0.015625f, 0.016846f,
+ 0.017822f, 0.018936f, 0.020279f, 0.021729f, 0.023117f, 0.024704f, 0.026505f, 0.028183f, 0.030289f, 0.032349f, 0.034546f, 0.037109f,
+ 0.039703f, 0.042786f, 0.045837f, 0.049133f, 0.053009f, 0.056763f, 0.061584f, 0.066284f, 0.071411f, 0.076843f, 0.083191f, 0.089722f,
+ 0.097290f, 0.104919f, 0.113647f, 0.122498f, 0.132324f, 0.142578f, 0.153809f, 0.164917f, 0.177612f, 0.190430f, 0.203857f, 0.218506f,
+ 0.233887f, 0.249390f, 0.606934f, 0.642578f, 0.649414f, 0.653320f, 0.652832f, 0.654785f, 0.000604f, 0.001636f, 0.002550f, 0.003180f,
+ 0.003799f, 0.004498f, 0.005051f, 0.005573f, 0.006325f, 0.006836f, 0.007607f, 0.008087f, 0.008820f, 0.009483f, 0.010132f, 0.010918f,
+ 0.011665f, 0.012527f, 0.013535f, 0.014297f, 0.015251f, 0.016190f, 0.017288f, 0.018433f, 0.019791f, 0.021133f, 0.022400f, 0.023865f,
+ 0.025742f, 0.027664f, 0.029373f, 0.031677f, 0.034027f, 0.036255f, 0.039032f, 0.042023f, 0.045197f, 0.048798f, 0.052643f, 0.056824f,
+ 0.061493f, 0.066467f, 0.072327f, 0.078308f, 0.084473f, 0.091858f, 0.099609f, 0.108032f, 0.117249f, 0.126831f, 0.137451f, 0.148193f,
+ 0.160034f, 0.172729f, 0.186035f, 0.199829f, 0.214722f, 0.229980f, 0.596680f, 0.632812f, 0.638672f, 0.642578f, 0.644531f, 0.645020f,
+ 0.000447f, 0.001384f, 0.001986f, 0.002697f, 0.003225f, 0.003828f, 0.004501f, 0.005009f, 0.005459f, 0.006027f, 0.006474f, 0.006935f,
+ 0.007591f, 0.008217f, 0.008644f, 0.009308f, 0.010025f, 0.010498f, 0.011330f, 0.012100f, 0.012909f, 0.013924f, 0.014618f, 0.015610f,
+ 0.016739f, 0.017807f, 0.019043f, 0.020340f, 0.021622f, 0.023178f, 0.024979f, 0.026520f, 0.028366f, 0.030640f, 0.032959f, 0.035492f,
+ 0.038239f, 0.041260f, 0.044495f, 0.048340f, 0.052399f, 0.056732f, 0.061768f, 0.067017f, 0.072754f, 0.079224f, 0.086304f, 0.093994f,
+ 0.102478f, 0.111511f, 0.121521f, 0.132080f, 0.143311f, 0.155518f, 0.168213f, 0.181763f, 0.196411f, 0.211548f, 0.583008f, 0.621094f,
+ 0.629395f, 0.632324f, 0.634766f, 0.635742f, 0.000375f, 0.001324f, 0.001728f, 0.002466f, 0.002872f, 0.003384f, 0.003685f, 0.004185f,
+ 0.004845f, 0.005184f, 0.005444f, 0.006130f, 0.006401f, 0.006844f, 0.007446f, 0.007957f, 0.008636f, 0.008965f, 0.009659f, 0.010139f,
+ 0.010971f, 0.011742f, 0.012497f, 0.013138f, 0.014099f, 0.014992f, 0.015900f, 0.017166f, 0.018143f, 0.019485f, 0.020676f, 0.022156f,
+ 0.023697f, 0.025528f, 0.027374f, 0.029556f, 0.031921f, 0.034424f, 0.037445f, 0.040375f, 0.044067f, 0.047577f, 0.052155f, 0.056824f,
+ 0.062042f, 0.067688f, 0.074158f, 0.081055f, 0.088745f, 0.097351f, 0.106323f, 0.116455f, 0.127075f, 0.138672f, 0.151123f, 0.164062f,
+ 0.177856f, 0.192871f, 0.570801f, 0.610840f, 0.619629f, 0.623047f, 0.625488f, 0.625977f, 0.000432f, 0.000921f, 0.001664f, 0.002056f,
+ 0.002697f, 0.003061f, 0.003326f, 0.003757f, 0.004044f, 0.004379f, 0.004761f, 0.004948f, 0.005463f, 0.005791f, 0.006199f, 0.006752f,
+ 0.007229f, 0.007526f, 0.008156f, 0.008621f, 0.009193f, 0.009712f, 0.010330f, 0.010994f, 0.011688f, 0.012466f, 0.013374f, 0.014153f,
+ 0.015099f, 0.016083f, 0.017212f, 0.018250f, 0.019623f, 0.021210f, 0.022614f, 0.024445f, 0.026321f, 0.028351f, 0.030762f, 0.033325f,
+ 0.036377f, 0.039642f, 0.043304f, 0.047485f, 0.051880f, 0.056885f, 0.062469f, 0.068542f, 0.075623f, 0.083374f, 0.091919f, 0.101135f,
+ 0.111389f, 0.122559f, 0.134277f, 0.146606f, 0.160278f, 0.174683f, 0.557617f, 0.600098f, 0.609375f, 0.612793f, 0.615723f, 0.616699f,
+ 0.000255f, 0.000997f, 0.001393f, 0.001908f, 0.002239f, 0.002512f, 0.002720f, 0.003166f, 0.003283f, 0.003616f, 0.003866f, 0.004223f,
+ 0.004597f, 0.004795f, 0.005127f, 0.005573f, 0.005939f, 0.006359f, 0.006657f, 0.007133f, 0.007687f, 0.008041f, 0.008545f, 0.009087f,
+ 0.009636f, 0.010300f, 0.010910f, 0.011757f, 0.012489f, 0.013313f, 0.014153f, 0.014954f, 0.016037f, 0.017258f, 0.018555f, 0.019867f,
+ 0.021530f, 0.023239f, 0.025055f, 0.027252f, 0.029663f, 0.032379f, 0.035339f, 0.038666f, 0.042664f, 0.047058f, 0.051849f, 0.057465f,
+ 0.063416f, 0.070557f, 0.078369f, 0.086731f, 0.096313f, 0.106384f, 0.117798f, 0.129761f, 0.143311f, 0.156982f, 0.544922f, 0.588867f,
+ 0.599121f, 0.602539f, 0.605469f, 0.606445f, 0.000353f, 0.000879f, 0.001276f, 0.001613f, 0.001785f, 0.002075f, 0.002300f, 0.002501f,
+ 0.002808f, 0.003010f, 0.003283f, 0.003487f, 0.003714f, 0.003967f, 0.004269f, 0.004597f, 0.004837f, 0.005230f, 0.005512f, 0.005878f,
+ 0.006203f, 0.006626f, 0.007030f, 0.007519f, 0.007866f, 0.008354f, 0.009010f, 0.009468f, 0.010017f, 0.010765f, 0.011444f, 0.012291f,
+ 0.013100f, 0.014030f, 0.015030f, 0.016098f, 0.017441f, 0.018646f, 0.020157f, 0.021912f, 0.023804f, 0.026047f, 0.028488f, 0.031342f,
+ 0.034424f, 0.037994f, 0.042206f, 0.046997f, 0.052338f, 0.058533f, 0.065369f, 0.073364f, 0.081787f, 0.091492f, 0.102356f, 0.113647f,
+ 0.126343f, 0.139526f, 0.531250f, 0.579102f, 0.587891f, 0.592773f, 0.595703f, 0.596680f, 0.000295f, 0.000784f, 0.000912f, 0.001261f,
+ 0.001517f, 0.001761f, 0.001893f, 0.002113f, 0.002211f, 0.002432f, 0.002676f, 0.002861f, 0.002993f, 0.003294f, 0.003479f, 0.003700f,
+ 0.003933f, 0.004242f, 0.004452f, 0.004745f, 0.004974f, 0.005428f, 0.005642f, 0.006081f, 0.006401f, 0.006817f, 0.007240f, 0.007641f,
+ 0.008209f, 0.008667f, 0.009361f, 0.009720f, 0.010506f, 0.011261f, 0.012024f, 0.012794f, 0.013840f, 0.014893f, 0.016113f, 0.017395f,
+ 0.018860f, 0.020493f, 0.022446f, 0.024658f, 0.027283f, 0.030228f, 0.033691f, 0.037659f, 0.042145f, 0.047546f, 0.053467f, 0.060547f,
+ 0.068359f, 0.077332f, 0.087158f, 0.098145f, 0.109741f, 0.123230f, 0.517090f, 0.566895f, 0.576660f, 0.581543f, 0.584961f, 0.587402f,
+ 0.000247f, 0.000702f, 0.000849f, 0.001033f, 0.001304f, 0.001416f, 0.001576f, 0.001754f, 0.001860f, 0.001953f, 0.002104f, 0.002327f,
+ 0.002419f, 0.002651f, 0.002785f, 0.003014f, 0.003134f, 0.003315f, 0.003584f, 0.003813f, 0.004078f, 0.004295f, 0.004555f, 0.004784f,
+ 0.005013f, 0.005329f, 0.005669f, 0.006069f, 0.006439f, 0.006821f, 0.007381f, 0.007797f, 0.008301f, 0.008812f, 0.009430f, 0.010139f,
+ 0.010948f, 0.011642f, 0.012573f, 0.013664f, 0.014671f, 0.016052f, 0.017502f, 0.019135f, 0.021255f, 0.023438f, 0.026199f, 0.029312f,
+ 0.033203f, 0.037476f, 0.042725f, 0.048828f, 0.055695f, 0.063721f, 0.072937f, 0.082947f, 0.094666f, 0.107117f, 0.504883f, 0.555664f,
+ 0.566406f, 0.572754f, 0.574707f, 0.577148f, 0.000217f, 0.000516f, 0.000750f, 0.000898f, 0.001011f, 0.001117f, 0.001203f, 0.001307f,
+ 0.001470f, 0.001604f, 0.001659f, 0.001750f, 0.001945f, 0.002121f, 0.002249f, 0.002316f, 0.002478f, 0.002581f, 0.002832f, 0.003000f,
+ 0.003164f, 0.003334f, 0.003593f, 0.003784f, 0.003990f, 0.004196f, 0.004440f, 0.004673f, 0.005035f, 0.005329f, 0.005642f, 0.005981f,
+ 0.006462f, 0.006916f, 0.007313f, 0.007805f, 0.008377f, 0.008987f, 0.009727f, 0.010521f, 0.011314f, 0.012421f, 0.013466f, 0.014755f,
+ 0.016235f, 0.017914f, 0.019913f, 0.022461f, 0.025330f, 0.028778f, 0.033081f, 0.038239f, 0.044189f, 0.051422f, 0.059662f, 0.069336f,
+ 0.080200f, 0.091980f, 0.492676f, 0.543945f, 0.555664f, 0.561035f, 0.564453f, 0.566406f, 0.000131f, 0.000355f, 0.000605f, 0.000759f,
+ 0.000832f, 0.000904f, 0.001018f, 0.000975f, 0.001144f, 0.001235f, 0.001336f, 0.001447f, 0.001518f, 0.001620f, 0.001668f, 0.001835f,
+ 0.001901f, 0.002045f, 0.002188f, 0.002270f, 0.002424f, 0.002577f, 0.002707f, 0.002893f, 0.003002f, 0.003223f, 0.003407f, 0.003572f,
+ 0.003851f, 0.004017f, 0.004391f, 0.004608f, 0.004833f, 0.005203f, 0.005497f, 0.005886f, 0.006351f, 0.006771f, 0.007278f, 0.007858f,
+ 0.008560f, 0.009315f, 0.010086f, 0.011078f, 0.012222f, 0.013443f, 0.015022f, 0.016769f, 0.018967f, 0.021591f, 0.024780f, 0.028931f,
+ 0.033875f, 0.039734f, 0.047241f, 0.056122f, 0.066101f, 0.077637f, 0.477783f, 0.532715f, 0.544922f, 0.551270f, 0.553711f, 0.555664f,
+ 0.000245f, 0.000303f, 0.000473f, 0.000498f, 0.000544f, 0.000707f, 0.000700f, 0.000767f, 0.000802f, 0.000892f, 0.001021f, 0.001086f,
+ 0.001140f, 0.001260f, 0.001303f, 0.001325f, 0.001462f, 0.001553f, 0.001603f, 0.001746f, 0.001816f, 0.001904f, 0.002043f, 0.002127f,
+ 0.002254f, 0.002356f, 0.002548f, 0.002672f, 0.002851f, 0.003092f, 0.003265f, 0.003374f, 0.003647f, 0.003891f, 0.004097f, 0.004360f,
+ 0.004669f, 0.004997f, 0.005390f, 0.005810f, 0.006226f, 0.006756f, 0.007450f, 0.008095f, 0.008934f, 0.009827f, 0.010902f, 0.012268f,
+ 0.013840f, 0.015701f, 0.018036f, 0.021072f, 0.024948f, 0.029800f, 0.035980f, 0.043945f, 0.053345f, 0.063843f, 0.465576f, 0.520996f,
+ 0.535645f, 0.540039f, 0.543457f, 0.545898f, 0.000108f, 0.000275f, 0.000332f, 0.000402f, 0.000462f, 0.000468f, 0.000580f, 0.000522f,
+ 0.000616f, 0.000657f, 0.000758f, 0.000762f, 0.000812f, 0.000870f, 0.000945f, 0.000978f, 0.001054f, 0.001109f, 0.001179f, 0.001213f,
+ 0.001311f, 0.001371f, 0.001473f, 0.001558f, 0.001629f, 0.001718f, 0.001837f, 0.001903f, 0.002016f, 0.002159f, 0.002258f, 0.002478f,
+ 0.002548f, 0.002731f, 0.002909f, 0.003086f, 0.003317f, 0.003580f, 0.003885f, 0.004116f, 0.004421f, 0.004818f, 0.005264f, 0.005745f,
+ 0.006294f, 0.006966f, 0.007748f, 0.008667f, 0.009766f, 0.011086f, 0.012787f, 0.014908f, 0.017746f, 0.021271f, 0.026382f, 0.032990f,
+ 0.041199f, 0.051239f, 0.452393f, 0.509277f, 0.522461f, 0.529297f, 0.533203f, 0.535156f, 0.000016f, 0.000143f, 0.000244f, 0.000315f,
+ 0.000309f, 0.000391f, 0.000344f, 0.000402f, 0.000429f, 0.000517f, 0.000522f, 0.000526f, 0.000546f, 0.000606f, 0.000628f, 0.000705f,
+ 0.000692f, 0.000781f, 0.000837f, 0.000868f, 0.000923f, 0.000969f, 0.001013f, 0.001070f, 0.001142f, 0.001186f, 0.001273f, 0.001326f,
+ 0.001397f, 0.001534f, 0.001561f, 0.001685f, 0.001775f, 0.001873f, 0.002024f, 0.002153f, 0.002272f, 0.002443f, 0.002611f, 0.002800f,
+ 0.003014f, 0.003250f, 0.003529f, 0.003868f, 0.004227f, 0.004692f, 0.005192f, 0.005836f, 0.006603f, 0.007587f, 0.008751f, 0.010193f,
+ 0.012001f, 0.014610f, 0.018219f, 0.023392f, 0.030594f, 0.039795f, 0.437744f, 0.498291f, 0.512207f, 0.517578f, 0.521484f, 0.525391f,
+ 0.000102f, 0.000186f, 0.000171f, 0.000181f, 0.000227f, 0.000229f, 0.000231f, 0.000278f, 0.000293f, 0.000304f, 0.000314f, 0.000375f,
+ 0.000365f, 0.000411f, 0.000446f, 0.000457f, 0.000496f, 0.000513f, 0.000533f, 0.000554f, 0.000603f, 0.000622f, 0.000669f, 0.000708f,
+ 0.000757f, 0.000789f, 0.000843f, 0.000875f, 0.000925f, 0.000964f, 0.001037f, 0.001094f, 0.001172f, 0.001243f, 0.001324f, 0.001373f,
+ 0.001497f, 0.001570f, 0.001712f, 0.001829f, 0.001947f, 0.002123f, 0.002291f, 0.002472f, 0.002703f, 0.003008f, 0.003342f, 0.003757f,
+ 0.004204f, 0.004810f, 0.005539f, 0.006554f, 0.007828f, 0.009537f, 0.011894f, 0.015442f, 0.021072f, 0.029282f, 0.424561f, 0.486084f,
+ 0.500488f, 0.506836f, 0.512207f, 0.514648f, 0.000014f, 0.000127f, 0.000112f, 0.000109f, 0.000143f, 0.000165f, 0.000141f, 0.000180f,
+ 0.000185f, 0.000191f, 0.000196f, 0.000203f, 0.000233f, 0.000252f, 0.000260f, 0.000274f, 0.000288f, 0.000314f, 0.000328f, 0.000363f,
+ 0.000362f, 0.000374f, 0.000400f, 0.000436f, 0.000464f, 0.000501f, 0.000504f, 0.000521f, 0.000563f, 0.000593f, 0.000635f, 0.000671f,
+ 0.000712f, 0.000740f, 0.000800f, 0.000837f, 0.000892f, 0.000955f, 0.001030f, 0.001092f, 0.001167f, 0.001270f, 0.001369f, 0.001491f,
+ 0.001626f, 0.001769f, 0.001993f, 0.002209f, 0.002523f, 0.002863f, 0.003325f, 0.003880f, 0.004715f, 0.005764f, 0.007320f, 0.009468f,
+ 0.013344f, 0.020187f, 0.410645f, 0.473877f, 0.489258f, 0.496826f, 0.500488f, 0.503906f, 0.000103f, 0.000078f, 0.000067f, 0.000065f,
+ 0.000086f, 0.000085f, 0.000101f, 0.000106f, 0.000106f, 0.000107f, 0.000115f, 0.000133f, 0.000118f, 0.000133f, 0.000154f, 0.000150f,
+ 0.000167f, 0.000177f, 0.000180f, 0.000190f, 0.000207f, 0.000213f, 0.000228f, 0.000238f, 0.000267f, 0.000277f, 0.000287f, 0.000298f,
+ 0.000313f, 0.000325f, 0.000347f, 0.000375f, 0.000393f, 0.000405f, 0.000440f, 0.000463f, 0.000486f, 0.000527f, 0.000562f, 0.000599f,
+ 0.000639f, 0.000688f, 0.000757f, 0.000807f, 0.000879f, 0.000961f, 0.001059f, 0.001180f, 0.001342f, 0.001533f, 0.001762f, 0.002102f,
+ 0.002502f, 0.003128f, 0.004028f, 0.005379f, 0.007591f, 0.012505f, 0.397217f, 0.462891f, 0.478760f, 0.485840f, 0.490479f, 0.492676f,
+ 0.000087f, 0.000063f, 0.000054f, 0.000048f, 0.000047f, 0.000044f, 0.000046f, 0.000047f, 0.000047f, 0.000060f, 0.000053f, 0.000056f,
+ 0.000072f, 0.000060f, 0.000064f, 0.000069f, 0.000078f, 0.000085f, 0.000084f, 0.000090f, 0.000094f, 0.000102f, 0.000105f, 0.000111f,
+ 0.000116f, 0.000126f, 0.000132f, 0.000150f, 0.000147f, 0.000158f, 0.000167f, 0.000178f, 0.000185f, 0.000192f, 0.000211f, 0.000216f,
+ 0.000226f, 0.000246f, 0.000265f, 0.000284f, 0.000299f, 0.000325f, 0.000349f, 0.000381f, 0.000415f, 0.000448f, 0.000490f, 0.000544f,
+ 0.000612f, 0.000694f, 0.000798f, 0.000943f, 0.001139f, 0.001436f, 0.001870f, 0.002586f, 0.003817f, 0.006474f, 0.383545f, 0.450195f,
+ 0.467041f, 0.474365f, 0.478760f, 0.482422f, 0.000065f, 0.000045f, 0.000037f, 0.000033f, 0.000030f, 0.000028f, 0.000026f, 0.000025f,
+ 0.000024f, 0.000022f, 0.000021f, 0.000025f, 0.000020f, 0.000021f, 0.000025f, 0.000029f, 0.000028f, 0.000031f, 0.000033f, 0.000034f,
+ 0.000036f, 0.000041f, 0.000045f, 0.000040f, 0.000045f, 0.000049f, 0.000051f, 0.000048f, 0.000055f, 0.000057f, 0.000061f, 0.000066f,
+ 0.000072f, 0.000068f, 0.000073f, 0.000078f, 0.000087f, 0.000089f, 0.000097f, 0.000104f, 0.000113f, 0.000115f, 0.000128f, 0.000137f,
+ 0.000148f, 0.000160f, 0.000174f, 0.000194f, 0.000221f, 0.000248f, 0.000283f, 0.000324f, 0.000396f, 0.000496f, 0.000657f, 0.000928f,
+ 0.001479f, 0.002684f, 0.371094f, 0.438477f, 0.455078f, 0.463867f, 0.468750f, 0.471191f, 0.000029f, 0.000019f, 0.000016f, 0.000014f,
+ 0.000014f, 0.000013f, 0.000012f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000010f,
+ 0.000009f, 0.000009f, 0.000009f, 0.000008f, 0.000008f, 0.000007f, 0.000008f, 0.000007f, 0.000008f, 0.000009f, 0.000010f, 0.000011f,
+ 0.000012f, 0.000011f, 0.000012f, 0.000013f, 0.000015f, 0.000017f, 0.000018f, 0.000018f, 0.000020f, 0.000019f, 0.000021f, 0.000024f,
+ 0.000024f, 0.000026f, 0.000028f, 0.000031f, 0.000031f, 0.000035f, 0.000040f, 0.000041f, 0.000045f, 0.000052f, 0.000059f, 0.000071f,
+ 0.000083f, 0.000099f, 0.000132f, 0.000188f, 0.000315f, 0.000712f, 0.356934f, 0.426514f, 0.444824f, 0.452637f, 0.457520f, 0.460938f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000001f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000003f, 0.000004f, 0.000004f, 0.000006f, 0.000010f, 0.000027f, 0.343750f, 0.414795f,
+ 0.433105f, 0.441895f, 0.446289f, 0.449951f,
+ },
+ {
+ 0.012436f, 0.037598f, 0.062805f, 0.087891f, 0.113037f, 0.137329f, 0.161621f, 0.185425f, 0.209717f, 0.232544f, 0.255371f, 0.278076f,
+ 0.300049f, 0.321289f, 0.343506f, 0.364014f, 0.385010f, 0.404785f, 0.424561f, 0.444824f, 0.463623f, 0.482422f, 0.501465f, 0.520020f,
+ 0.537598f, 0.554688f, 0.572266f, 0.589355f, 0.605957f, 0.622070f, 0.639648f, 0.655273f, 0.670410f, 0.685547f, 0.700684f, 0.715332f,
+ 0.730469f, 0.744629f, 0.758301f, 0.771973f, 0.785156f, 0.799316f, 0.812012f, 0.825684f, 0.837891f, 0.850586f, 0.863281f, 0.875000f,
+ 0.887207f, 0.898926f, 0.910156f, 0.921387f, 0.933105f, 0.944336f, 0.954102f, 0.964844f, 0.976074f, 0.985840f, 0.978027f, 0.947266f,
+ 0.925781f, 0.907715f, 0.892090f, 0.877930f, 0.011276f, 0.034546f, 0.058289f, 0.082031f, 0.105469f, 0.128662f, 0.152344f, 0.174805f,
+ 0.197876f, 0.219604f, 0.241455f, 0.263672f, 0.284912f, 0.306152f, 0.326416f, 0.347168f, 0.366699f, 0.387695f, 0.406494f, 0.426025f,
+ 0.444824f, 0.463379f, 0.481934f, 0.500000f, 0.518066f, 0.535645f, 0.552246f, 0.569824f, 0.586426f, 0.603027f, 0.619141f, 0.634766f,
+ 0.650391f, 0.666016f, 0.681152f, 0.695801f, 0.710938f, 0.725586f, 0.739258f, 0.753906f, 0.768066f, 0.781250f, 0.794922f, 0.807617f,
+ 0.821289f, 0.833496f, 0.846191f, 0.858398f, 0.870605f, 0.882812f, 0.894531f, 0.906250f, 0.917480f, 0.929199f, 0.939453f, 0.951660f,
+ 0.961426f, 0.972656f, 0.971680f, 0.942871f, 0.921875f, 0.904785f, 0.889160f, 0.875977f, 0.010628f, 0.032288f, 0.054932f, 0.076172f,
+ 0.099060f, 0.121216f, 0.142700f, 0.164795f, 0.186279f, 0.207642f, 0.229248f, 0.249756f, 0.269531f, 0.291016f, 0.310791f, 0.331543f,
+ 0.349609f, 0.369385f, 0.388916f, 0.409180f, 0.427246f, 0.444824f, 0.463135f, 0.480713f, 0.499512f, 0.516602f, 0.533203f, 0.550293f,
+ 0.567383f, 0.583496f, 0.599609f, 0.615723f, 0.630859f, 0.646973f, 0.661621f, 0.677246f, 0.691895f, 0.705566f, 0.720703f, 0.735352f,
+ 0.749512f, 0.763184f, 0.776367f, 0.790039f, 0.803223f, 0.816406f, 0.828613f, 0.842285f, 0.854492f, 0.867676f, 0.878418f, 0.890137f,
+ 0.902832f, 0.913086f, 0.925293f, 0.936035f, 0.947754f, 0.958008f, 0.964844f, 0.937500f, 0.917480f, 0.901367f, 0.886719f, 0.873535f,
+ 0.009926f, 0.030167f, 0.050995f, 0.071594f, 0.092346f, 0.113892f, 0.134399f, 0.154663f, 0.175537f, 0.195679f, 0.216309f, 0.235840f,
+ 0.256104f, 0.276611f, 0.295654f, 0.314453f, 0.333496f, 0.353027f, 0.370850f, 0.389404f, 0.408936f, 0.427490f, 0.445312f, 0.462891f,
+ 0.480225f, 0.497803f, 0.513672f, 0.531250f, 0.547363f, 0.563965f, 0.580078f, 0.597168f, 0.612305f, 0.627930f, 0.642578f, 0.658691f,
+ 0.673340f, 0.687500f, 0.702637f, 0.717285f, 0.731445f, 0.744629f, 0.758301f, 0.772461f, 0.786133f, 0.799316f, 0.811523f, 0.824707f,
+ 0.837891f, 0.849121f, 0.861816f, 0.874023f, 0.887207f, 0.898438f, 0.910156f, 0.920898f, 0.932617f, 0.943848f, 0.958008f, 0.932129f,
+ 0.913086f, 0.897461f, 0.883301f, 0.871094f, 0.009178f, 0.028107f, 0.047729f, 0.066895f, 0.086182f, 0.106384f, 0.125977f, 0.145386f,
+ 0.165527f, 0.184937f, 0.203857f, 0.224121f, 0.242676f, 0.261475f, 0.281006f, 0.300049f, 0.318604f, 0.336426f, 0.355469f, 0.372314f,
+ 0.391113f, 0.409424f, 0.426514f, 0.444092f, 0.461426f, 0.477783f, 0.495850f, 0.512207f, 0.528809f, 0.544434f, 0.561035f, 0.576660f,
+ 0.593262f, 0.608398f, 0.623047f, 0.638184f, 0.655273f, 0.668945f, 0.682617f, 0.697754f, 0.712402f, 0.726562f, 0.740234f, 0.753906f,
+ 0.768066f, 0.781250f, 0.794434f, 0.807617f, 0.820312f, 0.833496f, 0.845215f, 0.858398f, 0.870605f, 0.881836f, 0.894043f, 0.906738f,
+ 0.917480f, 0.928711f, 0.951172f, 0.926758f, 0.909180f, 0.893555f, 0.880859f, 0.868164f, 0.008667f, 0.025986f, 0.044922f, 0.062805f,
+ 0.081421f, 0.099854f, 0.118347f, 0.137085f, 0.155518f, 0.173828f, 0.193115f, 0.211304f, 0.229858f, 0.248413f, 0.266602f, 0.285400f,
+ 0.303223f, 0.321045f, 0.339111f, 0.357178f, 0.373779f, 0.391357f, 0.409424f, 0.426270f, 0.443115f, 0.460449f, 0.476807f, 0.494141f,
+ 0.510254f, 0.526855f, 0.541992f, 0.559082f, 0.574219f, 0.589355f, 0.605469f, 0.620117f, 0.636230f, 0.649902f, 0.664551f, 0.678711f,
+ 0.693848f, 0.707031f, 0.723145f, 0.736328f, 0.750977f, 0.762695f, 0.776855f, 0.790039f, 0.803223f, 0.816406f, 0.828613f, 0.842285f,
+ 0.853516f, 0.866211f, 0.878906f, 0.890625f, 0.902832f, 0.913574f, 0.944336f, 0.921875f, 0.903809f, 0.889160f, 0.876953f, 0.865234f,
+ 0.008057f, 0.024658f, 0.041321f, 0.058411f, 0.075989f, 0.093811f, 0.110535f, 0.128784f, 0.146729f, 0.164307f, 0.182007f, 0.200073f,
+ 0.217773f, 0.234619f, 0.252930f, 0.271240f, 0.288086f, 0.306152f, 0.322998f, 0.341064f, 0.357910f, 0.374756f, 0.391357f, 0.409180f,
+ 0.425293f, 0.442383f, 0.458496f, 0.475342f, 0.491455f, 0.507324f, 0.523438f, 0.539551f, 0.555176f, 0.570312f, 0.585938f, 0.601074f,
+ 0.616699f, 0.631836f, 0.646484f, 0.660645f, 0.676270f, 0.688477f, 0.704102f, 0.718262f, 0.731445f, 0.745117f, 0.760254f, 0.771484f,
+ 0.785156f, 0.799316f, 0.812500f, 0.824707f, 0.836914f, 0.850098f, 0.862793f, 0.874512f, 0.886719f, 0.898438f, 0.937500f, 0.915527f,
+ 0.899414f, 0.885254f, 0.872559f, 0.861816f, 0.007477f, 0.022919f, 0.038971f, 0.054901f, 0.070801f, 0.087646f, 0.104065f, 0.121155f,
+ 0.137573f, 0.155029f, 0.171875f, 0.188721f, 0.206177f, 0.222778f, 0.240112f, 0.257080f, 0.274170f, 0.290283f, 0.308350f, 0.324463f,
+ 0.342041f, 0.358154f, 0.375488f, 0.391113f, 0.407471f, 0.424561f, 0.440430f, 0.456787f, 0.474121f, 0.489746f, 0.505371f, 0.521484f,
+ 0.536133f, 0.552246f, 0.565918f, 0.582031f, 0.597168f, 0.613281f, 0.626953f, 0.642578f, 0.656738f, 0.670898f, 0.684570f, 0.699219f,
+ 0.712891f, 0.727539f, 0.741211f, 0.754395f, 0.768066f, 0.781738f, 0.794434f, 0.808105f, 0.820312f, 0.833984f, 0.846680f, 0.858887f,
+ 0.871582f, 0.883301f, 0.930176f, 0.910156f, 0.894043f, 0.880371f, 0.868652f, 0.858398f, 0.007023f, 0.021240f, 0.036224f, 0.051300f,
+ 0.066467f, 0.082092f, 0.097900f, 0.113892f, 0.129517f, 0.145752f, 0.161743f, 0.178223f, 0.194702f, 0.210327f, 0.227661f, 0.243408f,
+ 0.260986f, 0.276855f, 0.292725f, 0.309814f, 0.326172f, 0.342041f, 0.358398f, 0.375732f, 0.391113f, 0.406982f, 0.422852f, 0.438965f,
+ 0.454590f, 0.471191f, 0.486816f, 0.502441f, 0.517578f, 0.533203f, 0.548340f, 0.562988f, 0.578613f, 0.593750f, 0.609375f, 0.623535f,
+ 0.638184f, 0.652832f, 0.666992f, 0.680664f, 0.695312f, 0.708984f, 0.722656f, 0.736816f, 0.750000f, 0.764160f, 0.777344f, 0.789551f,
+ 0.803223f, 0.816895f, 0.830078f, 0.842773f, 0.854980f, 0.868652f, 0.922852f, 0.904297f, 0.889160f, 0.875977f, 0.864746f, 0.854492f,
+ 0.006458f, 0.019913f, 0.033691f, 0.048126f, 0.062744f, 0.077026f, 0.092224f, 0.106567f, 0.122192f, 0.137207f, 0.152222f, 0.167725f,
+ 0.183838f, 0.199951f, 0.215088f, 0.231323f, 0.246826f, 0.262695f, 0.279053f, 0.294678f, 0.310547f, 0.326172f, 0.342041f, 0.358887f,
+ 0.374268f, 0.389893f, 0.405518f, 0.421143f, 0.437012f, 0.452637f, 0.467773f, 0.483643f, 0.499512f, 0.513672f, 0.529785f, 0.545410f,
+ 0.560059f, 0.575195f, 0.590332f, 0.604980f, 0.618652f, 0.634277f, 0.648438f, 0.662598f, 0.676270f, 0.690918f, 0.704102f, 0.718750f,
+ 0.732422f, 0.745605f, 0.760254f, 0.773438f, 0.786621f, 0.801270f, 0.812988f, 0.826172f, 0.839844f, 0.851562f, 0.915527f, 0.897949f,
+ 0.883789f, 0.871094f, 0.860352f, 0.850586f, 0.006077f, 0.018921f, 0.031464f, 0.045258f, 0.058411f, 0.072144f, 0.085999f, 0.100220f,
+ 0.114258f, 0.129028f, 0.143677f, 0.158691f, 0.173584f, 0.188477f, 0.203247f, 0.219238f, 0.234497f, 0.249634f, 0.264893f, 0.280273f,
+ 0.295410f, 0.310791f, 0.326904f, 0.342285f, 0.357910f, 0.373535f, 0.388428f, 0.404053f, 0.420166f, 0.435303f, 0.450195f, 0.465332f,
+ 0.481201f, 0.496338f, 0.511230f, 0.525879f, 0.540527f, 0.556641f, 0.570312f, 0.585938f, 0.600098f, 0.614746f, 0.629883f, 0.644531f,
+ 0.657715f, 0.672363f, 0.687012f, 0.700684f, 0.714355f, 0.729004f, 0.742188f, 0.755371f, 0.769531f, 0.782227f, 0.796875f, 0.810059f,
+ 0.823242f, 0.836426f, 0.907715f, 0.891602f, 0.877930f, 0.866211f, 0.855957f, 0.846680f, 0.005596f, 0.017654f, 0.029587f, 0.041840f,
+ 0.055115f, 0.067871f, 0.080566f, 0.093994f, 0.107361f, 0.120911f, 0.134766f, 0.149414f, 0.163452f, 0.177979f, 0.192261f, 0.206787f,
+ 0.221191f, 0.236816f, 0.250732f, 0.266113f, 0.281250f, 0.295898f, 0.311279f, 0.326904f, 0.342041f, 0.356201f, 0.371826f, 0.387451f,
+ 0.402344f, 0.417236f, 0.432373f, 0.447266f, 0.462891f, 0.477539f, 0.492432f, 0.506836f, 0.522949f, 0.536621f, 0.551758f, 0.566895f,
+ 0.582031f, 0.596191f, 0.610352f, 0.625488f, 0.640625f, 0.653320f, 0.668457f, 0.682617f, 0.696777f, 0.710449f, 0.724609f, 0.739258f,
+ 0.751465f, 0.765625f, 0.780273f, 0.792480f, 0.806152f, 0.820801f, 0.899902f, 0.885742f, 0.872070f, 0.861328f, 0.851562f, 0.842285f,
+ 0.005451f, 0.016479f, 0.028259f, 0.039856f, 0.051331f, 0.063416f, 0.075867f, 0.088196f, 0.100952f, 0.113770f, 0.126953f, 0.140747f,
+ 0.153564f, 0.167847f, 0.181519f, 0.195679f, 0.210083f, 0.223633f, 0.237427f, 0.252197f, 0.267334f, 0.281738f, 0.296143f, 0.311035f,
+ 0.325928f, 0.340332f, 0.355469f, 0.370361f, 0.385010f, 0.400635f, 0.415039f, 0.429688f, 0.444092f, 0.459717f, 0.474121f, 0.489258f,
+ 0.503906f, 0.519043f, 0.533203f, 0.548828f, 0.562012f, 0.577637f, 0.591797f, 0.606445f, 0.621582f, 0.635742f, 0.650391f, 0.664551f,
+ 0.678223f, 0.692871f, 0.706055f, 0.721191f, 0.733887f, 0.747559f, 0.762207f, 0.775879f, 0.791016f, 0.804199f, 0.892090f, 0.878906f,
+ 0.866699f, 0.855957f, 0.846191f, 0.837891f, 0.004963f, 0.015343f, 0.026169f, 0.037079f, 0.047943f, 0.059570f, 0.070801f, 0.083008f,
+ 0.095093f, 0.106750f, 0.119507f, 0.132080f, 0.145142f, 0.158569f, 0.171143f, 0.184692f, 0.198730f, 0.211792f, 0.225830f, 0.239380f,
+ 0.253662f, 0.267578f, 0.281738f, 0.295898f, 0.309814f, 0.324219f, 0.340088f, 0.353760f, 0.368164f, 0.383057f, 0.397705f, 0.412842f,
+ 0.426758f, 0.441406f, 0.456787f, 0.470947f, 0.485352f, 0.500000f, 0.515137f, 0.529785f, 0.543945f, 0.559082f, 0.572754f, 0.588379f,
+ 0.602539f, 0.616699f, 0.631348f, 0.645996f, 0.659180f, 0.674805f, 0.689453f, 0.703125f, 0.716797f, 0.729980f, 0.744629f, 0.758789f,
+ 0.772461f, 0.786621f, 0.883789f, 0.872070f, 0.860840f, 0.850586f, 0.841309f, 0.833008f, 0.004726f, 0.014549f, 0.024109f, 0.034668f,
+ 0.044708f, 0.055573f, 0.066467f, 0.077820f, 0.088928f, 0.100342f, 0.112000f, 0.124390f, 0.136230f, 0.148804f, 0.161621f, 0.173950f,
+ 0.186768f, 0.200439f, 0.213623f, 0.226074f, 0.239868f, 0.253418f, 0.267090f, 0.281250f, 0.295410f, 0.309570f, 0.323486f, 0.337891f,
+ 0.352295f, 0.365967f, 0.381104f, 0.394775f, 0.409180f, 0.423828f, 0.438477f, 0.452881f, 0.467773f, 0.481689f, 0.496582f, 0.511230f,
+ 0.525391f, 0.539551f, 0.554199f, 0.568848f, 0.583984f, 0.599121f, 0.612305f, 0.627441f, 0.641113f, 0.656250f, 0.669922f, 0.684570f,
+ 0.699219f, 0.713379f, 0.727539f, 0.741699f, 0.755859f, 0.771484f, 0.875488f, 0.865723f, 0.854492f, 0.845215f, 0.836426f, 0.828613f,
+ 0.004452f, 0.013359f, 0.022690f, 0.032745f, 0.042297f, 0.051910f, 0.061920f, 0.072693f, 0.083496f, 0.094177f, 0.105408f, 0.116760f,
+ 0.128174f, 0.140137f, 0.151855f, 0.164185f, 0.176758f, 0.189087f, 0.201660f, 0.214478f, 0.227173f, 0.240356f, 0.253906f, 0.267578f,
+ 0.280273f, 0.294922f, 0.307373f, 0.321045f, 0.336670f, 0.350098f, 0.363770f, 0.378174f, 0.392334f, 0.406006f, 0.420410f, 0.434082f,
+ 0.448975f, 0.463623f, 0.478271f, 0.492676f, 0.506836f, 0.520996f, 0.536133f, 0.550781f, 0.565430f, 0.580078f, 0.593750f, 0.608887f,
+ 0.623047f, 0.638184f, 0.651367f, 0.666016f, 0.681152f, 0.695312f, 0.709473f, 0.723145f, 0.738281f, 0.752930f, 0.867676f, 0.858398f,
+ 0.848633f, 0.839355f, 0.831055f, 0.823730f, 0.004143f, 0.012794f, 0.021713f, 0.030396f, 0.039551f, 0.048645f, 0.058563f, 0.068176f,
+ 0.078308f, 0.088928f, 0.098328f, 0.109924f, 0.120728f, 0.131592f, 0.142944f, 0.154175f, 0.165771f, 0.178223f, 0.190186f, 0.202881f,
+ 0.214844f, 0.227417f, 0.240845f, 0.253906f, 0.265869f, 0.279541f, 0.293213f, 0.305908f, 0.320068f, 0.333496f, 0.347168f, 0.361816f,
+ 0.375000f, 0.389160f, 0.403320f, 0.417236f, 0.431396f, 0.444824f, 0.459473f, 0.473633f, 0.488525f, 0.503418f, 0.517578f, 0.532227f,
+ 0.545410f, 0.560547f, 0.575684f, 0.590332f, 0.604004f, 0.618652f, 0.632812f, 0.647949f, 0.663086f, 0.676758f, 0.691895f, 0.706543f,
+ 0.721191f, 0.735840f, 0.859375f, 0.852539f, 0.842773f, 0.833496f, 0.824707f, 0.818848f, 0.003839f, 0.012062f, 0.020126f, 0.028366f,
+ 0.036774f, 0.045593f, 0.054718f, 0.063416f, 0.073120f, 0.082825f, 0.092957f, 0.102966f, 0.113464f, 0.123535f, 0.134277f, 0.145020f,
+ 0.155762f, 0.167847f, 0.179199f, 0.190796f, 0.202393f, 0.214844f, 0.227417f, 0.239868f, 0.252197f, 0.264648f, 0.277588f, 0.291016f,
+ 0.304199f, 0.317383f, 0.330811f, 0.343750f, 0.357422f, 0.371826f, 0.385254f, 0.399902f, 0.413574f, 0.427246f, 0.441162f, 0.455566f,
+ 0.469971f, 0.484375f, 0.498535f, 0.514160f, 0.527344f, 0.541992f, 0.556152f, 0.570312f, 0.585449f, 0.600098f, 0.614746f, 0.629883f,
+ 0.645508f, 0.658203f, 0.673340f, 0.688477f, 0.703125f, 0.718262f, 0.851074f, 0.844727f, 0.835938f, 0.827637f, 0.820312f, 0.812988f,
+ 0.003786f, 0.011147f, 0.018921f, 0.026550f, 0.034729f, 0.042664f, 0.051117f, 0.060028f, 0.068298f, 0.077454f, 0.086914f, 0.096130f,
+ 0.105835f, 0.115662f, 0.126343f, 0.136475f, 0.146606f, 0.157715f, 0.168457f, 0.180176f, 0.191528f, 0.202759f, 0.215088f, 0.226929f,
+ 0.239014f, 0.251221f, 0.263428f, 0.275391f, 0.289062f, 0.301514f, 0.314941f, 0.328369f, 0.341797f, 0.354736f, 0.367676f, 0.382324f,
+ 0.395264f, 0.409912f, 0.423340f, 0.437012f, 0.451660f, 0.465576f, 0.480469f, 0.494629f, 0.508301f, 0.522949f, 0.538086f, 0.551758f,
+ 0.567383f, 0.582031f, 0.596191f, 0.610840f, 0.625977f, 0.639648f, 0.655273f, 0.670410f, 0.685547f, 0.700684f, 0.842285f, 0.837402f,
+ 0.829590f, 0.821289f, 0.813965f, 0.808105f, 0.003504f, 0.010445f, 0.017609f, 0.025131f, 0.032349f, 0.040314f, 0.047485f, 0.055756f,
+ 0.064026f, 0.072571f, 0.080872f, 0.089661f, 0.099426f, 0.108459f, 0.118286f, 0.127930f, 0.137817f, 0.147583f, 0.158203f, 0.169189f,
+ 0.180908f, 0.191040f, 0.203003f, 0.214111f, 0.225708f, 0.237549f, 0.249023f, 0.261475f, 0.273926f, 0.286865f, 0.299316f, 0.311768f,
+ 0.325684f, 0.338623f, 0.351562f, 0.364746f, 0.378418f, 0.392578f, 0.405518f, 0.419678f, 0.433105f, 0.447998f, 0.461670f, 0.475830f,
+ 0.490479f, 0.503906f, 0.519531f, 0.533203f, 0.547852f, 0.562988f, 0.576660f, 0.591797f, 0.606445f, 0.622070f, 0.636719f, 0.652344f,
+ 0.666504f, 0.682617f, 0.833496f, 0.830078f, 0.822754f, 0.815918f, 0.808594f, 0.802734f, 0.003447f, 0.009941f, 0.016373f, 0.023300f,
+ 0.030228f, 0.037689f, 0.044128f, 0.052551f, 0.059845f, 0.068115f, 0.076538f, 0.083862f, 0.092896f, 0.101440f, 0.110596f, 0.119995f,
+ 0.129028f, 0.138916f, 0.148926f, 0.158936f, 0.169189f, 0.180176f, 0.190308f, 0.201416f, 0.212769f, 0.224365f, 0.235962f, 0.247192f,
+ 0.259033f, 0.271973f, 0.283936f, 0.296631f, 0.309570f, 0.321777f, 0.334961f, 0.348389f, 0.361572f, 0.374756f, 0.388184f, 0.401611f,
+ 0.415771f, 0.429443f, 0.443359f, 0.457520f, 0.471436f, 0.486084f, 0.500977f, 0.514648f, 0.528809f, 0.543457f, 0.558594f, 0.573242f,
+ 0.588867f, 0.603516f, 0.617676f, 0.633301f, 0.648926f, 0.664551f, 0.824219f, 0.823242f, 0.815918f, 0.809082f, 0.802246f, 0.796387f,
+ 0.003141f, 0.009407f, 0.015251f, 0.021851f, 0.028107f, 0.034882f, 0.041779f, 0.048340f, 0.056244f, 0.062988f, 0.071106f, 0.078796f,
+ 0.087036f, 0.094910f, 0.103149f, 0.112305f, 0.121460f, 0.130371f, 0.139404f, 0.149048f, 0.159180f, 0.169189f, 0.179565f, 0.189087f,
+ 0.200317f, 0.211548f, 0.222412f, 0.233765f, 0.245117f, 0.257324f, 0.269043f, 0.281006f, 0.293213f, 0.305664f, 0.318848f, 0.331055f,
+ 0.343750f, 0.358398f, 0.369873f, 0.384033f, 0.397217f, 0.411865f, 0.424805f, 0.438965f, 0.453125f, 0.467529f, 0.481689f, 0.495850f,
+ 0.510254f, 0.524414f, 0.539551f, 0.554688f, 0.569824f, 0.584961f, 0.599121f, 0.614258f, 0.629883f, 0.645020f, 0.815430f, 0.814453f,
+ 0.809570f, 0.802734f, 0.796875f, 0.791504f, 0.002838f, 0.008461f, 0.014236f, 0.020676f, 0.026749f, 0.032593f, 0.039032f, 0.045715f,
+ 0.052216f, 0.059479f, 0.066467f, 0.073608f, 0.080933f, 0.088623f, 0.096619f, 0.104919f, 0.113098f, 0.121521f, 0.130493f, 0.139526f,
+ 0.148560f, 0.158203f, 0.167969f, 0.177979f, 0.187988f, 0.198730f, 0.208862f, 0.220093f, 0.231323f, 0.242798f, 0.253906f, 0.265869f,
+ 0.278320f, 0.289551f, 0.302246f, 0.314941f, 0.327393f, 0.340088f, 0.353516f, 0.365967f, 0.379883f, 0.392822f, 0.406738f, 0.420898f,
+ 0.434814f, 0.447998f, 0.462891f, 0.477539f, 0.491455f, 0.506836f, 0.520996f, 0.536133f, 0.550781f, 0.565918f, 0.581055f, 0.596680f,
+ 0.611816f, 0.627441f, 0.806152f, 0.807617f, 0.801270f, 0.796387f, 0.790039f, 0.784668f, 0.002689f, 0.008102f, 0.013618f, 0.019058f,
+ 0.024719f, 0.030548f, 0.036560f, 0.042725f, 0.048615f, 0.054779f, 0.061615f, 0.068604f, 0.075012f, 0.082703f, 0.090271f, 0.097900f,
+ 0.105530f, 0.113586f, 0.121826f, 0.130371f, 0.139282f, 0.147705f, 0.157349f, 0.166504f, 0.176147f, 0.186401f, 0.196289f, 0.207520f,
+ 0.217651f, 0.228394f, 0.239868f, 0.251465f, 0.262451f, 0.274414f, 0.286377f, 0.298828f, 0.311035f, 0.323730f, 0.336670f, 0.349121f,
+ 0.362549f, 0.375244f, 0.389160f, 0.402344f, 0.417236f, 0.429932f, 0.443848f, 0.458984f, 0.472168f, 0.487793f, 0.501953f, 0.517578f,
+ 0.531738f, 0.546875f, 0.561523f, 0.576660f, 0.593262f, 0.608398f, 0.797852f, 0.798828f, 0.794922f, 0.789551f, 0.784668f, 0.779297f,
+ 0.002666f, 0.007462f, 0.012596f, 0.018066f, 0.023026f, 0.028412f, 0.033813f, 0.039398f, 0.045166f, 0.051239f, 0.057587f, 0.063721f,
+ 0.070312f, 0.077148f, 0.084167f, 0.090820f, 0.098267f, 0.105591f, 0.113159f, 0.121460f, 0.129761f, 0.138428f, 0.147217f, 0.156128f,
+ 0.165283f, 0.174438f, 0.183960f, 0.194092f, 0.204834f, 0.214844f, 0.225830f, 0.236816f, 0.247925f, 0.259033f, 0.270752f, 0.282227f,
+ 0.294678f, 0.306641f, 0.319336f, 0.332031f, 0.344482f, 0.357910f, 0.371094f, 0.384033f, 0.398682f, 0.412109f, 0.425781f, 0.440186f,
+ 0.454102f, 0.468018f, 0.482910f, 0.497314f, 0.512207f, 0.528320f, 0.542969f, 0.558594f, 0.573242f, 0.589355f, 0.787598f, 0.791016f,
+ 0.787109f, 0.781738f, 0.777344f, 0.772461f, 0.002569f, 0.007069f, 0.012199f, 0.016739f, 0.021393f, 0.026672f, 0.031189f, 0.037109f,
+ 0.042480f, 0.047729f, 0.053345f, 0.059387f, 0.065430f, 0.071838f, 0.078186f, 0.084167f, 0.091492f, 0.098816f, 0.105774f, 0.112976f,
+ 0.121155f, 0.129028f, 0.136963f, 0.145508f, 0.153687f, 0.163086f, 0.172363f, 0.181885f, 0.191406f, 0.201782f, 0.211670f, 0.222412f,
+ 0.233032f, 0.244263f, 0.255371f, 0.266846f, 0.278809f, 0.290527f, 0.302734f, 0.314697f, 0.327393f, 0.340820f, 0.353027f, 0.366455f,
+ 0.380127f, 0.393799f, 0.406006f, 0.421143f, 0.435059f, 0.449707f, 0.463623f, 0.479248f, 0.494141f, 0.509277f, 0.523438f, 0.539551f,
+ 0.555176f, 0.570801f, 0.778320f, 0.783203f, 0.779785f, 0.775879f, 0.770996f, 0.767090f, 0.002398f, 0.006733f, 0.010918f, 0.015495f,
+ 0.020203f, 0.024963f, 0.029663f, 0.034485f, 0.039246f, 0.044678f, 0.049896f, 0.055267f, 0.060486f, 0.066345f, 0.072693f, 0.078857f,
+ 0.085083f, 0.091370f, 0.097961f, 0.105530f, 0.112244f, 0.119629f, 0.127563f, 0.135376f, 0.143799f, 0.152100f, 0.160889f, 0.169922f,
+ 0.178833f, 0.188843f, 0.198608f, 0.208496f, 0.218628f, 0.229492f, 0.240479f, 0.251953f, 0.262695f, 0.274902f, 0.286377f, 0.298340f,
+ 0.310547f, 0.323242f, 0.335693f, 0.349365f, 0.362061f, 0.375000f, 0.388916f, 0.402832f, 0.416748f, 0.430420f, 0.445068f, 0.459473f,
+ 0.474854f, 0.489258f, 0.504883f, 0.519531f, 0.535645f, 0.551758f, 0.769043f, 0.774902f, 0.771973f, 0.768555f, 0.764160f, 0.759766f,
+ 0.002062f, 0.006191f, 0.010384f, 0.014786f, 0.018402f, 0.023270f, 0.027435f, 0.031891f, 0.036163f, 0.041199f, 0.045685f, 0.051208f,
+ 0.056244f, 0.061371f, 0.066772f, 0.072510f, 0.078369f, 0.084656f, 0.091125f, 0.097290f, 0.104309f, 0.111145f, 0.118164f, 0.126221f,
+ 0.133301f, 0.141724f, 0.149658f, 0.157837f, 0.167236f, 0.176025f, 0.185547f, 0.195190f, 0.205444f, 0.215332f, 0.225830f, 0.236084f,
+ 0.247314f, 0.259033f, 0.270020f, 0.281982f, 0.293701f, 0.305908f, 0.318848f, 0.331787f, 0.344482f, 0.357178f, 0.370361f, 0.384521f,
+ 0.397461f, 0.411621f, 0.426025f, 0.440674f, 0.455322f, 0.470703f, 0.485596f, 0.500977f, 0.517578f, 0.532227f, 0.759277f, 0.766602f,
+ 0.764160f, 0.761230f, 0.757324f, 0.753418f, 0.002064f, 0.005859f, 0.009613f, 0.013626f, 0.017456f, 0.021606f, 0.025574f, 0.029526f,
+ 0.034302f, 0.038422f, 0.042938f, 0.047485f, 0.052155f, 0.056763f, 0.061951f, 0.067139f, 0.072754f, 0.078308f, 0.084167f, 0.090149f,
+ 0.096191f, 0.102722f, 0.109558f, 0.116699f, 0.123901f, 0.131104f, 0.139160f, 0.146729f, 0.155273f, 0.163940f, 0.173096f, 0.182129f,
+ 0.192017f, 0.201172f, 0.211060f, 0.221558f, 0.232544f, 0.243530f, 0.254150f, 0.266113f, 0.277588f, 0.289307f, 0.301758f, 0.313965f,
+ 0.326904f, 0.338867f, 0.352051f, 0.366211f, 0.379150f, 0.393066f, 0.407471f, 0.421875f, 0.436768f, 0.450439f, 0.466553f, 0.481201f,
+ 0.497314f, 0.513184f, 0.749512f, 0.758301f, 0.756348f, 0.753906f, 0.750000f, 0.746582f, 0.001851f, 0.005405f, 0.009109f, 0.012589f,
+ 0.016129f, 0.020020f, 0.023926f, 0.027481f, 0.031738f, 0.035492f, 0.039734f, 0.044128f, 0.048065f, 0.052765f, 0.057373f, 0.061859f,
+ 0.066711f, 0.072388f, 0.077393f, 0.083130f, 0.088745f, 0.094727f, 0.101135f, 0.107666f, 0.114380f, 0.121704f, 0.128540f, 0.136108f,
+ 0.144043f, 0.151733f, 0.160522f, 0.169678f, 0.178589f, 0.187622f, 0.197998f, 0.207397f, 0.217285f, 0.227905f, 0.238892f, 0.250000f,
+ 0.261230f, 0.272461f, 0.284180f, 0.296387f, 0.308838f, 0.321533f, 0.334473f, 0.347656f, 0.361328f, 0.375000f, 0.388672f, 0.402588f,
+ 0.417969f, 0.432617f, 0.447021f, 0.461914f, 0.478516f, 0.493652f, 0.739258f, 0.749512f, 0.749023f, 0.745605f, 0.742188f, 0.739746f,
+ 0.001666f, 0.005405f, 0.008575f, 0.011696f, 0.015327f, 0.018646f, 0.022293f, 0.025650f, 0.029327f, 0.032776f, 0.036530f, 0.040619f,
+ 0.044128f, 0.048828f, 0.052887f, 0.057098f, 0.061829f, 0.066467f, 0.071350f, 0.076355f, 0.081909f, 0.087341f, 0.092896f, 0.099304f,
+ 0.105469f, 0.112000f, 0.118835f, 0.125977f, 0.133545f, 0.140991f, 0.148438f, 0.156982f, 0.165771f, 0.174805f, 0.183960f, 0.193115f,
+ 0.203369f, 0.212891f, 0.223389f, 0.234497f, 0.244751f, 0.256348f, 0.268066f, 0.279541f, 0.291260f, 0.303955f, 0.316406f, 0.329590f,
+ 0.342529f, 0.355957f, 0.369385f, 0.384766f, 0.398926f, 0.413330f, 0.428467f, 0.442383f, 0.458740f, 0.474609f, 0.728516f, 0.740723f,
+ 0.740234f, 0.738281f, 0.735352f, 0.732910f, 0.001534f, 0.004936f, 0.007980f, 0.011223f, 0.013893f, 0.017212f, 0.020294f, 0.023361f,
+ 0.026688f, 0.030182f, 0.033600f, 0.037537f, 0.040924f, 0.044495f, 0.048340f, 0.052155f, 0.056732f, 0.061035f, 0.065430f, 0.069824f,
+ 0.075073f, 0.080078f, 0.085571f, 0.091003f, 0.096863f, 0.103271f, 0.109009f, 0.115723f, 0.123230f, 0.129639f, 0.137207f, 0.145264f,
+ 0.153320f, 0.161499f, 0.170410f, 0.179688f, 0.189087f, 0.198364f, 0.208740f, 0.218750f, 0.229126f, 0.240356f, 0.251465f, 0.263184f,
+ 0.274902f, 0.286621f, 0.299072f, 0.311768f, 0.324463f, 0.337402f, 0.351074f, 0.364746f, 0.378662f, 0.394287f, 0.408936f, 0.423096f,
+ 0.439453f, 0.455322f, 0.716797f, 0.731934f, 0.732422f, 0.729980f, 0.728027f, 0.725586f, 0.001639f, 0.004337f, 0.007439f, 0.009888f,
+ 0.013092f, 0.015717f, 0.018921f, 0.021805f, 0.024612f, 0.027542f, 0.030762f, 0.034088f, 0.037598f, 0.041107f, 0.044189f, 0.047699f,
+ 0.051666f, 0.055664f, 0.059723f, 0.064148f, 0.068542f, 0.073425f, 0.078003f, 0.083435f, 0.088806f, 0.094360f, 0.100159f, 0.106079f,
+ 0.112915f, 0.119690f, 0.125977f, 0.133667f, 0.141357f, 0.149414f, 0.157349f, 0.166260f, 0.175049f, 0.184326f, 0.193970f, 0.203735f,
+ 0.214355f, 0.224609f, 0.235352f, 0.246460f, 0.257568f, 0.269287f, 0.281738f, 0.294189f, 0.305908f, 0.319824f, 0.332520f, 0.346680f,
+ 0.360596f, 0.375244f, 0.389648f, 0.404297f, 0.419189f, 0.435791f, 0.707520f, 0.723145f, 0.723633f, 0.722656f, 0.720703f, 0.717773f,
+ 0.001469f, 0.004345f, 0.006844f, 0.009483f, 0.012428f, 0.014679f, 0.017166f, 0.019989f, 0.022949f, 0.025574f, 0.028320f, 0.031525f,
+ 0.034088f, 0.037323f, 0.040710f, 0.043762f, 0.047119f, 0.050873f, 0.054352f, 0.058441f, 0.062561f, 0.066711f, 0.071167f, 0.075989f,
+ 0.080627f, 0.086426f, 0.091553f, 0.097473f, 0.103210f, 0.109680f, 0.115723f, 0.122986f, 0.129761f, 0.137451f, 0.145142f, 0.153198f,
+ 0.161621f, 0.170654f, 0.179688f, 0.189087f, 0.198730f, 0.209229f, 0.219604f, 0.230225f, 0.241211f, 0.252197f, 0.264404f, 0.276367f,
+ 0.288574f, 0.301270f, 0.314453f, 0.328125f, 0.341309f, 0.354980f, 0.370117f, 0.385498f, 0.399902f, 0.415771f, 0.696289f, 0.714355f,
+ 0.715820f, 0.714355f, 0.712891f, 0.710449f, 0.001227f, 0.003862f, 0.006245f, 0.008644f, 0.010796f, 0.013344f, 0.015823f, 0.018448f,
+ 0.020645f, 0.023331f, 0.025681f, 0.028305f, 0.030975f, 0.033722f, 0.036987f, 0.039673f, 0.043121f, 0.046112f, 0.049774f, 0.053406f,
+ 0.056854f, 0.060760f, 0.064697f, 0.069397f, 0.073364f, 0.078369f, 0.083313f, 0.088257f, 0.094116f, 0.100098f, 0.105957f, 0.112122f,
+ 0.118774f, 0.125854f, 0.133057f, 0.140869f, 0.148682f, 0.157227f, 0.165405f, 0.174927f, 0.184082f, 0.193726f, 0.204102f, 0.214111f,
+ 0.225098f, 0.236328f, 0.247314f, 0.259277f, 0.270752f, 0.282959f, 0.296143f, 0.309082f, 0.322510f, 0.336426f, 0.350830f, 0.365479f,
+ 0.380371f, 0.396240f, 0.684570f, 0.705078f, 0.706543f, 0.706543f, 0.705078f, 0.703125f, 0.001069f, 0.003525f, 0.006062f, 0.008286f,
+ 0.010178f, 0.012589f, 0.014542f, 0.017075f, 0.019241f, 0.021179f, 0.023499f, 0.026047f, 0.028137f, 0.030762f, 0.033417f, 0.035889f,
+ 0.038757f, 0.041779f, 0.044586f, 0.048309f, 0.051056f, 0.054810f, 0.058777f, 0.062347f, 0.066528f, 0.070740f, 0.075256f, 0.080261f,
+ 0.085205f, 0.090393f, 0.095886f, 0.102478f, 0.108154f, 0.114441f, 0.121399f, 0.128784f, 0.135742f, 0.144165f, 0.151978f, 0.160767f,
+ 0.169434f, 0.178833f, 0.188721f, 0.198608f, 0.208984f, 0.220215f, 0.230957f, 0.241943f, 0.253906f, 0.265869f, 0.278564f, 0.291260f,
+ 0.304443f, 0.318359f, 0.332031f, 0.346680f, 0.361572f, 0.377197f, 0.673828f, 0.695801f, 0.698242f, 0.697754f, 0.697266f, 0.695312f,
+ 0.001211f, 0.003250f, 0.005112f, 0.007195f, 0.009651f, 0.011414f, 0.013641f, 0.015205f, 0.017334f, 0.019608f, 0.021164f, 0.023712f,
+ 0.025726f, 0.027863f, 0.029984f, 0.032410f, 0.035034f, 0.037689f, 0.040466f, 0.042938f, 0.046478f, 0.049591f, 0.052856f, 0.056274f,
+ 0.060089f, 0.063721f, 0.068115f, 0.072266f, 0.076904f, 0.081970f, 0.087036f, 0.092285f, 0.097961f, 0.104309f, 0.110535f, 0.117126f,
+ 0.124084f, 0.131226f, 0.139038f, 0.147095f, 0.155884f, 0.164429f, 0.174194f, 0.183228f, 0.192749f, 0.203491f, 0.214233f, 0.224976f,
+ 0.236206f, 0.247925f, 0.260498f, 0.272705f, 0.285889f, 0.299805f, 0.312988f, 0.327637f, 0.342529f, 0.356934f, 0.662598f, 0.686523f,
+ 0.689453f, 0.689453f, 0.688965f, 0.687500f, 0.001138f, 0.003206f, 0.005180f, 0.007309f, 0.008377f, 0.010635f, 0.012352f, 0.014153f,
+ 0.015640f, 0.017487f, 0.019272f, 0.021164f, 0.023026f, 0.025314f, 0.027222f, 0.029282f, 0.031433f, 0.033600f, 0.036041f, 0.038788f,
+ 0.041626f, 0.044281f, 0.047455f, 0.050507f, 0.054047f, 0.057556f, 0.061188f, 0.065063f, 0.069214f, 0.073486f, 0.078369f, 0.083191f,
+ 0.088196f, 0.093811f, 0.099609f, 0.106018f, 0.112305f, 0.119385f, 0.126343f, 0.134033f, 0.142090f, 0.150635f, 0.159546f, 0.168579f,
+ 0.177734f, 0.187500f, 0.198242f, 0.208618f, 0.219604f, 0.231812f, 0.242188f, 0.254883f, 0.267578f, 0.281494f, 0.294434f, 0.308350f,
+ 0.322998f, 0.338379f, 0.651367f, 0.676758f, 0.681152f, 0.680664f, 0.680664f, 0.679688f, 0.000977f, 0.002806f, 0.004559f, 0.006176f,
+ 0.008034f, 0.009476f, 0.011131f, 0.012741f, 0.014275f, 0.015732f, 0.017334f, 0.019104f, 0.020767f, 0.022293f, 0.024323f, 0.026016f,
+ 0.028198f, 0.030197f, 0.032257f, 0.034515f, 0.036957f, 0.039856f, 0.042084f, 0.044891f, 0.047791f, 0.051147f, 0.054535f, 0.058197f,
+ 0.061768f, 0.065674f, 0.069946f, 0.074585f, 0.079102f, 0.084412f, 0.089600f, 0.095398f, 0.101196f, 0.107544f, 0.114258f, 0.121094f,
+ 0.128662f, 0.137085f, 0.145020f, 0.153687f, 0.162720f, 0.172607f, 0.182129f, 0.192749f, 0.203125f, 0.214111f, 0.226074f, 0.237671f,
+ 0.249878f, 0.262207f, 0.275635f, 0.289551f, 0.304199f, 0.318848f, 0.639160f, 0.666992f, 0.671387f, 0.671875f, 0.671875f, 0.671387f,
+ 0.000968f, 0.002722f, 0.004318f, 0.005634f, 0.007393f, 0.008667f, 0.010139f, 0.011383f, 0.012856f, 0.014389f, 0.015427f, 0.016907f,
+ 0.018387f, 0.020081f, 0.021683f, 0.023315f, 0.025085f, 0.026840f, 0.028641f, 0.030624f, 0.032837f, 0.035065f, 0.037445f, 0.039948f,
+ 0.042542f, 0.045410f, 0.048340f, 0.051514f, 0.054840f, 0.058502f, 0.062408f, 0.066223f, 0.070679f, 0.075134f, 0.080078f, 0.085388f,
+ 0.090515f, 0.096436f, 0.102722f, 0.109314f, 0.116333f, 0.123352f, 0.131592f, 0.139526f, 0.147949f, 0.156860f, 0.166748f, 0.176758f,
+ 0.187134f, 0.197632f, 0.209106f, 0.220337f, 0.232666f, 0.244751f, 0.257568f, 0.270996f, 0.284912f, 0.300537f, 0.627441f, 0.657227f,
+ 0.662598f, 0.663574f, 0.663574f, 0.663086f, 0.001081f, 0.002466f, 0.003862f, 0.005348f, 0.006447f, 0.007927f, 0.009018f, 0.010490f,
+ 0.011436f, 0.012627f, 0.013916f, 0.015015f, 0.016449f, 0.017563f, 0.019165f, 0.020706f, 0.021973f, 0.023834f, 0.025467f, 0.027130f,
+ 0.029175f, 0.030991f, 0.033081f, 0.035156f, 0.037384f, 0.040039f, 0.042603f, 0.045502f, 0.048492f, 0.051636f, 0.054962f, 0.058716f,
+ 0.062439f, 0.066467f, 0.071045f, 0.075378f, 0.080811f, 0.085815f, 0.091492f, 0.098022f, 0.103943f, 0.111023f, 0.118164f, 0.125732f,
+ 0.133911f, 0.142456f, 0.151367f, 0.161011f, 0.170898f, 0.181396f, 0.192139f, 0.203247f, 0.214844f, 0.227173f, 0.239380f, 0.252441f,
+ 0.266602f, 0.281006f, 0.616699f, 0.647949f, 0.653320f, 0.655273f, 0.654785f, 0.655273f, 0.000735f, 0.002331f, 0.003601f, 0.005005f,
+ 0.005825f, 0.007061f, 0.008049f, 0.009148f, 0.010315f, 0.011131f, 0.012230f, 0.013367f, 0.014328f, 0.015541f, 0.016968f, 0.018234f,
+ 0.019257f, 0.020798f, 0.022202f, 0.023666f, 0.025452f, 0.027115f, 0.028885f, 0.030792f, 0.032715f, 0.035034f, 0.037323f, 0.039825f,
+ 0.042419f, 0.045258f, 0.048157f, 0.051422f, 0.054810f, 0.058411f, 0.062378f, 0.066528f, 0.071106f, 0.076233f, 0.081116f, 0.086853f,
+ 0.092407f, 0.098938f, 0.105469f, 0.112854f, 0.120361f, 0.128418f, 0.136841f, 0.145752f, 0.155273f, 0.165283f, 0.175537f, 0.186646f,
+ 0.197510f, 0.209473f, 0.221558f, 0.234619f, 0.248047f, 0.261719f, 0.603516f, 0.636719f, 0.644531f, 0.645020f, 0.645508f, 0.646484f,
+ 0.000837f, 0.002073f, 0.003357f, 0.004292f, 0.005409f, 0.006271f, 0.007271f, 0.007973f, 0.008873f, 0.009956f, 0.010811f, 0.012032f,
+ 0.012848f, 0.013664f, 0.014870f, 0.015839f, 0.017090f, 0.018280f, 0.019333f, 0.020691f, 0.022186f, 0.023453f, 0.025223f, 0.026779f,
+ 0.028595f, 0.030441f, 0.032410f, 0.034729f, 0.036743f, 0.039307f, 0.042023f, 0.044434f, 0.047791f, 0.050781f, 0.054413f, 0.058075f,
+ 0.061951f, 0.066711f, 0.071106f, 0.076355f, 0.081848f, 0.087341f, 0.093872f, 0.099854f, 0.107483f, 0.114441f, 0.122925f, 0.131104f,
+ 0.140381f, 0.149414f, 0.159180f, 0.170166f, 0.181152f, 0.192139f, 0.204468f, 0.216553f, 0.230103f, 0.244507f, 0.592773f, 0.626953f,
+ 0.635254f, 0.637207f, 0.636719f, 0.637695f, 0.000524f, 0.001863f, 0.003014f, 0.003777f, 0.004852f, 0.005516f, 0.006428f, 0.007111f,
+ 0.008095f, 0.008888f, 0.009476f, 0.010345f, 0.011063f, 0.012016f, 0.012810f, 0.013786f, 0.014648f, 0.015717f, 0.016891f, 0.017929f,
+ 0.019150f, 0.020401f, 0.021606f, 0.023193f, 0.024597f, 0.026276f, 0.027939f, 0.029770f, 0.031738f, 0.033936f, 0.036194f, 0.038574f,
+ 0.041107f, 0.043945f, 0.047180f, 0.050385f, 0.054291f, 0.057770f, 0.061981f, 0.066345f, 0.071167f, 0.076355f, 0.082153f, 0.088074f,
+ 0.094666f, 0.101685f, 0.109131f, 0.117249f, 0.125610f, 0.134399f, 0.143921f, 0.154175f, 0.164795f, 0.175659f, 0.187256f, 0.199341f,
+ 0.211670f, 0.225464f, 0.580078f, 0.617676f, 0.625000f, 0.627930f, 0.628906f, 0.628906f, 0.000657f, 0.001829f, 0.002909f, 0.003525f,
+ 0.004295f, 0.005051f, 0.005592f, 0.006123f, 0.006920f, 0.007553f, 0.008339f, 0.008888f, 0.009689f, 0.010262f, 0.011017f, 0.011848f,
+ 0.012634f, 0.013489f, 0.014572f, 0.015427f, 0.016449f, 0.017426f, 0.018539f, 0.019852f, 0.021133f, 0.022507f, 0.023834f, 0.025375f,
+ 0.027084f, 0.028976f, 0.030792f, 0.032959f, 0.035400f, 0.037720f, 0.040405f, 0.043243f, 0.046356f, 0.049530f, 0.053314f, 0.057190f,
+ 0.061554f, 0.066223f, 0.071472f, 0.076782f, 0.082825f, 0.089417f, 0.096191f, 0.103210f, 0.111633f, 0.119934f, 0.128662f, 0.138550f,
+ 0.148315f, 0.158813f, 0.170288f, 0.182373f, 0.194458f, 0.207642f, 0.567383f, 0.606445f, 0.615234f, 0.619141f, 0.620117f, 0.620117f,
+ 0.000584f, 0.001548f, 0.002333f, 0.003086f, 0.003660f, 0.004303f, 0.005020f, 0.005543f, 0.006042f, 0.006538f, 0.007118f, 0.007641f,
+ 0.008301f, 0.008919f, 0.009499f, 0.010147f, 0.010918f, 0.011414f, 0.012222f, 0.013084f, 0.013901f, 0.014954f, 0.015671f, 0.016724f,
+ 0.017914f, 0.019012f, 0.020325f, 0.021698f, 0.022949f, 0.024445f, 0.026215f, 0.027954f, 0.029755f, 0.032043f, 0.034210f, 0.036591f,
+ 0.039215f, 0.042297f, 0.045441f, 0.048676f, 0.052612f, 0.056580f, 0.061432f, 0.066040f, 0.071350f, 0.077332f, 0.083496f, 0.090393f,
+ 0.097717f, 0.105835f, 0.114380f, 0.123413f, 0.133301f, 0.143066f, 0.153931f, 0.165039f, 0.177124f, 0.190308f, 0.555176f, 0.597656f,
+ 0.604980f, 0.609375f, 0.609863f, 0.611328f, 0.000438f, 0.001456f, 0.001925f, 0.002811f, 0.003246f, 0.003731f, 0.004108f, 0.004669f,
+ 0.005344f, 0.005535f, 0.005913f, 0.006641f, 0.007038f, 0.007473f, 0.008049f, 0.008675f, 0.009361f, 0.009689f, 0.010513f, 0.011032f,
+ 0.011894f, 0.012695f, 0.013390f, 0.014183f, 0.015114f, 0.016037f, 0.016998f, 0.018280f, 0.019272f, 0.020645f, 0.022003f, 0.023361f,
+ 0.024796f, 0.026779f, 0.028656f, 0.030685f, 0.032928f, 0.035370f, 0.038147f, 0.040955f, 0.044403f, 0.047821f, 0.052032f, 0.056183f,
+ 0.060974f, 0.066162f, 0.071777f, 0.078125f, 0.084656f, 0.092102f, 0.100159f, 0.109009f, 0.117981f, 0.127563f, 0.138306f, 0.148804f,
+ 0.160645f, 0.173218f, 0.542969f, 0.586914f, 0.594727f, 0.599609f, 0.601074f, 0.601074f, 0.000520f, 0.001104f, 0.001921f, 0.002256f,
+ 0.002886f, 0.003389f, 0.003689f, 0.004063f, 0.004440f, 0.004829f, 0.005230f, 0.005466f, 0.005966f, 0.006332f, 0.006786f, 0.007347f,
+ 0.007835f, 0.008232f, 0.008812f, 0.009216f, 0.009865f, 0.010490f, 0.011124f, 0.011803f, 0.012573f, 0.013390f, 0.014275f, 0.015121f,
+ 0.016144f, 0.016953f, 0.018234f, 0.019257f, 0.020782f, 0.022064f, 0.023743f, 0.025360f, 0.027176f, 0.029327f, 0.031616f, 0.034058f,
+ 0.036957f, 0.039917f, 0.043182f, 0.047272f, 0.051025f, 0.055695f, 0.060913f, 0.066345f, 0.072693f, 0.079285f, 0.086548f, 0.094543f,
+ 0.103271f, 0.112793f, 0.122864f, 0.132812f, 0.144531f, 0.156616f, 0.530273f, 0.576660f, 0.585449f, 0.590332f, 0.592285f, 0.593262f,
+ 0.000366f, 0.001040f, 0.001583f, 0.002129f, 0.002522f, 0.002792f, 0.003012f, 0.003420f, 0.003630f, 0.003967f, 0.004246f, 0.004623f,
+ 0.005039f, 0.005253f, 0.005627f, 0.006096f, 0.006447f, 0.006939f, 0.007179f, 0.007710f, 0.008324f, 0.008698f, 0.009247f, 0.009796f,
+ 0.010414f, 0.011063f, 0.011627f, 0.012543f, 0.013191f, 0.014099f, 0.014938f, 0.015930f, 0.016983f, 0.018219f, 0.019440f, 0.020813f,
+ 0.022324f, 0.024002f, 0.025818f, 0.027969f, 0.030289f, 0.032898f, 0.035583f, 0.038727f, 0.042450f, 0.046234f, 0.050781f, 0.055695f,
+ 0.061157f, 0.067383f, 0.074158f, 0.081360f, 0.089478f, 0.098267f, 0.107788f, 0.117737f, 0.129028f, 0.140503f, 0.517578f, 0.566406f,
+ 0.575195f, 0.581055f, 0.582520f, 0.584473f, 0.000482f, 0.001008f, 0.001481f, 0.001818f, 0.002001f, 0.002296f, 0.002569f, 0.002781f,
+ 0.002998f, 0.003319f, 0.003620f, 0.003828f, 0.004082f, 0.004364f, 0.004658f, 0.004978f, 0.005257f, 0.005665f, 0.005993f, 0.006340f,
+ 0.006725f, 0.007160f, 0.007576f, 0.008095f, 0.008522f, 0.008980f, 0.009621f, 0.010170f, 0.010765f, 0.011543f, 0.012161f, 0.013023f,
+ 0.013840f, 0.014801f, 0.015869f, 0.016861f, 0.018127f, 0.019379f, 0.020859f, 0.022583f, 0.024261f, 0.026596f, 0.028839f, 0.031555f,
+ 0.034271f, 0.037628f, 0.041504f, 0.045837f, 0.050598f, 0.056000f, 0.062134f, 0.068726f, 0.076172f, 0.084656f, 0.093567f, 0.103088f,
+ 0.113586f, 0.125000f, 0.504883f, 0.554688f, 0.565918f, 0.570801f, 0.573242f, 0.574219f, 0.000400f, 0.000803f, 0.001046f, 0.001427f,
+ 0.001657f, 0.001952f, 0.002033f, 0.002337f, 0.002453f, 0.002678f, 0.002871f, 0.003120f, 0.003286f, 0.003605f, 0.003817f, 0.004036f,
+ 0.004299f, 0.004604f, 0.004848f, 0.005142f, 0.005428f, 0.005871f, 0.006107f, 0.006584f, 0.006908f, 0.007332f, 0.007736f, 0.008186f,
+ 0.008820f, 0.009308f, 0.009964f, 0.010422f, 0.011200f, 0.011993f, 0.012726f, 0.013512f, 0.014511f, 0.015610f, 0.016724f, 0.017914f,
+ 0.019440f, 0.021057f, 0.022827f, 0.024933f, 0.027466f, 0.030197f, 0.033295f, 0.036896f, 0.041077f, 0.045776f, 0.050995f, 0.056976f,
+ 0.063721f, 0.071167f, 0.079773f, 0.089172f, 0.098633f, 0.109314f, 0.491699f, 0.543457f, 0.555176f, 0.561035f, 0.563477f, 0.565430f,
+ 0.000279f, 0.000821f, 0.000974f, 0.001161f, 0.001382f, 0.001583f, 0.001670f, 0.001934f, 0.002064f, 0.002153f, 0.002306f, 0.002544f,
+ 0.002670f, 0.002909f, 0.003052f, 0.003288f, 0.003429f, 0.003624f, 0.003893f, 0.004082f, 0.004406f, 0.004635f, 0.004925f, 0.005196f,
+ 0.005444f, 0.005764f, 0.006134f, 0.006546f, 0.006947f, 0.007343f, 0.007858f, 0.008270f, 0.008858f, 0.009346f, 0.010010f, 0.010757f,
+ 0.011475f, 0.012260f, 0.013206f, 0.014214f, 0.015236f, 0.016479f, 0.017975f, 0.019623f, 0.021515f, 0.023590f, 0.026062f, 0.028976f,
+ 0.032471f, 0.036224f, 0.040833f, 0.046082f, 0.052094f, 0.059052f, 0.066650f, 0.075684f, 0.084778f, 0.094971f, 0.479492f, 0.532715f,
+ 0.545898f, 0.551270f, 0.553711f, 0.555664f, 0.000253f, 0.000612f, 0.000835f, 0.000998f, 0.001111f, 0.001228f, 0.001334f, 0.001452f,
+ 0.001619f, 0.001757f, 0.001837f, 0.001920f, 0.002140f, 0.002321f, 0.002453f, 0.002544f, 0.002670f, 0.002790f, 0.003086f, 0.003260f,
+ 0.003422f, 0.003620f, 0.003893f, 0.004101f, 0.004326f, 0.004528f, 0.004761f, 0.005051f, 0.005444f, 0.005756f, 0.006065f, 0.006435f,
+ 0.006882f, 0.007378f, 0.007763f, 0.008286f, 0.008865f, 0.009506f, 0.010162f, 0.011024f, 0.011826f, 0.012917f, 0.013916f, 0.015175f,
+ 0.016602f, 0.018204f, 0.020035f, 0.022293f, 0.024948f, 0.028076f, 0.031921f, 0.036377f, 0.041565f, 0.047577f, 0.054535f, 0.062622f,
+ 0.071777f, 0.081787f, 0.465576f, 0.522461f, 0.535645f, 0.541992f, 0.544922f, 0.546875f, 0.000155f, 0.000398f, 0.000680f, 0.000828f,
+ 0.000907f, 0.000989f, 0.001113f, 0.001081f, 0.001253f, 0.001350f, 0.001453f, 0.001573f, 0.001661f, 0.001777f, 0.001829f, 0.001978f,
+ 0.002062f, 0.002216f, 0.002346f, 0.002470f, 0.002644f, 0.002804f, 0.002930f, 0.003134f, 0.003265f, 0.003485f, 0.003674f, 0.003866f,
+ 0.004154f, 0.004333f, 0.004707f, 0.004910f, 0.005180f, 0.005581f, 0.005875f, 0.006283f, 0.006729f, 0.007164f, 0.007713f, 0.008270f,
+ 0.008934f, 0.009727f, 0.010513f, 0.011482f, 0.012520f, 0.013710f, 0.015152f, 0.016815f, 0.018799f, 0.021118f, 0.024048f, 0.027756f,
+ 0.032104f, 0.037201f, 0.043518f, 0.050903f, 0.059418f, 0.068420f, 0.453125f, 0.511719f, 0.525391f, 0.530762f, 0.535156f, 0.536621f,
+ 0.000303f, 0.000337f, 0.000498f, 0.000560f, 0.000603f, 0.000721f, 0.000782f, 0.000845f, 0.000880f, 0.000988f, 0.001119f, 0.001184f,
+ 0.001258f, 0.001377f, 0.001420f, 0.001446f, 0.001590f, 0.001666f, 0.001754f, 0.001889f, 0.001980f, 0.002073f, 0.002216f, 0.002308f,
+ 0.002447f, 0.002562f, 0.002758f, 0.002899f, 0.003084f, 0.003328f, 0.003506f, 0.003641f, 0.003922f, 0.004147f, 0.004391f, 0.004665f,
+ 0.004959f, 0.005322f, 0.005695f, 0.006119f, 0.006588f, 0.007072f, 0.007790f, 0.008392f, 0.009178f, 0.010056f, 0.011124f, 0.012383f,
+ 0.013832f, 0.015587f, 0.017685f, 0.020309f, 0.023926f, 0.028076f, 0.033447f, 0.039978f, 0.047638f, 0.056335f, 0.440186f, 0.500000f,
+ 0.514160f, 0.520996f, 0.524414f, 0.526855f, 0.000132f, 0.000296f, 0.000368f, 0.000444f, 0.000501f, 0.000519f, 0.000631f, 0.000580f,
+ 0.000675f, 0.000735f, 0.000820f, 0.000840f, 0.000882f, 0.000946f, 0.001029f, 0.001070f, 0.001164f, 0.001221f, 0.001286f, 0.001317f,
+ 0.001416f, 0.001494f, 0.001607f, 0.001681f, 0.001763f, 0.001863f, 0.001978f, 0.002069f, 0.002169f, 0.002348f, 0.002451f, 0.002661f,
+ 0.002754f, 0.002943f, 0.003130f, 0.003323f, 0.003553f, 0.003813f, 0.004124f, 0.004364f, 0.004669f, 0.005062f, 0.005493f, 0.005985f,
+ 0.006546f, 0.007172f, 0.007950f, 0.008850f, 0.009857f, 0.011116f, 0.012695f, 0.014603f, 0.016983f, 0.020157f, 0.024490f, 0.029968f,
+ 0.036957f, 0.045166f, 0.426025f, 0.488770f, 0.503906f, 0.511719f, 0.515137f, 0.517578f, 0.000063f, 0.000160f, 0.000267f, 0.000282f,
+ 0.000339f, 0.000417f, 0.000377f, 0.000433f, 0.000472f, 0.000570f, 0.000563f, 0.000578f, 0.000599f, 0.000663f, 0.000681f, 0.000759f,
+ 0.000760f, 0.000845f, 0.000910f, 0.000941f, 0.000997f, 0.001057f, 0.001110f, 0.001169f, 0.001238f, 0.001288f, 0.001381f, 0.001441f,
+ 0.001514f, 0.001655f, 0.001693f, 0.001815f, 0.001910f, 0.002028f, 0.002153f, 0.002308f, 0.002441f, 0.002607f, 0.002783f, 0.002962f,
+ 0.003214f, 0.003458f, 0.003744f, 0.004051f, 0.004444f, 0.004883f, 0.005402f, 0.006031f, 0.006699f, 0.007610f, 0.008766f, 0.009933f,
+ 0.011688f, 0.013931f, 0.017075f, 0.021454f, 0.027313f, 0.035004f, 0.414307f, 0.478271f, 0.493652f, 0.501465f, 0.505859f, 0.508301f,
+ 0.000120f, 0.000194f, 0.000194f, 0.000205f, 0.000245f, 0.000246f, 0.000251f, 0.000301f, 0.000322f, 0.000332f, 0.000343f, 0.000413f,
+ 0.000397f, 0.000448f, 0.000481f, 0.000494f, 0.000545f, 0.000556f, 0.000582f, 0.000601f, 0.000653f, 0.000676f, 0.000726f, 0.000767f,
+ 0.000821f, 0.000840f, 0.000919f, 0.000952f, 0.001011f, 0.001054f, 0.001116f, 0.001186f, 0.001263f, 0.001337f, 0.001418f, 0.001482f,
+ 0.001607f, 0.001685f, 0.001842f, 0.001965f, 0.002090f, 0.002235f, 0.002420f, 0.002613f, 0.002851f, 0.003159f, 0.003492f, 0.003887f,
+ 0.004345f, 0.004906f, 0.005600f, 0.006474f, 0.007645f, 0.009186f, 0.011230f, 0.014305f, 0.019135f, 0.025848f, 0.400635f, 0.466797f,
+ 0.483398f, 0.490967f, 0.495117f, 0.498047f, 0.000030f, 0.000140f, 0.000121f, 0.000114f, 0.000147f, 0.000178f, 0.000159f, 0.000195f,
+ 0.000199f, 0.000204f, 0.000216f, 0.000223f, 0.000255f, 0.000271f, 0.000288f, 0.000302f, 0.000314f, 0.000346f, 0.000357f, 0.000395f,
+ 0.000397f, 0.000408f, 0.000436f, 0.000470f, 0.000501f, 0.000542f, 0.000547f, 0.000566f, 0.000612f, 0.000641f, 0.000692f, 0.000722f,
+ 0.000767f, 0.000798f, 0.000861f, 0.000898f, 0.000963f, 0.001030f, 0.001107f, 0.001164f, 0.001255f, 0.001361f, 0.001464f, 0.001591f,
+ 0.001719f, 0.001871f, 0.002111f, 0.002312f, 0.002617f, 0.002964f, 0.003368f, 0.003902f, 0.004654f, 0.005653f, 0.006958f, 0.008888f,
+ 0.012161f, 0.017822f, 0.388672f, 0.456543f, 0.473389f, 0.481201f, 0.486328f, 0.489014f, 0.000102f, 0.000076f, 0.000076f, 0.000075f,
+ 0.000095f, 0.000092f, 0.000109f, 0.000111f, 0.000112f, 0.000113f, 0.000126f, 0.000147f, 0.000135f, 0.000144f, 0.000165f, 0.000161f,
+ 0.000179f, 0.000192f, 0.000198f, 0.000202f, 0.000224f, 0.000232f, 0.000248f, 0.000259f, 0.000278f, 0.000295f, 0.000308f, 0.000320f,
+ 0.000340f, 0.000353f, 0.000379f, 0.000402f, 0.000423f, 0.000440f, 0.000472f, 0.000503f, 0.000526f, 0.000564f, 0.000610f, 0.000644f,
+ 0.000690f, 0.000741f, 0.000810f, 0.000862f, 0.000946f, 0.001024f, 0.001121f, 0.001247f, 0.001407f, 0.001603f, 0.001822f, 0.002144f,
+ 0.002539f, 0.003098f, 0.003901f, 0.005096f, 0.006931f, 0.011024f, 0.375244f, 0.444092f, 0.462158f, 0.470215f, 0.475586f, 0.478760f,
+ 0.000085f, 0.000061f, 0.000052f, 0.000047f, 0.000049f, 0.000046f, 0.000047f, 0.000050f, 0.000055f, 0.000069f, 0.000060f, 0.000062f,
+ 0.000077f, 0.000066f, 0.000069f, 0.000075f, 0.000084f, 0.000093f, 0.000093f, 0.000098f, 0.000102f, 0.000108f, 0.000111f, 0.000121f,
+ 0.000129f, 0.000136f, 0.000142f, 0.000154f, 0.000162f, 0.000172f, 0.000182f, 0.000187f, 0.000197f, 0.000209f, 0.000225f, 0.000231f,
+ 0.000246f, 0.000262f, 0.000290f, 0.000306f, 0.000321f, 0.000349f, 0.000380f, 0.000402f, 0.000437f, 0.000480f, 0.000525f, 0.000579f,
+ 0.000649f, 0.000735f, 0.000842f, 0.000984f, 0.001173f, 0.001451f, 0.001855f, 0.002485f, 0.003542f, 0.005753f, 0.362305f, 0.434326f,
+ 0.451904f, 0.460693f, 0.465576f, 0.468506f, 0.000064f, 0.000044f, 0.000036f, 0.000032f, 0.000029f, 0.000027f, 0.000025f, 0.000024f,
+ 0.000022f, 0.000023f, 0.000021f, 0.000027f, 0.000023f, 0.000022f, 0.000028f, 0.000031f, 0.000030f, 0.000034f, 0.000036f, 0.000038f,
+ 0.000040f, 0.000045f, 0.000048f, 0.000042f, 0.000047f, 0.000053f, 0.000055f, 0.000054f, 0.000060f, 0.000062f, 0.000065f, 0.000072f,
+ 0.000078f, 0.000075f, 0.000079f, 0.000087f, 0.000093f, 0.000098f, 0.000106f, 0.000113f, 0.000121f, 0.000126f, 0.000136f, 0.000150f,
+ 0.000159f, 0.000173f, 0.000190f, 0.000209f, 0.000235f, 0.000265f, 0.000302f, 0.000343f, 0.000416f, 0.000515f, 0.000665f, 0.000917f,
+ 0.001396f, 0.002401f, 0.349854f, 0.421875f, 0.440918f, 0.449951f, 0.455811f, 0.458008f, 0.000030f, 0.000020f, 0.000016f, 0.000014f,
+ 0.000014f, 0.000013f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000009f, 0.000009f,
+ 0.000009f, 0.000008f, 0.000008f, 0.000008f, 0.000007f, 0.000007f, 0.000008f, 0.000008f, 0.000009f, 0.000011f, 0.000011f, 0.000013f,
+ 0.000013f, 0.000012f, 0.000013f, 0.000014f, 0.000016f, 0.000018f, 0.000018f, 0.000019f, 0.000021f, 0.000021f, 0.000023f, 0.000027f,
+ 0.000025f, 0.000028f, 0.000031f, 0.000032f, 0.000033f, 0.000038f, 0.000043f, 0.000046f, 0.000050f, 0.000055f, 0.000062f, 0.000074f,
+ 0.000088f, 0.000106f, 0.000138f, 0.000191f, 0.000312f, 0.000653f, 0.337402f, 0.410645f, 0.431152f, 0.438965f, 0.445068f, 0.448975f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000004f, 0.000004f, 0.000006f, 0.000010f, 0.000026f, 0.324219f, 0.399902f,
+ 0.419922f, 0.429688f, 0.435059f, 0.438965f,
+ },
+ {
+ 0.010521f, 0.032043f, 0.054443f, 0.076843f, 0.098572f, 0.121216f, 0.142700f, 0.164062f, 0.185913f, 0.207275f, 0.229004f, 0.249268f,
+ 0.270508f, 0.290527f, 0.311035f, 0.331055f, 0.350586f, 0.370361f, 0.389648f, 0.408936f, 0.428223f, 0.446533f, 0.465088f, 0.482666f,
+ 0.500977f, 0.519043f, 0.536133f, 0.553223f, 0.570801f, 0.587891f, 0.604980f, 0.621582f, 0.637207f, 0.653320f, 0.668945f, 0.685547f,
+ 0.700684f, 0.716309f, 0.730957f, 0.745605f, 0.760254f, 0.774902f, 0.789551f, 0.803711f, 0.816895f, 0.831543f, 0.845703f, 0.858887f,
+ 0.871582f, 0.885254f, 0.897949f, 0.910645f, 0.923340f, 0.936035f, 0.948242f, 0.959961f, 0.972168f, 0.984375f, 0.972656f, 0.936035f,
+ 0.910645f, 0.890137f, 0.872070f, 0.855957f, 0.010048f, 0.030350f, 0.051392f, 0.072266f, 0.093506f, 0.114319f, 0.135620f, 0.155273f,
+ 0.177124f, 0.197144f, 0.217773f, 0.237915f, 0.257568f, 0.277588f, 0.298096f, 0.316895f, 0.336182f, 0.355225f, 0.374268f, 0.393311f,
+ 0.411865f, 0.430176f, 0.448486f, 0.466309f, 0.483398f, 0.501465f, 0.519043f, 0.535645f, 0.552734f, 0.570312f, 0.586426f, 0.602539f,
+ 0.618652f, 0.635254f, 0.650879f, 0.666016f, 0.682129f, 0.697266f, 0.712402f, 0.727539f, 0.741699f, 0.756836f, 0.770996f, 0.785645f,
+ 0.799805f, 0.812988f, 0.826660f, 0.840332f, 0.854004f, 0.867676f, 0.881348f, 0.893066f, 0.907715f, 0.919434f, 0.932617f, 0.943848f,
+ 0.955566f, 0.968262f, 0.965332f, 0.930664f, 0.906738f, 0.886719f, 0.869629f, 0.854004f, 0.009254f, 0.028961f, 0.048615f, 0.068054f,
+ 0.088562f, 0.108093f, 0.128540f, 0.147705f, 0.167236f, 0.188599f, 0.207886f, 0.227295f, 0.244873f, 0.265625f, 0.284668f, 0.303955f,
+ 0.322510f, 0.340820f, 0.358887f, 0.378662f, 0.396484f, 0.414307f, 0.431885f, 0.448975f, 0.466797f, 0.484619f, 0.500977f, 0.519043f,
+ 0.535645f, 0.551758f, 0.568359f, 0.584961f, 0.600586f, 0.616699f, 0.632324f, 0.647949f, 0.663086f, 0.678223f, 0.693848f, 0.708984f,
+ 0.723633f, 0.738281f, 0.752930f, 0.767578f, 0.780762f, 0.794922f, 0.809082f, 0.822754f, 0.835938f, 0.849609f, 0.863770f, 0.875488f,
+ 0.888672f, 0.902344f, 0.915527f, 0.927246f, 0.939453f, 0.952637f, 0.958008f, 0.925293f, 0.901855f, 0.882812f, 0.866211f, 0.851562f,
+ 0.008736f, 0.027039f, 0.045807f, 0.064514f, 0.083801f, 0.102844f, 0.121826f, 0.140869f, 0.159302f, 0.179077f, 0.197388f, 0.216064f,
+ 0.234741f, 0.253662f, 0.271729f, 0.290283f, 0.308350f, 0.327148f, 0.344238f, 0.362061f, 0.381836f, 0.398926f, 0.416016f, 0.432373f,
+ 0.450195f, 0.466797f, 0.484375f, 0.500977f, 0.517090f, 0.533691f, 0.550781f, 0.567871f, 0.582031f, 0.598145f, 0.613770f, 0.629395f,
+ 0.645020f, 0.659668f, 0.675781f, 0.689941f, 0.705566f, 0.719727f, 0.734375f, 0.749512f, 0.763184f, 0.776855f, 0.791016f, 0.804688f,
+ 0.818848f, 0.832031f, 0.845215f, 0.858398f, 0.872559f, 0.884766f, 0.897949f, 0.909668f, 0.922852f, 0.936035f, 0.950684f, 0.919434f,
+ 0.896973f, 0.878906f, 0.862793f, 0.848633f, 0.008339f, 0.025543f, 0.043427f, 0.060974f, 0.078979f, 0.097168f, 0.115051f, 0.133179f,
+ 0.151367f, 0.169678f, 0.187988f, 0.206055f, 0.223999f, 0.241821f, 0.260742f, 0.277832f, 0.295166f, 0.313232f, 0.331299f, 0.347412f,
+ 0.365479f, 0.383057f, 0.399902f, 0.416992f, 0.433350f, 0.450195f, 0.467773f, 0.484863f, 0.499756f, 0.515625f, 0.532715f, 0.548340f,
+ 0.564941f, 0.580566f, 0.596191f, 0.610840f, 0.626953f, 0.641602f, 0.656738f, 0.671875f, 0.686035f, 0.701660f, 0.714844f, 0.730469f,
+ 0.745117f, 0.759766f, 0.772461f, 0.786621f, 0.801270f, 0.814453f, 0.827637f, 0.841309f, 0.854004f, 0.867676f, 0.880859f, 0.893555f,
+ 0.907227f, 0.919434f, 0.943359f, 0.913086f, 0.891602f, 0.874512f, 0.858887f, 0.845703f, 0.008102f, 0.024002f, 0.040802f, 0.057098f,
+ 0.074768f, 0.091553f, 0.108826f, 0.126343f, 0.143921f, 0.161377f, 0.179077f, 0.195923f, 0.213745f, 0.230835f, 0.248047f, 0.265869f,
+ 0.282227f, 0.299561f, 0.316895f, 0.334473f, 0.350586f, 0.367920f, 0.384277f, 0.400391f, 0.417725f, 0.434326f, 0.450195f, 0.467285f,
+ 0.482910f, 0.498291f, 0.514648f, 0.530762f, 0.546387f, 0.561523f, 0.577637f, 0.593262f, 0.608398f, 0.623535f, 0.637695f, 0.654297f,
+ 0.668457f, 0.682617f, 0.698242f, 0.711914f, 0.727051f, 0.741211f, 0.754395f, 0.768066f, 0.782715f, 0.796387f, 0.810547f, 0.823730f,
+ 0.836426f, 0.849609f, 0.863770f, 0.876465f, 0.889648f, 0.902344f, 0.934570f, 0.907715f, 0.887207f, 0.870117f, 0.854980f, 0.842285f,
+ 0.007504f, 0.022812f, 0.038727f, 0.054871f, 0.070312f, 0.087097f, 0.103088f, 0.119446f, 0.136475f, 0.153442f, 0.169556f, 0.186523f,
+ 0.203369f, 0.219971f, 0.236450f, 0.253418f, 0.270264f, 0.287109f, 0.302979f, 0.319824f, 0.336182f, 0.353271f, 0.369141f, 0.386230f,
+ 0.402100f, 0.417725f, 0.433594f, 0.450684f, 0.466553f, 0.482178f, 0.498047f, 0.513184f, 0.528809f, 0.543945f, 0.559082f, 0.575195f,
+ 0.589844f, 0.605469f, 0.621094f, 0.634277f, 0.649414f, 0.665039f, 0.679688f, 0.694824f, 0.708496f, 0.722168f, 0.736816f, 0.750000f,
+ 0.763184f, 0.778809f, 0.791504f, 0.805664f, 0.819336f, 0.832520f, 0.845703f, 0.858887f, 0.872070f, 0.885742f, 0.927246f, 0.900879f,
+ 0.881836f, 0.864746f, 0.851074f, 0.838867f, 0.006836f, 0.021683f, 0.036224f, 0.051666f, 0.066772f, 0.081970f, 0.098022f, 0.113831f,
+ 0.129517f, 0.145264f, 0.161011f, 0.177856f, 0.193359f, 0.209106f, 0.226196f, 0.241821f, 0.257812f, 0.274414f, 0.290283f, 0.306641f,
+ 0.322754f, 0.338623f, 0.354492f, 0.370361f, 0.386230f, 0.402100f, 0.417725f, 0.433838f, 0.449463f, 0.465088f, 0.480469f, 0.495605f,
+ 0.511719f, 0.527344f, 0.541016f, 0.556641f, 0.571777f, 0.587402f, 0.601562f, 0.617676f, 0.631836f, 0.646484f, 0.660645f, 0.674805f,
+ 0.689941f, 0.704102f, 0.718262f, 0.731934f, 0.746582f, 0.760254f, 0.774414f, 0.786621f, 0.801758f, 0.815430f, 0.828125f, 0.842285f,
+ 0.854980f, 0.868652f, 0.918457f, 0.894531f, 0.875977f, 0.859863f, 0.846680f, 0.834961f, 0.006672f, 0.020401f, 0.034088f, 0.048462f,
+ 0.062927f, 0.077820f, 0.092529f, 0.107666f, 0.122803f, 0.137695f, 0.152954f, 0.169067f, 0.183716f, 0.199829f, 0.214722f, 0.230347f,
+ 0.246704f, 0.262207f, 0.277832f, 0.292969f, 0.308105f, 0.324219f, 0.339600f, 0.354492f, 0.371094f, 0.386963f, 0.401855f, 0.418457f,
+ 0.432861f, 0.449219f, 0.463379f, 0.478271f, 0.494385f, 0.508301f, 0.523438f, 0.539551f, 0.553711f, 0.568848f, 0.583984f, 0.598633f,
+ 0.612793f, 0.627441f, 0.642578f, 0.656250f, 0.670898f, 0.685547f, 0.698730f, 0.714355f, 0.728027f, 0.742188f, 0.755859f, 0.769531f,
+ 0.783691f, 0.795898f, 0.810059f, 0.824707f, 0.838379f, 0.850586f, 0.910645f, 0.887695f, 0.870117f, 0.854980f, 0.842285f, 0.831055f,
+ 0.006207f, 0.019211f, 0.032623f, 0.046112f, 0.059662f, 0.073181f, 0.087585f, 0.102051f, 0.116577f, 0.130249f, 0.145142f, 0.159790f,
+ 0.175171f, 0.189575f, 0.205322f, 0.219238f, 0.235474f, 0.249634f, 0.265137f, 0.280029f, 0.294678f, 0.310547f, 0.325928f, 0.340820f,
+ 0.356201f, 0.371094f, 0.386230f, 0.401367f, 0.416504f, 0.431885f, 0.446533f, 0.461670f, 0.476074f, 0.492188f, 0.507324f, 0.520996f,
+ 0.535645f, 0.550781f, 0.564941f, 0.580078f, 0.594727f, 0.609863f, 0.623535f, 0.637695f, 0.652832f, 0.667480f, 0.681152f, 0.695312f,
+ 0.709473f, 0.723633f, 0.737793f, 0.751953f, 0.765137f, 0.779297f, 0.793945f, 0.807129f, 0.819824f, 0.833496f, 0.901855f, 0.880859f,
+ 0.864258f, 0.850098f, 0.837891f, 0.826660f, 0.006020f, 0.018219f, 0.030579f, 0.043365f, 0.055908f, 0.069153f, 0.082336f, 0.096802f,
+ 0.109497f, 0.123535f, 0.137451f, 0.151855f, 0.165649f, 0.180054f, 0.194702f, 0.208252f, 0.223999f, 0.238037f, 0.252930f, 0.267334f,
+ 0.281982f, 0.296875f, 0.312012f, 0.326904f, 0.340820f, 0.355957f, 0.370850f, 0.385986f, 0.400391f, 0.415039f, 0.430176f, 0.445801f,
+ 0.459229f, 0.474365f, 0.489014f, 0.502441f, 0.518066f, 0.533203f, 0.547363f, 0.562012f, 0.576660f, 0.590820f, 0.605469f, 0.619629f,
+ 0.633789f, 0.647949f, 0.663574f, 0.676758f, 0.690918f, 0.705566f, 0.719238f, 0.733398f, 0.746582f, 0.760254f, 0.774414f, 0.788574f,
+ 0.802246f, 0.816406f, 0.894043f, 0.874023f, 0.858398f, 0.844238f, 0.832031f, 0.822266f, 0.005520f, 0.017059f, 0.028625f, 0.040649f,
+ 0.053131f, 0.065552f, 0.077698f, 0.091187f, 0.104065f, 0.117371f, 0.130859f, 0.143677f, 0.157349f, 0.171021f, 0.184814f, 0.198730f,
+ 0.213135f, 0.226807f, 0.241211f, 0.255127f, 0.269775f, 0.283691f, 0.298096f, 0.312744f, 0.326660f, 0.341553f, 0.355957f, 0.370117f,
+ 0.384766f, 0.399170f, 0.414307f, 0.427979f, 0.442627f, 0.457764f, 0.471924f, 0.486084f, 0.500488f, 0.515137f, 0.529785f, 0.543945f,
+ 0.558594f, 0.572754f, 0.587402f, 0.601074f, 0.615234f, 0.629395f, 0.644043f, 0.657715f, 0.672852f, 0.685547f, 0.700684f, 0.714844f,
+ 0.728027f, 0.743164f, 0.756348f, 0.770508f, 0.785645f, 0.798340f, 0.885254f, 0.867676f, 0.852051f, 0.839355f, 0.828125f, 0.817871f,
+ 0.005241f, 0.015854f, 0.027481f, 0.038605f, 0.050171f, 0.061859f, 0.073853f, 0.085693f, 0.098328f, 0.111206f, 0.123474f, 0.136475f,
+ 0.149658f, 0.162598f, 0.175293f, 0.188477f, 0.202148f, 0.216431f, 0.229858f, 0.242798f, 0.256104f, 0.270264f, 0.284668f, 0.298828f,
+ 0.312744f, 0.326904f, 0.341064f, 0.355469f, 0.369141f, 0.383057f, 0.396729f, 0.411621f, 0.426025f, 0.439697f, 0.454590f, 0.468506f,
+ 0.482666f, 0.497070f, 0.512207f, 0.525391f, 0.540527f, 0.555176f, 0.567871f, 0.582031f, 0.596191f, 0.610840f, 0.625488f, 0.639648f,
+ 0.653809f, 0.668457f, 0.681641f, 0.695801f, 0.710449f, 0.724121f, 0.738770f, 0.751953f, 0.766602f, 0.780273f, 0.876465f, 0.860352f,
+ 0.845703f, 0.833984f, 0.822754f, 0.812988f, 0.004982f, 0.015274f, 0.025681f, 0.036438f, 0.047119f, 0.058167f, 0.069397f, 0.081055f,
+ 0.092957f, 0.104492f, 0.116577f, 0.128418f, 0.141113f, 0.153442f, 0.166504f, 0.179321f, 0.192261f, 0.205200f, 0.218506f, 0.231934f,
+ 0.244629f, 0.258301f, 0.271729f, 0.284912f, 0.299072f, 0.312988f, 0.325684f, 0.340088f, 0.353271f, 0.367676f, 0.381836f, 0.395508f,
+ 0.408936f, 0.423584f, 0.438232f, 0.451416f, 0.466309f, 0.479736f, 0.493896f, 0.507812f, 0.521973f, 0.536133f, 0.550293f, 0.563965f,
+ 0.578613f, 0.592773f, 0.606934f, 0.620605f, 0.635254f, 0.649414f, 0.663086f, 0.677246f, 0.691406f, 0.706543f, 0.720703f, 0.734375f,
+ 0.748047f, 0.762695f, 0.868164f, 0.853027f, 0.839355f, 0.828125f, 0.817383f, 0.808105f, 0.004745f, 0.014290f, 0.024506f, 0.034393f,
+ 0.044617f, 0.054749f, 0.065308f, 0.076538f, 0.087646f, 0.098938f, 0.110535f, 0.121582f, 0.134155f, 0.145264f, 0.157837f, 0.170166f,
+ 0.182373f, 0.194824f, 0.207153f, 0.220337f, 0.233276f, 0.245728f, 0.259277f, 0.271973f, 0.285645f, 0.298584f, 0.311768f, 0.325684f,
+ 0.338623f, 0.352539f, 0.365967f, 0.379395f, 0.393066f, 0.406738f, 0.421143f, 0.434326f, 0.448730f, 0.462402f, 0.475586f, 0.490479f,
+ 0.503906f, 0.518066f, 0.532227f, 0.546387f, 0.560059f, 0.574219f, 0.588379f, 0.602539f, 0.616211f, 0.630371f, 0.644531f, 0.658691f,
+ 0.673340f, 0.686523f, 0.701660f, 0.715332f, 0.730469f, 0.745117f, 0.858887f, 0.845215f, 0.833008f, 0.821777f, 0.812012f, 0.802734f,
+ 0.004494f, 0.013550f, 0.022675f, 0.032227f, 0.042145f, 0.052002f, 0.061554f, 0.072205f, 0.082520f, 0.093323f, 0.104614f, 0.115112f,
+ 0.126099f, 0.137817f, 0.149536f, 0.160767f, 0.172607f, 0.184692f, 0.196167f, 0.208862f, 0.221924f, 0.233765f, 0.246216f, 0.258545f,
+ 0.272461f, 0.284424f, 0.297119f, 0.310547f, 0.323242f, 0.336914f, 0.350586f, 0.363281f, 0.376953f, 0.390869f, 0.403564f, 0.416992f,
+ 0.431152f, 0.444824f, 0.458496f, 0.472656f, 0.486084f, 0.500000f, 0.513672f, 0.527832f, 0.541504f, 0.555664f, 0.569824f, 0.583496f,
+ 0.598145f, 0.611816f, 0.626465f, 0.639648f, 0.654297f, 0.668457f, 0.683594f, 0.697754f, 0.711914f, 0.726562f, 0.849609f, 0.838867f,
+ 0.826172f, 0.815918f, 0.806641f, 0.796875f, 0.004288f, 0.012619f, 0.021713f, 0.030945f, 0.039368f, 0.048737f, 0.058533f, 0.067932f,
+ 0.077759f, 0.088013f, 0.098755f, 0.108398f, 0.119080f, 0.129639f, 0.141235f, 0.152466f, 0.163940f, 0.174927f, 0.186768f, 0.198608f,
+ 0.210205f, 0.222290f, 0.234131f, 0.246094f, 0.258789f, 0.270508f, 0.283203f, 0.296631f, 0.309326f, 0.321777f, 0.335449f, 0.348145f,
+ 0.361084f, 0.374023f, 0.386963f, 0.400391f, 0.414062f, 0.427734f, 0.441162f, 0.455078f, 0.467773f, 0.482422f, 0.495117f, 0.509277f,
+ 0.523926f, 0.536621f, 0.550781f, 0.564941f, 0.579102f, 0.593262f, 0.607422f, 0.621582f, 0.635742f, 0.649902f, 0.664551f, 0.678711f,
+ 0.693848f, 0.708008f, 0.840820f, 0.831055f, 0.819336f, 0.809570f, 0.801270f, 0.792969f, 0.004013f, 0.012070f, 0.019989f, 0.029190f,
+ 0.037415f, 0.045776f, 0.055023f, 0.064392f, 0.073669f, 0.083374f, 0.092224f, 0.102295f, 0.112610f, 0.122742f, 0.133057f, 0.143799f,
+ 0.155273f, 0.165527f, 0.176880f, 0.188110f, 0.199463f, 0.210815f, 0.222534f, 0.234619f, 0.245972f, 0.258301f, 0.270508f, 0.282715f,
+ 0.294678f, 0.307129f, 0.320557f, 0.333008f, 0.345947f, 0.358398f, 0.371826f, 0.384277f, 0.397461f, 0.410889f, 0.424561f, 0.437256f,
+ 0.451416f, 0.464600f, 0.477783f, 0.491455f, 0.504395f, 0.518555f, 0.532715f, 0.546875f, 0.560547f, 0.574219f, 0.588379f, 0.604004f,
+ 0.617188f, 0.631348f, 0.645020f, 0.660645f, 0.674316f, 0.689941f, 0.832031f, 0.823242f, 0.813477f, 0.803711f, 0.794922f, 0.787109f,
+ 0.003790f, 0.011559f, 0.019119f, 0.027069f, 0.035034f, 0.043762f, 0.052032f, 0.060059f, 0.069153f, 0.078369f, 0.087280f, 0.096741f,
+ 0.105957f, 0.115967f, 0.125732f, 0.135620f, 0.146118f, 0.156128f, 0.166992f, 0.177612f, 0.188965f, 0.199829f, 0.210815f, 0.222290f,
+ 0.233887f, 0.244873f, 0.257324f, 0.268799f, 0.281006f, 0.292969f, 0.305420f, 0.317627f, 0.329834f, 0.341797f, 0.355469f, 0.368164f,
+ 0.380859f, 0.393311f, 0.407227f, 0.419434f, 0.433350f, 0.446533f, 0.459961f, 0.473633f, 0.486328f, 0.500488f, 0.515625f, 0.528320f,
+ 0.541504f, 0.556152f, 0.570312f, 0.584473f, 0.598633f, 0.612305f, 0.626465f, 0.640625f, 0.655762f, 0.670410f, 0.822266f, 0.815918f,
+ 0.805664f, 0.796387f, 0.788574f, 0.782227f, 0.003599f, 0.010727f, 0.018219f, 0.025177f, 0.033203f, 0.041046f, 0.048981f, 0.057220f,
+ 0.065247f, 0.073792f, 0.082764f, 0.091064f, 0.100220f, 0.108826f, 0.118591f, 0.128052f, 0.137573f, 0.147705f, 0.158081f, 0.167603f,
+ 0.177979f, 0.188721f, 0.198975f, 0.210205f, 0.221924f, 0.232544f, 0.243774f, 0.255615f, 0.267090f, 0.278564f, 0.290039f, 0.302490f,
+ 0.314941f, 0.327393f, 0.338623f, 0.352295f, 0.364014f, 0.377441f, 0.390381f, 0.403564f, 0.415039f, 0.428955f, 0.441895f, 0.455078f,
+ 0.468994f, 0.482666f, 0.496094f, 0.509277f, 0.523926f, 0.537598f, 0.551270f, 0.565430f, 0.579590f, 0.594238f, 0.608887f, 0.622559f,
+ 0.637207f, 0.651855f, 0.813477f, 0.807617f, 0.798340f, 0.790527f, 0.782715f, 0.775391f, 0.003355f, 0.009918f, 0.017105f, 0.023911f,
+ 0.031281f, 0.038147f, 0.045990f, 0.053284f, 0.061493f, 0.069214f, 0.077026f, 0.085571f, 0.093567f, 0.102600f, 0.111755f, 0.120728f,
+ 0.129761f, 0.138916f, 0.148804f, 0.158447f, 0.167725f, 0.177979f, 0.188965f, 0.198608f, 0.209473f, 0.220215f, 0.231567f, 0.242554f,
+ 0.253906f, 0.264160f, 0.276123f, 0.287109f, 0.300049f, 0.312012f, 0.323975f, 0.336182f, 0.348145f, 0.360840f, 0.372803f, 0.385986f,
+ 0.398438f, 0.411621f, 0.424316f, 0.437256f, 0.450439f, 0.464844f, 0.478027f, 0.490723f, 0.504395f, 0.518066f, 0.532715f, 0.546387f,
+ 0.561523f, 0.575684f, 0.589355f, 0.604004f, 0.618164f, 0.632324f, 0.802246f, 0.800293f, 0.792480f, 0.783691f, 0.776367f, 0.769531f,
+ 0.003265f, 0.009575f, 0.016144f, 0.022415f, 0.029510f, 0.036316f, 0.042755f, 0.050812f, 0.057556f, 0.065002f, 0.072388f, 0.080200f,
+ 0.087952f, 0.096680f, 0.104858f, 0.113281f, 0.122070f, 0.130493f, 0.139771f, 0.148926f, 0.158447f, 0.168335f, 0.177612f, 0.187500f,
+ 0.198120f, 0.208130f, 0.218750f, 0.229492f, 0.240234f, 0.250732f, 0.262207f, 0.273682f, 0.285156f, 0.296143f, 0.308594f, 0.320068f,
+ 0.332520f, 0.344482f, 0.357178f, 0.368652f, 0.381836f, 0.394043f, 0.406494f, 0.420410f, 0.433105f, 0.445801f, 0.459717f, 0.473633f,
+ 0.486816f, 0.500000f, 0.513672f, 0.527832f, 0.541992f, 0.556152f, 0.570312f, 0.585449f, 0.598633f, 0.613770f, 0.794434f, 0.791504f,
+ 0.784180f, 0.776855f, 0.770020f, 0.764160f, 0.002954f, 0.008904f, 0.014961f, 0.021210f, 0.027420f, 0.033905f, 0.040619f, 0.047363f,
+ 0.053986f, 0.060883f, 0.068054f, 0.075378f, 0.082703f, 0.090515f, 0.098022f, 0.105896f, 0.114319f, 0.122742f, 0.131592f, 0.139771f,
+ 0.149170f, 0.157959f, 0.167480f, 0.177124f, 0.186768f, 0.196411f, 0.206543f, 0.216919f, 0.227539f, 0.237671f, 0.248413f, 0.259277f,
+ 0.270264f, 0.281738f, 0.292725f, 0.304443f, 0.315918f, 0.327637f, 0.340576f, 0.352539f, 0.364746f, 0.377930f, 0.390137f, 0.401855f,
+ 0.415039f, 0.428223f, 0.441406f, 0.454834f, 0.468506f, 0.481689f, 0.494873f, 0.509277f, 0.523438f, 0.537598f, 0.551758f, 0.565918f,
+ 0.580078f, 0.594727f, 0.783691f, 0.783203f, 0.776855f, 0.770508f, 0.763672f, 0.757324f, 0.002836f, 0.008659f, 0.014351f, 0.019913f,
+ 0.025772f, 0.032074f, 0.037933f, 0.044128f, 0.050903f, 0.057159f, 0.064026f, 0.070496f, 0.077698f, 0.085022f, 0.091919f, 0.099426f,
+ 0.107727f, 0.114990f, 0.123169f, 0.131226f, 0.140015f, 0.148682f, 0.157349f, 0.166260f, 0.175171f, 0.184692f, 0.194214f, 0.203979f,
+ 0.214355f, 0.224487f, 0.234985f, 0.245728f, 0.256104f, 0.267334f, 0.278320f, 0.288818f, 0.301025f, 0.312256f, 0.324219f, 0.335938f,
+ 0.347900f, 0.360596f, 0.372070f, 0.384521f, 0.397217f, 0.410400f, 0.423340f, 0.436279f, 0.449463f, 0.463135f, 0.476807f, 0.490723f,
+ 0.503906f, 0.517578f, 0.532227f, 0.546875f, 0.561035f, 0.575684f, 0.773926f, 0.775391f, 0.769043f, 0.763672f, 0.757812f, 0.751953f,
+ 0.002506f, 0.008080f, 0.013100f, 0.018738f, 0.024384f, 0.029953f, 0.035797f, 0.041473f, 0.047485f, 0.053558f, 0.059265f, 0.065918f,
+ 0.072693f, 0.079468f, 0.086426f, 0.093384f, 0.100708f, 0.108032f, 0.115417f, 0.122986f, 0.130615f, 0.139038f, 0.147827f, 0.156494f,
+ 0.165039f, 0.173828f, 0.182617f, 0.192139f, 0.201782f, 0.211426f, 0.221558f, 0.231323f, 0.242188f, 0.252686f, 0.263672f, 0.274414f,
+ 0.284912f, 0.296143f, 0.308105f, 0.319824f, 0.331543f, 0.343750f, 0.355225f, 0.367432f, 0.379883f, 0.393066f, 0.405273f, 0.418457f,
+ 0.431641f, 0.444580f, 0.457764f, 0.471924f, 0.485840f, 0.499268f, 0.512695f, 0.527344f, 0.542480f, 0.556641f, 0.764160f, 0.766602f,
+ 0.761719f, 0.756348f, 0.750488f, 0.745605f, 0.002640f, 0.007809f, 0.012497f, 0.017593f, 0.023102f, 0.028122f, 0.033569f, 0.038879f,
+ 0.044250f, 0.049988f, 0.055908f, 0.061615f, 0.067627f, 0.074036f, 0.080566f, 0.087524f, 0.093262f, 0.100769f, 0.107910f, 0.114929f,
+ 0.121948f, 0.130371f, 0.137939f, 0.146362f, 0.154297f, 0.163208f, 0.171509f, 0.180664f, 0.189697f, 0.199341f, 0.208618f, 0.218506f,
+ 0.228394f, 0.238892f, 0.248779f, 0.259277f, 0.270752f, 0.281250f, 0.292236f, 0.303467f, 0.315186f, 0.326660f, 0.338867f, 0.351074f,
+ 0.362305f, 0.374756f, 0.387939f, 0.400146f, 0.413330f, 0.426514f, 0.439209f, 0.452881f, 0.466553f, 0.480225f, 0.494141f, 0.508301f,
+ 0.522949f, 0.537109f, 0.753906f, 0.758301f, 0.754395f, 0.749023f, 0.743652f, 0.739258f, 0.002441f, 0.007088f, 0.011993f, 0.016266f,
+ 0.021255f, 0.026031f, 0.031189f, 0.036072f, 0.041260f, 0.046753f, 0.052155f, 0.057587f, 0.063232f, 0.068787f, 0.075623f, 0.081055f,
+ 0.087341f, 0.094177f, 0.100647f, 0.106689f, 0.113892f, 0.121399f, 0.129028f, 0.136841f, 0.144287f, 0.152222f, 0.160522f, 0.169312f,
+ 0.178101f, 0.186523f, 0.196045f, 0.205200f, 0.214966f, 0.224487f, 0.234863f, 0.244751f, 0.255371f, 0.265625f, 0.276367f, 0.287842f,
+ 0.298828f, 0.310303f, 0.321533f, 0.333984f, 0.345459f, 0.357666f, 0.370117f, 0.382568f, 0.394287f, 0.407959f, 0.421875f, 0.433838f,
+ 0.446777f, 0.461426f, 0.475098f, 0.488525f, 0.504395f, 0.517578f, 0.744141f, 0.749512f, 0.746094f, 0.741699f, 0.736816f, 0.732422f,
+ 0.002172f, 0.006695f, 0.011093f, 0.015266f, 0.020081f, 0.024521f, 0.029388f, 0.033966f, 0.038727f, 0.043427f, 0.048706f, 0.053772f,
+ 0.059418f, 0.064270f, 0.069580f, 0.075500f, 0.081421f, 0.087280f, 0.093262f, 0.099670f, 0.106567f, 0.113220f, 0.119995f, 0.127197f,
+ 0.134644f, 0.142212f, 0.150146f, 0.157959f, 0.166382f, 0.174927f, 0.184082f, 0.192505f, 0.201904f, 0.211792f, 0.220825f, 0.230713f,
+ 0.240601f, 0.251221f, 0.261719f, 0.272461f, 0.282715f, 0.294434f, 0.305420f, 0.316650f, 0.328369f, 0.340088f, 0.352783f, 0.364746f,
+ 0.377197f, 0.389648f, 0.402832f, 0.416016f, 0.429443f, 0.442627f, 0.456055f, 0.469971f, 0.484863f, 0.499268f, 0.733887f, 0.741211f,
+ 0.737793f, 0.734375f, 0.729980f, 0.725586f, 0.002045f, 0.006187f, 0.010406f, 0.014664f, 0.018570f, 0.022675f, 0.027176f, 0.031586f,
+ 0.035858f, 0.040253f, 0.045227f, 0.049774f, 0.054504f, 0.059692f, 0.065186f, 0.070374f, 0.075500f, 0.080627f, 0.086792f, 0.092285f,
+ 0.098999f, 0.104675f, 0.111816f, 0.118286f, 0.125610f, 0.132324f, 0.139771f, 0.147339f, 0.155029f, 0.163696f, 0.171631f, 0.180420f,
+ 0.189087f, 0.197754f, 0.207275f, 0.216309f, 0.226440f, 0.236694f, 0.246338f, 0.256836f, 0.267334f, 0.278320f, 0.289062f, 0.300537f,
+ 0.312012f, 0.323975f, 0.335449f, 0.347168f, 0.359375f, 0.372314f, 0.384521f, 0.396973f, 0.410400f, 0.423584f, 0.437500f, 0.450928f,
+ 0.465332f, 0.479736f, 0.723145f, 0.732422f, 0.729980f, 0.726562f, 0.722656f, 0.718750f, 0.002148f, 0.005802f, 0.009811f, 0.013565f,
+ 0.017578f, 0.021179f, 0.025040f, 0.029053f, 0.033417f, 0.037445f, 0.042114f, 0.046112f, 0.050720f, 0.055511f, 0.060028f, 0.065002f,
+ 0.069458f, 0.075134f, 0.080078f, 0.085693f, 0.091492f, 0.097290f, 0.103394f, 0.109802f, 0.116089f, 0.122925f, 0.129883f, 0.136963f,
+ 0.144165f, 0.151733f, 0.160156f, 0.167847f, 0.176392f, 0.184692f, 0.193848f, 0.203003f, 0.212402f, 0.221680f, 0.231689f, 0.242065f,
+ 0.251953f, 0.262207f, 0.273193f, 0.283936f, 0.295410f, 0.306152f, 0.318359f, 0.329590f, 0.342285f, 0.354248f, 0.366455f, 0.379150f,
+ 0.391846f, 0.405273f, 0.418701f, 0.432617f, 0.446289f, 0.460205f, 0.712891f, 0.723633f, 0.722168f, 0.718750f, 0.715332f, 0.712402f,
+ 0.001963f, 0.005642f, 0.009071f, 0.012756f, 0.016006f, 0.020020f, 0.023422f, 0.027679f, 0.030762f, 0.034943f, 0.038605f, 0.042969f,
+ 0.047028f, 0.051178f, 0.055542f, 0.060120f, 0.064575f, 0.069153f, 0.074280f, 0.079041f, 0.084595f, 0.089905f, 0.095276f, 0.101440f,
+ 0.107300f, 0.113586f, 0.119751f, 0.127075f, 0.134033f, 0.141357f, 0.148438f, 0.155884f, 0.164062f, 0.172729f, 0.180542f, 0.190063f,
+ 0.198364f, 0.207764f, 0.217163f, 0.226807f, 0.236938f, 0.247070f, 0.257324f, 0.268066f, 0.278320f, 0.289795f, 0.301025f, 0.312744f,
+ 0.324707f, 0.336182f, 0.347900f, 0.360840f, 0.372803f, 0.386230f, 0.399902f, 0.413574f, 0.427246f, 0.441162f, 0.702148f, 0.714355f,
+ 0.713867f, 0.711426f, 0.707520f, 0.704590f, 0.001995f, 0.005245f, 0.008553f, 0.011543f, 0.015015f, 0.018326f, 0.021881f, 0.025131f,
+ 0.028641f, 0.032349f, 0.035675f, 0.039520f, 0.043549f, 0.047089f, 0.051086f, 0.054962f, 0.059265f, 0.063782f, 0.068054f, 0.072571f,
+ 0.077759f, 0.082520f, 0.088013f, 0.093323f, 0.098755f, 0.104858f, 0.111145f, 0.117371f, 0.123840f, 0.130615f, 0.137207f, 0.144897f,
+ 0.152344f, 0.160278f, 0.167969f, 0.176514f, 0.185425f, 0.193848f, 0.202881f, 0.212524f, 0.221924f, 0.231323f, 0.241821f, 0.251953f,
+ 0.262451f, 0.272949f, 0.284424f, 0.295166f, 0.306396f, 0.319092f, 0.329590f, 0.343018f, 0.355225f, 0.368652f, 0.381348f, 0.393799f,
+ 0.408447f, 0.422852f, 0.691406f, 0.706055f, 0.706055f, 0.703125f, 0.700684f, 0.697754f, 0.001692f, 0.004898f, 0.007828f, 0.011070f,
+ 0.013992f, 0.017227f, 0.020187f, 0.023499f, 0.026520f, 0.029526f, 0.033081f, 0.036377f, 0.039459f, 0.043396f, 0.047028f, 0.050323f,
+ 0.054199f, 0.058350f, 0.062317f, 0.066711f, 0.071106f, 0.075928f, 0.080750f, 0.085510f, 0.090820f, 0.096497f, 0.102234f, 0.107727f,
+ 0.114075f, 0.120300f, 0.126587f, 0.133789f, 0.141113f, 0.148193f, 0.156006f, 0.163696f, 0.171753f, 0.180542f, 0.188965f, 0.198120f,
+ 0.207275f, 0.216797f, 0.226318f, 0.236206f, 0.246338f, 0.256836f, 0.267334f, 0.278809f, 0.289795f, 0.300781f, 0.313232f, 0.324707f,
+ 0.337402f, 0.349365f, 0.362305f, 0.376221f, 0.389404f, 0.403809f, 0.680176f, 0.696289f, 0.697266f, 0.695312f, 0.692871f, 0.689941f,
+ 0.001606f, 0.004543f, 0.007450f, 0.010269f, 0.012962f, 0.015900f, 0.018677f, 0.021591f, 0.024628f, 0.027618f, 0.030182f, 0.033783f,
+ 0.036194f, 0.039734f, 0.042725f, 0.046478f, 0.049652f, 0.053253f, 0.057251f, 0.060883f, 0.065186f, 0.069336f, 0.073730f, 0.078247f,
+ 0.083252f, 0.088501f, 0.093628f, 0.099182f, 0.104553f, 0.110718f, 0.116577f, 0.123108f, 0.129883f, 0.136719f, 0.143921f, 0.151367f,
+ 0.159302f, 0.167114f, 0.175415f, 0.183960f, 0.192871f, 0.202148f, 0.210938f, 0.221436f, 0.230713f, 0.240723f, 0.250977f, 0.261963f,
+ 0.272461f, 0.283691f, 0.295166f, 0.306885f, 0.319092f, 0.331055f, 0.343750f, 0.356689f, 0.370361f, 0.383545f, 0.669434f, 0.687500f,
+ 0.688965f, 0.687500f, 0.685547f, 0.682617f, 0.001701f, 0.004345f, 0.006802f, 0.009514f, 0.012283f, 0.014793f, 0.017288f, 0.019958f,
+ 0.022614f, 0.025177f, 0.027695f, 0.030487f, 0.033081f, 0.035858f, 0.039185f, 0.042236f, 0.045319f, 0.048523f, 0.051941f, 0.055847f,
+ 0.059326f, 0.063171f, 0.067139f, 0.071594f, 0.075928f, 0.080566f, 0.085571f, 0.090454f, 0.095520f, 0.101196f, 0.106567f, 0.112427f,
+ 0.119019f, 0.125610f, 0.132324f, 0.139282f, 0.146973f, 0.154419f, 0.161987f, 0.170532f, 0.178833f, 0.187134f, 0.196777f, 0.206177f,
+ 0.214966f, 0.225220f, 0.235352f, 0.246094f, 0.255615f, 0.266846f, 0.278320f, 0.290039f, 0.301270f, 0.313477f, 0.325195f, 0.338867f,
+ 0.352539f, 0.365234f, 0.657715f, 0.678711f, 0.679688f, 0.679199f, 0.677734f, 0.675293f, 0.001310f, 0.003979f, 0.006393f, 0.008522f,
+ 0.011223f, 0.013557f, 0.015976f, 0.018433f, 0.020737f, 0.022842f, 0.025421f, 0.027649f, 0.030289f, 0.032806f, 0.035645f, 0.038025f,
+ 0.041199f, 0.044220f, 0.047058f, 0.050720f, 0.053589f, 0.057281f, 0.061157f, 0.064941f, 0.068787f, 0.072998f, 0.077698f, 0.082153f,
+ 0.086975f, 0.092102f, 0.097229f, 0.103027f, 0.108826f, 0.114746f, 0.121094f, 0.127930f, 0.134521f, 0.141846f, 0.149292f, 0.157227f,
+ 0.164673f, 0.173218f, 0.182007f, 0.190552f, 0.199951f, 0.209717f, 0.219360f, 0.229004f, 0.239502f, 0.250244f, 0.260986f, 0.272461f,
+ 0.282959f, 0.295166f, 0.307373f, 0.320557f, 0.333252f, 0.346436f, 0.646973f, 0.668945f, 0.670898f, 0.671387f, 0.669922f, 0.668457f,
+ 0.001348f, 0.003523f, 0.005863f, 0.008133f, 0.010338f, 0.012520f, 0.014511f, 0.016464f, 0.018768f, 0.020920f, 0.022888f, 0.025665f,
+ 0.027588f, 0.029861f, 0.032135f, 0.034485f, 0.037140f, 0.040039f, 0.042725f, 0.045532f, 0.048859f, 0.051971f, 0.055237f, 0.058594f,
+ 0.062408f, 0.066101f, 0.070251f, 0.074280f, 0.078735f, 0.083435f, 0.088318f, 0.093567f, 0.098633f, 0.104431f, 0.110291f, 0.116455f,
+ 0.122986f, 0.129517f, 0.136963f, 0.143921f, 0.152222f, 0.159546f, 0.167358f, 0.176514f, 0.185181f, 0.194214f, 0.203857f, 0.213623f,
+ 0.223389f, 0.233521f, 0.244385f, 0.255127f, 0.266602f, 0.277832f, 0.289307f, 0.301758f, 0.314697f, 0.328613f, 0.635254f, 0.659668f,
+ 0.663086f, 0.663086f, 0.662109f, 0.660156f, 0.001084f, 0.003263f, 0.005554f, 0.007416f, 0.009445f, 0.011185f, 0.013161f, 0.015366f,
+ 0.017136f, 0.019058f, 0.020935f, 0.022781f, 0.024857f, 0.026886f, 0.029160f, 0.031097f, 0.033569f, 0.035858f, 0.038361f, 0.040924f,
+ 0.043427f, 0.046478f, 0.049500f, 0.052948f, 0.056122f, 0.059418f, 0.063293f, 0.067139f, 0.070923f, 0.075073f, 0.079712f, 0.084229f,
+ 0.089233f, 0.094604f, 0.100037f, 0.105774f, 0.111694f, 0.117798f, 0.124634f, 0.131226f, 0.139038f, 0.146484f, 0.154175f, 0.162231f,
+ 0.170654f, 0.179199f, 0.188599f, 0.197754f, 0.207153f, 0.217407f, 0.227295f, 0.238159f, 0.248657f, 0.260986f, 0.271973f, 0.284912f,
+ 0.296631f, 0.308838f, 0.623535f, 0.650391f, 0.653809f, 0.654297f, 0.653809f, 0.652832f, 0.001070f, 0.003069f, 0.005108f, 0.006855f,
+ 0.008522f, 0.010384f, 0.011993f, 0.013847f, 0.015549f, 0.016968f, 0.018677f, 0.020660f, 0.022079f, 0.024048f, 0.026077f, 0.027954f,
+ 0.030014f, 0.032135f, 0.034210f, 0.036560f, 0.038971f, 0.041840f, 0.044434f, 0.047089f, 0.049896f, 0.053284f, 0.056763f, 0.060120f,
+ 0.063477f, 0.067505f, 0.071533f, 0.075928f, 0.080261f, 0.085205f, 0.089905f, 0.095520f, 0.100830f, 0.106567f, 0.113159f, 0.119385f,
+ 0.126221f, 0.133301f, 0.140259f, 0.148560f, 0.156494f, 0.165039f, 0.173462f, 0.182861f, 0.192017f, 0.201172f, 0.211548f, 0.221802f,
+ 0.232666f, 0.243286f, 0.254639f, 0.265869f, 0.278809f, 0.291260f, 0.611816f, 0.640625f, 0.645508f, 0.645996f, 0.645508f, 0.645020f,
+ 0.001057f, 0.002815f, 0.004646f, 0.006187f, 0.007935f, 0.009583f, 0.011139f, 0.012428f, 0.013878f, 0.015404f, 0.016830f, 0.018433f,
+ 0.019836f, 0.021637f, 0.023300f, 0.024857f, 0.026855f, 0.028519f, 0.030533f, 0.032593f, 0.034790f, 0.037140f, 0.039520f, 0.041748f,
+ 0.044525f, 0.047302f, 0.050232f, 0.053497f, 0.056580f, 0.059998f, 0.063721f, 0.067627f, 0.071777f, 0.076111f, 0.080627f, 0.085571f,
+ 0.090698f, 0.096130f, 0.101624f, 0.107849f, 0.114258f, 0.120544f, 0.127686f, 0.135132f, 0.142700f, 0.150269f, 0.158813f, 0.167725f,
+ 0.176392f, 0.185791f, 0.195312f, 0.205444f, 0.216064f, 0.226562f, 0.237793f, 0.248657f, 0.260254f, 0.272949f, 0.600098f, 0.631348f,
+ 0.636230f, 0.637207f, 0.637695f, 0.636719f, 0.001022f, 0.002628f, 0.004486f, 0.005684f, 0.007179f, 0.008636f, 0.009911f, 0.011307f,
+ 0.012428f, 0.013771f, 0.015152f, 0.016342f, 0.017822f, 0.018997f, 0.020584f, 0.022263f, 0.023651f, 0.025482f, 0.027191f, 0.028793f,
+ 0.030960f, 0.032715f, 0.034912f, 0.036987f, 0.039368f, 0.041840f, 0.044495f, 0.047180f, 0.050110f, 0.053314f, 0.056580f, 0.060059f,
+ 0.063660f, 0.067383f, 0.071777f, 0.075928f, 0.081055f, 0.085938f, 0.091187f, 0.096619f, 0.102356f, 0.108826f, 0.115051f, 0.121948f,
+ 0.129150f, 0.136475f, 0.144653f, 0.152832f, 0.161621f, 0.170288f, 0.179932f, 0.189209f, 0.198730f, 0.209595f, 0.220459f, 0.231201f,
+ 0.242798f, 0.255615f, 0.588867f, 0.621094f, 0.626953f, 0.629883f, 0.629395f, 0.629883f, 0.001016f, 0.002304f, 0.003975f, 0.005024f,
+ 0.006584f, 0.007812f, 0.008926f, 0.009987f, 0.011024f, 0.012199f, 0.013321f, 0.014595f, 0.015617f, 0.016830f, 0.018326f, 0.019577f,
+ 0.020798f, 0.022293f, 0.023758f, 0.025253f, 0.027145f, 0.028656f, 0.030640f, 0.032501f, 0.034546f, 0.036682f, 0.039001f, 0.041412f,
+ 0.044037f, 0.046875f, 0.049622f, 0.052917f, 0.056030f, 0.059387f, 0.063354f, 0.067383f, 0.071655f, 0.075928f, 0.080750f, 0.085876f,
+ 0.091248f, 0.097168f, 0.102905f, 0.109497f, 0.116272f, 0.123413f, 0.130859f, 0.138550f, 0.147217f, 0.155518f, 0.164551f, 0.173828f,
+ 0.183350f, 0.193481f, 0.204102f, 0.214600f, 0.225342f, 0.237915f, 0.575684f, 0.611816f, 0.617188f, 0.621094f, 0.621582f, 0.620605f,
+ 0.000768f, 0.002398f, 0.003801f, 0.004875f, 0.005848f, 0.006889f, 0.008072f, 0.008820f, 0.009758f, 0.010910f, 0.011810f, 0.013023f,
+ 0.013878f, 0.014786f, 0.016083f, 0.017166f, 0.018402f, 0.019577f, 0.020691f, 0.022125f, 0.023743f, 0.025009f, 0.026779f, 0.028336f,
+ 0.030075f, 0.031921f, 0.033997f, 0.036255f, 0.038452f, 0.040833f, 0.043488f, 0.045959f, 0.049011f, 0.052216f, 0.055634f, 0.059052f,
+ 0.062744f, 0.066956f, 0.071289f, 0.075745f, 0.080566f, 0.086060f, 0.091614f, 0.097351f, 0.103821f, 0.110291f, 0.117432f, 0.124939f,
+ 0.132568f, 0.140869f, 0.149414f, 0.158325f, 0.168213f, 0.177368f, 0.187744f, 0.197876f, 0.208984f, 0.219849f, 0.563965f, 0.602051f,
+ 0.608887f, 0.610840f, 0.613770f, 0.612305f, 0.000764f, 0.002028f, 0.003302f, 0.004276f, 0.005325f, 0.006035f, 0.007034f, 0.007843f,
+ 0.008904f, 0.009628f, 0.010323f, 0.011192f, 0.012039f, 0.013092f, 0.013924f, 0.014854f, 0.015793f, 0.016953f, 0.018036f, 0.019211f,
+ 0.020355f, 0.021667f, 0.023010f, 0.024582f, 0.026016f, 0.027771f, 0.029434f, 0.031235f, 0.033264f, 0.035217f, 0.037628f, 0.039886f,
+ 0.042084f, 0.044952f, 0.048126f, 0.051392f, 0.054779f, 0.058197f, 0.062164f, 0.066223f, 0.070740f, 0.075439f, 0.080566f, 0.086182f,
+ 0.091919f, 0.098145f, 0.104431f, 0.111633f, 0.119080f, 0.126587f, 0.134888f, 0.143311f, 0.152710f, 0.162109f, 0.171631f, 0.182129f,
+ 0.192139f, 0.203491f, 0.552246f, 0.591309f, 0.599609f, 0.602539f, 0.604004f, 0.604980f, 0.000782f, 0.001970f, 0.003082f, 0.003859f,
+ 0.004635f, 0.005611f, 0.006123f, 0.006767f, 0.007595f, 0.008270f, 0.009140f, 0.009674f, 0.010490f, 0.011040f, 0.011902f, 0.012749f,
+ 0.013573f, 0.014526f, 0.015656f, 0.016541f, 0.017548f, 0.018631f, 0.019730f, 0.021103f, 0.022446f, 0.023758f, 0.025162f, 0.026611f,
+ 0.028458f, 0.030441f, 0.032074f, 0.034302f, 0.036316f, 0.038727f, 0.041138f, 0.044098f, 0.046997f, 0.050232f, 0.053711f, 0.057281f,
+ 0.061340f, 0.065491f, 0.070435f, 0.075256f, 0.080688f, 0.086426f, 0.092346f, 0.098694f, 0.105896f, 0.113098f, 0.120911f, 0.129028f,
+ 0.137695f, 0.146606f, 0.155884f, 0.165894f, 0.175903f, 0.186768f, 0.540527f, 0.582520f, 0.590332f, 0.593750f, 0.594727f, 0.596191f,
+ 0.000711f, 0.001649f, 0.002529f, 0.003332f, 0.004036f, 0.004799f, 0.005444f, 0.006050f, 0.006638f, 0.007160f, 0.007771f, 0.008331f,
+ 0.008980f, 0.009644f, 0.010307f, 0.010887f, 0.011787f, 0.012306f, 0.013176f, 0.014099f, 0.014915f, 0.015839f, 0.016708f, 0.017822f,
+ 0.019073f, 0.020233f, 0.021423f, 0.022690f, 0.024033f, 0.025589f, 0.027344f, 0.028976f, 0.030930f, 0.032990f, 0.035156f, 0.037445f,
+ 0.040131f, 0.042847f, 0.045776f, 0.049042f, 0.052551f, 0.056519f, 0.060486f, 0.064941f, 0.069458f, 0.074951f, 0.080444f, 0.086487f,
+ 0.092957f, 0.099915f, 0.107361f, 0.114929f, 0.123535f, 0.131714f, 0.140747f, 0.150513f, 0.160767f, 0.171265f, 0.527832f, 0.572754f,
+ 0.581543f, 0.583496f, 0.586426f, 0.587402f, 0.000504f, 0.001575f, 0.002235f, 0.003147f, 0.003641f, 0.004150f, 0.004570f, 0.005173f,
+ 0.005863f, 0.006016f, 0.006462f, 0.007111f, 0.007660f, 0.008156f, 0.008736f, 0.009354f, 0.010094f, 0.010475f, 0.011253f, 0.011879f,
+ 0.012657f, 0.013603f, 0.014267f, 0.015099f, 0.016144f, 0.017014f, 0.017990f, 0.019104f, 0.020416f, 0.021652f, 0.022919f, 0.024353f,
+ 0.025986f, 0.027710f, 0.029602f, 0.031494f, 0.033722f, 0.036102f, 0.038635f, 0.041412f, 0.044525f, 0.047729f, 0.051636f, 0.055511f,
+ 0.059540f, 0.064331f, 0.069580f, 0.075073f, 0.080750f, 0.087341f, 0.094116f, 0.101379f, 0.109558f, 0.117676f, 0.126221f, 0.135376f,
+ 0.145874f, 0.155518f, 0.516113f, 0.562012f, 0.571777f, 0.576172f, 0.578125f, 0.579102f, 0.000445f, 0.001304f, 0.002201f, 0.002535f,
+ 0.003126f, 0.003664f, 0.004047f, 0.004463f, 0.004887f, 0.005234f, 0.005711f, 0.005997f, 0.006500f, 0.006901f, 0.007389f, 0.007904f,
+ 0.008293f, 0.008919f, 0.009499f, 0.009941f, 0.010635f, 0.011269f, 0.011948f, 0.012589f, 0.013435f, 0.014252f, 0.015091f, 0.016052f,
+ 0.017059f, 0.017960f, 0.019241f, 0.020264f, 0.021667f, 0.022995f, 0.024628f, 0.026230f, 0.027985f, 0.029984f, 0.032288f, 0.034515f,
+ 0.037140f, 0.040009f, 0.043152f, 0.046722f, 0.050354f, 0.054504f, 0.059143f, 0.064026f, 0.069458f, 0.075256f, 0.081726f, 0.088562f,
+ 0.095825f, 0.103516f, 0.112000f, 0.120850f, 0.130005f, 0.140381f, 0.502441f, 0.551758f, 0.562012f, 0.566406f, 0.568848f, 0.571289f,
+ 0.000396f, 0.001226f, 0.001812f, 0.002357f, 0.002796f, 0.003094f, 0.003328f, 0.003763f, 0.003979f, 0.004364f, 0.004642f, 0.005051f,
+ 0.005489f, 0.005745f, 0.006126f, 0.006611f, 0.007004f, 0.007473f, 0.007771f, 0.008293f, 0.008919f, 0.009392f, 0.009941f, 0.010483f,
+ 0.011169f, 0.011765f, 0.012436f, 0.013344f, 0.014030f, 0.014908f, 0.015778f, 0.016769f, 0.017838f, 0.018997f, 0.020279f, 0.021622f,
+ 0.023056f, 0.024704f, 0.026474f, 0.028580f, 0.030579f, 0.033051f, 0.035706f, 0.038605f, 0.041840f, 0.045380f, 0.049500f, 0.053986f,
+ 0.058685f, 0.063843f, 0.069885f, 0.076050f, 0.083191f, 0.090576f, 0.098511f, 0.107056f, 0.115479f, 0.125122f, 0.491211f, 0.541504f,
+ 0.552734f, 0.557617f, 0.560547f, 0.562012f, 0.000559f, 0.001152f, 0.001668f, 0.001955f, 0.002234f, 0.002550f, 0.002821f, 0.003057f,
+ 0.003296f, 0.003635f, 0.003948f, 0.004189f, 0.004448f, 0.004761f, 0.005077f, 0.005417f, 0.005699f, 0.006142f, 0.006458f, 0.006844f,
+ 0.007271f, 0.007717f, 0.008156f, 0.008675f, 0.009132f, 0.009590f, 0.010277f, 0.010864f, 0.011482f, 0.012131f, 0.012901f, 0.013741f,
+ 0.014595f, 0.015549f, 0.016525f, 0.017563f, 0.018799f, 0.020111f, 0.021484f, 0.023087f, 0.024765f, 0.026840f, 0.028992f, 0.031403f,
+ 0.034119f, 0.037323f, 0.040680f, 0.044464f, 0.048584f, 0.053345f, 0.058838f, 0.064514f, 0.071045f, 0.078247f, 0.085571f, 0.093567f,
+ 0.101685f, 0.111023f, 0.477539f, 0.531738f, 0.542969f, 0.548340f, 0.552246f, 0.553711f, 0.000459f, 0.000939f, 0.001184f, 0.001600f,
+ 0.001761f, 0.002144f, 0.002258f, 0.002546f, 0.002708f, 0.002922f, 0.003157f, 0.003414f, 0.003588f, 0.003918f, 0.004154f, 0.004387f,
+ 0.004662f, 0.004993f, 0.005249f, 0.005566f, 0.005867f, 0.006252f, 0.006573f, 0.007061f, 0.007408f, 0.007858f, 0.008270f, 0.008713f,
+ 0.009361f, 0.009911f, 0.010513f, 0.011047f, 0.011841f, 0.012566f, 0.013252f, 0.014175f, 0.015182f, 0.016220f, 0.017258f, 0.018524f,
+ 0.019882f, 0.021454f, 0.023132f, 0.025146f, 0.027405f, 0.029877f, 0.032745f, 0.035919f, 0.039642f, 0.043823f, 0.048492f, 0.053619f,
+ 0.059235f, 0.065735f, 0.072693f, 0.080383f, 0.088867f, 0.097412f, 0.466309f, 0.520508f, 0.533691f, 0.539062f, 0.542480f, 0.543945f,
+ 0.000369f, 0.000915f, 0.001124f, 0.001297f, 0.001534f, 0.001741f, 0.001833f, 0.002111f, 0.002272f, 0.002369f, 0.002516f, 0.002766f,
+ 0.002920f, 0.003162f, 0.003317f, 0.003551f, 0.003723f, 0.003941f, 0.004211f, 0.004425f, 0.004757f, 0.004993f, 0.005306f, 0.005581f,
+ 0.005859f, 0.006203f, 0.006592f, 0.007015f, 0.007450f, 0.007828f, 0.008377f, 0.008797f, 0.009361f, 0.009895f, 0.010582f, 0.011322f,
+ 0.012016f, 0.012772f, 0.013687f, 0.014748f, 0.015778f, 0.016907f, 0.018326f, 0.019821f, 0.021622f, 0.023483f, 0.025742f, 0.028473f,
+ 0.031525f, 0.034943f, 0.038910f, 0.043457f, 0.048645f, 0.054749f, 0.061279f, 0.068420f, 0.076111f, 0.084778f, 0.453613f, 0.510742f,
+ 0.523926f, 0.529785f, 0.533203f, 0.536133f, 0.000186f, 0.000582f, 0.000925f, 0.001026f, 0.001228f, 0.001351f, 0.001470f, 0.001606f,
+ 0.001765f, 0.001908f, 0.001999f, 0.002104f, 0.002281f, 0.002476f, 0.002659f, 0.002766f, 0.002911f, 0.003040f, 0.003344f, 0.003475f,
+ 0.003683f, 0.003922f, 0.004185f, 0.004417f, 0.004673f, 0.004890f, 0.005123f, 0.005440f, 0.005817f, 0.006126f, 0.006481f, 0.006859f,
+ 0.007275f, 0.007740f, 0.008202f, 0.008728f, 0.009315f, 0.009972f, 0.010597f, 0.011391f, 0.012268f, 0.013252f, 0.014221f, 0.015388f,
+ 0.016724f, 0.018265f, 0.020004f, 0.022049f, 0.024445f, 0.027206f, 0.030762f, 0.034424f, 0.038971f, 0.044220f, 0.050262f, 0.056976f,
+ 0.064575f, 0.072083f, 0.441650f, 0.500488f, 0.514160f, 0.520020f, 0.524414f, 0.526855f, 0.000194f, 0.000467f, 0.000775f, 0.000911f,
+ 0.000994f, 0.001081f, 0.001221f, 0.001204f, 0.001368f, 0.001479f, 0.001582f, 0.001707f, 0.001801f, 0.001921f, 0.001993f, 0.002146f,
+ 0.002245f, 0.002398f, 0.002531f, 0.002674f, 0.002871f, 0.003033f, 0.003172f, 0.003374f, 0.003519f, 0.003742f, 0.003963f, 0.004158f,
+ 0.004448f, 0.004650f, 0.005032f, 0.005230f, 0.005550f, 0.005932f, 0.006241f, 0.006634f, 0.007088f, 0.007572f, 0.008110f, 0.008636f,
+ 0.009323f, 0.010071f, 0.010834f, 0.011757f, 0.012779f, 0.013863f, 0.015190f, 0.016769f, 0.018555f, 0.020706f, 0.023331f, 0.026352f,
+ 0.030182f, 0.034760f, 0.040039f, 0.046356f, 0.053406f, 0.060638f, 0.427979f, 0.489502f, 0.504883f, 0.511719f, 0.515137f, 0.518066f,
+ 0.000339f, 0.000388f, 0.000559f, 0.000617f, 0.000667f, 0.000795f, 0.000853f, 0.000938f, 0.000972f, 0.001079f, 0.001217f, 0.001274f,
+ 0.001369f, 0.001480f, 0.001536f, 0.001581f, 0.001711f, 0.001804f, 0.001900f, 0.002047f, 0.002129f, 0.002245f, 0.002394f, 0.002493f,
+ 0.002645f, 0.002773f, 0.002974f, 0.003124f, 0.003307f, 0.003559f, 0.003757f, 0.003893f, 0.004169f, 0.004353f, 0.004684f, 0.004963f,
+ 0.005272f, 0.005615f, 0.005981f, 0.006420f, 0.006878f, 0.007378f, 0.008080f, 0.008682f, 0.009438f, 0.010239f, 0.011299f, 0.012459f,
+ 0.013809f, 0.015305f, 0.017212f, 0.019501f, 0.022583f, 0.026245f, 0.030838f, 0.036255f, 0.042938f, 0.049988f, 0.416504f, 0.479492f,
+ 0.495361f, 0.501465f, 0.505859f, 0.508789f, 0.000148f, 0.000349f, 0.000414f, 0.000480f, 0.000554f, 0.000575f, 0.000675f, 0.000641f,
+ 0.000743f, 0.000809f, 0.000882f, 0.000919f, 0.000967f, 0.001019f, 0.001122f, 0.001156f, 0.001264f, 0.001322f, 0.001392f, 0.001431f,
+ 0.001529f, 0.001625f, 0.001735f, 0.001802f, 0.001912f, 0.002007f, 0.002131f, 0.002237f, 0.002338f, 0.002525f, 0.002638f, 0.002850f,
+ 0.002962f, 0.003130f, 0.003347f, 0.003536f, 0.003784f, 0.004063f, 0.004364f, 0.004623f, 0.004929f, 0.005314f, 0.005714f, 0.006191f,
+ 0.006760f, 0.007385f, 0.008080f, 0.008919f, 0.009933f, 0.011078f, 0.012390f, 0.014130f, 0.016251f, 0.019012f, 0.022720f, 0.027496f,
+ 0.033234f, 0.040192f, 0.403320f, 0.468994f, 0.485352f, 0.491943f, 0.497070f, 0.500000f, 0.000093f, 0.000191f, 0.000299f, 0.000284f,
+ 0.000367f, 0.000453f, 0.000420f, 0.000467f, 0.000519f, 0.000611f, 0.000607f, 0.000626f, 0.000647f, 0.000722f, 0.000741f, 0.000815f,
+ 0.000829f, 0.000910f, 0.000967f, 0.001023f, 0.001076f, 0.001138f, 0.001197f, 0.001260f, 0.001334f, 0.001393f, 0.001490f, 0.001562f,
+ 0.001633f, 0.001772f, 0.001831f, 0.001949f, 0.002056f, 0.002167f, 0.002312f, 0.002472f, 0.002607f, 0.002781f, 0.002972f, 0.003145f,
+ 0.003387f, 0.003647f, 0.003941f, 0.004253f, 0.004604f, 0.005051f, 0.005558f, 0.006165f, 0.006836f, 0.007660f, 0.008652f, 0.009796f,
+ 0.011284f, 0.013260f, 0.015945f, 0.019608f, 0.024734f, 0.031082f, 0.390625f, 0.459229f, 0.475586f, 0.482910f, 0.488037f, 0.490723f,
+ 0.000132f, 0.000208f, 0.000217f, 0.000221f, 0.000267f, 0.000272f, 0.000277f, 0.000320f, 0.000356f, 0.000372f, 0.000372f, 0.000446f,
+ 0.000436f, 0.000487f, 0.000514f, 0.000531f, 0.000587f, 0.000601f, 0.000629f, 0.000658f, 0.000707f, 0.000736f, 0.000784f, 0.000816f,
+ 0.000880f, 0.000909f, 0.000978f, 0.001035f, 0.001084f, 0.001135f, 0.001200f, 0.001278f, 0.001357f, 0.001429f, 0.001516f, 0.001588f,
+ 0.001724f, 0.001802f, 0.001949f, 0.002085f, 0.002230f, 0.002373f, 0.002554f, 0.002743f, 0.003000f, 0.003300f, 0.003611f, 0.003963f,
+ 0.004425f, 0.004967f, 0.005630f, 0.006424f, 0.007462f, 0.008812f, 0.010551f, 0.013184f, 0.017258f, 0.022980f, 0.377686f, 0.448242f,
+ 0.465820f, 0.474121f, 0.478760f, 0.481934f, 0.000041f, 0.000149f, 0.000126f, 0.000128f, 0.000158f, 0.000196f, 0.000174f, 0.000206f,
+ 0.000216f, 0.000223f, 0.000231f, 0.000244f, 0.000276f, 0.000291f, 0.000312f, 0.000326f, 0.000338f, 0.000374f, 0.000387f, 0.000423f,
+ 0.000430f, 0.000447f, 0.000471f, 0.000509f, 0.000538f, 0.000583f, 0.000591f, 0.000613f, 0.000659f, 0.000688f, 0.000743f, 0.000779f,
+ 0.000833f, 0.000865f, 0.000924f, 0.000966f, 0.001033f, 0.001106f, 0.001186f, 0.001245f, 0.001336f, 0.001453f, 0.001559f, 0.001685f,
+ 0.001807f, 0.001980f, 0.002207f, 0.002417f, 0.002689f, 0.003027f, 0.003418f, 0.003933f, 0.004604f, 0.005482f, 0.006641f, 0.008263f,
+ 0.011017f, 0.015778f, 0.364746f, 0.437256f, 0.456055f, 0.463623f, 0.469238f, 0.472656f, 0.000100f, 0.000089f, 0.000085f, 0.000081f,
+ 0.000101f, 0.000096f, 0.000116f, 0.000116f, 0.000119f, 0.000126f, 0.000141f, 0.000157f, 0.000149f, 0.000158f, 0.000179f, 0.000176f,
+ 0.000195f, 0.000206f, 0.000216f, 0.000222f, 0.000240f, 0.000246f, 0.000269f, 0.000279f, 0.000303f, 0.000320f, 0.000333f, 0.000345f,
+ 0.000365f, 0.000379f, 0.000409f, 0.000434f, 0.000453f, 0.000477f, 0.000511f, 0.000541f, 0.000569f, 0.000608f, 0.000656f, 0.000689f,
+ 0.000738f, 0.000795f, 0.000867f, 0.000918f, 0.001005f, 0.001087f, 0.001189f, 0.001312f, 0.001465f, 0.001656f, 0.001873f, 0.002171f,
+ 0.002546f, 0.003056f, 0.003767f, 0.004765f, 0.006390f, 0.009811f, 0.353516f, 0.426758f, 0.446045f, 0.455078f, 0.459717f, 0.464111f,
+ 0.000084f, 0.000059f, 0.000050f, 0.000049f, 0.000049f, 0.000047f, 0.000052f, 0.000058f, 0.000061f, 0.000075f, 0.000065f, 0.000066f,
+ 0.000080f, 0.000071f, 0.000076f, 0.000082f, 0.000092f, 0.000102f, 0.000100f, 0.000105f, 0.000110f, 0.000115f, 0.000121f, 0.000133f,
+ 0.000140f, 0.000146f, 0.000152f, 0.000164f, 0.000177f, 0.000185f, 0.000192f, 0.000202f, 0.000213f, 0.000224f, 0.000241f, 0.000252f,
+ 0.000268f, 0.000283f, 0.000310f, 0.000328f, 0.000348f, 0.000374f, 0.000406f, 0.000431f, 0.000470f, 0.000515f, 0.000560f, 0.000614f,
+ 0.000688f, 0.000771f, 0.000884f, 0.001019f, 0.001202f, 0.001466f, 0.001827f, 0.002369f, 0.003269f, 0.005184f, 0.341797f, 0.416016f,
+ 0.435791f, 0.445557f, 0.450928f, 0.455078f, 0.000062f, 0.000042f, 0.000035f, 0.000030f, 0.000028f, 0.000026f, 0.000024f, 0.000023f,
+ 0.000023f, 0.000023f, 0.000023f, 0.000030f, 0.000024f, 0.000024f, 0.000031f, 0.000034f, 0.000035f, 0.000037f, 0.000039f, 0.000040f,
+ 0.000043f, 0.000048f, 0.000050f, 0.000046f, 0.000051f, 0.000057f, 0.000059f, 0.000058f, 0.000063f, 0.000068f, 0.000070f, 0.000077f,
+ 0.000082f, 0.000082f, 0.000086f, 0.000093f, 0.000100f, 0.000106f, 0.000114f, 0.000120f, 0.000131f, 0.000136f, 0.000145f, 0.000161f,
+ 0.000171f, 0.000186f, 0.000204f, 0.000222f, 0.000251f, 0.000281f, 0.000318f, 0.000364f, 0.000430f, 0.000530f, 0.000672f, 0.000902f,
+ 0.001316f, 0.002153f, 0.329346f, 0.406006f, 0.426758f, 0.436035f, 0.441650f, 0.445801f, 0.000031f, 0.000020f, 0.000016f, 0.000014f,
+ 0.000014f, 0.000013f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000009f,
+ 0.000008f, 0.000008f, 0.000007f, 0.000007f, 0.000007f, 0.000008f, 0.000009f, 0.000010f, 0.000011f, 0.000012f, 0.000012f, 0.000014f,
+ 0.000014f, 0.000013f, 0.000015f, 0.000016f, 0.000018f, 0.000019f, 0.000019f, 0.000020f, 0.000023f, 0.000023f, 0.000025f, 0.000027f,
+ 0.000028f, 0.000031f, 0.000034f, 0.000034f, 0.000037f, 0.000041f, 0.000045f, 0.000049f, 0.000053f, 0.000059f, 0.000066f, 0.000079f,
+ 0.000093f, 0.000112f, 0.000144f, 0.000196f, 0.000307f, 0.000598f, 0.317383f, 0.394531f, 0.416504f, 0.425781f, 0.432129f, 0.436279f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000004f, 0.000004f, 0.000007f, 0.000010f, 0.000026f, 0.305420f, 0.384277f,
+ 0.405762f, 0.416504f, 0.423340f, 0.427246f,
+ },
+ {
+ 0.009338f, 0.028412f, 0.047394f, 0.066895f, 0.086548f, 0.105774f, 0.125854f, 0.145142f, 0.165039f, 0.184570f, 0.204712f, 0.223389f,
+ 0.243164f, 0.261719f, 0.280762f, 0.299805f, 0.318848f, 0.338135f, 0.356445f, 0.374512f, 0.393066f, 0.412354f, 0.429932f, 0.447510f,
+ 0.465576f, 0.483887f, 0.501465f, 0.518555f, 0.536133f, 0.553711f, 0.570312f, 0.587402f, 0.604492f, 0.621094f, 0.637695f, 0.653809f,
+ 0.670898f, 0.687012f, 0.702637f, 0.719238f, 0.734863f, 0.750488f, 0.765137f, 0.780762f, 0.795898f, 0.811523f, 0.825684f, 0.840820f,
+ 0.855469f, 0.870605f, 0.884277f, 0.899414f, 0.913086f, 0.926758f, 0.940918f, 0.955078f, 0.967773f, 0.981934f, 0.966797f, 0.923828f,
+ 0.894531f, 0.870605f, 0.850586f, 0.832520f, 0.008652f, 0.026825f, 0.045380f, 0.063965f, 0.082703f, 0.101807f, 0.120544f, 0.139282f,
+ 0.158569f, 0.177246f, 0.196167f, 0.214722f, 0.233521f, 0.252197f, 0.270508f, 0.289062f, 0.307861f, 0.325928f, 0.343994f, 0.361328f,
+ 0.380615f, 0.397705f, 0.415771f, 0.433594f, 0.450928f, 0.469238f, 0.485596f, 0.502930f, 0.520020f, 0.537598f, 0.553223f, 0.570801f,
+ 0.586914f, 0.603516f, 0.620117f, 0.636719f, 0.652832f, 0.668945f, 0.683594f, 0.700684f, 0.716309f, 0.731934f, 0.746582f, 0.762695f,
+ 0.777344f, 0.792480f, 0.807617f, 0.821777f, 0.836914f, 0.850586f, 0.865723f, 0.880371f, 0.894043f, 0.908691f, 0.921875f, 0.937012f,
+ 0.950195f, 0.963867f, 0.958496f, 0.917969f, 0.889648f, 0.867188f, 0.847656f, 0.830566f, 0.008293f, 0.025620f, 0.042999f, 0.061035f,
+ 0.079163f, 0.097656f, 0.115112f, 0.132812f, 0.151367f, 0.170532f, 0.188599f, 0.206787f, 0.223999f, 0.242920f, 0.259766f, 0.278809f,
+ 0.296143f, 0.313232f, 0.331055f, 0.349609f, 0.367432f, 0.385010f, 0.401611f, 0.418945f, 0.435791f, 0.453369f, 0.469727f, 0.487061f,
+ 0.503906f, 0.520508f, 0.537598f, 0.553223f, 0.569824f, 0.586426f, 0.603027f, 0.619141f, 0.634277f, 0.650879f, 0.666504f, 0.682129f,
+ 0.697754f, 0.713379f, 0.729004f, 0.743164f, 0.758301f, 0.773926f, 0.789062f, 0.803711f, 0.818359f, 0.833008f, 0.847168f, 0.862305f,
+ 0.875488f, 0.890137f, 0.903809f, 0.917480f, 0.931152f, 0.945801f, 0.950195f, 0.911133f, 0.884766f, 0.862793f, 0.844238f, 0.828125f,
+ 0.008148f, 0.024506f, 0.041016f, 0.058289f, 0.075256f, 0.092712f, 0.109802f, 0.127319f, 0.145020f, 0.162964f, 0.180298f, 0.198120f,
+ 0.215454f, 0.232300f, 0.250244f, 0.267822f, 0.285400f, 0.302734f, 0.318848f, 0.335693f, 0.354004f, 0.371582f, 0.388672f, 0.405029f,
+ 0.421143f, 0.438965f, 0.455078f, 0.472168f, 0.487549f, 0.503906f, 0.521484f, 0.537598f, 0.551758f, 0.568359f, 0.584961f, 0.601562f,
+ 0.616211f, 0.633301f, 0.648926f, 0.664062f, 0.679199f, 0.694824f, 0.709473f, 0.725098f, 0.740234f, 0.755371f, 0.770020f, 0.785156f,
+ 0.799805f, 0.813965f, 0.828125f, 0.842773f, 0.856934f, 0.871582f, 0.884766f, 0.898926f, 0.912598f, 0.926270f, 0.941895f, 0.905273f,
+ 0.879883f, 0.858887f, 0.840332f, 0.824707f, 0.007523f, 0.023010f, 0.039246f, 0.055542f, 0.072021f, 0.088257f, 0.105347f, 0.122070f,
+ 0.138306f, 0.155273f, 0.172852f, 0.189575f, 0.206421f, 0.223145f, 0.240112f, 0.256592f, 0.274170f, 0.291260f, 0.307617f, 0.323730f,
+ 0.340576f, 0.358154f, 0.374023f, 0.390137f, 0.406738f, 0.422852f, 0.440430f, 0.456543f, 0.472656f, 0.489014f, 0.504395f, 0.520996f,
+ 0.537109f, 0.552734f, 0.568848f, 0.584473f, 0.599121f, 0.615234f, 0.630859f, 0.645020f, 0.660645f, 0.677246f, 0.690918f, 0.706055f,
+ 0.721680f, 0.736328f, 0.750977f, 0.766113f, 0.780273f, 0.794922f, 0.809570f, 0.823730f, 0.837891f, 0.852539f, 0.866211f, 0.880371f,
+ 0.894531f, 0.908691f, 0.933105f, 0.898438f, 0.874023f, 0.853516f, 0.836426f, 0.821289f, 0.007339f, 0.021912f, 0.037170f, 0.052948f,
+ 0.068665f, 0.084412f, 0.100281f, 0.116333f, 0.133057f, 0.149048f, 0.164795f, 0.181274f, 0.198242f, 0.214233f, 0.230835f, 0.247314f,
+ 0.262939f, 0.279053f, 0.295898f, 0.312500f, 0.328613f, 0.344971f, 0.360107f, 0.376953f, 0.392578f, 0.408691f, 0.425293f, 0.441406f,
+ 0.456787f, 0.472656f, 0.488525f, 0.504883f, 0.520020f, 0.535156f, 0.550781f, 0.567383f, 0.582520f, 0.597656f, 0.612793f, 0.628418f,
+ 0.642578f, 0.657715f, 0.673340f, 0.688477f, 0.702637f, 0.718750f, 0.731445f, 0.748047f, 0.762207f, 0.775879f, 0.791016f, 0.804199f,
+ 0.818848f, 0.833008f, 0.847656f, 0.861328f, 0.875000f, 0.890625f, 0.924316f, 0.891602f, 0.868164f, 0.849121f, 0.832520f, 0.817871f,
+ 0.006817f, 0.021133f, 0.035675f, 0.050018f, 0.065186f, 0.080505f, 0.096069f, 0.111389f, 0.126831f, 0.142456f, 0.158203f, 0.174194f,
+ 0.189819f, 0.205444f, 0.220703f, 0.237183f, 0.253174f, 0.268555f, 0.284668f, 0.300049f, 0.316406f, 0.332275f, 0.347656f, 0.363281f,
+ 0.379395f, 0.394775f, 0.409668f, 0.426270f, 0.442139f, 0.457275f, 0.472656f, 0.488037f, 0.503906f, 0.518555f, 0.534668f, 0.548828f,
+ 0.564941f, 0.579590f, 0.595215f, 0.610352f, 0.625000f, 0.640137f, 0.654785f, 0.669434f, 0.685059f, 0.699707f, 0.713379f, 0.728027f,
+ 0.742676f, 0.758301f, 0.770996f, 0.786621f, 0.799316f, 0.813965f, 0.828613f, 0.842285f, 0.856445f, 0.871094f, 0.915527f, 0.884766f,
+ 0.862305f, 0.843750f, 0.827637f, 0.813965f, 0.006611f, 0.020111f, 0.033752f, 0.047974f, 0.062378f, 0.076843f, 0.091431f, 0.106262f,
+ 0.120911f, 0.136230f, 0.151123f, 0.166382f, 0.181396f, 0.196899f, 0.211670f, 0.227295f, 0.242554f, 0.257812f, 0.272705f, 0.288086f,
+ 0.304199f, 0.318848f, 0.334473f, 0.349609f, 0.365967f, 0.379883f, 0.395996f, 0.410889f, 0.426270f, 0.441895f, 0.457764f, 0.472412f,
+ 0.487061f, 0.502930f, 0.517090f, 0.532227f, 0.547363f, 0.563477f, 0.577637f, 0.592285f, 0.606934f, 0.621582f, 0.636230f, 0.651367f,
+ 0.665039f, 0.679688f, 0.694336f, 0.709473f, 0.724121f, 0.738770f, 0.752930f, 0.767578f, 0.780762f, 0.795410f, 0.809082f, 0.823242f,
+ 0.837891f, 0.852539f, 0.906250f, 0.877441f, 0.855957f, 0.838379f, 0.823242f, 0.809570f, 0.006153f, 0.019150f, 0.031952f, 0.045624f,
+ 0.059326f, 0.073303f, 0.087158f, 0.101562f, 0.115540f, 0.129395f, 0.144653f, 0.159180f, 0.173584f, 0.187866f, 0.203613f, 0.217651f,
+ 0.232300f, 0.247559f, 0.262207f, 0.277344f, 0.292969f, 0.307617f, 0.322021f, 0.336914f, 0.352051f, 0.367188f, 0.381592f, 0.396729f,
+ 0.411377f, 0.427002f, 0.440918f, 0.456787f, 0.471436f, 0.486572f, 0.500977f, 0.514648f, 0.530273f, 0.545410f, 0.560059f, 0.574219f,
+ 0.589355f, 0.604004f, 0.618164f, 0.632324f, 0.647461f, 0.661133f, 0.676270f, 0.691406f, 0.705078f, 0.719727f, 0.733887f, 0.748047f,
+ 0.763184f, 0.777344f, 0.791016f, 0.805176f, 0.819336f, 0.833496f, 0.896973f, 0.870117f, 0.849609f, 0.833008f, 0.818359f, 0.805176f,
+ 0.005947f, 0.018311f, 0.030731f, 0.043243f, 0.056732f, 0.069580f, 0.083435f, 0.096558f, 0.110474f, 0.123962f, 0.137695f, 0.152100f,
+ 0.166016f, 0.180054f, 0.194092f, 0.208862f, 0.222656f, 0.236816f, 0.251465f, 0.266113f, 0.281250f, 0.294922f, 0.309814f, 0.324219f,
+ 0.338623f, 0.352783f, 0.368164f, 0.382568f, 0.397461f, 0.411377f, 0.426025f, 0.441162f, 0.455078f, 0.469971f, 0.484131f, 0.499268f,
+ 0.513672f, 0.528320f, 0.542969f, 0.557129f, 0.571289f, 0.585449f, 0.599609f, 0.614258f, 0.628418f, 0.643066f, 0.657227f, 0.671875f,
+ 0.686523f, 0.700195f, 0.714355f, 0.729004f, 0.743164f, 0.756836f, 0.770996f, 0.785645f, 0.800293f, 0.814453f, 0.888184f, 0.862305f,
+ 0.843262f, 0.827148f, 0.813477f, 0.800781f, 0.005646f, 0.017136f, 0.029388f, 0.041534f, 0.053802f, 0.066162f, 0.078979f, 0.092285f,
+ 0.104980f, 0.118408f, 0.130981f, 0.144897f, 0.158203f, 0.172363f, 0.185547f, 0.199951f, 0.213501f, 0.226440f, 0.240356f, 0.254883f,
+ 0.269287f, 0.283691f, 0.297607f, 0.311279f, 0.325439f, 0.339600f, 0.353760f, 0.368408f, 0.382812f, 0.396973f, 0.410645f, 0.425049f,
+ 0.439697f, 0.454102f, 0.468262f, 0.482178f, 0.496094f, 0.510742f, 0.524902f, 0.539551f, 0.554199f, 0.568359f, 0.582031f, 0.596191f,
+ 0.610352f, 0.624023f, 0.639160f, 0.652832f, 0.667969f, 0.681152f, 0.696289f, 0.709961f, 0.723633f, 0.738770f, 0.752441f, 0.765625f,
+ 0.780273f, 0.794922f, 0.878418f, 0.855469f, 0.836914f, 0.821289f, 0.808105f, 0.796387f, 0.005478f, 0.016174f, 0.027740f, 0.038849f,
+ 0.051270f, 0.063293f, 0.075317f, 0.087402f, 0.099854f, 0.112793f, 0.125366f, 0.138184f, 0.151001f, 0.164307f, 0.177734f, 0.190918f,
+ 0.204102f, 0.217529f, 0.231079f, 0.244141f, 0.257324f, 0.271240f, 0.284668f, 0.299072f, 0.312744f, 0.326660f, 0.339600f, 0.354004f,
+ 0.368408f, 0.382324f, 0.395264f, 0.410156f, 0.423096f, 0.437500f, 0.452148f, 0.465332f, 0.480469f, 0.493408f, 0.507812f, 0.521484f,
+ 0.535645f, 0.549316f, 0.563477f, 0.578125f, 0.592285f, 0.605957f, 0.620605f, 0.634766f, 0.647949f, 0.662109f, 0.676758f, 0.691406f,
+ 0.705078f, 0.718750f, 0.732910f, 0.747559f, 0.762207f, 0.777344f, 0.869141f, 0.847656f, 0.830078f, 0.815430f, 0.802734f, 0.791504f,
+ 0.005005f, 0.015762f, 0.026657f, 0.037384f, 0.048218f, 0.059998f, 0.071594f, 0.083618f, 0.095215f, 0.107666f, 0.119141f, 0.131958f,
+ 0.144043f, 0.156128f, 0.169800f, 0.182129f, 0.194824f, 0.207031f, 0.219849f, 0.233032f, 0.247559f, 0.260010f, 0.272949f, 0.286133f,
+ 0.300293f, 0.313477f, 0.326172f, 0.339844f, 0.353516f, 0.367188f, 0.381592f, 0.394531f, 0.407959f, 0.422363f, 0.436279f, 0.449463f,
+ 0.462891f, 0.477539f, 0.490723f, 0.504395f, 0.518066f, 0.532227f, 0.545898f, 0.560059f, 0.574219f, 0.586914f, 0.602051f, 0.616211f,
+ 0.629395f, 0.644531f, 0.657227f, 0.671875f, 0.685547f, 0.699707f, 0.713867f, 0.728516f, 0.742676f, 0.756836f, 0.859375f, 0.840332f,
+ 0.823730f, 0.809082f, 0.797363f, 0.786621f, 0.004894f, 0.014786f, 0.025269f, 0.035614f, 0.045990f, 0.057129f, 0.068420f, 0.079224f,
+ 0.090698f, 0.102112f, 0.113708f, 0.125610f, 0.137817f, 0.149536f, 0.161377f, 0.174316f, 0.185791f, 0.198486f, 0.211670f, 0.223389f,
+ 0.236816f, 0.249512f, 0.261230f, 0.274414f, 0.287598f, 0.300537f, 0.313232f, 0.326904f, 0.340576f, 0.353027f, 0.366211f, 0.379883f,
+ 0.393066f, 0.406006f, 0.419678f, 0.433350f, 0.446289f, 0.460205f, 0.473633f, 0.487305f, 0.500977f, 0.515137f, 0.528320f, 0.542480f,
+ 0.554688f, 0.569824f, 0.583008f, 0.597656f, 0.610840f, 0.625488f, 0.638672f, 0.652832f, 0.666504f, 0.681152f, 0.694824f, 0.708984f,
+ 0.723145f, 0.737793f, 0.850098f, 0.833008f, 0.817383f, 0.802734f, 0.791992f, 0.780762f, 0.004536f, 0.014160f, 0.023972f, 0.033630f,
+ 0.043823f, 0.053955f, 0.064697f, 0.075195f, 0.086365f, 0.096802f, 0.108276f, 0.119751f, 0.130493f, 0.142212f, 0.153687f, 0.165405f,
+ 0.177246f, 0.189331f, 0.201538f, 0.213501f, 0.225464f, 0.237915f, 0.250244f, 0.262939f, 0.274902f, 0.288086f, 0.300781f, 0.312988f,
+ 0.326172f, 0.339600f, 0.352051f, 0.365479f, 0.377930f, 0.390625f, 0.403564f, 0.417480f, 0.430420f, 0.444092f, 0.457520f, 0.470215f,
+ 0.483643f, 0.497559f, 0.510742f, 0.524414f, 0.537598f, 0.551270f, 0.564941f, 0.579102f, 0.592285f, 0.605957f, 0.619629f, 0.633789f,
+ 0.647949f, 0.661621f, 0.675293f, 0.689453f, 0.704102f, 0.718262f, 0.840332f, 0.825195f, 0.809570f, 0.797363f, 0.786133f, 0.776367f,
+ 0.004433f, 0.013138f, 0.022720f, 0.032013f, 0.041199f, 0.051147f, 0.061462f, 0.071716f, 0.082336f, 0.091919f, 0.102722f, 0.113586f,
+ 0.124390f, 0.135010f, 0.145996f, 0.157837f, 0.168823f, 0.180054f, 0.192383f, 0.203491f, 0.215332f, 0.227417f, 0.239502f, 0.251221f,
+ 0.263672f, 0.275635f, 0.287842f, 0.300537f, 0.312500f, 0.324707f, 0.338135f, 0.350342f, 0.363037f, 0.375977f, 0.388672f, 0.401611f,
+ 0.413818f, 0.427246f, 0.440186f, 0.453613f, 0.466064f, 0.479736f, 0.492920f, 0.506836f, 0.519531f, 0.533203f, 0.546875f, 0.560059f,
+ 0.573242f, 0.587402f, 0.600098f, 0.614746f, 0.628418f, 0.642578f, 0.657227f, 0.670898f, 0.685059f, 0.699707f, 0.830566f, 0.816406f,
+ 0.802734f, 0.791016f, 0.780273f, 0.770996f, 0.004372f, 0.012619f, 0.021393f, 0.030350f, 0.039276f, 0.048523f, 0.058289f, 0.067505f,
+ 0.077393f, 0.087585f, 0.097290f, 0.107727f, 0.118225f, 0.128296f, 0.138550f, 0.149414f, 0.160278f, 0.171631f, 0.182739f, 0.193359f,
+ 0.205200f, 0.216187f, 0.228027f, 0.240234f, 0.251465f, 0.263428f, 0.275146f, 0.287598f, 0.298828f, 0.311523f, 0.323242f, 0.336182f,
+ 0.348633f, 0.360107f, 0.372803f, 0.385986f, 0.398682f, 0.411621f, 0.424072f, 0.436523f, 0.449951f, 0.462891f, 0.475098f, 0.488525f,
+ 0.501953f, 0.514648f, 0.527344f, 0.541992f, 0.555176f, 0.569336f, 0.582031f, 0.596191f, 0.609863f, 0.623047f, 0.637695f, 0.651855f,
+ 0.665527f, 0.679688f, 0.821289f, 0.808105f, 0.795410f, 0.784180f, 0.774902f, 0.765137f, 0.003937f, 0.012169f, 0.020477f, 0.028641f,
+ 0.037781f, 0.046448f, 0.055481f, 0.064209f, 0.073181f, 0.082458f, 0.092651f, 0.101990f, 0.111572f, 0.121948f, 0.132202f, 0.142212f,
+ 0.151978f, 0.162720f, 0.173340f, 0.184326f, 0.195312f, 0.206055f, 0.217163f, 0.228516f, 0.239990f, 0.250977f, 0.262695f, 0.274658f,
+ 0.285889f, 0.297363f, 0.308838f, 0.321045f, 0.333496f, 0.345459f, 0.357422f, 0.370117f, 0.382324f, 0.395020f, 0.407227f, 0.419922f,
+ 0.432617f, 0.444336f, 0.458008f, 0.470703f, 0.483398f, 0.497559f, 0.510254f, 0.522949f, 0.536133f, 0.550293f, 0.562988f, 0.577637f,
+ 0.590820f, 0.603516f, 0.618164f, 0.632324f, 0.645508f, 0.660645f, 0.811035f, 0.800293f, 0.788086f, 0.777832f, 0.768555f, 0.760254f,
+ 0.003868f, 0.011368f, 0.019257f, 0.027512f, 0.035431f, 0.043274f, 0.051880f, 0.060852f, 0.069214f, 0.078003f, 0.087524f, 0.096924f,
+ 0.105896f, 0.115112f, 0.124817f, 0.134766f, 0.144409f, 0.154663f, 0.164673f, 0.175415f, 0.184814f, 0.196289f, 0.206299f, 0.216797f,
+ 0.228394f, 0.239380f, 0.250244f, 0.260986f, 0.273193f, 0.284424f, 0.295410f, 0.307373f, 0.319092f, 0.331299f, 0.342285f, 0.354248f,
+ 0.366455f, 0.378662f, 0.390869f, 0.403809f, 0.415771f, 0.427734f, 0.440430f, 0.453369f, 0.466309f, 0.479736f, 0.492188f, 0.504883f,
+ 0.518066f, 0.531250f, 0.544922f, 0.558105f, 0.571777f, 0.584473f, 0.598633f, 0.612305f, 0.626465f, 0.641602f, 0.801758f, 0.792480f,
+ 0.781738f, 0.770508f, 0.761230f, 0.753906f, 0.003616f, 0.010872f, 0.018387f, 0.026077f, 0.033875f, 0.041351f, 0.049591f, 0.057434f,
+ 0.065674f, 0.073669f, 0.082153f, 0.091064f, 0.100098f, 0.109009f, 0.117981f, 0.127563f, 0.137207f, 0.146362f, 0.156494f, 0.165894f,
+ 0.176025f, 0.186157f, 0.196655f, 0.206421f, 0.216919f, 0.227539f, 0.237915f, 0.249268f, 0.260254f, 0.270752f, 0.282471f, 0.293945f,
+ 0.305176f, 0.316406f, 0.328125f, 0.338867f, 0.350342f, 0.361816f, 0.375244f, 0.387207f, 0.398926f, 0.411133f, 0.423584f, 0.436523f,
+ 0.448730f, 0.461182f, 0.474121f, 0.485840f, 0.499756f, 0.513672f, 0.525391f, 0.539062f, 0.552734f, 0.565918f, 0.580566f, 0.593750f,
+ 0.608398f, 0.621094f, 0.790527f, 0.783691f, 0.773926f, 0.764160f, 0.755859f, 0.747559f, 0.003450f, 0.010429f, 0.017487f, 0.024445f,
+ 0.031860f, 0.039581f, 0.046631f, 0.054718f, 0.061951f, 0.070251f, 0.078003f, 0.086121f, 0.094910f, 0.102905f, 0.111572f, 0.120300f,
+ 0.129761f, 0.138428f, 0.147217f, 0.156982f, 0.166992f, 0.176147f, 0.186157f, 0.196045f, 0.206299f, 0.216187f, 0.226318f, 0.236938f,
+ 0.247437f, 0.258301f, 0.268311f, 0.279785f, 0.290527f, 0.301758f, 0.312744f, 0.324219f, 0.335449f, 0.346680f, 0.359131f, 0.370605f,
+ 0.382812f, 0.394531f, 0.406982f, 0.419189f, 0.430908f, 0.443604f, 0.456055f, 0.468506f, 0.481445f, 0.494873f, 0.506836f, 0.520996f,
+ 0.534180f, 0.547363f, 0.561035f, 0.573730f, 0.588379f, 0.601074f, 0.780762f, 0.775879f, 0.766602f, 0.757324f, 0.748535f, 0.741699f,
+ 0.003281f, 0.009811f, 0.016174f, 0.023438f, 0.030060f, 0.037109f, 0.044464f, 0.051239f, 0.058441f, 0.066345f, 0.073792f, 0.081238f,
+ 0.089539f, 0.097229f, 0.105286f, 0.113647f, 0.122498f, 0.130615f, 0.139526f, 0.148438f, 0.157837f, 0.166626f, 0.176636f, 0.185547f,
+ 0.195312f, 0.204956f, 0.215088f, 0.224976f, 0.234863f, 0.245239f, 0.255859f, 0.266113f, 0.276367f, 0.287354f, 0.298096f, 0.309326f,
+ 0.320801f, 0.331787f, 0.343018f, 0.355225f, 0.366211f, 0.378418f, 0.389893f, 0.401611f, 0.413574f, 0.425781f, 0.438721f, 0.451416f,
+ 0.463135f, 0.476074f, 0.489014f, 0.501465f, 0.514648f, 0.528809f, 0.541992f, 0.554688f, 0.568848f, 0.582520f, 0.770508f, 0.767090f,
+ 0.758789f, 0.750488f, 0.743164f, 0.735352f, 0.002901f, 0.009422f, 0.015488f, 0.021729f, 0.028290f, 0.035278f, 0.041321f, 0.048523f,
+ 0.055420f, 0.062195f, 0.069336f, 0.076477f, 0.084412f, 0.091858f, 0.099609f, 0.107361f, 0.115112f, 0.123535f, 0.131592f, 0.140137f,
+ 0.148438f, 0.157715f, 0.166382f, 0.174927f, 0.184692f, 0.193970f, 0.203369f, 0.212646f, 0.222656f, 0.232910f, 0.242920f, 0.252197f,
+ 0.263184f, 0.273438f, 0.284180f, 0.294922f, 0.305664f, 0.316895f, 0.327881f, 0.338867f, 0.349854f, 0.361328f, 0.373291f, 0.385254f,
+ 0.397461f, 0.408691f, 0.420898f, 0.433350f, 0.445801f, 0.458252f, 0.470703f, 0.483154f, 0.496826f, 0.510254f, 0.522461f, 0.535645f,
+ 0.549805f, 0.562988f, 0.760742f, 0.758789f, 0.750488f, 0.743652f, 0.736328f, 0.729492f, 0.002861f, 0.008606f, 0.014488f, 0.021057f,
+ 0.026810f, 0.032898f, 0.038879f, 0.045532f, 0.051666f, 0.058319f, 0.065125f, 0.072449f, 0.079224f, 0.086426f, 0.093689f, 0.100830f,
+ 0.108276f, 0.116089f, 0.123962f, 0.131958f, 0.140625f, 0.148560f, 0.156494f, 0.164795f, 0.174194f, 0.183228f, 0.192017f, 0.201294f,
+ 0.210815f, 0.220093f, 0.229858f, 0.239746f, 0.249390f, 0.260010f, 0.270508f, 0.280518f, 0.290771f, 0.301758f, 0.312744f, 0.323486f,
+ 0.334473f, 0.345215f, 0.356934f, 0.368408f, 0.379883f, 0.391846f, 0.403564f, 0.416016f, 0.427490f, 0.439453f, 0.452881f, 0.465332f,
+ 0.478271f, 0.490234f, 0.503906f, 0.517090f, 0.529785f, 0.543945f, 0.750000f, 0.750000f, 0.743164f, 0.736328f, 0.729492f, 0.723145f,
+ 0.002977f, 0.008492f, 0.013931f, 0.019745f, 0.024948f, 0.030991f, 0.036804f, 0.042755f, 0.048889f, 0.055267f, 0.061737f, 0.067932f,
+ 0.074829f, 0.081116f, 0.087646f, 0.095215f, 0.102356f, 0.109436f, 0.116760f, 0.124023f, 0.131714f, 0.139648f, 0.147461f, 0.155762f,
+ 0.164185f, 0.172485f, 0.181152f, 0.189697f, 0.198730f, 0.208130f, 0.217285f, 0.226685f, 0.236572f, 0.245850f, 0.255859f, 0.265869f,
+ 0.276367f, 0.286377f, 0.297607f, 0.307861f, 0.318359f, 0.329102f, 0.340576f, 0.351807f, 0.363281f, 0.374023f, 0.386230f, 0.397949f,
+ 0.409668f, 0.422119f, 0.434082f, 0.446777f, 0.459229f, 0.471924f, 0.484863f, 0.497803f, 0.511230f, 0.525391f, 0.739746f, 0.741211f,
+ 0.735352f, 0.729004f, 0.722656f, 0.717285f, 0.002441f, 0.007896f, 0.013443f, 0.018402f, 0.023911f, 0.029343f, 0.034454f, 0.040375f,
+ 0.045868f, 0.051453f, 0.057800f, 0.063721f, 0.070068f, 0.075928f, 0.082520f, 0.089233f, 0.095703f, 0.102478f, 0.109314f, 0.116638f,
+ 0.123596f, 0.131348f, 0.138550f, 0.145996f, 0.153809f, 0.162109f, 0.170044f, 0.179199f, 0.187866f, 0.196045f, 0.205078f, 0.213745f,
+ 0.223389f, 0.233032f, 0.242554f, 0.252197f, 0.261963f, 0.271973f, 0.281982f, 0.292236f, 0.303223f, 0.312988f, 0.324463f, 0.335693f,
+ 0.346191f, 0.357910f, 0.368652f, 0.380371f, 0.391846f, 0.404541f, 0.415527f, 0.428467f, 0.440674f, 0.453369f, 0.466553f, 0.479248f,
+ 0.491455f, 0.505371f, 0.729492f, 0.732422f, 0.727539f, 0.721191f, 0.716309f, 0.709961f, 0.002457f, 0.007553f, 0.012489f, 0.017548f,
+ 0.022217f, 0.027405f, 0.032471f, 0.037689f, 0.043060f, 0.048553f, 0.054230f, 0.059631f, 0.065369f, 0.071533f, 0.077393f, 0.083069f,
+ 0.089417f, 0.096069f, 0.102356f, 0.108398f, 0.115417f, 0.122925f, 0.130127f, 0.137451f, 0.144531f, 0.152100f, 0.160156f, 0.168091f,
+ 0.176514f, 0.184570f, 0.192871f, 0.201660f, 0.210571f, 0.219238f, 0.229126f, 0.238281f, 0.248413f, 0.257812f, 0.267578f, 0.277588f,
+ 0.287354f, 0.298096f, 0.308594f, 0.319336f, 0.329590f, 0.340820f, 0.351318f, 0.363770f, 0.375732f, 0.386963f, 0.397949f, 0.409912f,
+ 0.422363f, 0.434326f, 0.446533f, 0.459473f, 0.473145f, 0.486084f, 0.718750f, 0.723633f, 0.719727f, 0.713867f, 0.708984f, 0.703613f,
+ 0.002436f, 0.006939f, 0.011612f, 0.016113f, 0.021072f, 0.025497f, 0.030640f, 0.035339f, 0.040222f, 0.045441f, 0.050690f, 0.055725f,
+ 0.060669f, 0.066589f, 0.072144f, 0.077881f, 0.083740f, 0.089294f, 0.095215f, 0.101501f, 0.108032f, 0.114868f, 0.121643f, 0.128052f,
+ 0.135010f, 0.142334f, 0.150024f, 0.157349f, 0.164917f, 0.173340f, 0.181274f, 0.189697f, 0.198120f, 0.206909f, 0.215698f, 0.224365f,
+ 0.234497f, 0.243652f, 0.252930f, 0.262695f, 0.272461f, 0.282471f, 0.292480f, 0.302979f, 0.313721f, 0.324463f, 0.335205f, 0.346436f,
+ 0.357666f, 0.369141f, 0.380859f, 0.391602f, 0.404541f, 0.416016f, 0.428467f, 0.440918f, 0.454102f, 0.466553f, 0.708496f, 0.715820f,
+ 0.711426f, 0.706055f, 0.701660f, 0.696777f, 0.002188f, 0.006599f, 0.011032f, 0.015068f, 0.019897f, 0.024048f, 0.028656f, 0.033264f,
+ 0.037720f, 0.042236f, 0.047028f, 0.051941f, 0.056824f, 0.062012f, 0.067444f, 0.072449f, 0.077942f, 0.083374f, 0.088867f, 0.094727f,
+ 0.100769f, 0.106750f, 0.112732f, 0.119263f, 0.126099f, 0.133179f, 0.139648f, 0.146729f, 0.154175f, 0.161987f, 0.170044f, 0.177612f,
+ 0.185791f, 0.194214f, 0.203125f, 0.211670f, 0.220581f, 0.229370f, 0.238770f, 0.248047f, 0.257812f, 0.267822f, 0.277344f, 0.287109f,
+ 0.297363f, 0.307861f, 0.318848f, 0.329590f, 0.341064f, 0.351562f, 0.363037f, 0.374512f, 0.385498f, 0.397461f, 0.409668f, 0.422363f,
+ 0.434326f, 0.447021f, 0.697266f, 0.706543f, 0.703125f, 0.698730f, 0.694336f, 0.689941f, 0.002024f, 0.006165f, 0.010399f, 0.014481f,
+ 0.018555f, 0.022797f, 0.026627f, 0.030869f, 0.035187f, 0.039459f, 0.043732f, 0.047943f, 0.052917f, 0.057434f, 0.062622f, 0.067261f,
+ 0.071838f, 0.077454f, 0.082581f, 0.087891f, 0.093628f, 0.099182f, 0.105469f, 0.111206f, 0.117126f, 0.123779f, 0.130371f, 0.137085f,
+ 0.143921f, 0.151001f, 0.158691f, 0.166016f, 0.173950f, 0.181641f, 0.190063f, 0.198120f, 0.206909f, 0.215698f, 0.224976f, 0.233398f,
+ 0.242798f, 0.252197f, 0.262207f, 0.271973f, 0.281738f, 0.291992f, 0.302734f, 0.313477f, 0.323242f, 0.334229f, 0.345459f, 0.355957f,
+ 0.368652f, 0.380615f, 0.391602f, 0.403809f, 0.415771f, 0.428467f, 0.686523f, 0.696777f, 0.695312f, 0.691895f, 0.687500f, 0.683105f,
+ 0.001931f, 0.005970f, 0.009651f, 0.013557f, 0.017136f, 0.021088f, 0.024902f, 0.028748f, 0.032623f, 0.036743f, 0.040833f, 0.044983f,
+ 0.049591f, 0.053467f, 0.057800f, 0.062500f, 0.066833f, 0.071533f, 0.076538f, 0.081238f, 0.086670f, 0.092224f, 0.097290f, 0.103088f,
+ 0.108887f, 0.114990f, 0.120972f, 0.127197f, 0.134277f, 0.140503f, 0.147705f, 0.154663f, 0.162231f, 0.169922f, 0.177612f, 0.185303f,
+ 0.193604f, 0.201904f, 0.210815f, 0.219238f, 0.228516f, 0.237427f, 0.247070f, 0.256592f, 0.265869f, 0.275879f, 0.285645f, 0.295898f,
+ 0.306396f, 0.317139f, 0.328369f, 0.338623f, 0.350342f, 0.362305f, 0.374023f, 0.385010f, 0.397461f, 0.410156f, 0.675781f, 0.687988f,
+ 0.687012f, 0.683594f, 0.680664f, 0.676270f, 0.001725f, 0.005436f, 0.009171f, 0.012589f, 0.016190f, 0.019485f, 0.023132f, 0.026978f,
+ 0.030899f, 0.034180f, 0.037659f, 0.041565f, 0.045074f, 0.049438f, 0.053345f, 0.057739f, 0.061768f, 0.065918f, 0.070679f, 0.075073f,
+ 0.080078f, 0.084656f, 0.089966f, 0.095215f, 0.100464f, 0.106445f, 0.112000f, 0.117615f, 0.124207f, 0.130737f, 0.136719f, 0.144043f,
+ 0.151123f, 0.158081f, 0.165405f, 0.173096f, 0.181152f, 0.189087f, 0.197510f, 0.205688f, 0.214600f, 0.223145f, 0.232178f, 0.241699f,
+ 0.250732f, 0.260254f, 0.270264f, 0.279785f, 0.289795f, 0.300293f, 0.310791f, 0.322510f, 0.333496f, 0.344238f, 0.355713f, 0.367188f,
+ 0.379395f, 0.392090f, 0.664551f, 0.678711f, 0.678223f, 0.675781f, 0.672852f, 0.669922f, 0.001741f, 0.005077f, 0.008522f, 0.011810f,
+ 0.014946f, 0.018524f, 0.021332f, 0.024872f, 0.028519f, 0.031799f, 0.034973f, 0.038727f, 0.041992f, 0.045654f, 0.049072f, 0.052856f,
+ 0.056671f, 0.060638f, 0.064819f, 0.069092f, 0.073425f, 0.078125f, 0.082886f, 0.087280f, 0.092651f, 0.098206f, 0.103638f, 0.109192f,
+ 0.114563f, 0.120667f, 0.126709f, 0.133057f, 0.139771f, 0.146851f, 0.153931f, 0.160767f, 0.168457f, 0.175903f, 0.183838f, 0.192505f,
+ 0.200195f, 0.208618f, 0.217407f, 0.226562f, 0.236084f, 0.245239f, 0.254639f, 0.263672f, 0.273926f, 0.283447f, 0.294189f, 0.304932f,
+ 0.315674f, 0.326172f, 0.337402f, 0.348877f, 0.360107f, 0.373291f, 0.653809f, 0.670410f, 0.669922f, 0.667480f, 0.665527f, 0.662109f,
+ 0.001639f, 0.004951f, 0.007996f, 0.010857f, 0.013779f, 0.016968f, 0.019974f, 0.023392f, 0.026001f, 0.029373f, 0.032013f, 0.035370f,
+ 0.038513f, 0.041992f, 0.044586f, 0.048706f, 0.052124f, 0.055634f, 0.059723f, 0.063354f, 0.067444f, 0.071289f, 0.075745f, 0.080444f,
+ 0.085022f, 0.089722f, 0.095032f, 0.100220f, 0.105347f, 0.111206f, 0.117126f, 0.123108f, 0.129395f, 0.135620f, 0.142090f, 0.148682f,
+ 0.156372f, 0.163574f, 0.170898f, 0.178711f, 0.186890f, 0.194580f, 0.203613f, 0.211426f, 0.220459f, 0.229492f, 0.238281f, 0.248169f,
+ 0.257324f, 0.267578f, 0.277832f, 0.287354f, 0.298340f, 0.308350f, 0.319824f, 0.331543f, 0.342041f, 0.354248f, 0.641602f, 0.660645f,
+ 0.662109f, 0.660645f, 0.658203f, 0.654785f, 0.001569f, 0.004539f, 0.007538f, 0.010368f, 0.013359f, 0.016006f, 0.018539f, 0.021210f,
+ 0.024384f, 0.026855f, 0.029892f, 0.032471f, 0.035034f, 0.038177f, 0.041199f, 0.044434f, 0.047485f, 0.050781f, 0.054321f, 0.057953f,
+ 0.061523f, 0.065430f, 0.069275f, 0.073547f, 0.077820f, 0.082092f, 0.086731f, 0.091736f, 0.096985f, 0.101990f, 0.107361f, 0.112549f,
+ 0.118774f, 0.124878f, 0.131104f, 0.137573f, 0.144409f, 0.150635f, 0.157837f, 0.165283f, 0.173340f, 0.181274f, 0.188599f, 0.197510f,
+ 0.205933f, 0.214600f, 0.223633f, 0.232056f, 0.241577f, 0.251709f, 0.261230f, 0.270996f, 0.281250f, 0.291260f, 0.302246f, 0.313477f,
+ 0.323730f, 0.336182f, 0.630859f, 0.651855f, 0.652832f, 0.652344f, 0.650391f, 0.647461f, 0.001558f, 0.004139f, 0.007103f, 0.009560f,
+ 0.012077f, 0.014313f, 0.016983f, 0.019653f, 0.021988f, 0.024490f, 0.027023f, 0.029526f, 0.031891f, 0.034821f, 0.037903f, 0.040192f,
+ 0.043457f, 0.046417f, 0.049316f, 0.052795f, 0.055725f, 0.059357f, 0.063354f, 0.066895f, 0.070740f, 0.074890f, 0.078979f, 0.083801f,
+ 0.088440f, 0.093018f, 0.097961f, 0.103394f, 0.108704f, 0.114563f, 0.120239f, 0.126343f, 0.132690f, 0.139038f, 0.145874f, 0.152710f,
+ 0.159912f, 0.168091f, 0.175537f, 0.183228f, 0.191650f, 0.199707f, 0.208130f, 0.216797f, 0.226074f, 0.235352f, 0.244507f, 0.254395f,
+ 0.264404f, 0.274414f, 0.285156f, 0.296631f, 0.307373f, 0.318604f, 0.619141f, 0.643066f, 0.644531f, 0.644043f, 0.642578f, 0.639648f,
+ 0.001314f, 0.004002f, 0.006603f, 0.009056f, 0.011490f, 0.013184f, 0.015587f, 0.017883f, 0.020157f, 0.022415f, 0.024582f, 0.027206f,
+ 0.029160f, 0.031677f, 0.034088f, 0.036530f, 0.039337f, 0.042206f, 0.044891f, 0.047729f, 0.050751f, 0.053955f, 0.057312f, 0.060486f,
+ 0.064148f, 0.068054f, 0.071960f, 0.075867f, 0.079895f, 0.084595f, 0.089172f, 0.094238f, 0.098999f, 0.104492f, 0.109802f, 0.115173f,
+ 0.121338f, 0.127686f, 0.134033f, 0.140991f, 0.147095f, 0.154541f, 0.161865f, 0.169800f, 0.177368f, 0.185547f, 0.193848f, 0.201904f,
+ 0.211060f, 0.219116f, 0.229004f, 0.238525f, 0.248047f, 0.257812f, 0.267822f, 0.277832f, 0.289062f, 0.300537f, 0.607910f, 0.633301f,
+ 0.636230f, 0.635742f, 0.634766f, 0.633301f, 0.001217f, 0.003571f, 0.005947f, 0.008011f, 0.010391f, 0.012207f, 0.014313f, 0.016617f,
+ 0.018280f, 0.020523f, 0.022537f, 0.024475f, 0.026443f, 0.028778f, 0.030884f, 0.032867f, 0.035553f, 0.037872f, 0.040375f, 0.042938f,
+ 0.045593f, 0.048431f, 0.051605f, 0.054688f, 0.057953f, 0.061279f, 0.065002f, 0.068665f, 0.072266f, 0.076294f, 0.080872f, 0.085083f,
+ 0.089783f, 0.094482f, 0.099915f, 0.104736f, 0.110901f, 0.116272f, 0.122314f, 0.128784f, 0.134888f, 0.142090f, 0.148560f, 0.155884f,
+ 0.163574f, 0.171753f, 0.179077f, 0.187500f, 0.195679f, 0.204346f, 0.213745f, 0.222656f, 0.231812f, 0.241455f, 0.250977f, 0.261230f,
+ 0.272461f, 0.282959f, 0.596680f, 0.623535f, 0.627441f, 0.627930f, 0.627441f, 0.625000f, 0.001111f, 0.003542f, 0.005569f, 0.007504f,
+ 0.009338f, 0.011452f, 0.012939f, 0.015030f, 0.016678f, 0.018326f, 0.020203f, 0.022217f, 0.023788f, 0.025604f, 0.027771f, 0.029877f,
+ 0.031860f, 0.033813f, 0.036102f, 0.038605f, 0.040985f, 0.043579f, 0.046448f, 0.049042f, 0.051849f, 0.055054f, 0.058319f, 0.061615f,
+ 0.065125f, 0.068909f, 0.072815f, 0.076843f, 0.080872f, 0.085571f, 0.089905f, 0.095398f, 0.100159f, 0.105713f, 0.111206f, 0.116882f,
+ 0.122925f, 0.129517f, 0.135742f, 0.142822f, 0.149902f, 0.157349f, 0.165161f, 0.172852f, 0.181152f, 0.189331f, 0.198120f, 0.206909f,
+ 0.215820f, 0.225342f, 0.235474f, 0.245239f, 0.254883f, 0.266602f, 0.584473f, 0.614746f, 0.619141f, 0.619629f, 0.619141f, 0.618164f,
+ 0.001149f, 0.003147f, 0.004826f, 0.006886f, 0.008629f, 0.010452f, 0.012024f, 0.013359f, 0.015175f, 0.016647f, 0.018143f, 0.019882f,
+ 0.021332f, 0.023026f, 0.024902f, 0.026550f, 0.028397f, 0.030045f, 0.032318f, 0.034393f, 0.036682f, 0.038910f, 0.041107f, 0.043671f,
+ 0.046295f, 0.048950f, 0.051819f, 0.054993f, 0.058258f, 0.061523f, 0.065063f, 0.068481f, 0.072510f, 0.076965f, 0.081055f, 0.085510f,
+ 0.090393f, 0.095093f, 0.100342f, 0.105774f, 0.111694f, 0.117371f, 0.124084f, 0.130371f, 0.136963f, 0.143921f, 0.151245f, 0.159058f,
+ 0.166626f, 0.174927f, 0.182983f, 0.191650f, 0.200195f, 0.209473f, 0.218750f, 0.228149f, 0.238037f, 0.249146f, 0.572266f, 0.604980f,
+ 0.609863f, 0.611328f, 0.610352f, 0.611328f, 0.001009f, 0.003059f, 0.004620f, 0.006283f, 0.007881f, 0.009415f, 0.010864f, 0.011940f,
+ 0.013443f, 0.014847f, 0.016403f, 0.017700f, 0.019012f, 0.020493f, 0.021927f, 0.023697f, 0.025177f, 0.026947f, 0.028732f, 0.030472f,
+ 0.032654f, 0.034302f, 0.036591f, 0.038757f, 0.041046f, 0.043488f, 0.045837f, 0.048706f, 0.051544f, 0.054810f, 0.057770f, 0.061188f,
+ 0.064331f, 0.068237f, 0.072083f, 0.076416f, 0.080872f, 0.085388f, 0.090149f, 0.095276f, 0.100403f, 0.105896f, 0.111877f, 0.117798f,
+ 0.124329f, 0.130859f, 0.138062f, 0.145020f, 0.152710f, 0.160034f, 0.168335f, 0.176514f, 0.185059f, 0.193481f, 0.203125f, 0.212158f,
+ 0.221924f, 0.232178f, 0.562500f, 0.594727f, 0.601074f, 0.602539f, 0.603516f, 0.602539f, 0.000865f, 0.002674f, 0.004444f, 0.005615f,
+ 0.007233f, 0.008430f, 0.009827f, 0.010880f, 0.011917f, 0.013206f, 0.014412f, 0.015717f, 0.016876f, 0.018173f, 0.019501f, 0.020950f,
+ 0.022217f, 0.023773f, 0.025284f, 0.026749f, 0.028610f, 0.030151f, 0.032166f, 0.034149f, 0.036041f, 0.038330f, 0.040558f, 0.042877f,
+ 0.045532f, 0.048157f, 0.050934f, 0.053894f, 0.056946f, 0.060303f, 0.063843f, 0.067566f, 0.071472f, 0.075806f, 0.080261f, 0.084778f,
+ 0.089600f, 0.094971f, 0.100220f, 0.105896f, 0.111877f, 0.118103f, 0.125000f, 0.131348f, 0.138550f, 0.146362f, 0.153687f, 0.161987f,
+ 0.169678f, 0.178223f, 0.187134f, 0.196045f, 0.205811f, 0.215698f, 0.549805f, 0.584961f, 0.592773f, 0.594238f, 0.593750f, 0.595215f,
+ 0.000951f, 0.002476f, 0.003956f, 0.005062f, 0.006268f, 0.007637f, 0.008888f, 0.009666f, 0.010628f, 0.011810f, 0.012856f, 0.013878f,
+ 0.014946f, 0.015900f, 0.017227f, 0.018356f, 0.019592f, 0.020889f, 0.022003f, 0.023438f, 0.025101f, 0.026489f, 0.028122f, 0.029739f,
+ 0.031555f, 0.033295f, 0.035431f, 0.037537f, 0.039795f, 0.041962f, 0.044647f, 0.047302f, 0.049957f, 0.052979f, 0.056122f, 0.059387f,
+ 0.062927f, 0.066956f, 0.070679f, 0.074951f, 0.079468f, 0.084167f, 0.089294f, 0.094482f, 0.100098f, 0.106018f, 0.112061f, 0.118835f,
+ 0.125366f, 0.132446f, 0.139893f, 0.147827f, 0.155762f, 0.163574f, 0.172607f, 0.180786f, 0.190063f, 0.199951f, 0.536621f, 0.576172f,
+ 0.583496f, 0.586914f, 0.587402f, 0.586914f, 0.000788f, 0.002115f, 0.003592f, 0.004780f, 0.005939f, 0.006615f, 0.007740f, 0.008598f,
+ 0.009514f, 0.010376f, 0.011200f, 0.012138f, 0.013016f, 0.014069f, 0.014977f, 0.015961f, 0.016922f, 0.018036f, 0.019043f, 0.020447f,
+ 0.021606f, 0.022995f, 0.024323f, 0.025864f, 0.027344f, 0.028946f, 0.030731f, 0.032593f, 0.034515f, 0.036530f, 0.038910f, 0.041016f,
+ 0.043274f, 0.046021f, 0.048981f, 0.051819f, 0.055176f, 0.058472f, 0.062012f, 0.065857f, 0.069946f, 0.074219f, 0.078796f, 0.083801f,
+ 0.088806f, 0.094299f, 0.100281f, 0.106018f, 0.112793f, 0.119446f, 0.126343f, 0.133545f, 0.141357f, 0.149292f, 0.157104f, 0.165894f,
+ 0.174683f, 0.184326f, 0.524902f, 0.566895f, 0.575195f, 0.576660f, 0.579102f, 0.579590f, 0.000661f, 0.001961f, 0.003382f, 0.004311f,
+ 0.005161f, 0.006062f, 0.006737f, 0.007427f, 0.008286f, 0.008995f, 0.009857f, 0.010368f, 0.011230f, 0.011955f, 0.012833f, 0.013786f,
+ 0.014565f, 0.015480f, 0.016647f, 0.017578f, 0.018677f, 0.019806f, 0.020950f, 0.022263f, 0.023651f, 0.024994f, 0.026306f, 0.027863f,
+ 0.029724f, 0.031525f, 0.033325f, 0.035370f, 0.037292f, 0.039673f, 0.042114f, 0.044769f, 0.047546f, 0.050537f, 0.053680f, 0.057098f,
+ 0.060852f, 0.064514f, 0.069031f, 0.073303f, 0.078064f, 0.083069f, 0.088379f, 0.094238f, 0.100220f, 0.106689f, 0.113342f, 0.120300f,
+ 0.127563f, 0.135132f, 0.142700f, 0.151245f, 0.160034f, 0.168823f, 0.512695f, 0.557129f, 0.566406f, 0.569824f, 0.569824f, 0.571289f,
+ 0.000757f, 0.001709f, 0.002844f, 0.003582f, 0.004448f, 0.005192f, 0.005989f, 0.006519f, 0.007038f, 0.007801f, 0.008453f, 0.009071f,
+ 0.009727f, 0.010391f, 0.011009f, 0.011726f, 0.012650f, 0.013184f, 0.014107f, 0.014977f, 0.015900f, 0.016800f, 0.017776f, 0.018936f,
+ 0.020172f, 0.021271f, 0.022446f, 0.023697f, 0.025055f, 0.026703f, 0.028397f, 0.030014f, 0.031921f, 0.033905f, 0.035919f, 0.038177f,
+ 0.040680f, 0.043243f, 0.045898f, 0.049072f, 0.052216f, 0.055725f, 0.059784f, 0.063538f, 0.067688f, 0.072327f, 0.077271f, 0.082764f,
+ 0.088379f, 0.094299f, 0.100708f, 0.107239f, 0.114136f, 0.121582f, 0.128906f, 0.136963f, 0.145630f, 0.153564f, 0.500977f, 0.547852f,
+ 0.556641f, 0.561523f, 0.562500f, 0.563965f, 0.000704f, 0.001769f, 0.002542f, 0.003523f, 0.004036f, 0.004562f, 0.005032f, 0.005661f,
+ 0.006176f, 0.006542f, 0.007072f, 0.007698f, 0.008339f, 0.008827f, 0.009323f, 0.010094f, 0.010757f, 0.011276f, 0.012093f, 0.012733f,
+ 0.013489f, 0.014488f, 0.015244f, 0.016006f, 0.017151f, 0.017975f, 0.018967f, 0.020142f, 0.021255f, 0.022552f, 0.023880f, 0.025314f,
+ 0.026840f, 0.028503f, 0.030441f, 0.032166f, 0.034424f, 0.036438f, 0.039001f, 0.041656f, 0.044464f, 0.047455f, 0.050842f, 0.054443f,
+ 0.058167f, 0.062286f, 0.066956f, 0.071899f, 0.076904f, 0.082458f, 0.088501f, 0.094482f, 0.101196f, 0.108337f, 0.115662f, 0.123352f,
+ 0.130981f, 0.139282f, 0.489746f, 0.538574f, 0.547852f, 0.551270f, 0.554688f, 0.555176f, 0.000579f, 0.001450f, 0.002396f, 0.002857f,
+ 0.003454f, 0.004032f, 0.004356f, 0.004791f, 0.005333f, 0.005718f, 0.006130f, 0.006485f, 0.007042f, 0.007473f, 0.007988f, 0.008476f,
+ 0.008865f, 0.009613f, 0.010086f, 0.010651f, 0.011345f, 0.012047f, 0.012764f, 0.013435f, 0.014282f, 0.015144f, 0.015884f, 0.016846f,
+ 0.017868f, 0.018814f, 0.020050f, 0.021164f, 0.022507f, 0.023773f, 0.025192f, 0.026978f, 0.028564f, 0.030640f, 0.032623f, 0.034882f,
+ 0.037231f, 0.039886f, 0.042786f, 0.046143f, 0.049286f, 0.052979f, 0.057098f, 0.061279f, 0.066223f, 0.071167f, 0.076660f, 0.082581f,
+ 0.088989f, 0.095581f, 0.102661f, 0.109863f, 0.117737f, 0.125488f, 0.476807f, 0.528320f, 0.538574f, 0.543945f, 0.546875f, 0.546875f,
+ 0.000510f, 0.001428f, 0.002037f, 0.002613f, 0.003086f, 0.003290f, 0.003672f, 0.004108f, 0.004345f, 0.004768f, 0.005035f, 0.005470f,
+ 0.005959f, 0.006207f, 0.006599f, 0.007095f, 0.007568f, 0.008003f, 0.008377f, 0.008904f, 0.009575f, 0.010010f, 0.010643f, 0.011131f,
+ 0.011871f, 0.012535f, 0.013199f, 0.014038f, 0.014839f, 0.015640f, 0.016586f, 0.017502f, 0.018585f, 0.019745f, 0.021088f, 0.022354f,
+ 0.023727f, 0.025253f, 0.026962f, 0.028870f, 0.030762f, 0.033051f, 0.035492f, 0.038177f, 0.041229f, 0.044403f, 0.048004f, 0.051880f,
+ 0.056213f, 0.060516f, 0.065857f, 0.071045f, 0.077271f, 0.083374f, 0.090027f, 0.096863f, 0.104492f, 0.112183f, 0.463623f, 0.518066f,
+ 0.529785f, 0.535156f, 0.538086f, 0.540039f, 0.000473f, 0.001222f, 0.001771f, 0.002117f, 0.002323f, 0.002796f, 0.003096f, 0.003355f,
+ 0.003601f, 0.003975f, 0.004295f, 0.004543f, 0.004833f, 0.005142f, 0.005455f, 0.005848f, 0.006165f, 0.006535f, 0.006947f, 0.007370f,
+ 0.007809f, 0.008240f, 0.008690f, 0.009216f, 0.009758f, 0.010223f, 0.010925f, 0.011536f, 0.012146f, 0.012833f, 0.013573f, 0.014389f,
+ 0.015244f, 0.016220f, 0.017120f, 0.018219f, 0.019379f, 0.020599f, 0.021988f, 0.023514f, 0.025131f, 0.027054f, 0.029037f, 0.031311f,
+ 0.033752f, 0.036591f, 0.039520f, 0.042999f, 0.046661f, 0.050873f, 0.055603f, 0.060333f, 0.066101f, 0.071960f, 0.078491f, 0.084961f,
+ 0.091797f, 0.099426f, 0.452148f, 0.508301f, 0.520508f, 0.526367f, 0.528809f, 0.530273f, 0.000299f, 0.001057f, 0.001329f, 0.001771f,
+ 0.001957f, 0.002350f, 0.002483f, 0.002697f, 0.002964f, 0.003181f, 0.003441f, 0.003653f, 0.003904f, 0.004238f, 0.004501f, 0.004738f,
+ 0.005024f, 0.005390f, 0.005657f, 0.005985f, 0.006279f, 0.006714f, 0.007053f, 0.007507f, 0.007881f, 0.008369f, 0.008774f, 0.009300f,
+ 0.009888f, 0.010483f, 0.011093f, 0.011627f, 0.012398f, 0.013130f, 0.013855f, 0.014717f, 0.015686f, 0.016739f, 0.017761f, 0.018890f,
+ 0.020248f, 0.021698f, 0.023376f, 0.025131f, 0.027237f, 0.029556f, 0.032166f, 0.035004f, 0.038208f, 0.041962f, 0.045868f, 0.050507f,
+ 0.055359f, 0.060852f, 0.066772f, 0.073242f, 0.080017f, 0.087097f, 0.440674f, 0.498047f, 0.511719f, 0.517090f, 0.520508f, 0.522949f,
+ 0.000427f, 0.001020f, 0.001253f, 0.001431f, 0.001690f, 0.001900f, 0.002018f, 0.002304f, 0.002481f, 0.002569f, 0.002731f, 0.002998f,
+ 0.003157f, 0.003424f, 0.003592f, 0.003838f, 0.004017f, 0.004253f, 0.004551f, 0.004776f, 0.005100f, 0.005379f, 0.005699f, 0.005932f,
+ 0.006290f, 0.006630f, 0.007038f, 0.007465f, 0.007927f, 0.008286f, 0.008858f, 0.009293f, 0.009888f, 0.010429f, 0.011086f, 0.011765f,
+ 0.012482f, 0.013298f, 0.014168f, 0.015068f, 0.016129f, 0.017288f, 0.018585f, 0.019943f, 0.021622f, 0.023361f, 0.025436f, 0.027847f,
+ 0.030655f, 0.033447f, 0.037079f, 0.041229f, 0.045776f, 0.050568f, 0.056061f, 0.062317f, 0.068726f, 0.075684f, 0.427734f, 0.488525f,
+ 0.502441f, 0.508789f, 0.513184f, 0.513672f, 0.000255f, 0.000597f, 0.001032f, 0.001150f, 0.001353f, 0.001493f, 0.001608f, 0.001750f,
+ 0.001933f, 0.002062f, 0.002178f, 0.002302f, 0.002474f, 0.002670f, 0.002872f, 0.002995f, 0.003147f, 0.003298f, 0.003565f, 0.003729f,
+ 0.003941f, 0.004219f, 0.004436f, 0.004719f, 0.005005f, 0.005230f, 0.005489f, 0.005806f, 0.006191f, 0.006496f, 0.006897f, 0.007267f,
+ 0.007671f, 0.008179f, 0.008636f, 0.009163f, 0.009766f, 0.010368f, 0.011047f, 0.011810f, 0.012611f, 0.013527f, 0.014519f, 0.015640f,
+ 0.016800f, 0.018265f, 0.019897f, 0.021698f, 0.023895f, 0.026260f, 0.029175f, 0.032715f, 0.036682f, 0.041168f, 0.045929f, 0.051758f,
+ 0.057922f, 0.064575f, 0.415771f, 0.478271f, 0.493652f, 0.500000f, 0.503906f, 0.505859f, 0.000255f, 0.000544f, 0.000863f, 0.000994f,
+ 0.001086f, 0.001183f, 0.001317f, 0.001328f, 0.001491f, 0.001608f, 0.001716f, 0.001851f, 0.001943f, 0.002075f, 0.002161f, 0.002319f,
+ 0.002426f, 0.002596f, 0.002741f, 0.002884f, 0.003088f, 0.003265f, 0.003391f, 0.003620f, 0.003777f, 0.004005f, 0.004215f, 0.004452f,
+ 0.004734f, 0.004963f, 0.005341f, 0.005577f, 0.005875f, 0.006271f, 0.006603f, 0.006996f, 0.007450f, 0.007919f, 0.008446f, 0.009003f,
+ 0.009674f, 0.010338f, 0.011101f, 0.011909f, 0.012917f, 0.013977f, 0.015190f, 0.016495f, 0.018112f, 0.020325f, 0.022415f, 0.025146f,
+ 0.028473f, 0.032349f, 0.036804f, 0.041992f, 0.047913f, 0.054077f, 0.404541f, 0.468506f, 0.484131f, 0.490967f, 0.495361f, 0.498291f,
+ 0.000377f, 0.000440f, 0.000606f, 0.000685f, 0.000735f, 0.000876f, 0.000929f, 0.001035f, 0.001068f, 0.001157f, 0.001307f, 0.001381f,
+ 0.001473f, 0.001595f, 0.001664f, 0.001708f, 0.001850f, 0.001957f, 0.002043f, 0.002195f, 0.002291f, 0.002422f, 0.002571f, 0.002687f,
+ 0.002842f, 0.002979f, 0.003183f, 0.003345f, 0.003532f, 0.003794f, 0.004002f, 0.004154f, 0.004429f, 0.004635f, 0.004967f, 0.005253f,
+ 0.005573f, 0.005909f, 0.006275f, 0.006695f, 0.007183f, 0.007660f, 0.008316f, 0.008934f, 0.009644f, 0.010429f, 0.011360f, 0.012497f,
+ 0.013634f, 0.014977f, 0.016663f, 0.018875f, 0.021423f, 0.024643f, 0.028549f, 0.033020f, 0.038483f, 0.044525f, 0.391602f, 0.458984f,
+ 0.474854f, 0.482178f, 0.488037f, 0.489990f, 0.000159f, 0.000401f, 0.000450f, 0.000522f, 0.000605f, 0.000634f, 0.000728f, 0.000702f,
+ 0.000808f, 0.000882f, 0.000959f, 0.000991f, 0.001043f, 0.001112f, 0.001205f, 0.001245f, 0.001357f, 0.001419f, 0.001513f, 0.001546f,
+ 0.001648f, 0.001752f, 0.001863f, 0.001942f, 0.002056f, 0.002159f, 0.002289f, 0.002392f, 0.002506f, 0.002697f, 0.002827f, 0.003023f,
+ 0.003172f, 0.003330f, 0.003542f, 0.003750f, 0.004017f, 0.004292f, 0.004559f, 0.004871f, 0.005161f, 0.005539f, 0.005932f, 0.006416f,
+ 0.006973f, 0.007526f, 0.008232f, 0.008980f, 0.009918f, 0.010895f, 0.012085f, 0.013680f, 0.015472f, 0.017975f, 0.021103f, 0.025146f,
+ 0.029938f, 0.035645f, 0.379395f, 0.448486f, 0.465820f, 0.473633f, 0.478760f, 0.481689f, 0.000112f, 0.000220f, 0.000321f, 0.000322f,
+ 0.000401f, 0.000489f, 0.000469f, 0.000510f, 0.000568f, 0.000653f, 0.000659f, 0.000676f, 0.000703f, 0.000789f, 0.000811f, 0.000886f,
+ 0.000888f, 0.000994f, 0.001048f, 0.001096f, 0.001155f, 0.001220f, 0.001289f, 0.001357f, 0.001431f, 0.001496f, 0.001599f, 0.001675f,
+ 0.001759f, 0.001894f, 0.001965f, 0.002083f, 0.002193f, 0.002310f, 0.002464f, 0.002634f, 0.002758f, 0.002949f, 0.003134f, 0.003319f,
+ 0.003551f, 0.003830f, 0.004120f, 0.004440f, 0.004784f, 0.005188f, 0.005680f, 0.006222f, 0.006886f, 0.007614f, 0.008461f, 0.009529f,
+ 0.010864f, 0.012596f, 0.014961f, 0.018097f, 0.022263f, 0.027466f, 0.367920f, 0.438232f, 0.456543f, 0.465332f, 0.470215f, 0.472900f,
+ 0.000140f, 0.000219f, 0.000241f, 0.000245f, 0.000290f, 0.000291f, 0.000302f, 0.000342f, 0.000380f, 0.000409f, 0.000408f, 0.000485f,
+ 0.000473f, 0.000527f, 0.000556f, 0.000575f, 0.000630f, 0.000642f, 0.000673f, 0.000711f, 0.000762f, 0.000800f, 0.000852f, 0.000886f,
+ 0.000952f, 0.000982f, 0.001049f, 0.001108f, 0.001159f, 0.001220f, 0.001281f, 0.001369f, 0.001454f, 0.001522f, 0.001595f, 0.001695f,
+ 0.001839f, 0.001928f, 0.002068f, 0.002209f, 0.002337f, 0.002504f, 0.002686f, 0.002876f, 0.003139f, 0.003437f, 0.003723f, 0.004078f,
+ 0.004509f, 0.005009f, 0.005615f, 0.006332f, 0.007317f, 0.008461f, 0.009926f, 0.012154f, 0.015640f, 0.020325f, 0.356445f, 0.429199f,
+ 0.447266f, 0.456299f, 0.462158f, 0.464844f, 0.000048f, 0.000154f, 0.000141f, 0.000147f, 0.000174f, 0.000207f, 0.000188f, 0.000221f,
+ 0.000233f, 0.000242f, 0.000248f, 0.000271f, 0.000299f, 0.000312f, 0.000337f, 0.000350f, 0.000367f, 0.000403f, 0.000416f, 0.000458f,
+ 0.000465f, 0.000483f, 0.000507f, 0.000546f, 0.000576f, 0.000625f, 0.000637f, 0.000659f, 0.000705f, 0.000742f, 0.000797f, 0.000837f,
+ 0.000890f, 0.000925f, 0.000978f, 0.001036f, 0.001103f, 0.001181f, 0.001253f, 0.001329f, 0.001421f, 0.001529f, 0.001647f, 0.001782f,
+ 0.001906f, 0.002075f, 0.002291f, 0.002483f, 0.002758f, 0.003059f, 0.003450f, 0.003906f, 0.004536f, 0.005306f, 0.006325f, 0.007713f,
+ 0.010101f, 0.014084f, 0.343262f, 0.418457f, 0.437744f, 0.447510f, 0.452881f, 0.456543f, 0.000099f, 0.000100f, 0.000091f, 0.000085f,
+ 0.000105f, 0.000099f, 0.000127f, 0.000127f, 0.000130f, 0.000137f, 0.000152f, 0.000164f, 0.000164f, 0.000172f, 0.000195f, 0.000186f,
+ 0.000209f, 0.000222f, 0.000231f, 0.000241f, 0.000258f, 0.000266f, 0.000290f, 0.000301f, 0.000324f, 0.000343f, 0.000357f, 0.000369f,
+ 0.000392f, 0.000409f, 0.000440f, 0.000463f, 0.000484f, 0.000513f, 0.000544f, 0.000578f, 0.000607f, 0.000650f, 0.000702f, 0.000737f,
+ 0.000787f, 0.000846f, 0.000918f, 0.000977f, 0.001062f, 0.001146f, 0.001259f, 0.001379f, 0.001524f, 0.001701f, 0.001924f, 0.002207f,
+ 0.002542f, 0.003006f, 0.003628f, 0.004494f, 0.005821f, 0.008774f, 0.332031f, 0.409180f, 0.428467f, 0.438965f, 0.444336f, 0.447998f,
+ 0.000082f, 0.000057f, 0.000048f, 0.000051f, 0.000055f, 0.000054f, 0.000057f, 0.000064f, 0.000066f, 0.000079f, 0.000070f, 0.000070f,
+ 0.000084f, 0.000078f, 0.000084f, 0.000091f, 0.000099f, 0.000108f, 0.000108f, 0.000114f, 0.000119f, 0.000124f, 0.000129f, 0.000144f,
+ 0.000151f, 0.000158f, 0.000163f, 0.000176f, 0.000188f, 0.000196f, 0.000208f, 0.000220f, 0.000227f, 0.000239f, 0.000259f, 0.000273f,
+ 0.000290f, 0.000303f, 0.000331f, 0.000351f, 0.000376f, 0.000402f, 0.000432f, 0.000460f, 0.000500f, 0.000547f, 0.000593f, 0.000648f,
+ 0.000720f, 0.000805f, 0.000918f, 0.001045f, 0.001225f, 0.001462f, 0.001788f, 0.002264f, 0.003029f, 0.004623f, 0.320801f, 0.398682f,
+ 0.419922f, 0.430420f, 0.436279f, 0.440674f, 0.000061f, 0.000041f, 0.000033f, 0.000029f, 0.000026f, 0.000025f, 0.000024f, 0.000024f,
+ 0.000023f, 0.000023f, 0.000025f, 0.000032f, 0.000026f, 0.000027f, 0.000035f, 0.000037f, 0.000039f, 0.000041f, 0.000041f, 0.000041f,
+ 0.000044f, 0.000050f, 0.000054f, 0.000051f, 0.000055f, 0.000060f, 0.000061f, 0.000062f, 0.000069f, 0.000074f, 0.000075f, 0.000081f,
+ 0.000087f, 0.000090f, 0.000093f, 0.000098f, 0.000108f, 0.000114f, 0.000123f, 0.000130f, 0.000142f, 0.000144f, 0.000156f, 0.000173f,
+ 0.000179f, 0.000200f, 0.000218f, 0.000237f, 0.000267f, 0.000299f, 0.000335f, 0.000382f, 0.000448f, 0.000544f, 0.000677f, 0.000883f,
+ 0.001233f, 0.001933f, 0.309570f, 0.388672f, 0.410889f, 0.421143f, 0.427246f, 0.431885f, 0.000031f, 0.000020f, 0.000016f, 0.000014f,
+ 0.000013f, 0.000012f, 0.000012f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000008f, 0.000009f,
+ 0.000009f, 0.000007f, 0.000007f, 0.000007f, 0.000008f, 0.000009f, 0.000011f, 0.000012f, 0.000012f, 0.000012f, 0.000013f, 0.000015f,
+ 0.000015f, 0.000014f, 0.000016f, 0.000017f, 0.000019f, 0.000020f, 0.000020f, 0.000022f, 0.000025f, 0.000023f, 0.000026f, 0.000029f,
+ 0.000031f, 0.000034f, 0.000036f, 0.000037f, 0.000040f, 0.000044f, 0.000048f, 0.000052f, 0.000056f, 0.000063f, 0.000068f, 0.000083f,
+ 0.000098f, 0.000117f, 0.000149f, 0.000201f, 0.000301f, 0.000544f, 0.297607f, 0.379150f, 0.400879f, 0.411865f, 0.419189f, 0.423340f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f,
+ 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000002f, 0.000003f, 0.000004f, 0.000004f, 0.000004f, 0.000005f, 0.000007f, 0.000011f, 0.000026f, 0.286621f, 0.368896f,
+ 0.391846f, 0.402588f, 0.409912f, 0.414551f,
+ },
+ {
+ 0.007935f, 0.024429f, 0.041290f, 0.058838f, 0.076355f, 0.093933f, 0.111145f, 0.128174f, 0.146606f, 0.164429f, 0.182617f, 0.200562f,
+ 0.218750f, 0.236206f, 0.254150f, 0.271729f, 0.289551f, 0.308105f, 0.325684f, 0.342773f, 0.360596f, 0.379150f, 0.396240f, 0.414795f,
+ 0.431641f, 0.450439f, 0.468018f, 0.484619f, 0.502441f, 0.520020f, 0.536621f, 0.554688f, 0.571777f, 0.588379f, 0.605469f, 0.622559f,
+ 0.640137f, 0.657227f, 0.672852f, 0.689941f, 0.707031f, 0.723633f, 0.740234f, 0.756836f, 0.773926f, 0.789551f, 0.805664f, 0.821777f,
+ 0.838379f, 0.854980f, 0.870117f, 0.885742f, 0.901855f, 0.917480f, 0.932617f, 0.948730f, 0.963379f, 0.979492f, 0.960449f, 0.909668f,
+ 0.876465f, 0.850098f, 0.827637f, 0.807617f, 0.007530f, 0.023422f, 0.039764f, 0.056610f, 0.073303f, 0.090149f, 0.107300f, 0.124084f,
+ 0.141968f, 0.158569f, 0.176392f, 0.193604f, 0.210815f, 0.228760f, 0.246094f, 0.262695f, 0.280518f, 0.298340f, 0.315430f, 0.333252f,
+ 0.350586f, 0.367432f, 0.384766f, 0.402344f, 0.419678f, 0.436768f, 0.453613f, 0.471436f, 0.488037f, 0.504883f, 0.521973f, 0.538574f,
+ 0.556641f, 0.573242f, 0.589844f, 0.605957f, 0.623535f, 0.639160f, 0.656250f, 0.673340f, 0.688477f, 0.706055f, 0.721680f, 0.738770f,
+ 0.754883f, 0.770508f, 0.786133f, 0.803711f, 0.817871f, 0.834473f, 0.850586f, 0.866211f, 0.881348f, 0.896973f, 0.913086f, 0.928223f,
+ 0.942871f, 0.958984f, 0.951172f, 0.903320f, 0.871094f, 0.845703f, 0.824219f, 0.805664f, 0.007320f, 0.022552f, 0.038391f, 0.054260f,
+ 0.070312f, 0.086792f, 0.103271f, 0.120178f, 0.136841f, 0.153564f, 0.170410f, 0.187256f, 0.203735f, 0.220825f, 0.237793f, 0.255127f,
+ 0.271240f, 0.288086f, 0.305420f, 0.322021f, 0.339844f, 0.356689f, 0.373047f, 0.390137f, 0.406738f, 0.423340f, 0.440186f, 0.456787f,
+ 0.474121f, 0.490967f, 0.507324f, 0.523926f, 0.540527f, 0.557129f, 0.573242f, 0.590332f, 0.606445f, 0.623047f, 0.638672f, 0.655273f,
+ 0.671875f, 0.687500f, 0.703613f, 0.720215f, 0.735840f, 0.751953f, 0.767578f, 0.783203f, 0.799316f, 0.814941f, 0.830078f, 0.845703f,
+ 0.861328f, 0.877441f, 0.892090f, 0.908203f, 0.922852f, 0.938477f, 0.941895f, 0.895996f, 0.865723f, 0.841309f, 0.820801f, 0.802734f,
+ 0.007008f, 0.021667f, 0.036865f, 0.052216f, 0.067871f, 0.083862f, 0.099426f, 0.115479f, 0.131470f, 0.148315f, 0.164551f, 0.180298f,
+ 0.196899f, 0.213379f, 0.229370f, 0.246460f, 0.262695f, 0.279541f, 0.295410f, 0.311523f, 0.329102f, 0.345215f, 0.360840f, 0.378174f,
+ 0.394043f, 0.410156f, 0.427246f, 0.443115f, 0.459717f, 0.476318f, 0.493652f, 0.508789f, 0.524902f, 0.541016f, 0.557129f, 0.573242f,
+ 0.589844f, 0.605469f, 0.621582f, 0.638672f, 0.652832f, 0.669434f, 0.685547f, 0.701660f, 0.717285f, 0.731934f, 0.749023f, 0.764160f,
+ 0.779785f, 0.794922f, 0.810059f, 0.826172f, 0.841309f, 0.856445f, 0.872070f, 0.886719f, 0.902344f, 0.917480f, 0.932129f, 0.889648f,
+ 0.859863f, 0.835938f, 0.816895f, 0.799316f, 0.006817f, 0.020645f, 0.035156f, 0.050110f, 0.065247f, 0.080383f, 0.096313f, 0.111450f,
+ 0.126587f, 0.142456f, 0.158447f, 0.174316f, 0.189819f, 0.205566f, 0.221802f, 0.237427f, 0.253662f, 0.269775f, 0.285889f, 0.301514f,
+ 0.317627f, 0.333740f, 0.349609f, 0.366211f, 0.381348f, 0.397705f, 0.414307f, 0.429932f, 0.447266f, 0.462646f, 0.477539f, 0.494385f,
+ 0.509766f, 0.525879f, 0.541992f, 0.557617f, 0.571777f, 0.588379f, 0.605469f, 0.619629f, 0.636230f, 0.651855f, 0.666992f, 0.681152f,
+ 0.698242f, 0.714355f, 0.729980f, 0.745117f, 0.759766f, 0.775391f, 0.790527f, 0.806152f, 0.821289f, 0.835938f, 0.850586f, 0.866211f,
+ 0.882324f, 0.896484f, 0.922363f, 0.882324f, 0.854004f, 0.831543f, 0.812500f, 0.795898f, 0.006378f, 0.019989f, 0.034027f, 0.048004f,
+ 0.062744f, 0.077148f, 0.091980f, 0.107178f, 0.122192f, 0.137207f, 0.152466f, 0.167603f, 0.183960f, 0.199097f, 0.214111f, 0.229736f,
+ 0.244995f, 0.260254f, 0.276367f, 0.291504f, 0.306641f, 0.322998f, 0.338623f, 0.354248f, 0.369629f, 0.385254f, 0.400879f, 0.416504f,
+ 0.432617f, 0.447510f, 0.464111f, 0.479492f, 0.494141f, 0.511230f, 0.525879f, 0.541016f, 0.556641f, 0.572754f, 0.586914f, 0.602051f,
+ 0.617676f, 0.633789f, 0.648926f, 0.665039f, 0.679688f, 0.695312f, 0.710449f, 0.726074f, 0.739746f, 0.755859f, 0.771484f, 0.785645f,
+ 0.800781f, 0.815918f, 0.831055f, 0.846680f, 0.860840f, 0.875977f, 0.912598f, 0.874512f, 0.847656f, 0.826172f, 0.807617f, 0.791504f,
+ 0.006603f, 0.019287f, 0.032776f, 0.046356f, 0.060272f, 0.073914f, 0.088135f, 0.102905f, 0.117554f, 0.132690f, 0.147095f, 0.161377f,
+ 0.176636f, 0.191162f, 0.205444f, 0.221680f, 0.236572f, 0.251465f, 0.267090f, 0.281250f, 0.296875f, 0.312256f, 0.327393f, 0.342285f,
+ 0.357666f, 0.373291f, 0.388184f, 0.403076f, 0.418457f, 0.433838f, 0.448975f, 0.465088f, 0.479980f, 0.494385f, 0.509277f, 0.525879f,
+ 0.540039f, 0.555176f, 0.570801f, 0.586426f, 0.601074f, 0.616211f, 0.631348f, 0.646484f, 0.661133f, 0.676270f, 0.692383f, 0.705078f,
+ 0.720215f, 0.735352f, 0.751953f, 0.766602f, 0.781250f, 0.796387f, 0.810059f, 0.825684f, 0.840820f, 0.855469f, 0.902344f, 0.866699f,
+ 0.841797f, 0.820312f, 0.803223f, 0.787598f, 0.006111f, 0.018433f, 0.031097f, 0.044739f, 0.057892f, 0.071472f, 0.085205f, 0.099304f,
+ 0.113037f, 0.127319f, 0.141357f, 0.156128f, 0.169678f, 0.183838f, 0.198608f, 0.213745f, 0.227661f, 0.243652f, 0.257324f, 0.272705f,
+ 0.286865f, 0.301025f, 0.316406f, 0.331543f, 0.345703f, 0.360107f, 0.375000f, 0.390625f, 0.405762f, 0.420410f, 0.435303f, 0.449951f,
+ 0.465088f, 0.479492f, 0.494141f, 0.509277f, 0.523926f, 0.538574f, 0.553711f, 0.569336f, 0.583496f, 0.598145f, 0.612793f, 0.628418f,
+ 0.642578f, 0.657227f, 0.671387f, 0.687012f, 0.702637f, 0.716797f, 0.731934f, 0.745605f, 0.761230f, 0.775391f, 0.790527f, 0.805176f,
+ 0.819824f, 0.834961f, 0.892578f, 0.858887f, 0.834473f, 0.814941f, 0.798340f, 0.783203f, 0.005756f, 0.017761f, 0.029907f, 0.042572f,
+ 0.055481f, 0.068420f, 0.081482f, 0.095276f, 0.108826f, 0.122070f, 0.135620f, 0.149902f, 0.163330f, 0.177368f, 0.191284f, 0.206421f,
+ 0.219482f, 0.233521f, 0.247925f, 0.262451f, 0.277100f, 0.290771f, 0.304688f, 0.319580f, 0.334229f, 0.348389f, 0.362549f, 0.377441f,
+ 0.391602f, 0.406250f, 0.421143f, 0.435791f, 0.450439f, 0.463867f, 0.478760f, 0.493164f, 0.507812f, 0.521973f, 0.537109f, 0.551270f,
+ 0.565430f, 0.580078f, 0.594727f, 0.609863f, 0.624023f, 0.638672f, 0.653320f, 0.668457f, 0.682129f, 0.697266f, 0.711914f, 0.726562f,
+ 0.740723f, 0.755859f, 0.770996f, 0.785156f, 0.799805f, 0.814453f, 0.882812f, 0.851562f, 0.827148f, 0.808594f, 0.792969f, 0.778809f,
+ 0.005741f, 0.017166f, 0.029053f, 0.041138f, 0.053345f, 0.065796f, 0.078674f, 0.091248f, 0.104614f, 0.117004f, 0.130737f, 0.143921f,
+ 0.156860f, 0.170288f, 0.183960f, 0.197754f, 0.211304f, 0.224976f, 0.238892f, 0.251953f, 0.266357f, 0.280273f, 0.294922f, 0.308594f,
+ 0.322021f, 0.336914f, 0.350098f, 0.364502f, 0.378174f, 0.393066f, 0.407471f, 0.420166f, 0.435059f, 0.449219f, 0.463135f, 0.477295f,
+ 0.491699f, 0.506348f, 0.520996f, 0.534668f, 0.549316f, 0.563477f, 0.577148f, 0.591309f, 0.605469f, 0.620605f, 0.634766f, 0.648438f,
+ 0.663086f, 0.677734f, 0.691895f, 0.706543f, 0.720215f, 0.734863f, 0.750488f, 0.765137f, 0.779297f, 0.793945f, 0.872559f, 0.843262f,
+ 0.820801f, 0.803223f, 0.787598f, 0.773926f, 0.005283f, 0.016052f, 0.028030f, 0.039246f, 0.050751f, 0.063232f, 0.074829f, 0.087341f,
+ 0.099976f, 0.112732f, 0.125122f, 0.138062f, 0.150757f, 0.163696f, 0.176758f, 0.189697f, 0.203125f, 0.216553f, 0.229614f, 0.243286f,
+ 0.256592f, 0.269775f, 0.283203f, 0.297119f, 0.310547f, 0.324463f, 0.337891f, 0.351807f, 0.365234f, 0.378662f, 0.392822f, 0.406738f,
+ 0.419922f, 0.434814f, 0.448730f, 0.461182f, 0.476562f, 0.489746f, 0.502930f, 0.517578f, 0.531738f, 0.545410f, 0.559082f, 0.573730f,
+ 0.587402f, 0.602051f, 0.615723f, 0.629395f, 0.644043f, 0.658203f, 0.672363f, 0.686523f, 0.701660f, 0.714844f, 0.729980f, 0.743652f,
+ 0.758301f, 0.774414f, 0.862305f, 0.835449f, 0.813965f, 0.796875f, 0.782227f, 0.769043f, 0.005272f, 0.015427f, 0.026230f, 0.037506f,
+ 0.049164f, 0.060516f, 0.072021f, 0.083740f, 0.095825f, 0.108521f, 0.120361f, 0.132324f, 0.144897f, 0.156738f, 0.169922f, 0.182373f,
+ 0.195068f, 0.208008f, 0.220459f, 0.233887f, 0.246948f, 0.260254f, 0.272461f, 0.285889f, 0.299561f, 0.312500f, 0.325684f, 0.338867f,
+ 0.352783f, 0.365479f, 0.378906f, 0.392334f, 0.406006f, 0.419189f, 0.432861f, 0.446777f, 0.460693f, 0.473877f, 0.486572f, 0.500977f,
+ 0.515137f, 0.528809f, 0.542480f, 0.555176f, 0.569824f, 0.583984f, 0.597656f, 0.611328f, 0.625000f, 0.639648f, 0.653320f, 0.667480f,
+ 0.681641f, 0.695801f, 0.709961f, 0.723633f, 0.738281f, 0.752930f, 0.852539f, 0.827148f, 0.807129f, 0.790527f, 0.776367f, 0.764160f,
+ 0.004822f, 0.014885f, 0.025360f, 0.035767f, 0.046570f, 0.057587f, 0.068726f, 0.080139f, 0.091736f, 0.103577f, 0.115479f, 0.126709f,
+ 0.138672f, 0.150879f, 0.162231f, 0.174805f, 0.187622f, 0.199951f, 0.212524f, 0.224854f, 0.236694f, 0.249878f, 0.262207f, 0.275391f,
+ 0.287842f, 0.300293f, 0.313477f, 0.326904f, 0.340088f, 0.353027f, 0.365479f, 0.378174f, 0.391602f, 0.404541f, 0.417236f, 0.431641f,
+ 0.444336f, 0.457764f, 0.470703f, 0.484375f, 0.497803f, 0.510742f, 0.524902f, 0.537598f, 0.552246f, 0.564941f, 0.579590f, 0.592285f,
+ 0.606445f, 0.621094f, 0.634277f, 0.646973f, 0.662109f, 0.675781f, 0.689453f, 0.704102f, 0.718262f, 0.733398f, 0.842285f, 0.818848f,
+ 0.799805f, 0.784180f, 0.770996f, 0.758301f, 0.004745f, 0.014427f, 0.024277f, 0.034546f, 0.044800f, 0.055176f, 0.066040f, 0.076477f,
+ 0.087341f, 0.099060f, 0.110474f, 0.121216f, 0.132690f, 0.144165f, 0.156006f, 0.167358f, 0.179688f, 0.191284f, 0.203247f, 0.216187f,
+ 0.227905f, 0.239868f, 0.252441f, 0.264648f, 0.277100f, 0.289307f, 0.301270f, 0.314453f, 0.326660f, 0.338867f, 0.352539f, 0.364990f,
+ 0.377686f, 0.390137f, 0.403076f, 0.416016f, 0.428467f, 0.441406f, 0.453857f, 0.468262f, 0.480957f, 0.494385f, 0.507324f, 0.520020f,
+ 0.534180f, 0.547363f, 0.560059f, 0.573730f, 0.586914f, 0.601074f, 0.615234f, 0.628418f, 0.641602f, 0.656250f, 0.669434f, 0.683594f,
+ 0.697754f, 0.712402f, 0.832520f, 0.809570f, 0.792480f, 0.778320f, 0.764160f, 0.753906f, 0.004612f, 0.013840f, 0.023483f, 0.033081f,
+ 0.042999f, 0.052490f, 0.063049f, 0.073303f, 0.083801f, 0.094238f, 0.105042f, 0.115967f, 0.127319f, 0.138062f, 0.149048f, 0.160645f,
+ 0.171875f, 0.183228f, 0.194946f, 0.206665f, 0.218384f, 0.230347f, 0.241699f, 0.253906f, 0.265869f, 0.277832f, 0.290039f, 0.301758f,
+ 0.314209f, 0.326660f, 0.339111f, 0.351074f, 0.363281f, 0.375977f, 0.388428f, 0.401123f, 0.413330f, 0.426270f, 0.439453f, 0.451904f,
+ 0.464111f, 0.478027f, 0.489746f, 0.503418f, 0.515625f, 0.529297f, 0.542480f, 0.556152f, 0.569336f, 0.582031f, 0.595215f, 0.608887f,
+ 0.622559f, 0.636230f, 0.649902f, 0.663574f, 0.677246f, 0.691895f, 0.821289f, 0.802246f, 0.785645f, 0.771484f, 0.758789f, 0.748047f,
+ 0.004345f, 0.012985f, 0.022156f, 0.030884f, 0.040802f, 0.050568f, 0.060303f, 0.069946f, 0.079956f, 0.090393f, 0.100403f, 0.111084f,
+ 0.120667f, 0.131714f, 0.142700f, 0.153198f, 0.164429f, 0.175659f, 0.186523f, 0.197876f, 0.208496f, 0.220337f, 0.231567f, 0.243286f,
+ 0.254639f, 0.266113f, 0.277832f, 0.289795f, 0.301758f, 0.313477f, 0.325439f, 0.337402f, 0.349609f, 0.361328f, 0.373779f, 0.385986f,
+ 0.398193f, 0.410889f, 0.423340f, 0.435059f, 0.447998f, 0.460205f, 0.473389f, 0.486084f, 0.499023f, 0.511230f, 0.524414f, 0.537109f,
+ 0.549805f, 0.563477f, 0.576172f, 0.589355f, 0.603027f, 0.616699f, 0.629883f, 0.644531f, 0.658691f, 0.670898f, 0.811035f, 0.792969f,
+ 0.777832f, 0.764648f, 0.752441f, 0.742676f, 0.004002f, 0.012718f, 0.021210f, 0.029877f, 0.039246f, 0.048431f, 0.057281f, 0.067078f,
+ 0.076538f, 0.086121f, 0.096008f, 0.105957f, 0.115540f, 0.125732f, 0.136475f, 0.146729f, 0.157227f, 0.167236f, 0.177979f, 0.189819f,
+ 0.200195f, 0.210693f, 0.221802f, 0.232788f, 0.243896f, 0.255127f, 0.266602f, 0.278320f, 0.289062f, 0.300293f, 0.312012f, 0.323975f,
+ 0.335449f, 0.347168f, 0.359131f, 0.371094f, 0.382812f, 0.394775f, 0.406982f, 0.419434f, 0.431152f, 0.443604f, 0.455566f, 0.468506f,
+ 0.481445f, 0.493408f, 0.506348f, 0.519043f, 0.531738f, 0.544922f, 0.558105f, 0.570801f, 0.583984f, 0.597168f, 0.610352f, 0.624512f,
+ 0.637695f, 0.651855f, 0.800293f, 0.785156f, 0.770508f, 0.757812f, 0.747070f, 0.737305f, 0.003967f, 0.011940f, 0.020203f, 0.028931f,
+ 0.037109f, 0.045898f, 0.054840f, 0.063477f, 0.073059f, 0.082214f, 0.090942f, 0.100647f, 0.110535f, 0.120178f, 0.129639f, 0.139648f,
+ 0.149902f, 0.160156f, 0.170044f, 0.180786f, 0.190674f, 0.201416f, 0.211792f, 0.222412f, 0.233521f, 0.244751f, 0.255615f, 0.266113f,
+ 0.276855f, 0.288574f, 0.299561f, 0.311279f, 0.322266f, 0.333984f, 0.344727f, 0.356934f, 0.368164f, 0.379395f, 0.390869f, 0.403076f,
+ 0.415283f, 0.427246f, 0.439453f, 0.451172f, 0.464111f, 0.476807f, 0.488281f, 0.500977f, 0.513672f, 0.526367f, 0.538574f, 0.551758f,
+ 0.564453f, 0.577637f, 0.590820f, 0.604492f, 0.618164f, 0.631836f, 0.790039f, 0.775879f, 0.763184f, 0.750977f, 0.740723f, 0.731445f,
+ 0.003679f, 0.011749f, 0.019135f, 0.027237f, 0.035431f, 0.043884f, 0.052399f, 0.060577f, 0.069153f, 0.077881f, 0.086731f, 0.095947f,
+ 0.104797f, 0.114380f, 0.123535f, 0.133057f, 0.142700f, 0.152588f, 0.162231f, 0.171753f, 0.182129f, 0.192261f, 0.202026f, 0.212524f,
+ 0.222900f, 0.233643f, 0.243896f, 0.254395f, 0.264893f, 0.276123f, 0.286621f, 0.297119f, 0.308105f, 0.319336f, 0.331299f, 0.341553f,
+ 0.353027f, 0.364258f, 0.375977f, 0.387451f, 0.399414f, 0.410645f, 0.422607f, 0.434814f, 0.445801f, 0.458984f, 0.470703f, 0.482910f,
+ 0.495361f, 0.508301f, 0.520020f, 0.532227f, 0.545410f, 0.558594f, 0.570801f, 0.584961f, 0.597656f, 0.611816f, 0.778809f, 0.768066f,
+ 0.754883f, 0.743652f, 0.733887f, 0.725098f, 0.003525f, 0.010956f, 0.018433f, 0.026260f, 0.033295f, 0.041870f, 0.049377f, 0.057709f,
+ 0.065735f, 0.074463f, 0.082764f, 0.091736f, 0.099976f, 0.108582f, 0.118103f, 0.126465f, 0.135742f, 0.144775f, 0.154175f, 0.164307f,
+ 0.173218f, 0.182983f, 0.192505f, 0.202759f, 0.212646f, 0.221924f, 0.232910f, 0.242188f, 0.252930f, 0.262939f, 0.273926f, 0.284180f,
+ 0.294922f, 0.305420f, 0.316162f, 0.327637f, 0.338867f, 0.349609f, 0.361084f, 0.371826f, 0.382812f, 0.395020f, 0.406494f, 0.417725f,
+ 0.429688f, 0.441406f, 0.452637f, 0.465088f, 0.477783f, 0.489258f, 0.501953f, 0.514160f, 0.527344f, 0.539062f, 0.551758f, 0.564941f,
+ 0.578125f, 0.591797f, 0.768555f, 0.759277f, 0.748047f, 0.736816f, 0.728027f, 0.718750f, 0.003363f, 0.010353f, 0.017548f, 0.024765f,
+ 0.032196f, 0.039673f, 0.046936f, 0.054565f, 0.062561f, 0.070496f, 0.078308f, 0.086731f, 0.094910f, 0.103333f, 0.111633f, 0.120422f,
+ 0.129150f, 0.137695f, 0.146973f, 0.155762f, 0.164673f, 0.173950f, 0.183228f, 0.193359f, 0.201782f, 0.212036f, 0.221436f, 0.231323f,
+ 0.241699f, 0.251221f, 0.261719f, 0.271729f, 0.281494f, 0.291992f, 0.302734f, 0.312988f, 0.323730f, 0.334961f, 0.345459f, 0.357666f,
+ 0.367432f, 0.378662f, 0.389893f, 0.401855f, 0.412842f, 0.424316f, 0.435791f, 0.447266f, 0.459473f, 0.471436f, 0.482910f, 0.495605f,
+ 0.507324f, 0.520508f, 0.533203f, 0.545898f, 0.558594f, 0.570801f, 0.757812f, 0.750488f, 0.740234f, 0.729980f, 0.720703f, 0.712402f,
+ 0.003254f, 0.010048f, 0.016815f, 0.023453f, 0.030609f, 0.037537f, 0.044617f, 0.051971f, 0.059265f, 0.066833f, 0.074280f, 0.082153f,
+ 0.089905f, 0.097717f, 0.106018f, 0.113770f, 0.122131f, 0.131104f, 0.139282f, 0.147705f, 0.155762f, 0.165161f, 0.173950f, 0.183228f,
+ 0.192139f, 0.200928f, 0.210693f, 0.220093f, 0.229736f, 0.239258f, 0.248657f, 0.259277f, 0.268799f, 0.279053f, 0.288574f, 0.299561f,
+ 0.309814f, 0.319580f, 0.330322f, 0.340820f, 0.352783f, 0.362549f, 0.374023f, 0.385010f, 0.395752f, 0.407471f, 0.418701f, 0.429688f,
+ 0.441650f, 0.453125f, 0.465088f, 0.477539f, 0.489014f, 0.500977f, 0.513184f, 0.526855f, 0.539062f, 0.552246f, 0.747559f, 0.741699f,
+ 0.731934f, 0.722656f, 0.714355f, 0.707031f, 0.003345f, 0.009262f, 0.015900f, 0.022614f, 0.029282f, 0.035522f, 0.042633f, 0.048981f,
+ 0.056000f, 0.063110f, 0.070801f, 0.077454f, 0.084839f, 0.092590f, 0.100281f, 0.107849f, 0.116089f, 0.123169f, 0.131348f, 0.139648f,
+ 0.148193f, 0.156616f, 0.164795f, 0.173584f, 0.182617f, 0.191284f, 0.200073f, 0.208740f, 0.218140f, 0.227417f, 0.236694f, 0.246338f,
+ 0.255859f, 0.265381f, 0.275146f, 0.285889f, 0.294922f, 0.305420f, 0.315918f, 0.325928f, 0.336670f, 0.347412f, 0.358154f, 0.368652f,
+ 0.378662f, 0.390381f, 0.402100f, 0.412842f, 0.424316f, 0.435059f, 0.447021f, 0.458984f, 0.470459f, 0.482422f, 0.494873f, 0.508301f,
+ 0.520020f, 0.532227f, 0.737305f, 0.732910f, 0.723633f, 0.715820f, 0.708008f, 0.700195f, 0.003195f, 0.009010f, 0.015137f, 0.021225f,
+ 0.027466f, 0.033844f, 0.040161f, 0.046417f, 0.053497f, 0.059875f, 0.066711f, 0.073425f, 0.080505f, 0.087280f, 0.094788f, 0.102173f,
+ 0.109070f, 0.117004f, 0.124634f, 0.132446f, 0.139893f, 0.147705f, 0.155884f, 0.163940f, 0.172729f, 0.180908f, 0.189697f, 0.198242f,
+ 0.206665f, 0.215820f, 0.225220f, 0.233765f, 0.243408f, 0.251953f, 0.262207f, 0.271484f, 0.281494f, 0.291260f, 0.300537f, 0.311035f,
+ 0.320801f, 0.332520f, 0.341797f, 0.352051f, 0.362305f, 0.373535f, 0.384521f, 0.395264f, 0.406494f, 0.417480f, 0.429443f, 0.440430f,
+ 0.451904f, 0.463867f, 0.476074f, 0.487793f, 0.499268f, 0.513184f, 0.726562f, 0.723633f, 0.716309f, 0.708496f, 0.700684f, 0.694336f,
+ 0.002859f, 0.008507f, 0.014366f, 0.020203f, 0.026123f, 0.031891f, 0.038025f, 0.044281f, 0.050354f, 0.056519f, 0.062683f, 0.069275f,
+ 0.075195f, 0.082458f, 0.088806f, 0.095947f, 0.102783f, 0.110046f, 0.117065f, 0.124878f, 0.132080f, 0.139282f, 0.146851f, 0.154907f,
+ 0.162598f, 0.171265f, 0.178833f, 0.187500f, 0.195435f, 0.204590f, 0.213013f, 0.221680f, 0.231079f, 0.239502f, 0.248047f, 0.258301f,
+ 0.267334f, 0.277100f, 0.286133f, 0.296387f, 0.306641f, 0.316162f, 0.326416f, 0.336426f, 0.346924f, 0.357422f, 0.367188f, 0.378418f,
+ 0.389160f, 0.400391f, 0.411865f, 0.422852f, 0.433594f, 0.445557f, 0.457520f, 0.468994f, 0.481445f, 0.493408f, 0.715332f, 0.715332f,
+ 0.708984f, 0.700684f, 0.693848f, 0.687988f, 0.002701f, 0.008080f, 0.013718f, 0.019058f, 0.024582f, 0.030197f, 0.035675f, 0.041748f,
+ 0.047302f, 0.053589f, 0.059082f, 0.065308f, 0.071777f, 0.077576f, 0.084106f, 0.090332f, 0.097107f, 0.103577f, 0.110046f, 0.117493f,
+ 0.124146f, 0.131470f, 0.138550f, 0.145508f, 0.153564f, 0.161377f, 0.169067f, 0.176880f, 0.184814f, 0.192627f, 0.201294f, 0.209717f,
+ 0.218140f, 0.226929f, 0.235229f, 0.245117f, 0.253418f, 0.262939f, 0.272705f, 0.281738f, 0.290771f, 0.300781f, 0.310791f, 0.321289f,
+ 0.330566f, 0.341064f, 0.351562f, 0.361572f, 0.372559f, 0.382568f, 0.393066f, 0.405273f, 0.415771f, 0.426758f, 0.438721f, 0.450439f,
+ 0.461670f, 0.474121f, 0.704102f, 0.706543f, 0.700195f, 0.693359f, 0.687012f, 0.681152f, 0.002546f, 0.007771f, 0.012985f, 0.017975f,
+ 0.023392f, 0.028976f, 0.034180f, 0.039368f, 0.044556f, 0.050110f, 0.055847f, 0.061218f, 0.066895f, 0.072815f, 0.078674f, 0.085083f,
+ 0.091309f, 0.097168f, 0.103516f, 0.110107f, 0.116821f, 0.123413f, 0.130371f, 0.137329f, 0.144165f, 0.151733f, 0.158813f, 0.166382f,
+ 0.174438f, 0.182129f, 0.190063f, 0.197510f, 0.206055f, 0.214355f, 0.222778f, 0.231812f, 0.240723f, 0.249023f, 0.258789f, 0.267578f,
+ 0.276855f, 0.285889f, 0.295654f, 0.305420f, 0.315430f, 0.324463f, 0.334961f, 0.345215f, 0.354492f, 0.365234f, 0.376221f, 0.387451f,
+ 0.398926f, 0.409424f, 0.419678f, 0.432129f, 0.443848f, 0.455566f, 0.693848f, 0.697266f, 0.691895f, 0.686523f, 0.680176f, 0.674805f,
+ 0.002542f, 0.007271f, 0.012337f, 0.017181f, 0.021744f, 0.026840f, 0.031555f, 0.037231f, 0.042236f, 0.046906f, 0.051941f, 0.057709f,
+ 0.063049f, 0.068542f, 0.073853f, 0.079712f, 0.085266f, 0.091064f, 0.096985f, 0.103027f, 0.109009f, 0.115417f, 0.122192f, 0.128540f,
+ 0.135132f, 0.141846f, 0.148926f, 0.156250f, 0.163696f, 0.171387f, 0.178223f, 0.186035f, 0.194580f, 0.202271f, 0.210327f, 0.218994f,
+ 0.227173f, 0.235596f, 0.244385f, 0.252930f, 0.262451f, 0.271240f, 0.280762f, 0.290771f, 0.299805f, 0.309082f, 0.318359f, 0.329102f,
+ 0.338623f, 0.348633f, 0.358643f, 0.370117f, 0.379639f, 0.390869f, 0.401611f, 0.413330f, 0.425293f, 0.436523f, 0.682129f, 0.688477f,
+ 0.684082f, 0.678711f, 0.673340f, 0.667969f, 0.002300f, 0.007076f, 0.011505f, 0.016251f, 0.020401f, 0.025665f, 0.029816f, 0.034790f,
+ 0.039368f, 0.044159f, 0.048798f, 0.053955f, 0.059174f, 0.064148f, 0.069153f, 0.074463f, 0.079346f, 0.085266f, 0.090759f, 0.096191f,
+ 0.102112f, 0.108032f, 0.114075f, 0.120117f, 0.126587f, 0.133057f, 0.139648f, 0.146240f, 0.153442f, 0.160400f, 0.167725f, 0.174683f,
+ 0.182739f, 0.190308f, 0.198120f, 0.206177f, 0.214355f, 0.222656f, 0.230713f, 0.239258f, 0.248413f, 0.257080f, 0.265869f, 0.274658f,
+ 0.284424f, 0.292725f, 0.302490f, 0.313232f, 0.321777f, 0.331787f, 0.341797f, 0.352295f, 0.363281f, 0.373535f, 0.383545f, 0.395264f,
+ 0.405762f, 0.416992f, 0.671387f, 0.679688f, 0.675293f, 0.670898f, 0.666016f, 0.661133f, 0.002104f, 0.006474f, 0.010506f, 0.015099f,
+ 0.018875f, 0.023911f, 0.028534f, 0.032715f, 0.036652f, 0.041290f, 0.046021f, 0.050171f, 0.054535f, 0.059570f, 0.064575f, 0.069458f,
+ 0.074341f, 0.079346f, 0.084351f, 0.089844f, 0.095032f, 0.100830f, 0.106628f, 0.112122f, 0.117859f, 0.124084f, 0.130249f, 0.136841f,
+ 0.143188f, 0.149780f, 0.157349f, 0.163940f, 0.171021f, 0.178345f, 0.186279f, 0.193848f, 0.201172f, 0.209717f, 0.217529f, 0.225464f,
+ 0.233765f, 0.242676f, 0.251221f, 0.260254f, 0.268311f, 0.278076f, 0.287109f, 0.296143f, 0.305908f, 0.315674f, 0.325195f, 0.335449f,
+ 0.344971f, 0.355469f, 0.365967f, 0.377441f, 0.387939f, 0.398193f, 0.660645f, 0.670410f, 0.667969f, 0.663086f, 0.659180f, 0.654785f,
+ 0.002085f, 0.006306f, 0.010506f, 0.014107f, 0.018448f, 0.022293f, 0.026215f, 0.029953f, 0.034515f, 0.038391f, 0.042786f, 0.046844f,
+ 0.051361f, 0.055573f, 0.059784f, 0.064331f, 0.068970f, 0.073425f, 0.078430f, 0.083313f, 0.088318f, 0.093567f, 0.098816f, 0.104126f,
+ 0.109924f, 0.115662f, 0.121521f, 0.127197f, 0.133545f, 0.139771f, 0.146729f, 0.153076f, 0.160278f, 0.166992f, 0.174316f, 0.181274f,
+ 0.188965f, 0.196045f, 0.204468f, 0.212036f, 0.220459f, 0.228638f, 0.237183f, 0.245483f, 0.254150f, 0.262451f, 0.271484f, 0.281250f,
+ 0.290283f, 0.299561f, 0.308350f, 0.318115f, 0.328369f, 0.337158f, 0.349121f, 0.358887f, 0.370117f, 0.380615f, 0.649414f, 0.661133f,
+ 0.659668f, 0.655762f, 0.651855f, 0.647949f, 0.001922f, 0.005867f, 0.009399f, 0.013565f, 0.017380f, 0.020859f, 0.024551f, 0.028442f,
+ 0.032318f, 0.035980f, 0.039551f, 0.043488f, 0.047333f, 0.051239f, 0.055573f, 0.059875f, 0.063660f, 0.067810f, 0.072876f, 0.077087f,
+ 0.081726f, 0.086304f, 0.091370f, 0.096863f, 0.101746f, 0.107483f, 0.112732f, 0.117920f, 0.124329f, 0.130005f, 0.136108f, 0.142822f,
+ 0.149170f, 0.155396f, 0.162598f, 0.169434f, 0.176636f, 0.183838f, 0.191772f, 0.198975f, 0.206665f, 0.214478f, 0.222290f, 0.230835f,
+ 0.239258f, 0.247803f, 0.256836f, 0.264893f, 0.274414f, 0.283203f, 0.292725f, 0.301758f, 0.311035f, 0.321289f, 0.332275f, 0.340820f,
+ 0.351562f, 0.363037f, 0.637695f, 0.652832f, 0.651367f, 0.647949f, 0.644531f, 0.641602f, 0.002052f, 0.005253f, 0.009117f, 0.012482f,
+ 0.016113f, 0.019302f, 0.022842f, 0.026230f, 0.029831f, 0.033447f, 0.036682f, 0.040588f, 0.044189f, 0.047333f, 0.051178f, 0.055267f,
+ 0.058807f, 0.062683f, 0.067200f, 0.070984f, 0.075195f, 0.079895f, 0.084534f, 0.088806f, 0.093933f, 0.098999f, 0.104309f, 0.109619f,
+ 0.114807f, 0.120422f, 0.126587f, 0.132080f, 0.138550f, 0.144775f, 0.151245f, 0.157837f, 0.164551f, 0.171387f, 0.178467f, 0.186157f,
+ 0.193359f, 0.201294f, 0.208740f, 0.216797f, 0.224854f, 0.233398f, 0.241211f, 0.250000f, 0.258545f, 0.267822f, 0.276855f, 0.286133f,
+ 0.295410f, 0.304932f, 0.314697f, 0.324463f, 0.334229f, 0.344238f, 0.626953f, 0.642578f, 0.643066f, 0.641113f, 0.637695f, 0.634277f,
+ 0.001711f, 0.005424f, 0.008347f, 0.012024f, 0.014977f, 0.018066f, 0.021500f, 0.024399f, 0.027756f, 0.030869f, 0.034058f, 0.037048f,
+ 0.040558f, 0.044006f, 0.046906f, 0.050690f, 0.054169f, 0.057983f, 0.061584f, 0.065247f, 0.069336f, 0.073425f, 0.077576f, 0.082092f,
+ 0.086670f, 0.091064f, 0.095886f, 0.101196f, 0.105957f, 0.111267f, 0.116943f, 0.122559f, 0.128174f, 0.133789f, 0.140259f, 0.146118f,
+ 0.153076f, 0.159424f, 0.166016f, 0.173462f, 0.180542f, 0.187744f, 0.195435f, 0.203003f, 0.209961f, 0.218994f, 0.226562f, 0.234619f,
+ 0.243286f, 0.251709f, 0.260742f, 0.269531f, 0.277832f, 0.287354f, 0.297363f, 0.306885f, 0.316406f, 0.326660f, 0.615234f, 0.633789f,
+ 0.634277f, 0.632812f, 0.630371f, 0.626953f, 0.001721f, 0.004829f, 0.008034f, 0.010857f, 0.013893f, 0.016953f, 0.019806f, 0.022705f,
+ 0.025589f, 0.028793f, 0.031616f, 0.034180f, 0.036926f, 0.039978f, 0.043213f, 0.046356f, 0.049744f, 0.052887f, 0.056305f, 0.059906f,
+ 0.063416f, 0.067322f, 0.070862f, 0.075134f, 0.079285f, 0.083435f, 0.088074f, 0.092712f, 0.097534f, 0.102173f, 0.107544f, 0.112305f,
+ 0.118225f, 0.123657f, 0.129272f, 0.135376f, 0.141602f, 0.147705f, 0.153931f, 0.160889f, 0.167847f, 0.174683f, 0.181885f, 0.189209f,
+ 0.196533f, 0.204224f, 0.212524f, 0.219727f, 0.228271f, 0.236572f, 0.245483f, 0.253418f, 0.261719f, 0.270996f, 0.280029f, 0.289307f,
+ 0.300537f, 0.309326f, 0.604004f, 0.625000f, 0.626953f, 0.625000f, 0.622559f, 0.620117f, 0.001624f, 0.004730f, 0.007412f, 0.010300f,
+ 0.013199f, 0.015717f, 0.018448f, 0.020935f, 0.023163f, 0.026138f, 0.028687f, 0.031204f, 0.033875f, 0.036743f, 0.039825f, 0.042389f,
+ 0.045166f, 0.048523f, 0.051422f, 0.054535f, 0.057953f, 0.061249f, 0.064880f, 0.068542f, 0.072388f, 0.076355f, 0.080505f, 0.084534f,
+ 0.089294f, 0.093750f, 0.098389f, 0.103210f, 0.108337f, 0.113647f, 0.118896f, 0.124817f, 0.130737f, 0.135986f, 0.142212f, 0.148560f,
+ 0.155151f, 0.162109f, 0.168579f, 0.175415f, 0.183105f, 0.190552f, 0.197998f, 0.205322f, 0.213623f, 0.221436f, 0.229370f, 0.237915f,
+ 0.246216f, 0.254883f, 0.264160f, 0.273438f, 0.282471f, 0.292236f, 0.593262f, 0.615723f, 0.618164f, 0.617188f, 0.615234f, 0.612793f,
+ 0.001355f, 0.004463f, 0.007061f, 0.009506f, 0.011612f, 0.014381f, 0.016830f, 0.019394f, 0.021576f, 0.023697f, 0.026428f, 0.028778f,
+ 0.030975f, 0.033386f, 0.035950f, 0.038513f, 0.041260f, 0.044067f, 0.046967f, 0.049622f, 0.052612f, 0.055847f, 0.059052f, 0.062164f,
+ 0.065918f, 0.069397f, 0.073242f, 0.077271f, 0.081055f, 0.085327f, 0.089661f, 0.094177f, 0.098877f, 0.103455f, 0.108582f, 0.113647f,
+ 0.119812f, 0.125000f, 0.130981f, 0.137085f, 0.142944f, 0.149414f, 0.156006f, 0.162354f, 0.169434f, 0.176514f, 0.183716f, 0.191284f,
+ 0.198975f, 0.206421f, 0.214844f, 0.222412f, 0.231323f, 0.238647f, 0.247437f, 0.256592f, 0.265625f, 0.276367f, 0.581055f, 0.606445f,
+ 0.609863f, 0.608887f, 0.607910f, 0.606445f, 0.001413f, 0.004128f, 0.006180f, 0.008781f, 0.010994f, 0.013496f, 0.015427f, 0.017654f,
+ 0.019684f, 0.021881f, 0.024139f, 0.025879f, 0.028137f, 0.030334f, 0.032471f, 0.034821f, 0.037354f, 0.039642f, 0.042236f, 0.044708f,
+ 0.047394f, 0.050079f, 0.053223f, 0.056244f, 0.059479f, 0.062622f, 0.066223f, 0.069946f, 0.073608f, 0.077209f, 0.081604f, 0.085632f,
+ 0.089722f, 0.094360f, 0.098999f, 0.103943f, 0.108826f, 0.114319f, 0.119568f, 0.125122f, 0.131104f, 0.137085f, 0.143433f, 0.150024f,
+ 0.156494f, 0.163330f, 0.170044f, 0.177490f, 0.184326f, 0.191895f, 0.199707f, 0.207764f, 0.215698f, 0.223755f, 0.231812f, 0.240845f,
+ 0.249756f, 0.258789f, 0.568848f, 0.598145f, 0.601562f, 0.600586f, 0.600586f, 0.599121f, 0.001182f, 0.003773f, 0.005970f, 0.008293f,
+ 0.010277f, 0.012512f, 0.014030f, 0.016129f, 0.017929f, 0.019791f, 0.021683f, 0.023590f, 0.025452f, 0.027328f, 0.029404f, 0.031677f,
+ 0.033539f, 0.035583f, 0.037903f, 0.040314f, 0.042877f, 0.045319f, 0.048126f, 0.050690f, 0.053436f, 0.056519f, 0.059723f, 0.062744f,
+ 0.066284f, 0.069702f, 0.073608f, 0.077209f, 0.081055f, 0.085754f, 0.089783f, 0.094421f, 0.099060f, 0.103821f, 0.109192f, 0.114563f,
+ 0.119934f, 0.125488f, 0.131104f, 0.137695f, 0.144043f, 0.149780f, 0.156738f, 0.163940f, 0.170654f, 0.177856f, 0.185181f, 0.192871f,
+ 0.200439f, 0.208740f, 0.216675f, 0.225342f, 0.233521f, 0.242554f, 0.557617f, 0.587891f, 0.592285f, 0.592773f, 0.592285f, 0.592285f,
+ 0.001198f, 0.003677f, 0.005547f, 0.007561f, 0.009468f, 0.011253f, 0.012833f, 0.014465f, 0.016205f, 0.017792f, 0.019394f, 0.021240f,
+ 0.022751f, 0.024475f, 0.026260f, 0.028015f, 0.030136f, 0.031708f, 0.034088f, 0.036102f, 0.038361f, 0.040497f, 0.042816f, 0.045288f,
+ 0.047882f, 0.050476f, 0.053284f, 0.056183f, 0.059174f, 0.062500f, 0.065796f, 0.069153f, 0.072998f, 0.076904f, 0.080994f, 0.085083f,
+ 0.089478f, 0.094116f, 0.098633f, 0.103394f, 0.108704f, 0.113953f, 0.119934f, 0.125366f, 0.131348f, 0.137329f, 0.143555f, 0.150391f,
+ 0.157227f, 0.163818f, 0.170776f, 0.178467f, 0.185791f, 0.193359f, 0.201538f, 0.209717f, 0.218018f, 0.226807f, 0.544922f, 0.578613f,
+ 0.583984f, 0.584961f, 0.585449f, 0.584473f, 0.001067f, 0.003101f, 0.004974f, 0.006855f, 0.008522f, 0.009949f, 0.011635f, 0.012985f,
+ 0.014595f, 0.016052f, 0.017685f, 0.019012f, 0.020264f, 0.021851f, 0.023346f, 0.025146f, 0.026688f, 0.028336f, 0.030304f, 0.031860f,
+ 0.034119f, 0.035889f, 0.038025f, 0.040283f, 0.042450f, 0.044952f, 0.047302f, 0.050049f, 0.052765f, 0.055908f, 0.058594f, 0.061859f,
+ 0.064880f, 0.068481f, 0.072327f, 0.076172f, 0.080200f, 0.084290f, 0.088684f, 0.093262f, 0.098145f, 0.102905f, 0.108337f, 0.113708f,
+ 0.119080f, 0.125000f, 0.131348f, 0.137329f, 0.143921f, 0.150391f, 0.157593f, 0.164551f, 0.171753f, 0.179077f, 0.186768f, 0.194702f,
+ 0.203003f, 0.210815f, 0.534180f, 0.569336f, 0.575684f, 0.577637f, 0.577637f, 0.577148f, 0.001196f, 0.003178f, 0.004601f, 0.006241f,
+ 0.007782f, 0.009262f, 0.010391f, 0.011795f, 0.012955f, 0.014198f, 0.015518f, 0.016785f, 0.018097f, 0.019409f, 0.020782f, 0.022247f,
+ 0.023544f, 0.025269f, 0.026749f, 0.028152f, 0.030045f, 0.031555f, 0.033630f, 0.035645f, 0.037567f, 0.039642f, 0.041992f, 0.044281f,
+ 0.046692f, 0.049042f, 0.052094f, 0.054779f, 0.057831f, 0.060760f, 0.064209f, 0.067627f, 0.071228f, 0.075256f, 0.079224f, 0.083557f,
+ 0.087891f, 0.092468f, 0.097168f, 0.102356f, 0.107605f, 0.113098f, 0.119019f, 0.124878f, 0.130859f, 0.137451f, 0.144287f, 0.150635f,
+ 0.157471f, 0.164917f, 0.171997f, 0.179932f, 0.187378f, 0.196899f, 0.521973f, 0.560547f, 0.566895f, 0.569824f, 0.570312f, 0.568848f,
+ 0.001242f, 0.002674f, 0.004421f, 0.005573f, 0.006882f, 0.008354f, 0.009491f, 0.010559f, 0.011406f, 0.012695f, 0.013893f, 0.014908f,
+ 0.015854f, 0.017044f, 0.018234f, 0.019501f, 0.020752f, 0.022003f, 0.023254f, 0.024689f, 0.026154f, 0.027802f, 0.029434f, 0.031113f,
+ 0.032898f, 0.034668f, 0.036774f, 0.038910f, 0.040802f, 0.043030f, 0.045593f, 0.048065f, 0.050873f, 0.053680f, 0.056458f, 0.059692f,
+ 0.062866f, 0.066467f, 0.069946f, 0.074036f, 0.077942f, 0.082275f, 0.086731f, 0.091614f, 0.096313f, 0.101562f, 0.106934f, 0.112671f,
+ 0.118591f, 0.124634f, 0.130859f, 0.137207f, 0.144043f, 0.151123f, 0.157593f, 0.165283f, 0.173218f, 0.180664f, 0.510254f, 0.550781f,
+ 0.558105f, 0.561035f, 0.562012f, 0.562012f, 0.000842f, 0.002552f, 0.003769f, 0.005333f, 0.006149f, 0.007298f, 0.008362f, 0.009224f,
+ 0.010254f, 0.011230f, 0.012108f, 0.013092f, 0.014000f, 0.014992f, 0.016006f, 0.016953f, 0.017990f, 0.019196f, 0.020142f, 0.021622f,
+ 0.022827f, 0.024216f, 0.025513f, 0.026993f, 0.028564f, 0.030212f, 0.032013f, 0.033813f, 0.035706f, 0.037598f, 0.039703f, 0.041840f,
+ 0.044159f, 0.046539f, 0.049347f, 0.052155f, 0.055084f, 0.058228f, 0.061554f, 0.065002f, 0.068909f, 0.072693f, 0.076599f, 0.081238f,
+ 0.085388f, 0.090515f, 0.095764f, 0.100891f, 0.106689f, 0.112366f, 0.118103f, 0.124634f, 0.130859f, 0.137573f, 0.144287f, 0.151855f,
+ 0.158447f, 0.166260f, 0.498535f, 0.541992f, 0.549805f, 0.553711f, 0.554199f, 0.554688f, 0.000874f, 0.002186f, 0.003445f, 0.004807f,
+ 0.005562f, 0.006607f, 0.007378f, 0.008102f, 0.008919f, 0.009666f, 0.010513f, 0.011131f, 0.012039f, 0.012848f, 0.013779f, 0.014671f,
+ 0.015465f, 0.016464f, 0.017517f, 0.018585f, 0.019730f, 0.020798f, 0.022018f, 0.023300f, 0.024612f, 0.026093f, 0.027374f, 0.029022f,
+ 0.030624f, 0.032440f, 0.034180f, 0.036285f, 0.038116f, 0.040344f, 0.042725f, 0.045349f, 0.047913f, 0.050476f, 0.053406f, 0.056488f,
+ 0.059998f, 0.063354f, 0.067383f, 0.071289f, 0.075562f, 0.079834f, 0.084656f, 0.089478f, 0.094849f, 0.100342f, 0.106140f, 0.111877f,
+ 0.118042f, 0.124573f, 0.130981f, 0.137451f, 0.144653f, 0.152588f, 0.486816f, 0.531738f, 0.541016f, 0.545410f, 0.547363f, 0.546875f,
+ 0.000667f, 0.002001f, 0.003244f, 0.003895f, 0.004936f, 0.005608f, 0.006477f, 0.006901f, 0.007648f, 0.008354f, 0.009132f, 0.009766f,
+ 0.010490f, 0.011177f, 0.011780f, 0.012543f, 0.013420f, 0.014084f, 0.015045f, 0.015961f, 0.016876f, 0.017822f, 0.018768f, 0.019958f,
+ 0.021255f, 0.022232f, 0.023560f, 0.024780f, 0.026108f, 0.027634f, 0.029221f, 0.030762f, 0.032684f, 0.034576f, 0.036621f, 0.038605f,
+ 0.040985f, 0.043488f, 0.046021f, 0.049042f, 0.051727f, 0.054901f, 0.058441f, 0.061981f, 0.065552f, 0.069885f, 0.074097f, 0.078857f,
+ 0.083923f, 0.088623f, 0.094360f, 0.099854f, 0.105957f, 0.111694f, 0.118164f, 0.124817f, 0.131836f, 0.138794f, 0.474365f, 0.522949f,
+ 0.532227f, 0.536621f, 0.538574f, 0.539062f, 0.000876f, 0.002020f, 0.002857f, 0.003855f, 0.004436f, 0.005009f, 0.005482f, 0.006130f,
+ 0.006588f, 0.007084f, 0.007656f, 0.008286f, 0.008949f, 0.009506f, 0.010025f, 0.010803f, 0.011444f, 0.012047f, 0.012802f, 0.013512f,
+ 0.014305f, 0.015282f, 0.016052f, 0.016846f, 0.017914f, 0.018829f, 0.019882f, 0.021027f, 0.022232f, 0.023453f, 0.024689f, 0.026169f,
+ 0.027573f, 0.029327f, 0.031036f, 0.032806f, 0.034882f, 0.036743f, 0.039032f, 0.041626f, 0.044312f, 0.046936f, 0.050018f, 0.053253f,
+ 0.056610f, 0.060272f, 0.064392f, 0.068542f, 0.072937f, 0.078003f, 0.082886f, 0.088318f, 0.093933f, 0.099670f, 0.106140f, 0.112000f,
+ 0.118713f, 0.125732f, 0.463135f, 0.513672f, 0.524414f, 0.528809f, 0.530762f, 0.532227f, 0.000573f, 0.001698f, 0.002670f, 0.003082f,
+ 0.003735f, 0.004318f, 0.004673f, 0.005161f, 0.005779f, 0.006203f, 0.006565f, 0.007015f, 0.007591f, 0.007965f, 0.008583f, 0.009094f,
+ 0.009491f, 0.010239f, 0.010780f, 0.011353f, 0.012047f, 0.012787f, 0.013504f, 0.014206f, 0.015060f, 0.015915f, 0.016708f, 0.017685f,
+ 0.018677f, 0.019653f, 0.020828f, 0.021866f, 0.023224f, 0.024445f, 0.025818f, 0.027557f, 0.029114f, 0.030991f, 0.032928f, 0.035034f,
+ 0.037201f, 0.039581f, 0.042328f, 0.045166f, 0.048157f, 0.051392f, 0.054962f, 0.058685f, 0.062988f, 0.067444f, 0.072021f, 0.077148f,
+ 0.082520f, 0.088196f, 0.093750f, 0.100403f, 0.106201f, 0.112976f, 0.450928f, 0.503906f, 0.515137f, 0.520020f, 0.522949f, 0.524414f,
+ 0.000643f, 0.001637f, 0.002197f, 0.002800f, 0.003376f, 0.003613f, 0.003914f, 0.004391f, 0.004742f, 0.005150f, 0.005466f, 0.005924f,
+ 0.006344f, 0.006645f, 0.007046f, 0.007591f, 0.008118f, 0.008560f, 0.008934f, 0.009529f, 0.010147f, 0.010651f, 0.011276f, 0.011787f,
+ 0.012543f, 0.013229f, 0.013916f, 0.014740f, 0.015564f, 0.016388f, 0.017258f, 0.018188f, 0.019257f, 0.020355f, 0.021729f, 0.022766f,
+ 0.024277f, 0.025696f, 0.027237f, 0.029022f, 0.030945f, 0.033020f, 0.035248f, 0.037689f, 0.040405f, 0.043182f, 0.046295f, 0.049866f,
+ 0.053528f, 0.057526f, 0.061920f, 0.066284f, 0.071716f, 0.077209f, 0.082703f, 0.088196f, 0.094177f, 0.101074f, 0.438965f, 0.494629f,
+ 0.507324f, 0.512207f, 0.515137f, 0.516113f, 0.000484f, 0.001272f, 0.001968f, 0.002327f, 0.002573f, 0.003054f, 0.003338f, 0.003660f,
+ 0.003906f, 0.004303f, 0.004658f, 0.004921f, 0.005222f, 0.005547f, 0.005878f, 0.006290f, 0.006542f, 0.007015f, 0.007442f, 0.007851f,
+ 0.008339f, 0.008713f, 0.009247f, 0.009811f, 0.010345f, 0.010849f, 0.011490f, 0.012123f, 0.012733f, 0.013428f, 0.014183f, 0.014961f,
+ 0.015839f, 0.016815f, 0.017731f, 0.018768f, 0.019821f, 0.021072f, 0.022385f, 0.023727f, 0.025345f, 0.027084f, 0.028946f, 0.030914f,
+ 0.033295f, 0.035614f, 0.038513f, 0.041473f, 0.044678f, 0.048462f, 0.052338f, 0.056671f, 0.061310f, 0.066101f, 0.071533f, 0.077148f,
+ 0.083069f, 0.089172f, 0.427246f, 0.485352f, 0.498535f, 0.503906f, 0.508301f, 0.509766f, 0.000416f, 0.001121f, 0.001410f, 0.001959f,
+ 0.002159f, 0.002558f, 0.002724f, 0.002939f, 0.003220f, 0.003447f, 0.003733f, 0.003944f, 0.004219f, 0.004578f, 0.004810f, 0.005100f,
+ 0.005402f, 0.005783f, 0.006077f, 0.006382f, 0.006729f, 0.007141f, 0.007526f, 0.007965f, 0.008354f, 0.008858f, 0.009300f, 0.009789f,
+ 0.010452f, 0.010986f, 0.011658f, 0.012131f, 0.012833f, 0.013702f, 0.014435f, 0.015266f, 0.016113f, 0.017136f, 0.018143f, 0.019241f,
+ 0.020493f, 0.021820f, 0.023346f, 0.025085f, 0.027023f, 0.028976f, 0.031174f, 0.033966f, 0.036743f, 0.039856f, 0.043396f, 0.047180f,
+ 0.051605f, 0.056152f, 0.061127f, 0.066284f, 0.072021f, 0.078247f, 0.415283f, 0.475586f, 0.490234f, 0.496338f, 0.499756f, 0.501953f,
+ 0.000493f, 0.001126f, 0.001391f, 0.001574f, 0.001786f, 0.002073f, 0.002188f, 0.002417f, 0.002657f, 0.002785f, 0.002964f, 0.003189f,
+ 0.003384f, 0.003687f, 0.003859f, 0.004124f, 0.004330f, 0.004555f, 0.004890f, 0.005119f, 0.005451f, 0.005749f, 0.006054f, 0.006348f,
+ 0.006683f, 0.007050f, 0.007458f, 0.007889f, 0.008339f, 0.008751f, 0.009323f, 0.009766f, 0.010353f, 0.010887f, 0.011520f, 0.012192f,
+ 0.012932f, 0.013748f, 0.014542f, 0.015434f, 0.016434f, 0.017471f, 0.018723f, 0.019989f, 0.021500f, 0.023117f, 0.024948f, 0.027100f,
+ 0.029770f, 0.032166f, 0.035248f, 0.038696f, 0.042633f, 0.046875f, 0.051605f, 0.056427f, 0.061859f, 0.067688f, 0.403320f, 0.467041f,
+ 0.480957f, 0.487793f, 0.491699f, 0.494385f, 0.000336f, 0.000673f, 0.001150f, 0.001274f, 0.001482f, 0.001630f, 0.001748f, 0.001904f,
+ 0.002087f, 0.002232f, 0.002306f, 0.002497f, 0.002672f, 0.002872f, 0.003092f, 0.003225f, 0.003387f, 0.003553f, 0.003819f, 0.003979f,
+ 0.004230f, 0.004517f, 0.004738f, 0.005016f, 0.005322f, 0.005569f, 0.005848f, 0.006184f, 0.006573f, 0.006851f, 0.007271f, 0.007660f,
+ 0.008064f, 0.008568f, 0.009048f, 0.009567f, 0.010139f, 0.010788f, 0.011391f, 0.012161f, 0.012939f, 0.013763f, 0.014694f, 0.015717f,
+ 0.016815f, 0.018097f, 0.019714f, 0.021149f, 0.023270f, 0.025421f, 0.028015f, 0.030991f, 0.034271f, 0.038116f, 0.042328f, 0.046997f,
+ 0.052094f, 0.057770f, 0.391113f, 0.457031f, 0.472412f, 0.479736f, 0.484375f, 0.486816f, 0.000309f, 0.000612f, 0.000953f, 0.001086f,
+ 0.001191f, 0.001281f, 0.001351f, 0.001442f, 0.001610f, 0.001733f, 0.001783f, 0.001991f, 0.002087f, 0.002232f, 0.002337f, 0.002495f,
+ 0.002611f, 0.002775f, 0.002935f, 0.003101f, 0.003302f, 0.003496f, 0.003622f, 0.003839f, 0.004047f, 0.004265f, 0.004494f, 0.004738f,
+ 0.005039f, 0.005272f, 0.005650f, 0.005898f, 0.006210f, 0.006588f, 0.006950f, 0.007332f, 0.007782f, 0.008240f, 0.008766f, 0.009331f,
+ 0.009964f, 0.010612f, 0.011314f, 0.012062f, 0.013023f, 0.014038f, 0.015007f, 0.016251f, 0.017761f, 0.019501f, 0.021530f, 0.023926f,
+ 0.026718f, 0.030106f, 0.033905f, 0.038361f, 0.043060f, 0.048370f, 0.379395f, 0.446777f, 0.464111f, 0.471191f, 0.475586f, 0.479492f,
+ 0.000439f, 0.000476f, 0.000672f, 0.000752f, 0.000810f, 0.000949f, 0.001011f, 0.001121f, 0.001160f, 0.001249f, 0.001408f, 0.001493f,
+ 0.001591f, 0.001719f, 0.001788f, 0.001845f, 0.001982f, 0.002106f, 0.002201f, 0.002357f, 0.002460f, 0.002598f, 0.002724f, 0.002869f,
+ 0.003036f, 0.003187f, 0.003397f, 0.003569f, 0.003763f, 0.004017f, 0.004211f, 0.004414f, 0.004704f, 0.004890f, 0.005234f, 0.005524f,
+ 0.005825f, 0.006187f, 0.006535f, 0.006977f, 0.007423f, 0.007874f, 0.008553f, 0.009079f, 0.009857f, 0.010567f, 0.011360f, 0.012306f,
+ 0.013390f, 0.014702f, 0.016220f, 0.017960f, 0.020157f, 0.022995f, 0.026352f, 0.030212f, 0.034790f, 0.039459f, 0.368408f, 0.437744f,
+ 0.455322f, 0.463379f, 0.468018f, 0.471436f, 0.000202f, 0.000437f, 0.000488f, 0.000579f, 0.000664f, 0.000692f, 0.000792f, 0.000762f,
+ 0.000875f, 0.000949f, 0.001038f, 0.001068f, 0.001116f, 0.001196f, 0.001300f, 0.001352f, 0.001458f, 0.001529f, 0.001623f, 0.001667f,
+ 0.001770f, 0.001884f, 0.001989f, 0.002071f, 0.002203f, 0.002310f, 0.002445f, 0.002556f, 0.002680f, 0.002876f, 0.002991f, 0.003206f,
+ 0.003365f, 0.003531f, 0.003759f, 0.003956f, 0.004227f, 0.004513f, 0.004768f, 0.005074f, 0.005402f, 0.005756f, 0.006142f, 0.006603f,
+ 0.007160f, 0.007645f, 0.008339f, 0.008987f, 0.009819f, 0.010780f, 0.011803f, 0.013153f, 0.014763f, 0.016876f, 0.019623f, 0.022995f,
+ 0.026978f, 0.031708f, 0.356445f, 0.428223f, 0.446533f, 0.455078f, 0.460449f, 0.463379f, 0.000126f, 0.000241f, 0.000344f, 0.000353f,
+ 0.000437f, 0.000522f, 0.000513f, 0.000552f, 0.000613f, 0.000699f, 0.000717f, 0.000727f, 0.000763f, 0.000848f, 0.000877f, 0.000956f,
+ 0.000963f, 0.001068f, 0.001128f, 0.001170f, 0.001238f, 0.001311f, 0.001385f, 0.001454f, 0.001534f, 0.001603f, 0.001714f, 0.001779f,
+ 0.001885f, 0.002016f, 0.002092f, 0.002214f, 0.002331f, 0.002460f, 0.002613f, 0.002777f, 0.002924f, 0.003120f, 0.003298f, 0.003496f,
+ 0.003708f, 0.004009f, 0.004292f, 0.004601f, 0.004951f, 0.005341f, 0.005772f, 0.006260f, 0.006901f, 0.007572f, 0.008324f, 0.009300f,
+ 0.010445f, 0.011848f, 0.013870f, 0.016678f, 0.020218f, 0.024536f, 0.345703f, 0.419189f, 0.437500f, 0.447021f, 0.452393f, 0.455811f,
+ 0.000146f, 0.000240f, 0.000268f, 0.000268f, 0.000310f, 0.000311f, 0.000331f, 0.000366f, 0.000410f, 0.000447f, 0.000446f, 0.000517f,
+ 0.000511f, 0.000571f, 0.000596f, 0.000618f, 0.000674f, 0.000691f, 0.000723f, 0.000762f, 0.000822f, 0.000856f, 0.000912f, 0.000950f,
+ 0.001014f, 0.001049f, 0.001128f, 0.001188f, 0.001237f, 0.001303f, 0.001371f, 0.001466f, 0.001532f, 0.001623f, 0.001701f, 0.001805f,
+ 0.001945f, 0.002035f, 0.002186f, 0.002329f, 0.002460f, 0.002632f, 0.002819f, 0.003012f, 0.003271f, 0.003550f, 0.003819f, 0.004162f,
+ 0.004539f, 0.005024f, 0.005585f, 0.006233f, 0.007050f, 0.008072f, 0.009331f, 0.011269f, 0.014160f, 0.018112f, 0.333740f, 0.408447f,
+ 0.428711f, 0.438232f, 0.443359f, 0.447510f, 0.000053f, 0.000163f, 0.000155f, 0.000160f, 0.000191f, 0.000228f, 0.000206f, 0.000233f,
+ 0.000248f, 0.000263f, 0.000267f, 0.000294f, 0.000324f, 0.000335f, 0.000364f, 0.000378f, 0.000396f, 0.000435f, 0.000445f, 0.000490f,
+ 0.000502f, 0.000522f, 0.000543f, 0.000582f, 0.000619f, 0.000665f, 0.000679f, 0.000705f, 0.000755f, 0.000797f, 0.000856f, 0.000887f,
+ 0.000953f, 0.000988f, 0.001043f, 0.001103f, 0.001177f, 0.001256f, 0.001331f, 0.001410f, 0.001508f, 0.001612f, 0.001734f, 0.001873f,
+ 0.001999f, 0.002163f, 0.002378f, 0.002565f, 0.002827f, 0.003119f, 0.003479f, 0.003899f, 0.004463f, 0.005116f, 0.005951f, 0.007153f,
+ 0.009163f, 0.012535f, 0.322510f, 0.400146f, 0.420654f, 0.430176f, 0.436523f, 0.440430f, 0.000097f, 0.000107f, 0.000095f, 0.000087f,
+ 0.000107f, 0.000110f, 0.000137f, 0.000139f, 0.000140f, 0.000147f, 0.000168f, 0.000175f, 0.000177f, 0.000184f, 0.000210f, 0.000200f,
+ 0.000224f, 0.000239f, 0.000246f, 0.000258f, 0.000278f, 0.000288f, 0.000312f, 0.000324f, 0.000347f, 0.000368f, 0.000382f, 0.000395f,
+ 0.000418f, 0.000440f, 0.000471f, 0.000495f, 0.000521f, 0.000547f, 0.000577f, 0.000620f, 0.000649f, 0.000695f, 0.000749f, 0.000785f,
+ 0.000838f, 0.000897f, 0.000972f, 0.001028f, 0.001118f, 0.001204f, 0.001316f, 0.001432f, 0.001580f, 0.001748f, 0.001961f, 0.002207f,
+ 0.002533f, 0.002941f, 0.003487f, 0.004223f, 0.005371f, 0.007809f, 0.311523f, 0.390381f, 0.411377f, 0.421875f, 0.428467f, 0.432617f,
+ 0.000000f, 0.000055f, 0.000046f, 0.000054f, 0.000060f, 0.000058f, 0.000060f, 0.000068f, 0.000068f, 0.000082f, 0.000076f, 0.000078f,
+ 0.000092f, 0.000087f, 0.000091f, 0.000097f, 0.000105f, 0.000115f, 0.000118f, 0.000124f, 0.000128f, 0.000133f, 0.000139f, 0.000154f,
+ 0.000160f, 0.000172f, 0.000175f, 0.000191f, 0.000201f, 0.000211f, 0.000221f, 0.000238f, 0.000242f, 0.000257f, 0.000277f, 0.000295f,
+ 0.000309f, 0.000326f, 0.000351f, 0.000375f, 0.000400f, 0.000428f, 0.000459f, 0.000490f, 0.000535f, 0.000579f, 0.000626f, 0.000683f,
+ 0.000754f, 0.000836f, 0.000952f, 0.001064f, 0.001237f, 0.001460f, 0.001751f, 0.002157f, 0.002800f, 0.004189f, 0.299561f, 0.380127f,
+ 0.403076f, 0.413574f, 0.419922f, 0.424072f, 0.000059f, 0.000039f, 0.000032f, 0.000028f, 0.000025f, 0.000025f, 0.000025f, 0.000024f,
+ 0.000023f, 0.000024f, 0.000026f, 0.000034f, 0.000029f, 0.000031f, 0.000038f, 0.000040f, 0.000042f, 0.000043f, 0.000042f, 0.000043f,
+ 0.000048f, 0.000054f, 0.000058f, 0.000056f, 0.000060f, 0.000062f, 0.000066f, 0.000069f, 0.000072f, 0.000078f, 0.000082f, 0.000085f,
+ 0.000093f, 0.000096f, 0.000099f, 0.000106f, 0.000116f, 0.000123f, 0.000132f, 0.000140f, 0.000150f, 0.000154f, 0.000167f, 0.000184f,
+ 0.000192f, 0.000212f, 0.000231f, 0.000251f, 0.000282f, 0.000314f, 0.000350f, 0.000401f, 0.000463f, 0.000554f, 0.000679f, 0.000861f,
+ 0.001157f, 0.001750f, 0.289307f, 0.371582f, 0.394043f, 0.406006f, 0.412109f, 0.417236f, 0.000031f, 0.000020f, 0.000016f, 0.000014f,
+ 0.000013f, 0.000012f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000008f, 0.000008f, 0.000009f,
+ 0.000009f, 0.000007f, 0.000008f, 0.000008f, 0.000010f, 0.000011f, 0.000012f, 0.000013f, 0.000013f, 0.000013f, 0.000014f, 0.000017f,
+ 0.000017f, 0.000016f, 0.000018f, 0.000019f, 0.000021f, 0.000021f, 0.000022f, 0.000025f, 0.000027f, 0.000025f, 0.000028f, 0.000030f,
+ 0.000033f, 0.000036f, 0.000038f, 0.000040f, 0.000042f, 0.000047f, 0.000052f, 0.000057f, 0.000060f, 0.000068f, 0.000073f, 0.000089f,
+ 0.000104f, 0.000124f, 0.000153f, 0.000204f, 0.000293f, 0.000497f, 0.278076f, 0.362793f, 0.385498f, 0.397705f, 0.405029f, 0.409912f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000004f, 0.000005f, 0.000005f, 0.000008f, 0.000012f, 0.000026f, 0.267822f, 0.353027f,
+ 0.376953f, 0.388916f, 0.395996f, 0.401367f,
+ },
+ {
+ 0.006824f, 0.021286f, 0.036285f, 0.051208f, 0.066467f, 0.082825f, 0.098694f, 0.114563f, 0.130737f, 0.146973f, 0.162720f, 0.179932f,
+ 0.196411f, 0.212646f, 0.229370f, 0.246338f, 0.263184f, 0.279785f, 0.297363f, 0.314209f, 0.331055f, 0.348389f, 0.365479f, 0.383301f,
+ 0.400146f, 0.417725f, 0.435303f, 0.451904f, 0.469971f, 0.486816f, 0.503906f, 0.521484f, 0.539551f, 0.556641f, 0.573730f, 0.592285f,
+ 0.609375f, 0.627441f, 0.644531f, 0.662598f, 0.679688f, 0.696777f, 0.714355f, 0.731934f, 0.749512f, 0.768066f, 0.784180f, 0.802246f,
+ 0.820312f, 0.837891f, 0.854980f, 0.871582f, 0.889648f, 0.906738f, 0.924805f, 0.941406f, 0.959473f, 0.976074f, 0.953125f, 0.895020f,
+ 0.857422f, 0.827637f, 0.803223f, 0.781738f, 0.006741f, 0.020706f, 0.035187f, 0.049866f, 0.065125f, 0.079895f, 0.095581f, 0.111206f,
+ 0.126953f, 0.142822f, 0.158569f, 0.174561f, 0.190796f, 0.207031f, 0.223511f, 0.239380f, 0.256104f, 0.272705f, 0.289307f, 0.305664f,
+ 0.322754f, 0.338867f, 0.356201f, 0.372314f, 0.389404f, 0.406494f, 0.423828f, 0.440430f, 0.457520f, 0.474854f, 0.491211f, 0.508789f,
+ 0.525391f, 0.541992f, 0.559082f, 0.576660f, 0.594238f, 0.610840f, 0.627930f, 0.645508f, 0.662598f, 0.679199f, 0.696289f, 0.713379f,
+ 0.731445f, 0.747559f, 0.765137f, 0.782715f, 0.799805f, 0.816895f, 0.834473f, 0.851074f, 0.868164f, 0.884766f, 0.902344f, 0.919434f,
+ 0.936523f, 0.953613f, 0.942871f, 0.887695f, 0.851562f, 0.823730f, 0.799805f, 0.779297f, 0.006504f, 0.020004f, 0.033875f, 0.048676f,
+ 0.063110f, 0.077759f, 0.092712f, 0.108032f, 0.123230f, 0.138672f, 0.153931f, 0.170044f, 0.185791f, 0.200806f, 0.217041f, 0.233276f,
+ 0.248901f, 0.265137f, 0.280762f, 0.297363f, 0.313721f, 0.329834f, 0.346680f, 0.363037f, 0.378418f, 0.395752f, 0.411621f, 0.428467f,
+ 0.445312f, 0.461670f, 0.479004f, 0.494873f, 0.511230f, 0.527832f, 0.544434f, 0.561523f, 0.578613f, 0.594727f, 0.611328f, 0.628906f,
+ 0.645508f, 0.662109f, 0.679199f, 0.695312f, 0.712402f, 0.729004f, 0.746094f, 0.762695f, 0.779297f, 0.796387f, 0.812500f, 0.829590f,
+ 0.846191f, 0.863281f, 0.879395f, 0.896973f, 0.914062f, 0.930176f, 0.932129f, 0.879395f, 0.845703f, 0.818848f, 0.795898f, 0.776367f,
+ 0.006226f, 0.019318f, 0.032959f, 0.046631f, 0.060699f, 0.075745f, 0.089966f, 0.104553f, 0.119385f, 0.134277f, 0.149292f, 0.164917f,
+ 0.179932f, 0.195190f, 0.210693f, 0.226562f, 0.242188f, 0.257568f, 0.273438f, 0.289062f, 0.304932f, 0.320557f, 0.336426f, 0.352539f,
+ 0.368652f, 0.384766f, 0.400391f, 0.417236f, 0.433105f, 0.448730f, 0.465088f, 0.481689f, 0.497559f, 0.513672f, 0.528809f, 0.546875f,
+ 0.562500f, 0.578613f, 0.595215f, 0.612793f, 0.627930f, 0.645508f, 0.661621f, 0.677246f, 0.693848f, 0.709961f, 0.726562f, 0.743164f,
+ 0.759766f, 0.774902f, 0.791992f, 0.808594f, 0.825195f, 0.841309f, 0.856934f, 0.874023f, 0.890625f, 0.907715f, 0.921387f, 0.872070f,
+ 0.839355f, 0.813477f, 0.791504f, 0.772461f, 0.005928f, 0.018997f, 0.031830f, 0.045380f, 0.059235f, 0.072754f, 0.087463f, 0.101562f,
+ 0.115723f, 0.130371f, 0.145264f, 0.159668f, 0.175049f, 0.189453f, 0.204468f, 0.219482f, 0.234497f, 0.250000f, 0.266113f, 0.280273f,
+ 0.295410f, 0.311768f, 0.327393f, 0.343018f, 0.357422f, 0.373779f, 0.389404f, 0.404785f, 0.421143f, 0.437012f, 0.452881f, 0.468262f,
+ 0.484375f, 0.499512f, 0.515137f, 0.531738f, 0.546875f, 0.562500f, 0.579102f, 0.595215f, 0.610840f, 0.627441f, 0.643555f, 0.659180f,
+ 0.674805f, 0.691406f, 0.708008f, 0.723145f, 0.738770f, 0.755371f, 0.771484f, 0.787598f, 0.803711f, 0.819824f, 0.835449f, 0.851562f,
+ 0.867676f, 0.884277f, 0.910156f, 0.864258f, 0.832520f, 0.808105f, 0.787109f, 0.769043f, 0.005939f, 0.018066f, 0.030991f, 0.043488f,
+ 0.057312f, 0.070557f, 0.084473f, 0.098328f, 0.112610f, 0.126587f, 0.140259f, 0.154907f, 0.169678f, 0.184326f, 0.198608f, 0.213379f,
+ 0.227783f, 0.242065f, 0.257568f, 0.272705f, 0.287109f, 0.302246f, 0.318115f, 0.333252f, 0.347656f, 0.362549f, 0.378418f, 0.393555f,
+ 0.408936f, 0.423828f, 0.439697f, 0.455078f, 0.471191f, 0.484863f, 0.500488f, 0.517578f, 0.532227f, 0.547363f, 0.562500f, 0.579102f,
+ 0.594727f, 0.610352f, 0.625488f, 0.641602f, 0.657227f, 0.671875f, 0.687500f, 0.704102f, 0.719238f, 0.733887f, 0.750488f, 0.767090f,
+ 0.782715f, 0.798340f, 0.813965f, 0.830566f, 0.845215f, 0.862305f, 0.899902f, 0.855469f, 0.825684f, 0.801758f, 0.782227f, 0.764648f,
+ 0.005684f, 0.017639f, 0.030334f, 0.042572f, 0.055298f, 0.068054f, 0.081787f, 0.095276f, 0.108765f, 0.122192f, 0.136353f, 0.150513f,
+ 0.164307f, 0.178467f, 0.192627f, 0.206665f, 0.221436f, 0.234985f, 0.249634f, 0.264404f, 0.278564f, 0.293213f, 0.308350f, 0.321533f,
+ 0.337646f, 0.353027f, 0.367432f, 0.381592f, 0.395996f, 0.411865f, 0.426758f, 0.441895f, 0.456543f, 0.471680f, 0.485840f, 0.501465f,
+ 0.517090f, 0.531738f, 0.546387f, 0.562012f, 0.576660f, 0.592773f, 0.608398f, 0.623047f, 0.638672f, 0.654297f, 0.668457f, 0.684082f,
+ 0.699707f, 0.714844f, 0.730469f, 0.745605f, 0.761230f, 0.777832f, 0.791504f, 0.807617f, 0.823242f, 0.839355f, 0.889160f, 0.847656f,
+ 0.818848f, 0.796387f, 0.776855f, 0.760254f, 0.005417f, 0.017136f, 0.028778f, 0.041016f, 0.054047f, 0.066528f, 0.079590f, 0.092102f,
+ 0.105225f, 0.118652f, 0.131714f, 0.145630f, 0.158813f, 0.172607f, 0.186523f, 0.200317f, 0.213745f, 0.227905f, 0.242188f, 0.256104f,
+ 0.270020f, 0.283936f, 0.299072f, 0.312744f, 0.327148f, 0.341797f, 0.355957f, 0.369629f, 0.384766f, 0.399414f, 0.413574f, 0.427490f,
+ 0.443115f, 0.457764f, 0.472656f, 0.487061f, 0.501465f, 0.516602f, 0.530762f, 0.545898f, 0.560547f, 0.574707f, 0.589844f, 0.605469f,
+ 0.619629f, 0.633301f, 0.648926f, 0.665527f, 0.679688f, 0.694824f, 0.709961f, 0.725586f, 0.739746f, 0.755371f, 0.770020f, 0.786133f,
+ 0.802246f, 0.817383f, 0.877930f, 0.838867f, 0.812012f, 0.790039f, 0.771973f, 0.755371f, 0.005520f, 0.016464f, 0.027695f, 0.039948f,
+ 0.051575f, 0.063965f, 0.076660f, 0.089111f, 0.101807f, 0.114319f, 0.126953f, 0.140381f, 0.153564f, 0.166992f, 0.180298f, 0.193970f,
+ 0.207153f, 0.220337f, 0.234131f, 0.248169f, 0.261475f, 0.275146f, 0.288818f, 0.302734f, 0.316162f, 0.330566f, 0.345459f, 0.358887f,
+ 0.372803f, 0.386719f, 0.401367f, 0.415527f, 0.429199f, 0.443848f, 0.458008f, 0.472412f, 0.486572f, 0.500977f, 0.515137f, 0.529785f,
+ 0.544434f, 0.558105f, 0.572754f, 0.587891f, 0.601074f, 0.617188f, 0.631836f, 0.645020f, 0.660645f, 0.674805f, 0.689453f, 0.704590f,
+ 0.719727f, 0.734375f, 0.750000f, 0.764160f, 0.780273f, 0.794922f, 0.866699f, 0.830566f, 0.804688f, 0.784180f, 0.766113f, 0.750977f,
+ 0.005222f, 0.016022f, 0.026962f, 0.038086f, 0.050049f, 0.061798f, 0.074158f, 0.085876f, 0.098145f, 0.110718f, 0.122986f, 0.135864f,
+ 0.148438f, 0.161133f, 0.173584f, 0.187378f, 0.199707f, 0.213501f, 0.226440f, 0.240112f, 0.252441f, 0.266113f, 0.279785f, 0.292725f,
+ 0.306152f, 0.320068f, 0.333984f, 0.347900f, 0.361572f, 0.374512f, 0.387695f, 0.402344f, 0.416504f, 0.429688f, 0.443604f, 0.458008f,
+ 0.471680f, 0.485596f, 0.499023f, 0.513184f, 0.527832f, 0.541016f, 0.555664f, 0.569336f, 0.583984f, 0.598633f, 0.612793f, 0.626465f,
+ 0.641602f, 0.656250f, 0.669922f, 0.684570f, 0.698730f, 0.713867f, 0.728516f, 0.742188f, 0.757812f, 0.771484f, 0.855957f, 0.822266f,
+ 0.797852f, 0.777832f, 0.760742f, 0.746094f, 0.004944f, 0.015327f, 0.026230f, 0.037201f, 0.048187f, 0.059448f, 0.071167f, 0.082642f,
+ 0.094727f, 0.106506f, 0.119019f, 0.130371f, 0.143555f, 0.155640f, 0.167725f, 0.180908f, 0.193604f, 0.206177f, 0.218506f, 0.231812f,
+ 0.244873f, 0.257568f, 0.270996f, 0.283203f, 0.296387f, 0.309814f, 0.322754f, 0.336670f, 0.348877f, 0.362061f, 0.376465f, 0.389893f,
+ 0.402588f, 0.415283f, 0.429443f, 0.443115f, 0.457031f, 0.470459f, 0.483887f, 0.497314f, 0.511230f, 0.524414f, 0.538574f, 0.551758f,
+ 0.565918f, 0.579590f, 0.593750f, 0.606934f, 0.621094f, 0.635254f, 0.649902f, 0.664062f, 0.678223f, 0.692871f, 0.707031f, 0.721191f,
+ 0.735840f, 0.750488f, 0.846191f, 0.813477f, 0.790527f, 0.770996f, 0.754883f, 0.740723f, 0.004951f, 0.014656f, 0.025253f, 0.035309f,
+ 0.046417f, 0.057465f, 0.068665f, 0.079773f, 0.091370f, 0.102844f, 0.114441f, 0.126099f, 0.138062f, 0.150391f, 0.161987f, 0.174561f,
+ 0.186523f, 0.198730f, 0.211060f, 0.223267f, 0.235352f, 0.248779f, 0.260986f, 0.274414f, 0.286621f, 0.298584f, 0.312256f, 0.324463f,
+ 0.337158f, 0.350342f, 0.363281f, 0.376953f, 0.389404f, 0.402344f, 0.415283f, 0.428955f, 0.441162f, 0.455322f, 0.467285f, 0.481201f,
+ 0.493896f, 0.507324f, 0.520996f, 0.534668f, 0.547852f, 0.561035f, 0.575195f, 0.588867f, 0.603027f, 0.616211f, 0.630371f, 0.643555f,
+ 0.658203f, 0.671875f, 0.686035f, 0.699707f, 0.714844f, 0.729492f, 0.833984f, 0.804688f, 0.782227f, 0.764160f, 0.749512f, 0.735352f,
+ 0.004700f, 0.014343f, 0.024200f, 0.034515f, 0.044586f, 0.055176f, 0.066162f, 0.077209f, 0.087830f, 0.098816f, 0.110413f, 0.121826f,
+ 0.132690f, 0.144897f, 0.156372f, 0.168213f, 0.179443f, 0.191650f, 0.203369f, 0.215088f, 0.227661f, 0.239990f, 0.251709f, 0.263916f,
+ 0.276611f, 0.289551f, 0.301270f, 0.313965f, 0.325928f, 0.338135f, 0.350586f, 0.363037f, 0.376465f, 0.388428f, 0.401123f, 0.414062f,
+ 0.426514f, 0.439209f, 0.452393f, 0.465088f, 0.478271f, 0.491455f, 0.503906f, 0.517090f, 0.530273f, 0.543457f, 0.556641f, 0.570312f,
+ 0.583008f, 0.597168f, 0.610352f, 0.624512f, 0.638184f, 0.651367f, 0.665527f, 0.679199f, 0.692871f, 0.708496f, 0.823242f, 0.796387f,
+ 0.774902f, 0.757812f, 0.742676f, 0.729980f, 0.004395f, 0.013802f, 0.023499f, 0.033173f, 0.043121f, 0.053345f, 0.063538f, 0.073730f,
+ 0.085083f, 0.095581f, 0.106140f, 0.116760f, 0.127930f, 0.139160f, 0.150757f, 0.161621f, 0.173096f, 0.184814f, 0.196289f, 0.207520f,
+ 0.219971f, 0.231201f, 0.242920f, 0.254150f, 0.266602f, 0.278320f, 0.290527f, 0.302490f, 0.314209f, 0.326904f, 0.338867f, 0.349854f,
+ 0.362305f, 0.375488f, 0.387451f, 0.400146f, 0.412354f, 0.424805f, 0.436768f, 0.449219f, 0.461914f, 0.475098f, 0.487061f, 0.500000f,
+ 0.512695f, 0.525391f, 0.538574f, 0.551758f, 0.564453f, 0.577148f, 0.590820f, 0.604004f, 0.618164f, 0.631348f, 0.644531f, 0.658203f,
+ 0.672363f, 0.686523f, 0.812500f, 0.786621f, 0.767090f, 0.750977f, 0.736816f, 0.724609f, 0.004425f, 0.013405f, 0.022385f, 0.032043f,
+ 0.041565f, 0.051605f, 0.061340f, 0.071106f, 0.081116f, 0.091125f, 0.101868f, 0.112671f, 0.123169f, 0.133667f, 0.144897f, 0.155029f,
+ 0.166748f, 0.177246f, 0.188599f, 0.199585f, 0.211182f, 0.222046f, 0.233643f, 0.245361f, 0.255615f, 0.268066f, 0.279053f, 0.291260f,
+ 0.303223f, 0.314209f, 0.325684f, 0.338379f, 0.349854f, 0.361572f, 0.374023f, 0.385254f, 0.397949f, 0.409912f, 0.421143f, 0.434082f,
+ 0.445801f, 0.457764f, 0.470215f, 0.482910f, 0.495361f, 0.508301f, 0.520996f, 0.534180f, 0.546387f, 0.560059f, 0.572266f, 0.584961f,
+ 0.597168f, 0.610840f, 0.624023f, 0.638184f, 0.650879f, 0.666016f, 0.801270f, 0.778320f, 0.760254f, 0.744141f, 0.730469f, 0.719238f,
+ 0.004261f, 0.012543f, 0.021591f, 0.031052f, 0.039734f, 0.049164f, 0.058838f, 0.068420f, 0.077881f, 0.087402f, 0.098145f, 0.108276f,
+ 0.118225f, 0.128784f, 0.138550f, 0.149292f, 0.159790f, 0.170654f, 0.181519f, 0.191772f, 0.203003f, 0.213623f, 0.225098f, 0.235107f,
+ 0.247070f, 0.257324f, 0.269287f, 0.280273f, 0.291260f, 0.302246f, 0.313721f, 0.325439f, 0.336670f, 0.348145f, 0.359619f, 0.371338f,
+ 0.382812f, 0.395020f, 0.406738f, 0.418213f, 0.429932f, 0.442139f, 0.454102f, 0.466309f, 0.479004f, 0.490723f, 0.502930f, 0.515625f,
+ 0.526855f, 0.540527f, 0.552246f, 0.565918f, 0.578613f, 0.591309f, 0.604492f, 0.617188f, 0.630859f, 0.644043f, 0.790039f, 0.769531f,
+ 0.751953f, 0.737305f, 0.724121f, 0.713379f, 0.003983f, 0.012329f, 0.020538f, 0.029312f, 0.038452f, 0.047241f, 0.056244f, 0.065552f,
+ 0.075195f, 0.084290f, 0.094238f, 0.103638f, 0.113403f, 0.123413f, 0.133057f, 0.143066f, 0.153076f, 0.163696f, 0.173584f, 0.184204f,
+ 0.194580f, 0.204834f, 0.215332f, 0.225952f, 0.237305f, 0.247803f, 0.258545f, 0.269531f, 0.280518f, 0.291260f, 0.301758f, 0.312988f,
+ 0.324219f, 0.335205f, 0.346191f, 0.357178f, 0.368896f, 0.380127f, 0.391113f, 0.403076f, 0.414551f, 0.426270f, 0.437500f, 0.449951f,
+ 0.460938f, 0.473389f, 0.485596f, 0.497314f, 0.509277f, 0.522461f, 0.533691f, 0.546875f, 0.558594f, 0.571289f, 0.583496f, 0.596680f,
+ 0.608887f, 0.623047f, 0.778809f, 0.761230f, 0.744141f, 0.730957f, 0.718262f, 0.707031f, 0.003717f, 0.012016f, 0.020142f, 0.028137f,
+ 0.036682f, 0.045441f, 0.053711f, 0.062927f, 0.071777f, 0.080627f, 0.090210f, 0.099060f, 0.108643f, 0.118164f, 0.127808f, 0.137329f,
+ 0.147095f, 0.156128f, 0.166748f, 0.175903f, 0.186157f, 0.196655f, 0.206909f, 0.216797f, 0.227417f, 0.236816f, 0.247559f, 0.258301f,
+ 0.268799f, 0.278809f, 0.289795f, 0.299805f, 0.310547f, 0.321777f, 0.333008f, 0.343262f, 0.354492f, 0.365234f, 0.376953f, 0.387939f,
+ 0.398438f, 0.410400f, 0.421387f, 0.433105f, 0.444824f, 0.455811f, 0.467529f, 0.479736f, 0.491943f, 0.502930f, 0.515625f, 0.527344f,
+ 0.540039f, 0.551758f, 0.563965f, 0.576660f, 0.589844f, 0.602539f, 0.767578f, 0.751465f, 0.736328f, 0.723633f, 0.711914f, 0.701660f,
+ 0.003813f, 0.011337f, 0.019028f, 0.027252f, 0.035583f, 0.043396f, 0.051849f, 0.060028f, 0.068481f, 0.077026f, 0.086121f, 0.095093f,
+ 0.103821f, 0.112610f, 0.121765f, 0.131470f, 0.140503f, 0.149780f, 0.159058f, 0.168701f, 0.178711f, 0.187744f, 0.197998f, 0.207397f,
+ 0.217651f, 0.227661f, 0.236694f, 0.246704f, 0.257080f, 0.267334f, 0.277832f, 0.288330f, 0.298584f, 0.308838f, 0.319336f, 0.329590f,
+ 0.340332f, 0.351318f, 0.361816f, 0.372559f, 0.383301f, 0.395020f, 0.405273f, 0.416260f, 0.427734f, 0.439209f, 0.450195f, 0.462158f,
+ 0.473389f, 0.485107f, 0.497314f, 0.508301f, 0.520996f, 0.533203f, 0.544922f, 0.557617f, 0.568848f, 0.582031f, 0.757324f, 0.742676f,
+ 0.729004f, 0.716309f, 0.705566f, 0.695801f, 0.003633f, 0.011040f, 0.018280f, 0.026062f, 0.033569f, 0.041229f, 0.049591f, 0.057373f,
+ 0.065308f, 0.073975f, 0.082214f, 0.090393f, 0.099243f, 0.107544f, 0.116028f, 0.125854f, 0.134155f, 0.143311f, 0.151978f, 0.160767f,
+ 0.170410f, 0.179321f, 0.188477f, 0.198242f, 0.207764f, 0.217896f, 0.227051f, 0.236328f, 0.246338f, 0.256104f, 0.265869f, 0.276123f,
+ 0.285645f, 0.295898f, 0.306152f, 0.316162f, 0.326172f, 0.336914f, 0.347412f, 0.358154f, 0.368164f, 0.378906f, 0.389648f, 0.400146f,
+ 0.410889f, 0.421631f, 0.432861f, 0.444824f, 0.456055f, 0.466797f, 0.479004f, 0.490234f, 0.501465f, 0.514160f, 0.525879f, 0.537598f,
+ 0.549316f, 0.561523f, 0.745605f, 0.733887f, 0.721191f, 0.708496f, 0.699219f, 0.689453f, 0.003469f, 0.010429f, 0.017609f, 0.024612f,
+ 0.032135f, 0.039520f, 0.047516f, 0.055206f, 0.062347f, 0.070618f, 0.078308f, 0.085938f, 0.094727f, 0.102417f, 0.111511f, 0.119446f,
+ 0.127441f, 0.136475f, 0.144897f, 0.154175f, 0.162476f, 0.171509f, 0.180054f, 0.189697f, 0.198486f, 0.207886f, 0.216553f, 0.225830f,
+ 0.235229f, 0.244873f, 0.254395f, 0.263428f, 0.273193f, 0.283203f, 0.292969f, 0.302734f, 0.312744f, 0.322510f, 0.333008f, 0.342773f,
+ 0.353027f, 0.363037f, 0.374023f, 0.384521f, 0.395264f, 0.405762f, 0.416260f, 0.427002f, 0.438232f, 0.449219f, 0.460449f, 0.471924f,
+ 0.482910f, 0.494629f, 0.506348f, 0.517578f, 0.529785f, 0.541504f, 0.734375f, 0.725098f, 0.712891f, 0.701660f, 0.692383f, 0.683594f,
+ 0.003328f, 0.009804f, 0.016373f, 0.023727f, 0.030746f, 0.037994f, 0.044952f, 0.052032f, 0.059998f, 0.067383f, 0.074707f, 0.082214f,
+ 0.089783f, 0.097961f, 0.105774f, 0.114197f, 0.122131f, 0.129517f, 0.137695f, 0.146118f, 0.154419f, 0.163330f, 0.171997f, 0.180664f,
+ 0.188477f, 0.197388f, 0.206055f, 0.215332f, 0.224365f, 0.233765f, 0.242798f, 0.251709f, 0.260986f, 0.270020f, 0.279785f, 0.289062f,
+ 0.299561f, 0.308594f, 0.318115f, 0.328613f, 0.338135f, 0.348877f, 0.358154f, 0.368408f, 0.378174f, 0.388916f, 0.399658f, 0.410156f,
+ 0.420898f, 0.431885f, 0.442871f, 0.453369f, 0.463867f, 0.475342f, 0.486572f, 0.498535f, 0.510742f, 0.521973f, 0.723633f, 0.715820f,
+ 0.705078f, 0.694336f, 0.686035f, 0.677246f, 0.003090f, 0.009628f, 0.016129f, 0.022644f, 0.029068f, 0.036407f, 0.042633f, 0.049866f,
+ 0.056946f, 0.063904f, 0.071167f, 0.078186f, 0.085327f, 0.092896f, 0.100098f, 0.107788f, 0.115662f, 0.123230f, 0.131104f, 0.139160f,
+ 0.146973f, 0.154907f, 0.162964f, 0.171265f, 0.179565f, 0.188110f, 0.196777f, 0.204834f, 0.213745f, 0.222168f, 0.231079f, 0.239868f,
+ 0.248779f, 0.258057f, 0.267090f, 0.276611f, 0.285645f, 0.294434f, 0.304688f, 0.314209f, 0.323242f, 0.332520f, 0.342773f, 0.353027f,
+ 0.362549f, 0.373047f, 0.383057f, 0.393311f, 0.404053f, 0.414307f, 0.424561f, 0.435059f, 0.445801f, 0.456787f, 0.467773f, 0.479004f,
+ 0.490479f, 0.501953f, 0.712891f, 0.707031f, 0.696777f, 0.687500f, 0.679199f, 0.671387f, 0.003096f, 0.009026f, 0.015450f, 0.021606f,
+ 0.027695f, 0.034302f, 0.040833f, 0.047455f, 0.054077f, 0.060669f, 0.067444f, 0.074097f, 0.081604f, 0.088501f, 0.095337f, 0.102295f,
+ 0.109375f, 0.116821f, 0.124146f, 0.131592f, 0.139404f, 0.147217f, 0.155029f, 0.162231f, 0.170288f, 0.177979f, 0.186646f, 0.194092f,
+ 0.203247f, 0.211670f, 0.219604f, 0.228149f, 0.236816f, 0.245605f, 0.254639f, 0.263184f, 0.272217f, 0.281250f, 0.290527f, 0.299805f,
+ 0.308838f, 0.318604f, 0.327637f, 0.337646f, 0.347900f, 0.356934f, 0.367432f, 0.376953f, 0.387451f, 0.397217f, 0.407227f, 0.417480f,
+ 0.427979f, 0.439209f, 0.449463f, 0.459717f, 0.470947f, 0.482666f, 0.701172f, 0.698242f, 0.688477f, 0.680176f, 0.671875f, 0.665039f,
+ 0.002831f, 0.008789f, 0.014702f, 0.020523f, 0.026642f, 0.032684f, 0.038757f, 0.044708f, 0.051666f, 0.057312f, 0.063660f, 0.070190f,
+ 0.076904f, 0.083435f, 0.090454f, 0.097046f, 0.103821f, 0.110535f, 0.117981f, 0.124817f, 0.131714f, 0.138916f, 0.146606f, 0.153687f,
+ 0.161011f, 0.168823f, 0.176270f, 0.184570f, 0.192139f, 0.200317f, 0.208008f, 0.216309f, 0.224609f, 0.233032f, 0.241821f, 0.250244f,
+ 0.258789f, 0.268066f, 0.276611f, 0.285400f, 0.294678f, 0.303223f, 0.312500f, 0.322021f, 0.331787f, 0.340088f, 0.350830f, 0.360596f,
+ 0.369385f, 0.380371f, 0.389893f, 0.399658f, 0.410645f, 0.420654f, 0.430908f, 0.442383f, 0.452148f, 0.464111f, 0.690430f, 0.688965f,
+ 0.681152f, 0.672852f, 0.665039f, 0.658691f, 0.002712f, 0.008553f, 0.013878f, 0.019638f, 0.025360f, 0.030716f, 0.037231f, 0.042633f,
+ 0.048615f, 0.054810f, 0.060638f, 0.066650f, 0.072205f, 0.078796f, 0.085083f, 0.091492f, 0.097961f, 0.104065f, 0.110718f, 0.117859f,
+ 0.124207f, 0.130981f, 0.138550f, 0.145142f, 0.152588f, 0.160156f, 0.166992f, 0.174561f, 0.181885f, 0.189453f, 0.197754f, 0.205444f,
+ 0.213013f, 0.220825f, 0.229004f, 0.237061f, 0.246094f, 0.254639f, 0.262939f, 0.271484f, 0.280273f, 0.288818f, 0.298584f, 0.307129f,
+ 0.316162f, 0.325195f, 0.334229f, 0.344482f, 0.353516f, 0.363525f, 0.372803f, 0.382812f, 0.392822f, 0.402344f, 0.412842f, 0.423096f,
+ 0.433350f, 0.444092f, 0.679199f, 0.679688f, 0.672852f, 0.665039f, 0.658203f, 0.651855f, 0.002674f, 0.007828f, 0.013290f, 0.018723f,
+ 0.023743f, 0.029160f, 0.034790f, 0.040100f, 0.045929f, 0.051544f, 0.057068f, 0.063110f, 0.068359f, 0.074280f, 0.080078f, 0.086243f,
+ 0.092346f, 0.098206f, 0.104919f, 0.110779f, 0.117493f, 0.123291f, 0.130005f, 0.136963f, 0.143677f, 0.150635f, 0.157471f, 0.164307f,
+ 0.171631f, 0.179199f, 0.186279f, 0.193604f, 0.201904f, 0.209229f, 0.217163f, 0.224976f, 0.233154f, 0.240967f, 0.249634f, 0.258301f,
+ 0.266113f, 0.274414f, 0.283691f, 0.291748f, 0.301025f, 0.310059f, 0.319336f, 0.327148f, 0.337402f, 0.347168f, 0.355957f, 0.364746f,
+ 0.375488f, 0.385498f, 0.394043f, 0.405273f, 0.415283f, 0.426025f, 0.667969f, 0.670410f, 0.664551f, 0.657227f, 0.651367f, 0.645508f,
+ 0.002731f, 0.007622f, 0.012627f, 0.017868f, 0.022781f, 0.028107f, 0.032959f, 0.037811f, 0.043121f, 0.048615f, 0.053925f, 0.059235f,
+ 0.064514f, 0.070007f, 0.075562f, 0.080688f, 0.086914f, 0.092102f, 0.098083f, 0.104309f, 0.110107f, 0.115906f, 0.122314f, 0.128540f,
+ 0.135010f, 0.141479f, 0.147949f, 0.154663f, 0.161865f, 0.168579f, 0.175415f, 0.182739f, 0.191040f, 0.197510f, 0.205200f, 0.212891f,
+ 0.219971f, 0.228638f, 0.236328f, 0.244263f, 0.252686f, 0.260498f, 0.268799f, 0.278076f, 0.286133f, 0.294434f, 0.303223f, 0.312500f,
+ 0.320801f, 0.329834f, 0.339844f, 0.347656f, 0.357910f, 0.367676f, 0.376709f, 0.386963f, 0.396729f, 0.406982f, 0.656738f, 0.662598f,
+ 0.656738f, 0.649902f, 0.644531f, 0.638672f, 0.002411f, 0.007168f, 0.012238f, 0.016739f, 0.021957f, 0.026184f, 0.031311f, 0.035583f,
+ 0.041016f, 0.045685f, 0.050568f, 0.055573f, 0.060791f, 0.065735f, 0.070557f, 0.076111f, 0.081238f, 0.086792f, 0.092163f, 0.097534f,
+ 0.103271f, 0.108887f, 0.114563f, 0.120605f, 0.126587f, 0.132446f, 0.139038f, 0.145508f, 0.152100f, 0.158447f, 0.165527f, 0.171997f,
+ 0.178833f, 0.186035f, 0.193481f, 0.200928f, 0.207886f, 0.215820f, 0.222900f, 0.230713f, 0.238770f, 0.246948f, 0.255127f, 0.262695f,
+ 0.271484f, 0.280029f, 0.287842f, 0.296631f, 0.305420f, 0.313965f, 0.322754f, 0.331787f, 0.340576f, 0.350342f, 0.359375f, 0.369385f,
+ 0.379150f, 0.388184f, 0.645508f, 0.652832f, 0.648438f, 0.643066f, 0.637695f, 0.632324f, 0.002480f, 0.006691f, 0.011452f, 0.015900f,
+ 0.020828f, 0.024734f, 0.029327f, 0.033752f, 0.038513f, 0.042999f, 0.047638f, 0.052429f, 0.056671f, 0.061859f, 0.066040f, 0.071289f,
+ 0.075684f, 0.080688f, 0.086243f, 0.091248f, 0.096436f, 0.101562f, 0.107300f, 0.112366f, 0.118347f, 0.124146f, 0.130249f, 0.135864f,
+ 0.141968f, 0.148438f, 0.155029f, 0.161377f, 0.167969f, 0.174683f, 0.181641f, 0.188599f, 0.195679f, 0.203247f, 0.210449f, 0.217529f,
+ 0.225342f, 0.233398f, 0.241577f, 0.249023f, 0.256592f, 0.264893f, 0.273193f, 0.281494f, 0.289795f, 0.297607f, 0.306885f, 0.315430f,
+ 0.323730f, 0.333496f, 0.342529f, 0.351318f, 0.360840f, 0.370605f, 0.634766f, 0.643555f, 0.640625f, 0.635742f, 0.630859f, 0.625488f,
+ 0.002230f, 0.006477f, 0.010582f, 0.014870f, 0.019073f, 0.023270f, 0.027893f, 0.031860f, 0.036072f, 0.040253f, 0.044373f, 0.048706f,
+ 0.052856f, 0.057312f, 0.061859f, 0.066406f, 0.070984f, 0.075317f, 0.080139f, 0.084839f, 0.089661f, 0.094910f, 0.099792f, 0.104858f,
+ 0.110718f, 0.115356f, 0.121399f, 0.126831f, 0.132690f, 0.138672f, 0.145142f, 0.151001f, 0.157471f, 0.164185f, 0.170532f, 0.177002f,
+ 0.184082f, 0.191040f, 0.197876f, 0.205200f, 0.212402f, 0.219604f, 0.227295f, 0.234985f, 0.242188f, 0.250244f, 0.257812f, 0.266113f,
+ 0.274170f, 0.282471f, 0.290771f, 0.299072f, 0.307373f, 0.316162f, 0.326416f, 0.333984f, 0.343750f, 0.353271f, 0.622070f, 0.634277f,
+ 0.631836f, 0.627930f, 0.623535f, 0.619141f, 0.002220f, 0.006039f, 0.010353f, 0.014328f, 0.017838f, 0.022141f, 0.025742f, 0.029510f,
+ 0.033600f, 0.037781f, 0.041443f, 0.045502f, 0.049469f, 0.053436f, 0.057190f, 0.061462f, 0.065735f, 0.069946f, 0.074524f, 0.078674f,
+ 0.083069f, 0.087830f, 0.092468f, 0.097412f, 0.102783f, 0.107910f, 0.112793f, 0.118164f, 0.123901f, 0.129395f, 0.135132f, 0.140991f,
+ 0.147339f, 0.152954f, 0.159302f, 0.165527f, 0.172363f, 0.178589f, 0.185425f, 0.191895f, 0.199219f, 0.206665f, 0.213989f, 0.221069f,
+ 0.228516f, 0.236206f, 0.243042f, 0.251709f, 0.258789f, 0.266846f, 0.275146f, 0.283203f, 0.291260f, 0.300537f, 0.308350f, 0.317627f,
+ 0.326904f, 0.335938f, 0.611816f, 0.625000f, 0.624023f, 0.620117f, 0.616211f, 0.612793f, 0.001965f, 0.005882f, 0.009613f, 0.013184f,
+ 0.016785f, 0.020370f, 0.024384f, 0.027664f, 0.031311f, 0.035126f, 0.038727f, 0.042572f, 0.046112f, 0.049347f, 0.053253f, 0.056915f,
+ 0.060883f, 0.064697f, 0.068909f, 0.072693f, 0.076843f, 0.081055f, 0.085754f, 0.090088f, 0.094849f, 0.099609f, 0.104614f, 0.109741f,
+ 0.114746f, 0.119995f, 0.125488f, 0.130981f, 0.136719f, 0.142700f, 0.148315f, 0.154541f, 0.160522f, 0.166870f, 0.173828f, 0.179932f,
+ 0.186768f, 0.193604f, 0.200439f, 0.207764f, 0.214844f, 0.221802f, 0.228882f, 0.236328f, 0.244385f, 0.252197f, 0.259277f, 0.268066f,
+ 0.275635f, 0.283447f, 0.292236f, 0.301270f, 0.309570f, 0.318848f, 0.600098f, 0.616211f, 0.615234f, 0.612793f, 0.609375f, 0.605469f,
+ 0.001966f, 0.005653f, 0.009109f, 0.012428f, 0.015945f, 0.018967f, 0.022537f, 0.025894f, 0.029175f, 0.032440f, 0.035797f, 0.038818f,
+ 0.042389f, 0.046051f, 0.049072f, 0.052521f, 0.056335f, 0.059906f, 0.063293f, 0.067017f, 0.070923f, 0.075134f, 0.078979f, 0.083496f,
+ 0.087646f, 0.091980f, 0.096619f, 0.101196f, 0.105957f, 0.111145f, 0.116028f, 0.121277f, 0.126831f, 0.132080f, 0.137817f, 0.143311f,
+ 0.149780f, 0.155029f, 0.161621f, 0.167847f, 0.173950f, 0.180786f, 0.187622f, 0.194214f, 0.201050f, 0.207764f, 0.215210f, 0.222046f,
+ 0.229370f, 0.236816f, 0.244751f, 0.251953f, 0.260010f, 0.268311f, 0.276123f, 0.284180f, 0.293213f, 0.301514f, 0.588379f, 0.606934f,
+ 0.607422f, 0.604980f, 0.602051f, 0.599609f, 0.001963f, 0.005333f, 0.008377f, 0.011589f, 0.014450f, 0.017593f, 0.021133f, 0.023972f,
+ 0.027145f, 0.030075f, 0.033295f, 0.035858f, 0.038818f, 0.041992f, 0.045288f, 0.048279f, 0.051849f, 0.054840f, 0.058289f, 0.061737f,
+ 0.065186f, 0.068848f, 0.072632f, 0.076721f, 0.080505f, 0.084717f, 0.088806f, 0.093079f, 0.097717f, 0.102356f, 0.106934f, 0.111755f,
+ 0.116882f, 0.121887f, 0.127319f, 0.132935f, 0.138306f, 0.144287f, 0.149902f, 0.156250f, 0.162109f, 0.168579f, 0.174316f, 0.180908f,
+ 0.187500f, 0.194458f, 0.201538f, 0.208252f, 0.215210f, 0.222656f, 0.229980f, 0.237061f, 0.244629f, 0.252441f, 0.260254f, 0.267334f,
+ 0.276123f, 0.284180f, 0.576660f, 0.597656f, 0.599609f, 0.598145f, 0.595215f, 0.591797f, 0.001631f, 0.004906f, 0.007805f, 0.010826f,
+ 0.013802f, 0.016983f, 0.019485f, 0.022079f, 0.024750f, 0.027939f, 0.030136f, 0.033112f, 0.035797f, 0.038727f, 0.041443f, 0.044281f,
+ 0.047058f, 0.050018f, 0.053253f, 0.056396f, 0.059662f, 0.063049f, 0.066406f, 0.069946f, 0.073730f, 0.077454f, 0.081360f, 0.085388f,
+ 0.089417f, 0.093750f, 0.098267f, 0.102844f, 0.107727f, 0.112244f, 0.117615f, 0.122253f, 0.127441f, 0.133057f, 0.138550f, 0.144287f,
+ 0.150024f, 0.156250f, 0.161987f, 0.167969f, 0.174805f, 0.181274f, 0.187744f, 0.194580f, 0.201294f, 0.208374f, 0.215210f, 0.222412f,
+ 0.229736f, 0.237183f, 0.244629f, 0.252197f, 0.260010f, 0.269287f, 0.566406f, 0.588867f, 0.590820f, 0.590332f, 0.587891f, 0.585938f,
+ 0.001858f, 0.004318f, 0.007465f, 0.010246f, 0.012550f, 0.015793f, 0.018143f, 0.020782f, 0.022980f, 0.025116f, 0.027924f, 0.030106f,
+ 0.032623f, 0.035126f, 0.037720f, 0.040283f, 0.042847f, 0.045380f, 0.048492f, 0.051300f, 0.054321f, 0.057373f, 0.060516f, 0.063599f,
+ 0.067139f, 0.070496f, 0.074219f, 0.078003f, 0.081848f, 0.085754f, 0.089783f, 0.093994f, 0.098267f, 0.102783f, 0.107239f, 0.112366f,
+ 0.117371f, 0.122498f, 0.127686f, 0.132935f, 0.138428f, 0.144043f, 0.150024f, 0.155884f, 0.161865f, 0.168091f, 0.174316f, 0.180664f,
+ 0.187622f, 0.194214f, 0.200928f, 0.207520f, 0.214966f, 0.221680f, 0.229370f, 0.236816f, 0.244751f, 0.252441f, 0.553223f, 0.579102f,
+ 0.583496f, 0.582031f, 0.581055f, 0.579590f, 0.001425f, 0.004284f, 0.007019f, 0.009521f, 0.011894f, 0.014191f, 0.016632f, 0.018723f,
+ 0.021210f, 0.023209f, 0.025482f, 0.027344f, 0.029617f, 0.032043f, 0.034210f, 0.036407f, 0.039001f, 0.041077f, 0.043976f, 0.046448f,
+ 0.049133f, 0.051819f, 0.054932f, 0.057770f, 0.060730f, 0.063965f, 0.067322f, 0.070862f, 0.074280f, 0.077698f, 0.082031f, 0.085571f,
+ 0.089844f, 0.093994f, 0.098022f, 0.102722f, 0.107178f, 0.111877f, 0.116821f, 0.121887f, 0.127075f, 0.132446f, 0.138062f, 0.143799f,
+ 0.149414f, 0.155518f, 0.161377f, 0.167480f, 0.173950f, 0.180176f, 0.186890f, 0.193481f, 0.200562f, 0.207397f, 0.214355f, 0.221313f,
+ 0.229492f, 0.237427f, 0.541504f, 0.570801f, 0.575195f, 0.575195f, 0.573730f, 0.572266f, 0.001613f, 0.004181f, 0.006252f, 0.008774f,
+ 0.011108f, 0.013054f, 0.015152f, 0.016937f, 0.019150f, 0.021011f, 0.023163f, 0.024826f, 0.026993f, 0.028793f, 0.030823f, 0.033081f,
+ 0.035156f, 0.037201f, 0.039612f, 0.041748f, 0.044464f, 0.046814f, 0.049438f, 0.052155f, 0.054840f, 0.057831f, 0.060699f, 0.063599f,
+ 0.067078f, 0.070374f, 0.073853f, 0.077087f, 0.081177f, 0.085083f, 0.089111f, 0.093262f, 0.097473f, 0.101929f, 0.106689f, 0.111023f,
+ 0.116455f, 0.121277f, 0.126343f, 0.132080f, 0.137573f, 0.142700f, 0.148682f, 0.154907f, 0.161133f, 0.167236f, 0.173340f, 0.179688f,
+ 0.186768f, 0.193115f, 0.200684f, 0.207275f, 0.214233f, 0.221924f, 0.530273f, 0.561523f, 0.565430f, 0.567383f, 0.564941f, 0.564941f,
+ 0.001237f, 0.003775f, 0.006348f, 0.008141f, 0.010117f, 0.012184f, 0.013763f, 0.015656f, 0.017319f, 0.018967f, 0.020645f, 0.022507f,
+ 0.023926f, 0.025757f, 0.027573f, 0.029449f, 0.031677f, 0.033325f, 0.035645f, 0.037659f, 0.039734f, 0.041809f, 0.044189f, 0.046692f,
+ 0.049133f, 0.051697f, 0.054504f, 0.057251f, 0.060059f, 0.063110f, 0.066467f, 0.069763f, 0.072937f, 0.076477f, 0.080505f, 0.084290f,
+ 0.088013f, 0.092407f, 0.096436f, 0.101013f, 0.105713f, 0.110352f, 0.115356f, 0.120605f, 0.125488f, 0.130981f, 0.136353f, 0.142090f,
+ 0.148438f, 0.153931f, 0.159912f, 0.166260f, 0.172485f, 0.179321f, 0.185791f, 0.193115f, 0.199463f, 0.206665f, 0.520020f, 0.552246f,
+ 0.558105f, 0.559570f, 0.559082f, 0.557617f, 0.001151f, 0.003399f, 0.005611f, 0.007439f, 0.009354f, 0.010925f, 0.012489f, 0.014061f,
+ 0.015610f, 0.017258f, 0.018845f, 0.020248f, 0.021484f, 0.023193f, 0.024796f, 0.026459f, 0.028183f, 0.029785f, 0.031738f, 0.033386f,
+ 0.035309f, 0.037384f, 0.039368f, 0.041626f, 0.043701f, 0.046204f, 0.048553f, 0.051178f, 0.053955f, 0.056488f, 0.059418f, 0.062256f,
+ 0.065308f, 0.068542f, 0.071899f, 0.075623f, 0.079224f, 0.082947f, 0.087097f, 0.091064f, 0.095520f, 0.099854f, 0.104736f, 0.109314f,
+ 0.114136f, 0.119324f, 0.124756f, 0.130127f, 0.135498f, 0.141113f, 0.146973f, 0.153198f, 0.159180f, 0.165527f, 0.172241f, 0.178711f,
+ 0.185425f, 0.192749f, 0.507324f, 0.543945f, 0.549316f, 0.552246f, 0.551270f, 0.551270f, 0.001070f, 0.002996f, 0.004986f, 0.006851f,
+ 0.008514f, 0.009850f, 0.011330f, 0.012596f, 0.014015f, 0.015259f, 0.016586f, 0.017731f, 0.019287f, 0.020676f, 0.022079f, 0.023468f,
+ 0.024765f, 0.026489f, 0.028030f, 0.029465f, 0.031311f, 0.032898f, 0.034851f, 0.036743f, 0.038940f, 0.040833f, 0.043091f, 0.045074f,
+ 0.047729f, 0.050079f, 0.052673f, 0.055389f, 0.058136f, 0.061188f, 0.064087f, 0.067261f, 0.070618f, 0.074158f, 0.077942f, 0.081726f,
+ 0.085815f, 0.089783f, 0.094055f, 0.098572f, 0.103088f, 0.107971f, 0.113037f, 0.118164f, 0.123413f, 0.128784f, 0.134521f, 0.140137f,
+ 0.146118f, 0.152100f, 0.158325f, 0.164307f, 0.171387f, 0.177368f, 0.496094f, 0.534668f, 0.541992f, 0.543945f, 0.544434f, 0.544434f,
+ 0.001086f, 0.003069f, 0.004463f, 0.006256f, 0.007393f, 0.009026f, 0.010178f, 0.011276f, 0.012260f, 0.013542f, 0.014648f, 0.015808f,
+ 0.016861f, 0.017899f, 0.019333f, 0.020599f, 0.021942f, 0.023117f, 0.024384f, 0.025833f, 0.027344f, 0.028992f, 0.030579f, 0.032318f,
+ 0.034149f, 0.035828f, 0.037842f, 0.039764f, 0.041901f, 0.044037f, 0.046539f, 0.048645f, 0.051147f, 0.053894f, 0.056641f, 0.059631f,
+ 0.062500f, 0.065735f, 0.069031f, 0.072754f, 0.076294f, 0.080139f, 0.083984f, 0.088379f, 0.092712f, 0.097229f, 0.101929f, 0.106873f,
+ 0.111694f, 0.117004f, 0.122314f, 0.127930f, 0.133789f, 0.139282f, 0.145142f, 0.151367f, 0.157349f, 0.163818f, 0.484619f, 0.525391f,
+ 0.534180f, 0.536621f, 0.536133f, 0.536621f, 0.001125f, 0.002892f, 0.003883f, 0.005867f, 0.006603f, 0.007935f, 0.009026f, 0.009911f,
+ 0.010956f, 0.012077f, 0.012909f, 0.013901f, 0.014977f, 0.015671f, 0.016983f, 0.018021f, 0.019058f, 0.020279f, 0.021225f, 0.022598f,
+ 0.023941f, 0.025299f, 0.026535f, 0.028107f, 0.029755f, 0.031113f, 0.033020f, 0.034668f, 0.036682f, 0.038483f, 0.040527f, 0.042511f,
+ 0.044708f, 0.046936f, 0.049744f, 0.052216f, 0.054840f, 0.057800f, 0.060791f, 0.064087f, 0.067505f, 0.071045f, 0.074463f, 0.078491f,
+ 0.082397f, 0.086609f, 0.091248f, 0.095581f, 0.100342f, 0.105530f, 0.110474f, 0.116272f, 0.120972f, 0.126953f, 0.132812f, 0.138672f,
+ 0.144287f, 0.150513f, 0.472412f, 0.516113f, 0.524902f, 0.528809f, 0.529785f, 0.529785f, 0.000859f, 0.002470f, 0.003815f, 0.005226f,
+ 0.005913f, 0.007206f, 0.007942f, 0.008652f, 0.009583f, 0.010406f, 0.011223f, 0.011971f, 0.012856f, 0.013664f, 0.014664f, 0.015549f,
+ 0.016464f, 0.017487f, 0.018478f, 0.019592f, 0.020767f, 0.021774f, 0.023117f, 0.024338f, 0.025604f, 0.027008f, 0.028519f, 0.029953f,
+ 0.031525f, 0.033173f, 0.034943f, 0.036865f, 0.038696f, 0.040863f, 0.042969f, 0.045471f, 0.048004f, 0.050293f, 0.052979f, 0.055847f,
+ 0.058960f, 0.062042f, 0.065491f, 0.069153f, 0.072937f, 0.076660f, 0.080750f, 0.085144f, 0.089539f, 0.094177f, 0.099304f, 0.104187f,
+ 0.109741f, 0.114807f, 0.120483f, 0.125977f, 0.131836f, 0.138306f, 0.460449f, 0.507812f, 0.516602f, 0.520020f, 0.522461f, 0.522949f,
+ 0.000906f, 0.002359f, 0.003643f, 0.004356f, 0.005310f, 0.005989f, 0.007030f, 0.007507f, 0.008255f, 0.009010f, 0.009834f, 0.010483f,
+ 0.011230f, 0.011887f, 0.012573f, 0.013367f, 0.014252f, 0.014954f, 0.015900f, 0.016785f, 0.017776f, 0.018631f, 0.019775f, 0.020874f,
+ 0.022110f, 0.023117f, 0.024368f, 0.025589f, 0.026932f, 0.028549f, 0.029938f, 0.031525f, 0.033325f, 0.035187f, 0.037109f, 0.038971f,
+ 0.041138f, 0.043396f, 0.045715f, 0.048370f, 0.051025f, 0.053772f, 0.057129f, 0.060089f, 0.063416f, 0.067261f, 0.070679f, 0.075012f,
+ 0.079285f, 0.083618f, 0.088379f, 0.093018f, 0.098083f, 0.102478f, 0.108093f, 0.114380f, 0.119507f, 0.125488f, 0.448975f, 0.498291f,
+ 0.508789f, 0.513672f, 0.514648f, 0.516113f, 0.000728f, 0.001932f, 0.003067f, 0.003990f, 0.004784f, 0.005295f, 0.005974f, 0.006584f,
+ 0.007099f, 0.007652f, 0.008255f, 0.008904f, 0.009491f, 0.010109f, 0.010658f, 0.011497f, 0.012131f, 0.012718f, 0.013535f, 0.014336f,
+ 0.015083f, 0.016083f, 0.016785f, 0.017761f, 0.018738f, 0.019669f, 0.020691f, 0.021805f, 0.023010f, 0.024170f, 0.025467f, 0.026794f,
+ 0.028336f, 0.029922f, 0.031555f, 0.033203f, 0.035034f, 0.036987f, 0.039062f, 0.041290f, 0.043671f, 0.046143f, 0.048920f, 0.051880f,
+ 0.054901f, 0.058228f, 0.061615f, 0.065369f, 0.069214f, 0.073425f, 0.077637f, 0.082214f, 0.087097f, 0.091797f, 0.096497f, 0.102356f,
+ 0.107483f, 0.113464f, 0.437256f, 0.489746f, 0.500977f, 0.504883f, 0.507812f, 0.509277f, 0.000724f, 0.001842f, 0.002728f, 0.003332f,
+ 0.004101f, 0.004707f, 0.005020f, 0.005497f, 0.006245f, 0.006603f, 0.007027f, 0.007515f, 0.008156f, 0.008537f, 0.009125f, 0.009659f,
+ 0.010101f, 0.010864f, 0.011482f, 0.012070f, 0.012756f, 0.013496f, 0.014236f, 0.014931f, 0.015808f, 0.016632f, 0.017487f, 0.018433f,
+ 0.019379f, 0.020416f, 0.021530f, 0.022583f, 0.023804f, 0.024979f, 0.026443f, 0.027939f, 0.029526f, 0.031235f, 0.033020f, 0.035004f,
+ 0.037018f, 0.039185f, 0.041595f, 0.044159f, 0.046783f, 0.049866f, 0.052856f, 0.056274f, 0.059906f, 0.063721f, 0.067749f, 0.072327f,
+ 0.076172f, 0.081299f, 0.085938f, 0.091309f, 0.096558f, 0.101807f, 0.426270f, 0.480469f, 0.492676f, 0.498047f, 0.500488f, 0.501953f,
+ 0.000673f, 0.001715f, 0.002426f, 0.002953f, 0.003588f, 0.003944f, 0.004200f, 0.004776f, 0.005131f, 0.005527f, 0.005886f, 0.006371f,
+ 0.006790f, 0.007076f, 0.007538f, 0.008133f, 0.008644f, 0.009140f, 0.009483f, 0.010071f, 0.010689f, 0.011230f, 0.011879f, 0.012474f,
+ 0.013222f, 0.013916f, 0.014587f, 0.015411f, 0.016190f, 0.016983f, 0.017883f, 0.018845f, 0.019867f, 0.020935f, 0.022141f, 0.023270f,
+ 0.024567f, 0.026001f, 0.027481f, 0.029114f, 0.030777f, 0.032684f, 0.034698f, 0.036865f, 0.039337f, 0.041748f, 0.044647f, 0.047882f,
+ 0.050964f, 0.054260f, 0.058258f, 0.062195f, 0.066528f, 0.070679f, 0.075623f, 0.080505f, 0.085510f, 0.090515f, 0.414307f, 0.472168f,
+ 0.484131f, 0.490234f, 0.492920f, 0.495850f, 0.000484f, 0.001445f, 0.002169f, 0.002569f, 0.002836f, 0.003317f, 0.003569f, 0.003952f,
+ 0.004215f, 0.004623f, 0.004959f, 0.005306f, 0.005592f, 0.005951f, 0.006306f, 0.006737f, 0.007004f, 0.007492f, 0.007942f, 0.008331f,
+ 0.008865f, 0.009270f, 0.009781f, 0.010338f, 0.010887f, 0.011429f, 0.012047f, 0.012726f, 0.013336f, 0.014030f, 0.014771f, 0.015572f,
+ 0.016418f, 0.017258f, 0.018234f, 0.019196f, 0.020279f, 0.021423f, 0.022675f, 0.023987f, 0.025375f, 0.027039f, 0.028702f, 0.030563f,
+ 0.032623f, 0.034698f, 0.037262f, 0.040039f, 0.042664f, 0.046051f, 0.049194f, 0.052948f, 0.057129f, 0.061371f, 0.065613f, 0.070007f,
+ 0.075317f, 0.080200f, 0.402588f, 0.462402f, 0.476807f, 0.482666f, 0.485107f, 0.487061f, 0.000459f, 0.001265f, 0.001572f, 0.002138f,
+ 0.002365f, 0.002775f, 0.002920f, 0.003189f, 0.003454f, 0.003723f, 0.003986f, 0.004250f, 0.004536f, 0.004906f, 0.005150f, 0.005463f,
+ 0.005787f, 0.006172f, 0.006481f, 0.006794f, 0.007156f, 0.007542f, 0.007980f, 0.008430f, 0.008827f, 0.009361f, 0.009796f, 0.010300f,
+ 0.010910f, 0.011497f, 0.012161f, 0.012672f, 0.013336f, 0.014183f, 0.014893f, 0.015640f, 0.016541f, 0.017517f, 0.018448f, 0.019485f,
+ 0.020676f, 0.021912f, 0.023392f, 0.024979f, 0.026627f, 0.028351f, 0.030457f, 0.032806f, 0.035034f, 0.037933f, 0.041229f, 0.044373f,
+ 0.047821f, 0.052002f, 0.056244f, 0.060547f, 0.065247f, 0.069885f, 0.390869f, 0.453857f, 0.468018f, 0.475098f, 0.478027f, 0.480469f,
+ 0.000332f, 0.001075f, 0.001464f, 0.001721f, 0.001911f, 0.002235f, 0.002375f, 0.002558f, 0.002834f, 0.002998f, 0.003185f, 0.003441f,
+ 0.003647f, 0.003952f, 0.004139f, 0.004421f, 0.004631f, 0.004879f, 0.005180f, 0.005447f, 0.005795f, 0.006115f, 0.006416f, 0.006718f,
+ 0.007099f, 0.007462f, 0.007881f, 0.008331f, 0.008797f, 0.009140f, 0.009735f, 0.010223f, 0.010803f, 0.011337f, 0.011986f, 0.012611f,
+ 0.013283f, 0.014076f, 0.014847f, 0.015732f, 0.016693f, 0.017700f, 0.018784f, 0.019897f, 0.021317f, 0.022873f, 0.024429f, 0.026306f,
+ 0.028473f, 0.030960f, 0.033600f, 0.036407f, 0.039856f, 0.043549f, 0.047119f, 0.051392f, 0.055969f, 0.060394f, 0.379639f, 0.444580f,
+ 0.458984f, 0.467529f, 0.470947f, 0.472900f, 0.000408f, 0.000770f, 0.001271f, 0.001390f, 0.001601f, 0.001762f, 0.001848f, 0.002052f,
+ 0.002247f, 0.002401f, 0.002491f, 0.002684f, 0.002878f, 0.003086f, 0.003304f, 0.003452f, 0.003626f, 0.003805f, 0.004074f, 0.004257f,
+ 0.004513f, 0.004807f, 0.005039f, 0.005299f, 0.005638f, 0.005905f, 0.006191f, 0.006516f, 0.006927f, 0.007206f, 0.007645f, 0.008034f,
+ 0.008415f, 0.008911f, 0.009384f, 0.009941f, 0.010483f, 0.011116f, 0.011711f, 0.012428f, 0.013191f, 0.013969f, 0.014862f, 0.015854f,
+ 0.016785f, 0.017975f, 0.019348f, 0.020721f, 0.022461f, 0.024445f, 0.026733f, 0.029175f, 0.032227f, 0.035248f, 0.038788f, 0.042755f,
+ 0.046967f, 0.051636f, 0.367920f, 0.435059f, 0.452148f, 0.459229f, 0.463623f, 0.466797f, 0.000382f, 0.000669f, 0.001037f, 0.001185f,
+ 0.001293f, 0.001379f, 0.001470f, 0.001565f, 0.001729f, 0.001864f, 0.001928f, 0.002138f, 0.002237f, 0.002398f, 0.002510f, 0.002672f,
+ 0.002802f, 0.002966f, 0.003134f, 0.003319f, 0.003517f, 0.003723f, 0.003870f, 0.004089f, 0.004311f, 0.004532f, 0.004772f, 0.005013f,
+ 0.005314f, 0.005573f, 0.005924f, 0.006203f, 0.006523f, 0.006897f, 0.007240f, 0.007660f, 0.008041f, 0.008530f, 0.009048f, 0.009621f,
+ 0.010201f, 0.010841f, 0.011467f, 0.012192f, 0.013138f, 0.013969f, 0.014931f, 0.016113f, 0.017380f, 0.018936f, 0.020630f, 0.022751f,
+ 0.025208f, 0.027924f, 0.031311f, 0.034851f, 0.038879f, 0.043274f, 0.356689f, 0.426270f, 0.443848f, 0.451660f, 0.456055f, 0.459473f,
+ 0.000482f, 0.000542f, 0.000723f, 0.000822f, 0.000881f, 0.001025f, 0.001100f, 0.001209f, 0.001249f, 0.001355f, 0.001522f, 0.001599f,
+ 0.001708f, 0.001836f, 0.001918f, 0.001970f, 0.002129f, 0.002251f, 0.002357f, 0.002522f, 0.002636f, 0.002768f, 0.002911f, 0.003056f,
+ 0.003237f, 0.003393f, 0.003605f, 0.003771f, 0.003994f, 0.004234f, 0.004444f, 0.004635f, 0.004932f, 0.005150f, 0.005486f, 0.005779f,
+ 0.006081f, 0.006458f, 0.006775f, 0.007179f, 0.007668f, 0.008110f, 0.008690f, 0.009209f, 0.009926f, 0.010551f, 0.011330f, 0.012184f,
+ 0.013184f, 0.014297f, 0.015610f, 0.017181f, 0.019165f, 0.021500f, 0.024384f, 0.027618f, 0.031372f, 0.035614f, 0.345459f, 0.417236f,
+ 0.435303f, 0.443604f, 0.448730f, 0.451904f, 0.000240f, 0.000479f, 0.000533f, 0.000625f, 0.000716f, 0.000746f, 0.000857f, 0.000835f,
+ 0.000941f, 0.001024f, 0.001104f, 0.001155f, 0.001204f, 0.001282f, 0.001396f, 0.001453f, 0.001554f, 0.001627f, 0.001737f, 0.001787f,
+ 0.001894f, 0.002012f, 0.002119f, 0.002218f, 0.002335f, 0.002453f, 0.002611f, 0.002714f, 0.002848f, 0.003050f, 0.003168f, 0.003395f,
+ 0.003529f, 0.003740f, 0.003963f, 0.004158f, 0.004429f, 0.004688f, 0.004982f, 0.005280f, 0.005600f, 0.005959f, 0.006340f, 0.006775f,
+ 0.007252f, 0.007748f, 0.008369f, 0.008980f, 0.009705f, 0.010513f, 0.011513f, 0.012665f, 0.014069f, 0.015869f, 0.018158f, 0.020950f,
+ 0.024338f, 0.028366f, 0.335205f, 0.408203f, 0.427002f, 0.435547f, 0.441162f, 0.445312f, 0.000138f, 0.000265f, 0.000381f, 0.000386f,
+ 0.000465f, 0.000556f, 0.000558f, 0.000597f, 0.000659f, 0.000748f, 0.000770f, 0.000786f, 0.000829f, 0.000904f, 0.000940f, 0.001021f,
+ 0.001043f, 0.001139f, 0.001201f, 0.001253f, 0.001327f, 0.001396f, 0.001481f, 0.001555f, 0.001637f, 0.001712f, 0.001813f, 0.001899f,
+ 0.002005f, 0.002140f, 0.002220f, 0.002348f, 0.002462f, 0.002600f, 0.002733f, 0.002932f, 0.003075f, 0.003279f, 0.003452f, 0.003630f,
+ 0.003872f, 0.004166f, 0.004436f, 0.004742f, 0.005077f, 0.005459f, 0.005848f, 0.006310f, 0.006874f, 0.007492f, 0.008171f, 0.009026f,
+ 0.009995f, 0.011307f, 0.013008f, 0.015343f, 0.018265f, 0.021881f, 0.323486f, 0.399170f, 0.418945f, 0.428467f, 0.434326f, 0.437988f,
+ 0.000165f, 0.000260f, 0.000287f, 0.000296f, 0.000331f, 0.000339f, 0.000360f, 0.000395f, 0.000442f, 0.000482f, 0.000487f, 0.000551f,
+ 0.000546f, 0.000611f, 0.000640f, 0.000667f, 0.000711f, 0.000742f, 0.000775f, 0.000816f, 0.000876f, 0.000916f, 0.000974f, 0.001015f,
+ 0.001081f, 0.001123f, 0.001195f, 0.001267f, 0.001317f, 0.001388f, 0.001459f, 0.001558f, 0.001630f, 0.001718f, 0.001804f, 0.001916f,
+ 0.002033f, 0.002148f, 0.002295f, 0.002455f, 0.002583f, 0.002754f, 0.002941f, 0.003134f, 0.003386f, 0.003639f, 0.003910f, 0.004215f,
+ 0.004597f, 0.005013f, 0.005520f, 0.006130f, 0.006821f, 0.007690f, 0.008789f, 0.010452f, 0.012909f, 0.016174f, 0.312012f, 0.390381f,
+ 0.410645f, 0.420654f, 0.426270f, 0.430664f, 0.000057f, 0.000171f, 0.000164f, 0.000170f, 0.000211f, 0.000213f, 0.000229f, 0.000247f,
+ 0.000267f, 0.000279f, 0.000289f, 0.000317f, 0.000349f, 0.000364f, 0.000390f, 0.000407f, 0.000427f, 0.000467f, 0.000476f, 0.000521f,
+ 0.000537f, 0.000561f, 0.000578f, 0.000626f, 0.000667f, 0.000714f, 0.000729f, 0.000753f, 0.000806f, 0.000855f, 0.000911f, 0.000945f,
+ 0.001004f, 0.001054f, 0.001112f, 0.001172f, 0.001251f, 0.001333f, 0.001406f, 0.001489f, 0.001595f, 0.001694f, 0.001811f, 0.001952f,
+ 0.002090f, 0.002243f, 0.002453f, 0.002638f, 0.002888f, 0.003143f, 0.003489f, 0.003870f, 0.004353f, 0.004921f, 0.005672f, 0.006664f,
+ 0.008423f, 0.011230f, 0.301758f, 0.381104f, 0.402832f, 0.413330f, 0.418457f, 0.423828f, 0.000096f, 0.000112f, 0.000097f, 0.000090f,
+ 0.000113f, 0.000119f, 0.000144f, 0.000149f, 0.000151f, 0.000158f, 0.000181f, 0.000184f, 0.000179f, 0.000201f, 0.000224f, 0.000216f,
+ 0.000237f, 0.000255f, 0.000263f, 0.000276f, 0.000297f, 0.000308f, 0.000332f, 0.000347f, 0.000369f, 0.000395f, 0.000408f, 0.000422f,
+ 0.000447f, 0.000471f, 0.000500f, 0.000531f, 0.000554f, 0.000583f, 0.000617f, 0.000660f, 0.000690f, 0.000739f, 0.000795f, 0.000833f,
+ 0.000885f, 0.000948f, 0.001022f, 0.001085f, 0.001175f, 0.001262f, 0.001371f, 0.001487f, 0.001633f, 0.001778f, 0.001986f, 0.002218f,
+ 0.002502f, 0.002865f, 0.003330f, 0.003979f, 0.004932f, 0.007000f, 0.291260f, 0.372070f, 0.394043f, 0.404541f, 0.412109f, 0.416260f,
+ 0.000000f, 0.000056f, 0.000049f, 0.000061f, 0.000064f, 0.000061f, 0.000062f, 0.000071f, 0.000072f, 0.000088f, 0.000083f, 0.000086f,
+ 0.000097f, 0.000094f, 0.000098f, 0.000105f, 0.000116f, 0.000122f, 0.000126f, 0.000134f, 0.000137f, 0.000143f, 0.000150f, 0.000164f,
+ 0.000171f, 0.000183f, 0.000188f, 0.000204f, 0.000214f, 0.000224f, 0.000236f, 0.000255f, 0.000258f, 0.000277f, 0.000293f, 0.000315f,
+ 0.000328f, 0.000349f, 0.000376f, 0.000396f, 0.000426f, 0.000454f, 0.000486f, 0.000521f, 0.000563f, 0.000605f, 0.000657f, 0.000714f,
+ 0.000791f, 0.000866f, 0.000977f, 0.001085f, 0.001243f, 0.001441f, 0.001703f, 0.002058f, 0.002573f, 0.003740f, 0.280029f, 0.362793f,
+ 0.385742f, 0.397217f, 0.404297f, 0.408936f, 0.000058f, 0.000038f, 0.000031f, 0.000027f, 0.000025f, 0.000026f, 0.000025f, 0.000024f,
+ 0.000024f, 0.000027f, 0.000030f, 0.000038f, 0.000032f, 0.000035f, 0.000040f, 0.000041f, 0.000044f, 0.000045f, 0.000045f, 0.000047f,
+ 0.000052f, 0.000058f, 0.000061f, 0.000059f, 0.000065f, 0.000067f, 0.000069f, 0.000073f, 0.000078f, 0.000083f, 0.000089f, 0.000091f,
+ 0.000099f, 0.000103f, 0.000106f, 0.000114f, 0.000124f, 0.000132f, 0.000141f, 0.000150f, 0.000158f, 0.000164f, 0.000180f, 0.000193f,
+ 0.000205f, 0.000225f, 0.000245f, 0.000267f, 0.000297f, 0.000329f, 0.000365f, 0.000416f, 0.000479f, 0.000563f, 0.000676f, 0.000839f,
+ 0.001088f, 0.001589f, 0.270264f, 0.353760f, 0.377197f, 0.390137f, 0.396973f, 0.402100f, 0.000030f, 0.000019f, 0.000016f, 0.000014f,
+ 0.000013f, 0.000012f, 0.000011f, 0.000011f, 0.000010f, 0.000010f, 0.000009f, 0.000009f, 0.000009f, 0.000008f, 0.000007f, 0.000009f,
+ 0.000009f, 0.000008f, 0.000009f, 0.000010f, 0.000011f, 0.000012f, 0.000012f, 0.000014f, 0.000014f, 0.000014f, 0.000015f, 0.000018f,
+ 0.000017f, 0.000017f, 0.000019f, 0.000020f, 0.000022f, 0.000022f, 0.000023f, 0.000026f, 0.000028f, 0.000027f, 0.000030f, 0.000032f,
+ 0.000035f, 0.000038f, 0.000040f, 0.000042f, 0.000045f, 0.000049f, 0.000055f, 0.000060f, 0.000065f, 0.000074f, 0.000078f, 0.000095f,
+ 0.000109f, 0.000129f, 0.000160f, 0.000205f, 0.000284f, 0.000452f, 0.259766f, 0.345703f, 0.369629f, 0.382812f, 0.390625f, 0.395264f,
+ 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000000f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f,
+ 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000001f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f, 0.000002f,
+ 0.000002f, 0.000003f, 0.000003f, 0.000004f, 0.000004f, 0.000005f, 0.000006f, 0.000009f, 0.000012f, 0.000026f, 0.249878f, 0.336182f,
+ 0.362061f, 0.374512f, 0.382080f, 0.387695f,
+ }
+};
+
/* 4 different blue noise, one per channel */
static float blue_noise[64 * 64][4] = {
{0.367188f, 0.855469f, 0.523438f, 0.375000f}, {0.242188f, 0.699219f, 0.164062f, 0.292969f},
diff --git a/source/blender/draw/engines/eevee/eevee_materials.c b/source/blender/draw/engines/eevee/eevee_materials.c
index 836f111d977..070b6be94a4 100644
--- a/source/blender/draw/engines/eevee/eevee_materials.c
+++ b/source/blender/draw/engines/eevee/eevee_materials.c
@@ -98,6 +98,7 @@ extern char datatoc_default_frag_glsl[];
extern char datatoc_default_world_frag_glsl[];
extern char datatoc_ltc_lib_glsl[];
extern char datatoc_bsdf_lut_frag_glsl[];
+extern char datatoc_btdf_lut_frag_glsl[];
extern char datatoc_bsdf_common_lib_glsl[];
extern char datatoc_bsdf_direct_lib_glsl[];
extern char datatoc_bsdf_sampling_lib_glsl[];
@@ -105,6 +106,8 @@ extern char datatoc_irradiance_lib_glsl[];
extern char datatoc_octahedron_lib_glsl[];
extern char datatoc_lit_surface_frag_glsl[];
extern char datatoc_lit_surface_vert_glsl[];
+extern char datatoc_raytrace_lib_glsl[];
+extern char datatoc_ssr_lib_glsl[];
extern char datatoc_shadow_vert_glsl[];
extern char datatoc_shadow_geom_glsl[];
extern char datatoc_lightprobe_geom_glsl[];
@@ -178,8 +181,97 @@ static struct GPUTexture *create_ggx_lut_texture(int UNUSED(w), int UNUSED(h))
return tex;
}
-#endif
+static struct GPUTexture *create_ggx_refraction_lut_texture(int w, int h)
+{
+ struct GPUTexture *tex;
+ struct GPUTexture *hammersley = create_hammersley_sample_texture(8192);
+ struct GPUFrameBuffer *fb = NULL;
+ static float samples_ct = 8192.0f;
+ static float a2 = 0.0f;
+ static float inv_samples_ct = 1.0f / 8192.0f;
+
+ char *frag_str = NULL;
+
+ DynStr *ds_vert = BLI_dynstr_new();
+ BLI_dynstr_append(ds_vert, datatoc_bsdf_common_lib_glsl);
+ BLI_dynstr_append(ds_vert, datatoc_bsdf_sampling_lib_glsl);
+ BLI_dynstr_append(ds_vert, datatoc_btdf_lut_frag_glsl);
+ frag_str = BLI_dynstr_get_cstring(ds_vert);
+ BLI_dynstr_free(ds_vert);
+
+ struct GPUShader *sh = DRW_shader_create_fullscreen(frag_str,
+ "#define HAMMERSLEY_SIZE 8192\n"
+ "#define BRDF_LUT_SIZE 64\n"
+ "#define NOISE_SIZE 64\n"
+ "#define LUT_SIZE 64\n");
+
+ MEM_freeN(frag_str);
+
+ DRWPass *pass = DRW_pass_create("LightProbe Filtering", DRW_STATE_WRITE_COLOR);
+ DRWShadingGroup *grp = DRW_shgroup_create(sh, pass);
+ DRW_shgroup_uniform_float(grp, "a2", &a2, 1);
+ DRW_shgroup_uniform_float(grp, "sampleCount", &samples_ct, 1);
+ DRW_shgroup_uniform_float(grp, "invSampleCount", &inv_samples_ct, 1);
+ DRW_shgroup_uniform_texture(grp, "texHammersley", hammersley);
+ DRW_shgroup_uniform_texture(grp, "utilTex", e_data.util_tex);
+
+ struct Gwn_Batch *geom = DRW_cache_fullscreen_quad_get();
+ DRW_shgroup_call_add(grp, geom, NULL);
+
+ float *texels = MEM_mallocN(sizeof(float[2]) * w * h, "lut");
+
+ tex = DRW_texture_create_2D(w, h, DRW_TEX_R_16, DRW_TEX_FILTER, (float *)texels);
+
+ DRWFboTexture tex_filter = {&tex, DRW_TEX_R_16, DRW_TEX_FILTER};
+ DRW_framebuffer_init(&fb, &draw_engine_eevee_type, w, h, &tex_filter, 1);
+
+ DRW_framebuffer_bind(fb);
+
+ float *data = MEM_mallocN(sizeof(float[3]) * w * h, "lut");
+
+ float inc = 1.0f / 31.0f;
+ float roughness = 1e-8f - inc;
+ FILE *f = BLI_fopen("btdf_split_sum_ggx.h", "w");
+ fprintf(f, "static float btdf_split_sum_ggx[32][64 * 64] = {\n");
+ do {
+ roughness += inc;
+ CLAMP(roughness, 1e-4f, 1.0f);
+ a2 = powf(roughness, 4.0f);
+ DRW_draw_pass(pass);
+
+ DRW_framebuffer_read_data(0, 0, w, h, 3, 0, data);
+
+ #if 1
+ fprintf(f, "\t{\n\t\t");
+ for (int i = 0; i < w*h * 3; i+=3) {
+ fprintf(f, "%ff,", data[i]);
+ if (((i/3)+1) % 12 == 0) fprintf(f, "\n\t\t");
+ else fprintf(f, " ");
+ }
+ fprintf(f, "\n\t},\n");
+ #else
+ for (int i = 0; i < w*h * 3; i+=3) {
+ if (data[i] < 0.01) printf(" ");
+ else if (data[i] < 0.3) printf(".");
+ else if (data[i] < 0.6) printf("+");
+ else if (data[i] < 0.9) printf("%%");
+ else printf("#");
+ if ((i/3+1) % 64 == 0) printf("\n");
+ }
+ #endif
+
+ } while (roughness < 1.0f);
+ fprintf(f, "\n};\n");
+
+ fclose(f);
+
+ MEM_freeN(texels);
+ MEM_freeN(data);
+
+ return tex;
+}
+#endif
/* XXX TODO define all shared resources in a shared place without duplication */
struct GPUTexture *EEVEE_materials_get_util_tex(void)
{
@@ -205,15 +297,9 @@ static char *eevee_get_defines(int options)
if ((options & VAR_MAT_PROBE) != 0) {
BLI_dynstr_appendf(ds, "#define PROBE_CAPTURE\n");
}
- if ((options & VAR_MAT_AO) != 0) {
- BLI_dynstr_appendf(ds, "#define USE_AO\n");
- }
if ((options & VAR_MAT_FLAT) != 0) {
BLI_dynstr_appendf(ds, "#define USE_FLAT_NORMAL\n");
}
- if ((options & VAR_MAT_BENT) != 0) {
- BLI_dynstr_appendf(ds, "#define USE_BENT_NORMAL\n");
- }
if ((options & VAR_MAT_CLIP) != 0) {
BLI_dynstr_appendf(ds, "#define USE_ALPHA_CLIP\n");
}
@@ -229,6 +315,9 @@ static char *eevee_get_defines(int options)
if ((options & VAR_MAT_MULT) != 0) {
BLI_dynstr_appendf(ds, "#define USE_MULTIPLY\n");
}
+ if ((options & VAR_MAT_REFRACT) != 0) {
+ BLI_dynstr_appendf(ds, "#define USE_REFRACTION\n");
+ }
str = BLI_dynstr_get_cstring(ds);
BLI_dynstr_free(ds);
@@ -268,7 +357,9 @@ static char *eevee_get_volume_defines(int options)
/**
* ssr_id can be null to disable ssr contribution.
**/
-static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, int *ssr_id)
+static void add_standard_uniforms(
+ DRWShadingGroup *shgrp, EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata,
+ int *ssr_id, float *refract_depth, bool use_ssrefraction)
{
if (ssr_id == NULL) {
static int no_ssr = -1.0f;
@@ -294,10 +385,25 @@ static void add_standard_uniforms(DRWShadingGroup *shgrp, EEVEE_SceneLayerData *
DRW_shgroup_uniform_buffer(shgrp, "shadowCubes", &sldata->shadow_depth_cube_pool);
DRW_shgroup_uniform_buffer(shgrp, "shadowCascades", &sldata->shadow_depth_cascade_pool);
DRW_shgroup_uniform_int(shgrp, "outputSsrId", ssr_id, 1);
+ DRW_shgroup_uniform_vec4(shgrp, "aoParameters[0]", &vedata->stl->effects->ao_dist, 2);
+ if (refract_depth != NULL) {
+ DRW_shgroup_uniform_float(shgrp, "refractionDepth", refract_depth, 1);
+ }
+ if (vedata->stl->effects->use_ao || use_ssrefraction) {
+ DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)vedata->stl->g_data->viewvecs, 2);
+ DRW_shgroup_uniform_buffer(shgrp, "maxzBuffer", &vedata->txl->maxzbuffer);
+ DRW_shgroup_uniform_vec2(shgrp, "mipRatio[0]", (float *)vedata->stl->g_data->mip_ratio, 10);
+ }
+ if (use_ssrefraction) {
+ DRW_shgroup_uniform_buffer(shgrp, "colorBuffer", &vedata->txl->refract_color);
+ DRW_shgroup_uniform_vec4(shgrp, "ssrParameters", &vedata->stl->effects->ssr_quality, 1);
+ DRW_shgroup_uniform_float(shgrp, "borderFadeFactor", &vedata->stl->effects->ssr_border_fac, 1);
+ DRW_shgroup_uniform_float(shgrp, "maxRoughness", &vedata->stl->effects->ssr_max_roughness, 1);
+ DRW_shgroup_uniform_int(shgrp, "rayCount", &vedata->stl->effects->ssr_ray_count, 1);
+ }
if (vedata->stl->effects->use_ao) {
- DRW_shgroup_uniform_vec4(shgrp, "viewvecs[0]", (float *)&vedata->stl->g_data->viewvecs, 2);
- DRW_shgroup_uniform_buffer(shgrp, "minMaxDepthTex", &vedata->txl->maxzbuffer);
- DRW_shgroup_uniform_vec3(shgrp, "aoParameters", &vedata->stl->effects->ao_dist, 1);
+ DRW_shgroup_uniform_buffer(shgrp, "horizonBuffer", &vedata->txl->gtao_horizons);
+ DRW_shgroup_uniform_ivec2(shgrp, "aoHorizonTexSize", (int *)vedata->stl->effects->ao_texsize, 1);
}
}
@@ -337,7 +443,10 @@ void EEVEE_materials_init(EEVEE_StorageList *stl)
{
DynStr *ds_frag = BLI_dynstr_new();
BLI_dynstr_append(ds_frag, datatoc_bsdf_common_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_bsdf_sampling_lib_glsl);
BLI_dynstr_append(ds_frag, datatoc_ambient_occlusion_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_raytrace_lib_glsl);
+ BLI_dynstr_append(ds_frag, datatoc_ssr_lib_glsl);
BLI_dynstr_append(ds_frag, datatoc_octahedron_lib_glsl);
BLI_dynstr_append(ds_frag, datatoc_irradiance_lib_glsl);
BLI_dynstr_append(ds_frag, datatoc_lightprobe_lib_glsl);
@@ -409,7 +518,7 @@ void EEVEE_materials_init(EEVEE_StorageList *stl)
MEM_freeN(hair_fiber_vert_str);
/* Textures */
- const int layers = 3;
+ const int layers = 3 + 16;
float (*texels)[4] = MEM_mallocN(sizeof(float[4]) * 64 * 64 * layers, "utils texels");
float (*texels_layer)[4] = texels;
@@ -433,6 +542,16 @@ void EEVEE_materials_init(EEVEE_StorageList *stl)
texels_layer[i][3] = sinf(blue_noise[i][1] * 2.0 * M_PI);
}
+ for (int j = 0; j < 16; ++j) {
+ texels_layer += 64 * 64;
+ for (int i = 0; i < 64 * 64; i++) {
+ texels_layer[i][0] = btdf_split_sum_ggx[j*2][i];
+ texels_layer[i][1] = btdf_split_sum_ggx[j*2][i];
+ texels_layer[i][2] = btdf_split_sum_ggx[j*2][i];
+ texels_layer[i][3] = btdf_split_sum_ggx[j*2][i];
+ }
+ }
+
e_data.util_tex = DRW_texture_create_2D_array(64, 64, layers, DRW_TEX_RGBA_16, DRW_TEX_FILTER | DRW_TEX_WRAP, (float *)texels);
MEM_freeN(texels);
}
@@ -542,15 +661,14 @@ struct GPUMaterial *EEVEE_material_world_volume_get(
struct GPUMaterial *EEVEE_material_mesh_get(
struct Scene *scene, Material *ma,
- bool use_ao, bool use_bent_normals, bool use_blend, bool use_multiply)
+ bool use_blend, bool use_multiply, bool use_refract)
{
const void *engine = &DRW_engine_viewport_eevee_type;
int options = VAR_MAT_MESH;
- if (use_ao) options |= VAR_MAT_AO;
- if (use_bent_normals) options |= VAR_MAT_BENT;
if (use_blend) options |= VAR_MAT_BLEND;
if (use_multiply) options |= VAR_MAT_MULT;
+ if (use_refract) options |= VAR_MAT_REFRACT;
GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options);
if (mat) {
@@ -613,17 +731,13 @@ struct GPUMaterial *EEVEE_material_mesh_depth_get(
}
struct GPUMaterial *EEVEE_material_hair_get(
- struct Scene *scene, Material *ma,
- bool use_fibers, bool use_ao, bool use_bent_normals)
+ struct Scene *scene, Material *ma, bool use_fibers)
{
const void *engine = &DRW_engine_viewport_eevee_type;
int options = VAR_MAT_HAIR | VAR_MAT_MESH;
if (use_fibers) {
options |= VAR_MAT_HAIR_FIBERS;
}
- if (use_ao) options |= VAR_MAT_AO;
- if (use_bent_normals) options |= VAR_MAT_BENT;
-
GPUMaterial *mat = GPU_material_from_nodetree_find(&ma->gpumaterial, engine, options);
if (mat) {
return mat;
@@ -656,7 +770,7 @@ struct GPUMaterial *EEVEE_material_hair_get(
**/
static struct DRWShadingGroup *EEVEE_default_shading_group_create(
EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, DRWPass *pass,
- bool is_hair, bool is_hair_fibers, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_blend, bool use_ssr)
+ bool is_hair, bool is_hair_fibers, bool is_flat_normal, bool use_blend, bool use_ssr)
{
static int ssr_id;
ssr_id = (use_ssr) ? 0 : -1;
@@ -664,8 +778,6 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(
if (is_hair) options |= VAR_MAT_HAIR;
if (is_hair_fibers) options |= VAR_MAT_HAIR_FIBERS;
- if (use_ao) options |= VAR_MAT_AO;
- if (use_bent_normals) options |= VAR_MAT_BENT;
if (is_flat_normal) options |= VAR_MAT_FLAT;
if (use_blend) options |= VAR_MAT_BLEND;
@@ -674,7 +786,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(
}
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], pass);
- add_standard_uniforms(shgrp, sldata, vedata, &ssr_id);
+ add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false);
return shgrp;
}
@@ -684,7 +796,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_create(
**/
static struct DRWShadingGroup *EEVEE_default_shading_group_get(
EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata,
- bool is_hair, bool is_hair_fibers, bool is_flat_normal, bool use_ao, bool use_bent_normals, bool use_ssr)
+ bool is_hair, bool is_hair_fibers, bool is_flat_normal, bool use_ssr)
{
static int ssr_id;
ssr_id = (use_ssr) ? 0 : -1;
@@ -692,8 +804,6 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(
if (is_hair) options |= VAR_MAT_HAIR;
if (is_hair_fibers) options |= VAR_MAT_HAIR_FIBERS;
- if (use_ao) options |= VAR_MAT_AO;
- if (use_bent_normals) options |= VAR_MAT_BENT;
if (is_flat_normal) options |= VAR_MAT_FLAT;
if (e_data.default_lit[options] == NULL) {
@@ -706,7 +816,7 @@ static struct DRWShadingGroup *EEVEE_default_shading_group_get(
vedata->psl->default_pass[options] = DRW_pass_create("Default Lit Pass", state);
DRWShadingGroup *shgrp = DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
- add_standard_uniforms(shgrp, sldata, vedata, &ssr_id);
+ add_standard_uniforms(shgrp, sldata, vedata, &ssr_id, NULL, false);
}
return DRW_shgroup_create(e_data.default_lit[options], vedata->psl->default_pass[options]);
@@ -778,22 +888,22 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE;
psl->depth_pass = DRW_pass_create("Depth Pass", state);
stl->g_data->depth_shgrp = DRW_shgroup_create(e_data.default_prepass_sh, psl->depth_pass);
- stl->g_data->depth_shgrp_hair_fibers = DRW_shgroup_create(e_data.default_prepass_hair_fiber_sh, psl->depth_pass);
+ stl->g_data->hair_fibers_depth_shgrp = DRW_shgroup_create(e_data.default_prepass_hair_fiber_sh, psl->depth_pass);
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK;
psl->depth_pass_cull = DRW_pass_create("Depth Pass Cull", state);
stl->g_data->depth_shgrp_cull = DRW_shgroup_create(e_data.default_prepass_sh, psl->depth_pass_cull);
- stl->g_data->depth_shgrp_hair_fibers_cull = DRW_shgroup_create(e_data.default_prepass_hair_fiber_sh, psl->depth_pass_cull);
+ stl->g_data->hair_fibers_depth_shgrp_cull = DRW_shgroup_create(e_data.default_prepass_hair_fiber_sh, psl->depth_pass_cull);
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
psl->depth_pass_clip = DRW_pass_create("Depth Pass Clip", state);
stl->g_data->depth_shgrp_clip = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->depth_pass_clip);
- stl->g_data->depth_shgrp_hair_fibers_clip = DRW_shgroup_create(e_data.default_prepass_hair_fiber_clip_sh, psl->depth_pass_clip);
+ stl->g_data->hair_fibers_depth_shgrp_clip = DRW_shgroup_create(e_data.default_prepass_hair_fiber_clip_sh, psl->depth_pass_clip);
state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_CULL_BACK;
psl->depth_pass_clip_cull = DRW_pass_create("Depth Pass Cull Clip", state);
stl->g_data->depth_shgrp_clip_cull = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->depth_pass_clip_cull);
- stl->g_data->depth_shgrp_hair_fibers_clip_cull = DRW_shgroup_create(e_data.default_prepass_hair_fiber_clip_sh, psl->depth_pass_clip_cull);
+ stl->g_data->hair_fibers_depth_shgrp_clip_cull = DRW_shgroup_create(e_data.default_prepass_hair_fiber_clip_sh, psl->depth_pass_clip_cull);
}
{
@@ -802,6 +912,29 @@ void EEVEE_materials_cache_init(EEVEE_Data *vedata)
}
{
+ DRWState state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE;
+ psl->refract_depth_pass = DRW_pass_create("Refract Depth Pass", state);
+ stl->g_data->refract_depth_shgrp = DRW_shgroup_create(e_data.default_prepass_sh, psl->refract_depth_pass);
+
+ state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CULL_BACK;
+ psl->refract_depth_pass_cull = DRW_pass_create("Refract Depth Pass Cull", state);
+ stl->g_data->refract_depth_shgrp_cull = DRW_shgroup_create(e_data.default_prepass_sh, psl->refract_depth_pass_cull);
+
+ state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
+ psl->refract_depth_pass_clip = DRW_pass_create("Refract Depth Pass Clip", state);
+ stl->g_data->refract_depth_shgrp_clip = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip);
+
+ state = DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_CULL_BACK;
+ psl->refract_depth_pass_clip_cull = DRW_pass_create("Refract Depth Pass Cull Clip", state);
+ stl->g_data->refract_depth_shgrp_clip_cull = DRW_shgroup_create(e_data.default_prepass_clip_sh, psl->refract_depth_pass_clip_cull);
+ }
+
+ {
+ DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_EQUAL | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
+ psl->refract_pass = DRW_pass_create("Opaque Refraction Pass", state);
+ }
+
+ {
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_DEPTH_LESS | DRW_STATE_CLIP_PLANES | DRW_STATE_WIRE;
psl->transparent_pass = DRW_pass_create("Material Transparent Pass", state);
}
@@ -844,6 +977,7 @@ static void material_opaque(
float *rough_p = &ma->gloss_mir;
const bool use_gpumat = (ma->use_nodes && ma->nodetree);
+ const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0);
EeveeMaterialShadingGroups *emsg = BLI_ghash_lookup(material_hash, (const void *)ma);
@@ -854,7 +988,7 @@ static void material_opaque(
/* This will have been created already, just perform a lookup. */
*gpumat = (use_gpumat) ? EEVEE_material_mesh_get(
- scene, ma, stl->effects->use_ao, stl->effects->use_bent_normals, false, false) : NULL;
+ scene, ma, false, false, use_refract) : NULL;
*gpumat_depth = (use_gpumat) ? EEVEE_material_mesh_depth_get(
scene, ma, (ma->blend_method == MA_BM_HASHED), false) : NULL;
return;
@@ -862,14 +996,14 @@ static void material_opaque(
if (use_gpumat) {
/* Shading */
- *gpumat = EEVEE_material_mesh_get(scene, ma,
- stl->effects->use_ao, stl->effects->use_bent_normals, false, false);
+ *gpumat = EEVEE_material_mesh_get(scene, ma, false, false, use_refract);
- *shgrp = DRW_shgroup_material_create(*gpumat, psl->material_pass);
+ *shgrp = DRW_shgroup_material_create(*gpumat, use_refract ? psl->refract_pass : psl->material_pass);
if (*shgrp) {
- static int ssr_id;
- ssr_id = (stl->effects->use_ssr) ? 0 : -1;
- add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id);
+ static int no_ssr = -1;
+ static int first_ssr = 0;
+ int *ssr_id = (stl->effects->use_ssr && !use_refract) ? &first_ssr : &no_ssr;
+ add_standard_uniforms(*shgrp, sldata, vedata, ssr_id, &ma->refract_depth, use_refract);
}
else {
/* Shader failed : pink color */
@@ -886,8 +1020,14 @@ static void material_opaque(
*gpumat_depth = EEVEE_material_mesh_depth_get(scene, ma,
(ma->blend_method == MA_BM_HASHED), false);
- *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_cull : psl->depth_pass);
- *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, do_cull ? psl->depth_pass_clip_cull : psl->depth_pass_clip);
+ if (use_refract) {
+ *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_cull : psl->refract_depth_pass);
+ *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->refract_depth_pass_clip_cull : psl->refract_depth_pass_clip);
+ }
+ else {
+ *shgrp_depth = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->depth_pass_cull : psl->depth_pass);
+ *shgrp_depth_clip = DRW_shgroup_material_create(*gpumat_depth, (do_cull) ? psl->depth_pass_clip_cull : psl->depth_pass_clip);
+ }
if (*shgrp != NULL) {
if (ma->blend_method == MA_BM_CLIP) {
@@ -900,8 +1040,7 @@ static void material_opaque(
/* Fallback to default shader */
if (*shgrp == NULL) {
- *shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, false, use_flat_nor,
- stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr);
+ *shgrp = EEVEE_default_shading_group_get(sldata, vedata, false, false, use_flat_nor, stl->effects->use_ssr);
DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
@@ -910,8 +1049,14 @@ static void material_opaque(
/* Fallback default depth prepass */
if (*shgrp_depth == NULL) {
- *shgrp_depth = do_cull ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
- *shgrp_depth_clip = do_cull ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip;
+ if (use_refract) {
+ *shgrp_depth = (do_cull) ? stl->g_data->refract_depth_shgrp_cull : stl->g_data->refract_depth_shgrp;
+ *shgrp_depth_clip = (do_cull) ? stl->g_data->refract_depth_shgrp_clip_cull : stl->g_data->refract_depth_shgrp_clip;
+ }
+ else {
+ *shgrp_depth = (do_cull) ? stl->g_data->depth_shgrp_cull : stl->g_data->depth_shgrp;
+ *shgrp_depth_clip = (do_cull) ? stl->g_data->depth_shgrp_clip_cull : stl->g_data->depth_shgrp_clip;
+ }
}
emsg = MEM_mallocN(sizeof("EeveeMaterialShadingGroups"), "EeveeMaterialShadingGroups");
@@ -930,6 +1075,8 @@ static void material_transparent(
EEVEE_StorageList *stl = ((EEVEE_Data *)vedata)->stl;
EEVEE_PassList *psl = ((EEVEE_Data *)vedata)->psl;
+ const bool use_refract = ((ma->blend_flag & MA_BL_SS_REFRACTION) != 0) && ((stl->effects->enabled_effects & EFFECT_REFRACT) != 0);
+
float *color_p = &ma->r;
float *metal_p = &ma->ray_mirror;
float *spec_p = &ma->spec;
@@ -937,14 +1084,12 @@ static void material_transparent(
if (ma->use_nodes && ma->nodetree) {
/* Shading */
- *gpumat = EEVEE_material_mesh_get(scene, ma,
- stl->effects->use_ao, stl->effects->use_bent_normals,
- true, (ma->blend_method == MA_BM_MULTIPLY));
+ *gpumat = EEVEE_material_mesh_get(scene, ma, true, (ma->blend_method == MA_BM_MULTIPLY), use_refract);
*shgrp = DRW_shgroup_material_create(*gpumat, psl->transparent_pass);
if (*shgrp) {
static int ssr_id = -1; /* TODO transparent SSR */
- add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id);
+ add_standard_uniforms(*shgrp, sldata, vedata, &ssr_id, &ma->refract_depth, use_refract);
}
else {
/* Shader failed : pink color */
@@ -960,7 +1105,7 @@ static void material_transparent(
if (*shgrp == NULL) {
*shgrp = EEVEE_default_shading_group_create(
sldata, vedata, psl->transparent_pass,
- false, false, use_flat_nor, stl->effects->use_ao, stl->effects->use_bent_normals, true, false);
+ false, false, use_flat_nor, true, false);
DRW_shgroup_uniform_vec3(*shgrp, "basecol", color_p, 1);
DRW_shgroup_uniform_float(*shgrp, "metallic", metal_p, 1);
DRW_shgroup_uniform_float(*shgrp, "specular", spec_p, 1);
@@ -1051,12 +1196,11 @@ static void material_particle_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *ved
float *rough_p = &ma->gloss_mir;
if (ma->use_nodes && ma->nodetree) {
- struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma,
- false, stl->effects->use_ao, stl->effects->use_bent_normals);
+ struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma, false);
shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass);
if (shgrp) {
- add_standard_uniforms(shgrp, sldata, vedata, NULL);
+ add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false);
BLI_ghash_insert(material_hash, ma, shgrp);
}
@@ -1072,8 +1216,7 @@ static void material_particle_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *ved
/* Fallback to default shader */
if (shgrp == NULL) {
- shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, false,
- false, stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr);
+ shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, false, false, stl->effects->use_ssr);
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
@@ -1128,12 +1271,12 @@ static void material_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, Obje
ma = &defmaterial;
}
- DRW_shgroup_call_add(stl->g_data->depth_shgrp_hair_fibers, hair_geom, mat);
- DRW_hair_shader_uniforms(stl->g_data->depth_shgrp_hair_fibers, scene,
+ DRW_shgroup_call_add(stl->g_data->hair_fibers_depth_shgrp, hair_geom, mat);
+ DRW_hair_shader_uniforms(stl->g_data->hair_fibers_depth_shgrp, scene,
fiber_texture, fiber_buffer);
- DRW_shgroup_call_add(stl->g_data->depth_shgrp_hair_fibers_clip, hair_geom, mat);
- DRW_hair_shader_uniforms(stl->g_data->depth_shgrp_hair_fibers_clip, scene,
+ DRW_shgroup_call_add(stl->g_data->hair_fibers_depth_shgrp_clip, hair_geom, mat);
+ DRW_hair_shader_uniforms(stl->g_data->hair_fibers_depth_shgrp_clip, scene,
fiber_texture, fiber_buffer);
DRWShadingGroup *shgrp = BLI_ghash_lookup(material_hash, (const void *)ma);
@@ -1144,12 +1287,11 @@ static void material_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, Obje
float *rough_p = &ma->gloss_mir;
if (ma->use_nodes && ma->nodetree) {
- struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma,
- true, stl->effects->use_ao, stl->effects->use_bent_normals);
+ struct GPUMaterial *gpumat = EEVEE_material_hair_get(scene, ma, true);
shgrp = DRW_shgroup_material_create(gpumat, psl->material_pass);
if (shgrp) {
- add_standard_uniforms(shgrp, sldata, vedata, NULL);
+ add_standard_uniforms(shgrp, sldata, vedata, NULL, NULL, false);
BLI_ghash_insert(material_hash, ma, shgrp);
}
@@ -1165,8 +1307,7 @@ static void material_hair(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata, Obje
/* Fallback to default shader */
if (shgrp == NULL) {
- shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, true,
- false, stl->effects->use_ao, stl->effects->use_bent_normals, stl->effects->use_ssr);
+ shgrp = EEVEE_default_shading_group_get(sldata, vedata, true, true, false, stl->effects->use_ssr);
DRW_shgroup_uniform_vec3(shgrp, "basecol", color_p, 1);
DRW_shgroup_uniform_float(shgrp, "metallic", metal_p, 1);
DRW_shgroup_uniform_float(shgrp, "specular", spec_p, 1);
diff --git a/source/blender/draw/engines/eevee/eevee_private.h b/source/blender/draw/engines/eevee/eevee_private.h
index f8a506511b2..4a798c7435c 100644
--- a/source/blender/draw/engines/eevee/eevee_private.h
+++ b/source/blender/draw/engines/eevee/eevee_private.h
@@ -63,21 +63,20 @@ enum {
VAR_MAT_MESH = (1 << 0),
VAR_MAT_PROBE = (1 << 1),
VAR_MAT_HAIR = (1 << 2),
- VAR_MAT_AO = (1 << 3),
- VAR_MAT_FLAT = (1 << 4),
- VAR_MAT_BENT = (1 << 5),
- VAR_MAT_BLEND = (1 << 6),
- VAR_MAT_HAIR_FIBERS = (1 << 7),
+ VAR_MAT_FLAT = (1 << 3),
+ VAR_MAT_BLEND = (1 << 4),
+ VAR_MAT_HAIR_FIBERS = (1 << 5),
/* Max number of variation */
/* IMPORTANT : Leave it last and set
* it's value accordingly. */
- VAR_MAT_MAX = (1 << 8),
+ VAR_MAT_MAX = (1 << 6),
/* These are options that are not counted in VAR_MAT_MAX
* because they are not cumulative with the others above. */
VAR_MAT_CLIP = (1 << 9),
VAR_MAT_HASH = (1 << 10),
VAR_MAT_MULT = (1 << 11),
VAR_MAT_SHADOW = (1 << 12),
+ VAR_MAT_REFRACT = (1 << 12),
};
typedef struct EEVEE_PassList {
@@ -95,6 +94,8 @@ typedef struct EEVEE_PassList {
struct DRWPass *probe_planar_downsample_ps;
/* Effects */
+ struct DRWPass *ao_horizon_search;
+ struct DRWPass *ao_horizon_debug;
struct DRWPass *motion_blur;
struct DRWPass *bloom_blit;
struct DRWPass *bloom_downsample_first;
@@ -110,6 +111,7 @@ typedef struct EEVEE_PassList {
struct DRWPass *ssr_raytrace;
struct DRWPass *ssr_resolve;
struct DRWPass *color_downsample_ps;
+ struct DRWPass *color_downsample_cube_ps;
/* HiZ */
struct DRWPass *minz_downlevel_ps;
@@ -125,14 +127,21 @@ typedef struct EEVEE_PassList {
struct DRWPass *depth_pass_cull;
struct DRWPass *depth_pass_clip;
struct DRWPass *depth_pass_clip_cull;
+ struct DRWPass *refract_depth_pass;
+ struct DRWPass *refract_depth_pass_cull;
+ struct DRWPass *refract_depth_pass_clip;
+ struct DRWPass *refract_depth_pass_clip_cull;
struct DRWPass *default_pass[VAR_MAT_MAX];
struct DRWPass *material_pass;
+ struct DRWPass *refract_pass;
struct DRWPass *transparent_pass;
struct DRWPass *background_pass;
} EEVEE_PassList;
typedef struct EEVEE_FramebufferList {
/* Effects */
+ struct GPUFrameBuffer *gtao_fb;
+ struct GPUFrameBuffer *gtao_debug_fb;
struct GPUFrameBuffer *downsample_fb;
struct GPUFrameBuffer *effect_fb;
struct GPUFrameBuffer *bloom_blit_fb;
@@ -143,6 +152,7 @@ typedef struct EEVEE_FramebufferList {
struct GPUFrameBuffer *dof_scatter_near_fb;
struct GPUFrameBuffer *volumetric_fb;
struct GPUFrameBuffer *screen_tracing_fb;
+ struct GPUFrameBuffer *refract_fb;
struct GPUFrameBuffer *planarref_fb;
@@ -161,13 +171,15 @@ typedef struct EEVEE_TextureList {
struct GPUTexture *bloom_blit; /* R16_G16_B16 */
struct GPUTexture *bloom_downsample[MAX_BLOOM_STEP]; /* R16_G16_B16 */
struct GPUTexture *bloom_upsample[MAX_BLOOM_STEP-1]; /* R16_G16_B16 */
-
struct GPUTexture *ssr_normal_input;
struct GPUTexture *ssr_specrough_input;
+ struct GPUTexture *refract_color;
struct GPUTexture *planar_pool;
struct GPUTexture *planar_depth;
+ struct GPUTexture *gtao_horizons;
+
struct GPUTexture *maxzbuffer;
struct GPUTexture *color; /* R16_G16_B16 */
@@ -335,7 +347,10 @@ typedef struct EEVEE_EffectsInfo {
/* Ambient Occlusion */
bool use_ao, use_bent_normals;
- float ao_dist, ao_samples, ao_factor;
+ float ao_dist, ao_samples, ao_factor, ao_samples_inv;
+ float ao_offset, ao_bounce_fac, ao_quality, ao_settings;
+ float ao_sample_nbr;
+ int ao_texsize[2], hori_tex_layers;
/* Motion Blur */
float current_ndc_to_world[4][4];
@@ -355,7 +370,8 @@ typedef struct EEVEE_EffectsInfo {
float source_texel_size[2];
float blit_texel_size[2];
float downsamp_texel_size[MAX_BLOOM_STEP][2];
- float bloom_intensity;
+ float bloom_color[3];
+ float bloom_clamp;
float bloom_sample_scale;
float bloom_curve_threshold[4];
float unf_source_texel_size[2];
@@ -374,6 +390,8 @@ enum {
EFFECT_VOLUMETRIC = (1 << 3),
EFFECT_SSR = (1 << 4),
EFFECT_DOUBLE_BUFFER = (1 << 5), /* Not really an effect but a feature */
+ EFFECT_REFRACT = (1 << 6),
+ EFFECT_GTAO = (1 << 7),
};
/* ************** SCENE LAYER DATA ************** */
@@ -459,10 +477,14 @@ typedef struct EEVEE_PrivateData {
struct DRWShadingGroup *depth_shgrp_cull;
struct DRWShadingGroup *depth_shgrp_clip;
struct DRWShadingGroup *depth_shgrp_clip_cull;
- struct DRWShadingGroup *depth_shgrp_hair_fibers;
- struct DRWShadingGroup *depth_shgrp_hair_fibers_cull;
- struct DRWShadingGroup *depth_shgrp_hair_fibers_clip;
- struct DRWShadingGroup *depth_shgrp_hair_fibers_clip_cull;
+ struct DRWShadingGroup *hair_fibers_depth_shgrp;
+ struct DRWShadingGroup *hair_fibers_depth_shgrp_cull;
+ struct DRWShadingGroup *hair_fibers_depth_shgrp_clip;
+ struct DRWShadingGroup *hair_fibers_depth_shgrp_clip_cull;
+ struct DRWShadingGroup *refract_depth_shgrp;
+ struct DRWShadingGroup *refract_depth_shgrp_cull;
+ struct DRWShadingGroup *refract_depth_shgrp_clip;
+ struct DRWShadingGroup *refract_depth_shgrp_clip_cull;
struct DRWShadingGroup *cube_display_shgrp;
struct DRWShadingGroup *planar_downsample;
struct GHash *material_hash;
@@ -471,10 +493,13 @@ typedef struct EEVEE_PrivateData {
struct GPUTexture *ssr_hit_output[4];
struct GPUTexture *volumetric;
struct GPUTexture *volumetric_transmit;
+ struct GPUTexture *gtao_horizons_debug;
float background_alpha; /* TODO find a better place for this. */
float viewvecs[2][4];
/* For planar probes */
float texel_size[2];
+ /* To correct mip level texel mis-alignement */
+ float mip_ratio[10][2]; /* TODO put in a UBO */
/* For double buffering */
bool valid_double_buffer;
float prev_persmat[4][4];
@@ -497,9 +522,9 @@ struct GPUMaterial *EEVEE_material_world_background_get(struct Scene *scene, str
struct GPUMaterial *EEVEE_material_world_volume_get(
struct Scene *scene, struct World *wo, bool use_lights, bool use_volume_shadows, bool is_homogeneous, bool use_color_transmit);
struct GPUMaterial *EEVEE_material_mesh_get(
- struct Scene *scene, Material *ma, bool use_ao, bool use_bent_normals, bool use_blend, bool use_multiply);
+ struct Scene *scene, Material *ma, bool use_blend, bool use_multiply, bool use_refract);
struct GPUMaterial *EEVEE_material_mesh_depth_get(struct Scene *scene, Material *ma, bool use_hashed_alpha, bool is_shadow);
-struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma, bool use_fibers, bool use_ao, bool use_bent_normals);
+struct GPUMaterial *EEVEE_material_hair_get(struct Scene *scene, Material *ma, bool use_fibers);
void EEVEE_materials_free(void);
void EEVEE_draw_default_passes(EEVEE_PassList *psl);
@@ -529,8 +554,11 @@ void EEVEE_effects_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_effects_cache_init(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_create_minmax_buffer(EEVEE_Data *vedata, struct GPUTexture *depth_src, int layer);
void EEVEE_downsample_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, struct GPUTexture *texture_src, int level);
+void EEVEE_downsample_cube_buffer(EEVEE_Data *vedata, struct GPUFrameBuffer *fb_src, struct GPUTexture *texture_src, int level);
void EEVEE_effects_do_volumetrics(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_effects_do_ssr(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_effects_do_refraction(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
+void EEVEE_effects_do_gtao(EEVEE_SceneLayerData *sldata, EEVEE_Data *vedata);
void EEVEE_draw_effects(EEVEE_Data *vedata);
void EEVEE_effects_free(void);
diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
index 5a59e362fba..e346009bba8 100644
--- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl
@@ -4,209 +4,312 @@
* http://blog.selfshadow.com/publications/s2016-shading-course/activision/s2016_pbs_activision_occlusion.pptx */
#define MAX_PHI_STEP 32
-/* NOTICE : this is multiplied by 2 */
-#define MAX_THETA_STEP 12
+#define MAX_SEARCH_ITER 32
+#define MAX_LOD 6.0
-uniform sampler2D minMaxDepthTex;
-uniform vec3 aoParameters;
+#ifndef UTIL_TEX
+#define UTIL_TEX
+uniform sampler2DArray utilTex;
+#endif /* UTIL_TEX */
-#define aoDistance aoParameters.x
-#define aoSamples aoParameters.y
-#define aoFactor aoParameters.z
+uniform vec4 aoParameters[2];
+uniform sampler2DArray horizonBuffer;
-float get_max_horizon(vec2 co, vec3 x, float h, float lod)
-{
- float depth = textureLod(minMaxDepthTex, co, floor(lod)).r;
+/* Cannot use textureSize(horizonBuffer) when rendering to it */
+uniform ivec2 aoHorizonTexSize;
- /* Background case */
- /* this is really slow and is only a problem
- * if the far clip plane is near enough to notice */
- // depth += step(1.0, depth) * 1e20;
+#define aoDistance aoParameters[0].x
+#define aoSamples aoParameters[0].y
+#define aoFactor aoParameters[0].z
+#define aoInvSamples aoParameters[0].w
- vec3 s = get_view_space_from_depth(co, depth); /* s View coordinate */
- vec3 omega_s = s - x;
- float len = length(omega_s);
+#define aoOffset aoParameters[1].x
+#define aoBounceFac aoParameters[1].y
+#define aoQuality aoParameters[1].z
+#define aoSettings aoParameters[1].w
- float max_h = max(h, omega_s.z / len);
- /* Blend weight after half the aoDistance to fade artifacts */
- float blend = saturate((1.0 - len / aoDistance) * 2.0);
+#define USE_AO 1
+#define USE_BENT_NORMAL 2
+#define USE_DENOISE 4
- return mix(h, max_h, blend);
-}
+vec2 pack_horizons(vec2 v) { return v * 0.5 + 0.5; }
+vec2 unpack_horizons(vec2 v) { return v * 2.0 - 1.0; }
-void search_step(
- vec2 t_phi, vec3 x, vec2 x_, float rand, vec2 pixel_ratio,
- inout float j, inout float ofs, inout float h1, inout float h2)
+/* Returns the texel coordinate in horizonBuffer
+ * for a given fullscreen coord */
+ivec2 get_hr_co(ivec2 fs_co)
{
- ofs += ofs; /* Step size is doubled each iteration */
+ bvec2 quarter = notEqual(fs_co & ivec2(1), ivec2(0));
- vec2 s_ = t_phi * ofs * rand * pixel_ratio; /* s^ Screen coordinate */
- vec2 co;
+ ivec2 hr_co = fs_co / 2;
+ hr_co += ivec2(quarter) * (aoHorizonTexSize / 2);
+
+ return hr_co;
+}
- co = x_ + s_;
- h1 = get_max_horizon(co, x, h1, j);
+/* Returns the texel coordinate in fullscreen (depthBuffer)
+ * for a given horizonBuffer coord */
+ivec2 get_fs_co(ivec2 hr_co)
+{
+ hr_co *= 2;
+ bvec2 quarter = greaterThanEqual(hr_co, aoHorizonTexSize);
- co = x_ - s_;
- h2 = get_max_horizon(co, x, h2, j);
+ hr_co -= ivec2(quarter) * (aoHorizonTexSize - 1);
- j += 0.5;
+ return hr_co;
}
-void search_horizon(
- vec2 t_phi, vec3 x, vec2 x_, float rand,
- float max_dist, vec2 pixel_ratio, float pixel_len,
- inout float h1, inout float h2)
+/* Returns the phi angle in horizonBuffer
+ * for a given horizonBuffer coord */
+float get_phi(ivec2 hr_co, ivec2 fs_co, float sample)
{
- float ofs = 1.5 * pixel_len;
- float j = 0.0;
-
-#if 0 /* manually unrolled bellow */
- for (int i = 0; i < MAX_THETA_STEP; i++) {
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist)
- return;
+ bvec2 quarter = greaterThanEqual(hr_co, aoHorizonTexSize / 2);
+ ivec2 tex_co = ((int(aoSettings) & USE_DENOISE) != 0) ? hr_co - ivec2(quarter) * (aoHorizonTexSize / 2) : fs_co;
+ float blue_noise = texture(utilTex, vec3((vec2(tex_co) + 0.5) / LUT_SIZE, 2.0)).r;
+
+ float phi = sample * aoInvSamples;
+
+ if ((int(aoSettings) & USE_DENOISE) != 0) {
+ /* Interleaved jitter for spatial 2x2 denoising */
+ phi += 0.25 * aoInvSamples * (float(quarter.x) + 2.0 * float(quarter.y));
+ blue_noise *= 0.25;
}
-#endif
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+ /* Blue noise is scaled to cover the rest of the range. */
+ phi += aoInvSamples * blue_noise;
+ /* Rotate everything (for multisampling) */
+ phi += aoOffset;
+ phi *= M_PI;
+
+ return phi;
+}
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+/* Returns direction jittered offset for a given fullscreen coord */
+float get_offset(ivec2 fs_co, float sample)
+{
+ float offset = sample * aoInvSamples;
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+ /* Interleaved jitter for spatial 2x2 denoising */
+ offset += 0.25 * dot(vec2(1.0), vec2(fs_co & 1));
+ offset += texture(utilTex, vec3((vec2(fs_co / 2) + 0.5 + 16.0) / LUT_SIZE, 2.0)).r;
+ offset = fract(offset + aoOffset);
+ return offset;
+}
+
+/* Returns maximum screen distance an AO ray can travel for a given view depth */
+vec2 get_max_dir(float view_depth)
+{
+ float homcco = ProjectionMatrix[2][3] * view_depth + ProjectionMatrix[3][3];
+ float max_dist = aoDistance / homcco;
+ return vec2(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) * max_dist;
+}
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+void get_max_horizon_grouped(vec4 co1, vec4 co2, vec3 x, float lod, inout float h)
+{
+ co1 *= mipRatio[int(lod + 1.0)].xyxy; /* +1 because we are using half res top level */
+ co2 *= mipRatio[int(lod + 1.0)].xyxy; /* +1 because we are using half res top level */
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+ float depth1 = textureLod(maxzBuffer, co1.xy, floor(lod)).r;
+ float depth2 = textureLod(maxzBuffer, co1.zw, floor(lod)).r;
+ float depth3 = textureLod(maxzBuffer, co2.xy, floor(lod)).r;
+ float depth4 = textureLod(maxzBuffer, co2.zw, floor(lod)).r;
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+ vec4 len, s_h;
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+ vec3 s1 = get_view_space_from_depth(co1.xy, depth1); /* s View coordinate */
+ vec3 omega_s1 = s1 - x;
+ len.x = length(omega_s1);
+ s_h.x = omega_s1.z / len.x;
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+ vec3 s2 = get_view_space_from_depth(co1.zw, depth2); /* s View coordinate */
+ vec3 omega_s2 = s2 - x;
+ len.y = length(omega_s2);
+ s_h.y = omega_s2.z / len.y;
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+ vec3 s3 = get_view_space_from_depth(co2.xy, depth3); /* s View coordinate */
+ vec3 omega_s3 = s3 - x;
+ len.z = length(omega_s3);
+ s_h.z = omega_s3.z / len.z;
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+ vec3 s4 = get_view_space_from_depth(co2.zw, depth4); /* s View coordinate */
+ vec3 omega_s4 = s4 - x;
+ len.w = length(omega_s4);
+ s_h.w = omega_s4.z / len.w;
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
- if (ofs > max_dist) return;
+ /* Blend weight after half the aoDistance to fade artifacts */
+ vec4 blend = saturate((1.0 - len / aoDistance) * 2.0);
- search_step(t_phi, x, x_, rand, pixel_ratio, j, ofs, h1, h2);
+ h = mix(h, max(h, s_h.x), blend.x);
+ h = mix(h, max(h, s_h.y), blend.y);
+ h = mix(h, max(h, s_h.z), blend.z);
+ h = mix(h, max(h, s_h.w), blend.w);
}
-void integrate_slice(
- float iter, vec3 x, vec3 normal, vec2 x_, vec2 noise,
- float max_dist, vec2 pixel_ratio, float pixel_len,
- inout float visibility, inout vec3 bent_normal)
+vec2 search_horizon_sweep(float phi, vec3 pos, vec2 uvs, float jitter, vec2 max_dir)
{
- float phi = M_PI * ((noise.r + iter) / aoSamples);
-
- /* Rotate with random direction to get jittered result. */
vec2 t_phi = vec2(cos(phi), sin(phi)); /* Screen space direction */
- /* Search maximum horizon angles h1 and h2 */
- float h1 = -1.0, h2 = -1.0; /* init at cos(pi) */
- search_horizon(t_phi, x, x_, noise.g, max_dist, pixel_ratio, pixel_len, h1, h2);
+ max_dir *= max_v2(abs(t_phi));
- /* (Slide 54) */
- h1 = -fast_acos(h1);
- h2 = fast_acos(h2);
+ /* Convert to pixel space. */
+ t_phi /= vec2(textureSize(maxzBuffer, 0));
+
+ /* Avoid division by 0 */
+ t_phi += vec2(1e-5);
+
+ jitter *= 0.25;
+
+ /* Compute end points */
+ vec2 corner1 = min(vec2(1.0) - uvs, max_dir); /* Top right */
+ vec2 corner2 = max(vec2(0.0) - uvs, -max_dir); /* Bottom left */
+ vec2 iter1 = corner1 / t_phi;
+ vec2 iter2 = corner2 / t_phi;
+
+ vec2 min_iter = max(-iter1, -iter2);
+ vec2 max_iter = max( iter1, iter2);
+
+ vec2 times = vec2(-min_v2(min_iter), min_v2(max_iter));
+
+ vec2 h = vec2(-1.0); /* init at cos(pi) */
+
+ /* This is freaking sexy optimized. */
+ for (float i = 0.0, ofs = 4.0, time = -1.0;
+ i < MAX_SEARCH_ITER && time > times.x;
+ i++, time -= ofs, ofs = min(exp2(MAX_LOD) * 4.0, ofs + ofs * aoQuality))
+ {
+ vec4 t = max(times.xxxx, vec4(time) - (vec4(0.25, 0.5, 0.75, 1.0) - jitter) * ofs);
+ vec4 cos1 = uvs.xyxy + t_phi.xyxy * t.xxyy;
+ vec4 cos2 = uvs.xyxy + t_phi.xyxy * t.zzww;
+ float lod = min(MAX_LOD, max(i - jitter * 4.0, 0.0) * aoQuality);
+ get_max_horizon_grouped(cos1, cos2, pos, lod, h.y);
+ }
+
+ for (float i = 0.0, ofs = 4.0, time = 1.0;
+ i < MAX_SEARCH_ITER && time < times.y;
+ i++, time += ofs, ofs = min(exp2(MAX_LOD) * 4.0, ofs + ofs * aoQuality))
+ {
+ vec4 t = min(times.yyyy, vec4(time) + (vec4(0.25, 0.5, 0.75, 1.0) - jitter) * ofs);
+ vec4 cos1 = uvs.xyxy + t_phi.xyxy * t.xxyy;
+ vec4 cos2 = uvs.xyxy + t_phi.xyxy * t.zzww;
+ float lod = min(MAX_LOD, max(i - jitter * 4.0, 0.0) * aoQuality);
+ get_max_horizon_grouped(cos1, cos2, pos, lod, h.x);
+ }
+
+ return h;
+}
+
+void integrate_slice(vec3 normal, float phi, vec2 horizons, inout float visibility, inout vec3 bent_normal)
+{
+ /* TODO OPTI Could be precomputed. */
+ vec2 t_phi = vec2(cos(phi), sin(phi)); /* Screen space direction */
/* Projecting Normal to Plane P defined by t_phi and omega_o */
- vec3 h = vec3(t_phi.y, -t_phi.x, 0.0); /* Normal vector to Integration plane */
+ vec3 np = vec3(t_phi.y, -t_phi.x, 0.0); /* Normal vector to Integration plane */
vec3 t = vec3(-t_phi, 0.0);
- vec3 n_proj = normal - h * dot(h, normal);
+ vec3 n_proj = normal - np * dot(np, normal);
float n_proj_len = max(1e-16, length(n_proj));
- /* Clamping thetas (slide 58) */
float cos_n = clamp(n_proj.z / n_proj_len, -1.0, 1.0);
float n = sign(dot(n_proj, t)) * fast_acos(cos_n); /* Angle between view vec and normal */
- h1 = n + max(h1 - n, -M_PI_2);
- h2 = n + min(h2 - n, M_PI_2);
+
+ /* (Slide 54) */
+ vec2 h = fast_acos(horizons);
+ h.x = -h.x;
+
+ /* Clamping thetas (slide 58) */
+ h.x = n + max(h.x - n, -M_PI_2);
+ h.y = n + min(h.y - n, M_PI_2);
/* Solving inner integral */
- float sin_n = sin(n);
- float h1_2 = 2.0 * h1;
- float h2_2 = 2.0 * h2;
- float vd = (-cos(h1_2 - n) + cos_n + h1_2 * sin_n) + (-cos(h2_2 - n) + cos_n + h2_2 * sin_n);
- vd *= 0.25 * n_proj_len;
- visibility += vd;
-
-#ifdef USE_BENT_NORMAL
+ vec2 h_2 = 2.0 * h;
+ vec2 vd = -cos(h_2 - n) + cos_n + h_2 * sin(n);
+ float vis = (vd.x + vd.y) * 0.25 * n_proj_len;
+
+ visibility += vis;
+
/* Finding Bent normal */
- float b_angle = (h1 + h2) / 2.0;
+ float b_angle = (h.x + h.y) * 0.5;
/* The 0.5 factor below is here to equilibrate the accumulated vectors.
* (sin(b_angle) * -t_phi) will accumulate to (phi_step * result_nor.xy * 0.5).
* (cos(b_angle) * 0.5) will accumulate to (phi_step * result_nor.z * 0.5). */
- /* Weight sample by vd */
- bent_normal += vec3(sin(b_angle) * -t_phi, cos(b_angle) * 0.5) * vd;
-#endif
+ bent_normal += vec3(sin(b_angle) * -t_phi, cos(b_angle) * 0.5);
}
-void gtao(vec3 normal, vec3 position, vec2 noise, out float visibility
-#ifdef USE_BENT_NORMAL
- , out vec3 bent_normal
-#endif
- )
+void denoise_ao(vec3 normal, float frag_depth, inout float visibility, inout vec3 bent_normal)
+{
+ vec2 d_sign = vec2(ivec2(gl_FragCoord.xy) & 1) - 0.5;
+
+ if ((int(aoSettings) & USE_DENOISE) == 0) {
+ d_sign *= 0.0;
+ }
+
+ /* 2x2 Bilateral Filter using derivatives. */
+ vec2 n_step = step(-0.2, -abs(vec2(length(dFdx(normal)), length(dFdy(normal)))));
+ vec2 z_step = step(-0.1, -abs(vec2(dFdx(frag_depth), dFdy(frag_depth))));
+
+ visibility -= dFdx(visibility) * d_sign.x * z_step.x * n_step.x;
+ visibility -= dFdy(visibility) * d_sign.y * z_step.y * n_step.y;
+
+ bent_normal -= dFdx(bent_normal) * d_sign.x * z_step.x * n_step.x;
+ bent_normal -= dFdy(bent_normal) * d_sign.y * z_step.y * n_step.y;
+}
+
+void gtao_deferred(vec3 normal, vec3 position, float frag_depth, out float visibility, out vec3 bent_normal)
{
- vec2 screenres = vec2(textureSize(minMaxDepthTex, 0)) * 2.0;
- vec2 pixel_size = vec2(1.0) / screenres.xy;
+ vec2 uvs = get_uvs_from_view(position);
+
+ vec4 texel_size = vec4(-1.0, -1.0, 1.0, 1.0) / vec2(textureSize(depthBuffer, 0)).xyxy;
+
+ ivec2 fs_co = ivec2(gl_FragCoord.xy);
+ ivec2 hr_co = get_hr_co(fs_co);
+
+ bent_normal = vec3(0.0);
+ visibility = 0.0;
+
+ for (float i = 0.0; i < MAX_PHI_STEP; i++) {
+ if (i >= aoSamples) break;
- /* Renaming */
- vec2 x_ = gl_FragCoord.xy * pixel_size; /* x^ Screen coordinate */
- vec3 x = position; /* x view space coordinate */
+ vec2 horiz = unpack_horizons(texelFetch(horizonBuffer, ivec3(hr_co, int(i)), 0).rg);
+ float phi = get_phi(hr_co, fs_co, i);
- /* NOTE : We set up integration domain around the camera forward axis
- * and not the view vector like in the paper.
- * This allows us to save a lot of dot products. */
- /* omega_o = vec3(0.0, 0.0, 1.0); */
+ integrate_slice(normal, phi, horiz.xy, visibility, bent_normal);
+ }
+
+ visibility *= aoInvSamples;
+ bent_normal = normalize(bent_normal);
+}
+
+void gtao(vec3 normal, vec3 position, vec2 noise, out float visibility, out vec3 bent_normal)
+{
+ vec2 uvs = get_uvs_from_view(position);
- vec2 pixel_ratio = vec2(screenres.y / screenres.x, 1.0);
- float pixel_len = length(pixel_size);
float homcco = ProjectionMatrix[2][3] * position.z + ProjectionMatrix[3][3];
float max_dist = aoDistance / homcco; /* Search distance */
+ vec2 max_dir = max_dist * vec2(ProjectionMatrix[0][0], ProjectionMatrix[1][1]);
- /* Integral over PI */
- visibility = 0.0;
-#ifdef USE_BENT_NORMAL
bent_normal = vec3(0.0);
-#else
- vec3 bent_normal = vec3(0.0);
-#endif
+ visibility = 0.0;
+
for (float i = 0.0; i < MAX_PHI_STEP; i++) {
if (i >= aoSamples) break;
- integrate_slice(i, x, normal, x_, noise, max_dist, pixel_ratio, pixel_len, visibility, bent_normal);
- }
- /* aoSamples can be 0.0 to temporary disable the effect. */
- visibility = clamp(max(1e-8, visibility) / max(1e-8, aoSamples), 1e-8, 1.0);
+ float phi = M_PI * (i + noise.x) * aoInvSamples;
+ vec2 horizons = search_horizon_sweep(phi, position, uvs, noise.g, max_dir);
-#ifdef USE_BENT_NORMAL
- /* The bent normal will show the facet look of the mesh. Try to minimize this. */
- bent_normal = normalize(mix(bent_normal / visibility, normal, visibility * visibility * visibility));
-#endif
+ integrate_slice(normal, phi, horizons, visibility, bent_normal);
+ }
- /* Scale by user factor */
- visibility = pow(visibility, aoFactor);
+ visibility *= aoInvSamples;
+ bent_normal = normalize(bent_normal);
}
/* Multibounce approximation base on surface albedo.
* Page 78 in the .pdf version. */
float gtao_multibounce(float visibility, vec3 albedo)
{
+ if (aoBounceFac == 0.0) return visibility;
+
/* Median luminance. Because Colored multibounce looks bad. */
- float lum = albedo.x * 0.3333;
- lum += albedo.y * 0.3333;
- lum += albedo.z * 0.3333;
+ float lum = dot(albedo, vec3(0.3333));
float a = 2.0404 * lum - 0.3324;
float b = -4.7951 * lum + 0.6417;
@@ -219,24 +322,38 @@ float gtao_multibounce(float visibility, vec3 albedo)
/* Use the right occlusion */
float occlusion_compute(vec3 N, vec3 vpos, float user_occlusion, vec2 randuv, out vec3 bent_normal)
{
-#ifdef USE_AO /* Screen Space Occlusion */
-
- float computed_occlusion;
- vec3 vnor = mat3(ViewMatrix) * N;
+ if ((int(aoSettings) & USE_AO) == 0) {
+ bent_normal = N;
+ return user_occlusion;
+ }
+ else {
+ float visibility;
+ vec3 vnor = mat3(ViewMatrix) * N;
-#ifdef USE_BENT_NORMAL
- gtao(vnor, vpos, randuv, computed_occlusion, bent_normal);
- bent_normal = mat3(ViewMatrixInverse) * bent_normal;
+#if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY) && !defined(USE_ALPHA_BLEND)
+ gtao_deferred(vnor, vpos, gl_FragCoord.z, visibility, bent_normal);
#else
- gtao(vnor, vpos, randuv, computed_occlusion);
- bent_normal = N;
+ gtao(vnor, vpos, randuv, visibility, bent_normal);
#endif
- return min(computed_occlusion, user_occlusion);
+ denoise_ao(vnor, gl_FragCoord.z, visibility, bent_normal);
-#else /* No added Occlusion. */
+ /* Prevent some problems down the road. */
+ visibility = max(1e-3, visibility);
- bent_normal = N;
- return user_occlusion;
+ if ((int(aoSettings) & USE_BENT_NORMAL) != 0) {
+ /* The bent normal will show the facet look of the mesh. Try to minimize this. */
+ float mix_fac = visibility * visibility;
+ bent_normal = normalize(mix(bent_normal, vnor, mix_fac));
-#endif
+ bent_normal = transform_direction(ViewMatrixInverse, bent_normal);
+ }
+ else {
+ bent_normal = N;
+ }
+
+ /* Scale by user factor */
+ visibility = pow(visibility, aoFactor);
+
+ return min(visibility, user_occlusion);
+ }
}
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
index e80835ee498..fc339e93927 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_common_lib.glsl
@@ -27,6 +27,15 @@ flat in int shFace; /* Shadow layer we are rendering to. */
#define ViewMatrix FaceViewMatrix[shFace]
#endif
+uniform vec2 mipRatio[10];
+
+/* Buffers */
+uniform sampler2D colorBuffer;
+uniform sampler2D depthBuffer;
+uniform sampler2D maxzBuffer;
+uniform sampler2D minzBuffer;
+uniform sampler2DArray planarDepth;
+
#define cameraForward normalize(ViewMatrixInverse[2].xyz)
#define cameraPos ViewMatrixInverse[3].xyz
#define cameraVec ((ProjectionMatrix[3][3] == 0.0) ? normalize(cameraPos - worldPosition) : cameraForward)
@@ -102,6 +111,7 @@ vec3 project_point(mat4 m, vec3 v) {
return tmp.xyz / tmp.w;
}
+float min_v2(vec2 v) { return min(v.x, v.y); }
float min_v3(vec3 v) { return min(v.x, min(v.y, v.z)); }
float max_v2(vec2 v) { return max(v.x, v.y); }
@@ -116,20 +126,38 @@ float len_squared(vec3 a) { return dot(a, a); }
float inverse_distance(vec3 V) { return max( 1 / length(V), 1e-8); }
+vec2 mip_ratio_interp(float mip) {
+ float low_mip = floor(mip);
+ return mix(mipRatio[int(low_mip)], mipRatio[int(low_mip + 1.0)], mip - low_mip);
+}
/* ------- Fast Math ------- */
/* [Drobot2014a] Low Level Optimizations for GCN */
-float fast_sqrt(float x)
+float fast_sqrt(float v)
+{
+ return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
+}
+
+vec2 fast_sqrt(vec2 v)
{
- return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(x) >> 1));
+ return intBitsToFloat(0x1fbd1df5 + (floatBitsToInt(v) >> 1));
}
/* [Eberly2014] GPGPU Programming for Games and Science */
-float fast_acos(float x)
+float fast_acos(float v)
{
- float res = -0.156583 * abs(x) + M_PI_2;
- res *= fast_sqrt(1.0 - abs(x));
- return (x >= 0) ? res : M_PI - res;
+ float res = -0.156583 * abs(v) + M_PI_2;
+ res *= fast_sqrt(1.0 - abs(v));
+ return (v >= 0) ? res : M_PI - res;
+}
+
+vec2 fast_acos(vec2 v)
+{
+ vec2 res = -0.156583 * abs(v) + M_PI_2;
+ res *= fast_sqrt(1.0 - abs(v));
+ v.x = (v.x >= 0) ? res.x : M_PI - res.x;
+ v.y = (v.y >= 0) ? res.y : M_PI - res.y;
+ return v;
}
float point_plane_projection_dist(vec3 lineorigin, vec3 planeorigin, vec3 planenormal)
@@ -266,6 +294,12 @@ float get_view_z_from_depth(float depth)
}
}
+vec2 get_uvs_from_view(vec3 view)
+{
+ vec3 ndc = project_point(ProjectionMatrix, view);
+ return ndc.xy * 0.5 + 0.5;
+}
+
vec3 get_view_space_from_depth(vec2 uvcoords, float depth)
{
if (ProjectionMatrix[3][3] == 0.0) {
@@ -281,7 +315,7 @@ vec3 get_world_space_from_depth(vec2 uvcoords, float depth)
return (ViewMatrixInverse * vec4(get_view_space_from_depth(uvcoords, depth), 1.0)).xyz;
}
-vec3 get_specular_dominant_dir(vec3 N, vec3 V, float roughness)
+vec3 get_specular_reflection_dominant_dir(vec3 N, vec3 V, float roughness)
{
vec3 R = -reflect(V, N);
float smoothness = 1.0 - roughness;
@@ -294,6 +328,69 @@ float specular_occlusion(float NV, float AO, float roughness)
return saturate(pow(NV + AO, roughness) - 1.0 + AO);
}
+/* --- Refraction utils --- */
+
+float ior_from_f0(float f0)
+{
+ float f = sqrt(f0);
+ return (-f - 1.0) / (f - 1.0);
+}
+
+float f0_from_ior(float eta)
+{
+ float A = (eta - 1.0) / (eta + 1.0);
+ return A * A;
+}
+
+vec3 get_specular_refraction_dominant_dir(vec3 N, vec3 V, float roughness, float ior)
+{
+ /* TODO: This a bad approximation. Better approximation should fit
+ * the refracted vector and roughness into the best prefiltered reflection
+ * lobe. */
+ /* Correct the IOR for ior < 1.0 to not see the abrupt delimitation or the TIR */
+ ior = (ior < 1.0) ? mix(ior, 1.0, roughness) : ior;
+ float eta = 1.0 / ior;
+
+ float NV = dot(N, -V);
+
+ /* Custom Refraction. */
+ float k = 1.0 - eta * eta * (1.0 - NV * NV);
+ k = max(0.0, k); /* Only this changes. */
+ vec3 R = eta * -V - (eta * NV + sqrt(k)) * N;
+
+ return R;
+}
+
+float get_btdf_lut(sampler2DArray btdf_lut_tex, float NV, float roughness, float ior)
+{
+ const vec3 lut_scale_bias_texel_size = vec3((LUT_SIZE - 1.0), 0.5, 1.5) / LUT_SIZE;
+
+ vec3 coords;
+ /* Try to compensate for the low resolution and interpolation error. */
+ coords.x = (ior > 1.0)
+ ? (0.9 + lut_scale_bias_texel_size.z) + (0.1 - lut_scale_bias_texel_size.z) * f0_from_ior(ior)
+ : (0.9 + lut_scale_bias_texel_size.z) * ior * ior;
+ coords.y = 1.0 - saturate(NV);
+ coords.xy *= lut_scale_bias_texel_size.x;
+ coords.xy += lut_scale_bias_texel_size.y;
+
+ const float lut_lvl_ofs = 4.0; /* First texture lvl of roughness. */
+ const float lut_lvl_scale = 16.0; /* How many lvl of roughness in the lut. */
+
+ float mip = roughness * lut_lvl_scale;
+ float mip_floor = floor(mip);
+
+ coords.z = lut_lvl_ofs + mip_floor + 1.0;
+ float btdf_high = textureLod(btdf_lut_tex, coords, 0.0).r;
+
+ coords.z -= 1.0;
+ float btdf_low = textureLod(btdf_lut_tex, coords, 0.0).r;
+
+ float btdf = (ior == 1.0) ? 1.0 : mix(btdf_low, btdf_high, mip - coords.z);
+
+ return btdf;
+}
+
/* ---- Encode / Decode Normal buffer data ---- */
/* From http://aras-p.info/texts/CompactNormalStorage.html
* Using Method #4: Spheremap Transform */
@@ -314,10 +411,38 @@ vec3 normal_decode(vec2 enc, vec3 view)
return n;
}
+/* Fresnel monochromatic, perfect mirror */
+float F_eta(float eta, float cos_theta)
+{
+ /* compute fresnel reflectance without explicitly computing
+ * the refracted direction */
+ float c = abs(cos_theta);
+ float g = eta * eta - 1.0 + c * c;
+ float result;
+
+ if (g > 0.0) {
+ g = sqrt(g);
+ vec2 g_c = vec2(g) + vec2(c, -c);
+ float A = g_c.y / g_c.x;
+ A *= A;
+ g_c *= c;
+ float B = (g_c.y - 1.0) / (g_c.x + 1.0);
+ B *= B;
+ result = 0.5 * A * (1.0 + B);
+ }
+ else {
+ result = 1.0; /* TIR (no refracted component) */
+ }
+
+ return result;
+}
+
/* Fresnel */
vec3 F_schlick(vec3 f0, float cos_theta)
{
- float fac = pow(1.0 - cos_theta, 5);
+ float fac = 1.0 - cos_theta;
+ float fac2 = fac * fac;
+ fac = fac2 * fac2 * fac;
/* Unreal specular matching : if specular color is below 2% intensity,
* (using green channel for intensity) treat as shadowning */
@@ -334,7 +459,7 @@ vec3 F_area(vec3 f0, vec2 lut)
return saturate(50.0 * dot(f0, vec3(0.3, 0.6, 0.1))) * fac.y + fac.x * f0;
}
-/* Fresnel approximation for LTC area lights (not MRP) */
+/* Fresnel approximation for IBL */
vec3 F_ibl(vec3 f0, vec2 lut)
{
/* Unreal specular matching : if specular color is below 2% intensity,
@@ -469,7 +594,7 @@ Closure closure_add(Closure cl1, Closure cl2)
return cl;
}
-#if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER)
+#if defined(MESH_SHADER) && !defined(USE_ALPHA_HASH) && !defined(USE_ALPHA_CLIP) && !defined(SHADOW_SHADER) && !defined(USE_MULTIPLY)
layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec4 ssrNormals;
layout(location = 2) out vec4 ssrData;
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
index 5ab572e03ea..d0a365f5a3e 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_direct_lib.glsl
@@ -85,6 +85,7 @@ float direct_diffuse_unit_disc(vec3 N, vec3 L)
/* ----------- GGx ------------ */
vec3 direct_ggx_point(vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
{
+ roughness = max(1e-3, roughness);
float dist = l_vector.w;
vec3 L = l_vector.xyz / dist;
float bsdf = bsdf_ggx(N, L, V, roughness);
@@ -97,15 +98,16 @@ vec3 direct_ggx_point(vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
vec3 direct_ggx_sun(LightData ld, vec3 N, vec3 V, float roughness, vec3 f0)
{
+ roughness = max(1e-3, roughness);
float bsdf = bsdf_ggx(N, -ld.l_forward, V, roughness);
- float VH = max(dot(V, normalize(V - ld.l_forward)), 0.0);
+ float VH = dot(V, -ld.l_forward) * 0.5 + 0.5;
return F_schlick(f0, VH) * bsdf;
}
vec3 direct_ggx_sphere(LightData ld, vec3 N, vec3 V, vec4 l_vector, float roughness, vec3 f0)
{
vec3 L = l_vector.xyz / l_vector.w;
- vec3 spec_dir = get_specular_dominant_dir(N, V, roughness);
+ vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughness);
vec3 P = line_aligned_plane_intersect(vec3(0.0), spec_dir, l_vector.xyz);
vec3 Px = normalize(P - l_vector.xyz) * ld.l_radius;
diff --git a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
index c7daea77782..f58dac6c0a0 100644
--- a/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/bsdf_sampling_lib.glsl
@@ -6,12 +6,16 @@ uniform float invSampleCount;
vec2 jitternoise = vec2(0.0);
-#ifdef NOISE_SIZE
+#ifndef UTIL_TEX
+#define UTIL_TEX
+uniform sampler2DArray utilTex;
+#endif /* UTIL_TEX */
+
void setup_noise(void)
{
- jitternoise = texture(texJitter, gl_FragCoord.xy / NOISE_SIZE).rg; /* Global variable */
+ jitternoise = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0)).rg; /* Global variable */
+ jitternoise.g = (jitternoise.g - 0.5) * 2.0;
}
-#endif
#ifdef HAMMERSLEY_SIZE
vec3 hammersley_3d(float i, float invsamplenbr)
diff --git a/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
new file mode 100644
index 00000000000..2c604d69641
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/btdf_lut_frag.glsl
@@ -0,0 +1,59 @@
+
+uniform float a2;
+
+out vec4 FragColor;
+
+void main() {
+ vec3 N, T, B, V;
+
+ float x = gl_FragCoord.x / BRDF_LUT_SIZE;
+ float y = gl_FragCoord.y / BRDF_LUT_SIZE;
+ /* There is little variation if ior > 1.0 so we
+ * maximize LUT precision for ior < 1.0 */
+ x = x * 1.1;
+ float ior = (x > 1.0) ? ior_from_f0((x-1.0) * 10.0) : sqrt(x);
+ float NV = (1.0 - (clamp(y, 1e-4, 0.9999)));
+
+ N = vec3(0.0, 0.0, 1.0);
+ T = vec3(1.0, 0.0, 0.0);
+ B = vec3(0.0, 1.0, 0.0);
+ V = vec3(sqrt(1.0 - NV * NV), 0.0, NV);
+
+ setup_noise();
+
+ /* Integrating BTDF */
+ float btdf_accum = 0.0;
+ for (float i = 0.0; i < sampleCount; i++) {
+ vec3 H = sample_ggx(i, a2, N, T, B); /* Microfacet normal */
+
+ float VH = dot(V, H);
+
+ /* Check if there is total internal reflections. */
+ float c = abs(VH);
+ float g = ior * ior - 1.0 + c * c;
+
+ float eta = 1.0/ior;
+ if (dot(H, V) < 0.0) {
+ H = -H;
+ eta = ior;
+ }
+
+ vec3 L = refract(-V, H, eta);
+ float NL = -dot(N, L);
+
+ if ((NL > 0.0) && (g > 0.0)) {
+ float LH = dot(L, H);
+
+ float G1_l = NL * 2.0 / G1_Smith_GGX(NL, a2); /* Balancing the adjustments made in G1_Smith */
+
+ /* btdf = abs(VH*LH) * (ior*ior) * D * G(V) * G(L) / (Ht2 * NV)
+ * pdf = (VH * abs(LH)) * (ior*ior) * D * G(V) / (Ht2 * NV) */
+ float btdf = G1_l * abs(VH*LH) / (VH * abs(LH));
+
+ btdf_accum += btdf;
+ }
+ }
+ btdf_accum /= sampleCount;
+
+ FragColor = vec4(btdf_accum, 0.0, 0.0, 1.0);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
index 5bb9607d33c..29543e82f43 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_bloom_frag.glsl
@@ -31,6 +31,7 @@ uniform vec2 sourceBufferTexelSize;
/* Step Blit */
uniform vec4 curveThreshold;
+uniform float clampIntensity;
/* Step Upsample */
uniform sampler2D baseBuffer; /* Previous accumulation buffer */
@@ -38,7 +39,7 @@ uniform vec2 baseBufferTexelSize;
uniform float sampleScale;
/* Step Resolve */
-uniform float bloomIntensity;
+uniform vec3 bloomColor;
in vec4 uvcoordsvar;
@@ -161,7 +162,11 @@ vec4 step_blit(void)
rq = curveThreshold.z * rq * rq;
/* Combine and apply the brightness response curve. */
- m *= max(rq, br - curveThreshold.w) / max(br, 1e-5);
+ m *= max(rq, br - curveThreshold.w) / max(1e-5, br);
+
+ /* Clamp pixel intensity */
+ br = max(1e-5, brightness(m));
+ m *= 1.0 - max(0.0, br - clampIntensity) / br;
return vec4(m, 1.0);
}
@@ -195,7 +200,7 @@ vec4 step_resolve(void)
vec3 blur = upsample_filter(sourceBuffer, uvcoordsvar.xy, sourceBufferTexelSize);
#endif
vec4 base = textureLod(baseBuffer, uvcoordsvar.xy, 0.0);
- vec3 cout = base.rgb + blur * bloomIntensity;
+ vec3 cout = base.rgb + blur * bloomColor;
return vec4(cout, base.a);
}
diff --git a/source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl
new file mode 100644
index 00000000000..eb463d51146
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_downsample_cube_frag.glsl
@@ -0,0 +1,30 @@
+/**
+ * Simple downsample shader. Takes the average of the 4 texels of lower mip.
+ **/
+
+uniform samplerCube source;
+uniform float texelSize;
+
+flat in int fFace;
+
+out vec4 FragColor;
+
+const vec3 maj_axes[6] = vec3[6](vec3(1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), vec3(0.0, -1.0, 0.0), vec3( 0.0, 0.0, 1.0), vec3( 0.0, 0.0, -1.0));
+const vec3 x_axis[6] = vec3[6](vec3(0.0, 0.0, -1.0), vec3( 0.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0), vec3(1.0, 0.0, 0.0), vec3( 1.0, 0.0, 0.0), vec3(-1.0, 0.0, 0.0));
+const vec3 y_axis[6] = vec3[6](vec3(0.0, -1.0, 0.0), vec3( 0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, -1.0), vec3( 0.0, -1.0, 0.0), vec3( 0.0, -1.0, 0.0));
+
+float brightness(vec3 c)
+{
+ return max(max(c.r, c.g), c.b);
+}
+
+void main()
+{
+ vec2 uvs = gl_FragCoord.xy * texelSize;
+
+ uvs = 2.0 * uvs - 1.0;
+
+ vec3 cubevec = x_axis[fFace] * uvs.x + y_axis[fFace] * uvs.y + maj_axes[fFace];
+
+ FragColor = textureLod(source, cubevec, 0.0);
+} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl
index 1e57aec5ea2..156be108a14 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_downsample_frag.glsl
@@ -3,13 +3,35 @@
**/
uniform sampler2D source;
+uniform float fireflyFactor;
out vec4 FragColor;
+float brightness(vec3 c)
+{
+ return max(max(c.r, c.g), c.b);
+}
+
void main()
{
+#if 0
/* Reconstructing Target uvs like this avoid missing pixels if NPO2 */
vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(source, 0));
FragColor = textureLod(source, uvs, 0.0);
+#else
+ vec2 texel_size = 1.0 / vec2(textureSize(source, 0));
+ vec2 uvs = gl_FragCoord.xy * 2.0 * texel_size;
+ vec4 ofs = texel_size.xyxy * vec4(0.75, 0.75, -0.75, -0.75);
+
+ FragColor = textureLod(source, uvs + ofs.xy, 0.0);
+ FragColor += textureLod(source, uvs + ofs.xw, 0.0);
+ FragColor += textureLod(source, uvs + ofs.zy, 0.0);
+ FragColor += textureLod(source, uvs + ofs.zw, 0.0);
+ FragColor *= 0.25;
+
+ /* Clamped brightness. */
+ float luma = max(1e-8, brightness(FragColor.rgb));
+ FragColor *= 1.0 - max(0.0, luma - fireflyFactor) / luma;
+#endif
} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
new file mode 100644
index 00000000000..1c63051c65b
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl
@@ -0,0 +1,69 @@
+/**
+ * This shader only compute maximum horizon angles for each directions.
+ * The final integration is done at the resolve stage with the shading normal.
+ **/
+
+uniform float rotationOffset;
+
+out vec4 FragColor;
+
+#ifdef DEBUG_AO
+uniform sampler2D normalBuffer;
+
+void main()
+{
+ vec4 texel_size = 1.0 / vec2(textureSize(depthBuffer, 0)).xyxy;
+ vec2 uvs = saturate(gl_FragCoord.xy * texel_size.xy);
+
+ float depth = textureLod(depthBuffer, uvs, 0.0).r;
+
+ vec3 viewPosition = get_view_space_from_depth(uvs, depth);
+ vec3 V = viewCameraVec;
+ vec3 normal = normal_decode(texture(normalBuffer, uvs).rg, V);
+
+ vec3 bent_normal;
+ float visibility;
+#if 1
+ gtao_deferred(normal, viewPosition, depth, visibility, bent_normal);
+#else
+ vec2 rand = vec2((1.0 / 4.0) * float((int(gl_FragCoord.y) & 0x1) * 2 + (int(gl_FragCoord.x) & 0x1)), 0.5);
+ rand = fract(rand.x + texture(utilTex, vec3(floor(gl_FragCoord.xy * 0.5) / LUT_SIZE, 2.0)).rg);
+ gtao(normal, viewPosition, rand, visibility, bent_normal);
+#endif
+ denoise_ao(normal, depth, visibility, bent_normal);
+
+ FragColor = vec4(visibility);
+}
+
+#else
+uniform float sampleNbr;
+
+void main()
+{
+ ivec2 hr_co = ivec2(gl_FragCoord.xy);
+ ivec2 fs_co = get_fs_co(hr_co);
+
+ vec2 uvs = saturate((vec2(fs_co) + 0.5) / vec2(textureSize(depthBuffer, 0)));
+ float depth = textureLod(depthBuffer, uvs, 0.0).r;
+
+ if (depth == 1.0) {
+ /* Do not trace for background */
+ FragColor = vec4(0.0);
+ return;
+ }
+
+ /* Avoid self shadowing. */
+ depth = saturate(depth - 3e-6); /* Tweaked for 24bit depth buffer. */
+
+ vec3 viewPosition = get_view_space_from_depth(uvs, depth);
+
+ float phi = get_phi(hr_co, fs_co, sampleNbr);
+ float offset = get_offset(fs_co, sampleNbr);
+ vec2 max_dir = get_max_dir(viewPosition.z);
+
+ FragColor.xy = search_horizon_sweep(phi, viewPosition, uvs, offset, max_dir);
+
+ /* Resize output for integer texture. */
+ FragColor = pack_horizons(FragColor.xy).xyxy;
+}
+#endif
diff --git a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl
index 3d580d0ce39..ce6f3568cdf 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_minmaxz_frag.glsl
@@ -11,23 +11,17 @@ uniform int depthLayer;
uniform sampler2D depthBuffer;
#endif
-float sampleLowerMip(ivec2 texel)
-{
#ifdef LAYERED
- return texelFetch(depthBuffer, ivec3(texel, depthLayer), 0).r;
+#define sampleLowerMip(t) texelFetch(depthBuffer, ivec3(t, depthLayer), 0).r
#else
- return texelFetch(depthBuffer, texel, 0).r;
+#define sampleLowerMip(t) texelFetch(depthBuffer, t, 0).r
#endif
-}
-void minmax(inout float out_val, float in_val)
-{
#ifdef MIN_PASS
- out_val = min(out_val, in_val);
+#define minmax(a, b) min(a, b)
#else /* MAX_PASS */
- out_val = max(out_val, in_val);
+#define minmax(a, b) max(a, b)
#endif
-}
void main()
{
@@ -40,23 +34,30 @@ void main()
float val = sampleLowerMip(texelPos);
#ifndef COPY_DEPTH
- minmax(val, sampleLowerMip(texelPos + ivec2(1, 0)));
- minmax(val, sampleLowerMip(texelPos + ivec2(1, 1)));
- minmax(val, sampleLowerMip(texelPos + ivec2(0, 1)));
+ float val2 = sampleLowerMip(texelPos + ivec2(1, 0));
+ float val3 = sampleLowerMip(texelPos + ivec2(1, 1));
+ float val4 = sampleLowerMip(texelPos + ivec2(0, 1));
+ val = minmax(val, val2);
+ val = minmax(val, val3);
+ val = minmax(val, val4);
/* if we are reducing an odd-width texture then fetch the edge texels */
- if (((mipsize.x & 1) != 0) && (int(gl_FragCoord.x) == mipsize.x-3)) {
+ if (((mipsize.x & 1) != 0) && (texelPos.x == mipsize.x - 3)) {
/* if both edges are odd, fetch the top-left corner texel */
- if (((mipsize.y & 1) != 0) && (int(gl_FragCoord.y) == mipsize.y-3)) {
- minmax(val, sampleLowerMip(texelPos + ivec2(-1, -1)));
+ if (((mipsize.y & 1) != 0) && (texelPos.y == mipsize.y - 3)) {
+ val = minmax(val, sampleLowerMip(texelPos + ivec2(2, 2)));
}
- minmax(val, sampleLowerMip(texelPos + ivec2(0, -1)));
- minmax(val, sampleLowerMip(texelPos + ivec2(1, -1)));
+ float val2 = sampleLowerMip(texelPos + ivec2(2, 0));
+ float val3 = sampleLowerMip(texelPos + ivec2(2, 1));
+ val = minmax(val, val2);
+ val = minmax(val, val3);
}
/* if we are reducing an odd-height texture then fetch the edge texels */
- else if (((mipsize.y & 1) != 0) && (int(gl_FragCoord.y) == mipsize.y-3)) {
- minmax(val, sampleLowerMip(texelPos + ivec2(0, -1)));
- minmax(val, sampleLowerMip(texelPos + ivec2(1, -1)));
+ if (((mipsize.y & 1) != 0) && (texelPos.y == mipsize.y - 3)) {
+ float val2 = sampleLowerMip(texelPos + ivec2(0, 2));
+ float val3 = sampleLowerMip(texelPos + ivec2(1, 2));
+ val = minmax(val, val2);
+ val = minmax(val, val3);
}
#endif
diff --git a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
index 8e5ffb37e2e..7dc047882c3 100644
--- a/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/effect_ssr_frag.glsl
@@ -7,26 +7,7 @@
uniform sampler2DArray utilTex;
#endif /* UTIL_TEX */
-uniform int rayCount;
-uniform float maxRoughness;
-
#define BRDF_BIAS 0.7
-
-vec3 generate_ray(vec3 V, vec3 N, float a2, vec3 rand, out float pdf)
-{
- float NH;
- vec3 T, B;
- make_orthonormal_basis(N, T, B); /* Generate tangent space */
-
- /* Importance sampling bias */
- rand.x = mix(rand.x, 0.0, BRDF_BIAS);
-
- /* TODO distribution of visible normals */
- vec3 H = sample_ggx(rand, a2, N, T, B, NH); /* Microfacet normal */
- pdf = min(1024e32, pdf_ggx_reflect(NH, a2)); /* Theoretical limit of 16bit float */
- return reflect(-V, H);
-}
-
#define MAX_MIP 9.0
#ifdef STEP_RAYTRACE
@@ -41,51 +22,57 @@ layout(location = 1) out vec4 hitData1;
layout(location = 2) out vec4 hitData2;
layout(location = 3) out vec4 hitData3;
-bool has_hit_backface(vec3 hit_pos, vec3 R, vec3 V)
+vec4 do_planar_ssr(int index, vec3 V, vec3 N, vec3 T, vec3 B, vec3 planeNormal, vec3 viewPosition, float a2, vec3 rand, float ofs)
{
- vec2 hit_co = project_point(ProjectionMatrix, hit_pos).xy * 0.5 + 0.5;
- vec3 hit_N = normal_decode(textureLod(normalBuffer, hit_co, 0.0).rg, V);
- return (dot(-R, hit_N) < 0.0);
-}
+ float pdf, NH;
+ float jitter = fract(rand.x + ofs);
-vec4 do_planar_ssr(int index, vec3 V, vec3 N, vec3 planeNormal, vec3 viewPosition, float a2, vec3 rand, float ray_nbr)
-{
- float pdf;
- vec3 R = generate_ray(V, N, a2, rand, pdf);
+ /* Importance sampling bias */
+ rand.x = mix(rand.x, 0.0, BRDF_BIAS);
+ vec3 H = sample_ggx(rand, a2, N, T, B, NH); /* Microfacet normal */
+ pdf = pdf_ggx_reflect(NH, a2);
+
+ vec3 R = reflect(-V, H);
R = reflect(R, planeNormal);
- pdf *= -1.0; /* Tag as planar ray. */
- /* If ray is bad (i.e. going below the plane) do not trace. */
+ /* If ray is bad (i.e. going below the plane) regenerate. */
if (dot(R, planeNormal) > 0.0) {
- vec3 R = generate_ray(V, N, a2, rand * vec3(1.0, -1.0, -1.0), pdf);
- }
+ vec3 H = sample_ggx(rand * vec3(1.0, -1.0, -1.0), a2, N, T, B, NH); /* Microfacet normal */
+ pdf = pdf_ggx_reflect(NH, a2);
- vec3 hit_pos;
- if (abs(dot(-R, V)) < 0.9999) {
- /* Since viewspace hit position can land behind the camera in this case,
- * we save the reflected view position (visualize it as the hit position
- * below the reflection plane). This way it's garanted that the hit will
- * be in front of the camera. That let us tag the bad rays with a negative
- * sign in the Z component. */
- hit_pos = raycast(index, viewPosition, R, fract(rand.x + (ray_nbr / float(rayCount))), a2);
- }
- else {
- vec2 uvs = project_point(ProjectionMatrix, viewPosition).xy * 0.5 + 0.5;
- float raw_depth = textureLod(planarDepth, vec3(uvs, float(index)), 0.0).r;
- hit_pos = get_view_space_from_depth(uvs, raw_depth);
- hit_pos.z *= (raw_depth < 1.0) ? 1.0 : -1.0;
+ R = reflect(-V, H);
+ R = reflect(R, planeNormal);
}
+ pdf = min(1024e32, pdf); /* Theoretical limit of 16bit float */
+ pdf *= -1.0; /* Tag as planar ray. */
+
+ /* Since viewspace hit position can land behind the camera in this case,
+ * we save the reflected view position (visualize it as the hit position
+ * below the reflection plane). This way it's garanted that the hit will
+ * be in front of the camera. That let us tag the bad rays with a negative
+ * sign in the Z component. */
+ vec3 hit_pos = raycast(index, viewPosition, R, 1e16, jitter, a2);
+
return vec4(hit_pos, pdf);
}
-vec4 do_ssr(vec3 V, vec3 N, vec3 viewPosition, float a2, vec3 rand, float ray_nbr)
+vec4 do_ssr(vec3 V, vec3 N, vec3 T, vec3 B, vec3 viewPosition, float a2, vec3 rand, float ofs)
{
- float pdf;
- vec3 R = generate_ray(V, N, a2, rand, pdf);
+ float pdf, NH;
+ float jitter = fract(rand.x + ofs);
- vec3 hit_pos = raycast(-1, viewPosition, R, fract(rand.x + (ray_nbr / float(rayCount))), a2);
+ /* Importance sampling bias */
+ rand.x = mix(rand.x, 0.0, BRDF_BIAS);
+
+ vec3 H = sample_ggx(rand, a2, N, T, B, NH); /* Microfacet normal */
+ pdf = pdf_ggx_reflect(NH, a2);
+
+ vec3 R = reflect(-V, H);
+ pdf = min(1024e32, pdf); /* Theoretical limit of 16bit float */
+
+ vec3 hit_pos = raycast(-1, viewPosition, R, ssrThickness, jitter, a2);
return vec4(hit_pos, pdf);
}
@@ -138,6 +125,11 @@ void main()
vec3 worldPosition = transform_point(ViewMatrixInverse, viewPosition);
vec3 wN = transform_direction(ViewMatrixInverse, N);
+ vec3 T, B;
+ make_orthonormal_basis(N, T, B); /* Generate tangent space */
+
+ float ray_ofs = 1.0 / float(rayCount);
+
/* Planar Reflections */
for (int i = 0; i < MAX_PLANAR && i < planar_count; ++i) {
PlanarData pd = planars_data[i];
@@ -152,24 +144,24 @@ void main()
vec3 planeNormal = transform_direction(ViewMatrix, pd.pl_normal);
/* TODO : Raytrace together if textureGather is supported. */
- hitData0 = do_planar_ssr(i, V, N, planeNormal, tracePosition, a2, rand, 0.0);
- if (rayCount > 1) hitData1 = do_planar_ssr(i, V, N, planeNormal, tracePosition, a2, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0);
- if (rayCount > 2) hitData2 = do_planar_ssr(i, V, N, planeNormal, tracePosition, a2, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0);
- if (rayCount > 3) hitData3 = do_planar_ssr(i, V, N, planeNormal, tracePosition, a2, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0);
+ hitData0 = do_planar_ssr(i, V, N, T, B, planeNormal, tracePosition, a2, rand, 0.0);
+ if (rayCount > 1) hitData1 = do_planar_ssr(i, V, N, T, B, planeNormal, tracePosition, a2, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0 * ray_ofs);
+ if (rayCount > 2) hitData2 = do_planar_ssr(i, V, N, T, B, planeNormal, tracePosition, a2, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0 * ray_ofs);
+ if (rayCount > 3) hitData3 = do_planar_ssr(i, V, N, T, B, planeNormal, tracePosition, a2, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0 * ray_ofs);
return;
}
}
/* TODO : Raytrace together if textureGather is supported. */
- hitData0 = do_ssr(V, N, viewPosition, a2, rand, 0.0);
- if (rayCount > 1) hitData1 = do_ssr(V, N, viewPosition, a2, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0);
- if (rayCount > 2) hitData2 = do_ssr(V, N, viewPosition, a2, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0);
- if (rayCount > 3) hitData3 = do_ssr(V, N, viewPosition, a2, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0);
+ hitData0 = do_ssr(V, N, T, B, viewPosition, a2, rand, 0.0);
+ if (rayCount > 1) hitData1 = do_ssr(V, N, T, B, viewPosition, a2, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0 * ray_ofs);
+ if (rayCount > 2) hitData2 = do_ssr(V, N, T, B, viewPosition, a2, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0 * ray_ofs);
+ if (rayCount > 3) hitData3 = do_ssr(V, N, T, B, viewPosition, a2, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0 * ray_ofs);
}
#else /* STEP_RESOLVE */
-uniform sampler2D colorBuffer; /* previous frame */
+uniform sampler2D prevColorBuffer; /* previous frame */
uniform sampler2D normalBuffer;
uniform sampler2D specroughBuffer;
@@ -181,9 +173,6 @@ uniform sampler2D hitBuffer3;
uniform int probe_count;
uniform int planar_count;
-uniform float borderFadeFactor;
-uniform float fireflyFactor;
-
uniform mat4 PastViewProjectionMatrix;
out vec4 fragColor;
@@ -191,7 +180,7 @@ out vec4 fragColor;
void fallback_cubemap(vec3 N, vec3 V, vec3 W, float roughness, float roughnessSquared, inout vec4 spec_accum)
{
/* Specular probes */
- vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared);
+ vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
/* Starts at 1 because 0 is world probe */
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
@@ -242,17 +231,6 @@ float brightness(vec3 c)
return max(max(c.r, c.g), c.b);
}
-float screen_border_mask(vec2 hit_co)
-{
- const float margin = 0.003;
- float atten = borderFadeFactor + margin; /* Screen percentage */
- hit_co = smoothstep(margin, atten, hit_co) * (1 - smoothstep(1.0 - atten, 1.0 - margin, hit_co));
-
- float screenfade = hit_co.x * hit_co.y;
-
- return screenfade;
-}
-
vec2 get_reprojected_reflection(vec3 hit, vec3 pos, vec3 N)
{
/* TODO real reprojection with motion vectors, etc... */
@@ -274,38 +252,38 @@ vec4 get_ssr_sample(
vec3 hit_pos = transform_point(ViewMatrixInverse, hit_co_pdf.xyz);
vec2 ref_uvs;
- vec3 L;
+ vec3 hit_vec;
float mask = 1.0;
- float cone_footprint;
if (is_planar) {
/* Reflect back the hit position to have it in non-reflected world space */
vec3 trace_pos = line_plane_intersect(worldPosition, V, pd.pl_plane_eq);
- vec3 hit_vec = hit_pos - trace_pos;
+ hit_vec = hit_pos - trace_pos;
hit_vec = reflect(hit_vec, pd.pl_normal);
- hit_pos = hit_vec + trace_pos;
- L = normalize(hit_vec);
ref_uvs = project_point(ProjectionMatrix, hit_co_pdf.xyz).xy * 0.5 + 0.5;
- vec2 uvs = gl_FragCoord.xy / texture_size;
-
- /* Compute cone footprint in screen space. */
- float homcoord = ProjectionMatrix[2][3] * hit_co_pdf.z + ProjectionMatrix[3][3];
- cone_footprint = length(hit_vec) * cone_tan * ProjectionMatrix[0][0] / homcoord;
}
else {
/* Find hit position in previous frame. */
ref_uvs = get_reprojected_reflection(hit_pos, worldPosition, N);
- L = normalize(hit_pos - worldPosition);
- vec2 uvs = gl_FragCoord.xy / vec2(textureSize(depthBuffer, 0));
- mask *= screen_border_mask(uvs);
-
- /* Compute cone footprint Using UV distance because we are using screen space filtering. */
- cone_footprint = cone_tan * distance(ref_uvs, source_uvs);
+ hit_vec = hit_pos - worldPosition;
+ mask = screen_border_mask(gl_FragCoord.xy / texture_size);
}
mask = min(mask, screen_border_mask(ref_uvs));
mask *= float(has_hit);
+ float hit_dist = max(1e-8, length(hit_vec));
+ vec3 L = hit_vec / hit_dist;
+
+ float cone_footprint = hit_dist * cone_tan;
+
+ /* Compute cone footprint in screen space. */
+ float homcoord = ProjectionMatrix[2][3] * hit_co_pdf.z + ProjectionMatrix[3][3];
+ cone_footprint = BRDF_BIAS * 0.5 * cone_footprint * max(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) / homcoord;
+
/* Estimate a cone footprint to sample a corresponding mipmap level. */
- float mip = BRDF_BIAS * clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, MAX_MIP) - 1.0;
+ float mip = clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, MAX_MIP);
+
+ /* Correct UVs for mipmaping mis-alignment */
+ ref_uvs *= mip_ratio_interp(mip);
/* Slide 54 */
float bsdf = bsdf_ggx(N, L, V, roughnessSquared);
@@ -317,7 +295,7 @@ vec4 get_ssr_sample(
sample = textureLod(probePlanars, vec3(ref_uvs, planar_index), mip).rgb;
}
else {
- sample = textureLod(colorBuffer, ref_uvs, mip).rgb;
+ sample = textureLod(prevColorBuffer, ref_uvs, mip).rgb;
}
/* Clamped brightness. */
@@ -327,6 +305,10 @@ vec4 get_ssr_sample(
/* Do not add light if ray has failed. */
sample *= float(has_hit);
+#if 0 /* Enable to see where NANs come from. */
+ sample = (any(isnan(sample))) ? vec3(0.0) : sample;
+#endif
+
return vec4(sample, mask) * weight;
}
@@ -384,7 +366,7 @@ void main()
/* Resolve SSR */
float cone_cos = cone_cosine(roughnessSquared);
float cone_tan = sqrt(1 - cone_cos * cone_cos) / cone_cos;
- cone_tan *= mix(saturate(dot(N, V) * 2.0), 1.0, roughness); /* Elongation fit */
+ cone_tan *= mix(saturate(dot(N, -V) * 2.0), 1.0, roughness); /* Elongation fit */
vec2 source_uvs = project_point(PastViewProjectionMatrix, worldPosition).xy * 0.5 + 0.5;
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
index 222d272da72..7e63f4cdaf7 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_geom.glsl
@@ -6,6 +6,7 @@ uniform int Layer;
in vec4 vPos[];
flat in int face[];
+flat out int fFace;
out vec3 worldPosition;
out vec3 viewPosition; /* Required. otherwise generate linking error. */
@@ -17,12 +18,12 @@ const vec3 x_axis[6] = vec3[6](vec3(0.0, 0.0, -1.0), vec3( 0.0, 0.0, 1.0), v
const vec3 y_axis[6] = vec3[6](vec3(0.0, -1.0, 0.0), vec3( 0.0, -1.0, 0.0), vec3(0.0, 0.0, 1.0), vec3(0.0, 0.0, -1.0), vec3( 0.0, -1.0, 0.0), vec3( 0.0, -1.0, 0.0));
void main() {
- int f = face[0];
- gl_Layer = Layer + f;
+ fFace = face[0];
+ gl_Layer = Layer + fFace;
for (int v = 0; v < 3; ++v) {
gl_Position = vPos[v];
- worldPosition = x_axis[f] * vPos[v].x + y_axis[f] * vPos[v].y + maj_axes[f];
+ worldPosition = x_axis[fFace] * vPos[v].x + y_axis[fFace] * vPos[v].y + maj_axes[fFace];
#ifdef ATTRIB
pass_attrib(v);
#endif
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
index 0200b32d969..73524cae950 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_lib.glsl
@@ -167,8 +167,7 @@ vec3 probe_evaluate_world_spec(vec3 R, float roughness)
vec3 probe_evaluate_planar(
float id, PlanarData pd, vec3 W, vec3 N, vec3 V,
- float rand, float roughness,
- inout float fade)
+ float roughness, inout float fade)
{
/* Find view vector / reflection plane intersection. */
vec3 point_on_plane = line_plane_intersect(W, V, pd.pl_plane_eq);
diff --git a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl
index c2ef085ca01..3b3abdef00c 100644
--- a/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lightprobe_planar_downsample_frag.glsl
@@ -3,29 +3,38 @@
**/
uniform sampler2DArray source;
-uniform vec2 texelSize;
+uniform float fireflyFactor;
in vec2 uvs;
flat in float layer;
out vec4 FragColor;
-void main()
+float brightness(vec3 c)
{
- /* Reconstructing Target uvs like this avoid missing pixels */
- vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(source, 0).xy);
-
-#if 0 /* Slower and does not match the main framebuffer downsampling. */
- /* Downsample with a 4x4 box filter */
- vec4 d = texelSize.xyxy * vec4(-1, -1, +1, +1);
-
- FragColor = texture(source, vec3(uvs + d.xy, layer)).rgba;
- FragColor += texture(source, vec3(uvs + d.zy, layer)).rgba;
- FragColor += texture(source, vec3(uvs + d.xw, layer)).rgba;
- FragColor += texture(source, vec3(uvs + d.zw, layer)).rgba;
+ return max(max(c.r, c.g), c.b);
+}
- FragColor /= 4.0;
+void main()
+{
+#if 0
+ /* Reconstructing Target uvs like this avoid missing pixels if NPO2 */
+ vec2 uvs = gl_FragCoord.xy * 2.0 / vec2(textureSize(source, 0));
+
+ FragColor = textureLod(source, vec3(uvs, layer), 0.0);
+#else
+ vec2 texel_size = 1.0 / vec2(textureSize(source, 0));
+ vec2 uvs = gl_FragCoord.xy * 2.0 * texel_size;
+ vec4 ofs = texel_size.xyxy * vec4(0.75, 0.75, -0.75, -0.75);
+
+ FragColor = textureLod(source, vec3(uvs + ofs.xy, layer), 0.0);
+ FragColor += textureLod(source, vec3(uvs + ofs.xw, layer), 0.0);
+ FragColor += textureLod(source, vec3(uvs + ofs.zy, layer), 0.0);
+ FragColor += textureLod(source, vec3(uvs + ofs.zw, layer), 0.0);
+ FragColor *= 0.25;
+
+ /* Clamped brightness. */
+ float luma = max(1e-8, brightness(FragColor.rgb));
+ FragColor *= 1.0 - max(0.0, luma - fireflyFactor) / luma;
#endif
-
- FragColor = texture(source, vec3(uvs, layer));
} \ No newline at end of file
diff --git a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
index 21202a10fb0..16b3283b624 100644
--- a/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
+++ b/source/blender/draw/engines/eevee/shaders/lit_surface_frag.glsl
@@ -7,6 +7,8 @@ uniform int planar_count;
uniform bool specToggle;
uniform bool ssrToggle;
+uniform float refractionDepth;
+
#ifndef UTIL_TEX
#define UTIL_TEX
uniform sampler2DArray utilTex;
@@ -45,8 +47,6 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao,
vec3 V = cameraVec;
- vec4 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0));
-
/* ---------------- SCENE LAMPS LIGHTING ----------------- */
#ifdef HAIR_SHADER
@@ -99,13 +99,13 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao,
float fade = probe_attenuation_planar(pd, worldPosition, N, roughness);
if (fade > 0.0) {
- vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, roughness, fade);
+ vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, roughness, fade);
accumulate_light(spec, fade, spec_accum);
}
}
/* Specular probes */
- vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared);
+ vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
/* Starts at 1 because 0 is world probe */
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
@@ -126,6 +126,8 @@ vec3 eevee_surface_lit(vec3 N, vec3 albedo, vec3 f0, float roughness, float ao,
}
}
+ vec4 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0));
+
/* Ambient Occlusion */
vec3 bent_normal;
float final_ao = occlusion_compute(N, viewPosition, ao, rand.rg, bent_normal);
@@ -178,11 +180,27 @@ vec3 eevee_surface_clearcoat_lit(
C_roughness = clamp(C_roughness, 1e-8, 0.9999);
float C_roughnessSquared = C_roughness * C_roughness;
- vec3 V = cameraVec;
+ /* Zero length vectors cause issues, see: T51979. */
+#if 0
N = normalize(N);
C_N = normalize(C_N);
+#else
+ {
+ float len = length(N);
+ if (isnan(len)) {
+ return vec3(0.0);
+ }
+ N /= len;
- vec4 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0));
+ len = length(C_N);
+ if (isnan(len)) {
+ return vec3(0.0);
+ }
+ C_N /= len;
+ }
+#endif
+
+ vec3 V = cameraVec;
/* ---------------- SCENE LAMPS LIGHTING ----------------- */
@@ -239,18 +257,18 @@ vec3 eevee_surface_clearcoat_lit(
if (fade > 0.0) {
if (!(ssrToggle && ssr_id == outputSsrId)) {
- vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, roughness, fade);
+ vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, roughness, fade);
accumulate_light(spec, fade, spec_accum);
}
- vec3 C_spec = probe_evaluate_planar(float(i), pd, worldPosition, C_N, V, rand.r, C_roughness, fade);
+ vec3 C_spec = probe_evaluate_planar(float(i), pd, worldPosition, C_N, V, C_roughness, fade);
accumulate_light(C_spec, fade, C_spec_accum);
}
}
/* Specular probes */
- vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared);
- vec3 C_spec_dir = get_specular_dominant_dir(C_N, V, C_roughnessSquared);
+ vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
+ vec3 C_spec_dir = get_specular_reflection_dominant_dir(C_N, V, C_roughnessSquared);
/* Starts at 1 because 0 is world probe */
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
@@ -280,6 +298,8 @@ vec3 eevee_surface_clearcoat_lit(
accumulate_light(C_spec, 1.0, C_spec_accum);
}
+ vec4 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0));
+
/* Ambient Occlusion */
vec3 bent_normal;
float final_ao = occlusion_compute(N, viewPosition, ao, rand.rg, bent_normal);
@@ -330,9 +350,19 @@ vec3 eevee_surface_clearcoat_lit(
vec3 eevee_surface_diffuse_lit(vec3 N, vec3 albedo, float ao)
{
vec3 V = cameraVec;
- N = normalize(N);
- vec4 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0));
+ /* Zero length vectors cause issues, see: T51979. */
+#if 0
+ N = normalize(N);
+#else
+ {
+ float len = length(N);
+ if (isnan(len)) {
+ return vec3(0.0);
+ }
+ N /= len;
+ }
+#endif
/* ---------------- SCENE LAMPS LIGHTING ----------------- */
@@ -371,6 +401,8 @@ vec3 eevee_surface_diffuse_lit(vec3 N, vec3 albedo, float ao)
/* ---------------- DIFFUSE ENVIRONMENT LIGHTING ----------------- */
+ vec4 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0));
+
/* Ambient Occlusion */
vec3 bent_normal;
float final_ao = occlusion_compute(N, viewPosition, ao, rand.rg, bent_normal);
@@ -410,9 +442,19 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao, int ss
float roughnessSquared = roughness * roughness;
vec3 V = cameraVec;
- N = normalize(N);
- vec4 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0));
+ /* Zero length vectors cause issues, see: T51979. */
+#if 0
+ N = normalize(N);
+#else
+ {
+ float len = length(N);
+ if (isnan(len)) {
+ return vec3(0.0);
+ }
+ N /= len;
+ }
+#endif
/* ---------------- SCENE LAMPS LIGHTING ----------------- */
@@ -462,13 +504,13 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao, int ss
float fade = probe_attenuation_planar(pd, worldPosition, N, roughness);
if (fade > 0.0) {
- vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, rand.r, roughness, fade);
+ vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, roughness, fade);
accumulate_light(spec, fade, spec_accum);
}
}
/* Specular probes */
- vec3 spec_dir = get_specular_dominant_dir(N, V, roughnessSquared);
+ vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
/* Starts at 1 because 0 is world probe */
for (int i = 1; i < MAX_PROBE && i < probe_count && spec_accum.a < 0.999; ++i) {
@@ -489,6 +531,8 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao, int ss
}
}
+ vec4 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0));
+
/* Ambient Occlusion */
vec3 bent_normal;
float final_ao = occlusion_compute(N, viewPosition, ao, rand.rg, bent_normal);
@@ -502,3 +546,252 @@ vec3 eevee_surface_glossy_lit(vec3 N, vec3 f0, float roughness, float ao, int ss
return out_light;
}
+
+/* ----------- Transmission ----------- */
+
+vec3 eevee_surface_refraction(vec3 N, vec3 f0, float roughness, float ior)
+{
+ /* Zero length vectors cause issues, see: T51979. */
+#if 0
+ N = normalize(N);
+#else
+ {
+ float len = length(N);
+ if (isnan(len)) {
+ return vec3(0.0);
+ }
+ N /= len;
+ }
+#endif
+ vec3 V = cameraVec;
+ ior = (gl_FrontFacing) ? ior : 1.0 / ior;
+
+ roughness = clamp(roughness, 1e-8, 0.9999);
+ float roughnessSquared = roughness * roughness;
+
+ /* ---------------- SCENE LAMPS LIGHTING ----------------- */
+
+ /* No support for now. Supporting LTCs mean having a 3D LUT.
+ * We could support point lights easily though. */
+
+ /* ---------------- SPECULAR ENVIRONMENT LIGHTING ----------------- */
+
+ /* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */
+ vec4 trans_accum = vec4(0.0);
+
+ /* Refract the view vector using the depth heuristic.
+ * Then later Refract a second time the already refracted
+ * ray using the inverse ior. */
+ float final_ior = (refractionDepth > 0.0) ? 1.0 / ior : ior;
+ vec3 refr_V = (refractionDepth > 0.0) ? -refract(-V, N, final_ior) : V;
+ vec3 refr_pos = (refractionDepth > 0.0) ? line_plane_intersect(worldPosition, refr_V, worldPosition - N * refractionDepth, N) : worldPosition;
+
+#ifdef USE_REFRACTION
+ /* Screen Space Refraction */
+ if (ssrToggle && roughness < maxRoughness + 0.2) {
+ vec3 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0)).xzw;
+
+ /* Find approximated position of the 2nd refraction event. */
+ vec3 refr_vpos = (refractionDepth > 0.0) ? transform_point(ViewMatrix, refr_pos) : viewPosition;
+
+ float ray_ofs = 1.0 / float(rayCount);
+ vec4 spec = screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand, 0.0);
+ if (rayCount > 1) spec += screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0 * ray_ofs);
+ if (rayCount > 2) spec += screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0 * ray_ofs);
+ if (rayCount > 3) spec += screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0 * ray_ofs);
+ spec /= float(rayCount);
+ spec.a *= smoothstep(maxRoughness + 0.2, maxRoughness, roughness);
+ accumulate_light(spec.rgb, spec.a, trans_accum);
+ }
+#endif
+
+ /* Specular probes */
+ /* NOTE: This bias the IOR */
+ vec3 refr_dir = get_specular_refraction_dominant_dir(N, refr_V, roughness, final_ior);
+
+ /* Starts at 1 because 0 is world probe */
+ for (int i = 1; i < MAX_PROBE && i < probe_count && trans_accum.a < 0.999; ++i) {
+ CubeData cd = probes_data[i];
+
+ float fade = probe_attenuation_cube(cd, worldPosition);
+
+ if (fade > 0.0) {
+ vec3 spec = probe_evaluate_cube(float(i), cd, refr_pos, refr_dir, roughnessSquared);
+ accumulate_light(spec, fade, trans_accum);
+ }
+ }
+
+ /* World Specular */
+ if (trans_accum.a < 0.999) {
+ vec3 spec = probe_evaluate_world_spec(refr_dir, roughnessSquared);
+ accumulate_light(spec, 1.0, trans_accum);
+ }
+
+ float btdf = get_btdf_lut(utilTex, dot(N, V), roughness, ior);
+
+ return trans_accum.rgb * btdf;
+}
+
+vec3 eevee_surface_glass(vec3 N, vec3 transmission_col, float roughness, float ior, int ssr_id, out vec3 ssr_spec)
+{
+ /* Zero length vectors cause issues, see: T51979. */
+#if 0
+ N = normalize(N);
+#else
+ {
+ float len = length(N);
+ if (isnan(len)) {
+ return vec3(0.0);
+ }
+ N /= len;
+ }
+#endif
+ vec3 V = cameraVec;
+ ior = (gl_FrontFacing) ? ior : 1.0 / ior;
+
+ if (!specToggle) return vec3(0.0);
+
+ roughness = clamp(roughness, 1e-8, 0.9999);
+ float roughnessSquared = roughness * roughness;
+
+ /* ---------------- SCENE LAMPS LIGHTING ----------------- */
+
+#ifdef HAIR_SHADER
+ vec3 norm_view = cross(V, N);
+ norm_view = normalize(cross(norm_view, N)); /* Normal facing view */
+#endif
+
+ vec3 spec = vec3(0.0);
+ for (int i = 0; i < MAX_LIGHT && i < light_count; ++i) {
+ LightData ld = lights_data[i];
+
+ vec4 l_vector; /* Non-Normalized Light Vector with length in last component. */
+ l_vector.xyz = ld.l_position - worldPosition;
+ l_vector.w = length(l_vector.xyz);
+
+ vec3 l_color_vis = ld.l_color * light_visibility(ld, worldPosition, l_vector);
+
+#ifdef HAIR_SHADER
+ vec3 norm_lamp, view_vec;
+ float occlu_trans, occlu;
+ light_hair_common(ld, N, V, l_vector, norm_view, occlu_trans, occlu, norm_lamp, view_vec);
+
+ spec += l_color_vis * light_specular(ld, N, view_vec, l_vector, roughnessSquared, vec3(1.0)) * occlu;
+#else
+ spec += l_color_vis * light_specular(ld, N, V, l_vector, roughnessSquared, vec3(1.0));
+#endif
+ }
+
+ /* Accumulate outgoing radiance */
+ vec3 out_light = spec;
+
+#ifdef HAIR_SHADER
+ N = -norm_view;
+#endif
+
+
+ /* ---------------- SPECULAR ENVIRONMENT LIGHTING ----------------- */
+
+ /* Accumulate light from all sources until accumulator is full. Then apply Occlusion and BRDF. */
+ vec4 spec_accum = vec4(0.0);
+
+ /* Planar Reflections */
+ if (!(ssrToggle && ssr_id == outputSsrId)) {
+ for (int i = 0; i < MAX_PLANAR && i < planar_count && spec_accum.a < 0.999 && roughness < 0.1; ++i) {
+ PlanarData pd = planars_data[i];
+
+ float fade = probe_attenuation_planar(pd, worldPosition, N, roughness);
+
+ if (fade > 0.0) {
+ vec3 spec = probe_evaluate_planar(float(i), pd, worldPosition, N, V, roughness, fade);
+ accumulate_light(spec, fade, spec_accum);
+ }
+ }
+ }
+
+ /* Refract the view vector using the depth heuristic.
+ * Then later Refract a second time the already refracted
+ * ray using the inverse ior. */
+ float final_ior = (refractionDepth > 0.0) ? 1.0 / ior : ior;
+ vec3 refr_V = (refractionDepth > 0.0) ? -refract(-V, N, final_ior) : V;
+ vec3 refr_pos = (refractionDepth > 0.0) ? line_plane_intersect(worldPosition, refr_V, worldPosition - N * refractionDepth, N) : worldPosition;
+
+ vec4 trans_accum = vec4(0.0);
+
+#ifdef USE_REFRACTION
+ /* Screen Space Refraction */
+ if (ssrToggle && roughness < maxRoughness + 0.2) {
+ vec3 rand = texture(utilTex, vec3(gl_FragCoord.xy / LUT_SIZE, 2.0)).xzw;
+
+ /* Find approximated position of the 2nd refraction event. */
+ vec3 refr_vpos = (refractionDepth > 0.0) ? transform_point(ViewMatrix, refr_pos) : viewPosition;
+
+ float ray_ofs = 1.0 / float(rayCount);
+ vec4 spec = screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand, 0.0);
+ if (rayCount > 1) spec += screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand.xyz * vec3(1.0, -1.0, -1.0), 1.0 * ray_ofs);
+ if (rayCount > 2) spec += screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand.xzy * vec3(1.0, 1.0, -1.0), 2.0 * ray_ofs);
+ if (rayCount > 3) spec += screen_space_refraction(refr_vpos, N, refr_V, final_ior, roughnessSquared, rand.xzy * vec3(1.0, -1.0, 1.0), 3.0 * ray_ofs);
+ spec /= float(rayCount);
+ spec.a *= smoothstep(maxRoughness + 0.2, maxRoughness, roughness);
+ accumulate_light(spec.rgb, spec.a, trans_accum);
+ }
+#endif
+
+ /* Specular probes */
+ vec3 refr_dir = get_specular_refraction_dominant_dir(N, refr_V, roughness, final_ior);
+ vec3 spec_dir = get_specular_reflection_dominant_dir(N, V, roughnessSquared);
+
+ /* Starts at 1 because 0 is world probe */
+ for (int i = 1; i < MAX_PROBE && i < probe_count && (spec_accum.a < 0.999 || trans_accum.a < 0.999); ++i) {
+ CubeData cd = probes_data[i];
+
+ float fade = probe_attenuation_cube(cd, worldPosition);
+
+ if (fade > 0.0) {
+ if (!(ssrToggle && ssr_id == outputSsrId)) {
+ vec3 spec = probe_evaluate_cube(float(i), cd, worldPosition, spec_dir, roughness);
+ accumulate_light(spec, fade, spec_accum);
+ }
+
+ spec = probe_evaluate_cube(float(i), cd, refr_pos, refr_dir, roughnessSquared);
+ accumulate_light(spec, fade, trans_accum);
+ }
+ }
+
+ /* World Specular */
+ if (spec_accum.a < 0.999) {
+ if (!(ssrToggle && ssr_id == outputSsrId)) {
+ vec3 spec = probe_evaluate_world_spec(spec_dir, roughness);
+ accumulate_light(spec, 1.0, spec_accum);
+ }
+ }
+
+ if (trans_accum.a < 0.999) {
+ spec = probe_evaluate_world_spec(refr_dir, roughnessSquared);
+ accumulate_light(spec, 1.0, trans_accum);
+ }
+
+ /* Ambient Occlusion */
+ /* TODO : when AO will be cheaper */
+ float final_ao = 1.0;
+
+ float NV = dot(N, V);
+ /* Get Brdf intensity */
+ vec2 uv = lut_coords(NV, roughness);
+ vec2 brdf_lut = texture(utilTex, vec3(uv, 1.0)).rg;
+
+ float fresnel = F_eta(ior, NV);
+
+ /* Apply fresnel on lamps. */
+ out_light *= vec3(fresnel);
+
+ ssr_spec = vec3(fresnel) * F_ibl(vec3(1.0), brdf_lut) * specular_occlusion(NV, final_ao, roughness);
+ out_light += spec_accum.rgb * ssr_spec;
+
+
+ float btdf = get_btdf_lut(utilTex, NV, roughness, ior);
+
+ out_light += vec3(1.0 - fresnel) * transmission_col * trans_accum.rgb * btdf;
+
+ return out_light;
+}
diff --git a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
index 855755adfe4..d0fc14f8a29 100644
--- a/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
+++ b/source/blender/draw/engines/eevee/shaders/raytrace_lib.glsl
@@ -2,46 +2,28 @@
#define MAX_REFINE_STEP 32 /* Should be max allowed stride */
uniform vec4 ssrParameters;
-
-uniform sampler2D depthBuffer;
-uniform sampler2D maxzBuffer;
-uniform sampler2D minzBuffer;
-uniform sampler2DArray planarDepth;
+uniform int rayCount;
#define ssrQuality ssrParameters.x
#define ssrThickness ssrParameters.y
#define ssrPixelSize ssrParameters.zw
+uniform float maxRoughness;
+uniform float borderFadeFactor;
+uniform float fireflyFactor;
+
float sample_depth(vec2 uv, int index, float lod)
{
if (index > -1) {
return textureLod(planarDepth, vec3(uv, index), 0.0).r;
}
else {
+ /* Correct UVs for mipmaping mis-alignment */
+ uv *= mipRatio[int(lod + 1.0)];
return textureLod(maxzBuffer, uv, lod).r;
}
}
-float sample_minz_depth(vec2 uv, int index)
-{
- if (index > -1) {
- return textureLod(planarDepth, vec3(uv, index), 0.0).r;
- }
- else {
- return textureLod(minzBuffer, uv, 0.0).r;
- }
-}
-
-float sample_maxz_depth(vec2 uv, int index)
-{
- if (index > -1) {
- return textureLod(planarDepth, vec3(uv, index), 0.0).r;
- }
- else {
- return textureLod(maxzBuffer, uv, 0.0).r;
- }
-}
-
vec4 sample_depth_grouped(vec4 uv1, vec4 uv2, int index, float lod)
{
vec4 depths;
@@ -80,7 +62,7 @@ float refine_isect(float prev_delta, float curr_delta)
return saturate(prev_delta / (prev_delta - curr_delta));
}
-void prepare_raycast(vec3 ray_origin, vec3 ray_dir, out vec4 ss_step, out vec4 ss_ray, out float max_time)
+void prepare_raycast(vec3 ray_origin, vec3 ray_dir, float thickness, out vec4 ss_step, out vec4 ss_ray, out float max_time)
{
/* Negate the ray direction if it goes towards the camera.
* This way we don't need to care if the projected point
@@ -89,27 +71,42 @@ void prepare_raycast(vec3 ray_origin, vec3 ray_dir, out vec4 ss_step, out vec4 s
vec3 ray_end = z_sign * ray_dir * 1e16 + ray_origin;
/* Project into screen space. */
- vec3 ss_start = project_point(ProjectionMatrix, ray_origin);
- vec3 ss_end = project_point(ProjectionMatrix, ray_end);
- /* 4th component is current stride */
- ss_step = vec4(z_sign * normalize(ss_end - ss_start), 1.0);
+ vec4 ss_start, ss_end;
+ ss_start.xyz = project_point(ProjectionMatrix, ray_origin);
+ ss_end.xyz = project_point(ProjectionMatrix, ray_end);
+
+ /* We interpolate the ray Z + thickness values to check if depth is within threshold. */
+ ray_origin.z -= thickness;
+ ray_end.z -= thickness;
+ ss_start.w = project_point(ProjectionMatrix, ray_origin).z;
+ ss_end.w = project_point(ProjectionMatrix, ray_end).z;
+
+ /* XXX This is a hack a better method is welcome ! */
+ /* We take the delta between the offseted depth and the depth and substract it from the ray depth.
+ * This will change the world space thickness appearance a bit but we can have negative
+ * values without worries. We cannot do this in viewspace because of the perspective division. */
+ ss_start.w = 2.0 * ss_start.z - ss_start.w;
+ ss_end.w = 2.0 * ss_end.z - ss_end.w;
+
+ ss_step = ss_end - ss_start;
+ ss_step = z_sign * ss_step / length(ss_step.xyz);
/* If the line is degenerate, make it cover at least one pixel
* to not have to handle zero-pixel extent as a special case later */
- ss_step.xy += vec2((dot(ss_step.xy, ss_step.xy) < 0.00001) ? 0.001 : 0.0);
+ ss_step.xy += vec2((dot(ss_step.xy, ss_step.xy) < 0.000001) ? 0.001 : 0.0);
/* Make ss_step cover one pixel. */
- ss_step.xyz /= max(abs(ss_step.x), abs(ss_step.y));
- ss_step.xyz *= ((abs(ss_step.x) > abs(ss_step.y)) ? ssrPixelSize.x : ssrPixelSize.y);
+ ss_step /= max(abs(ss_step.x), abs(ss_step.y));
+ ss_step *= ((abs(ss_step.x) > abs(ss_step.y)) ? ssrPixelSize.x : ssrPixelSize.y);
/* Clipping to frustum sides. */
- max_time = line_unit_box_intersect_dist(ss_start, ss_step.xyz) - 1.0;
+ max_time = line_unit_box_intersect_dist(ss_start.xyz, ss_step.xyz);
/* Convert to texture coords. Z component included
* since this is how it's stored in the depth buffer.
* 4th component how far we are on the ray */
- ss_ray = vec4(ss_start * 0.5 + 0.5, 0.0);
- ss_step.xyz *= 0.5;
+ ss_ray = ss_start * 0.5 + 0.5;
+ ss_step *= 0.5;
}
/* See times_and_deltas. */
@@ -118,30 +115,35 @@ void prepare_raycast(vec3 ray_origin, vec3 ray_dir, out vec4 ss_step, out vec4 s
#define curr_delta times_and_deltas.z
#define prev_delta times_and_deltas.w
-// #define GROUPED_FETCHES
+// #define GROUPED_FETCHES /* is still slower, need to see where is the bottleneck. */
/* Return the hit position, and negate the z component (making it positive) if not hit occured. */
-vec3 raycast(int index, vec3 ray_origin, vec3 ray_dir, float ray_jitter, float roughness)
+vec3 raycast(int index, vec3 ray_origin, vec3 ray_dir, float thickness, float ray_jitter, float roughness)
{
vec4 ss_step, ss_start;
float max_time;
- prepare_raycast(ray_origin, ray_dir, ss_step, ss_start, max_time);
+ prepare_raycast(ray_origin, ray_dir, thickness, ss_step, ss_start, max_time);
+
+ float max_trace_time = max(0.001, max_time - 0.01);
#ifdef GROUPED_FETCHES
ray_jitter *= 0.25;
#endif
- /* x : current_time, y: previous_time, z: previous_delta, w: current_delta */
- vec4 times_and_deltas = vec4(0.0, 0.0, 0.001, 0.001);
+
+ /* x : current_time, y: previous_time, z: current_delta, w: previous_delta */
+ vec4 times_and_deltas = vec4(0.0);
float ray_time = 0.0;
- float depth_sample;
+ float depth_sample = sample_depth(ss_start.xy, index, 0.0);
+ curr_delta = depth_sample - ss_start.z;
float lod_fac = saturate(fast_sqrt(roughness) * 2.0 - 0.4);
bool hit = false;
float iter;
- for (iter = 1.0; !hit && (ray_time <= max_time) && (iter < MAX_STEP); iter++) {
+ for (iter = 1.0; !hit && (ray_time < max_time) && (iter < MAX_STEP); iter++) {
/* Minimum stride of 2 because we are using half res minmax zbuffer. */
float stride = max(1.0, iter * ssrQuality) * 2.0;
float lod = log2(stride * 0.5 * ssrQuality) * lod_fac;
+ ray_time += stride;
/* Save previous values. */
times_and_deltas.xyzw = times_and_deltas.yxwz;
@@ -150,7 +152,7 @@ vec3 raycast(int index, vec3 ray_origin, vec3 ray_dir, float ray_jitter, float r
stride *= 4.0;
vec4 jit_stride = mix(vec4(2.0), vec4(stride), vec4(0.0, 0.25, 0.5, 0.75) + ray_jitter);
- vec4 times = vec4(ray_time) + jit_stride;
+ vec4 times = min(vec4(ray_time) + jit_stride, vec4(max_trace_time));
vec4 uv1 = ss_start.xyxy + ss_step.xyxy * times.xxyy;
vec4 uv2 = ss_start.xyxy + ss_step.xyxy * times.zzww;
@@ -158,11 +160,13 @@ vec3 raycast(int index, vec3 ray_origin, vec3 ray_dir, float ray_jitter, float r
vec4 depth_samples = sample_depth_grouped(uv1, uv2, index, lod);
vec4 ray_z = ss_start.zzzz + ss_step.zzzz * times.xyzw;
+ vec4 ray_w = ss_start.wwww + ss_step.wwww * vec4(prev_time, times.xyz);
vec4 deltas = depth_samples - ray_z;
- /* Same as component wise (depth_samples <= ray_z) && (ray_time <= max_time). */
- bvec4 test = equal(step(deltas, vec4(0.0)) * step(times, vec4(max_time)), vec4(1.0));
+ /* Same as component wise (curr_delta <= 0.0) && (prev_w <= depth_sample). */
+ bvec4 test = equal(step(deltas, vec4(0.0)) * step(ray_w, depth_samples), vec4(1.0));
hit = any(test);
+
if (hit) {
vec2 m = vec2(1.0, 0.0); /* Mask */
@@ -175,54 +179,52 @@ vec3 raycast(int index, vec3 ray_origin, vec3 ray_dir, float ray_jitter, float r
depth_sample = (test.z) ? depth_samples.z : depth_sample;
depth_sample = (test.y) ? depth_samples.y : depth_sample;
depth_sample = (test.x) ? depth_samples.x : depth_sample;
- break;
}
- curr_time = times.w;
- curr_delta = deltas.w;
- ray_time += stride;
+ else {
+ curr_time = times.w;
+ curr_delta = deltas.w;
+ }
#else
float jit_stride = mix(2.0, stride, ray_jitter);
- curr_time = ray_time + jit_stride;
+ curr_time = min(ray_time + jit_stride, max_trace_time);
vec4 ss_ray = ss_start + ss_step * curr_time;
depth_sample = sample_depth(ss_ray.xy, index, lod);
+ float prev_w = ss_start.w + ss_step.w * prev_time;
curr_delta = depth_sample - ss_ray.z;
- hit = (curr_delta <= 0.0) && (curr_time <= max_time);
-
- ray_time += stride;
+ hit = (curr_delta <= 0.0) && (prev_w <= depth_sample);
#endif
}
+ /* Discard backface hits */
+ hit = hit && (prev_delta > 0.0);
+
+ /* Reject hit if background. */
+ hit = hit && (depth_sample != 1.0);
+
curr_time = (hit) ? mix(prev_time, curr_time, refine_isect(prev_delta, curr_delta)) : curr_time;
ray_time = (hit) ? curr_time : ray_time;
-#if 0 /* Not needed if using refine_isect() */
- /* Binary search */
- for (float time_step = (curr_time - prev_time) * 0.5; time_step > 1.0; time_step /= 2.0) {
- ray_time -= time_step;
- vec4 ss_ray = ss_start + ss_step * ray_time;
- float depth_sample = sample_maxz_depth(ss_ray.xy, index);
- bool is_hit = (depth_sample - ss_ray.z <= 0.0);
- ray_time = (is_hit) ? ray_time : ray_time + time_step;
- }
-#endif
-
/* Clip to frustum. */
- ray_time = min(ray_time, max_time - 0.5);
+ ray_time = max(0.001, min(ray_time, max_time - 1.5));
vec4 ss_ray = ss_start + ss_step * ray_time;
vec3 hit_pos = get_view_space_from_depth(ss_ray.xy, ss_ray.z);
- /* Reject hit if not within threshold. */
- /* TODO do this check while tracing. Potentially higher quality */
- if (hit && (index == -1)) {
- float z = get_view_z_from_depth(depth_sample);
- hit = hit && ((z - hit_pos.z - ssrThickness) <= ssrThickness);
- }
-
/* Tag Z if ray failed. */
hit_pos.z *= (hit) ? 1.0 : -1.0;
return hit_pos;
}
+
+float screen_border_mask(vec2 hit_co)
+{
+ const float margin = 0.003;
+ float atten = borderFadeFactor + margin; /* Screen percentage */
+ hit_co = smoothstep(margin, atten, hit_co) * (1 - smoothstep(1.0 - atten, 1.0 - margin, hit_co));
+
+ float screenfade = hit_co.x * hit_co.y;
+
+ return screenfade;
+}
diff --git a/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
new file mode 100644
index 00000000000..68e0c2a682f
--- /dev/null
+++ b/source/blender/draw/engines/eevee/shaders/ssr_lib.glsl
@@ -0,0 +1,72 @@
+/* ------------ Refraction ------------ */
+
+#define BTDF_BIAS 0.85
+
+vec4 screen_space_refraction(vec3 viewPosition, vec3 N, vec3 V, float ior, float roughnessSquared, vec3 rand, float ofs)
+{
+ float a2 = max(5e-6, roughnessSquared * roughnessSquared);
+ float jitter = fract(rand.x + ofs);
+
+ /* Importance sampling bias */
+ rand.x = mix(rand.x, 0.0, BTDF_BIAS);
+
+ vec3 T, B;
+ float NH;
+ make_orthonormal_basis(N, T, B);
+ vec3 H = sample_ggx(rand, a2, N, T, B, NH); /* Microfacet normal */
+ float pdf = pdf_ggx_reflect(NH, a2);
+
+ /* If ray is bad (i.e. going below the plane) regenerate. */
+ if (F_eta(ior, dot(H, V)) < 1.0) {
+ H = sample_ggx(rand * vec3(1.0, -1.0, -1.0), a2, N, T, B, NH); /* Microfacet normal */
+ pdf = pdf_ggx_reflect(NH, a2);
+ }
+
+ vec3 vV = viewCameraVec;
+ float eta = 1.0/ior;
+ if (dot(H, V) < 0.0) {
+ H = -H;
+ eta = ior;
+ }
+
+ vec3 R = refract(-V, H, 1.0 / ior);
+
+ R = transform_direction(ViewMatrix, R);
+
+ vec3 hit_pos = raycast(-1, viewPosition, R, ssrThickness, jitter, roughnessSquared);
+
+ if ((hit_pos.z < 0.0) && (F_eta(ior, dot(H, V)) < 1.0)) {
+ float hit_dist = distance(hit_pos, viewPosition);
+
+ float cone_cos = cone_cosine(roughnessSquared);
+ float cone_tan = sqrt(1 - cone_cos * cone_cos) / cone_cos;
+
+ /* Empirical fit for refraction. */
+ /* TODO find a better fit or precompute inside the LUT. */
+ cone_tan *= 0.5 * fast_sqrt(f0_from_ior((ior < 1.0) ? 1.0 / ior : ior));
+
+ float cone_footprint = hit_dist * cone_tan;
+
+ /* find the offset in screen space by multiplying a point
+ * in camera space at the depth of the point by the projection matrix. */
+ float homcoord = ProjectionMatrix[2][3] * hit_pos.z + ProjectionMatrix[3][3];
+ /* UV space footprint */
+ cone_footprint = BTDF_BIAS * 0.5 * max(ProjectionMatrix[0][0], ProjectionMatrix[1][1]) * cone_footprint / homcoord;
+
+ vec2 hit_uvs = project_point(ProjectionMatrix, hit_pos).xy * 0.5 + 0.5;
+
+ /* Texel footprint */
+ vec2 texture_size = vec2(textureSize(colorBuffer, 0).xy);
+ float mip = clamp(log2(cone_footprint * max(texture_size.x, texture_size.y)), 0.0, 9.0);
+
+ /* Correct UVs for mipmaping mis-alignment */
+ hit_uvs *= mip_ratio_interp(mip);
+
+ vec3 spec = textureLod(colorBuffer, hit_uvs, mip).xyz;
+ float mask = screen_border_mask(hit_uvs);
+
+ return vec4(spec, mask);
+ }
+
+ return vec4(0.0);
+}
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c
index fb7773d4b71..e94268e7b86 100644
--- a/source/blender/draw/intern/draw_cache.c
+++ b/source/blender/draw/intern/draw_cache.c
@@ -40,6 +40,7 @@
#include "draw_cache.h"
#include "draw_cache_impl.h"
+/* Batch's only (free'd as an array) */
static struct DRWShapeCache {
Gwn_Batch *drw_single_vertice;
Gwn_Batch *drw_fullscreen_quad;
@@ -94,54 +95,12 @@ static struct DRWShapeCache {
void DRW_shape_cache_free(void)
{
- BATCH_DISCARD_ALL_SAFE(SHC.drw_single_vertice);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_fullscreen_quad);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_plain_axes);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_single_arrow);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_cube);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_circle);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_square);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_line);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_line_endpoints);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_empty_sphere);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_empty_cone);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_arrows);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_axis_names);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_image_plane);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_image_plane_wire);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_field_wind);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_field_force);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_field_vortex);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_field_tube_limit);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_field_cone_limit);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_sunrays);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_area);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_hemi);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_spot);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_lamp_spot_square);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_speaker);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_lightprobe_cube);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_lightprobe_planar);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_lightprobe_grid);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_octahedral);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_octahedral_wire);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_box);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_box_wire);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_wire_wire);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope_distance);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope_wire);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_envelope_head_wire);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_point);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_point_wire);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_bone_arrows);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_camera);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_camera_tria);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_camera_focus);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_particle_cross);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_particle_circle);
- BATCH_DISCARD_ALL_SAFE(SHC.drw_particle_axis);
+ uint i = sizeof(SHC) / sizeof(Gwn_Batch *);
+ Gwn_Batch **batch = (Gwn_Batch **)&SHC;
+ while (i--) {
+ GWN_BATCH_DISCARD_SAFE(*batch);
+ batch++;
+ }
}
@@ -294,7 +253,7 @@ Gwn_Batch *DRW_cache_fullscreen_quad_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.uvs, i, uvs[i]);
}
- SHC.drw_fullscreen_quad = GWN_batch_create(GWN_PRIM_TRIS, vbo, NULL);
+ SHC.drw_fullscreen_quad = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_fullscreen_quad;
}
@@ -302,7 +261,7 @@ Gwn_Batch *DRW_cache_fullscreen_quad_get(void)
/* Sphere */
Gwn_Batch *DRW_cache_sphere_get(void)
{
- return Batch_get_sphere(2);
+ return GPU_batch_preset_sphere(2);
}
/** \} */
@@ -342,7 +301,7 @@ Gwn_Batch *DRW_cache_cube_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, i, verts[indices[i]]);
}
- SHC.drw_cube = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_cube = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_cube;
}
@@ -375,7 +334,7 @@ Gwn_Batch *DRW_cache_circle_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, a * 2 + 1, v);
}
- SHC.drw_circle = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_circle = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_circle;
#undef CIRCLE_RESOL
@@ -404,7 +363,7 @@ Gwn_Batch *DRW_cache_square_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 2 + 1, p[(i+1) % 4]);
}
- SHC.drw_square = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_square = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_square;
}
@@ -429,7 +388,7 @@ Gwn_Batch *DRW_cache_single_line_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v1);
GWN_vertbuf_attr_set(vbo, attr_id.pos, 1, v2);
- SHC.drw_line = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_line = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_line;
}
@@ -454,7 +413,7 @@ Gwn_Batch *DRW_cache_single_line_endpoints_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v1);
GWN_vertbuf_attr_set(vbo, attr_id.pos, 1, v2);
- SHC.drw_line_endpoints = GWN_batch_create(GWN_PRIM_POINTS, vbo, NULL);
+ SHC.drw_line_endpoints = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_line_endpoints;
}
@@ -481,7 +440,7 @@ Gwn_Batch *DRW_cache_screenspace_circle_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, a, v);
}
- SHC.drw_screenspace_circle = GWN_batch_create(GWN_PRIM_LINE_STRIP, vbo, NULL);
+ SHC.drw_screenspace_circle = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_screenspace_circle;
#undef CIRCLE_RESOL
@@ -569,7 +528,7 @@ Gwn_Batch *DRW_cache_plain_axes_get(void)
v1[axis] = v2[axis] = 0.0f;
}
- SHC.drw_plain_axes = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_plain_axes = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_plain_axes;
}
@@ -609,7 +568,7 @@ Gwn_Batch *DRW_cache_single_arrow_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, sides * 3 + 2, v3);
}
- SHC.drw_single_arrow = GWN_batch_create(GWN_PRIM_TRIS, vbo, NULL);
+ SHC.drw_single_arrow = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_single_arrow;
}
@@ -618,7 +577,7 @@ Gwn_Batch *DRW_cache_empty_sphere_get(void)
{
if (!SHC.drw_empty_sphere) {
Gwn_VertBuf *vbo = sphere_wire_vbo(1.0f);
- SHC.drw_empty_sphere = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_empty_sphere = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_empty_sphere;
}
@@ -665,7 +624,7 @@ Gwn_Batch *DRW_cache_empty_cone_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, i * 4 + 3, v);
}
- SHC.drw_empty_cone = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_empty_cone = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_empty_cone;
#undef NSEGMENTS
@@ -676,7 +635,7 @@ Gwn_Batch *DRW_cache_arrows_get(void)
if (!SHC.drw_arrows) {
Gwn_VertBuf *vbo = fill_arrows_vbo(1.0f);
- SHC.drw_arrows = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_arrows = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_arrows;
}
@@ -737,7 +696,7 @@ Gwn_Batch *DRW_cache_axis_names_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, 12, v1);
GWN_vertbuf_attr_set(vbo, attr_id.pos, 13, v2);
- SHC.drw_axis_names = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_axis_names = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_axis_names;
}
@@ -758,7 +717,7 @@ Gwn_Batch *DRW_cache_image_plane_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, j, quad[j]);
GWN_vertbuf_attr_set(vbo, attr_id.texCoords, j, quad[j]);
}
- SHC.drw_image_plane = GWN_batch_create(GWN_PRIM_TRI_FAN, vbo, NULL);
+ SHC.drw_image_plane = GWN_batch_create_ex(GWN_PRIM_TRI_FAN, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_image_plane;
}
@@ -777,7 +736,7 @@ Gwn_Batch *DRW_cache_image_plane_wire_get(void)
for (uint j = 0; j < 4; j++) {
GWN_vertbuf_attr_set(vbo, attr_id.pos, j, quad[j]);
}
- SHC.drw_image_plane_wire = GWN_batch_create(GWN_PRIM_LINE_LOOP, vbo, NULL);
+ SHC.drw_image_plane_wire = GWN_batch_create_ex(GWN_PRIM_LINE_LOOP, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_image_plane_wire;
}
@@ -814,7 +773,7 @@ Gwn_Batch *DRW_cache_field_wind_get(void)
}
}
- SHC.drw_field_wind = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_field_wind = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_field_wind;
#undef CIRCLE_RESOL
@@ -851,7 +810,7 @@ Gwn_Batch *DRW_cache_field_force_get(void)
}
}
- SHC.drw_field_force = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_field_force = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_field_force;
#undef CIRCLE_RESOL
@@ -888,7 +847,7 @@ Gwn_Batch *DRW_cache_field_vortex_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v);
}
- SHC.drw_field_vortex = GWN_batch_create(GWN_PRIM_LINE_STRIP, vbo, NULL);
+ SHC.drw_field_vortex = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_field_vortex;
#undef SPIRAL_RESOL
@@ -937,7 +896,7 @@ Gwn_Batch *DRW_cache_field_tube_limit_get(void)
}
}
- SHC.drw_field_tube_limit = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_field_tube_limit = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_field_tube_limit;
#undef CIRCLE_RESOL
@@ -986,7 +945,7 @@ Gwn_Batch *DRW_cache_field_cone_limit_get(void)
}
}
- SHC.drw_field_cone_limit = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_field_cone_limit = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_field_cone_limit;
#undef CIRCLE_RESOL
@@ -1025,7 +984,7 @@ Gwn_Batch *DRW_cache_lamp_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, a * 2 + 1, v);
}
- SHC.drw_lamp = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_lamp = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_lamp;
#undef NSEGMENTS
@@ -1057,7 +1016,7 @@ Gwn_Batch *DRW_cache_lamp_sunrays_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, a * 2 + 1, v2);
}
- SHC.drw_lamp_sunrays = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_lamp_sunrays = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_lamp_sunrays;
}
@@ -1091,7 +1050,7 @@ Gwn_Batch *DRW_cache_lamp_area_get(void)
v1[1] = 0.5f;
GWN_vertbuf_attr_set(vbo, attr_id.pos, 7, v1);
- SHC.drw_lamp_area = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_lamp_area = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_lamp_area;
}
@@ -1153,7 +1112,7 @@ Gwn_Batch *DRW_cache_lamp_hemi_get(void)
}
- SHC.drw_lamp_hemi = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_lamp_hemi = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_lamp_hemi;
#undef CIRCLE_RESOL
@@ -1223,7 +1182,7 @@ Gwn_Batch *DRW_cache_lamp_spot_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.n2, i * 4 + 3, neg[(i) % NSEGMENTS]);
}
- SHC.drw_lamp_spot = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_lamp_spot = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_lamp_spot;
#undef NSEGMENTS
@@ -1259,7 +1218,7 @@ Gwn_Batch *DRW_cache_lamp_spot_square_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, p[((i+1) % 4)+1]);
}
- SHC.drw_lamp_spot_square = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_lamp_spot_square = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_lamp_spot_square;
}
@@ -1323,7 +1282,7 @@ Gwn_Batch *DRW_cache_speaker_get(void)
}
}
- SHC.drw_speaker = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_speaker = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_speaker;
}
@@ -1375,7 +1334,7 @@ Gwn_Batch *DRW_cache_lightprobe_cube_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[3]);
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]);
- SHC.drw_lightprobe_cube = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_lightprobe_cube = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_lightprobe_cube;
}
@@ -1432,7 +1391,7 @@ Gwn_Batch *DRW_cache_lightprobe_grid_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[3]);
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[6]);
- SHC.drw_lightprobe_grid = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_lightprobe_grid = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_lightprobe_grid;
}
@@ -1464,7 +1423,7 @@ Gwn_Batch *DRW_cache_lightprobe_planar_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, v[(i + 1) % 4]);
}
- SHC.drw_lightprobe_planar = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_lightprobe_planar = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_lightprobe_planar;
}
@@ -1548,7 +1507,7 @@ Gwn_Batch *DRW_cache_bone_octahedral_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, bone_octahedral_verts[bone_octahedral_solid_tris[i][2]]);
}
- SHC.drw_bone_octahedral = GWN_batch_create(GWN_PRIM_TRIS, vbo, NULL);
+ SHC.drw_bone_octahedral = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_octahedral;
}
@@ -1578,7 +1537,7 @@ Gwn_Batch *DRW_cache_bone_octahedral_wire_outline_get(void)
add_fancy_edge(vbo, attr_id.pos, attr_id.n1, attr_id.n2, &v_idx, co1, co2, n1, n2);
}
- SHC.drw_bone_octahedral_wire = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_bone_octahedral_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_octahedral_wire;
}
@@ -1674,7 +1633,7 @@ Gwn_Batch *DRW_cache_bone_box_get(void)
}
}
- SHC.drw_bone_box = GWN_batch_create(GWN_PRIM_TRIS, vbo, NULL);
+ SHC.drw_bone_box = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_box;
}
@@ -1704,7 +1663,7 @@ Gwn_Batch *DRW_cache_bone_box_wire_outline_get(void)
add_fancy_edge(vbo, attr_id.pos, attr_id.n1, attr_id.n2, &v_idx, co1, co2, n1, n2);
}
- SHC.drw_bone_box_wire = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_bone_box_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_box_wire;
}
@@ -1732,7 +1691,7 @@ Gwn_Batch *DRW_cache_bone_wire_wire_outline_get(void)
const float n[3] = {1.0f, 0.0f, 0.0f};
add_fancy_edge(vbo, attr_id.pos, attr_id.n1, attr_id.n2, &v_idx, co1, co2, n, n);
- SHC.drw_bone_wire_wire = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_bone_wire_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_wire_wire;
}
@@ -1824,7 +1783,7 @@ Gwn_Batch *DRW_cache_bone_envelope_solid_get(void)
}
}
- SHC.drw_bone_envelope = GWN_batch_create(GWN_PRIM_TRIS, vbo, NULL);
+ SHC.drw_bone_envelope = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_envelope;
}
@@ -1863,7 +1822,7 @@ Gwn_Batch *DRW_cache_bone_envelope_distance_outline_get(void)
}
}
- SHC.drw_bone_envelope_distance = GWN_batch_create(GWN_PRIM_TRI_STRIP, vbo, NULL);
+ SHC.drw_bone_envelope_distance = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_envelope_distance;
#undef CIRCLE_RESOL
@@ -1894,7 +1853,7 @@ Gwn_Batch *DRW_cache_bone_envelope_wire_outline_get(void)
GWN_vertbuf_attr_set(vbo, pos_id, v_idx++, (const float[4]){-1.0f, 0.0f, 0.0f, 0.0f});
GWN_vertbuf_attr_set(vbo, pos_id, v_idx++, (const float[4]){-1.0f, 0.0f, 1.0f, 0.0f});
- SHC.drw_bone_envelope_wire = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_bone_envelope_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_envelope_wire;
}
@@ -1928,7 +1887,7 @@ Gwn_Batch *DRW_cache_bone_envelope_head_wire_outline_get(void)
GWN_vertbuf_attr_set(vbo, pos_id, v_idx++, (const float[4]){ x, y, 0.0f, 0.0f});
}
- SHC.drw_bone_envelope_head_wire = GWN_batch_create(GWN_PRIM_LINE_LOOP, vbo, NULL);
+ SHC.drw_bone_envelope_head_wire = GWN_batch_create_ex(GWN_PRIM_LINE_LOOP, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_envelope_head_wire;
#undef CIRCLE_RESOL
@@ -1974,7 +1933,7 @@ Gwn_Batch *DRW_cache_bone_point_get(void)
}
}
- SHC.drw_bone_point = GWN_batch_create(GWN_PRIM_TRIS, vbo, NULL);
+ SHC.drw_bone_point = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_point;
}
@@ -1983,7 +1942,7 @@ Gwn_Batch *DRW_cache_bone_point_wire_outline_get(void)
{
if (!SHC.drw_bone_point_wire) {
Gwn_VertBuf *vbo = sphere_wire_vbo(0.05f);
- SHC.drw_bone_point_wire = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_bone_point_wire = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_point_wire;
}
@@ -1992,7 +1951,7 @@ Gwn_Batch *DRW_cache_bone_arrows_get(void)
{
if (!SHC.drw_bone_arrows) {
Gwn_VertBuf *vbo = fill_arrows_vbo(0.25f);
- SHC.drw_bone_arrows = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_bone_arrows = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_bone_arrows;
}
@@ -2065,7 +2024,7 @@ Gwn_Batch *DRW_cache_camera_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, &v7);
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, &v5);
- SHC.drw_camera = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_camera = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_camera;
}
@@ -2096,7 +2055,7 @@ Gwn_Batch *DRW_cache_camera_tria_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, &v6);
GWN_vertbuf_attr_set(vbo, attr_id.pos, v_idx++, &v7);
- SHC.drw_camera_tria = GWN_batch_create(GWN_PRIM_TRIS, vbo, NULL);
+ SHC.drw_camera_tria = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_camera_tria;
}
@@ -2126,7 +2085,7 @@ Gwn_Batch *DRW_cache_single_vert_get(void)
GWN_vertbuf_attr_set(vbo, attr_id.pos, 0, v1);
- SHC.drw_single_vertice = GWN_batch_create(GWN_PRIM_POINTS, vbo, NULL);
+ SHC.drw_single_vertice = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_single_vertice;
}
@@ -2496,7 +2455,7 @@ Gwn_Batch *DRW_cache_particles_get_prim(int type)
GWN_vertbuf_attr_set(vbo, pos_id, 5, co);
GWN_vertbuf_attr_set(vbo, axis_id, 5, &axis);
- SHC.drw_particle_cross = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_particle_cross = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_particle_cross;
@@ -2543,7 +2502,7 @@ Gwn_Batch *DRW_cache_particles_get_prim(int type)
GWN_vertbuf_attr_set(vbo, pos_id, 5, co);
GWN_vertbuf_attr_set(vbo, axis_id, 5, &axis);
- SHC.drw_particle_axis = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ SHC.drw_particle_axis = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_particle_axis;
@@ -2572,7 +2531,7 @@ Gwn_Batch *DRW_cache_particles_get_prim(int type)
GWN_vertbuf_attr_set(vbo, axis_id, a, &axis);
}
- SHC.drw_particle_circle = GWN_batch_create(GWN_PRIM_LINE_LOOP, vbo, NULL);
+ SHC.drw_particle_circle = GWN_batch_create_ex(GWN_PRIM_LINE_LOOP, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return SHC.drw_particle_circle;
diff --git a/source/blender/draw/intern/draw_cache_impl.h b/source/blender/draw/intern/draw_cache_impl.h
index 31ffb3e5a91..57ccdd15054 100644
--- a/source/blender/draw/intern/draw_cache_impl.h
+++ b/source/blender/draw/intern/draw_cache_impl.h
@@ -95,7 +95,8 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_all_triangles(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(struct Mesh *me, int defgroup);
struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(struct Mesh *me);
-struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide);
+struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide, uint select_id_offset);
+struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide);
struct Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_all_verts(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(struct Mesh *me);
@@ -105,6 +106,10 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_edges_nor(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_loose_verts(struct Mesh *me);
struct Gwn_Batch *DRW_mesh_batch_cache_get_overlay_facedots(struct Mesh *me);
+/* edit-mesh selection (use generic function for faces) */
+struct Gwn_Batch *DRW_mesh_batch_cache_get_facedots_with_select_id(struct Mesh *me, uint select_id_offset);
+struct Gwn_Batch *DRW_mesh_batch_cache_get_edges_with_select_id(struct Mesh *me, uint select_id_offset);
+struct Gwn_Batch *DRW_mesh_batch_cache_get_verts_with_select_id(struct Mesh *me, uint select_id_offset);
void DRW_mesh_cache_sculpt_coords_ensure(struct Mesh *me);
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.c b/source/blender/draw/intern/draw_cache_impl_curve.c
index 9ff9fab4c64..e6e52fe4579 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.c
+++ b/source/blender/draw/intern/draw_cache_impl_curve.c
@@ -422,12 +422,12 @@ void DRW_curve_batch_cache_dirty(Curve *cu, int mode)
break;
case BKE_CURVE_BATCH_DIRTY_SELECT:
/* editnurb */
- BATCH_DISCARD_ALL_SAFE(cache->overlay.verts);
- BATCH_DISCARD_ALL_SAFE(cache->overlay.edges);
+ GWN_BATCH_DISCARD_SAFE(cache->overlay.verts);
+ GWN_BATCH_DISCARD_SAFE(cache->overlay.edges);
/* editfont */
- BATCH_DISCARD_ALL_SAFE(cache->text.select);
- BATCH_DISCARD_ALL_SAFE(cache->text.cursor);
+ GWN_BATCH_DISCARD_SAFE(cache->text.select);
+ GWN_BATCH_DISCARD_SAFE(cache->text.cursor);
break;
default:
BLI_assert(0);
@@ -441,38 +441,26 @@ static void curve_batch_cache_clear(Curve *cu)
return;
}
- BATCH_DISCARD_ALL_SAFE(cache->overlay.verts);
- BATCH_DISCARD_ALL_SAFE(cache->overlay.edges);
+ GWN_BATCH_DISCARD_SAFE(cache->overlay.verts);
+ GWN_BATCH_DISCARD_SAFE(cache->overlay.edges);
- BATCH_DISCARD_ALL_SAFE(cache->surface.batch);
+ GWN_BATCH_DISCARD_SAFE(cache->surface.batch);
- if (cache->wire.batch) {
- BATCH_DISCARD_ALL_SAFE(cache->wire.batch);
- cache->wire.verts = NULL;
- cache->wire.edges = NULL;
- cache->wire.elem = NULL;
- }
- else {
- GWN_VERTBUF_DISCARD_SAFE(cache->wire.verts);
- GWN_VERTBUF_DISCARD_SAFE(cache->wire.edges);
- GWN_INDEXBUF_DISCARD_SAFE(cache->wire.elem);
- }
+ /* don't own vbo & elems */
+ GWN_BATCH_DISCARD_SAFE(cache->wire.batch);
+ GWN_VERTBUF_DISCARD_SAFE(cache->wire.verts);
+ GWN_VERTBUF_DISCARD_SAFE(cache->wire.edges);
+ GWN_INDEXBUF_DISCARD_SAFE(cache->wire.elem);
- if (cache->normal.batch) {
- BATCH_DISCARD_ALL_SAFE(cache->normal.batch);
- cache->normal.verts = NULL;
- cache->normal.edges = NULL;
- cache->normal.elem = NULL;
- }
- else {
- GWN_VERTBUF_DISCARD_SAFE(cache->normal.verts);
- GWN_VERTBUF_DISCARD_SAFE(cache->normal.edges);
- GWN_INDEXBUF_DISCARD_SAFE(cache->normal.elem);
- }
+ /* don't own vbo & elems */
+ GWN_BATCH_DISCARD_SAFE(cache->normal.batch);
+ GWN_VERTBUF_DISCARD_SAFE(cache->normal.verts);
+ GWN_VERTBUF_DISCARD_SAFE(cache->normal.edges);
+ GWN_INDEXBUF_DISCARD_SAFE(cache->normal.elem);
/* 3d text */
- BATCH_DISCARD_ALL_SAFE(cache->text.cursor);
- BATCH_DISCARD_ALL_SAFE(cache->text.select);
+ GWN_BATCH_DISCARD_SAFE(cache->text.cursor);
+ GWN_BATCH_DISCARD_SAFE(cache->text.select);
}
void DRW_curve_batch_cache_free(Curve *cu)
@@ -726,7 +714,7 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu)
GWN_vertbuf_data_resize(vbo, vbo_len_used);
}
- cache->overlay.verts = GWN_batch_create(GWN_PRIM_POINTS, vbo, NULL);
+ cache->overlay.verts = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
@@ -798,7 +786,7 @@ static void curve_batch_cache_create_overlay_batches(Curve *cu)
GWN_vertbuf_data_resize(vbo, vbo_len_used);
}
- cache->overlay.edges = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ cache->overlay.edges = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
curve_render_data_free(rdata);
@@ -892,7 +880,7 @@ static Gwn_Batch *curve_batch_cache_get_overlay_select(CurveRenderData *rdata, C
GWN_vertbuf_attr_set(vbo, attr_id.pos, vbo_len_used++, box[3]);
}
BLI_assert(vbo_len_used == vbo_len_capacity);
- cache->text.select = GWN_batch_create(GWN_PRIM_TRIS, vbo, NULL);
+ cache->text.select = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return cache->text.select;
}
@@ -913,7 +901,7 @@ static Gwn_Batch *curve_batch_cache_get_overlay_cursor(CurveRenderData *rdata, C
for (int i = 0; i < 4; i++) {
GWN_vertbuf_attr_set(vbo, attr_id.pos, i, rdata->text.edit_font->textcurs[i]);
}
- cache->text.cursor = GWN_batch_create(GWN_PRIM_TRI_FAN, vbo, NULL);
+ cache->text.cursor = GWN_batch_create_ex(GWN_PRIM_TRI_FAN, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
return cache->text.cursor;
}
@@ -950,7 +938,8 @@ Gwn_Batch *DRW_curve_batch_cache_get_normal_edge(Curve *cu, CurveCache *ob_curve
if (cache->normal.batch != NULL) {
cache->normal_size = normal_size;
if (cache->normal_size != normal_size) {
- BATCH_DISCARD_ALL_SAFE(cache->normal.batch);
+ GWN_BATCH_DISCARD_SAFE(cache->normal.batch);
+ GWN_VERTBUF_DISCARD_SAFE(cache->normal.edges);
}
}
cache->normal_size = normal_size;
diff --git a/source/blender/draw/intern/draw_cache_impl_displist.c b/source/blender/draw/intern/draw_cache_impl_displist.c
index fd36b7ad4a3..30eed85f49d 100644
--- a/source/blender/draw/intern/draw_cache_impl_displist.c
+++ b/source/blender/draw/intern/draw_cache_impl_displist.c
@@ -163,6 +163,8 @@ Gwn_Batch *BLI_displist_batch_calc_surface(ListBase *lb)
}
}
- return GWN_batch_create(GWN_PRIM_TRIS, vbo, GWN_indexbuf_build(&elb));
+ return GWN_batch_create_ex(
+ GWN_PRIM_TRIS, vbo, GWN_indexbuf_build(&elb),
+ GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_VBO);
}
}
diff --git a/source/blender/draw/intern/draw_cache_impl_lattice.c b/source/blender/draw/intern/draw_cache_impl_lattice.c
index 84b061aff9a..20698fe6592 100644
--- a/source/blender/draw/intern/draw_cache_impl_lattice.c
+++ b/source/blender/draw/intern/draw_cache_impl_lattice.c
@@ -376,7 +376,7 @@ void DRW_lattice_batch_cache_dirty(Lattice *lt, int mode)
break;
case BKE_LATTICE_BATCH_DIRTY_SELECT:
/* TODO Separate Flag vbo */
- BATCH_DISCARD_ALL_SAFE(cache->overlay_verts);
+ GWN_BATCH_DISCARD_SAFE(cache->overlay_verts);
break;
default:
BLI_assert(0);
@@ -392,7 +392,7 @@ static void lattice_batch_cache_clear(Lattice *lt)
GWN_BATCH_DISCARD_SAFE(cache->all_verts);
GWN_BATCH_DISCARD_SAFE(cache->all_edges);
- BATCH_DISCARD_ALL_SAFE(cache->overlay_verts);
+ GWN_BATCH_DISCARD_SAFE(cache->overlay_verts);
GWN_VERTBUF_DISCARD_SAFE(cache->pos);
GWN_INDEXBUF_DISCARD_SAFE(cache->edges);
@@ -537,7 +537,7 @@ static void lattice_batch_cache_create_overlay_batches(Lattice *lt)
GWN_vertbuf_attr_set(vbo, attr_id.data, i, &vflag);
}
- cache->overlay_verts = GWN_batch_create(GWN_PRIM_POINTS, vbo, NULL);
+ cache->overlay_verts = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
lattice_render_data_free(rdata);
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index f48d739f11b..f77411c91e8 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -245,7 +245,7 @@ static void mesh_cd_calc_used_gpu_layers(
struct GPUMaterial **gpumat_array, int gpumat_array_len)
{
/* See: DM_vertex_attributes_from_gpu for similar logic */
- GPUVertexAttribs gattribs = {0};
+ GPUVertexAttribs gattribs = {{{0}}};
for (int i = 0; i < gpumat_array_len; i++) {
GPUMaterial *gpumat = gpumat_array[i];
@@ -1420,28 +1420,39 @@ typedef struct MeshBatchCache {
Gwn_VertBuf *nor_in_order;
Gwn_IndexBuf *edges_in_order;
Gwn_IndexBuf *triangles_in_order;
- Gwn_IndexBuf *overlay_triangles_vpaint;
Gwn_Batch *all_verts;
Gwn_Batch *all_edges;
Gwn_Batch *all_triangles;
Gwn_VertBuf *pos_with_normals;
- Gwn_VertBuf *pos_with_normals_visible_only; /* for paint modes with vert/face hide support. */
- Gwn_VertBuf *tri_aligned_weights;
- Gwn_VertBuf *tri_aligned_vert_colors;
- Gwn_VertBuf *tri_aligned_select_id;
Gwn_VertBuf *tri_aligned_uv; /* Active UV layer (mloopuv) */
- Gwn_VertBuf *edge_pos_with_select_bool;
- Gwn_VertBuf *pos_with_select_bool;
+
+ /**
+ * Other uses are all positions or loose elements.
+ * This stores all visible elements, needed for selection.
+ */
+ Gwn_VertBuf *ed_fcenter_pos_with_nor_and_sel;
+ Gwn_VertBuf *ed_edge_pos;
+ Gwn_VertBuf *ed_vert_pos;
+
Gwn_Batch *triangles_with_normals;
- /* Skip hidden (depending on paint select mode),
- * 'pos_with_normals' or 'pos_with_normals_visible_only'. */
+ /* Skip hidden (depending on paint select mode) */
Gwn_Batch *triangles_with_weights;
Gwn_Batch *triangles_with_vert_colors;
/* Always skip hidden */
+ Gwn_Batch *triangles_with_select_mask;
Gwn_Batch *triangles_with_select_id;
+ uint triangles_with_select_id_offset;
+
+ Gwn_Batch *facedot_with_select_id; /* shares vbo with 'overlay_facedots' */
+ Gwn_Batch *edges_with_select_id;
+ Gwn_Batch *verts_with_select_id;
+
+ uint facedot_with_select_id_offset;
+ uint edges_with_select_id_offset;
+ uint verts_with_select_id_offset;
Gwn_Batch *points_with_normals;
Gwn_Batch *fancy_edges; /* owns its vertex buffer (not shared) */
@@ -1471,9 +1482,6 @@ typedef struct MeshBatchCache {
Gwn_VertBuf *ed_lvert_nor; /* VertNor */
Gwn_VertBuf *ed_lvert_data;
- Gwn_VertBuf *ed_fcenter_pos;
- Gwn_VertBuf *ed_fcenter_nor;
-
Gwn_Batch *overlay_triangles;
Gwn_Batch *overlay_triangles_nor; /* GWN_PRIM_POINTS */
Gwn_Batch *overlay_loose_edges;
@@ -1591,12 +1599,18 @@ void DRW_mesh_batch_cache_dirty(Mesh *me, int mode)
GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_data);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_ledge_data);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data);
- GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_nor); /* Contains select flag */
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel); /* Contains select flag */
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos);
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos);
+
GWN_BATCH_DISCARD_SAFE(cache->overlay_triangles);
GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_verts);
GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_edges);
-
- BATCH_DISCARD_ALL_SAFE(cache->overlay_facedots);
+ GWN_BATCH_DISCARD_SAFE(cache->overlay_facedots);
+ /* Edit mode selection. */
+ GWN_BATCH_DISCARD_SAFE(cache->facedot_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
break;
case BKE_MESH_BATCH_DIRTY_NOCHECK:
cache->is_really_dirty = true;
@@ -1626,10 +1640,8 @@ static void mesh_batch_cache_clear(Mesh *me)
GWN_BATCH_DISCARD_SAFE(cache->all_triangles);
GWN_VERTBUF_DISCARD_SAFE(cache->pos_in_order);
- GWN_VERTBUF_DISCARD_SAFE(cache->pos_with_select_bool);
GWN_INDEXBUF_DISCARD_SAFE(cache->edges_in_order);
GWN_INDEXBUF_DISCARD_SAFE(cache->triangles_in_order);
- GWN_INDEXBUF_DISCARD_SAFE(cache->overlay_triangles_vpaint);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_pos);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_tri_nor);
@@ -1640,8 +1652,6 @@ static void mesh_batch_cache_clear(Mesh *me)
GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_pos);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_nor);
GWN_VERTBUF_DISCARD_SAFE(cache->ed_lvert_data);
- GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos);
- GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_nor);
GWN_BATCH_DISCARD_SAFE(cache->overlay_triangles);
GWN_BATCH_DISCARD_SAFE(cache->overlay_triangles_nor);
GWN_BATCH_DISCARD_SAFE(cache->overlay_loose_verts);
@@ -1650,22 +1660,25 @@ static void mesh_batch_cache_clear(Mesh *me)
GWN_BATCH_DISCARD_SAFE(cache->overlay_weight_faces);
GWN_BATCH_DISCARD_SAFE(cache->overlay_weight_verts);
- BATCH_DISCARD_ALL_SAFE(cache->overlay_paint_edges);
- BATCH_DISCARD_ALL_SAFE(cache->overlay_facedots);
+ GWN_BATCH_DISCARD_SAFE(cache->overlay_paint_edges);
+ GWN_BATCH_DISCARD_SAFE(cache->overlay_facedots);
GWN_BATCH_DISCARD_SAFE(cache->triangles_with_normals);
GWN_BATCH_DISCARD_SAFE(cache->points_with_normals);
GWN_VERTBUF_DISCARD_SAFE(cache->pos_with_normals);
- GWN_VERTBUF_DISCARD_SAFE(cache->pos_with_normals_visible_only);
- GWN_VERTBUF_DISCARD_SAFE(cache->tri_aligned_vert_colors);
- GWN_VERTBUF_DISCARD_SAFE(cache->tri_aligned_weights);
GWN_BATCH_DISCARD_SAFE(cache->triangles_with_weights);
GWN_BATCH_DISCARD_SAFE(cache->triangles_with_vert_colors);
- GWN_VERTBUF_DISCARD_SAFE(cache->tri_aligned_select_id);
GWN_VERTBUF_DISCARD_SAFE(cache->tri_aligned_uv);
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_fcenter_pos_with_nor_and_sel);
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_edge_pos);
+ GWN_VERTBUF_DISCARD_SAFE(cache->ed_vert_pos);
+ GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_mask);
GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->facedot_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
+ GWN_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
- BATCH_DISCARD_ALL_SAFE(cache->fancy_edges);
+ GWN_BATCH_DISCARD_SAFE(cache->fancy_edges);
GWN_VERTBUF_DISCARD_SAFE(cache->shaded_triangles_data);
if (cache->shaded_triangles_in_order) {
@@ -2060,22 +2073,317 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals(
rdata, false,
&cache->pos_with_normals);
}
-static Gwn_VertBuf *mesh_batch_cache_get_tri_pos_and_normals_visible_only(
- MeshRenderData *rdata, MeshBatchCache *cache)
+static Gwn_VertBuf *mesh_create_tri_pos_and_normals_visible_only(
+ MeshRenderData *rdata)
{
+ Gwn_VertBuf *vbo_dummy = NULL;
return mesh_batch_cache_get_tri_pos_and_normals_ex(
rdata, true,
- &cache->pos_with_normals_visible_only);
+ &vbo_dummy);
+}
+
+static Gwn_VertBuf *mesh_batch_cache_get_facedot_pos_with_normals_and_flag(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ if (cache->ed_fcenter_pos_with_nor_and_sel == NULL) {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ attr_id.data = GWN_vertformat_attr_add(&format, "norAndFlag", GWN_COMP_I10, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
+ int vidx = 0;
+
+ Gwn_VertBuf *vbo = cache->ed_fcenter_pos_with_nor_and_sel = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ for (int i = 0; i < vbo_len_capacity; ++i) {
+ float pcenter[3], pnor[3];
+ bool selected = false;
+
+ if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) {
+
+ Gwn_PackedNormal nor = { .x = 0, .y = 0, .z = -511 };
+ nor = GWN_normal_convert_i10_v3(pnor);
+ nor.w = selected ? 1 : 0;
+ GWN_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor);
+
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter);
+
+ vidx += 1;
+ }
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ BLI_assert(vbo_len_capacity == vbo_len_used);
+ UNUSED_VARS_NDEBUG(vbo_len_used);
+ }
+
+ return cache->ed_fcenter_pos_with_nor_and_sel;
+}
+
+static Gwn_VertBuf *mesh_batch_cache_get_edges_visible(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
+
+ if (cache->ed_edge_pos == NULL) {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2;
+ int vidx = 0;
+
+ Gwn_VertBuf *vbo = cache->ed_edge_pos = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMEdge *eed;
+
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v1->co);
+ vidx += 1;
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, eed->v2->co);
+ vidx += 1;
+ }
+ }
+ }
+ else {
+ /* not yet done! */
+ BLI_assert(0);
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ UNUSED_VARS_NDEBUG(vbo_len_used);
+ }
+
+ return cache->ed_edge_pos;
+}
+
+static Gwn_VertBuf *mesh_batch_cache_get_verts_visible(
+ MeshRenderData *rdata, MeshBatchCache *cache)
+{
+ BLI_assert(rdata->types & MR_DATATYPE_VERT);
+
+ if (cache->ed_vert_pos == NULL) {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, data; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata);
+ uint vidx = 0;
+
+ Gwn_VertBuf *vbo = cache->ed_vert_pos = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMVert *eve;
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, eve->co);
+ vidx += 1;
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < vbo_len_capacity; i++) {
+ const MVert *mv = &rdata->mvert[i];
+ if (!(mv->flag & ME_HIDE)) {
+ GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, mv->co);
+ vidx += 1;
+ }
+ }
+ }
+ const uint vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+
+ UNUSED_VARS_NDEBUG(vbo_len_used);
+ }
+
+ return cache->ed_vert_pos;
+}
+
+static Gwn_VertBuf *mesh_create_facedot_select_id(
+ MeshRenderData *rdata, uint select_id_offset)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ Gwn_VertBuf *vbo;
+ {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, col; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
+ int vidx = 0;
+
+ vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ uint select_index = select_id_offset;
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMEdge *efa;
+
+ BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
+ if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+ int select_id;
+ GPU_select_index_get(select_index, &select_id);
+ GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
+ vidx += 1;
+ }
+ select_index += 1;
+ }
+ }
+ else {
+ /* not yet done! */
+ BLI_assert(0);
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ }
+
+ return vbo;
+}
+
+static Gwn_VertBuf *mesh_create_edges_select_id(
+ MeshRenderData *rdata, uint select_id_offset)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE));
+
+ Gwn_VertBuf *vbo;
+ {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, col; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_edges_len_get(rdata) * 2;
+ int vidx = 0;
+
+ vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ uint select_index = select_id_offset;
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMEdge *eed;
+
+ BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
+ if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) {
+ int select_id;
+ GPU_select_index_get(select_index, &select_id);
+ GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
+ vidx += 1;
+ GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
+ vidx += 1;
+ }
+ select_index += 1;
+ }
+ }
+ else {
+ /* not yet done! */
+ BLI_assert(0);
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ }
+
+ return vbo;
}
-static Gwn_VertBuf *mesh_batch_cache_get_tri_weights(
- MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide, int defgroup)
+static Gwn_VertBuf *mesh_create_verts_select_id(
+ MeshRenderData *rdata, uint select_id_offset)
+{
+ BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+
+ Gwn_VertBuf *vbo;
+ {
+ static Gwn_VertFormat format = { 0 };
+ static struct { uint pos, col; } attr_id;
+ if (format.attrib_ct == 0) {
+ attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_I32, 1, GWN_FETCH_INT);
+ }
+
+ const int vbo_len_capacity = mesh_render_data_verts_len_get(rdata);
+ int vidx = 0;
+
+ vbo = GWN_vertbuf_create_with_format(&format);
+ GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
+ uint select_index = select_id_offset;
+
+ if (rdata->edit_bmesh) {
+ BMesh *bm = rdata->edit_bmesh->bm;
+ BMIter iter;
+ BMVert *eve;
+
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) {
+ int select_id;
+ GPU_select_index_get(select_index, &select_id);
+ GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
+ vidx += 1;
+ }
+ select_index += 1;
+ }
+ }
+ else {
+ for (int i = 0; i < vbo_len_capacity; i++) {
+ const MVert *mv = &rdata->mvert[i];
+ if (!(mv->flag & ME_HIDE)) {
+ int select_id;
+ GPU_select_index_get(select_index, &select_id);
+ GWN_vertbuf_attr_set(vbo, attr_id.col, vidx, &select_id);
+ vidx += 1;
+ }
+ select_index += 1;
+ }
+ }
+ const int vbo_len_used = vidx;
+ if (vbo_len_used != vbo_len_capacity) {
+ GWN_vertbuf_data_resize(vbo, vbo_len_used);
+ }
+ }
+
+ return vbo;
+}
+
+static Gwn_VertBuf *mesh_create_tri_weights(
+ MeshRenderData *rdata, bool use_hide, int defgroup)
{
BLI_assert(
rdata->types &
(MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT));
- if (cache->tri_aligned_weights == NULL) {
+ Gwn_VertBuf *vbo;
+ {
unsigned int cidx = 0;
static Gwn_VertFormat format = { 0 };
@@ -2084,10 +2392,9 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_weights(
attr_id.col = GWN_vertformat_attr_add(&format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
}
- const int tri_len = mesh_render_data_looptri_len_get(rdata);
-
- Gwn_VertBuf *vbo = cache->tri_aligned_weights = GWN_vertbuf_create_with_format(&format);
+ vbo = GWN_vertbuf_create_with_format(&format);
+ const int tri_len = mesh_render_data_looptri_len_get(rdata);
const int vbo_len_capacity = tri_len * 3;
int vbo_len_used = 0;
GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
@@ -2125,17 +2432,18 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_weights(
}
}
- return cache->tri_aligned_weights;
+ return vbo;
}
-static Gwn_VertBuf *mesh_batch_cache_get_tri_vert_colors(
- MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
+static Gwn_VertBuf *mesh_create_tri_vert_colors(
+ MeshRenderData *rdata, bool use_hide)
{
BLI_assert(
rdata->types &
(MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPCOL));
- if (cache->tri_aligned_vert_colors == NULL) {
+ Gwn_VertBuf *vbo;
+ {
unsigned int cidx = 0;
static Gwn_VertFormat format = { 0 };
@@ -2146,7 +2454,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_vert_colors(
const int tri_len = mesh_render_data_looptri_len_get(rdata);
- Gwn_VertBuf *vbo = cache->tri_aligned_vert_colors = GWN_vertbuf_create_with_format(&format);
+ vbo = GWN_vertbuf_create_with_format(&format);
const uint vbo_len_capacity = tri_len * 3;
GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
@@ -2184,17 +2492,18 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_vert_colors(
}
}
- return cache->tri_aligned_vert_colors;
+ return vbo;
}
-static Gwn_VertBuf *mesh_batch_cache_get_tri_select_id(
- MeshRenderData *rdata, MeshBatchCache *cache, bool use_hide)
+static Gwn_VertBuf *mesh_create_tri_select_id(
+ MeshRenderData *rdata, bool use_hide, uint select_id_offset)
{
BLI_assert(
rdata->types &
(MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
- if (cache->tri_aligned_select_id == NULL) {
+ Gwn_VertBuf *vbo;
+ {
unsigned int cidx = 0;
static Gwn_VertFormat format = { 0 };
@@ -2205,7 +2514,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_select_id(
const int tri_len = mesh_render_data_looptri_len_get(rdata);
- Gwn_VertBuf *vbo = cache->tri_aligned_select_id = GWN_vertbuf_create_with_format(&format);
+ vbo = GWN_vertbuf_create_with_format(&format);
const int vbo_len_capacity = tri_len * 3;
int vbo_len_used = 0;
@@ -2218,7 +2527,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_select_id(
if (!BM_elem_flag_test(ltri[0]->f, BM_ELEM_HIDDEN)) {
const int poly_index = BM_elem_index_get(ltri[0]->f);
int select_id;
- GPU_select_index_get(poly_index + 1, &select_id);
+ GPU_select_index_get(poly_index + select_id_offset, &select_id);
for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id);
}
@@ -2231,7 +2540,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_select_id(
const int poly_index = mlt->poly;
if (!(use_hide && (rdata->mpoly[poly_index].flag & ME_HIDE))) {
int select_id;
- GPU_select_index_get(poly_index + 1, &select_id);
+ GPU_select_index_get(poly_index + select_id_offset, &select_id);
for (uint tri_corner = 0; tri_corner < 3; tri_corner++) {
GWN_vertbuf_attr_set(vbo, attr_id.col, cidx++, &select_id);
}
@@ -2244,8 +2553,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_tri_select_id(
GWN_vertbuf_data_resize(vbo, vbo_len_used);
}
}
-
- return cache->tri_aligned_select_id;
+ return vbo;
}
static Gwn_VertBuf *mesh_batch_cache_get_vert_pos_and_nor_in_order(
@@ -2780,13 +3088,14 @@ static Gwn_IndexBuf **mesh_batch_cache_get_triangles_in_order_split_by_material(
return cache->shaded_triangles_in_order;
}
-static Gwn_VertBuf *mesh_batch_cache_get_edge_pos_with_sel(
- MeshRenderData *rdata, MeshBatchCache *cache, bool use_wire, bool use_select_bool)
+static Gwn_VertBuf *mesh_create_edge_pos_with_sel(
+ MeshRenderData *rdata, bool use_wire, bool use_select_bool)
{
BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP));
BLI_assert(rdata->edit_bmesh == NULL);
- if (!cache->edge_pos_with_select_bool) {
+ Gwn_VertBuf *vbo;
+ {
unsigned int vidx = 0, cidx = 0;
static Gwn_VertFormat format = { 0 };
@@ -2798,7 +3107,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_edge_pos_with_sel(
const int edge_len = mesh_render_data_edges_len_get(rdata);
- Gwn_VertBuf *vbo = cache->edge_pos_with_select_bool = GWN_vertbuf_create_with_format(&format);
+ vbo= GWN_vertbuf_create_with_format(&format);
const int vbo_len_capacity = edge_len * 2;
int vbo_len_used = 0;
@@ -2836,15 +3145,15 @@ static Gwn_VertBuf *mesh_batch_cache_get_edge_pos_with_sel(
}
}
- return cache->edge_pos_with_select_bool;
+ return vbo;
}
-static Gwn_IndexBuf *mesh_batch_cache_get_tri_overlay_weight_faces(
- MeshRenderData *rdata, MeshBatchCache *cache)
+static Gwn_IndexBuf *mesh_create_tri_overlay_weight_faces(
+ MeshRenderData *rdata)
{
BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI));
- if (cache->overlay_triangles_vpaint == NULL) {
+ {
const int vert_len = mesh_render_data_verts_len_get(rdata);
const int tri_len = mesh_render_data_looptri_len_get(rdata);
@@ -2859,22 +3168,21 @@ static Gwn_IndexBuf *mesh_batch_cache_get_tri_overlay_weight_faces(
}
}
}
- cache->overlay_triangles_vpaint = GWN_indexbuf_build(&elb);
+ return GWN_indexbuf_build(&elb);
}
-
- return cache->overlay_triangles_vpaint;
}
/**
* Non-edit mode vertices (only used for weight-paint mode).
*/
-static Gwn_VertBuf *mesh_batch_cache_get_vert_pos_with_overlay_data(
- MeshRenderData *rdata, MeshBatchCache *cache)
+static Gwn_VertBuf *mesh_create_vert_pos_with_overlay_data(
+ MeshRenderData *rdata)
{
BLI_assert(rdata->types & (MR_DATATYPE_VERT));
BLI_assert(rdata->edit_bmesh == NULL);
- if (cache->pos_with_select_bool == NULL) {
+ Gwn_VertBuf *vbo;
+ {
unsigned int cidx = 0;
static Gwn_VertFormat format = { 0 };
@@ -2885,7 +3193,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_vert_pos_with_overlay_data(
const int vert_len = mesh_render_data_verts_len_get(rdata);
- Gwn_VertBuf *vbo = cache->pos_with_select_bool = GWN_vertbuf_create_with_format(&format);
+ vbo = GWN_vertbuf_create_with_format(&format);
const int vbo_len_capacity = vert_len;
int vbo_len_used = 0;
@@ -2902,8 +3210,7 @@ static Gwn_VertBuf *mesh_batch_cache_get_vert_pos_with_overlay_data(
GWN_vertbuf_data_resize(vbo, vbo_len_used);
}
}
-
- return cache->pos_with_select_bool;
+ return vbo;
}
/** \} */
@@ -2979,14 +3286,14 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_weights(Mesh *me,
MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_DVERT;
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
- cache->triangles_with_weights = GWN_batch_create(
- GWN_PRIM_TRIS, mesh_batch_cache_get_tri_weights(rdata, cache, use_hide, defgroup), NULL);
+ cache->triangles_with_weights = GWN_batch_create_ex(
+ GWN_PRIM_TRIS, mesh_create_tri_weights(rdata, use_hide, defgroup), NULL, GWN_BATCH_OWNS_VBO);
Gwn_VertBuf *vbo_tris = use_hide ?
- mesh_batch_cache_get_tri_pos_and_normals_visible_only(rdata, cache) :
+ mesh_create_tri_pos_and_normals_visible_only(rdata) :
mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
- GWN_batch_vertbuf_add(cache->triangles_with_weights, vbo_tris);
+ GWN_batch_vertbuf_add_ex(cache->triangles_with_weights, vbo_tris, use_hide);
mesh_render_data_free(rdata);
}
@@ -3004,13 +3311,13 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh
MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY | MR_DATATYPE_LOOPCOL;
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
- cache->triangles_with_vert_colors = GWN_batch_create(
- GWN_PRIM_TRIS, mesh_batch_cache_get_tri_vert_colors(rdata, cache, use_hide), NULL);
+ cache->triangles_with_vert_colors = GWN_batch_create_ex(
+ GWN_PRIM_TRIS, mesh_create_tri_vert_colors(rdata, use_hide), NULL, GWN_BATCH_OWNS_VBO);
Gwn_VertBuf *vbo_tris = use_hide ?
- mesh_batch_cache_get_tri_pos_and_normals_visible_only(rdata, cache) :
+ mesh_create_tri_pos_and_normals_visible_only(rdata) :
mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
- GWN_batch_vertbuf_add(cache->triangles_with_vert_colors, vbo_tris);
+ GWN_batch_vertbuf_add_ex(cache->triangles_with_vert_colors, vbo_tris, use_hide);
mesh_render_data_free(rdata);
}
@@ -3019,22 +3326,28 @@ Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_normals_and_vert_colors(Mesh
}
-struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh *me, bool use_hide)
+struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(
+ struct Mesh *me, bool use_hide, uint select_id_offset)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
+ if (cache->triangles_with_select_id_offset != select_id_offset) {
+ cache->triangles_with_select_id_offset = select_id_offset;
+ GWN_BATCH_DISCARD_SAFE(cache->triangles_with_select_id);
+ }
+
if (cache->triangles_with_select_id == NULL) {
const int datatype =
MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
- cache->triangles_with_select_id = GWN_batch_create(
- GWN_PRIM_TRIS, mesh_batch_cache_get_tri_select_id(rdata, cache, use_hide), NULL);
+ cache->triangles_with_select_id = GWN_batch_create_ex(
+ GWN_PRIM_TRIS, mesh_create_tri_select_id(rdata, use_hide, select_id_offset), NULL, GWN_BATCH_OWNS_VBO);
Gwn_VertBuf *vbo_tris = use_hide ?
- mesh_batch_cache_get_tri_pos_and_normals_visible_only(rdata, cache) :
+ mesh_create_tri_pos_and_normals_visible_only(rdata) :
mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
- GWN_batch_vertbuf_add(cache->triangles_with_select_id, vbo_tris);
+ GWN_batch_vertbuf_add_ex(cache->triangles_with_select_id, vbo_tris, use_hide);
mesh_render_data_free(rdata);
}
@@ -3042,6 +3355,31 @@ struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_id(struct Mesh
return cache->triangles_with_select_id;
}
+/**
+ * Same as #DRW_mesh_batch_cache_get_triangles_with_select_id
+ * without the ID's, use to mask out geometry, eg - dont select face-dots behind other faces.
+ */
+struct Gwn_Batch *DRW_mesh_batch_cache_get_triangles_with_select_mask(struct Mesh *me, bool use_hide)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+ if (cache->triangles_with_select_mask == NULL) {
+ const int datatype =
+ MR_DATATYPE_VERT | MR_DATATYPE_LOOPTRI | MR_DATATYPE_LOOP | MR_DATATYPE_POLY;
+ MeshRenderData *rdata = mesh_render_data_create(me, datatype);
+
+ Gwn_VertBuf *vbo_tris = use_hide ?
+ mesh_create_tri_pos_and_normals_visible_only(rdata) :
+ mesh_batch_cache_get_tri_pos_and_normals(rdata, cache);
+
+ cache->triangles_with_select_mask = GWN_batch_create_ex(
+ GWN_PRIM_TRIS, vbo_tris, NULL, use_hide ? GWN_BATCH_OWNS_VBO : 0);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->triangles_with_select_mask;
+}
+
Gwn_Batch *DRW_mesh_batch_cache_get_points_with_normals(Mesh *me)
{
MeshBatchCache *cache = mesh_batch_cache_get(me);
@@ -3133,7 +3471,7 @@ Gwn_Batch *DRW_mesh_batch_cache_get_fancy_edges(Mesh *me)
GWN_vertbuf_data_resize(vbo, vbo_len_used);
}
- cache->fancy_edges = GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ cache->fancy_edges = GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
mesh_render_data_free(rdata);
}
@@ -3251,46 +3589,90 @@ Gwn_Batch *DRW_mesh_batch_cache_get_overlay_facedots(Mesh *me)
if (cache->overlay_facedots == NULL) {
MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
- static Gwn_VertFormat format = { 0 };
- static struct { uint pos, data; } attr_id;
- if (format.attrib_ct == 0) {
- attr_id.pos = GWN_vertformat_attr_add(&format, "pos", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
- attr_id.data = GWN_vertformat_attr_add(&format, "norAndFlag", GWN_COMP_I10, 4, GWN_FETCH_INT_TO_FLOAT_UNIT);
- }
+ cache->overlay_facedots = GWN_batch_create(
+ GWN_PRIM_POINTS, mesh_batch_cache_get_facedot_pos_with_normals_and_flag(rdata, cache), NULL);
- const int vbo_len_capacity = mesh_render_data_polys_len_get(rdata);
- int vidx = 0;
+ mesh_render_data_free(rdata);
+ }
- Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&format);
- GWN_vertbuf_data_alloc(vbo, vbo_len_capacity);
- for (int i = 0; i < vbo_len_capacity; ++i) {
- float pcenter[3], pnor[3];
- bool selected = false;
+ return cache->overlay_facedots;
+}
- if (mesh_render_data_pnors_pcenter_select_get(rdata, i, pnor, pcenter, &selected)) {
+Gwn_Batch *DRW_mesh_batch_cache_get_facedots_with_select_id(Mesh *me, uint select_id_offset)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
- Gwn_PackedNormal nor = { .x = 0, .y = 0, .z = -511 };
- nor = GWN_normal_convert_i10_v3(pnor);
- nor.w = selected ? 1 : 0;
- GWN_vertbuf_attr_set(vbo, attr_id.data, vidx, &nor);
+ if (cache->facedot_with_select_id_offset != select_id_offset) {
+ cache->facedot_with_select_id_offset = select_id_offset;
+ GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
+ }
- GWN_vertbuf_attr_set(vbo, attr_id.pos, vidx, pcenter);
+ if (cache->facedot_with_select_id == NULL) {
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY);
- vidx += 1;
+ /* We only want the 'pos', not the normals or flag.
+ * Use since this is almost certainly already created. */
+ cache->facedot_with_select_id = GWN_batch_create(
+ GWN_PRIM_POINTS, mesh_batch_cache_get_facedot_pos_with_normals_and_flag(rdata, cache), NULL);
- }
- }
- const int vbo_len_used = vidx;
- if (vbo_len_used != vbo_len_capacity) {
- GWN_vertbuf_data_resize(vbo, vbo_len_used);
- }
+ GWN_batch_vertbuf_add_ex(
+ cache->facedot_with_select_id,
+ mesh_create_facedot_select_id(rdata, select_id_offset), true);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->facedot_with_select_id;
+}
+
+Gwn_Batch *DRW_mesh_batch_cache_get_edges_with_select_id(Mesh *me, uint select_id_offset)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
- cache->overlay_facedots = GWN_batch_create(GWN_PRIM_POINTS, vbo, NULL);
+ if (cache->edges_with_select_id_offset != select_id_offset) {
+ cache->edges_with_select_id_offset = select_id_offset;
+ GWN_BATCH_DISCARD_SAFE(cache->edges_with_select_id);
+ }
+
+ if (cache->edges_with_select_id == NULL) {
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT | MR_DATATYPE_EDGE);
+
+ cache->edges_with_select_id = GWN_batch_create(
+ GWN_PRIM_LINES, mesh_batch_cache_get_edges_visible(rdata, cache), NULL);
+
+ GWN_batch_vertbuf_add_ex(
+ cache->edges_with_select_id,
+ mesh_create_edges_select_id(rdata, select_id_offset), true);
mesh_render_data_free(rdata);
}
- return cache->overlay_facedots;
+ return cache->edges_with_select_id;
+}
+
+Gwn_Batch *DRW_mesh_batch_cache_get_verts_with_select_id(Mesh *me, uint select_id_offset)
+{
+ MeshBatchCache *cache = mesh_batch_cache_get(me);
+
+ if (cache->verts_with_select_id_offset != select_id_offset) {
+ cache->verts_with_select_id_offset = select_id_offset;
+ GWN_BATCH_DISCARD_SAFE(cache->verts_with_select_id);
+ }
+
+ if (cache->verts_with_select_id == NULL) {
+ MeshRenderData *rdata = mesh_render_data_create(me, MR_DATATYPE_VERT);
+
+ cache->verts_with_select_id = GWN_batch_create(
+ GWN_PRIM_POINTS, mesh_batch_cache_get_verts_visible(rdata, cache), NULL);
+
+ GWN_batch_vertbuf_add_ex(
+ cache->verts_with_select_id,
+ mesh_create_verts_select_id(rdata, select_id_offset), true);
+
+ mesh_render_data_free(rdata);
+ }
+
+ return cache->verts_with_select_id;
}
Gwn_Batch **DRW_mesh_batch_cache_get_surface_shaded(
@@ -3391,8 +3773,8 @@ Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_edges(Mesh *me, bool use_wire
const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_EDGE | MR_DATATYPE_POLY | MR_DATATYPE_LOOP;
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
- cache->overlay_paint_edges = GWN_batch_create(
- GWN_PRIM_LINES, mesh_batch_cache_get_edge_pos_with_sel(rdata, cache, use_wire, use_sel), NULL);
+ cache->overlay_paint_edges = GWN_batch_create_ex(
+ GWN_PRIM_LINES, mesh_create_edge_pos_with_sel(rdata, use_wire, use_sel), NULL, GWN_BATCH_OWNS_VBO);
mesh_render_data_free(rdata);
}
@@ -3409,9 +3791,9 @@ Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_faces(Mesh *me)
const int datatype = MR_DATATYPE_VERT | MR_DATATYPE_POLY | MR_DATATYPE_LOOP | MR_DATATYPE_LOOPTRI;
MeshRenderData *rdata = mesh_render_data_create(me, datatype);
- cache->overlay_weight_faces = GWN_batch_create(
+ cache->overlay_weight_faces = GWN_batch_create_ex(
GWN_PRIM_TRIS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache),
- mesh_batch_cache_get_tri_overlay_weight_faces(rdata, cache));
+ mesh_create_tri_overlay_weight_faces(rdata), GWN_BATCH_OWNS_INDEX);
mesh_render_data_free(rdata);
}
@@ -3430,9 +3812,9 @@ Gwn_Batch *DRW_mesh_batch_cache_get_weight_overlay_verts(Mesh *me)
cache->overlay_weight_verts = GWN_batch_create(
GWN_PRIM_POINTS, mesh_batch_cache_get_vert_pos_and_nor_in_order(rdata, cache), NULL);
- GWN_batch_vertbuf_add(
+ GWN_batch_vertbuf_add_ex(
cache->overlay_weight_verts,
- mesh_batch_cache_get_vert_pos_with_overlay_data(rdata, cache));
+ mesh_create_vert_pos_with_overlay_data(rdata), true);
mesh_render_data_free(rdata);
}
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 40f136a07f0..02df1f55ae7 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -360,6 +360,9 @@ static struct DRWGlobalState {
struct DRWTextStore **text_store_p;
ListBase enabled_engines; /* RenderEngineType */
+
+ /* Profiling */
+ double cache_time;
} DST = {NULL};
static struct DRWMatrixOveride {
@@ -394,16 +397,16 @@ static void drw_texture_get_format(
case DRW_TEX_RGBA_16: *r_data_type = GPU_RGBA16F; break;
case DRW_TEX_RGB_16: *r_data_type = GPU_RGB16F; break;
case DRW_TEX_RGB_11_11_10: *r_data_type = GPU_R11F_G11F_B10F; break;
+ case DRW_TEX_RG_8: *r_data_type = GPU_RG8; break;
case DRW_TEX_RG_16: *r_data_type = GPU_RG16F; break;
case DRW_TEX_RG_32: *r_data_type = GPU_RG32F; break;
case DRW_TEX_R_8: *r_data_type = GPU_R8; break;
case DRW_TEX_R_16: *r_data_type = GPU_R16F; break;
case DRW_TEX_R_32: *r_data_type = GPU_R32F; break;
#if 0
- case DRW_TEX_RGBA_32: *data_type = GPU_RGBA32F; break;
- case DRW_TEX_RGB_8: *data_type = GPU_RGB8; break;
- case DRW_TEX_RGB_32: *data_type = GPU_RGB32F; break;
- case DRW_TEX_RG_8: *data_type = GPU_RG8; break;
+ case DRW_TEX_RGBA_32: *r_data_type = GPU_RGBA32F; break;
+ case DRW_TEX_RGB_8: *r_data_type = GPU_RGB8; break;
+ case DRW_TEX_RGB_32: *r_data_type = GPU_RGB32F; break;
#endif
case DRW_TEX_DEPTH_16: *r_data_type = GPU_DEPTH_COMPONENT16; break;
case DRW_TEX_DEPTH_24: *r_data_type = GPU_DEPTH_COMPONENT24; break;
@@ -906,14 +909,14 @@ void DRW_shgroup_free(struct DRWShadingGroup *shgroup)
BLI_freelistN(&shgroup->interface->attribs);
if (shgroup->interface->instance_vbo &&
- (shgroup->interface->instance_batch == 0))
+ (shgroup->interface->instance_batch == 0))
{
glDeleteBuffers(1, &shgroup->interface->instance_vbo);
}
MEM_freeN(shgroup->interface);
- BATCH_DISCARD_ALL_SAFE(shgroup->batch_geom);
+ GWN_BATCH_DISCARD_SAFE(shgroup->batch_geom);
}
void DRW_shgroup_instance_batch(DRWShadingGroup *shgroup, struct Gwn_Batch *instances)
@@ -1254,9 +1257,9 @@ static void shgroup_dynamic_batch(DRWShadingGroup *shgroup)
/* TODO make the batch dynamic instead of freeing it every times */
if (shgroup->batch_geom)
- GWN_batch_discard_all(shgroup->batch_geom);
+ GWN_batch_discard(shgroup->batch_geom);
- shgroup->batch_geom = GWN_batch_create(type, vbo, NULL);
+ shgroup->batch_geom = GWN_batch_create_ex(type, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
static void shgroup_dynamic_instance(DRWShadingGroup *shgroup)
@@ -2207,6 +2210,7 @@ static GPUTextureFormat convert_tex_format(
switch (fbo_format) {
case DRW_TEX_R_16: *r_channels = 1; return GPU_R16F;
case DRW_TEX_R_32: *r_channels = 1; return GPU_R32F;
+ case DRW_TEX_RG_8: *r_channels = 2; return GPU_RG8;
case DRW_TEX_RG_16: *r_channels = 2; return GPU_RG16F;
case DRW_TEX_RG_32: *r_channels = 2; return GPU_RG32F;
case DRW_TEX_RGBA_8: *r_channels = 4; return GPU_RGBA8;
@@ -2676,13 +2680,9 @@ static void DRW_engines_cache_init(void)
DST.text_store_p = &data->text_draw_cache;
}
- PROFILE_START(stime);
- data->cache_time = 0.0;
-
if (engine->cache_init) {
engine->cache_init(data);
}
- PROFILE_END_ACCUM(data->cache_time, stime);
}
}
@@ -2691,13 +2691,10 @@ static void DRW_engines_cache_populate(Object *ob)
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
DrawEngineType *engine = link->data;
ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
- PROFILE_START(stime);
if (engine->cache_populate) {
engine->cache_populate(data, ob);
}
-
- PROFILE_END_ACCUM(data->cache_time, stime);
}
}
@@ -2706,13 +2703,10 @@ static void DRW_engines_cache_finish(void)
for (LinkData *link = DST.enabled_engines.first; link; link = link->next) {
DrawEngineType *engine = link->data;
ViewportEngineData *data = DRW_viewport_engine_data_get(engine);
- PROFILE_START(stime);
if (engine->cache_finish) {
engine->cache_finish(data);
}
-
- PROFILE_END_ACCUM(data->cache_time, stime);
}
}
@@ -2952,7 +2946,7 @@ static void DRW_engines_enable_external(void)
static void DRW_engines_enable(const Scene *scene, SceneLayer *sl)
{
- Object *obact = OBACT_NEW;
+ Object *obact = OBACT_NEW(sl);
const int mode = CTX_data_mode_enum_ex(scene->obedit, obact);
DRW_engines_enable_from_engine(scene);
@@ -2991,7 +2985,7 @@ static void draw_stat(rcti *rect, int u, int v, const char *txt, const int size)
static void DRW_debug_cpu_stats(void)
{
int u, v;
- double cache_tot_time = 0.0, init_tot_time = 0.0, background_tot_time = 0.0, render_tot_time = 0.0, tot_time = 0.0;
+ double init_tot_time = 0.0, background_tot_time = 0.0, render_tot_time = 0.0, tot_time = 0.0;
/* local coordinate visible rect inside region, to accomodate overlapping ui */
rcti rect;
struct ARegion *ar = DST.draw_ctx.ar;
@@ -3005,8 +2999,6 @@ static void DRW_debug_cpu_stats(void)
char col_label[32];
sprintf(col_label, "Engine");
draw_stat(&rect, u++, v, col_label, sizeof(col_label));
- sprintf(col_label, "Cache");
- draw_stat(&rect, u++, v, col_label, sizeof(col_label));
sprintf(col_label, "Init");
draw_stat(&rect, u++, v, col_label, sizeof(col_label));
sprintf(col_label, "Background");
@@ -3026,10 +3018,6 @@ static void DRW_debug_cpu_stats(void)
draw_stat(&rect, u++, v, engine->idname, sizeof(engine->idname));
- cache_tot_time += data->cache_time;
- sprintf(time_to_txt, "%.2fms", data->cache_time);
- draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
-
init_tot_time += data->init_time;
sprintf(time_to_txt, "%.2fms", data->init_time);
draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
@@ -3052,8 +3040,6 @@ static void DRW_debug_cpu_stats(void)
u = 0;
sprintf(col_label, "Sub Total");
draw_stat(&rect, u++, v, col_label, sizeof(col_label));
- sprintf(time_to_txt, "%.2fms", cache_tot_time);
- draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
sprintf(time_to_txt, "%.2fms", init_tot_time);
draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
sprintf(time_to_txt, "%.2fms", background_tot_time);
@@ -3062,6 +3048,13 @@ static void DRW_debug_cpu_stats(void)
draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
sprintf(time_to_txt, "%.2fms", tot_time);
draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
+ v += 2;
+
+ u = 0;
+ sprintf(col_label, "Cache Time");
+ draw_stat(&rect, u++, v, col_label, sizeof(col_label));
+ sprintf(time_to_txt, "%.2fms", DST.cache_time);
+ draw_stat(&rect, u++, v, time_to_txt, sizeof(time_to_txt));
}
/* Display GPU time for each passes */
@@ -3074,7 +3067,7 @@ static void DRW_debug_gpu_stats(void)
UI_FontThemeColor(BLF_default(), TH_TEXT_HI);
- int v = BLI_listbase_count(&DST.enabled_engines) + 3;
+ int v = BLI_listbase_count(&DST.enabled_engines) + 5;
char stat_string[32];
@@ -3145,7 +3138,7 @@ void DRW_draw_render_loop_ex(
cache_is_dirty = GPU_viewport_cache_validate(DST.viewport, DRW_engines_get_hash());
DST.draw_ctx = (DRWContextState){
- ar, rv3d, v3d, scene, sl, OBACT_NEW,
+ ar, rv3d, v3d, scene, sl, OBACT_NEW(sl),
/* reuse if caller sets */
DST.draw_ctx.evil_C,
};
@@ -3165,6 +3158,7 @@ void DRW_draw_render_loop_ex(
/* ideally only refresh when objects are added/removed */
/* or render properties / materials change */
if (cache_is_dirty) {
+ PROFILE_START(stime);
DRW_engines_cache_init();
DEG_OBJECT_ITER(graph, ob, DEG_OBJECT_ITER_FLAG_ALL);
@@ -3176,6 +3170,7 @@ void DRW_draw_render_loop_ex(
DEG_OBJECT_ITER_END
DRW_engines_cache_finish();
+ PROFILE_END_ACCUM(DST.cache_time, stime);
}
DRW_stats_begin();
@@ -3327,7 +3322,7 @@ void DRW_draw_select_loop(
/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
DST.draw_ctx = (DRWContextState){
- ar, rv3d, v3d, scene, sl, OBACT_NEW, (bContext *)NULL,
+ ar, rv3d, v3d, scene, sl, OBACT_NEW(sl), (bContext *)NULL,
};
DRW_viewport_var_init();
@@ -3423,7 +3418,7 @@ void DRW_draw_depth_loop(
/* Instead of 'DRW_context_state_init(C, &DST.draw_ctx)', assign from args */
DST.draw_ctx = (DRWContextState){
- ar, rv3d, v3d, scene, sl, OBACT_NEW, (bContext *)NULL,
+ ar, rv3d, v3d, scene, sl, OBACT_NEW(sl), (bContext *)NULL,
};
DRW_viewport_var_init();
diff --git a/source/blender/draw/intern/draw_manager_profiling.c b/source/blender/draw/intern/draw_manager_profiling.c
index bca9e50da99..2b913bcbb8d 100644
--- a/source/blender/draw/intern/draw_manager_profiling.c
+++ b/source/blender/draw/intern/draw_manager_profiling.c
@@ -231,12 +231,12 @@ void DRW_stats_draw(rcti *rect)
time_ms = MIN2(time_ms, 999.0);
time_percent = MIN2(time_percent, 100.0);
+ BLI_snprintf(stat_string, sizeof(stat_string), "%s", timer->name);
+ BLF_draw_default_ascii(rect->xmin + (1 + timer->lvl) * U.widget_unit, rect->ymax - v * U.widget_unit, 0.0f, stat_string, sizeof(stat_string));
BLI_snprintf(stat_string, sizeof(stat_string), "%.2fms", time_ms);
- BLF_draw_default_ascii(rect->xmin + 1 * U.widget_unit, rect->ymax - v * U.widget_unit, 0.0f, stat_string, sizeof(stat_string));
+ BLF_draw_default_ascii(rect->xmin + (13 + timer->lvl) * U.widget_unit, rect->ymax - v * U.widget_unit, 0.0f, stat_string, sizeof(stat_string));
BLI_snprintf(stat_string, sizeof(stat_string), "%.0f", time_percent);
- BLF_draw_default_ascii(rect->xmin + 4 * U.widget_unit, rect->ymax - v * U.widget_unit, 0.0f, stat_string, sizeof(stat_string));
- BLI_snprintf(stat_string, sizeof(stat_string), "%s", timer->name);
- BLF_draw_default_ascii(rect->xmin + (6 + timer->lvl) * U.widget_unit, rect->ymax - v * U.widget_unit, 0.0f, stat_string, sizeof(stat_string));
+ BLF_draw_default_ascii(rect->xmin + (17 + timer->lvl) * U.widget_unit, rect->ymax - v * U.widget_unit, 0.0f, stat_string, sizeof(stat_string));
v++;
}
} \ No newline at end of file
diff --git a/source/blender/draw/intern/draw_view.c b/source/blender/draw/intern/draw_view.c
index 67bb781562e..ea1d93a6a85 100644
--- a/source/blender/draw/intern/draw_view.c
+++ b/source/blender/draw/intern/draw_view.c
@@ -613,7 +613,7 @@ void DRW_draw_background(void)
static bool is_cursor_visible(Scene *scene, SceneLayer *sl)
{
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
/* don't draw cursor in paint modes, but with a few exceptions */
if (ob && ob->mode & OB_MODE_ALL_PAINT) {
diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c
index 26d67a28226..cb782bacde0 100644
--- a/source/blender/draw/modes/object_mode.c
+++ b/source/blender/draw/modes/object_mode.c
@@ -696,7 +696,7 @@ static void OBJECT_cache_init(void *vedata)
{
DRWState state = DRW_STATE_WRITE_COLOR | DRW_STATE_WRITE_DEPTH | DRW_STATE_DEPTH_LESS | DRW_STATE_WIRE;
- psl->outlines = DRW_pass_create("Outlines Pass", state);
+ psl->outlines = DRW_pass_create("Outlines Depth Pass", state);
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
@@ -725,7 +725,7 @@ static void OBJECT_cache_init(void *vedata)
static bool bTrue = true;
static bool bFalse = false;
- psl->outlines_search = DRW_pass_create("Outlines Expand Pass", state);
+ psl->outlines_search = DRW_pass_create("Outlines Detect Pass", state);
DRWShadingGroup *grp = DRW_shgroup_create(e_data.outline_detect_sh, psl->outlines_search);
DRW_shgroup_uniform_buffer(grp, "outlineColor", &e_data.outlines_color_tx);
@@ -1571,7 +1571,7 @@ static void DRW_shgroup_object_center(OBJECT_StorageList *stl, Object *ob, Scene
const bool is_library = ob->id.us > 1 || ID_IS_LINKED_DATABLOCK(ob);
DRWShadingGroup *shgroup;
- if (ob == OBACT_NEW) {
+ if (ob == OBACT_NEW(sl)) {
shgroup = stl->g_data->center_active;
}
else if (ob->base_flag & BASE_SELECTED) {
diff --git a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
index 5565a0f1e09..dc0ea938436 100644
--- a/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_outline_detect_frag.glsl
@@ -32,30 +32,48 @@ void search_outline(ivec2 uv, vec4 ref_col, inout bool ref_occlu, inout bool out
void main()
{
ivec2 uv = ivec2(gl_FragCoord.xy);
+
+ vec4 color[4];
+ /* Idea : Use a 16bit ID to identify the color
+ * and store the colors in a UBO. And fetch all ids
+ * for discontinuity check with one textureGather \o/ */
vec4 ref_col = texelFetch(outlineColor, uv, 0).rgba;
+ color[0] = texelFetchOffset(outlineColor, uv, 0, ivec2( 1, 0)).rgba;
+ color[1] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, 1)).rgba;
+ color[2] = texelFetchOffset(outlineColor, uv, 0, ivec2(-1, 0)).rgba;
+ color[3] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, -1)).rgba;
+ /* TODO GATHER */
+ vec4 depths;
float depth = texelFetch(outlineDepth, uv, 0).r;
- /* Modulate color if occluded */
+ depths.x = texelFetchOffset(outlineDepth, uv, 0, ivec2( 1, 0)).r;
+ depths.y = texelFetchOffset(outlineDepth, uv, 0, ivec2( 0, 1)).r;
+ depths.z = texelFetchOffset(outlineDepth, uv, 0, ivec2(-1, 0)).r;
+ depths.w = texelFetchOffset(outlineDepth, uv, 0, ivec2( 0, -1)).r;
+
+ vec4 scene_depths;
float scene_depth = texelFetch(sceneDepth, uv, 0).r;
+ scene_depths.x = texelFetchOffset(sceneDepth, uv, 0, ivec2( 1, 0)).r;
+ scene_depths.y = texelFetchOffset(sceneDepth, uv, 0, ivec2( 0, 1)).r;
+ scene_depths.z = texelFetchOffset(sceneDepth, uv, 0, ivec2(-1, 0)).r;
+ scene_depths.w = texelFetchOffset(sceneDepth, uv, 0, ivec2( 0, -1)).r;
bool ref_occlu = (depth > scene_depth);
-
bool outline = false;
+#if 1
+ bvec4 occlu = (!ref_occlu) ? notEqual(greaterThan(depths, scene_depths), bvec4(ref_occlu)) : bvec4(false);
+ outline = (!outline) ? (color[0] != ref_col) || occlu.x : true;
+ outline = (!outline) ? (color[1] != ref_col) || occlu.y : true;
+ outline = (!outline) ? (color[2] != ref_col) || occlu.z : true;
+ outline = (!outline) ? (color[3] != ref_col) || occlu.w : true;
+#else
search_outline(uv + ivec2( 1, 0), ref_col, ref_occlu, outline);
search_outline(uv + ivec2( 0, 1), ref_col, ref_occlu, outline);
search_outline(uv + ivec2(-1, 0), ref_col, ref_occlu, outline);
search_outline(uv + ivec2( 0, -1), ref_col, ref_occlu, outline);
+#endif
FragColor = ref_col;
-
- /* We Hit something ! */
- if (outline) {
- if (ref_occlu) {
- FragColor.a *= alphaOcclu;
- }
- }
- else {
- FragColor.a = 0.0;
- }
+ FragColor.a *= (outline) ? (ref_occlu) ? alphaOcclu : 1.0 : 0.0;
}
diff --git a/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl b/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl
index e0568d1157a..c753e3ab39c 100644
--- a/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl
+++ b/source/blender/draw/modes/shaders/object_outline_expand_frag.glsl
@@ -9,37 +9,30 @@ uniform sampler2D outlineDepth;
uniform float alpha;
uniform bool doExpand;
-void search_outline(ivec2 uv, inout bool found_edge)
-{
- if (!found_edge) {
- vec4 color = texelFetch(outlineColor, uv, 0).rgba;
- if (color.a != 0.0) {
- if (doExpand || color.a != 1.0) {
- FragColor = color;
- found_edge = true;
- }
- }
- }
-}
-
void main()
{
ivec2 uv = ivec2(gl_FragCoord.xy);
FragColor = texelFetch(outlineColor, uv, 0).rgba;
float depth = texelFetch(outlineDepth, uv, 0).r;
- if (FragColor.a != 0.0 || (depth == 1.0 && !doExpand))
- return;
+ vec4 color[4];
+ color[0] = texelFetchOffset(outlineColor, uv, 0, ivec2( 1, 0)).rgba;
+ color[1] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, 1)).rgba;
+ color[2] = texelFetchOffset(outlineColor, uv, 0, ivec2(-1, 0)).rgba;
+ color[3] = texelFetchOffset(outlineColor, uv, 0, ivec2( 0, -1)).rgba;
+
+ vec4 values = vec4(color[0].a, color[1].a, color[2].a, color[3].a);
+
+ bool is_blank_pixel = !(FragColor.a != 0.0 || (depth == 1.0 && !doExpand));
+ vec4 tests = vec4(is_blank_pixel);
+ tests *= step(vec4(1e-6), values); /* (color.a != 0.0) */
+ tests *= (doExpand) ? vec4(1.0) : step(values, vec4(0.999)); /* (doExpand || color.a != 1.0) */
+ bvec4 btests = equal(tests, vec4(1.0));
- bool found_edge = false;
- search_outline(uv + ivec2( 1, 0), found_edge);
- search_outline(uv + ivec2( 0, 1), found_edge);
- search_outline(uv + ivec2(-1, 0), found_edge);
- search_outline(uv + ivec2( 0, -1), found_edge);
+ FragColor = (btests.x) ? color[0] : FragColor;
+ FragColor = (btests.y) ? color[1] : FragColor;
+ FragColor = (btests.z) ? color[2] : FragColor;
+ FragColor = (btests.w) ? color[3] : FragColor;
- /* We Hit something ! */
- if (found_edge) {
- /* only change alpha */
- FragColor.a *= alpha;
- }
+ FragColor *= (is_blank_pixel) ? alpha : 1.0;
}
diff --git a/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl b/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl
index a950a9b86ba..54ae319307a 100644
--- a/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl
+++ b/source/blender/draw/modes/shaders/object_particle_prim_vert.glsl
@@ -39,16 +39,18 @@ void main()
}
#ifdef USE_AXIS
- finalColor.rgb = vec3(0.0);
- finalColor[axis] = 1.0;
+ if (axis == 0)
+ finalColor = vec4(1.0, 0.0, 0.0, 1.0);
+ else if (axis == 1)
+ finalColor = vec4(0.0, 1.0, 0.0, 1.0);
+ else
+ finalColor = vec4(0.0, 0.0, 1.0, 1.0);
#else
if (val < 0.0) {
- finalColor.rgb = color;
+ finalColor = vec4(color, 1.0);
}
else {
- finalColor.rgb = texture(ramp, val).rgb;
+ finalColor = vec4(texture(ramp, val).rgb, 1.0);
}
#endif
-
- finalColor.a = 1.0;
}
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index 5b7ae216c55..9d296c03160 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -136,7 +136,7 @@ static Key *actedit_get_shapekeys(bAnimContext *ac)
Object *ob;
Key *key;
- ob = OBACT_NEW;
+ ob = OBACT_NEW(sl);
if (ob == NULL)
return NULL;
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 82aaee19029..66872c77b04 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -1788,7 +1788,9 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
NlaStrip *strip = (NlaStrip *)ptr.data;
FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
- success = insert_keyframe_direct(op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, 0);
+ if (fcu) {
+ success = insert_keyframe_direct(op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, 0);
+ }
}
else if (UI_but_flag_is_set(but, UI_BUT_DRIVEN)) {
/* Driven property - Find driver */
@@ -1893,27 +1895,27 @@ static int delete_key_button_exec(bContext *C, wmOperator *op)
NlaStrip *strip = (NlaStrip *)ptr.data;
FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), 0);
- BLI_assert(fcu != NULL); /* NOTE: This should be true, or else we wouldn't be able to get here */
-
- if (BKE_fcurve_is_protected(fcu)) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
- strip->name, BKE_idcode_to_name(GS(id->name)), id->name + 2);
- }
- else {
- /* remove the keyframe directly
- * NOTE: cannot use delete_keyframe_fcurve(), as that will free the curve,
- * and delete_keyframe() expects the FCurve to be part of an action
- */
- bool found = false;
- int i;
-
- /* try to find index of beztriple to get rid of */
- i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
- if (found) {
- /* delete the key at the index (will sanity check + do recalc afterwards) */
- delete_fcurve_key(fcu, i, 1);
- success = true;
+ if (fcu) {
+ if (BKE_fcurve_is_protected(fcu)) {
+ BKE_reportf(op->reports, RPT_WARNING,
+ "Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
+ strip->name, BKE_idcode_to_name(GS(id->name)), id->name + 2);
+ }
+ else {
+ /* remove the keyframe directly
+ * NOTE: cannot use delete_keyframe_fcurve(), as that will free the curve,
+ * and delete_keyframe() expects the FCurve to be part of an action
+ */
+ bool found = false;
+ int i;
+
+ /* try to find index of beztriple to get rid of */
+ i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
+ if (found) {
+ /* delete the key at the index (will sanity check + do recalc afterwards) */
+ delete_fcurve_key(fcu, i, 1);
+ success = true;
+ }
}
}
}
diff --git a/source/blender/editors/armature/armature_edit.c b/source/blender/editors/armature/armature_edit.c
index 47e73f9b777..67d5a038c78 100644
--- a/source/blender/editors/armature/armature_edit.c
+++ b/source/blender/editors/armature/armature_edit.c
@@ -66,7 +66,7 @@
/* ************************** Object Tools Exports ******************************* */
/* NOTE: these functions are exported to the Object module to be called from the tools there */
-void ED_armature_apply_transform(Object *ob, float mat[4][4])
+void ED_armature_apply_transform(Object *ob, float mat[4][4], const bool do_props)
{
bArmature *arm = ob->data;
@@ -74,14 +74,14 @@ void ED_armature_apply_transform(Object *ob, float mat[4][4])
ED_armature_to_edit(arm);
/* Transform the bones */
- ED_armature_transform_bones(arm, mat);
+ ED_armature_transform_bones(arm, mat, do_props);
/* Turn the list into an armature */
ED_armature_from_edit(arm);
ED_armature_edit_free(arm);
}
-void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4])
+void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const bool do_props)
{
EditBone *ebone;
float scale = mat4_to_scale(mat); /* store the scale of the matrix here to use on envelopes */
@@ -106,27 +106,29 @@ void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4])
/* apply the transformed roll back */
mat3_to_vec_roll(tmat, NULL, &ebone->roll);
- ebone->rad_head *= scale;
- ebone->rad_tail *= scale;
- ebone->dist *= scale;
-
- /* we could be smarter and scale by the matrix along the x & z axis */
- ebone->xwidth *= scale;
- ebone->zwidth *= scale;
+ if (do_props) {
+ ebone->rad_head *= scale;
+ ebone->rad_tail *= scale;
+ ebone->dist *= scale;
+
+ /* we could be smarter and scale by the matrix along the x & z axis */
+ ebone->xwidth *= scale;
+ ebone->zwidth *= scale;
+ }
}
}
-void ED_armature_transform(struct bArmature *arm, float mat[4][4])
+void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do_props)
{
if (arm->edbo) {
- ED_armature_transform_bones(arm, mat);
+ ED_armature_transform_bones(arm, mat, do_props);
}
else {
/* Put the armature into editmode */
ED_armature_to_edit(arm);
/* Transform the bones */
- ED_armature_transform_bones(arm, mat);
+ ED_armature_transform_bones(arm, mat, do_props);
/* Go back to object mode*/
ED_armature_from_edit(arm);
diff --git a/source/blender/editors/armature/armature_relations.c b/source/blender/editors/armature/armature_relations.c
index a6f63548c96..99907e9e6ae 100644
--- a/source/blender/editors/armature/armature_relations.c
+++ b/source/blender/editors/armature/armature_relations.c
@@ -383,7 +383,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
if (base->object->adt) {
if (ob->adt == NULL) {
/* no animdata, so just use a copy of the whole thing */
- ob->adt = BKE_animdata_copy(base->object->adt, false);
+ ob->adt = BKE_animdata_copy(bmain, base->object->adt, false);
}
else {
/* merge in data - we'll fix the drivers manually */
@@ -394,7 +394,7 @@ int join_armature_exec(bContext *C, wmOperator *op)
if (curarm->adt) {
if (arm->adt == NULL) {
/* no animdata, so just use a copy of the whole thing */
- arm->adt = BKE_animdata_copy(curarm->adt, false);
+ arm->adt = BKE_animdata_copy(bmain, curarm->adt, false);
}
else {
/* merge in data - we'll fix the drivers manually */
diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c
index bffa58dbf05..cbf16d38f6b 100644
--- a/source/blender/editors/armature/armature_select.c
+++ b/source/blender/editors/armature/armature_select.c
@@ -53,6 +53,8 @@
#include "ED_screen.h"
#include "ED_view3d.h"
+#include "DEG_depsgraph.h"
+
#include "armature_intern.h"
/* utility macros for storing a temp int in the bone (selection flag) */
@@ -166,18 +168,20 @@ void *get_bone_from_selectbuffer(
/* x and y are mouse coords (area space) */
void *get_nearest_bone(bContext *C, const int xy[2], bool findunsel)
{
+ EvaluationContext eval_ctx;
ViewContext vc;
rcti rect;
unsigned int buffer[MAXPICKBUF];
short hits;
-
+
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
// rect.xmin = ... mouseco!
rect.xmin = rect.xmax = xy[0];
rect.ymin = rect.ymax = xy[1];
- hits = view3d_opengl_select(C, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
+ hits = view3d_opengl_select(&eval_ctx, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
if (hits > 0)
return get_bone_from_selectbuffer(vc.scene, vc.scene_layer->basact, buffer, hits, findunsel, true);
@@ -291,7 +295,7 @@ static int selectbuffer_ret_hits_5(unsigned int *buffer, const int hits12, const
/* does bones and points */
/* note that BONE ROOT only gets drawn for root bones (or without IK) */
static EditBone *get_nearest_editbonepoint(
- const bContext *C, ViewContext *vc, const int mval[2],
+ const EvaluationContext *eval_ctx, ViewContext *vc, const int mval[2],
ListBase *edbo, bool findunsel, bool use_cycle, int *r_selmask)
{
bArmature *arm = (bArmature *)vc->obedit->data;
@@ -344,7 +348,7 @@ static EditBone *get_nearest_editbonepoint(
view3d_opengl_select_cache_begin();
BLI_rcti_init_pt_radius(&rect, mval, 12);
- hits12 = view3d_opengl_select(C, vc, buffer, MAXPICKBUF, &rect, select_mode);
+ hits12 = view3d_opengl_select(eval_ctx, vc, buffer, MAXPICKBUF, &rect, select_mode);
if (hits12 == 1) {
hits = selectbuffer_ret_hits_12(buffer, hits12);
goto cache_end;
@@ -354,7 +358,7 @@ static EditBone *get_nearest_editbonepoint(
offs = 4 * hits12;
BLI_rcti_init_pt_radius(&rect, mval, 5);
- hits5 = view3d_opengl_select(C, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
+ hits5 = view3d_opengl_select(eval_ctx, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
if (hits5 == 1) {
hits = selectbuffer_ret_hits_5(buffer, hits12, hits5);
@@ -482,17 +486,19 @@ bool ED_armature_select_pick(bContext *C, const int mval[2], bool extend, bool d
{
Object *obedit = CTX_data_edit_object(C);
bArmature *arm = obedit->data;
+ EvaluationContext eval_ctx;
ViewContext vc;
EditBone *nearBone = NULL;
int selmask;
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
-
+
if (BIF_sk_selectStroke(C, mval, extend)) {
return true;
}
- nearBone = get_nearest_editbonepoint(C, &vc, mval, arm->edbo, true, true, &selmask);
+ nearBone = get_nearest_editbonepoint(&eval_ctx, &vc, mval, arm->edbo, true, true, &selmask);
if (nearBone) {
if (!extend && !deselect && !toggle) {
diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c
index cb4d863b7b5..b96e04a8a60 100644
--- a/source/blender/editors/armature/editarmature_sketch.c
+++ b/source/blender/editors/armature/editarmature_sketch.c
@@ -50,6 +50,8 @@
#include "ED_transform.h"
#include "ED_transform_snap_object_context.h"
+#include "DEG_depsgraph.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -448,8 +450,8 @@ static void sk_drawPoint(SK_Point *pt, float size, float color[4])
gpuScaleUniform(sk_clampPointSize(pt, size));
- batch = Batch_get_sphere(0);
- Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ batch = GPU_batch_preset_sphere(0);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
GWN_batch_uniform_4fv(batch, "color", color);
GWN_batch_draw(batch);
@@ -1005,7 +1007,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S
if (ts->snap_mode == SCE_SNAP_MODE_VOLUME) {
float size;
if (peelObjectsSnapContext(
- C, snap_context, mvalf,
+ snap_context, mvalf,
&(const struct SnapObjectParams){
.snap_select = SNAP_NOT_SELECTED,
.use_object_edit_cage = false,
@@ -1045,7 +1047,7 @@ static int sk_getStrokeSnapPoint(bContext *C, SK_Point *pt, SK_Sketch *sketch, S
/* try to snap to closer object */
{
if (ED_transform_snap_object_project_view3d(
- C, snap_context,
+ snap_context,
ts->snap_mode,
&(const struct SnapObjectParams){
.snap_select = SNAP_NOT_SELECTED,
@@ -1922,16 +1924,18 @@ static void sk_applyGesture(bContext *C, SK_Sketch *sketch)
static bool sk_selectStroke(bContext *C, SK_Sketch *sketch, const int mval[2], const bool extend)
{
+ EvaluationContext eval_ctx;
ViewContext vc;
rcti rect;
unsigned int buffer[MAXPICKBUF];
short hits;
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
BLI_rcti_init_pt_radius(&rect, mval, 5);
- hits = view3d_opengl_select(C, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
+ hits = view3d_opengl_select(&eval_ctx, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
if (hits > 0) {
int besthitresult = -1;
diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c
index 0d1752e07a1..e43212c7bde 100644
--- a/source/blender/editors/armature/pose_select.c
+++ b/source/blender/editors/armature/pose_select.c
@@ -146,7 +146,7 @@ bool ED_do_pose_selectbuffer(
/* if the bone cannot be affected, don't do anything */
if ((nearBone) && !(nearBone->flag & BONE_UNSELECTABLE)) {
- Object *ob_act = OBACT_NEW;
+ Object *ob_act = OBACT_NEW(sl);
bArmature *arm = ob->data;
/* since we do unified select, we don't shift+select a bone if the
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index abbe7197d92..5064205fe41 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -5021,7 +5021,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
vc.ar, vc.v3d);
ED_transform_snap_object_project_view3d_mixed(
- C, snap_context,
+ snap_context,
SCE_SELECT_FACE,
&(const struct SnapObjectParams){
.snap_select = (vc.scene->obedit != NULL) ? SNAP_NOT_ACTIVE : SNAP_ALL,
diff --git a/source/blender/editors/curve/editcurve_paint.c b/source/blender/editors/curve/editcurve_paint.c
index 25bad71af88..f6bbff2f5d4 100644
--- a/source/blender/editors/curve/editcurve_paint.c
+++ b/source/blender/editors/curve/editcurve_paint.c
@@ -383,8 +383,8 @@ static void curve_draw_stroke_3d(const struct bContext *UNUSED(C), ARegion *UNUS
float color[3];
UI_GetThemeColor3fv(TH_WIRE, color);
- Gwn_Batch *sphere = Batch_get_sphere(0);
- Batch_set_builtin_program(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
+ Gwn_Batch *sphere = GPU_batch_preset_sphere(0);
+ GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
GWN_batch_uniform_3fv(sphere, "color", color);
/* scale to edit-mode space */
@@ -1091,10 +1091,13 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
if ((cps->depth_mode == CURVE_PAINT_PROJECT_SURFACE) &&
(v3d->drawtype > OB_WIRE))
{
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
/* needed or else the draw matrix can be incorrect */
view3d_operator_needs_opengl(C);
- ED_view3d_autodist_init(C, cdd->vc.depsgraph, cdd->vc.ar, cdd->vc.v3d, 0);
+ ED_view3d_autodist_init(&eval_ctx, cdd->vc.depsgraph, cdd->vc.ar, cdd->vc.v3d, 0);
if (cdd->vc.rv3d->depths) {
cdd->vc.rv3d->depths->damaged = true;
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index ced7cd07347..4cd628b7fd3 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -79,6 +79,8 @@
#include "ED_view3d.h"
#include "ED_space_api.h"
+#include "DEG_depsgraph.h"
+
#include "gpencil_intern.h"
/* ************************************************ */
@@ -2106,9 +2108,12 @@ static int gp_strokes_reproject_exec(bContext *C, wmOperator *op)
/* init autodist for geometry projection */
if (mode == GP_REPROJECT_SURFACE) {
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
struct Depsgraph *graph = CTX_data_depsgraph(C);
view3d_region_operator_needs_opengl(CTX_wm_window(C), gsc.ar);
- ED_view3d_autodist_init(C, graph, gsc.ar, CTX_wm_view3d(C), 0);
+ ED_view3d_autodist_init(&eval_ctx, graph, gsc.ar, CTX_wm_view3d(C), 0);
}
// TODO: For deforming geometry workflow, create new frames?
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 834a1ced69d..ffad8da84ff 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -80,6 +80,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "DEG_depsgraph.h"
+
#include "gpencil_intern.h"
/* ******************************************* */
@@ -114,6 +116,7 @@ typedef enum eGPencil_PaintFlags {
* "p" = op->customdata
*/
typedef struct tGPsdata {
+ EvaluationContext eval_ctx;
Scene *scene; /* current scene from context */
struct Depsgraph *graph;
@@ -484,7 +487,8 @@ static void gp_brush_angle(bGPdata *gpd, bGPDbrush *brush, tGPspoint *pt, const
}
/* add current stroke-point to buffer (returns whether point was successfully added) */
-static short gp_stroke_addpoint(const bContext *C, tGPsdata *p, const int mval[2], float pressure, double curtime)
+static short gp_stroke_addpoint(
+ tGPsdata *p, const int mval[2], float pressure, double curtime)
{
bGPdata *gpd = p->gpd;
bGPDbrush *brush = p->brush;
@@ -643,7 +647,7 @@ static short gp_stroke_addpoint(const bContext *C, tGPsdata *p, const int mval[2
view3d_region_operator_needs_opengl(p->win, p->ar);
ED_view3d_autodist_init(
- C, p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
+ &p->eval_ctx, p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
}
/* convert screen-coordinates to appropriate coordinates (and store them) */
@@ -679,7 +683,7 @@ static short gp_stroke_addpoint(const bContext *C, tGPsdata *p, const int mval[2
* - applies a reverse Chaikin filter
* - code adapted from etch-a-ton branch (editarmature_sketch.c)
*/
-static void gp_stroke_simplify(const bContext *C, tGPsdata *p)
+static void gp_stroke_simplify(tGPsdata *p)
{
bGPdata *gpd = p->gpd;
tGPspoint *old_points = (tGPspoint *)gpd->sbuffer;
@@ -715,7 +719,7 @@ static void gp_stroke_simplify(const bContext *C, tGPsdata *p)
} (void)0
/* XXX Here too, do not lose start and end points! */
- gp_stroke_addpoint(C, p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time);
+ gp_stroke_addpoint(p, &old_points->x, old_points->pressure, p->inittime + (double)old_points->time);
for (i = 0, j = 0; i < num_points; i++) {
if (i - j == 3) {
float co[2], pressure, time;
@@ -738,12 +742,12 @@ static void gp_stroke_simplify(const bContext *C, tGPsdata *p)
mco[1] = (int)co[1];
/* ignore return values on this... assume to be ok for now */
- gp_stroke_addpoint(C, p, mco, pressure, p->inittime + (double)time);
-
+ gp_stroke_addpoint(p, mco, pressure, p->inittime + (double)time);
+
j += 2;
}
}
- gp_stroke_addpoint(C, p, &old_points[num_points - 1].x, old_points[num_points - 1].pressure,
+ gp_stroke_addpoint(p, &old_points[num_points - 1].x, old_points[num_points - 1].pressure,
p->inittime + (double)old_points[num_points - 1].time);
/* free old buffer */
@@ -1228,7 +1232,7 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p,
}
/* erase strokes which fall under the eraser strokes */
-static void gp_stroke_doeraser(const bContext *C, tGPsdata *p)
+static void gp_stroke_doeraser(tGPsdata *p)
{
bGPDlayer *gpl;
bGPDstroke *gps, *gpn;
@@ -1244,7 +1248,7 @@ static void gp_stroke_doeraser(const bContext *C, tGPsdata *p)
if (p->flags & GP_PAINTFLAG_V3D_ERASER_DEPTH) {
View3D *v3d = p->sa->spacedata.first;
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(C, p->graph, p->ar, v3d, 0);
+ ED_view3d_autodist_init(&p->eval_ctx, p->graph, p->ar, v3d, 0);
}
}
@@ -1397,6 +1401,7 @@ static bool gp_session_initdata(bContext *C, tGPsdata *p)
}
/* pass on current scene and window */
+ CTX_data_eval_ctx(C, &p->eval_ctx);
p->scene = CTX_data_scene(C);
p->graph = CTX_data_depsgraph(C);
p->win = CTX_wm_window(C);
@@ -1800,7 +1805,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode)
}
/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */
-static void gp_paint_strokeend(const bContext *C, tGPsdata *p)
+static void gp_paint_strokeend(tGPsdata *p)
{
ToolSettings *ts = p->scene->toolsettings;
/* for surface sketching, need to set the right OpenGL context stuff so that
@@ -1811,14 +1816,14 @@ static void gp_paint_strokeend(const bContext *C, tGPsdata *p)
/* need to restore the original projection settings before packing up */
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(C, p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
+ ED_view3d_autodist_init(&p->eval_ctx, p->graph, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
}
/* check if doing eraser or not */
if ((p->gpd->sbuffer_sflag & GP_STROKE_ERASER) == 0) {
/* simplify stroke before transferring? */
- gp_stroke_simplify(C, p);
-
+ gp_stroke_simplify(p);
+
/* transfer stroke to frame */
gp_stroke_newfrombuffer(p);
}
@@ -1828,14 +1833,14 @@ static void gp_paint_strokeend(const bContext *C, tGPsdata *p)
}
/* finish off stroke painting operation */
-static void gp_paint_cleanup(const bContext *C, tGPsdata *p)
+static void gp_paint_cleanup(tGPsdata *p)
{
/* p->gpd==NULL happens when stroke failed to initialize,
* for example when GP is hidden in current space (sergey)
*/
if (p->gpd) {
/* finish off a stroke */
- gp_paint_strokeend(C, p);
+ gp_paint_strokeend(p);
}
/* "unlock" frame */
@@ -1941,7 +1946,7 @@ static void gpencil_draw_exit(bContext *C, wmOperator *op)
U.gp_eraser = p->radius;
/* cleanup */
- gp_paint_cleanup(C, p);
+ gp_paint_cleanup(p);
gp_session_cleanup(p);
/* finally, free the temp data */
@@ -2051,13 +2056,13 @@ static void gpencil_draw_status_indicators(tGPsdata *p)
/* ------------------------------- */
/* create a new stroke point at the point indicated by the painting context */
-static void gpencil_draw_apply(const bContext *C, wmOperator *op, tGPsdata *p)
+static void gpencil_draw_apply(wmOperator *op, tGPsdata *p)
{
/* handle drawing/erasing -> test for erasing first */
if (p->paintmode == GP_PAINTMODE_ERASER) {
/* do 'live' erasing now */
- gp_stroke_doeraser(C, p);
-
+ gp_stroke_doeraser(p);
+
/* store used values */
p->mvalo[0] = p->mval[0];
p->mvalo[1] = p->mval[1];
@@ -2066,12 +2071,12 @@ static void gpencil_draw_apply(const bContext *C, wmOperator *op, tGPsdata *p)
/* only add current point to buffer if mouse moved (even though we got an event, it might be just noise) */
else if (gp_stroke_filtermval(p, p->mval, p->mvalo)) {
/* try to add point */
- short ok = gp_stroke_addpoint(C, p, p->mval, p->pressure, p->curtime);
-
+ short ok = gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
+
/* handle errors while adding point */
if ((ok == GP_STROKEADD_FULL) || (ok == GP_STROKEADD_OVERFLOW)) {
/* finish off old stroke */
- gp_paint_strokeend(C, p);
+ gp_paint_strokeend(p);
/* And start a new one!!! Else, projection errors! */
gp_paint_initstroke(p, p->paintmode);
@@ -2080,12 +2085,12 @@ static void gpencil_draw_apply(const bContext *C, wmOperator *op, tGPsdata *p)
/* XXX We only need to reuse previous point if overflow! */
if (ok == GP_STROKEADD_OVERFLOW) {
p->inittime = p->ocurtime;
- gp_stroke_addpoint(C, p, p->mvalo, p->opressure, p->ocurtime);
+ gp_stroke_addpoint(p, p->mvalo, p->opressure, p->ocurtime);
}
else {
p->inittime = p->curtime;
}
- gp_stroke_addpoint(C, p, p->mval, p->pressure, p->curtime);
+ gp_stroke_addpoint(p, p->mval, p->pressure, p->curtime);
}
else if (ok == GP_STROKEADD_INVALID) {
/* the painting operation cannot continue... */
@@ -2106,7 +2111,7 @@ static void gpencil_draw_apply(const bContext *C, wmOperator *op, tGPsdata *p)
}
/* handle draw event */
-static void gpencil_draw_apply_event(const bContext *C, wmOperator *op, const wmEvent *event)
+static void gpencil_draw_apply_event(wmOperator *op, const wmEvent *event)
{
tGPsdata *p = op->customdata;
PointerRNA itemptr;
@@ -2211,8 +2216,8 @@ static void gpencil_draw_apply_event(const bContext *C, wmOperator *op, const wm
RNA_float_set(&itemptr, "time", p->curtime - p->inittime);
/* apply the current latest drawing point */
- gpencil_draw_apply(C, op, p);
-
+ gpencil_draw_apply(op, p);
+
/* force refresh */
ED_region_tag_redraw(p->ar); /* just active area for now, since doing whole screen is too slow */
}
@@ -2259,7 +2264,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
*/
if ((p->flags & GP_PAINTFLAG_FIRSTRUN) == 0) {
/* TODO: both of these ops can set error-status, but we probably don't need to worry */
- gp_paint_strokeend(C, p);
+ gp_paint_strokeend(p);
gp_paint_initstroke(p, p->paintmode);
}
}
@@ -2275,7 +2280,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
}
/* apply this data as necessary now (as per usual) */
- gpencil_draw_apply(C, op, p);
+ gpencil_draw_apply(op, p);
}
RNA_END;
@@ -2334,7 +2339,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
p->status = GP_STATUS_PAINTING;
/* handle the initial drawing - i.e. for just doing a simple dot */
- gpencil_draw_apply_event(C, op, event);
+ gpencil_draw_apply_event(op, event);
op->flag |= OP_IS_MODAL_CURSOR_REGION;
}
else {
@@ -2385,12 +2390,12 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op)
return op->customdata;
}
-static void gpencil_stroke_end(bContext *C, wmOperator *op)
+static void gpencil_stroke_end(wmOperator *op)
{
tGPsdata *p = op->customdata;
-
- gp_paint_cleanup(C, p);
-
+
+ gp_paint_cleanup(p);
+
gpencil_undo_push(p->gpd);
gp_session_cleanup(p);
@@ -2523,8 +2528,8 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (sketch) {
/* end stroke only, and then wait to resume painting soon */
/* printf("\t\tGP - end stroke only\n"); */
- gpencil_stroke_end(C, op);
-
+ gpencil_stroke_end(op);
+
/* If eraser mode is on, turn it off after the stroke finishes
* NOTE: This just makes it nicer to work with drawing sessions
*/
@@ -2666,8 +2671,8 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) || (p->flags & GP_PAINTFLAG_FIRSTRUN)) {
/* handle drawing event */
/* printf("\t\tGP - add point\n"); */
- gpencil_draw_apply_event(C, op, event);
-
+ gpencil_draw_apply_event(op, event);
+
/* finish painting operation if anything went wrong just now */
if (p->status == GP_STATUS_ERROR) {
printf("\t\t\t\tGP - add error done!\n");
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 07fac0fdfac..fae08bd771e 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -65,6 +65,8 @@
#include "ED_clip.h"
#include "ED_view3d.h"
+#include "DEG_depsgraph.h"
+
#include "gpencil_intern.h"
/* ******************************************************** */
@@ -538,11 +540,14 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
View3D *v3d = (View3D *)CTX_wm_space_data(C);
RegionView3D *rv3d = ar->regiondata;
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
/* init 3d depth buffers */
view3d_operator_needs_opengl(C);
view3d_region_operator_needs_opengl(win, ar);
- ED_view3d_autodist_init(C, graph, ar, v3d, 0);
+ ED_view3d_autodist_init(&eval_ctx, graph, ar, v3d, 0);
/* for camera view set the subrect */
if (rv3d->persp == RV3D_CAMOB) {
diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h
index 7066095a93a..bbc6e8912c3 100644
--- a/source/blender/editors/include/ED_armature.h
+++ b/source/blender/editors/include/ED_armature.h
@@ -166,9 +166,9 @@ void ED_armature_ebone_from_mat4(EditBone *ebone, float mat[4][4]);
void transform_armature_mirror_update(struct Object *obedit);
void ED_armature_origin_set(struct Scene *scene, struct Object *ob, float cursor[3], int centermode, int around);
-void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4]);
-void ED_armature_apply_transform(struct Object *ob, float mat[4][4]);
-void ED_armature_transform(struct bArmature *arm, float mat[4][4]);
+void ED_armature_transform_bones(struct bArmature *arm, float mat[4][4], const bool do_props);
+void ED_armature_apply_transform(struct Object *ob, float mat[4][4], const bool do_props);
+void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do_props);
#define ARM_GROUPS_NAME 1
#define ARM_GROUPS_ENVELOPE 2
diff --git a/source/blender/editors/include/ED_manipulator_library.h b/source/blender/editors/include/ED_manipulator_library.h
index b8981acf1da..84e8f7d14c7 100644
--- a/source/blender/editors/include/ED_manipulator_library.h
+++ b/source/blender/editors/include/ED_manipulator_library.h
@@ -114,11 +114,14 @@ enum {
/* draw_options */
enum {
ED_MANIPULATOR_GRAB_DRAW_FLAG_NOP = 0,
+ /* only for solid shapes */
ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL = (1 << 0),
+ ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW = (1 << 1),
};
enum {
- ED_MANIPULATOR_GRAB_STYLE_RING = 0,
+ ED_MANIPULATOR_GRAB_STYLE_RING_2D = 0,
+ ED_MANIPULATOR_GRAB_STYLE_CROSS_2D = 1,
};
diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h
index c3186f7afdf..52edfc22d21 100644
--- a/source/blender/editors/include/ED_mesh.h
+++ b/source/blender/editors/include/ED_mesh.h
@@ -36,6 +36,7 @@ extern "C" {
#endif
struct ID;
+struct EvaluationContext;
struct View3D;
struct ARegion;
struct bContext;
@@ -134,35 +135,36 @@ void EDBM_select_mirrored(
int *r_totmirr, int *r_totfail);
void EDBM_automerge(struct Scene *scene, struct Object *ob, bool update, const char hflag);
-bool EDBM_backbuf_border_init(const struct bContext *C, struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax);
+bool EDBM_backbuf_border_init(const struct EvaluationContext *eval_ctx, struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax);
bool EDBM_backbuf_check(unsigned int index);
void EDBM_backbuf_free(void);
-bool EDBM_backbuf_border_mask_init(const struct bContext *C, struct ViewContext *vc, const int mcords[][2], short tot,
- short xmin, short ymin, short xmax, short ymax);
-bool EDBM_backbuf_circle_init(const struct bContext *C, struct ViewContext *vc, short xs, short ys, short rads);
+bool EDBM_backbuf_border_mask_init(
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, const int mcords[][2], short tot,
+ short xmin, short ymin, short xmax, short ymax);
+bool EDBM_backbuf_circle_init(const struct EvaluationContext *eval_ctx, struct ViewContext *vc, short xs, short ys, short rads);
struct BMVert *EDBM_vert_find_nearest_ex(
- const struct bContext *C, struct ViewContext *vc, float *r_dist,
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, float *r_dist,
const bool use_select_bias, bool use_cycle);
struct BMVert *EDBM_vert_find_nearest(
- const struct bContext *C, struct ViewContext *vc, float *r_dist);
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, float *r_dist);
struct BMEdge *EDBM_edge_find_nearest_ex(
- const struct bContext *C, struct ViewContext *vc, float *r_dist,
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, float *r_dist,
float *r_dist_center,
const bool use_select_bias, const bool use_cycle,
struct BMEdge **r_eed_zbuf);
struct BMEdge *EDBM_edge_find_nearest(
- const struct bContext *C, struct ViewContext *vc, float *r_dist);
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, float *r_dist);
struct BMFace *EDBM_face_find_nearest_ex(
- const struct bContext *C, struct ViewContext *vc, float *r_dist,
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, float *r_dist,
float *r_dist_center,
const bool use_select_bias, const bool use_cycle,
struct BMFace **r_efa_zbuf);
struct BMFace *EDBM_face_find_nearest(
- const struct bContext *C, struct ViewContext *vc, float *r_dist);
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, float *r_dist);
bool EDBM_select_pick(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
@@ -199,7 +201,7 @@ void EMBM_project_snap_verts(struct bContext *C, struct ARegion *ar, struct BMEd
/* editface.c */
void paintface_flush_flags(struct Object *ob, short flag);
bool paintface_mouse_select(struct bContext *C, struct Object *ob, const int mval[2], bool extend, bool deselect, bool toggle);
-int do_paintface_box_select(const struct bContext *C, struct ViewContext *vc, struct rcti *rect, bool select, bool extend);
+int do_paintface_box_select(const struct EvaluationContext *eval_ctx, struct ViewContext *vc, struct rcti *rect, bool select, bool extend);
void paintface_deselect_all_visible(struct Object *ob, int action, bool flush_flags);
void paintface_select_linked(struct bContext *C, struct Object *ob, const int mval[2], const bool select);
bool paintface_minmax(struct Object *ob, float r_min[3], float r_max[3]);
diff --git a/source/blender/editors/include/ED_particle.h b/source/blender/editors/include/ED_particle.h
index 7bce95182bf..f8bd8a22897 100644
--- a/source/blender/editors/include/ED_particle.h
+++ b/source/blender/editors/include/ED_particle.h
@@ -46,15 +46,16 @@ int PE_start_edit(struct PTCacheEdit *edit);
/* access */
struct PTCacheEdit *PE_get_current(struct Scene *scene, struct SceneLayer *sl, struct Object *ob);
-struct PTCacheEdit *PE_create_current(const struct bContext *C, struct Scene *scene, struct Object *ob);
-void PE_current_changed(const struct bContext *C, struct Scene *scene, struct Object *ob);
+struct PTCacheEdit *PE_create_current(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
+void PE_current_changed(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob);
int PE_minmax(struct Scene *scene, struct SceneLayer *sl, float min[3], float max[3]);
struct ParticleEditSettings *PE_settings(struct Scene *scene);
/* update calls */
void PE_hide_keys_time(struct Scene *scene, struct PTCacheEdit *edit, float cfra);
-void PE_update_object(const struct bContext *C, struct Scene *scene,
- struct SceneLayer *sl, struct Object *ob, int useflag);
+void PE_update_object(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene,
+ struct SceneLayer *sl, struct Object *ob, int useflag);
/* selection tools */
int PE_mouse_particles(struct bContext *C, const int mval[2], bool extend, bool deselect, bool toggle);
diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h
index 39dd6024022..84d1edd23ec 100644
--- a/source/blender/editors/include/ED_transform.h
+++ b/source/blender/editors/include/ED_transform.h
@@ -167,12 +167,6 @@ void ED_widgetgroup_manipulator2d_draw_prepare(const struct bContext *C, struct
/* Snapping */
-typedef enum SnapSelect {
- SNAP_ALL = 0,
- SNAP_NOT_SELECTED = 1,
- SNAP_NOT_ACTIVE = 2,
-} SnapSelect;
-
#define SNAP_MIN_DISTANCE 30
bool peelObjectsTransform(
@@ -182,7 +176,7 @@ bool peelObjectsTransform(
/* return args */
float r_loc[3], float r_no[3], float *r_thickness);
bool peelObjectsSnapContext(
- const struct bContext *C, struct SnapObjectContext *sctx,
+ struct SnapObjectContext *sctx,
const float mval[2],
const struct SnapObjectParams *params,
const bool use_peel_object,
@@ -195,11 +189,7 @@ bool snapObjectsTransform(
/* return args */
float r_loc[3], float r_no[3]);
bool snapNodesTransform(
- struct TransInfo *t, const int mval[2], SnapSelect snap_select,
- /* return args */
- float r_loc[2], float *r_dist_px, char *r_node_border);
-bool snapNodesContext(
- struct bContext *C, const int mval[2], SnapSelect snap_select,
+ struct TransInfo *t, const int mval[2],
/* return args */
float r_loc[2], float *r_dist_px, char *r_node_border);
diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h
index 4f93c35b8d6..b802694444b 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -42,6 +42,12 @@ struct bContext;
/* ED_transform_snap_object_*** API */
+typedef enum SnapSelect {
+ SNAP_ALL = 0,
+ SNAP_NOT_SELECTED = 1,
+ SNAP_NOT_ACTIVE = 2,
+} SnapSelect;
+
/** used for storing multiple hits */
struct SnapObjectHitDepth {
struct SnapObjectHitDepth *next, *prev;
@@ -85,34 +91,34 @@ void ED_transform_snap_object_context_set_editmesh_callbacks(
void *user_data);
bool ED_transform_snap_object_project_ray_ex(
- const struct bContext *C, struct SnapObjectContext *sctx,
+ struct SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3], float *ray_depth,
/* return args */
float r_loc[3], float r_no[3], int *r_index,
struct Object **r_ob, float r_obmat[4][4]);
bool ED_transform_snap_object_project_ray(
- const struct bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float ray_origin[3], const float ray_direction[3], float *ray_depth,
float r_co[3], float r_no[3]);
bool ED_transform_snap_object_project_ray_all(
- const struct bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3],
float ray_depth, bool sort,
struct ListBase *r_hit_list);
bool ED_transform_snap_object_project_view3d_ex(
- const struct bContext *C, struct SnapObjectContext *sctx,
+ struct SnapObjectContext *sctx,
const unsigned short snap_to,
const struct SnapObjectParams *params,
const float mval[2], float *dist_px,
float *ray_depth,
float r_loc[3], float r_no[3], int *r_index);
bool ED_transform_snap_object_project_view3d(
- const struct bContext *C, struct SnapObjectContext *sctx,
+ struct SnapObjectContext *sctx,
const unsigned short snap_to,
const struct SnapObjectParams *params,
const float mval[2], float *dist_px,
@@ -120,7 +126,7 @@ bool ED_transform_snap_object_project_view3d(
/* return args */
float r_loc[3], float r_no[3]);
bool ED_transform_snap_object_project_view3d_mixed(
- const struct bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const unsigned short snap_to_flag,
const struct SnapObjectParams *params,
const float mval_fl[2], float *dist_px,
@@ -128,7 +134,7 @@ bool ED_transform_snap_object_project_view3d_mixed(
float r_co[3], float r_no[3]);
bool ED_transform_snap_object_project_all_view3d_ex(
- const struct bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float mval[2],
float ray_depth, bool sort,
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 4b7eaa4f3d4..0dcfd68c0f1 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -152,20 +152,20 @@ typedef enum {
/* foreach iterators */
void meshobject_foreachScreenVert(
- const struct bContext *C, struct ViewContext *vc,
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc,
void (*func)(void *userData, struct MVert *eve, const float screen_co[2], int index),
void *userData, const eV3DProjTest clip_flag);
void mesh_foreachScreenVert(
- const struct bContext *C, struct ViewContext *vc,
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc,
void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index),
void *userData, const eV3DProjTest clip_flag);
void mesh_foreachScreenEdge(
- const struct bContext *C, struct ViewContext *vc,
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc,
void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2],
int index),
void *userData, const eV3DProjTest clip_flag);
void mesh_foreachScreenFace(
- const struct bContext *C, struct ViewContext *vc,
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc,
void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index),
void *userData, const eV3DProjTest clip_flag);
void nurbs_foreachScreenVert(
@@ -295,21 +295,23 @@ float ED_view3d_radius_to_dist(
void imm_drawcircball(const float cent[3], float rad, const float tmat[4][4], unsigned pos);
/* backbuffer select and draw support */
-void ED_view3d_backbuf_validate(const struct bContext *C, struct ViewContext *vc);
-struct ImBuf *ED_view3d_backbuf_read(const struct bContext *C, struct ViewContext *vc, int xmin, int ymin, int xmax, int ymax);
+void ED_view3d_backbuf_validate(const struct EvaluationContext *eval_ctx, struct ViewContext *vc);
+struct ImBuf *ED_view3d_backbuf_read(
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, int xmin, int ymin, int xmax, int ymax);
unsigned int ED_view3d_backbuf_sample_rect(
- const struct bContext *C, struct ViewContext *vc, const int mval[2], int size,
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, const int mval[2], int size,
unsigned int min, unsigned int max, float *r_dist);
int ED_view3d_backbuf_sample_size_clamp(struct ARegion *ar, const float dist);
-unsigned int ED_view3d_backbuf_sample(const struct bContext *C, struct ViewContext *vc, int x, int y);
+unsigned int ED_view3d_backbuf_sample(
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, int x, int y);
bool ED_view3d_autodist(
- const struct bContext *C, struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d,
+ const struct EvaluationContext *eval_ctx, struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d,
const int mval[2], float mouse_worldloc[3],
const bool alphaoverride, const float fallback_depth_pt[3]);
/* only draw so ED_view3d_autodist_simple can be called many times after */
-void ED_view3d_autodist_init(const struct bContext *C, struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d, int mode);
+void ED_view3d_autodist_init(const struct EvaluationContext *eval_ctx, struct Depsgraph *graph, struct ARegion *ar, struct View3D *v3d, int mode);
bool ED_view3d_autodist_simple(struct ARegion *ar, const int mval[2], float mouse_worldloc[3], int margin, float *force_depth);
bool ED_view3d_autodist_depth(struct ARegion *ar, const int mval[2], int margin, float *depth);
bool ED_view3d_autodist_depth_seg(struct ARegion *ar, const int mval_sta[2], const int mval_end[2], int margin, float *depth);
@@ -331,7 +333,7 @@ void view3d_opengl_select_cache_begin(void);
void view3d_opengl_select_cache_end(void);
int view3d_opengl_select(
- const struct bContext *C, struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const struct rcti *input,
+ const struct EvaluationContext *eval_ctx, struct ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const struct rcti *input,
eV3DSelectMode select_mode);
/* view3d_select.c */
@@ -363,26 +365,27 @@ int ED_view3d_scene_layer_set(int lay, const int *values, int *active);
struct RV3DMatrixStore *ED_view3d_mats_rv3d_backup(struct RegionView3D *rv3d);
void ED_view3d_mats_rv3d_restore(struct RegionView3D *rv3d, struct RV3DMatrixStore *rv3dmat);
-void ED_draw_object_facemap(const struct bContext *C, struct Scene *scene, struct Object *ob, const float col[4], const int facemap);
+void ED_draw_object_facemap(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, const float col[4], const int facemap);
bool ED_view3d_context_activate(struct bContext *C);
-void ED_view3d_draw_offscreen_init(struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d);
+void ED_view3d_draw_offscreen_init(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d);
void ED_view3d_draw_offscreen(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4],
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar, int winx, int winy, float viewmat[4][4],
float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
struct GPUFX *fx, struct GPUFXSettings *fx_settings,
struct GPUOffScreen *ofs);
void ED_view3d_draw_setup_view(
- struct wmWindow *win, const struct bContext *C, struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
+ struct wmWindow *win, const struct EvaluationContext *eval_ctx, struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
float viewmat[4][4], float winmat[4][4], const struct rcti *rect);
struct ImBuf *ED_view3d_draw_offscreen_imbuf(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct View3D *v3d, struct ARegion *ar,
int sizex, int sizey, unsigned int flag, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]);
struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct Object *camera, int width, int height,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct SceneLayer *sl, struct Object *camera, int width, int height,
unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
struct GPUFX *fx, struct GPUOffScreen *ofs, char err_out[256]);
@@ -390,7 +393,7 @@ struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
struct BaseLegacy *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip);
void ED_view3d_update_viewmat(
- struct EvaluationContext *eval_ctx, struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
float viewmat[4][4], float winmat[4][4], const struct rcti *rect);
bool ED_view3d_quat_from_axis_view(const char view, float quat[4]);
char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon);
diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h
index ac657a4ac73..7d2837ffe4e 100644
--- a/source/blender/editors/include/UI_resources.h
+++ b/source/blender/editors/include/UI_resources.h
@@ -279,6 +279,12 @@ enum {
TH_AXIS_Y,
TH_AXIS_Z,
+ TH_MANIPULATOR_HI,
+ TH_MANIPULATOR_PRIMARY,
+ TH_MANIPULATOR_SECONDARY,
+ TH_MANIPULATOR_A,
+ TH_MANIPULATOR_B,
+
TH_LOW_GRAD,
TH_HIGH_GRAD,
TH_SHOW_BACK_GRAD,
@@ -303,7 +309,6 @@ enum {
TH_EDGE_BEVEL,
TH_VERTEX_BEVEL
};
-/* XXX WARNING: previous is saved in file, so do not change order! */
/* specific defines per space should have higher define values */
diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c
index 89400bd24a3..bdedb265d73 100644
--- a/source/blender/editors/interface/interface_draw.c
+++ b/source/blender/editors/interface/interface_draw.c
@@ -771,12 +771,12 @@ static void waveform_draw_one(float *waveform, int nbr, const float col[3])
GWN_vertbuf_attr_fill(vbo, pos_id, waveform);
/* TODO store the Gwn_Batch inside the scope */
- Gwn_Batch *batch = GWN_batch_create(GWN_PRIM_POINTS, vbo, NULL);
- Batch_set_builtin_program(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+ Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
GWN_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
GWN_batch_draw(batch);
- GWN_batch_discard_all(batch);
+ GWN_batch_discard(batch);
}
void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), const rcti *recti)
@@ -1443,8 +1443,8 @@ void ui_draw_but_UNITVEC(uiBut *but, uiWidgetColors *wcol, const rcti *rect)
gpuTranslate2f(rect->xmin + 0.5f * BLI_rcti_size_x(rect), rect->ymin + 0.5f * BLI_rcti_size_y(rect));
gpuScaleUniform(size);
- Gwn_Batch *sphere = Batch_get_sphere(2);
- Batch_set_builtin_program(sphere, GPU_SHADER_SIMPLE_LIGHTING);
+ Gwn_Batch *sphere = GPU_batch_preset_sphere(2);
+ GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING);
GWN_batch_uniform_4f(sphere, "color", diffuse[0], diffuse[1], diffuse[2], 1.0f);
GWN_batch_uniform_3fv(sphere, "light", light);
GWN_batch_draw(sphere);
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 40c6058c7c3..2695d4c9dd9 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -913,6 +913,9 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx,
my - ar->winrct.ymin};
float co[3];
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
CTX_wm_area_set(C, sa);
CTX_wm_region_set(C, ar);
@@ -921,7 +924,7 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx,
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(C, graph, ar, v3d, mval, co, true, NULL)) {
+ if (ED_view3d_autodist(&eval_ctx, graph, ar, v3d, mval, co, true, NULL)) {
const float mval_center_fl[2] = {
(float)ar->winx / 2,
(float)ar->winy / 2};
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 278cd511abb..4b4235528ad 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -6793,8 +6793,8 @@ static bool ui_but_menu(bContext *C, uiBut *but)
/* set the prop and pointer data for python access to the hovered ui element; TODO, index could be supported as well*/
PointerRNA temp_ptr;
RNA_pointer_create(NULL, &RNA_Property, but->rnaprop, &temp_ptr);
- uiLayoutSetContextPointer(layout,"button_prop", &temp_ptr);
- uiLayoutSetContextPointer(layout,"button_pointer", ptr);
+ uiLayoutSetContextPointer(layout, "button_prop", &temp_ptr);
+ uiLayoutSetContextPointer(layout, "button_pointer", ptr);
/* second slower test, saved people finding keyframe items in menus when its not possible */
if (is_anim)
@@ -7013,8 +7013,9 @@ static bool ui_but_menu(bContext *C, uiBut *but)
}
/* Set the operator pointer for python access */
- if (but->opptr)
- uiLayoutSetContextPointer(layout,"button_operator", but->opptr);
+ if (but->opptr) {
+ uiLayoutSetContextPointer(layout, "button_operator", but->opptr);
+ }
uiItemS(layout);
}
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 3c26798f886..393692e51c1 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -247,7 +247,9 @@ static int ui_text_icon_width(uiLayout *layout, const char *name, int icon, bool
variable = (ui_layout_vary_direction(layout) == UI_ITEM_VARY_X);
if (variable) {
- layout->item.flag |= UI_ITEM_MIN;
+ if (layout->alignment != UI_LAYOUT_ALIGN_EXPAND) {
+ layout->item.flag |= UI_ITEM_MIN;
+ }
const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
/* it may seem odd that the icon only adds (UI_UNIT_X / 4)
* but taking margins into account its fine */
@@ -2387,7 +2389,6 @@ static void ui_litem_estimate_box(uiLayout *litem)
uiStyle *style = litem->root->style;
ui_litem_estimate_column(litem, true);
- litem->item.flag &= ~UI_ITEM_MIN;
litem->w += 2 * style->boxspace;
litem->h += 2 * style->boxspace;
}
@@ -3059,8 +3060,11 @@ static void ui_item_estimate(uiItem *item)
for (subitem = litem->items.first; subitem; subitem = subitem->next)
ui_item_estimate(subitem);
- if (BLI_listbase_is_empty(&litem->items))
+ if (BLI_listbase_is_empty(&litem->items)) {
+ litem->w = 0;
+ litem->h = 0;
return;
+ }
if (litem->scale[0] != 0.0f || litem->scale[1] != 0.0f)
ui_item_scale(litem, litem->scale);
@@ -3324,8 +3328,9 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
ui_item_size((uiItem *)bitem, &w, &h);
/* XXX uiBut hasn't scaled yet
* we can flag the button as not expandable, depending on its size */
- if (w <= 2 * UI_UNIT_X)
+ if (w <= 2 * UI_UNIT_X && (!but->str || but->str[0] == '\0')) {
bitem->item.flag |= UI_ITEM_MIN;
+ }
BLI_addtail(&layout->items, bitem);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 274429d5390..bf42316289f 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -667,6 +667,17 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo
case TH_AXIS_Z:
cp = btheme->tui.zaxis; break;
+ case TH_MANIPULATOR_HI:
+ cp = btheme->tui.manipulator_hi; break;
+ case TH_MANIPULATOR_PRIMARY:
+ cp = btheme->tui.manipulator_primary; break;
+ case TH_MANIPULATOR_SECONDARY:
+ cp = btheme->tui.manipulator_secondary; break;
+ case TH_MANIPULATOR_A:
+ cp = btheme->tui.manipulator_a; break;
+ case TH_MANIPULATOR_B:
+ cp = btheme->tui.manipulator_b; break;
+
case TH_INFO_SELECTED:
cp = ts->info_selected;
break;
@@ -837,6 +848,15 @@ static void ui_theme_space_init_handles_color(ThemeSpace *theme_space)
rgba_char_args_set(theme_space->act_spline, 0xdb, 0x25, 0x12, 255);
}
+static void ui_theme_space_init_manipulator_colors(bTheme *btheme)
+{
+ rgba_char_args_set(btheme->tui.manipulator_hi, 255, 255, 255, 255);
+ rgba_char_args_set(btheme->tui.manipulator_primary, 222, 255, 13, 255);
+ rgba_char_args_set(btheme->tui.manipulator_secondary, 0, 255, 255, 255);
+ rgba_char_args_set(btheme->tui.manipulator_a, 23, 127, 23, 255);
+ rgba_char_args_set(btheme->tui.manipulator_b, 127, 23, 23, 255);
+}
+
/**
* initialize default theme
* \note: when you add new colors, created & saved themes need initialized
@@ -877,6 +897,9 @@ void ui_theme_init_default(void)
/* common (new) variables */
ui_theme_init_new(btheme);
+ /* Manipulator. */
+ ui_theme_space_init_manipulator_colors(btheme);
+
/* space view3d */
rgba_char_args_set_fl(btheme->tv3d.back, 0.225, 0.225, 0.225, 1.0);
rgba_char_args_set(btheme->tv3d.text, 0, 0, 0, 255);
@@ -2892,6 +2915,25 @@ void init_userdef_do_versions(void)
btheme->ttime.time_keyframe[3] = btheme->ttime.time_gp_keyframe[3] = 255;
}
}
+
+ if (!USER_VERSION_ATLEAST(278, 6)) {
+ /* Clear preference flags for re-use. */
+ U.flag &= ~(
+ USER_FLAG_DEPRECATED_1 | USER_FLAG_DEPRECATED_2 | USER_FLAG_DEPRECATED_3 |
+ USER_FLAG_DEPRECATED_6 | USER_FLAG_DEPRECATED_7 |
+ USER_FLAG_DEPRECATED_9 | USER_FLAG_DEPRECATED_10);
+ U.uiflag &= ~(
+ USER_UIFLAG_DEPRECATED_7);
+ U.transopts &= ~(
+ USER_TR_DEPRECATED_2 | USER_TR_DEPRECATED_3 | USER_TR_DEPRECATED_4 |
+ USER_TR_DEPRECATED_6 | USER_TR_DEPRECATED_7);
+ U.gameflags &= ~(
+ USER_GL_RENDER_DEPRECATED_0 | USER_GL_RENDER_DEPRECATED_1 |
+ USER_GL_RENDER_DEPRECATED_3 | USER_GL_RENDER_DEPRECATED_4);
+
+ U.uiflag |= USER_LOCK_CURSOR_ADJUST;
+ }
+
if (!USER_VERSION_ATLEAST(280, 1)) {
/* interface_widgets.c */
struct uiWidgetColors wcol_tab = {
@@ -2912,31 +2954,15 @@ void init_userdef_do_versions(void)
}
}
- if (!USER_VERSION_ATLEAST(278, 6)) {
- /* Clear preference flags for re-use. */
- U.flag &= ~(
- USER_FLAG_DEPRECATED_1 | USER_FLAG_DEPRECATED_2 | USER_FLAG_DEPRECATED_3 |
- USER_FLAG_DEPRECATED_6 | USER_FLAG_DEPRECATED_7 |
- USER_FLAG_DEPRECATED_9 | USER_FLAG_DEPRECATED_10);
- U.uiflag &= ~(
- USER_UIFLAG_DEPRECATED_7);
- U.transopts &= ~(
- USER_TR_DEPRECATED_2 | USER_TR_DEPRECATED_3 | USER_TR_DEPRECATED_4 |
- USER_TR_DEPRECATED_6 | USER_TR_DEPRECATED_7);
- U.gameflags &= ~(
- USER_GL_RENDER_DEPRECATED_0 | USER_GL_RENDER_DEPRECATED_1 |
- USER_GL_RENDER_DEPRECATED_3 | USER_GL_RENDER_DEPRECATED_4);
-
- U.uiflag |= USER_LOCK_CURSOR_ADJUST;
- }
-
/**
* Include next version bump.
*
* (keep this block even if it becomes empty).
*/
- {
-
+ if (((bTheme *)U.themes.first)->tui.manipulator_hi[3] == 0) {
+ for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
+ ui_theme_space_init_manipulator_colors(btheme);
+ }
}
if (U.pixelsize == 0.0f)
@@ -2945,11 +2971,8 @@ void init_userdef_do_versions(void)
if (U.image_draw_method == 0)
U.image_draw_method = IMAGE_DRAW_METHOD_2DTEXTURE;
- // keep the following until the new audaspace is default to be built with
-#ifdef WITH_SYSTEM_AUDASPACE
// we default to the first audio device
U.audiodevice = 0;
-#endif
/* funny name, but it is GE stuff, moves userdef stuff to engine */
// XXX space_set_commmandline_options();
diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c
index a5e90ebbe7a..975bbddd893 100644
--- a/source/blender/editors/io/io_cache.c
+++ b/source/blender/editors/io/io_cache.c
@@ -93,7 +93,7 @@ static int cachefile_open_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
- CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, BLI_path_basename(filename));
+ CacheFile *cache_file = BKE_libblock_alloc(bmain, ID_CF, BLI_path_basename(filename), 0);
BLI_strncpy(cache_file->filepath, filename, FILE_MAX);
BKE_cachefile_reload(bmain, cache_file);
diff --git a/source/blender/editors/manipulator_library/manipulator_draw_utils.c b/source/blender/editors/manipulator_library/manipulator_draw_utils.c
index 26f9ebbe54e..f15cd9c9793 100644
--- a/source/blender/editors/manipulator_library/manipulator_draw_utils.c
+++ b/source/blender/editors/manipulator_library/manipulator_draw_utils.c
@@ -95,8 +95,8 @@ void wm_manipulator_geometryinfo_draw(const ManipulatorGeomInfo *info, const boo
GWN_vertbuf_attr_fill(vbo, nor_id, info->normals);
}
- batch = GWN_batch_create(GWN_PRIM_TRIS, vbo, el);
- Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ batch = GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, el, GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
GWN_batch_uniform_4fv(batch, "color", color);
@@ -115,7 +115,7 @@ void wm_manipulator_geometryinfo_draw(const ManipulatorGeomInfo *info, const boo
#endif
- GWN_batch_discard_all(batch);
+ GWN_batch_discard(batch);
}
void wm_manipulator_vec_draw(
diff --git a/source/blender/editors/manipulator_library/manipulator_library_intern.h b/source/blender/editors/manipulator_library/manipulator_library_intern.h
index a22afda8730..92ca195f21d 100644
--- a/source/blender/editors/manipulator_library/manipulator_library_intern.h
+++ b/source/blender/editors/manipulator_library/manipulator_library_intern.h
@@ -50,10 +50,10 @@ typedef struct ManipulatorCommonData {
typedef struct ManipulatorInteraction {
float init_value; /* initial property value */
- float init_matrix[4][4];
float init_mval[2];
float init_offset;
- float init_scale;
+ float init_matrix_final[4][4];
+ float init_matrix_basis[4][4];
/* offset of last handling step */
float prev_offset;
diff --git a/source/blender/editors/manipulator_library/manipulator_library_presets.c b/source/blender/editors/manipulator_library/manipulator_library_presets.c
index e8111bda657..e552a7a6aa3 100644
--- a/source/blender/editors/manipulator_library/manipulator_library_presets.c
+++ b/source/blender/editors/manipulator_library/manipulator_library_presets.c
@@ -46,6 +46,7 @@
#include "MEM_guardedalloc.h"
+#include "DEG_depsgraph.h"
#include "RNA_access.h"
@@ -139,9 +140,12 @@ void ED_manipulator_draw_preset_facemap(
GPU_select_load_id(select_id);
}
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
gpuPushMatrix();
gpuMultMatrix(ob->obmat);
- ED_draw_object_facemap(C, scene, ob, color, facemap);
+ ED_draw_object_facemap(&eval_ctx, scene, ob, color, facemap);
gpuPopMatrix();
if (is_select) {
diff --git a/source/blender/editors/manipulator_library/manipulator_library_utils.c b/source/blender/editors/manipulator_library/manipulator_library_utils.c
index 58999a82bba..d807ee07917 100644
--- a/source/blender/editors/manipulator_library/manipulator_library_utils.c
+++ b/source/blender/editors/manipulator_library/manipulator_library_utils.c
@@ -173,11 +173,23 @@ bool manipulator_window_project_2d(
float r_co[2])
{
float mat[4][4];
- if (use_offset) {
- mul_m4_series(mat, mpr->matrix_space, mpr->matrix_basis, mpr->matrix_offset);
- }
- else {
- mul_m4_series(mat, mpr->matrix_space, mpr->matrix_basis);
+ {
+ float matrix_basis_buf[4][4];
+ const void *matrix_basis;
+ if (mpr->type->matrix_basis_get) {
+ mpr->type->matrix_basis_get(mpr, matrix_basis_buf);
+ matrix_basis = &matrix_basis_buf[0][0];
+ }
+ else {
+ matrix_basis = &mpr->matrix_basis[0][0];
+ }
+
+ if (use_offset) {
+ mul_m4_series(mat, mpr->matrix_space, matrix_basis, mpr->matrix_offset);
+ }
+ else {
+ mul_m4_series(mat, mpr->matrix_space, matrix_basis);
+ }
}
/* rotate mouse in relation to the center and relocate it */
diff --git a/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c
index 59a1e08d95a..1185bec2a2d 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/arrow2d_manipulator.c
@@ -66,18 +66,12 @@ static void arrow2d_draw_geom(wmManipulator *mpr, const float matrix[4][4], cons
const float size_h = size / 2.0f;
const float arrow_length = RNA_float_get(mpr->ptr, "length");
const float arrow_angle = RNA_float_get(mpr->ptr, "angle");
- const float draw_line_ofs = (mpr->line_width * 0.5f) / mpr->scale_final;
uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
gpuPushMatrix();
gpuMultMatrix(matrix);
- gpuScaleUniform(mpr->scale_final);
gpuRotate2D(RAD2DEGF(arrow_angle));
- /* local offset */
- gpuTranslate2f(
- mpr->matrix_offset[3][0] + draw_line_ofs,
- mpr->matrix_offset[3][1]);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
@@ -101,20 +95,25 @@ static void arrow2d_draw_geom(wmManipulator *mpr, const float matrix[4][4], cons
static void manipulator_arrow2d_draw(const bContext *UNUSED(C), wmManipulator *mpr)
{
- float col[4];
+ float color[4];
- manipulator_color_get(mpr, mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT, col);
+ float matrix_final[4][4];
+
+ manipulator_color_get(mpr, mpr->state & WM_MANIPULATOR_STATE_HIGHLIGHT, color);
glLineWidth(mpr->line_width);
+
+ WM_manipulator_calc_matrix_final(mpr, matrix_final);
+
glEnable(GL_BLEND);
- arrow2d_draw_geom(mpr, mpr->matrix_basis, col);
+ arrow2d_draw_geom(mpr, matrix_final, color);
glDisable(GL_BLEND);
if (mpr->interaction_data) {
ManipulatorInteraction *inter = mpr->interaction_data;
glEnable(GL_BLEND);
- arrow2d_draw_geom(mpr, inter->init_matrix, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f});
+ arrow2d_draw_geom(mpr, inter->init_matrix_final, (const float[4]){0.5f, 0.5f, 0.5f, 0.5f});
glDisable(GL_BLEND);
}
}
@@ -129,7 +128,9 @@ static void manipulator_arrow2d_invoke(
{
ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__);
- copy_m4_m4(inter->init_matrix, mpr->matrix_basis);
+ copy_m4_m4(inter->init_matrix_basis, mpr->matrix_basis);
+ WM_manipulator_calc_matrix_final(mpr, inter->init_matrix_final);
+
mpr->interaction_data = inter;
}
diff --git a/source/blender/editors/manipulator_library/manipulator_types/arrow3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/arrow3d_manipulator.c
index 923eca27e7c..61f5a7b2786 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/arrow3d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/arrow3d_manipulator.c
@@ -36,8 +36,6 @@
* - `matrix[0]` is derived from Y and Z.
* - `matrix[1]` is 'up' for manipulator types that have an up.
* - `matrix[2]` is the arrow direction (for all arrowes).
- *
- * TODO: use matrix_space
*/
#include "BIF_gl.h"
@@ -81,7 +79,7 @@ typedef struct ArrowManipulator3D {
/* -------------------------------------------------------------------- */
-static void manipulator_arrow_matrix_world_get(wmManipulator *mpr, float r_matrix[4][4])
+static void manipulator_arrow_matrix_basis_get(const wmManipulator *mpr, float r_matrix[4][4])
{
ArrowManipulator3D *arrow = (ArrowManipulator3D *)mpr;
@@ -130,7 +128,7 @@ static void arrow_draw_geom(const ArrowManipulator3D *arrow, const bool select,
const float vec[2][3] = {
{0.0f, 0.0f, 0.0f},
- {0.0f, 0.0f, RNA_float_get(arrow->manipulator.ptr, "length")},
+ {0.0f, 0.0f, arrow_length},
};
glLineWidth(arrow->manipulator.line_width);
@@ -184,33 +182,33 @@ static void arrow_draw_geom(const ArrowManipulator3D *arrow, const bool select,
static void arrow_draw_intern(ArrowManipulator3D *arrow, const bool select, const bool highlight)
{
- float col[4];
- float final_matrix[4][4];
+ wmManipulator *mpr = &arrow->manipulator;
+ float color[4];
+ float matrix_basis_adjust[4][4];
+ float matrix_final[4][4];
- manipulator_color_get(&arrow->manipulator, highlight, col);
- manipulator_arrow_matrix_world_get(&arrow->manipulator, final_matrix);
+ manipulator_color_get(mpr, highlight, color);
+ manipulator_arrow_matrix_basis_get(mpr, matrix_basis_adjust);
- mul_mat3_m4_fl(final_matrix, arrow->manipulator.scale_final);
- mul_m4_m4m4(final_matrix, final_matrix, arrow->manipulator.matrix_offset);
+ WM_manipulator_calc_matrix_final_params(
+ mpr, &((struct WM_ManipulatorMatrixParams) {
+ .matrix_basis = matrix_basis_adjust,
+ }), matrix_final);
gpuPushMatrix();
- gpuMultMatrix(final_matrix);
+ gpuMultMatrix(matrix_final);
glEnable(GL_BLEND);
- arrow_draw_geom(arrow, select, col);
+ arrow_draw_geom(arrow, select, color);
glDisable(GL_BLEND);
gpuPopMatrix();
- if (arrow->manipulator.interaction_data) {
- ManipulatorInteraction *inter = arrow->manipulator.interaction_data;
- float offset_matrix[4][4];
-
- copy_m4_m4(offset_matrix, inter->init_matrix);
- mul_mat3_m4_fl(offset_matrix, inter->init_scale);
+ if (mpr->interaction_data) {
+ ManipulatorInteraction *inter = mpr->interaction_data;
gpuPushMatrix();
- gpuMultMatrix(offset_matrix);
- gpuMultMatrix(arrow->manipulator.matrix_offset);
+ gpuMultMatrix(inter->init_matrix_final);
+
glEnable(GL_BLEND);
arrow_draw_geom(arrow, select, (const float [4]){0.5f, 0.5f, 0.5f, 0.5f});
@@ -255,7 +253,7 @@ static void manipulator_arrow_modal(
bool use_vertical = false;
- copy_v3_v3(orig_origin, inter->init_matrix[3]);
+ copy_v3_v3(orig_origin, inter->init_matrix_basis[3]);
orig_origin[3] = 1.0f;
add_v3_v3v3(offset, orig_origin, arrow->manipulator.matrix_basis[2]);
offset[3] = 1.0f;
@@ -299,7 +297,7 @@ static void manipulator_arrow_modal(
float zfac = ED_view3d_calc_zfac(rv3d, orig_origin, NULL);
ED_view3d_win_to_delta(ar, dir2d_final, offset, zfac);
- add_v3_v3v3(orig_origin, offset, inter->init_matrix[3]);
+ add_v3_v3v3(orig_origin, offset, inter->init_matrix_basis[3]);
/* calculate view vector for the new position */
if (rv3d->is_persp) {
@@ -382,9 +380,8 @@ static void manipulator_arrow_invoke(
inter->init_mval[0] = event->mval[0];
inter->init_mval[1] = event->mval[1];
- inter->init_scale = mpr->scale_final;
-
- manipulator_arrow_matrix_world_get(mpr, inter->init_matrix);
+ manipulator_arrow_matrix_basis_get(mpr, inter->init_matrix_basis);
+ WM_manipulator_calc_matrix_final(mpr, inter->init_matrix_final);
mpr->interaction_data = inter;
}
@@ -400,14 +397,19 @@ static void manipulator_arrow_property_update(wmManipulator *mpr, wmManipulatorP
static void manipulator_arrow_exit(bContext *C, wmManipulator *mpr, const bool cancel)
{
- if (!cancel)
- return;
-
ArrowManipulator3D *arrow = (ArrowManipulator3D *)mpr;
ManipulatorCommonData *data = &arrow->data;
+ wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
+
+ if (!cancel) {
+ /* Assign incase applying the opetration needs an updated offset
+ * editmesh bisect needs this. */
+ data->offset = WM_manipulator_target_property_value_get(mpr, mpr_prop);
+ return;
+ }
+
ManipulatorInteraction *inter = mpr->interaction_data;
- wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
manipulator_property_value_reset(C, mpr, inter, mpr_prop);
data->offset = inter->init_offset;
}
@@ -458,7 +460,7 @@ static void MANIPULATOR_WT_arrow_3d(wmManipulatorType *wt)
/* api callbacks */
wt->draw = manipulator_arrow_draw;
wt->draw_select = manipulator_arrow_draw_select;
- wt->matrix_world_get = manipulator_arrow_matrix_world_get;
+ wt->matrix_basis_get = manipulator_arrow_matrix_basis_get;
wt->modal = manipulator_arrow_modal;
wt->setup = manipulator_arrow_setup;
wt->invoke = manipulator_arrow_invoke;
diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
index ee8d0e85dfd..40ef5f48492 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
@@ -111,7 +111,7 @@ static void rect_transform_draw_corners(
}
static void rect_transform_draw_interaction(
- const float col[4], const int highlighted,
+ const float color[4], const int highlighted,
const float half_w, const float half_h,
const float w, const float h, const float line_width)
{
@@ -163,34 +163,65 @@ static void rect_transform_draw_interaction(
verts[3][1] = half_h - h;
break;
+ /* Only used for 3D view selection, never displayed to the user. */
+ case ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE:
+ verts[0][0] = -half_w;
+ verts[0][1] = -half_h;
+
+ verts[1][0] = -half_w;
+ verts[1][1] = half_h;
+
+ verts[2][0] = half_w;
+ verts[2][1] = half_h;
+
+ verts[3][0] = half_w;
+ verts[3][1] = -half_h;
+ break;
+
default:
return;
}
Gwn_VertFormat *format = immVertexFormat();
- uint pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- uint color = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT);
+ struct {
+ uint pos, col;
+ } attr_id = {
+ .pos = GWN_vertformat_attr_add(format, "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT),
+ .col = GWN_vertformat_attr_add(format, "color", GWN_COMP_F32, 3, GWN_FETCH_FLOAT),
+ };
immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
- glLineWidth(line_width + 3.0f);
+ if (highlighted == ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE) {
+ immBegin(GWN_PRIM_TRI_FAN, 4);
+ immAttrib3f(attr_id.col, 0.0f, 0.0f, 0.0f);
+ immVertex2fv(attr_id.pos, verts[0]);
+ immVertex2fv(attr_id.pos, verts[1]);
+ immVertex2fv(attr_id.pos, verts[2]);
+ immVertex2fv(attr_id.pos, verts[3]);
+ immEnd();
+ }
+ else {
+ glLineWidth(line_width + 3.0f);
- immBegin(GWN_PRIM_LINE_STRIP, 3);
- immAttrib3f(color, 0.0f, 0.0f, 0.0f);
- immVertex2fv(pos, verts[0]);
- immVertex2fv(pos, verts[1]);
- immVertex2fv(pos, verts[2]);
- immEnd();
+ immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immAttrib3f(attr_id.col, 0.0f, 0.0f, 0.0f);
+ immVertex2fv(attr_id.pos, verts[0]);
+ immVertex2fv(attr_id.pos, verts[1]);
+ immVertex2fv(attr_id.pos, verts[2]);
+ immEnd();
- glLineWidth(line_width);
+ glLineWidth(line_width);
- immBegin(GWN_PRIM_LINE_STRIP, 3);
- immAttrib3fv(color, col);
- immVertex2fv(pos, verts[0]);
- immVertex2fv(pos, verts[1]);
- immVertex2fv(pos, verts[2]);
- immEnd();
+ immBegin(GWN_PRIM_LINE_STRIP, 3);
+ immAttrib3fv(attr_id.col, color);
+ immVertex2fv(attr_id.pos, verts[0]);
+ immVertex2fv(attr_id.pos, verts[1]);
+ immVertex2fv(attr_id.pos, verts[2]);
+ immEnd();
+ }
immUnbindProgram();
+
}
static void manipulator_rect_transform_draw_intern(
@@ -242,16 +273,16 @@ static void manipulator_rect_transform_draw_intern(
/* corner manipulators */
{
- float col[4];
- manipulator_color_get(mpr, highlight, col);
+ float color[4];
+ manipulator_color_get(mpr, highlight, color);
glLineWidth(mpr->line_width);
- rect_transform_draw_corners(&r, w, h, col);
+ rect_transform_draw_corners(&r, w, h, color);
}
if (select) {
if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE) {
int scale_parts[] = {
- ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT,
+ ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_LEFT,
ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEX_RIGHT,
ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_UP,
ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_SCALEY_DOWN,
@@ -263,11 +294,21 @@ static void manipulator_rect_transform_draw_intern(
w, h, mpr->line_width);
}
}
+ if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_TRANSLATE) {
+ const int transform_part = ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE;
+ GPU_select_load_id(select_id | transform_part);
+ rect_transform_draw_interaction(
+ mpr->color, transform_part, half_w, half_h,
+ w, h, mpr->line_width);
+ }
}
else {
- rect_transform_draw_interaction(
- mpr->color, mpr->highlight_part, half_w, half_h,
- w, h, mpr->line_width);
+ /* Don't draw translate (only for selection). */
+ if (mpr->highlight_part != ED_MANIPULATOR_RECT_TRANSFORM_INTERSECT_TRANSLATE) {
+ rect_transform_draw_interaction(
+ mpr->color, mpr->highlight_part, half_w, half_h,
+ w, h, mpr->line_width);
+ }
}
glLineWidth(1.0);
@@ -572,11 +613,6 @@ static void manipulator_rect_transform_modal(
wmManipulatorProperty *mpr_prop;
- mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
- if (mpr_prop->type != NULL) {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, offset);
- }
-
mpr_prop = WM_manipulator_target_property_find(mpr, "scale");
if (mpr_prop->type != NULL) {
if (transform_flag & ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM) {
@@ -593,21 +629,26 @@ static void manipulator_rect_transform_modal(
}
}
+ mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
+ if (mpr_prop->type != NULL) {
+ WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, offset);
+ }
+
/* tag the region for redraw */
ED_region_tag_redraw(CTX_wm_region(C));
}
static void manipulator_rect_transform_property_update(wmManipulator *mpr, wmManipulatorProperty *mpr_prop)
{
- if (STREQ(mpr_prop->type->idname, "offset")) {
- manipulator_rect_transform_get_prop_value(mpr, mpr_prop, mpr->matrix_offset[3]);
- }
- else if (STREQ(mpr_prop->type->idname, "scale")) {
+ if (STREQ(mpr_prop->type->idname, "scale")) {
float scale[2];
manipulator_rect_transform_get_prop_value(mpr, mpr_prop, scale);
mpr->matrix_offset[0][0] = scale[0];
mpr->matrix_offset[1][1] = scale[1];
}
+ else if (STREQ(mpr_prop->type->idname, "offset")) {
+ manipulator_rect_transform_get_prop_value(mpr, mpr_prop, mpr->matrix_offset[3]);
+ }
else {
BLI_assert(0);
}
@@ -623,11 +664,6 @@ static void manipulator_rect_transform_exit(bContext *C, wmManipulator *mpr, con
wmManipulatorProperty *mpr_prop;
/* reset properties */
- mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
- if (mpr_prop->type != NULL) {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, data->orig_matrix_offset[3]);
- }
-
mpr_prop = WM_manipulator_target_property_find(mpr, "scale");
if (mpr_prop->type != NULL) {
const float orig_scale[2] = {data->orig_matrix_offset[0][0], data->orig_matrix_offset[1][1]};
@@ -645,6 +681,11 @@ static void manipulator_rect_transform_exit(bContext *C, wmManipulator *mpr, con
}
}
+ mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
+ if (mpr_prop->type != NULL) {
+ WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, data->orig_matrix_offset[3]);
+ }
+
copy_m4_m4(mpr->matrix_offset, data->orig_matrix_offset);
}
@@ -662,11 +703,11 @@ static void MANIPULATOR_WT_cage_2d(wmManipulatorType *wt)
/* api callbacks */
wt->draw = manipulator_rect_transform_draw;
wt->draw_select = manipulator_rect_transform_draw_select;
+ wt->test_select = manipulator_rect_transform_test_select;
wt->setup = manipulator_rect_transform_setup;
wt->invoke = manipulator_rect_transform_invoke;
wt->property_update = manipulator_rect_transform_property_update;
wt->modal = manipulator_rect_transform_modal;
- wt->test_select = manipulator_rect_transform_test_select;
wt->exit = manipulator_rect_transform_exit;
wt->cursor_get = manipulator_rect_transform_get_cursor;
diff --git a/source/blender/editors/manipulator_library/manipulator_types/dial3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/dial3d_manipulator.c
index 742b4c70613..f7511c581ed 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/dial3d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/dial3d_manipulator.c
@@ -36,8 +36,6 @@
* - `matrix[0]` is derived from Y and Z.
* - `matrix[1]` is 'up' when DialManipulator.use_start_y_axis is set.
* - `matrix[2]` is the axis the dial rotates around (all dials).
- *
- * TODO: use matrix_space
*/
#include "BIF_gl.h"
@@ -107,13 +105,12 @@ static void dial_calc_matrix(const wmManipulator *mpr, float mat[4][4])
rotation_between_vecs_to_mat3(rot, up, mpr->matrix_basis[2]);
copy_m4_m3(mat, rot);
copy_v3_v3(mat[3], mpr->matrix_basis[3]);
- mul_mat3_m4_fl(mat, mpr->scale_final);
}
/* -------------------------------------------------------------------- */
static void dial_geom_draw(
- const wmManipulator *mpr, const float col[4], const bool select,
+ const wmManipulator *mpr, const float color[4], const bool select,
float axis_modal_mat[4][4], float clip_plane[4])
{
#ifdef USE_MANIPULATOR_CUSTOM_DIAL
@@ -138,7 +135,7 @@ static void dial_geom_draw(
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
}
- immUniformColor4fv(col);
+ immUniformColor4fv(color);
if (filled) {
imm_draw_circle_fill(pos, 0, 0, 1.0, DIAL_RESOLUTION);
@@ -156,7 +153,7 @@ static void dial_geom_draw(
/**
* Draws a line from (0, 0, 0) to \a co_outer, at \a angle.
*/
-static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[3], const float col[4])
+static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[3], const float color[4])
{
glLineWidth(1.0f);
@@ -167,7 +164,7 @@ static void dial_ghostarc_draw_helpline(const float angle, const float co_outer[
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- immUniformColor4fv(col);
+ immUniformColor4fv(color);
immBegin(GWN_PRIM_LINE_STRIP, 2);
immVertex3f(pos, 0.0f, 0.0f, 0.0f);
@@ -275,18 +272,23 @@ static void dial_draw_intern(
const bContext *C, wmManipulator *mpr,
const bool select, const bool highlight, float clip_plane[4])
{
- float mat[4][4];
- float col[4];
+ float matrix_basis_adjust[4][4];
+ float matrix_final[4][4];
+ float color[4];
BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D);
- manipulator_color_get(mpr, highlight, col);
+ manipulator_color_get(mpr, highlight, color);
+
+ dial_calc_matrix(mpr, matrix_basis_adjust);
- dial_calc_matrix(mpr, mat);
+ WM_manipulator_calc_matrix_final_params(
+ mpr, &((struct WM_ManipulatorMatrixParams) {
+ .matrix_basis = (void *)matrix_basis_adjust,
+ }), matrix_final);
gpuPushMatrix();
- gpuMultMatrix(mat);
- gpuMultMatrix(mpr->matrix_offset);
+ gpuMultMatrix(matrix_final);
/* draw rotation indicator arc first */
if ((mpr->flag & WM_MANIPULATOR_DRAW_VALUE) &&
@@ -309,8 +311,8 @@ static void dial_draw_intern(
for (int i = 0; i < 2; i++) {
dial_ghostarc_draw(mpr, angle_ofs, angle_delta, (const float [4]){0.8f, 0.8f, 0.8f, 0.4f});
- dial_ghostarc_draw_helpline(angle_ofs, co_outer, col); /* starting position */
- dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, col); /* starting position + current value */
+ dial_ghostarc_draw_helpline(angle_ofs, co_outer, color); /* starting position */
+ dial_ghostarc_draw_helpline(angle_ofs + angle_delta, co_outer, color); /* starting position + current value */
if (i == 0) {
const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
@@ -324,7 +326,7 @@ static void dial_draw_intern(
}
/* draw actual dial manipulator */
- dial_geom_draw(mpr, col, select, mat, clip_plane);
+ dial_geom_draw(mpr, color, select, matrix_basis_adjust, clip_plane);
gpuPopMatrix();
}
diff --git a/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c
index d4b98ec514a..38e350762c1 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/grab3d_manipulator.c
@@ -23,7 +23,7 @@
*
* \name Grab Manipulator
*
- * 3D Manipulator
+ * 3D Manipulator, also works in 2D views.
*
* \brief Simple manipulator to grab and translate.
*
@@ -31,8 +31,6 @@
* - `matrix[1]` currently not used.
* - `matrix[2]` is the widget direction (for all manipulators).
*
- * TODO: use matrix_space
- *
*/
#include "BIF_gl.h"
@@ -65,6 +63,20 @@
#include "../manipulator_geometry.h"
#include "../manipulator_library_intern.h"
+typedef struct GrabManipulator3D {
+ wmManipulator manipulator;
+ /* Added to 'matrix_basis' when calculating the matrix. */
+ float prop_co[3];
+} GrabManipulator3D;
+
+static void manipulator_grab_matrix_basis_get(const wmManipulator *mpr, float r_matrix[4][4])
+{
+ GrabManipulator3D *grab = (GrabManipulator3D *)mpr;
+
+ copy_m4_m4(r_matrix, grab->manipulator.matrix_basis);
+ add_v3_v3(r_matrix[3], grab->prop_co);
+}
+
static void manipulator_grab_modal(
bContext *C, wmManipulator *mpr, const wmEvent *event,
eWM_ManipulatorTweak tweak_flag);
@@ -75,11 +87,7 @@ typedef struct GrabInteraction {
/* only for when using properties */
float init_prop_co[3];
- /* final output values, used for drawing */
- struct {
- float co_ofs[3];
- float co_final[3];
- } output;
+ float init_matrix_final[4][4];
} GrabInteraction;
#define DIAL_RESOLUTION 32
@@ -87,13 +95,13 @@ typedef struct GrabInteraction {
/* -------------------------------------------------------------------- */
static void grab_geom_draw(
- const wmManipulator *mpr, const float col[4], const bool select)
+ const wmManipulator *mpr, const float color[4], const bool select, const int draw_options)
{
#ifdef USE_MANIPULATOR_CUSTOM_DIAL
UNUSED_VARS(grab3d, col, axis_modal_mat);
wm_manipulator_geometryinfo_draw(&wm_manipulator_geom_data_grab3d, select);
#else
- const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const int draw_style = RNA_enum_get(mpr->ptr, "draw_style");
const bool filled = (draw_options & ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL) != 0;
glLineWidth(mpr->line_width);
@@ -103,13 +111,27 @@ static void grab_geom_draw(
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
- immUniformColor4fv(col);
+ immUniformColor4fv(color);
- if (filled) {
- imm_draw_circle_fill(pos, 0, 0, 1.0, DIAL_RESOLUTION);
+ if (draw_style == ED_MANIPULATOR_GRAB_STYLE_RING_2D) {
+ if (filled) {
+ imm_draw_circle_fill(pos, 0, 0, 1.0f, DIAL_RESOLUTION);
+ }
+ else {
+ imm_draw_circle_wire(pos, 0, 0, 1.0f, DIAL_RESOLUTION);
+ }
+ }
+ else if (draw_style == ED_MANIPULATOR_GRAB_STYLE_CROSS_2D) {
+ immBegin(GWN_PRIM_LINES, 4);
+ immVertex2f(pos, 1.0f, 1.0f);
+ immVertex2f(pos, -1.0f, -1.0f);
+
+ immVertex2f(pos, -1.0f, 1.0f);
+ immVertex2f(pos, 1.0f, -1.0f);
+ immEnd();
}
else {
- imm_draw_circle_wire(pos, 0, 0, 1.0, DIAL_RESOLUTION);
+ BLI_assert(0);
}
immUnbindProgram();
@@ -129,45 +151,68 @@ static void grab3d_get_translate(
};
RegionView3D *rv3d = ar->regiondata;
- const float *co_ref = inter->init_prop_co;
+ float co_ref[3];
+ mul_v3_mat3_m4v3(co_ref, mpr->matrix_space, inter->init_prop_co);
const float zfac = ED_view3d_calc_zfac(rv3d, co_ref, NULL);
ED_view3d_win_to_delta(ar, mval_delta, co_delta, zfac);
+
+ float matrix_space_inv[3][3];
+ copy_m3_m4(matrix_space_inv, mpr->matrix_space);
+ invert_m3(matrix_space_inv);
+ mul_m3_v3(matrix_space_inv, co_delta);
}
static void grab3d_draw_intern(
const bContext *C, wmManipulator *mpr,
const bool select, const bool highlight)
{
- float mat[4][4];
- float col[4];
-
- BLI_assert(CTX_wm_area(C)->spacetype == SPACE_VIEW3D);
- UNUSED_VARS_NDEBUG(C);
-
- manipulator_color_get(mpr, highlight, col);
-
- copy_m4_m4(mat, mpr->matrix_basis);
- mul_mat3_m4_fl(mat, mpr->scale_final);
+ GrabInteraction *inter = mpr->interaction_data;
+ const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
+ const bool align_view = (draw_options & ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW) != 0;
+ float color[4];
+ float matrix_final[4][4];
+ float matrix_align[4][4];
+
+ manipulator_color_get(mpr, highlight, color);
+
+ {
+ float matrix_basis_adjust[4][4];
+ manipulator_grab_matrix_basis_get(mpr, matrix_basis_adjust);
+ WM_manipulator_calc_matrix_final_params(
+ mpr, &((struct WM_ManipulatorMatrixParams) {
+ .matrix_basis = matrix_basis_adjust,
+ }), matrix_final);
+ }
gpuPushMatrix();
- if (mpr->interaction_data) {
- GrabInteraction *inter = mpr->interaction_data;
- gpuTranslate3fv(inter->output.co_ofs);
+ gpuMultMatrix(matrix_final);
+
+ if (align_view) {
+ float matrix_final_unit[4][4];
+ RegionView3D *rv3d = CTX_wm_region_view3d(C);
+ normalize_m4_m4(matrix_final_unit, matrix_final);
+ mul_m4_m4m4(matrix_align, rv3d->viewmat, matrix_final_unit);
+ zero_v3(matrix_align[3]);
+ transpose_m4(matrix_align);
+ gpuMultMatrix(matrix_align);
}
- gpuMultMatrix(mat);
- gpuMultMatrix(mpr->matrix_offset);
+
glEnable(GL_BLEND);
- grab_geom_draw(mpr, col, select);
+ grab_geom_draw(mpr, color, select, draw_options);
glDisable(GL_BLEND);
gpuPopMatrix();
if (mpr->interaction_data) {
gpuPushMatrix();
- gpuMultMatrix(mat);
- gpuMultMatrix(mpr->matrix_offset);
+ gpuMultMatrix(inter->init_matrix_final);
+
+ if (align_view) {
+ gpuMultMatrix(matrix_align);
+ }
+
glEnable(GL_BLEND);
- grab_geom_draw(mpr, (const float [4]){0.5f, 0.5f, 0.5f, 0.5f}, select);
+ grab_geom_draw(mpr, (const float [4]){0.5f, 0.5f, 0.5f, 0.5f}, select, draw_options);
glDisable(GL_BLEND);
gpuPopMatrix();
}
@@ -195,17 +240,35 @@ static void manipulator_grab_modal(
bContext *C, wmManipulator *mpr, const wmEvent *event,
eWM_ManipulatorTweak UNUSED(tweak_flag))
{
+ GrabManipulator3D *grab = (GrabManipulator3D *)mpr;
GrabInteraction *inter = mpr->interaction_data;
+ ARegion *ar = CTX_wm_region(C);
- grab3d_get_translate(mpr, event, CTX_wm_region(C), inter->output.co_ofs);
-
- add_v3_v3v3(inter->output.co_final, inter->init_prop_co, inter->output.co_ofs);
+ float prop_delta[3];
+ if (CTX_wm_area(C)->spacetype == SPACE_VIEW3D) {
+ grab3d_get_translate(mpr, event, ar, prop_delta);
+ }
+ else {
+ float mval_proj_init[2], mval_proj_curr[2];
+ if ((manipulator_window_project_2d(
+ C, mpr, inter->init_mval, 2, false, mval_proj_init) == false) ||
+ (manipulator_window_project_2d(
+ C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, false, mval_proj_curr) == false))
+ {
+ return;
+ }
+ sub_v2_v2v2(prop_delta, mval_proj_curr, mval_proj_init);
+ prop_delta[2] = 0.0f;
+ }
+ add_v3_v3v3(grab->prop_co, inter->init_prop_co, prop_delta);
/* set the property for the operator and call its modal function */
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
if (WM_manipulator_target_property_is_valid(mpr_prop)) {
- WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, inter->output.co_final);
+ WM_manipulator_target_property_value_set_array(C, mpr, mpr_prop, grab->prop_co);
}
+
+ ED_region_tag_redraw(ar);
}
static void manipulator_grab_invoke(
@@ -216,14 +279,57 @@ static void manipulator_grab_invoke(
inter->init_mval[0] = event->mval[0];
inter->init_mval[1] = event->mval[1];
+#if 0
+ copy_v3_v3(inter->init_prop_co, grab->prop_co);
+#else
wmManipulatorProperty *mpr_prop = WM_manipulator_target_property_find(mpr, "offset");
if (WM_manipulator_target_property_is_valid(mpr_prop)) {
WM_manipulator_target_property_value_get_array(mpr, mpr_prop, inter->init_prop_co);
}
+#endif
+
+ {
+ float matrix_basis_adjust[4][4];
+ manipulator_grab_matrix_basis_get(mpr, matrix_basis_adjust);
+ WM_manipulator_calc_matrix_final_params(
+ mpr, &((struct WM_ManipulatorMatrixParams) {
+ .matrix_basis = matrix_basis_adjust,
+ }), inter->init_matrix_final);
+ }
mpr->interaction_data = inter;
}
+
+static int manipulator_grab_test_select(
+ bContext *C, wmManipulator *mpr, const wmEvent *event)
+{
+ float point_local[2];
+
+ if (manipulator_window_project_2d(
+ C, mpr, (const float[2]){UNPACK2(event->mval)}, 2, true, point_local) == false)
+ {
+ return 0;
+ }
+
+ if (len_squared_v2(point_local) < SQUARE(mpr->scale_final)) {
+ return true;
+ }
+
+ return 0;
+}
+
+static void manipulator_grab_property_update(wmManipulator *mpr, wmManipulatorProperty *mpr_prop)
+{
+ GrabManipulator3D *grab = (GrabManipulator3D *)mpr;
+ WM_manipulator_target_property_value_get_array(mpr, mpr_prop, grab->prop_co);
+}
+
+static int manipulator_grab_cursor_get(wmManipulator *UNUSED(mpr))
+{
+ return BC_HANDCURSOR;
+}
+
/* -------------------------------------------------------------------- */
/** \name Grab Manipulator API
*
@@ -237,22 +343,28 @@ static void MANIPULATOR_WT_grab_3d(wmManipulatorType *wt)
/* api callbacks */
wt->draw = manipulator_grab_draw;
wt->draw_select = manipulator_grab_draw_select;
+ wt->test_select = manipulator_grab_test_select;
+ wt->matrix_basis_get = manipulator_grab_matrix_basis_get;
wt->invoke = manipulator_grab_invoke;
+ wt->property_update = manipulator_grab_property_update;
wt->modal = manipulator_grab_modal;
+ wt->cursor_get = manipulator_grab_cursor_get;
- wt->struct_size = sizeof(wmManipulator);
+ wt->struct_size = sizeof(GrabManipulator3D);
/* rna */
static EnumPropertyItem rna_enum_draw_style[] = {
- {ED_MANIPULATOR_GRAB_STYLE_RING, "RING", 0, "Ring", ""},
+ {ED_MANIPULATOR_GRAB_STYLE_RING_2D, "RING_2D", 0, "Ring", ""},
+ {ED_MANIPULATOR_GRAB_STYLE_CROSS_2D, "CROSS_2D", 0, "Ring", ""},
{0, NULL, 0, NULL, NULL}
};
static EnumPropertyItem rna_enum_draw_options[] = {
{ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL, "FILL", 0, "Filled", ""},
+ {ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW, "ALIGN_VIEW", 0, "Align View", ""},
{0, NULL, 0, NULL, NULL}
};
- RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_MANIPULATOR_GRAB_STYLE_RING, "Draw Style", "");
+ RNA_def_enum(wt->srna, "draw_style", rna_enum_draw_style, ED_MANIPULATOR_GRAB_STYLE_RING_2D, "Draw Style", "");
RNA_def_enum_flag(wt->srna, "draw_options", rna_enum_draw_options, 0, "Draw Options", "");
WM_manipulatortype_target_property_def(wt, "offset", PROP_FLOAT, 3);
diff --git a/source/blender/editors/manipulator_library/manipulator_types/primitive3d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/primitive3d_manipulator.c
index 6a7fde5a5b5..44878a24430 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/primitive3d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/primitive3d_manipulator.c
@@ -27,8 +27,6 @@
*
* \brief Manipulator with primitive drawing type (plane, cube, etc.).
* Currently only plane primitive supported without own handling, use with operator only.
- *
- * TODO: use matrix_space
*/
#include "BIF_gl.h"
@@ -90,23 +88,21 @@ static void manipulator_primitive_draw_intern(
wmManipulator *mpr, const bool UNUSED(select),
const bool highlight)
{
- float col_inner[4], col_outer[4];
- float mat[4][4];
+ float color_inner[4], color_outer[4];
+ float matrix_final[4][4];
const int draw_style = RNA_enum_get(mpr->ptr, "draw_style");
- manipulator_color_get(mpr, highlight, col_outer);
- copy_v4_v4(col_inner, col_outer);
- col_inner[3] *= 0.5f;
+ manipulator_color_get(mpr, highlight, color_outer);
+ copy_v4_v4(color_inner, color_outer);
+ color_inner[3] *= 0.5f;
- copy_m4_m4(mat, mpr->matrix_basis);
- mul_mat3_m4_fl(mat, mpr->scale_final);
+ WM_manipulator_calc_matrix_final(mpr, matrix_final);
gpuPushMatrix();
- gpuMultMatrix(mat);
+ gpuMultMatrix(matrix_final);
glEnable(GL_BLEND);
- gpuMultMatrix(mpr->matrix_offset);
- manipulator_primitive_draw_geom(col_inner, col_outer, draw_style);
+ manipulator_primitive_draw_geom(color_inner, color_outer, draw_style);
glDisable(GL_BLEND);
gpuPopMatrix();
@@ -114,19 +110,15 @@ static void manipulator_primitive_draw_intern(
if (mpr->interaction_data) {
ManipulatorInteraction *inter = mpr->interaction_data;
- copy_v4_fl(col_inner, 0.5f);
- copy_v3_fl(col_outer, 0.5f);
- col_outer[3] = 0.8f;
-
- copy_m4_m4(mat, inter->init_matrix);
- mul_mat3_m4_fl(mat, inter->init_scale);
+ copy_v4_fl(color_inner, 0.5f);
+ copy_v3_fl(color_outer, 0.5f);
+ color_outer[3] = 0.8f;
gpuPushMatrix();
- gpuMultMatrix(mat);
+ gpuMultMatrix(inter->init_matrix_final);
glEnable(GL_BLEND);
- gpuMultMatrix(mpr->matrix_offset);
- manipulator_primitive_draw_geom(col_inner, col_outer, draw_style);
+ manipulator_primitive_draw_geom(color_inner, color_outer, draw_style);
glDisable(GL_BLEND);
gpuPopMatrix();
@@ -158,8 +150,7 @@ static void manipulator_primitive_invoke(
{
ManipulatorInteraction *inter = MEM_callocN(sizeof(ManipulatorInteraction), __func__);
- copy_m4_m4(inter->init_matrix, mpr->matrix_basis);
- inter->init_scale = mpr->scale_final;
+ WM_manipulator_calc_matrix_final(mpr, inter->init_matrix_final);
mpr->interaction_data = inter;
}
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index 8aa3b63f795..94fe433e5d7 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -396,7 +396,7 @@ bool paintface_mouse_select(struct bContext *C, Object *ob, const int mval[2], b
return true;
}
-int do_paintface_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend)
+int do_paintface_box_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, rcti *rect, bool select, bool extend)
{
Object *ob = vc->obact;
Mesh *me;
@@ -427,7 +427,7 @@ int do_paintface_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool
}
}
- ED_view3d_backbuf_validate(C, vc);
+ ED_view3d_backbuf_validate(eval_ctx, vc);
ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect);
rt = ibuf->rect;
diff --git a/source/blender/editors/mesh/editmesh_bisect.c b/source/blender/editors/mesh/editmesh_bisect.c
index 9b97484c8d9..228677a51c8 100644
--- a/source/blender/editors/mesh/editmesh_bisect.c
+++ b/source/blender/editors/mesh/editmesh_bisect.c
@@ -50,6 +50,8 @@
#include "ED_screen.h"
#include "ED_view3d.h"
+#include "UI_resources.h"
+
#include "mesh_intern.h" /* own include */
#define USE_MANIPULATOR
@@ -426,8 +428,8 @@ static void manipulator_mesh_bisect_update_from_op(ManipulatorGroup *man)
RNA_property_float_get_array(op->ptr, man->data.prop_plane_no, plane_no);
WM_manipulator_set_matrix_location(man->translate_z, plane_co);
- WM_manipulator_set_matrix_location(man->translate_c, plane_co);
WM_manipulator_set_matrix_location(man->rotate_c, plane_co);
+ /* translate_c location comes from the property. */
WM_manipulator_set_matrix_rotation_from_z_axis(man->translate_z, plane_no);
@@ -619,8 +621,12 @@ static void manipulator_mesh_bisect_setup(const bContext *C, wmManipulatorGroup
man->translate_c = WM_manipulator_new_ptr(wt_grab, mgroup, NULL);
man->rotate_c = WM_manipulator_new_ptr(wt_dial, mgroup, NULL);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, man->translate_z->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, man->translate_c->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_SECONDARY, man->rotate_c->color);
+
RNA_enum_set(man->translate_z->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_NORMAL);
- RNA_enum_set(man->translate_c->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_RING);
+ RNA_enum_set(man->translate_c->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_RING_2D);
WM_manipulator_set_flag(man->translate_c, WM_MANIPULATOR_DRAW_VALUE, true);
WM_manipulator_set_flag(man->rotate_c, WM_MANIPULATOR_DRAW_VALUE, true);
diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c
index e7be66e0276..e7fcad9e633 100644
--- a/source/blender/editors/mesh/editmesh_extrude.c
+++ b/source/blender/editors/mesh/editmesh_extrude.c
@@ -53,6 +53,8 @@
#include "ED_transform.h"
#include "ED_view3d.h"
+#include "UI_resources.h"
+
#include "MEM_guardedalloc.h"
#include "mesh_intern.h" /* own include */
@@ -859,9 +861,9 @@ static void manipulator_mesh_spin_update_from_op(ManipulatorSpinGroup *man)
RNA_property_float_get_array(op->ptr, man->data.prop_axis_no, plane_no);
WM_manipulator_set_matrix_location(man->translate_z, plane_co);
- WM_manipulator_set_matrix_location(man->translate_c, plane_co);
WM_manipulator_set_matrix_location(man->rotate_c, plane_co);
WM_manipulator_set_matrix_location(man->angle_z, plane_co);
+ /* translate_c location comes from the property. */
WM_manipulator_set_matrix_rotation_from_z_axis(man->translate_z, plane_no);
WM_manipulator_set_matrix_rotation_from_z_axis(man->angle_z, plane_no);
@@ -878,7 +880,7 @@ static void manipulator_mesh_spin_update_from_op(ManipulatorSpinGroup *man)
normalize_v3(man->data.rotate_up);
WM_manipulator_set_matrix_rotation_from_z_axis(man->translate_c, plane_no);
- WM_manipulator_set_matrix_rotation_from_yz_axis(man->rotate_c, man->data.rotate_axis, plane_no);
+ WM_manipulator_set_matrix_rotation_from_yz_axis(man->rotate_c, plane_no, man->data.rotate_axis);
/* show the axis instead of mouse cursor */
RNA_enum_set(man->rotate_c->ptr, "draw_options",
@@ -1083,8 +1085,14 @@ static void manipulator_mesh_spin_setup(const bContext *C, wmManipulatorGroup *m
man->rotate_c = WM_manipulator_new_ptr(wt_dial, mgroup, NULL);
man->angle_z = WM_manipulator_new_ptr(wt_dial, mgroup, NULL);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, man->translate_z->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, man->translate_c->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_SECONDARY, man->rotate_c->color);
+ UI_GetThemeColor3fv(TH_AXIS_Z, man->angle_z->color);
+
+
RNA_enum_set(man->translate_z->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_NORMAL);
- RNA_enum_set(man->translate_c->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_RING);
+ RNA_enum_set(man->translate_c->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_RING_2D);
WM_manipulator_set_flag(man->translate_c, WM_MANIPULATOR_DRAW_VALUE, true);
WM_manipulator_set_flag(man->rotate_c, WM_MANIPULATOR_DRAW_VALUE, true);
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index 37d86ee313f..5aa10620936 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -161,6 +161,7 @@ typedef struct KnifePosData {
typedef struct KnifeTool_OpData {
ARegion *ar; /* region that knifetool was activated in */
void *draw_handle; /* for drawing preview loop */
+ EvaluationContext eval_ctx;
ViewContext vc; /* note: _don't_ use 'mval', instead use the one we define below */
float mval[2]; /* mouse value with snapping applied */
//bContext *C;
@@ -1814,7 +1815,7 @@ static void knife_input_ray_segment(KnifeTool_OpData *kcd, const float mval[2],
mul_m4_v3(kcd->ob->imat, r_origin_ofs);
}
-static BMFace *knife_find_closest_face(const bContext *C, KnifeTool_OpData *kcd, float co[3], float cageco[3], bool *is_space)
+static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], bool *is_space)
{
BMFace *f;
float dist = KMAXDIST;
@@ -1839,7 +1840,7 @@ static BMFace *knife_find_closest_face(const bContext *C, KnifeTool_OpData *kcd,
if (!f) {
if (kcd->is_interactive) {
/* try to use backbuffer selection method if ray casting failed */
- f = EDBM_face_find_nearest(C, &kcd->vc, &dist);
+ f = EDBM_face_find_nearest(&kcd->eval_ctx, &kcd->vc, &dist);
/* cheat for now; just put in the origin instead
* of a true coordinate on the face.
@@ -1853,7 +1854,7 @@ static BMFace *knife_find_closest_face(const bContext *C, KnifeTool_OpData *kcd,
/* find the 2d screen space density of vertices within a radius. used to scale snapping
* distance for picking edges/verts.*/
-static int knife_sample_screen_density(const bContext *C, KnifeTool_OpData *kcd, const float radius)
+static int knife_sample_screen_density(KnifeTool_OpData *kcd, const float radius)
{
BMFace *f;
bool is_space;
@@ -1861,7 +1862,7 @@ static int knife_sample_screen_density(const bContext *C, KnifeTool_OpData *kcd,
BLI_assert(kcd->is_interactive == true);
- f = knife_find_closest_face(C, kcd, co, cageco, &is_space);
+ f = knife_find_closest_face(kcd, co, cageco, &is_space);
if (f && !is_space) {
const float radius_sq = radius * radius;
@@ -1904,15 +1905,15 @@ static int knife_sample_screen_density(const bContext *C, KnifeTool_OpData *kcd,
/* returns snapping distance for edges/verts, scaled by the density of the
* surrounding mesh (in screen space)*/
-static float knife_snap_size(const bContext *C, KnifeTool_OpData *kcd, float maxsize)
+static float knife_snap_size(KnifeTool_OpData *kcd, float maxsize)
{
- float density = (float)knife_sample_screen_density(C, kcd, maxsize * 2.0f);
+ float density = (float)knife_sample_screen_density(kcd, maxsize * 2.0f);
return min_ff(maxsize / (density * 0.5f), maxsize);
}
/* p is closest point on edge to the mouse cursor */
-static KnifeEdge *knife_find_closest_edge(const bContext *C, KnifeTool_OpData *kcd, float p[3], float cagep[3],
+static KnifeEdge *knife_find_closest_edge(KnifeTool_OpData *kcd, float p[3], float cagep[3],
BMFace **fptr, bool *is_space)
{
BMFace *f;
@@ -1920,7 +1921,7 @@ static KnifeEdge *knife_find_closest_edge(const bContext *C, KnifeTool_OpData *k
float maxdist;
if (kcd->is_interactive) {
- maxdist = knife_snap_size(C, kcd, kcd->ethresh);
+ maxdist = knife_snap_size(kcd, kcd->ethresh);
if (kcd->ignore_vert_snapping) {
maxdist *= 0.5f;
@@ -1930,7 +1931,7 @@ static KnifeEdge *knife_find_closest_edge(const bContext *C, KnifeTool_OpData *k
maxdist = KNIFE_FLT_EPS;
}
- f = knife_find_closest_face(C, kcd, co, cageco, NULL);
+ f = knife_find_closest_face(kcd, co, cageco, NULL);
*is_space = !f;
kcd->curr.bmface = f;
@@ -2044,7 +2045,7 @@ static KnifeEdge *knife_find_closest_edge(const bContext *C, KnifeTool_OpData *k
}
/* find a vertex near the mouse cursor, if it exists */
-static KnifeVert *knife_find_closest_vert(const bContext *C, KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr,
+static KnifeVert *knife_find_closest_vert(KnifeTool_OpData *kcd, float p[3], float cagep[3], BMFace **fptr,
bool *is_space)
{
BMFace *f;
@@ -2052,7 +2053,7 @@ static KnifeVert *knife_find_closest_vert(const bContext *C, KnifeTool_OpData *k
float maxdist;
if (kcd->is_interactive) {
- maxdist = knife_snap_size(C, kcd, kcd->vthresh);
+ maxdist = knife_snap_size(kcd, kcd->vthresh);
if (kcd->ignore_vert_snapping) {
maxdist *= 0.5f;
}
@@ -2061,7 +2062,7 @@ static KnifeVert *knife_find_closest_vert(const bContext *C, KnifeTool_OpData *k
maxdist = KNIFE_FLT_EPS;
}
- f = knife_find_closest_face(C, kcd, co, cageco, is_space);
+ f = knife_find_closest_face(kcd, co, cageco, is_space);
kcd->curr.bmface = f;
@@ -2183,7 +2184,7 @@ static bool knife_snap_angle(KnifeTool_OpData *kcd)
}
/* update active knife edge/vert pointers */
-static int knife_update_active(const bContext *C, KnifeTool_OpData *kcd)
+static int knife_update_active(KnifeTool_OpData *kcd)
{
knife_pos_data_clear(&kcd->curr);
copy_v2_v2(kcd->curr.mval, kcd->mval);
@@ -2198,13 +2199,13 @@ static int knife_update_active(const bContext *C, KnifeTool_OpData *kcd)
kcd->is_angle_snapping = false;
}
- kcd->curr.vert = knife_find_closest_vert(C, kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space);
+ kcd->curr.vert = knife_find_closest_vert(kcd, kcd->curr.co, kcd->curr.cage, &kcd->curr.bmface, &kcd->curr.is_space);
if (!kcd->curr.vert &&
/* no edge snapping while dragging (edges are too sticky when cuts are immediate) */
!kcd->is_drag_hold)
{
- kcd->curr.edge = knife_find_closest_edge(C, kcd, kcd->curr.co, kcd->curr.cage,
+ kcd->curr.edge = knife_find_closest_edge(kcd, kcd->curr.co, kcd->curr.cage,
&kcd->curr.bmface, &kcd->curr.is_space);
}
@@ -2571,30 +2572,27 @@ static void knifetool_exit(bContext *C, wmOperator *op)
op->customdata = NULL;
}
-static void knifetool_update_mval(const bContext *C, KnifeTool_OpData *kcd, const float mval[2])
+static void knifetool_update_mval(KnifeTool_OpData *kcd, const float mval[2])
{
knife_recalc_projmat(kcd);
copy_v2_v2(kcd->mval, mval);
- if (knife_update_active(C, kcd)) {
+ if (knife_update_active(kcd)) {
ED_region_tag_redraw(kcd->ar);
}
}
-static void knifetool_update_mval_i(const bContext *C, KnifeTool_OpData *kcd, const int mval_i[2])
+static void knifetool_update_mval_i(KnifeTool_OpData *kcd, const int mval_i[2])
{
float mval[2] = {UNPACK2(mval_i)};
- knifetool_update_mval(C, kcd, mval);
+ knifetool_update_mval(kcd, mval);
}
-static void knifetool_init_bmbvh(const bContext *C, KnifeTool_OpData *kcd)
+static void knifetool_init_bmbvh(KnifeTool_OpData *kcd)
{
- EvaluationContext eval_ctx;
BM_mesh_elem_index_ensure(kcd->em->bm, BM_VERT);
- CTX_data_eval_ctx(C, &eval_ctx);
-
- kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(&eval_ctx, kcd->em, kcd->scene, NULL);
+ kcd->cagecos = (const float (*)[3])BKE_editmesh_vertexCos_get(&kcd->eval_ctx, kcd->em, kcd->scene, NULL);
kcd->bmbvh = BKE_bmbvh_new_from_editmesh(
kcd->em,
@@ -2628,6 +2626,7 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
kcd->ob = obedit;
kcd->ar = CTX_wm_region(C);
+ CTX_data_eval_ctx(C, &kcd->eval_ctx);
em_setup_viewcontext(C, &kcd->vc);
kcd->em = BKE_editmesh_from_object(kcd->ob);
@@ -2637,7 +2636,7 @@ static void knifetool_init(bContext *C, KnifeTool_OpData *kcd,
kcd->cut_through = cut_through;
kcd->only_select = only_select;
- knifetool_init_bmbvh(C, kcd);
+ knifetool_init_bmbvh(kcd);
kcd->arena = BLI_memarena_new(MEM_SIZE_OPTIMAL(1 << 15), "knife");
#ifdef USE_NET_ISLAND_CONNECT
@@ -2709,7 +2708,7 @@ static int knifetool_invoke(bContext *C, wmOperator *op, const wmEvent *event)
WM_cursor_modal_set(CTX_wm_window(C), BC_KNIFECURSOR);
WM_event_add_modal_handler(C, op);
- knifetool_update_mval_i(C, kcd, event->mval);
+ knifetool_update_mval_i(kcd, event->mval);
knife_update_header(C, op, kcd);
@@ -2782,6 +2781,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_FINISHED;
}
+ CTX_data_eval_ctx(C, &kcd->eval_ctx);
em_setup_viewcontext(C, &kcd->vc);
kcd->ar = kcd->vc.ar;
@@ -2815,7 +2815,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
kcd->snap_midpoints = true;
knife_recalc_projmat(kcd);
- knife_update_active(C, kcd);
+ knife_update_active(kcd);
knife_update_header(C, op, kcd);
ED_region_tag_redraw(kcd->ar);
do_refresh = true;
@@ -2824,7 +2824,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
kcd->snap_midpoints = false;
knife_recalc_projmat(kcd);
- knife_update_active(C, kcd);
+ knife_update_active(kcd);
knife_update_header(C, op, kcd);
ED_region_tag_redraw(kcd->ar);
do_refresh = true;
@@ -2879,7 +2879,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
kcd->is_drag_hold = false;
/* needed because the last face 'hit' is ignored when dragging */
- knifetool_update_mval(C, kcd, kcd->curr.mval);
+ knifetool_update_mval(kcd, kcd->curr.mval);
}
ED_region_tag_redraw(kcd->ar);
@@ -2890,14 +2890,14 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* shouldn't be possible with default key-layout, just incase... */
if (kcd->is_drag_hold) {
kcd->is_drag_hold = false;
- knifetool_update_mval(C, kcd, kcd->curr.mval);
+ knifetool_update_mval(kcd, kcd->curr.mval);
}
kcd->prev = kcd->curr;
kcd->curr = kcd->init;
knife_project_v2(kcd, kcd->curr.cage, kcd->curr.mval);
- knifetool_update_mval(C, kcd, kcd->curr.mval);
+ knifetool_update_mval(kcd, kcd->curr.mval);
knife_add_cut(kcd);
@@ -2931,7 +2931,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_PASS_THROUGH;
case MOUSEMOVE: /* mouse moved somewhere to select another loop */
if (kcd->mode != MODE_PANNING) {
- knifetool_update_mval_i(C, kcd, event->mval);
+ knifetool_update_mval_i(kcd, event->mval);
if (kcd->is_drag_hold) {
if (kcd->totlinehit >= 2) {
@@ -2954,7 +2954,7 @@ static int knifetool_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (do_refresh) {
/* we don't really need to update mval,
* but this happens to be the best way to refresh at the moment */
- knifetool_update_mval_i(C, kcd, event->mval);
+ knifetool_update_mval_i(kcd, event->mval);
}
/* keep going until the user confirms */
@@ -3042,7 +3042,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
int i;
for (i = 0; i < mval_tot; i++) {
- knifetool_update_mval(C, kcd, mval_fl[i]);
+ knifetool_update_mval(kcd, mval_fl[i]);
if (i == 0) {
knife_start_cut(kcd);
kcd->mode = MODE_DRAGGING;
@@ -3073,7 +3073,7 @@ void EDBM_mesh_knife(bContext *C, LinkNode *polys, bool use_tag, bool cut_throug
/* freed on knifetool_finish_ex, but we need again to check if points are visible */
if (kcd->cut_through == false) {
- knifetool_init_bmbvh(C, kcd);
+ knifetool_init_bmbvh(kcd);
}
ED_view3d_ob_project_mat_get(kcd->ar->regiondata, kcd->ob, projmat);
diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c
index 8db3a2c8d04..a4a6ad82dfb 100644
--- a/source/blender/editors/mesh/editmesh_loopcut.c
+++ b/source/blender/editors/mesh/editmesh_loopcut.c
@@ -63,6 +63,8 @@
#include "WM_api.h"
#include "WM_types.h"
+#include "DEG_depsgraph.h"
+
#include "mesh_intern.h" /* own include */
#define SUBD_SMOOTH_MAX 4.0f
@@ -556,20 +558,23 @@ static void loopcut_update_edge(RingSelOpData *lcd, BMEdge *e, const int preview
}
}
-static void loopcut_mouse_move(const bContext *C, RingSelOpData *lcd, const int previewlines)
+static void loopcut_mouse_move(const struct EvaluationContext *eval_ctx, RingSelOpData *lcd, const int previewlines)
{
float dist = ED_view3d_select_dist_px();
- BMEdge *e = EDBM_edge_find_nearest(C, &lcd->vc, &dist);
+ BMEdge *e = EDBM_edge_find_nearest(eval_ctx, &lcd->vc, &dist);
loopcut_update_edge(lcd, e, previewlines);
}
/* called by both init() and exec() */
static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
{
+ EvaluationContext eval_ctx;
const bool is_interactive = (event != NULL);
Object *obedit = CTX_data_edit_object(C);
RingSelOpData *lcd;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
if (modifiers_isDeformedByLattice(obedit) || modifiers_isDeformedByArmature(obedit))
BKE_report(op->reports, RPT_WARNING, "Loop cut does not work well on deformed edit mesh display");
@@ -597,7 +602,7 @@ static int loopcut_init(bContext *C, wmOperator *op, const wmEvent *event)
if (is_interactive) {
copy_v2_v2_int(lcd->vc.mval, event->mval);
- loopcut_mouse_move(C, lcd, is_interactive ? 1 : 0);
+ loopcut_mouse_move(&eval_ctx, lcd, is_interactive ? 1 : 0);
}
else {
const int e_index = RNA_int_get(op->ptr, "edge_index");
@@ -670,12 +675,14 @@ static int loopcut_finish(RingSelOpData *lcd, bContext *C, wmOperator *op)
static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
+ EvaluationContext eval_ctx;
RingSelOpData *lcd = op->customdata;
float cuts = lcd->cuts;
float smoothness = lcd->smoothness;
bool show_cuts = false;
const bool has_numinput = hasNumInput(&lcd->num);
+ CTX_data_eval_ctx(C, &eval_ctx);
em_setup_viewcontext(C, &lcd->vc);
lcd->ar = lcd->vc.ar;
@@ -761,7 +768,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (!has_numinput) {
lcd->vc.mval[0] = event->mval[0];
lcd->vc.mval[1] = event->mval[1];
- loopcut_mouse_move(C, lcd, (int)lcd->cuts);
+ loopcut_mouse_move(&eval_ctx, lcd, (int)lcd->cuts);
ED_region_tag_redraw(lcd->ar);
handled = true;
diff --git a/source/blender/editors/mesh/editmesh_path.c b/source/blender/editors/mesh/editmesh_path.c
index 0a36b735f39..29bca00f1a9 100644
--- a/source/blender/editors/mesh/editmesh_path.c
+++ b/source/blender/editors/mesh/editmesh_path.c
@@ -59,6 +59,8 @@
#include "bmesh.h"
#include "bmesh_tools.h"
+#include "DEG_depsgraph.h"
+
#include "mesh_intern.h" /* own include */
struct PathSelectParams {
@@ -570,19 +572,19 @@ static bool edbm_shortest_path_pick_ex(
static int edbm_shortest_path_pick_exec(bContext *C, wmOperator *op);
-static BMElem *edbm_elem_find_nearest(const bContext *C, ViewContext *vc, const char htype)
+static BMElem *edbm_elem_find_nearest(const struct EvaluationContext *eval_ctx, ViewContext *vc, const char htype)
{
BMEditMesh *em = vc->em;
float dist = ED_view3d_select_dist_px();
if ((em->selectmode & SCE_SELECT_VERTEX) && (htype == BM_VERT)) {
- return (BMElem *)EDBM_vert_find_nearest(C, vc, &dist);
+ return (BMElem *)EDBM_vert_find_nearest(eval_ctx, vc, &dist);
}
else if ((em->selectmode & SCE_SELECT_EDGE) && (htype == BM_EDGE)) {
- return (BMElem *)EDBM_edge_find_nearest(C, vc, &dist);
+ return (BMElem *)EDBM_edge_find_nearest(eval_ctx, vc, &dist);
}
else if ((em->selectmode & SCE_SELECT_FACE) && (htype == BM_FACE)) {
- return (BMElem *)EDBM_face_find_nearest(C, vc, &dist);
+ return (BMElem *)EDBM_face_find_nearest(eval_ctx, vc, &dist);
}
return NULL;
@@ -605,10 +607,12 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
return edbm_shortest_path_pick_exec(C, op);
}
+ EvaluationContext eval_ctx;
ViewContext vc;
BMEditMesh *em;
bool track_active = true;
+ CTX_data_eval_ctx(C, &eval_ctx);
em_setup_viewcontext(C, &vc);
copy_v2_v2_int(vc.mval, event->mval);
em = vc.em;
@@ -617,14 +621,14 @@ static int edbm_shortest_path_pick_invoke(bContext *C, wmOperator *op, const wmE
BMElem *ele_src, *ele_dst;
if (!(ele_src = edbm_elem_active_elem_or_face_get(em->bm)) ||
- !(ele_dst = edbm_elem_find_nearest(C, &vc, ele_src->head.htype)))
+ !(ele_dst = edbm_elem_find_nearest(&eval_ctx, &vc, ele_src->head.htype)))
{
/* special case, toggle edge tags even when we don't have a path */
if (((em->selectmode & SCE_SELECT_EDGE) &&
(vc.scene->toolsettings->edge_mode != EDGE_MODE_SELECT)) &&
/* check if we only have a destination edge */
((ele_src == NULL) &&
- (ele_dst = edbm_elem_find_nearest(C, &vc, BM_EDGE))))
+ (ele_dst = edbm_elem_find_nearest(&eval_ctx, &vc, BM_EDGE))))
{
ele_src = ele_dst;
track_active = false;
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index 97ae8ae166d..7fe4e58d2e0 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -68,6 +68,8 @@
#include "bmesh_tools.h"
+#include "DEG_depsgraph.h"
+
#include "mesh_intern.h" /* own include */
/* use bmesh operator flags for a few operators */
@@ -194,7 +196,9 @@ static BLI_bitmap *edbm_backbuf_alloc(const int size)
/* reads rect, and builds selection array for quick lookup */
/* returns if all is OK */
-bool EDBM_backbuf_border_init(const bContext *C, ViewContext *vc, short xmin, short ymin, short xmax, short ymax)
+bool EDBM_backbuf_border_init(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, short xmin,
+ short ymin, short xmax, short ymax)
{
struct ImBuf *buf;
unsigned int *dr;
@@ -204,7 +208,7 @@ bool EDBM_backbuf_border_init(const bContext *C, ViewContext *vc, short xmin, sh
return false;
}
- buf = ED_view3d_backbuf_read(C, vc, xmin, ymin, xmax, ymax);
+ buf = ED_view3d_backbuf_read(eval_ctx, vc, xmin, ymin, xmax, ymax);
if ((buf == NULL) || (bm_vertoffs == 0)) {
return false;
}
@@ -267,7 +271,7 @@ static void edbm_mask_lasso_px_cb(int x, int x_end, int y, void *user_data)
* - grab again and compare
* returns 'OK'
*/
-bool EDBM_backbuf_border_mask_init(const bContext *C, ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
+bool EDBM_backbuf_border_mask_init(const struct EvaluationContext *eval_ctx, ViewContext *vc, const int mcords[][2], short tot, short xmin, short ymin, short xmax, short ymax)
{
unsigned int *dr, *dr_mask, *dr_mask_arr;
struct ImBuf *buf;
@@ -284,7 +288,7 @@ bool EDBM_backbuf_border_mask_init(const bContext *C, ViewContext *vc, const int
return false;
}
- buf = ED_view3d_backbuf_read(C, vc, xmin, ymin, xmax, ymax);
+ buf = ED_view3d_backbuf_read(eval_ctx, vc, xmin, ymin, xmax, ymax);
if ((buf == NULL) || (bm_vertoffs == 0)) {
return false;
}
@@ -317,7 +321,9 @@ bool EDBM_backbuf_border_mask_init(const bContext *C, ViewContext *vc, const int
}
/* circle shaped sample area */
-bool EDBM_backbuf_circle_init(const bContext *C, ViewContext *vc, short xs, short ys, short rads)
+bool EDBM_backbuf_circle_init(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc,
+ short xs, short ys, short rads)
{
struct ImBuf *buf;
unsigned int *dr;
@@ -336,7 +342,7 @@ bool EDBM_backbuf_circle_init(const bContext *C, ViewContext *vc, short xs, shor
xmin = xs - rads; xmax = xs + rads;
ymin = ys - rads; ymax = ys + rads;
- buf = ED_view3d_backbuf_read(C, vc, xmin, ymin, xmax, ymax);
+ buf = ED_view3d_backbuf_read(eval_ctx, vc, xmin, ymin, xmax, ymax);
if ((buf == NULL) || (bm_vertoffs == 0)) {
return false;
}
@@ -435,7 +441,7 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, const float
* \param use_cycle Cycle over elements within #FIND_NEAR_CYCLE_THRESHOLD_MIN in order of index.
*/
BMVert *EDBM_vert_find_nearest_ex(
- const bContext *C, ViewContext *vc, float *r_dist,
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, float *r_dist,
const bool use_select_bias, bool use_cycle)
{
BMesh *bm = vc->em->bm;
@@ -447,10 +453,10 @@ BMVert *EDBM_vert_find_nearest_ex(
BMVert *eve;
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
- ED_view3d_backbuf_validate(C, vc);
+ ED_view3d_backbuf_validate(eval_ctx, vc);
index = ED_view3d_backbuf_sample_rect(
- C, vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test);
+ eval_ctx, vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test);
eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL;
if (eve) {
@@ -485,7 +491,7 @@ BMVert *EDBM_vert_find_nearest_ex(
data.cycle_index_prev = prev_select_index;
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenVert(C, vc, findnearestvert__doClosest, &data, clip_flag);
+ mesh_foreachScreenVert(eval_ctx, vc, findnearestvert__doClosest, &data, clip_flag);
hit = (data.use_cycle && data.hit_cycle.vert) ? &data.hit_cycle : &data.hit;
*r_dist = hit->dist;
@@ -497,9 +503,9 @@ BMVert *EDBM_vert_find_nearest_ex(
}
}
-BMVert *EDBM_vert_find_nearest(const bContext *C, ViewContext *vc, float *r_dist)
+BMVert *EDBM_vert_find_nearest(const struct EvaluationContext *eval_ctx, ViewContext *vc, float *r_dist)
{
- return EDBM_vert_find_nearest_ex(C, vc, r_dist, false, false);
+ return EDBM_vert_find_nearest_ex(eval_ctx, vc, r_dist, false, false);
}
/* find the distance to the edge we already have */
@@ -621,7 +627,7 @@ static void find_nearest_edge__doClosest(
}
BMEdge *EDBM_edge_find_nearest_ex(
- const bContext *C, ViewContext *vc, float *r_dist,
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, float *r_dist,
float *r_dist_center,
const bool use_select_bias, const bool use_cycle,
BMEdge **r_eed_zbuf)
@@ -635,9 +641,9 @@ BMEdge *EDBM_edge_find_nearest_ex(
BMEdge *eed;
/* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
- ED_view3d_backbuf_validate(C, vc);
+ ED_view3d_backbuf_validate(eval_ctx, vc);
- index = ED_view3d_backbuf_sample_rect(C, vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test);
+ index = ED_view3d_backbuf_sample_rect(eval_ctx, vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test);
eed = index ? BM_edge_at_index_find_or_table(bm, index - 1) : NULL;
if (r_eed_zbuf) {
@@ -655,7 +661,7 @@ BMEdge *EDBM_edge_find_nearest_ex(
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenEdge(C, vc, find_nearest_edge_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenEdge(eval_ctx, vc, find_nearest_edge_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
*r_dist_center = data.dist;
}
@@ -695,7 +701,7 @@ BMEdge *EDBM_edge_find_nearest_ex(
data.cycle_index_prev = prev_select_index;
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenEdge(C, vc, find_nearest_edge__doClosest, &data, clip_flag);
+ mesh_foreachScreenEdge(eval_ctx, vc, find_nearest_edge__doClosest, &data, clip_flag);
hit = (data.use_cycle && data.hit_cycle.edge) ? &data.hit_cycle : &data.hit;
*r_dist = hit->dist;
@@ -711,9 +717,9 @@ BMEdge *EDBM_edge_find_nearest_ex(
}
BMEdge *EDBM_edge_find_nearest(
- const bContext *C, ViewContext *vc, float *r_dist)
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, float *r_dist)
{
- return EDBM_edge_find_nearest_ex(C, vc, r_dist, NULL, false, false, NULL);
+ return EDBM_edge_find_nearest_ex(eval_ctx, vc, r_dist, NULL, false, false, NULL);
}
/* find the distance to the face we already have */
@@ -787,7 +793,7 @@ static void findnearestface__doClosest(void *userData, BMFace *efa, const float
BMFace *EDBM_face_find_nearest_ex(
- const bContext *C, ViewContext *vc, float *r_dist,
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, float *r_dist,
float *r_dist_center,
const bool use_select_bias, const bool use_cycle,
BMFace **r_efa_zbuf)
@@ -799,9 +805,9 @@ BMFace *EDBM_face_find_nearest_ex(
unsigned int index;
BMFace *efa;
- ED_view3d_backbuf_validate(C, vc);
+ ED_view3d_backbuf_validate(eval_ctx, vc);
- index = ED_view3d_backbuf_sample(C, vc, vc->mval[0], vc->mval[1]);
+ index = ED_view3d_backbuf_sample(eval_ctx, vc, vc->mval[0], vc->mval[1]);
efa = index ? BM_face_at_index_find_or_table(bm, index - 1) : NULL;
if (r_efa_zbuf) {
@@ -819,7 +825,7 @@ BMFace *EDBM_face_find_nearest_ex(
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenFace(C, vc, find_nearest_face_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenFace(eval_ctx, vc, find_nearest_face_center__doZBuf, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
*r_dist_center = data.dist;
}
@@ -857,7 +863,7 @@ BMFace *EDBM_face_find_nearest_ex(
data.cycle_index_prev = prev_select_index;
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
- mesh_foreachScreenFace(C, vc, findnearestface__doClosest, &data, clip_flag);
+ mesh_foreachScreenFace(eval_ctx, vc, findnearestface__doClosest, &data, clip_flag);
hit = (data.use_cycle && data.hit_cycle.face) ? &data.hit_cycle : &data.hit;
*r_dist = hit->dist;
@@ -872,9 +878,9 @@ BMFace *EDBM_face_find_nearest_ex(
}
}
-BMFace *EDBM_face_find_nearest(const bContext *C, ViewContext *vc, float *r_dist)
+BMFace *EDBM_face_find_nearest(const struct EvaluationContext *eval_ctx, ViewContext *vc, float *r_dist)
{
- return EDBM_face_find_nearest_ex(C, vc, r_dist, NULL, false, false, NULL);
+ return EDBM_face_find_nearest_ex(eval_ctx, vc, r_dist, NULL, false, false, NULL);
}
#undef FIND_NEAR_SELECT_BIAS
@@ -886,7 +892,9 @@ BMFace *EDBM_face_find_nearest(const bContext *C, ViewContext *vc, float *r_dist
* selected vertices and edges get disadvantage
* return 1 if found one
*/
-static int unified_findnearest(const bContext *C, ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
+static int unified_findnearest(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc,
+ BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa)
{
BMEditMesh *em = vc->em;
static short mval_prev[2] = {-1, -1};
@@ -905,12 +913,12 @@ static int unified_findnearest(const bContext *C, ViewContext *vc, BMVert **r_ev
/* no afterqueue (yet), so we check it now, otherwise the em_xxxofs indices are bad */
- ED_view3d_backbuf_validate(C, vc);
+ ED_view3d_backbuf_validate(eval_ctx, vc);
if ((dist > 0.0f) && em->selectmode & SCE_SELECT_FACE) {
float dist_center = 0.0f;
float *dist_center_p = (em->selectmode & (SCE_SELECT_EDGE | SCE_SELECT_VERTEX)) ? &dist_center : NULL;
- efa = EDBM_face_find_nearest_ex(C, vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf);
+ efa = EDBM_face_find_nearest_ex(eval_ctx, vc, &dist, dist_center_p, true, use_cycle, &efa_zbuf);
if (efa && dist_center_p) {
dist = min_ff(dist_margin, dist_center);
}
@@ -919,14 +927,14 @@ static int unified_findnearest(const bContext *C, ViewContext *vc, BMVert **r_ev
if ((dist > 0.0f) && (em->selectmode & SCE_SELECT_EDGE)) {
float dist_center = 0.0f;
float *dist_center_p = (em->selectmode & SCE_SELECT_VERTEX) ? &dist_center : NULL;
- eed = EDBM_edge_find_nearest_ex(C, vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf);
+ eed = EDBM_edge_find_nearest_ex(eval_ctx, vc, &dist, dist_center_p, true, use_cycle, &eed_zbuf);
if (eed && dist_center_p) {
dist = min_ff(dist_margin, dist_center);
}
}
if ((dist > 0.0f) && em->selectmode & SCE_SELECT_VERTEX) {
- eve = EDBM_vert_find_nearest_ex(C, vc, &dist, true, use_cycle);
+ eve = EDBM_vert_find_nearest_ex(eval_ctx, vc, &dist, true, use_cycle);
}
/* return only one of 3 pointers, for frontbuffer redraws */
@@ -1559,6 +1567,7 @@ static void mouse_mesh_loop_edge(BMEditMesh *em, BMEdge *eed, bool select, bool
static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle, bool ring)
{
+ EvaluationContext eval_ctx;
ViewContext vc;
BMEditMesh *em;
BMEdge *eed;
@@ -1568,15 +1577,16 @@ static bool mouse_mesh_loop(bContext *C, const int mval[2], bool extend, bool de
float dist = ED_view3d_select_dist_px() * 0.6666f;
float mvalf[2];
+ CTX_data_eval_ctx(C, &eval_ctx);
em_setup_viewcontext(C, &vc);
mvalf[0] = (float)(vc.mval[0] = mval[0]);
mvalf[1] = (float)(vc.mval[1] = mval[1]);
em = vc.em;
/* no afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad */
- ED_view3d_backbuf_validate(C, &vc);
+ ED_view3d_backbuf_validate(&eval_ctx, &vc);
- eed = EDBM_edge_find_nearest_ex(C, &vc, &dist, NULL, true, true, NULL);
+ eed = EDBM_edge_find_nearest_ex(&eval_ctx, &vc, &dist, NULL, true, true, NULL);
if (eed == NULL) {
return false;
}
@@ -1819,17 +1829,19 @@ void MESH_OT_select_interior_faces(wmOperatorType *ot)
/* gets called via generic mouse select operator */
bool EDBM_select_pick(bContext *C, const int mval[2], bool extend, bool deselect, bool toggle)
{
+ EvaluationContext eval_ctx;
ViewContext vc;
BMVert *eve = NULL;
BMEdge *eed = NULL;
BMFace *efa = NULL;
/* setup view context for argument to callbacks */
+ CTX_data_eval_ctx(C, &eval_ctx);
em_setup_viewcontext(C, &vc);
vc.mval[0] = mval[0];
vc.mval[1] = mval[1];
- if (unified_findnearest(C, &vc, &eve, &eed, &efa)) {
+ if (unified_findnearest(&eval_ctx, &vc, &eve, &eed, &efa)) {
/* Deselect everything */
if (extend == false && deselect == false && toggle == false)
@@ -2793,6 +2805,7 @@ static void edbm_select_linked_pick_ex(BMEditMesh *em, BMElem *ele, bool sel, in
static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *obedit = CTX_data_edit_object(C);
+ EvaluationContext eval_ctx;
ViewContext vc;
BMEditMesh *em;
BMesh *bm;
@@ -2810,6 +2823,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
view3d_operator_needs_opengl(C);
/* setup view context for argument to callbacks */
+ CTX_data_eval_ctx(C, &eval_ctx);
em_setup_viewcontext(C, &vc);
em = vc.em;
bm = em->bm;
@@ -2822,7 +2836,7 @@ static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmE
vc.mval[1] = event->mval[1];
/* return warning! */
- if (unified_findnearest(C, &vc, &eve, &eed, &efa) == 0) {
+ if (unified_findnearest(&eval_ctx, &vc, &eve, &eed, &efa) == 0) {
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit);
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 023b05db62f..62d087257ea 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -317,7 +317,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em)
float mval[2], co_proj[3];
if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) {
if (ED_transform_snap_object_project_view3d_mixed(
- C, snap_context,
+ snap_context,
SCE_SELECT_FACE,
&(const struct SnapObjectParams){
.snap_select = SNAP_NOT_ACTIVE,
@@ -5063,7 +5063,7 @@ static void sort_bmelem_flag(Scene *scene, Object *ob,
}
BM_mesh_remap(em->bm, map[0], map[1], map[2]);
-/* DAG_id_tag_update(ob->data, 0);*/
+/* DEG_id_tag_update(ob->data, 0);*/
for (j = 3; j--; ) {
if (map[j])
diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c
index 555fe6c917d..f24b7911e34 100644
--- a/source/blender/editors/mesh/editmesh_utils.c
+++ b/source/blender/editors/mesh/editmesh_utils.c
@@ -383,7 +383,7 @@ void EDBM_mesh_make(ToolSettings *ts, Object *ob, const bool add_key_index)
/**
* \warning This can invalidate the #DerivedMesh cache of other objects (for linked duplicates).
- * Most callers should run #DAG_id_tag_update on \a ob->data, see: T46738, T46913
+ * Most callers should run #DEG_id_tag_update on \a ob->data, see: T46738, T46913
*/
void EDBM_mesh_load(Object *ob)
{
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 7ec8e42e6df..8fddf2551b8 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -88,6 +88,7 @@ static void join_mesh_single(
Material **matar, int *matmap, int totcol,
int *vertofs, int *edgeofs, int *loopofs, int *polyofs)
{
+ EvaluationContext eval_ctx;
int a, b;
Mesh *me = base_src->object->data;
@@ -95,7 +96,6 @@ static void join_mesh_single(
MEdge *medge = *medge_pp;
MLoop *mloop = *mloop_pp;
MPoly *mpoly = *mpoly_pp;
- EvaluationContext eval_ctx;
CTX_data_eval_ctx(C, &eval_ctx);
@@ -1106,6 +1106,7 @@ int *mesh_get_x_mirror_faces(Object *ob, BMEditMesh *em, DerivedMesh *dm)
*/
bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int *index, int size)
{
+ EvaluationContext eval_ctx;
ViewContext vc;
Mesh *me = ob->data;
@@ -1114,6 +1115,7 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int
if (!me || me->totpoly == 0)
return false;
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
if (size) {
@@ -1121,11 +1123,11 @@ bool ED_mesh_pick_face(bContext *C, Object *ob, const int mval[2], unsigned int
* on an edge in the backbuf, we can still select a face */
float dummy_dist;
- *index = ED_view3d_backbuf_sample_rect(C, &vc, mval, size, 1, me->totpoly + 1, &dummy_dist);
+ *index = ED_view3d_backbuf_sample_rect(&eval_ctx, &vc, mval, size, 1, me->totpoly + 1, &dummy_dist);
}
else {
/* sample only on the exact position */
- *index = ED_view3d_backbuf_sample(C, &vc, mval[0], mval[1]);
+ *index = ED_view3d_backbuf_sample(&eval_ctx, &vc, mval[0], mval[1]);
}
if ((*index) == 0 || (*index) > (unsigned int)me->totpoly)
@@ -1293,11 +1295,11 @@ bool ED_mesh_pick_vert(bContext *C, Object *ob, const int mval[2], unsigned int
* on an face in the backbuf, we can still select a vert */
float dummy_dist;
- *index = ED_view3d_backbuf_sample_rect(C, &vc, mval, size, 1, me->totvert + 1, &dummy_dist);
+ *index = ED_view3d_backbuf_sample_rect(&eval_ctx, &vc, mval, size, 1, me->totvert + 1, &dummy_dist);
}
else {
/* sample only on the exact position */
- *index = ED_view3d_backbuf_sample(C, &vc, mval[0], mval[1]);
+ *index = ED_view3d_backbuf_sample(&eval_ctx, &vc, mval[0], mval[1]);
}
if ((*index) == 0 || (*index) > (unsigned int)me->totvert)
diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c
index 4a7e08c522e..d987808412a 100644
--- a/source/blender/editors/metaball/mball_edit.c
+++ b/source/blender/editors/metaball/mball_edit.c
@@ -584,6 +584,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
{
static MetaElem *startelem = NULL;
Object *obedit = CTX_data_edit_object(C);
+ EvaluationContext eval_ctx;
ViewContext vc;
MetaBall *mb = (MetaBall *)obedit->data;
MetaElem *ml, *ml_act = NULL;
@@ -591,11 +592,12 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese
unsigned int buffer[MAXPICKBUF];
rcti rect;
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
BLI_rcti_init_pt_radius(&rect, mval, 12);
- hits = view3d_opengl_select(C, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
+ hits = view3d_opengl_select(&eval_ctx, &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST);
/* does startelem exist? */
ml = mb->editelems->first;
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index a7cc8e44443..7df436efdd5 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1427,86 +1427,84 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
{
Main *bmain = CTX_data_main(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- ListBase *lb;
+ ListBase *lb_duplis;
DupliObject *dob;
- GHash *dupli_gh = NULL, *parent_gh = NULL;
- Object *object;
+ GHash *dupli_gh, *parent_gh = NULL;
- if (!(base->object->transflag & OB_DUPLI))
+ if (!(base->object->transflag & OB_DUPLI)) {
return;
+ }
- lb = object_duplilist(bmain->eval_ctx, scene, base->object);
+ lb_duplis = object_duplilist(bmain->eval_ctx, scene, base->object);
- if (use_hierarchy || use_base_parent) {
- dupli_gh = BLI_ghash_ptr_new(__func__);
- if (use_hierarchy) {
- if (base->object->transflag & OB_DUPLIGROUP) {
- parent_gh = BLI_ghash_new(dupliobject_group_hash, dupliobject_group_cmp, __func__);
- }
- else {
- parent_gh = BLI_ghash_new(dupliobject_hash, dupliobject_cmp, __func__);
- }
+ dupli_gh = BLI_ghash_ptr_new(__func__);
+ if (use_hierarchy) {
+ if (base->object->transflag & OB_DUPLIGROUP) {
+ parent_gh = BLI_ghash_new(dupliobject_group_hash, dupliobject_group_cmp, __func__);
+ }
+ else {
+ parent_gh = BLI_ghash_new(dupliobject_hash, dupliobject_cmp, __func__);
}
}
- for (dob = lb->first; dob; dob = dob->next) {
- Base *basen;
- Object *ob = ID_NEW_SET(dob->ob, BKE_object_copy(bmain, dob->ob));
+ for (dob = lb_duplis->first; dob; dob = dob->next) {
+ Object *ob_src = dob->ob;
+ Object *ob_dst = ID_NEW_SET(dob->ob, BKE_object_copy(bmain, ob_src));
+ Base *base_dst;
/* font duplis can have a totcol without material, we get them from parent
* should be implemented better...
*/
- if (ob->mat == NULL) ob->totcol = 0;
+ if (ob_dst->mat == NULL) {
+ ob_dst->totcol = 0;
+ }
- BKE_collection_object_add_from(scene, dob->ob, ob);
- basen = BKE_scene_layer_base_find(sl, ob);
+ BKE_collection_object_add_from(scene, ob_src, ob_dst);
+ base_dst = BKE_scene_layer_base_find(sl, ob_dst);
- BKE_scene_object_base_flag_sync_from_base(basen);
+ BKE_scene_object_base_flag_sync_from_base(base_dst);
/* make sure apply works */
- BKE_animdata_free(&ob->id, true);
- ob->adt = NULL;
+ BKE_animdata_free(&ob_dst->id, true);
+ ob_dst->adt = NULL;
/* Proxies are not to be copied. */
- ob->proxy_from = NULL;
- ob->proxy_group = NULL;
- ob->proxy = NULL;
+ ob_dst->proxy_from = NULL;
+ ob_dst->proxy_group = NULL;
+ ob_dst->proxy = NULL;
- ob->parent = NULL;
- BKE_constraints_free(&ob->constraints);
- ob->curve_cache = NULL;
- ob->transflag &= ~OB_DUPLI;
+ ob_dst->parent = NULL;
+ BKE_constraints_free(&ob_dst->constraints);
+ ob_dst->curve_cache = NULL;
+ ob_dst->transflag &= ~OB_DUPLI;
- copy_m4_m4(ob->obmat, dob->mat);
- BKE_object_apply_mat4(ob, ob->obmat, false, false);
+ copy_m4_m4(ob_dst->obmat, dob->mat);
+ BKE_object_apply_mat4(ob_dst, ob_dst->obmat, false, false);
- if (dupli_gh) {
- BLI_ghash_insert(dupli_gh, dob, ob);
- }
+ BLI_ghash_insert(dupli_gh, dob, ob_dst);
if (parent_gh) {
void **val;
/* Due to nature of hash/comparison of this ghash, a lot of duplis may be considered as 'the same',
* this avoids trying to insert same key several time and raise asserts in debug builds... */
if (!BLI_ghash_ensure_p(parent_gh, dob, &val)) {
- *val = ob;
+ *val = ob_dst;
}
}
+ }
+
+ for (dob = lb_duplis->first; dob; dob = dob->next) {
+ Object *ob_src = dob->ob;
+ Object *ob_dst = BLI_ghash_lookup(dupli_gh, dob);
/* Remap new object to itself, and clear again newid pointer of orig object. */
- BKE_libblock_relink_to_newid(&ob->id);
- set_sca_new_poins_ob(ob);
- BKE_id_clear_newpoin(&dob->ob->id);
+ BKE_libblock_relink_to_newid(&ob_dst->id);
+ set_sca_new_poins_ob(ob_dst);
- DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
- }
+ DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
- if (use_hierarchy) {
- for (dob = lb->first; dob; dob = dob->next) {
+ if (use_hierarchy) {
/* original parents */
- Object *ob_src = dob->ob;
Object *ob_src_par = ob_src->parent;
-
- Object *ob_dst = BLI_ghash_lookup(dupli_gh, dob);
Object *ob_dst_par = NULL;
/* find parent that was also made real */
@@ -1517,8 +1515,8 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
dob_key.ob = ob_src_par;
if (base->object->transflag & OB_DUPLIGROUP) {
memcpy(&dob_key.persistent_id[1],
- &dob->persistent_id[1],
- sizeof(dob->persistent_id[1]) * (MAX_DUPLI_RECUR - 1));
+ &dob->persistent_id[1],
+ sizeof(dob->persistent_id[1]) * (MAX_DUPLI_RECUR - 1));
}
else {
dob_key.persistent_id[0] = dob->persistent_id[0];
@@ -1542,49 +1540,42 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
ob_dst->parent = base->object;
ob_dst->partype = PAROBJECT;
}
-
- if (ob_dst->parent) {
- /* note, this may be the parent of other objects, but it should
- * still work out ok */
- BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
-
- /* to set ob_dst->orig and in case theres any other discrepicies */
- DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
- }
}
- }
- else if (use_base_parent) {
- /* since we are ignoring the internal hierarchy - parent all to the
- * base object */
- for (dob = lb->first; dob; dob = dob->next) {
- /* original parents */
- Object *ob_dst = BLI_ghash_lookup(dupli_gh, dob);
-
+ else if (use_base_parent) {
+ /* since we are ignoring the internal hierarchy - parent all to the
+ * base object */
ob_dst->parent = base->object;
ob_dst->partype = PAROBJECT;
+ }
- /* similer to the code above, see comments */
+ if (ob_dst->parent) {
+ /* note, this may be the parent of other objects, but it should
+ * still work out ok */
BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
+
+ /* to set ob_dst->orig and in case theres any other discrepicies */
DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
}
}
if (base->object->transflag & OB_DUPLIGROUP && base->object->dup_group) {
- for (object = bmain->object.first; object; object = object->id.next) {
- if (object->proxy_group == base->object) {
- object->proxy = NULL;
- object->proxy_from = NULL;
- DEG_id_tag_update(&object->id, OB_RECALC_OB);
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->proxy_group == base->object) {
+ ob->proxy = NULL;
+ ob->proxy_from = NULL;
+ DEG_id_tag_update(&ob->id, OB_RECALC_OB);
}
}
}
- if (dupli_gh)
- BLI_ghash_free(dupli_gh, NULL, NULL);
- if (parent_gh)
+ BLI_ghash_free(dupli_gh, NULL, NULL);
+ if (parent_gh) {
BLI_ghash_free(parent_gh, NULL, NULL);
+ }
+
+ free_object_duplilist(lb_duplis);
- free_object_duplilist(lb);
+ BKE_main_id_clear_newpoins(bmain);
base->object->transflag &= ~OB_DUPLI;
}
@@ -2038,11 +2029,11 @@ static int convert_exec(bContext *C, wmOperator *op)
if (basact) {
/* active base was changed */
ED_object_base_activate(C, basact);
- BASACT_NEW = basact;
+ BASACT_NEW(sl) = basact;
}
- else if (BASACT_NEW->object->flag & OB_DONE) {
- WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT_NEW->object);
- WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT_NEW->object);
+ else if (BASACT_NEW(sl)->object->flag & OB_DONE) {
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, BASACT_NEW(sl)->object);
+ WM_event_add_notifier(C, NC_OBJECT | ND_DATA, BASACT_NEW(sl)->object);
}
DEG_relations_tag_update(bmain);
@@ -2375,7 +2366,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
}
/* new object becomes active */
- if (BASACT_NEW == base)
+ if (BASACT_NEW(sl) == base)
ED_object_base_activate(C, basen);
if (basen->object->data) {
diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c
index e3dd47295fe..b02cb3e02a8 100644
--- a/source/blender/editors/object/object_bake.c
+++ b/source/blender/editors/object/object_bake.c
@@ -625,7 +625,7 @@ static void init_bake_internal(BakeRender *bkr, bContext *C)
bkr->sa = sc ? BKE_screen_find_big_area(sc, SPACE_IMAGE, 10) : NULL; /* can be NULL */
bkr->main = CTX_data_main(C);
bkr->scene = scene;
- bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT_NEW : NULL;
+ bkr->actob = (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT_NEW(sl) : NULL;
bkr->re = RE_NewRender("_Bake View_");
if (scene->r.bake_mode == RE_BAKE_AO) {
@@ -858,7 +858,7 @@ static int bake_image_exec(bContext *C, wmOperator *op)
RE_test_break_cb(bkr.re, NULL, thread_break);
G.is_break = false; /* BKE_blender_test_break uses this global */
- RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT_NEW : NULL);
+ RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE) ? OBACT_NEW(sl) : NULL);
/* baking itself is threaded, cannot use test_break in threads */
BLI_init_threads(&threads, do_bake_render, 1);
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 0605be5c773..4e578906e07 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -1689,14 +1689,14 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Base *base = BASACT_NEW, *newbase = NULL;
+ Base *base = BASACT_NEW(sl), *newbase = NULL;
Object *obt;
/* add new target object */
obt = BKE_object_add(bmain, scene, sl, OB_EMPTY, NULL);
/* set layers OK */
- newbase = BASACT_NEW;
+ newbase = BASACT_NEW(sl);
newbase->lay = base->lay;
obt->lay = newbase->lay;
@@ -1715,7 +1715,7 @@ static bool get_new_constraint_target(bContext *C, int con_type, Object **tar_ob
}
/* restore, BKE_object_add sets active */
- BASACT_NEW = base;
+ BASACT_NEW(sl) = base;
base->flag |= BASE_SELECTED;
/* make our new target the new object */
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 90de4517a52..850b772baed 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -545,8 +545,8 @@ static void copymenu_properties(SceneLayer *sl, Object *ob)
nr = pupmenu(str);
if (nr == 1 || nr == 2) {
- for (base = FIRSTBASE_NEW; base; base = base->next) {
- if ((base != BASACT_NEW) && (TESTBASELIB_NEW(base))) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
+ if ((base != BASACT_NEW(sl)) && (TESTBASELIB_NEW(base))) {
if (nr == 1) { /* replace */
BKE_bproperty_copy_list(&base->object->prop, &ob->prop);
}
@@ -562,8 +562,8 @@ static void copymenu_properties(SceneLayer *sl, Object *ob)
prop = BLI_findlink(&ob->prop, nr - 4); /* account for first 3 menu items & menu index starting at 1*/
if (prop) {
- for (base = FIRSTBASE_NEW; base; base = base->next) {
- if ((base != BASACT_NEW) && (TESTBASELIB_NEW(base))) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
+ if ((base != BASACT_NEW(sl)) && (TESTBASELIB_NEW(base))) {
BKE_bproperty_object_set(base->object, prop);
}
}
@@ -578,7 +578,7 @@ static void copymenu_logicbricks(SceneLayer *sl, Object *ob)
//XXX no longer used - to be removed - replaced by logicbricks_copy_exec
Base *base;
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (base->object != ob) {
if (TESTBASELIB_NEW(base)) {
@@ -591,9 +591,9 @@ static void copymenu_logicbricks(SceneLayer *sl, Object *ob)
/* now copy it, this also works without logicbricks! */
clear_sca_new_poins_ob(ob);
- copy_sensors(&base->object->sensors, &ob->sensors);
- copy_controllers(&base->object->controllers, &ob->controllers);
- copy_actuators(&base->object->actuators, &ob->actuators);
+ copy_sensors(&base->object->sensors, &ob->sensors, 0);
+ copy_controllers(&base->object->controllers, &ob->controllers, 0);
+ copy_actuators(&base->object->actuators, &ob->actuators, 0);
set_sca_new_poins_ob(base->object);
/* some menu settings */
@@ -669,7 +669,7 @@ static void copy_attr(Main *bmain, Scene *scene, SceneLayer *sl, short event)
if (ID_IS_LINKED_DATABLOCK(scene)) return;
- if (!(ob = OBACT_NEW)) return;
+ if (!(ob = OBACT_NEW(sl))) return;
if (scene->obedit) { // XXX get from context
/* obedit_copymenu(); */
@@ -689,8 +689,8 @@ static void copy_attr(Main *bmain, Scene *scene, SceneLayer *sl, short event)
return;
}
- for (base = FIRSTBASE_NEW; base; base = base->next) {
- if (base != BASACT_NEW) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
+ if (base != BASACT_NEW(sl)) {
if (TESTBASELIB_NEW(base)) {
DEG_id_tag_update(&base->object->id, OB_RECALC_DATA);
@@ -752,7 +752,7 @@ static void copy_attr(Main *bmain, Scene *scene, SceneLayer *sl, short event)
base->object->collision_boundtype = ob->collision_boundtype;
}
base->object->margin = ob->margin;
- base->object->bsoft = copy_bulletsoftbody(ob->bsoft);
+ base->object->bsoft = copy_bulletsoftbody(ob->bsoft, 0);
}
else if (event == 17) { /* tex space */
@@ -860,7 +860,7 @@ static void copy_attr(Main *bmain, Scene *scene, SceneLayer *sl, short event)
base->object->softflag = ob->softflag;
if (base->object->soft) sbFree(base->object->soft);
- base->object->soft = copy_softbody(ob->soft, false);
+ base->object->soft = copy_softbody(ob->soft, 0);
if (!modifiers_findByType(base->object, eModifierType_Softbody)) {
BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody));
@@ -916,7 +916,7 @@ static void UNUSED_FUNCTION(copy_attr_menu) (Main *bmain, Scene *scene, SceneLay
short event;
char str[512];
- if (!(ob = OBACT_NEW)) return;
+ if (!(ob = OBACT_NEW(sl))) return;
if (scene->obedit) { /* XXX get from context */
/* if (ob->type == OB_MESH) */
@@ -1341,7 +1341,7 @@ static void UNUSED_FUNCTION(image_aspect) (Scene *scene, SceneLayer *sl)
if (scene->obedit) return; // XXX get from context
if (ID_IS_LINKED_DATABLOCK(scene)) return;
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (TESTBASELIB_NEW(base)) {
ob = base->object;
done = false;
@@ -1944,9 +1944,9 @@ static int logicbricks_copy_exec(bContext *C, wmOperator *UNUSED(op))
/* now copy it, this also works without logicbricks! */
clear_sca_new_poins_ob(ob);
- copy_sensors(&ob_iter->sensors, &ob->sensors);
- copy_controllers(&ob_iter->controllers, &ob->controllers);
- copy_actuators(&ob_iter->actuators, &ob->actuators);
+ copy_sensors(&ob_iter->sensors, &ob->sensors, 0);
+ copy_controllers(&ob_iter->controllers, &ob->controllers, 0);
+ copy_actuators(&ob_iter->actuators, &ob->actuators, 0);
set_sca_new_poins_ob(ob_iter);
/* some menu settings */
@@ -2007,7 +2007,7 @@ static int game_physics_copy_exec(bContext *C, wmOperator *UNUSED(op))
copy_v3_v3(ob_iter->anisotropicFriction, ob->anisotropicFriction);
ob_iter->collision_boundtype = ob->collision_boundtype;
ob_iter->margin = ob->margin;
- ob_iter->bsoft = copy_bulletsoftbody(ob->bsoft);
+ ob_iter->bsoft = copy_bulletsoftbody(ob->bsoft, 0);
if (ob->restrictflag & OB_RESTRICT_RENDER)
ob_iter->restrictflag |= OB_RESTRICT_RENDER;
else
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 3064bf8af1a..b32fb975ea8 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -201,7 +201,7 @@ static int objects_remove_active_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
int single_group_index = RNA_enum_get(op->ptr, "group");
Group *single_group = group_object_active_find_index(ob, single_group_index);
Group *group;
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 8b4eb794820..04ac42a5471 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -247,7 +247,7 @@ static int vertex_parent_set_exec(bContext *C, wmOperator *op)
else {
Object workob;
- ob->parent = BASACT_NEW->object;
+ ob->parent = BASACT_NEW(sl)->object;
if (v3) {
ob->partype = PARVERT3;
ob->par1 = v1 - 1;
@@ -354,7 +354,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
if (ob) {
Object *newob;
- BaseLegacy *newbase, *oldbase = BASACT_NEW;
+ BaseLegacy *newbase, *oldbase = BASACT_NEW(sl);
char name[MAX_ID_NAME + 4];
BLI_snprintf(name, sizeof(name), "%s_proxy", ((ID *)(gob ? gob : ob))->name + 2);
@@ -363,7 +363,7 @@ static int make_proxy_exec(bContext *C, wmOperator *op)
newob = BKE_object_add(bmain, scene, sl, OB_EMPTY, name);
/* set layers OK */
- newbase = BASACT_NEW; /* BKE_object_add sets active... */
+ newbase = BASACT_NEW(sl); /* BKE_object_add sets active... */
newbase->lay = oldbase->lay;
newob->lay = newbase->lay;
@@ -1470,13 +1470,13 @@ static int make_links_data_exec(bContext *C, wmOperator *op)
DEG_id_tag_update(&ob_dst->id, OB_RECALC_DATA);
break;
case MAKE_LINKS_ANIMDATA:
- BKE_animdata_copy_id((ID *)ob_dst, (ID *)ob_src, false);
+ BKE_animdata_copy_id(bmain, (ID *)ob_dst, (ID *)ob_src, false);
if (ob_dst->data && ob_src->data) {
if (ID_IS_LINKED_DATABLOCK(obdata_id)) {
is_lib = true;
break;
}
- BKE_animdata_copy_id((ID *)ob_dst->data, (ID *)ob_src->data, false);
+ BKE_animdata_copy_id(bmain, (ID *)ob_dst->data, (ID *)ob_src->data, false);
}
DEG_id_tag_update(&ob_dst->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
break;
@@ -2053,7 +2053,9 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo
IDP_RelinkProperty(scene->gpd->id.properties);
}
- IDP_RelinkProperty(scene->world->id.properties);
+ if (scene->world) {
+ IDP_RelinkProperty(scene->world->id.properties);
+ }
if (scene->clip) {
IDP_RelinkProperty(scene->clip->id.properties);
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 0a9b8b749f1..628c5b846a3 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -425,7 +425,7 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
}
- ob = OBACT_NEW;
+ ob = OBACT_NEW(sl);
if (ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active object");
return OPERATOR_CANCELLED;
@@ -836,7 +836,7 @@ static int object_select_grouped_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
}
- ob = OBACT_NEW;
+ ob = OBACT_NEW(sl);
if (ob == NULL) {
BKE_report(op->reports, RPT_ERROR, "No active object");
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index cf68bd3e419..1baa1926bd2 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -422,7 +422,10 @@ static void ignore_parent_tx(const bContext *C, Main *bmain, Scene *scene, Objec
}
}
-static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_loc, bool apply_rot, bool apply_scale)
+static int apply_objects_internal(
+ bContext *C, ReportList *reports,
+ bool apply_loc, bool apply_rot, bool apply_scale,
+ bool do_props)
{
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
@@ -542,7 +545,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l
BKE_mesh_calc_normals(me);
}
else if (ob->type == OB_ARMATURE) {
- ED_armature_apply_transform(ob, mat);
+ ED_armature_apply_transform(ob, mat, do_props);
}
else if (ob->type == OB_LATTICE) {
Lattice *lt = ob->data;
@@ -551,12 +554,12 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l
}
else if (ob->type == OB_MBALL) {
MetaBall *mb = ob->data;
- BKE_mball_transform(mb, mat);
+ BKE_mball_transform(mb, mat, do_props);
}
else if (ELEM(ob->type, OB_CURVE, OB_SURF)) {
Curve *cu = ob->data;
scale = mat3_to_scale(rsmat);
- BKE_curve_transform_ex(cu, mat, true, scale);
+ BKE_curve_transform_ex(cu, mat, true, do_props, scale);
}
else if (ob->type == OB_FONT) {
Curve *cu = ob->data;
@@ -572,7 +575,9 @@ static int apply_objects_internal(bContext *C, ReportList *reports, bool apply_l
tb->h *= scale;
}
- cu->fsize *= scale;
+ if (do_props) {
+ cu->fsize *= scale;
+ }
}
else if (ob->type == OB_CAMERA) {
MovieClip *clip = BKE_object_movieclip_get(scene, ob, false);
@@ -691,9 +696,10 @@ static int object_transform_apply_exec(bContext *C, wmOperator *op)
const bool loc = RNA_boolean_get(op->ptr, "location");
const bool rot = RNA_boolean_get(op->ptr, "rotation");
const bool sca = RNA_boolean_get(op->ptr, "scale");
+ const bool do_props = RNA_boolean_get(op->ptr, "properties");
if (loc || rot || sca) {
- return apply_objects_internal(C, op->reports, loc, rot, sca);
+ return apply_objects_internal(C, op->reports, loc, rot, sca, do_props);
}
else {
/* allow for redo */
@@ -718,6 +724,8 @@ void OBJECT_OT_transform_apply(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "location", 0, "Location", "");
RNA_def_boolean(ot->srna, "rotation", 0, "Rotation", "");
RNA_def_boolean(ot->srna, "scale", 0, "Scale", "");
+ RNA_def_boolean(ot->srna, "properties", true, "Apply Properties",
+ "Modify properties such as curve vertex radius, font size and bone envelope");
}
/********************* Set Object Center ************************/
@@ -1269,7 +1277,11 @@ static int object_transform_axis_target_invoke(bContext *C, wmOperator *op, cons
return OPERATOR_PASS_THROUGH;
}
- ED_view3d_autodist_init(C, vc.depsgraph, vc.ar, vc.v3d, 0);
+ EvaluationContext eval_ctx;
+
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ ED_view3d_autodist_init(&eval_ctx, vc.depsgraph, vc.ar, vc.v3d, 0);
if (vc.rv3d->depths != NULL) {
vc.rv3d->depths->damaged = true;
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index ca454cca576..171c5f4ed30 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -86,7 +86,9 @@
#include "physics_intern.h"
-void PE_create_particle_edit(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys);
+void PE_create_particle_edit(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *ob,
+ PointCache *cache, ParticleSystem *psys);
void PTCacheUndo_clear(PTCacheEdit *edit);
void recalc_lengths(PTCacheEdit *edit);
void recalc_emitter_field(Object *ob, ParticleSystem *psys);
@@ -216,7 +218,8 @@ static float pe_brush_size_get(const Scene *UNUSED(scene), ParticleBrushData *br
*
* note: this function runs on poll, therefor it can runs many times a second
* keep it fast! */
-static PTCacheEdit *pe_get_current(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, int create)
+static PTCacheEdit *pe_get_current(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *ob, int create)
{
ParticleEditSettings *pset= PE_settings(scene);
PTCacheEdit *edit = NULL;
@@ -256,18 +259,18 @@ static PTCacheEdit *pe_get_current(const bContext *C, Scene *scene, SceneLayer *
if (psys->part && psys->part->type == PART_HAIR) {
if (psys->flag & PSYS_HAIR_DYNAMICS && psys->pointcache->flag & PTCACHE_BAKED) {
if (create && !psys->pointcache->edit)
- PE_create_particle_edit(C, scene, sl, ob, pid->cache, NULL);
+ PE_create_particle_edit(eval_ctx, scene, sl, ob, pid->cache, NULL);
edit = pid->cache->edit;
}
else {
if (create && !psys->edit && psys->flag & PSYS_HAIR_DONE)
- PE_create_particle_edit(C, scene, sl, ob, NULL, psys);
+ PE_create_particle_edit(eval_ctx, scene, sl, ob, NULL, psys);
edit = psys->edit;
}
}
else {
if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit)
- PE_create_particle_edit(C, scene, sl, ob, pid->cache, psys);
+ PE_create_particle_edit(eval_ctx, scene, sl, ob, pid->cache, psys);
edit = pid->cache->edit;
}
@@ -278,7 +281,7 @@ static PTCacheEdit *pe_get_current(const bContext *C, Scene *scene, SceneLayer *
if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) {
pset->flag |= PE_FADE_TIME;
// NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB;
- PE_create_particle_edit(C, scene, sl, ob, pid->cache, NULL);
+ PE_create_particle_edit(eval_ctx, scene, sl, ob, pid->cache, NULL);
}
edit = pid->cache->edit;
break;
@@ -287,7 +290,7 @@ static PTCacheEdit *pe_get_current(const bContext *C, Scene *scene, SceneLayer *
if (create && pid->cache->flag & PTCACHE_BAKED && !pid->cache->edit) {
pset->flag |= PE_FADE_TIME;
// NICE TO HAVE but doesn't work: pset->brushtype = PE_BRUSH_COMB;
- PE_create_particle_edit(C, scene, sl, ob, pid->cache, NULL);
+ PE_create_particle_edit(eval_ctx, scene, sl, ob, pid->cache, NULL);
}
edit = pid->cache->edit;
break;
@@ -307,15 +310,16 @@ PTCacheEdit *PE_get_current(Scene *scene, SceneLayer *sl, Object *ob)
return pe_get_current(NULL, scene, sl, ob, 0);
}
-PTCacheEdit *PE_create_current(const bContext *C, Scene *scene, Object *ob)
+PTCacheEdit *PE_create_current(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
- return pe_get_current(C, scene, NULL, ob, 1);
+ return pe_get_current(eval_ctx, scene, NULL, ob, 1);
}
-void PE_current_changed(const bContext *C, Scene *scene, Object *ob)
+void PE_current_changed(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
- if (ob->mode == OB_MODE_PARTICLE_EDIT)
- PE_create_current(C, scene, ob);
+ if (ob->mode == OB_MODE_PARTICLE_EDIT) {
+ PE_create_current(eval_ctx, scene, ob);
+ }
}
void PE_hide_keys_time(Scene *scene, PTCacheEdit *edit, float cfra)
@@ -408,10 +412,13 @@ static void PE_set_view3d_data(bContext *C, PEData *data)
if (V3D_IS_ZBUF(data->vc.v3d)) {
if (data->vc.v3d->flag & V3D_INVALID_BACKBUF) {
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
/* needed or else the draw matrix can be incorrect */
view3d_operator_needs_opengl(C);
- ED_view3d_backbuf_validate(C, &data->vc);
+ ED_view3d_backbuf_validate(&eval_ctx, &data->vc);
/* we may need to force an update here by setting the rv3d as dirty
* for now it seems ok, but take care!:
* rv3d->depths->dirty = 1; */
@@ -430,7 +437,6 @@ static bool PE_create_shape_tree(PEData *data, Object *shapeob)
return false;
}
- DM_ensure_looptri(dm);
return (bvhtree_from_mesh_looptri(&data->shape_bvh, dm, 0.0f, 4, 8) != NULL);
}
@@ -1267,20 +1273,17 @@ static void update_velocities(PTCacheEdit *edit)
}
}
-void PE_update_object(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, int useflag)
+void PE_update_object(const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *ob, int useflag)
{
/* use this to do partial particle updates, not usable when adding or
* removing, then a full redo is necessary and calling this may crash */
ParticleEditSettings *pset= PE_settings(scene);
PTCacheEdit *edit = PE_get_current(scene, sl, ob);
- EvaluationContext eval_ctx;
POINT_P;
if (!edit)
return;
- CTX_data_eval_ctx(C, &eval_ctx);
-
/* flag all particles to be updated if not using flag */
if (!useflag)
LOOP_POINTS {
@@ -1300,7 +1303,7 @@ void PE_update_object(const bContext *C, Scene *scene, SceneLayer *sl, Object *o
PE_hide_keys_time(scene, edit, CFRA);
/* regenerate path caches */
- psys_cache_edit_paths(&eval_ctx, scene, ob, edit, CFRA, G.is_rendering);
+ psys_cache_edit_paths(eval_ctx, scene, ob, edit, CFRA, G.is_rendering);
/* disable update flag */
LOOP_POINTS {
@@ -2201,6 +2204,9 @@ static int rekey_exec(bContext *C, wmOperator *op)
{
PEData data;
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
PE_set_data(C, &data);
data.dval= 1.0f / (float)(data.totrekey-1);
@@ -2209,7 +2215,7 @@ static int rekey_exec(bContext *C, wmOperator *op)
foreach_selected_point(&data, rekey_particle);
recalc_lengths(data.edit);
- PE_update_object(C, data.scene, data.scene_layer, data.ob, 1);
+ PE_update_object(&eval_ctx, data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob);
return OPERATOR_FINISHED;
@@ -2543,11 +2549,14 @@ static int subdivide_exec(bContext *C, wmOperator *UNUSED(op))
{
PEData data;
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
PE_set_data(C, &data);
foreach_point(&data, subdivide_particle);
recalc_lengths(data.edit);
- PE_update_object(C, data.scene, data.scene_layer, data.ob, 1);
+ PE_update_object(&eval_ctx, data.scene, data.scene_layer, data.ob, 1);
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, data.ob);
return OPERATOR_FINISHED;
@@ -3822,6 +3831,9 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
if (!PE_start_edit(edit))
return;
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
RNA_float_get_array(itemptr, "mouse", mousef);
mouse[0] = mousef[0];
mouse[1] = mousef[1];
@@ -4003,8 +4015,9 @@ static void brush_edit_apply(bContext *C, wmOperator *op, PointerRNA *itemptr)
psys_free_path_cache(NULL, edit);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
- else
- PE_update_object(C, scene, sl, ob, 1);
+ else {
+ PE_update_object(&eval_ctx, scene, sl, ob, 1);
+ }
}
if (edit->psys) {
@@ -4237,6 +4250,9 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
if (!PE_start_edit(edit))
return OPERATOR_CANCELLED;
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
/* disable locking temporatily for disconnected hair */
if (edit->psys && edit->psys->flag & PSYS_GLOBAL_HAIR)
pset->flag &= ~PE_LOCK_FIRST;
@@ -4264,8 +4280,9 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op))
psys_free_path_cache(NULL, edit);
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
- else
- PE_update_object(C, scene, sl, ob, 1);
+ else {
+ PE_update_object(&eval_ctx, scene, sl, ob, 1);
+ }
if (edit->psys) {
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
@@ -4439,7 +4456,7 @@ static void get_PTCacheUndo(PTCacheEdit *edit, PTCacheUndo *undo)
void PE_undo_push(Scene *scene, SceneLayer *sl, const char *str)
{
- PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW(sl));
PTCacheUndo *undo;
int nr;
@@ -4481,7 +4498,7 @@ void PE_undo_push(Scene *scene, SceneLayer *sl, const char *str)
void PE_undo_step(Scene *scene, SceneLayer *sl, int step)
{
- PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW(sl));
if (!edit) return;
@@ -4512,12 +4529,12 @@ void PE_undo_step(Scene *scene, SceneLayer *sl, int step)
}
}
- DEG_id_tag_update(&OBACT_NEW->id, OB_RECALC_DATA);
+ DEG_id_tag_update(&OBACT_NEW(sl)->id, OB_RECALC_DATA);
}
bool PE_undo_is_valid(Scene *scene, SceneLayer *sl)
{
- PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW(sl));
if (edit) {
return (edit->undo.last != edit->undo.first);
@@ -4552,7 +4569,7 @@ void PE_redo(Scene *scene, SceneLayer *sl)
void PE_undo_number(Scene *scene, SceneLayer *sl, int nr)
{
- PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW(sl));
PTCacheUndo *undo;
int a=0;
@@ -4568,7 +4585,7 @@ void PE_undo_number(Scene *scene, SceneLayer *sl, int nr)
/* if active pointer, set it to 1 if true */
const char *PE_undo_get_name(Scene *scene, SceneLayer *sl, int nr, bool *r_active)
{
- PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW);
+ PTCacheEdit *edit= PE_get_current(scene, sl, OBACT_NEW(sl));
PTCacheUndo *undo;
if (r_active) *r_active = false;
@@ -4589,7 +4606,7 @@ const char *PE_undo_get_name(Scene *scene, SceneLayer *sl, int nr, bool *r_activ
int PE_minmax(Scene *scene, SceneLayer *sl, float min[3], float max[3])
{
- Object *ob= OBACT_NEW;
+ Object *ob= OBACT_NEW(sl);
PTCacheEdit *edit= PE_get_current(scene, sl, ob);
ParticleSystem *psys;
ParticleSystemModifierData *psmd = NULL;
@@ -4627,7 +4644,8 @@ int PE_minmax(Scene *scene, SceneLayer *sl, float min[3], float max[3])
/************************ particle edit toggle operator ************************/
/* initialize needed data for bake edit */
-void PE_create_particle_edit(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys)
+void PE_create_particle_edit(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *ob, PointCache *cache, ParticleSystem *psys)
{
PTCacheEdit *edit;
ParticleSystemModifierData *psmd = (psys) ? psys_get_modifier(ob, psys) : NULL;
@@ -4728,7 +4746,7 @@ void PE_create_particle_edit(const bContext *C, Scene *scene, SceneLayer *sl, Ob
recalc_lengths(edit);
if (psys && !cache)
recalc_emitter_field(ob, psys);
- PE_update_object(C, scene, sl, ob, 1);
+ PE_update_object(eval_ctx, scene, sl, ob, 1);
PTCacheUndo_clear(edit);
PE_undo_push(scene, sl, "Original");
@@ -4769,8 +4787,11 @@ static int particle_edit_toggle_exec(bContext *C, wmOperator *op)
if (!is_mode_set) {
PTCacheEdit *edit;
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
ob->mode |= mode_flag;
- edit= PE_create_current(C, scene, ob);
+ edit= PE_create_current(&eval_ctx, scene, ob);
/* mesh may have changed since last entering editmode.
* note, this may have run before if the edit data was just created, so could avoid this and speed up a little */
@@ -4941,12 +4962,16 @@ static int unify_length_exec(bContext *C, wmOperator *UNUSED(op))
SceneLayer *sl = CTX_data_scene_layer(C);
PTCacheEdit *edit = PE_get_current(scene, sl, ob);
float average_length = calculate_average_length(edit);
+
if (average_length == 0.0f) {
return OPERATOR_CANCELLED;
}
scale_points_to_length(edit, average_length);
- PE_update_object(C, scene, sl, ob, 1);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ PE_update_object(&eval_ctx, scene, sl, ob, 1);
if (edit->psys) {
WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob);
}
diff --git a/source/blender/editors/physics/particle_object.c b/source/blender/editors/physics/particle_object.c
index 8a08be75421..571a8ab18f0 100644
--- a/source/blender/editors/physics/particle_object.c
+++ b/source/blender/editors/physics/particle_object.c
@@ -568,7 +568,9 @@ void PARTICLE_OT_dupliob_move_down(wmOperatorType *ot)
/************************ connect/disconnect hair operators *********************/
-static void disconnect_hair(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys)
+static void disconnect_hair(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl,
+ Object *ob, ParticleSystem *psys)
{
ParticleSystemModifierData *psmd = psys_get_modifier(ob, psys);
ParticleEditSettings *pset= PE_settings(scene);
@@ -614,7 +616,7 @@ static void disconnect_hair(const bContext *C, Scene *scene, SceneLayer *sl, Obj
if (ELEM(pset->brushtype, PE_BRUSH_ADD, PE_BRUSH_PUFF))
pset->brushtype = PE_BRUSH_NONE;
- PE_update_object(C, scene, sl, ob, 0);
+ PE_update_object(eval_ctx, scene, sl, ob, 0);
}
static int disconnect_hair_exec(bContext *C, wmOperator *op)
@@ -625,17 +627,20 @@ static int disconnect_hair_exec(bContext *C, wmOperator *op)
ParticleSystem *psys= NULL;
const bool all = RNA_boolean_get(op->ptr, "all");
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
if (!ob)
return OPERATOR_CANCELLED;
if (all) {
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
- disconnect_hair(C, scene, sl, ob, psys);
+ disconnect_hair(&eval_ctx, scene, sl, ob, psys);
}
}
else {
psys = psys_get_current(ob);
- disconnect_hair(C, scene, sl, ob, psys);
+ disconnect_hair(&eval_ctx, scene, sl, ob, psys);
}
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -661,9 +666,10 @@ void PARTICLE_OT_disconnect_hair(wmOperatorType *ot)
/* from/to_world_space : whether from/to particles are in world or hair space
* from/to_mat : additional transform for from/to particles (e.g. for using object space copying)
*/
-static bool remap_hair_emitter(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys,
- Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit,
- float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global)
+static bool remap_hair_emitter(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys,
+ Object *target_ob, ParticleSystem *target_psys, PTCacheEdit *target_edit,
+ float from_mat[4][4], float to_mat[4][4], bool from_global, bool to_global)
{
ParticleSystemModifierData *target_psmd = psys_get_modifier(target_ob, target_psys);
ParticleData *pa, *tpa;
@@ -847,19 +853,23 @@ static bool remap_hair_emitter(const bContext *C, Scene *scene, SceneLayer *sl,
psys_free_path_cache(target_psys, target_edit);
- PE_update_object(C, scene, sl, target_ob, 0);
+ PE_update_object(eval_ctx, scene, sl, target_ob, 0);
return true;
}
-static bool connect_hair(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys)
+static bool connect_hair(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl,
+ Object *ob, ParticleSystem *psys)
{
bool ok;
if (!psys)
return false;
- ok = remap_hair_emitter(C, scene, sl, ob, psys, ob, psys, psys->edit, ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
+ ok = remap_hair_emitter(
+ eval_ctx, scene, sl, ob, psys, ob, psys, psys->edit,
+ ob->obmat, ob->obmat, psys->flag & PSYS_GLOBAL_HAIR, false);
psys->flag &= ~PSYS_GLOBAL_HAIR;
return ok;
@@ -867,6 +877,7 @@ static bool connect_hair(const bContext *C, Scene *scene, SceneLayer *sl, Object
static int connect_hair_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
Scene *scene= CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
Object *ob= ED_object_context(C);
@@ -877,14 +888,16 @@ static int connect_hair_exec(bContext *C, wmOperator *op)
if (!ob)
return OPERATOR_CANCELLED;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
if (all) {
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
- any_connected |= connect_hair(C, scene, sl, ob, psys);
+ any_connected |= connect_hair(&eval_ctx, scene, sl, ob, psys);
}
}
else {
psys = psys_get_current(ob);
- any_connected |= connect_hair(C, scene, sl, ob, psys);
+ any_connected |= connect_hair(&eval_ctx, scene, sl, ob, psys);
}
if (!any_connected) {
@@ -920,7 +933,9 @@ typedef enum eCopyParticlesSpace {
PAR_COPY_SPACE_WORLD = 1,
} eCopyParticlesSpace;
-static void copy_particle_edit(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
+static void copy_particle_edit(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl,
+ Object *ob, ParticleSystem *psys, ParticleSystem *psys_from)
{
PTCacheEdit *edit_from = psys_from->edit, *edit;
ParticleData *pa;
@@ -970,7 +985,7 @@ static void copy_particle_edit(const bContext *C, Scene *scene, SceneLayer *sl,
recalc_lengths(edit);
recalc_emitter_field(ob, psys);
- PE_update_object(C, scene, sl, ob, true);
+ PE_update_object(eval_ctx, scene, sl, ob, true);
PTCacheUndo_clear(edit);
PE_undo_push(scene, sl, "Original");
@@ -1045,7 +1060,7 @@ static bool copy_particle_systems_to_object(const bContext *C,
psys_from;
psys_from = PSYS_FROM_NEXT(psys_from), ++i) {
- psys = BKE_object_copy_particlesystem(psys_from);
+ psys = BKE_object_copy_particlesystem(psys_from, 0);
tmp_psys[i] = psys;
if (psys_start == NULL)
@@ -1087,8 +1102,9 @@ static bool copy_particle_systems_to_object(const bContext *C,
CDDM_calc_normals(psmd->dm_final);
DM_ensure_tessface(psmd->dm_final);
- if (psys_from->edit)
- copy_particle_edit(C, scene, sl, ob_to, psys, psys_from);
+ if (psys_from->edit) {
+ copy_particle_edit(&eval_ctx, scene, sl, ob_to, psys, psys_from);
+ }
if (duplicate_settings) {
id_us_min(&psys->part->id);
@@ -1122,7 +1138,9 @@ static bool copy_particle_systems_to_object(const bContext *C,
break;
}
if (ob_from != ob_to) {
- remap_hair_emitter(C, scene, sl, ob_from, psys_from, ob_to, psys, psys->edit, from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
+ remap_hair_emitter(
+ &eval_ctx, scene, sl, ob_from, psys_from, ob_to, psys, psys->edit,
+ from_mat, to_mat, psys_from->flag & PSYS_GLOBAL_HAIR, psys->flag & PSYS_GLOBAL_HAIR);
}
/* tag for recalc */
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index 9cd571c68cf..b38b8640c8d 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -349,7 +349,7 @@ static void fluid_init_all_channels(bContext *C, Object *UNUSED(fsDomain), Fluid
channels->DomainTime = MEM_callocN(length * (CHANNEL_FLOAT+1) * sizeof(float), "channel DomainTime");
/* allocate fluid objects */
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
Object *ob = base->object;
FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
@@ -586,7 +586,7 @@ static int fluid_validate_scene(ReportList *reports, SceneLayer *sl, Object *fsD
int channelObjCount = 0;
int fluidInputCount = 0;
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
Object *ob = base->object;
FluidsimModifierData *fluidmdtmp = (FluidsimModifierData *)modifiers_findByType(ob, eModifierType_Fluidsim);
diff --git a/source/blender/editors/physics/rigidbody_constraint.c b/source/blender/editors/physics/rigidbody_constraint.c
index d93eb95243e..1c9b59268e4 100644
--- a/source/blender/editors/physics/rigidbody_constraint.c
+++ b/source/blender/editors/physics/rigidbody_constraint.c
@@ -121,7 +121,7 @@ static int rigidbody_con_add_exec(bContext *C, wmOperator *op)
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
RigidBodyWorld *rbw = BKE_rigidbody_get_world(scene);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
int type = RNA_enum_get(op->ptr, "type");
bool changed;
@@ -170,7 +170,7 @@ static int rigidbody_con_remove_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
/* apply to active object */
if (ELEM(NULL, ob, ob->rigidbody_constraint)) {
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index f3987b8eb39..f915fd5ec64 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -1175,7 +1175,7 @@ static void render_update_resolution(Render *re, const RenderPreview *rp,
}
if (rp->has_freestyle) {
- if (rp->resolution_divider == 1) {
+ if (rp->resolution_divider == BKE_render_preview_pixel_size(&rp->scene->r)) {
RE_ChangeModeFlag(re, R_EDGE_FRS, false);
}
else {
@@ -1316,11 +1316,12 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
RE_updateRenderInstances(re, ob_inst_update_flag);
for (;;) {
+ int pixel_size = BKE_render_preview_pixel_size(&rp->scene->r);
if (first_time == false) {
if (restore)
RE_DataBase_IncrementalView(re, rp->viewmat, 1);
- rp->resolution_divider /= 2;
+ rp->resolution_divider = MAX2(rp->resolution_divider/2, pixel_size);
*do_update = 1;
render_update_resolution(re, rp, use_border, &cliprct);
@@ -1337,7 +1338,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
first_time = false;
- if (*stop || rp->resolution_divider == 1) {
+ if (*stop || rp->resolution_divider == pixel_size) {
break;
}
}
@@ -1439,7 +1440,7 @@ static void render_view3d_do(RenderEngine *engine, const bContext *C)
Scene *scene = CTX_data_scene(C);
ARegion *ar = CTX_wm_region(C);
int width = ar->winx, height = ar->winy;
- int divider = 1;
+ int divider = BKE_render_preview_pixel_size(&scene->r);
int resolution_threshold = scene->r.preview_start_resolution *
scene->r.preview_start_resolution;
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 5071c5db4ea..016013ab492 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -1302,16 +1302,16 @@ static int freestyle_modifier_copy_exec(bContext *C, wmOperator *op)
switch (freestyle_get_modifier_type(&ptr)) {
case LS_MODIFIER_TYPE_COLOR:
- BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier);
+ BKE_linestyle_color_modifier_copy(lineset->linestyle, modifier, 0);
break;
case LS_MODIFIER_TYPE_ALPHA:
- BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier);
+ BKE_linestyle_alpha_modifier_copy(lineset->linestyle, modifier, 0);
break;
case LS_MODIFIER_TYPE_THICKNESS:
- BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier);
+ BKE_linestyle_thickness_modifier_copy(lineset->linestyle, modifier, 0);
break;
case LS_MODIFIER_TYPE_GEOMETRY:
- BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier);
+ BKE_linestyle_geometry_modifier_copy(lineset->linestyle, modifier, 0);
break;
default:
BKE_report(op->reports, RPT_ERROR, "The object the data pointer refers to is not a valid modifier");
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index 3a9d11be3fd..67354a70e4a 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -202,7 +202,7 @@ void ED_render_engine_changed(Main *bmain)
}
/***************************** Updates ***********************************
- * ED_render_id_flush_update gets called from DAG_id_tag_update, to do *
+ * ED_render_id_flush_update gets called from DEG_id_tag_update, to do *
* editor level updates when the ID changes. when these ID blocks are in *
* the dependency graph, we can get rid of the manual dependency checks */
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index d762419b550..56fe11a5006 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -463,8 +463,8 @@ bScreen *screen_add(const char *name, const int winsize_x, const int winsize_y)
{
bScreen *sc;
ScrVert *sv1, *sv2, *sv3, *sv4;
-
- sc = BKE_libblock_alloc(G.main, ID_SCR, name);
+
+ sc = BKE_libblock_alloc(G.main, ID_SCR, name, 0);
sc->do_refresh = true;
sc->redraws_flag = TIME_ALL_3D_WIN | TIME_ALL_ANIM_WIN;
@@ -472,15 +472,15 @@ bScreen *screen_add(const char *name, const int winsize_x, const int winsize_y)
sv2 = screen_addvert(sc, 0, winsize_y - 1);
sv3 = screen_addvert(sc, winsize_x - 1, winsize_y - 1);
sv4 = screen_addvert(sc, winsize_x - 1, 0);
-
+
screen_addedge(sc, sv1, sv2);
screen_addedge(sc, sv2, sv3);
screen_addedge(sc, sv3, sv4);
screen_addedge(sc, sv4, sv1);
-
+
/* dummy type, no spacedata */
screen_addarea(sc, sv1, sv2, sv3, sv4, HEADERDOWN, SPACE_EMPTY);
-
+
return sc;
}
@@ -992,7 +992,7 @@ void ED_region_exit(bContext *C, ARegion *ar)
wm_subwindow_close(win, ar->swinid);
ar->swinid = 0;
}
-
+
if (ar->headerstr) {
MEM_freeN(ar->headerstr);
ar->headerstr = NULL;
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 8c6b3b0106c..d2115aae2ac 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -766,7 +766,7 @@ static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const flo
/* initialize from context */
if (CTX_wm_region_view3d(C)) {
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
bool uvs, mat, tex, stencil;
if (!BKE_paint_proj_mesh_data_check(scene, ob, &uvs, &mat, &tex, &stencil)) {
BKE_paint_data_warning(op->reports, uvs, mat, tex, stencil);
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index 65f4618e43e..2ffd9757f92 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -5027,6 +5027,7 @@ void paint_proj_stroke(
/* clone gets special treatment here to avoid going through image initialization */
if (ps_handle->is_clone_cursor_pick) {
+ EvaluationContext eval_ctx;
Scene *scene = ps_handle->scene;
struct Depsgraph *graph = CTX_data_depsgraph(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -5036,7 +5037,9 @@ void paint_proj_stroke(
view3d_operator_needs_opengl(C);
- if (!ED_view3d_autodist(C, graph, ar, v3d, mval_i, cursor, false, NULL)) {
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ if (!ED_view3d_autodist(&eval_ctx, graph, ar, v3d, mval_i, cursor, false, NULL)) {
return;
}
@@ -5323,7 +5326,7 @@ static int texture_paint_camera_project_exec(bContext *C, wmOperator *op)
int orig_brush_size;
IDProperty *idgroup;
IDProperty *view_data = NULL;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
bool uvs, mat, tex;
if (ob == NULL || ob->type != OB_MESH) {
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index f8c8d8fb41e..17ecb309e27 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -348,13 +348,15 @@ static void imapaint_pick_uv(EvaluationContext *eval_ctx, Scene *scene, Object *
}
/* returns 0 if not found, otherwise 1 */
-static int imapaint_pick_face(const bContext *C, ViewContext *vc, const int mval[2], unsigned int *r_index, unsigned int totpoly)
+static int imapaint_pick_face(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, const int mval[2],
+ unsigned int *r_index, unsigned int totpoly)
{
if (totpoly == 0)
return 0;
/* sample only on the exact position */
- *r_index = ED_view3d_backbuf_sample(C, vc, mval[0], mval[1]);
+ *r_index = ED_view3d_backbuf_sample(eval_ctx, vc, mval[0], mval[1]);
if ((*r_index) == 0 || (*r_index) > (unsigned int)totpoly) {
return 0;
@@ -447,7 +449,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
if (CTX_wm_view3d(C) && texpaint_proj) {
/* first try getting a colour directly from the mesh faces if possible */
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
bool sample_success = false;
ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;
bool use_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
@@ -466,7 +468,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
view3d_operator_needs_opengl(C);
- if (imapaint_pick_face(C, &vc, mval, &faceindex, totpoly)) {
+ if (imapaint_pick_face(&eval_ctx, &vc, mval, &faceindex, totpoly)) {
Image *image;
if (use_material)
diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c
index b395ac5c49d..321ce1fe306 100644
--- a/source/blender/editors/sculpt_paint/paint_vertex.c
+++ b/source/blender/editors/sculpt_paint/paint_vertex.c
@@ -814,7 +814,9 @@ static unsigned int vpaint_blend(VPaint *vp, unsigned int col, unsigned int colo
}
-static int sample_backbuf_area(const bContext *C, ViewContext *vc, int *indexar, int totpoly, int x, int y, float size)
+static int sample_backbuf_area(
+ const EvaluationContext *eval_ctx, ViewContext *vc,
+ int *indexar, int totpoly, int x, int y, float size)
{
struct ImBuf *ibuf;
int a, tot = 0, index;
@@ -823,7 +825,7 @@ static int sample_backbuf_area(const bContext *C, ViewContext *vc, int *indexar,
* brushes with size > 64, why is this here? */
/*if (size > 64.0) size = 64.0;*/
- ibuf = ED_view3d_backbuf_read(C, vc, x - size, y - size, x + size, y + size);
+ ibuf = ED_view3d_backbuf_read(eval_ctx, vc, x - size, y - size, x + size, y + size);
if (ibuf) {
unsigned int *rt = ibuf->rect;
@@ -2162,6 +2164,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
VPaint *wp = ts->wpaint;
Brush *brush = BKE_paint_brush(&wp->paint);
struct WPaintData *wpd = paint_stroke_mode_data(stroke);
+ EvaluationContext eval_ctx;
ViewContext *vc;
Object *ob;
Mesh *me;
@@ -2201,9 +2204,12 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
me = ob->data;
indexar = wpd->indexar;
+
view3d_operator_needs_opengl(C);
ED_view3d_init_mats_rv3d(ob, vc->rv3d);
+ CTX_data_eval_ctx(C, &eval_ctx);
+
/* load projection matrix */
mul_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
@@ -2243,7 +2249,7 @@ static void wpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
/* Ugly x2, we need this so hidden faces don't draw */
me->editflag |= ME_EDIT_PAINT_FACE_SEL;
}
- totindex = sample_backbuf_area(C, vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
+ totindex = sample_backbuf_area(&eval_ctx, vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
me->editflag = editflag_prev;
if (use_face_sel && me->totpoly) {
@@ -2799,6 +2805,7 @@ static void vpaint_paint_poly(VPaint *vp, VPaintData *vpd, Mesh *me,
static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, PointerRNA *itemptr)
{
+ EvaluationContext eval_ctx;
Scene *scene = CTX_data_scene(C);
ToolSettings *ts = CTX_data_tool_settings(C);
struct VPaintData *vpd = paint_stroke_mode_data(stroke);
@@ -2827,7 +2834,8 @@ static void vpaint_stroke_update_step(bContext *C, struct PaintStroke *stroke, P
mul_m4_m4m4(mat, vc->rv3d->persmat, ob->obmat);
/* which faces are involved */
- totindex = sample_backbuf_area(C, vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
+ CTX_data_eval_ctx(C, &eval_ctx);
+ totindex = sample_backbuf_area(&eval_ctx, vc, indexar, me->totpoly, mval[0], mval[1], brush_size_pressure);
if ((me->editflag & ME_EDIT_PAINT_FACE_SEL) && me->mpoly) {
for (index = 0; index < totindex; index++) {
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index ac1c16f1d76..236aa5a1c6a 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -4734,7 +4734,7 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st
* Could be optimized later, but currently don't think it's so
* much common scenario.
*
- * Same applies to the DAG_id_tag_update() invoked from
+ * Same applies to the DEG_id_tag_update() invoked from
* sculpt_flush_update().
*/
if (ss->modifiers_active) {
diff --git a/source/blender/editors/sound/CMakeLists.txt b/source/blender/editors/sound/CMakeLists.txt
index 535cd579030..9efdf11e8d7 100644
--- a/source/blender/editors/sound/CMakeLists.txt
+++ b/source/blender/editors/sound/CMakeLists.txt
@@ -39,7 +39,7 @@ set(SRC
)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index d103530fa81..ecc00f4b7e5 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -67,7 +67,7 @@
#include "WM_types.h"
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
#include "ED_sound.h"
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 9af3ebf3cbb..1872fe108ca 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -821,7 +821,8 @@ static void clip_keymap(struct wmKeyConfig *keyconf)
#endif
}
-static const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL};
+/* DO NOT make this static, this hides the symbol and breaks API generation script. */
+const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL};
static int clip_context(const bContext *C, const char *member, bContextDataResult *result)
{
diff --git a/source/blender/editors/space_clip/tracking_ops_orient.c b/source/blender/editors/space_clip/tracking_ops_orient.c
index 7b21e11d342..c411f64a88b 100644
--- a/source/blender/editors/space_clip/tracking_ops_orient.c
+++ b/source/blender/editors/space_clip/tracking_ops_orient.c
@@ -99,7 +99,7 @@ static Object *get_orientation_object(bContext *C)
object = get_camera_with_movieclip(scene, clip);
}
else {
- object = OBACT_NEW;
+ object = OBACT_NEW(sl);
}
if (object != NULL && object->parent != NULL) {
@@ -122,7 +122,7 @@ static int set_orientation_poll(bContext *C)
return true;
}
else {
- return OBACT_NEW != NULL;
+ return OBACT_NEW(sl) != NULL;
}
}
}
diff --git a/source/blender/editors/space_graph/CMakeLists.txt b/source/blender/editors/space_graph/CMakeLists.txt
index 64ce1704b07..2840324e65e 100644
--- a/source/blender/editors/space_graph/CMakeLists.txt
+++ b/source/blender/editors/space_graph/CMakeLists.txt
@@ -49,7 +49,7 @@ set(SRC
)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index 01dc272ead4..d917e3b85a2 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -221,7 +221,7 @@ static void draw_fcurve_selected_handle_vertices(FCurve *fcu, View2D *v2d, bool
float hcolor[3];
UI_GetThemeColor3fv(sel ? TH_HANDLE_VERTEX_SELECT : TH_HANDLE_VERTEX, hcolor);
immUniform4f("outlineColor", hcolor[0], hcolor[1], hcolor[2], 1.0f);
- immUniformColor3fvAlpha(hcolor, 0.4f);
+ immUniformColor3fvAlpha(hcolor, 0.01f); /* almost invisible - only keep for smoothness */
immBeginAtMost(GWN_PRIM_POINTS, fcu->totvert * 2);
@@ -260,7 +260,7 @@ static void draw_fcurve_handle_vertices(FCurve *fcu, View2D *v2d, bool sel_handl
/* set handle size */
immUniform1f("size", (1.4f * UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE)) * U.pixelsize);
- immUniform1f("outlineWidth", 1.0f * U.pixelsize);
+ immUniform1f("outlineWidth", 1.5f * U.pixelsize);
draw_fcurve_selected_handle_vertices(fcu, v2d, false, sel_handle_only, pos);
draw_fcurve_selected_handle_vertices(fcu, v2d, true, sel_handle_only, pos);
@@ -1039,7 +1039,7 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
/* set color/drawing style for curve itself */
/* draw active F-Curve thicker than the rest to make it stand out */
if (fcu->flag & FCURVE_ACTIVE) {
- glLineWidth(2.0);
+ glLineWidth(2.5);
}
else {
glLineWidth(1.0);
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 09e38579c21..56b67f921fc 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -36,7 +36,7 @@
#include <float.h>
#ifdef WITH_AUDASPACE
-# include AUD_SPECIAL_H
+# include <AUD_Special.h>
#endif
#include "MEM_guardedalloc.h"
diff --git a/source/blender/editors/space_image/image_edit.c b/source/blender/editors/space_image/image_edit.c
index a3a115b3e6a..fbc67ab8090 100644
--- a/source/blender/editors/space_image/image_edit.c
+++ b/source/blender/editors/space_image/image_edit.c
@@ -377,7 +377,7 @@ bool ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
bool ED_space_image_check_show_maskedit(SceneLayer *sl, SpaceImage *sima)
{
/* check editmode - this is reserved for UV editing */
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob && ob->mode & OB_MODE_EDIT && ED_space_image_show_uvedit(sima, ob)) {
return false;
}
diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c
index 58fb75edd84..514cb1ab97e 100644
--- a/source/blender/editors/space_image/space_image.c
+++ b/source/blender/editors/space_image/space_image.c
@@ -537,7 +537,7 @@ static void image_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn, co
case ND_MODIFIER:
{
SceneLayer *sl = BKE_scene_layer_context_active_PLACEHOLDER(scene);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob && (ob == wmn->reference) && (ob->mode & OB_MODE_EDIT)) {
if (sima->lock && (sima->flag & SI_DRAWSHADOW)) {
ED_area_tag_refresh(sa);
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index 04790f54057..3fd2805efe0 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -485,7 +485,7 @@ static ID **get_selected_and_linked_obs(bContext *C, short *count, short scavisf
ob= ob->id.next;
}
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if ((base->flag & BASE_VISIBLED) && (base->flag & SELECT)) {
if (scavisflag & BUTS_SENS_SEL) base->object->scavisflag |= OB_VIS_SENS;
if (scavisflag & BUTS_CONT_SEL) base->object->scavisflag |= OB_VIS_CONT;
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 966f24269c7..fe846666894 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -56,6 +56,7 @@
#include "BIF_glutil.h"
#include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
#include "GPU_draw.h"
#include "WM_types.h"
@@ -107,7 +108,7 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, floa
action_to_keylist(adt, act, &keys, NULL);
BLI_dlrbTree_linkedlist_sync(&keys);
- if (!(act && keys.first))
+ if (ELEM(NULL, act, keys.first))
return;
/* draw a darkened region behind the strips
@@ -135,10 +136,8 @@ static void nla_action_draw_keyframes(AnimData *adt, bAction *act, float y, floa
immUnbindProgram();
/* count keys before drawing */
- unsigned int key_ct = 0;
- for (ActKeyColumn *ak = keys.first; ak; ak = ak->next) {
- key_ct++;
- }
+ /* Note: It's safe to cast DLRBT_Tree, as it's designed to degrade down to a ListBase */
+ unsigned int key_ct = BLI_listbase_count((ListBase *)&keys);
if (key_ct > 0) {
format = immVertexFormat();
@@ -174,7 +173,7 @@ static void nla_actionclip_draw_markers(NlaStrip *strip, float yminc, float ymax
{
const bAction *act = strip->act;
- if (!(act && act->markers.first))
+ if (ELEM(NULL, act, act->markers.first))
return;
const uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
@@ -232,6 +231,8 @@ static void nla_strip_draw_markers(NlaStrip *strip, float yminc, float ymaxc)
}
}
}
+
+ glLineWidth(1.0f);
}
/* Strips (Proper) ---------------------- */
@@ -301,9 +302,9 @@ static void nla_strip_get_color_inside(AnimData *adt, NlaStrip *strip, float col
/* helper call for drawing influence/time control curves for a given NLA-strip */
static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, unsigned int pos)
{
- immUniformColor3f(0.7f, 0.7f, 0.7f);
-
const float yheight = ymaxc - yminc;
+
+ immUniformColor3f(0.7f, 0.7f, 0.7f);
/* draw with AA'd line */
glEnable(GL_LINE_SMOOTH);
@@ -358,18 +359,50 @@ static void nla_draw_strip_curves(NlaStrip *strip, float yminc, float ymaxc, uns
glDisable(GL_BLEND);
}
+/* helper call to setup dashed-lines for strip outlines */
+static uint nla_draw_use_dashed_outlines(float color[4], bool muted)
+{
+ /* Note that we use dashed shader here, and make it draw solid lines if not muted... */
+ uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+
+ float viewport_size[4];
+ glGetFloatv(GL_VIEWPORT, viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+
+ immUniform1i("num_colors", 0); /* Simple dashes. */
+ immUniformColor3fv(color);
+
+ /* line style: dotted for muted */
+ if (muted) {
+ /* dotted - and slightly thicker for readability of the dashes */
+ immUniform1f("dash_width", 5.0f);
+ immUniform1f("dash_factor", 0.4f);
+ glLineWidth(1.5f);
+ }
+ else {
+ /* solid line */
+ immUniform1f("dash_factor", 2.0f);
+ glLineWidth(1.0f);
+ }
+
+ return shdr_pos;
+}
+
/* main call for drawing a single NLA-strip */
static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStrip *strip, View2D *v2d, float yminc, float ymaxc)
{
const bool non_solo = ((adt && (adt->flag & ADT_NLA_SOLO_TRACK)) && (nlt->flag & NLATRACK_SOLO) == 0);
+ const bool muted = ((nlt->flag & NLATRACK_MUTED) || (strip->flag & NLASTRIP_FLAG_MUTED));
float color[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-
+ uint shdr_pos;
+
/* get color of strip */
nla_strip_get_color_inside(adt, strip, color);
-
- uint shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+ shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
+
/* draw extrapolation info first (as backdrop)
* - but this should only be drawn if track has some contribution
*/
@@ -459,29 +492,20 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
color[0] = color[1] = color[2] = 0.0f; /* FIXME: or 1.0f ?? */
}
- /* draw outline */
- /* XXX TODO Was dashed like code below, not implemented for now so kept solid... */
- UI_draw_roundbox_shade_x(false, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1, color);
-
- /* restore current vertex format & program (roundbox trashes it) */
- /* Note that we use dahsed shader here, and make it draw solid lines if not muted... */
- shdr_pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
-
- float viewport_size[4];
- glGetFloatv(GL_VIEWPORT, viewport_size);
- immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
-
- immUniform1i("num_colors", 0); /* Simple dashes. */
- immUniformColor3fv(color);
-
- /* - line style: dotted for muted */
- if ((nlt->flag & NLATRACK_MUTED) || (strip->flag & NLASTRIP_FLAG_MUTED)) {
- immUniform1f("dash_width", 4.0f);
- immUniform1f("dash_factor", 0.5f);
+ /* draw outline
+ * - dashed-line shader is loaded after this block
+ */
+ if (muted) {
+ /* muted - draw dotted, squarish outline (for simplicity) */
+ shdr_pos = nla_draw_use_dashed_outlines(color, muted);
+ imm_draw_line_box(shdr_pos, strip->start, yminc, strip->end, ymaxc);
}
else {
- immUniform1f("dash_factor", 2.0f); /* solid line */
+ /* non-muted - draw solid, rounded outline */
+ UI_draw_roundbox_shade_x(false, strip->start, yminc, strip->end, ymaxc, 0.0, 0.0, 0.1, color);
+
+ /* restore current vertex format & program (roundbox trashes it) */
+ shdr_pos = nla_draw_use_dashed_outlines(color, muted);
}
/* if action-clip strip, draw lines delimiting repeats too (in the same color as outline) */
@@ -505,7 +529,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
}
/* or if meta-strip, draw lines delimiting extents of sub-strips (in same color as outline, if more than 1 exists) */
else if ((strip->type == NLASTRIP_TYPE_META) && (strip->strips.first != strip->strips.last)) {
- float y = (ymaxc - yminc) * 0.5f + yminc;
+ const float y = (ymaxc - yminc) * 0.5f + yminc;
immBeginAtMost(GWN_PRIM_LINES, 4 * BLI_listbase_count(&strip->strips)); /* up to 2 lines per strip */
@@ -589,6 +613,7 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
const float ytol = 1.0f; /* small offset to vertical positioning of text, for legibility */
const char col[4] = {220, 220, 220, 255}; /* light gray */
char numstr[32];
+ size_t numstr_len;
/* Always draw times above the strip, whereas sequencer drew below + above.
* However, we should be fine having everything on top, since these tend to be
@@ -597,7 +622,7 @@ static void nla_draw_strip_frames_text(NlaTrack *UNUSED(nlt), NlaStrip *strip, V
* while also preserving some accuracy, since we do use floats
*/
/* start frame */
- size_t numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->start);
+ numstr_len = BLI_snprintf_rlen(numstr, sizeof(numstr), "%.1f", strip->start);
UI_view2d_text_cache_add(v2d, strip->start - 1.0f, ymaxc + ytol, numstr, numstr_len, col);
/* end frame */
@@ -625,6 +650,7 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
* start of list offset, and the second is as a correction for the scrollers.
*/
int height = ((items * NLACHANNEL_STEP(snla)) + (NLACHANNEL_HEIGHT(snla) * 2));
+
/* don't use totrect set, as the width stays the same
* (NOTE: this is ok here, the configuration is pretty straightforward)
*/
@@ -647,10 +673,11 @@ void draw_nla_main_data(bAnimContext *ac, SpaceNla *snla, ARegion *ar)
{
AnimData *adt = ale->adt;
NlaTrack *nlt = (NlaTrack *)ale->data;
+ NlaStrip *strip;
+ int index;
/* draw each strip in the track (if visible) */
- int index = 1;
- for (NlaStrip *strip = nlt->strips.first; strip; strip = strip->next, index++) {
+ for (strip = nlt->strips.first, index = 1; strip; strip = strip->next, index++) {
if (BKE_nlastrip_within_bounds(strip, v2d->cur.xmin, v2d->cur.xmax)) {
const float xminc = strip->start + text_margin_x;
const float xmaxc = strip->end + text_margin_x;
@@ -744,14 +771,16 @@ void draw_nla_channel_list(const bContext *C, bAnimContext *ac, ARegion *ar)
{
ListBase anim_data = {NULL, NULL};
bAnimListElem *ale;
+ int filter;
SpaceNla *snla = (SpaceNla *)ac->sl;
View2D *v2d = &ar->v2d;
float y = 0.0f;
+ size_t items;
/* build list of channels to draw */
- int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
/* Update max-extent of channels here (taking into account scrollers):
* - this is done to allow the channel list to be scrollable, but must be done here
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index 33382af9087..fa3508ecfd1 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -399,8 +399,8 @@ void ED_node_shader_default(const bContext *C, ID *id)
ma->nodetree = ntree;
if (BKE_scene_uses_blender_eevee(scene)) {
- output_type = SH_NODE_OUTPUT_EEVEE_MATERIAL;
- shader_type = SH_NODE_EEVEE_METALLIC;
+ output_type = SH_NODE_OUTPUT_MATERIAL;
+ shader_type = SH_NODE_BSDF_PRINCIPLED;
}
else if (BKE_scene_use_new_shading_nodes(scene)) {
output_type = SH_NODE_OUTPUT_MATERIAL;
diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h
index 7e8d092cdbe..12e3c33007e 100644
--- a/source/blender/editors/space_node/node_intern.h
+++ b/source/blender/editors/space_node/node_intern.h
@@ -222,6 +222,8 @@ void NODE_OT_clear_viewer_border(struct wmOperatorType *ot);
/* node_widgets.c */
void NODE_WGT_backdrop_transform(struct wmManipulatorGroupType *wgt);
void NODE_WGT_backdrop_crop(struct wmManipulatorGroupType *wgt);
+void NODE_WGT_backdrop_sun_beams(struct wmManipulatorGroupType *wgt);
+void NODE_WGT_backdrop_corner_pin(struct wmManipulatorGroupType *wgt);
extern const char *node_context_dir[];
diff --git a/source/blender/editors/space_node/node_manipulators.c b/source/blender/editors/space_node/node_manipulators.c
index 8f614137a84..61006597da8 100644
--- a/source/blender/editors/space_node/node_manipulators.c
+++ b/source/blender/editors/space_node/node_manipulators.c
@@ -47,6 +47,35 @@
/* -------------------------------------------------------------------- */
+/** \name Local Utilities
+ * \{ */
+
+static void node_manipulator_calc_matrix_space(
+ const SpaceNode *snode, const ARegion *ar, float matrix_space[4][4])
+{
+ unit_m4(matrix_space);
+ mul_v3_fl(matrix_space[0], snode->zoom);
+ mul_v3_fl(matrix_space[1], snode->zoom);
+ matrix_space[3][0] = (ar->winx / 2) + snode->xof;
+ matrix_space[3][1] = (ar->winy / 2) + snode->yof;
+}
+
+static void node_manipulator_calc_matrix_space_with_image_dims(
+ const SpaceNode *snode, const ARegion *ar, const float image_dims[2], float matrix_space[4][4])
+{
+ unit_m4(matrix_space);
+ mul_v3_fl(matrix_space[0], snode->zoom * image_dims[0]);
+ mul_v3_fl(matrix_space[1], snode->zoom * image_dims[1]);
+ matrix_space[3][0] = ((ar->winx / 2) + snode->xof) - ((image_dims[0] / 2.0f) * snode->zoom);
+ matrix_space[3][1] = ((ar->winy / 2) + snode->yof) - ((image_dims[1] / 2.0f) * snode->zoom);
+}
+
+/** \} */
+
+
+
+/* -------------------------------------------------------------------- */
+
/** \name Backdrop Manipulator
* \{ */
@@ -304,11 +333,7 @@ static void WIDGETGROUP_node_crop_draw_prepare(const bContext *C, wmManipulatorG
SpaceNode *snode = CTX_wm_space_node(C);
- unit_m4(mpr->matrix_space);
- mul_v3_fl(mpr->matrix_space[0], snode->zoom);
- mul_v3_fl(mpr->matrix_space[1], snode->zoom);
- mpr->matrix_space[3][0] = (ar->winx / 2) + snode->xof;
- mpr->matrix_space[3][1] = (ar->winy / 2) + snode->yof;
+ node_manipulator_calc_matrix_space(snode, ar, mpr->matrix_space);
}
static void WIDGETGROUP_node_crop_refresh(const bContext *C, wmManipulatorGroup *mgroup)
@@ -373,3 +398,226 @@ void NODE_WGT_backdrop_crop(wmManipulatorGroupType *wgt)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Sun Beams
+ * \{ */
+
+struct NodeSunBeamsWidgetGroup {
+ wmManipulator *manipulator;
+
+ struct {
+ float dims[2];
+ } state;
+};
+
+static bool WIDGETGROUP_node_sbeam_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ if ((snode->flag & SNODE_BACKDRAW) == 0) {
+ return false;
+ }
+
+ if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) {
+ bNode *node = nodeGetActive(snode->edittree);
+
+ if (node && ELEM(node->type, CMP_NODE_SUNBEAMS)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void WIDGETGROUP_node_sbeam_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ struct NodeSunBeamsWidgetGroup *sbeam_group = MEM_mallocN(sizeof(struct NodeSunBeamsWidgetGroup), __func__);
+
+ sbeam_group->manipulator = WM_manipulator_new("MANIPULATOR_WT_grab_3d", mgroup, NULL);
+ wmManipulator *mpr = sbeam_group->manipulator;
+
+ RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_CROSS_2D);
+
+ mpr->scale_basis = 0.05f;
+
+ mgroup->customdata = sbeam_group;
+}
+
+static void WIDGETGROUP_node_sbeam_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata;
+ ARegion *ar = CTX_wm_region(C);
+ wmManipulator *mpr = mgroup->manipulators.first;
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ node_manipulator_calc_matrix_space_with_image_dims(snode, ar, sbeam_group->state.dims, mpr->matrix_space);
+}
+
+static void WIDGETGROUP_node_sbeam_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NodeSunBeamsWidgetGroup *sbeam_group = mgroup->customdata;
+ wmManipulator *mpr = sbeam_group->manipulator;
+
+ void *lock;
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ sbeam_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f;
+ sbeam_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f;
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNode *node = nodeGetActive(snode->edittree);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ PointerRNA nodeptr;
+ RNA_pointer_create((ID *)snode->edittree, &RNA_CompositorNodeSunBeams, node, &nodeptr);
+ WM_manipulator_target_property_def_rna(mpr, "offset", &nodeptr, "source", -1);
+
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_MODAL, true);
+ }
+ else {
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true);
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+}
+
+void NODE_WGT_backdrop_sun_beams(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Sun Beams Widget";
+ wgt->idname = "NODE_WGT_sbeam";
+
+ wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT;
+
+ wgt->poll = WIDGETGROUP_node_sbeam_poll;
+ wgt->setup = WIDGETGROUP_node_sbeam_setup;
+ wgt->draw_prepare = WIDGETGROUP_node_sbeam_draw_prepare;
+ wgt->refresh = WIDGETGROUP_node_sbeam_refresh;
+}
+
+/** \} */
+
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Corner Pin
+ * \{ */
+
+struct NodeCornerPinWidgetGroup {
+ wmManipulator *manipulators[4];
+
+ struct {
+ float dims[2];
+ } state;
+};
+
+static bool WIDGETGROUP_node_corner_pin_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ if ((snode->flag & SNODE_BACKDRAW) == 0) {
+ return false;
+ }
+
+ if (snode && snode->edittree && snode->edittree->type == NTREE_COMPOSIT) {
+ bNode *node = nodeGetActive(snode->edittree);
+
+ if (node && ELEM(node->type, CMP_NODE_CORNERPIN)) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static void WIDGETGROUP_node_corner_pin_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ struct NodeCornerPinWidgetGroup *cpin_group = MEM_mallocN(sizeof(struct NodeCornerPinWidgetGroup), __func__);
+ const wmManipulatorType *wt_grab_3d = WM_manipulatortype_find("MANIPULATOR_WT_grab_3d", false);
+
+ for (int i = 0; i < 4; i++) {
+ cpin_group->manipulators[i] = WM_manipulator_new_ptr(wt_grab_3d, mgroup, NULL);
+ wmManipulator *mpr = cpin_group->manipulators[i];
+
+ RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_CROSS_2D);
+
+ mpr->scale_basis = 0.01f;
+ }
+
+ mgroup->customdata = cpin_group;
+}
+
+static void WIDGETGROUP_node_corner_pin_draw_prepare(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata;
+ ARegion *ar = CTX_wm_region(C);
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+
+ float matrix_space[4][4];
+ node_manipulator_calc_matrix_space_with_image_dims(snode, ar, cpin_group->state.dims, matrix_space);
+
+ for (int i = 0; i < 4; i++) {
+ wmManipulator *mpr = cpin_group->manipulators[i];
+ copy_m4_m4(mpr->matrix_space, matrix_space);
+ }
+}
+
+static void WIDGETGROUP_node_corner_pin_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct NodeCornerPinWidgetGroup *cpin_group = mgroup->customdata;
+
+ void *lock;
+ Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
+
+ if (ibuf) {
+ cpin_group->state.dims[0] = (ibuf->x > 0) ? ibuf->x : 64.0f;
+ cpin_group->state.dims[1] = (ibuf->y > 0) ? ibuf->y : 64.0f;
+
+ SpaceNode *snode = CTX_wm_space_node(C);
+ bNode *node = nodeGetActive(snode->edittree);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ int i = 0;
+ for (bNodeSocket *sock = node->inputs.first; sock && i < 4; sock = sock->next) {
+ if (sock->type == SOCK_VECTOR) {
+ wmManipulator *mpr = cpin_group->manipulators[i++];
+
+ PointerRNA sockptr;
+ RNA_pointer_create((ID *)snode->edittree, &RNA_NodeSocket, sock, &sockptr);
+ WM_manipulator_target_property_def_rna(mpr, "offset", &sockptr, "default_value", -1);
+
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_MODAL, true);
+ }
+ }
+ }
+ else {
+ for (int i = 0; i < 4; i++) {
+ wmManipulator *mpr = cpin_group->manipulators[i];
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_HIDDEN, true);
+ }
+ }
+
+ BKE_image_release_ibuf(ima, ibuf, lock);
+}
+
+void NODE_WGT_backdrop_corner_pin(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Corner Pin Widget";
+ wgt->idname = "NODE_WGT_backdrop_corner_pin";
+
+ wgt->flag |= WM_MANIPULATORGROUPTYPE_PERSISTENT;
+
+ wgt->poll = WIDGETGROUP_node_corner_pin_poll;
+ wgt->setup = WIDGETGROUP_node_corner_pin_setup;
+ wgt->draw_prepare = WIDGETGROUP_node_corner_pin_draw_prepare;
+ wgt->refresh = WIDGETGROUP_node_corner_pin_refresh;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index bc4918430ef..af71851cf64 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -867,6 +867,8 @@ static void node_widgets(void)
&(const struct wmManipulatorMapType_Params){SPACE_NODE, RGN_TYPE_WINDOW});
WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_transform);
WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_crop);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_sun_beams);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, NODE_WGT_backdrop_corner_pin);
}
static void node_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c
index ed3bd84be8c..6b8b3466fe8 100644
--- a/source/blender/editors/space_outliner/outliner_draw.c
+++ b/source/blender/editors/space_outliner/outliner_draw.c
@@ -337,7 +337,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
BLI_strncpy(newname, ebone->name, sizeof(ebone->name));
BLI_strncpy(ebone->name, oldname, sizeof(ebone->name));
ED_armature_bone_rename(obedit->data, oldname, newname);
- WM_event_add_notifier(C, NC_OBJECT | ND_POSE, OBACT_NEW);
+ WM_event_add_notifier(C, NC_OBJECT | ND_POSE, OBACT_NEW(sl));
}
break;
}
@@ -350,7 +350,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
/* always make current object active */
tree_element_active(C, scene, sl, soops, te, OL_SETSEL_NORMAL, true);
- ob = OBACT_NEW;
+ ob = OBACT_NEW(sl);
/* restore bone name */
BLI_strncpy(newname, bone->name, sizeof(bone->name));
@@ -367,7 +367,7 @@ static void namebutton_cb(bContext *C, void *tsep, char *oldname)
/* always make current pose-bone active */
tree_element_active(C, scene, sl, soops, te, OL_SETSEL_NORMAL, true);
- ob = OBACT_NEW;
+ ob = OBACT_NEW(sl);
BLI_assert(ob->type == OB_ARMATURE);
@@ -1220,7 +1220,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Sce
/* active blocks get white circle */
if (tselem->type == 0) {
if (te->idcode == ID_OB) {
- active = (OBACT_NEW == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE;
+ active = (OBACT_NEW(sl) == (Object *)tselem->id) ? OL_DRAWSEL_NORMAL : OL_DRAWSEL_NONE;
}
else if (scene->obedit && scene->obedit->data == tselem->id) {
active = OL_DRAWSEL_NORMAL;
@@ -1326,13 +1326,13 @@ static void outliner_draw_tree_element(
else if (te->idcode == ID_OB) {
Object *ob = (Object *)tselem->id;
- if (ob == OBACT_NEW || (ob->flag & SELECT)) {
+ if (ob == OBACT_NEW(sl) || (ob->flag & SELECT)) {
char col[4] = {0, 0, 0, 0};
/* outliner active ob: always white text, circle color now similar to view3d */
active = OL_DRAWSEL_ACTIVE;
- if (ob == OBACT_NEW) {
+ if (ob == OBACT_NEW(sl)) {
if (ob->flag & SELECT) {
UI_GetThemeColorType4ubv(TH_ACTIVE, SPACE_VIEW3D, col);
col[3] = alpha;
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 498e1cfe87f..d9a54f51f7c 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -986,7 +986,7 @@ static int outliner_show_active_exec(bContext *C, wmOperator *UNUSED(op))
TreeElement *te;
int xdelta, ytop;
- Object *obact = OBACT_NEW;
+ Object *obact = OBACT_NEW(sl);
if (!obact)
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index d9590d2af7f..a470711d9df 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -103,7 +103,7 @@ static void do_outliner_object_select_recursive(SceneLayer *sl, Object *ob_paren
{
Base *base;
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
Object *ob = base->object;
if ((((base->flag & BASE_VISIBLED) == 0) && BKE_object_is_child_recursive(ob_parent, ob))) {
ED_object_base_select(base, select ? BA_SELECT : BA_DESELECT);
@@ -151,7 +151,7 @@ static eOLDrawState tree_element_set_active_object(
}
else {
ob = (Object *)outliner_search_back(soops, te, ID_OB);
- if (ob == OBACT_NEW) {
+ if (ob == OBACT_NEW(sl)) {
return OL_DRAWSEL_NONE;
}
}
@@ -209,7 +209,7 @@ static eOLDrawState tree_element_active_material(
/* we search for the object parent */
ob = (Object *)outliner_search_back(soops, te, ID_OB);
// note: ob->matbits can be NULL when a local object points to a library mesh.
- if (ob == NULL || ob != OBACT_NEW || ob->matbits == NULL) {
+ if (ob == NULL || ob != OBACT_NEW(sl) || ob->matbits == NULL) {
return OL_DRAWSEL_NONE; /* just paranoia */
}
@@ -258,7 +258,7 @@ static eOLDrawState tree_element_active_texture(
{
TreeElement *tep;
TreeStoreElem /* *tselem,*/ *tselemp;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
SpaceButs *sbuts = NULL;
if (ob == NULL) {
@@ -347,7 +347,7 @@ static eOLDrawState tree_element_active_lamp(
/* we search for the object parent */
ob = (Object *)outliner_search_back(soops, te, ID_OB);
- if (ob == NULL || ob != OBACT_NEW) {
+ if (ob == NULL || ob != OBACT_NEW(sl)) {
/* just paranoia */
return OL_DRAWSEL_NONE;
}
@@ -423,7 +423,7 @@ static eOLDrawState tree_element_active_defgroup(
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
}
else {
- if (ob == OBACT_NEW)
+ if (ob == OBACT_NEW(sl))
if (ob->actdef == te->index + 1) {
return OL_DRAWSEL_NORMAL;
}
@@ -443,7 +443,7 @@ static eOLDrawState tree_element_active_posegroup(
}
}
else {
- if (ob == OBACT_NEW && ob->pose) {
+ if (ob == OBACT_NEW(sl) && ob->pose) {
if (ob->pose->active_group == te->index + 1) {
return OL_DRAWSEL_NORMAL;
}
@@ -487,7 +487,7 @@ static eOLDrawState tree_element_active_posechannel(
}
}
else {
- if (ob == OBACT_NEW && ob->pose) {
+ if (ob == OBACT_NEW(sl) && ob->pose) {
if (pchan->bone->flag & BONE_SELECTED) {
return OL_DRAWSEL_NORMAL;
}
@@ -504,7 +504,7 @@ static eOLDrawState tree_element_active_bone(
if (set != OL_SETSEL_NONE) {
if (!(bone->flag & BONE_HIDDEN_P)) {
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob) {
if (set != OL_SETSEL_EXTEND) {
/* single select forces all other bones to get unselected */
@@ -533,7 +533,7 @@ static eOLDrawState tree_element_active_bone(
}
}
else {
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob && ob->data == arm) {
if (bone->flag & BONE_SELECTED) {
@@ -842,7 +842,7 @@ eOLDrawState tree_element_type_active(
if (set != OL_SETSEL_NONE) {
tree_element_set_active_object(C, scene, sl, soops, te, set, false);
}
- else if (tselem->id == (ID *)OBACT_NEW) {
+ else if (tselem->id == (ID *)OBACT_NEW(sl)) {
return OL_DRAWSEL_NORMAL;
}
break;
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index adb019766ea..0401505b4cd 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1871,7 +1871,7 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops
}
}
else if (soops->outlinevis == SO_SAME_TYPE) {
- Object *ob_active = OBACT_NEW;
+ Object *ob_active = OBACT_NEW(sl);
if (ob_active) {
FOREACH_SCENE_OBJECT(scene, ob)
{
@@ -1950,8 +1950,8 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SceneLayer *sl, SpaceOops
outliner_add_collections_master(soops, scene);
}
else {
- ten = outliner_add_element(soops, &soops->tree, OBACT_NEW, NULL, 0, 0);
- ten->directdata = BASACT_NEW;
+ ten = outliner_add_element(soops, &soops->tree, OBACT_NEW(sl), NULL, 0, 0);
+ ten->directdata = BASACT_NEW(sl);
}
if ((soops->flag & SO_SKIP_SORT_ALPHA) == 0) {
diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt
index 6dce962ee02..6b8108a1265 100644
--- a/source/blender/editors/space_sequencer/CMakeLists.txt
+++ b/source/blender/editors/space_sequencer/CMakeLists.txt
@@ -54,7 +54,7 @@ set(SRC
)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/editors/space_sequencer/sequencer_add.c b/source/blender/editors/space_sequencer/sequencer_add.c
index 46f212e3679..49c687632f8 100644
--- a/source/blender/editors/space_sequencer/sequencer_add.c
+++ b/source/blender/editors/space_sequencer/sequencer_add.c
@@ -69,7 +69,7 @@
#include "BKE_sound.h"
#ifdef WITH_AUDASPACE
-# include AUD_SEQUENCE_H
+# include <AUD_Sequence.h>
#endif
/* own include */
diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c
index e541c4be653..beb252eb149 100644
--- a/source/blender/editors/space_sequencer/sequencer_draw.c
+++ b/source/blender/editors/space_sequencer/sequencer_draw.c
@@ -40,6 +40,7 @@
#include "DNA_scene_types.h"
#include "DNA_mask_types.h"
+#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_space_types.h"
#include "DNA_userdef_types.h"
@@ -1104,18 +1105,16 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
bool draw_metadata = false;
- if (G.is_rendering == false && (scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
+ if (G.is_rendering == false && (scene->r.seq_prev_type) == OB_RENDER) {
/* stop all running jobs, except screen one. currently previews frustrate Render
* needed to make so sequencer's rendering doesn't conflict with compositor
*/
WM_jobs_kill_type(CTX_wm_manager(C), NULL, WM_JOB_TYPE_COMPOSITE);
- if ((scene->r.seq_flag & R_SEQ_GL_PREV) == 0) {
- /* in case of final rendering used for preview, kill all previews,
- * otherwise threading conflict will happen in rendering module
- */
- WM_jobs_kill_type(CTX_wm_manager(C), NULL, WM_JOB_TYPE_RENDER_PREVIEW);
- }
+ /* in case of final rendering used for preview, kill all previews,
+ * otherwise threading conflict will happen in rendering module
+ */
+ WM_jobs_kill_type(CTX_wm_manager(C), NULL, WM_JOB_TYPE_RENDER_PREVIEW);
}
if ((!draw_overlay || sseq->overlay_type == SEQ_DRAW_OVERLAY_REFERENCE) && !draw_backdrop) {
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 650687429b4..407f4306fec 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -727,7 +727,7 @@ static Sequence *cut_seq_hard(Scene *scene, Sequence *seq, int cutframe)
if (!skip_dup) {
/* Duplicate AFTER the first change */
- seqn = BKE_sequence_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
+ seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
}
if (seqn) {
@@ -820,7 +820,7 @@ static Sequence *cut_seq_soft(Scene *scene, Sequence *seq, int cutframe)
if (!skip_dup) {
/* Duplicate AFTER the first change */
- seqn = BKE_sequence_dupli_recursive(scene, NULL, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
+ seqn = BKE_sequence_dupli_recursive(scene, scene, seq, SEQ_DUPE_UNIQUE_NAME | SEQ_DUPE_ANIM);
}
if (seqn) {
@@ -2139,7 +2139,7 @@ static int sequencer_add_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
if (ed == NULL)
return OPERATOR_CANCELLED;
- BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT);
+ BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_CONTEXT, 0);
if (nseqbase.first) {
Sequence *seq = nseqbase.first;
@@ -3177,7 +3177,7 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME);
+ BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, ed->seqbasep, SEQ_DUPE_UNIQUE_NAME, 0);
/* To make sure the copied strips have unique names between each other add
* them temporarily to the end of the original seqbase. (bug 25932)
@@ -3244,7 +3244,7 @@ static int sequencer_paste_exec(bContext *C, wmOperator *UNUSED(op))
ED_sequencer_deselect_all(scene);
ofs = scene->r.cfra - seqbase_clipboard_frame;
- BKE_sequence_base_dupli_recursive(scene, NULL, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME);
+ BKE_sequence_base_dupli_recursive(scene, scene, &nseqbase, &seqbase_clipboard, SEQ_DUPE_UNIQUE_NAME, 0);
/* transform pasted strips before adding */
if (ofs) {
diff --git a/source/blender/editors/space_sequencer/space_sequencer.c b/source/blender/editors/space_sequencer/space_sequencer.c
index 5dfcba9b4d1..3b04e6c80cd 100644
--- a/source/blender/editors/space_sequencer/space_sequencer.c
+++ b/source/blender/editors/space_sequencer/space_sequencer.c
@@ -436,7 +436,8 @@ static void sequencer_dropboxes(void)
/* ************* end drop *********** */
-static const char *sequencer_context_dir[] = {"edit_mask", NULL};
+/* DO NOT make this static, this hides the symbol and breaks API generation script. */
+const char *sequencer_context_dir[] = {"edit_mask", NULL};
static int sequencer_context(const bContext *C, const char *member, bContextDataResult *result)
{
diff --git a/source/blender/editors/space_text/text_format_pov.c b/source/blender/editors/space_text/text_format_pov.c
index 0d19c503798..1ef3322711c 100644
--- a/source/blender/editors/space_text/text_format_pov.c
+++ b/source/blender/editors/space_text/text_format_pov.c
@@ -49,36 +49,38 @@ static int txtfmt_pov_find_keyword(const char *string)
{
int i, len;
/* Language Directives */
- if (STR_LITERAL_STARTSWITH(string, "append", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "case", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "debug", len)) i = len;
+ if (STR_LITERAL_STARTSWITH(string, "deprecated", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "persistent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "statistics", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "version", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "warning", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "declare", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "default", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "deprecated", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "include", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "append", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "elseif", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "debug", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "end", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "error", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "fclose", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "fopen", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "ifndef", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "ifdef", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "include", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "patch", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "local", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "macro", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "range", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "read", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "render", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "statistics", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "switch", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "undef", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "version", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "warning", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "while", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "write", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "case", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "end", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
else i = 0;
/* If next source char is an identifier (eg. 'i' in "definate") no match */
@@ -92,221 +94,275 @@ static int txtfmt_pov_find_reserved_keywords(const char *string)
* list is from...
* http://www.povray.org/documentation/view/3.7.0/212/
*/
+
+ /* Float Functions */
+ if (STR_LITERAL_STARTSWITH(string, "conserve_energy", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_intersections", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dimension_size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bitwise_and", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bitwise_or", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bitwise_xor", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "file_exists", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "precompute", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dimensions", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clipped_by", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "shadowless", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "turb_depth", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "reciprocal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quaternion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "phong_size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tesselate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "save_file", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "load_file", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_trace", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "transform", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "translate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "direction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "roughness", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "metallic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gts_load", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gts_save", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "location", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "altitude", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "function", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "evaluate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inverse", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "collect", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "target", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "albedo", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rotate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "matrix", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "look_at", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "jitter", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "angle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "right", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "scale", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "child", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "crand", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "blink", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "defined", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "degrees", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inside", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "radians", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vlength", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "select", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "floor", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strcmp", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strlen", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tessel", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sturm", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "abs", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "acosh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "prod", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "with", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "acos", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "asc", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "asinh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "asin", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "atan2", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "atand", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "atanh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "atan", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ceil", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "warp", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cosh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "log", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "min", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mod", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pow", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rand", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "seed", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "form", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sinh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sqrt", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tanh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vdot", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sin", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sqr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sum", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pwr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tan", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "val", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cos", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "div", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "exp", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "int", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sky", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "up", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ln", len)) i = len;
+ /* Color Identifiers */
+ else if (STR_LITERAL_STARTSWITH(string, "transmit", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "filter", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "srgbft", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "srgbf", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "srgbt", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rgbft", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gamma", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "green", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "blue", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gray", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "srgb", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sRGB", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "SRGB", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rgbf", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rgbt", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rgb", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "red", len)) i = len;
+ /* Color Spaces */
+ else if (STR_LITERAL_STARTSWITH(string, "pov", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hsl", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hsv", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "xyl", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "xyv", len)) i = len;
+ /* Vector Functions */
+ else if (STR_LITERAL_STARTSWITH(string, "vaxis_rotate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vturbulence", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "min_extent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vnormalize", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_extent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vrotate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vcross", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "trace", len)) i = len;
+ /* String Functions */
+ else if (STR_LITERAL_STARTSWITH(string, "file_time", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "datetime", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "concat", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strlwr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strupr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "substr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vstr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "chr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "str", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
+}
+
+
+static int txtfmt_pov_find_reserved_builtins(const char *string)
+{
+ int i, len;
+
+ /* POV-Ray Built-in Variables
+ * list is from...
+ * http://www.povray.org/documentation/view/3.7.0/212/
+ */
/* Language Keywords */
- if (STR_LITERAL_STARTSWITH(string, "aa_level", len)) i = len;
+ if (STR_LITERAL_STARTSWITH(string, "reflection_exponent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "area_illumination", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "all_intersections", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cutaway_textures", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "smooth_triangle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lommel_seeliger", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "falloff_angle", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "aa_threshold", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hypercomplex", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "major_radius", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_distance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_iteration", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "colour_space", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "color_space", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "iridescence", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "subsurface", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "scattering", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "absorption", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "accuracy", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "adc_bailout", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "albedo", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "all_intersections", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "translucency", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "all", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "alpha", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "altitude", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "always_sample", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ambient_light", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ambient", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "angle", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "aperture", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "water_level", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "reflection", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_extent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "oren_nayar", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "refraction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hierarchy", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "radiosity", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tolerance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "interior", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "toroidal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "emission", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "material", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "internal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "photons", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "arc_angle", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "area_light", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "area_illumination", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "minnaert", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "texture", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "array", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "assumed_gamma", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "autostop", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "black_hole", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "blur_samples", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "brightness", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "brilliance", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "caustics", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "charset", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "collect", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "component", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "composite", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "confidence", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "conserve_energy", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "contained_by", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "coords", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "count", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "crand", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "cube", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "cutaway_textures", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "diffuse", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "direction", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "dispersion_samples", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "dispersion", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "dist_exp", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "distance", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "eccentricity", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "emission", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "error_bound", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "evaluate", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "expand_thresholds", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "exponent", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "exterior", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "extinction", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "face_indices", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "falloff_angle", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "falloff", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "file_gamma", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "flatness", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "planet", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "screw", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "keep", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "flip", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "focal_point", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "fog_alt", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "fog_offset", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "fog_type", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "form", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "fresnel", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "function", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "gamma", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "gather", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "global_settings", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "gray_threshold", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "hf_gray_16", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "hierarchy", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "hypercomplex", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "importance", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "inside_vector", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "internal", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "intervals", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ior", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "irid_wavelength", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "irid", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "load_file", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "location", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "move", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "roll", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "look_at", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "looks_like", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "low_error_factor", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "major_radius", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "max_distance", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "max_extent", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "max_gradient", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "max_intersections", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "max_iteration", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "max_sample", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "max_trace_level", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "max_trace", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "maximum_reuse", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "metallic", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "method", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "metric", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "minimum_reuse", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "nearest_count", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "normal_indices", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "normal_vectors", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "now", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "number_of_waves", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "offset", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "open", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "orientation", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pass_through", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "pattern", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "phong_size", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "phong", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "point_at", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pot", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "precision", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "precompute", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pretrace_end", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pretrace_start", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "prod", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pwr", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "quaternion", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "radiosity", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "radius", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ratio", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "reciprocal", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "recursion_limit", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "reflection_exponent", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "reflection", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "refraction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "width", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "repeat", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "right", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "roughness", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "samples", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "save_file", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "scattering", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bend", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "size", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sky", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "alpha", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "slice", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "smooth", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "solid", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "spacing", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "specular", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "split_union", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "spotlight", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "strength", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sturm", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sum", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "target", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "texture_list", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "thickness", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "threshold", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "tightness", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "tolerance", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "toroidal", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ttf", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "turb_depth", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "all", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "now", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pot", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "type", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "u_steps", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "up", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "use_alpha", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "uv_indices", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "uv_vectors", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "v_steps", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "variance", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "vertex_vectors", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "water_level", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "width", len)) i = len;
-
- else i = 0;
-
- /* If next source char is an identifier (eg. 'i' in "definate") no match */
- return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
-}
-
-
-static int txtfmt_pov_find_reserved_builtins(const char *string)
-{
- int i, len;
-
- /* POV-Ray Built-in Variables
- * list is from...
- * http://www.povray.org/documentation/view/3.7.0/212/
- */
- if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "clock", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "clock_on", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "final_clock", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "final_frame", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "frame_number", len)) i = len;
+ /* Animation Options */
+ else if (STR_LITERAL_STARTSWITH(string, "global_settings", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "input_file_name", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "initial_clock", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "initial_frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "frame_number", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "image_height", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "image_width", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "input_file_name", len)) i = len;
- /* Color Identifiers */
- else if (STR_LITERAL_STARTSWITH(string, "blue", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "filter", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "gray", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "green", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "red", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "rgbft", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "rgbf", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "rgbt", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "rgb", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "srgb", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sRGB", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "SRGB", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "srgbft", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "srgbf", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "srgbt", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "transmit", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "final_clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "final_frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock_on", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock", len)) i = len;
+ /* Spline Identifiers */
+ else if (STR_LITERAL_STARTSWITH(string, "extended_x_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "general_x_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quadratic_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "basic_x_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "natural_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "linear_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bezier_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "akima_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sor_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tcb_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "linear_sweep", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "conic_sweep", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "b_spline", len)) i = len;
/* Patterns */
- else if (STR_LITERAL_STARTSWITH(string, "agate", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "aoi", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pigment_pattern", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_pattern", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "density_file", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cylindrical", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "proportion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "triangular", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "proximity", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spherical", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bump_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "wrinkles", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "average", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "voronoi", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "masonry", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "binary", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "boxed", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "bozo", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "brick", len)) i = len;
@@ -315,14 +371,11 @@ static int txtfmt_pov_find_reserved_builtins(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "checker", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "crackle", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "cubic", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "cylindrical", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "density_file", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "dents", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "facets", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "gradient", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "granite", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "hexagon", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "image_pattern", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "julia", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "leopard", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "magnet", len)) i = len;
@@ -330,13 +383,11 @@ static int txtfmt_pov_find_reserved_builtins(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "marble", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "onion", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "pavement", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pigment_pattern", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "planar", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "quilted", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "radial", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "ripples", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "slope", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "spherical", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "spiral1", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "spiral2", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "spotted", len)) i = len;
@@ -344,97 +395,68 @@ static int txtfmt_pov_find_reserved_builtins(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "tile2", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "tiling", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "tiles", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "triangular", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "waves", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "wood", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "wrinkles", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "agate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "aoi", len)) i = len;
/* Objects */
- else if (STR_LITERAL_STARTSWITH(string, "background", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "superellipsoid", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "bicubic_patch", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "blob", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "box", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "camera", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "cone", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "cubic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "julia_fractal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "height_field", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sphere_sweep", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "light_group", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "light_source", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "intersection", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "isosurface", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "background", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sky_sphere", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "cylinder", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "difference", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "brilliance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "parametric", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "interunion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "intermerge", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "polynomial", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "displace", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "specular", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ambient", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "diffuse", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "polygon", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quadric", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quartic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rainbow", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sphere", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "prism", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "camera", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "galley", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "phong", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cone", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "blob", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "box", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "disc", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "fog", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "height_field", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "intersection", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "isosurface", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "julia_fractal", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "lathe", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "light_group", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "light_source", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "merge", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "mesh2", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "mesh", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "object", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "ovus", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "lemon", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "parametric", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "plane", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "poly", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "polygon", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "polynomial", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "prism", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "quadric", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "quartic", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "rainbow", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sky_sphere", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "smooth_triangle", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "cubic_spline", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sphere_sweep", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sphere", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "spline", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "superellipsoid", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "irid", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "sor", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "text", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "torus", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "triangle", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "union", len)) i = len;
- /* Filetypes */
- else if (STR_LITERAL_STARTSWITH(string, "df3", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "exr", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "gif", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "hdr", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "iff", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "jpeg", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pgm", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "png", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ppm", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sys", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "tga", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "tiff", len)) i = len;
- /* Spline Identifiers */
- else if (STR_LITERAL_STARTSWITH(string, "b_spline", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "bezier_spline", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "conic_sweep", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "cubic_spline", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "linear_spline", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "linear_sweep", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "natural_spline", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "quadratic_spline", len)) i = len;
- /* Encodings */
- else if (STR_LITERAL_STARTSWITH(string, "ascii", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "utf8", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "uint8", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "uint16be", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "uint16le", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sint8", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sint16be", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sint16le", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sint32be", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sint32le", len)) i = len;
- /* Camera Types */
- else if (STR_LITERAL_STARTSWITH(string, "fisheye", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "mesh_camera", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "omnimax", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "orthographic", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "panoramic", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "perspective", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ultra_wide_angle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "colour", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "color", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "media", len)) i = len;
/* Built-in Vectors */
else if (STR_LITERAL_STARTSWITH(string, "t", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "u", len)) i = len;
@@ -442,7 +464,6 @@ static int txtfmt_pov_find_reserved_builtins(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "x", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "y", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "z", len)) i = len;
-
else i = 0;
/* If next source char is an identifier (eg. 'i' in "definate") no match */
@@ -465,156 +486,201 @@ static int txtfmt_pov_find_specialvar(const char *string)
{
int i, len;
/* Modifiers */
- if (STR_LITERAL_STARTSWITH(string, "interior_texture", len)) i = len;
+ if (STR_LITERAL_STARTSWITH(string, "dispersion_samples", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "projected_through", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "double_illuminate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "expand_thresholds", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "media_interaction", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "media_attenuation", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "projected_through", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "low_error_factor", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "recursion_limit", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "interior_texture", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_trace_level", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gray_threshold", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pretrace_start", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "normal_indices", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "normal_vectors", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vertex_vectors", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "noise_generator", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "irid_wavelength", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "number_of_waves", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ambient_light", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inside_vector", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "face_indices", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "texture_list", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_gradient", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uv_indices", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uv_vectors", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fade_distance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "global_lights", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_bump_scale", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pretrace_end", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_radiosity", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_reflection", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "assumed_gamma", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "scallop_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "triangle_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "nearest_count", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "maximum_reuse", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "minimum_reuse", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "always_sample", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "translucency", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "eccentricity", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "contained_by", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inside_point", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "adc_bailout", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "density_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "split_union", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mm_per_unit", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "agate_turb", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "bounded_by", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "brick_size", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "bump_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "bump_size", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "circular", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "clipped_by", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "cubic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hf_gray_16", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dispersion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "extinction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "thickness", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "color_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "color", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "colour_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "colour", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "control0", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "control1", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "cubic_wave", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "density_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "density", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "fade_color", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "fade_colour", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "fade_distance", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "fade_power", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "frequency", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "global_lights", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "hollow", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "image_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "adaptive", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "interior", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "interpolate", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "inverse", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "jitter", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "lambda", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "map_type", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "material_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "material", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "matrix", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "media", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "mm_per_unit", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "mortar", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "no_bump_scale", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "no_image", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "no_radiosity", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "no_reflection", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "no_shadow", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fade_color", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "normal_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "normal", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "octaves", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "omega", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "once", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "orient", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "parallel", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "phase", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "photons", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "pigment_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pigment", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "finish", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "poly_wave", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "quick_color", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "quick_colour", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ramp_wave", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "rotate", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "scale", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "scallop_wave", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "shadowless", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sine_wave", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "slope_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "subsurface", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "material_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pass_through", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "interpolate", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "texture_map", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "texture", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "transform", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "translate", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "triangle_wave", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "turbulence", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "error_bound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "brightness", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "use_color", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "use_alpha", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "use_colour", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "use_index", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "uv_mapping", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "warp", len)) i = len;
-
- /* Vector Functions */
- else if (STR_LITERAL_STARTSWITH(string, "max_extent", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "min_extent", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "trace", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "vaxis_rotate", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "vcross", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "vnormalize", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "vrotate", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "vturbulence", len)) i = len;
- /* String Functions */
- else if (STR_LITERAL_STARTSWITH(string, "chr", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "concat", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "datetime", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "str", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "strlwr", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "strupr", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "substr", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "vstr", len)) i = len;
- /* Float Functions */
- else if (STR_LITERAL_STARTSWITH(string, "abs", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "acosh", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "acos", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "asc", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "asinh", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "asin", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "atan2", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "atand", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "atanh", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "atan", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "bitwise_and", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "bitwise_or", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "bitwise_xor", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ceil", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "cosh", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "cos", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "defined", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "degrees", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "dimension_size", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "dimensions", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "div", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "exp", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "file_exists", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "floor", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "inside", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "int", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ln", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "log", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "max", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "min", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "mod", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pow", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "radians", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "rand", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "seed", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "select", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sinh", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sin", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sqrt", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "sqr", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "strcmp", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "strlen", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "tanh", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "tan", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "val", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "vdot", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "vlength", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "importance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_sample", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "intervals", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sine_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "slope_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "poly_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_shadow", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ramp_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "precision", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "original", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "accuracy", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "map_type", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_image", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "distance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "autostop", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "caustics", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "octaves", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "aa_level", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "frequency", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fog_offset", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "modulation", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "outbound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_cache", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pigment", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "charset", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inbound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "outside", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inner", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "turbulence", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "threshold", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "accuracy", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "polarity", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bump_size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "circular", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "control0", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "control1", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "maximal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "minimal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fog_type", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fog_alt", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "samples", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "origin", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "amount", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "adaptive", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "exponent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strength", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "density", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fresnel", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "albinos", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "finish", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "method", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "omega", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fixed", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spacing", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "u_steps", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "v_steps", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "offset", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hollow", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gather", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lambda", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mortar", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "count", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "once", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "orient", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "normal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "phase", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ratio", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "open", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ior", len)) i = len;
+ /* Light Types and options*/
+ else if (STR_LITERAL_STARTSWITH(string, "area_light", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "looks_like", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fade_power", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tightness", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spotlight", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "parallel", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "point_at", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "falloff", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "radius", len)) i = len;
+ /* Camera Types and options*/
+ else if (STR_LITERAL_STARTSWITH(string, "omni_directional_stereo", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lambert_cylindrical", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "miller_cylindrical", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lambert_azimuthal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ultra_wide_angle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "camera_direction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "camera_location ", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "van_der_grinten", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "aitoff_hammer", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "smyth_craster", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "orthographic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "camera_right", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "blur_samples", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "plate_carree", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "camera_type", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "perspective", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mesh_camera", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "focal_point", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "balthasart", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "confidence", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "parallaxe", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hobo_dyer", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "camera_up", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "panoramic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "eckert_vi", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "eckert_iv", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mollweide", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "aperture", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "behrmann", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "variance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "stereo", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "icosa", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tetra", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "octa", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mercator", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "omnimax", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fisheye", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "edwards", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "peters", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gall", len)) i = len;
else i = 0;
/* If next source char is an identifier (eg. 'i' in "definate") no match */
@@ -625,15 +691,43 @@ static int txtfmt_pov_find_bool(const char *string)
{
int i, len;
/*Built-in Constants*/
- if (STR_LITERAL_STARTSWITH(string, "false", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "no", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "off", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "true", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "yes", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "on", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "pi", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "tau", len)) i = len;
- else i = 0;
+ if (STR_LITERAL_STARTSWITH(string, "unofficial", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "false", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "off", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "true", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "yes", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "on", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pi", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tau", len)) i = len;
+ /* Encodings */
+ else if (STR_LITERAL_STARTSWITH(string, "sint16be", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint16le", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint32be", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint32le", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uint16be", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uint16le", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bt2020", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bt709", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint8", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uint8", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ascii", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "utf8", len)) i = len;
+ /* Filetypes */
+ else if (STR_LITERAL_STARTSWITH(string, "tiff", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "df3", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "exr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gif", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hdr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "iff", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "jpeg", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pgm", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "png", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ppm", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sys", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tga", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ttf", len)) i = len;
+ else i = 0;
/* If next source char is an identifier (eg. 'i' in "Nonetheless") no match */
return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
@@ -645,7 +739,7 @@ static char txtfmt_pov_format_identifier(const char *str)
if ((txtfmt_pov_find_specialvar(str)) != -1) fmt = FMT_TYPE_SPECIAL;
else if ((txtfmt_pov_find_keyword(str)) != -1) fmt = FMT_TYPE_KEYWORD;
else if ((txtfmt_pov_find_reserved_keywords(str)) != -1) fmt = FMT_TYPE_RESERVED;
- else if ((txtfmt_pov_find_reserved_builtins(str)) != -1) fmt = FMT_TYPE_RESERVED;
+ else if ((txtfmt_pov_find_reserved_builtins(str)) != -1) fmt = FMT_TYPE_DIRECTIVE;
else fmt = FMT_TYPE_DEFAULT;
return fmt;
}
@@ -770,7 +864,7 @@ static void txtfmt_pov_format_line(SpaceText *st, TextLine *line, const bool do_
if ((i = txtfmt_pov_find_specialvar(str)) != -1) prev = FMT_TYPE_SPECIAL;
else if ((i = txtfmt_pov_find_keyword(str)) != -1) prev = FMT_TYPE_KEYWORD;
else if ((i = txtfmt_pov_find_reserved_keywords(str)) != -1) prev = FMT_TYPE_RESERVED;
- else if ((i = txtfmt_pov_find_reserved_builtins(str)) != -1) prev = FMT_TYPE_RESERVED;
+ else if ((i = txtfmt_pov_find_reserved_builtins(str)) != -1) prev = FMT_TYPE_DIRECTIVE;
if (i > 0) {
text_format_fill_ascii(&str, &fmt, prev, i);
diff --git a/source/blender/editors/space_text/text_format_pov_ini.c b/source/blender/editors/space_text/text_format_pov_ini.c
index 719f4e3c036..453dd1d748c 100644
--- a/source/blender/editors/space_text/text_format_pov_ini.c
+++ b/source/blender/editors/space_text/text_format_pov_ini.c
@@ -49,36 +49,36 @@ static int txtfmt_ini_find_keyword(const char *string)
{
int i, len;
/* Language Directives */
- if (STR_LITERAL_STARTSWITH(string, "append", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "case", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "debug", len)) i = len;
+ if (STR_LITERAL_STARTSWITH(string, "deprecated", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "statistics", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "declare", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "default", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "deprecated", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "version", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "warning", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "include", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fclose", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ifndef", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "append", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "elseif", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "end", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "debug", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "error", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "fclose", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "fopen", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "ifdef", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ifndef", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "include", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "local", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "macro", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "range", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "read", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "render", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "statistics", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "switch", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "undef", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "version", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "warning", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "while", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "write", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "case", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "read", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "end", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "I", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "S", len)) i = len;
@@ -104,29 +104,54 @@ static int txtfmt_ini_find_reserved(const char *string)
* list is from...
* http://www.povray.org/documentation/view/3.7.0/212/
*/
- if (STR_LITERAL_STARTSWITH(string, "Antialias_Threshold", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Bounding_Method", len)) i = len;
+ if (STR_LITERAL_STARTSWITH(string, "RenderCompleteSoundEnabled", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Create_Continue_Trace_Log", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ParseErrorSoundEnabled", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "RenderErrorSoundEnabled", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "HideWhenMainMinimized", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Antialias_Confidence", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "RenderCompleteSound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ParseErrorSound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "RenderErrorSound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "UseExtensions", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ReadWriteSourceDir", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionLeft", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionTop", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionRight", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionBottom", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Pre_Scene_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Pre_Frame_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Post_Scene_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Post_Frame_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "User_Abort_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Fatal_Error_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionX", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionY", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Pre_Scene_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Pre_Frame_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Post_Scene_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Post_Frame_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "User_Abort_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Fatal_Error_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Antialias_Threshold", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Antialias_Gamma", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Antialias_Depth", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "clock_on", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "clock", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "final_clock", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "final_frame", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "frame_number", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "initial_clock", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "initial_frame", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "image_height", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "image_width", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "input_file_name", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Subset_Start_Frame", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Subset_End_Frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "UseToolbar", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "UseTooltips", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Frame_Step", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Cyclic_Animation", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Field_Render", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Odd_Field", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Height", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "final_clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "final_frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "frame_number", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "initial_clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "initial_frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_height", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_width", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Start_Column", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Start_Row", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "End_Column", len)) i = len;
@@ -134,7 +159,7 @@ static int txtfmt_ini_find_reserved(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "Test_Abort_Count", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Test_Abort", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Continue_Trace", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Create_Continue_Trace_Log", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Bounding_Method", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Create_Ini", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Display_Gamma", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Display", len)) i = len;
@@ -151,19 +176,6 @@ static int txtfmt_ini_find_reserved(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "Bits_Per_Color", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Compression", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Dither_Method", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Dither", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Pre_Scene_Command", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Pre_Frame_Command", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Post_Scene_Command", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Post_Frame_Command", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "User_Abort_Command", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Fatal_Error_Command", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Pre_Scene_Return", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Pre_Frame_Return", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Post_Scene_Return", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Post_Frame_Return", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "User_Abort_Return", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Fatal_Error_Return", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Include_Header", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Library_Path", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Debug_Console", len)) i = len;
@@ -187,7 +199,9 @@ static int txtfmt_ini_find_reserved(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "Remove_Bounds", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Split_Unions", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Antialias", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Glare_Desaturation", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Sampling_Method", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Stochastic_Seed", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Jitter_Amount", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Jitter", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Antialias_Depth", len)) i = len;
@@ -221,25 +235,14 @@ static int txtfmt_ini_find_reserved(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "Band3Width", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Band4Width", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "ShowCmd", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "NormalPositionLeft", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "NormalPositionTop", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "NormalPositionRight", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "NormalPositionBottom", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "UseToolbar", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "UseTooltips", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "NormalPositionX", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "NormalPositionY", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Flags", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Transparency", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Use8BitMode", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "MakeActive", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "KeepAboveMain", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "HideWhenMainMinimized", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "AutoClose", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "PreserveBitmap", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "FontSize", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "FontWeight", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "Font", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "KeepMessages", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "AlertSound", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Completion", len)) i = len;
@@ -250,14 +253,6 @@ static int txtfmt_ini_find_reserved(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "PreventSleep", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "NoShelloutWait", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "SystemNoActive", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "RenderCompleteSoundEnabled", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ParseErrorSoundEnabled", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "RenderErrorSoundEnabled", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "RenderCompleteSound", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ParseErrorSound", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "RenderErrorSound", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "UseExtensions", len)) i = len;
- else if (STR_LITERAL_STARTSWITH(string, "ReadWriteSourceDir", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "NoShellOuts", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "VideoSource", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "SceneFile", len)) i = len;
@@ -269,6 +264,14 @@ static int txtfmt_ini_find_reserved(const char *string)
else if (STR_LITERAL_STARTSWITH(string, "RenderwinClose", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Append_File", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "Warning Level", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock_on", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Height", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Dither", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Flags", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Font", len)) i = len;
/* Filetypes */
else if (STR_LITERAL_STARTSWITH(string, "df3", len)) i = len;
else if (STR_LITERAL_STARTSWITH(string, "exr", len)) i = len;
diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt
index 6802658803b..6bf0d142aa4 100644
--- a/source/blender/editors/space_view3d/CMakeLists.txt
+++ b/source/blender/editors/space_view3d/CMakeLists.txt
@@ -60,7 +60,9 @@ set(SRC
view3d_walk.c
view3d_header.c
view3d_iterators.c
+ view3d_manipulator_armature.c
view3d_manipulator_camera.c
+ view3d_manipulator_empty.c
view3d_manipulator_forcefield.c
view3d_manipulator_lamp.c
view3d_ops.c
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 191dfed01bf..11aa3476ee1 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -411,11 +411,11 @@ static void drawsolidcube_size(float xsize, float ysize, float zsize)
gpuScale3f(xsize, ysize, zsize);
if (flat_color) {
- Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
else {
/* TODO replace with good default lighting shader ? */
- Batch_set_builtin_program(&batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_SIMPLE_LIGHTING);
GWN_batch_uniform_3fv(&batch, "light", light_vec);
}
GWN_batch_uniform_4fv(&batch, "color", fcolor);
@@ -451,7 +451,7 @@ static void drawcube_size(float xsize, float ysize, float zsize)
}
GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, &el);
- Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
gpuPushMatrix();
@@ -507,7 +507,7 @@ static void draw_bonevert(void)
}
GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, NULL);
- Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
GWN_batch_program_use_begin(&batch);
@@ -517,18 +517,18 @@ static void draw_bonevert(void)
static void draw_bonevert_solid(void)
{
- Gwn_Batch *batch = Batch_get_sphere(0);
+ Gwn_Batch *batch = GPU_batch_preset_sphere(0);
const float light_vec[3] = {0.0f, 0.0f, 1.0f};
gpuPushMatrix();
gpuScaleUniform(0.05);
if (flat_color) {
- Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
else {
/* TODO replace with good default lighting shader ? */
- Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING);
GWN_batch_uniform_3fv(batch, "light", light_vec);
}
GWN_batch_uniform_4fv(batch, "color", fcolor);
@@ -603,7 +603,7 @@ static void draw_bone_octahedral(void)
}
GWN_batch_init(&batch, GWN_PRIM_LINES, &vbo, &el);
- Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
GWN_batch_program_use_begin(&batch);
@@ -640,11 +640,11 @@ static void draw_bone_solid_octahedral(void)
}
if (flat_color) {
- Batch_set_builtin_program(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_3D_UNIFORM_COLOR);
}
else {
/* TODO replace with good default lighting shader ? */
- Batch_set_builtin_program(&batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_SIMPLE_LIGHTING);
GWN_batch_uniform_3fv(&batch, "light", light_vec);
}
GWN_batch_uniform_4fv(&batch, "color", fcolor);
@@ -993,13 +993,13 @@ static void draw_sphere_bone_wire(float smat[4][4], float imat[4][4],
static void draw_sphere_bone(const short dt, int armflag, int boneflag, short constflag, unsigned int id,
bPoseChannel *pchan, EditBone *ebone)
{
- Gwn_Batch *sphere = Batch_get_sphere(1);
+ Gwn_Batch *sphere = GPU_batch_preset_sphere(1);
float head, tail, length;
float fac1, fac2, size1, size2;
const float light_vec[3] = {0.0f, 0.0f, 1.0f};
/* dt is always OB_SOlID */
- Batch_set_builtin_program(sphere, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_program_set_builtin(sphere, GPU_SHADER_SIMPLE_LIGHTING);
GWN_batch_uniform_3fv(sphere, "light", light_vec);
gpuPushMatrix();
@@ -1610,8 +1610,10 @@ static void draw_bone(const short dt, int armflag, int boneflag, short constflag
}
}
-static void draw_custom_bone(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob,
- const short dt, int armflag, int boneflag, unsigned int id, float length)
+static void draw_custom_bone(
+ const struct EvaluationContext *eval_ctx,
+ Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob,
+ const short dt, int armflag, int boneflag, unsigned int id, float length)
{
if (ob == NULL) return;
@@ -1626,7 +1628,7 @@ static void draw_custom_bone(const bContext *C, Scene *scene, SceneLayer *sl, Vi
GPU_select_load_id((GLuint) id | BONESEL_BONE);
}
- draw_object_instance(C, scene, sl, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE, fcolor);
+ draw_object_instance(eval_ctx, scene, sl, v3d, rv3d, ob, dt, armflag & ARM_POSEMODE, fcolor);
}
@@ -1930,9 +1932,10 @@ static void bone_matrix_translate_y(float mat[4][4], float y)
}
/* assumes object is Armature with pose */
-static void draw_pose_bones(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
- const short dt, const unsigned char ob_wire_col[4],
- const bool do_const_color, const bool is_outline)
+static void draw_pose_bones(
+ const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
+ const short dt, const unsigned char ob_wire_col[4],
+ const bool do_const_color, const bool is_outline)
{
RegionView3D *rv3d = ar->regiondata;
Object *ob = base->object;
@@ -2057,7 +2060,7 @@ static void draw_pose_bones(const bContext *C, Scene *scene, SceneLayer *sl, Vie
glDisable(GL_CULL_FACE);
}
- draw_custom_bone(C, scene, sl, v3d, rv3d, pchan->custom,
+ draw_custom_bone(eval_ctx, scene, sl, v3d, rv3d, pchan->custom,
OB_SOLID, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan));
}
}
@@ -2153,7 +2156,7 @@ static void draw_pose_bones(const bContext *C, Scene *scene, SceneLayer *sl, Vie
if (bone == arm->act_bone)
flag |= BONE_DRAW_ACTIVE;
- draw_custom_bone(C, scene, sl, v3d, rv3d, pchan->custom,
+ draw_custom_bone(eval_ctx, scene, sl, v3d, rv3d, pchan->custom,
OB_WIRE, arm->flag, flag, index, PCHAN_CUSTOM_DRAW_SIZE(pchan));
gpuPopMatrix();
@@ -2659,9 +2662,9 @@ static void ghost_poses_tag_unselected(Object *ob, short unset)
/* draw ghosts that occur within a frame range
* note: object should be in posemode
*/
-static void draw_ghost_poses_range(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base)
+static void draw_ghost_poses_range(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base)
{
- EvaluationContext eval_ctx;
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
bArmature *arm = ob->data;
@@ -2669,8 +2672,6 @@ static void draw_ghost_poses_range(const bContext *C, Scene *scene, SceneLayer *
float start, end, stepsize, range, colfac;
int cfrao, flago;
unsigned char col[4];
-
- CTX_data_eval_ctx(C, &eval_ctx);
start = (float)arm->ghostsf;
end = (float)arm->ghostef;
@@ -2706,8 +2707,8 @@ static void draw_ghost_poses_range(const bContext *C, Scene *scene, SceneLayer *
UI_GetThemeColorShadeAlpha4ubv(TH_WIRE, 0, -128 - (int)(120.0f * sqrtf(colfac)), col);
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(&eval_ctx, scene, ob);
- draw_pose_bones(C, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
+ BKE_pose_where_is(eval_ctx, scene, ob);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2729,9 +2730,10 @@ static void draw_ghost_poses_range(const bContext *C, Scene *scene, SceneLayer *
/* draw ghosts on keyframes in action within range
* - object should be in posemode
*/
-static void draw_ghost_poses_keys(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, BaseLegacy *base)
+static void draw_ghost_poses_keys(
+ const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl,
+ View3D *v3d, ARegion *ar, BaseLegacy *base)
{
- EvaluationContext eval_ctx;
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
bAction *act = (adt) ? adt->action : NULL;
@@ -2742,8 +2744,6 @@ static void draw_ghost_poses_keys(const bContext *C, Scene *scene, SceneLayer *s
float start, end, range, colfac, i;
int cfrao, flago;
unsigned char col[4];
-
- CTX_data_eval_ctx(C, &eval_ctx);
start = (float)arm->ghostsf;
end = (float)arm->ghostef;
@@ -2790,8 +2790,8 @@ static void draw_ghost_poses_keys(const bContext *C, Scene *scene, SceneLayer *s
CFRA = (int)ak->cfra;
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(&eval_ctx, scene, ob);
- draw_pose_bones(C, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
+ BKE_pose_where_is(eval_ctx, scene, ob);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
glDisable(GL_BLEND);
if (v3d->zbuf) glEnable(GL_DEPTH_TEST);
@@ -2814,9 +2814,10 @@ static void draw_ghost_poses_keys(const bContext *C, Scene *scene, SceneLayer *s
/* draw ghosts around current frame
* - object is supposed to be armature in posemode
*/
-static void draw_ghost_poses(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base)
+static void draw_ghost_poses(
+ const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl,
+ View3D *v3d, ARegion *ar, Base *base)
{
- EvaluationContext eval_ctx;
Object *ob = base->object;
AnimData *adt = BKE_animdata_from_id(&ob->id);
bArmature *arm = ob->data;
@@ -2825,8 +2826,6 @@ static void draw_ghost_poses(const bContext *C, Scene *scene, SceneLayer *sl, Vi
int cfrao, flago;
unsigned char col[4];
- CTX_data_eval_ctx(C, &eval_ctx);
-
/* pre conditions, get an action with sufficient frames */
if (ELEM(NULL, adt, adt->action))
return;
@@ -2871,8 +2870,8 @@ static void draw_ghost_poses(const bContext *C, Scene *scene, SceneLayer *sl, Vi
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(&eval_ctx, scene, ob);
- draw_pose_bones(C, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
+ BKE_pose_where_is(eval_ctx, scene, ob);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
}
@@ -2886,8 +2885,8 @@ static void draw_ghost_poses(const bContext *C, Scene *scene, SceneLayer *sl, Vi
if (CFRA != cfrao) {
BKE_animsys_evaluate_animdata(scene, &ob->id, adt, (float)CFRA, ADT_RECALC_ALL);
- BKE_pose_where_is(&eval_ctx, scene, ob);
- draw_pose_bones(C, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
+ BKE_pose_where_is(eval_ctx, scene, ob);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, col, true, false);
}
}
}
@@ -2912,9 +2911,10 @@ static void draw_ghost_poses(const bContext *C, Scene *scene, SceneLayer *sl, Vi
/* called from drawobject.c, return true if nothing was drawn
* (ob_wire_col == NULL) when drawing ghost */
-bool draw_armature(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
- const short dt, const short dflag, const unsigned char ob_wire_col[4],
- const bool is_outline)
+bool draw_armature(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
+ const short dt, const short dflag, const unsigned char ob_wire_col[4],
+ const bool is_outline)
{
Object *ob = base->object;
bArmature *arm = ob->data;
@@ -2972,27 +2972,27 @@ bool draw_armature(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d,
}
else if (ob->mode & OB_MODE_POSE) {
if (arm->ghosttype == ARM_GHOST_RANGE) {
- draw_ghost_poses_range(C, scene, sl, v3d, ar, base);
+ draw_ghost_poses_range(eval_ctx, scene, sl, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_KEYS) {
- draw_ghost_poses_keys(C, scene, sl, v3d, ar, base);
+ draw_ghost_poses_keys(eval_ctx, scene, sl, v3d, ar, base);
}
else if (arm->ghosttype == ARM_GHOST_CUR) {
if (arm->ghostep)
- draw_ghost_poses(C, scene, sl, v3d, ar, base);
+ draw_ghost_poses(eval_ctx, scene, sl, v3d, ar, base);
}
if ((dflag & DRAW_SCENESET) == 0) {
- if (ob == OBACT_NEW)
+ if (ob == OBACT_NEW(sl))
arm->flag |= ARM_POSEMODE;
- else if (OBACT_NEW && (OBACT_NEW->mode & OB_MODE_WEIGHT_PAINT)) {
- if (ob == modifiers_isDeformedByArmature(OBACT_NEW))
+ else if (OBACT_NEW(sl) && (OBACT_NEW(sl)->mode & OB_MODE_WEIGHT_PAINT)) {
+ if (ob == modifiers_isDeformedByArmature(OBACT_NEW(sl)))
arm->flag |= ARM_POSEMODE;
}
draw_pose_paths(scene, v3d, ar, ob);
}
}
}
- draw_pose_bones(C, scene, sl, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline);
+ draw_pose_bones(eval_ctx, scene, sl, v3d, ar, base, dt, ob_wire_col, (dflag & DRAW_CONSTCOLOR), is_outline);
arm->flag &= ~ARM_POSEMODE;
}
else {
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index df187574777..4543172feb4 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -119,6 +119,8 @@
/* prototypes */
static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos);
+// #define USE_MESH_DM_SELECT
+
/* Workaround for sequencer scene render mode.
*
* Strips doesn't use DAG to update objects or so, which
@@ -319,7 +321,7 @@ bool draw_glsl_material(Scene *scene, SceneLayer *sl, Object *ob, View3D *v3d, c
return false;
if (!check_object_draw_texture(scene, v3d, dt))
return false;
- if (ob == OBACT_NEW && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
+ if (ob == OBACT_NEW(sl) && (ob && ob->mode & OB_MODE_WEIGHT_PAINT))
return false;
if (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)
@@ -1763,29 +1765,29 @@ static void draw_viewport_object_reconstruction(
/* selection outline */
if (selected) {
- batch = Batch_get_sphere_wire(1);
+ batch = GPU_batch_preset_sphere_wire(1);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
- Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
GWN_batch_uniform_4f(batch, "color",
ob_wire_col[0] / 255.f,
ob_wire_col[1] / 255.f,
ob_wire_col[2] / 255.f, 1.0f);
}
else {
- Batch_set_builtin_program(batch, GPU_SHADER_3D_DEPTH_ONLY);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_DEPTH_ONLY);
}
glLineWidth(2.0f);
GWN_batch_draw(batch);
}
- batch = Batch_get_sphere(0);
+ batch = GPU_batch_preset_sphere(0);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
const float light[3] = {0.0f, 0.0f, 1.0f};
float col[3];
- Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING);
GWN_batch_uniform_3fv(batch, "light", light);
if (track->flag & TRACK_CUSTOMCOLOR) copy_v3_v3(col, track->color);
@@ -1793,7 +1795,7 @@ static void draw_viewport_object_reconstruction(
GWN_batch_uniform_4f(batch, "color", col[0], col[1], col[2], 1.0f);
}
else {
- Batch_set_builtin_program(batch, GPU_SHADER_3D_DEPTH_ONLY);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_DEPTH_ONLY);
}
GWN_batch_draw(batch);
@@ -2396,7 +2398,8 @@ static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, i
}
#ifdef SEQUENCER_DAG_WORKAROUND
-static void ensure_curve_cache(const bContext *C, Scene *scene, Object *object)
+static void ensure_curve_cache(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *object)
{
bool need_recalc = object->curve_cache == NULL;
/* Render thread might have freed the curve cache if the
@@ -2421,21 +2424,17 @@ static void ensure_curve_cache(const bContext *C, Scene *scene, Object *object)
object->curve_cache->bev.first != NULL;
}
if (need_recalc) {
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(C, &eval_ctx);
-
switch (object->type) {
case OB_CURVE:
case OB_SURF:
case OB_FONT:
- BKE_displist_make_curveTypes(&eval_ctx, scene, object, false);
+ BKE_displist_make_curveTypes(eval_ctx, scene, object, false);
break;
case OB_MBALL:
- BKE_displist_make_mball(&eval_ctx, scene, object);
+ BKE_displist_make_mball(eval_ctx, scene, object);
break;
case OB_LATTICE:
- BKE_lattice_modifiers_calc(&eval_ctx, scene, object);
+ BKE_lattice_modifiers_calc(eval_ctx, scene, object);
break;
}
}
@@ -4159,7 +4158,7 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D
/* disable depth writes for transparent surface, so it doesn't interfere with itself */
glDepthMask(GL_FALSE);
- Batch_set_builtin_program(surface, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(surface, GPU_SHADER_3D_UNIFORM_COLOR);
GWN_batch_uniform_4f(surface, "color", 1.0f, 0.5f, 0.0f, 0.5f);
GWN_batch_draw(surface);
@@ -4167,7 +4166,7 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D
if (finalDM != cageDM) {
puts("finalDM != cageDM");
Gwn_Batch *finalSurface = MBC_get_all_triangles(finalDM);
- Batch_set_builtin_program(finalSurface, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(finalSurface, GPU_SHADER_3D_UNIFORM_COLOR);
GWN_batch_uniform_4f(finalSurface, "color", 0.0f, 0.0f, 0.0f, 0.05f);
GWN_batch_draw(finalSurface);
}
@@ -4179,19 +4178,19 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D
* NOTE: does not help as much as desired
* TODO: draw edit object last to avoid this mess
*/
- Batch_set_builtin_program(surface, GPU_SHADER_3D_DEPTH_ONLY);
+ GWN_batch_program_set_builtin(surface, GPU_SHADER_3D_DEPTH_ONLY);
GWN_batch_draw(surface);
if (GLEW_VERSION_3_2) {
#if 0
Gwn_Batch *overlay = DRW_mesh_batch_cache_get_overlay_edges(me);
- Batch_set_builtin_program(overlay, GPU_SHADER_EDGES_OVERLAY);
+ GWN_batch_program_set_builtin(overlay, GPU_SHADER_EDGES_OVERLAY);
GWN_batch_uniform_2f(overlay, "viewportSize", ar->winx, ar->winy);
GWN_batch_draw(overlay);
#endif
#if 0 /* TODO: use this SIMPLE variant for pure triangle meshes */
- Batch_set_builtin_program(surface, GPU_SHADER_EDGES_OVERLAY_SIMPLE);
+ GWN_batch_program_set_builtin(surface, GPU_SHADER_EDGES_OVERLAY_SIMPLE);
/* use these defaults:
* const float edgeColor[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
* GWN_batch_uniform_4f(surface, "fillColor", edgeColor[0], edgeColor[1], edgeColor[2], 0.0f);
@@ -4204,7 +4203,7 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D
}
else {
Gwn_Batch *edges = DRW_mesh_batch_cache_get_all_edges(me);
- Batch_set_builtin_program(edges, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(edges, GPU_SHADER_3D_UNIFORM_COLOR);
GWN_batch_uniform_4f(edges, "color", 0.0f, 0.0f, 0.0f, 1.0f);
glEnable(GL_LINE_SMOOTH);
glLineWidth(1.5f);
@@ -4216,7 +4215,7 @@ static void draw_em_fancy_new(Scene *UNUSED(scene), ARegion *UNUSED(ar), View3D
Gwn_Batch *verts = MBC_get_all_verts(me);
glEnable(GL_BLEND);
- Batch_set_builtin_program(verts, GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
+ GWN_batch_program_set_builtin(verts, GPU_SHADER_3D_POINT_UNIFORM_SIZE_UNIFORM_COLOR_AA);
GWN_batch_uniform_4f(verts, "color", 0.0f, 0.0f, 0.0f, 1.0f);
GWN_batch_uniform_1f(verts, "size", UI_GetThemeValuef(TH_VERTEX_SIZE) * 1.5f);
GWN_batch_draw(verts);
@@ -4268,14 +4267,14 @@ static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object
Gwn_Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me);
if (rv3d->persp == RV3D_ORTHO) {
- Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
+ GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
/* set eye vector, transformed to object coords */
float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye);
GWN_batch_uniform_3fv(fancy_edges, "eye", eye);
}
else {
- Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP);
+ GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP);
}
GWN_batch_uniform_1b(fancy_edges, "drawFront", false);
@@ -4286,7 +4285,7 @@ static void draw_mesh_object_outline_new(View3D *v3d, RegionView3D *rv3d, Object
GWN_batch_draw(fancy_edges);
#else /* alternate version that matches look of old viewport (but more efficient) */
Gwn_Batch *batch = MBC_get_all_edges(dm);
- Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
GWN_batch_uniform_4fv(batch, "color", outline_color);
GWN_batch_draw(batch);
#endif
@@ -4301,8 +4300,9 @@ static bool object_is_halo(Scene *scene, Object *ob)
return (ma && (ma->material_type == MA_TYPE_HALO) && !BKE_scene_use_new_shading_nodes(scene));
}
-static void draw_mesh_fancy(EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const unsigned char ob_wire_col[4], const short dflag)
+static void draw_mesh_fancy(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
#ifdef WITH_GAMEENGINE
Object *ob = (rv3d->rflag & RV3D_IS_GAME_ENGINE) ? BKE_object_lod_meshob_get(base->object, sl) : base->object;
@@ -4313,7 +4313,7 @@ static void draw_mesh_fancy(EvaluationContext *eval_ctx, Scene *scene, SceneLaye
eWireDrawMode draw_wire = OBDRAW_WIRE_OFF;
bool /* no_verts,*/ no_edges, no_faces;
DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask);
- const bool is_obact = (ob == OBACT_NEW);
+ const bool is_obact = (ob == OBACT_NEW(sl));
int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
if (!dm)
@@ -4565,18 +4565,16 @@ static void draw_mesh_fancy(EvaluationContext *eval_ctx, Scene *scene, SceneLaye
}
/* returns true if nothing was drawn, for detecting to draw an object center */
-static bool draw_mesh_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, BaseLegacy *base,
- const char dt, const unsigned char ob_wire_col[4], const short dflag)
+static bool draw_mesh_object(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, RegionView3D *rv3d, BaseLegacy *base,
+ const char dt, const unsigned char ob_wire_col[4], const short dflag)
{
- EvaluationContext eval_ctx;
Object *ob = base->object;
Object *obedit = scene->obedit;
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
bool do_alpha_after = false, drawlinked = false, retval = false;
- CTX_data_eval_ctx(C, &eval_ctx);
-
/* If we are drawing shadows and any of the materials don't cast a shadow,
* then don't draw the object */
if (v3d->flag2 & V3D_RENDER_SHADOW) {
@@ -4609,7 +4607,7 @@ static bool draw_mesh_object(const bContext *C, Scene *scene, SceneLayer *sl, AR
}
else {
cageDM = editbmesh_get_derived_cage_and_final(
- &eval_ctx, scene, ob, em, scene->customdata_mask,
+ eval_ctx, scene, ob, em, scene->customdata_mask,
&finalDM);
}
@@ -4650,7 +4648,7 @@ static bool draw_mesh_object(const bContext *C, Scene *scene, SceneLayer *sl, AR
}
}
- draw_mesh_fancy(&eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
+ draw_mesh_fancy(eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
GPU_end_object_materials();
@@ -4731,7 +4729,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, Scene
eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; /* could be bool draw_wire_overlay */
bool no_edges, no_faces;
DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask);
- const bool is_obact = (ob == OBACT_NEW);
+ const bool is_obact = (ob == OBACT_NEW(sl));
int draw_flags = (is_obact && BKE_paint_select_face_test(ob)) ? DRAW_FACE_SELECT : 0;
if (!dm)
@@ -4795,14 +4793,14 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, Scene
Gwn_Batch *fancy_edges = DRW_mesh_batch_cache_get_fancy_edges(me);
if (rv3d->persp == RV3D_ORTHO) {
- Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
+ GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_ORTHO);
/* set eye vector, transformed to object coords */
float eye[3] = { 0.0f, 0.0f, 1.0f }; /* looking into the screen */
mul_m3_v3(gpuGetNormalMatrixInverse(NULL), eye);
GWN_batch_uniform_3fv(fancy_edges, "eye", eye);
}
else {
- Batch_set_builtin_program(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP);
+ GWN_batch_program_set_builtin(fancy_edges, GPU_SHADER_EDGES_FRONT_BACK_PERSP);
}
float frontColor[4];
@@ -4831,7 +4829,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, Scene
#else /* simple wireframes */
Gwn_Batch *batch = MBC_get_all_edges(dm);
- Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
float color[4];
rgba_uchar_to_float(color, ob_wire_col);
@@ -4852,7 +4850,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, Scene
!(G.f & G_PICKSEL || (draw_flags & DRAW_FACE_SELECT)) &&
(draw_wire == OBDRAW_WIRE_OFF))
{
- draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT_NEW));
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT_NEW(sl)));
}
if (draw_glsl_material(scene, sl, ob, v3d, dt) && !(draw_flags & DRAW_MODIFIERS_PREVIEW)) {
@@ -4919,7 +4917,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, Scene
(draw_wire == OBDRAW_WIRE_OFF) &&
(ob->sculpt == NULL))
{
- draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT_NEW));
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT_NEW(sl)));
}
/* materials arent compatible with vertex colors */
@@ -4944,7 +4942,7 @@ static void draw_mesh_fancy_new(EvaluationContext *eval_ctx, Scene *scene, Scene
(ob->sculpt == NULL))
{
/* TODO: move this into a separate pass */
- draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT_NEW));
+ draw_mesh_object_outline_new(v3d, rv3d, ob, me, (ob == OBACT_NEW(sl)));
}
glFrontFace((ob->transflag & OB_NEG_SCALE) ? GL_CW : GL_CCW);
@@ -5145,13 +5143,13 @@ static void drawDispListVerts(Gwn_PrimType prim_type, const void *data, unsigned
GWN_vertbuf_attr_fill(vbo, pos_id, data);
- Gwn_Batch *batch = GWN_batch_create(prim_type, vbo, NULL);
- Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
if (wire_col) {
GWN_batch_uniform_4f(batch, "color", wire_col[0] / 255.0f, wire_col[1] / 255.0f, wire_col[2] / 255.0f, 1.0f);
}
GWN_batch_draw(batch);
- GWN_batch_discard_all(batch);
+ GWN_batch_discard(batch);
}
/* convert dispList with elem indices to batch, only support triangles and quads
@@ -5207,15 +5205,16 @@ static void drawDispListElem(
}
}
- Gwn_Batch *batch = GWN_batch_create(GWN_PRIM_TRIS, vbo, GWN_indexbuf_build(&elb));
- Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ Gwn_Batch *batch = GWN_batch_create_ex(
+ GWN_PRIM_TRIS, vbo, GWN_indexbuf_build(&elb), GWN_BATCH_OWNS_VBO | GWN_BATCH_OWNS_INDEX);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING);
if (wire_col) {
GWN_batch_uniform_4f(batch, "color", wire_col[0] / 255.0f, wire_col[1] / 255.0f, wire_col[2] / 255.0f, 1.0f);
}
GWN_batch_uniform_4f(batch, "color", 0.8f, 0.8f, 0.8f, 1.0f);
GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f);
GWN_batch_draw(batch);
- GWN_batch_discard_all(batch);
+ GWN_batch_discard(batch);
}
/**
@@ -5586,8 +5585,9 @@ static bool drawDispList_nobackface(Scene *scene, SceneLayer *sl, View3D *v3d, R
return false;
}
-static bool drawDispList(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+static bool drawDispList(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
bool retval;
@@ -5599,7 +5599,7 @@ static bool drawDispList(const bContext *C, Scene *scene, SceneLayer *sl, View3D
}
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(C, scene, base->object);
+ ensure_curve_cache(eval_ctx, scene, base->object);
#endif
if (drawCurveDerivedMesh(scene, sl, v3d, rv3d, base, dt) == false) {
@@ -5657,25 +5657,25 @@ static void draw_vertex_array(Gwn_PrimType prim_type, const float *vert, const f
if (color) GWN_vertbuf_attr_fill_stride(vbo, col_id, stride, color);
}
- Gwn_Batch *batch = GWN_batch_create(prim_type, vbo, NULL);
+ Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO);
if (nor && color) {
- Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING_SMOOTH_COLOR);
GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f);
}
else if (nor) {
- Batch_set_builtin_program(batch, GPU_SHADER_SIMPLE_LIGHTING);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_SIMPLE_LIGHTING);
GWN_batch_uniform_3f(batch, "light", 0.0f, 0.0f, 1.0f);
if (col) GWN_batch_uniform_4fv(batch, "color", col);
}
else if (color) {
- Batch_set_builtin_program(batch, GPU_SHADER_3D_SMOOTH_COLOR);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR);
}
else {
- Batch_set_builtin_program(batch, GPU_SHADER_3D_UNIFORM_COLOR);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR);
if (col) GWN_batch_uniform_4fv(batch, "color", col);
}
GWN_batch_draw(batch);
- GWN_batch_discard_all(batch);
+ GWN_batch_discard(batch);
}
static void draw_particle_arrays_new(int draw_as, int ob_dt, int select,
@@ -5908,9 +5908,10 @@ static void draw_particle_data(ParticleSystem *psys, RegionView3D *rv3d,
* 6. draw the arrays
* 7. clean up
*/
-static void draw_new_particle_system(EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d,
- Base *base, ParticleSystem *psys,
- const char ob_dt, const short dflag)
+static void draw_new_particle_system(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d,
+ Base *base, ParticleSystem *psys,
+ const char ob_dt, const short dflag)
{
Object *ob = base->object;
ParticleEditSettings *pset = PE_settings(scene);
@@ -6594,18 +6595,15 @@ static void draw_new_particle_system(EvaluationContext *eval_ctx, Scene *scene,
}
}
-static void draw_update_ptcache_edit(const bContext *C, Scene *scene, SceneLayer *sl, Object *ob, PTCacheEdit *edit)
+static void draw_update_ptcache_edit(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *ob, PTCacheEdit *edit)
{
if (edit->psys && edit->psys->flag & PSYS_HAIR_UPDATED)
- PE_update_object(C, scene, sl, ob, 0);
+ PE_update_object(eval_ctx, scene, sl, ob, 0);
/* create path and child path cache if it doesn't exist already */
if (edit->pathcache == NULL) {
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(C, &eval_ctx);
-
- psys_cache_edit_paths(&eval_ctx, scene, ob, edit, CFRA, G.is_rendering);
+ psys_cache_edit_paths(eval_ctx, scene, ob, edit, CFRA, G.is_rendering);
}
}
@@ -6683,10 +6681,10 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
GWN_vertbuf_attr_fill_stride(vbo, col_id, sizeof(ParticleCacheKey), path->col);
}
- Gwn_Batch *batch = GWN_batch_create(GWN_PRIM_LINE_STRIP, vbo, NULL);
- Batch_set_builtin_program(batch, GPU_SHADER_3D_SMOOTH_COLOR);
+ Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_LINE_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR);
GWN_batch_draw(batch);
- GWN_batch_discard_all(batch);
+ GWN_batch_discard(batch);
}
if (pathcol) { MEM_freeN(pathcol); pathcol = NULL; }
@@ -6754,10 +6752,10 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit)
GWN_vertbuf_attr_fill(vbo, col_id, cd);
- Gwn_Batch *batch = GWN_batch_create(GWN_PRIM_POINTS, vbo, NULL);
- Batch_set_builtin_program(batch, GPU_SHADER_3D_SMOOTH_COLOR);
+ Gwn_Batch *batch = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_SMOOTH_COLOR);
GWN_batch_draw(batch);
- GWN_batch_discard_all(batch);
+ GWN_batch_discard(batch);
pd += pd ? 3 * point->totkey : 0;
cd += (timed ? 4 : 3) * point->totkey;
@@ -7340,7 +7338,8 @@ static void draw_editnurb_splines(Object *ob, Nurb *nurb, const bool sel)
}
static void draw_editnurb(
- const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl,
+ View3D *v3d, RegionView3D *rv3d, Base *base, Nurb *nurb,
const char dt, const short dflag, const unsigned char UNUSED(ob_wire_col[4]))
{
ToolSettings *ts = scene->toolsettings;
@@ -7354,7 +7353,7 @@ static void draw_editnurb(
/* DispList */
UI_GetThemeColor3ubv(TH_WIRE_EDIT, wire_col);
- drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, wire_col);
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, wire_col);
/* for shadows only show solid faces */
if (v3d->flag2 & V3D_RENDER_SHADOW)
@@ -7479,8 +7478,9 @@ static void draw_editfont_textcurs(RegionView3D *rv3d, float textcurs[4][2])
immUnbindProgram();
}
-static void draw_editfont(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+static void draw_editfont(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
Curve *cu = ob->data;
@@ -7492,11 +7492,11 @@ static void draw_editfont(const bContext *C, Scene *scene, SceneLayer *sl, View3
if (cu->flag & CU_FAST) {
imm_cpack(0xFFFFFF);
set_inverted_drawing(1);
- drawDispList(C, scene, sl, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col);
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, OB_WIRE, dflag, ob_wire_col);
set_inverted_drawing(0);
}
else {
- drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
if (cu->linewidth != 0.0f) {
@@ -7798,8 +7798,9 @@ static void imm_drawcone(const float vec[3], float radius, float height, float t
}
/* return true if nothing was drawn */
-static bool drawmball(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
- const char dt, const short dflag, const unsigned char ob_wire_col[4])
+static bool drawmball(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Base *base,
+ const char dt, const short dflag, const unsigned char ob_wire_col[4])
{
Object *ob = base->object;
MetaElem *ml;
@@ -7812,13 +7813,13 @@ static bool drawmball(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v
if ((G.f & G_PICKSEL) == 0) {
unsigned char wire_col[4];
UI_GetThemeColor4ubv(TH_WIRE_EDIT, wire_col);
- drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, wire_col);
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, wire_col);
}
ml = mb->editelems->first;
}
else {
if ((base->flag_legacy & OB_FROMDUPLI) == 0) {
- drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
ml = mb->elems.first;
}
@@ -8087,8 +8088,8 @@ static void imm_draw_box(const float vec[8][3], bool solid, unsigned pos)
static void imm_draw_bb(BoundBox *bb, char type, bool around_origin, const unsigned char ob_wire_col[4])
{
float size[3], cent[3];
- Gwn_Batch *sphere = Batch_get_sphere_wire(0);
- Batch_set_builtin_program(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
+ Gwn_Batch *sphere = GPU_batch_preset_sphere_wire(0);
+ GWN_batch_program_set_builtin(sphere, GPU_SHADER_3D_UNIFORM_COLOR);
if (ob_wire_col) GWN_batch_uniform_4f(sphere, "color", ob_wire_col[0] / 255.0f, ob_wire_col[1] / 255.0f, ob_wire_col[2] / 255.0f, 1.0f);
BKE_boundbox_calc_size_aabb(bb, size);
@@ -8266,7 +8267,7 @@ static void drawtexspace(Object *ob, const unsigned char ob_wire_col[3])
/* draws wire outline */
static void draw_object_selected_outline(
- const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
const unsigned char ob_wire_col[4])
{
RegionView3D *rv3d = ar->regiondata;
@@ -8278,7 +8279,7 @@ static void draw_object_selected_outline(
bool has_faces = false;
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(C, scene, ob);
+ ensure_curve_cache(eval_ctx, scene, ob);
#endif
DerivedMesh *dm = ob->derivedFinal;
@@ -8315,7 +8316,7 @@ static void draw_object_selected_outline(
else if (ob->type == OB_ARMATURE) {
if (!(ob->mode & OB_MODE_POSE && base == sl->basact)) {
glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f);
- draw_armature(C, scene, sl, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true);
+ draw_armature(eval_ctx, scene, sl, v3d, ar, base, OB_WIRE, 0, ob_wire_col, true);
}
}
@@ -8567,7 +8568,9 @@ void draw_rigidbody_shape(Object *ob, const unsigned char ob_wire_col[4])
* main object drawing function, draws in selection
* \param dflag (draw flag) can be DRAW_PICKING and/or DRAW_CONSTCOLOR, DRAW_SCENESET
*/
-void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base, const short dflag)
+void draw_object(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d,
+ Base *base, const short dflag)
{
ModifierData *md = NULL;
Object *ob = base->object;
@@ -8576,15 +8579,12 @@ void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, V
unsigned char _ob_wire_col[4]; /* dont initialize this */
const unsigned char *ob_wire_col = NULL; /* dont initialize this, use NULL crashes as a way to find invalid use */
bool zbufoff = false, is_paint = false, empty_object = false;
- const bool is_obact = (ob == OBACT_NEW);
+ const bool is_obact = (ob == OBACT_NEW(sl));
const bool render_override = (v3d->flag2 & V3D_RENDER_OVERRIDE) != 0;
const bool is_picking = (G.f & G_PICKSEL) != 0;
const bool has_particles = (ob->particlesystem.first != NULL);
bool skip_object = false; /* Draw particles but not their emitter object. */
SmokeModifierData *smd = NULL;
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(C, &eval_ctx);
if (ob != scene->obedit) {
if (ob->restrictflag & OB_RESTRICT_VIEW)
@@ -8752,7 +8752,7 @@ void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, V
if ((v3d->flag & V3D_SELECT_OUTLINE) && !render_override && ob->type != OB_MESH) {
if (dt > OB_WIRE && (ob->mode & (OB_MODE_EDIT | OB_MODE_HAIR_EDIT)) == 0 && (dflag & DRAW_SCENESET) == 0) {
if (!(ob->dtx & OB_DRAWWIRE) && (base->flag & BASE_SELECTED) && !(dflag & (DRAW_PICKING | DRAW_CONSTCOLOR))) {
- draw_object_selected_outline(C, scene, sl, v3d, ar, base, ob_wire_col);
+ draw_object_selected_outline(eval_ctx, scene, sl, v3d, ar, base, ob_wire_col);
}
}
}
@@ -8766,7 +8766,7 @@ void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, V
switch (ob->type) {
case OB_MESH:
- empty_object = draw_mesh_object(C, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
+ empty_object = draw_mesh_object(eval_ctx, scene, sl, ar, v3d, rv3d, base, dt, ob_wire_col, dflag);
if ((dflag & DRAW_CONSTCOLOR) == 0) {
/* mesh draws wire itself */
dtx &= ~OB_DRAWWIRE;
@@ -8776,18 +8776,18 @@ void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, V
case OB_FONT:
cu = ob->data;
if (cu->editfont) {
- draw_editfont(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ draw_editfont(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
else if (dt == OB_BOUNDBOX) {
if ((render_override && v3d->drawtype >= OB_WIRE) == 0) {
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(C, scene, base->object);
+ ensure_curve_cache(eval_ctx, scene, base->object);
#endif
draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
}
else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
- empty_object = drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ empty_object = drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
break;
@@ -8797,18 +8797,18 @@ void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, V
if (cu->editnurb) {
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- draw_editnurb(C, scene, sl, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col);
+ draw_editnurb(eval_ctx, scene, sl, v3d, rv3d, base, nurbs->first, dt, dflag, ob_wire_col);
}
else if (dt == OB_BOUNDBOX) {
if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) {
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(C, scene, base->object);
+ ensure_curve_cache(eval_ctx, scene, base->object);
#endif
draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
}
else if (ED_view3d_boundbox_clip(rv3d, ob->bb)) {
- empty_object = drawDispList(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ empty_object = drawDispList(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
}
break;
case OB_MBALL:
@@ -8816,17 +8816,17 @@ void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, V
MetaBall *mb = ob->data;
if (mb->editelems)
- drawmball(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ drawmball(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
else if (dt == OB_BOUNDBOX) {
if ((render_override && (v3d->drawtype >= OB_WIRE)) == 0) {
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(C, scene, base->object);
+ ensure_curve_cache(eval_ctx, scene, base->object);
#endif
draw_bounding_volume(ob, ob->boundtype, ob_wire_col);
}
}
else
- empty_object = drawmball(C, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
+ empty_object = drawmball(eval_ctx, scene, sl, v3d, rv3d, base, dt, dflag, ob_wire_col);
break;
}
case OB_EMPTY:
@@ -8865,7 +8865,7 @@ void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, V
}
else {
#ifdef SEQUENCER_DAG_WORKAROUND
- ensure_curve_cache(C, scene, ob);
+ ensure_curve_cache(eval_ctx, scene, ob);
#endif
drawlattice(v3d, ob, dflag, ob_wire_col);
}
@@ -8890,7 +8890,7 @@ void draw_object(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, V
else
copy_v4_v4_uchar(arm_col, ob_wire_col);
- empty_object = draw_armature(C, scene, sl, v3d, ar, base, dt, dflag, arm_col, false);
+ empty_object = draw_armature(eval_ctx, scene, sl, v3d, ar, base, dt, dflag, arm_col, false);
}
}
break;
@@ -8944,12 +8944,12 @@ afterdraw:
if (!(ob->mode & OB_MODE_HAIR_EDIT)) {
/* run this so that possible child particles get cached */
if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
- PTCacheEdit *edit = PE_create_current(C, scene, ob);
+ PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob);
if (edit && edit->psys == psys)
- draw_update_ptcache_edit(C, scene, sl, ob, edit);
+ draw_update_ptcache_edit(eval_ctx, scene, sl, ob, edit);
}
- draw_new_particle_system(&eval_ctx, scene, v3d, rv3d, base, psys, dt, dflag);
+ draw_new_particle_system(eval_ctx, scene, v3d, rv3d, base, psys, dt, dflag);
}
}
invert_m4_m4(ob->imat, ob->obmat);
@@ -8966,10 +8966,10 @@ afterdraw:
{
if (ob->mode & OB_MODE_PARTICLE_EDIT && is_obact) {
- PTCacheEdit *edit = PE_create_current(C, scene, ob);
+ PTCacheEdit *edit = PE_create_current(eval_ctx, scene, ob);
if (edit) {
gpuLoadMatrix(rv3d->viewmat);
- draw_update_ptcache_edit(C, scene, sl, ob, edit);
+ draw_update_ptcache_edit(eval_ctx, scene, sl, ob, edit);
draw_ptcache_edit(scene, v3d, edit);
gpuMultMatrix(ob->obmat);
}
@@ -9291,7 +9291,7 @@ afterdraw:
for (ct = targets.first; ct; ct = ct->next) {
/* calculate target's matrix */
if (cti->get_target_matrix)
- cti->get_target_matrix(&eval_ctx, curcon, cob, ct, BKE_scene_frame_get(scene));
+ cti->get_target_matrix(eval_ctx, curcon, cob, ct, BKE_scene_frame_get(scene));
else
unit_m4(ct->matrix);
@@ -9340,10 +9340,12 @@ afterdraw:
* Drawing for selection picking,
* caller must have called 'GPU_select_load_id(base->selcode)' first.
*/
-void draw_object_select(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, Base *base, const short dflag)
+void draw_object_select(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d,
+ Base *base, const short dflag)
{
BLI_assert(dflag & DRAW_PICKING && dflag & DRAW_CONSTCOLOR);
- draw_object(C, scene, sl, ar, v3d, base, dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, dflag);
/* we draw duplicators for selection too */
if ((base->object->transflag & OB_DUPLI)) {
@@ -9352,7 +9354,7 @@ void draw_object_select(const bContext *C, Scene *scene, SceneLayer *sl, ARegion
Base tbase;
tbase.flag_legacy = OB_FROMDUPLI;
- lb = object_duplilist(G.main->eval_ctx, scene, base->object);
+ lb = object_duplilist(eval_ctx, scene, base->object);
for (dob = lb->first; dob; dob = dob->next) {
float omat[4][4];
@@ -9366,7 +9368,7 @@ void draw_object_select(const bContext *C, Scene *scene, SceneLayer *sl, ARegion
char dt = tbase.object->dt; tbase.object->dt = MIN2(tbase.object->dt, base->object->dt);
short dtx = tbase.object->dtx; tbase.object->dtx = base->object->dtx;
- draw_object(C, scene, sl, ar, v3d, &tbase, dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, &tbase, dflag);
tbase.object->dt = dt;
tbase.object->dtx = dtx;
@@ -9379,6 +9381,7 @@ void draw_object_select(const bContext *C, Scene *scene, SceneLayer *sl, ARegion
/* ***************** BACKBUF SEL (BBS) ********* */
+#ifdef USE_MESH_DM_SELECT
static void bbs_obmode_mesh_verts__mapFunc(void *userData, int index, const float co[3],
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
@@ -9419,7 +9422,17 @@ static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *dm, int offset)
immUnbindProgram();
}
+#else
+static void bbs_obmode_mesh_verts(Object *ob, DerivedMesh *UNUSED(dm), int offset)
+{
+ Mesh *me = ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_verts__mapFunc(void *userData, int index, const float co[3],
const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
{
@@ -9452,7 +9465,17 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset)
immUnbindProgram();
}
+#else
+static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
+{
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_verts_with_select_id(me, offset);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_wire__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3])
{
drawBMOffset_userData *data = userData;
@@ -9492,7 +9515,19 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset)
immUnbindProgram();
}
+#else
+static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *UNUSED(dm), int offset)
+{
+ glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE));
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_edges_with_select_id(me, offset);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
+
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select)
{
UNUSED_VARS(dm);
@@ -9545,7 +9580,29 @@ static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *dm, const bool use_select
immUnbindProgram();
}
+#else
+static void bbs_mesh_face(BMEditMesh *em, DerivedMesh *UNUSED(dm), const bool use_select)
+{
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch;
+
+ if (use_select) {
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+ }
+ else {
+ int selcol;
+ GPU_select_index_get(0, &selcol);
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
+ GWN_batch_uniform_1i(batch, "color", selcol);
+ GWN_batch_draw(batch);
+ }
+}
+#endif
+#ifdef USE_MESH_DM_SELECT
static void bbs_mesh_solid__drawCenter(void *userData, int index, const float cent[3], const float UNUSED(no[3]))
{
drawBMOffset_userData *data = (drawBMOffset_userData *)userData;
@@ -9577,6 +9634,15 @@ static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *dm)
immUnbindProgram();
}
+#else
+static void bbs_mesh_face_dot(BMEditMesh *em, DerivedMesh *UNUSED(dm))
+{
+ Mesh *me = em->ob->data;
+ Gwn_Batch *batch = DRW_mesh_batch_cache_get_facedots_with_select_id(me, 1);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_draw(batch);
+}
+#endif
/* two options, facecolors or black */
static void bbs_mesh_solid_EM(BMEditMesh *em, Scene *scene, View3D *v3d,
@@ -9612,6 +9678,7 @@ static DMDrawOption bbs_mesh_solid_hide__setDrawOpts(void *userData, int index)
}
}
+#ifdef USE_MESH_DM_SELECT
/* must have called GPU_framebuffer_index_set beforehand */
static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index)
{
@@ -9625,7 +9692,7 @@ static DMDrawOption bbs_mesh_solid_hide2__setDrawOpts(void *userData, int index)
}
}
-static void bbs_mesh_solid_verts(EvaluationContext *eval_ctx, Scene *scene, Object *ob)
+static void bbs_mesh_solid_verts(const EvaluationContext *eval_ctx, Scene *scene, Object *ob)
{
Mesh *me = ob->data;
DerivedMesh *dm = mesh_get_derived_final(eval_ctx, scene, ob, scene->customdata_mask);
@@ -9644,6 +9711,31 @@ static void bbs_mesh_solid_verts(EvaluationContext *eval_ctx, Scene *scene, Obje
bm_vertoffs = me->totvert + 1;
dm->release(dm);
}
+#else
+static void bbs_mesh_solid_verts(const EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *ob)
+{
+ Mesh *me = ob->data;
+
+ /* Only draw faces to mask out verts, we don't want their selection ID's. */
+ const int G_f_orig = G.f;
+ G.f &= ~G_BACKBUFSEL;
+
+ {
+ int selcol;
+ Gwn_Batch *batch;
+ GPU_select_index_get(0, &selcol);
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_mask(me, true);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_UNIFORM_COLOR_U32);
+ GWN_batch_uniform_1i(batch, "color", selcol);
+ GWN_batch_draw(batch);
+ }
+
+ G.f |= (G_f_orig & G_BACKBUFSEL);
+
+ bbs_obmode_mesh_verts(ob, NULL, 1);
+ bm_vertoffs = me->totvert + 1;
+}
+#endif
static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
{
@@ -9651,22 +9743,20 @@ static void bbs_mesh_solid_faces(Scene *scene, Object *ob)
UNUSED_VARS(scene, bbs_mesh_solid_hide__setDrawOpts, bbs_mesh_solid__setDrawOpts);
Gwn_Batch *batch;
if ((me->editflag & ME_EDIT_PAINT_FACE_SEL)) {
- batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true);
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, true, 1);
}
else {
- batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false);
+ batch = DRW_mesh_batch_cache_get_triangles_with_select_id(me, false, 1);
}
- Batch_set_builtin_program(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_3D_FLAT_COLOR_U32);
GWN_batch_draw(batch);
}
-void draw_object_backbufsel(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
+void draw_object_backbufsel(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
{
- EvaluationContext eval_ctx;
ToolSettings *ts = scene->toolsettings;
- CTX_data_eval_ctx(C, &eval_ctx);
-
gpuMultMatrix(ob->obmat);
glClearDepth(1.0); glClear(GL_DEPTH_BUFFER_BIT);
@@ -9678,7 +9768,7 @@ void draw_object_backbufsel(const bContext *C, Scene *scene, View3D *v3d, Region
Mesh *me = ob->data;
BMEditMesh *em = me->edit_btmesh;
- DerivedMesh *dm = editbmesh_get_derived_cage(&eval_ctx, scene, ob, em, CD_MASK_BAREMESH);
+ DerivedMesh *dm = editbmesh_get_derived_cage(eval_ctx, scene, ob, em, CD_MASK_BAREMESH);
BM_mesh_elem_table_ensure(em->bm, BM_VERT | BM_EDGE | BM_FACE);
@@ -9715,7 +9805,7 @@ void draw_object_backbufsel(const bContext *C, Scene *scene, View3D *v3d, Region
/* currently vertex select only supports weight paint */
(ob->mode & OB_MODE_WEIGHT_PAINT))
{
- bbs_mesh_solid_verts(&eval_ctx, scene, ob);
+ bbs_mesh_solid_verts(eval_ctx, scene, ob);
}
else {
bbs_mesh_solid_faces(scene, ob);
@@ -9735,21 +9825,19 @@ void draw_object_backbufsel(const bContext *C, Scene *scene, View3D *v3d, Region
/* assumes all matrices/etc set OK */
/* helper function for drawing object instances - meshes */
-static void draw_object_mesh_instance(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d,
- Object *ob, const short dt, int outline, const unsigned char ob_wire_col[4])
+static void draw_object_mesh_instance(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d,
+ Object *ob, const short dt, int outline, const unsigned char ob_wire_col[4])
{
- EvaluationContext eval_ctx;
Mesh *me = ob->data;
DerivedMesh *dm = NULL, *edm = NULL;
-
- CTX_data_eval_ctx(C, &eval_ctx);
if (ob->mode & OB_MODE_EDIT) {
edm = editbmesh_get_derived_base(ob, me->edit_btmesh, CD_MASK_BAREMESH);
DM_update_materials(edm, ob);
}
else {
- dm = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH);
+ dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH);
DM_update_materials(dm, ob);
}
@@ -9785,7 +9873,7 @@ static void draw_object_mesh_instance(const bContext *C, Scene *scene, SceneLaye
if (dm) dm->release(dm);
}
-void draw_object_instance(const bContext *C, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline, const float wire_col[4])
+void draw_object_instance(const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, Object *ob, const char dt, int outline, const float wire_col[4])
{
if (ob == NULL)
return;
@@ -9795,7 +9883,7 @@ void draw_object_instance(const bContext *C, Scene *scene, SceneLayer *sl, View3
switch (ob->type) {
case OB_MESH:
- draw_object_mesh_instance(C, scene, sl, v3d, rv3d, ob, dt, outline, bcol);
+ draw_object_mesh_instance(eval_ctx, scene, sl, v3d, rv3d, ob, dt, outline, bcol);
break;
case OB_EMPTY:
if (ob->empty_drawtype == OB_EMPTY_IMAGE) {
@@ -9808,13 +9896,11 @@ void draw_object_instance(const bContext *C, Scene *scene, SceneLayer *sl, View3
}
}
-void ED_draw_object_facemap(const bContext *C, Scene *scene, Object *ob, const float col[4], const int facemap)
+void ED_draw_object_facemap(
+ const EvaluationContext *eval_ctx, Scene *scene, Object *ob, const float col[4], const int facemap)
{
- EvaluationContext eval_ctx;
DerivedMesh *dm = NULL;
- CTX_data_eval_ctx(C, &eval_ctx);
-
/* happens on undo */
if (ob->type != OB_MESH || !ob->data)
return;
@@ -9824,7 +9910,7 @@ void ED_draw_object_facemap(const bContext *C, Scene *scene, Object *ob, const f
return;
}
- dm = mesh_get_derived_final(&eval_ctx, scene, ob, CD_MASK_BAREMESH);
+ dm = mesh_get_derived_final(eval_ctx, scene, ob, CD_MASK_BAREMESH);
if (!dm || !CustomData_has_layer(&dm->polyData, CD_FACEMAP))
return;
diff --git a/source/blender/editors/space_view3d/space_view3d.c b/source/blender/editors/space_view3d/space_view3d.c
index fa15fa5ca94..2dd0e101ea9 100644
--- a/source/blender/editors/space_view3d/space_view3d.c
+++ b/source/blender/editors/space_view3d/space_view3d.c
@@ -744,6 +744,8 @@ static void view3d_widgets(void)
WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_force_field);
WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera);
WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_camera_view);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_empty_image);
+ WM_manipulatorgrouptype_append_and_link(mmap_type, VIEW3D_WGT_armature_spline);
}
@@ -883,6 +885,7 @@ static void view3d_main_region_listener(
BKE_screen_view3d_sync(v3d, wmn->reference);
}
ED_region_tag_redraw(ar);
+ WM_manipulatormap_tag_refresh(mmap);
break;
case ND_OB_ACTIVE:
case ND_OB_SELECT:
diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c
index a8e5e1ad536..ddb87d96ec1 100644
--- a/source/blender/editors/space_view3d/view3d_buttons.c
+++ b/source/blender/editors/space_view3d/view3d_buttons.c
@@ -788,7 +788,7 @@ static void do_view3d_vgroup_buttons(bContext *C, void *UNUSED(arg), int event)
static int view3d_panel_vgroup_poll(const bContext *C, PanelType *UNUSED(pt))
{
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob && (BKE_object_is_in_editmode_vgroup(ob) ||
BKE_object_is_in_wpaint_select_vert(ob)))
{
@@ -1099,7 +1099,7 @@ static void do_view3d_region_buttons(bContext *C, void *UNUSED(index), int event
{
SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = CTX_wm_view3d(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
switch (event) {
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 04cc77ddd9c..c85cf689068 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -119,7 +119,9 @@ static bool use_depth_doit(Scene *scene, View3D *v3d)
/**
* \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
*/
-void ED_view3d_update_viewmat(EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
+void ED_view3d_update_viewmat(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar,
+ float viewmat[4][4], float winmat[4][4], const rcti *rect)
{
RegionView3D *rv3d = ar->regiondata;
@@ -181,7 +183,8 @@ void ED_view3d_update_viewmat(EvaluationContext *eval_ctx, Scene *scene, View3D
}
static void view3d_main_region_setup_view(
- EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
+ const EvaluationContext *eval_ctx, Scene *scene,
+ View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
{
RegionView3D *rv3d = ar->regiondata;
@@ -235,14 +238,12 @@ static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, Reg
* we do a small hack to replace it temporarily so we don't need to change the
* view3d)main_region_setup_view() code to account for that.
*/
-static void view3d_stereo3d_setup(const bContext *C, Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
+static void view3d_stereo3d_setup(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
{
bool is_left;
const char *names[2] = { STEREO_LEFT_NAME, STEREO_RIGHT_NAME };
const char *viewname;
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(C, &eval_ctx);
/* show only left or right camera */
if (v3d->stereo3d_camera != STEREO_3D_ID)
@@ -264,7 +265,7 @@ static void view3d_stereo3d_setup(const bContext *C, Scene *scene, View3D *v3d,
data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, viewmat, NULL, rect);
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, NULL, rect);
data->shiftx = shiftx;
BLI_unlock_thread(LOCK_VIEW3D);
@@ -278,7 +279,7 @@ static void view3d_stereo3d_setup(const bContext *C, Scene *scene, View3D *v3d,
v3d->camera = camera;
BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, viewmat, NULL, rect);
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, NULL, rect);
v3d->camera = view_ob;
BLI_unlock_thread(LOCK_VIEW3D);
@@ -289,20 +290,17 @@ static void view3d_stereo3d_setup(const bContext *C, Scene *scene, View3D *v3d,
* Set the correct matrices
*/
void ED_view3d_draw_setup_view(
- wmWindow *win, const bContext *C, Scene *scene, ARegion *ar, View3D *v3d,
+ wmWindow *win, const EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d,
float viewmat[4][4], float winmat[4][4], const rcti *rect)
{
RegionView3D *rv3d = ar->regiondata;
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(C, &eval_ctx);
/* Setup the view matrix. */
if (view3d_stereo3d_active(win, scene, v3d, rv3d)) {
- view3d_stereo3d_setup(C, scene, v3d, ar, rect);
+ view3d_stereo3d_setup(eval_ctx, scene, v3d, ar, rect);
}
else {
- view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, viewmat, winmat, rect);
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, rect);
}
}
@@ -702,7 +700,7 @@ static void drawrenderborder(ARegion *ar, View3D *v3d)
}
void ED_view3d_draw_depth(
- const bContext *C, struct Depsgraph *graph,
+ const EvaluationContext *eval_ctx, struct Depsgraph *graph,
ARegion *ar, View3D *v3d, bool alphaoverride)
{
Scene *scene = DEG_get_evaluated_scene(graph);
@@ -718,7 +716,7 @@ void ED_view3d_draw_depth(
U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */
U.obcenter_dia = 0;
- ED_view3d_draw_setup_view(NULL, C, scene, ar, v3d, NULL, NULL, NULL);
+ ED_view3d_draw_setup_view(NULL, eval_ctx, scene, ar, v3d, NULL, NULL, NULL);
glClear(GL_DEPTH_BUFFER_BIT);
@@ -1313,7 +1311,7 @@ float ED_view3d_grid_scale(Scene *scene, View3D *v3d, const char **grid_unit)
static bool is_cursor_visible(Scene *scene, SceneLayer *sl)
{
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
/* don't draw cursor in paint modes, but with a few exceptions */
if (ob && ob->mode & OB_MODE_ALL_PAINT) {
@@ -1844,7 +1842,7 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
if (U.uiflag & USER_DRAWVIEWINFO) {
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
draw_selected_name(scene, ob, &rect);
}
#if 0 /* TODO */
@@ -1865,7 +1863,10 @@ void view3d_draw_region_info(const bContext *C, ARegion *ar, const int offset)
static void view3d_draw_view(const bContext *C, ARegion *ar)
{
- ED_view3d_draw_setup_view(CTX_wm_window(C), C, CTX_data_scene(C), ar, CTX_wm_view3d(C), NULL, NULL, NULL);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ ED_view3d_draw_setup_view(CTX_wm_window(C), &eval_ctx, CTX_data_scene(C), ar, CTX_wm_view3d(C), NULL, NULL, NULL);
/* Only 100% compliant on new spec goes bellow */
DRW_draw_view(C);
@@ -1903,7 +1904,7 @@ void view3d_main_region_draw(const bContext *C, ARegion *ar)
* \{ */
static void view3d_stereo3d_setup_offscreen(
- EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar,
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar,
float winmat[4][4], const char *viewname)
{
/* update the viewport matrices with the new camera */
@@ -1923,7 +1924,7 @@ static void view3d_stereo3d_setup_offscreen(
}
}
-void ED_view3d_draw_offscreen_init(EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d)
+void ED_view3d_draw_offscreen_init(const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d)
{
RenderEngineType *type = RE_engines_find(scene->r.engine);
if (type->flag & RE_USE_LEGACY_PIPELINE) {
@@ -1953,7 +1954,7 @@ static void view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar)
* stuff like shadow buffers
*/
void ED_view3d_draw_offscreen(
- EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int winx, int winy,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int winx, int winy,
float viewmat[4][4], float winmat[4][4],
bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
GPUFX *fx, GPUFXSettings *fx_settings,
@@ -2025,7 +2026,7 @@ void ED_view3d_draw_offscreen(
v3d->fx_settings.ssao = ssao;
}
- VP_deprecated_view3d_draw_objects(NULL, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
+ VP_deprecated_view3d_draw_objects(NULL, eval_ctx, scene, v3d, ar, NULL, do_bgpic, true, do_compositing ? fx : NULL);
/* post process */
if (do_compositing) {
@@ -2073,7 +2074,7 @@ void ED_view3d_draw_offscreen(
* (avoids re-creating when doing multiple GL renders).
*/
ImBuf *ED_view3d_draw_offscreen_imbuf(
- EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int sizex, int sizey,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar, int sizex, int sizey,
unsigned int flag, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
/* output vars */
@@ -2238,7 +2239,7 @@ ImBuf *ED_view3d_draw_offscreen_imbuf(
* \note used by the sequencer
*/
ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
- EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *camera, int width, int height,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, Object *camera, int width, int height,
unsigned int flag, int drawtype, bool use_solid_tex, bool use_gpencil, bool draw_background,
int alpha_mode, int samples, bool full_samples, const char *viewname,
GPUFX *fx, GPUOffScreen *ofs, char err_out[256])
@@ -2341,23 +2342,21 @@ void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool
drawfloor(scene, v3d, grid_unit, write_depth);
}
-void VP_legacy_view3d_main_region_setup_view(const bContext *C, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
+void VP_legacy_view3d_main_region_setup_view(
+ const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d,
+ ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(C, &eval_ctx);
-
- view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, viewmat, winmat, NULL);
+ view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, viewmat, winmat, NULL);
}
-bool VP_legacy_view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
+bool VP_legacy_view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
- return view3d_stereo3d_active(CTX_wm_window(C), scene, v3d, rv3d);
+ return view3d_stereo3d_active(win, scene, v3d, rv3d);
}
-void VP_legacy_view3d_stereo3d_setup(const bContext *C, Scene *scene, View3D *v3d, ARegion *ar)
+void VP_legacy_view3d_stereo3d_setup(const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar)
{
- view3d_stereo3d_setup(C, scene, v3d, ar, NULL);
+ view3d_stereo3d_setup(eval_ctx, scene, v3d, ar, NULL);
}
bool VP_legacy_use_depth(Scene *scene, View3D *v3d)
diff --git a/source/blender/editors/space_view3d/view3d_draw_legacy.c b/source/blender/editors/space_view3d/view3d_draw_legacy.c
index 5c923d3c91b..6184ed63543 100644
--- a/source/blender/editors/space_view3d/view3d_draw_legacy.c
+++ b/source/blender/editors/space_view3d/view3d_draw_legacy.c
@@ -213,7 +213,7 @@ static void draw_view_icon(RegionView3D *rv3d, rcti *rect)
/* *********************** backdraw for selection *************** */
-static void backdrawview3d(const bContext *C, Scene *scene, SceneLayer *sl, wmWindow *win, ARegion *ar, View3D *v3d)
+static void backdrawview3d(const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, wmWindow *win, ARegion *ar, View3D *v3d)
{
RegionView3D *rv3d = ar->regiondata;
struct Base *base = sl->basact;
@@ -314,7 +314,7 @@ static void backdrawview3d(const bContext *C, Scene *scene, SceneLayer *sl, wmWi
G.f |= G_BACKBUFSEL;
if (base && ((base->flag & BASE_VISIBLED) != 0))
- draw_object_backbufsel(C, scene, v3d, rv3d, base->object);
+ draw_object_backbufsel(eval_ctx, scene, v3d, rv3d, base->object);
if (rv3d->gpuoffscreen)
GPU_offscreen_unbind(rv3d->gpuoffscreen, true);
@@ -355,10 +355,11 @@ static void view3d_opengl_read_Z_pixels(ARegion *ar, int x, int y, int w, int h,
glReadPixels(ar->winrct.xmin + x, ar->winrct.ymin + y, w, h, format, type, data);
}
-void ED_view3d_backbuf_validate(const bContext *C, ViewContext *vc)
+void ED_view3d_backbuf_validate(const struct EvaluationContext *eval_ctx, ViewContext *vc)
{
- if (vc->v3d->flag & V3D_INVALID_BACKBUF)
- backdrawview3d(C, vc->scene, vc->scene_layer, vc->win, vc->ar, vc->v3d);
+ if (vc->v3d->flag & V3D_INVALID_BACKBUF) {
+ backdrawview3d(eval_ctx, vc->scene, vc->scene_layer, vc->win, vc->ar, vc->v3d);
+ }
}
/**
@@ -371,13 +372,14 @@ int ED_view3d_backbuf_sample_size_clamp(ARegion *ar, const float dist)
}
/* samples a single pixel (copied from vpaint) */
-unsigned int ED_view3d_backbuf_sample(const bContext *C, ViewContext *vc, int x, int y)
+unsigned int ED_view3d_backbuf_sample(
+ const EvaluationContext *eval_ctx, ViewContext *vc, int x, int y)
{
if (x >= vc->ar->winx || y >= vc->ar->winy) {
return 0;
}
- ED_view3d_backbuf_validate(C, vc);
+ ED_view3d_backbuf_validate(eval_ctx, vc);
unsigned int col;
view3d_opengl_read_pixels(vc->ar, x, y, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &col);
@@ -391,7 +393,8 @@ unsigned int ED_view3d_backbuf_sample(const bContext *C, ViewContext *vc, int x,
}
/* reads full rect, converts indices */
-ImBuf *ED_view3d_backbuf_read(const bContext *C, ViewContext *vc, int xmin, int ymin, int xmax, int ymax)
+ImBuf *ED_view3d_backbuf_read(
+ const EvaluationContext *eval_ctx, ViewContext *vc, int xmin, int ymin, int xmax, int ymax)
{
/* clip */
const rcti clip = {
@@ -409,7 +412,7 @@ ImBuf *ED_view3d_backbuf_read(const bContext *C, ViewContext *vc, int xmin, int
ImBuf *ibuf_clip = IMB_allocImBuf(size_clip[0], size_clip[1], 32, IB_rect);
- ED_view3d_backbuf_validate(C, vc);
+ ED_view3d_backbuf_validate(eval_ctx, vc);
view3d_opengl_read_pixels(vc->ar, clip.xmin, clip.ymin, size_clip[0], size_clip[1], GL_RGBA, GL_UNSIGNED_BYTE, ibuf_clip->rect);
@@ -448,7 +451,7 @@ ImBuf *ED_view3d_backbuf_read(const bContext *C, ViewContext *vc, int xmin, int
/* smart function to sample a rect spiralling outside, nice for backbuf selection */
unsigned int ED_view3d_backbuf_sample_rect(
- const bContext *C, ViewContext *vc, const int mval[2], int size,
+ const EvaluationContext *eval_ctx, ViewContext *vc, const int mval[2], int size,
unsigned int min, unsigned int max, float *r_dist)
{
int dirvec[4][2];
@@ -457,7 +460,7 @@ unsigned int ED_view3d_backbuf_sample_rect(
const int minx = mval[0] - (amount + 1);
const int miny = mval[1] - (amount + 1);
- ImBuf *buf = ED_view3d_backbuf_read(C, vc, minx, miny, minx + size - 1, miny + size - 1);
+ ImBuf *buf = ED_view3d_backbuf_read(eval_ctx, vc, minx, miny, minx + size - 1, miny + size - 1);
if (!buf) return 0;
unsigned index = 0;
@@ -837,7 +840,8 @@ void ED_view3d_after_add(ListBase *lb, BaseLegacy *base, const short dflag)
}
/* disables write in zbuffer and draws it over */
-static void view3d_draw_transp(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d)
+static void view3d_draw_transp(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d)
{
View3DAfter *v3da;
@@ -845,7 +849,7 @@ static void view3d_draw_transp(const bContext *C, Scene *scene, SceneLayer *sl,
v3d->transp = true;
while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
- draw_object(C, scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, v3da->dflag);
MEM_freeN(v3da);
}
v3d->transp = false;
@@ -855,7 +859,8 @@ static void view3d_draw_transp(const bContext *C, Scene *scene, SceneLayer *sl,
}
/* clears zbuffer and draws it over */
-static void view3d_draw_xray(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear)
+static void view3d_draw_xray(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear)
{
if (*clear && v3d->zbuf) {
glClear(GL_DEPTH_BUFFER_BIT);
@@ -865,7 +870,7 @@ static void view3d_draw_xray(const bContext *C, Scene *scene, SceneLayer *sl, AR
v3d->xray = true;
View3DAfter *v3da;
while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
- draw_object(C, scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, v3da->dflag);
MEM_freeN(v3da);
}
v3d->xray = false;
@@ -873,7 +878,8 @@ static void view3d_draw_xray(const bContext *C, Scene *scene, SceneLayer *sl, AR
/* clears zbuffer and draws it over */
-static void view3d_draw_xraytransp(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, const bool clear)
+static void view3d_draw_xraytransp(
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, const bool clear)
{
if (clear && v3d->zbuf)
glClear(GL_DEPTH_BUFFER_BIT);
@@ -885,7 +891,7 @@ static void view3d_draw_xraytransp(const bContext *C, Scene *scene, SceneLayer *
View3DAfter *v3da;
while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
- draw_object(C, scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, v3da->dflag);
MEM_freeN(v3da);
}
@@ -897,7 +903,8 @@ static void view3d_draw_xraytransp(const bContext *C, Scene *scene, SceneLayer *
/* clears zbuffer and draws it over,
* note that in the select version we don't care about transparent flag as with regular drawing */
-static void view3d_draw_xray_select(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear)
+static void view3d_draw_xray_select(
+ const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, bool *clear)
{
/* Not ideal, but we need to read from the previous depths before clearing
* otherwise we could have a function to load the depths after drawing.
@@ -917,7 +924,7 @@ static void view3d_draw_xray_select(const bContext *C, Scene *scene, SceneLayer
v3d->xray = true;
while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
if (GPU_select_load_id(v3da->base->object->select_color)) {
- draw_object_select(C, scene, sl, ar, v3d, v3da->base, v3da->dflag);
+ draw_object_select(eval_ctx, scene, sl, ar, v3d, v3da->base, v3da->dflag);
}
MEM_freeN(v3da);
}
@@ -953,7 +960,7 @@ static DupliObject *dupli_step(DupliObject *dob)
}
static void draw_dupli_objects_color(
- const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base,
+ const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base,
const short dflag, const int color)
{
RegionView3D *rv3d = ar->regiondata;
@@ -967,9 +974,6 @@ static void draw_dupli_objects_color(
char dt;
short dtx;
DupliApplyData *apply_data;
- EvaluationContext eval_ctx;
-
- CTX_data_eval_ctx(C, &eval_ctx);
if ((base->flag & BASE_VISIBLED) == 0) return;
if ((base->object->restrictflag & OB_RESTRICT_RENDER) && (v3d->flag2 & V3D_RENDER_OVERRIDE)) return;
@@ -983,10 +987,10 @@ static void draw_dupli_objects_color(
tbase.flag_legacy = OB_FROMDUPLI | base->flag_legacy;
tbase.flag = base->flag;
- lb = object_duplilist(G.main->eval_ctx, scene, base->object);
+ lb = object_duplilist(eval_ctx, scene, base->object);
// BLI_listbase_sort(lb, dupli_ob_sort); /* might be nice to have if we have a dupli list with mixed objects. */
- apply_data = duplilist_apply(&eval_ctx, base->object, scene, lb);
+ apply_data = duplilist_apply(eval_ctx, base->object, scene, lb);
DupliObject *dob_next = NULL;
DupliObject *dob = dupli_step(lb->first);
@@ -1039,7 +1043,7 @@ static void draw_dupli_objects_color(
if (!testbb || ED_view3d_boundbox_clip_ex(rv3d, &bb, dob->mat)) {
copy_m4_m4(dob->ob->obmat, dob->mat);
GPU_begin_dupli_object(dob);
- draw_object(C, scene, sl, ar, v3d, &tbase, dflag_dupli);
+ draw_object(eval_ctx, scene, sl, ar, v3d, &tbase, dflag_dupli);
GPU_end_dupli_object();
}
@@ -1057,7 +1061,7 @@ static void draw_dupli_objects_color(
free_object_duplilist(lb);
}
-void draw_dupli_objects(const bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base)
+void draw_dupli_objects(const EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base)
{
/* define the color here so draw_dupli_objects_color can be called
* from the set loop */
@@ -1067,7 +1071,7 @@ void draw_dupli_objects(const bContext *C, Scene *scene, SceneLayer *sl, ARegion
if (base->object->dup_group && base->object->dup_group->id.us < 1)
color = TH_REDALERT;
- draw_dupli_objects_color(C, scene, sl, ar, v3d, base, 0, color);
+ draw_dupli_objects_color(eval_ctx, scene, sl, ar, v3d, base, 0, color);
}
/* XXX warning, not using gpu offscreen here */
@@ -1180,12 +1184,13 @@ float view3d_depth_near(ViewDepths *d)
return far == far_real ? FLT_MAX : far;
}
-void ED_view3d_draw_depth_gpencil(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d)
+void ED_view3d_draw_depth_gpencil(
+ const EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d)
{
bool zbuf = v3d->zbuf;
/* Setup view matrix. */
- ED_view3d_draw_setup_view(NULL, C, scene, ar, v3d, NULL, NULL, NULL);
+ ED_view3d_draw_setup_view(NULL, eval_ctx, scene, ar, v3d, NULL, NULL, NULL);
glClear(GL_DEPTH_BUFFER_BIT);
@@ -1200,10 +1205,10 @@ void ED_view3d_draw_depth_gpencil(const bContext *C, Scene *scene, ARegion *ar,
if (!zbuf) glDisable(GL_DEPTH_TEST);
}
-void ED_view3d_draw_depth_loop(const bContext *C, Scene *scene, ARegion *ar, View3D *v3d)
+void ED_view3d_draw_depth_loop(const EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d)
{
Base *base;
- SceneLayer *sl = CTX_data_scene_layer(C);
+ SceneLayer *sl = eval_ctx->scene_layer;
/* no need for color when drawing depth buffer */
const short dflag_depth = DRAW_CONSTCOLOR;
@@ -1212,9 +1217,9 @@ void ED_view3d_draw_depth_loop(const bContext *C, Scene *scene, ARegion *ar, Vie
Scene *sce_iter;
for (SETLOOPER(scene->set, sce_iter, base)) {
if ((base->flag & BASE_VISIBLED) != 0) {
- draw_object(C, scene, sl, ar, v3d, base, 0);
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, 0);
if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects_color(C, scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED);
+ draw_dupli_objects_color(eval_ctx, scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED);
}
}
}
@@ -1224,9 +1229,9 @@ void ED_view3d_draw_depth_loop(const bContext *C, Scene *scene, ARegion *ar, Vie
if ((base->flag & BASE_VISIBLED) != 0) {
/* dupli drawing */
if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects_color(C, scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED);
+ draw_dupli_objects_color(eval_ctx, scene, sl, ar, v3d, base, dflag_depth, TH_UNDEFINED);
}
- draw_object(C, scene, sl, ar, v3d, base, dflag_depth);
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, dflag_depth);
}
}
@@ -1247,7 +1252,7 @@ void ED_view3d_draw_depth_loop(const bContext *C, Scene *scene, ARegion *ar, Vie
if (v3d->afterdraw_xray.first || v3d->afterdraw_xraytransp.first) {
glDepthFunc(GL_ALWAYS); /* always write into the depth bufer, overwriting front z values */
for (v3da = v3d->afterdraw_xray.first; v3da; v3da = v3da->next) {
- draw_object(C, scene, sl, ar, v3d, v3da->base, dflag_depth);
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, dflag_depth);
}
glDepthFunc(GL_LEQUAL); /* Now write the depth buffer normally */
}
@@ -1256,21 +1261,21 @@ void ED_view3d_draw_depth_loop(const bContext *C, Scene *scene, ARegion *ar, Vie
v3d->xray = false;
v3d->transp = true;
while ((v3da = BLI_pophead(&v3d->afterdraw_transp))) {
- draw_object(C, scene, sl, ar, v3d, v3da->base, dflag_depth);
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, dflag_depth);
MEM_freeN(v3da);
}
v3d->xray = true;
v3d->transp = false;
while ((v3da = BLI_pophead(&v3d->afterdraw_xray))) {
- draw_object(C, scene, sl, ar, v3d, v3da->base, dflag_depth);
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, dflag_depth);
MEM_freeN(v3da);
}
v3d->xray = true;
v3d->transp = true;
while ((v3da = BLI_pophead(&v3d->afterdraw_xraytransp))) {
- draw_object(C, scene, sl, ar, v3d, v3da->base, dflag_depth);
+ draw_object(eval_ctx, scene, sl, ar, v3d, v3da->base, dflag_depth);
MEM_freeN(v3da);
}
@@ -1283,19 +1288,19 @@ void ED_view3d_draw_depth_loop(const bContext *C, Scene *scene, ARegion *ar, Vie
}
void ED_view3d_draw_select_loop(
- const bContext *C, ViewContext *vc, Scene *scene, SceneLayer *sl, View3D *v3d, ARegion *ar,
- bool use_obedit_skip, bool use_nearest)
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, Scene *scene, SceneLayer *sl,
+ View3D *v3d, ARegion *ar, bool use_obedit_skip, bool use_nearest)
{
short code = 1;
const short dflag = DRAW_PICKING | DRAW_CONSTCOLOR;
if (vc->obedit && vc->obedit->type == OB_MBALL) {
- draw_object(C, scene, sl, ar, v3d, BASACT_NEW, dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, BASACT_NEW(sl), dflag);
}
else if ((vc->obedit && vc->obedit->type == OB_ARMATURE)) {
/* if not drawing sketch, draw bones */
if (!BDR_drawSketchNames(vc)) {
- draw_object(C, scene, sl, ar, v3d, BASACT_NEW, dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, BASACT_NEW(sl), dflag);
}
}
else {
@@ -1316,7 +1321,7 @@ void ED_view3d_draw_select_loop(
}
else {
if (GPU_select_load_id(code)) {
- draw_object(C, scene, sl, ar, v3d, base, dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, dflag);
}
}
code++;
@@ -1327,7 +1332,7 @@ void ED_view3d_draw_select_loop(
if (use_nearest) {
bool xrayclear = true;
if (v3d->afterdraw_xray.first) {
- view3d_draw_xray_select(C, scene, sl, ar, v3d, &xrayclear);
+ view3d_draw_xray_select(eval_ctx, scene, sl, ar, v3d, &xrayclear);
}
}
}
@@ -1358,7 +1363,7 @@ static void gpu_render_lamp_update(Scene *scene, View3D *v3d,
if (layers &&
GPU_lamp_has_shadow_buffer(lamp) &&
/* keep last, may do string lookup */
- GPU_lamp_override_visible(lamp, srl, NULL))
+ GPU_lamp_visible(lamp, srl, NULL))
{
View3DShadow *shadow = MEM_callocN(sizeof(View3DShadow), "View3DShadow");
shadow->lamp = lamp;
@@ -1367,7 +1372,7 @@ static void gpu_render_lamp_update(Scene *scene, View3D *v3d,
}
}
-static void gpu_update_lamps_shadows_world(EvaluationContext *eval_ctx, Scene *scene, View3D *v3d)
+static void gpu_update_lamps_shadows_world(const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d)
{
ListBase shadows;
Scene *sce_iter;
@@ -1500,6 +1505,7 @@ CustomDataMask ED_view3d_screen_datamask(const Scene *scene, const bScreen *scre
*/
static void view3d_draw_objects(
const bContext *C,
+ const EvaluationContext *eval_ctx,
Scene *scene, View3D *v3d, ARegion *ar,
const char **grid_unit,
const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
@@ -1563,10 +1569,10 @@ static void view3d_draw_objects(
for (SETLOOPER(scene->set, sce_iter, base)) {
if ((base->flag & BASE_VISIBLED) != 0) {
UI_ThemeColorBlend(TH_WIRE, TH_BACK, 0.6f);
- draw_object(C, scene, sl, ar, v3d, base, dflag);
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, dflag);
if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects_color(C, scene, sl, ar, v3d, base, dflag, TH_UNDEFINED);
+ draw_dupli_objects_color(eval_ctx, scene, sl, ar, v3d, base, dflag, TH_UNDEFINED);
}
}
}
@@ -1578,10 +1584,11 @@ static void view3d_draw_objects(
for (base = sl->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_VISIBLED) != 0) {
/* dupli drawing */
- if (base->object->transflag & OB_DUPLI)
- draw_dupli_objects(C, scene, sl, ar, v3d, base);
+ if (base->object->transflag & OB_DUPLI) {
+ draw_dupli_objects(eval_ctx, scene, sl, ar, v3d, base);
+ }
- draw_object(C, scene, sl, ar, v3d, base, 0);
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, 0);
}
}
}
@@ -1596,11 +1603,11 @@ static void view3d_draw_objects(
/* dupli drawing */
if (base->object->transflag & OB_DUPLI) {
- draw_dupli_objects(C, scene, sl, ar, v3d, base);
+ draw_dupli_objects(eval_ctx, scene, sl, ar, v3d, base);
}
if ((base->flag & BASE_SELECTED) == 0) {
if (base->object != scene->obedit)
- draw_object(C, scene, sl, ar, v3d, base, 0);
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, 0);
}
}
}
@@ -1612,7 +1619,7 @@ static void view3d_draw_objects(
for (base = sl->object_bases.first; base; base = base->next) {
if ((base->flag & BASE_VISIBLED) != 0) {
if (base->object == scene->obedit || (base->flag & BASE_SELECTED)) {
- draw_object(C, scene, sl, ar, v3d, base, 0);
+ draw_object(eval_ctx, scene, sl, ar, v3d, base, 0);
}
}
}
@@ -1634,7 +1641,7 @@ static void view3d_draw_objects(
}
/* transp and X-ray afterdraw stuff */
- if (v3d->afterdraw_transp.first) view3d_draw_transp(C, scene, sl, ar, v3d);
+ if (v3d->afterdraw_transp.first) view3d_draw_transp(eval_ctx, scene, sl, ar, v3d);
/* always do that here to cleanup depth buffers if none needed */
if (fx) {
@@ -1642,8 +1649,8 @@ static void view3d_draw_objects(
GPU_fx_compositor_setup_XRay_pass(fx, do_composite_xray);
}
- if (v3d->afterdraw_xray.first) view3d_draw_xray(C, scene, sl, ar, v3d, &xrayclear);
- if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(C, scene, sl, ar, v3d, xrayclear);
+ if (v3d->afterdraw_xray.first) view3d_draw_xray(eval_ctx, scene, sl, ar, v3d, &xrayclear);
+ if (v3d->afterdraw_xraytransp.first) view3d_draw_xraytransp(eval_ctx, scene, sl, ar, v3d, xrayclear);
if (fx && do_composite_xray) {
GPU_fx_compositor_XRay_resolve(fx);
@@ -1823,14 +1830,16 @@ bool ED_view3d_calc_render_border(const Scene *scene, View3D *v3d, ARegion *ar,
* IMPORTANT: this is deprecated, any changes made in this function should
* be mirrored in view3d_draw_render_draw() in view3d_draw.c
*/
-static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene,
- ARegion *ar, View3D *v3d,
- bool clip_border, const rcti *border_rect)
+static bool view3d_main_region_draw_engine(
+ const bContext *C, const EvaluationContext *eval_ctx, Scene *scene,
+ ARegion *ar, View3D *v3d,
+ bool clip_border, const rcti *border_rect)
{
RegionView3D *rv3d = ar->regiondata;
RenderEngineType *type;
GLint scissor[4];
+
/* create render engine */
if (!rv3d->render_engine) {
RenderEngine *engine;
@@ -1851,7 +1860,7 @@ static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene,
}
/* setup view matrices */
- VP_legacy_view3d_main_region_setup_view(C, scene, v3d, ar, NULL, NULL);
+ VP_legacy_view3d_main_region_setup_view(eval_ctx, scene, v3d, ar, NULL, NULL);
/* background draw */
ED_region_pixelspace(ar);
@@ -1955,10 +1964,12 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Sce
}
/* setup the view matrix */
- if (VP_legacy_view3d_stereo3d_active(C, scene, v3d, rv3d))
- VP_legacy_view3d_stereo3d_setup(C, scene, v3d, ar);
- else
- VP_legacy_view3d_main_region_setup_view(C, scene, v3d, ar, NULL, NULL);
+ if (VP_legacy_view3d_stereo3d_active(win, scene, v3d, rv3d)) {
+ VP_legacy_view3d_stereo3d_setup(&eval_ctx, scene, v3d, ar);
+ }
+ else {
+ VP_legacy_view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, NULL, NULL);
+ }
rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
#ifdef WITH_GAMEENGINE
@@ -1992,7 +2003,7 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Sce
}
/* main drawing call */
- view3d_draw_objects(C, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
+ view3d_draw_objects(C, &eval_ctx, scene, v3d, ar, grid_unit, true, false, do_compositing ? rv3d->compositor : NULL);
/* draw depth culled manipulators - manipulators need to be updated *after* view matrix was set up */
/* TODO depth culling manipulators is not yet supported, just drawing _3D here, should
@@ -2054,7 +2065,7 @@ static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
draw_view_icon(rv3d, &rect);
if (U.uiflag & USER_DRAWVIEWINFO) {
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
VP_legacy_draw_selected_name(scene, ob, &rect);
}
}
@@ -2089,6 +2100,7 @@ static void view3d_main_region_draw_info(const bContext *C, Scene *scene,
void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar)
{
+ EvaluationContext eval_ctx;
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
View3D *v3d = CTX_wm_view3d(C);
@@ -2105,6 +2117,8 @@ void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar)
gpuPushMatrix();
gpuLoadIdentity();
+ CTX_data_eval_ctx(C, &eval_ctx);
+
/* draw viewport using opengl */
if (v3d->drawtype != OB_RENDER || !view3d_main_region_do_render_draw(scene) || clip_border) {
VP_view3d_main_region_clear(scene, v3d, ar); /* background */
@@ -2118,10 +2132,11 @@ void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar)
}
/* draw viewport using external renderer */
- if (v3d->drawtype == OB_RENDER)
- view3d_main_region_draw_engine(C, scene, ar, v3d, clip_border, &border_rect);
+ if (v3d->drawtype == OB_RENDER) {
+ view3d_main_region_draw_engine(C, &eval_ctx, scene, ar, v3d, clip_border, &border_rect);
+ }
- VP_legacy_view3d_main_region_setup_view(C, scene, v3d, ar, NULL, NULL);
+ VP_legacy_view3d_main_region_setup_view(&eval_ctx, scene, v3d, ar, NULL, NULL);
glClear(GL_DEPTH_BUFFER_BIT);
ED_region_pixelspace(ar);
@@ -2153,14 +2168,15 @@ void view3d_main_region_draw_legacy(const bContext *C, ARegion *ar)
void VP_deprecated_view3d_draw_objects(
const bContext *C,
+ const EvaluationContext *eval_ctx,
Scene *scene, View3D *v3d, ARegion *ar,
const char **grid_unit,
const bool do_bgpic, const bool draw_offscreen, GPUFX *fx)
{
- view3d_draw_objects(C, scene, v3d, ar, grid_unit, do_bgpic, draw_offscreen, fx);
+ view3d_draw_objects(C, eval_ctx, scene, v3d, ar, grid_unit, do_bgpic, draw_offscreen, fx);
}
-void VP_deprecated_gpu_update_lamps_shadows_world(EvaluationContext *eval_ctx, Scene *scene, View3D *v3d)
+void VP_deprecated_gpu_update_lamps_shadows_world(const EvaluationContext *eval_ctx, Scene *scene, View3D *v3d)
{
gpu_update_lamps_shadows_world(eval_ctx, scene, v3d);
}
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index 0350a67f3d4..fd29658061e 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -623,7 +623,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob_act = OBACT_NEW;
+ Object *ob_act = OBACT_NEW(sl);
if (ob_act && (ob_act->mode & OB_MODE_ALL_PAINT) &&
/* with weight-paint + pose-mode, fall through to using calculateTransformCenter */
@@ -665,7 +665,7 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
float select_center[3];
zero_v3(select_center);
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (TESTBASE_NEW(base)) {
/* use the boundbox if we can */
Object *ob = base->object;
@@ -737,15 +737,18 @@ static void viewops_data_create_ex(
/* we need the depth info before changing any viewport options */
if (orbit_mode & VIEWOPS_ORBIT_DEPTH) {
+ EvaluationContext eval_ctx;
struct Depsgraph *graph = CTX_data_depsgraph(C);
float fallback_depth_pt[3];
+ CTX_data_eval_ctx(C, &eval_ctx);
+
view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
negate_v3_v3(fallback_depth_pt, rv3d->ofs);
vod->use_dyn_ofs = ED_view3d_autodist(
- C, graph, vod->ar, vod->v3d,
+ &eval_ctx, graph, vod->ar, vod->v3d,
event->mval, vod->dyn_ofs, true, fallback_depth_pt);
}
else {
@@ -3071,7 +3074,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
const bool is_face_map = ((is_gp_edit == false) && ar->manipulator_map &&
WM_manipulatormap_is_any_selected(ar->manipulator_map));
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
Object *obedit = CTX_data_edit_object(C);
float min[3], max[3];
bool ok = false, ok_dist = true;
@@ -3139,7 +3142,7 @@ static int viewselected_exec(bContext *C, wmOperator *op)
}
else {
Base *base;
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (TESTBASE_NEW(base)) {
if (skip_camera && base->object == v3d->camera) {
@@ -3320,15 +3323,18 @@ static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *ev
ARegion *ar = CTX_wm_region(C);
if (rv3d) {
+ EvaluationContext eval_ctx;
struct Depsgraph *graph = CTX_data_depsgraph(C);
float new_ofs[3];
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ CTX_data_eval_ctx(C, &eval_ctx);
+
ED_view3d_smooth_view_force_finish(C, v3d, ar);
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(C, graph, ar, v3d, event->mval, new_ofs, false, NULL)) {
+ if (ED_view3d_autodist(&eval_ctx, graph, ar, v3d, event->mval, new_ofs, false, NULL)) {
/* pass */
}
else {
@@ -3583,6 +3589,7 @@ void VIEW3D_OT_clear_render_border(wmOperatorType *ot)
static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
ARegion *ar = CTX_wm_region(C);
View3D *v3d = CTX_wm_view3d(C);
RegionView3D *rv3d = CTX_wm_region_view3d(C);
@@ -3605,6 +3612,8 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
/* note; otherwise opengl won't work */
view3d_operator_needs_opengl(C);
+ CTX_data_eval_ctx(C, &eval_ctx);
+
/* get border select values using rna */
WM_operator_properties_border_to_rcti(op, &rect);
@@ -3614,7 +3623,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op)
ED_view3d_dist_range_get(v3d, dist_range);
/* Get Z Depths, needed for perspective, nice for ortho */
- ED_view3d_draw_depth(C, CTX_data_depsgraph(C), ar, v3d, true);
+ ED_view3d_draw_depth(&eval_ctx, CTX_data_depsgraph(C), ar, v3d, true);
{
/* avoid allocating the whole depth buffer */
@@ -3937,7 +3946,7 @@ static int viewnumpad_exec(bContext *C, wmOperator *op)
/* lastview - */
if (rv3d->persp != RV3D_CAMOB) {
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (!rv3d->smooth_timer) {
/* store settings of current view before allowing overwriting with camera view
@@ -4714,9 +4723,13 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
}
if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */
+ EvaluationContext eval_ctx;
struct Depsgraph *graph = CTX_data_depsgraph(C);
+
+ CTX_data_eval_ctx(C, &eval_ctx);
+
view3d_operator_needs_opengl(C);
- if (ED_view3d_autodist(C, graph, ar, v3d, mval, fp, true, NULL)) {
+ if (ED_view3d_autodist(&eval_ctx, graph, ar, v3d, mval, fp, true, NULL)) {
depth_used = true;
}
}
@@ -4750,7 +4763,7 @@ void ED_view3d_cursor3d_update(bContext *C, const int mval[2])
float co_curr[2], co_prev[2];
if ((ED_view3d_project_float_global(ar, fp_prev, co_prev, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) &&
- (ED_view3d_project_float_global(ar, fp_curr, co_curr, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
+ (ED_view3d_project_float_global(ar, fp_curr, co_curr, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK))
{
rv3d->ofs_lock[0] += (co_curr[0] - co_prev[0]) / (ar->winx * 0.5f);
rv3d->ofs_lock[1] += (co_curr[1] - co_prev[1]) / (ar->winy * 0.5f);
@@ -4900,7 +4913,7 @@ static float view_autodist_depth_margin(ARegion *ar, const int mval[2], int marg
* \param fallback_depth_pt: Use this points depth when no depth can be found.
*/
bool ED_view3d_autodist(
- const bContext *C, struct Depsgraph *graph, ARegion *ar, View3D *v3d,
+ const EvaluationContext *eval_ctx, struct Depsgraph *graph, ARegion *ar, View3D *v3d,
const int mval[2], float mouse_worldloc[3],
const bool alphaoverride, const float fallback_depth_pt[3])
{
@@ -4910,7 +4923,7 @@ bool ED_view3d_autodist(
bool depth_ok = false;
/* Get Z Depths, needed for perspective, nice for ortho */
- ED_view3d_draw_depth(C, graph, ar, v3d, alphaoverride);
+ ED_view3d_draw_depth(eval_ctx, graph, ar, v3d, alphaoverride);
/* Attempt with low margin's first */
i = 0;
@@ -4939,18 +4952,18 @@ bool ED_view3d_autodist(
}
void ED_view3d_autodist_init(
- const bContext *C, struct Depsgraph *graph,
+ const EvaluationContext *eval_ctx, struct Depsgraph *graph,
ARegion *ar, View3D *v3d, int mode)
{
/* Get Z Depths, needed for perspective, nice for ortho */
switch (mode) {
case 0:
- ED_view3d_draw_depth(C, graph, ar, v3d, true);
+ ED_view3d_draw_depth(eval_ctx, graph, ar, v3d, true);
break;
case 1:
{
Scene *scene = DEG_get_evaluated_scene(graph);
- ED_view3d_draw_depth_gpencil(C, scene, ar, v3d);
+ ED_view3d_draw_depth_gpencil(eval_ctx, scene, ar, v3d);
break;
}
}
diff --git a/source/blender/editors/space_view3d/view3d_header.c b/source/blender/editors/space_view3d/view3d_header.c
index e2ca076e5ad..82ab57e44aa 100644
--- a/source/blender/editors/space_view3d/view3d_header.c
+++ b/source/blender/editors/space_view3d/view3d_header.c
@@ -283,7 +283,7 @@ void uiTemplateHeader3D(uiLayout *layout, struct bContext *C)
SceneLayer *sl = CTX_data_scene_layer(C);
ToolSettings *ts = CTX_data_tool_settings(C);
PointerRNA v3dptr, toolsptr, sceneptr;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
Object *obedit = CTX_data_edit_object(C);
bGPdata *gpd = CTX_data_gpencil_data(C);
uiBlock *block;
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index 49c38b9a0f7..e39bbec70e3 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -146,14 +146,18 @@ void draw_motion_paths_cleanup(View3D *v3d);
/* drawobject.c */
-void draw_object(const struct bContext *C, Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d, BaseLegacy *base, const short dflag);
-void draw_object_select(const struct bContext *C, Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d, Base *base, const short dflag);
+void draw_object(
+ const struct EvaluationContext *eval_ctx, Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d,
+ BaseLegacy *base, const short dflag);
+void draw_object_select(
+ const struct EvaluationContext *eval_ctx, Scene *scene, struct SceneLayer *sl, struct ARegion *ar, View3D *v3d,
+ Base *base, const short dflag);
void draw_mesh_object_outline(View3D *v3d, Object *ob, struct DerivedMesh *dm, const unsigned char ob_wire_col[4]);
bool draw_glsl_material(Scene *scene, struct SceneLayer *sl, struct Object *ob, View3D *v3d, const char dt);
-void draw_object_instance(const struct bContext *C, Scene *scene, struct SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]);
-void draw_object_backbufsel(const struct bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
+void draw_object_instance(const struct EvaluationContext *eval_ctx, Scene *scene, struct SceneLayer *sl, View3D *v3d, RegionView3D *rv3d, struct Object *ob, const char dt, int outline, const float wire_col[4]);
+void draw_object_backbufsel(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, RegionView3D *rv3d, struct Object *ob);
void draw_object_wire_color(Scene *scene, struct SceneLayer *, Base *base, unsigned char r_ob_wire_col[4]);
void drawaxes(const float viewmat_local[4][4], float size, char drawtype, const unsigned char color[4]);
@@ -185,9 +189,10 @@ enum {
int view3d_effective_drawtype(const struct View3D *v3d);
/* drawarmature.c */
-bool draw_armature(const struct bContext *C, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
- const short dt, const short dflag, const unsigned char ob_wire_col[4],
- const bool is_outline);
+bool draw_armature(
+ const struct EvaluationContext *eval_ctx, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar, Base *base,
+ const short dt, const short dflag, const unsigned char ob_wire_col[4],
+ const bool is_outline);
/* drawmesh.c */
void draw_mesh_textured(Scene *scene, struct SceneLayer *sl, View3D *v3d, RegionView3D *rv3d,
@@ -217,18 +222,19 @@ void view3d_main_region_draw(const struct bContext *C, struct ARegion *ar);
void view3d_draw_region_info(const struct bContext *C, struct ARegion *ar, const int offset);
void ED_view3d_draw_depth(
- const struct bContext *C, struct Depsgraph *graph,
+ const struct EvaluationContext *eval_ctx, struct Depsgraph *graph,
struct ARegion *ar, View3D *v3d, bool alphaoverride);
/* view3d_draw_legacy.c */
void view3d_main_region_draw_legacy(const struct bContext *C, struct ARegion *ar);
-void ED_view3d_draw_depth_gpencil(const struct bContext *C, Scene *scene, ARegion *ar, View3D *v3d);
+void ED_view3d_draw_depth_gpencil(const struct EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d);
void ED_view3d_draw_select_loop(
- const struct bContext *C, ViewContext *vc, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar,
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, Scene *scene, struct SceneLayer *sl, View3D *v3d, ARegion *ar,
bool use_obedit_skip, bool use_nearest);
-void ED_view3d_draw_depth_loop(const struct bContext *C, Scene *scene, ARegion *ar, View3D *v3d);
+void ED_view3d_draw_depth_loop(
+ const struct EvaluationContext *eval_ctx, Scene *scene, ARegion *ar, View3D *v3d);
void ED_view3d_after_add(ListBase *lb, BaseLegacy *base, const short dflag);
@@ -274,7 +280,7 @@ void ED_view3d_smooth_view_force_finish(
struct View3D *v3d, struct ARegion *ar);
void view3d_winmatrix_set(ARegion *ar, const View3D *v3d, const rcti *rect);
-void view3d_viewmatrix_set(struct EvaluationContext *eval_ctx, Scene *scene, const View3D *v3d, RegionView3D *rv3d);
+void view3d_viewmatrix_set(const struct EvaluationContext *eval_ctx, Scene *scene, const View3D *v3d, RegionView3D *rv3d);
void fly_modal_keymap(struct wmKeyConfig *keyconf);
void walk_modal_keymap(struct wmKeyConfig *keyconf);
@@ -324,13 +330,14 @@ ARegion *view3d_has_tools_region(ScrArea *sa);
extern const char *view3d_context_dir[]; /* doc access */
/* view3d_widgets.c */
-void VIEW3D_WGT_lamp_spot (struct wmManipulatorGroupType *wgt);
-void VIEW3D_WGT_lamp_area (struct wmManipulatorGroupType *wgt);
-void VIEW3D_WGT_lamp_target (struct wmManipulatorGroupType *wgt);
-void VIEW3D_WGT_camera (struct wmManipulatorGroupType *wgt);
-void VIEW3D_WGT_camera_view (struct wmManipulatorGroupType *wgt);
-void VIEW3D_WGT_force_field (struct wmManipulatorGroupType *wgt);
-void VIEW3D_WGT_armature_facemaps(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_lamp_spot(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_lamp_area(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_lamp_target(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_camera(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_camera_view(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_force_field(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_empty_image(struct wmManipulatorGroupType *wgt);
+void VIEW3D_WGT_armature_spline(struct wmManipulatorGroupType *wgt);
/* draw_volume.c */
void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob,
@@ -357,10 +364,10 @@ void VP_legacy_draw_viewport_name(ARegion *ar, View3D *v3d, rcti *rect);
void VP_legacy_draw_selected_name(Scene *scene, Object *ob, rcti *rect);
void VP_legacy_drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char **grid_unit);
void VP_legacy_drawfloor(Scene *scene, View3D *v3d, const char **grid_unit, bool write_depth);
-void VP_legacy_view3d_main_region_setup_view(const struct bContext *C, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]);
-bool VP_legacy_view3d_stereo3d_active(const struct bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d);
-void VP_legacy_view3d_stereo3d_setup(const struct bContext *C, Scene *scene, View3D *v3d, ARegion *ar);
-void draw_dupli_objects(const struct bContext *C, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base);
+void VP_legacy_view3d_main_region_setup_view(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4]);
+bool VP_legacy_view3d_stereo3d_active(struct wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d);
+void VP_legacy_view3d_stereo3d_setup(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d, ARegion *ar);
+void draw_dupli_objects(const struct EvaluationContext *eval_ctx, Scene *scene, SceneLayer *sl, ARegion *ar, View3D *v3d, BaseLegacy *base);
bool VP_legacy_use_depth(Scene *scene, View3D *v3d);
void VP_drawviewborder(Scene *scene, ARegion *ar, View3D *v3d);
void VP_drawrenderborder(ARegion *ar, View3D *v3d);
@@ -369,9 +376,10 @@ void VP_view3d_draw_background_world(Scene *scene, View3D *v3d, RegionView3D *rv
void VP_view3d_main_region_clear(Scene *scene, View3D *v3d, ARegion *ar);
/* temporary legacy calls, only when there is a switch between new/old draw calls */
-void VP_deprecated_gpu_update_lamps_shadows_world(struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d);
+void VP_deprecated_gpu_update_lamps_shadows_world(const struct EvaluationContext *eval_ctx, Scene *scene, View3D *v3d);
void VP_deprecated_view3d_draw_objects(
const struct bContext *C,
+ const struct EvaluationContext *eval_ctx,
Scene *scene, View3D *v3d, ARegion *ar,
const char **grid_unit,
const bool do_bgpic, const bool draw_offscreen, struct GPUFX *fx);
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index 48dd3d64e86..4f80270e1e7 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -107,17 +107,14 @@ static void meshobject_foreachScreenVert__mapFunc(void *userData, int index, con
}
void meshobject_foreachScreenVert(
- const bContext *C, ViewContext *vc,
+ const EvaluationContext *eval_ctx, ViewContext *vc,
void (*func)(void *userData, MVert *eve, const float screen_co[2], int index),
void *userData, eV3DProjTest clip_flag)
{
foreachScreenObjectVert_userData data;
- EvaluationContext eval_ctx;
DerivedMesh *dm;
- CTX_data_eval_ctx(C, &eval_ctx);
-
- dm = mesh_get_derived_deform(&eval_ctx, vc->scene, vc->obact, CD_MASK_BAREMESH);
+ dm = mesh_get_derived_deform(eval_ctx, vc->scene, vc->obact, CD_MASK_BAREMESH);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -153,17 +150,14 @@ static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const flo
}
void mesh_foreachScreenVert(
- const bContext *C, ViewContext *vc,
+ const EvaluationContext *eval_ctx, ViewContext *vc,
void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index),
void *userData, eV3DProjTest clip_flag)
{
foreachScreenVert_userData data;
- EvaluationContext eval_ctx;
DerivedMesh *dm;
- CTX_data_eval_ctx(C, &eval_ctx);
-
- dm = editbmesh_get_derived_cage(&eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+ dm = editbmesh_get_derived_cage(eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -212,17 +206,14 @@ static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const flo
}
void mesh_foreachScreenEdge(
- const bContext *C, ViewContext *vc,
+ const EvaluationContext *eval_ctx, ViewContext *vc,
void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index),
void *userData, eV3DProjTest clip_flag)
{
foreachScreenEdge_userData data;
- EvaluationContext eval_ctx;
DerivedMesh *dm;
- CTX_data_eval_ctx(C, &eval_ctx);
-
- dm = editbmesh_get_derived_cage(&eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+ dm = editbmesh_get_derived_cage(eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
ED_view3d_check_mats_rv3d(vc->rv3d);
@@ -263,17 +254,14 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo
}
void mesh_foreachScreenFace(
- const bContext *C, ViewContext *vc,
+ const EvaluationContext *eval_ctx, ViewContext *vc,
void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index),
void *userData, const eV3DProjTest clip_flag)
{
foreachScreenFace_userData data;
- EvaluationContext eval_ctx;
DerivedMesh *dm;
- CTX_data_eval_ctx(C, &eval_ctx);
-
- dm = editbmesh_get_derived_cage(&eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
+ dm = editbmesh_get_derived_cage(eval_ctx, vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH);
ED_view3d_check_mats_rv3d(vc->rv3d);
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_armature.c b/source/blender/editors/space_view3d/view3d_manipulator_armature.c
new file mode 100644
index 00000000000..5d3d88ff2a2
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_armature.c
@@ -0,0 +1,220 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_armature.c
+ * \ingroup spview3d
+ */
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_armature.h"
+#include "BKE_action.h"
+#include "BKE_context.h"
+#include "BKE_object.h"
+
+#include "DNA_object_types.h"
+#include "DNA_armature_types.h"
+
+#include "ED_armature.h"
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h" /* own include */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Armature Spline Manipulator
+ *
+ * \{ */
+
+/*
+ * TODO(campbell): Current conversion is a approximation (usable not correct),
+ * we'll need to take the next/previous bones into account to get the tangent directions.
+ * First last matrices from 'b_bone_spline_setup' are close but also not quite accurate
+ * since they're not at either end-points on the curve.
+ *
+ * Likely we'll need a function especially to get the first/last orientations.
+ */
+
+#define BBONE_SCALE_Y 3.0f
+
+struct BoneSplineHandle {
+ wmManipulator *manipulator;
+ bPoseChannel *pchan;
+ /* We could remove, keep since at the moment for checking the conversion. */
+ float co[3];
+ int index;
+};
+
+struct BoneSplineWidgetGroup {
+ struct BoneSplineHandle handles[2];
+};
+
+static void manipulator_bbone_offset_get(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data;
+ bPoseChannel *pchan = bh->pchan;
+
+ float *value = value_p;
+ BLI_assert(mpr_prop->type->array_length == 3);
+
+ if (bh->index == 0) {
+ bh->co[1] = pchan->bone->ease1 / BBONE_SCALE_Y;
+ bh->co[0] = pchan->curveInX;
+ bh->co[2] = pchan->curveInY;
+ }
+ else {
+ bh->co[1] = -pchan->bone->ease2 / BBONE_SCALE_Y;
+ bh->co[0] = pchan->curveOutX;
+ bh->co[2] = pchan->curveOutY;
+ }
+ copy_v3_v3(value, bh->co);
+}
+
+static void manipulator_bbone_offset_set(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ struct BoneSplineHandle *bh = mpr_prop->custom_func.user_data;
+ bPoseChannel *pchan = bh->pchan;
+
+ const float *value = value_p;
+
+ BLI_assert(mpr_prop->type->array_length == 3);
+ copy_v3_v3(bh->co, value);
+
+ if (bh->index == 0) {
+ pchan->bone->ease1 = max_ff(0.0f, bh->co[1] * BBONE_SCALE_Y);
+ pchan->curveInX = bh->co[0];
+ pchan->curveInY = bh->co[2];
+ }
+ else {
+ pchan->bone->ease2 = max_ff(0.0f, -bh->co[1] * BBONE_SCALE_Y);
+ pchan->curveOutX = bh->co[0];
+ pchan->curveOutY = bh->co[2];
+ }
+
+}
+
+static bool WIDGETGROUP_armature_spline_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+ if (ob != NULL) {
+ const bArmature *arm = ob->data;
+ if (arm->drawtype == ARM_B_BONE) {
+ if (arm->act_bone && arm->act_bone->segments > 1) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+
+static void WIDGETGROUP_armature_spline_setup(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+
+ const wmManipulatorType *wt_grab = WM_manipulatortype_find("MANIPULATOR_WT_grab_3d", true);
+
+ struct BoneSplineWidgetGroup *bspline_group = MEM_callocN(sizeof(struct BoneSplineWidgetGroup), __func__);
+ mgroup->customdata = bspline_group;
+
+ /* Handles */
+ for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
+ wmManipulator *mpr;
+ mpr = bspline_group->handles[i].manipulator = WM_manipulator_new_ptr(wt_grab, mgroup, NULL);
+ RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_GRAB_STYLE_RING_2D);
+ RNA_enum_set(mpr->ptr, "draw_options",
+ ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL | ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW);
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_VALUE, true);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+
+ mpr->scale_basis = 0.06f;
+
+ if (i == 0) {
+ copy_v3_v3(mpr->matrix_basis[3], pchan->loc);
+ }
+ }
+}
+
+static void WIDGETGROUP_armature_spline_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ Object *ob = BKE_object_pose_armature_get(CTX_data_active_object(C));
+
+ if (!mgroup->customdata)
+ return;
+
+ struct BoneSplineWidgetGroup *bspline_group = mgroup->customdata;
+ bPoseChannel *pchan = BKE_pose_channel_active(ob);
+
+ /* Handles */
+ for (int i = 0; i < ARRAY_SIZE(bspline_group->handles); i++) {
+ wmManipulator *mpr = bspline_group->handles[i].manipulator;
+ bspline_group->handles[i].pchan = pchan;
+ bspline_group->handles[i].index = i;
+
+ float mat[4][4];
+ mul_m4_m4m4(mat, ob->obmat, (i == 0) ? pchan->disp_mat : pchan->disp_tail_mat);
+ copy_m4_m4(mpr->matrix_space, mat);
+
+ /* need to set property here for undo. TODO would prefer to do this in _init */
+ WM_manipulator_target_property_def_func(
+ mpr, "offset",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_bbone_offset_get,
+ .value_set_fn = manipulator_bbone_offset_set,
+ .range_get_fn = NULL,
+ .user_data = &bspline_group->handles[i],
+ });
+ }
+}
+
+void VIEW3D_WGT_armature_spline(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Armature Spline Widgets";
+ wgt->idname = "VIEW3D_WGT_armature_spline";
+
+ wgt->flag = (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_3D);
+
+ wgt->poll = WIDGETGROUP_armature_spline_poll;
+ wgt->setup = WIDGETGROUP_armature_spline_setup;
+ wgt->refresh = WIDGETGROUP_armature_spline_refresh;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_camera.c b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
index 51467775298..a1ad45ae6b6 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_camera.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_camera.c
@@ -37,6 +37,8 @@
#include "ED_screen.h"
#include "ED_manipulator_library.h"
+#include "UI_resources.h"
+
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
@@ -105,37 +107,32 @@ static void WIDGETGROUP_camera_setup(const bContext *C, wmManipulatorGroup *mgro
/* dof distance */
{
wmManipulator *mpr;
- const float color[4] = {1.0f, 0.3f, 0.0f, 1.0f};
- const float color_hi[4] = {1.0f, 0.3f, 0.0f, 1.0f};
-
mpr = camgroup->dop_dist = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CROSS);
WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_HOVER, true);
- WM_manipulator_set_color(mpr, color);
- WM_manipulator_set_color_highlight(mpr, color_hi);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_A, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
}
/* focal length
* - logic/calculations are similar to BKE_camera_view_frame_ex, better keep in sync */
{
wmManipulator *mpr;
- const float color[4] = {1.0f, 1.0, 0.27f, 0.5f};
- const float color_hi[4] = {1.0f, 1.0, 0.27f, 1.0f};
-
mpr = camgroup->focal_len = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE);
RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED);
- WM_manipulator_set_color(mpr, color);
- WM_manipulator_set_color_highlight(mpr, color_hi);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
cameragroup_property_setup(mpr, ob, ca, false);
mpr = camgroup->ortho_scale = WM_manipulator_new_ptr(wt_arrow, mgroup, NULL);
RNA_enum_set(mpr->ptr, "draw_style", ED_MANIPULATOR_ARROW_STYLE_CONE);
RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED);
- WM_manipulator_set_color(mpr, color);
- WM_manipulator_set_color_highlight(mpr, color_hi);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
cameragroup_property_setup(mpr, ob, ca, true);
}
}
@@ -304,6 +301,16 @@ static bool WIDGETGROUP_camera_view_poll(const bContext *C, wmManipulatorGroupTy
Scene *scene = CTX_data_scene(C);
View3D *v3d = CTX_wm_view3d(C);
+ /* This is just so the border isn't always in the way,
+ * stealing mouse clicks from regular usage.
+ * We could change the rules for when to show. */
+ {
+ SceneLayer *sl = CTX_data_scene_layer(C);
+ if (scene->camera != OBACT_NEW(sl)) {
+ return false;
+ }
+ }
+
if (rv3d->persp == RV3D_CAMOB) {
if (scene->r.mode & R_BORDER) {
return true;
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_empty.c b/source/blender/editors/space_view3d/view3d_manipulator_empty.c
new file mode 100644
index 00000000000..146f15b0691
--- /dev/null
+++ b/source/blender/editors/space_view3d/view3d_manipulator_empty.c
@@ -0,0 +1,211 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_view3d/view3d_manipulator_empty.c
+ * \ingroup spview3d
+ */
+
+
+#include "BLI_blenlib.h"
+#include "BLI_math.h"
+#include "BLI_utildefines.h"
+
+#include "BKE_context.h"
+#include "BKE_object.h"
+#include "BKE_image.h"
+
+#include "DNA_object_types.h"
+#include "DNA_lamp_types.h"
+
+#include "ED_screen.h"
+#include "ED_manipulator_library.h"
+
+#include "UI_resources.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "RNA_access.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "view3d_intern.h" /* own include */
+
+/* -------------------------------------------------------------------- */
+
+/** \name Empty Image Manipulators
+ * \{ */
+
+struct EmptyImageWidgetGroup {
+ wmManipulator *manipulator;
+ struct {
+ Object *ob;
+ float dims[2];
+ } state;
+};
+
+/* translate callbacks */
+static void manipulator_empty_image_prop_size_get(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ float *value = value_p;
+ struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
+ const Object *ob = imgroup->state.ob;
+ value[0] = ob->empty_drawsize;
+ value[1] = ob->empty_drawsize;
+}
+
+static void manipulator_empty_image_prop_size_set(
+ const wmManipulator *UNUSED(mpr), wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ const float *value = value_p;
+ BLI_assert(mpr_prop->type->array_length == 2);
+ struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
+ Object *ob = imgroup->state.ob;
+ ob->empty_drawsize = value[0];
+}
+
+/* translate callbacks */
+static void manipulator_empty_image_prop_offset_get(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ void *value_p)
+{
+ float *value = value_p;
+ BLI_assert(mpr_prop->type->array_length == 2);
+ const struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
+ const Object *ob = imgroup->state.ob;
+
+ float dims[2] = {0.0f, 0.0f};
+ RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ dims[0] *= ob->empty_drawsize;
+ dims[1] *= ob->empty_drawsize;
+
+ value[0] = (ob->ima_ofs[0] * dims[0]) + (0.5f * dims[0]);
+ value[1] = (ob->ima_ofs[1] * dims[1]) + (0.5f * dims[1]);
+}
+
+static void manipulator_empty_image_prop_offset_set(
+ const wmManipulator *mpr, wmManipulatorProperty *mpr_prop,
+ const void *value_p)
+{
+ const float *value = value_p;
+ BLI_assert(mpr_prop->type->array_length == 2);
+ struct EmptyImageWidgetGroup *imgroup = mpr_prop->custom_func.user_data;
+ Object *ob = imgroup->state.ob;
+
+ float dims[2];
+ RNA_float_get_array(mpr->ptr, "dimensions", dims);
+ dims[0] *= ob->empty_drawsize;
+ dims[1] *= ob->empty_drawsize;
+
+ ob->ima_ofs[0] = (value[0] - (0.5f * dims[0])) / dims[0];
+ ob->ima_ofs[1] = (value[1] - (0.5f * dims[1])) / dims[1];
+}
+
+static bool WIDGETGROUP_empty_image_poll(const bContext *C, wmManipulatorGroupType *UNUSED(wgt))
+{
+ Object *ob = CTX_data_active_object(C);
+
+ if (ob && ob->type == OB_EMPTY) {
+ return (ob->empty_drawtype == OB_EMPTY_IMAGE);
+ }
+ return false;
+}
+
+static void WIDGETGROUP_empty_image_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
+{
+ struct EmptyImageWidgetGroup *imgroup = MEM_mallocN(sizeof(struct EmptyImageWidgetGroup), __func__);
+ imgroup->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL);
+ wmManipulator *mpr = imgroup->manipulator;
+ RNA_enum_set(mpr->ptr, "transform",
+ ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE);
+
+ mgroup->customdata = imgroup;
+
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_HOVER, true);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
+}
+
+static void WIDGETGROUP_empty_image_refresh(const bContext *C, wmManipulatorGroup *mgroup)
+{
+ struct EmptyImageWidgetGroup *imgroup = mgroup->customdata;
+ Object *ob = CTX_data_active_object(C);
+ wmManipulator *mpr = imgroup->manipulator;
+
+ copy_m4_m4(mpr->matrix_basis, ob->obmat);
+
+ RNA_enum_set(mpr->ptr, "transform",
+ ED_MANIPULATOR_RECT_TRANSFORM_FLAG_TRANSLATE |
+ ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE |
+ ED_MANIPULATOR_RECT_TRANSFORM_FLAG_SCALE_UNIFORM);
+
+ imgroup->state.ob = ob;
+
+ /* Use dimensions for aspect. */
+ if (ob->data != NULL) {
+ ImageUser iuser = *ob->iuser;
+ int w, h;
+ BKE_image_get_size(ob->data, &iuser, &w, &h);
+ const float dims_max = max_ff(w, h);
+ imgroup->state.dims[0] = (float)w / dims_max;
+ imgroup->state.dims[1] = (float)h / dims_max;
+ }
+ else {
+ copy_v2_fl(imgroup->state.dims, 1.0f);
+ }
+ RNA_float_set_array(mpr->ptr, "dimensions", imgroup->state.dims);
+
+ WM_manipulator_target_property_def_func(
+ mpr, "scale",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_empty_image_prop_size_get,
+ .value_set_fn = manipulator_empty_image_prop_size_set,
+ .range_get_fn = NULL,
+ .user_data = imgroup,
+ });
+ WM_manipulator_target_property_def_func(
+ mpr, "offset",
+ &(const struct wmManipulatorPropertyFnParams) {
+ .value_get_fn = manipulator_empty_image_prop_offset_get,
+ .value_set_fn = manipulator_empty_image_prop_offset_set,
+ .range_get_fn = NULL,
+ .user_data = imgroup,
+ });
+}
+
+void VIEW3D_WGT_empty_image(wmManipulatorGroupType *wgt)
+{
+ wgt->name = "Area Lamp Widgets";
+ wgt->idname = "VIEW3D_WGT_empty_image";
+
+ wgt->flag |= (WM_MANIPULATORGROUPTYPE_PERSISTENT |
+ WM_MANIPULATORGROUPTYPE_3D |
+ WM_MANIPULATORGROUPTYPE_DEPTH_3D);
+
+ wgt->poll = WIDGETGROUP_empty_image_poll;
+ wgt->setup = WIDGETGROUP_empty_image_setup;
+ wgt->refresh = WIDGETGROUP_empty_image_refresh;
+}
+
+/** \} */
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
index e3bfd0ac300..6a34f493caf 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_forcefield.c
@@ -36,6 +36,8 @@
#include "ED_screen.h"
#include "ED_manipulator_library.h"
+#include "UI_resources.h"
+
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
@@ -59,9 +61,6 @@ static bool WIDGETGROUP_forcefield_poll(const bContext *C, wmManipulatorGroupTyp
static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
{
- const float col[4] = {0.8f, 0.8f, 0.45f, 0.5f};
- const float col_hi[4] = {0.8f, 0.8f, 0.45f, 1.0f};
-
/* only wind effector for now */
wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
mgroup->customdata = wwrapper;
@@ -71,8 +70,9 @@ static void WIDGETGROUP_forcefield_setup(const bContext *UNUSED(C), wmManipulato
RNA_enum_set(mpr->ptr, "draw_options", ED_MANIPULATOR_ARROW_STYLE_CONSTRAINED);
ED_manipulator_arrow3d_set_ui_range(mpr, -200.0f, 200.0f);
ED_manipulator_arrow3d_set_range_fac(mpr, 6.0f);
- WM_manipulator_set_color(mpr, col);
- WM_manipulator_set_color_highlight(mpr, col_hi);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
}
static void WIDGETGROUP_forcefield_refresh(const bContext *C, wmManipulatorGroup *mgroup)
diff --git a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
index 4b550fd0b2e..9454ff1e158 100644
--- a/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
+++ b/source/blender/editors/space_view3d/view3d_manipulator_lamp.c
@@ -36,6 +36,8 @@
#include "ED_screen.h"
#include "ED_manipulator_library.h"
+#include "UI_resources.h"
+
#include "MEM_guardedalloc.h"
#include "RNA_access.h"
@@ -63,9 +65,6 @@ static bool WIDGETGROUP_lamp_spot_poll(const bContext *C, wmManipulatorGroupType
static void WIDGETGROUP_lamp_spot_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
{
- const float color[4] = {0.5f, 0.5f, 1.0f, 1.0f};
- const float color_hi[4] = {0.8f, 0.8f, 0.45f, 1.0f};
-
wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_arrow_3d", mgroup, NULL);
@@ -75,8 +74,8 @@ static void WIDGETGROUP_lamp_spot_setup(const bContext *UNUSED(C), wmManipulator
mgroup->customdata = wwrapper;
ED_manipulator_arrow3d_set_range_fac(mpr, 4.0f);
- WM_manipulator_set_color(mpr, color);
- WM_manipulator_set_color_highlight(mpr, color_hi);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_SECONDARY, mpr->color);
}
static void WIDGETGROUP_lamp_spot_refresh(const bContext *C, wmManipulatorGroup *mgroup)
@@ -172,9 +171,6 @@ static bool WIDGETGROUP_lamp_area_poll(const bContext *C, wmManipulatorGroupType
static void WIDGETGROUP_lamp_area_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
{
- const float color[4] = {1.0f, 1.0f, 0.5f, 1.0f};
- const float color_hi[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-
wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_cage_2d", mgroup, NULL);
wmManipulator *mpr = wwrapper->manipulator;
@@ -184,8 +180,9 @@ static void WIDGETGROUP_lamp_area_setup(const bContext *UNUSED(C), wmManipulator
mgroup->customdata = wwrapper;
WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_HOVER, true);
- WM_manipulator_set_color(mpr, color);
- WM_manipulator_set_color_highlight(mpr, color_hi);
+
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
}
static void WIDGETGROUP_lamp_area_refresh(const bContext *C, wmManipulatorGroup *mgroup)
@@ -243,30 +240,33 @@ static bool WIDGETGROUP_lamp_target_poll(const bContext *C, wmManipulatorGroupTy
Lamp *la = ob->data;
return (ELEM(la->type, LA_SUN, LA_SPOT, LA_HEMI, LA_AREA));
}
+#if 0
else if (ob->type == OB_CAMERA) {
return true;
}
+#endif
}
return false;
}
static void WIDGETGROUP_lamp_target_setup(const bContext *UNUSED(C), wmManipulatorGroup *mgroup)
{
- const float color[4] = {1.0f, 1.0f, 0.5f, 1.0f};
- const float color_hi[4] = {1.0f, 1.0f, 1.0f, 1.0f};
-
wmManipulatorWrapper *wwrapper = MEM_mallocN(sizeof(wmManipulatorWrapper), __func__);
wwrapper->manipulator = WM_manipulator_new("MANIPULATOR_WT_grab_3d", mgroup, NULL);
wmManipulator *mpr = wwrapper->manipulator;
mgroup->customdata = wwrapper;
- WM_manipulator_set_color(mpr, color);
- WM_manipulator_set_color_highlight(mpr, color_hi);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_PRIMARY, mpr->color);
+ UI_GetThemeColor3fv(TH_MANIPULATOR_HI, mpr->color_hi);
- mpr->scale_basis = 0.05f;
+ mpr->scale_basis = 0.06f;
wmOperatorType *ot = WM_operatortype_find("OBJECT_OT_transform_axis_target", true);
+
+ RNA_enum_set(mpr->ptr, "draw_options",
+ ED_MANIPULATOR_GRAB_DRAW_FLAG_FILL | ED_MANIPULATOR_GRAB_DRAW_FLAG_ALIGN_VIEW);
+
WM_manipulator_set_operator(mpr, ot, NULL);
}
@@ -279,6 +279,7 @@ static void WIDGETGROUP_lamp_target_draw_prepare(const bContext *C, wmManipulato
copy_m4_m4(mpr->matrix_basis, ob->obmat);
unit_m4(mpr->matrix_offset);
mpr->matrix_offset[3][2] = -2.4f / mpr->scale_basis;
+ WM_manipulator_set_flag(mpr, WM_MANIPULATOR_DRAW_OFFSET_SCALE, true);
}
void VIEW3D_WGT_lamp_target(wmManipulatorGroupType *wgt)
diff --git a/source/blender/editors/space_view3d/view3d_ruler.c b/source/blender/editors/space_view3d/view3d_ruler.c
index acf8ed29c6b..9aaa766be74 100644
--- a/source/blender/editors/space_view3d/view3d_ruler.c
+++ b/source/blender/editors/space_view3d/view3d_ruler.c
@@ -51,7 +51,6 @@
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "ED_transform.h"
#include "ED_transform_snap_object_context.h"
#include "ED_space_api.h"
@@ -738,7 +737,7 @@ static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3],
/* use for mousemove events */
static bool view3d_ruler_item_mousemove(
- const bContext *C, RulerInfo *ruler_info, const int mval[2],
+ RulerInfo *ruler_info, const int mval[2],
const bool do_thickness, const bool do_snap)
{
const float eps_bias = 0.0002f;
@@ -763,7 +762,7 @@ static bool view3d_ruler_item_mousemove(
co_other = ruler_item->co[ruler_item->co_index == 0 ? 2 : 0];
if (ED_transform_snap_object_project_view3d_mixed(
- C, ruler_info->snap_context,
+ ruler_info->snap_context,
SCE_SELECT_FACE,
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
@@ -776,7 +775,7 @@ static bool view3d_ruler_item_mousemove(
/* add some bias */
madd_v3_v3v3fl(ray_start, co, ray_normal, eps_bias);
ED_transform_snap_object_project_ray(
- C, ruler_info->snap_context,
+ ruler_info->snap_context,
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
.use_object_edit_cage = true,
@@ -792,7 +791,7 @@ static bool view3d_ruler_item_mousemove(
bool use_depth = (v3d->drawtype >= OB_SOLID);
if (ED_transform_snap_object_project_view3d_mixed(
- C, ruler_info->snap_context,
+ ruler_info->snap_context,
(SCE_SELECT_VERTEX | SCE_SELECT_EDGE) | (use_depth ? SCE_SELECT_FACE : 0),
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
@@ -924,7 +923,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (use_depth) {
/* snap the first point added, not essential but handy */
ruler_item->co_index = 0;
- view3d_ruler_item_mousemove(C, ruler_info, event->mval, false, true);
+ view3d_ruler_item_mousemove(ruler_info, event->mval, false, true);
copy_v3_v3(ruler_info->drag_start_co, ruler_item->co[ruler_item->co_index]);
}
else {
@@ -977,7 +976,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
/* update the new location */
- view3d_ruler_item_mousemove(C, ruler_info, event->mval,
+ view3d_ruler_item_mousemove(ruler_info, event->mval,
event->shift != 0, event->ctrl != 0);
do_draw = true;
}
@@ -1026,7 +1025,7 @@ static int view3d_ruler_modal(bContext *C, wmOperator *op, const wmEvent *event)
case MOUSEMOVE:
{
if (ruler_info->state == RULER_STATE_DRAG) {
- if (view3d_ruler_item_mousemove(C, ruler_info, event->mval,
+ if (view3d_ruler_item_mousemove(ruler_info, event->mval,
event->shift != 0, event->ctrl != 0))
{
do_draw = true;
diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c
index 2534fdfd6f0..2fa32c44fc7 100644
--- a/source/blender/editors/space_view3d/view3d_select.c
+++ b/source/blender/editors/space_view3d/view3d_select.c
@@ -458,7 +458,9 @@ static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, cons
}
}
-static void do_lasso_select_mesh(const bContext *C, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
+static void do_lasso_select_mesh(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc,
+ const int mcords[][2], short moves, bool extend, bool select)
{
LassoSelectUserData data;
ToolSettings *ts = vc->scene->toolsettings;
@@ -479,24 +481,24 @@ static void do_lasso_select_mesh(const bContext *C, ViewContext *vc, const int m
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
gpuLoadMatrix(vc->rv3d->viewmat);
- bbsel = EDBM_backbuf_border_mask_init(C, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ bbsel = EDBM_backbuf_border_mask_init(eval_ctx, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
if (ts->selectmode & SCE_SELECT_VERTEX) {
if (bbsel) {
edbm_backbuf_check_and_select_verts(vc->em, select);
}
else {
- mesh_foreachScreenVert(C, vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenVert(eval_ctx, vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
if (ts->selectmode & SCE_SELECT_EDGE) {
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(C, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == false) {
data.pass = 1;
- mesh_foreachScreenEdge(C, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -505,7 +507,7 @@ static void do_lasso_select_mesh(const bContext *C, ViewContext *vc, const int m
edbm_backbuf_check_and_select_faces(vc->em, select);
}
else {
- mesh_foreachScreenFace(C, vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenFace(eval_ctx, vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -704,7 +706,7 @@ static void do_lasso_select_meshobject__doSelectVert(void *userData, MVert *mv,
BKE_BIT_TEST_SET(mv->flag, data->select, SELECT);
}
}
-static void do_lasso_select_paintvert(const bContext *C, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
+static void do_lasso_select_paintvert(const struct EvaluationContext *eval_ctx, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
{
const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0;
Object *ob = vc->obact;
@@ -722,7 +724,7 @@ static void do_lasso_select_paintvert(const bContext *C, ViewContext *vc, const
if (use_zbuf) {
bm_vertoffs = me->totvert + 1; /* max index array */
- EDBM_backbuf_border_mask_init(C, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ EDBM_backbuf_border_mask_init(eval_ctx, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
edbm_backbuf_check_and_select_verts_obmode(me, select);
@@ -735,7 +737,7 @@ static void do_lasso_select_paintvert(const bContext *C, ViewContext *vc, const
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
- meshobject_foreachScreenVert(C, vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ meshobject_foreachScreenVert(eval_ctx, vc, do_lasso_select_meshobject__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
@@ -744,7 +746,7 @@ static void do_lasso_select_paintvert(const bContext *C, ViewContext *vc, const
}
paintvert_flush_flags(ob);
}
-static void do_lasso_select_paintface(const bContext *C, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
+static void do_lasso_select_paintface(const struct EvaluationContext *eval_ctx, ViewContext *vc, const int mcords[][2], short moves, bool extend, bool select)
{
Object *ob = vc->obact;
Mesh *me = ob->data;
@@ -759,7 +761,7 @@ static void do_lasso_select_paintface(const bContext *C, ViewContext *vc, const
bm_vertoffs = me->totpoly + 1; /* max index array */
BLI_lasso_boundbox(&rect, mcords, moves);
- EDBM_backbuf_border_mask_init(C, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
+ EDBM_backbuf_border_mask_init(eval_ctx, vc, mcords, moves, rect.xmin, rect.ymin, rect.xmax, rect.ymax);
edbm_backbuf_check_and_select_tfaces(me, select);
@@ -805,18 +807,25 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc,
{
Object *ob = CTX_data_active_object(C);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
if (vc->obedit == NULL) { /* Object Mode */
- if (BKE_paint_select_face_test(ob))
- do_lasso_select_paintface(C, vc, mcords, moves, extend, select);
- else if (BKE_paint_select_vert_test(ob))
- do_lasso_select_paintvert(C, vc, mcords, moves, extend, select);
+ if (BKE_paint_select_face_test(ob)) {
+ do_lasso_select_paintface(&eval_ctx, vc, mcords, moves, extend, select);
+ }
+ else if (BKE_paint_select_vert_test(ob)) {
+ do_lasso_select_paintvert(&eval_ctx, vc, mcords, moves, extend, select);
+ }
else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) {
/* pass */
}
- else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT))
+ else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) {
PE_lasso_select(C, mcords, moves, extend, select);
- else if (ob && (ob->mode & OB_MODE_HAIR_EDIT))
+ }
+ else if (ob && (ob->mode & OB_MODE_HAIR_EDIT)) {
ED_hair_lasso_select(C, mcords, moves, extend, select);
+ }
else {
do_lasso_select_objects(vc, mcords, moves, extend, select);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, vc->scene);
@@ -825,7 +834,7 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc,
else { /* Edit Mode */
switch (vc->obedit->type) {
case OB_MESH:
- do_lasso_select_mesh(C, vc, mcords, moves, extend, select);
+ do_lasso_select_mesh(&eval_ctx, vc, mcords, moves, extend, select);
break;
case OB_CURVE:
case OB_SURF:
@@ -1180,7 +1189,7 @@ static int selectbuffer_ret_hits_5(unsigned int *buffer, const int hits15, const
/* we want a select buffer with bones, if there are... */
/* so check three selection levels and compare */
static int mixed_bones_object_selectbuffer(
- const bContext *C, ViewContext *vc, unsigned int *buffer, const int mval[2],
+ const EvaluationContext *eval_ctx, ViewContext *vc, unsigned int *buffer, const int mval[2],
bool use_cycle, bool enumerate,
bool *r_do_nearest)
{
@@ -1220,7 +1229,7 @@ static int mixed_bones_object_selectbuffer(
view3d_opengl_select_cache_begin();
BLI_rcti_init_pt_radius(&rect, mval, 14);
- hits15 = view3d_opengl_select(C, vc, buffer, MAXPICKBUF, &rect, select_mode);
+ hits15 = view3d_opengl_select(eval_ctx, vc, buffer, MAXPICKBUF, &rect, select_mode);
if (hits15 == 1) {
hits = selectbuffer_ret_hits_15(buffer, hits15);
goto finally;
@@ -1231,7 +1240,7 @@ static int mixed_bones_object_selectbuffer(
offs = 4 * hits15;
BLI_rcti_init_pt_radius(&rect, mval, 9);
- hits9 = view3d_opengl_select(C, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
+ hits9 = view3d_opengl_select(eval_ctx, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
if (hits9 == 1) {
hits = selectbuffer_ret_hits_9(buffer, hits15, hits9);
goto finally;
@@ -1241,7 +1250,7 @@ static int mixed_bones_object_selectbuffer(
offs += 4 * hits9;
BLI_rcti_init_pt_radius(&rect, mval, 5);
- hits5 = view3d_opengl_select(C, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
+ hits5 = view3d_opengl_select(eval_ctx, vc, buffer + offs, MAXPICKBUF - offs, &rect, select_mode);
if (hits5 == 1) {
hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5);
goto finally;
@@ -1290,8 +1299,8 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
}
else {
/* only exclude active object when it is selected... */
- if (BASACT_NEW && (BASACT_NEW->flag & BASE_SELECTED) && hits > 1) {
- notcol = BASACT_NEW->object->select_color;
+ if (BASACT_NEW(sl) && (BASACT_NEW(sl)->flag & BASE_SELECTED) && hits > 1) {
+ notcol = BASACT_NEW(sl)->object->select_color;
}
for (a = 0; a < hits; a++) {
@@ -1302,7 +1311,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
}
}
- base = FIRSTBASE_NEW;
+ base = FIRSTBASE_NEW(sl);
while (base) {
if (BASE_SELECTABLE_NEW(base)) {
if (base->object->select_color == selcol) break;
@@ -1319,7 +1328,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
* with an un-selectable choice */
if ((base->flag & BASE_SELECTABLED) == 0) {
base = base->next;
- if (base == NULL) base = FIRSTBASE_NEW;
+ if (base == NULL) base = FIRSTBASE_NEW(sl);
if (base == startbase) break;
}
@@ -1342,7 +1351,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
if (basact) break;
base = base->next;
- if (base == NULL) base = FIRSTBASE_NEW;
+ if (base == NULL) base = FIRSTBASE_NEW(sl);
if (base == startbase) break;
}
}
@@ -1353,6 +1362,7 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, unsigned int *buffer, int
/* mval comes from event->mval, only use within region handlers */
Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
{
+ EvaluationContext eval_ctx;
ViewContext vc;
Base *basact = NULL;
unsigned int buffer[MAXPICKBUF];
@@ -1361,9 +1371,11 @@ Base *ED_view3d_give_base_under_cursor(bContext *C, const int mval[2])
/* setup view context for argument to callbacks */
view3d_operator_needs_opengl(C);
+
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
- hits = mixed_bones_object_selectbuffer(C, &vc, buffer, mval, false, false, &do_nearest);
+ hits = mixed_bones_object_selectbuffer(&eval_ctx, &vc, buffer, mval, false, false, &do_nearest);
if (hits > 0) {
const bool has_bones = selectbuffer_has_bones(buffer, hits);
@@ -1397,6 +1409,7 @@ static bool ed_object_select_pick(
bContext *C, const int mval[2],
bool extend, bool deselect, bool toggle, bool obcenter, bool enumerate, bool object)
{
+ EvaluationContext eval_ctx;
ViewContext vc;
ARegion *ar = CTX_wm_region(C);
Scene *scene = CTX_data_scene(C);
@@ -1410,6 +1423,7 @@ static bool ed_object_select_pick(
/* setup view context for argument to callbacks */
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
is_obedit = (vc.obedit != NULL);
@@ -1419,8 +1433,8 @@ static bool ed_object_select_pick(
}
/* always start list from basact in wire mode */
- startbase = FIRSTBASE_NEW;
- if (BASACT_NEW && BASACT_NEW->next) startbase = BASACT_NEW->next;
+ startbase = FIRSTBASE_NEW(sl);
+ if (BASACT_NEW(sl) && BASACT_NEW(sl)->next) startbase = BASACT_NEW(sl)->next;
/* This block uses the control key to make the object selected by its center point rather than its contents */
/* in editmode do not activate */
@@ -1439,7 +1453,7 @@ static bool ed_object_select_pick(
V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN | V3D_PROJ_TEST_CLIP_NEAR) == V3D_PROJ_RET_OK)
{
float dist_temp = len_manhattan_v2v2(mval_fl, screen_co);
- if (base == BASACT_NEW) dist_temp += 10.0f;
+ if (base == BASACT_NEW(sl)) dist_temp += 10.0f;
if (dist_temp < dist) {
dist = dist_temp;
basact = base;
@@ -1448,7 +1462,7 @@ static bool ed_object_select_pick(
}
base = base->next;
- if (base == NULL) base = FIRSTBASE_NEW;
+ if (base == NULL) base = FIRSTBASE_NEW(sl);
if (base == startbase) break;
}
}
@@ -1460,7 +1474,7 @@ static bool ed_object_select_pick(
// TIMEIT_START(select_time);
/* if objects have posemode set, the bones are in the same selection buffer */
- hits = mixed_bones_object_selectbuffer(C, &vc, buffer, mval, true, enumerate, &do_nearest);
+ hits = mixed_bones_object_selectbuffer(&eval_ctx, &vc, buffer, mval, true, enumerate, &do_nearest);
// TIMEIT_END(select_time);
@@ -1478,7 +1492,7 @@ static bool ed_object_select_pick(
if (has_bones && basact) {
if (basact->object->type == OB_CAMERA) {
- if (BASACT_NEW == basact) {
+ if (BASACT_NEW(sl) == basact) {
int i, hitresult;
bool changed = false;
@@ -1548,14 +1562,14 @@ static bool ed_object_select_pick(
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_ACTIVE, basact->object);
/* in weightpaint, we use selected bone to select vertexgroup, so no switch to new active object */
- if (BASACT_NEW && (BASACT_NEW->object->mode & OB_MODE_WEIGHT_PAINT)) {
+ if (BASACT_NEW(sl) && (BASACT_NEW(sl)->object->mode & OB_MODE_WEIGHT_PAINT)) {
/* prevent activating */
basact = NULL;
}
}
/* prevent bone selecting to pass on to object selecting */
- if (basact == BASACT_NEW)
+ if (basact == BASACT_NEW(sl))
basact = NULL;
}
}
@@ -1573,7 +1587,7 @@ static bool ed_object_select_pick(
/* also prevent making it active on mouse selection */
else if (BASE_SELECTABLE_NEW(basact)) {
- oldbasact = BASACT_NEW;
+ oldbasact = BASACT_NEW(sl);
if (extend) {
ED_object_base_select(basact, BA_SELECT);
@@ -1653,7 +1667,8 @@ static void do_paintvert_box_select__doSelectVert(void *userData, MVert *mv, con
BKE_BIT_TEST_SET(mv->flag, data->select, SELECT);
}
}
-static int do_paintvert_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend)
+static int do_paintvert_box_select(
+ const EvaluationContext *eval_ctx, ViewContext *vc, rcti *rect, bool select, bool extend)
{
const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0;
Mesh *me;
@@ -1677,7 +1692,7 @@ static int do_paintvert_box_select(const bContext *C, ViewContext *vc, rcti *rec
if (use_zbuf) {
selar = MEM_callocN(me->totvert + 1, "selar");
- ED_view3d_backbuf_validate(C, vc);
+ ED_view3d_backbuf_validate(eval_ctx, vc);
ibuf = IMB_allocImBuf(size[0], size[1], 32, IB_rect);
rt = ibuf->rect;
@@ -1725,7 +1740,7 @@ static int do_paintvert_box_select(const bContext *C, ViewContext *vc, rcti *rec
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d);
- meshobject_foreachScreenVert(C, vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ meshobject_foreachScreenVert(eval_ctx, vc, do_paintvert_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
if (select == false) {
@@ -1840,7 +1855,8 @@ static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, const
BM_face_select_set(data->vc->em->bm, efa, data->select);
}
}
-static int do_mesh_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend)
+static int do_mesh_box_select(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, rcti *rect, bool select, bool extend)
{
BoxSelectUserData data;
ToolSettings *ts = vc->scene->toolsettings;
@@ -1855,25 +1871,25 @@ static int do_mesh_box_select(const bContext *C, ViewContext *vc, rcti *rect, bo
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d);
gpuLoadMatrix(vc->rv3d->viewmat);
- bbsel = EDBM_backbuf_border_init(C, vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
+ bbsel = EDBM_backbuf_border_init(eval_ctx, vc, rect->xmin, rect->ymin, rect->xmax, rect->ymax);
if (ts->selectmode & SCE_SELECT_VERTEX) {
if (bbsel) {
edbm_backbuf_check_and_select_verts(vc->em, select);
}
else {
- mesh_foreachScreenVert(C, vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenVert(eval_ctx, vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
if (ts->selectmode & SCE_SELECT_EDGE) {
/* Does both bbsel and non-bbsel versions (need screen cos for both) */
data.pass = 0;
- mesh_foreachScreenEdge(C, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
if (data.is_done == 0) {
data.pass = 1;
- mesh_foreachScreenEdge(C, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -1882,7 +1898,7 @@ static int do_mesh_box_select(const bContext *C, ViewContext *vc, rcti *rect, bo
edbm_backbuf_check_and_select_faces(vc->em, select);
}
else {
- mesh_foreachScreenFace(C, vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenFace(eval_ctx, vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -1893,7 +1909,9 @@ static int do_mesh_box_select(const bContext *C, ViewContext *vc, rcti *rect, bo
return OPERATOR_FINISHED;
}
-static int do_meta_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend)
+static int do_meta_box_select(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc,
+ const rcti *rect, bool select, bool extend)
{
MetaBall *mb = (MetaBall *)vc->obedit->data;
MetaElem *ml;
@@ -1902,7 +1920,7 @@ static int do_meta_box_select(const bContext *C, ViewContext *vc, rcti *rect, bo
unsigned int buffer[MAXPICKBUF];
int hits;
- hits = view3d_opengl_select(C, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
+ hits = view3d_opengl_select(eval_ctx, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
if (extend == false && select)
BKE_mball_deselect_all(mb);
@@ -1927,7 +1945,9 @@ static int do_meta_box_select(const bContext *C, ViewContext *vc, rcti *rect, bo
return OPERATOR_FINISHED;
}
-static int do_armature_box_select(const bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend)
+static int do_armature_box_select(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc,
+ const rcti *rect, bool select, bool extend)
{
bArmature *arm = vc->obedit->data;
EditBone *ebone;
@@ -1936,7 +1956,7 @@ static int do_armature_box_select(const bContext *C, ViewContext *vc, rcti *rect
unsigned int buffer[MAXPICKBUF];
int hits;
- hits = view3d_opengl_select(C, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
+ hits = view3d_opengl_select(eval_ctx, vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL);
/* clear flag we use to detect point was affected */
for (ebone = arm->edbo->first; ebone; ebone = ebone->next)
@@ -2023,6 +2043,7 @@ static int opengl_select_buffer_cmp(const void *sel_a_p, const void *sel_b_p)
static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, bool select, bool extend)
{
+ EvaluationContext eval_ctx;
Bone *bone;
Object *ob = vc->obact;
unsigned int *vbuffer = NULL; /* selection buffer */
@@ -2032,6 +2053,8 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
int totobj = MAXPICKBUF; /* XXX solve later */
int hits;
+ CTX_data_eval_ctx(C, &eval_ctx);
+
if ((ob) && (ob->mode & OB_MODE_POSE))
bone_only = 1;
else
@@ -2054,7 +2077,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
/* selection buffer now has bones potentially too, so we add MAXPICKBUF */
vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(unsigned int), "selection buffer");
- hits = view3d_opengl_select(C, vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL);
+ hits = view3d_opengl_select(&eval_ctx, vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL);
/*
* LOGIC NOTES (theeth):
* The buffer and ListBase have the same relative order, which makes the selection
@@ -2128,6 +2151,7 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, b
static int view3d_borderselect_exec(bContext *C, wmOperator *op)
{
+ EvaluationContext eval_ctx;
ViewContext vc;
rcti rect;
bool extend;
@@ -2138,6 +2162,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
view3d_operator_needs_opengl(C);
/* setup view context for argument to callbacks */
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
select = (RNA_int_get(op->ptr, "gesture_mode") == GESTURE_MODAL_SELECT);
@@ -2148,7 +2173,7 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
switch (vc.obedit->type) {
case OB_MESH:
vc.em = BKE_editmesh_from_object(vc.obedit);
- ret = do_mesh_box_select(C, &vc, &rect, select, extend);
+ ret = do_mesh_box_select(&eval_ctx, &vc, &rect, select, extend);
// if (EM_texFaceCheck())
if (ret & OPERATOR_FINISHED) {
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
@@ -2162,13 +2187,13 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
}
break;
case OB_MBALL:
- ret = do_meta_box_select(C, &vc, &rect, select, extend);
+ ret = do_meta_box_select(&eval_ctx, &vc, &rect, select, extend);
if (ret & OPERATOR_FINISHED) {
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, vc.obedit->data);
}
break;
case OB_ARMATURE:
- ret = do_armature_box_select(C, &vc, &rect, select, extend);
+ ret = do_armature_box_select(&eval_ctx, &vc, &rect, select, extend);
if (ret & OPERATOR_FINISHED) {
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, vc.obedit);
}
@@ -2189,10 +2214,10 @@ static int view3d_borderselect_exec(bContext *C, wmOperator *op)
ret = ED_sculpt_mask_box_select(C, &vc, &rect, select, extend);
}
else if (vc.obact && BKE_paint_select_face_test(vc.obact)) {
- ret = do_paintface_box_select(C, &vc, &rect, select, extend);
+ ret = do_paintface_box_select(&eval_ctx, &vc, &rect, select, extend);
}
else if (vc.obact && BKE_paint_select_vert_test(vc.obact)) {
- ret = do_paintvert_box_select(C, &vc, &rect, select, extend);
+ ret = do_paintvert_box_select(&eval_ctx, &vc, &rect, select, extend);
}
else if (vc.obact && vc.obact->mode & OB_MODE_PARTICLE_EDIT) {
ret = PE_border_select(C, &rect, select, extend);
@@ -2441,13 +2466,13 @@ static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float sc
}
}
-static void mesh_circle_select(const bContext *C, ViewContext *vc, const bool select, const int mval[2], float rad)
+static void mesh_circle_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad)
{
ToolSettings *ts = vc->scene->toolsettings;
int bbsel;
CircleSelectUserData data;
- bbsel = EDBM_backbuf_circle_init(C, vc, mval[0], mval[1], (short)(rad + 1.0f));
+ bbsel = EDBM_backbuf_circle_init(eval_ctx, vc, mval[0], mval[1], (short)(rad + 1.0f));
ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */
vc->em = BKE_editmesh_from_object(vc->obedit);
@@ -2459,7 +2484,7 @@ static void mesh_circle_select(const bContext *C, ViewContext *vc, const bool se
edbm_backbuf_check_and_select_verts(vc->em, select);
}
else {
- mesh_foreachScreenVert(C, vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenVert(eval_ctx, vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -2468,7 +2493,7 @@ static void mesh_circle_select(const bContext *C, ViewContext *vc, const bool se
edbm_backbuf_check_and_select_edges(vc->em, select);
}
else {
- mesh_foreachScreenEdge(C, vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
+ mesh_foreachScreenEdge(eval_ctx, vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_CLIP_NEAR);
}
}
@@ -2477,7 +2502,7 @@ static void mesh_circle_select(const bContext *C, ViewContext *vc, const bool se
edbm_backbuf_check_and_select_faces(vc->em, select);
}
else {
- mesh_foreachScreenFace(C, vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ mesh_foreachScreenFace(eval_ctx, vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
}
@@ -2485,7 +2510,7 @@ static void mesh_circle_select(const bContext *C, ViewContext *vc, const bool se
EDBM_selectmode_flush(vc->em);
}
-static void paint_facesel_circle_select(const bContext *C, ViewContext *vc, const bool select, const int mval[2], float rad)
+static void paint_facesel_circle_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad)
{
Object *ob = vc->obact;
Mesh *me = ob->data;
@@ -2493,7 +2518,7 @@ static void paint_facesel_circle_select(const bContext *C, ViewContext *vc, cons
bm_vertoffs = me->totpoly + 1; /* max index array */
- bbsel = EDBM_backbuf_circle_init(C, vc, mval[0], mval[1], (short)(rad + 1.0f));
+ bbsel = EDBM_backbuf_circle_init(eval_ctx, vc, mval[0], mval[1], (short)(rad + 1.0f));
if (bbsel) {
edbm_backbuf_check_and_select_tfaces(me, select);
EDBM_backbuf_free();
@@ -2509,7 +2534,7 @@ static void paint_vertsel_circle_select_doSelectVert(void *userData, MVert *mv,
BKE_BIT_TEST_SET(mv->flag, data->select, SELECT);
}
}
-static void paint_vertsel_circle_select(const bContext *C, ViewContext *vc, const bool select, const int mval[2], float rad)
+static void paint_vertsel_circle_select(const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad)
{
const bool use_zbuf = (vc->v3d->flag & V3D_ZBUF_SELECT) != 0;
Object *ob = vc->obact;
@@ -2520,7 +2545,7 @@ static void paint_vertsel_circle_select(const bContext *C, ViewContext *vc, cons
if (use_zbuf) {
bm_vertoffs = me->totvert + 1; /* max index array */
- bbsel = EDBM_backbuf_circle_init(C, vc, mval[0], mval[1], (short)(rad + 1.0f));
+ bbsel = EDBM_backbuf_circle_init(eval_ctx, vc, mval[0], mval[1], (short)(rad + 1.0f));
if (bbsel) {
edbm_backbuf_check_and_select_verts_obmode(me, select);
EDBM_backbuf_free();
@@ -2532,7 +2557,7 @@ static void paint_vertsel_circle_select(const bContext *C, ViewContext *vc, cons
ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */
view3d_userdata_circleselect_init(&data, vc, select, mval, rad);
- meshobject_foreachScreenVert(C, vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
+ meshobject_foreachScreenVert(eval_ctx, vc, paint_vertsel_circle_select_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT);
}
if (select != LEFTMOUSE) {
@@ -2786,11 +2811,12 @@ static void mball_circle_select(ViewContext *vc, const bool select, const int mv
/** Callbacks for circle selection in Editmode */
-static void obedit_circle_select(const bContext *C, ViewContext *vc, const bool select, const int mval[2], float rad)
+static void obedit_circle_select(
+ const struct EvaluationContext *eval_ctx, ViewContext *vc, const bool select, const int mval[2], float rad)
{
switch (vc->obedit->type) {
case OB_MESH:
- mesh_circle_select(C, vc, select, mval, rad);
+ mesh_circle_select(eval_ctx, vc, select, mval, rad);
break;
case OB_CURVE:
case OB_SURF:
@@ -2820,7 +2846,7 @@ static bool object_circle_select(ViewContext *vc, const bool select, const int m
Base *base;
- for (base = FIRSTBASE_NEW; base; base = base->next) {
+ for (base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (BASE_SELECTABLE_NEW(base) && ((base->flag & BASE_SELECTED) != select_flag)) {
float screen_co[2];
if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co,
@@ -2851,22 +2877,24 @@ static int view3d_circle_select_exec(bContext *C, wmOperator *op)
if (CTX_data_edit_object(C) || BKE_paint_select_elem_test(obact) ||
(obact && (obact->mode & (OB_MODE_PARTICLE_EDIT | OB_MODE_POSE | OB_MODE_HAIR_EDIT))) )
{
+ EvaluationContext eval_ctx;
ViewContext vc;
view3d_operator_needs_opengl(C);
+ CTX_data_eval_ctx(C, &eval_ctx);
view3d_set_viewcontext(C, &vc);
if (CTX_data_edit_object(C)) {
- obedit_circle_select(C, &vc, select, mval, (float)radius);
+ obedit_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
else if (BKE_paint_select_face_test(obact)) {
- paint_facesel_circle_select(C, &vc, select, mval, (float)radius);
+ paint_facesel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
else if (BKE_paint_select_vert_test(obact)) {
- paint_vertsel_circle_select(C, &vc, select, mval, (float)radius);
+ paint_vertsel_circle_select(&eval_ctx, &vc, select, mval, (float)radius);
WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obact->data);
}
else if (obact->mode & OB_MODE_POSE) {
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index 3ffd21294df..4be03e31b0d 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -1106,7 +1106,7 @@ bool ED_view3d_lock(RegionView3D *rv3d)
}
/* don't set windows active in here, is used by renderwin too */
-void view3d_viewmatrix_set(EvaluationContext *eval_ctx, Scene *scene, const View3D *v3d, RegionView3D *rv3d)
+void view3d_viewmatrix_set(const EvaluationContext *eval_ctx, Scene *scene, const View3D *v3d, RegionView3D *rv3d)
{
if (rv3d->persp == RV3D_CAMOB) { /* obs/camera */
if (v3d->camera) {
@@ -1195,7 +1195,7 @@ void view3d_opengl_select_cache_end(void)
* \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection.
*/
int view3d_opengl_select(
- const bContext *C, ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input,
+ const EvaluationContext *eval_ctx, ViewContext *vc, unsigned int *buffer, unsigned int bufsize, const rcti *input,
eV3DSelectMode select_mode)
{
Depsgraph *graph = vc->depsgraph;
@@ -1256,7 +1256,7 @@ int view3d_opengl_select(
/* Important we use the 'viewmat' and don't re-calculate since
* the object & bone view locking takes 'rect' into account, see: T51629. */
- ED_view3d_draw_setup_view(vc->win, C, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
+ ED_view3d_draw_setup_view(vc->win, eval_ctx, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
if (v3d->drawtype > OB_WIRE) {
v3d->zbuf = true;
@@ -1300,7 +1300,7 @@ int view3d_opengl_select(
}
G.f &= ~G_PICKSEL;
- ED_view3d_draw_setup_view(vc->win, C, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
+ ED_view3d_draw_setup_view(vc->win, eval_ctx, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
if (v3d->drawtype > OB_WIRE) {
v3d->zbuf = 0;
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 4ff084129c3..44b7fadd29f 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -49,7 +49,6 @@
#include "ED_screen.h"
#include "ED_space_api.h"
-#include "ED_transform.h"
#include "ED_transform_snap_object_context.h"
#include "PIL_time.h" /* smoothview */
@@ -423,7 +422,7 @@ static void walk_navigation_mode_set(bContext *C, wmOperator *op, WalkInfo *walk
* \param r_distance Distance to the hit point
*/
static bool walk_floor_distance_get(
- const bContext *C, RegionView3D *rv3d, WalkInfo *walk, const float dvec[3],
+ RegionView3D *rv3d, WalkInfo *walk, const float dvec[3],
float *r_distance)
{
float ray_normal[3] = {0, 0, -1}; /* down */
@@ -441,7 +440,7 @@ static bool walk_floor_distance_get(
add_v3_v3(ray_start, dvec_tmp);
ret = ED_transform_snap_object_project_ray(
- C, walk->snap_context,
+ walk->snap_context,
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
},
@@ -459,7 +458,7 @@ static bool walk_floor_distance_get(
* \param r_normal Normal of the hit surface, transformed to always face the camera
*/
static bool walk_ray_cast(
- const bContext *C, RegionView3D *rv3d, WalkInfo *walk,
+ RegionView3D *rv3d, WalkInfo *walk,
float r_location[3], float r_normal[3], float *ray_distance)
{
float ray_normal[3] = {0, 0, -1}; /* forward */
@@ -475,7 +474,7 @@ static bool walk_ray_cast(
normalize_v3(ray_normal);
ret = ED_transform_snap_object_project_ray(
- C, walk->snap_context,
+ walk->snap_context,
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
},
@@ -921,7 +920,7 @@ static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent
{
float loc[3], nor[3];
float distance;
- bool ret = walk_ray_cast(C, walk->rv3d, walk, loc, nor, &distance);
+ bool ret = walk_ray_cast(walk->rv3d, walk, loc, nor, &distance);
/* in case we are teleporting middle way from a jump */
walk->speed_jump = 0.0f;
@@ -1201,7 +1200,7 @@ static int walkApply(bContext *C, wmOperator *op, WalkInfo *walk)
float difference = -100.0f;
float fall_distance;
- ret = walk_floor_distance_get(C, rv3d, walk, dvec, &ray_distance);
+ ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
if (ret) {
difference = walk->view_height - ray_distance;
@@ -1254,7 +1253,7 @@ static int walkApply(bContext *C, wmOperator *op, WalkInfo *walk)
if (t > walk->teleport.duration) {
/* check to see if we are landing */
- ret = walk_floor_distance_get(C, rv3d, walk, dvec, &ray_distance);
+ ret = walk_floor_distance_get(rv3d, walk, dvec, &ray_distance);
if (ret) {
difference = walk->view_height - ray_distance;
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index d79babde707..cb5274e7967 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1906,7 +1906,7 @@ static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, vo
TransInfo *t = arg;
Scene *scene = t->scene;
SceneLayer *sl = t->scene_layer;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
/* draw autokeyframing hint in the corner
* - only draw if enabled (advanced users may be distracted/annoyed),
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index b7dc4abc3c5..3b85c254698 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -293,7 +293,7 @@ static void createTransTexspace(TransInfo *t)
ID *id;
short *texflag;
- ob = OBACT_NEW;
+ ob = OBACT_NEW(sl);
if (ob == NULL) { // Shouldn't logically happen, but still...
t->total = 0;
@@ -2012,7 +2012,7 @@ void flushTransParticles(TransInfo *t)
{
Scene *scene = t->scene;
SceneLayer *sl = t->scene_layer;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
PTCacheEdit *edit = PE_get_current(scene, sl, ob);
ParticleSystem *psys = edit->psys;
ParticleSystemModifierData *psmd = NULL;
@@ -2052,7 +2052,9 @@ void flushTransParticles(TransInfo *t)
point->flag |= PEP_EDIT_RECALC;
}
- PE_update_object(t->context, scene, sl, OBACT_NEW, 1);
+ EvaluationContext eval_ctx;
+ CTX_data_eval_ctx(t->context, &eval_ctx);
+ PE_update_object(&eval_ctx, scene, sl, OBACT_NEW(sl), 1);
}
@@ -2102,7 +2104,7 @@ static void StrandVertsToTransData(TransInfo *t, TransData *td,
static void createTransStrandVerts(TransInfo *t)
{
SceneLayer *sl = t->scene_layer;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
BMEditStrands *edit = BKE_editstrands_from_object(ob);
BMesh *bm = edit->base.bm;
TransData *tob = NULL;
@@ -2268,7 +2270,7 @@ cleanup:
void flushTransStrands(TransInfo *t)
{
SceneLayer *sl = t->scene_layer;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
BMEditStrands *edit = BKE_editstrands_from_object(ob);
BMEditStrandsLocations origlocs = t->custom.type.data;
@@ -5977,7 +5979,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, SceneLayer *sl, View3D *
}
else if (ELEM(tmode, TFM_ROTATION, TFM_TRACKBALL)) {
if (v3d->around == V3D_AROUND_ACTIVE) {
- if (ob != OBACT_NEW)
+ if (ob != OBACT_NEW(sl))
do_loc = true;
}
else if (v3d->around == V3D_AROUND_CURSOR)
@@ -5988,7 +5990,7 @@ void autokeyframe_ob_cb_func(bContext *C, Scene *scene, SceneLayer *sl, View3D *
}
else if (tmode == TFM_RESIZE) {
if (v3d->around == V3D_AROUND_ACTIVE) {
- if (ob != OBACT_NEW)
+ if (ob != OBACT_NEW(sl))
do_loc = true;
}
else if (v3d->around == V3D_AROUND_CURSOR)
@@ -8295,7 +8297,7 @@ void createTransData(bContext *C, TransInfo *t)
{
Scene *scene = t->scene;
SceneLayer *sl = t->scene_layer;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
/* if tests must match recalcData for correct updates */
if (t->options & CTX_TEXTURE) {
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index 9c21be26732..90e12f03979 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -330,7 +330,7 @@ static void recalcData_actedit(TransInfo *t)
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
ac.scene = t->scene;
ac.scene_layer = t->scene_layer;
- ac.obact = OBACT_NEW;
+ ac.obact = OBACT_NEW(sl);
ac.sa = t->sa;
ac.ar = t->ar;
ac.sl = (t->sa) ? t->sa->spacedata.first : NULL;
@@ -380,7 +380,7 @@ static void recalcData_graphedit(TransInfo *t)
/* NOTE: sync this with the code in ANIM_animdata_get_context() */
ac.scene = t->scene;
ac.scene_layer = t->scene_layer;
- ac.obact = OBACT_NEW;
+ ac.obact = OBACT_NEW(sl);
ac.sa = t->sa;
ac.ar = t->ar;
ac.sl = (t->sa) ? t->sa->spacedata.first : NULL;
@@ -1800,7 +1800,7 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
}
else if (t->flag & T_POSE) {
SceneLayer *sl = t->scene_layer;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob) {
bPoseChannel *pchan = BKE_pose_channel_active(ob);
if (pchan && (!select_only || (pchan->bone->flag & BONE_SELECTED))) {
@@ -1820,8 +1820,8 @@ bool calculateCenterActive(TransInfo *t, bool select_only, float r_center[3])
else {
/* object mode */
SceneLayer *sl = t->scene_layer;
- Object *ob = OBACT_NEW;
- Base *base = BASACT_NEW;
+ Object *ob = OBACT_NEW(sl);
+ Base *base = BASACT_NEW(sl);
if (ob && ((!select_only) || ((base->flag & BASE_SELECTED) != 0))) {
copy_v3_v3(r_center, ob->obmat[3]);
ok = true;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index 5b4eebc963f..8825d1e55bc 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -603,7 +603,7 @@ static int calc_manipulator_stats(const bContext *C)
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
Base *base;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
bGPdata *gpd = CTX_data_gpencil_data(C);
const bool is_gp_edit = ((gpd) && (gpd->flag & GP_DATA_STROKE_EDITMODE));
int a, totsel = 0;
@@ -913,8 +913,8 @@ static int calc_manipulator_stats(const bContext *C)
else {
/* we need the one selected object, if its not active */
- base = BASACT_NEW;
- ob = OBACT_NEW;
+ base = BASACT_NEW(sl);
+ ob = OBACT_NEW(sl);
if (base && ((base->flag & BASE_SELECTED) == 0)) ob = NULL;
for (base = sl->object_bases.first; base; base = base->next) {
@@ -1025,7 +1025,7 @@ static void manipulator_prepare_mat(const bContext *C, View3D *v3d, RegionView3D
case V3D_AROUND_ACTIVE:
{
bGPdata *gpd = CTX_data_gpencil_data(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (((v3d->around == V3D_AROUND_ACTIVE) && (scene->obedit == NULL)) &&
((gpd == NULL) || !(gpd->flag & GP_DATA_STROKE_EDITMODE)) &&
@@ -1205,6 +1205,7 @@ static void WIDGETGROUP_manipulator_setup(const bContext *UNUSED(C), wmManipulat
const float ofs[3] = {ofs_ax, ofs_ax, 0.0f};
WM_manipulator_set_scale(axis, 0.07f);
WM_manipulator_set_matrix_offset_location(axis, ofs);
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_DRAW_OFFSET_SCALE, true);
break;
}
case MAN_AXIS_TRANS_C:
@@ -1310,6 +1311,7 @@ static void WIDGETGROUP_manipulator_refresh(const bContext *C, wmManipulatorGrou
WM_manipulator_set_matrix_rotation_from_z_axis(axis, rv3d->twmat[aidx_norm]);
RNA_float_set(axis->ptr, "length", len);
WM_manipulator_set_matrix_offset_location(axis, start_co);
+ WM_manipulator_set_flag(axis, WM_MANIPULATOR_DRAW_OFFSET_SCALE, true);
break;
}
case MAN_AXIS_ROT_X:
@@ -1369,10 +1371,10 @@ static void WIDGETGROUP_manipulator_draw_prepare(const bContext *C, wmManipulato
continue;
}
- float col[4], col_hi[4];
- manipulator_get_axis_color(axis_idx, idot, col, col_hi);
- WM_manipulator_set_color(axis, col);
- WM_manipulator_set_color_highlight(axis, col_hi);
+ float color[4], color_hi[4];
+ manipulator_get_axis_color(axis_idx, idot, color, color_hi);
+ WM_manipulator_set_color(axis, color);
+ WM_manipulator_set_color_highlight(axis, color_hi);
switch (axis_idx) {
case MAN_AXIS_TRANS_C:
diff --git a/source/blender/editors/transform/transform_manipulator2d.c b/source/blender/editors/transform/transform_manipulator2d.c
index dd6fe762423..2059d646551 100644
--- a/source/blender/editors/transform/transform_manipulator2d.c
+++ b/source/blender/editors/transform/transform_manipulator2d.c
@@ -191,8 +191,8 @@ void ED_widgetgroup_manipulator2d_setup(const bContext *UNUSED(C), wmManipulator
{
const float offset[3] = {0.0f, 0.2f};
- float col[4], col_hi[4];
- manipulator2d_get_axis_color(axis_idx, col, col_hi);
+ float color[4], color_hi[4];
+ manipulator2d_get_axis_color(axis_idx, color, color_hi);
/* custom handler! */
WM_manipulator_set_fn_custom_modal(axis, manipulator2d_modal);
@@ -202,8 +202,8 @@ void ED_widgetgroup_manipulator2d_setup(const bContext *UNUSED(C), wmManipulator
WM_manipulator_set_matrix_offset_location(axis, offset);
WM_manipulator_set_line_width(axis, MANIPULATOR_AXIS_LINE_WIDTH);
WM_manipulator_set_scale(axis, U.manipulator_size);
- WM_manipulator_set_color(axis, col);
- WM_manipulator_set_color_highlight(axis, col_hi);
+ WM_manipulator_set_color(axis, color);
+ WM_manipulator_set_color_highlight(axis, color_hi);
/* assign operator */
PointerRNA *ptr = WM_manipulator_set_operator(axis, ot_translate, NULL);
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 8db1c619b25..4f436a24ef5 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -581,7 +581,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
SceneLayer *sl = CTX_data_scene_layer(C);
Object *obedit = CTX_data_edit_object(C);
Base *base;
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
int result = ORIENTATION_NONE;
const bool activeOnly = (around == V3D_AROUND_ACTIVE);
@@ -1044,8 +1044,8 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
}
else {
/* we need the one selected object, if its not active */
- base = BASACT_NEW;
- ob = OBACT_NEW;
+ base = BASACT_NEW(sl);
+ ob = OBACT_NEW(sl);
if (base && ((base->flag & BASE_SELECTED) != 0)) {
/* pass */
}
diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c
index 906a6ce20ef..ddb46bce3ea 100644
--- a/source/blender/editors/transform/transform_snap.c
+++ b/source/blender/editors/transform/transform_snap.c
@@ -1001,7 +1001,7 @@ static void CalcSnapGeometry(TransInfo *t, float *UNUSED(vec))
float dist_px = SNAP_MIN_DISTANCE; // Use a user defined value here
char node_border;
- if (snapNodesTransform(t, t->mval, t->tsnap.modeSelect, loc, &dist_px, &node_border)) {
+ if (snapNodesTransform(t, t->mval, loc, &dist_px, &node_border)) {
copy_v2_v2(t->tsnap.snapPoint, loc);
t->tsnap.snapNodeBorder = node_border;
@@ -1197,7 +1197,7 @@ bool snapObjectsTransform(
float r_loc[3], float r_no[3])
{
return ED_transform_snap_object_project_view3d_ex(
- t->context, t->tsnap.object_context,
+ t->tsnap.object_context,
t->scene->toolsettings->snap_mode,
&(const struct SnapObjectParams){
.snap_select = t->tsnap.modeSelect,
@@ -1211,7 +1211,7 @@ bool snapObjectsTransform(
/******************** PEELING *********************************/
bool peelObjectsSnapContext(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const float mval[2],
const struct SnapObjectParams *params,
const bool use_peel_object,
@@ -1220,7 +1220,7 @@ bool peelObjectsSnapContext(
{
ListBase depths_peel = {0};
ED_transform_snap_object_project_all_view3d_ex(
- C, sctx,
+ sctx,
params,
mval, -1.0f, false,
&depths_peel);
@@ -1287,7 +1287,7 @@ bool peelObjectsTransform(
float r_loc[3], float r_no[3], float *r_thickness)
{
return peelObjectsSnapContext(
- t->context, t->tsnap.object_context,
+ t->tsnap.object_context,
mval,
&(const struct SnapObjectParams){
.snap_select = t->tsnap.modeSelect,
@@ -1397,22 +1397,11 @@ static bool snapNodes(
}
bool snapNodesTransform(
- TransInfo *t, const int mval[2], SnapSelect snap_select,
+ TransInfo *t, const int mval[2],
float r_loc[2], float *r_dist_px, char *r_node_border)
{
return snapNodes(
- t->settings, t->sa->spacedata.first, t->ar, mval, snap_select,
- r_loc, r_dist_px, r_node_border);
-}
-
-bool snapNodesContext(
- bContext *C, const int mval[2], SnapSelect snap_select,
- float r_loc[2], float *r_dist_px, char *r_node_border)
-{
- Scene *scene = CTX_data_scene(C);
- ARegion *ar = CTX_wm_region(C);
- return snapNodes(
- scene->toolsettings, CTX_wm_space_node(C), ar, mval, snap_select,
+ t->settings, t->sa->spacedata.first, t->ar, mval, t->tsnap.modeSelect,
r_loc, r_dist_px, r_node_border);
}
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index 49f8a41d743..52673fdf4da 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -104,7 +104,8 @@ typedef struct SnapObjectData_EditMesh {
struct SnapObjectContext {
Main *bmain;
Scene *scene;
- SceneLayer *scene_layer;
+ EvaluationContext eval_ctx;
+
int flag;
/* Optional: when performing screen-space projection.
@@ -143,7 +144,7 @@ struct SnapObjectContext {
* \{ */
-typedef void(*IterSnapObjsCallback)(const bContext *C, SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data);
+typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data);
/**
* Walks through all objects in the scene to create the list of objets to snap.
@@ -153,42 +154,41 @@ typedef void(*IterSnapObjsCallback)(const bContext *C, SnapObjectContext *sctx,
* \param obedit : Object Edited to use its coordinates of BMesh(if any) to do the snapping.
*/
static void iter_snap_objects(
- const bContext *C,
SnapObjectContext *sctx,
const SnapSelect snap_select,
Object *obedit,
IterSnapObjsCallback sob_callback,
void *data)
{
- Base *base_act = sctx->scene_layer->basact;
+ Base *base_act = sctx->eval_ctx.scene_layer->basact;
/* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA
* which makes the loop skip it, even the derived mesh will never change
*
* To solve that problem, we do it first as an exception.
* */
if (base_act && base_act->object && base_act->object->mode & OB_MODE_PARTICLE_EDIT) {
- sob_callback(C, sctx, false, base_act->object, base_act->object->obmat, data);
+ sob_callback(sctx, false, base_act->object, base_act->object->obmat, data);
}
- for (Base *base = sctx->scene_layer->object_bases.first; base != NULL; base = base->next) {
+ for (Base *base = sctx->eval_ctx.scene_layer->object_bases.first; base != NULL; base = base->next) {
if ((BASE_VISIBLE_NEW(base)) && (base->flag_legacy & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 &&
- !((snap_select == SNAP_NOT_SELECTED && ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) ||
- (snap_select == SNAP_NOT_ACTIVE && base == base_act)))
+ !((snap_select == SNAP_NOT_SELECTED && ((base->flag & BASE_SELECTED) || (base->flag_legacy & BA_WAS_SEL))) ||
+ (snap_select == SNAP_NOT_ACTIVE && base == base_act)))
{
bool use_obedit;
Object *obj = base->object;
if (obj->transflag & OB_DUPLI) {
DupliObject *dupli_ob;
- ListBase *lb = object_duplilist(sctx->bmain->eval_ctx, sctx->scene, obj);
+ ListBase *lb = object_duplilist(&sctx->eval_ctx, sctx->scene, obj);
for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
use_obedit = obedit && dupli_ob->ob->data == obedit->data;
- sob_callback(C, sctx, use_obedit, use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data);
+ sob_callback(sctx, use_obedit, use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data);
}
free_object_duplilist(lb);
}
use_obedit = obedit && obj->data == obedit->data;
- sob_callback(C, sctx, use_obedit, use_obedit ? obedit : obj, obj->obmat, data);
+ sob_callback(sctx, use_obedit, use_obedit ? obedit : obj, obj->obmat, data);
}
}
}
@@ -409,7 +409,7 @@ static bool raycastDerivedMesh(
if (bb) {
/* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
if (!isect_ray_aabb_v3_simple(
- ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, NULL))
+ ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, NULL))
{
return retval;
}
@@ -440,21 +440,18 @@ static bool raycastDerivedMesh(
free_bvhtree_from_mesh(treedata);
}
else {
- if (!treedata->vert_allocated) {
+ if (treedata->vert == NULL) {
treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
}
- if (!treedata->loop_allocated) {
+ if (treedata->loop == NULL) {
treedata->loop = DM_get_loop_array(dm, &treedata->loop_allocated);
}
- if (!treedata->looptri_allocated) {
- if (!sod->poly_allocated) {
+ if (treedata->looptri == NULL) {
+ if (sod->mpoly == NULL) {
sod->mpoly = DM_get_poly_array(dm, &sod->poly_allocated);
}
- treedata->looptri = DM_get_looptri_array(
- dm, treedata->vert,
- sod->mpoly, dm->getNumPolys(dm),
- treedata->loop, dm->getNumLoops(dm),
- &treedata->looptri_allocated);
+ treedata->looptri = dm->getLoopTriArray(dm);
+ treedata->looptri_allocated = false;
}
}
}
@@ -478,8 +475,7 @@ static bool raycastDerivedMesh(
if (len_diff == 0.0f) { /* do_ray_start_correction */
/* We *need* a reasonably valid len_diff in this case.
* Get the distance to bvhtree root */
- if (!isect_ray_bvhroot_v3(treedata->tree, ray_start_local, ray_normal_local, &len_diff))
- {
+ if (!isect_ray_bvhroot_v3(treedata->tree, ray_start_local, ray_normal_local, &len_diff)) {
return retval;
}
}
@@ -521,8 +517,8 @@ static bool raycastDerivedMesh(
BVHTreeRayHit hit = {.index = -1, .dist = local_depth};
if (BLI_bvhtree_ray_cast(
- treedata->tree, ray_start_local, ray_normal_local, 0.0f,
- &hit, treedata->raycast_callback, treedata) != -1)
+ treedata->tree, ray_start_local, ray_normal_local, 0.0f,
+ &hit, treedata->raycast_callback, treedata) != -1)
{
hit.dist += len_diff;
hit.dist /= local_scale;
@@ -635,8 +631,7 @@ static bool raycastEditMesh(
if (sctx->use_v3d && !((RegionView3D *)sctx->v3d_data.ar->regiondata)->is_persp) { /* do_ray_start_correction */
/* We *need* a reasonably valid len_diff in this case.
* Get the distance to bvhtree root */
- if (!isect_ray_bvhroot_v3(treedata->tree, ray_start_local, ray_normal_local, &len_diff))
- {
+ if (!isect_ray_bvhroot_v3(treedata->tree, ray_start_local, ray_normal_local, &len_diff)) {
return retval;
}
/* You need to make sure that ray_start is really far away,
@@ -713,7 +708,7 @@ static bool raycastEditMesh(
* \note Duplicate args here are documented at #snapObjectsRay
*/
static bool raycastObj(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const float ray_start[3], const float ray_dir[3],
Object *ob, float obmat[4][4], const unsigned int ob_index,
bool use_obedit,
@@ -724,11 +719,8 @@ static bool raycastObj(
Object **r_ob, float r_obmat[4][4],
ListBase *r_hit_list)
{
- EvaluationContext eval_ctx;
bool retval = false;
- CTX_data_eval_ctx(C, &eval_ctx);
-
if (ob->type == OB_MESH) {
BMEditMesh *em;
@@ -746,18 +738,16 @@ static bool raycastObj(
DerivedMesh *dm;
em = BKE_editmesh_from_object(ob);
if (em) {
- editbmesh_get_derived_cage_and_final(&eval_ctx, sctx->scene, ob, em, CD_MASK_BAREMESH, &dm);
+ editbmesh_get_derived_cage_and_final(&sctx->eval_ctx, sctx->scene, ob, em, CD_MASK_BAREMESH, &dm);
}
else {
- dm = mesh_get_derived_final(&eval_ctx, sctx->scene, ob, CD_MASK_BAREMESH);
+ dm = mesh_get_derived_final(&sctx->eval_ctx, sctx->scene, ob, CD_MASK_BAREMESH);
}
retval = raycastDerivedMesh(
sctx,
ray_start, ray_dir,
ob, dm, obmat, ob_index,
ray_depth, r_loc, r_no, r_index, r_hit_list);
-
- dm->release(dm);
}
}
@@ -788,11 +778,11 @@ struct RaycastObjUserData {
bool ret;
};
-static void raycast_obj_cb(const bContext *C, SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data)
+static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data)
{
struct RaycastObjUserData *dt = data;
dt->ret |= raycastObj(
- C, sctx,
+ sctx,
dt->ray_start, dt->ray_dir,
ob, obmat, dt->ob_index++, is_obedit,
dt->ray_depth,
@@ -831,7 +821,7 @@ static void raycast_obj_cb(const bContext *C, SnapObjectContext *sctx, bool is_o
*
*/
static bool raycastObjects(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const float ray_start[3], const float ray_dir[3],
const SnapSelect snap_select, const bool use_object_edit_cage,
/* read/write args */
@@ -857,7 +847,7 @@ static bool raycastObjects(
.ret = false,
};
- iter_snap_objects(C, sctx, snap_select, obedit, raycast_obj_cb, &data);
+ iter_snap_objects(sctx, snap_select, obedit, raycast_obj_cb, &data);
return data.ret;
}
@@ -1718,10 +1708,10 @@ static bool snapDerivedMesh(
free_bvhtree_from_mesh(treedata);
}
else {
- if (!treedata->vert_allocated) {
+ if (treedata->vert == NULL) {
treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
}
- if ((tree_index == 1) && !treedata->edge_allocated) {
+ if ((tree_index == 1) && (treedata->edge == NULL)) {
treedata->edge = DM_get_edge_array(dm, &treedata->edge_allocated);
}
}
@@ -1950,7 +1940,7 @@ static bool snapEditMesh(
* \note Duplicate args here are documented at #snapObjectsRay
*/
static bool snapObject(
- const bContext *C, SnapObjectContext *sctx, SnapData *snapdata,
+ SnapObjectContext *sctx, SnapData *snapdata,
Object *ob, float obmat[4][4],
bool use_obedit,
/* read/write args */
@@ -1959,11 +1949,8 @@ static bool snapObject(
float r_loc[3], float r_no[3],
Object **r_ob, float r_obmat[4][4])
{
- EvaluationContext eval_ctx;
bool retval = false;
- CTX_data_eval_ctx(C, &eval_ctx);
-
if (ob->type == OB_MESH) {
BMEditMesh *em;
@@ -1980,10 +1967,10 @@ static bool snapObject(
DerivedMesh *dm;
em = BKE_editmesh_from_object(ob);
if (em) {
- editbmesh_get_derived_cage_and_final(&eval_ctx, sctx->scene, ob, em, CD_MASK_BAREMESH, &dm);
+ editbmesh_get_derived_cage_and_final(&sctx->eval_ctx, sctx->scene, ob, em, CD_MASK_BAREMESH, &dm);
}
else {
- dm = mesh_get_derived_final(&eval_ctx, sctx->scene, ob, CD_MASK_BAREMESH);
+ dm = mesh_get_derived_final(&sctx->eval_ctx, sctx->scene, ob, CD_MASK_BAREMESH);
}
retval = snapDerivedMesh(
sctx, snapdata, ob, dm, obmat,
@@ -2047,11 +2034,11 @@ struct SnapObjUserData {
bool ret;
};
-static void sanp_obj_cb(const bContext *C, SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data)
+static void sanp_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data)
{
struct SnapObjUserData *dt = data;
dt->ret |= snapObject(
- C, sctx, dt->snapdata,
+ sctx, dt->snapdata,
ob, obmat, is_obedit,
/* read/write args */
dt->ray_depth, dt->dist_px,
@@ -2090,7 +2077,7 @@ static void sanp_obj_cb(const bContext *C, SnapObjectContext *sctx, bool is_obed
*
*/
static bool snapObjectsRay(
- const bContext *C, SnapObjectContext *sctx, SnapData *snapdata,
+ SnapObjectContext *sctx, SnapData *snapdata,
const SnapSelect snap_select, const bool use_object_edit_cage,
/* read/write args */
float *ray_depth, float *dist_px,
@@ -2111,7 +2098,7 @@ static bool snapObjectsRay(
.ret = false,
};
- iter_snap_objects(C, sctx, snap_select, obedit, sanp_obj_cb, &data);
+ iter_snap_objects(sctx, snap_select, obedit, sanp_obj_cb, &data);
return data.ret;
}
@@ -2133,7 +2120,8 @@ SnapObjectContext *ED_transform_snap_object_context_create(
sctx->bmain = bmain;
sctx->scene = scene;
- sctx->scene_layer = sl;
+
+ DEG_evaluation_context_init_from_scene(&sctx->eval_ctx, scene, sl, DAG_EVAL_VIEWPORT);
sctx->cache.object_map = BLI_ghash_ptr_new(__func__);
sctx->cache.mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
@@ -2207,7 +2195,7 @@ void ED_transform_snap_object_context_set_editmesh_callbacks(
}
bool ED_transform_snap_object_project_ray_ex(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3],
float *ray_depth,
@@ -2215,7 +2203,7 @@ bool ED_transform_snap_object_project_ray_ex(
Object **r_ob, float r_obmat[4][4])
{
return raycastObjects(
- C, sctx,
+ sctx,
ray_start, ray_normal,
params->snap_select, params->use_object_edit_cage,
ray_depth, r_loc, r_no, r_index, r_ob, r_obmat, NULL);
@@ -2229,7 +2217,7 @@ bool ED_transform_snap_object_project_ray_ex(
* \param r_hit_list: List of #SnapObjectHitDepth (caller must free).
*/
bool ED_transform_snap_object_project_ray_all(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3],
float ray_depth, bool sort,
@@ -2244,7 +2232,7 @@ bool ED_transform_snap_object_project_ray_all(
#endif
bool retval = raycastObjects(
- C, sctx,
+ sctx,
ray_start, ray_normal,
params->snap_select, params->use_object_edit_cage,
&ray_depth, NULL, NULL, NULL, NULL, NULL,
@@ -2270,7 +2258,7 @@ bool ED_transform_snap_object_project_ray_all(
* \return Snap success
*/
static bool transform_snap_context_project_ray_impl(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3], float *ray_depth,
float r_co[3], float r_no[3])
@@ -2279,7 +2267,7 @@ static bool transform_snap_context_project_ray_impl(
/* try snap edge, then face if it fails */
ret = ED_transform_snap_object_project_ray_ex(
- C, sctx,
+ sctx,
params,
ray_start, ray_normal, ray_depth,
r_co, r_no, NULL,
@@ -2289,7 +2277,7 @@ static bool transform_snap_context_project_ray_impl(
}
bool ED_transform_snap_object_project_ray(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float ray_origin[3], const float ray_direction[3], float *ray_depth,
float r_co[3], float r_no[3])
@@ -2301,14 +2289,14 @@ bool ED_transform_snap_object_project_ray(
}
return transform_snap_context_project_ray_impl(
- C, sctx,
+ sctx,
params,
ray_origin, ray_direction, ray_depth,
r_co, r_no);
}
static bool transform_snap_context_project_view3d_mixed_impl(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const unsigned short snap_to_flag,
const struct SnapObjectParams *params,
const float mval[2], float *dist_px,
@@ -2332,7 +2320,7 @@ static bool transform_snap_context_project_view3d_mixed_impl(
*dist_px = dist_px_orig;
}
if (ED_transform_snap_object_project_view3d(
- C, sctx,
+ sctx,
elem_type[i], params,
mval, dist_px, &ray_depth,
r_co, r_no))
@@ -2349,7 +2337,7 @@ static bool transform_snap_context_project_view3d_mixed_impl(
for (int i = 0; i < 3; i++) {
if (snap_to_flag & (1 << i)) {
if (ED_transform_snap_object_project_view3d(
- C, sctx,
+ sctx,
elem_type[i], params,
mval, dist_px, &ray_depth,
r_co, r_no))
@@ -2378,7 +2366,7 @@ static bool transform_snap_context_project_view3d_mixed_impl(
* \return Snap success
*/
bool ED_transform_snap_object_project_view3d_mixed(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const unsigned short snap_to_flag,
const struct SnapObjectParams *params,
const float mval_fl[2], float *dist_px,
@@ -2386,14 +2374,14 @@ bool ED_transform_snap_object_project_view3d_mixed(
float r_co[3], float r_no[3])
{
return transform_snap_context_project_view3d_mixed_impl(
- C, sctx,
+ sctx,
snap_to_flag, params,
mval_fl, dist_px, use_depth,
r_co, r_no);
}
bool ED_transform_snap_object_project_view3d_ex(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const unsigned short snap_to,
const struct SnapObjectParams *params,
const float mval[2], float *dist_px,
@@ -2427,7 +2415,7 @@ bool ED_transform_snap_object_project_view3d_ex(
if (snap_to == SCE_SNAP_MODE_FACE) {
return raycastObjects(
- C, sctx,
+ sctx,
ray_start, ray_normal,
params->snap_select, params->use_object_edit_cage,
ray_depth, r_loc, r_no, r_index, NULL, NULL, NULL);
@@ -2439,14 +2427,14 @@ bool ED_transform_snap_object_project_view3d_ex(
ray_origin, ray_start, ray_normal, depth_range);
return snapObjectsRay(
- C, sctx, &snapdata,
+ sctx, &snapdata,
params->snap_select, params->use_object_edit_cage,
ray_depth, dist_px, r_loc, r_no, NULL, NULL);
}
}
bool ED_transform_snap_object_project_view3d(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const unsigned short snap_to,
const struct SnapObjectParams *params,
const float mval[2], float *dist_px,
@@ -2454,7 +2442,7 @@ bool ED_transform_snap_object_project_view3d(
float r_loc[3], float r_no[3])
{
return ED_transform_snap_object_project_view3d_ex(
- C, sctx,
+ sctx,
snap_to,
params,
mval, dist_px,
@@ -2466,7 +2454,7 @@ bool ED_transform_snap_object_project_view3d(
* see: #ED_transform_snap_object_project_ray_all
*/
bool ED_transform_snap_object_project_all_view3d_ex(
- const bContext *C, SnapObjectContext *sctx,
+ SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float mval[2],
float ray_depth, bool sort,
@@ -2482,7 +2470,7 @@ bool ED_transform_snap_object_project_all_view3d_ex(
}
return ED_transform_snap_object_project_ray_all(
- C, sctx,
+ sctx,
params,
ray_start, ray_normal, ray_depth, sort,
r_hit_list);
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 55c439924cd..55ce45e5e2a 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -1541,13 +1541,15 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no
normalize_v2(normal);
}
+/**
+ */
static void stitch_draw_vbo(Gwn_VertBuf *vbo, Gwn_PrimType prim_type, const float col[4])
{
- Gwn_Batch *batch = GWN_batch_create(prim_type, vbo, NULL);
- Batch_set_builtin_program(batch, GPU_SHADER_2D_UNIFORM_COLOR);
+ Gwn_Batch *batch = GWN_batch_create_ex(prim_type, vbo, NULL, GWN_BATCH_OWNS_VBO);
+ GWN_batch_program_set_builtin(batch, GPU_SHADER_2D_UNIFORM_COLOR);
GWN_batch_uniform_4fv(batch, "color", col);
GWN_batch_draw(batch);
- GWN_batch_discard_all(batch);
+ GWN_batch_discard(batch);
}
/* TODO make things pretier : store batches inside StitchPreviewer instead of the bare verts pos */
diff --git a/source/blender/gpu/GPU_batch.h b/source/blender/gpu/GPU_batch.h
index d052a2d831f..27d1d1f902e 100644
--- a/source/blender/gpu/GPU_batch.h
+++ b/source/blender/gpu/GPU_batch.h
@@ -31,7 +31,7 @@
#ifndef __GPU_BATCH_H__
#define __GPU_BATCH_H__
-#include "../../../intern/gawain/gawain/batch.h"
+#include "../../../intern/gawain/gawain/gwn_batch.h"
// TODO: CMake magic to do this:
// #include "gawain/batch.h"
@@ -39,11 +39,11 @@
#include "GPU_shader.h"
/* Extend GWN_batch_program_set to use Blender’s library of built-in shader programs. */
-void Batch_set_builtin_program(Gwn_Batch*, GPUBuiltinShader);
+void GWN_batch_program_set_builtin(Gwn_Batch*, GPUBuiltinShader);
/* Replacement for gluSphere */
-Gwn_Batch *Batch_get_sphere(int lod);
-Gwn_Batch *Batch_get_sphere_wire(int lod);
+Gwn_Batch *GPU_batch_preset_sphere(int lod);
+Gwn_Batch *GPU_batch_preset_sphere_wire(int lod);
void gpu_batch_init(void);
void gpu_batch_exit(void);
diff --git a/source/blender/gpu/GPU_immediate.h b/source/blender/gpu/GPU_immediate.h
index 2eb4eb94f48..6206e973908 100644
--- a/source/blender/gpu/GPU_immediate.h
+++ b/source/blender/gpu/GPU_immediate.h
@@ -31,12 +31,12 @@
#ifndef __GPU_IMMEDIATE_H__
#define __GPU_IMMEDIATE_H__
-#include "../../../intern/gawain/gawain/immediate.h"
-#include "../../../intern/gawain/gawain/imm_util.h"
+#include "../../../intern/gawain/gawain/gwn_immediate.h"
+#include "../../../intern/gawain/gawain/gwn_imm_util.h"
// TODO: CMake magic to do this:
-// #include "gawain/immediate.h"
-// #include "gawain/imm_util.h"
+// #include "gawain/gwn_immediate.h"
+// #include "gawain/gwn_imm_util.h"
#include "GPU_shader.h"
diff --git a/source/blender/gpu/GPU_lamp.h b/source/blender/gpu/GPU_lamp.h
index e08fbede80a..f6fd817cc3f 100644
--- a/source/blender/gpu/GPU_lamp.h
+++ b/source/blender/gpu/GPU_lamp.h
@@ -54,7 +54,7 @@ GPULamp *GPU_lamp_from_blender(struct Scene *scene, struct Object *ob, struct Ob
void GPU_lamp_free(struct Object *ob);
void GPU_lamp_engine_data_free(LampEngineData *led);
-bool GPU_lamp_override_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
+bool GPU_lamp_visible(GPULamp *lamp, struct SceneRenderLayer *srl, struct Material *ma);
bool GPU_lamp_has_shadow_buffer(GPULamp *lamp);
void GPU_lamp_update_buffer_mats(GPULamp *lamp);
void GPU_lamp_shadow_buffer_bind(GPULamp *lamp, float viewmat[4][4], int *winsize, float winmat[4][4]);
diff --git a/source/blender/gpu/GPU_matrix.h b/source/blender/gpu/GPU_matrix.h
index a3fd75b662b..219c7b1c6c1 100644
--- a/source/blender/gpu/GPU_matrix.h
+++ b/source/blender/gpu/GPU_matrix.h
@@ -33,8 +33,7 @@
#define __GPU_MATRIX_H__
#include "BLI_sys_types.h"
-#include "GPU_glew.h"
-#include "../../../intern/gawain/gawain/shader_interface.h"
+#include "../../../intern/gawain/gawain/gwn_shader_interface.h"
#ifdef __cplusplus
extern "C" {
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index 7c8ee07eb88..5b62bafd402 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -118,6 +118,7 @@ typedef enum GPUBuiltinShader {
GPU_SHADER_2D_DIAG_STRIPES,
/* for simple 3D drawing */
GPU_SHADER_3D_UNIFORM_COLOR,
+ GPU_SHADER_3D_UNIFORM_COLOR_U32,
GPU_SHADER_3D_UNIFORM_COLOR_INSTANCE,
GPU_SHADER_3D_FLAT_COLOR,
GPU_SHADER_3D_FLAT_COLOR_U32, /* use for select-id's */
diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h
index b32bee55f60..742daee22ee 100644
--- a/source/blender/gpu/GPU_texture.h
+++ b/source/blender/gpu/GPU_texture.h
@@ -69,6 +69,7 @@ typedef enum GPUTextureFormat {
GPU_RG16F,
GPU_R32F,
GPU_R16F,
+ GPU_RG8,
GPU_R8,
#if 0
GPU_RGBA32I,
@@ -83,7 +84,6 @@ typedef enum GPUTextureFormat {
GPU_RG16,
GPU_RG16I,
GPU_RG16UI,
- GPU_RG8,
GPU_RG8I,
GPU_RG8UI,
GPU_R32I,
diff --git a/source/blender/gpu/GPU_uniformbuffer.h b/source/blender/gpu/GPU_uniformbuffer.h
index e342078d8fd..57c4612c865 100644
--- a/source/blender/gpu/GPU_uniformbuffer.h
+++ b/source/blender/gpu/GPU_uniformbuffer.h
@@ -32,7 +32,6 @@
#ifndef __GPU_UNIFORMBUFFER_H__
#define __GPU_UNIFORMBUFFER_H__
-typedef enum GPUType GPUType;
struct ListBase;
typedef struct GPUUniformBuffer GPUUniformBuffer;
diff --git a/source/blender/gpu/intern/gpu_batch.c b/source/blender/gpu/intern/gpu_batch.c
index 92bab13dcb5..5d347fc80e8 100644
--- a/source/blender/gpu/intern/gpu_batch.c
+++ b/source/blender/gpu/intern/gpu_batch.c
@@ -31,7 +31,7 @@
#include "GPU_batch.h"
#include "gpu_shader_private.h"
-void Batch_set_builtin_program(Gwn_Batch *batch, GPUBuiltinShader shader_id)
+void GWN_batch_program_set_builtin(Gwn_Batch *batch, GPUBuiltinShader shader_id)
{
GPUShader *shader = GPU_shader_get_builtin_shader(shader_id);
GWN_batch_program_set(batch, shader->program, shader->interface);
@@ -93,7 +93,7 @@ static Gwn_Batch *batch_sphere(int lat_res, int lon_res)
}
}
- return GWN_batch_create(GWN_PRIM_TRIS, vbo, NULL);
+ return GWN_batch_create_ex(GWN_PRIM_TRIS, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
static Gwn_Batch *batch_sphere_wire(int lat_res, int lon_res)
@@ -125,10 +125,10 @@ static Gwn_Batch *batch_sphere_wire(int lat_res, int lon_res)
}
}
- return GWN_batch_create(GWN_PRIM_LINES, vbo, NULL);
+ return GWN_batch_create_ex(GWN_PRIM_LINES, vbo, NULL, GWN_BATCH_OWNS_VBO);
}
-Gwn_Batch *Batch_get_sphere(int lod)
+Gwn_Batch *GPU_batch_preset_sphere(int lod)
{
BLI_assert(lod >= 0 && lod <= 2);
@@ -140,7 +140,7 @@ Gwn_Batch *Batch_get_sphere(int lod)
return sphere_high;
}
-Gwn_Batch *Batch_get_sphere_wire(int lod)
+Gwn_Batch *GPU_batch_preset_sphere_wire(int lod)
{
BLI_assert(lod >= 0 && lod <= 1);
@@ -163,9 +163,9 @@ void gpu_batch_init(void)
void gpu_batch_exit(void)
{
- GWN_batch_discard_all(sphere_low);
- GWN_batch_discard_all(sphere_med);
- GWN_batch_discard_all(sphere_high);
- GWN_batch_discard_all(sphere_wire_low);
- GWN_batch_discard_all(sphere_wire_med);
+ GWN_batch_discard(sphere_low);
+ GWN_batch_discard(sphere_med);
+ GWN_batch_discard(sphere_high);
+ GWN_batch_discard(sphere_wire_low);
+ GWN_batch_discard(sphere_wire_med);
}
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index afd28aece12..5bb9fe95099 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -285,7 +285,7 @@ GPUFX *GPU_fx_compositor_create(void)
GWN_vertbuf_attr_set(vbo, pos, i, fullscreencos[i]);
GWN_vertbuf_attr_set(vbo, uvs, i, fullscreenuvs[i]);
}
- fx->quad_batch = GWN_batch_create(GWN_PRIM_TRI_STRIP, vbo, NULL);
+ fx->quad_batch = GWN_batch_create_ex(GWN_PRIM_TRI_STRIP, vbo, NULL, GWN_BATCH_OWNS_VBO);
/* Point Buffer */
static Gwn_VertFormat format_point = {0};
@@ -297,7 +297,7 @@ GPUFX *GPU_fx_compositor_create(void)
Gwn_VertBuf *vbo_point = GWN_vertbuf_create_with_format(&format_point);
GWN_vertbuf_data_alloc(vbo_point, 1);
GWN_vertbuf_attr_set(vbo_point, dummy_attrib, 0, &dummy);
- fx->point_batch = GWN_batch_create(GWN_PRIM_POINTS, vbo_point, NULL);
+ fx->point_batch = GWN_batch_create_ex(GWN_PRIM_POINTS, vbo_point, NULL, GWN_BATCH_OWNS_VBO);
return fx;
}
@@ -387,8 +387,8 @@ static void cleanup_fx_gl_data(GPUFX *fx, bool do_fbo)
void GPU_fx_compositor_destroy(GPUFX *fx)
{
cleanup_fx_gl_data(fx, true);
- GWN_batch_discard_all(fx->quad_batch);
- GWN_batch_discard_all(fx->point_batch);
+ GWN_batch_discard(fx->quad_batch);
+ GWN_batch_discard(fx->point_batch);
MEM_freeN(fx);
}
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index e6c37425828..601de2249f5 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -2023,7 +2023,7 @@ int GPU_scene_object_lights(SceneLayer *sl, float viewmat[4][4], int ortho)
int count = 0;
- for (Base *base = FIRSTBASE_NEW; base; base = base->next) {
+ for (Base *base = FIRSTBASE_NEW(sl); base; base = base->next) {
if (base->object->type != OB_LAMP)
continue;
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index 5a64b0ec781..48a8267bff2 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -480,7 +480,7 @@ void GPU_framebuffer_blur(
GPU_texture_bind(tex, 0);
- Batch_set_builtin_program(&batch, GPU_SHADER_SEP_GAUSSIAN_BLUR);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_SEP_GAUSSIAN_BLUR);
GWN_batch_uniform_2f(&batch, "ScaleU", scaleh[0], scaleh[1]);
GWN_batch_uniform_1i(&batch, "textureSource", GL_TEXTURE0);
GWN_batch_draw(&batch);
@@ -496,7 +496,7 @@ void GPU_framebuffer_blur(
GPU_texture_bind(blurtex, 0);
/* Hack to make the following uniform stick */
- Batch_set_builtin_program(&batch, GPU_SHADER_SEP_GAUSSIAN_BLUR);
+ GWN_batch_program_set_builtin(&batch, GPU_SHADER_SEP_GAUSSIAN_BLUR);
GWN_batch_uniform_2f(&batch, "ScaleU", scalev[0], scalev[1]);
GWN_batch_uniform_1i(&batch, "textureSource", GL_TEXTURE0);
GWN_batch_draw(&batch);
@@ -543,6 +543,7 @@ void GPU_framebuffer_blit(GPUFrameBuffer *fb_read, int read_slot, GPUFrameBuffer
void GPU_framebuffer_recursive_downsample(
GPUFrameBuffer *fb, GPUTexture *tex, int num_iter, void (*callback)(void *userData, int level), void *userData)
{
+ int i;
int current_dim[2] = {GPU_texture_width(tex), GPU_texture_height(tex)};
GLenum attachment;
@@ -567,7 +568,7 @@ void GPU_framebuffer_recursive_downsample(
glReadBuffer(GL_COLOR_ATTACHMENT0);
}
- for (int i=1; i < num_iter+1 && (current_dim[0] > 1 && current_dim[1] > 1); i++) {
+ for (i=1; i < num_iter+1 && (current_dim[0] > 4 && current_dim[1] > 4); i++) {
/* calculate next viewport size */
current_dim[0] /= 2;
@@ -595,7 +596,7 @@ void GPU_framebuffer_recursive_downsample(
/* reset mipmap level range for the depth image */
GPU_texture_bind(tex, 0);
glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_BASE_LEVEL, 0);
- glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, num_iter);
+ glTexParameteri(GPU_texture_target(tex), GL_TEXTURE_MAX_LEVEL, i-1);
GPU_texture_unbind(tex);
}
diff --git a/source/blender/gpu/intern/gpu_lamp.c b/source/blender/gpu/intern/gpu_lamp.c
index 8bf343568b1..23bfb1dfb6b 100644
--- a/source/blender/gpu/intern/gpu_lamp.c
+++ b/source/blender/gpu/intern/gpu_lamp.c
@@ -52,9 +52,11 @@
#include "gpu_lamp_private.h"
-bool GPU_lamp_override_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
+bool GPU_lamp_visible(GPULamp *lamp, SceneRenderLayer *srl, Material *ma)
{
- if (srl && srl->light_override)
+ if (lamp->hide)
+ return false;
+ else if (srl && srl->light_override)
return BKE_group_object_exists(srl->light_override, lamp->ob);
else if (ma && ma->group)
return BKE_group_object_exists(ma->group, lamp->ob);
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index f62c599a9b6..a08bef4472a 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -280,8 +280,8 @@ void GPU_material_bind(
for (LinkData *nlink = material->lamps.first; nlink; nlink = nlink->next) {
GPULamp *lamp = nlink->data;
- if (!lamp->hide && (lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) &&
- GPU_lamp_override_visible(lamp, srl, material->ma))
+ if ((lamp->lay & viewlay) && (!(lamp->mode & LA_LAYER) || (lamp->lay & oblay)) &&
+ GPU_lamp_visible(lamp, srl, material->ma))
{
lamp->dynenergy = lamp->energy;
copy_v3_v3(lamp->dyncol, lamp->col);
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index e67e5bc933d..5d5be2ec4ef 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -663,6 +663,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
[GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR] = { datatoc_gpu_shader_2D_image_vert_glsl,
datatoc_gpu_shader_image_shuffle_color_frag_glsl },
[GPU_SHADER_3D_UNIFORM_COLOR] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
+ [GPU_SHADER_3D_UNIFORM_COLOR_U32] = { datatoc_gpu_shader_3D_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
[GPU_SHADER_3D_FLAT_COLOR] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
datatoc_gpu_shader_flat_color_frag_glsl },
[GPU_SHADER_3D_FLAT_COLOR_U32] = { datatoc_gpu_shader_3D_flat_color_vert_glsl,
@@ -767,6 +768,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
defines = "#define USE_INSTANCE_COLOR;\n";
break;
case GPU_SHADER_3D_FLAT_COLOR_U32:
+ case GPU_SHADER_3D_UNIFORM_COLOR_U32:
defines = "#define USE_COLOR_U32;\n";
break;
case GPU_SHADER_SIMPLE_LIGHTING_FLAT_COLOR:
diff --git a/source/blender/gpu/intern/gpu_shader_private.h b/source/blender/gpu/intern/gpu_shader_private.h
index 2de05b5746b..f883773df17 100644
--- a/source/blender/gpu/intern/gpu_shader_private.h
+++ b/source/blender/gpu/intern/gpu_shader_private.h
@@ -26,7 +26,7 @@
#define __GPU_SHADER_PRIVATE_H__
#include "GPU_glew.h"
-#include "gawain/shader_interface.h"
+#include "gawain/gwn_shader_interface.h"
struct GPUShader {
GLuint program; /* handle for full program (links shader stages below) */
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 48ed3fc1de1..959fc7e8794 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -167,6 +167,7 @@ static GLenum gpu_texture_get_format(
break;
case GPU_DEPTH_COMPONENT16:
case GPU_R16F:
+ case GPU_RG8:
*bytesize = 2;
break;
case GPU_R8:
@@ -189,6 +190,7 @@ static GLenum gpu_texture_get_format(
case GPU_RGBA8: return GL_RGBA8;
case GPU_R32F: return GL_R32F;
case GPU_R16F: return GL_R16F;
+ case GPU_RG8: return GL_RG8;
case GPU_R8: return GL_R8;
/* Special formats texture & renderbuffer */
case GPU_R11F_G11F_B10F: return GL_R11F_G11F_B10F;
@@ -874,6 +876,9 @@ void GPU_texture_mipmap_mode(GPUTexture *tex, bool use_mipmap, bool use_filter)
: use_mipmap ? GL_NEAREST_MIPMAP_LINEAR : GL_NEAREST;
glTexParameteri(tex->target_base, GL_TEXTURE_MIN_FILTER, mipmap);
+ GLenum filter = use_filter ? GL_LINEAR : GL_NEAREST;
+ glTexParameteri(tex->target_base, GL_TEXTURE_MAG_FILTER, filter);
+
if (tex->number != 0)
glActiveTexture(GL_TEXTURE0);
}
diff --git a/source/blender/gpu/intern/gpu_uniformbuffer.c b/source/blender/gpu/intern/gpu_uniformbuffer.c
index e3072d729c3..46cf9d19a47 100644
--- a/source/blender/gpu/intern/gpu_uniformbuffer.c
+++ b/source/blender/gpu/intern/gpu_uniformbuffer.c
@@ -51,12 +51,12 @@ typedef enum GPUUniformBufferType {
GPU_UBO_DYNAMIC = 1,
} GPUUniformBufferType;
-typedef struct GPUUniformBuffer {
+struct GPUUniformBuffer {
int size; /* in bytes */
GLuint bindcode; /* opengl identifier for UBO */
int bindpoint; /* current binding point */
GPUUniformBufferType type;
-} GPUUniformBuffer;
+};
#define GPUUniformBufferStatic GPUUniformBuffer
@@ -67,20 +67,25 @@ typedef struct GPUUniformBufferDynamic {
char flag;
} GPUUniformBufferDynamic;
-typedef struct GPUUniformBufferDynamicItem {
+struct GPUUniformBufferDynamicItem {
struct GPUUniformBufferDynamicItem *next, *prev;
GPUType gputype;
float *data;
int size;
-} GPUUniformBufferDynamicItem;
+};
/* Prototypes */
+static GPUType get_padded_gpu_type(struct LinkData *link);
static void gpu_uniformbuffer_inputs_sort(struct ListBase *inputs);
static GPUUniformBufferDynamicItem *gpu_uniformbuffer_populate(
GPUUniformBufferDynamic *ubo, const GPUType gputype, float *num);
+/* Only support up to this type, if you want to extend it, make sure the
+ * padding logic is correct for the new types. */
+#define MAX_UBO_GPU_TYPE GPU_VEC4
+
static void gpu_uniformbuffer_initialize(GPUUniformBuffer *ubo, const void *data)
{
glBindBuffer(GL_UNIFORM_BUFFER, ubo->bindcode);
@@ -153,7 +158,8 @@ GPUUniformBuffer *GPU_uniformbuffer_dynamic_create(ListBase *inputs, char err_ou
for (LinkData *link = inputs->first; link; link = link->next) {
GPUInput *input = link->data;
- gpu_uniformbuffer_populate(ubo, input->type, input->dynamicvec);
+ GPUType gputype = get_padded_gpu_type(link);
+ gpu_uniformbuffer_populate(ubo, gputype, input->dynamicvec);
}
ubo->data = MEM_mallocN(ubo->buffer.size, __func__);
@@ -225,6 +231,26 @@ void GPU_uniformbuffer_dynamic_update(GPUUniformBuffer *ubo_)
}
/**
+ * We need to pad some data types (vec3) on the C side
+ * To match the GPU expected memory block alignment.
+ */
+static GPUType get_padded_gpu_type(LinkData *link)
+{
+ GPUInput *input = link->data;
+ GPUType gputype = input->type;
+
+ /* Unless the vec3 is followed by a float we need to treat it as a vec4. */
+ if (gputype == GPU_VEC3 &&
+ (link->next != NULL) &&
+ (((GPUInput *)link->next->data)->type != GPU_FLOAT))
+ {
+ gputype = GPU_VEC4;
+ }
+
+ return gputype;
+}
+
+/**
* Returns 1 if the first item shold be after second item.
* We make sure the vec4 uniforms come first.
*/
@@ -241,7 +267,51 @@ static int inputs_cmp(const void *a, const void *b)
*/
static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
{
+ /* Order them as vec4, vec3, vec2, float. */
BLI_listbase_sort(inputs, inputs_cmp);
+
+ /* Creates a lookup table for the different types; */
+ LinkData *inputs_lookup[MAX_UBO_GPU_TYPE + 1] = {NULL};
+ GPUType cur_type = MAX_UBO_GPU_TYPE + 1;
+
+ for (LinkData *link = inputs->first; link; link = link->next) {
+ GPUInput *input = link->data;
+ if (input->type == cur_type) {
+ continue;
+ }
+ else {
+ inputs_lookup[input->type] = link;
+ cur_type = input->type;
+ }
+ }
+
+ /* If there is no GPU_VEC3 there is no need for alignment. */
+ if (inputs_lookup[GPU_VEC3] == NULL) {
+ return;
+ }
+
+ LinkData *link = inputs_lookup[GPU_VEC3];
+ while (link != NULL && ((GPUInput *)link->data)->type == GPU_VEC3) {
+ LinkData *link_next = link->next;
+
+ /* If GPU_VEC3 is followed by nothing or a GPU_FLOAT, no need for aligment. */
+ if ((link_next == NULL) ||
+ ((GPUInput *)link_next->data)->type == GPU_FLOAT)
+ {
+ break;
+ }
+
+ /* If there is a float, move it next to current vec3. */
+ if (inputs_lookup[GPU_FLOAT] != NULL) {
+ LinkData *float_input = inputs_lookup[GPU_FLOAT];
+ inputs_lookup[GPU_FLOAT] = float_input->next;
+
+ BLI_remlink(inputs, float_input);
+ BLI_insertlinkafter(inputs, link, float_input);
+ }
+
+ link = link_next;
+ }
}
/**
@@ -251,15 +321,12 @@ static void gpu_uniformbuffer_inputs_sort(ListBase *inputs)
static GPUUniformBufferDynamicItem *gpu_uniformbuffer_populate(
GPUUniformBufferDynamic *ubo, const GPUType gputype, float *num)
{
- BLI_assert(gputype <= GPU_VEC4);
+ BLI_assert(gputype <= MAX_UBO_GPU_TYPE);
GPUUniformBufferDynamicItem *item = MEM_callocN(sizeof(GPUUniformBufferDynamicItem), __func__);
- /* Treat VEC3 as VEC4 because of UBO struct alignment requirements. */
- GPUType type = gputype == GPU_VEC3 ? GPU_VEC4 : gputype;
-
- item->gputype = type;
+ item->gputype = gputype;
item->data = num;
- item->size = type * sizeof(float);
+ item->size = gputype * sizeof(float);
ubo->buffer.size += item->size;
ubo->flag |= GPU_UBO_FLAG_DIRTY;
@@ -299,3 +366,5 @@ void GPU_uniformbuffer_tag_dirty(GPUUniformBuffer *ubo_) {
GPUUniformBufferDynamic *ubo = (GPUUniformBufferDynamic *)ubo_;
ubo->flag |= GPU_UBO_FLAG_DIRTY;
}
+
+#undef MAX_UBO_GPU_TYPE
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 416907c8453..2470b607b07 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2664,7 +2664,7 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result)
#ifdef EEVEE_ENGINE
vec3 L = eevee_surface_diffuse_lit(N, vec3(1.0), 1.0);
vec3 vN = normalize(mat3(ViewMatrix) * N);
- result = Closure(L * color.rgb, 1.0, vec4(0.0), normal_encode(N, viewCameraVec), -1);
+ result = Closure(L * color.rgb, 1.0, vec4(0.0), normal_encode(vN, viewCameraVec), -1);
#else
/* ambient light */
vec3 L = vec3(0.2);
@@ -2720,9 +2720,17 @@ void node_bsdf_anisotropic(
node_bsdf_diffuse(color, 0.0, N, result);
}
-void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out Closure result)
+void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, float ssr_id, out Closure result)
{
+#ifdef EEVEE_ENGINE
+ vec3 ssr_spec;
+ roughness = sqrt(roughness);
+ vec3 L = eevee_surface_glass(N, (refractionDepth > 0.0) ? color.rgb : vec3(1.0), roughness, ior, int(ssr_id), ssr_spec);
+ vec3 vN = normalize(mat3(ViewMatrix) * N);
+ result = Closure(L * color.rgb, 1.0, vec4(ssr_spec * color.rgb, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
+#else
node_bsdf_diffuse(color, 0.0, N, result);
+#endif
}
void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out Closure result)
@@ -2881,8 +2889,9 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs
}
result = Closure(surface_color.rgb / surface_color.a, 1.0);
#else
-
+ vec3 L_trans = (transmission <= 0.0) ? vec3(0.0) : eevee_surface_glass(N, base_color.rgb * ((refractionDepth > 0.0) ? base_color.rgb : vec3(1.0)), roughness, ior, int(-2), ssr_spec);
vec3 L = eevee_surface_clearcoat_lit(N, diffuse, f0, roughness, CN, clearcoat, clearcoat_roughness, 1.0, int(ssr_id), ssr_spec);
+ L = mix(L, L_trans, transmission);
vec3 vN = normalize(mat3(ViewMatrix) * N);
result = Closure(L, 1.0, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
#endif
@@ -2896,7 +2905,7 @@ void node_bsdf_principled_clearcoat(vec4 base_color, float subsurface, vec3 subs
void node_bsdf_translucent(vec4 color, vec3 N, out Closure result)
{
- node_bsdf_diffuse(color, 0.0, N, result);
+ node_bsdf_diffuse(color, 0.0, -N, result);
}
void node_bsdf_transparent(vec4 color, out Closure result)
@@ -2918,6 +2927,18 @@ void node_subsurface_scattering(
node_bsdf_diffuse(color, 0.0, N, result);
}
+void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result)
+{
+#ifdef EEVEE_ENGINE
+ color.rgb *= (refractionDepth > 0.0) ? color.rgb : vec3(1.0); /* Simulate 2 absorption event. */
+ roughness = sqrt(roughness);
+ vec3 L = eevee_surface_refraction(N, vec3(1.0), roughness, ior);
+ result = Closure(L * color.rgb, 1.0, vec4(0.0), vec2(0.0), int(-2));
+#else
+ node_bsdf_diffuse(color, 0.0, N, result);
+#endif /* EEVEE_ENGINE */
+}
+
/* Unsupported for now */
#ifndef EEVEE_ENGINE
void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv, vec3 tangent, out Closure result)
@@ -2925,11 +2946,6 @@ void node_bsdf_hair(vec4 color, float offset, float roughnessu, float roughnessv
result = Closure(color.rgb, color.a);
}
-void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Closure result)
-{
- node_bsdf_diffuse(color, 0.0, N, result);
-}
-
void node_ambient_occlusion(vec4 color, out Closure result)
{
result = Closure(color.rgb, color.a);
@@ -4039,19 +4055,6 @@ void world_normals_get(out vec3 N)
N = gl_FrontFacing ? worldNormal : -worldNormal;
}
-void node_eevee_metallic(
- vec4 basecol, float metallic, float specular, float roughness, vec4 emissive, float transp, vec3 normal,
- float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
- float occlusion, float ssr_id, out Closure result)
-{
- vec3 diffuse, f0, ssr_spec;
- convert_metallic_to_specular(basecol.rgb, metallic, specular, diffuse, f0);
-
- vec3 L = eevee_surface_lit(normal, diffuse, f0, roughness, occlusion, int(ssr_id), ssr_spec);
- vec3 vN = normalize(mat3(ViewMatrix) * normal);
- result = Closure(L + emissive.rgb, 1.0 - transp, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
-}
-
void node_eevee_specular(
vec4 diffuse, vec4 specular, float roughness, vec4 emissive, float transp, vec3 normal,
float clearcoat, float clearcoat_roughness, vec3 clearcoat_normal,
@@ -4064,11 +4067,6 @@ void node_eevee_specular(
result = Closure(L + emissive.rgb, 1.0 - transp, vec4(ssr_spec, roughness), normal_encode(vN, viewCameraVec), int(ssr_id));
}
-void node_output_eevee_material(Closure surface, out Closure result)
-{
- result = surface;
-}
-
#endif /* EEVEE_ENGINE */
#endif /* VOLUMETRICS */
diff --git a/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
index 5dd1352adc5..118a661863d 100644
--- a/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_uniform_color_frag.glsl
@@ -1,9 +1,21 @@
+#if defined(USE_COLOR_U32)
+uniform uint color;
+#else
uniform vec4 color;
+#endif
out vec4 fragColor;
void main()
{
+#if defined(USE_COLOR_U32)
+ fragColor = vec4(
+ ((color ) & uint(0xFF)) * (1.0f / 255.0f),
+ ((color >> 8) & uint(0xFF)) * (1.0f / 255.0f),
+ ((color >> 16) & uint(0xFF)) * (1.0f / 255.0f),
+ ((color >> 24) ) * (1.0f / 255.0f));
+#else
fragColor = color;
+#endif
}
diff --git a/source/blender/ikplugin/BIK_api.h b/source/blender/ikplugin/BIK_api.h
index 8fd13507d3a..ad842029941 100644
--- a/source/blender/ikplugin/BIK_api.h
+++ b/source/blender/ikplugin/BIK_api.h
@@ -62,8 +62,8 @@ struct BIK_ParamValue {
};
typedef struct BIK_ParamValue BIK_ParamValue;
-void BIK_initialize_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
-void BIK_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime);
+void BIK_initialize_tree(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
+void BIK_execute_tree(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime);
void BIK_release_tree(struct Scene *scene, struct Object *ob, float ctime);
void BIK_clear_data(struct bPose *pose);
void BIK_clear_cache(struct bPose *pose);
diff --git a/source/blender/ikplugin/intern/ikplugin_api.c b/source/blender/ikplugin/intern/ikplugin_api.c
index 09a2c3b88ed..0ee26ff45f1 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.c
+++ b/source/blender/ikplugin/intern/ikplugin_api.c
@@ -89,7 +89,7 @@ static IKPlugin *get_plugin(bPose *pose)
/*----------------------------------------*/
/* Plugin API */
-void BIK_initialize_tree(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime)
+void BIK_initialize_tree(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime)
{
IKPlugin *plugin = get_plugin(ob->pose);
@@ -97,7 +97,7 @@ void BIK_initialize_tree(struct EvaluationContext *eval_ctx, Scene *scene, Objec
plugin->initialize_tree_func(eval_ctx, scene, ob, ctime);
}
-void BIK_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, bPoseChannel *pchan, float ctime)
+void BIK_execute_tree(const struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, bPoseChannel *pchan, float ctime)
{
IKPlugin *plugin = get_plugin(ob->pose);
diff --git a/source/blender/ikplugin/intern/ikplugin_api.h b/source/blender/ikplugin/intern/ikplugin_api.h
index 07dd601012f..9a71463ede4 100644
--- a/source/blender/ikplugin/intern/ikplugin_api.h
+++ b/source/blender/ikplugin/intern/ikplugin_api.h
@@ -45,8 +45,8 @@ struct EvaluationContext;
struct IKPlugin {
- void (*initialize_tree_func)(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
- void (*execute_tree_func)(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime);
+ void (*initialize_tree_func)(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
+ void (*execute_tree_func)(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan, float ctime);
void (*release_tree_func)(struct Scene *scene, struct Object *ob, float ctime);
void (*remove_armature_func)(struct bPose *pose);
void (*clear_cache)(struct bPose *pose);
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index 1917db24d4f..5169b72590c 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -252,7 +252,7 @@ static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3]) // nr =
/* called from within the core BKE_pose_where_is loop, all animsystems and constraints
* were executed & assigned. Now as last we do an IK pass */
-static void execute_posetree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, PoseTree *tree)
+static void execute_posetree(const struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, PoseTree *tree)
{
float R_parmat[3][3], identity[3][3];
float iR_parmat[3][3];
@@ -534,7 +534,7 @@ static void free_posetree(PoseTree *tree)
///----------------------------------------
/// Plugin API for legacy iksolver
-void iksolver_initialize_tree(struct EvaluationContext *UNUSED(eval_ctx), struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime))
+void iksolver_initialize_tree(const struct EvaluationContext *UNUSED(eval_ctx), struct Scene *UNUSED(scene), struct Object *ob, float UNUSED(ctime))
{
bPoseChannel *pchan;
@@ -545,7 +545,7 @@ void iksolver_initialize_tree(struct EvaluationContext *UNUSED(eval_ctx), struct
ob->pose->flag &= ~POSE_WAS_REBUILT;
}
-void iksolver_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
+void iksolver_execute_tree(const struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
{
while (pchan_root->iktree.first) {
PoseTree *tree = pchan_root->iktree.first;
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.h b/source/blender/ikplugin/intern/iksolver_plugin.h
index b9bdbd892ec..f1ca91ebb49 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.h
+++ b/source/blender/ikplugin/intern/iksolver_plugin.h
@@ -40,9 +40,11 @@
extern "C" {
#endif
-void iksolver_initialize_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
-void iksolver_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
- struct bPoseChannel *pchan_root, float ctime);
+void iksolver_initialize_tree(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
+void iksolver_execute_tree(
+ const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob,
+ struct bPoseChannel *pchan_root, float ctime);
#ifdef __cplusplus
}
diff --git a/source/blender/ikplugin/intern/itasc_plugin.cpp b/source/blender/ikplugin/intern/itasc_plugin.cpp
index 2227747e7a1..93460559067 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.cpp
+++ b/source/blender/ikplugin/intern/itasc_plugin.cpp
@@ -542,7 +542,7 @@ static void GetJointRotation(KDL::Rotation& boneRot, int type, double *rot)
}
}
-static bool target_callback(struct EvaluationContext *eval_ctx, const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param)
+static bool target_callback(const struct EvaluationContext *eval_ctx, const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param)
{
IK_Target *target = (IK_Target *)param;
// compute next target position
@@ -577,7 +577,7 @@ static bool target_callback(struct EvaluationContext *eval_ctx, const iTaSC::Tim
return true;
}
-static bool base_callback(struct EvaluationContext *eval_ctx, const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param)
+static bool base_callback(const struct EvaluationContext *eval_ctx, const iTaSC::Timestamp& timestamp, const iTaSC::Frame& current, iTaSC::Frame& next, void *param)
{
IK_Scene *ikscene = (IK_Scene *)param;
// compute next armature base pose
@@ -863,7 +863,7 @@ static bool joint_callback(const iTaSC::Timestamp& timestamp, iTaSC::ConstraintV
}
// build array of joint corresponding to IK chain
-static int convert_channels(struct EvaluationContext *eval_ctx, IK_Scene *ikscene, PoseTree *tree, float ctime)
+static int convert_channels(const struct EvaluationContext *eval_ctx, IK_Scene *ikscene, PoseTree *tree, float ctime)
{
IK_Channel *ikchan;
bPoseChannel *pchan;
@@ -1056,7 +1056,7 @@ static void BKE_pose_rest(IK_Scene *ikscene)
}
}
-static IK_Scene *convert_tree(struct EvaluationContext *eval_ctx, Scene *blscene, Object *ob, bPoseChannel *pchan, float ctime)
+static IK_Scene *convert_tree(const struct EvaluationContext *eval_ctx, Scene *blscene, Object *ob, bPoseChannel *pchan, float ctime)
{
PoseTree *tree = (PoseTree *)pchan->iktree.first;
PoseTarget *target;
@@ -1526,7 +1526,7 @@ static IK_Scene *convert_tree(struct EvaluationContext *eval_ctx, Scene *blscene
return ikscene;
}
-static void create_scene(struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime)
+static void create_scene(const struct EvaluationContext *eval_ctx, Scene *scene, Object *ob, float ctime)
{
bPoseChannel *pchan;
@@ -1576,7 +1576,7 @@ static int init_scene(Object *ob)
return 0;
}
-static void execute_scene(struct EvaluationContext *eval_ctx, Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, float ctime, float frtime)
+static void execute_scene(const struct EvaluationContext *eval_ctx, Scene *blscene, IK_Scene *ikscene, bItasc *ikparam, float ctime, float frtime)
{
int i;
IK_Channel *ikchan;
@@ -1744,7 +1744,7 @@ static void execute_scene(struct EvaluationContext *eval_ctx, Scene *blscene, IK
//---------------------------------------------------
// plugin interface
//
-void itasc_initialize_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, float ctime)
+void itasc_initialize_tree(const struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, float ctime)
{
bPoseChannel *pchan;
int count = 0;
@@ -1770,7 +1770,7 @@ void itasc_initialize_tree(struct EvaluationContext *eval_ctx, struct Scene *sce
ob->pose->flag &= ~POSE_WAS_REBUILT;
}
-void itasc_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
+void itasc_execute_tree(const struct EvaluationContext *eval_ctx, struct Scene *scene, Object *ob, bPoseChannel *pchan_root, float ctime)
{
if (ob->pose->ikdata) {
IK_Data *ikdata = (IK_Data *)ob->pose->ikdata;
diff --git a/source/blender/ikplugin/intern/itasc_plugin.h b/source/blender/ikplugin/intern/itasc_plugin.h
index fb948e98696..2f4e4036d76 100644
--- a/source/blender/ikplugin/intern/itasc_plugin.h
+++ b/source/blender/ikplugin/intern/itasc_plugin.h
@@ -40,8 +40,8 @@
extern "C" {
#endif
-void itasc_initialize_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
-void itasc_execute_tree(struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan_root, float ctime);
+void itasc_initialize_tree(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, float ctime);
+void itasc_execute_tree(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob, struct bPoseChannel *pchan_root, float ctime);
void itasc_release_tree(struct Scene *scene, struct Object *ob, float ctime);
void itasc_clear_data(struct bPose *pose);
void itasc_clear_cache(struct bPose *pose);
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 03f71b5878c..1f3be8d73bb 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -2565,6 +2565,14 @@ const char *IMB_colormanagement_colorspace_get_indexed_name(int index)
void IMB_colormanagment_colorspace_from_ibuf_ftype(ColorManagedColorspaceSettings *colorspace_settings, ImBuf *ibuf)
{
+ /* Don't modify non-color data space, it does not change with file type. */
+ ColorSpace *colorspace = colormanage_colorspace_get_named(colorspace_settings->name);
+
+ if (colorspace && colorspace->is_data) {
+ return;
+ }
+
+ /* Get color space from file type. */
const ImFileType *type;
for (type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) {
diff --git a/source/blender/imbuf/intern/jp2.c b/source/blender/imbuf/intern/jp2.c
index 390f2502ee7..388c2734fe9 100644
--- a/source/blender/imbuf/intern/jp2.c
+++ b/source/blender/imbuf/intern/jp2.c
@@ -588,7 +588,7 @@ static opj_image_t *ibuftoimage(ImBuf *ibuf, opj_cparameters_t *parameters)
img_fol_t img_fol; /* only needed for cinema presets */
memset(&img_fol, 0, sizeof(img_fol_t));
- if (ibuf->float_colorspace) {
+ if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
/* float buffer was managed already, no need in color space conversion */
chanel_colormanage_cb = channel_colormanage_noop;
}
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index 503e63a3fb1..dded0f7aecf 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -152,7 +152,7 @@ int imb_savepng(struct ImBuf *ibuf, const char *name, int flags)
compression = (int)(((float)(ibuf->foptions.quality) / 11.1111f));
compression = compression < 0 ? 0 : (compression > 9 ? 9 : compression);
- if (ibuf->float_colorspace) {
+ if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
/* float buffer was managed already, no need in color space conversion */
chanel_colormanage_cb = channel_colormanage_noop;
}
diff --git a/source/blender/imbuf/intern/tiff.c b/source/blender/imbuf/intern/tiff.c
index 4368a428186..8e5cf80e013 100644
--- a/source/blender/imbuf/intern/tiff.c
+++ b/source/blender/imbuf/intern/tiff.c
@@ -822,7 +822,7 @@ int imb_savetiff(ImBuf *ibuf, const char *name, int flags)
/* convert from float source */
float rgb[4];
- if (ibuf->float_colorspace) {
+ if (ibuf->float_colorspace || (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA)) {
/* float buffer was managed already, no need in color space conversion */
copy_v3_v3(rgb, &fromf[from_i]);
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index d457401bb33..4b628c4bc70 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -138,8 +138,7 @@ typedef struct ID {
/**
* LIB_TAG_... tags (runtime only, cleared at read time).
*/
- short tag;
- short pad_s1;
+ int tag;
int us;
int icon_id;
IDProperty *properties;
@@ -366,7 +365,14 @@ enum {
LIB_TAG_ID_RECALC_ALL = (LIB_TAG_ID_RECALC | LIB_TAG_ID_RECALC_DATA),
/* The datablock is a copy-on-write version. */
- LIB_TAG_COPY_ON_WRITE = (1 << 15),
+ LIB_TAG_COPY_ON_WRITE = 1 << 15,
+
+ /* RESET_NEVER tag datablock for freeing etc. behavior (usually set when copying real one into temp/runtime one). */
+ LIB_TAG_NO_MAIN = 1 << 16, /* Datablock is not listed in Main database. */
+ LIB_TAG_NO_USER_REFCOUNT = 1 << 17, /* Datablock does not refcount usages of other IDs. */
+ /* Datablock was not allocated by standard system (BKE_libblock_alloc), do not free its memory
+ * (usual type-specific freeing is called though). */
+ LIB_TAG_NOT_ALLOCATED = 1 << 18,
};
/* To filter ID types (filter_id) */
diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h
index 41ad12e63f2..220326fb01d 100644
--- a/source/blender/makesdna/DNA_material_types.h
+++ b/source/blender/makesdna/DNA_material_types.h
@@ -213,10 +213,11 @@ typedef struct Material {
/* Transparency */
float alpha_threshold;
+ float refract_depth;
char blend_method;
char blend_shadow;
char blend_flag;
- char pad6;
+ char pad6[5];
/* image to use for image/uv space, also bake target
* (not to be used shading/rendering pipeline, this is editor featyure only!). */
@@ -510,7 +511,8 @@ enum {
/* blend_flag */
enum {
- MA_BL_HIDE_BACKSIDE = (1 << 0),
+ MA_BL_HIDE_BACKSIDE = (1 << 0),
+ MA_BL_SS_REFRACTION = (1 << 1),
};
/* blend_shadow */
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index f6dc5741863..93413819025 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -754,7 +754,7 @@ typedef struct RenderData {
/* sequencer options */
char seq_prev_type;
- char seq_rend_type;
+ char seq_rend_type; /* UNUSED! */
char seq_flag; /* flag use for sequence render/draw */
char pad5[5];
@@ -793,14 +793,13 @@ typedef struct RenderData {
struct BakeData bake;
int preview_start_resolution;
+ short preview_pixel_size;
/* Type of the debug pass to use.
* Only used when built with debug passes support.
*/
short debug_pass_type;
- short pad;
-
/* MultiView */
ListBase views; /* SceneRenderView */
short actview;
@@ -1792,8 +1791,7 @@ typedef struct Scene {
/* use preview range */
#define SCER_PRV_RANGE (1<<0)
#define SCER_LOCK_FRAME_SELECTION (1<<1)
- /* timeline/keyframe jumping - only selected items (on by default) */
-#define SCE_KEYS_NO_SELONLY (1<<2)
+ /* show/use subframes (for checking motion blur) */
#define SCER_SHOW_SUBFRAME (1<<3)
/* mode (int now) */
@@ -1833,7 +1831,7 @@ typedef struct Scene {
#define R_USE_WS_SHADING 0x8000000 /* use world space interpretation of lighting data */
/* seq_flag */
-#define R_SEQ_GL_PREV 1
+// #define R_SEQ_GL_PREV 1 // UNUSED, we just use setting from seq_prev_type now.
// #define R_SEQ_GL_REND 2 // UNUSED, opengl render has its own operator now.
#define R_SEQ_SOLID_TEX 4
@@ -2021,10 +2019,10 @@ extern const char *RE_engine_id_CYCLES;
#define BASACT (scene->basact)
#define OBACT (BASACT ? BASACT->object: NULL)
-#define FIRSTBASE_NEW (sl)->object_bases.first
-#define LASTBASE_NEW (sl)->object_bases.last
-#define BASACT_NEW ((sl)->basact)
-#define OBACT_NEW (BASACT_NEW ? BASACT_NEW->object: NULL)
+#define FIRSTBASE_NEW(_sl) ((_sl)->object_bases.first)
+#define LASTBASE_NEW(_sl) ((_sl)->object_bases.last)
+#define BASACT_NEW(_sl) ((_sl)->basact)
+#define OBACT_NEW(_sl) (BASACT_NEW(_sl) ? BASACT_NEW(_sl)->object: NULL)
#define V3D_CAMERA_LOCAL(v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : NULL)
#define V3D_CAMERA_SCENE(scene, v3d) ((!(v3d)->scenelock && (v3d)->camera) ? (v3d)->camera : (scene)->camera)
@@ -2130,6 +2128,7 @@ typedef enum eVGroupSelect {
#define SCE_DS_COLLAPSED (1<<1)
#define SCE_NLA_EDIT_ON (1<<2)
#define SCE_FRAME_DROP (1<<3)
+#define SCE_KEYS_NO_SELONLY (1<<4)
/* return flag BKE_scene_base_iter_next functions */
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 742bdba6fad..ab3fe1b51b9 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -183,6 +183,14 @@ typedef struct ThemeUI {
/* Axis Colors */
char xaxis[4], yaxis[4], zaxis[4];
+
+ /* Manipulator Colors. */
+ char manipulator_hi[4];
+ char manipulator_primary[4];
+ char manipulator_secondary[4];
+ char manipulator_a[4];
+ char manipulator_b[4];
+ char pad2[4];
} ThemeUI;
/* try to put them all in one, if needed a special struct can be created as well
@@ -473,7 +481,7 @@ typedef struct UserDef {
int scrollback; /* console scrollback limit */
int dpi; /* range 48-128? */
float ui_scale; /* interface scale */
- int pad1;
+ int ui_line_width; /* interface line width */
char node_margin; /* node insert offset (aka auto-offset) margin, but might be useful for later stuff as well */
char pad2;
short transopts; /* eUserpref_Translation_Flags */
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index 74efd2e7ed2..e6f2d19b9cd 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -132,6 +132,7 @@ extern StructRNA RNA_CompositorNodeCombRGBA;
extern StructRNA RNA_CompositorNodeCombYCCA;
extern StructRNA RNA_CompositorNodeCombYUVA;
extern StructRNA RNA_CompositorNodeComposite;
+extern StructRNA RNA_CompositorNodeCornerPin;
extern StructRNA RNA_CompositorNodeCrop;
extern StructRNA RNA_CompositorNodeCurveRGB;
extern StructRNA RNA_CompositorNodeCurveVec;
@@ -175,6 +176,7 @@ extern StructRNA RNA_CompositorNodeSepYCCA;
extern StructRNA RNA_CompositorNodeSepYUVA;
extern StructRNA RNA_CompositorNodeSetAlpha;
extern StructRNA RNA_CompositorNodeSplitViewer;
+extern StructRNA RNA_CompositorNodeSunBeams;
extern StructRNA RNA_CompositorNodeSwitchView;
extern StructRNA RNA_CompositorNodeTexture;
extern StructRNA RNA_CompositorNodeTime;
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 54938b236d5..0be3d2fc3c8 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -70,7 +70,8 @@ void RNA_def_struct_refine_func(StructRNA *srna, const char *refine);
void RNA_def_struct_idprops_func(StructRNA *srna, const char *refine);
void RNA_def_struct_register_funcs(StructRNA *srna, const char *reg, const char *unreg, const char *instance);
void RNA_def_struct_path_func(StructRNA *srna, const char *path);
-void RNA_def_struct_identifier(StructRNA *srna, const char *identifier);
+void RNA_def_struct_identifier_no_struct_map(StructRNA *srna, const char *identifier);
+void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier);
void RNA_def_struct_ui_text(StructRNA *srna, const char *name, const char *description);
void RNA_def_struct_ui_icon(StructRNA *srna, int icon);
void RNA_struct_free_extension(StructRNA *srna, ExtensionRNA *ext);
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 985192c6b35..0327bf6dd58 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -235,7 +235,7 @@ if(WITH_IMAGE_FRAMESERVER)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 579b72e55ad..bb3212d0df9 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -2583,17 +2583,23 @@ static void rna_generate_blender(BlenderRNA *brna, FILE *f)
{
StructRNA *srna;
- fprintf(f, "BlenderRNA BLENDER_RNA = {");
-
+ fprintf(f,
+ "BlenderRNA BLENDER_RNA = {\n"
+ "\t.structs = {"
+ );
srna = brna->structs.first;
- if (srna) fprintf(f, "{&RNA_%s, ", srna->identifier);
- else fprintf(f, "{NULL, ");
+ if (srna) fprintf(f, "&RNA_%s, ", srna->identifier);
+ else fprintf(f, "NULL, ");
srna = brna->structs.last;
- if (srna) fprintf(f, "&RNA_%s}", srna->identifier);
- else fprintf(f, "NULL}");
+ if (srna) fprintf(f, "&RNA_%s},\n", srna->identifier);
+ else fprintf(f, "NULL},\n");
- fprintf(f, "};\n\n");
+ fprintf(f,
+ "\t.structs_map = NULL,\n"
+ "\t.structs_len = 0,\n"
+ "};\n\n"
+ );
}
static void rna_generate_property_prototypes(BlenderRNA *UNUSED(brna), StructRNA *srna, FILE *f)
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index f349d4a44dc..9a7fd9589b0 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -77,6 +77,9 @@ void RNA_init(void)
StructRNA *srna;
PropertyRNA *prop;
+ BLENDER_RNA.structs_map = BLI_ghash_str_new_ex(__func__, 2048);
+ BLENDER_RNA.structs_len = 0;
+
for (srna = BLENDER_RNA.structs.first; srna; srna = srna->cont.next) {
if (!srna->cont.prophash) {
srna->cont.prophash = BLI_ghash_str_new("RNA_init gh");
@@ -87,6 +90,8 @@ void RNA_init(void)
}
}
}
+ BLI_ghash_insert(BLENDER_RNA.structs_map, (void *)srna->identifier, srna);
+ BLENDER_RNA.structs_len += 1;
}
}
@@ -514,13 +519,7 @@ static const char *rna_ensure_property_name(const PropertyRNA *prop)
StructRNA *RNA_struct_find(const char *identifier)
{
- StructRNA *type;
- if (identifier) {
- for (type = BLENDER_RNA.structs.first; type; type = type->cont.next)
- if (STREQ(type->identifier, identifier))
- return type;
- }
- return NULL;
+ return BLI_ghash_lookup(BLENDER_RNA.structs_map, identifier);
}
const char *RNA_struct_identifier(const StructRNA *type)
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 014a08b70ce..a2c5d90b91e 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -481,7 +481,7 @@ static int rna_Armature_is_editmode_get(PointerRNA *ptr)
static void rna_Armature_transform(struct bArmature *arm, float *mat)
{
- ED_armature_transform(arm, (float (*)[4])mat);
+ ED_armature_transform(arm, (float (*)[4])mat, true);
}
#else
diff --git a/source/blender/makesrna/intern/rna_curve_api.c b/source/blender/makesrna/intern/rna_curve_api.c
index 4da262daf8d..b518b0cb5b0 100644
--- a/source/blender/makesrna/intern/rna_curve_api.c
+++ b/source/blender/makesrna/intern/rna_curve_api.c
@@ -45,7 +45,7 @@
#ifdef RNA_RUNTIME
static void rna_Curve_transform(Curve *cu, float *mat, int shape_keys)
{
- BKE_curve_transform(cu, (float (*)[4])mat, shape_keys);
+ BKE_curve_transform(cu, (float (*)[4])mat, shape_keys, true);
DEG_id_tag_update(&cu->id, 0);
}
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 42c0344f46e..b10a2b33317 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -135,6 +135,36 @@ void rna_freelistN(ListBase *listbase)
listbase->first = listbase->last = NULL;
}
+static void rna_brna_structs_add(BlenderRNA *brna, StructRNA *srna)
+{
+ rna_addtail(&brna->structs, srna);
+ brna->structs_len += 1;
+
+ /* This exception is only needed for pre-processing.
+ * otherwise we don't allow empty names. */
+ if (srna->identifier[0] != '\0') {
+ BLI_ghash_insert(brna->structs_map, (void *)srna->identifier, srna);
+ }
+}
+
+#ifdef RNA_RUNTIME
+static void rna_brna_structs_remove_and_free(BlenderRNA *brna, StructRNA *srna)
+{
+ if (brna->structs_map) {
+ if (srna->identifier[0] != '\0') {
+ BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL);
+ }
+ }
+
+ RNA_def_struct_free_pointers(srna);
+
+ if (srna->flag & STRUCT_RUNTIME) {
+ rna_freelinkN(&brna->structs, srna);
+ }
+ brna->structs_len -= 1;
+}
+#endif
+
StructDefRNA *rna_find_struct_def(StructRNA *srna)
{
StructDefRNA *dsrna;
@@ -534,6 +564,8 @@ BlenderRNA *RNA_create(void)
const char *error_message = NULL;
BLI_listbase_clear(&DefRNA.structs);
+ brna->structs_map = BLI_ghash_str_new_ex(__func__, 2048);
+
DefRNA.error = 0;
DefRNA.preprocess = 1;
@@ -640,10 +672,8 @@ void RNA_struct_free(BlenderRNA *brna, StructRNA *srna)
rna_freelinkN(&srna->functions, func);
}
- RNA_def_struct_free_pointers(srna);
- if (srna->flag & STRUCT_RUNTIME)
- rna_freelinkN(&brna->structs, srna);
+ rna_brna_structs_remove_and_free(brna, srna);
#else
UNUSED_VARS(brna, srna);
#endif
@@ -654,6 +684,9 @@ void RNA_free(BlenderRNA *brna)
StructRNA *srna, *nextsrna;
FunctionRNA *func;
+ BLI_ghash_free(brna->structs_map, NULL, NULL);
+ brna->structs_map = NULL;
+
if (DefRNA.preprocess) {
RNA_define_free(brna);
@@ -747,7 +780,7 @@ StructRNA *RNA_def_struct_ptr(BlenderRNA *brna, const char *identifier, StructRN
if (!srnafrom)
srna->icon = ICON_DOT;
- rna_addtail(&brna->structs, srna);
+ rna_brna_structs_add(brna, srna);
if (DefRNA.preprocess) {
ds = MEM_callocN(sizeof(StructDefRNA), "StructDefRNA");
@@ -819,10 +852,8 @@ StructRNA *RNA_def_struct(BlenderRNA *brna, const char *identifier, const char *
if (from) {
/* find struct to derive from */
- for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
- if (STREQ(srnafrom->identifier, from))
- break;
-
+ /* Inline RNA_struct_find(...) because it wont link from here. */
+ srnafrom = BLI_ghash_lookup(brna->structs_map, from);
if (!srnafrom) {
fprintf(stderr, "%s: struct %s not found to define %s.\n", __func__, from, identifier);
DefRNA.error = 1;
@@ -901,10 +932,7 @@ void RNA_def_struct_nested(BlenderRNA *brna, StructRNA *srna, const char *struct
StructRNA *srnafrom;
/* find struct to derive from */
- for (srnafrom = brna->structs.first; srnafrom; srnafrom = srnafrom->cont.next)
- if (STREQ(srnafrom->identifier, structname))
- break;
-
+ srnafrom = BLI_ghash_lookup(brna->structs_map, structname);
if (!srnafrom) {
fprintf(stderr, "%s: struct %s not found for %s.\n", __func__, structname, srna->identifier);
DefRNA.error = 1;
@@ -965,7 +993,30 @@ void RNA_def_struct_path_func(StructRNA *srna, const char *path)
if (path) srna->path = (StructPathFunc)path;
}
-void RNA_def_struct_identifier(StructRNA *srna, const char *identifier)
+void RNA_def_struct_identifier(BlenderRNA *brna, StructRNA *srna, const char *identifier)
+{
+ if (DefRNA.preprocess) {
+ fprintf(stderr, "%s: only at runtime.\n", __func__);
+ return;
+ }
+
+ /* Operator registration may set twice, see: operator_properties_init */
+ if (identifier != srna->identifier) {
+ if (srna->identifier[0] != '\0') {
+ BLI_ghash_remove(brna->structs_map, (void *)srna->identifier, NULL, NULL);
+ }
+ if (identifier[0] != '\0') {
+ BLI_ghash_insert(brna->structs_map, (void *)identifier, srna);
+ }
+ }
+
+ srna->identifier = identifier;
+}
+
+/**
+ * Only used in one case when we name the struct for the purpose of useful error messages.
+ */
+void RNA_def_struct_identifier_no_struct_map(StructRNA *srna, const char *identifier)
{
if (DefRNA.preprocess) {
fprintf(stderr, "%s: only at runtime.\n", __func__);
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index c412d110e5e..3e17704ccc6 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -404,6 +404,9 @@ struct StructRNA {
struct BlenderRNA {
ListBase structs;
+ struct GHash *structs_map;
+ /* Needed because types with an empty identifier aren't included in 'structs_map'. */
+ unsigned int structs_len;
};
#define CONTAINER_RNA_ID(cont) (*(const char **)(((ContainerRNA *)(cont))+1))
diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c
index d01ce407815..bd10bbc49ea 100644
--- a/source/blender/makesrna/intern/rna_material.c
+++ b/source/blender/makesrna/intern/rna_material.c
@@ -1869,6 +1869,18 @@ void RNA_def_material(BlenderRNA *brna)
"(avoids transparency sorting problems)");
RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+ prop = RNA_def_property(srna, "use_screen_refraction", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "blend_flag", MA_BL_SS_REFRACTION);
+ RNA_def_property_ui_text(prop, "Screen Space Refraction" , "Use raytraced screen space refractions");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
+ prop = RNA_def_property(srna, "refraction_depth", PROP_FLOAT, PROP_DISTANCE);
+ RNA_def_property_float_sdna(prop, NULL, "refract_depth");
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
+ RNA_def_property_ui_text(prop, "Refraction Depth", "Approximate the thickness of the object to compute two refraction "
+ "event (0 is disabled)");
+ RNA_def_property_update(prop, 0, "rna_Material_draw_update");
+
/* For Preview Render */
prop = RNA_def_property(srna, "preview_render_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "pr_type");
diff --git a/source/blender/makesrna/intern/rna_meta_api.c b/source/blender/makesrna/intern/rna_meta_api.c
index 117162babd5..46547677dfd 100644
--- a/source/blender/makesrna/intern/rna_meta_api.c
+++ b/source/blender/makesrna/intern/rna_meta_api.c
@@ -45,7 +45,7 @@
#ifdef RNA_RUNTIME
static void rna_Meta_transform(struct MetaBall *mb, float *mat)
{
- BKE_mball_transform(mb, (float (*)[4])mat);
+ BKE_mball_transform(mb, (float (*)[4])mat, true);
DEG_id_tag_update(&mb->id, 0);
}
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 9ea4bed5857..51d377ed214 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -599,11 +599,10 @@ static void rna_NodeTree_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
RNA_struct_free_extension(type, &nt->ext);
+ RNA_struct_free(&BLENDER_RNA, type);
ntreeTypeFreeLink(nt);
- RNA_struct_free(&BLENDER_RNA, type);
-
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
}
@@ -1352,11 +1351,11 @@ static void rna_Node_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
RNA_struct_free_extension(type, &nt->ext);
+ RNA_struct_free(&BLENDER_RNA, type);
/* this also frees the allocated nt pointer, no MEM_free call needed! */
nodeUnregisterType(nt);
- RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
@@ -1814,10 +1813,10 @@ static void rna_NodeSocket_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
RNA_struct_free_extension(type, &st->ext_socket);
+ RNA_struct_free(&BLENDER_RNA, type);
nodeUnregisterSocketType(st);
- RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
WM_main_add_notifier(NC_NODE | NA_EDITED, NULL);
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 19002d1229b..7bcf116d6b7 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -35,6 +35,8 @@
#include "DEG_depsgraph.h"
+#include "BKE_scene.h"
+
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -125,6 +127,11 @@ static int engine_support_display_space_shader(RenderEngine *UNUSED(engine), Sce
return IMB_colormanagement_support_glsl_draw(&scene->view_settings);
}
+static int engine_get_preview_pixel_size(RenderEngine *UNUSED(engine), Scene *scene)
+{
+ return BKE_render_preview_pixel_size(&scene->r);
+}
+
static void engine_bind_display_space_shader(RenderEngine *UNUSED(engine), Scene *scene)
{
IMB_colormanagement_setup_glsl_draw(&scene->view_settings,
@@ -299,8 +306,8 @@ static void rna_RenderEngine_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
RNA_struct_free_extension(type, &et->ext);
- BLI_freelinkN(&R_engines, et);
RNA_struct_free(&BLENDER_RNA, type);
+ BLI_freelinkN(&R_engines, et);
}
static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
@@ -686,6 +693,13 @@ static void rna_def_render_engine(BlenderRNA *brna)
parm = RNA_def_boolean(func, "supported", 0, "Supported", "");
RNA_def_function_return(func, parm);
+ func = RNA_def_function(srna, "get_preview_pixel_size", "engine_get_preview_pixel_size");
+ RNA_def_function_ui_description(func, "Get the pixel size that should be used for preview rendering");
+ parm = RNA_def_pointer(func, "scene", "Scene", "", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_int(func, "pixel_size", 0, 1, 8, "Pixel Size", "", 1, 8);
+ RNA_def_function_return(func, parm);
+
RNA_define_verify_sdna(0);
prop = RNA_def_property(srna, "is_animation", PROP_BOOLEAN, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_rna.c b/source/blender/makesrna/intern/rna_rna.c
index abded187b33..bbd0fe2486e 100644
--- a/source/blender/makesrna/intern/rna_rna.c
+++ b/source/blender/makesrna/intern/rna_rna.c
@@ -985,19 +985,22 @@ static int rna_Function_use_self_type_get(PointerRNA *ptr)
static void rna_BlenderRNA_structs_begin(CollectionPropertyIterator *iter, PointerRNA *ptr)
{
- rna_iterator_listbase_begin(iter, &((BlenderRNA *)ptr->data)->structs, NULL);
+ BlenderRNA *brna = ptr->data;
+ rna_iterator_listbase_begin(iter, &brna->structs, NULL);
}
/* optional, for faster lookups */
static int rna_BlenderRNA_structs_length(PointerRNA *ptr)
{
- return BLI_listbase_count(&((BlenderRNA *)ptr->data)->structs);
+ BlenderRNA *brna = ptr->data;
+ BLI_assert(brna->structs_len == BLI_listbase_count(&brna->structs));
+ return brna->structs_len;
}
static int rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
{
- StructRNA *srna = BLI_findlink(&((BlenderRNA *)ptr->data)->structs, index);
-
- if (srna) {
+ BlenderRNA *brna = ptr->data;
+ StructRNA *srna = index < brna->structs_len ? BLI_findlink(&brna->structs, index) : NULL;
+ if (srna != NULL) {
RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
return true;
}
@@ -1007,12 +1010,11 @@ static int rna_BlenderRNA_structs_lookup_int(PointerRNA *ptr, int index, Pointer
}
static int rna_BlenderRNA_structs_lookup_string(PointerRNA *ptr, const char *key, PointerRNA *r_ptr)
{
- StructRNA *srna = ((BlenderRNA *)ptr->data)->structs.first;
- for (; srna; srna = srna->cont.next) {
- if (key[0] == srna->identifier[0] && STREQ(key, srna->identifier)) {
- RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
- return true;
- }
+ BlenderRNA *brna = ptr->data;
+ StructRNA *srna = BLI_ghash_lookup(brna->structs_map, (void *)key);
+ if (srna != NULL) {
+ RNA_pointer_create(NULL, &RNA_Struct, srna, r_ptr);
+ return true;
}
return false;
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 7587f4fe2a1..40d5b3a7378 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -65,7 +65,7 @@
#ifdef WITH_QUICKTIME
# include "quicktime_export.h"
-# include AUD_TYPES_H
+# include <AUD_Types.h>
#endif
#ifdef WITH_FFMPEG
@@ -1885,6 +1885,13 @@ static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), Pointer
rna_Scene_use_simplify_update(bmain, sce, ptr);
}
+static void rna_SceneRenderData_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
+{
+ Scene *sce = ptr->id.data;
+
+ DEG_id_tag_update(&sce->id, 0);
+}
+
static void rna_Scene_use_persistent_data_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
Scene *sce = ptr->id.data;
@@ -2152,7 +2159,7 @@ static char *rna_MeshStatVis_path(PointerRNA *UNUSED(ptr))
static void rna_Scene_update_active_object_data(bContext *C, PointerRNA *UNUSED(ptr))
{
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob) {
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -2556,6 +2563,9 @@ static void rna_LayerEngineSettings_##_ENGINE_##_##_NAME_##_set(PointerRNA *ptr,
#define RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(_NAME_) \
RNA_LAYER_ENGINE_GET_SET(float, Eevee, COLLECTION_MODE_NONE, _NAME_)
+#define RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT_ARRAY(_NAME_, _LEN_) \
+ RNA_LAYER_ENGINE_GET_SET_ARRAY(float, Eevee, COLLECTION_MODE_NONE, _NAME_, _LEN_)
+
#define RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(_NAME_) \
RNA_LAYER_ENGINE_GET_SET(int, Eevee, COLLECTION_MODE_NONE, _NAME_)
@@ -2610,7 +2620,10 @@ RNA_LAYER_ENGINE_CLAY_GET_SET_FLOAT(hair_brightness_randomness)
/* SceneLayer settings. */
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(gtao_enable)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(gtao_use_bent_normals)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(gtao_denoise)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(gtao_bounce)
RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(gtao_factor)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(gtao_quality)
RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(gtao_distance)
RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(gtao_samples)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(dof_enable)
@@ -2618,8 +2631,10 @@ RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bokeh_max_size)
RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bokeh_threshold)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(bloom_enable)
RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_threshold)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT_ARRAY(bloom_color, 3)
RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_knee)
RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_radius)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_clamp)
RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(bloom_intensity)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(motion_blur_enable)
RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(motion_blur_samples)
@@ -2634,6 +2649,7 @@ RNA_LAYER_ENGINE_EEVEE_GET_SET_FLOAT(volumetric_light_clamp)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_shadows)
RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(volumetric_shadow_samples)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(volumetric_colored_transmittance)
+RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_refraction)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_enable)
RNA_LAYER_ENGINE_EEVEE_GET_SET_BOOL(ssr_halfres)
RNA_LAYER_ENGINE_EEVEE_GET_SET_INT(ssr_ray_count)
@@ -2684,7 +2700,7 @@ static void rna_LayerCollectionEngineSettings_wire_update(bContext *C, PointerRN
{
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob != NULL && ob->type == OB_MESH) {
BKE_mesh_batch_cache_dirty(ob->data, BKE_MESH_BATCH_DIRTY_NOCHECK);
@@ -6208,6 +6224,13 @@ static void rna_def_scene_layer_engine_settings_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+ prop = RNA_def_property(srna, "ssr_refraction", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_refraction_get",
+ "rna_LayerEngineSettings_Eevee_ssr_refraction_set");
+ RNA_def_property_ui_text(prop, "Screen Space Refractions", "Enable screen space Refractions");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
prop = RNA_def_property(srna, "ssr_halfres", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_ssr_halfres_get",
"rna_LayerEngineSettings_Eevee_ssr_halfres_set");
@@ -6357,14 +6380,36 @@ static void rna_def_scene_layer_engine_settings_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+ prop = RNA_def_property(srna, "gtao_denoise", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_denoise_get",
+ "rna_LayerEngineSettings_Eevee_gtao_denoise_set");
+ RNA_def_property_ui_text(prop, "Denoise", "Use denoising to filter the resulting occlusion and bent normal but exhibit 2x2 pixel blocks");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
+ prop = RNA_def_property(srna, "gtao_bounce", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_bounce_get",
+ "rna_LayerEngineSettings_Eevee_gtao_bounce_set");
+ RNA_def_property_ui_text(prop, "Bounces Approximation", "An approximation to simulate light bounces "
+ "giving less occlusion on brighter objects");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
prop = RNA_def_property(srna, "gtao_factor", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_factor_get", "rna_LayerEngineSettings_Eevee_gtao_factor_set", NULL);
RNA_def_property_ui_text(prop, "Factor", "Factor for ambient occlusion blending");
- RNA_def_property_range(prop, 0, FLT_MAX);
+ RNA_def_property_range(prop, 0.0f, FLT_MAX);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1f, 2);
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+ prop = RNA_def_property(srna, "gtao_quality", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_quality_get", "rna_LayerEngineSettings_Eevee_gtao_quality_set", NULL);
+ RNA_def_property_ui_text(prop, "Trace Quality", "Quality of the horizon search");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_LayerCollectionEngineSettings_update");
+
prop = RNA_def_property(srna, "gtao_distance", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_gtao_distance_get", "rna_LayerEngineSettings_Eevee_gtao_distance_set", NULL);
RNA_def_property_ui_text(prop, "Distance", "Distance of object that contribute to the ambient occlusion effect");
@@ -6424,6 +6469,14 @@ static void rna_def_scene_layer_engine_settings_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+ prop = RNA_def_property(srna, "bloom_color", PROP_FLOAT, PROP_COLOR);
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_color_get",
+ "rna_LayerEngineSettings_Eevee_bloom_color_set", NULL);
+ RNA_def_property_ui_text(prop, "Color", "Color applied to the bloom effect");
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
prop = RNA_def_property(srna, "bloom_knee", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_knee_get",
"rna_LayerEngineSettings_Eevee_bloom_knee_set", NULL);
@@ -6441,6 +6494,15 @@ static void rna_def_scene_layer_engine_settings_eevee(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+ prop = RNA_def_property(srna, "bloom_clamp", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_clamp_get",
+ "rna_LayerEngineSettings_Eevee_bloom_clamp_set", NULL);
+ RNA_def_property_ui_text(prop, "Clamp", "Maximum intensity a bloom pixel can have");
+ RNA_def_property_range(prop, 0.0f, 1000.0f);
+ RNA_def_property_ui_range(prop, 0.0f, 10.0f, 1, 3);
+ RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE);
+ RNA_def_property_update(prop, NC_SCENE | ND_LAYER_CONTENT, "rna_SceneLayerEngineSettings_update");
+
prop = RNA_def_property(srna, "bloom_intensity", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_funcs(prop, "rna_LayerEngineSettings_Eevee_bloom_intensity_get",
"rna_LayerEngineSettings_Eevee_bloom_intensity_set", NULL);
@@ -7909,6 +7971,15 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem pixel_size_items[] = {
+ {0, "AUTO", 0, "Automatic", "Automatic pixel size, depends on the UI scale"},
+ {1, "1", 0, "1x", "Render at full resolution"},
+ {2, "2", 0, "2x", "Render at 50% resolution"},
+ {4, "4", 0, "4x", "Render at 25% resolution"},
+ {8, "8", 0, "8x", "Render at 12.5% resolution"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
static EnumPropertyItem octree_resolution_items[] = {
{64, "64", 0, "64", ""},
{128, "128", 0, "128", ""},
@@ -8032,6 +8103,12 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
"progressively increasing it to the full viewport size");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
+ prop = RNA_def_property(srna, "preview_pixel_size", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "preview_pixel_size");
+ RNA_def_property_enum_items(prop, pixel_size_items);
+ RNA_def_property_ui_text(prop, "Pixel Size", "Pixel size for viewport rendering");
+ RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_SceneRenderData_update");
+
prop = RNA_def_property(srna, "pixel_aspect_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xasp");
RNA_def_property_flag(prop, PROP_PROPORTIONAL);
@@ -8264,8 +8341,8 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "blurfac");
RNA_def_property_ui_range(prop, 0.01f, 2.0f, 1, 2);
- RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close");
- RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
+ RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close "
+ "(NOTE: Blender Internal does not support animated shutter)");
RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update");
prop = RNA_def_property(srna, "motion_blur_shutter_curve", PROP_POINTER, PROP_NONE);
@@ -8627,11 +8704,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
/* sequencer draw options */
- prop = RNA_def_property(srna, "use_sequencer_gl_preview", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_GL_PREV);
- RNA_def_property_ui_text(prop, "Sequencer OpenGL", "");
- RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SceneSequencer_update");
-
#if 0 /* see R_SEQ_GL_REND comment */
prop = RNA_def_property(srna, "use_sequencer_gl_render", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_GL_REND);
@@ -8644,10 +8716,13 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Sequencer Preview Shading", "Method to draw in the sequencer view");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SceneSequencer_update");
+#if 0 /* UNUSED, see R_SEQ_GL_REND comment */
prop = RNA_def_property(srna, "sequencer_gl_render", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "seq_rend_type");
RNA_def_property_enum_items(prop, rna_enum_viewport_shade_items);
+ /* XXX Label and tooltips are obviously wrong! */
RNA_def_property_ui_text(prop, "Sequencer Preview Shading", "Method to draw in the sequencer view");
+#endif
prop = RNA_def_property(srna, "use_sequencer_gl_textured_solid", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "seq_flag", R_SEQ_SOLID_TEX);
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index ff870ec40b7..a1ef3f17bd6 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -151,7 +151,7 @@ static void rna_SceneRender_get_frame_path(RenderData *rd, int frame, int previe
}
static void rna_Scene_ray_cast(
- Scene *scene, bContext *C, SceneLayer *sl, float origin[3], float direction[3], float ray_dist,
+ Scene *scene, SceneLayer *sl, float origin[3], float direction[3], float ray_dist,
int *r_success, float r_location[3], float r_normal[3], int *r_index,
Object **r_ob, float r_obmat[16])
{
@@ -161,7 +161,7 @@ static void rna_Scene_ray_cast(
G.main, scene, sl, 0);
bool ret = ED_transform_snap_object_project_ray_ex(
- C, sctx,
+ sctx,
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
},
@@ -352,7 +352,6 @@ void RNA_api_scene(StructRNA *srna)
/* Ray Cast */
func = RNA_def_function(srna, "ray_cast", "rna_Scene_ray_cast");
RNA_def_function_ui_description(func, "Cast a ray onto in object space");
- RNA_def_function_flag(func, FUNC_USE_CONTEXT);
parm = RNA_def_pointer(func, "scene_layer", "SceneLayer", "", "Scene Layer");
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
/* ray start and end */
diff --git a/source/blender/makesrna/intern/rna_sculpt_paint.c b/source/blender/makesrna/intern/rna_sculpt_paint.c
index 5090c06ad21..eb352057928 100644
--- a/source/blender/makesrna/intern/rna_sculpt_paint.c
+++ b/source/blender/makesrna/intern/rna_sculpt_paint.c
@@ -158,7 +158,7 @@ static void rna_ParticleEdit_redo(bContext *C, PointerRNA *UNUSED(ptr))
{
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
PTCacheEdit *edit = PE_get_current(scene, sl, ob);
if (!edit)
@@ -170,7 +170,7 @@ static void rna_ParticleEdit_redo(bContext *C, PointerRNA *UNUSED(ptr))
static void rna_ParticleEdit_update(Main *UNUSED(bmain), Scene *UNUSED(scene), bContext *C, PointerRNA *UNUSED(ptr))
{
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob) DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
@@ -194,7 +194,7 @@ static EnumPropertyItem *rna_ParticleEdit_tool_itemf(bContext *C, PointerRNA *UN
PropertyRNA *UNUSED(prop), bool *UNUSED(r_free))
{
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
#if 0
Scene *scene = CTX_data_scene(C);
PTCacheEdit *edit = PE_get_current(scene, ob);
@@ -270,7 +270,7 @@ static void rna_Sculpt_update(bContext *C, PointerRNA *UNUSED(ptr))
{
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob) {
DEG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -286,7 +286,7 @@ static void rna_Sculpt_update(bContext *C, PointerRNA *UNUSED(ptr))
static void rna_Sculpt_ShowDiffuseColor_update(bContext *C, Scene *scene, PointerRNA *UNUSED(ptr))
{
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob && ob->sculpt) {
Sculpt *sd = scene->toolsettings->sculpt;
@@ -349,7 +349,7 @@ static void rna_ImaPaint_mode_update(bContext *C, PointerRNA *UNUSED(ptr))
{
Scene *scene = CTX_data_scene(C);\
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob && ob->type == OB_MESH) {
/* of course we need to invalidate here */
@@ -366,7 +366,7 @@ static void rna_ImaPaint_stencil_update(bContext *C, PointerRNA *UNUSED(ptr))
{
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if (ob && ob->type == OB_MESH) {
GPU_drawobject_free(ob->derivedFinal);
@@ -380,7 +380,7 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA *UNUSED(ptr))
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
bScreen *sc;
Image *ima = scene->toolsettings->imapaint.canvas;
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index a43baffeb26..cc12cd9568e 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -1308,7 +1308,7 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, bContext *C, Sce
{
SpaceAction *saction = (SpaceAction *)(ptr->data);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *obact = OBACT_NEW;
+ Object *obact = OBACT_NEW(sl);
/* we must set this action to be the one used by active object (if not pinned) */
if (obact /* && saction->pin == 0*/) {
@@ -1384,7 +1384,7 @@ static void rna_SpaceDopeSheetEditor_mode_update(bContext *C, PointerRNA *ptr)
{
SpaceAction *saction = (SpaceAction *)(ptr->data);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *obact = OBACT_NEW;
+ Object *obact = OBACT_NEW(sl);
/* special exceptions for ShapeKey Editor mode */
if (saction->mode == SACTCONT_SHAPEKEY) {
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 54b82fc89d6..64b41ac789f 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -177,9 +177,9 @@ static void rna_Panel_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
RNA_struct_free_extension(type, &pt->ext);
+ RNA_struct_free(&BLENDER_RNA, type);
BLI_freelinkN(&art->paneltypes, pt);
- RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -455,11 +455,10 @@ static void rna_UIList_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
RNA_struct_free_extension(type, &ult->ext);
+ RNA_struct_free(&BLENDER_RNA, type);
WM_uilisttype_freelink(ult);
- RNA_struct_free(&BLENDER_RNA, type);
-
/* update while blender is running */
WM_main_add_notifier(NC_WINDOW, NULL);
}
@@ -551,9 +550,9 @@ static void rna_Header_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
RNA_struct_free_extension(type, &ht->ext);
+ RNA_struct_free(&BLENDER_RNA, type);
BLI_freelinkN(&art->headertypes, ht);
- RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -673,11 +672,10 @@ static void rna_Menu_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
RNA_struct_free_extension(type, &mt->ext);
+ RNA_struct_free(&BLENDER_RNA, type);
WM_menutype_freelink(mt);
- RNA_struct_free(&BLENDER_RNA, type);
-
/* update while blender is running */
WM_main_add_notifier(NC_WINDOW, NULL);
}
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 0a4e69934b7..628adbddd36 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -519,7 +519,6 @@ static EnumPropertyItem *rna_userdef_audio_device_itemf(bContext *UNUSED(C), Poi
int totitem = 0;
EnumPropertyItem *item = NULL;
-#ifdef WITH_SYSTEM_AUDASPACE
int i;
char **names = BKE_sound_get_device_names();
@@ -528,31 +527,6 @@ static EnumPropertyItem *rna_userdef_audio_device_itemf(bContext *UNUSED(C), Poi
EnumPropertyItem new_item = {i, names[i], 0, names[i], names[i]};
RNA_enum_item_add(&item, &totitem, &new_item);
}
-#else
- /* NONE */
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
-
-#ifdef WITH_SDL
-# ifdef WITH_SDL_DYNLOAD
- if (sdlewInit() == SDLEW_SUCCESS)
-# endif
- {
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index]);
- }
- index++;
-#endif
-
-#ifdef WITH_OPENAL
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index++]);
-#endif
-
-#ifdef WITH_JACK
- if (BKE_sound_is_jack_supported()) {
- RNA_enum_item_add(&item, &totitem, &audio_device_items[index]);
- }
- index++;
-#endif
-#endif
/* may be unused */
UNUSED_VARS(index, audio_device_items);
@@ -609,9 +583,9 @@ static void rna_AddonPref_unregister(Main *UNUSED(bmain), StructRNA *type)
return;
RNA_struct_free_extension(type, &apt->ext);
+ RNA_struct_free(&BLENDER_RNA, type);
BKE_addon_pref_type_remove(apt);
- RNA_struct_free(&BLENDER_RNA, type);
/* update while blender is running */
WM_main_add_notifier(NC_WINDOW, NULL);
@@ -1074,6 +1048,37 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
RNA_def_property_array(prop, 3);
RNA_def_property_ui_text(prop, "Z Axis", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ /* Generic manipulator colors. */
+ prop = RNA_def_property(srna, "manipulator_hi", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "manipulator_hi");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Manipulator Highlight", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "manipulator_primary", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "manipulator_primary");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Manipulator Primary", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "manipulator_secondary", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "manipulator_secondary");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Manipulator Secondary", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "manipulator_a", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "manipulator_a");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Manipulator A", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
+
+ prop = RNA_def_property(srna, "manipulator_b", PROP_FLOAT, PROP_COLOR_GAMMA);
+ RNA_def_property_float_sdna(prop, NULL, "manipulator_b");
+ RNA_def_property_array(prop, 3);
+ RNA_def_property_ui_text(prop, "Manipulator B", "");
+ RNA_def_property_update(prop, 0, "rna_userdef_update");
}
static void rna_def_userdef_theme_space_common(StructRNA *srna)
@@ -1277,7 +1282,7 @@ static void rna_def_userdef_theme_spaces_vertex(StructRNA *srna)
RNA_def_property_update(prop, 0, "rna_userdef_update");
prop = RNA_def_property(srna, "vertex_size", PROP_INT, PROP_NONE);
- RNA_def_property_range(prop, 1, 10);
+ RNA_def_property_range(prop, 1, 32);
RNA_def_property_ui_text(prop, "Vertex Size", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
@@ -1499,7 +1504,7 @@ static void rna_def_userdef_theme_spaces_curves(StructRNA *srna, bool incl_nurbs
RNA_def_property_update(prop, 0, "rna_userdef_update");
prop = RNA_def_property(srna, "handle_vertex_size", PROP_INT, PROP_NONE);
- RNA_def_property_range(prop, 0, 255);
+ RNA_def_property_range(prop, 1, 100);
RNA_def_property_ui_text(prop, "Handle Vertex Size", "");
RNA_def_property_update(prop, 0, "rna_userdef_update");
}
@@ -3307,6 +3312,13 @@ static void rna_def_userdef_view(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
+ static EnumPropertyItem line_width[] = {
+ {-1, "THIN", 0, "Thin", "Thinner lines than the default"},
+ { 0, "AUTO", 0, "Auto", "Automatic line width based on UI scale"},
+ { 1, "THICK", 0, "Thick", "Thicker lines than the default"},
+ {0, NULL, 0, NULL, NULL}
+ };
+
PropertyRNA *prop;
StructRNA *srna;
@@ -3324,6 +3336,12 @@ static void rna_def_userdef_view(BlenderRNA *brna)
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
+ prop = RNA_def_property(srna, "ui_line_width", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_items(prop, line_width);
+ RNA_def_property_ui_text(prop, "UI Line Width",
+ "Changes the thickness of lines and points in the interface");
+ RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
+
/* display */
prop = RNA_def_property(srna, "show_tooltips", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_TOOLTIPS);
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index fe30890d5ba..14e27235b81 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -1361,10 +1361,11 @@ static void rna_Operator_unregister(struct Main *bmain, StructRNA *type)
idname = ot->idname;
WM_operatortype_remove_ptr(ot);
- MEM_freeN((void *)idname);
/* not to be confused with the RNA_struct_free that WM_operatortype_remove calls, they are 2 different srna's */
RNA_struct_free(&BLENDER_RNA, type);
+
+ MEM_freeN((void *)idname);
}
static void **rna_Operator_instance(PointerRNA *ptr)
diff --git a/source/blender/makesrna/intern/rna_wm_manipulator.c b/source/blender/makesrna/intern/rna_wm_manipulator.c
index 9334d7da159..5e19298764e 100644
--- a/source/blender/makesrna/intern/rna_wm_manipulator.c
+++ b/source/blender/makesrna/intern/rna_wm_manipulator.c
@@ -369,6 +369,7 @@ RNA_MANIPULATOR_GENERIC_FLOAT_RW_DEF(line_width, line_width);
RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_hover, flag, WM_MANIPULATOR_DRAW_HOVER);
RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_modal, flag, WM_MANIPULATOR_DRAW_MODAL);
RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_value, flag, WM_MANIPULATOR_DRAW_VALUE);
+RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_use_draw_offset_scale, flag, WM_MANIPULATOR_DRAW_OFFSET_SCALE);
RNA_MANIPULATOR_GENERIC_FLAG_RW_DEF(flag_hide, flag, WM_MANIPULATOR_HIDDEN);
/* wmManipulator.state */
@@ -1055,6 +1056,12 @@ static void rna_def_manipulator(BlenderRNA *brna, PropertyRNA *cprop)
prop, "rna_Manipulator_flag_use_draw_value_get", "rna_Manipulator_flag_use_draw_value_set");
RNA_def_property_ui_text(prop, "Draw Value", "Show an indicator for the current value while dragging");
RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
+ /* WM_MANIPULATOR_DRAW_OFFSET_SCALE */
+ prop = RNA_def_property(srna, "use_draw_offset_scale", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_funcs(
+ prop, "rna_Manipulator_flag_use_draw_offset_scale_get", "rna_Manipulator_flag_use_draw_offset_scale_set");
+ RNA_def_property_ui_text(prop, "Draw Value", "Scale the offset matrix (use to apply screen-space offset)");
+ RNA_def_property_update(prop, NC_SCREEN | NA_EDITED, NULL);
/* wmManipulator.state (readonly) */
/* WM_MANIPULATOR_STATE_HIGHLIGHT */
diff --git a/source/blender/makesrna/intern/rna_wm_manipulator_api.c b/source/blender/makesrna/intern/rna_wm_manipulator_api.c
index 7c805512e0b..f40a2208cf9 100644
--- a/source/blender/makesrna/intern/rna_wm_manipulator_api.c
+++ b/source/blender/makesrna/intern/rna_wm_manipulator_api.c
@@ -178,7 +178,7 @@ void RNA_api_manipulator(StructRNA *srna)
func = RNA_def_function(srna, "draw_preset_box", "rna_manipulator_draw_preset_box");
RNA_def_function_ui_description(func, "Draw a box");
parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
- RNA_def_property_flag(parm, PARM_REQUIRED);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
RNA_def_property_ui_text(parm, "", "The matrix to transform");
RNA_def_int(func, "select_id", -1, -1, INT_MAX, "Zero when not selecting", "", -1, INT_MAX);
@@ -187,7 +187,7 @@ void RNA_api_manipulator(StructRNA *srna)
func = RNA_def_function(srna, "draw_preset_arrow", "rna_manipulator_draw_preset_arrow");
RNA_def_function_ui_description(func, "Draw a box");
parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
- RNA_def_property_flag(parm, PARM_REQUIRED);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
RNA_def_property_ui_text(parm, "", "The matrix to transform");
RNA_def_enum(func, "axis", rna_enum_object_axis_items, 2, "", "Arrow Orientation");
@@ -196,7 +196,7 @@ void RNA_api_manipulator(StructRNA *srna)
func = RNA_def_function(srna, "draw_preset_circle", "rna_manipulator_draw_preset_circle");
RNA_def_function_ui_description(func, "Draw a box");
parm = RNA_def_property(func, "matrix", PROP_FLOAT, PROP_MATRIX);
- RNA_def_property_flag(parm, PARM_REQUIRED);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_property_multi_array(parm, 2, rna_matrix_dimsize_4x4);
RNA_def_property_ui_text(parm, "", "The matrix to transform");
RNA_def_enum(func, "axis", rna_enum_object_axis_items, 2, "", "Arrow Orientation");
diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c
index 7530cc4427b..60c7998853e 100644
--- a/source/blender/modifiers/intern/MOD_armature.c
+++ b/source/blender/modifiers/intern/MOD_armature.c
@@ -62,13 +62,13 @@ static void initData(ModifierData *md)
static void copyData(ModifierData *md, ModifierData *target)
{
+#if 0
ArmatureModifierData *amd = (ArmatureModifierData *) md;
+#endif
ArmatureModifierData *tamd = (ArmatureModifierData *) target;
- tamd->object = amd->object;
- tamd->deformflag = amd->deformflag;
- tamd->multi = amd->multi;
- BLI_strncpy(tamd->defgrp_name, amd->defgrp_name, sizeof(tamd->defgrp_name));
+ modifier_copyData_generic(md, target);
+ tamd->prevCos = NULL;
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md))
@@ -110,7 +110,7 @@ static void updateDepsgraph(ModifierData *md,
}
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -131,7 +131,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *em,
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *em,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
ArmatureModifierData *amd = (ArmatureModifierData *) md;
@@ -154,7 +154,7 @@ static void deformVertsEM(
}
static void deformMatricesEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *em,
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *em,
DerivedMesh *derivedData, float (*vertexCos)[3],
float (*defMats)[3][3], int numVerts)
{
@@ -169,7 +169,7 @@ static void deformMatricesEM(
if (!derivedData) dm->release(dm);
}
-static void deformMatrices(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
+static void deformMatrices(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
{
ArmatureModifierData *amd = (ArmatureModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index fcd38f904d8..66ff1fe0a85 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -356,7 +356,7 @@ static void dm_merge_transform(
}
static DerivedMesh *arrayModifier_doArray(
- ArrayModifierData *amd, EvaluationContext *eval_ctx,
+ ArrayModifierData *amd, const EvaluationContext *eval_ctx,
Scene *scene, Object *ob, DerivedMesh *dm,
ModifierApplyFlag flag)
{
@@ -725,7 +725,7 @@ static DerivedMesh *arrayModifier_doArray(
}
-static DerivedMesh *applyModifier(ModifierData *md, EvaluationContext *eval_ctx,
+static DerivedMesh *applyModifier(ModifierData *md, const EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *dm,
ModifierApplyFlag flag)
{
diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c
index b0433cac569..35b8a3fd9cb 100644
--- a/source/blender/modifiers/intern/MOD_bevel.c
+++ b/source/blender/modifiers/intern/MOD_bevel.c
@@ -65,19 +65,11 @@ static void initData(ModifierData *md)
static void copyData(ModifierData *md, ModifierData *target)
{
+#if 0
BevelModifierData *bmd = (BevelModifierData *) md;
BevelModifierData *tbmd = (BevelModifierData *) target;
-
- tbmd->value = bmd->value;
- tbmd->res = bmd->res;
- tbmd->flags = bmd->flags;
- tbmd->val_flags = bmd->val_flags;
- tbmd->lim_flags = bmd->lim_flags;
- tbmd->e_flags = bmd->e_flags;
- tbmd->mat = bmd->mat;
- tbmd->profile = bmd->profile;
- tbmd->bevel_angle = bmd->bevel_angle;
- BLI_strncpy(tbmd->defgrp_name, bmd->defgrp_name, sizeof(tbmd->defgrp_name));
+#endif
+ modifier_copyData_generic(md, target);
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
@@ -94,7 +86,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
/*
* This calls the new bevel code (added since 2.64)
*/
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
struct Object *ob, DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_boolean.c b/source/blender/modifiers/intern/MOD_boolean.c
index 22609ec46b7..26b4bf883a6 100644
--- a/source/blender/modifiers/intern/MOD_boolean.c
+++ b/source/blender/modifiers/intern/MOD_boolean.c
@@ -402,7 +402,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(
}
static DerivedMesh *applyModifier(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag flag)
{
diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c
index 640412e1d27..0a0ad11fe16 100644
--- a/source/blender/modifiers/intern/MOD_build.c
+++ b/source/blender/modifiers/intern/MOD_build.c
@@ -75,7 +75,7 @@ static bool dependsOnTime(ModifierData *UNUSED(md))
return true;
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *UNUSED(ob), DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c
index c2515c5f5de..93a5b9607bf 100644
--- a/source/blender/modifiers/intern/MOD_cast.c
+++ b/source/blender/modifiers/intern/MOD_cast.c
@@ -433,7 +433,7 @@ static void cuboid_do(
}
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -456,7 +456,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, struct BMEditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c
index 10603e6dccf..b234cc63228 100644
--- a/source/blender/modifiers/intern/MOD_cloth.c
+++ b/source/blender/modifiers/intern/MOD_cloth.c
@@ -69,7 +69,7 @@ static void initData(ModifierData *md)
cloth_init(clmd);
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3],
+static void deformVerts(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3],
int numVerts, ModifierApplyFlag UNUSED(flag))
{
DerivedMesh *dm;
diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c
index 0e0e93fc727..b9a2310366a 100644
--- a/source/blender/modifiers/intern/MOD_collision.c
+++ b/source/blender/modifiers/intern/MOD_collision.c
@@ -98,7 +98,7 @@ static bool dependsOnTime(ModifierData *UNUSED(md))
return true;
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int UNUSED(numVerts),
@@ -153,8 +153,6 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
collmd->current_v = MEM_dupallocN(collmd->x); // inter-frame
collmd->mvert_num = mvert_num;
-
- DM_ensure_looptri(dm);
collmd->tri_num = dm->getNumLoopTri(dm);
{
diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c
index 831b3034235..716b918d0f0 100644
--- a/source/blender/modifiers/intern/MOD_correctivesmooth.c
+++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c
@@ -713,7 +713,7 @@ error:
static void deformVerts(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag))
{
DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false);
@@ -727,7 +727,7 @@ static void deformVerts(
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false);
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index c232a32fe00..198f08334f0 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -115,7 +115,7 @@ static void updateDepsgraph(ModifierData *md,
DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "Curve Modifier");
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx,
+static void deformVerts(ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -130,7 +130,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx,
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em,
+ ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
DerivedMesh *dm = derivedData;
diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c
index 89ae1d364cf..e7069937868 100644
--- a/source/blender/modifiers/intern/MOD_datatransfer.c
+++ b/source/blender/modifiers/intern/MOD_datatransfer.c
@@ -152,7 +152,7 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
DT_TYPE_SHARP_FACE \
)
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
DataTransferModifierData *dtmd = (DataTransferModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c
index 80e1b09ddb5..078a3085fc7 100644
--- a/source/blender/modifiers/intern/MOD_decimate.c
+++ b/source/blender/modifiers/intern/MOD_decimate.c
@@ -86,7 +86,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index a1f526507f9..c9ccdc3b8c2 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -74,14 +74,10 @@ static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
DisplaceModifierData *dmd = (DisplaceModifierData *) md;
-#endif
DisplaceModifierData *tdmd = (DisplaceModifierData *) target;
+#endif
modifier_copyData_generic(md, target);
-
- if (tdmd->texture) {
- id_us_plus(&tdmd->texture->id);
- }
}
static void freeData(ModifierData *md)
@@ -375,7 +371,7 @@ static void displaceModifier_do(
}
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -391,7 +387,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
DerivedMesh *dm = get_cddm(ob, editData, derivedData, vertexCos, dependsOnNormals(md));
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index 3c5afc6bb69..cf3f84364ea 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -114,7 +114,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *eval_ctx,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *dm,
ModifierApplyFlag flag)
{
diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c
index bee65cb0f4a..0e344a851f2 100644
--- a/source/blender/modifiers/intern/MOD_edgesplit.c
+++ b/source/blender/modifiers/intern/MOD_edgesplit.c
@@ -121,7 +121,7 @@ static void copyData(ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *UNUSED(ob), DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c
index 3d013d273d0..38785abbc19 100644
--- a/source/blender/modifiers/intern/MOD_explode.c
+++ b/source/blender/modifiers/intern/MOD_explode.c
@@ -785,9 +785,10 @@ static DerivedMesh *cutEdges(ExplodeModifierData *emd, DerivedMesh *dm)
return splitdm;
}
-static DerivedMesh *explodeMesh(ExplodeModifierData *emd,
- ParticleSystemModifierData *psmd, struct EvaluationContext *eval_ctx, Scene *scene,
- Object *ob, DerivedMesh *to_explode)
+static DerivedMesh *explodeMesh(
+ ExplodeModifierData *emd,
+ ParticleSystemModifierData *psmd, const struct EvaluationContext *eval_ctx, Scene *scene,
+ Object *ob, DerivedMesh *to_explode)
{
DerivedMesh *explode, *dm = to_explode;
MFace *mf = NULL, *mface;
@@ -994,7 +995,7 @@ static ParticleSystemModifierData *findPrecedingParticlesystem(Object *ob, Modif
}
return psmd;
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *eval_ctx,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c
index 4a6c2328d53..f9e7f10653b 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim.c
@@ -82,7 +82,7 @@ static void copyData(ModifierData *md, ModifierData *target)
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *dm,
ModifierApplyFlag flag)
{
diff --git a/source/blender/modifiers/intern/MOD_hair.c b/source/blender/modifiers/intern/MOD_hair.c
index a31303cdce8..d17a629e055 100644
--- a/source/blender/modifiers/intern/MOD_hair.c
+++ b/source/blender/modifiers/intern/MOD_hair.c
@@ -94,7 +94,7 @@ static void freeData(ModifierData *md)
}
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *UNUSED(ob), DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c
index 354b131c74b..25617c84dac 100644
--- a/source/blender/modifiers/intern/MOD_hook.c
+++ b/source/blender/modifiers/intern/MOD_hook.c
@@ -356,7 +356,7 @@ static void deformVerts_do(HookModifierData *hmd, Object *ob, DerivedMesh *dm,
}
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts,
ModifierApplyFlag UNUSED(flag))
{
@@ -372,7 +372,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
dm->release(dm);
}
-static void deformVertsEM(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
+static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
HookModifierData *hmd = (HookModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c
index 47ce14efc1f..a1c126313a2 100644
--- a/source/blender/modifiers/intern/MOD_laplaciandeform.c
+++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c
@@ -539,7 +539,7 @@ static void initSystem(LaplacianDeformModifierData *lmd, Object *ob, DerivedMesh
STACK_PUSH(index_anchors, i);
}
}
- DM_ensure_looptri(dm);
+
total_anchors = STACK_SIZE(index_anchors);
lmd->cache_system = initLaplacianSystem(numVerts, dm->getNumEdges(dm), dm->getNumLoopTri(dm),
total_anchors, lmd->anchor_grp_name, lmd->repeat);
@@ -724,7 +724,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag))
{
DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false);
@@ -736,7 +736,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false);
diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
index 66cc3deb727..d7bc7b6c427 100644
--- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c
+++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c
@@ -506,7 +506,7 @@ static CustomDataMask required_data_mask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag))
{
DerivedMesh *dm;
@@ -524,7 +524,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
DerivedMesh *dm;
diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c
index d150bf3c8e0..cd8b6139d75 100644
--- a/source/blender/modifiers/intern/MOD_lattice.c
+++ b/source/blender/modifiers/intern/MOD_lattice.c
@@ -103,7 +103,7 @@ static void updateDepsgraph(ModifierData *md,
DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "Lattice Modifier");
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -119,7 +119,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em,
+ ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
DerivedMesh *dm = derivedData;
diff --git a/source/blender/modifiers/intern/MOD_mask.c b/source/blender/modifiers/intern/MOD_mask.c
index b66007b8a87..d942b23b216 100644
--- a/source/blender/modifiers/intern/MOD_mask.c
+++ b/source/blender/modifiers/intern/MOD_mask.c
@@ -94,7 +94,7 @@ static void updateDepsgraph(ModifierData *md,
}
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c
index 4c377f7fe90..c990951c578 100644
--- a/source/blender/modifiers/intern/MOD_meshcache.c
+++ b/source/blender/modifiers/intern/MOD_meshcache.c
@@ -272,7 +272,7 @@ static void meshcache_do(
}
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -284,7 +284,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *UNUSED(editData),
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *UNUSED(editData),
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
MeshCacheModifierData *mcmd = (MeshCacheModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index 8360c8ffda7..4b2b3f17d18 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -146,7 +146,7 @@ bool MOD_meshcache_read_pc2_index(FILE *fp,
return false;
}
- if (fseek(fp, sizeof(float) * 3 * index * pc2_head.verts_tot , SEEK_CUR) != 0) {
+ if (fseek(fp, sizeof(float) * 3 * index * pc2_head.verts_tot, SEEK_CUR) != 0) {
*err_str = "Failed to seek frame";
return false;
}
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 35fc40b82d3..ab43204365d 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -272,7 +272,7 @@ static void meshdeform_vert_task(void *userdata, const int iter)
}
static void meshdeformModifier_do(
- ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *dm,
+ ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *dm,
float (*vertexCos)[3], int numVerts)
{
MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
@@ -402,7 +402,7 @@ static void meshdeformModifier_do(
cagedm->release(cagedm);
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob,
+static void deformVerts(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob,
DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -418,7 +418,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx, Ob
dm->release(dm);
}
-static void deformVertsEM(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob,
+static void deformVertsEM(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob,
struct BMEditMesh *UNUSED(editData),
DerivedMesh *derivedData,
float (*vertexCos)[3],
diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c
index 5d623295edf..86c2a24eddf 100644
--- a/source/blender/modifiers/intern/MOD_meshsequencecache.c
+++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c
@@ -25,12 +25,14 @@
*/
#include "DNA_cachefile_types.h"
+#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_cachefile.h"
#include "BKE_DerivedMesh.h"
+#include "BKE_cdderivedmesh.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
@@ -92,13 +94,17 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
return (mcmd->cache_file == NULL) || (mcmd->object_path[0] == '\0');
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *dm,
- ModifierApplyFlag flag)
+ ModifierApplyFlag UNUSED(flag))
{
#ifdef WITH_ALEMBIC
MeshSeqCacheModifierData *mcmd = (MeshSeqCacheModifierData *) md;
+ /* Only used to check whether we are operating on org data or not... */
+ Mesh *me = (ob->type == OB_MESH) ? ob->data : NULL;
+ DerivedMesh *org_dm = dm;
+
Scene *scene = md->scene;
const float frame = BKE_scene_frame_get(scene);
const float time = BKE_cachefile_time_offset(mcmd->cache_file, frame, FPS);
@@ -120,6 +126,16 @@ static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UN
}
}
+ if (me != NULL) {
+ MVert *mvert = dm->getVertArray(dm);
+ MEdge *medge = dm->getEdgeArray(dm);
+ MPoly *mpoly = dm->getPolyArray(dm);
+ if ((me->mvert == mvert) || (me->medge == medge) || (me->mpoly == mpoly)) {
+ /* We need to duplicate data here, otherwise we'll modify org mesh, see T51701. */
+ dm = CDDM_copy(dm);
+ }
+ }
+
DerivedMesh *result = ABC_read_mesh(mcmd->reader,
ob,
dm,
@@ -131,11 +147,15 @@ static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UN
modifier_setError(md, "%s", err_str);
}
+ if (!ELEM(result, NULL, dm) && (dm != org_dm)) {
+ dm->release(dm);
+ dm = org_dm;
+ }
+
return result ? result : dm;
- UNUSED_VARS(flag);
#else
return dm;
- UNUSED_VARS(md, ob, flag);
+ UNUSED_VARS(md, ob);
#endif
}
diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c
index a9e07fe4448..5c40bad90c4 100644
--- a/source/blender/modifiers/intern/MOD_mirror.c
+++ b/source/blender/modifiers/intern/MOD_mirror.c
@@ -321,7 +321,7 @@ static DerivedMesh *mirrorModifier__doMirror(MirrorModifierData *mmd,
return result;
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c
index b63b507586c..2b675d36140 100644
--- a/source/blender/modifiers/intern/MOD_multires.c
+++ b/source/blender/modifiers/intern/MOD_multires.c
@@ -67,7 +67,7 @@ static void copyData(ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
DerivedMesh *dm, ModifierApplyFlag flag)
{
MultiresModifierData *mmd = (MultiresModifierData *)md;
diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c
index ca6aa71eb37..1c7c640b971 100644
--- a/source/blender/modifiers/intern/MOD_normal_edit.c
+++ b/source/blender/modifiers/intern/MOD_normal_edit.c
@@ -521,7 +521,7 @@ static void updateDepsgraph(ModifierData *md,
}
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
DerivedMesh *dm, ModifierApplyFlag UNUSED(flag))
{
return normalEditModifier_do((NormalEditModifierData *)md, ob, dm);
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index 878f17dd04a..189cfb8553e 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -542,7 +542,7 @@ static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob),
}
#endif /* WITH_OCEANSIM */
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index f25b6b225a5..de59635f335 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -166,7 +166,7 @@ static int particle_skip(ParticleInstanceModifierData *pimd, ParticleSystem *psy
return 0;
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *eval_ctx,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c
index 777487fabcf..9cc6e5f56b5 100644
--- a/source/blender/modifiers/intern/MOD_particlesystem.c
+++ b/source/blender/modifiers/intern/MOD_particlesystem.c
@@ -97,7 +97,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
}
/* saves the current emitter state for a particle system and calculates particles */
-static void deformVerts(ModifierData *md, struct EvaluationContext *eval_ctx,
+static void deformVerts(ModifierData *md, const struct EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int UNUSED(numVerts),
diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c
index f5fa6abe37b..c9070cced7e 100644
--- a/source/blender/modifiers/intern/MOD_remesh.c
+++ b/source/blender/modifiers/intern/MOD_remesh.c
@@ -143,7 +143,7 @@ static void dualcon_add_quad(void *output_v, const int vert_indices[4])
}
static DerivedMesh *applyModifier(ModifierData *md,
- struct EvaluationContext *UNUSED(eval_ctx),
+ const struct EvaluationContext *UNUSED(eval_ctx),
Object *UNUSED(ob),
DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
@@ -205,7 +205,7 @@ static DerivedMesh *applyModifier(ModifierData *md,
#else /* !WITH_MOD_REMESH */
static DerivedMesh *applyModifier(ModifierData *UNUSED(md),
- struct EvaluationContext *UNUSED(eval_ctx),
+ const struct EvaluationContext *UNUSED(eval_ctx),
Object *UNUSED(ob),
DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c
index 04599fcb535..b951c4afc00 100644
--- a/source/blender/modifiers/intern/MOD_screw.c
+++ b/source/blender/modifiers/intern/MOD_screw.c
@@ -133,7 +133,7 @@ static void copyData(ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag flag)
{
diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c
index b5039669b63..822decea423 100644
--- a/source/blender/modifiers/intern/MOD_shapekey.c
+++ b/source/blender/modifiers/intern/MOD_shapekey.c
@@ -44,7 +44,7 @@
#include "MOD_modifiertypes.h"
-static void deformVerts(ModifierData *UNUSED(md), struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *UNUSED(md), const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *UNUSED(derivedData),
float (*vertexCos)[3],
int numVerts,
@@ -61,7 +61,7 @@ static void deformVerts(ModifierData *UNUSED(md), struct EvaluationContext *UNUS
}
}
-static void deformMatrices(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData,
+static void deformMatrices(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], float (*defMats)[3][3], int numVerts)
{
Key *key = BKE_key_from_object(ob);
@@ -83,7 +83,7 @@ static void deformMatrices(ModifierData *md, struct EvaluationContext *eval_ctx,
deformVerts(md, eval_ctx, ob, derivedData, vertexCos, numVerts, 0);
}
-static void deformVertsEM(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob,
+static void deformVertsEM(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob,
struct BMEditMesh *UNUSED(editData),
DerivedMesh *derivedData,
float (*vertexCos)[3],
@@ -95,7 +95,7 @@ static void deformVertsEM(ModifierData *md, struct EvaluationContext *eval_ctx,
deformVerts(md, eval_ctx, ob, derivedData, vertexCos, numVerts, 0);
}
-static void deformMatricesEM(ModifierData *UNUSED(md), struct EvaluationContext *UNUSED(eval_ctx),
+static void deformMatricesEM(ModifierData *UNUSED(md), const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, struct BMEditMesh *UNUSED(editData),
DerivedMesh *UNUSED(derivedData),
float (*vertexCos)[3],
diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c
index c197e2ff7b1..c87fdd321ab 100644
--- a/source/blender/modifiers/intern/MOD_shrinkwrap.c
+++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c
@@ -103,7 +103,7 @@ static void foreachObjectLink(ModifierData *md, Object *ob, ObjectWalkFunc walk,
walk(userData, ob, &smd->auxTarget, IDWALK_CB_NOP);
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -124,7 +124,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
dm->release(dm);
}
-static void deformVertsEM(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
+static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
struct BMEditMesh *editData, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts)
{
diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c
index 658c8b54c62..146e882a6b6 100644
--- a/source/blender/modifiers/intern/MOD_simpledeform.c
+++ b/source/blender/modifiers/intern/MOD_simpledeform.c
@@ -302,7 +302,7 @@ static void updateDepsgraph(ModifierData *md,
}
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -322,7 +322,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
dm->release(dm);
}
-static void deformVertsEM(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, struct BMEditMesh *editData,
DerivedMesh *derivedData,
float (*vertexCos)[3],
diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c
index 92c4cea9c17..9d1c6913c1c 100644
--- a/source/blender/modifiers/intern/MOD_skin.c
+++ b/source/blender/modifiers/intern/MOD_skin.c
@@ -1917,7 +1917,7 @@ static void copyData(ModifierData *md, ModifierData *target)
}
static DerivedMesh *applyModifier(ModifierData *md,
- struct EvaluationContext *UNUSED(eval_ctx),
+ const struct EvaluationContext *UNUSED(eval_ctx),
Object *UNUSED(ob),
DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c
index c2a43f8b42e..e66afe07841 100644
--- a/source/blender/modifiers/intern/MOD_smoke.c
+++ b/source/blender/modifiers/intern/MOD_smoke.c
@@ -102,7 +102,7 @@ static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
return dataMask;
}
-static DerivedMesh *applyModifier(ModifierData *md, EvaluationContext *eval_ctx,
+static DerivedMesh *applyModifier(ModifierData *md, const EvaluationContext *eval_ctx,
Object *ob, DerivedMesh *dm,
ModifierApplyFlag flag)
{
diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c
index 148a0d01230..be55030e18a 100644
--- a/source/blender/modifiers/intern/MOD_smooth.c
+++ b/source/blender/modifiers/intern/MOD_smooth.c
@@ -215,7 +215,7 @@ static void smoothModifier_do(
MEM_freeN(uctmp);
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag))
{
DerivedMesh *dm = get_dm(ob, NULL, derivedData, NULL, false, false);
@@ -228,7 +228,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
DerivedMesh *dm = get_dm(ob, editData, derivedData, NULL, false, false);
diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c
index f59d28fca84..020dd3da6a5 100644
--- a/source/blender/modifiers/intern/MOD_softbody.c
+++ b/source/blender/modifiers/intern/MOD_softbody.c
@@ -49,7 +49,7 @@
#include "MOD_modifiertypes.h"
-static void deformVerts(ModifierData *md, EvaluationContext *eval_ctx, Object *ob,
+static void deformVerts(ModifierData *md, const EvaluationContext *eval_ctx, Object *ob,
DerivedMesh *UNUSED(derivedData),
float (*vertexCos)[3],
int numVerts,
diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c
index 1389622bdcb..81f19539803 100644
--- a/source/blender/modifiers/intern/MOD_solidify.c
+++ b/source/blender/modifiers/intern/MOD_solidify.c
@@ -205,7 +205,7 @@ BLI_INLINE void madd_v3v3short_fl(float r[3], const short a[3], const float f)
}
static DerivedMesh *applyModifier(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c
index 93a2e1e1c06..6a07f842cf3 100644
--- a/source/blender/modifiers/intern/MOD_subsurf.c
+++ b/source/blender/modifiers/intern/MOD_subsurf.c
@@ -98,7 +98,7 @@ static bool isDisabled(ModifierData *md, int useRenderParams)
return get_render_subsurf_level(&md->scene->r, levels, useRenderParams != 0) == 0;
}
-static DerivedMesh *applyModifier(ModifierData *md, EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag flag)
{
@@ -162,10 +162,11 @@ static DerivedMesh *applyModifier(ModifierData *md, EvaluationContext *UNUSED(ev
return result;
}
-static DerivedMesh *applyModifierEM(ModifierData *md, EvaluationContext *UNUSED(eval_ctx),
- Object *UNUSED(ob), struct BMEditMesh *UNUSED(editData),
- DerivedMesh *derivedData,
- ModifierApplyFlag flag)
+static DerivedMesh *applyModifierEM(
+ ModifierData *md, const EvaluationContext *UNUSED(eval_ctx),
+ Object *UNUSED(ob), struct BMEditMesh *UNUSED(editData),
+ DerivedMesh *derivedData,
+ ModifierApplyFlag flag)
{
SubsurfModifierData *smd = (SubsurfModifierData *) md;
DerivedMesh *result;
diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c
index 00ac9452be2..c408b4fbd63 100644
--- a/source/blender/modifiers/intern/MOD_surface.c
+++ b/source/blender/modifiers/intern/MOD_surface.c
@@ -85,7 +85,7 @@ static bool dependsOnTime(ModifierData *UNUSED(md))
return true;
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int UNUSED(numVerts),
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 9a108df0bdd..b623293ed5c 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -1162,7 +1162,7 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
}
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *UNUSED(derivedData),
float (*vertexCos)[3], int numVerts,
ModifierApplyFlag UNUSED(flag))
@@ -1170,7 +1170,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
surfacedeformModifier_do(md, vertexCos, numVerts, ob);
}
-static void deformVertsEM(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVertsEM(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, struct BMEditMesh *UNUSED(editData),
DerivedMesh *UNUSED(derivedData),
float (*vertexCos)[3], int numVerts)
diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c
index 9124032e3d8..5dd7e3dfda4 100644
--- a/source/blender/modifiers/intern/MOD_triangulate.c
+++ b/source/blender/modifiers/intern/MOD_triangulate.c
@@ -85,7 +85,7 @@ static void copyData(ModifierData *md, ModifierData *target)
}
static DerivedMesh *applyModifier(ModifierData *md,
- struct EvaluationContext *UNUSED(eval_ctx),
+ const struct EvaluationContext *UNUSED(eval_ctx),
Object *UNUSED(ob),
DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 473b3ec045c..c9a842621b6 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -335,7 +335,7 @@ static DerivedMesh *uvprojectModifier_do(UVProjectModifierData *umd,
return dm;
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c
index b24ea55696e..3773eed26dc 100644
--- a/source/blender/modifiers/intern/MOD_uvwarp.c
+++ b/source/blender/modifiers/intern/MOD_uvwarp.c
@@ -143,7 +143,7 @@ static void uv_warp_compute(void *userdata, const int i)
}
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *dm,
ModifierApplyFlag UNUSED(flag))
{
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index b275d02f5a8..566ee5b2d24 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -313,7 +313,7 @@ static int warp_needs_dm(WarpModifierData *wmd)
return wmd->texture || wmd->defgrp_name[0];
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag))
{
DerivedMesh *dm = NULL;
@@ -330,7 +330,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
}
-static void deformVertsEM(ModifierData *md, struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em,
+static void deformVertsEM(ModifierData *md, const struct EvaluationContext *eval_ctx, Object *ob, struct BMEditMesh *em,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
DerivedMesh *dm = derivedData;
diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c
index 6d3f621105c..8b7af867b7d 100644
--- a/source/blender/modifiers/intern/MOD_wave.c
+++ b/source/blender/modifiers/intern/MOD_wave.c
@@ -88,14 +88,10 @@ static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
WaveModifierData *wmd = (WaveModifierData *) md;
-#endif
WaveModifierData *twmd = (WaveModifierData *) target;
+#endif
modifier_copyData_generic(md, target);
-
- if (twmd->texture) {
- id_us_plus(&twmd->texture->id);
- }
}
static bool dependsOnTime(ModifierData *UNUSED(md))
@@ -314,7 +310,7 @@ static void waveModifier_do(WaveModifierData *md,
if (wmd->texture) MEM_freeN(tex_co);
}
-static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx),
+static void deformVerts(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob, DerivedMesh *derivedData,
float (*vertexCos)[3],
int numVerts,
@@ -335,7 +331,7 @@ static void deformVerts(ModifierData *md, struct EvaluationContext *UNUSED(eval_
}
static void deformVertsEM(
- ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
+ ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob, struct BMEditMesh *editData,
DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts)
{
DerivedMesh *dm = derivedData;
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index af92277bb30..dbdaafaa5a7 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -92,10 +92,6 @@ static void copyData(ModifierData *md, ModifierData *target)
modifier_copyData_generic(md, target);
twmd->cmap_curve = curvemapping_copy(wmd->cmap_curve);
-
- if (twmd->mask_texture) {
- id_us_plus(&twmd->mask_texture->id);
- }
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
@@ -167,7 +163,7 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
}
static DerivedMesh *applyModifier(ModifierData *md,
- struct EvaluationContext *UNUSED(eval_ctx),
+ const struct EvaluationContext *UNUSED(eval_ctx),
Object *ob,
DerivedMesh *derivedData,
ModifierApplyFlag UNUSED(flag))
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 75edc216879..5f30d4ca72a 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -137,14 +137,10 @@ static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
-#endif
WeightVGMixModifierData *twmd = (WeightVGMixModifierData *) target;
+#endif
modifier_copyData_generic(md, target);
-
- if (twmd->mask_texture) {
- id_us_plus(&twmd->mask_texture->id);
- }
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
@@ -217,7 +213,7 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
return (wmd->defgrp_name_a[0] == '\0');
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag))
{
WeightVGMixModifierData *wmd = (WeightVGMixModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c
index 4c8a1be5ceb..c8bbbfe44b2 100644
--- a/source/blender/modifiers/intern/MOD_weightvgproximity.c
+++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c
@@ -287,14 +287,10 @@ static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
-#endif
WeightVGProximityModifierData *twmd = (WeightVGProximityModifierData *) target;
+#endif
modifier_copyData_generic(md, target);
-
- if (twmd->mask_texture) {
- id_us_plus(&twmd->mask_texture->id);
- }
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
@@ -374,7 +370,7 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
return (wmd->proximity_ob_target == NULL);
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag))
{
WeightVGProximityModifierData *wmd = (WeightVGProximityModifierData *) md;
diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c
index b5825d9aab2..6fc1907ba0a 100644
--- a/source/blender/modifiers/intern/MOD_wireframe.c
+++ b/source/blender/modifiers/intern/MOD_wireframe.c
@@ -107,7 +107,7 @@ static DerivedMesh *WireframeModifier_do(WireframeModifierData *wmd, Object *ob,
}
-static DerivedMesh *applyModifier(ModifierData *md, struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
+static DerivedMesh *applyModifier(ModifierData *md, const struct EvaluationContext *UNUSED(eval_ctx), Object *ob,
DerivedMesh *dm, ModifierApplyFlag UNUSED(flag))
{
return WireframeModifier_do((WireframeModifierData *)md, ob, dm);
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index 2c46791ae18..d65b71a35e5 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -184,11 +184,9 @@ set(SRC
shader/nodes/node_shader_normal_map.c
shader/nodes/node_shader_object_info.c
shader/nodes/node_shader_hair_info.c
- shader/nodes/node_shader_eevee_metallic.c
shader/nodes/node_shader_eevee_specular.c
shader/nodes/node_shader_output_lamp.c
shader/nodes/node_shader_output_material.c
- shader/nodes/node_shader_output_eevee_material.c
shader/nodes/node_shader_output_world.c
shader/nodes/node_shader_output_linestyle.c
shader/nodes/node_shader_particle_info.c
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index d8944776cbb..783e1a388c1 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -67,9 +67,7 @@ DefNode( ShaderNode, SH_NODE_COMBRGB, 0, "COMBR
DefNode( ShaderNode, SH_NODE_HUE_SAT, 0, "HUE_SAT", HueSaturation, "Hue/Saturation", "" )
DefNode( ShaderNode, SH_NODE_OUTPUT_MATERIAL, def_sh_output, "OUTPUT_MATERIAL", OutputMaterial, "Material Output", "" )
-DefNode( ShaderNode, SH_NODE_EEVEE_METALLIC, 0, "EEVEE_METALLIC", EeveeMetallic, "Metallic", "")
DefNode( ShaderNode, SH_NODE_EEVEE_SPECULAR, 0, "EEVEE_SPECULAR", EeveeSpecular, "Specular", "")
-DefNode( ShaderNode, SH_NODE_OUTPUT_EEVEE_MATERIAL, def_sh_output, "OUTPUT_EEVEE_MATERIAL", OutputEeveeMaterial, "Material Output", "")
DefNode( ShaderNode, SH_NODE_OUTPUT_LAMP, def_sh_output, "OUTPUT_LAMP", OutputLamp, "Lamp Output", "" )
DefNode( ShaderNode, SH_NODE_OUTPUT_WORLD, def_sh_output, "OUTPUT_WORLD", OutputWorld, "World Output", "" )
DefNode( ShaderNode, SH_NODE_OUTPUT_LINESTYLE, def_sh_output_linestyle,"OUTPUT_LINESTYLE", OutputLineStyle, "Line Style Output", "" )
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 8139e29bade..a95c3233132 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -178,6 +178,9 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node, LinkNod
cmp_node_image_add_pass_output(ntree, node, "Alpha", RE_PASSNAME_COMBINED, -1, SOCK_FLOAT, false, available_sockets, &prev_index);
if (ima) {
+ if (!ima->rr) {
+ cmp_node_image_add_pass_output(ntree, node, RE_PASSNAME_Z, RE_PASSNAME_Z, -1, SOCK_FLOAT, false, available_sockets, &prev_index);
+ }
BKE_image_release_ibuf(ima, ibuf, NULL);
}
}
diff --git a/source/blender/nodes/shader/node_shader_tree.c b/source/blender/nodes/shader/node_shader_tree.c
index ec35959f31a..35a8c712905 100644
--- a/source/blender/nodes/shader/node_shader_tree.c
+++ b/source/blender/nodes/shader/node_shader_tree.c
@@ -80,7 +80,7 @@ static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tre
SpaceNode *snode = CTX_wm_space_node(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
if ((snode->shaderfrom == SNODE_SHADER_OBJECT) ||
(BKE_scene_use_new_shading_nodes(scene) == false))
@@ -482,10 +482,10 @@ static bool ntree_tag_ssr_bsdf_cb(bNode *fromnode, bNode *UNUSED(tonode), void *
{
switch (fromnode->type) {
case SH_NODE_BSDF_ANISOTROPIC:
- case SH_NODE_EEVEE_METALLIC:
case SH_NODE_EEVEE_SPECULAR:
case SH_NODE_BSDF_PRINCIPLED:
case SH_NODE_BSDF_GLOSSY:
+ case SH_NODE_BSDF_GLASS:
fromnode->ssr_id = (*(float *)userdata);
(*(float *)userdata) += 1;
break;
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
index 25f76ba9ecb..1537e07ca16 100644
--- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c
@@ -52,7 +52,7 @@ static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *node, bNodeExecDa
if (!in[3].link)
GPU_link(mat, "world_normals_get", &in[3].link);
- return GPU_stack_link(mat, node, "node_bsdf_glass", in, out);
+ return GPU_stack_link(mat, node, "node_bsdf_glass", in, out, GPU_uniform(&node->ssr_id));
}
/* node type definition */
diff --git a/source/blender/nodes/shader/nodes/node_shader_eevee_metallic.c b/source/blender/nodes/shader/nodes/node_shader_eevee_metallic.c
deleted file mode 100644
index 071486493fa..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_eevee_metallic.c
+++ /dev/null
@@ -1,88 +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) 2005 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): Clément Foucault.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "../node_shader_util.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_eevee_metallic_in[] = {
- { SOCK_RGBA, 1, N_("Base Color"), 0.8f, 0.8f, 0.8f, 1.0f},
- { SOCK_FLOAT, 1, N_("Metallic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- { SOCK_FLOAT, 1, N_("Specular"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- { SOCK_RGBA, 1, N_("Emissive Color"), 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 1, N_("Transparency"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- { SOCK_FLOAT, 1, N_("Clear Coat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- { SOCK_FLOAT, 1, N_("Clear Coat Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
- { SOCK_VECTOR, 1, N_("Clear Coat Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- { SOCK_FLOAT, 1, N_("Ambient Occlusion"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
- { -1, 0, "" }
-};
-
-static bNodeSocketTemplate sh_node_eevee_metallic_out[] = {
- { SOCK_SHADER, 0, N_("BSDF")},
- { -1, 0, "" }
-};
-
-static int node_shader_gpu_eevee_metallic(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
-{
- static float one = 1.0f;
-
- /* Normals */
- if (!in[6].link) {
- GPU_link(mat, "world_normals_get", &in[6].link);
- }
-
- /* Clearcoat Normals */
- if (!in[9].link) {
- GPU_link(mat, "world_normals_get", &in[9].link);
- }
-
- /* Occlusion */
- if (!in[10].link) {
- GPU_link(mat, "set_value", GPU_uniform(&one), &in[10].link);
- }
-
- return GPU_stack_link(mat, node, "node_eevee_metallic", in, out, GPU_uniform(&node->ssr_id));
-}
-
-
-/* node type definition */
-void register_node_type_sh_eevee_metallic(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_EEVEE_METALLIC, "Metallic", NODE_CLASS_SHADER, 0);
- node_type_compatibility(&ntype, NODE_NEW_SHADING);
- node_type_socket_templates(&ntype, sh_node_eevee_metallic_in, sh_node_eevee_metallic_out);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_eevee_metallic);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/shader/nodes/node_shader_output_eevee_material.c b/source/blender/nodes/shader/nodes/node_shader_output_eevee_material.c
deleted file mode 100644
index faf715f2b66..00000000000
--- a/source/blender/nodes/shader/nodes/node_shader_output_eevee_material.c
+++ /dev/null
@@ -1,66 +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) 2005 Blender Foundation.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "../node_shader_util.h"
-
-#include "BKE_scene.h"
-
-/* **************** OUTPUT ******************** */
-
-static bNodeSocketTemplate sh_node_output_eevee_material_in[] = {
- { SOCK_SHADER, 1, N_("Surface")},
- { -1, 0, "" }
-};
-
-static int node_shader_gpu_output_eevee_material(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
-{
- GPUNodeLink *outlink;
-
- GPU_stack_link(mat, node, "node_output_eevee_material", in, out, &outlink);
- GPU_material_output_link(mat, outlink);
-
- return true;
-}
-
-
-/* node type definition */
-void register_node_type_sh_output_eevee_material(void)
-{
- static bNodeType ntype;
-
- sh_node_type_base(&ntype, SH_NODE_OUTPUT_EEVEE_MATERIAL, "Material Output", NODE_CLASS_OUTPUT, 0);
- node_type_compatibility(&ntype, NODE_NEW_SHADING);
- node_type_socket_templates(&ntype, sh_node_output_eevee_material_in, NULL);
- node_type_init(&ntype, NULL);
- node_type_storage(&ntype, "", NULL, NULL);
- node_type_gpu(&ntype, node_shader_gpu_output_eevee_material);
-
- /* Do not allow muting output node. */
- node_type_internal_links(&ntype, NULL);
-
- nodeRegisterType(&ntype);
-}
diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c
index 3b53d29d147..2ac4ce2f48c 100644
--- a/source/blender/nodes/texture/node_texture_tree.c
+++ b/source/blender/nodes/texture/node_texture_tree.c
@@ -63,7 +63,7 @@ static void texture_get_from_context(const bContext *C, bNodeTreeType *UNUSED(tr
SpaceNode *snode = CTX_wm_space_node(C);
Scene *scene = CTX_data_scene(C);
SceneLayer *sl = CTX_data_scene_layer(C);
- Object *ob = OBACT_NEW;
+ Object *ob = OBACT_NEW(sl);
Tex *tx = NULL;
if (snode->texfrom == SNODE_TEX_OBJECT) {
diff --git a/source/blender/python/CMakeLists.txt b/source/blender/python/CMakeLists.txt
index e855f3a3756..8d26fee0abd 100644
--- a/source/blender/python/CMakeLists.txt
+++ b/source/blender/python/CMakeLists.txt
@@ -17,6 +17,7 @@
# ***** END GPL LICENSE BLOCK *****
add_subdirectory(intern)
+add_subdirectory(gawain)
add_subdirectory(generic)
add_subdirectory(mathutils)
add_subdirectory(bmesh)
diff --git a/source/blender/python/gawain/CMakeLists.txt b/source/blender/python/gawain/CMakeLists.txt
new file mode 100644
index 00000000000..6b6c902f48a
--- /dev/null
+++ b/source/blender/python/gawain/CMakeLists.txt
@@ -0,0 +1,47 @@
+# ***** 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.
+#
+# Contributor(s): Campbell Barton
+#
+# ***** END GPL LICENSE BLOCK *****
+
+set(INC
+ .
+ ../../blenkernel
+ ../../blenlib
+ ../../gpu
+ ../../makesdna
+ ../../../../intern/gawain
+ ../../../../intern/guardedalloc
+ ../../../../intern/glew-mx
+)
+
+set(INC_SYS
+ ${GLEW_INCLUDE_PATH}
+ ${PYTHON_INCLUDE_DIRS}
+)
+
+set(SRC
+ gwn_py_api.c
+ gwn_py_types.c
+
+ gwn_py_api.h
+ gwn_py_types.h
+)
+
+add_definitions(${GL_DEFINITIONS})
+
+blender_add_lib(bf_python_gawain "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/python/gawain/gwn_py_api.c b/source/blender/python/gawain/gwn_py_api.c
new file mode 100644
index 00000000000..d79ef070649
--- /dev/null
+++ b/source/blender/python/gawain/gwn_py_api.c
@@ -0,0 +1,63 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/gawain/gwn_py_api.c
+ * \ingroup pygawain
+ *
+ * Experimental Python API, not considered public yet (called '_gawain'),
+ * we may re-expose as public later.
+ */
+
+#include <Python.h>
+
+#include "gawain/gwn_batch.h"
+#include "gawain/gwn_vertex_format.h"
+
+#include "gwn_py_api.h"
+#include "gwn_py_types.h"
+
+#include "BLI_utildefines.h"
+
+#include "../generic/python_utildefines.h"
+
+PyDoc_STRVAR(GWN_doc,
+"This module provides access to gawain drawing functions."
+);
+static struct PyModuleDef GWN_module_def = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "_gawain", /* m_name */
+ .m_doc = GWN_doc, /* m_doc */
+};
+
+PyObject *BPyInit_gawain(void)
+{
+ PyObject *sys_modules = PyThreadState_GET()->interp->modules;
+ PyObject *submodule;
+ PyObject *mod;
+
+ mod = PyModule_Create(&GWN_module_def);
+
+ /* _gawain.types */
+ PyModule_AddObject(mod, "types", (submodule = BPyInit_gawain_types()));
+ PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
+ Py_INCREF(submodule);
+
+ return mod;
+}
diff --git a/source/blender/python/gawain/gwn_py_api.h b/source/blender/python/gawain/gwn_py_api.h
new file mode 100644
index 00000000000..aacb14094bc
--- /dev/null
+++ b/source/blender/python/gawain/gwn_py_api.h
@@ -0,0 +1,30 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __GWN_PY_API__
+#define __GWN_PY_API__
+
+/** \file blender/python/gawain/gwn_py_api.h
+ * \ingroup pygawain
+ */
+
+PyObject *BPyInit_gawain(void);
+
+#endif /* __GWN_PY_API__ */
diff --git a/source/blender/python/gawain/gwn_py_types.c b/source/blender/python/gawain/gwn_py_types.c
new file mode 100644
index 00000000000..82fb043cebd
--- /dev/null
+++ b/source/blender/python/gawain/gwn_py_types.c
@@ -0,0 +1,848 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/gawain/gwn_py_types.c
+ * \ingroup pygawain
+ *
+ * - Use ``bpygwn_`` for local API.
+ * - Use ``BPyGwn_`` for public API.
+ */
+
+#include <Python.h>
+
+#include "gawain/gwn_batch.h"
+#include "gawain/gwn_vertex_format.h"
+
+#include "BLI_math.h"
+
+#include "GPU_batch.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "../generic/py_capi_utils.h"
+#include "../generic/python_utildefines.h"
+
+#include "gwn_py_types.h" /* own include */
+
+#ifdef __BIG_ENDIAN__
+ /* big endian */
+# define MAKE_ID2(c, d) ((c) << 8 | (d))
+# define MAKE_ID3(a, b, c) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 )
+# define MAKE_ID4(a, b, c, d) ( (int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d) )
+#else
+ /* little endian */
+# define MAKE_ID2(c, d) ((d) << 8 | (c))
+# define MAKE_ID3(a, b, c) ( (int)(c) << 16 | (b) << 8 | (a) )
+# define MAKE_ID4(a, b, c, d) ( (int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a) )
+#endif
+
+/* -------------------------------------------------------------------- */
+
+/** \name Enum Conversion
+ *
+ * Use with PyArg_ParseTuple's "O&" formatting.
+ * \{ */
+
+static int bpygwn_ParseVertCompType(PyObject *o, void *p)
+{
+ Py_ssize_t comp_type_id_len;
+ const char *comp_type_id = _PyUnicode_AsStringAndSize(o, &comp_type_id_len);
+ if (comp_type_id == NULL) {
+ PyErr_Format(PyExc_ValueError,
+ "expected a string, got %s",
+ Py_TYPE(o)->tp_name);
+ return 0;
+ }
+
+ Gwn_VertCompType comp_type;
+ if (comp_type_id_len == 2) {
+ switch (*((ushort *)comp_type_id)) {
+ case MAKE_ID2('I', '8'): { comp_type = GWN_COMP_I8; goto success; }
+ case MAKE_ID2('U', '8'): { comp_type = GWN_COMP_U8; goto success; }
+ }
+ }
+ else if (comp_type_id_len == 3) {
+ switch (*((uint *)comp_type_id)) {
+ case MAKE_ID3('I', '1', '6'): { comp_type = GWN_COMP_I16; goto success; }
+ case MAKE_ID3('U', '1', '6'): { comp_type = GWN_COMP_U16; goto success; }
+ case MAKE_ID3('I', '3', '2'): { comp_type = GWN_COMP_I32; goto success; }
+ case MAKE_ID3('U', '3', '2'): { comp_type = GWN_COMP_U32; goto success; }
+ case MAKE_ID3('F', '3', '2'): { comp_type = GWN_COMP_F32; goto success; }
+ case MAKE_ID3('I', '1', '0'): { comp_type = GWN_COMP_I10; goto success; }
+ }
+ }
+
+ PyErr_Format(PyExc_ValueError,
+ "unknown type literal: '%s'",
+ comp_type_id);
+ return 0;
+
+success:
+ *((Gwn_VertCompType *)p) = comp_type;
+ return 1;
+}
+
+static int bpygwn_ParseVertFetchMode(PyObject *o, void *p)
+{
+ Py_ssize_t mode_id_len;
+ const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len);
+ if (mode_id == NULL) {
+ PyErr_Format(PyExc_ValueError,
+ "expected a string, got %s",
+ Py_TYPE(o)->tp_name);
+ return 0;
+ }
+#define MATCH_ID(id) \
+ if (mode_id_len == strlen(STRINGIFY(id))) { \
+ if (STREQ(mode_id, STRINGIFY(id))) { \
+ mode = GWN_FETCH_##id; \
+ goto success; \
+ } \
+ } ((void)0)
+
+ Gwn_VertCompType mode;
+ MATCH_ID(FLOAT);
+ MATCH_ID(INT);
+ MATCH_ID(INT_TO_FLOAT_UNIT);
+ MATCH_ID(INT_TO_FLOAT);
+#undef MATCH_ID
+ PyErr_Format(PyExc_ValueError,
+ "unknown type literal: '%s'",
+ mode_id);
+ return 0;
+
+success:
+ (*(Gwn_VertFetchMode *)p) = mode;
+ return 1;
+}
+
+static int bpygwn_ParsePrimType(PyObject *o, void *p)
+{
+ Py_ssize_t mode_id_len;
+ const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len);
+ if (mode_id == NULL) {
+ PyErr_Format(PyExc_ValueError,
+ "expected a string, got %s",
+ Py_TYPE(o)->tp_name);
+ return 0;
+ }
+#define MATCH_ID(id) \
+ if (mode_id_len == strlen(STRINGIFY(id))) { \
+ if (STREQ(mode_id, STRINGIFY(id))) { \
+ mode = GWN_PRIM_##id; \
+ goto success; \
+ } \
+ } ((void)0)
+
+ Gwn_PrimType mode;
+ MATCH_ID(POINTS);
+ MATCH_ID(LINES);
+ MATCH_ID(TRIS);
+ MATCH_ID(LINE_STRIP);
+ MATCH_ID(LINE_LOOP);
+ MATCH_ID(TRI_STRIP);
+ MATCH_ID(TRI_FAN);
+ MATCH_ID(LINE_STRIP_ADJ);
+
+#undef MATCH_ID
+ PyErr_Format(PyExc_ValueError,
+ "unknown type literal: '%s'",
+ mode_id);
+ return 0;
+
+success:
+ (*(Gwn_VertFetchMode *)p) = mode;
+ return 1;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Utility Functions
+ * \{ */
+
+#ifdef __GNUC__
+# define WARN_TYPE_LIMIT_PUSH \
+ _Pragma("warning(push)") _Pragma("GCC diagnostic ignored \"-Wtype-limits\"") ((void)0)
+# define WARN_TYPE_LIMIT_POP \
+ _Pragma("warning(pop)") ((void)0)
+#else
+# define WARN_TYPE_LIMIT_DISABLE ((void)0)
+# define WARN_TYPE_LIMIT_ENABLE ((void)0)
+#endif
+
+/* Use for both tuple and single item, TODO: GWN_COMP_I10 */
+static const char *fill_format_elem_range_error = "Value out of range";
+
+#define PY_AS_NATIVE_SWITCH(attr) \
+ switch (attr->comp_type) { \
+ case GWN_COMP_I8: { PY_AS_NATIVE(int8_t, INT8_MIN, INT8_MAX, int, _PyLong_AsInt); break; } \
+ case GWN_COMP_U8: { PY_AS_NATIVE(uint8_t, 0, UINT8_MAX, int, _PyLong_AsInt); break; } \
+ case GWN_COMP_I16: { PY_AS_NATIVE(int16_t, INT16_MIN, INT16_MAX, int, _PyLong_AsInt); break; } \
+ case GWN_COMP_U16: { PY_AS_NATIVE(uint16_t, 0, UINT8_MAX, int, _PyLong_AsInt); break; } \
+ case GWN_COMP_I32: { PY_AS_NATIVE(int32_t, INT32_MIN, INT8_MAX, int, _PyLong_AsInt); break; } \
+ case GWN_COMP_U32: { PY_AS_NATIVE(uint32_t, 0, UINT8_MAX, uint, _PyLong_AsInt); break; } \
+ case GWN_COMP_F32: { PY_AS_NATIVE(float, 0, 0, float, PyFloat_AsDouble); break; } \
+ default: \
+ BLI_assert(0); \
+ } ((void)0)
+
+/* No error checking, callers must run PyErr_Occurred */
+static void fill_format_elem(void *data_dst_void, PyObject *py_src, const Gwn_VertAttr *attr)
+{
+#define PY_AS_NATIVE(ty_dst, ty_dst_min, ty_dst_max, ty_src, py_as_native) \
+{ \
+ ty_dst *data_dst = data_dst_void; \
+ ty_src v = py_as_native(py_src); \
+ WARN_TYPE_LIMIT_PUSH; \
+ if ((ty_dst_min != ty_dst_max) && (v < ty_dst_min || v > ty_dst_max)) { \
+ PyErr_SetString(PyExc_ValueError, fill_format_elem_range_error); \
+ } \
+ WARN_TYPE_LIMIT_POP; \
+ *data_dst = v; \
+} ((void)0)
+
+ PY_AS_NATIVE_SWITCH(attr);
+
+#undef PY_AS_NATIVE
+}
+
+/* No error checking, callers must run PyErr_Occurred */
+static void fill_format_tuple(void *data_dst_void, PyObject *py_src, const Gwn_VertAttr *attr)
+{
+ const uint len = attr->comp_ct;
+
+/**
+ * Args are constants, so range checks will be optimized out if they're nop's.
+ */
+#define PY_AS_NATIVE(ty_dst, ty_dst_min, ty_dst_max, ty_src, py_as_native) \
+ ty_dst *data_dst = data_dst_void; \
+ for (uint i = 0; i < len; i++) { \
+ ty_src v = py_as_native(PyTuple_GET_ITEM(py_src, i)); \
+ WARN_TYPE_LIMIT_PUSH; \
+ if ((ty_dst_min != ty_dst_max) && (v < ty_dst_min || v > ty_dst_max)) { \
+ PyErr_SetString(PyExc_ValueError, fill_format_elem_range_error); \
+ } \
+ WARN_TYPE_LIMIT_POP; \
+ data_dst[i] = v; \
+ } ((void)0)
+
+ PY_AS_NATIVE_SWITCH(attr);
+
+#undef PY_AS_NATIVE
+}
+
+#undef PY_AS_NATIVE_SWITCH
+#undef WARN_TYPE_LIMIT_PUSH
+#undef WARN_TYPE_LIMIT_POP
+
+static bool bpygwn_vertbuf_fill_impl(
+ Gwn_VertBuf *vbo,
+ uint data_id, PyObject *seq)
+{
+ bool ok = true;
+ const Gwn_VertAttr *attr = &vbo->format.attribs[data_id];
+
+ Gwn_VertBufRaw data_step;
+ GWN_vertbuf_attr_get_raw_data(vbo, data_id, &data_step);
+
+ PyObject *seq_fast = PySequence_Fast(seq, "Vertex buffer fill");
+ if (seq_fast == NULL) {
+ goto finally;
+ }
+
+ const uint seq_len = PySequence_Fast_GET_SIZE(seq_fast);
+
+ if (seq_len != vbo->vertex_ct) {
+ PyErr_Format(PyExc_ValueError,
+ "Expected a sequence of size %d, got %d",
+ vbo->vertex_ct, seq_len);
+ }
+
+ PyObject **seq_items = PySequence_Fast_ITEMS(seq_fast);
+
+ if (attr->comp_ct == 1) {
+ for (uint i = 0; i < seq_len; i++) {
+ uchar *data = (uchar *)GWN_vertbuf_raw_step(&data_step);
+ PyObject *item = seq_items[i];
+ fill_format_elem(data, item, attr);
+ }
+ }
+ else {
+ for (uint i = 0; i < seq_len; i++) {
+ uchar *data = (uchar *)GWN_vertbuf_raw_step(&data_step);
+ PyObject *item = seq_items[i];
+ if (!PyTuple_CheckExact(item)) {
+ PyErr_Format(PyExc_ValueError,
+ "expected a tuple, got %s",
+ Py_TYPE(item)->tp_name);
+ ok = false;
+ goto finally;
+ }
+ if (PyTuple_GET_SIZE(item) != attr->comp_ct) {
+ PyErr_Format(PyExc_ValueError,
+ "expected a tuple of size %d, got %d",
+ attr->comp_ct, PyTuple_GET_SIZE(item));
+ ok = false;
+ goto finally;
+ }
+
+ /* May trigger error, check below */
+ fill_format_tuple(data, item, attr);
+ }
+ }
+
+ if (PyErr_Occurred()) {
+ ok = false;
+ }
+
+finally:
+
+ Py_DECREF(seq_fast);
+ return ok;
+}
+
+/* handy, but not used just now */
+#if 0
+static int bpygwn_find_id(const Gwn_VertFormat *fmt, const char *id)
+{
+ for (int i = 0; i < fmt->attrib_ct; i++) {
+ for (uint j = 0; j < fmt->name_ct; j++) {
+ if (STREQ(fmt->attribs[i].name[j], id)) {
+ return i;
+ }
+ }
+ }
+ return -1;
+}
+#endif
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name VertFormat Type
+ * \{ */
+
+static PyObject *bpygwn_VertFormat_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
+{
+ if (PyTuple_GET_SIZE(args) || (kwds && PyDict_Size(kwds))) {
+ PyErr_SetString(PyExc_TypeError,
+ "VertFormat(): takes no arguments");
+ return NULL;
+ }
+
+ BPyGwn_VertFormat *ret = (BPyGwn_VertFormat *)BPyGwn_VertFormat_CreatePyObject(NULL);
+
+ return (PyObject *)ret;
+}
+
+PyDoc_STRVAR(bpygwn_VertFormat_attr_add_doc,
+"TODO"
+);
+static PyObject *bpygwn_VertFormat_attr_add(BPyGwn_VertFormat *self, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"id", "comp_type", "len", "fetch_mode", NULL};
+
+ struct {
+ const char *id;
+ Gwn_VertCompType comp_type;
+ uint len;
+ Gwn_VertFetchMode fetch_mode;
+ } params;
+
+ if (self->fmt.attrib_ct == GWN_VERT_ATTR_MAX_LEN) {
+ PyErr_SetString(PyExc_ValueError, "Maxumum attr reached " STRINGIFY(GWN_VERT_ATTR_MAX_LEN));
+ return NULL;
+ }
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwds, "$sO&IO&:attr_add", (char **)kwlist,
+ &params.id,
+ bpygwn_ParseVertCompType, &params.comp_type,
+ &params.len,
+ bpygwn_ParseVertFetchMode, &params.fetch_mode))
+ {
+ return NULL;
+ }
+
+ uint attr_id = GWN_vertformat_attr_add(&self->fmt, params.id, params.comp_type, params.len, params.fetch_mode);
+ return PyLong_FromLong(attr_id);
+}
+
+static struct PyMethodDef bpygwn_VertFormat_methods[] = {
+ {"attr_add", (PyCFunction)bpygwn_VertFormat_attr_add,
+ METH_VARARGS | METH_KEYWORDS, bpygwn_VertFormat_attr_add_doc},
+ {NULL, NULL, 0, NULL}
+};
+
+
+static void bpygwn_VertFormat_dealloc(BPyGwn_VertFormat *self)
+{
+ Py_TYPE(self)->tp_free(self);
+}
+
+PyTypeObject BPyGwn_VertFormat_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "Gwn_VertFormat",
+ .tp_basicsize = sizeof(BPyGwn_VertFormat),
+ .tp_dealloc = (destructor)bpygwn_VertFormat_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_methods = bpygwn_VertFormat_methods,
+ .tp_new = bpygwn_VertFormat_new,
+};
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name VertBuf Type
+ * \{ */
+
+static PyObject *bpygwn_VertBuf_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
+{
+ const char * const keywords[] = {"len", "format", NULL};
+
+ struct {
+ BPyGwn_VertFormat *py_fmt;
+ uint len;
+ } params;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwds,
+ "$IO!:Gwn_VertBuf.__new__", (char **)keywords,
+ &params.len,
+ &BPyGwn_VertFormat_Type, &params.py_fmt))
+ {
+ return NULL;
+ }
+
+ struct Gwn_VertBuf *vbo = GWN_vertbuf_create_with_format(&params.py_fmt->fmt);
+
+ GWN_vertbuf_data_alloc(vbo, params.len);
+
+ return BPyGwn_VertBuf_CreatePyObject(vbo);
+}
+
+PyDoc_STRVAR(bpygwn_VertBuf_fill_doc,
+"TODO"
+);
+static PyObject *bpygwn_VertBuf_fill(BPyGwn_VertBuf *self, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"id", "data", NULL};
+
+ struct {
+ uint id;
+ PyObject *py_seq_data;
+ } params;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwds, "$IO:fill", (char **)kwlist,
+ &params.id,
+ &params.py_seq_data))
+ {
+ return NULL;
+ }
+
+ if (params.id >= self->buf->format.attrib_ct) {
+ PyErr_Format(PyExc_ValueError,
+ "Format id %d out of range",
+ params.id);
+ return NULL;
+ }
+
+ if (self->buf->vbo_id != 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "Can't fill, buffer already in use");
+ return NULL;
+ }
+
+ if (!bpygwn_vertbuf_fill_impl(self->buf, params.id, params.py_seq_data)) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+static struct PyMethodDef bpygwn_VertBuf_methods[] = {
+ {"fill", (PyCFunction) bpygwn_VertBuf_fill,
+ METH_VARARGS | METH_KEYWORDS, bpygwn_VertBuf_fill_doc},
+ {NULL, NULL, 0, NULL}
+};
+
+static void bpygwn_VertBuf_dealloc(BPyGwn_VertBuf *self)
+{
+ GWN_vertbuf_discard(self->buf);
+ Py_TYPE(self)->tp_free(self);
+}
+
+PyTypeObject BPyGwn_VertBuf_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "Gwn_VertBuf",
+ .tp_basicsize = sizeof(BPyGwn_VertBuf),
+ .tp_dealloc = (destructor)bpygwn_VertBuf_dealloc,
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_methods = bpygwn_VertBuf_methods,
+ .tp_new = bpygwn_VertBuf_new,
+};
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name VertBatch Type
+ * \{ */
+
+static PyObject *bpygwn_Batch_new(PyTypeObject *UNUSED(type), PyObject *args, PyObject *kwds)
+{
+ const char * const keywords[] = {"type", "buf", NULL};
+
+ struct {
+ Gwn_PrimType type_id;
+ BPyGwn_VertBuf *py_buf;
+ } params;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwds,
+ "$O&O!:Gwn_Batch.__new__", (char **)keywords,
+ bpygwn_ParsePrimType, &params.type_id,
+ &BPyGwn_VertBuf_Type, &params.py_buf))
+ {
+ return NULL;
+ }
+
+ Gwn_Batch *batch = GWN_batch_create(params.type_id, params.py_buf->buf, NULL);
+ BPyGwn_Batch *ret = (BPyGwn_Batch *)BPyGwn_Batch_CreatePyObject(batch);
+
+#ifdef USE_GWN_PY_REFERENCES
+ ret->references = PyList_New(1);
+ PyList_SET_ITEM(ret->references, 0, (PyObject *)params.py_buf);
+ Py_INCREF(params.py_buf);
+ PyObject_GC_Track(ret);
+#endif
+
+ return (PyObject *)ret;
+}
+
+PyDoc_STRVAR(bpygwn_VertBatch_vertbuf_add_doc,
+"TODO"
+);
+static PyObject *bpygwn_VertBatch_vertbuf_add(BPyGwn_Batch *self, BPyGwn_VertBuf *py_buf)
+{
+ if (!BPyGwn_VertBuf_Check(py_buf)) {
+ PyErr_Format(PyExc_TypeError,
+ "Expected a Gwn_VertBuf, got %s",
+ Py_TYPE(py_buf)->tp_name);
+ return NULL;
+ }
+
+ if (self->batch->verts[0]->vertex_ct != py_buf->buf->vertex_ct) {
+ PyErr_Format(PyExc_TypeError,
+ "Expected %d length, got %d",
+ self->batch->verts[0]->vertex_ct, py_buf->buf->vertex_ct);
+ return NULL;
+ }
+
+#ifdef USE_GWN_PY_REFERENCES
+ /* Hold user */
+ PyList_Append(self->references, (PyObject *)py_buf);
+#endif
+
+ GWN_batch_vertbuf_add(self->batch, py_buf->buf);
+ Py_RETURN_NONE;
+}
+
+/* Currently magic number from Py perspective. */
+PyDoc_STRVAR(bpygwn_VertBatch_program_set_builtin_doc,
+"TODO"
+);
+static PyObject *bpygwn_VertBatch_program_set_builtin(BPyGwn_Batch *self, PyObject *args, PyObject *kwds)
+{
+ static const char *kwlist[] = {"id", NULL};
+
+ struct {
+ const char *shader;
+ } params;
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwds, "s:program_set_builtin", (char **)kwlist,
+ &params.shader))
+ {
+ return NULL;
+ }
+
+ GPUBuiltinShader shader;
+
+#define MATCH_ID(id) \
+ if (STREQ(params.shader, STRINGIFY(id))) { \
+ shader = GPU_SHADER_##id; \
+ goto success; \
+ } ((void)0)
+
+ MATCH_ID(2D_FLAT_COLOR);
+ MATCH_ID(2D_SMOOTH_COLOR);
+ MATCH_ID(2D_UNIFORM_COLOR);
+
+ MATCH_ID(3D_FLAT_COLOR);
+ MATCH_ID(3D_SMOOTH_COLOR);
+ MATCH_ID(3D_UNIFORM_COLOR);
+
+#undef MATCH_ID
+
+ PyErr_SetString(PyExc_ValueError,
+ "shader name not known");
+ return NULL;
+
+success:
+ GWN_batch_program_set_builtin(self->batch, shader);
+ Py_RETURN_NONE;
+}
+
+static PyObject *bpygwn_VertBatch_uniform_bool(BPyGwn_Batch *self, PyObject *args)
+{
+ struct {
+ const char *id;
+ bool values[1];
+ } params;
+
+ if (!PyArg_ParseTuple(
+ args, "si:uniform_b",
+ &params.id,
+ &params.values[0]))
+ {
+ return NULL;
+ }
+
+ GWN_batch_uniform_1b(self->batch, params.id, params.values[0]);
+ Py_RETURN_NONE;
+}
+
+static PyObject *bpygwn_VertBatch_uniform_i32(BPyGwn_Batch *self, PyObject *args)
+{
+ struct {
+ const char *id;
+ int values[1];
+ } params;
+
+ if (!PyArg_ParseTuple(
+ args, "si:uniform_i",
+ &params.id,
+ &params.values[0]))
+ {
+ return NULL;
+ }
+
+ GWN_batch_uniform_1i(self->batch, params.id, params.values[0]);
+ Py_RETURN_NONE;
+}
+
+static PyObject *bpygwn_VertBatch_uniform_f32(BPyGwn_Batch *self, PyObject *args)
+{
+ struct {
+ const char *id;
+ float values[4];
+ } params;
+
+ if (!PyArg_ParseTuple(
+ args, "sf|fff:uniform_f",
+ &params.id,
+ &params.values[0], &params.values[1], &params.values[2], &params.values[3]))
+ {
+ return NULL;
+ }
+
+ switch(PyTuple_GET_SIZE(args)) {
+ case 2: GWN_batch_uniform_1f(self->batch, params.id, params.values[0]); break;
+ case 3: GWN_batch_uniform_2fv(self->batch, params.id, params.values); break;
+ case 4: GWN_batch_uniform_3fv(self->batch, params.id, params.values); break;
+ case 5: GWN_batch_uniform_4fv(self->batch, params.id, params.values); break;
+ default:
+ BLI_assert(0);
+ }
+ Py_RETURN_NONE;
+}
+
+PyDoc_STRVAR(bpygwn_VertBatch_draw_doc,
+"TODO"
+);
+static PyObject *bpygwn_VertBatch_draw(BPyGwn_Batch *self)
+{
+ if (!glIsProgram(self->batch->program)) {
+ PyErr_SetString(PyExc_ValueError,
+ "batch program has not not set");
+ }
+ GWN_batch_draw(self->batch);
+ Py_RETURN_NONE;
+}
+
+static struct PyMethodDef bpygwn_VertBatch_methods[] = {
+ {"vertbuf_add", (PyCFunction)bpygwn_VertBatch_vertbuf_add,
+ METH_O, bpygwn_VertBatch_vertbuf_add_doc},
+ {"program_set_builtin", (PyCFunction)bpygwn_VertBatch_program_set_builtin,
+ METH_VARARGS | METH_KEYWORDS, bpygwn_VertBatch_program_set_builtin_doc},
+ {"uniform_bool", (PyCFunction)bpygwn_VertBatch_uniform_bool,
+ METH_VARARGS, NULL},
+ {"uniform_i32", (PyCFunction)bpygwn_VertBatch_uniform_i32,
+ METH_VARARGS, NULL},
+ {"uniform_f32", (PyCFunction)bpygwn_VertBatch_uniform_f32,
+ METH_VARARGS, NULL},
+ {"draw", (PyCFunction) bpygwn_VertBatch_draw,
+ METH_NOARGS, bpygwn_VertBatch_draw_doc},
+ {NULL, NULL, 0, NULL}
+};
+
+#ifdef USE_GWN_PY_REFERENCES
+
+static int bpygwn_Batch_traverse(BPyGwn_Batch *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->references);
+ return 0;
+}
+
+static int bpygwn_Batch_clear(BPyGwn_Batch *self)
+{
+ Py_CLEAR(self->references);
+ return 0;
+}
+
+#endif
+
+static void bpygwn_Batch_dealloc(BPyGwn_Batch *self)
+{
+ GWN_batch_discard(self->batch);
+
+#ifdef USE_GWN_PY_REFERENCES
+ if (self->references) {
+ PyObject_GC_UnTrack(self);
+ bpygwn_Batch_clear(self);
+ Py_XDECREF(self->references);
+ }
+#endif
+
+ Py_TYPE(self)->tp_free(self);
+}
+
+PyTypeObject BPyGwn_Batch_Type = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "Gwn_Batch",
+ .tp_basicsize = sizeof(BPyGwn_Batch),
+ .tp_dealloc = (destructor)bpygwn_Batch_dealloc,
+#ifdef USE_GWN_PY_REFERENCES
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_traverse = (traverseproc)bpygwn_Batch_traverse,
+ .tp_clear = (inquiry)bpygwn_Batch_clear,
+#else
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+#endif
+ .tp_methods = bpygwn_VertBatch_methods,
+ .tp_new = bpygwn_Batch_new,
+};
+
+/* -------------------------------------------------------------------- */
+
+
+/** \name Gawain Types Module
+ * \{ */
+
+static struct PyModuleDef BPy_BM_types_module_def = {
+ PyModuleDef_HEAD_INIT,
+ .m_name = "_gawain.types",
+};
+
+PyObject *BPyInit_gawain_types(void)
+{
+ PyObject *submodule;
+
+ submodule = PyModule_Create(&BPy_BM_types_module_def);
+
+ if (PyType_Ready(&BPyGwn_VertFormat_Type) < 0)
+ return NULL;
+ if (PyType_Ready(&BPyGwn_VertBuf_Type) < 0)
+ return NULL;
+ if (PyType_Ready(&BPyGwn_Batch_Type) < 0)
+ return NULL;
+
+#define MODULE_TYPE_ADD(s, t) \
+ PyModule_AddObject(s, t.tp_name, (PyObject *)&t); Py_INCREF((PyObject *)&t)
+
+ MODULE_TYPE_ADD(submodule, BPyGwn_VertFormat_Type);
+ MODULE_TYPE_ADD(submodule, BPyGwn_VertBuf_Type);
+ MODULE_TYPE_ADD(submodule, BPyGwn_Batch_Type);
+
+#undef MODULE_TYPE_ADD
+
+ return submodule;
+}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Public API
+ * \{ */
+
+PyObject *BPyGwn_VertFormat_CreatePyObject(Gwn_VertFormat *fmt)
+{
+ BPyGwn_VertFormat *self;
+
+ self = PyObject_New(BPyGwn_VertFormat, &BPyGwn_VertFormat_Type);
+ if (fmt) {
+ self->fmt = *fmt;
+ }
+ else {
+ memset(&self->fmt, 0, sizeof(self->fmt));
+ }
+
+ return (PyObject *)self;
+}
+
+PyObject *BPyGwn_VertBuf_CreatePyObject(Gwn_VertBuf *buf)
+{
+ BPyGwn_VertBuf *self;
+
+ self = PyObject_New(BPyGwn_VertBuf, &BPyGwn_VertBuf_Type);
+ self->buf = buf;
+
+ return (PyObject *)self;
+}
+
+
+PyObject *BPyGwn_Batch_CreatePyObject(Gwn_Batch *batch)
+{
+ BPyGwn_Batch *self;
+
+#ifdef USE_GWN_PY_REFERENCES
+ self = (BPyGwn_Batch *)_PyObject_GC_New(&BPyGwn_Batch_Type);
+ self->references = NULL;
+#else
+ self = PyObject_New(BPyGwn_Batch, &BPyGwn_Batch_Type);
+#endif
+
+ self->batch = batch;
+
+ return (PyObject *)self;
+}
+
+/** \} */
diff --git a/source/blender/python/gawain/gwn_py_types.h b/source/blender/python/gawain/gwn_py_types.h
new file mode 100644
index 00000000000..dde6cf98827
--- /dev/null
+++ b/source/blender/python/gawain/gwn_py_types.h
@@ -0,0 +1,67 @@
+/*
+ * ***** 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.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/gawain/gwn_py_types.h
+ * \ingroup pygawain
+ */
+
+#ifndef __GWN_PY_TYPES_H__
+#define __GWN_PY_TYPES_H__
+
+#include "BLI_compiler_attrs.h"
+
+#define USE_GWN_PY_REFERENCES
+
+extern PyTypeObject BPyGwn_VertFormat_Type;
+extern PyTypeObject BPyGwn_VertBuf_Type;
+extern PyTypeObject BPyGwn_Batch_Type;
+
+#define BPyGwn_VertFormat_Check(v) (Py_TYPE(v) == &BPyGwn_VertFormat_Type)
+#define BPyGwn_VertBuf_Check(v) (Py_TYPE(v) == &BPyGwn_VertBuf_Type)
+#define BPyGwn_Batch_Check(v) (Py_TYPE(v) == &BPyGwn_Batch_Type)
+
+typedef struct BPyGwn_VertFormat {
+ PyObject_VAR_HEAD
+ struct Gwn_VertFormat fmt;
+} BPyGwn_VertFormat;
+
+typedef struct BPyGwn_VertBuf {
+ PyObject_VAR_HEAD
+ /* The buf is owned, we may support thin wrapped batches later. */
+ struct Gwn_VertBuf *buf;
+} BPyGwn_VertBuf;
+
+typedef struct BPyGwn_Batch {
+ PyObject_VAR_HEAD
+ /* The batch is owned, we may support thin wrapped batches later. */
+ struct Gwn_Batch *batch;
+#ifdef USE_GWN_PY_REFERENCES
+ /* Just to keep a user to prevent freeing buf's we're using */
+ PyObject *references;
+#endif
+} BPyGwn_Batch;
+
+PyObject *BPyInit_gawain_types(void);
+
+PyObject *BPyGwn_VertFormat_CreatePyObject(struct Gwn_VertFormat *fmt);
+PyObject *BPyGwn_VertBuf_CreatePyObject(struct Gwn_VertBuf *vbo) ATTR_NONNULL(1);
+PyObject *BPyGwn_Batch_CreatePyObject(struct Gwn_Batch *batch) ATTR_NONNULL(1);
+
+#endif /* __GWN_PY_TYPES_H__ */
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index c6337f2ac28..7ddb41c3b0d 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -72,6 +72,7 @@
#include "../generic/bgl.h"
#include "../generic/blf_py_api.h"
#include "../generic/idprop_py_api.h"
+#include "../gawain/gwn_py_api.h"
#include "../bmesh/bmesh_py_api.h"
#include "../mathutils/mathutils.h"
@@ -212,6 +213,7 @@ static struct _inittab bpy_internal_modules[] = {
{"mathutils.kdtree", PyInit_mathutils_kdtree},
#endif
{"_bpy_path", BPyInit__bpy_path},
+ {"_gawain", BPyInit_gawain},
{"bgl", BPyInit_bgl},
{"blf", BPyInit_blf},
{"bmesh", BPyInit_bmesh},
diff --git a/source/blender/python/intern/bpy_manipulator_wrap.c b/source/blender/python/intern/bpy_manipulator_wrap.c
index db9fcdb377a..a4188698a5e 100644
--- a/source/blender/python/intern/bpy_manipulator_wrap.c
+++ b/source/blender/python/intern/bpy_manipulator_wrap.c
@@ -130,7 +130,7 @@ static void manipulator_properties_init(wmManipulatorType *wt)
/* only call this so pyrna_deferred_register_class gives a useful error
* WM_operatortype_append_ptr will call RNA_def_struct_identifier
* later */
- RNA_def_struct_identifier(wt->srna, wt->idname);
+ RNA_def_struct_identifier_no_struct_map(wt->srna, wt->idname);
if (pyrna_deferred_register_class(wt->srna, py_class) != 0) {
PyErr_Print(); /* failed to register operator props */
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 90719905a79..9d57adca946 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -48,10 +48,12 @@ static void operator_properties_init(wmOperatorType *ot)
PyTypeObject *py_class = ot->ext.data;
RNA_struct_blender_type_set(ot->ext.srna, ot);
- /* only call this so pyrna_deferred_register_class gives a useful error
- * WM_operatortype_append_ptr will call RNA_def_struct_identifier
- * later */
- RNA_def_struct_identifier(ot->srna, ot->idname);
+ /* Only call this so pyrna_deferred_register_class gives a useful error
+ * WM_operatortype_append_ptr will call RNA_def_struct_identifier later.
+ *
+ * Note the 'no_struct_map' function is used since the actual struct name is already used by the operator.
+ */
+ RNA_def_struct_identifier_no_struct_map(ot->srna, ot->idname);
if (pyrna_deferred_register_class(ot->srna, py_class) != 0) {
PyErr_Print(); /* failed to register operator props */
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index 2963951838b..bc3cd0bf416 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -1163,7 +1163,6 @@ static PyObject *C_BVHTree_FromObject(PyObject *UNUSED(cls), PyObject *args, PyO
/* Get data for tessellation */
{
- DM_ensure_looptri(dm);
lt = dm->getLoopTriArray(dm);
tris_len = (unsigned int)dm->getNumLoopTri(dm);
diff --git a/source/blender/quicktime/CMakeLists.txt b/source/blender/quicktime/CMakeLists.txt
index f853c35457f..cee2cea99fb 100644
--- a/source/blender/quicktime/CMakeLists.txt
+++ b/source/blender/quicktime/CMakeLists.txt
@@ -52,7 +52,7 @@ set(SRC
add_definitions(-DWITH_QUICKTIME)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/quicktime/apple/qtkit_export.m b/source/blender/quicktime/apple/qtkit_export.m
index 1ac3c58f888..d2508fe108a 100644
--- a/source/blender/quicktime/apple/qtkit_export.m
+++ b/source/blender/quicktime/apple/qtkit_export.m
@@ -35,7 +35,7 @@
#include "DNA_userdef_types.h"
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
+# include <AUD_Device.h>
#endif
#include "BLI_utildefines.h"
diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt
index cfa97a9e177..0894f246445 100644
--- a/source/blender/windowmanager/CMakeLists.txt
+++ b/source/blender/windowmanager/CMakeLists.txt
@@ -97,7 +97,7 @@ set(SRC
)
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index da1b5feea3d..6da6d1df348 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -430,7 +430,7 @@ void wm_clear_default_size(bContext *C)
/* on startup, it adds all data, for matching */
void wm_add_default(bContext *C)
{
- wmWindowManager *wm = BKE_libblock_alloc(CTX_data_main(C), ID_WM, "WinMan");
+ wmWindowManager *wm = BKE_libblock_alloc(CTX_data_main(C), ID_WM, "WinMan", 0);
wmWindow *win;
bScreen *screen = CTX_wm_screen(C); /* XXX from file read hrmf */
struct WorkSpace *workspace = G.main->workspaces.last;
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index cedf50a3035..784cdcc97dd 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -457,7 +457,7 @@ void wm_file_read_report(bContext *C)
* Logic shared between #WM_file_read & #wm_homefile_read,
* updates to make after reading a file.
*/
-static void wm_file_read_post(bContext *C, bool is_startup_file)
+static void wm_file_read_post(bContext *C, const bool is_startup_file, const bool use_userdef)
{
bool addons_loaded = false;
wmWindowManager *wm = CTX_wm_manager(C);
@@ -476,13 +476,14 @@ static void wm_file_read_post(bContext *C, bool is_startup_file)
if (is_startup_file) {
/* possible python hasn't been initialized */
if (CTX_py_init_get(C)) {
- /* Only run when we have a template path found. */
- if (BKE_appdir_app_template_any()) {
- BPY_execute_string(C, "__import__('bl_app_template_utils').reset()");
+ if (use_userdef) {
+ /* Only run when we have a template path found. */
+ if (BKE_appdir_app_template_any()) {
+ BPY_execute_string(C, "__import__('bl_app_template_utils').reset()");
+ }
+ /* sync addons, these may have changed from the defaults */
+ BPY_execute_string(C, "__import__('addon_utils').reset_all()");
}
- /* sync addons, these may have changed from the defaults */
- BPY_execute_string(C, "__import__('addon_utils').reset_all()");
-
BPY_python_reset(C);
addons_loaded = true;
}
@@ -596,7 +597,7 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
}
}
- wm_file_read_post(C, false);
+ wm_file_read_post(C, false, false);
success = true;
}
@@ -644,13 +645,15 @@ bool WM_file_read(bContext *C, const char *filepath, ReportList *reports)
*
* \param use_factory_settings: Ignore on-disk startup file, use bundled ``datatoc_startup_blend`` instead.
* Used for "Restore Factory Settings".
+ * \param use_userdef: Load factory settings as well as startup file.
+ * Disabled for "File New" we don't want to reload preferences.
* \param filepath_startup_override: Optional path pointing to an alternative blend file (may be NULL).
* \param app_template_override: Template to use instead of the template defined in user-preferences.
* When not-null, this is written into the user preferences.
*/
int wm_homefile_read(
bContext *C, ReportList *reports,
- bool use_factory_settings, bool use_empty_data,
+ bool use_factory_settings, bool use_empty_data, bool use_userdef,
const char *filepath_startup_override, const char *app_template_override)
{
ListBase wmbase;
@@ -674,7 +677,7 @@ int wm_homefile_read(
* And in this case versioning code is to be run.
*/
bool read_userdef_from_memory = false;
- eBLOReadSkip skip_flags = 0;
+ eBLOReadSkip skip_flags = use_userdef ? 0 : BLO_READ_SKIP_USERDEF;
/* options exclude eachother */
BLI_assert((use_factory_settings && filepath_startup_override) == 0);
@@ -701,7 +704,9 @@ int wm_homefile_read(
if (!use_factory_settings) {
if (cfgdir) {
BLI_path_join(filepath_startup, sizeof(filepath_startup), cfgdir, BLENDER_STARTUP_FILE, NULL);
- BLI_path_join(filepath_userdef, sizeof(filepath_startup), cfgdir, BLENDER_USERPREF_FILE, NULL);
+ if (use_userdef) {
+ BLI_path_join(filepath_userdef, sizeof(filepath_startup), cfgdir, BLENDER_USERPREF_FILE, NULL);
+ }
}
else {
use_factory_settings = true;
@@ -713,14 +718,16 @@ int wm_homefile_read(
}
/* load preferences before startup.blend */
- if (!use_factory_settings && BLI_exists(filepath_userdef)) {
- UserDef *userdef = BKE_blendfile_userdef_read(filepath_userdef, NULL);
- if (userdef != NULL) {
- BKE_blender_userdef_set_data(userdef);
- MEM_freeN(userdef);
-
- skip_flags |= BLO_READ_SKIP_USERDEF;
- printf("Read prefs: %s\n", filepath_userdef);
+ if (use_userdef) {
+ if (!use_factory_settings && BLI_exists(filepath_userdef)) {
+ UserDef *userdef = BKE_blendfile_userdef_read(filepath_userdef, NULL);
+ if (userdef != NULL) {
+ BKE_blender_userdef_set_data(userdef);
+ MEM_freeN(userdef);
+
+ skip_flags |= BLO_READ_SKIP_USERDEF;
+ printf("Read prefs: %s\n", filepath_userdef);
+ }
}
}
@@ -729,20 +736,20 @@ int wm_homefile_read(
if (filepath_startup_override != NULL) {
/* pass */
}
- else if (app_template_override && app_template_override[0]) {
+ else if (app_template_override) {
+ /* This may be clearing the current template by setting to an empty string. */
app_template = app_template_override;
}
else if (!use_factory_settings && U.app_template[0]) {
app_template = U.app_template;
}
- if (app_template != NULL) {
+ if ((app_template != NULL) && (app_template[0] != '\0')) {
BKE_appdir_app_template_id_search(app_template, app_template_system, sizeof(app_template_system));
BLI_path_join(app_template_config, sizeof(app_template_config), cfgdir, app_template, NULL);
- }
- /* insert template name into startup file */
- if (app_template != NULL) {
+ /* Insert template name into startup file. */
+
/* note that the path is being set even when 'use_factory_settings == true'
* this is done so we can load a templates factory-settings */
if (!use_factory_settings) {
@@ -780,8 +787,12 @@ int wm_homefile_read(
success = BKE_blendfile_read_from_memory(
C, datatoc_startup_blend, datatoc_startup_blend_size,
NULL, skip_flags, true);
- if (success && !(skip_flags & BLO_READ_SKIP_USERDEF)) {
- read_userdef_from_memory = true;
+ if (success) {
+ if (use_userdef) {
+ if ((skip_flags & BLO_READ_SKIP_USERDEF) == 0) {
+ read_userdef_from_memory = true;
+ }
+ }
}
if (BLI_listbase_is_empty(&wmbase)) {
wm_clear_default_size(C);
@@ -809,21 +820,23 @@ int wm_homefile_read(
BLI_path_join(temp_path, sizeof(temp_path), app_template_system, BLENDER_USERPREF_FILE, NULL);
}
- UserDef *userdef_template = NULL;
- /* just avoids missing file warning */
- if (BLI_exists(temp_path)) {
- userdef_template = BKE_blendfile_userdef_read(temp_path, NULL);
- }
- if (userdef_template == NULL) {
- /* we need to have preferences load to overwrite preferences from previous template */
- userdef_template = BKE_blendfile_userdef_read_from_memory(
- datatoc_startup_blend, datatoc_startup_blend_size, NULL);
- read_userdef_from_memory = true;
- }
- if (userdef_template) {
- BKE_blender_userdef_set_app_template(userdef_template);
- BKE_blender_userdef_free_data(userdef_template);
- MEM_freeN(userdef_template);
+ if (use_userdef) {
+ UserDef *userdef_template = NULL;
+ /* just avoids missing file warning */
+ if (BLI_exists(temp_path)) {
+ userdef_template = BKE_blendfile_userdef_read(temp_path, NULL);
+ }
+ if (userdef_template == NULL) {
+ /* we need to have preferences load to overwrite preferences from previous template */
+ userdef_template = BKE_blendfile_userdef_read_from_memory(
+ datatoc_startup_blend, datatoc_startup_blend_size, NULL);
+ read_userdef_from_memory = true;
+ }
+ if (userdef_template) {
+ BKE_blender_userdef_set_app_template(userdef_template);
+ BKE_blender_userdef_free_data(userdef_template);
+ MEM_freeN(userdef_template);
+ }
}
}
@@ -834,9 +847,11 @@ int wm_homefile_read(
/* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise
* can remove this eventually, only in a 2.53 and older, now its not written */
G.fileflags &= ~G_FILE_RELATIVE_REMAP;
-
- /* check userdef before open window, keymaps etc */
- wm_init_userdef(CTX_data_main(C), read_userdef_from_memory);
+
+ if (use_userdef) {
+ /* check userdef before open window, keymaps etc */
+ wm_init_userdef(CTX_data_main(C), read_userdef_from_memory);
+ }
/* match the read WM with current WM */
wm_window_match_do(C, &wmbase);
@@ -844,9 +859,11 @@ int wm_homefile_read(
G.main->name[0] = '\0';
- /* When loading factory settings, the reset solid OpenGL lights need to be applied. */
- if (!G.background) {
- GPU_default_lights();
+ if (use_userdef) {
+ /* When loading factory settings, the reset solid OpenGL lights need to be applied. */
+ if (!G.background) {
+ GPU_default_lights();
+ }
}
/* start with save preference untitled.blend */
@@ -854,7 +871,7 @@ int wm_homefile_read(
/* disable auto-play in startup.blend... */
G.fileflags &= ~G_FILE_AUTOPLAY;
- wm_file_read_post(C, true);
+ wm_file_read_post(C, true, use_userdef);
return true;
}
@@ -1576,6 +1593,7 @@ void WM_OT_read_history(wmOperatorType *ot)
static int wm_homefile_read_exec(bContext *C, wmOperator *op)
{
const bool use_factory_settings = (STREQ(op->type->idname, "WM_OT_read_factory_settings"));
+ bool use_userdef = false;
char filepath_buf[FILE_MAX];
const char *filepath = NULL;
@@ -1599,6 +1617,8 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
else {
/* always load UI for factory settings (prefs will re-init) */
G.fileflags &= ~G_FILE_NO_UI;
+ /* Always load preferences with factory settings. */
+ use_userdef = true;
}
char app_template_buf[sizeof(U.app_template)];
@@ -1610,17 +1630,15 @@ static int wm_homefile_read_exec(bContext *C, wmOperator *op)
if (prop_app_template && RNA_property_is_set(op->ptr, prop_app_template)) {
RNA_property_string_get(op->ptr, prop_app_template, app_template_buf);
app_template = app_template_buf;
- }
- else if (!use_factory_settings) {
- /* TODO: dont reset prefs on 'New File' */
- BLI_strncpy(app_template_buf, U.app_template, sizeof(app_template_buf));
- app_template = app_template_buf;
+
+ /* Always load preferences when switching templates. */
+ use_userdef = true;
}
else {
app_template = NULL;
}
- if (wm_homefile_read(C, op->reports, use_factory_settings, use_empty_data, filepath, app_template)) {
+ if (wm_homefile_read(C, op->reports, use_factory_settings, use_empty_data, use_userdef, filepath, app_template)) {
if (use_splash) {
WM_init_splash(C);
}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index ec248c28f0f..8346535cd6a 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -189,15 +189,12 @@ void WM_init(bContext *C, int argc, const char **argv)
BLF_init(); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */
BLT_lang_init();
- /* Enforce loading the UI for the initial homefile */
- G.fileflags &= ~G_FILE_NO_UI;
-
/* reports cant be initialized before the wm,
* but keep before file reading, since that may report errors */
wm_init_reports(C);
/* get the default database, plus a wm */
- wm_homefile_read(C, NULL, G.factory_startup, false, NULL, NULL);
+ wm_homefile_read(C, NULL, G.factory_startup, false, true, NULL, NULL);
BLT_lang_set(NULL);
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index eeab9309a59..38d122aff5f 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -179,7 +179,7 @@ static void wm_operatortype_append__end(wmOperatorType *ot)
/* XXX All ops should have a description but for now allow them not to. */
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description ? ot->description : UNDOCUMENTED_OPERATOR_TIP);
- RNA_def_struct_identifier(ot->srna, ot->idname);
+ RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
}
@@ -401,7 +401,7 @@ wmOperatorType *WM_operatortype_append_macro(const char *idname, const char *nam
ot->description = UNDOCUMENTED_OPERATOR_TIP;
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
- RNA_def_struct_identifier(ot->srna, ot->idname);
+ RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
/* Use i18n context from ext.srna if possible (py operators). */
i18n_context = ot->ext.srna ? RNA_struct_translation_context(ot->ext.srna) : BLT_I18NCONTEXT_OPERATOR_DEFAULT;
RNA_def_struct_translation_context(ot->srna, i18n_context);
@@ -435,7 +435,7 @@ void WM_operatortype_append_macro_ptr(void (*opfunc)(wmOperatorType *, void *),
opfunc(ot, userdata);
RNA_def_struct_ui_text(ot->srna, ot->name, ot->description);
- RNA_def_struct_identifier(ot->srna, ot->idname);
+ RNA_def_struct_identifier(&BLENDER_RNA, ot->srna, ot->idname);
BLI_ghash_insert(global_ops_hash, (void *)ot->idname, ot);
}
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index fdcded8e50a..2c766efc6a2 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -77,10 +77,10 @@
#include "WM_api.h" /* only for WM_main_playanim */
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
-# include AUD_HANDLE_H
-# include AUD_SOUND_H
-# include AUD_SPECIAL_H
+# include <AUD_Device.h>
+# include <AUD_Handle.h>
+# include <AUD_Sound.h>
+# include <AUD_Special.h>
static AUD_Sound *source = NULL;
static AUD_Handle *playback_handle = NULL;
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 595ccc94584..efa0932ba92 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -416,12 +416,12 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
void WM_window_set_dpi(wmWindow *win)
{
- int auto_dpi = GHOST_GetDPIHint(win->ghostwin);
+ float auto_dpi = GHOST_GetDPIHint(win->ghostwin);
/* Clamp auto DPI to 96, since our font/interface drawing does not work well
* with lower sizes. The main case we are interested in supporting is higher
* DPI. If a smaller UI is desired it is still possible to adjust UI scale. */
- auto_dpi = MAX2(auto_dpi, 96);
+ auto_dpi = max_ff(auto_dpi, 96.0f);
/* Lazily init UI scale size, preserving backwards compatibility by
* computing UI scale from ratio of previous DPI and auto DPI */
@@ -441,13 +441,16 @@ void WM_window_set_dpi(wmWindow *win)
/* Blender's UI drawing assumes DPI 72 as a good default following macOS
* while Windows and Linux use DPI 96. GHOST assumes a default 96 so we
* remap the DPI to Blender's convention. */
+ auto_dpi *= GHOST_GetNativePixelSize(win->ghostwin);
int dpi = auto_dpi * U.ui_scale * (72.0 / 96.0f);
/* Automatically set larger pixel size for high DPI. */
- int pixelsize = MAX2(1, dpi / 54);
+ int pixelsize = max_ii(1, (int)(dpi / 64));
+ /* User adjustment for pixel size. */
+ pixelsize = max_ii(1, pixelsize + U.ui_line_width);
/* Set user preferences globals for drawing, and for forward compatibility. */
- U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin) * pixelsize;
+ U.pixelsize = pixelsize;
U.dpi = dpi / pixelsize;
U.virtual_pixel = (pixelsize == 1) ? VIRTUAL_PIXEL_NATIVE : VIRTUAL_PIXEL_DOUBLE;
U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72;
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_api.h b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
index a29e31985a0..2939070db01 100644
--- a/source/blender/windowmanager/manipulators/WM_manipulator_api.h
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_api.h
@@ -97,10 +97,26 @@ void WM_manipulator_set_flag(struct wmManipulator *mpr, const int flag, const bo
void WM_manipulator_set_scale(struct wmManipulator *mpr, float scale);
void WM_manipulator_set_line_width(struct wmManipulator *mpr, const float line_width);
-void WM_manipulator_get_color(const struct wmManipulator *mpr, float col[4]);
-void WM_manipulator_set_color(struct wmManipulator *mpr, const float col[4]);
-void WM_manipulator_get_color_highlight(const struct wmManipulator *mpr, float col_hi[4]);
-void WM_manipulator_set_color_highlight(struct wmManipulator *mpr, const float col[4]);
+void WM_manipulator_get_color(const struct wmManipulator *mpr, float color[4]);
+void WM_manipulator_set_color(struct wmManipulator *mpr, const float color[4]);
+void WM_manipulator_get_color_highlight(const struct wmManipulator *mpr, float color_hi[4]);
+void WM_manipulator_set_color_highlight(struct wmManipulator *mpr, const float color[4]);
+
+/**
+ * Leaving values NULL use values from #wmManipulator.
+ */
+struct WM_ManipulatorMatrixParams {
+ const float(*matrix_space)[4];
+ const float(*matrix_basis)[4];
+ const float(*matrix_offset)[4];
+ const float *scale_final;
+};
+
+void WM_manipulator_calc_matrix_final_params(
+ const struct wmManipulator *mpr, const struct WM_ManipulatorMatrixParams *params,
+ float r_mat[4][4]);
+
+void WM_manipulator_calc_matrix_final(const struct wmManipulator *mpr, float r_mat[4][4]);
/* properties */
void WM_manipulator_properties_create_ptr(struct PointerRNA *ptr, struct wmManipulatorType *wt);
diff --git a/source/blender/windowmanager/manipulators/WM_manipulator_types.h b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
index 065206eb9b3..82bf556ce20 100644
--- a/source/blender/windowmanager/manipulators/WM_manipulator_types.h
+++ b/source/blender/windowmanager/manipulators/WM_manipulator_types.h
@@ -71,6 +71,10 @@ typedef enum eWM_ManipulatorFlag {
WM_MANIPULATOR_DRAW_MODAL = (1 << 1), /* draw while dragging */
WM_MANIPULATOR_DRAW_VALUE = (1 << 2), /* draw an indicator for the current value while dragging */
WM_MANIPULATOR_HIDDEN = (1 << 3),
+ /**
+ * When set 'scale_final' value also scales the offset.
+ * Use when offset is to avoid screen-space overlap instead of absolute positioning. */
+ WM_MANIPULATOR_DRAW_OFFSET_SCALE = (1 << 4),
} eWM_ManipulatorFlag;
/**
@@ -192,9 +196,6 @@ struct wmManipulator {
/* over alloc target_properties after 'wmManipulatorType.struct_size' */
};
-typedef void (*wmManipulatorGroupFnInit)(
- const struct bContext *, struct wmManipulatorGroup *);
-
/* Similar to PropertyElemRNA, but has an identifier. */
typedef struct wmManipulatorProperty {
const struct wmManipulatorPropertyType *type;
@@ -272,7 +273,7 @@ typedef struct wmManipulatorType {
* - Scale isn't applied (wmManipulator.scale/user_scale).
* - Offset isn't applied (wmManipulator.matrix_offset).
*/
- wmManipulatorFnMatrixWorldGet matrix_world_get;
+ wmManipulatorFnMatrixWorldGet matrix_basis_get;
/* activate a manipulator state when the user clicks on it */
wmManipulatorFnInvoke invoke;
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
index 3f10864995f..fe7dbb56d6e 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator.c
@@ -336,13 +336,13 @@ void WM_manipulator_set_line_width(wmManipulator *mpr, const float line_width)
* \param col Normal state color.
* \param col_hi Highlighted state color.
*/
-void WM_manipulator_get_color(const wmManipulator *mpr, float col[4])
+void WM_manipulator_get_color(const wmManipulator *mpr, float color[4])
{
- copy_v4_v4(col, mpr->color);
+ copy_v4_v4(color, mpr->color);
}
-void WM_manipulator_set_color(wmManipulator *mpr, const float col[4])
+void WM_manipulator_set_color(wmManipulator *mpr, const float color[4])
{
- copy_v4_v4(mpr->color, col);
+ copy_v4_v4(mpr->color, color);
}
void WM_manipulator_get_color_highlight(const wmManipulator *mpr, float color_hi[4])
@@ -446,15 +446,18 @@ void wm_manipulator_calculate_scale(wmManipulator *mpr, const bContext *C)
scale *= U.manipulator_size;
if (rv3d) {
/* 'ED_view3d_pixel_size' includes 'U.pixelsize', remove it. */
- if (mpr->type->matrix_world_get) {
- float matrix_world[4][4];
-
- mpr->type->matrix_world_get(mpr, matrix_world);
- scale *= ED_view3d_pixel_size(rv3d, matrix_world[3]) / U.pixelsize;
+ float matrix_world[4][4];
+ if (mpr->type->matrix_basis_get) {
+ float matrix_basis[4][4];
+ mpr->type->matrix_basis_get(mpr, matrix_basis);
+ mul_m4_m4m4(matrix_world, mpr->matrix_space, matrix_basis);
}
else {
- scale *= ED_view3d_pixel_size(rv3d, mpr->matrix_basis[3]) / U.pixelsize;
+ mul_m4_m4m4(matrix_world, mpr->matrix_space, mpr->matrix_basis);
}
+
+ /* Exclude matrix_offset from scale. */
+ scale *= ED_view3d_pixel_size(rv3d, matrix_world[3]) / U.pixelsize;
}
else {
scale *= 0.02f;
@@ -508,6 +511,44 @@ int wm_manipulator_is_visible(wmManipulator *mpr)
return WM_MANIPULATOR_IS_VISIBLE_UPDATE | WM_MANIPULATOR_IS_VISIBLE_DRAW;
}
+void WM_manipulator_calc_matrix_final_params(
+ const wmManipulator *mpr,
+ const struct WM_ManipulatorMatrixParams *params,
+ float r_mat[4][4])
+{
+ const float (* const matrix_space)[4] = params->matrix_space ? params->matrix_space : mpr->matrix_space;
+ const float (* const matrix_basis)[4] = params->matrix_basis ? params->matrix_basis : mpr->matrix_basis;
+ const float (* const matrix_offset)[4] = params->matrix_offset ? params->matrix_offset : mpr->matrix_offset;
+ const float *scale_final = params->scale_final ? params->scale_final : &mpr->scale_final;
+
+ float final_matrix[4][4];
+
+ copy_m4_m4(final_matrix, matrix_basis);
+
+ if (mpr->flag & WM_MANIPULATOR_DRAW_OFFSET_SCALE) {
+ mul_mat3_m4_fl(final_matrix, *scale_final);
+ mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
+ }
+ else {
+ mul_m4_m4m4(final_matrix, final_matrix, matrix_offset);
+ mul_mat3_m4_fl(final_matrix, *scale_final);
+ }
+
+ mul_m4_m4m4(r_mat, matrix_space, final_matrix);
+}
+
+void WM_manipulator_calc_matrix_final(const wmManipulator *mpr, float r_mat[4][4])
+{
+ WM_manipulator_calc_matrix_final_params(
+ mpr,
+ &((struct WM_ManipulatorMatrixParams) {
+ .matrix_space = mpr->matrix_space,
+ .matrix_basis = mpr->matrix_basis,
+ .matrix_offset = mpr->matrix_offset,
+ .scale_final = &mpr->scale_final,
+ }), r_mat
+ );
+}
/** \name Manipulator Propery Access
*
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
index 085b7b1c787..4273bc75cc9 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_map.c
@@ -50,6 +50,8 @@
#include "WM_types.h"
#include "wm_event_system.h"
+#include "DEG_depsgraph.h"
+
/* own includes */
#include "wm_manipulator_wmapi.h"
#include "wm_manipulator_intern.h"
@@ -462,6 +464,7 @@ static int manipulator_find_intersected_3d_intern(
ListBase *visible_manipulators, const bContext *C, const int co[2],
const int hotspot)
{
+ EvaluationContext eval_ctx;
ScrArea *sa = CTX_wm_area(C);
ARegion *ar = CTX_wm_region(C);
View3D *v3d = sa->spacedata.first;
@@ -473,7 +476,9 @@ static int manipulator_find_intersected_3d_intern(
BLI_rcti_init_pt_radius(&rect, co, hotspot);
- ED_view3d_draw_setup_view(CTX_wm_window(C), C, CTX_data_scene(C), ar, v3d, NULL, NULL, &rect);
+ CTX_data_eval_ctx(C, &eval_ctx);
+
+ ED_view3d_draw_setup_view(CTX_wm_window(C), &eval_ctx, CTX_data_scene(C), ar, v3d, NULL, NULL, &rect);
if (do_passes)
GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
@@ -490,7 +495,7 @@ static int manipulator_find_intersected_3d_intern(
GPU_select_end();
}
- ED_view3d_draw_setup_view(CTX_wm_window(C), C, CTX_data_scene(C), ar, v3d, NULL, NULL, NULL);
+ ED_view3d_draw_setup_view(CTX_wm_window(C), &eval_ctx, CTX_data_scene(C), ar, v3d, NULL, NULL, NULL);
const GLuint *hit_near = GPU_select_buffer_near(buffer, hits);
@@ -835,6 +840,9 @@ void wm_manipulatormap_modal_set(
wmManipulatorMap *mmap, bContext *C, const wmEvent *event, wmManipulator *mpr)
{
if (mpr && C) {
+ /* For now only grab cursor for 3D manipulators. */
+ bool grab_cursor = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) != 0;
+
mpr->state |= WM_MANIPULATOR_STATE_MODAL;
mmap->mmap_context.modal = mpr;
@@ -862,7 +870,10 @@ void wm_manipulatormap_modal_set(
mpr->type->invoke(C, mpr, event);
}
}
- WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL);
+
+ if (grab_cursor) {
+ WM_cursor_grab_enable(CTX_wm_window(C), true, true, NULL);
+ }
}
else {
mpr = mmap->mmap_context.modal;
diff --git a/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c b/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c
index 18265319024..b2f6a251d1f 100644
--- a/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c
+++ b/source/blender/windowmanager/manipulators/intern/wm_manipulator_type.c
@@ -102,7 +102,7 @@ static void wm_manipulatortype_append__end(wmManipulatorType *wt)
{
BLI_assert(wt->struct_size >= sizeof(wmManipulator));
- RNA_def_struct_identifier(wt->srna, wt->idname);
+ RNA_def_struct_identifier(&BLENDER_RNA, wt->srna, wt->idname);
BLI_ghash_insert(global_manipulatortype_hash, (void *)wt->idname, wt);
}
diff --git a/source/blender/windowmanager/manipulators/wm_manipulator_fn.h b/source/blender/windowmanager/manipulators/wm_manipulator_fn.h
index a9dd9b1f114..a92648455d4 100644
--- a/source/blender/windowmanager/manipulators/wm_manipulator_fn.h
+++ b/source/blender/windowmanager/manipulators/wm_manipulator_fn.h
@@ -52,7 +52,7 @@ typedef void (*wmManipulatorFnDrawSelect)(const struct bContext *, struct wmM
typedef int (*wmManipulatorFnTestSelect)(struct bContext *, struct wmManipulator *, const struct wmEvent *);
typedef void (*wmManipulatorFnModal)(struct bContext *, struct wmManipulator *, const struct wmEvent *, eWM_ManipulatorTweak);
typedef void (*wmManipulatorFnPropertyUpdate)(struct wmManipulator *, struct wmManipulatorProperty *);
-typedef void (*wmManipulatorFnMatrixWorldGet)(struct wmManipulator *, float[4][4]);
+typedef void (*wmManipulatorFnMatrixWorldGet)(const struct wmManipulator *, float[4][4]);
typedef void (*wmManipulatorFnInvoke)(struct bContext *, struct wmManipulator *, const struct wmEvent *);
typedef void (*wmManipulatorFnExit)(struct bContext *, struct wmManipulator *, const bool);
typedef int (*wmManipulatorFnCursorGet)(struct wmManipulator *);
diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h
index 4fbbe3d2879..6f63e55e8ab 100644
--- a/source/blender/windowmanager/wm_files.h
+++ b/source/blender/windowmanager/wm_files.h
@@ -37,7 +37,7 @@ struct wmOperatorType;
void wm_history_file_read(void);
int wm_homefile_read(
struct bContext *C, struct ReportList *reports,
- bool use_factory_settings, bool use_empty_data,
+ bool use_factory_settings, bool use_empty_data, bool use_userdef,
const char *filepath_startup_override, const char *app_template_override);
void wm_file_read_report(bContext *C);
diff --git a/source/blenderplayer/CMakeLists.txt b/source/blenderplayer/CMakeLists.txt
index 4f0e64b0955..bd07961c556 100644
--- a/source/blenderplayer/CMakeLists.txt
+++ b/source/blenderplayer/CMakeLists.txt
@@ -91,6 +91,12 @@ list(APPEND BLENDER_LINK_LIBS
blenkernel_blc
)
+if(WITH_AUDASPACE AND NOT WITH_SYSTEM_AUDASPACE)
+ list(APPEND BLENDER_LINK_LIBS
+ audaspace
+ audaspace-py)
+endif()
+
if(CMAKE_SYSTEM_NAME MATCHES "Linux")
list(APPEND BLENDER_LINK_LIBS extern_binreloc)
endif()
@@ -150,6 +156,8 @@ endif()
bf_blenfont
bf_blentranslation
bf_intern_audaspace
+ audaspace
+ audaspace-py
blenkernel_blc
bf_bmesh
bf_blenlib
diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c
index 2ead8db0146..5d9045be621 100644
--- a/source/blenderplayer/bad_level_call_stubs/stubs.c
+++ b/source/blenderplayer/bad_level_call_stubs/stubs.c
@@ -410,7 +410,7 @@ int WM_enum_search_invoke(struct bContext *C, struct wmOperator *op, const struc
void WM_event_add_notifier(const struct bContext *C, unsigned int type, void *reference) RET_NONE
void WM_main_add_notifier(unsigned int type, void *reference) RET_NONE
void ED_armature_bone_rename(struct bArmature *arm, const char *oldnamep, const char *newnamep) RET_NONE
-void ED_armature_transform(struct bArmature *arm, float mat[4][4]) RET_NONE
+void ED_armature_transform(struct bArmature *arm, float mat[4][4], const bool do_props) RET_NONE
struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op) RET_NULL
struct wmTimer *WM_event_add_timer(struct wmWindowManager *wm, struct wmWindow *win, int event_type, double timestep) RET_NULL
void WM_event_remove_timer(struct wmWindowManager *wm, struct wmWindow *win, struct wmTimer *timer) RET_NONE
@@ -471,7 +471,7 @@ char *ED_fsmenu_entry_get_name(struct FSMenuEntry *fsentry) RET_NULL
void ED_fsmenu_entry_set_name(struct FSMenuEntry *fsentry, const char *name) RET_NONE
struct PTCacheEdit *PE_get_current(struct Scene *scene, struct SceneLayer *sl, struct Object *ob) RET_NULL
-void PE_current_changed(const struct bContext *C, struct Scene *scene, struct Object *ob) RET_NONE
+void PE_current_changed(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct Object *ob) RET_NONE
/* rna keymap */
struct wmKeyMap *WM_keymap_active(struct wmWindowManager *wm, struct wmKeyMap *keymap) RET_NULL
@@ -538,7 +538,7 @@ void ED_view3d_from_m4(float mat[4][4], float ofs[3], float quat[4], float *dist
struct BGpic *ED_view3D_background_image_new(struct View3D *v3d) RET_NULL
void ED_view3D_background_image_remove(struct View3D *v3d, struct BGpic *bgpic) RET_NONE
void ED_view3D_background_image_clear(struct View3D *v3d) RET_NONE
-void ED_view3d_update_viewmat(struct EvaluationContext *eval_ctx, struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4], const struct rcti *rect) RET_NONE
+void ED_view3d_update_viewmat(const struct EvaluationContext *eval_ctx, struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4], const struct rcti *rect) RET_NONE
float ED_view3d_grid_scale(struct Scene *scene, struct View3D *v3d, const char **grid_unit) RET_ZERO
void ED_view3d_shade_update(struct Main *bmain, struct Scene *scene, struct View3D *v3d, struct ScrArea *sa) RET_NONE
void ED_node_shader_default(const struct bContext *C, struct ID *id) RET_NONE
@@ -611,7 +611,6 @@ SnapObjectContext *ED_transform_snap_object_context_create_view3d(
const struct ARegion *ar, const struct View3D *v3d) RET_NULL
void ED_transform_snap_object_context_destroy(SnapObjectContext *sctx) RET_NONE
bool ED_transform_snap_object_project_ray_ex(
- const struct bContext *C,
struct SnapObjectContext *sctx,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3], float *ray_depth,
@@ -811,7 +810,7 @@ int UI_pie_menu_invoke_from_operator_enum(struct bContext *C, const char *title,
const char *propname, const struct wmEvent *event) RET_ZERO
/* RNA COLLADA dependency */
-int collada_export(struct EvaluationContext *eval_ctx,
+int collada_export(const struct EvaluationContext *eval_ctx,
struct Scene *sce,
struct SceneLayer *scene_layer,
const char *filepath,
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index 11e22fffa4d..023d04f5da7 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -851,6 +851,13 @@ elseif(APPLE)
PATTERN "__MACOSX" EXCLUDE
PATTERN ".DS_Store" EXCLUDE
PATTERN "config-${PYTHON_VERSION}m/*.a" EXCLUDE # static lib
+ PATTERN "lib2to3" EXCLUDE # ./lib2to3
+ PATTERN "tkinter" EXCLUDE # ./tkinter
+ PATTERN "lib-dynload/_tkinter.*" EXCLUDE # ./lib-dynload/_tkinter.co
+ PATTERN "idlelib" EXCLUDE # ./idlelib
+ PATTERN "test" EXCLUDE # ./test
+ PATTERN "turtledemo" EXCLUDE # ./turtledemo
+ PATTERN "turtle.py" EXCLUDE # ./turtle.py
)
endmacro()
@@ -914,41 +921,49 @@ elseif(APPLE)
# python
if(WITH_PYTHON AND NOT WITH_PYTHON_MODULE AND NOT WITH_PYTHON_FRAMEWORK)
- # the python zip is first extracted as part of the build process,
- # and then later installed as part of make install. this is much
- # quicker, and means we can easily exclude files on copy
- # Not needed for PYTHON_MODULE or WEB_PLUGIN due uses Pyhon framework
- # use a hash of the .zip path to handle switching between different
- # lib directories without needing a clean build
- string(SHA1 PYTHON_ZIP_HASH ${LIBDIR}/release/${PYTHON_ZIP})
- set(PYTHON_EXTRACT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_ZIP_HASH}/python)
-
- add_custom_target(
- extractpyzip
- DEPENDS ${PYTHON_EXTRACT_DIR})
-
- set(PYTHON_ZIP "python_${CMAKE_OSX_ARCHITECTURES}.zip")
-
- add_custom_command(
- OUTPUT ${PYTHON_EXTRACT_DIR}
- COMMAND ${CMAKE_COMMAND} -E remove_directory "${PYTHON_EXTRACT_DIR}/"
- COMMAND ${CMAKE_COMMAND} -E make_directory "${PYTHON_EXTRACT_DIR}/"
- COMMAND ${CMAKE_COMMAND} -E chdir "${PYTHON_EXTRACT_DIR}/"
- ${CMAKE_COMMAND} -E tar xzfv "${LIBDIR}/release/${PYTHON_ZIP}"
- DEPENDS ${LIBDIR}/release/${PYTHON_ZIP})
-
- add_dependencies(blender extractpyzip)
-
- # copy extracted python files
- install_dir(
- ${PYTHON_EXTRACT_DIR}
- \${TARGETDIR_VER}
- )
- # copy site-packages files
- install_dir(
- ${LIBDIR}/release/site-packages
- \${TARGETDIR_VER}/python/lib/python${PYTHON_VERSION}
- )
+ if(WITH_CXX11)
+ # Copy the python libs into the install directory
+ install_dir(
+ ${PYTHON_LIBPATH}
+ ${TARGETDIR_VER}/python/lib
+ )
+ else()
+ # the python zip is first extracted as part of the build process,
+ # and then later installed as part of make install. this is much
+ # quicker, and means we can easily exclude files on copy
+ # Not needed for PYTHON_MODULE or WEB_PLUGIN due uses Pyhon framework
+ # use a hash of the .zip path to handle switching between different
+ # lib directories without needing a clean build
+ string(SHA1 PYTHON_ZIP_HASH ${LIBDIR}/release/${PYTHON_ZIP})
+ set(PYTHON_EXTRACT_DIR ${CMAKE_CURRENT_BINARY_DIR}/${PYTHON_ZIP_HASH}/python)
+
+ add_custom_target(
+ extractpyzip
+ DEPENDS ${PYTHON_EXTRACT_DIR})
+
+ set(PYTHON_ZIP "python_${CMAKE_OSX_ARCHITECTURES}.zip")
+
+ add_custom_command(
+ OUTPUT ${PYTHON_EXTRACT_DIR}
+ COMMAND ${CMAKE_COMMAND} -E remove_directory "${PYTHON_EXTRACT_DIR}/"
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${PYTHON_EXTRACT_DIR}/"
+ COMMAND ${CMAKE_COMMAND} -E chdir "${PYTHON_EXTRACT_DIR}/"
+ ${CMAKE_COMMAND} -E tar xzfv "${LIBDIR}/release/${PYTHON_ZIP}"
+ DEPENDS ${LIBDIR}/release/${PYTHON_ZIP})
+
+ add_dependencies(blender extractpyzip)
+
+ # copy extracted python files
+ install_dir(
+ ${PYTHON_EXTRACT_DIR}
+ \${TARGETDIR_VER}
+ )
+ # copy site-packages files
+ install_dir(
+ ${LIBDIR}/release/site-packages
+ \${TARGETDIR_VER}/python/lib/python${PYTHON_VERSION}
+ )
+ endif()
install(DIRECTORY ${LIBDIR}/python/bin
DESTINATION ${TARGETDIR_VER}/python
@@ -1003,19 +1018,27 @@ elseif(APPLE)
# python
if(WITH_PYTHON AND NOT WITH_PYTHON_FRAMEWORK)
- add_custom_command(
- OUTPUT ${PYTHON_EXTRACT_DIR}
- COMMAND ${CMAKE_COMMAND} -E remove_directory "${PYTHON_EXTRACT_DIR}/"
- COMMAND ${CMAKE_COMMAND} -E make_directory "${PYTHON_EXTRACT_DIR}/"
- COMMAND ${CMAKE_COMMAND} -E chdir "${PYTHON_EXTRACT_DIR}/"
- ${CMAKE_COMMAND} -E tar xzfv "${LIBDIR}/release/${PYTHON_ZIP}"
- DEPENDS ${LIBDIR}/release/${PYTHON_ZIP})
-
- # copy extracted python files
- install_dir(
- ${PYTHON_EXTRACT_DIR}
- \${PLAYER_TARGETDIR_VER}
- )
+ if(WITH_CXX11)
+ # Copy the python libs into the install directory
+ install_dir(
+ ${PYTHON_LIBPATH}
+ ${PLAYER_TARGETDIR_VER}/python/lib
+ )
+ else()
+ add_custom_command(
+ OUTPUT ${PYTHON_EXTRACT_DIR}
+ COMMAND ${CMAKE_COMMAND} -E remove_directory "${PYTHON_EXTRACT_DIR}/"
+ COMMAND ${CMAKE_COMMAND} -E make_directory "${PYTHON_EXTRACT_DIR}/"
+ COMMAND ${CMAKE_COMMAND} -E chdir "${PYTHON_EXTRACT_DIR}/"
+ ${CMAKE_COMMAND} -E tar xzfv "${LIBDIR}/release/${PYTHON_ZIP}"
+ DEPENDS ${LIBDIR}/release/${PYTHON_ZIP})
+
+ # copy extracted python files
+ install_dir(
+ ${PYTHON_EXTRACT_DIR}
+ \${PLAYER_TARGETDIR_VER}
+ )
+ endif()
endif()
endif()
diff --git a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
index 99f3d0639f3..4e8f0eba9b7 100644
--- a/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
+++ b/source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
@@ -101,7 +101,7 @@ typedef void * wmUIHandlerRemoveFunc;
}
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
+# include <AUD_Device.h>
#endif
static BlendFileData *load_game_data(const char *filename)
diff --git a/source/gameengine/BlenderRoutines/CMakeLists.txt b/source/gameengine/BlenderRoutines/CMakeLists.txt
index aaeb2e10462..42293050753 100644
--- a/source/gameengine/BlenderRoutines/CMakeLists.txt
+++ b/source/gameengine/BlenderRoutines/CMakeLists.txt
@@ -56,7 +56,7 @@ set(SRC
add_definitions(${GL_DEFINITIONS})
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/gameengine/Converter/CMakeLists.txt b/source/gameengine/Converter/CMakeLists.txt
index 4db9fcebd06..7d6195e3c38 100644
--- a/source/gameengine/Converter/CMakeLists.txt
+++ b/source/gameengine/Converter/CMakeLists.txt
@@ -113,7 +113,7 @@ if(WITH_BULLET)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 974dcbca95b..d78ea4eed54 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -42,7 +42,7 @@
#include "KX_ConvertActuators.h"
#ifdef WITH_AUDASPACE
-# include AUD_SOUND_H
+# include <AUD_Sound.h>
#endif
// Actuators
diff --git a/source/gameengine/GamePlayer/ghost/CMakeLists.txt b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
index 6d6d53b1e17..5bce9fcd248 100644
--- a/source/gameengine/GamePlayer/ghost/CMakeLists.txt
+++ b/source/gameengine/GamePlayer/ghost/CMakeLists.txt
@@ -95,7 +95,7 @@ if(WITH_INTERNATIONAL)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
index ddb04e9f84d..1b6b6defdf9 100644
--- a/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
+++ b/source/gameengine/GamePlayer/ghost/GPG_Application.cpp
@@ -99,7 +99,7 @@ extern "C"
#include "GHOST_Rect.h"
#ifdef WITH_AUDASPACE
-# include AUD_DEVICE_H
+# include <AUD_Device.h>
#endif
static void frameTimerProc(GHOST_ITimerTask* task, GHOST_TUns64 time);
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index 417f54cc8b9..cb7c0180f30 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -244,7 +244,7 @@ if(WITH_CODEC_FFMPEG)
endif()
if(WITH_AUDASPACE)
- add_definitions(${AUDASPACE_DEFINITIONS})
+ add_definitions(-DWITH_AUDASPACE)
list(APPEND INC_SYS
${AUDASPACE_C_INCLUDE_DIRS}
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.cpp b/source/gameengine/Ketsji/KX_SoundActuator.cpp
index d858097abef..04ec3f9cd04 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.cpp
+++ b/source/gameengine/Ketsji/KX_SoundActuator.cpp
@@ -37,14 +37,12 @@
#include "KX_SoundActuator.h"
#ifdef WITH_AUDASPACE
-# ifdef WITH_SYSTEM_AUDASPACE
typedef float sample_t;
-# include AUD_PYTHON_H
-# endif
-# include AUD_SOUND_H
-# include AUD_SPECIAL_H
-# include AUD_DEVICE_H
-# include AUD_HANDLE_H
+# include <python/PyAPI.h>
+# include <AUD_Sound.h>
+# include <AUD_Special.h>
+# include <AUD_Device.h>
+# include <AUD_Handle.h>
#endif
#include "KX_GameObject.h"
diff --git a/source/gameengine/Ketsji/KX_SoundActuator.h b/source/gameengine/Ketsji/KX_SoundActuator.h
index 5ec2fda722f..4f3e6f707e0 100644
--- a/source/gameengine/Ketsji/KX_SoundActuator.h
+++ b/source/gameengine/Ketsji/KX_SoundActuator.h
@@ -35,8 +35,8 @@
#include "SCA_IActuator.h"
#ifdef WITH_AUDASPACE
-# include AUD_SOUND_H
-# include AUD_HANDLE_H
+# include <AUD_Sound.h>
+# include <AUD_Handle.h>
#endif
#include "BKE_sound.h"
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index fa0b86a2637..64326f34377 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,7 +1,8 @@
# Python CTests
-add_subdirectory(python)
+if(WITH_BLENDER)
+ add_subdirectory(python)
+endif()
# GTest
add_subdirectory(gtests)
-
diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index 28ce095b0e8..dd824b9f824 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -518,6 +518,7 @@ if(WITH_CYCLES)
-blender "$<TARGET_FILE:blender>"
-testdir "${TEST_SRC_DIR}/cycles/ctests/${subject}"
-idiff "${OPENIMAGEIO_IDIFF}"
+ -outdir "${TEST_OUT_DIR}/cycles"
)
else()
add_test(
@@ -526,17 +527,24 @@ if(WITH_CYCLES)
-blender "$<TARGET_FILE:blender>"
-testdir "${TEST_SRC_DIR}/cycles/ctests/${subject}"
-idiff "${OPENIMAGEIO_IDIFF}"
+ -outdir "${TEST_OUT_DIR}/cycles"
)
endif()
endmacro()
if(WITH_OPENGL_TESTS)
add_cycles_render_test(opengl)
endif()
- add_cycles_render_test(image)
+ add_cycles_render_test(denoise)
+ add_cycles_render_test(displacement)
+ add_cycles_render_test(image_data_types)
+ add_cycles_render_test(image_mapping)
+ add_cycles_render_test(image_texture_limit)
add_cycles_render_test(mblur)
add_cycles_render_test(reports)
add_cycles_render_test(render)
add_cycles_render_test(shader)
+ add_cycles_render_test(shadow_catcher)
+ add_cycles_render_test(volume)
else()
MESSAGE(STATUS "Disabling Cycles tests because tests folder does not exist")
endif()
diff --git a/tests/python/bl_alembic_import_test.py b/tests/python/bl_alembic_import_test.py
index 9f758b0b161..e64da2fe540 100644
--- a/tests/python/bl_alembic_import_test.py
+++ b/tests/python/bl_alembic_import_test.py
@@ -179,22 +179,26 @@ class SimpleImportTest(AbstractAlembicTest):
res = bpy.ops.wm.alembic_import(filepath=str(abc), as_background_job=False)
self.assertEqual({'FINISHED'}, res)
- cube = bpy.context.active_object
+ plane = bpy.context.active_object
# Check that the file loaded ok.
bpy.context.scene.frame_set(6)
- self.assertAlmostEqual(-1, cube.data.vertices[0].co.x)
- self.assertAlmostEqual(-1, cube.data.vertices[0].co.y)
- self.assertAlmostEqual(0.5905638933181763, cube.data.vertices[0].co.z)
+ scene = bpy.context.scene
+ layer = scene.render_layers[scene.active_layer]
+ mesh = plane.to_mesh(scene, layer, True, 'RENDER')
+ self.assertAlmostEqual(-1, mesh.vertices[0].co.x)
+ self.assertAlmostEqual(-1, mesh.vertices[0].co.y)
+ self.assertAlmostEqual(0.5905638933181763, mesh.vertices[0].co.z)
# Change path from absolute to relative. This should not break the animation.
- bpy.context.scene.frame_set(1)
+ scene.frame_set(1)
bpy.data.cache_files[fname].filepath = relpath
- bpy.context.scene.frame_set(6)
+ scene.frame_set(6)
- self.assertAlmostEqual(1, cube.data.vertices[3].co.x)
- self.assertAlmostEqual(1, cube.data.vertices[3].co.y)
- self.assertAlmostEqual(0.5905638933181763, cube.data.vertices[3].co.z)
+ mesh = plane.to_mesh(scene, layer, True, 'RENDER')
+ self.assertAlmostEqual(1, mesh.vertices[3].co.x)
+ self.assertAlmostEqual(1, mesh.vertices[3].co.y)
+ self.assertAlmostEqual(0.5905638933181763, mesh.vertices[3].co.z)
def test_import_long_names(self):
# This file contains very long names. The longest name is 4047 chars.
diff --git a/tests/python/bl_load_py_modules.py b/tests/python/bl_load_py_modules.py
index 7ffececd1d9..2d8a908406f 100644
--- a/tests/python/bl_load_py_modules.py
+++ b/tests/python/bl_load_py_modules.py
@@ -123,6 +123,8 @@ def load_addons():
def load_modules():
+ VERBOSE = os.environ.get("BLENDER_VERBOSE") is not None
+
modules = []
module_paths = []
@@ -162,6 +164,14 @@ def load_modules():
del module_names
#
+ # test we tested all files except for presets and templates
+ ignore_paths = [
+ os.sep + "presets" + os.sep,
+ os.sep + "templates" + os.sep,
+ ] + ([(os.sep + f + os.sep) for f in BLACKLIST] +
+ [(os.sep + f + ".py") for f in BLACKLIST])
+
+ #
# now submodules
for m in modules:
filepath = m.__file__
@@ -199,7 +209,14 @@ def load_modules():
# import failure.
# - We want to catch all failures of this script instead of stopping on
# a first big failure.
- traceback.print_exc()
+ do_print = True
+ if not VERBOSE:
+ for ignore in ignore_paths:
+ if ignore in submod_full:
+ do_print = False
+ break
+ if do_print:
+ traceback.print_exc()
#
# check which filepaths we didn't load
@@ -218,14 +235,6 @@ def load_modules():
for f in loaded_files:
source_files.remove(f)
- #
- # test we tested all files except for presets and templates
- ignore_paths = [
- os.sep + "presets" + os.sep,
- os.sep + "templates" + os.sep,
- ] + ([(os.sep + f + os.sep) for f in BLACKLIST] +
- [(os.sep + f + ".py") for f in BLACKLIST])
-
for f in source_files:
for ignore in ignore_paths:
if ignore in f:
diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py
index a030cc5e0de..0b90ab5b55f 100755
--- a/tests/python/cycles_render_tests.py
+++ b/tests/python/cycles_render_tests.py
@@ -2,7 +2,9 @@
# Apache License, Version 2.0
import argparse
+import glob
import os
+import pathlib
import shutil
import subprocess
import sys
@@ -24,7 +26,7 @@ class COLORS_DUMMY:
COLORS = COLORS_DUMMY
-def printMessage(type, status, message):
+def print_message(message, type=None, status=''):
if type == 'SUCCESS':
print(COLORS.GREEN, end="")
elif type == 'FAILURE':
@@ -109,20 +111,153 @@ def test_get_name(filepath):
filename = os.path.basename(filepath)
return os.path.splitext(filename)[0]
-
-def verify_output(filepath):
+def test_get_images(filepath):
testname = test_get_name(filepath)
dirpath = os.path.dirname(filepath)
- reference_dirpath = os.path.join(dirpath, "reference_renders")
- reference_image = os.path.join(reference_dirpath, testname + ".png")
- failed_image = os.path.join(reference_dirpath, testname + ".fail.png")
- if not os.path.exists(reference_image):
+ ref_dirpath = os.path.join(dirpath, "reference_renders")
+ ref_img = os.path.join(ref_dirpath, testname + ".png")
+ new_dirpath = os.path.join(OUTDIR, os.path.basename(dirpath))
+ if not os.path.exists(new_dirpath):
+ os.makedirs(new_dirpath)
+ new_img = os.path.join(new_dirpath, testname + ".png")
+ diff_dirpath = os.path.join(OUTDIR, os.path.basename(dirpath), "diff")
+ if not os.path.exists(diff_dirpath):
+ os.makedirs(diff_dirpath)
+ diff_img = os.path.join(diff_dirpath, testname + ".diff.png")
+ return ref_img, new_img, diff_img
+
+
+class Report:
+ def __init__(self, testname):
+ self.failed_tests = ""
+ self.passed_tests = ""
+ self.testname = testname
+
+ def output(self):
+ # write intermediate data for single test
+ outdir = os.path.join(OUTDIR, self.testname)
+ f = open(os.path.join(outdir, "failed.data"), "w")
+ f.write(self.failed_tests)
+ f.close()
+
+ f = open(os.path.join(outdir, "passed.data"), "w")
+ f.write(self.passed_tests)
+ f.close()
+
+ # gather intermediate data for all tests
+ failed_data = sorted(glob.glob(os.path.join(OUTDIR, "*/failed.data")))
+ passed_data = sorted(glob.glob(os.path.join(OUTDIR, "*/passed.data")))
+
+ failed_tests = ""
+ passed_tests = ""
+
+ for filename in failed_data:
+ failed_tests += open(os.path.join(OUTDIR, filename), "r").read()
+ for filename in passed_data:
+ passed_tests += open(os.path.join(OUTDIR, filename), "r").read()
+
+ # write html for all tests
+ self.html = """
+<html>
+<head>
+ <title>Cycles Test Report</title>
+ <style>
+ img {{ image-rendering: pixelated; width: 256; background-color: #000; }}
+ img.render {{
+ background-color: #fff;
+ background-image:
+ -moz-linear-gradient(45deg, #eee 25%, transparent 25%),
+ -moz-linear-gradient(-45deg, #eee 25%, transparent 25%),
+ -moz-linear-gradient(45deg, transparent 75%, #eee 75%),
+ -moz-linear-gradient(-45deg, transparent 75%, #eee 75%);
+ background-image:
+ -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.25, #eee), color-stop(.25, transparent)),
+ -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.25, #eee), color-stop(.25, transparent)),
+ -webkit-gradient(linear, 0 100%, 100% 0, color-stop(.75, transparent), color-stop(.75, #eee)),
+ -webkit-gradient(linear, 0 0, 100% 100%, color-stop(.75, transparent), color-stop(.75, #eee));
+
+ -moz-background-size:50px 50px;
+ background-size:50px 50px;
+ -webkit-background-size:50px 51px; /* override value for shitty webkit */
+
+ background-position:0 0, 25px 0, 25px -25px, 0px 25px;
+ }}
+ table td:first-child {{ width: 100%; }}
+ </style>
+ <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css">
+</head>
+<body>
+ <div class="container">
+ <br/>
+ <h1>Cycles Test Report</h1>
+ <br/>
+ <table class="table table-striped">
+ <thead class="thead-default">
+ <tr><th>Name</th><th>New</th><th>Reference</th><th>Diff</th>
+ </thead>
+ {}{}
+ </table>
+ <br/>
+ </div>
+</body>
+</html>
+ """ . format(failed_tests, passed_tests)
+
+ filepath = os.path.join(OUTDIR, "report.html")
+ f = open(filepath, "w")
+ f.write(self.html)
+ f.close()
+
+ print_message("Report saved to: " + pathlib.Path(filepath).as_uri())
+
+ def add_test(self, filepath, error):
+ name = test_get_name(filepath)
+
+ ref_img, new_img, diff_img = test_get_images(filepath)
+
+ status = error if error else ""
+ style = """ style="background-color: #f99;" """ if error else ""
+
+ new_url = pathlib.Path(new_img).as_uri()
+ ref_url = pathlib.Path(ref_img).as_uri()
+ diff_url = pathlib.Path(diff_img).as_uri()
+
+ test_html = """
+ <tr{}>
+ <td><b>{}</b><br/>{}<br/>{}</td>
+ <td><img src="{}" onmouseover="this.src='{}';" onmouseout="this.src='{}';" class="render"></td>
+ <td><img src="{}" onmouseover="this.src='{}';" onmouseout="this.src='{}';" class="render"></td>
+ <td><img src="{}"></td>
+ </tr>""" . format(style, name, self.testname, status,
+ new_url, ref_url, new_url,
+ ref_url, new_url, ref_url,
+ diff_url)
+
+ if error:
+ self.failed_tests += test_html
+ else:
+ self.passed_tests += test_html
+
+
+def verify_output(report, filepath):
+ ref_img, new_img, diff_img = test_get_images(filepath)
+
+ # copy new image
+ if os.path.exists(new_img):
+ os.remove(new_img)
+ if os.path.exists(TEMP_FILE):
+ shutil.copy(TEMP_FILE, new_img)
+
+
+ if not os.path.exists(ref_img):
return False
+
+ # diff test with threshold
command = (
IDIFF,
- "-fail", "0.015",
+ "-fail", "0.016",
"-failpercent", "1",
- reference_image,
+ ref_img,
TEMP_FILE,
)
try:
@@ -130,47 +265,60 @@ def verify_output(filepath):
failed = False
except subprocess.CalledProcessError as e:
if VERBOSE:
- print(e.output.decode("utf-8"))
+ print_message(e.output.decode("utf-8"))
failed = e.returncode != 1
- if failed:
- shutil.copy(TEMP_FILE, failed_image)
- elif os.path.exists(failed_image):
- os.remove(failed_image)
+
+ # generate diff image
+ command = (
+ IDIFF,
+ "-o", diff_img,
+ "-abs", "-scale", "16",
+ ref_img,
+ TEMP_FILE
+ )
+
+ try:
+ subprocess.check_output(command)
+ except subprocess.CalledProcessError as e:
+ if VERBOSE:
+ print_message(e.output.decode("utf-8"))
+
return not failed
-def run_test(filepath):
+def run_test(report, filepath):
testname = test_get_name(filepath)
spacer = "." * (32 - len(testname))
- printMessage('SUCCESS', 'RUN', testname)
+ print_message(testname, 'SUCCESS', 'RUN')
time_start = time.time()
error = render_file(filepath)
status = "FAIL"
if not error:
- if not verify_output(filepath):
+ if not verify_output(report, filepath):
error = "VERIFY"
time_end = time.time()
elapsed_ms = int((time_end - time_start) * 1000)
if not error:
- printMessage('SUCCESS', 'OK', "{} ({} ms)" .
- format(testname, elapsed_ms))
+ print_message("{} ({} ms)" . format(testname, elapsed_ms),
+ 'SUCCESS', 'OK')
else:
if error == "NO_CYCLES":
- print("Can't perform tests because Cycles failed to load!")
- return False
+ print_message("Can't perform tests because Cycles failed to load!")
+ return error
elif error == "NO_START":
- print('Can not perform tests because blender fails to start.',
+ print_message('Can not perform tests because blender fails to start.',
'Make sure INSTALL target was run.')
- return False
+ return error
elif error == 'VERIFY':
- print("Rendered result is different from reference image")
+ print_message("Rendered result is different from reference image")
else:
- print("Unknown error %r" % error)
- printMessage('FAILURE', 'FAILED', "{} ({} ms)" .
- format(testname, elapsed_ms))
+ print_message("Unknown error %r" % error)
+ print_message("{} ({} ms)" . format(testname, elapsed_ms),
+ 'FAILURE', 'FAILED')
return error
+
def blend_list(path):
for dirpath, dirnames, filenames in os.walk(path):
for filename in filenames:
@@ -178,17 +326,18 @@ def blend_list(path):
filepath = os.path.join(dirpath, filename)
yield filepath
-
def run_all_tests(dirpath):
passed_tests = []
failed_tests = []
all_files = list(blend_list(dirpath))
all_files.sort()
- printMessage('SUCCESS', "==========",
- "Running {} tests from 1 test case." . format(len(all_files)))
+ report = Report(os.path.basename(dirpath))
+ print_message("Running {} tests from 1 test case." .
+ format(len(all_files)),
+ 'SUCCESS', "==========")
time_start = time.time()
for filepath in all_files:
- error = run_test(filepath)
+ error = run_test(report, filepath)
testname = test_get_name(filepath)
if error:
if error == "NO_CYCLES":
@@ -198,28 +347,33 @@ def run_all_tests(dirpath):
failed_tests.append(testname)
else:
passed_tests.append(testname)
+ report.add_test(filepath, error)
time_end = time.time()
elapsed_ms = int((time_end - time_start) * 1000)
- print("")
- printMessage('SUCCESS', "==========",
- "{} tests from 1 test case ran. ({} ms total)" .
- format(len(all_files), elapsed_ms))
- printMessage('SUCCESS', 'PASSED', "{} tests." .
- format(len(passed_tests)))
+ print_message("")
+ print_message("{} tests from 1 test case ran. ({} ms total)" .
+ format(len(all_files), elapsed_ms),
+ 'SUCCESS', "==========")
+ print_message("{} tests." .
+ format(len(passed_tests)),
+ 'SUCCESS', 'PASSED')
if failed_tests:
- printMessage('FAILURE', 'FAILED', "{} tests, listed below:" .
- format(len(failed_tests)))
+ print_message("{} tests, listed below:" .
+ format(len(failed_tests)),
+ 'FAILURE', 'FAILED')
failed_tests.sort()
for test in failed_tests:
- printMessage('FAILURE', "FAILED", "{}" . format(test))
- return False
- return True
+ print_message("{}" . format(test), 'FAILURE', "FAILED")
+
+ report.output()
+ return not bool(failed_tests)
def create_argparse():
parser = argparse.ArgumentParser()
parser.add_argument("-blender", nargs="+")
parser.add_argument("-testdir", nargs=1)
+ parser.add_argument("-outdir", nargs=1)
parser.add_argument("-idiff", nargs=1)
return parser
@@ -229,7 +383,7 @@ def main():
args = parser.parse_args()
global COLORS
- global BLENDER, ROOT, IDIFF
+ global BLENDER, TESTDIR, IDIFF, OUTDIR
global TEMP_FILE, TEMP_FILE_MASK, TEST_SCRIPT
global VERBOSE
@@ -237,8 +391,12 @@ def main():
COLORS = COLORS_ANSI
BLENDER = args.blender[0]
- ROOT = args.testdir[0]
+ TESTDIR = args.testdir[0]
IDIFF = args.idiff[0]
+ OUTDIR = args.outdir[0]
+
+ if not os.path.exists(OUTDIR):
+ os.makedirs(OUTDIR)
TEMP = tempfile.mkdtemp()
TEMP_FILE_MASK = os.path.join(TEMP, "test")
@@ -248,7 +406,7 @@ def main():
VERBOSE = os.environ.get("BLENDER_VERBOSE") is not None
- ok = run_all_tests(ROOT)
+ ok = run_all_tests(TESTDIR)
# Cleanup temp files and folders
if os.path.exists(TEMP_FILE):
diff --git a/tests/python/render_layer/CMakeLists.txt b/tests/python/render_layer/CMakeLists.txt
index b3c064289a0..5ff985073e3 100644
--- a/tests/python/render_layer/CMakeLists.txt
+++ b/tests/python/render_layer/CMakeLists.txt
@@ -170,5 +170,6 @@ RENDER_LAYER_TEST(scene_copy_b)
RENDER_LAYER_TEST(scene_copy_c)
RENDER_LAYER_TEST(scene_copy_d)
RENDER_LAYER_TEST(scene_copy_e)
+RENDER_LAYER_TEST(scene_copy_f)
RENDER_LAYER_TEST(scene_delete)
RENDER_LAYER_TEST(scene_write_read)
diff --git a/tests/python/render_layer/test_scene_copy_d.py b/tests/python/render_layer/test_scene_copy_d.py
index 54988f49036..f398650eade 100644
--- a/tests/python/render_layer/test_scene_copy_d.py
+++ b/tests/python/render_layer/test_scene_copy_d.py
@@ -16,7 +16,7 @@ from render_layer_common import *
class UnitTesting(RenderLayerTesting):
def test_scene_layers_link(self):
"""
- See if scene copying 'FULL_COPY' is working for scene layers
+ See if scene copying 'LINK_OBJECTS' is working for scene layers
"""
import os
ROOT = self.get_root()
diff --git a/tests/python/render_layer/test_scene_copy_f.py b/tests/python/render_layer/test_scene_copy_f.py
new file mode 100644
index 00000000000..fd4298675f2
--- /dev/null
+++ b/tests/python/render_layer/test_scene_copy_f.py
@@ -0,0 +1,94 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+ def test_shared_layer_collections_copy_full(self):
+ """
+ See if scene copying 'FULL_COPY' is keeping collections visibility
+ and selectability.
+ """
+ import os
+ import bpy
+
+ scene = bpy.context.scene
+
+ hide_lookup = [0, 1, 1, 0]
+ hide_lookup_sub = [1, 0, 1]
+
+ hide_select_lookup = [0, 0, 1, 1]
+ hide_select_lookup_sub = [1, 0, 1, 0]
+ new_collections = []
+
+ # clean everything
+ for layer in scene.render_layers:
+ while layer.collections:
+ layer.collections.unlink(layer.collections[0])
+
+ # create new collections
+ for i in range(4):
+ collection = scene.master_collection.collections.new(str(i))
+ new_collections.append(collection)
+
+ for j in range(3):
+ sub_collection = collection.collections.new("{0}:{1}".format(i, j))
+
+ # link to the original scene
+ for layer in scene.render_layers:
+ for i, collection in enumerate(new_collections):
+ layer.collections.link(collection)
+ self.assertEqual(layer.collections[-1], layer.collections[i])
+
+ layer.collections[i].hide = hide_lookup[i]
+ layer.collections[i].hide_select = hide_select_lookup[i]
+
+ for j, sub_collection in enumerate(layer.collections[i].collections):
+ sub_collection.hide = hide_lookup_sub[j]
+ sub_collection.hide_select = hide_select_lookup_sub[j]
+
+ # copy scene
+ bpy.ops.scene.new(type='FULL_COPY')
+ new_scene = bpy.context.scene
+ self.assertNotEqual(scene, new_scene)
+
+ # update depsgrah
+ scene.update() # update depsgraph
+
+ # compare scenes
+ for h, layer in enumerate(scene.render_layers):
+ new_layer = new_scene.render_layers[h]
+
+ for i, collection in enumerate(layer.collections):
+ new_collection = new_layer.collections[i]
+ self.assertEqual(collection.hide, new_collection.hide)
+ self.assertEqual(collection.hide_select, new_collection.hide_select)
+
+ for j, sub_collection in enumerate(layer.collections[i].collections):
+ new_sub_collection = new_collection.collections[j]
+ self.assertEqual(sub_collection.hide, new_sub_collection.hide)
+ self.assertEqual(sub_collection.hide_select, new_sub_collection.hide_select)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+ import sys
+
+ extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv else []
+ sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in sys.argv else [])
+
+ UnitTesting._extra_arguments = extra_arguments
+ unittest.main()