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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
Diffstat (limited to 'intern')
-rw-r--r--intern/CMakeLists.txt6
-rw-r--r--intern/Makefile2
-rw-r--r--intern/SConscript6
-rw-r--r--intern/SoundSystem/CMakeLists.txt42
-rw-r--r--intern/SoundSystem/SConscript20
-rw-r--r--intern/SoundSystem/SND_C-api.h354
-rw-r--r--intern/SoundSystem/SND_CDObject.h83
-rw-r--r--intern/SoundSystem/SND_DeviceManager.h79
-rw-r--r--intern/SoundSystem/SND_IAudioDevice.h343
-rw-r--r--intern/SoundSystem/SND_Object.h54
-rw-r--r--intern/SoundSystem/SND_Scene.h104
-rw-r--r--intern/SoundSystem/SND_SoundListener.h82
-rw-r--r--intern/SoundSystem/SND_SoundObject.h159
-rw-r--r--intern/SoundSystem/SND_Utils.h111
-rw-r--r--intern/SoundSystem/SND_WaveCache.h66
-rw-r--r--intern/SoundSystem/SND_WaveSlot.h92
-rw-r--r--intern/SoundSystem/SND_test/Makefile48
-rw-r--r--intern/SoundSystem/SND_test/SND_test.c154
-rw-r--r--intern/SoundSystem/SoundDefines.h107
-rw-r--r--intern/SoundSystem/dummy/SND_DummyDevice.cpp52
-rw-r--r--intern/SoundSystem/dummy/SND_DummyDevice.h93
-rw-r--r--intern/SoundSystem/intern/SND_AudioDevice.cpp242
-rw-r--r--intern/SoundSystem/intern/SND_AudioDevice.h115
-rw-r--r--intern/SoundSystem/intern/SND_C-api.cpp392
-rw-r--r--intern/SoundSystem/intern/SND_CDObject.cpp182
-rw-r--r--intern/SoundSystem/intern/SND_DeviceManager.cpp126
-rw-r--r--intern/SoundSystem/intern/SND_IdObject.cpp76
-rw-r--r--intern/SoundSystem/intern/SND_IdObject.h58
-rw-r--r--intern/SoundSystem/intern/SND_Scene.cpp544
-rw-r--r--intern/SoundSystem/intern/SND_SoundListener.cpp185
-rw-r--r--intern/SoundSystem/intern/SND_SoundObject.cpp508
-rw-r--r--intern/SoundSystem/intern/SND_Utils.cpp424
-rw-r--r--intern/SoundSystem/intern/SND_WaveCache.cpp138
-rw-r--r--intern/SoundSystem/intern/SND_WaveSlot.cpp180
-rw-r--r--intern/SoundSystem/make/msvc_6_0/SoundSystem.dsp206
-rw-r--r--intern/SoundSystem/make/msvc_6_0/dummy/DummySoundSystem.dsp103
-rw-r--r--intern/SoundSystem/make/msvc_6_0/openal/OpenALSoundSystem.dsp106
-rw-r--r--intern/SoundSystem/make/msvc_7_0/SoundSystem.vcproj339
-rw-r--r--intern/SoundSystem/make/msvc_7_0/dummy/DummySoundSystem.vcproj243
-rw-r--r--intern/SoundSystem/make/msvc_7_0/openal/OpenALSoundSystem.vcproj249
-rw-r--r--intern/SoundSystem/make/msvc_9_0/SoundSystem.vcproj447
-rw-r--r--intern/SoundSystem/make/msvc_9_0/dummy/DummySoundSystem.vcproj343
-rw-r--r--intern/SoundSystem/make/msvc_9_0/openal/OpenALSoundSystem.vcproj351
-rw-r--r--intern/SoundSystem/openal/SND_OpenALDevice.cpp864
-rw-r--r--intern/SoundSystem/openal/SND_OpenALDevice.h107
-rw-r--r--intern/SoundSystem/openal/pthread_cancel.cpp67
-rw-r--r--intern/SoundSystem/sdl/SND_SDLCDDevice.cpp171
-rw-r--r--intern/SoundSystem/sdl/SND_SDLCDDevice.h58
-rw-r--r--intern/audaspace/CMakeLists.txt64
-rw-r--r--intern/audaspace/COPYING674
-rw-r--r--intern/audaspace/COPYING.LESSER165
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.cpp58
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.h70
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.cpp111
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.h73
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.cpp158
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.h83
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.cpp50
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.h76
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.cpp78
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.h66
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.cpp84
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.h111
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.cpp133
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.h86
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.cpp67
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.h84
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.cpp95
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.h64
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.cpp57
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.h74
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.cpp107
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.h69
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.cpp67
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.h51
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.cpp48
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.h70
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.cpp39
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.h54
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.cpp43
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.h50
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.cpp111
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.h74
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.cpp57
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.h72
-rw-r--r--intern/audaspace/FX/AUD_VolumeReader.cpp97
-rw-r--r--intern/audaspace/FX/AUD_VolumeReader.h72
-rw-r--r--intern/audaspace/FX/Makefile (renamed from intern/SoundSystem/dummy/Makefile)9
-rw-r--r--intern/audaspace/Makefile106
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp1362
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h171
-rw-r--r--intern/audaspace/OpenAL/Makefile39
-rw-r--r--intern/audaspace/SConscript34
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.cpp90
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.h66
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixer.cpp83
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixer.h76
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixerFactory.cpp65
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixerFactory.h45
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixerReader.cpp216
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixerReader.h128
-rw-r--r--intern/audaspace/SDL/Makefile (renamed from intern/SoundSystem/sdl/Makefile)6
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.cpp53
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.h46
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.cpp119
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.h102
-rw-r--r--intern/audaspace/SRC/Makefile (renamed from intern/SoundSystem/openal/Makefile)12
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp65
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h73
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp388
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h139
-rw-r--r--intern/audaspace/ffmpeg/Makefile (renamed from intern/SoundSystem/intern/Makefile)11
-rw-r--r--intern/audaspace/intern/AUD_Buffer.cpp67
-rw-r--r--intern/audaspace/intern/AUD_Buffer.h75
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.cpp91
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.h74
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp579
-rw-r--r--intern/audaspace/intern/AUD_C-API.h342
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.cpp125
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.h65
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.cpp108
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.h76
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.cpp54
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.h45
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.cpp502
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.h156
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.cpp260
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.h71
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.cpp95
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.h71
-rw-r--r--intern/audaspace/intern/AUD_FloatMixer.cpp172
-rw-r--r--intern/audaspace/intern/AUD_FloatMixer.h100
-rw-r--r--intern/audaspace/intern/AUD_I3DDevice.h103
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h191
-rw-r--r--intern/audaspace/intern/AUD_IFactory.h55
-rw-r--r--intern/audaspace/intern/AUD_IMixer.h77
-rw-r--r--intern/audaspace/intern/AUD_IReader.h117
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.cpp109
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.h117
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp108
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h65
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.cpp64
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.h68
-rw-r--r--intern/audaspace/intern/AUD_Reference.h115
-rw-r--r--intern/audaspace/intern/AUD_ResampleFactory.h33
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.cpp51
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.h70
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.cpp104
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.h86
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp444
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.h137
-rw-r--r--intern/audaspace/intern/AUD_SourceCaps.h41
-rw-r--r--intern/audaspace/intern/AUD_Space.h295
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.cpp80
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.h62
-rw-r--r--intern/audaspace/intern/Makefile70
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.cpp149
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.h92
-rw-r--r--intern/audaspace/jack/Makefile44
-rw-r--r--intern/audaspace/make/msvc_9_0/audaspace.vcproj768
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.cpp67
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.h71
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.cpp233
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.h131
-rw-r--r--intern/audaspace/sndfile/Makefile40
-rw-r--r--intern/boolop/make/msvc_9_0/boolop.vcproj1
-rw-r--r--intern/bsp/make/msvc_9_0/bsplib.vcproj1
-rw-r--r--intern/container/make/msvc_9_0/container.vcproj1
-rw-r--r--intern/decimation/make/msvc_9_0/decimation.vcproj1
-rw-r--r--intern/elbeem/CMakeLists.txt6
-rw-r--r--intern/elbeem/SConscript2
-rw-r--r--intern/elbeem/intern/paraloopend.h6
-rw-r--r--intern/elbeem/intern/solver_init.cpp2
-rw-r--r--intern/elbeem/make/msvc_9_0/elbeem.vcproj1
-rw-r--r--intern/ghost/CMakeLists.txt46
-rw-r--r--intern/ghost/GHOST_C-api.h11
-rw-r--r--intern/ghost/GHOST_IWindow.h8
-rw-r--r--intern/ghost/GHOST_Types.h10
-rw-r--r--intern/ghost/SConscript2
-rw-r--r--intern/ghost/intern/GHOST_C-api.cpp8
-rw-r--r--intern/ghost/intern/GHOST_EventManager.cpp9
-rw-r--r--intern/ghost/intern/GHOST_System.cpp3
-rw-r--r--intern/ghost/intern/GHOST_System.h2
-rw-r--r--intern/ghost/intern/GHOST_SystemCarbon.cpp10
-rw-r--r--intern/ghost/intern/GHOST_SystemWin32.cpp34
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.cpp62
-rw-r--r--intern/ghost/intern/GHOST_SystemX11.h8
-rw-r--r--intern/ghost/intern/GHOST_Window.cpp15
-rw-r--r--intern/ghost/intern/GHOST_Window.h16
-rw-r--r--intern/ghost/intern/GHOST_WindowCarbon.cpp2
-rw-r--r--intern/ghost/intern/GHOST_WindowManager.cpp1
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp36
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp167
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.h9
-rw-r--r--intern/ghost/make/msvc_9_0/ghost.vcproj1
-rw-r--r--intern/guardedalloc/BLO_sys_types.h2
-rw-r--r--intern/guardedalloc/CMakeLists.txt7
-rw-r--r--intern/guardedalloc/MEM_guardedalloc.h2
-rw-r--r--intern/guardedalloc/SConscript2
-rw-r--r--intern/guardedalloc/cpp/mallocn.cpp (renamed from intern/SoundSystem/SND_DependKludge.h)43
-rw-r--r--intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj1
-rw-r--r--intern/iksolver/SConscript2
-rw-r--r--intern/iksolver/intern/TNT/tntmath.h4
-rw-r--r--intern/iksolver/make/msvc_9_0/iksolver.vcproj1
-rw-r--r--intern/itasc/Armature.cpp769
-rw-r--r--intern/itasc/Armature.hpp137
-rw-r--r--intern/itasc/CMakeLists.txt32
-rw-r--r--intern/itasc/Cache.cpp621
-rw-r--r--intern/itasc/Cache.hpp227
-rw-r--r--intern/itasc/ConstraintSet.cpp170
-rw-r--r--intern/itasc/ConstraintSet.hpp115
-rw-r--r--intern/itasc/ControlledObject.cpp61
-rw-r--r--intern/itasc/ControlledObject.hpp70
-rw-r--r--intern/itasc/CopyPose.cpp481
-rw-r--r--intern/itasc/CopyPose.hpp99
-rw-r--r--intern/itasc/Distance.cpp322
-rw-r--r--intern/itasc/Distance.hpp62
-rw-r--r--intern/itasc/FixedObject.cpp70
-rw-r--r--intern/itasc/FixedObject.hpp45
-rw-r--r--intern/itasc/Makefile53
-rw-r--r--intern/itasc/MovingFrame.cpp157
-rw-r--r--intern/itasc/MovingFrame.hpp48
-rw-r--r--intern/itasc/Object.hpp48
-rw-r--r--intern/itasc/SConscript11
-rw-r--r--intern/itasc/Scene.cpp543
-rw-r--r--intern/itasc/Scene.hpp104
-rw-r--r--intern/itasc/Solver.hpp33
-rw-r--r--intern/itasc/UncontrolledObject.cpp43
-rw-r--r--intern/itasc/UncontrolledObject.hpp37
-rw-r--r--intern/itasc/WDLSSolver.cpp85
-rw-r--r--intern/itasc/WDLSSolver.hpp47
-rw-r--r--intern/itasc/WSDLSSolver.cpp122
-rw-r--r--intern/itasc/WSDLSSolver.hpp40
-rw-r--r--intern/itasc/WorldObject.cpp26
-rw-r--r--intern/itasc/WorldObject.hpp30
-rw-r--r--intern/itasc/eigen_types.cpp12
-rw-r--r--intern/itasc/eigen_types.hpp84
-rw-r--r--intern/itasc/kdl/Makefile42
-rw-r--r--intern/itasc/kdl/chain.cpp75
-rw-r--r--intern/itasc/kdl/chain.hpp95
-rw-r--r--intern/itasc/kdl/chainfksolver.hpp107
-rw-r--r--intern/itasc/kdl/chainfksolverpos_recursive.cpp61
-rw-r--r--intern/itasc/kdl/chainfksolverpos_recursive.hpp50
-rw-r--r--intern/itasc/kdl/chainjnttojacsolver.cpp80
-rw-r--r--intern/itasc/kdl/chainjnttojacsolver.hpp65
-rw-r--r--intern/itasc/kdl/frameacc.cpp26
-rw-r--r--intern/itasc/kdl/frameacc.hpp259
-rw-r--r--intern/itasc/kdl/frameacc.inl598
-rw-r--r--intern/itasc/kdl/frames.cpp389
-rw-r--r--intern/itasc/kdl/frames.hpp1097
-rw-r--r--intern/itasc/kdl/frames.inl1390
-rw-r--r--intern/itasc/kdl/frames_io.cpp310
-rw-r--r--intern/itasc/kdl/frames_io.hpp114
-rw-r--r--intern/itasc/kdl/framevel.cpp27
-rw-r--r--intern/itasc/kdl/framevel.hpp382
-rw-r--r--intern/itasc/kdl/framevel.inl534
-rw-r--r--intern/itasc/kdl/inertia.cpp48
-rw-r--r--intern/itasc/kdl/inertia.hpp70
-rw-r--r--intern/itasc/kdl/jacobian.cpp129
-rw-r--r--intern/itasc/kdl/jacobian.hpp68
-rw-r--r--intern/itasc/kdl/jntarray.cpp152
-rw-r--r--intern/itasc/kdl/jntarray.hpp217
-rw-r--r--intern/itasc/kdl/jntarrayacc.cpp170
-rw-r--r--intern/itasc/kdl/jntarrayacc.hpp66
-rw-r--r--intern/itasc/kdl/jntarrayvel.cpp111
-rw-r--r--intern/itasc/kdl/jntarrayvel.hpp59
-rw-r--r--intern/itasc/kdl/joint.cpp153
-rw-r--r--intern/itasc/kdl/joint.hpp138
-rw-r--r--intern/itasc/kdl/kinfam_io.cpp101
-rw-r--r--intern/itasc/kdl/kinfam_io.hpp70
-rw-r--r--intern/itasc/kdl/segment.cpp68
-rw-r--r--intern/itasc/kdl/segment.hpp149
-rw-r--r--intern/itasc/kdl/tree.cpp117
-rw-r--r--intern/itasc/kdl/tree.hpp167
-rw-r--r--intern/itasc/kdl/treefksolver.hpp110
-rw-r--r--intern/itasc/kdl/treefksolverpos_recursive.cpp71
-rw-r--r--intern/itasc/kdl/treefksolverpos_recursive.hpp53
-rw-r--r--intern/itasc/kdl/treejnttojacsolver.cpp78
-rw-r--r--intern/itasc/kdl/treejnttojacsolver.hpp38
-rw-r--r--intern/itasc/kdl/utilities/Makefile37
-rw-r--r--intern/itasc/kdl/utilities/error.h245
-rw-r--r--intern/itasc/kdl/utilities/error_stack.cpp59
-rw-r--r--intern/itasc/kdl/utilities/error_stack.h70
-rw-r--r--intern/itasc/kdl/utilities/kdl-config.h33
-rw-r--r--intern/itasc/kdl/utilities/rall1d.h478
-rw-r--r--intern/itasc/kdl/utilities/rall2d.h538
-rw-r--r--intern/itasc/kdl/utilities/svd_eigen_HH.hpp309
-rw-r--r--intern/itasc/kdl/utilities/traits.h111
-rw-r--r--intern/itasc/kdl/utilities/utility.cpp21
-rw-r--r--intern/itasc/kdl/utilities/utility.h298
-rw-r--r--intern/itasc/kdl/utilities/utility_io.cpp208
-rw-r--r--intern/itasc/kdl/utilities/utility_io.h79
-rw-r--r--intern/itasc/make/msvc_9_0/itasc.vcproj539
-rw-r--r--intern/itasc/ublas_types.hpp82
-rw-r--r--intern/memutil/SConscript2
-rw-r--r--intern/memutil/make/msvc_9_0/memutil.vcproj1
-rw-r--r--intern/moto/SConscript2
-rw-r--r--intern/moto/make/msvc_9_0/moto.vcproj1
-rw-r--r--intern/opennl/superlu/BLO_sys_types.h2
-rw-r--r--intern/smoke/CMakeLists.txt42
-rw-r--r--intern/smoke/Makefile (renamed from intern/SoundSystem/Makefile)42
-rw-r--r--intern/smoke/SConscript18
-rw-r--r--intern/smoke/extern/smoke_API.h79
-rw-r--r--intern/smoke/intern/EIGENVALUE_HELPER.h47
-rw-r--r--intern/smoke/intern/FFT_NOISE.h178
-rw-r--r--intern/smoke/intern/FLUID_3D.cpp717
-rw-r--r--intern/smoke/intern/FLUID_3D.h168
-rw-r--r--intern/smoke/intern/FLUID_3D_SOLVERS.cpp524
-rw-r--r--intern/smoke/intern/FLUID_3D_STATIC.cpp610
-rw-r--r--intern/smoke/intern/IMAGE.h277
-rw-r--r--intern/smoke/intern/INTERPOLATE.h227
-rw-r--r--intern/smoke/intern/LICENSE.txt674
-rw-r--r--intern/smoke/intern/LU_HELPER.h56
-rw-r--r--intern/smoke/intern/MERSENNETWISTER.h429
-rw-r--r--intern/smoke/intern/Makefile52
-rw-r--r--intern/smoke/intern/Makefile.FFT22
-rw-r--r--intern/smoke/intern/Makefile.cygwin23
-rw-r--r--intern/smoke/intern/Makefile.linux23
-rw-r--r--intern/smoke/intern/Makefile.mac35
-rw-r--r--intern/smoke/intern/OBSTACLE.h41
-rw-r--r--intern/smoke/intern/SPHERE.cpp50
-rw-r--r--intern/smoke/intern/SPHERE.h41
-rw-r--r--intern/smoke/intern/VEC3.h986
-rw-r--r--intern/smoke/intern/WAVELET_NOISE.h458
-rw-r--r--intern/smoke/intern/WTURBULENCE.cpp988
-rw-r--r--intern/smoke/intern/WTURBULENCE.h130
-rw-r--r--intern/smoke/intern/smoke_API.cpp262
-rw-r--r--intern/smoke/intern/tnt/jama_eig.h1050
-rw-r--r--intern/smoke/intern/tnt/jama_lu.h319
-rw-r--r--intern/smoke/intern/tnt/tnt.h64
-rw-r--r--intern/smoke/intern/tnt/tnt_array1d.h278
-rw-r--r--intern/smoke/intern/tnt/tnt_array1d_utils.h230
-rw-r--r--intern/smoke/intern/tnt/tnt_array2d.h315
-rw-r--r--intern/smoke/intern/tnt/tnt_array2d_utils.h287
-rw-r--r--intern/smoke/intern/tnt/tnt_array3d.h296
-rw-r--r--intern/smoke/intern/tnt/tnt_array3d_utils.h236
-rw-r--r--intern/smoke/intern/tnt/tnt_cmat.h580
-rw-r--r--intern/smoke/intern/tnt/tnt_fortran_array1d.h267
-rw-r--r--intern/smoke/intern/tnt/tnt_fortran_array1d_utils.h242
-rw-r--r--intern/smoke/intern/tnt/tnt_fortran_array2d.h225
-rw-r--r--intern/smoke/intern/tnt/tnt_fortran_array2d_utils.h236
-rw-r--r--intern/smoke/intern/tnt/tnt_fortran_array3d.h223
-rw-r--r--intern/smoke/intern/tnt/tnt_fortran_array3d_utils.h249
-rw-r--r--intern/smoke/intern/tnt/tnt_i_refvec.h243
-rw-r--r--intern/smoke/intern/tnt/tnt_math_utils.h36
-rw-r--r--intern/smoke/intern/tnt/tnt_sparse_matrix_csr.h103
-rw-r--r--intern/smoke/intern/tnt/tnt_stopwatch.h95
-rw-r--r--intern/smoke/intern/tnt/tnt_subscript.h54
-rw-r--r--intern/smoke/intern/tnt/tnt_vec.h404
-rw-r--r--intern/smoke/intern/tnt/tnt_version.h39
-rw-r--r--intern/smoke/make/msvc_9_0/smoke.vcproj512
-rw-r--r--intern/string/SConscript2
-rw-r--r--intern/string/STR_String.h14
-rw-r--r--intern/string/intern/STR_String.cpp6
-rw-r--r--intern/string/make/msvc_9_0/string.vcproj1
355 files changed, 44771 insertions, 9034 deletions
diff --git a/intern/CMakeLists.txt b/intern/CMakeLists.txt
index 697d0b6b575..ac08b780ab8 100644
--- a/intern/CMakeLists.txt
+++ b/intern/CMakeLists.txt
@@ -24,7 +24,7 @@
#
# ***** END GPL LICENSE BLOCK *****
-ADD_SUBDIRECTORY(SoundSystem)
+ADD_SUBDIRECTORY(audaspace)
ADD_SUBDIRECTORY(string)
ADD_SUBDIRECTORY(ghost)
ADD_SUBDIRECTORY(guardedalloc)
@@ -33,11 +33,13 @@ ADD_SUBDIRECTORY(container)
ADD_SUBDIRECTORY(memutil)
ADD_SUBDIRECTORY(decimation)
ADD_SUBDIRECTORY(iksolver)
+ADD_SUBDIRECTORY(itasc)
ADD_SUBDIRECTORY(boolop)
ADD_SUBDIRECTORY(opennl)
+ADD_SUBDIRECTORY(smoke)
IF(WITH_ELBEEM)
- ADD_SUBDIRECTORY(elbeem)
+ ADD_SUBDIRECTORY(elbeem)
ENDIF(WITH_ELBEEM)
ADD_SUBDIRECTORY(bsp)
diff --git a/intern/Makefile b/intern/Makefile
index 995dc56c7d3..32375f16b7a 100644
--- a/intern/Makefile
+++ b/intern/Makefile
@@ -32,7 +32,7 @@ SOURCEDIR = intern
# include nan_subdirs.mk
ALLDIRS = string ghost guardedalloc moto container memutil
-ALLDIRS += decimation iksolver bsp SoundSystem opennl elbeem boolop
+ALLDIRS += decimation iksolver itasc bsp SoundSystem opennl elbeem boolop smoke audaspace
all::
@for i in $(ALLDIRS); do \
diff --git a/intern/SConscript b/intern/SConscript
index bb8525d5ce5..241662b7088 100644
--- a/intern/SConscript
+++ b/intern/SConscript
@@ -1,7 +1,7 @@
#!/usr/bin/python
Import ('env')
-SConscript(['SoundSystem/SConscript',
+SConscript(['audaspace/SConscript',
'string/SConscript',
'ghost/SConscript',
'guardedalloc/SConscript',
@@ -10,8 +10,10 @@ SConscript(['SoundSystem/SConscript',
'memutil/SConscript/',
'decimation/SConscript',
'iksolver/SConscript',
+ 'itasc/SConscript',
'boolop/SConscript',
- 'opennl/SConscript'])
+ 'opennl/SConscript',
+ 'smoke/SConscript'])
# NEW_CSG was intended for intern/csg, but
# getting it to compile is difficult
diff --git a/intern/SoundSystem/CMakeLists.txt b/intern/SoundSystem/CMakeLists.txt
deleted file mode 100644
index 9a370af2268..00000000000
--- a/intern/SoundSystem/CMakeLists.txt
+++ /dev/null
@@ -1,42 +0,0 @@
-# $Id$
-# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2006, Blender Foundation
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): Jacques Beaurain.
-#
-# ***** END GPL LICENSE BLOCK *****
-
-SET(INC . intern ../moto/include ../string dummy openal sdl)
-
-IF(WITH_OPENAL)
- FILE(GLOB SRC dummy/*.cpp intern/*.cpp openal/*.cpp sdl/*.cpp)
- INCLUDE_DIRECTORIES(${OPENAL_INC} ${SDL_INC})
- STRING(REGEX MATCH ".*ramework.*" FRAMEWORK ${OPENAL_INC})
- IF(FRAMEWORK)
- ADD_DEFINITIONS(-DAPPLE_FRAMEWORK_FIX)
- ENDIF(FRAMEWORK)
-ELSE(WITH_OPENAL)
- FILE(GLOB SRC dummy/*.cpp intern/*.cpp)
- ADD_DEFINITIONS(-DNO_SOUND)
-ENDIF(WITH_OPENAL)
-
-BLENDERLIB(bf_soundsystem "${SRC}" "${INC}")
-#, libtype=['core','player'], priority = [20,140] )
diff --git a/intern/SoundSystem/SConscript b/intern/SoundSystem/SConscript
deleted file mode 100644
index 256b7904a0f..00000000000
--- a/intern/SoundSystem/SConscript
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/usr/bin/python
-
-Import ('env')
-
-sources = env.Glob('dummy/*.cpp') + env.Glob('intern/*.cpp')
-
-incs = '. intern ../moto/include ../string dummy openal sdl'
-defs = ''
-if env['WITH_BF_OPENAL']:
- sources += env.Glob('openal/*.cpp') + env.Glob('sdl/*.cpp')
- incs += ' ' + env['BF_OPENAL_INC']
- incs += ' ' + env['BF_SDL_INC']
- defs = 'USE_OPENAL'
-else:
- defs = 'NO_SOUND'
-
-if not env['WITH_BF_SDL']:
- defs += ' DISABLE_SDL'
-
-env.BlenderLib ('bf_soundsystem', sources, Split(incs), Split(defs), libtype=['intern','player'], priority = [25,135] )
diff --git a/intern/SoundSystem/SND_C-api.h b/intern/SoundSystem/SND_C-api.h
deleted file mode 100644
index f8e439a9c26..00000000000
--- a/intern/SoundSystem/SND_C-api.h
+++ /dev/null
@@ -1,354 +0,0 @@
-/**
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef SND_BLENDER_H
-#define SND_BLENDER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "SoundDefines.h"
-
-#define SND_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
-
-SND_DECLARE_HANDLE(SND_AudioDeviceInterfaceHandle);
-SND_DECLARE_HANDLE(SND_SceneHandle);
-SND_DECLARE_HANDLE(SND_ObjectHandle);
-SND_DECLARE_HANDLE(SND_ListenerHandle);
-
-/**
- * set the specified type
- */
-extern void SND_SetDeviceType(int device_type);
-
-/**
- * get an audiodevice
- */
-extern SND_AudioDeviceInterfaceHandle SND_GetAudioDevice(void);
-
-/**
- * and let go of it
- */
-extern void SND_ReleaseDevice(void);
-
-/**
- * check if playback is desired
- */
-extern int SND_IsPlaybackWanted(SND_SceneHandle scene);
-
-/**
- * add memlocation to cache
- */
-extern int SND_AddSample(SND_SceneHandle scene,
- const char* filename,
- void* memlocation,
- int size);
-
-/**
- * remove all samples
- */
-extern void SND_RemoveAllSamples(SND_SceneHandle scene);
-
-/**
- * forces the object to check its buffer, and fix it if it's wrong
- */
-extern int SND_CheckBuffer(SND_SceneHandle scene, SND_ObjectHandle object);
-
-/**
- * Creates a scene, initializes it and returns a handle to that scene.
- *
- * @param audiodevice: handle to the audiodevice.
- */
-extern SND_SceneHandle SND_CreateScene(SND_AudioDeviceInterfaceHandle audiodevice);
-
-/**
- * Stops all sounds, suspends the scene (so all resources will be freed) and deletes the scene.
- *
- * @param scene: handle to the soundscene.
- */
-extern void SND_DeleteScene(SND_SceneHandle scene);
-
-/**
- * Adds a soundobject to the scene, gets the buffer the sample is loaded into.
- *
- * @param scene: handle to the soundscene.
- * @param object: handle to soundobject.
- */
-extern void SND_AddSound(SND_SceneHandle scene, SND_ObjectHandle object);
-
-/**
- * Removes a soundobject from the scene.
- *
- * @param scene: handle to the soundscene.
- * @param object: handle to soundobject.
- */
-extern void SND_RemoveSound(SND_SceneHandle scene, SND_ObjectHandle object);
-
-/**
- * Removes all soundobjects from the scene.
- *
- * @param scene: handle to the soundscene.
- */
-extern void SND_RemoveAllSounds(SND_SceneHandle scene);
-
-/**
- * Stopss all soundobjects in the scene.
- *
- * @param scene: handle to the soundscene.
- */
-extern void SND_StopAllSounds(SND_SceneHandle scene);
-
-/**
- * Updates the listener, checks the status of all soundobjects, builds a list of all active
- * objects, updates the active objects.
- *
- * @param audiodevice: handle to the audiodevice.
- * @param scene: handle to the soundscene.
- */
-extern void SND_Proceed(SND_AudioDeviceInterfaceHandle audiodevice, SND_SceneHandle scene);
-
-/**
- * Returns a handle to the listener.
- *
- * @param scene: handle to the soundscene.
- */
-extern SND_ListenerHandle SND_GetListener(SND_SceneHandle scene);
-
-/**
- * Sets the gain of the listener.
- *
- * @param scene: handle to the soundscene.
- * @param gain: factor the gain gets multiplied with.
- */
-extern void SND_SetListenerGain(SND_SceneHandle scene, double gain);
-
-/**
- * Sets a scaling to exaggerate or deemphasize the Doppler (pitch) shift resulting from the
- * calculation.
- * @attention $f' = dopplerfactor * f * frac{dopplervelocity - listener_velocity}{dopplervelocity + object_velocity}$
- * @attention f: frequency in sample (soundobject)
- * @attention f': effective Doppler shifted frequency
- *
- * @param object: handle to soundobject.
- * @param dopplerfactor: the dopplerfactor.
- */
-extern void SND_SetDopplerFactor(SND_SceneHandle scene, double dopplerfactor);
-
-/**
- * Sets the value of the propagation speed relative to which the source velocities are interpreted.
- * @attention $f' = dopplerfactor * f * frac{dopplervelocity - listener_velocity}{dopplervelocity + object_velocity}$
- * @attention f: frequency in sample (soundobject)
- * @attention f': effective Doppler shifted frequency
- *
- * @param object: handle to soundobject.
- * @param dopplervelocity: the dopplervelocity.
- */
-extern void SND_SetDopplerVelocity(SND_SceneHandle scene, double dopplervelocity);
-
-/**
- * Creates a new soundobject and returns a handle to it.
- */
-extern SND_ObjectHandle SND_CreateSound(void);
-
-/**
- * Deletes a soundobject.
- *
- * @param object: handle to soundobject.
- */
-extern void SND_DeleteSound(SND_ObjectHandle object);
-
-/**
- * Sets a soundobject to SND_MUST_PLAY, so with the next proceed it will be updated and played.
- *
- * @param object: handle to soundobject.
- */
-extern void SND_StartSound(SND_SceneHandle scene, SND_ObjectHandle object);
-
-/**
- * Sets a soundobject to SND_MUST_STOP, so with the next proceed it will be stopped.
- *
- * @param object: handle to soundobject.
- */
-extern void SND_StopSound(SND_SceneHandle scene, SND_ObjectHandle object);
-
-/**
- * Sets a soundobject to SND_MUST_PAUSE, so with the next proceed it will be paused.
- *
- * @param object: handle to soundobject.
- */
-extern void SND_PauseSound(SND_SceneHandle scene, SND_ObjectHandle object);
-
-/**
- * Sets the name of the sample to reference the soundobject to it.
- *
- * @param object: handle to soundobject.
- * @param samplename: the name of the sample
- */
-extern void SND_SetSampleName(SND_ObjectHandle object, char* samplename);
-
-/**
- * Sets the gain of a soundobject.
- *
- * @param object: handle to soundobject.
- * @param gain: factor the gain gets multiplied with.
- */
-extern void SND_SetGain(SND_ObjectHandle object, double gain);
-
-/**
- * Sets the minimum gain of a soundobject.
- *
- * @param object: handle to soundobject.
- * @param minimumgain: lower threshold for the gain.
- */
-extern void SND_SetMinimumGain(SND_ObjectHandle object, double minimumgain);
-
-/**
- * Sets the maximum gain of a soundobject.
- *
- * @param object: handle to soundobject.
- * @param maximumgain: upper threshold for the gain.
- */
-extern void SND_SetMaximumGain(SND_ObjectHandle object, double maximumgain);
-
-/**
- * Sets the rollofffactor. The rollofffactor is a per-Source parameter the application
- * can use to increase or decrease the range of a source by decreasing or increasing the
- * attenuation, respectively. The default value is 1. The implementation is free to optimize
- * for a rollofffactor value of 0, which indicates that the application does not wish any
- * distance attenuation on the respective Source.
- *
- * @param object: handle to soundobject.
- * @param rollofffactor: the rollofffactor.
- */
-extern void SND_SetRollOffFactor(SND_ObjectHandle object, double rollofffactor);
-
-/**
- * Sets the referencedistance at which the listener will experience gain.
- * @attention G_dB = gain - 20 * log10(1 + rollofffactor * (dist - referencedistance)/referencedistance);
- *
- * @param object: handle to soundobject.
- * @param distance: the reference distance.
- */
-extern void SND_SetReferenceDistance(SND_ObjectHandle object, double referencedistance);
-
-/**
- * Sets the pitch of a soundobject.
- *
- * @param object: handle to soundobject.
- * @param pitch: pitchingfactor: 2.0 for doubling the frequency, 0.5 for half the frequency.
- */
-extern void SND_SetPitch(SND_ObjectHandle object, double pitch);
-
-/**
- * Sets the position a soundobject.
- *
- * @param object: handle to soundobject.
- * @param position: position[3].
- */
-extern void SND_SetPosition(SND_ObjectHandle object, double* position);
-
-/**
- * Sets the velocity of a soundobject.
- *
- * @param object: handle to soundobject.
- * @param velocity: velocity[3].
- */
-extern void SND_SetVelocity(SND_ObjectHandle object, double* velocity);
-
-/**
- * Sets the orientation of a soundobject.
- *
- * @param object: handle to soundobject.
- * @param orientation: orientation[9].
- */
-extern void SND_SetOrientation(SND_ObjectHandle object, double* orientation);
-
-/**
- * Sets the loopmode of a soundobject.
- *
- * @param object: handle to soundobject.
- * @param loopmode type of the loop (SND_LOOP_OFF, SND_LOOP_NORMAL, SND_LOOP_BIDIRECTIONAL);
- */
-extern void SND_SetLoopMode(SND_ObjectHandle object, int loopmode);
-
-/**
- * Sets the looppoints of a soundobject.
- *
- * @param object: handle to soundobject.
- * @param loopstart startpoint of the loop
- * @param loopend endpoint of the loop
- */
-extern void SND_SetLoopPoints(SND_ObjectHandle object, unsigned int loopstart, unsigned int loopend);
-
-/**
- * Gets the gain of a soundobject.
- *
- * @param object: handle to soundobject.
- */
-extern float SND_GetGain(SND_ObjectHandle object);
-
-/**
- * Gets the pitch of a soundobject.
- *
- * @param object: handle to soundobject.
- */
-extern float SND_GetPitch(SND_ObjectHandle object);
-
-/**
- * Gets the looping of a soundobject.
- * 0: SND_LOOP_OFF
- * 1: SND_LOOP_NORMAL
- * 2: SND_LOOP_BIDIRECTIONAL
- *
- * @param object: handle to soundobject.
- */
-extern int SND_GetLoopMode(SND_ObjectHandle object);
-
-/**
- * Gets the playstate of a soundobject.
- * SND_UNKNOWN = -1
- * SND_INITIAL
- * SND_MUST_PLAY
- * SND_PLAYING
- * SND_MUST_STOP
- * SND_STOPPED
- * SND_MUST_PAUSE
- * SND_PAUSED
- * SND_MUST_BE_DELETED
- *
- * @param object: handle to soundobject.
- */
-extern int SND_GetPlaystate(SND_ObjectHandle object);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/intern/SoundSystem/SND_CDObject.h b/intern/SoundSystem/SND_CDObject.h
deleted file mode 100644
index c79f62d9862..00000000000
--- a/intern/SoundSystem/SND_CDObject.h
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * SND_CDObject.h
- *
- * Implementation for CD playback
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __SND_CDOBJECT_H
-#define __SND_CDOBJECT_H
-
-#include "SND_Object.h"
-
-class SND_CDObject : public SND_Object
-{
-private:
-
- /**
- * Private to enforce singleton
- */
- SND_CDObject();
- SND_CDObject(const SND_CDObject&);
-
- static SND_CDObject* m_instance;
- MT_Scalar m_gain; /* the gain of the object */
- int m_playmode; /* the way CD is played back (all, random, track, trackloop) */
- int m_track; /* the track for 'track' and 'trackloop' */
- int m_playstate; /* flag for current state of object */
- bool m_modified;
- bool m_used; /* flag for checking if we used the cd, if not don't
- call the stop cd at the end */
-
-public:
- static bool CreateSystem();
- static bool DisposeSystem();
- static SND_CDObject* Instance();
-
- ~SND_CDObject();
-
- void SetGain(MT_Scalar gain);
- void SetPlaymode(int playmode);
- void SetTrack(int track);
- void SetPlaystate(int playstate);
- void SetModified(bool modified);
- void SetUsed();
- bool GetUsed();
-
- bool IsModified() const;
-
- int GetTrack() const;
- MT_Scalar GetGain() const;
- int GetPlaymode() const;
- int GetPlaystate() const;
-
-};
-
-#endif //__SND_CDOBJECT_H
-
diff --git a/intern/SoundSystem/SND_DeviceManager.h b/intern/SoundSystem/SND_DeviceManager.h
deleted file mode 100644
index 708db030519..00000000000
--- a/intern/SoundSystem/SND_DeviceManager.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * SND_DeviceManager.h
- *
- * singleton for creating, switching and deleting audiodevices
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __SND_DEVICEMANAGER_H
-#define __SND_DEVICEMANAGER_H
-
-#include "SND_IAudioDevice.h"
-
-class SND_DeviceManager
-{
-public :
-
- /**
- * a subscription is needed before instances are given away
- * applications must call subscribe first, get an instance, and
- * when they are finished with sound, unsubscribe
- */
- static void Subscribe();
- static void Unsubscribe();
-
- static SND_IAudioDevice* Instance();
- static void SetDeviceType(int device_type);
-
-private :
-
- /**
- * Private to enforce singleton
- */
- SND_DeviceManager();
- SND_DeviceManager(const SND_DeviceManager&);
- ~SND_DeviceManager();
-
- static SND_IAudioDevice* m_instance;
-
- /**
- * The type of device to be created on a call
- * to Instance().
- */
- static int m_device_type;
-
- /**
- * Remember the number of subscriptions.
- * if 0, delete the device
- */
- static int m_subscriptions;
-};
-
-#endif //__SND_DEVICEMANAGER_H
-
diff --git a/intern/SoundSystem/SND_IAudioDevice.h b/intern/SoundSystem/SND_IAudioDevice.h
deleted file mode 100644
index d6b3936e6ef..00000000000
--- a/intern/SoundSystem/SND_IAudioDevice.h
+++ /dev/null
@@ -1,343 +0,0 @@
-/**
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef SND_IAUDIODEVICE
-#define SND_IAUDIODEVICE
-
-#include "SND_SoundObject.h"
-#include "SND_CDObject.h"
-#include "SND_WaveCache.h"
-#include "SND_WaveSlot.h"
-#include "MT_Matrix3x3.h"
-
-class SND_IAudioDevice
-{
-public:
-
- /**
- * constructor
- */
- SND_IAudioDevice() {};
-
- /**
- * destructor
- */
- virtual ~SND_IAudioDevice() {};
-
- /**
- * check to see if initialization was successfull
- *
- * @return indication of succes
- */
- virtual bool IsInitialized()=0;
-
- /**
- * get the wavecache (which does sample (un)loading)
- *
- * @return pointer to the wavecache
- */
- virtual SND_WaveCache* GetWaveCache() const =0;
-
- /**
- * loads a sample into the device
- *
- * @param samplename the name of the sample
- * @param memlocation pointer where the sample is stored
- * @param size size of the sample in memory
- *
- * @return pointer to the slot with sample data
- */
- virtual SND_WaveSlot* LoadSample(const STR_String& samplename,
- void* memlocation,
- int size)=0;
-
- /**
- * remove a sample from the wavecache
- *
- * @param filename pointer to filename
- */
-// virtual void RemoveSample(const char* filename)=0;
-
- /**
- * remove all samples from the wavecache
- */
- virtual void RemoveAllSamples()=0;
-
- /**
- * get a new id from the device
- *
- * @param pObject pointer to soundobject
- *
- * @return indication of success
- */
- virtual bool GetNewId(SND_SoundObject* pObject)=0;
-
- /**
- * clear an id
- *
- * @param pObject pointer to soundobject
- */
- virtual void ClearId(SND_SoundObject* pObject)=0;
-
- /**
- * initialize the listener
- */
- virtual void InitListener()=0;
-
- /**
- * set the value of the propagation speed relative to which the
- * source velocities are interpreted.
- * f' = DOPPLER_FACTOR * f * (DOPPLER_VELOCITY - Vl) / (DOPPLER_VELOCITY + Vo)
- * f: frequency in sample (soundobject)
- * f': effective Doppler shifted frequency
- * Vl: velocity listener
- * Vo: velocity soundobject
- *
- * @param dopplervelocity scaling factor for doppler effect
- */
- virtual void SetDopplerVelocity(MT_Scalar dopplervelocity) const =0;
-
- /**
- * set a scaling to exaggerate or deemphasize the Doppler (pitch)
- * shift resulting from the calculation.
- * f' = DOPPLER_FACTOR * f * (DOPPLER_VELOCITY - Listener_velocity )/(DOPPLER_VELOCITY + object_velocity )
- *
- * @param dopplerfactor scaling factor for doppler effect
- */
- virtual void SetDopplerFactor(MT_Scalar dopplerfactor) const =0;
-
- /**
- * set the roll-off factor
- *
- * @param rollofffactor a global volume scaling factor
- */
- virtual void SetListenerRollOffFactor(MT_Scalar rollofffactor) const =0;
-
- /**
- * make the context the current one
- */
- virtual void MakeCurrent() const =0;
-
- /**
- * update the device
- */
- virtual void NextFrame() const =0;
-
- /**
- * set the volume of the listener.
- *
- * @param gain the mastergain
- */
- virtual void SetListenerGain(float gain) const =0;
-
- /**
- * connect the buffer with the source
- *
- * @param id the id of the object
- * @param buffer the buffer the sample is stored in
- */
- virtual void SetObjectBuffer(int id, unsigned int buffer)=0;
-
- /**
- * pause playback of the cd
- * @param id the id of the object
- *
- * @return the state the object is in
- */
- virtual int GetPlayState(int id) =0;
-
- /**
- * play a sound belonging to an object.
- *
- * @param id the id of the object
- */
- virtual void PlayObject(int id) =0;
-
- /**
- * stop a sound belonging to an object.
- *
- * @param id the id of the object
- */
- virtual void StopObject(int id) const =0;
-
- /**
- * stop all sounds.
- */
- virtual void StopAllObjects()=0;
-
- /**
- * pause the sound belonging to an object.
- *
- * @param id the id of the object
- */
- virtual void PauseObject(int id) const =0;
-
- /**
- * set the sound to looping or non-looping.
- *
- * @param id the id of the object
- * @param loopmode type of looping (no loop, normal, bidirectional)
- */
- virtual void SetObjectLoop(int id, unsigned int loopmode) const =0;
-
- /**
- * set the looppoints of a sound
- *
- * @param id the id of the object
- * @param loopstart the startpoint of the loop (in samples)
- * @param loopend the endpoint of the loop (in samples)
- */
- virtual void SetObjectLoopPoints(int id, unsigned int loopstart, unsigned int loopend) const =0;
-
- /**
- * set the pitch of the sound.
- *
- * @param id the id of the object
- * @param pitch the pitch
- */
- virtual void SetObjectPitch(int id, MT_Scalar pitch) const =0;
-
- /**
- * set the gain of the sound.
- *
- * @param id the id of the object
- * @param gain the gain
- */
- virtual void SetObjectGain(int id, MT_Scalar gain) const =0;
-
- /**
- * ROLLOFF_FACTOR is per-Source parameter the application can use to increase or decrease
- * the range of a source by decreasing or increasing the attenuation, respectively. The
- * default value is 1. The implementation is free to optimize for a ROLLOFF_FACTOR value
- * of 0, which indicates that the application does not wish any distance attenuation on
- * the respective Source.
- *
- * @param id the id of the object
- * @param rolloff a per-source volume scaling factor
- */
- virtual void SetObjectRollOffFactor(int id, MT_Scalar rolloff) const =0;
-
- /**
- * min_gain indicates the minimal gain which is always guaranteed for this sound
- *
- * @param id the id of the object
- * @param mingain the minimum gain of the object
- */
- virtual void SetObjectMinGain(int id, MT_Scalar mingain) const =0;
-
- /**
- * max_gain indicates the maximal gain which is always guaranteed for this sound
- *
- * @param id the id of the object
- * @param maxgain the maximum gain of the object
- */
- virtual void SetObjectMaxGain(int id, MT_Scalar maxgain) const =0;
- /**
- * set the distance at which the Listener will experience gain.
- * G_dB = GAIN - 20*log10(1 + ROLLOFF_FACTOR*(dist-REFERENCE_DISTANCE)/REFERENCE_DISTANCE );
- *
- * @param id the id of the object
- * @param referencedistance the distance at which the listener will start hearing
- */
- virtual void SetObjectReferenceDistance(int id, MT_Scalar referencedistance) const =0;
-
- /**
- * set the position, velocity and orientation of a sound.
- *
- * @param id the id of the object
- * @param position the position of the object
- * @param velocity the velocity of the object
- * @param orientation the orientation of the object
- * @param lisposition the position of the listener
- * @param rollofffactor the rollofffactor of the object
- */
- virtual void SetObjectTransform(int id,
- const MT_Vector3& position,
- const MT_Vector3& velocity,
- const MT_Matrix3x3& orientation,
- const MT_Vector3& lisposition,
- const MT_Scalar& rollofffactor) const =0;
-
- /**
- * make a sound 2D
- *
- * @param id the id of the object
- */
- virtual void ObjectIs2D(int id) const =0;
-
- /**
- * tell the device we want cd suppport
- */
- virtual void UseCD() const =0;
-
- /**
- * start playback of the cd
- *
- * @param track the tracknumber to start playback from
- */
- virtual void PlayCD(int track) const =0;
-
- /**
- * pause playback of the cd (true == pause, false == resume)
- */
- virtual void PauseCD(bool pause) const =0;
-
- /**
- * stop playback of the cd
- */
- virtual void StopCD() const =0;
-
- /**
- * set the playbackmode of the cd
- * SND_CD_ALL play all tracks
- * SND_CD_TRACK play one track
- * SND_CD_TRACKLOOP play one track looped
- * SND_CD_RANDOM play all tracks in random order
- *
- * @param playmode playmode
- */
- virtual void SetCDPlaymode(int playmode) const =0;
-
- /**
- * set the volume playback of the cd
- *
- * @param gain the gain
- */
- virtual void SetCDGain(MT_Scalar gain) const =0;
-
- virtual void StartUsingDSP() =0;
- virtual float* GetSpectrum() =0;
- virtual void StopUsingDSP() =0;
-
-protected:
-
- virtual void RevokeSoundObject(SND_SoundObject* pObject)=0;
-};
-
-#endif //SND_IAUDIODEVICE
-
diff --git a/intern/SoundSystem/SND_Object.h b/intern/SoundSystem/SND_Object.h
deleted file mode 100644
index f23827974e3..00000000000
--- a/intern/SoundSystem/SND_Object.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * SND_Object.h
- *
- * Abstract sound object
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __SND_OBJECT_H
-#define __SND_OBJECT_H
-
-#include "GEN_List.h"
-#include "MT_Matrix3x3.h"
-#include "SoundDefines.h"
-
-/**
- * SND_Object is an interface class for soundobjects, listeners and other
- * kinds of sound related thingies.
- */
-
-class SND_Object : public GEN_Link
-{
-public:
- SND_Object() {};
- virtual ~SND_Object() {};
-};
-
-#endif //__SND_OBJECT_H
-
diff --git a/intern/SoundSystem/SND_Scene.h b/intern/SoundSystem/SND_Scene.h
deleted file mode 100644
index bb3ff932bce..00000000000
--- a/intern/SoundSystem/SND_Scene.h
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * SND_Scene.h
- *
- * The scene for sounds.
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifdef WIN32
-#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
-#endif //WIN32
-
-#ifndef __SND_SCENE_H
-#define __SND_SCENE_H
-
-#include "SoundDefines.h"
-#include "SND_SoundObject.h"
-#include "SND_CDObject.h"
-#include "SND_SoundListener.h"
-#include "SND_WaveSlot.h"
-
-#include "MT_Vector3.h"
-#include "MT_Matrix3x3.h"
-#include "STR_String.h"
-
-#include <set>
-
-
-class SND_Scene
-{
- std::set<class SND_SoundObject*> m_soundobjects;
-
- GEN_List m_activeobjects;
- class SND_IAudioDevice* m_audiodevice;
- class SND_WaveCache* m_wavecache;
- class SND_SoundListener m_listener;
- bool m_audio; // to check if audio works
- bool m_audioplayback; // to check if audioplayback is wanted
-
- void UpdateListener();
- void BuildActiveList(MT_Scalar curtime);
- void UpdateActiveObects();
- void UpdateCD();
-
-public:
- SND_Scene(SND_IAudioDevice* adi);
- ~SND_Scene();
-
- bool IsPlaybackWanted();
-
- void AddActiveObject(SND_SoundObject* pObject, MT_Scalar curtime);
- void RemoveActiveObject(SND_SoundObject* pObject);
- void DeleteObjectWhenFinished(SND_SoundObject* pObject);
-
- void Proceed();
-
- int LoadSample(const STR_String& samplename,
- void* memlocation,
- int size);
- void RemoveAllSamples();
- bool CheckBuffer(SND_SoundObject* pObject);
- bool IsSampleLoaded(STR_String& samplename);
-
- void AddObject(SND_SoundObject* pObject);
- bool SetCDObject(SND_CDObject* cdobject);
- void DeleteObject(SND_SoundObject* pObject);
- void RemoveAllObjects();
- void StopAllObjects();
- int GetObjectStatus(SND_SoundObject* pObject) const;
-
- void SetListenerTransform(const MT_Vector3& pos,
- const MT_Vector3& vel,
- const MT_Matrix3x3& mat);
-
- SND_SoundListener* GetListener();
-};
-
-#endif //__SND_SCENE_H
-
diff --git a/intern/SoundSystem/SND_SoundListener.h b/intern/SoundSystem/SND_SoundListener.h
deleted file mode 100644
index 2f6a6e8cddd..00000000000
--- a/intern/SoundSystem/SND_SoundListener.h
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * SND_SoundListener.h
- *
- * A SoundListener is for sound what a camera is for vision.
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __SND_SOUNDLISTENER_H
-#define __SND_SOUNDLISTENER_H
-
-#include "SND_Object.h"
-
-class SND_SoundListener : public SND_Object
-{
-public:
- SND_SoundListener();
- virtual ~SND_SoundListener();
-
- void SetStateFlag(unsigned int stateflags);
- void SetGain(MT_Scalar gain);
- void SetPosition(const MT_Vector3& pos);
- void SetVelocity(const MT_Vector3& vel);
- void SetOrientation(const MT_Matrix3x3& ori);
- void SetDopplerFactor(MT_Scalar dopplerfactor);
- void SetDopplerVelocity(MT_Scalar dopplervelocity);
- void SetScale(MT_Scalar scale);
-
- void SetModified(bool modified);
- bool IsModified() const;
-
- unsigned int GetStateFlags() const;
- MT_Scalar GetGain() const;
- MT_Vector3 GetPosition() const;
- MT_Vector3 GetVelocity() const;
- MT_Matrix3x3 GetOrientation();
-
- MT_Scalar GetDopplerFactor() const;
- MT_Scalar GetDopplerVelocity() const;
- MT_Scalar GetScale() const;
-
-private:
- void* m_listener;
- bool m_modified;
-
- MT_Scalar m_gain; /* overall gain */
- MT_Vector3 m_position; /* position; left/right, up/down, in/out */
- MT_Vector3 m_velocity; /* velocity of the listener */
- MT_Matrix3x3 m_orientation; /* orientation of the listener */
-
- MT_Scalar m_dopplerfactor; /* scaling factor for the Doppler (pitch) shift */
- MT_Scalar m_dopplervelocity; /* factor for the reference velocity (for Dopplereffect) */
- MT_Scalar m_scale;
-};
-
-#endif //__SND_SOUNDLISTENER_H
-
diff --git a/intern/SoundSystem/SND_SoundObject.h b/intern/SoundSystem/SND_SoundObject.h
deleted file mode 100644
index 7bd43fb4e66..00000000000
--- a/intern/SoundSystem/SND_SoundObject.h
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * SND_SoundObject.h
- *
- * Implementation of the abstract sound object
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __SND_SOUNDOBJECT_H
-#define __SND_SOUNDOBJECT_H
-
-#include "SND_Object.h"
-#include "STR_String.h"
-
-/**
- * SND_SoundObject is a class for api independent sounddata storage conected to an actuator
- */
-
-class SND_SoundObject : public SND_Object
-{
-private:
- STR_String m_samplename; /* name of the sample */
- STR_String m_objectname; /* name of the object */
- unsigned int m_buffer;
-
- bool m_active; /* is the object active or not? */
- int m_id;
- MT_Scalar m_lifespan; /* the lifespan of the sound seconds */
- MT_Scalar m_timestamp;
-
- MT_Scalar m_length; /* length of the sample in seconds */
-
- MT_Scalar m_gain; /* the gain of the object */
- MT_Scalar m_rollofffactor; /* the scaling factor to increase or decrease the range
- of a source by decreasing or increasing the
- attenuation, respectively */
- MT_Scalar m_referencedistance;/* the distance at which the listener will experience
- gain */
- MT_Scalar m_mingain; /* indicates the minimal gain which is always guaranteed
- for this source */
- MT_Scalar m_maxgain; /* indicates the maximal gain which is always guaranteed
- for this source */
-
- MT_Scalar m_pitch; /* the pitch of the object */
- MT_Vector3 m_position; /* position; left/right, up/down, in/out */
- MT_Vector3 m_velocity; /* velocity of the object */
- MT_Matrix3x3 m_orientation; /* orientation of the object */
- unsigned int m_loopmode; /* loop normal or bidirectional? */
- unsigned int m_loopstart; /* start of looppoint in samples! */
- unsigned int m_loopend; /* end of looppoint in samples! */
- bool m_is3d; /* is the object 3D or 2D? */
- int m_playstate; /* flag for current state of object */
- bool m_modified;
- unsigned int m_running;
- bool m_highpriority; /* may the sound be ditched when we run out of voices? */
-
-public:
-
- SND_SoundObject();
- ~SND_SoundObject();
-
- void SetBuffer(unsigned int buffer);
- void SetActive(bool active);
-
- void StartSound();
- void StopSound();
- void PauseSound();
- void DeleteWhenFinished();
-
- void SetObjectName(STR_String objectname);
- void SetSampleName(STR_String samplename);
- void SetLength(MT_Scalar length);
-
- void SetPitch(MT_Scalar pitch);
- void SetGain(MT_Scalar gain);
- void SetMinGain(MT_Scalar mingain);
- void SetMaxGain(MT_Scalar maxgain);
- void SetRollOffFactor(MT_Scalar rollofffactor);
- void SetReferenceDistance(MT_Scalar distance);
- void SetPosition(const MT_Vector3& pos);
- void SetVelocity(const MT_Vector3& vel);
- void SetOrientation(const MT_Matrix3x3& orient);
- void SetLoopMode(unsigned int loopmode);
- void SetLoopStart(unsigned int loopstart);
- void SetLoopEnd(unsigned int loopend);
- void Set3D(bool threedee);
- void SetPlaystate(int playstate);
- void SetHighPriority(bool priority);
-
- void SetId(int id);
- void SetLifeSpan();
- void SetTimeStamp(MT_Scalar timestamp);
-
- void SetModified(bool modified);
-
- bool IsLifeSpanOver(MT_Scalar curtime) const;
- bool IsActive() const;
- bool IsModified() const;
- bool IsHighPriority() const;
-
- void InitRunning();
- bool IsRunning() const;
- void AddRunning();
-
- int GetId() const;
- MT_Scalar GetLifeSpan() const;
- MT_Scalar GetTimestamp() const;
-
- unsigned int GetBuffer();
- const STR_String& GetSampleName();
- const STR_String& GetObjectName();
-
- MT_Scalar GetLength() const;
- MT_Scalar GetGain() const;
- MT_Scalar GetPitch() const;
-
- MT_Scalar GetMinGain() const;
- MT_Scalar GetMaxGain() const;
- MT_Scalar GetRollOffFactor() const;
- MT_Scalar GetReferenceDistance() const;
-
- MT_Vector3 GetPosition() const;
- MT_Vector3 GetVelocity() const;
- MT_Matrix3x3 GetOrientation() const;
- unsigned int GetLoopMode() const;
- unsigned int GetLoopStart() const;
- unsigned int GetLoopEnd() const;
- bool Is3D() const;
- int GetPlaystate() const;
-
-};
-
-#endif //__SND_SOUNDOBJECT_H
-
diff --git a/intern/SoundSystem/SND_Utils.h b/intern/SoundSystem/SND_Utils.h
deleted file mode 100644
index 82b7c69a595..00000000000
--- a/intern/SoundSystem/SND_Utils.h
+++ /dev/null
@@ -1,111 +0,0 @@
-/**
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef SND_UTILS_H
-#define SND_UTILS_H
-
-#include "SND_WaveSlot.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef struct
-{
- unsigned char riff[4];
- signed int size;
- unsigned char type[4];
-} WavFileHeader;
-
-typedef struct
-{
- unsigned short format;
- unsigned short numberofchannels;
- unsigned int samplerate;
- unsigned int bytespersec;
- unsigned short blockalignment;
- unsigned short bitrate;
-} WavFmtHeader;
-
-typedef struct
-{
- unsigned short size;
- unsigned short samplesperblock;
-} WavFmtExHeader;
-
-typedef struct
-{
- unsigned int Manufacturer;
- unsigned int Product;
- unsigned int SamplePeriod;
- unsigned int Note;
- unsigned int FineTune;
- unsigned int SMPTEFormat;
- unsigned int SMPTEOffest;
- unsigned int loops;
- unsigned int SamplerData;
- struct
- {
- unsigned int Identifier;
- unsigned int Type;
- unsigned int Start;
- unsigned int End;
- unsigned int Fraction;
- unsigned int Count;
- } Loop[1];
-} WavSampleHeader;
-
-typedef struct
-{
- unsigned char id[4];
- unsigned int size;
-} WavChunkHeader;
-
-/**
- * loads a sample and returns a pointer
- */
-extern void* SND_LoadSample(char *filename);
-
-extern bool SND_IsSampleValid(const STR_String& name, void* memlocation);
-extern unsigned int SND_GetSampleFormat(void* sample);
-extern unsigned int SND_GetNumberOfChannels(void* sample);
-extern unsigned int SND_GetSampleRate(void* sample);
-extern unsigned int SND_GetBitRate(void* sample);
-extern unsigned int SND_GetNumberOfSamples(void* sample, unsigned int sample_length);
-extern unsigned int SND_GetHeaderSize(void* sample, unsigned int sample_length);
-extern unsigned int SND_GetExtraChunk(void* sample);
-
-extern void SND_GetSampleInfo(signed char* sample, SND_WaveSlot* waveslot);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-
diff --git a/intern/SoundSystem/SND_WaveCache.h b/intern/SoundSystem/SND_WaveCache.h
deleted file mode 100644
index 2c457797768..00000000000
--- a/intern/SoundSystem/SND_WaveCache.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * SND_WaveCache.h
- *
- * abstract wavecache, a way to organize samples
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifdef WIN32
-#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
-#endif //WIN32
-
-#ifndef __SND_WAVECACHE_H
-#define __SND_WAVECACHE_H
-
-#include "SND_WaveSlot.h"
-#include "SoundDefines.h"
-#include "SND_SoundObject.h"
-#include <map>
-
-class SND_WaveCache
-{
-public:
- SND_WaveCache();
- virtual ~SND_WaveCache();
-
- SND_WaveSlot* GetWaveSlot(const STR_String& samplename);
-
- void RemoveAllSamples();
- void RemoveSample(const STR_String& samplename, int buffer);
-
-private:
- std::map<STR_String, SND_WaveSlot*> m_samplecache;
-
- SND_WaveSlot* m_bufferList[NUM_BUFFERS];
-
- void FreeSamples();
-};
-
-#endif //__SND_WAVECACHE_H
-
diff --git a/intern/SoundSystem/SND_WaveSlot.h b/intern/SoundSystem/SND_WaveSlot.h
deleted file mode 100644
index 75cddfa36d8..00000000000
--- a/intern/SoundSystem/SND_WaveSlot.h
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * SND_WaveSlot.cpp
- *
- * class for storing sample related information
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __SND_WAVESLOT_H
-#define __SND_WAVESLOT_H
-
-#include "STR_String.h"
-
-class SND_WaveSlot
-{
- STR_String m_samplename;
- bool m_loaded;
- void* m_data;
- unsigned int m_buffer;
- unsigned int m_sampleformat;
- unsigned int m_numberofchannels;
- unsigned int m_samplerate;
- unsigned int m_bitrate;
- unsigned int m_numberofsamples;
- unsigned int m_filesize;
-
-public:
-
- SND_WaveSlot(): m_loaded(false),
- m_data(NULL),
- m_buffer(0),
- m_sampleformat(0),
- m_numberofchannels(0),
- m_samplerate(0),
- m_bitrate(0),
- m_numberofsamples(0),
- m_filesize(0)
- {};
- ~SND_WaveSlot();
-
- void SetSampleName(STR_String samplename);
- void SetLoaded(bool loaded);
- void SetData(void* data);
- void SetBuffer(unsigned int buffer);
- void SetSampleFormat(unsigned int sampleformat);
- void SetNumberOfChannels(unsigned int numberofchannels);
- void SetSampleRate(unsigned int samplerate);
- void SetBitRate(unsigned int bitrate);
- void SetNumberOfSamples(unsigned int numberofsamples);
- void SetFileSize(unsigned int filesize);
-
-
- const STR_String& GetSampleName();
- bool IsLoaded() const;
- void* GetData();
- unsigned int GetBuffer() const;
- unsigned int GetSampleFormat() const;
- unsigned int GetNumberOfChannels() const;
- unsigned int GetSampleRate() const;
- unsigned int GetBitRate() const;
- unsigned int GetNumberOfSamples() const;
- unsigned int GetFileSize() const;
-
-};
-
-#endif //__SND_WAVESLOT_H
-
diff --git a/intern/SoundSystem/SND_test/Makefile b/intern/SoundSystem/SND_test/Makefile
deleted file mode 100644
index 279eeace0d8..00000000000
--- a/intern/SoundSystem/SND_test/Makefile
+++ /dev/null
@@ -1,48 +0,0 @@
-#
-# $Id$
-#
-# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-#
-# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
-# All rights reserved.
-#
-# The Original Code is: all of this file.
-#
-# Contributor(s): none yet.
-#
-# ***** END GPL LICENSE BLOCK *****
-#
-#
-
-LIBNAME = soundsystem
-DIR = $(OCGDIR)/intern/SoundSystem
-ALLTARGETS = $(OBJS) $(DIR)/$(DEBUG_DIR)SoundSystem
-
-include nan_compile.mk
-
-CPPFLAGS += $(NAN_LEVEL_1_WARNINGS)
-
-CPPFLAGS += -I$(NAN_MOTO)/include
-CPPFLAGS += -I.. -I../SND_BlenderWaveCache -I../SND_OpenAL
-
-TESTLIB = $(OCGDIR)/gameengine/OpenALSoundSystem/$(DEBUG_DIR)libOpenALSoundSystem.a
-TESTLIB += $(OCGDIR)/gameengine/BlenderWaveCache/$(DEBUG_DIR)libBlenderWaveCache.a
-TESTLIB += $(OCGDIR)/intern/SoundSystem/$(DEBUG_DIR)libsoundsystem.a
-TESTLIB += $(NAN_OPENAL)/lib/libopenal.a
-
-$(DIR)/$(DEBUG_DIR)SoundSystem: $(OBJS) $(TESTLIB)
- $(CC) $(LDFLAGS) -o $@ $(OBJS) $(TESTLIB) -lm -pthread -ldl -lstdc++
diff --git a/intern/SoundSystem/SND_test/SND_test.c b/intern/SoundSystem/SND_test/SND_test.c
deleted file mode 100644
index 0d19dc2e131..00000000000
--- a/intern/SoundSystem/SND_test/SND_test.c
+++ /dev/null
@@ -1,154 +0,0 @@
-/* SND_test.c nov 2000
-*
-* testfile for the SND module
-*
-* janco verduin
-*
-* $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
-*/
-
-#include "SND_C-api.h"
-#include "BlenderWaveCacheCApi.h"
-#include "OpenALC-Api.h"
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#if defined(WIN32)
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-#include <fcntl.h>
-
-static int buf[3];
-
-float oPos[3]={3.0, 0.0,-1.0};
-float oVel[3]={0.0, 0.0, 1.0};
-float oOri[6]={0.0, 0.0, 1.0, 0.0, 1.0, 0.0};
-
-void* ReadFile(char *filename)
-{
- int file, filelen;
- void *data = NULL;
-
-#if defined(WIN32)
- file = open(filename, O_BINARY|O_RDONLY);
-#else
- file = open(filename, 0|O_RDONLY);
-#endif
-
- if (file == -1) {
- printf("can't open file.\n");
- printf("press q for quit.\n");
-
- }
- else {
- filelen = lseek(file, 0, SEEK_END);
- lseek(file, 0, SEEK_SET);
-
- if (filelen != 0){
- data = malloc(filelen);
- if (read(file, data, filelen) != filelen) {
- free(data);
- data = NULL;
- }
- }
- close(file);
-
- }
- return (data);
-}
-
-int main(int argc, char* argv[])
-{
- int ch;
- char* samplename = NULL;
- void* sampleinmemory = NULL;
- SND_CacheHandle wavecache = NULL;
- SND_SceneHandle scene = NULL;
- SND_ObjectHandle object = NULL;
-
- wavecache = SND_GetWaveCache();
- scene = SND_CreateOpenALScene(wavecache);
-
- samplename = "2.wav";
- sampleinmemory = ReadFile(samplename);
-
- if (sampleinmemory) {
-
- object = SND_CreateObject();
- SND_AddMemoryLocation(samplename, sampleinmemory);
- SND_SetSampleName(object, samplename);
- SND_AddObject(scene, object);
- printf("go your gang...\n");
- printf("1: play\n");
- printf("2: stop\n");
- printf("q: quit\n");
- }
- do
- {
- ch = getchar();
- ch = toupper(ch);
- switch (ch)
- {
- case '1':
- {
- SND_SetPitch(object, 1.0);
- SND_SetGain(object, 1.0);
- SND_StartSound(object);
- break;
- }
- case '2':
- {
- SND_StopSound(object);
- break;
- }
- default:
- break;
- }
-
- SND_Proceed(scene);
-
- } while (ch != 'Q');
-
- if (object) {
-
- SND_RemoveObject(scene, object);
- SND_DeleteObject(object);
- }
-
- SND_DeleteScene(scene);
- SND_DeleteCache();
-
- return 0;
-
-}
diff --git a/intern/SoundSystem/SoundDefines.h b/intern/SoundSystem/SoundDefines.h
deleted file mode 100644
index 5238507c866..00000000000
--- a/intern/SoundSystem/SoundDefines.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
- * SoundDefines.h
- *
- * this is where all kinds of defines are stored
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __SOUNDDEFINES_H
-#define __SOUNDDEFINES_H
-
-/* the types of devices */
-enum
-{
- snd_e_dummydevice = 0,
- snd_e_openaldevice
-};
-
-/* general stuff */
-#define NUM_BUFFERS 128
-#define NUM_SOURCES 24 /* 24 is the limit for openal on windows, was 16 in 2.47 and previous */
-
-/* openal related stuff */
-#define AL_LOOPING 0x1007
-
-/* activelist defines */
-enum
-{
- SND_REMOVE_ACTIVE_OBJECT = 0,
- SND_ADD_ACTIVE_OBJECT,
- SND_DO_NOTHING
-};
-
-/* playstate flags */
-enum
-{
- SND_UNKNOWN = -1,
- SND_INITIAL,
- SND_MUST_PLAY,
- SND_PLAYING,
- SND_MUST_STOP,
- SND_STOPPED,
- SND_MUST_PAUSE,
- SND_PAUSED,
- SND_MUST_RESUME,
- SND_MUST_STOP_WHEN_FINISHED,
- SND_MUST_BE_DELETED
-};
-
-/* loopmodes */
-enum
-{
- SND_LOOP_OFF = 0,
- SND_LOOP_NORMAL,
- SND_LOOP_BIDIRECTIONAL
-};
-
-
-/* cd playstate flags */
-enum
-{
- SND_CD_ALL = 0,
- SND_CD_TRACK,
- SND_CD_TRACKLOOP
-};
-
-/* sample types */
-enum
-{
- SND_WAVE_FORMAT_UNKNOWN = 0,
- SND_WAVE_FORMAT_PCM,
- SND_WAVE_FORMAT_ADPCM,
- SND_WAVE_FORMAT_ALAW = 6,
- SND_WAVE_FORMAT_MULAW,
- SND_WAVE_FORMAT_DIALOGIC_OKI_ADPCM = 17,
- SND_WAVE_FORMAT_CONTROL_RES_VQLPC = 34,
- SND_WAVE_FORMAT_GSM_610 = 49,
- SND_WAVE_FORMAT_MPEG3 = 85
-};
-
-#endif //__SOUNDDEFINES_H
-
diff --git a/intern/SoundSystem/dummy/SND_DummyDevice.cpp b/intern/SoundSystem/dummy/SND_DummyDevice.cpp
deleted file mode 100644
index 672c73e9c52..00000000000
--- a/intern/SoundSystem/dummy/SND_DummyDevice.cpp
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- * SND_DummyDevice derived from SND_IAudioDevice
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef WIN32
-#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
-#endif //WIN32
-
-#include "SND_DummyDevice.h"
-
-SND_DummyDevice::SND_DummyDevice()
-{
-}
-
-SND_DummyDevice::~SND_DummyDevice()
-{
-#ifdef ONTKEVER
- printf("SND_DummyDevice destructor");
-#endif
-}
-
-
diff --git a/intern/SoundSystem/dummy/SND_DummyDevice.h b/intern/SoundSystem/dummy/SND_DummyDevice.h
deleted file mode 100644
index 988f731d1bf..00000000000
--- a/intern/SoundSystem/dummy/SND_DummyDevice.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/**
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef SND_DUMMYDEVICE
-#define SND_DUMMYDEVICE
-
-#include "SND_AudioDevice.h"
-
-class SND_DummyDevice : public SND_AudioDevice
-{
-public:
- SND_DummyDevice();
- ~SND_DummyDevice();
-
- bool Init() { return false; }
-
- SND_WaveSlot* LoadSample(const STR_String& samplename,
- void* memlocation,
- int size) { return NULL; }
-
- void InitListener() {};
- void SetListenerGain(float gain) const {};
- void SetDopplerVelocity(MT_Scalar dopplervelocity) const {};
- void SetDopplerFactor(MT_Scalar dopplerfactor) const {};
- void SetListenerRollOffFactor(MT_Scalar rollofffactor) const {};
-
- void MakeCurrent() const {};
-
- void NextFrame() const {};
-
- void SetObjectBuffer(int id, unsigned int buffer) {};
-
- int GetPlayState(int id) { return SND_UNKNOWN; }
- void PlayObject(int id) {};
- void StopObject(int id) const {};
- void StopAllObjects() {};
- void PauseObject(int id) const {};
-
- void SetObjectLoop(int id, unsigned int loopmode) const {};
- void SetObjectLoopPoints(int id, unsigned int loopstart, unsigned int loopend) const {};
- void SetObjectPitch(int id, MT_Scalar pitch) const {};
- void SetObjectGain(int id, MT_Scalar gain) const {};
- void SetObjectMinGain(int id, MT_Scalar mingain) const {};
- void SetObjectMaxGain(int id, MT_Scalar maxgain) const {};
- void SetObjectRollOffFactor(int id, MT_Scalar rolloff) const {};
- void SetObjectReferenceDistance(int id, MT_Scalar distance) const {};
-
- void SetObjectTransform(int id,
- const MT_Vector3& position,
- const MT_Vector3& velocity,
- const MT_Matrix3x3& orientation,
- const MT_Vector3& lisposition,
- const MT_Scalar& rollofffactor) const {};
- void ObjectIs2D(int id) const {};
-
- void PlayCD(int track) const {};
- void PauseCD(bool pause) const {};
- void StopCD() const {};
- void SetCDPlaymode(int playmode) const {};
- void SetCDGain(MT_Scalar gain) const {};
-
- void StartUsingDSP() {};
- float* GetSpectrum() { return NULL; }
- void StopUsingDSP() {};
-};
-
-#endif //SND_DUMMYDEVICE
-
diff --git a/intern/SoundSystem/intern/SND_AudioDevice.cpp b/intern/SoundSystem/intern/SND_AudioDevice.cpp
deleted file mode 100644
index 4a5c0e2c498..00000000000
--- a/intern/SoundSystem/intern/SND_AudioDevice.cpp
+++ /dev/null
@@ -1,242 +0,0 @@
-/**
- * $Id$
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "SND_AudioDevice.h"
-#include "SND_SoundObject.h"
-
-#ifdef WIN32
-// This warning tells us about truncation of __long__ stl-generated names.
-// It can occasionally cause DevStudio to have internal compiler warnings.
-#pragma warning( disable : 4786 )
-#endif
-
-
-SND_AudioDevice::SND_AudioDevice()
-{
- m_wavecache = NULL;
- m_audio = false;
-
- for (int i = 0; i < NUM_SOURCES; i++)
- {
- m_idObjectArray[i] = new SND_IdObject();
- m_idObjectArray[i]->SetId(i);
- m_idObjectArray[i]->SetSoundObject(NULL);
- m_idObjectList.addTail(m_idObjectArray[i]);
- }
-}
-
-
-
-SND_AudioDevice::~SND_AudioDevice()
-{
- for (int i = 0; i < NUM_SOURCES; i++)
- {
- delete m_idObjectArray[i];
- m_idObjectArray[i] = NULL;
- }
-
- if (m_wavecache)
- {
- delete m_wavecache;
- m_wavecache = NULL;
- }
-}
-
-
-
-bool SND_AudioDevice::IsInitialized()
-{
- return m_audio;
-}
-
-
-
-SND_WaveCache* SND_AudioDevice::GetWaveCache() const
-{
- return m_wavecache;
-}
-
-
-
-/* seeks an unused id and returns it */
-bool SND_AudioDevice::GetNewId(SND_SoundObject* pObject)
-{
-#ifdef ONTKEVER
- printf("SND_AudioDevice::GetNewId\n");
-#endif
-
- bool result = false;
-
- // first, get the oldest (the first) idobject
- SND_IdObject* pIdObject = (SND_IdObject*)m_idObjectList.getHead();
-
- if (pIdObject->isTail())
- {
- }
- else
- {
- // find the first id object which doesn't have a high priority soundobject
- bool ThisSoundMustStay = false;
- bool OutOfIds = false;
-
- do
- {
- // if no soundobject present, it's seat may be taken
- if (pIdObject->GetSoundObject())
- {
- // and also if it ain't highprio
- if (pIdObject->GetSoundObject()->IsHighPriority())
- {
- ThisSoundMustStay = true;
- pIdObject = (SND_IdObject*)pIdObject->getNext();
-
- // if the last one is a priority sound too, then there are no id's left
- // and we won't add any new sounds
- if (pIdObject->isTail())
- OutOfIds = true;
- }
- else
- {
- ThisSoundMustStay = false;
- }
- }
- else
- {
- ThisSoundMustStay = false;
- }
-
- } while (ThisSoundMustStay && !OutOfIds);
-
- if (!OutOfIds)
- {
- SND_SoundObject* oldobject = pIdObject->GetSoundObject();
-
- // revoke the old object if present
- if (oldobject)
- {
-#ifdef ONTKEVER
- printf("oldobject: %x\n", oldobject);
-#endif
- RevokeSoundObject(oldobject);
- }
-
- // set the new soundobject into the idobject
- pIdObject->SetSoundObject(pObject);
-
- // set the id into the soundobject
- int id = pIdObject->GetId();
- pObject->SetId(id);
-
- // connect the new id to the buffer the sample is stored in
- SetObjectBuffer(id, pObject->GetBuffer());
-
- // remove the idobject from the list and add it in the back again
- pIdObject->remove();
- m_idObjectList.addTail(pIdObject);
-
- result = true;
- }
- }
-
- return result;
-}
-
-
-
-void SND_AudioDevice::ClearId(SND_SoundObject* pObject)
-{
-#ifdef ONTKEVER
- printf("SND_AudioDevice::ClearId\n");
-#endif
-
- if (pObject)
- {
- int id = pObject->GetId();
-
- if (id != -1)
- {
- // lets get the idobject belonging to the soundobject
- SND_IdObject* pIdObject = m_idObjectArray[id];
- SND_SoundObject* oldobject = pIdObject->GetSoundObject();
-
- if (oldobject)
- {
- RevokeSoundObject(oldobject);
-
- // clear the idobject from the soundobject
- pIdObject->SetSoundObject(NULL);
- }
-
- // remove the idobject and place it in front
- pIdObject->remove();
- m_idObjectList.addHead(pIdObject);
- }
- }
-}
-
-
-
-void SND_AudioDevice::RevokeSoundObject(SND_SoundObject* pObject)
-{
-#ifdef ONTKEVER
- printf("SND_AudioDevice::RevokeSoundObject\n");
-#endif
-
- // stop the soundobject
- int id = pObject->GetId();
-
- if (id >= 0 && id < NUM_SOURCES)
- {
- StopObject(id);
-
- // remove the object from the 'activelist'
- pObject->SetActive(false);
-
-#ifdef ONTKEVER
- printf("pObject->remove();\n");
-#endif
- }
-
- // make sure its id is invalid
- pObject->SetId(-1);
-}
-
-/*
-void SND_AudioDevice::RemoveSample(const char* filename)
-{
- if (m_wavecache)
- m_wavecache->RemoveSample(filename);
-}
-*/
-
-void SND_AudioDevice::RemoveAllSamples()
-{
- if (m_wavecache)
- m_wavecache->RemoveAllSamples();
-}
-
diff --git a/intern/SoundSystem/intern/SND_AudioDevice.h b/intern/SoundSystem/intern/SND_AudioDevice.h
deleted file mode 100644
index 54e8feea90e..00000000000
--- a/intern/SoundSystem/intern/SND_AudioDevice.h
+++ /dev/null
@@ -1,115 +0,0 @@
-/**
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef SND_AUDIODEVICE
-#define SND_AUDIODEVICE
-
-#include "SND_IAudioDevice.h"
-#include "SoundDefines.h"
-#include "SND_IdObject.h"
-
-class SND_AudioDevice : public SND_IAudioDevice
-{
-public:
- SND_AudioDevice();
- virtual ~SND_AudioDevice();
-
- virtual bool IsInitialized();
-
- SND_WaveCache* GetWaveCache() const;
-
- bool GetNewId(SND_SoundObject* pObject);
- void ClearId(SND_SoundObject* pObject);
-
- void UseCD() const {};
-
- /* to be implemented in derived class
-
- virtual SND_WaveSlot* LoadSample(const STR_String& samplename,
- void* memlocation,
- int size) =0;
- */
-// void RemoveSample(const char* filename);
- void RemoveAllSamples();
-
- /* to be implemented in derived class
-
- virtual void InitListener()=0;
- virtual void SetListenerGain(float gain) const =0;
- virtual void SetDopplerVelocity(MT_Scalar dopplervelocity) const =0;
- virtual void SetDopplerFactor(MT_Scalar dopplerfactor) const =0;
- virtual void SetListenerRollOffFactor(MT_Scalar rollofffactor) const =0;
-
- virtual void MakeCurrent() const =0;
-
- virtual void UpdateDevice() const =0;
-
- virtual void SetObjectBuffer(int id, unsigned int buffer)=0;
- virtual int GetPlayState(int id)=0;
- virtual void PlayObject(int id)=0;
- virtual void StopObject(int id) const =0;
- virtual void StopAllObjects()=0;
- virtual void PauseObject(int id) const =0;
-
- virtual void SetObjectLoop(int id, bool loop) const =0;
- virtual void SetObjectLoopPoints(int id, unsigned int loopstart, unsigned int loopend) const =0;
- virtual void SetObjectPitch(int id, MT_Scalar pitch) const =0;
- virtual void SetObjectGain(int id, MT_Scalar gain) const =0;
- virtual void SetObjectRollOffFactor(int id, MT_Scalar rolloff) const =0;
- virtual void SetObjectMinGain(int id, MT_Scalar mingain) const =0;
- virtual void SetObjectMaxGain(int id, MT_Scalar maxgain) const =0;
- virtual void SetObjectReferenceDistance(int id, MT_Scalar referencedistance) const =0;
-
- virtual void SetObjectTransform(int id,
- const MT_Vector3& position,
- const MT_Vector3& velocity,
- const MT_Matrix3x3& orientation,
- const MT_Vector3& lisposition,
- const MT_Scalar& rollofffactor) const =0;
- virtual void ObjectIs2D(int id) const =0;
-
- virtual void PlayCD(int track) const =0;
- virtual void PauseCD(bool pause) const =0;
- virtual void StopCD() const =0;
- virtual void SetCDPlaymode(int playmode) const =0;
- virtual void SetCDGain(MT_Scalar gain) const =0;
- virtual float* GetSpectrum() =0;
- */
-
-protected:
- bool m_audio;
- GEN_List m_idObjectList;
- SND_IdObject* m_idObjectArray[NUM_SOURCES];
- SND_WaveCache* m_wavecache;
-
-private:
- void RevokeSoundObject(SND_SoundObject* pObject);
-};
-
-#endif //SND_AUDIODEVICE
-
diff --git a/intern/SoundSystem/intern/SND_C-api.cpp b/intern/SoundSystem/intern/SND_C-api.cpp
deleted file mode 100644
index 09846269dcc..00000000000
--- a/intern/SoundSystem/intern/SND_C-api.cpp
+++ /dev/null
@@ -1,392 +0,0 @@
-/*
- * SND_C-Api.cpp
- *
- * C Api for soundmodule
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "SND_C-api.h"
-#include "SND_DeviceManager.h"
-#include "SND_Scene.h"
-
-#ifdef WIN32
-#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
-#endif //WIN32
-
-
-
-void SND_SetDeviceType(int device_type)
-{
- SND_DeviceManager::SetDeviceType(device_type);
-}
-
-
-
-SND_AudioDeviceInterfaceHandle SND_GetAudioDevice()
-{
- SND_IAudioDevice* audiodevice = NULL;
-
- SND_DeviceManager::Subscribe();
- audiodevice = SND_DeviceManager::Instance();
-
- if (!audiodevice->IsInitialized())
- {
- SND_DeviceManager::SetDeviceType(snd_e_dummydevice);
- audiodevice = SND_DeviceManager::Instance();
- }
-
- return (SND_AudioDeviceInterfaceHandle)audiodevice;
-}
-
-
-
-void SND_ReleaseDevice()
-{
- SND_DeviceManager::Unsubscribe();
-}
-
-
-
-int SND_IsPlaybackWanted(SND_SceneHandle scene)
-{
- assert(scene);
- bool result = ((SND_Scene*)scene)->IsPlaybackWanted();
-
- return (int)result;
-}
-
-
-
-// create a scene
-SND_SceneHandle SND_CreateScene(SND_AudioDeviceInterfaceHandle audiodevice)
-{
- // initialize sound scene and object
- SND_Scene* scene = new SND_Scene((SND_IAudioDevice*)audiodevice);
-
- return (SND_SceneHandle)scene;
-}
-
-
-
-void SND_DeleteScene(SND_SceneHandle scene)
-{
- assert(scene);
- delete (SND_Scene*)scene;
-}
-
-
-
-int SND_AddSample(SND_SceneHandle scene,
- const char* filename,
- void* memlocation,
- int size)
-{
- assert(scene);
- assert(memlocation);
- int buffer = ((SND_Scene*)scene)->LoadSample(filename, memlocation, size);
-
- return buffer;
-}
-
-
-
-void SND_RemoveAllSamples(SND_SceneHandle scene)
-{
- assert(scene);
- ((SND_Scene*)scene)->RemoveAllSamples();
-}
-
-
-
-int SND_CheckBuffer(SND_SceneHandle scene, SND_ObjectHandle object)
-{
- assert(scene);
- assert(object);
- int result = (int)((SND_Scene*)scene)->CheckBuffer((SND_SoundObject*)object);
-
- return result;
-}
-
-
-
-void SND_AddSound(SND_SceneHandle scene, SND_ObjectHandle object)
-{
- assert(scene);
- assert(object);
- ((SND_Scene*)scene)->AddObject((SND_SoundObject *)object);
-}
-
-
-
-void SND_RemoveSound(SND_SceneHandle scene, SND_ObjectHandle object)
-{
- assert(scene);
- assert(object);
- ((SND_Scene*)scene)->DeleteObject((SND_SoundObject *)object);
-}
-
-
-
-void SND_RemoveAllSounds(SND_SceneHandle scene)
-{
- assert(scene);
- ((SND_Scene*)scene)->RemoveAllObjects();
-}
-
-
-
-void SND_StopAllSounds(SND_SceneHandle scene)
-{
- assert(scene);
- ((SND_Scene*)scene)->StopAllObjects();
-}
-
-
-
-void SND_Proceed(SND_AudioDeviceInterfaceHandle audiodevice, SND_SceneHandle scene)
-{
- assert(scene);
- ((SND_Scene*)scene)->Proceed();
- ((SND_IAudioDevice*)audiodevice)->NextFrame();
-}
-
-
-
-SND_ListenerHandle SND_GetListener(SND_SceneHandle scene)
-{
- assert(scene);
- return (SND_ListenerHandle)((SND_Scene*)scene)->GetListener();
-}
-
-
-
-void SND_SetListenerGain(SND_SceneHandle scene, double gain)
-{
- assert(scene);
- SND_SoundListener* listener = ((SND_Scene*)scene)->GetListener();
- listener->SetGain((MT_Scalar)gain);
-}
-
-
-
-void SND_SetDopplerFactor(SND_SceneHandle scene, double dopplerfactor)
-{
- assert(scene);
- SND_SoundListener* listener = ((SND_Scene*)scene)->GetListener();
- listener->SetDopplerFactor(dopplerfactor);
-}
-
-
-
-void SND_SetDopplerVelocity(SND_SceneHandle scene, double dopplervelocity)
-{
- assert(scene);
- SND_SoundListener* listener = ((SND_Scene*)scene)->GetListener();
- listener->SetDopplerVelocity(dopplervelocity);
-}
-
-
-
-// Object instantiation
-SND_ObjectHandle SND_CreateSound()
-{
- return (SND_ObjectHandle)new SND_SoundObject();
-}
-
-
-
-void SND_DeleteSound(SND_ObjectHandle object)
-{
- assert(object);
- delete (SND_SoundObject*)object;
-}
-
-
-
-// Object control
-void SND_StartSound(SND_SceneHandle scene, SND_ObjectHandle object)
-{
- assert(scene);
- assert(object);
- ((SND_Scene*)scene)->AddActiveObject((SND_SoundObject*)object, 0);
-}
-
-
-
-void SND_StopSound(SND_SceneHandle scene, SND_ObjectHandle object)
-{
- assert(scene);
- assert(object);
- ((SND_Scene*)scene)->RemoveActiveObject((SND_SoundObject*)object);
-}
-
-
-
-void SND_PauseSound(SND_SceneHandle scene, SND_ObjectHandle object)
-{
- assert(scene);
- assert(object);
- ((SND_Scene*)scene)->RemoveActiveObject((SND_SoundObject*)object);
-}
-
-
-
-void SND_SetSampleName(SND_ObjectHandle object, char* samplename)
-{
- assert(object);
- STR_String name = samplename;
- ((SND_SoundObject*)object)->SetSampleName(name);
-}
-
-
-
-void SND_SetGain(SND_ObjectHandle object, double gain)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetGain(gain);
-}
-
-
-
-void SND_SetMinimumGain(SND_ObjectHandle object, double minimumgain)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetMinGain(minimumgain);
-}
-
-
-
-void SND_SetMaximumGain(SND_ObjectHandle object, double maximumgain)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetMaxGain(maximumgain);
-}
-
-
-
-void SND_SetRollOffFactor(SND_ObjectHandle object, double rollofffactor)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetRollOffFactor(rollofffactor);
-}
-
-
-
-void SND_SetReferenceDistance(SND_ObjectHandle object, double referencedistance)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetReferenceDistance(referencedistance);
-}
-
-
-
-void SND_SetPitch(SND_ObjectHandle object, double pitch)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetPitch(pitch);
-}
-
-
-
-void SND_SetPosition(SND_ObjectHandle object, double* position)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetPosition(position);
-}
-
-
-
-void SND_SetVelocity(SND_ObjectHandle object, double* velocity)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetVelocity(velocity);
-}
-
-
-
-void SND_SetOrientation(SND_ObjectHandle object, double* orientation)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetOrientation(orientation);
-}
-
-
-
-void SND_SetLoopMode(SND_ObjectHandle object, int loopmode)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetLoopMode(loopmode);
-}
-
-
-
-void SND_SetLoopPoints(SND_ObjectHandle object, unsigned int loopstart, unsigned int loopend)
-{
- assert(object);
- ((SND_SoundObject*)object)->SetLoopStart(loopstart);
- ((SND_SoundObject*)object)->SetLoopEnd(loopend);
-}
-
-
-
-float SND_GetGain(SND_ObjectHandle object)
-{
- assert(object);
- MT_Scalar gain = ((SND_SoundObject*)object)->GetGain();
- return (float) gain;
-}
-
-
-
-float SND_GetPitch(SND_ObjectHandle object)
-{
- assert(object);
- MT_Scalar pitch = ((SND_SoundObject*)object)->GetPitch();
- return (float) pitch;
-}
-
-
-
-int SND_GetLoopMode(SND_ObjectHandle object)
-{
- assert(object);
- return ((SND_SoundObject*)object)->GetLoopMode();
-}
-
-
-
-int SND_GetPlaystate(SND_ObjectHandle object)
-{
- assert(object);
- return ((SND_SoundObject*)object)->GetPlaystate();
-}
diff --git a/intern/SoundSystem/intern/SND_CDObject.cpp b/intern/SoundSystem/intern/SND_CDObject.cpp
deleted file mode 100644
index 089e0d554e4..00000000000
--- a/intern/SoundSystem/intern/SND_CDObject.cpp
+++ /dev/null
@@ -1,182 +0,0 @@
-/*
- * SND_CDObject.cpp
- *
- * Implementation for CD playback
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "SND_CDObject.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-SND_CDObject* SND_CDObject::m_instance = NULL;
-
-bool SND_CDObject::CreateSystem()
-{
- bool result = false;
-
- if (!m_instance)
- {
- m_instance = new SND_CDObject();
- result = true;
- }
-
- return result;
-}
-
-
-
-bool SND_CDObject::DisposeSystem()
-{
- bool result = false;
-
- if (m_instance)
- {
- delete m_instance;
- m_instance = NULL;
- result = true;
- }
-
- return result;
-}
-
-
-
-SND_CDObject* SND_CDObject::Instance()
-{
- return m_instance;
-}
-
-
-
-SND_CDObject::SND_CDObject()
-{
- m_gain = 1;
- m_playmode = SND_CD_ALL;
- m_track = 1;
- m_playstate = SND_STOPPED;
- m_used = false;
-
- // don't set the cd standard on modified:
- // if not used, we don't wanna touch it (performance)
- m_modified = false;
-}
-
-
-
-SND_CDObject::~SND_CDObject()
-{
-}
-
-
-
-void SND_CDObject::SetGain(MT_Scalar gain)
-{
- m_gain = gain;
- m_modified = true;
-}
-
-
-
-void SND_CDObject::SetPlaymode(int playmode)
-{
- m_playmode = playmode;
-}
-
-
-
-void SND_CDObject::SetPlaystate(int playstate)
-{
- m_playstate = playstate;
-}
-
-
-
-void SND_CDObject::SetTrack(int track)
-{
- m_track = track;
-}
-
-
-
-int SND_CDObject::GetTrack() const
-{
- return m_track;
-}
-
-
-
-MT_Scalar SND_CDObject::GetGain() const
-{
- return m_gain;
-}
-
-
-int SND_CDObject::GetPlaystate() const
-{
- return m_playstate;
-}
-
-
-
-bool SND_CDObject::IsModified() const
-{
- return m_modified;
-}
-
-
-
-void SND_CDObject::SetModified(bool modified)
-{
- m_modified = modified;
-}
-
-
-
-int SND_CDObject::GetPlaymode() const
-{
- return m_playmode;
-}
-
-
-
-void SND_CDObject::SetUsed()
-{
- m_used = true;
-}
-
-
-
-bool SND_CDObject::GetUsed()
-{
- return m_used;
-}
-
diff --git a/intern/SoundSystem/intern/SND_DeviceManager.cpp b/intern/SoundSystem/intern/SND_DeviceManager.cpp
deleted file mode 100644
index c4bc887dffe..00000000000
--- a/intern/SoundSystem/intern/SND_DeviceManager.cpp
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * SND_DeviceManager.h
- *
- * singleton for creating, switching and deleting audiodevices
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include "SND_DeviceManager.h"
-#include "SND_DependKludge.h"
-#include "SND_DummyDevice.h"
-#ifdef USE_OPENAL
-#include "SND_OpenALDevice.h"
-#endif
-
-SND_IAudioDevice* SND_DeviceManager::m_instance = NULL;
-int SND_DeviceManager::m_subscriptions = 0;
-
-#ifdef USE_OPENAL
-int SND_DeviceManager::m_device_type = snd_e_openaldevice;
-#else
-int SND_DeviceManager::m_device_type = snd_e_dummydevice;
-#endif
-
-void SND_DeviceManager::Subscribe()
-{
- ++m_subscriptions;
-}
-
-
-
-void SND_DeviceManager::Unsubscribe()
-{
- --m_subscriptions;
-
- // only release memory if there is a m_instance but no subscriptions left
- if (m_subscriptions == 0 && m_instance)
- {
- delete m_instance;
- m_instance = NULL;
- }
-
- if (m_subscriptions < 0)
- m_subscriptions = 0;
-}
-
-
-
-SND_IAudioDevice* SND_DeviceManager::Instance()
-{
- // only give away an instance if there are subscriptions
- if (m_subscriptions)
- {
- // if there's no instance yet, set and create a new one
- if (m_instance == NULL)
- {
- SetDeviceType(m_device_type);
- }
-
- return m_instance;
- }
- else
- {
- return NULL;
- }
-}
-
-
-
-void SND_DeviceManager::SetDeviceType(int device_type)
-{
- // if we want to change devicetype, first delete the old one
- if (m_instance)
- {
- delete m_instance;
- m_instance = NULL;
- }
-
- // let's create the chosen device
- switch (device_type)
- {
-#ifdef USE_OPENAL
- case snd_e_openaldevice:
- {
- m_instance = new SND_OpenALDevice();
- m_device_type = device_type;
- break;
- }
-#endif
- default:
- {
- m_instance = new SND_DummyDevice();
- m_device_type = device_type;
- break;
- }
- }
-}
diff --git a/intern/SoundSystem/intern/SND_IdObject.cpp b/intern/SoundSystem/intern/SND_IdObject.cpp
deleted file mode 100644
index b261442db0a..00000000000
--- a/intern/SoundSystem/intern/SND_IdObject.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * SND_IdObject.cpp
- *
- * Object for storing runtime data, like id's, soundobjects etc
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "SND_IdObject.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-SND_IdObject::SND_IdObject()
-{
-}
-
-
-
-SND_IdObject::~SND_IdObject()
-{
-}
-
-
-
-SND_SoundObject* SND_IdObject::GetSoundObject()
-{
- return m_soundObject;
-}
-
-
-
-void SND_IdObject::SetSoundObject(SND_SoundObject* pObject)
-{
- m_soundObject = pObject;
-}
-
-
-
-int SND_IdObject::GetId()
-{
- return m_id;
-}
-
-
-
-void SND_IdObject::SetId(int id)
-{
- m_id = id;
-}
diff --git a/intern/SoundSystem/intern/SND_IdObject.h b/intern/SoundSystem/intern/SND_IdObject.h
deleted file mode 100644
index 86611b026f0..00000000000
--- a/intern/SoundSystem/intern/SND_IdObject.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * SND_IdObject.h
- *
- * Object for storing runtime data, like id's, soundobjects etc
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifndef __SND_IDOBJECT_H
-#define __SND_IDOBJECT_H
-
-#include "SND_SoundObject.h"
-#include "GEN_List.h"
-#include "SoundDefines.h"
-
-class SND_IdObject : public GEN_Link
-{
- SND_SoundObject* m_soundObject;
- int m_id;
-
-public:
- SND_IdObject();
- virtual ~SND_IdObject();
-
- SND_SoundObject* GetSoundObject();
- void SetSoundObject(SND_SoundObject* pObject);
-
- int GetId();
- void SetId(int id);
-};
-
-#endif //__SND_OBJECT_H
-
diff --git a/intern/SoundSystem/intern/SND_Scene.cpp b/intern/SoundSystem/intern/SND_Scene.cpp
deleted file mode 100644
index af1b43a08aa..00000000000
--- a/intern/SoundSystem/intern/SND_Scene.cpp
+++ /dev/null
@@ -1,544 +0,0 @@
-/*
-* SND_Scene.cpp
-*
-* The scene for sounds.
-*
-* $Id$
-*
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
-*/
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef WIN32
-#pragma warning (disable:4786) // Get rid of stupid stl-visual compiler debug warning
-#endif //WIN32
-
-#include "SND_Scene.h"
-#include "SND_DependKludge.h"
-#include "SND_IAudioDevice.h"
-
-#include <stdlib.h>
-#include <iostream>
-
-//static unsigned int tijd = 0;
-
-SND_Scene::SND_Scene(SND_IAudioDevice* audiodevice)
- : m_audiodevice(audiodevice)
-{
- if (m_audiodevice)
- m_wavecache = m_audiodevice->GetWaveCache();
-
- if (!m_wavecache || !audiodevice)
- {
- m_audio = false;
- }
- else
- {
- //if so, go ahead!
- m_audio = true;
-#ifdef ONTKEVER
- printf("SND_Scene::SND_Scene() m_audio == true\n");
-#endif
- m_audiodevice->InitListener();
- }
-
- IsPlaybackWanted();
-}
-
-
-
-SND_Scene::~SND_Scene()
-{
- StopAllObjects();
-}
-
-
-
-// check if audioplayback is wanted
-bool SND_Scene::IsPlaybackWanted()
-{
- /* Removed the functionality for checking if noaudio was provided on */
- /* the commandline. */
- if (m_audiodevice && m_wavecache)
- {
- m_audioplayback = true;
- }
- else
- {
- StopAllObjects();
- m_audioplayback = false;
- }
-
- return m_audioplayback;
-}
-
-
-
-int SND_Scene::LoadSample(const STR_String& samplename,
- void* memlocation,
- int size)
-{
- int result = -1;
-
- if (m_audiodevice)
- {
- SND_WaveSlot* waveslot = m_audiodevice->LoadSample(samplename, memlocation, size);
-
- if (waveslot)
- result = waveslot->GetBuffer();
- }
-
- return result;
-}
-
-
-
-void SND_Scene::RemoveAllSamples()
-{
- if (m_audio && m_audiodevice)
- m_audiodevice->RemoveAllSamples();
-}
-
-
-
-bool SND_Scene::CheckBuffer(SND_SoundObject* pObject)
-{
- bool result = false;
-
- if (pObject && m_wavecache)
- {
- SND_WaveSlot* waveslot = m_wavecache->GetWaveSlot(pObject->GetSampleName());
-
- if (waveslot)
- {
- pObject->SetBuffer(waveslot->GetBuffer());
-
- result = true;
- }
- }
-
- return result;
-}
-
-
-
-bool SND_Scene::IsSampleLoaded(STR_String& samplename)
-{
- bool result = false;
-
- if (samplename && m_wavecache)
- {
- SND_WaveSlot* waveslot = m_wavecache->GetWaveSlot(samplename);
-
- if (waveslot && waveslot->IsLoaded())
- result = true;
- }
-
- return result;
-}
-
-
-
-void SND_Scene::AddObject(SND_SoundObject* pObject)
-{
- if (m_audio)
- {
- STR_String samplename = pObject->GetSampleName();
- SND_WaveSlot* slot = NULL;
-
- // don't add the object if no valid sample is referenced
- if (samplename != "")
- {
- // check if the sample is already loaded
- slot = m_wavecache->GetWaveSlot(samplename);
- }
-
- if (slot)
- {
- pObject->SetBuffer(slot->GetBuffer());
-
- // needed for expected lifespan of the sample, but ain't necesary anymore i think
- MT_Scalar samplelength = slot->GetNumberOfSamples();
- MT_Scalar samplerate = slot->GetSampleRate();
- MT_Scalar soundlength = samplelength/samplerate;
- pObject->SetLength(soundlength);
-
- // add the object to the list
- m_soundobjects.insert((SND_SoundObject*)pObject);
- }
- }
-}
-
-
-
-void SND_Scene::SetListenerTransform(const MT_Vector3& pos,
- const MT_Vector3& vel,
- const MT_Matrix3x3& ori)
-{
- if (m_audio)
- {
- GetListener()->SetPosition(pos);
- GetListener()->SetVelocity(vel);
- GetListener()->SetOrientation(ori);
- }
-}
-
-
-
-void SND_Scene::UpdateListener()
-{
- // process the listener if modified
- if (m_listener.IsModified())
- {
- m_audiodevice->SetListenerGain(m_listener.GetGain());
- m_audiodevice->SetDopplerVelocity(m_listener.GetDopplerVelocity());
- m_audiodevice->SetDopplerFactor(m_listener.GetDopplerFactor());
- m_listener.SetModified(false);
- }
-}
-
-
-
-void SND_Scene::AddActiveObject(SND_SoundObject* pObject, MT_Scalar curtime)
-{
- if (m_audio)
- {
- if (pObject)
- {
-#ifdef ONTKEVER
- printf("SND_Scene::AddActiveObject\n");
-#endif
-
- // first check if the object is already on the list
- if (pObject->IsActive())
- {
- pObject->SetTimeStamp(curtime);
- pObject->StartSound();
- }
- else
- {
- pObject->SetTimeStamp(curtime);
-
- // compute the expected lifespan
- pObject->SetLifeSpan();
-
- // lets give the new active-to-be object an id
- if (m_audiodevice->GetNewId(pObject))
- {
- // and add the object
- m_activeobjects.addTail(pObject);
- pObject->StartSound();
- pObject->SetActive(true);
- }
- }
- }
- }
-}
-
-
-
-void SND_Scene::RemoveActiveObject(SND_SoundObject* pObject)
-{
- if (m_audio)
- {
- if (pObject)
- {
-#ifdef ONTKEVER
- printf("SND_Scene::RemoveActiveObject\n");
-#endif
- // if inactive, remove it from the list
- if (pObject->IsActive())
- {
- // first make sure it is stopped
- m_audiodevice->ClearId(pObject);
- }
- }
- }
-}
-
-
-
-void SND_Scene::UpdateActiveObects()
-{
-// ++tijd;
-
- SND_SoundObject* pObject;
- // update only the objects that need to be updated
- for (pObject = (SND_SoundObject*)m_activeobjects.getHead();
- !pObject->isTail();
- pObject = (SND_SoundObject*)pObject->getNext())
- {
- int id = pObject->GetId();
-
- if (id >= 0)
- {
- if (pObject->Is3D())
- {
- // Get the global positions and velocity vectors
- // of the listener and soundobject
- MT_Vector3 op = pObject->GetPosition();
- MT_Vector3 lp = m_listener.GetPosition();
- MT_Vector3 position = op - lp;
-
- // Calculate relative velocity in global coordinates
- // of the sound with respect to the listener.
- MT_Vector3 ov = pObject->GetVelocity();
- MT_Vector3 lv = m_listener.GetVelocity();
- MT_Vector3 velocity = ov - lv;
-
- // Now map the object position and velocity into
- // the local coordinates of the listener.
- MT_Matrix3x3 lo = m_listener.GetOrientation();
-
- MT_Vector3 local_sound_pos = position * lo;
- MT_Vector3 local_sound_vel = velocity * lo;
-
- m_audiodevice->SetObjectTransform(
- id,
- local_sound_pos,
- local_sound_vel,
- pObject->GetOrientation(), // make relative to listener!
- lp,
- pObject->GetRollOffFactor());
- }
- else
- {
- m_audiodevice->ObjectIs2D(id);
- }
-
- // update the situation
- if (pObject->IsModified())
- {
- m_audiodevice->SetObjectPitch(id, pObject->GetPitch());
- m_audiodevice->SetObjectGain(id, pObject->GetGain());
- m_audiodevice->SetObjectMinGain(id, pObject->GetMinGain());
- m_audiodevice->SetObjectMaxGain(id, pObject->GetMaxGain());
- m_audiodevice->SetObjectReferenceDistance(id, pObject->GetReferenceDistance());
- m_audiodevice->SetObjectRollOffFactor(id, pObject->GetRollOffFactor());
- m_audiodevice->SetObjectLoop(id, pObject->GetLoopMode());
- m_audiodevice->SetObjectLoopPoints(id, pObject->GetLoopStart(), pObject->GetLoopEnd());
- pObject->SetModified(false);
- }
-
- pObject->AddRunning();
-
-#ifdef ONTKEVER
- STR_String naam = pObject->GetObjectName();
- STR_String sample = pObject->GetSampleName();
-
- int id = pObject->GetId();
- int buffer = pObject->GetBuffer();
-
- float gain = pObject->GetGain();
- float pitch = pObject->GetPitch();
- float timestamp = pObject->GetTimestamp();
-
- printf("naam: %s, sample: %s \n", naam.Ptr(), sample.Ptr());
- printf("id: %d, buffer: %d \n", id, buffer);
- printf("gain: %f, pitch: %f, ts: %f \n\n", gain, pitch, timestamp);
-#endif
-#ifdef USE_OPENAL
- // ok, properties Set. now see if it must play
- switch (pObject->GetPlaystate()){
- case SND_MUST_PLAY:
- m_audiodevice->PlayObject(id);
- pObject->SetPlaystate(SND_PLAYING);
- break;
- case SND_MUST_STOP:
- RemoveActiveObject(pObject);
- break;
- case SND_MUST_PAUSE:
- m_audiodevice->PauseObject(id);
- pObject->SetPlaystate(SND_PAUSED);
- break;
- }
-#endif
-
- // check to see if the sound is still playing
- // if not: release its id
- int playstate = m_audiodevice->GetPlayState(id);
-#ifdef ONTKEVER
- if (playstate != 2)
- printf("%d - ",playstate);
-#endif
-
- if ((playstate == SND_STOPPED) && !pObject->GetLoopMode())
- {
- RemoveActiveObject(pObject);
- }
- }
- }
-}
-
-
-
-void SND_Scene::UpdateCD()
-{
- if (m_audiodevice)
- {
- SND_CDObject* pCD = SND_CDObject::Instance();
-
- if (pCD)
- {
- int playstate = pCD->GetPlaystate();
-
- switch (playstate)
- {
- case SND_MUST_PLAY:
- {
- // initialize the cd only when you need it
- m_audiodevice->SetCDGain(pCD->GetGain());
- m_audiodevice->SetCDPlaymode(pCD->GetPlaymode());
- m_audiodevice->PlayCD(pCD->GetTrack());
- pCD->SetPlaystate(SND_PLAYING);
- pCD->SetUsed();
- break;
- }
- case SND_MUST_PAUSE:
- {
- m_audiodevice->PauseCD(true);
- pCD->SetPlaystate(SND_PAUSED);
- break;
- }
- case SND_MUST_RESUME:
- {
- m_audiodevice->PauseCD(false);
- pCD->SetPlaystate(SND_PLAYING);
- break;
- }
- case SND_MUST_STOP:
- {
- m_audiodevice->StopCD();
- pCD->SetPlaystate(SND_STOPPED);
- break;
- }
- default:
- {
- }
- }
-
- // this one is only for realtime modifying settings
- if (pCD->IsModified())
- {
- m_audiodevice->SetCDGain(pCD->GetGain());
- pCD->SetModified(false);
- }
- }
- }
-}
-
-
-
-void SND_Scene::Proceed()
-{
- if (m_audio && m_audioplayback)
- {
- m_audiodevice->MakeCurrent();
-
- UpdateListener();
- UpdateActiveObects();
- UpdateCD();
-
-// m_audiodevice->UpdateDevice();
- }
-}
-
-
-void SND_Scene::DeleteObject(SND_SoundObject* pObject)
-{
-#ifdef ONTKEVER
- printf("SND_Scene::DeleteObject\n");
-#endif
-
- if (pObject)
- {
- if (m_audiodevice)
- m_audiodevice->ClearId(pObject);
-
- // must remove object from m_activeList
- std::set<SND_SoundObject*>::iterator set_it;
- set_it = m_soundobjects.find(pObject);
-
- if (set_it != m_soundobjects.end())
- m_soundobjects.erase(set_it);
-
- // release the memory
- delete pObject;
- pObject = NULL;
- }
-}
-
-
-
-void SND_Scene::RemoveAllObjects()
-{
-#ifdef ONTKEVER
- printf("SND_Scene::RemoveAllObjects\n");
-#endif
-
- StopAllObjects();
-
- std::set<SND_SoundObject*>::iterator it = m_soundobjects.begin();
-
- while (it != m_soundobjects.end())
- {
- delete (*it);
- it++;
- }
-
- m_soundobjects.clear();
-}
-
-
-
-void SND_Scene::StopAllObjects()
-{
- if (m_audio)
- {
-#ifdef ONTKEVER
- printf("SND_Scene::StopAllObjects\n");
-#endif
-
- SND_SoundObject* pObject;
-
- for (pObject = (SND_SoundObject*)m_activeobjects.getHead();
- !pObject->isTail();
- pObject = (SND_SoundObject*)pObject->getNext())
- {
- m_audiodevice->ClearId(pObject);
- }
- }
-}
-
-
-
-SND_SoundListener* SND_Scene::GetListener()
-{
- return &m_listener;
-}
diff --git a/intern/SoundSystem/intern/SND_SoundListener.cpp b/intern/SoundSystem/intern/SND_SoundListener.cpp
deleted file mode 100644
index 26163e87765..00000000000
--- a/intern/SoundSystem/intern/SND_SoundListener.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * SND_SoundListener.cpp
- *
- * A SoundListener is for sound what a camera is for vision.
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "SND_SoundListener.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-SND_SoundListener::SND_SoundListener()
-{
- m_modified = true;
- m_gain = 1.0;
- m_dopplerfactor = 1.0;
- m_dopplervelocity = 1.0;
- m_scale = 1.0;
- m_position[0] = 0.0;
- m_position[1] = 0.0;
- m_position[2] = 0.0;
- m_velocity[0] = 0.0;
- m_velocity[1] = 0.0;
- m_velocity[2] = 0.0;
- m_orientation[0][0] = 1.0;
- m_orientation[0][1] = 0.0;
- m_orientation[0][2] = 0.0;
- m_orientation[1][0] = 0.0;
- m_orientation[1][1] = 1.0;
- m_orientation[1][2] = 0.0;
- m_orientation[2][0] = 0.0;
- m_orientation[2][1] = 0.0;
- m_orientation[2][2] = 1.0;
-}
-
-
-SND_SoundListener::~SND_SoundListener()
-{
- ; /* intentionally empty */
-
-}
-
-
-
-void SND_SoundListener::SetGain(MT_Scalar gain)
-{
- m_gain = gain;
- m_modified = true;
-}
-
-
-
-void SND_SoundListener::SetPosition (const MT_Vector3& pos)
-{
- m_position = pos;
-}
-
-
-
-void SND_SoundListener::SetVelocity(const MT_Vector3& vel)
-{
- m_velocity = vel;
-}
-
-
-
-void SND_SoundListener::SetOrientation(const MT_Matrix3x3& ori)
-{
- m_orientation = ori;
-}
-
-
-
-void SND_SoundListener::SetDopplerFactor(MT_Scalar dopplerfactor)
-{
- m_dopplerfactor = dopplerfactor;
- m_modified = true;
-}
-
-
-
-void SND_SoundListener::SetDopplerVelocity(MT_Scalar dopplervelocity)
-{
- m_dopplervelocity = dopplervelocity;
- m_modified = true;
-}
-
-
-
-void SND_SoundListener::SetScale(MT_Scalar scale)
-{
- m_scale = scale;
- m_modified = true;
-}
-
-
-
-MT_Scalar SND_SoundListener::GetGain() const
-{
- return m_gain;
-}
-
-
-
-MT_Vector3 SND_SoundListener::GetPosition() const
-{
- return m_position;
-}
-
-
-
-MT_Vector3 SND_SoundListener::GetVelocity() const
-{
- return m_velocity;
-}
-
-
-
-MT_Matrix3x3 SND_SoundListener::GetOrientation()
-{
- return m_orientation;
-}
-
-
-
-MT_Scalar SND_SoundListener::GetDopplerFactor() const
-{
- return m_dopplerfactor;
-}
-
-
-
-MT_Scalar SND_SoundListener::GetDopplerVelocity() const
-{
- return m_dopplervelocity;
-}
-
-
-
-MT_Scalar SND_SoundListener::GetScale() const
-{
- return m_scale;
-}
-
-
-
-bool SND_SoundListener::IsModified() const
-{
- return m_modified;
-}
-
-
-
-void SND_SoundListener::SetModified(bool modified)
-{
- m_modified = modified;
-}
diff --git a/intern/SoundSystem/intern/SND_SoundObject.cpp b/intern/SoundSystem/intern/SND_SoundObject.cpp
deleted file mode 100644
index 7a244b5090d..00000000000
--- a/intern/SoundSystem/intern/SND_SoundObject.cpp
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- * SND_SoundObject.cpp
- *
- * Implementation of the abstract sound object
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "SND_SoundObject.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-SND_SoundObject::SND_SoundObject()// : m_modified(true)
-{
- m_samplename = "";
- m_length = 0;
- m_buffer = 0;
-
- m_gain = 0.0;
- m_pitch = 1.0;
-
- m_mingain = 0.0;
- m_maxgain = 1.0;
- m_rollofffactor = 1.0;
- m_referencedistance = 1.0;
-
- m_position[0] = 0.0;
- m_position[1] = 0.0;
- m_position[2] = 0.0;
- m_velocity[0] = 0.0;
- m_velocity[1] = 0.0;
- m_velocity[2] = 0.0;
- m_orientation[0][0] = 1.0;
- m_orientation[0][1] = 0.0;
- m_orientation[0][2] = 0.0;
- m_orientation[1][0] = 0.0;
- m_orientation[1][1] = 1.0;
- m_orientation[1][2] = 0.0;
- m_orientation[2][0] = 0.0;
- m_orientation[2][1] = 0.0;
- m_orientation[2][2] = 1.0;
-
- m_loopstart = 0;
- m_loopend = 0;
- m_loopmode = SND_LOOP_NORMAL;
- m_is3d = true;
- m_playstate = SND_INITIAL;
- m_active = false;
- m_id = -1;
- m_lifespan = 0;
- m_timestamp = 0;
- m_modified = true;
- m_running = 0;
- m_highpriority = false;
-}
-
-
-
-SND_SoundObject::~SND_SoundObject()
-{
-}
-
-
-
-void SND_SoundObject::StartSound()
-{
- if (m_id >= 0)
- m_playstate = SND_MUST_PLAY;
-}
-
-
-
-void SND_SoundObject::StopSound()
-{
- if (m_id >= 0)
- m_playstate = SND_MUST_STOP;
-}
-
-
-
-void SND_SoundObject::PauseSound()
-{
- if (m_id >= 0)
- m_playstate = SND_MUST_PAUSE;
-}
-
-
-
-void SND_SoundObject::DeleteWhenFinished()
-{
- m_playstate = SND_MUST_BE_DELETED;
-}
-
-
-
-void SND_SoundObject::SetGain(MT_Scalar gain)
-{
- m_gain = gain;
- m_modified = true;
-}
-
-
-
-void SND_SoundObject::SetMinGain(MT_Scalar mingain)
-{
- m_mingain = mingain;
- m_modified = true;
-}
-
-
-
-void SND_SoundObject::SetMaxGain(MT_Scalar maxgain)
-{
- m_maxgain = maxgain;
- m_modified = true;
-}
-
-
-
-void SND_SoundObject::SetRollOffFactor(MT_Scalar rollofffactor)
-{
- m_rollofffactor = rollofffactor;
- m_modified = true;
-}
-
-
-
-void SND_SoundObject::SetReferenceDistance(MT_Scalar referencedistance)
-{
- m_referencedistance = referencedistance;
- m_modified = true;
-}
-
-
-
-void SND_SoundObject::SetPitch(MT_Scalar pitch)
-{
- m_pitch = pitch;
- m_modified = true;
-}
-
-
-
-void SND_SoundObject::SetLoopMode(unsigned int loopmode)
-{
- m_loopmode = loopmode;
- m_modified = true;
-}
-
-
-
-void SND_SoundObject::SetLoopStart(unsigned int loopstart)
-{
- m_loopstart = loopstart;
- m_modified = true;
-}
-
-
-
-void SND_SoundObject::SetLoopEnd(unsigned int loopend)
-{
- m_loopend = loopend;
- m_modified = true;
-}
-
-
-
-void SND_SoundObject::Set3D(bool threedee)
-{
- m_is3d = threedee;
-}
-
-
-
-void SND_SoundObject::SetLifeSpan()
-{
- m_lifespan = m_length / m_pitch;
-}
-
-
-
-bool SND_SoundObject::IsLifeSpanOver(MT_Scalar curtime) const
-{
- bool result = false;
-
- if ((curtime - m_timestamp) > m_lifespan)
- result = true;
-
- return result;
-}
-
-
-
-void SND_SoundObject::SetActive(bool active)
-{
- m_active = active;
-
- if (!active)
- {
- m_playstate = SND_STOPPED;
- (this)->remove();
- }
-}
-
-
-
-void SND_SoundObject::SetBuffer(unsigned int buffer)
-{
- m_buffer = buffer;
-}
-
-
-
-void SND_SoundObject::SetObjectName(STR_String objectname)
-{
- m_objectname = objectname;
-}
-
-
-
-void SND_SoundObject::SetSampleName(STR_String samplename)
-{
- m_samplename = samplename;
-}
-
-
-
-void SND_SoundObject::SetLength(MT_Scalar length)
-{
- m_length = length;
-}
-
-
-
-void SND_SoundObject::SetPosition(const MT_Vector3& pos)
-{
- m_position = pos;
-}
-
-
-
-void SND_SoundObject::SetVelocity(const MT_Vector3& vel)
-{
- m_velocity = vel;
-}
-
-
-
-void SND_SoundObject::SetOrientation(const MT_Matrix3x3& orient)
-{
- m_orientation = orient;
-}
-
-
-
-void SND_SoundObject::SetPlaystate(int playstate)
-{
- m_playstate = playstate;
-}
-
-
-
-void SND_SoundObject::SetId(int id)
-{
- m_id = id;
-}
-
-
-
-void SND_SoundObject::SetTimeStamp(MT_Scalar timestamp)
-{
- m_timestamp = timestamp;
-}
-
-
-
-void SND_SoundObject::SetHighPriority(bool priority)
-{
- m_highpriority = priority;
-}
-
-
-
-bool SND_SoundObject::IsHighPriority() const
-{
- return m_highpriority;
-}
-
-
-
-bool SND_SoundObject::IsActive()const
-{
- return m_active;
-}
-
-
-
-int SND_SoundObject::GetId()const
-{
- return m_id;
-}
-
-
-
-MT_Scalar SND_SoundObject::GetLifeSpan()const
-{
- return m_lifespan;
-}
-
-
-
-MT_Scalar SND_SoundObject::GetTimestamp()const
-{
- return m_timestamp;
-}
-
-
-
-unsigned int SND_SoundObject::GetBuffer()
-{
- return m_buffer;
-}
-
-
-
-const STR_String& SND_SoundObject::GetSampleName()
-{
- return m_samplename;
-}
-
-
-
-const STR_String& SND_SoundObject::GetObjectName()
-{
- return m_objectname;
-}
-
-
-
-MT_Scalar SND_SoundObject::GetLength() const
-{
- return m_length;
-}
-
-
-
-MT_Scalar SND_SoundObject::GetGain() const
-{
- return m_gain;
-}
-
-
-
-MT_Scalar SND_SoundObject::GetPitch() const
-{
- return m_pitch;
-}
-
-
-
-MT_Scalar SND_SoundObject::GetMinGain() const
-{
- return m_mingain;
-}
-
-
-
-MT_Scalar SND_SoundObject::GetMaxGain() const
-{
- return m_maxgain;
-}
-
-
-
-MT_Scalar SND_SoundObject::GetRollOffFactor() const
-{
- return m_rollofffactor;
-}
-
-
-
-MT_Scalar SND_SoundObject::GetReferenceDistance() const
-{
- return m_referencedistance;
-}
-
-
-
-MT_Vector3 SND_SoundObject::GetPosition() const
-{
- return m_position;
-}
-
-
-
-MT_Vector3 SND_SoundObject::GetVelocity() const
-{
- return m_velocity;
-}
-
-
-
-MT_Matrix3x3 SND_SoundObject::GetOrientation() const
-{
- return m_orientation;
-}
-
-
-
-unsigned int SND_SoundObject::GetLoopMode() const
-{
- return m_loopmode;
-}
-
-
-
-unsigned int SND_SoundObject::GetLoopStart() const
-{
- return m_loopstart;
-}
-
-
-
-unsigned int SND_SoundObject::GetLoopEnd() const
-{
- return m_loopend;
-}
-
-
-
-bool SND_SoundObject::Is3D() const
-{
- return m_is3d;
-}
-
-
-
-int SND_SoundObject::GetPlaystate() const
-{
- return m_playstate;
-}
-
-
-
-bool SND_SoundObject::IsModified() const
-{
- return m_modified;
-}
-
-
-
-void SND_SoundObject::SetModified(bool modified)
-{
- m_modified = modified;
-}
-
-
-
-void SND_SoundObject::InitRunning()
-{
- m_running = 0;
-}
-
-
-
-bool SND_SoundObject::IsRunning() const
-{
- bool result = false;
-
- if (m_running > 100)
- result = true;
-
- return result;
-}
-
-
-
-void SND_SoundObject::AddRunning()
-{
- ++m_running;
-}
diff --git a/intern/SoundSystem/intern/SND_Utils.cpp b/intern/SoundSystem/intern/SND_Utils.cpp
deleted file mode 100644
index dbc3135b35c..00000000000
--- a/intern/SoundSystem/intern/SND_Utils.cpp
+++ /dev/null
@@ -1,424 +0,0 @@
-/*
- * SND_Utils.cpp
- *
- * Util functions for soundthingies
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "SND_Utils.h"
-#include "SoundDefines.h"
-#include "SND_DependKludge.h"
-#include <stdio.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <math.h>
-#include <string.h>
-
-#if defined(_WIN32)
-#include <io.h>
-#define open _open
-#define read _read
-#define close _close
-#define write _write
-#define lseek _lseek
-#else
-#include <unistd.h>
-#endif
-
-#define BUFFERSIZE 32
-
-
-/*****************************************************************************
- * Begin of temporary Endian stuff.
- * I think there should be a central place to handle endian conversion but for
- * the time being it suffices. Note that the defines come from the Blender
- * source.
- *****************************************************************************/
-typedef enum
-{
- SND_endianBig = 0,
- SND_endianLittle
-} SND_TEndian;
-
-#if defined(__BIG_ENDIAN__) || defined(__sparc) || defined(__sparc__)
-const SND_TEndian SND_fEndian = SND_endianBig;
-#else
-const SND_TEndian SND_fEndian = SND_endianLittle;
-#endif
-
-/* This one swaps the bytes in a short */
-#define SWITCH_SHORT(a) { \
- char s_i, *p_i; \
- p_i= (char *)&(a); \
- s_i=p_i[0]; \
- p_i[0] = p_i[1]; \
- p_i[1] = s_i; }
-
-/* This one rotates the bytes in an int */
-#define SWITCH_INT(a) { \
- char s_i, *p_i; \
- p_i= (char *)&(a); \
- s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \
- s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; }
-/*****************************************************************************
- * End of temporary Endian stuff.
- *****************************************************************************/
-
-
-/* loads a file */
-void* SND_LoadSample(char *filename)
-{
- int file, filelen, buffersize = BUFFERSIZE;
- void* data = NULL;
-
-#if defined(WIN32)
- file = open(filename, O_BINARY|O_RDONLY);
-#else
- file = open(filename, 0|O_RDONLY);
-#endif
-
- if (file == -1)
- {
- //printf("can't open file.\n");
- //printf("press q for quit.\n");
- }
- else
- {
- filelen = lseek(file, 0, SEEK_END);
- lseek(file, 0, SEEK_SET);
-
- if (filelen != 0)
- {
- data = malloc(buffersize);
-
- if (read(file, data, buffersize) != buffersize)
- {
- free(data);
- data = NULL;
- }
- }
- close(file);
-
- }
- return (data);
-}
-
-
-
-bool SND_IsSampleValid(const STR_String& name, void* memlocation)
-{
- bool result = false;
- bool loadedsample = false;
- char buffer[BUFFERSIZE];
-
- if (!memlocation)
- {
- STR_String samplename = name;
- memlocation = SND_LoadSample(samplename.Ptr());
-
- if (memlocation)
- loadedsample = true;
- }
-
- if (memlocation)
- {
- memcpy(&buffer, memlocation, BUFFERSIZE);
-
- if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8)))
- {
- /* This was endian unsafe. See top of the file for the define. */
- short shortbuf = *((short *) &buffer[20]);
- if (SND_fEndian == SND_endianBig) SWITCH_SHORT(shortbuf);
-
- if (shortbuf == SND_WAVE_FORMAT_PCM)
- result = true;
- }
- }
- if (loadedsample)
- {
- free(memlocation);
- memlocation = NULL;
- }
-
- return result;
-}
-
-
-
-/* checks if the passed pointer is a valid sample */
-static bool CheckSample(void* sample)
-{
- bool valid = false;
- char buffer[32];
-
- memcpy(buffer, sample, 16);
-
- if(!(memcmp(buffer, "RIFF", 4) && memcmp(&(buffer[8]), "WAVEfmt ", 8)))
- {
- valid = true;
- }
-
- return valid;
-}
-
-
-
-/* gets the type of the sample (0 == unknown, 1 == PCM etc */
-unsigned int SND_GetSampleFormat(void* sample)
-{
- short sampletype = 0;
-
- if (CheckSample(sample))
- {
- memcpy(&sampletype, ((char*)sample) + 20, 2);
- }
- /* This was endian unsafe. See top of the file for the define. */
- if (SND_fEndian == SND_endianBig) SWITCH_SHORT(sampletype);
-
- return (unsigned int)sampletype;
-}
-
-
-
-/* gets the number of channels in a sample */
-unsigned int SND_GetNumberOfChannels(void* sample)
-{
- short numberofchannels = 0;
-
- if (CheckSample(sample))
- {
- memcpy(&numberofchannels, ((char*)sample) + 22, 2);
- }
- /* This was endian unsafe. See top of the file for the define. */
- if (SND_fEndian == SND_endianBig) SWITCH_SHORT(numberofchannels);
-
- return (unsigned int)numberofchannels;
-}
-
-
-
-/* gets the samplerate of a sample */
-unsigned int SND_GetSampleRate(void* sample)
-{
- unsigned int samplerate = 0;
-
- if (CheckSample(sample))
- {
- memcpy(&samplerate, ((char*)sample) + 24, 4);
- }
- /* This was endian unsafe. See top of the file for the define. */
- if (SND_fEndian == SND_endianBig) SWITCH_INT(samplerate);
-
- return samplerate;
-}
-
-
-
-/* gets the bitrate of a sample */
-unsigned int SND_GetBitRate(void* sample)
-{
- short bitrate = 0;
-
- if (CheckSample(sample))
- {
- memcpy(&bitrate, ((char*)sample) + 34, 2);
- }
- /* This was endian unsafe. See top of the file for the define. */
- if (SND_fEndian == SND_endianBig) SWITCH_SHORT(bitrate);
-
- return (unsigned int)bitrate;
-}
-
-
-
-/* gets the length of the actual sample data (without the header) */
-unsigned int SND_GetNumberOfSamples(void* sample, unsigned int sample_length)
-{
- unsigned int chunklength, length = 0, offset;
- unsigned short block_align;
- if (CheckSample(sample))
- {
- memcpy(&chunklength, ((char*)sample) + 16, 4);
- memcpy(&block_align, ((char*)sample) + 32, 2); /* always 2 or 4 it seems */
-
- /* This was endian unsafe. See top of the file for the define. */
- if (SND_fEndian == SND_endianBig)
- {
- SWITCH_INT(chunklength);
- SWITCH_SHORT(block_align);
- }
-
- offset = 16 + chunklength + 4;
-
- /* This seems very unsafe, what if data is never found (f.i. corrupt file)... */
- // lets find "data"
- while (memcmp(((char*)sample) + offset, "data", 4))
- {
- offset += block_align;
-
- if (offset+block_align > sample_length) /* save us from crashing */
- return 0;
- }
- offset += 4;
- memcpy(&length, ((char*)sample) + offset, 4);
-
- /* This was endian unsafe. See top of the file for the define. */
- if (SND_fEndian == SND_endianBig) SWITCH_INT(length);
- }
-
- return length;
-}
-
-
-
-/* gets the size of the entire header (file - sampledata) */
-unsigned int SND_GetHeaderSize(void* sample, unsigned int sample_length)
-{
- unsigned int chunklength, headersize = 0, offset = 16;
- unsigned short block_align;
- if (CheckSample(sample))
- {
- memcpy(&chunklength, ((char*)sample) + offset, 4);
- memcpy(&block_align, ((char*)sample) + 32, 2); /* always 2 or 4 it seems */
-
- /* This was endian unsafe. See top of the file for the define. */
- if (SND_fEndian == SND_endianBig)
- {
- SWITCH_INT(chunklength);
- SWITCH_SHORT(block_align);
- }
- offset = offset + chunklength + 4;
-
- // lets find "data"
- while (memcmp(((char*)sample) + offset, "data", 4))
- {
- offset += block_align;
-
- if (offset+block_align > sample_length) /* save us from crashing */
- return 0;
- }
- headersize = offset + 8;
- }
-
- return headersize;
-}
-
-
-unsigned int SND_GetExtraChunk(void* sample)
-{
- unsigned int extrachunk = 0, chunklength, offset = 16;
- char data[4];
-
- if (CheckSample(sample))
- {
- memcpy(&chunklength, ((char*)sample) + offset, 4);
- offset = offset + chunklength + 4;
- memcpy(data, ((char*)sample) + offset, 4);
-
- // lets find "cue"
- while (memcmp(data, "cue", 3))
- {
- offset += 4;
- memcpy(data, ((char*)sample) + offset, 4);
- }
- }
-
- return extrachunk;
-}
-
-
-
-void SND_GetSampleInfo(signed char* sample, SND_WaveSlot* waveslot)
-{
- WavFileHeader fileheader;
- WavFmtHeader fmtheader;
- WavFmtExHeader fmtexheader;
- WavSampleHeader sampleheader;
- WavChunkHeader chunkheader;
-
- if (CheckSample(sample))
- {
- memcpy(&fileheader, sample, sizeof(WavFileHeader));
- fileheader.size = SND_GetHeaderSize(sample, waveslot->GetFileSize());
- if (fileheader.size) { /* this may fail for corrupt files */
- sample += sizeof(WavFileHeader);
- fileheader.size = ((fileheader.size+1) & ~1) - 4;
-
- while ((fileheader.size > 0) && (memcpy(&chunkheader, sample, sizeof(WavChunkHeader))))
- {
- sample += sizeof(WavChunkHeader);
- if (!memcmp(chunkheader.id, "fmt ", 4))
- {
- memcpy(&fmtheader, sample, sizeof(WavFmtHeader));
- waveslot->SetSampleFormat(fmtheader.format);
-
- if (fmtheader.format == 0x0001)
- {
- waveslot->SetNumberOfChannels(fmtheader.numberofchannels);
- waveslot->SetBitRate(fmtheader.bitrate);
- waveslot->SetSampleRate(fmtheader.samplerate);
- sample += chunkheader.size;
- }
- else
- {
- memcpy(&fmtexheader, sample, sizeof(WavFmtExHeader));
- sample += chunkheader.size;
- }
- }
- else if (!memcmp(chunkheader.id, "data", 4))
- {
- if (fmtheader.format == 0x0001)
- {
- waveslot->SetNumberOfSamples(chunkheader.size);
- sample += chunkheader.size;
- }
- else if (fmtheader.format == 0x0011)
- {
- //IMA ADPCM
- }
- else if (fmtheader.format == 0x0055)
- {
- //MP3 WAVE
- }
- }
- else if (!memcmp(chunkheader.id, "smpl", 4))
- {
- memcpy(&sampleheader, sample, sizeof(WavSampleHeader));
- //loop = sampleheader.loops;
- sample += chunkheader.size;
- }
- else
- sample += chunkheader.size;
-
- sample += chunkheader.size & 1;
- fileheader.size -= (((chunkheader.size + 1) & ~1) + 8);
- }
- }
- }
-}
diff --git a/intern/SoundSystem/intern/SND_WaveCache.cpp b/intern/SoundSystem/intern/SND_WaveCache.cpp
deleted file mode 100644
index a678bd554bb..00000000000
--- a/intern/SoundSystem/intern/SND_WaveCache.cpp
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * SND_WaveCache.cpp
- *
- * abstract wavecache, a way to organize samples
- *
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef WIN32
-#pragma warning (disable:4786) // Get rid of stupid stl-visual compiler debug warning
-#endif //WIN32
-
-#include "SND_WaveCache.h"
-#include <stdio.h>
-
-#ifdef __APPLE__
-# include <sys/malloc.h>
-#else
-# ifdef __FreeBSD__
-# include <stdlib.h>
-# else
-# include <malloc.h>
-# endif
-#endif
-
-SND_WaveCache::SND_WaveCache()
-{
- // do the buffer administration
- for (int i = 0; i < NUM_BUFFERS; i++)
- m_bufferList[i] = NULL;
-}
-
-
-
-SND_WaveCache::~SND_WaveCache()
-{
- // clean up the mess
- FreeSamples();
- RemoveAllSamples();
-}
-
-
-
-SND_WaveSlot* SND_WaveCache::GetWaveSlot(const STR_String& samplename)
-{
- SND_WaveSlot* waveslot = NULL;
-
- std::map<STR_String, SND_WaveSlot*>::iterator find_result = m_samplecache.find(samplename);
-
- // let's see if we have already loaded this sample
- if (find_result != m_samplecache.end())
- {
- waveslot = (*find_result).second;
- }
- else
- {
- // so the sample wasn't loaded, so do it here
- for (int bufnum = 0; bufnum < NUM_BUFFERS; bufnum++)
- {
- // find an empty buffer
- if (m_bufferList[bufnum] == NULL)
- {
- waveslot = new SND_WaveSlot();
- waveslot->SetSampleName(samplename);
- waveslot->SetBuffer(bufnum);
- m_bufferList[bufnum] = waveslot;
- break;
- }
- }
- m_samplecache.insert(std::pair<STR_String, SND_WaveSlot*>(samplename, waveslot));
- }
-
- return waveslot;
-}
-
-
-
-void SND_WaveCache::RemoveAllSamples()
-{
- // remove all samples
- m_samplecache.clear();
-
- // reset the list of buffers
- for (int i = 0; i < NUM_BUFFERS; i++)
- m_bufferList[i] = NULL;
-}
-
-
-
-void SND_WaveCache::RemoveSample(const STR_String& samplename, int buffer)
-{
- m_samplecache.erase(samplename);
- m_bufferList[buffer] = NULL;
-}
-
-
-
-void SND_WaveCache::FreeSamples()
-{
- // iterate through the bufferlist and delete the waveslot if present
- for (int i = 0; i < NUM_BUFFERS; i++)
- {
- if (m_bufferList[i])
- {
- delete m_bufferList[i];
- m_bufferList[i] = NULL;
- }
- }
-}
diff --git a/intern/SoundSystem/intern/SND_WaveSlot.cpp b/intern/SoundSystem/intern/SND_WaveSlot.cpp
deleted file mode 100644
index 43b2bb55892..00000000000
--- a/intern/SoundSystem/intern/SND_WaveSlot.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/**
- * $Id$
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-#include "SND_WaveSlot.h"
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-SND_WaveSlot::~SND_WaveSlot()
-{
-#ifdef ONTKEVER
- printf("neeeeeee...\n");
-#endif
-}
-
-
-
-void SND_WaveSlot::SetSampleName(STR_String samplename)
-{
- m_samplename = samplename;
-}
-
-
-
-void SND_WaveSlot::SetLoaded(bool loaded)
-{
- m_loaded = loaded;
-}
-
-
-
-void SND_WaveSlot::SetData(void* data)
-{
- m_data = data;
-}
-
-
-
-void SND_WaveSlot::SetBuffer(unsigned int buffer)
-{
- m_buffer = buffer;
-}
-
-
-
-void SND_WaveSlot::SetSampleFormat(unsigned int sampleformat)
-{
- m_sampleformat = sampleformat;
-}
-
-
-
-void SND_WaveSlot::SetNumberOfChannels(unsigned int numberofchannels)
-{
- m_numberofchannels = numberofchannels;
-}
-
-
-
-void SND_WaveSlot::SetSampleRate(unsigned int samplerate)
-{
- m_samplerate = samplerate;
-}
-
-
-
-void SND_WaveSlot::SetBitRate(unsigned int bitrate)
-{
- m_bitrate = bitrate;
-}
-
-
-
-void SND_WaveSlot::SetNumberOfSamples(unsigned int numberofsamples)
-{
- m_numberofsamples = numberofsamples;
-}
-
-
-
-void SND_WaveSlot::SetFileSize(unsigned int filesize)
-{
- m_filesize = filesize;
-}
-
-
-
-const STR_String& SND_WaveSlot::GetSampleName()
-{
- return m_samplename;
-}
-
-
-
-bool SND_WaveSlot::IsLoaded() const
-{
- return m_loaded;
-}
-
-
-
-void* SND_WaveSlot::GetData()
-{
- return m_data;
-}
-
-
-
-unsigned int SND_WaveSlot::GetBuffer() const
-{
- return m_buffer;
-}
-
-
-
-unsigned int SND_WaveSlot::GetSampleFormat() const
-{
- return m_sampleformat;
-}
-
-
-
-unsigned int SND_WaveSlot::GetNumberOfChannels() const
-{
- return m_numberofchannels;
-}
-
-
-
-unsigned int SND_WaveSlot::GetSampleRate() const
-{
- return m_samplerate;
-}
-
-
-
-unsigned int SND_WaveSlot::GetBitRate() const
-{
- return m_bitrate;
-}
-
-
-
-unsigned int SND_WaveSlot::GetNumberOfSamples() const
-{
- return m_numberofsamples;
-}
-
-
-
-unsigned int SND_WaveSlot::GetFileSize() const
-{
- return m_filesize;
-}
diff --git a/intern/SoundSystem/make/msvc_6_0/SoundSystem.dsp b/intern/SoundSystem/make/msvc_6_0/SoundSystem.dsp
deleted file mode 100644
index 1bd973dfb6c..00000000000
--- a/intern/SoundSystem/make/msvc_6_0/SoundSystem.dsp
+++ /dev/null
@@ -1,206 +0,0 @@
-# Microsoft Developer Studio Project File - Name="SoundSystem" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=SoundSystem - Win32 Release
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "SoundSystem.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "SoundSystem.mak" CFG="SoundSystem - Win32 Release"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "SoundSystem - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "SoundSystem - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "SoundSystem - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\..\..\..\obj\windows\intern\soundsystem"
-# PROP Intermediate_Dir "..\..\..\..\obj\windows\intern\soundsystem"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "../../" /I "../../../../../lib/windows/string/include" /I "../../../../../lib/windows/moto/include" /I "../../dummy" /I "../../openal" /I "..\..\..\string" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\obj\windows\intern\soundsystem\libSoundSystem.lib"
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=ECHO Copying header files XCOPY /Y ..\..\*.h ..\..\..\..\..\lib\windows\SoundSystem\include\*.h ECHO Copying lib XCOPY /Y ..\..\..\..\obj\windows\intern\soundsystem\*.lib ..\..\..\..\..\lib\windows\SoundSystem\lib\*.a ECHO Done
-# End Special Build Tool
-
-!ELSEIF "$(CFG)" == "SoundSystem - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "SoundSystem___Win32_Debug"
-# PROP BASE Intermediate_Dir "SoundSystem___Win32_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\..\..\..\obj\windows\intern\soundsystem\debug"
-# PROP Intermediate_Dir "..\..\..\..\obj\windows\intern\soundsystem\debug"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "../../" /I "../../../../../lib/windows/string/include" /I "../../../../../lib/windows/moto/include" /I "../../dummy" /I "../../openal" /I "..\..\..\string" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\obj\windows\intern\soundsystem\debug\libSoundSystem.lib"
-# Begin Special Build Tool
-SOURCE="$(InputPath)"
-PostBuild_Cmds=ECHO Copying header files XCOPY /Y ..\..\*.h ..\..\..\..\..\lib\windows\SoundSystem\include\*.h ECHO Copying lib XCOPY /Y ..\..\..\..\obj\windows\intern\soundsystem\debug\*.lib ..\..\..\..\..\lib\windows\SoundSystem\lib\debug\*.a ECHO Done
-# End Special Build Tool
-
-!ENDIF
-
-# Begin Target
-
-# Name "SoundSystem - Win32 Release"
-# Name "SoundSystem - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\intern\SND_AudioDevice.cpp
-# End Source File
-# Begin Source File
-
-SOURCE="..\..\intern\SND_C-api.cpp"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_CDObject.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_DeviceManager.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_IdObject.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_Scene.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_SoundListener.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_SoundObject.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_Utils.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_WaveCache.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_WaveSlot.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\intern\SND_AudioDevice.h
-# End Source File
-# Begin Source File
-
-SOURCE="..\..\SND_C-api.h"
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_CDObject.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_DependKludge.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_DeviceManager.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_IAudioDevice.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\intern\SND_IdObject.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_Object.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_Scene.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_SoundListener.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_SoundObject.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_Utils.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_WaveCache.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SND_WaveSlot.h
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\SoundDefines.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/intern/SoundSystem/make/msvc_6_0/dummy/DummySoundSystem.dsp b/intern/SoundSystem/make/msvc_6_0/dummy/DummySoundSystem.dsp
deleted file mode 100644
index 2bf372d0382..00000000000
--- a/intern/SoundSystem/make/msvc_6_0/dummy/DummySoundSystem.dsp
+++ /dev/null
@@ -1,103 +0,0 @@
-# Microsoft Developer Studio Project File - Name="DummySoundSystem" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=DummySoundSystem - Win32 Release
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "DummySoundSystem.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "DummySoundSystem.mak" CFG="DummySoundSystem - Win32 Release"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "DummySoundSystem - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "DummySoundSystem - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "DummySoundSystem - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\..\..\..\..\obj\windows\intern\soundsystem\dummy"
-# PROP Intermediate_Dir "..\..\..\..\..\obj\windows\intern\soundsystem\dummy"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\intern" /I "..\..\..\..\SoundSystem" /I "..\..\..\..\moto\include" /I "..\..\..\..\string" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /J /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\..\obj\windows\intern\soundsystem\dummy\libDummySoundSystem.lib"
-
-!ELSEIF "$(CFG)" == "DummySoundSystem - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "Debug"
-# PROP BASE Intermediate_Dir "Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\..\..\..\..\obj\windows\intern\soundsystem\dummy\debug"
-# PROP Intermediate_Dir "..\..\..\..\..\obj\windows\intern\soundsystem\dummy\debug"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\intern" /I "..\..\..\..\SoundSystem" /I "..\..\..\..\moto\include" /I "..\..\..\..\string" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /J /FD /c
-# SUBTRACT CPP /Fr
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\..\obj\windows\intern\soundsystem\dummy\debug\libDummySoundSystem.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "DummySoundSystem - Win32 Release"
-# Name "DummySoundSystem - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\..\dummy\SND_DummyDevice.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\..\dummy\SND_DummyDevice.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/intern/SoundSystem/make/msvc_6_0/openal/OpenALSoundSystem.dsp b/intern/SoundSystem/make/msvc_6_0/openal/OpenALSoundSystem.dsp
deleted file mode 100644
index ef0c10e8eff..00000000000
--- a/intern/SoundSystem/make/msvc_6_0/openal/OpenALSoundSystem.dsp
+++ /dev/null
@@ -1,106 +0,0 @@
-# Microsoft Developer Studio Project File - Name="OpenALSoundSystem" - Package Owner=<4>
-# Microsoft Developer Studio Generated Build File, Format Version 6.00
-# ** DO NOT EDIT **
-
-# TARGTYPE "Win32 (x86) Static Library" 0x0104
-
-CFG=OpenALSoundSystem - Win32 Release
-!MESSAGE This is not a valid makefile. To build this project using NMAKE,
-!MESSAGE use the Export Makefile command and run
-!MESSAGE
-!MESSAGE NMAKE /f "OpenALSoundSystem.mak".
-!MESSAGE
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "OpenALSoundSystem.mak" CFG="OpenALSoundSystem - Win32 Release"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "OpenALSoundSystem - Win32 Release" (based on "Win32 (x86) Static Library")
-!MESSAGE "OpenALSoundSystem - Win32 Debug" (based on "Win32 (x86) Static Library")
-!MESSAGE
-
-# Begin Project
-# PROP AllowPerConfigDependencies 0
-# PROP Scc_ProjName ""
-# PROP Scc_LocalPath ""
-CPP=cl.exe
-RSC=rc.exe
-
-!IF "$(CFG)" == "OpenALSoundSystem - Win32 Release"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "..\..\..\..\..\obj\windows\intern\soundsystem\openal"
-# PROP Intermediate_Dir "..\..\..\..\..\obj\windows\intern\soundsystem\openal"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
-# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\..\..\intern" /I "..\..\..\..\SoundSystem" /I "..\..\..\..\SoundSystem\sdl" /I "..\..\..\..\moto\include" /I "..\..\..\..\string" /I "..\..\..\..\..\..\lib\windows\openal\include" /I "..\..\..\..\..\..\lib\windows\sdl\include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /d "NDEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\..\obj\windows\intern\soundsystem\openal\libOpenALSoundSystem.lib"
-
-!ELSEIF "$(CFG)" == "OpenALSoundSystem - Win32 Debug"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 1
-# PROP BASE Output_Dir "OpenALSoundSystem___Win32_Debug"
-# PROP BASE Intermediate_Dir "OpenALSoundSystem___Win32_Debug"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 1
-# PROP Output_Dir "..\..\..\..\..\obj\windows\intern\soundsystem\openal\debug"
-# PROP Intermediate_Dir "..\..\..\..\..\obj\windows\intern\soundsystem\openal\debug"
-# PROP Target_Dir ""
-LINK32=link.exe -lib
-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
-# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\..\..\intern" /I "..\..\..\..\SoundSystem" /I "..\..\..\..\SoundSystem\sdl" /I "..\..\..\..\moto\include" /I "..\..\..\..\string" /I "..\..\..\..\..\..\lib\windows\sdl\include" /I "..\..\..\..\..\..\lib\windows\openal\include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /J /FD /c
-# ADD BASE RSC /l 0x409 /d "_DEBUG"
-# ADD RSC /l 0x409 /d "_DEBUG"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LIB32=link.exe -lib
-# ADD BASE LIB32 /nologo
-# ADD LIB32 /nologo /out:"..\..\..\..\..\obj\windows\intern\soundsystem\openal\debug\libOpenALSoundSystem.lib"
-
-!ENDIF
-
-# Begin Target
-
-# Name "OpenALSoundSystem - Win32 Release"
-# Name "OpenALSoundSystem - Win32 Debug"
-# Begin Group "Source Files"
-
-# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
-# Begin Source File
-
-SOURCE=..\..\..\openal\SND_OpenALDevice.cpp
-# End Source File
-# Begin Source File
-
-SOURCE=..\..\..\sdl\SND_SDLCDDevice.cpp
-# End Source File
-# End Group
-# Begin Group "Header Files"
-
-# PROP Default_Filter "h;hpp;hxx;hm;inl"
-# Begin Source File
-
-SOURCE=..\..\..\openal\SND_OpenALDevice.h
-# End Source File
-# End Group
-# End Target
-# End Project
diff --git a/intern/SoundSystem/make/msvc_7_0/SoundSystem.vcproj b/intern/SoundSystem/make/msvc_7_0/SoundSystem.vcproj
deleted file mode 100644
index f0952c582b7..00000000000
--- a/intern/SoundSystem/make/msvc_7_0/SoundSystem.vcproj
+++ /dev/null
@@ -1,339 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="SoundSystem"
- ProjectGUID="{98330220-47A6-42E0-9DE4-AD0FF5D204D6}"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Blender Debug|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_7\intern\soundsystem\debug"
- IntermediateDirectory="..\..\..\..\..\build\msvc_7\intern\soundsystem\debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..;..\..\dummy;..\..\openal;..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\build\msvc_7\intern\moto\include"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_7\intern\soundsystem\debug\SoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_7\intern\soundsystem\debug\"
- ObjectFile="..\..\..\..\..\build\msvc_7\intern\soundsystem\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_7\intern\soundsystem\debug\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_7\libs\intern\debug\libSoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying SND SoundSystem files library (debug target) to lib tree."
- CommandLine="ECHO Copying header files
-IF NOT EXIST ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include MKDIR ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include
-XCOPY /Y ..\..\*.h ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include
-ECHO Done
-"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Blender Release|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_7\intern\soundsystem"
- IntermediateDirectory="..\..\..\..\..\build\msvc_7\intern\soundsystem"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..;..\..\dummy;..\..\openal;..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\build\msvc_7\intern\moto\include"
- PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_7\intern\soundsystem\SoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_7\intern\soundsystem\"
- ObjectFile="..\..\..\..\..\build\msvc_7\intern\soundsystem\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_7\intern\soundsystem\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_7\libs\intern\libSoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying SND SoundSystem files library to lib tree."
- CommandLine="ECHO Copying header files
-IF NOT EXIST ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include MKDIR ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include
-XCOPY /Y ..\..\*.h ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include
-ECHO Done
-"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="3DPlugin Release|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll"
- IntermediateDirectory="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..;..\..\dummy;..\..\openal;..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\build\msvc_7\intern\moto\include"
- PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="TRUE"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\SoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\"
- ObjectFile="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_7\libs\intern\mtdll\libSoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying SND SoundSystem files library to lib tree."
- CommandLine="ECHO Copying header files
-IF NOT EXIST ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include MKDIR ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include
-XCOPY /Y ..\..\*.h ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include
-ECHO Done
-"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="3DPlugin Debug|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\debug"
- IntermediateDirectory="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..;..\..\dummy;..\..\openal;..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\build\msvc_7\intern\moto\include"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\debug\SoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\debug\"
- ObjectFile="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_7\intern\soundsystem\mtdll\debug\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_7\libs\intern\mtdll\debug\libSoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying SND SoundSystem files library (debug target) to lib tree."
- CommandLine="ECHO Copying header files
-IF NOT EXIST ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include MKDIR ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include
-XCOPY /Y ..\..\*.h ..\..\..\..\..\build\msvc_7\intern\SoundSystem\include
-ECHO Done
-"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
- <File
- RelativePath="..\..\intern\SND_AudioDevice.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_C-api.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_CDObject.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_DeviceManager.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_IdObject.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_Scene.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_SoundListener.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_SoundObject.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_Utils.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_WaveCache.cpp">
- </File>
- <File
- RelativePath="..\..\intern\SND_WaveSlot.cpp">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl">
- <File
- RelativePath="..\..\intern\SND_AudioDevice.h">
- </File>
- <File
- RelativePath="..\..\SND_C-api.h">
- </File>
- <File
- RelativePath="..\..\SND_CDObject.h">
- </File>
- <File
- RelativePath="..\..\SND_DependKludge.h">
- </File>
- <File
- RelativePath="..\..\SND_DeviceManager.h">
- </File>
- <File
- RelativePath="..\..\SND_IAudioDevice.h">
- </File>
- <File
- RelativePath="..\..\intern\SND_IdObject.h">
- </File>
- <File
- RelativePath="..\..\SND_Object.h">
- </File>
- <File
- RelativePath="..\..\SND_Scene.h">
- </File>
- <File
- RelativePath="..\..\SND_SoundListener.h">
- </File>
- <File
- RelativePath="..\..\SND_SoundObject.h">
- </File>
- <File
- RelativePath="..\..\SND_Utils.h">
- </File>
- <File
- RelativePath="..\..\SND_WaveCache.h">
- </File>
- <File
- RelativePath="..\..\SND_WaveSlot.h">
- </File>
- <File
- RelativePath="..\..\SoundDefines.h">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/intern/SoundSystem/make/msvc_7_0/dummy/DummySoundSystem.vcproj b/intern/SoundSystem/make/msvc_7_0/dummy/DummySoundSystem.vcproj
deleted file mode 100644
index 103b589e732..00000000000
--- a/intern/SoundSystem/make/msvc_7_0/dummy/DummySoundSystem.vcproj
+++ /dev/null
@@ -1,243 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="DummySoundSystem"
- ProjectGUID="{FAF46346-65CC-4DB2-85C4-B99826F79D0C}"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Blender Release|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\intern;..\..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_7\intern\moto\include"
- PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\DummySoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\"
- ObjectFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_7\libs\intern\libDummySoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Blender Debug|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\debug"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\intern;..\..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_7\intern\moto\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\debug\DummySoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\debug\"
- ObjectFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\debug\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_7\libs\intern\debug\libDummySoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="3DPlugin Release|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\intern;..\..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_7\intern\moto\include"
- PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="TRUE"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\DummySoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\"
- ObjectFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_7\libs\intern\mtdll\libDummySoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="3DPlugin Debug|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\debug"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\intern;..\..\..\..\..\..\build\msvc_7\intern\string\include;..\..\..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_7\intern\moto\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\debug\DummySoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\debug\"
- ObjectFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\dummy\mtdll\debug\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_7\libs\intern\mtdll\debug\libDummySoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
- <File
- RelativePath="..\..\..\dummy\SND_DummyDevice.cpp">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl">
- <File
- RelativePath="..\..\..\dummy\SND_DummyDevice.h">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/intern/SoundSystem/make/msvc_7_0/openal/OpenALSoundSystem.vcproj b/intern/SoundSystem/make/msvc_7_0/openal/OpenALSoundSystem.vcproj
deleted file mode 100644
index 8ce971ac1aa..00000000000
--- a/intern/SoundSystem/make/msvc_7_0/openal/OpenALSoundSystem.vcproj
+++ /dev/null
@@ -1,249 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="7.10"
- Name="OpenALSoundSystem"
- ProjectGUID="{213356A9-3A1F-41DA-9819-1297BCD17DEE}"
- SccProjectName=""
- SccLocalPath="">
- <Platforms>
- <Platform
- Name="Win32"/>
- </Platforms>
- <Configurations>
- <Configuration
- Name="Blender Debug|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\debug"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\sdl;..\..\..\intern;..\..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\intern\string\include"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\debug\OpenALSoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\debug\"
- ObjectFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\debug\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_7\libs\intern\debug\libOpenALSoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="Blender Release|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\sdl;..\..\..\intern;..\..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\intern\string\include"
- PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="TRUE"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\OpenALSoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\"
- ObjectFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_7\libs\intern\libOpenALSoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="3DPlugin Release|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\sdl;..\..\..\intern;..\..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\intern\string\include"
- PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
- StringPooling="TRUE"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="TRUE"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\OpenALSoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\"
- ObjectFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_7\libs\intern\mtdll\libOpenALSoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- <Configuration
- Name="3DPlugin Debug|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\debug"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\debug"
- ConfigurationType="4"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="FALSE"
- CharacterSet="2">
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\sdl;..\..\..\intern;..\..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\..\build\msvc_7\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_7\intern\moto\include;..\..\..\..\..\..\build\msvc_7\intern\string\include"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- DefaultCharIsUnsigned="TRUE"
- UsePrecompiledHeader="2"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\debug\OpenALSoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\debug\"
- ObjectFile="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_7\intern\soundsystem\openal\mtdll\debug\"
- WarningLevel="2"
- SuppressStartupBanner="TRUE"
- DebugInformationFormat="3"
- CompileAs="0"/>
- <Tool
- Name="VCCustomBuildTool"/>
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_7\libs\intern\mtdll\debug\libOpenALSoundSystem.lib"
- SuppressStartupBanner="TRUE"/>
- <Tool
- Name="VCMIDLTool"/>
- <Tool
- Name="VCPostBuildEventTool"/>
- <Tool
- Name="VCPreBuildEventTool"/>
- <Tool
- Name="VCPreLinkEventTool"/>
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"/>
- <Tool
- Name="VCWebServiceProxyGeneratorTool"/>
- <Tool
- Name="VCXMLDataGeneratorTool"/>
- <Tool
- Name="VCManagedWrapperGeneratorTool"/>
- <Tool
- Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat">
- <File
- RelativePath="..\..\..\openal\SND_OpenALDevice.cpp">
- </File>
- <File
- RelativePath="..\..\..\sdl\SND_SDLCDDevice.cpp">
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl">
- <File
- RelativePath="..\..\..\openal\SND_OpenALDevice.h">
- </File>
- <File
- RelativePath="..\..\..\sdl\SND_SDLCDDevice.h">
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/intern/SoundSystem/make/msvc_9_0/SoundSystem.vcproj b/intern/SoundSystem/make/msvc_9_0/SoundSystem.vcproj
deleted file mode 100644
index bd75fe88d43..00000000000
--- a/intern/SoundSystem/make/msvc_9_0/SoundSystem.vcproj
+++ /dev/null
@@ -1,447 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="9,00"
- Name="INT_SoundSystem"
- ProjectGUID="{98330220-47A6-42E0-9DE4-AD0FF5D204D6}"
- RootNamespace="SoundSystem"
- TargetFrameworkVersion="131072"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Blender Debug|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_9\intern\soundsystem\debug"
- IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\soundsystem\debug"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..;..\..\dummy;..\..\openal;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\moto\include"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\soundsystem\debug\SoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\soundsystem\debug\"
- ObjectFile="..\..\..\..\..\build\msvc_9\intern\soundsystem\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\soundsystem\debug\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- DebugInformationFormat="3"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\debug\libSoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying SND SoundSystem files library (debug target) to lib tree."
- CommandLine="ECHO Copying header files&#x0D;&#x0A;IF NOT EXIST ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include MKDIR ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include&#x0D;&#x0A;XCOPY /Y ..\..\*.h ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include&#x0D;&#x0A;ECHO Done&#x0D;&#x0A;"
- />
- </Configuration>
- <Configuration
- Name="Blender Release|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_9\intern\soundsystem"
- IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\soundsystem"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..;..\..\dummy;..\..\openal;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\moto\include"
- PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
- StringPooling="true"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="true"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\soundsystem\SoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\soundsystem\"
- ObjectFile="..\..\..\..\..\build\msvc_9\intern\soundsystem\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\soundsystem\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\libSoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying SND SoundSystem files library to lib tree."
- CommandLine="ECHO Copying header files&#x0D;&#x0A;IF NOT EXIST ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include MKDIR ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include&#x0D;&#x0A;XCOPY /Y ..\..\*.h ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include&#x0D;&#x0A;ECHO Done&#x0D;&#x0A;"
- />
- </Configuration>
- <Configuration
- Name="3DPlugin Release|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll"
- IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..;..\..\dummy;..\..\openal;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\moto\include"
- PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\SoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\"
- ObjectFile="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\mtdll\libSoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying SND SoundSystem files library to lib tree."
- CommandLine="ECHO Copying header files&#x0D;&#x0A;IF NOT EXIST ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include MKDIR ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include&#x0D;&#x0A;XCOPY /Y ..\..\*.h ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include&#x0D;&#x0A;ECHO Done&#x0D;&#x0A;"
- />
- </Configuration>
- <Configuration
- Name="3DPlugin Debug|Win32"
- OutputDirectory="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\debug"
- IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\debug"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..;..\..\dummy;..\..\openal;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\build\msvc_9\intern\moto\include"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\debug\SoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\debug\"
- ObjectFile="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\soundsystem\mtdll\debug\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- DebugInformationFormat="3"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\mtdll\debug\libSoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- Description="Copying SND SoundSystem files library (debug target) to lib tree."
- CommandLine="ECHO Copying header files&#x0D;&#x0A;IF NOT EXIST ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include MKDIR ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include&#x0D;&#x0A;XCOPY /Y ..\..\*.h ..\..\..\..\..\build\msvc_9\intern\SoundSystem\include&#x0D;&#x0A;ECHO Done&#x0D;&#x0A;"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
- >
- <File
- RelativePath="..\..\intern\SND_AudioDevice.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_C-api.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_CDObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_DeviceManager.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_IdObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_Scene.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_SoundListener.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_SoundObject.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_Utils.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_WaveCache.cpp"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_WaveSlot.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl"
- >
- <File
- RelativePath="..\..\intern\SND_AudioDevice.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_C-api.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_CDObject.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_DependKludge.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_DeviceManager.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_IAudioDevice.h"
- >
- </File>
- <File
- RelativePath="..\..\intern\SND_IdObject.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_Object.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_Scene.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_SoundListener.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_SoundObject.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_Utils.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_WaveCache.h"
- >
- </File>
- <File
- RelativePath="..\..\SND_WaveSlot.h"
- >
- </File>
- <File
- RelativePath="..\..\SoundDefines.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/intern/SoundSystem/make/msvc_9_0/dummy/DummySoundSystem.vcproj b/intern/SoundSystem/make/msvc_9_0/dummy/DummySoundSystem.vcproj
deleted file mode 100644
index 2109d92d430..00000000000
--- a/intern/SoundSystem/make/msvc_9_0/dummy/DummySoundSystem.vcproj
+++ /dev/null
@@ -1,343 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="9,00"
- Name="INT_DummySoundSystem"
- ProjectGUID="{FAF46346-65CC-4DB2-85C4-B99826F79D0C}"
- RootNamespace="DummySoundSystem"
- TargetFrameworkVersion="131072"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Blender Release|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\intern;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_9\intern\moto\include"
- PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
- StringPooling="true"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="true"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\DummySoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\"
- ObjectFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_9\libs\intern\libDummySoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Blender Debug|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\debug"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\debug"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\intern;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_9\intern\moto\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\debug\DummySoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\debug\"
- ObjectFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\debug\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- DebugInformationFormat="3"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_9\libs\intern\debug\libDummySoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="3DPlugin Release|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\intern;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_9\intern\moto\include"
- PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\DummySoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\"
- ObjectFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_9\libs\intern\mtdll\libDummySoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="3DPlugin Debug|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\debug"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\debug"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\intern;..\..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_9\intern\moto\include"
- PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\debug\DummySoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\debug\"
- ObjectFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\dummy\mtdll\debug\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- DebugInformationFormat="3"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_9\libs\intern\mtdll\debug\libDummySoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
- >
- <File
- RelativePath="..\..\..\dummy\SND_DummyDevice.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl"
- >
- <File
- RelativePath="..\..\..\dummy\SND_DummyDevice.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/intern/SoundSystem/make/msvc_9_0/openal/OpenALSoundSystem.vcproj b/intern/SoundSystem/make/msvc_9_0/openal/OpenALSoundSystem.vcproj
deleted file mode 100644
index 5593f00cb2b..00000000000
--- a/intern/SoundSystem/make/msvc_9_0/openal/OpenALSoundSystem.vcproj
+++ /dev/null
@@ -1,351 +0,0 @@
-<?xml version="1.0" encoding="Windows-1252"?>
-<VisualStudioProject
- ProjectType="Visual C++"
- Version="9,00"
- Name="INT_OpenALSoundSystem"
- ProjectGUID="{213356A9-3A1F-41DA-9819-1297BCD17DEE}"
- RootNamespace="OpenALSoundSystem"
- TargetFrameworkVersion="131072"
- >
- <Platforms>
- <Platform
- Name="Win32"
- />
- </Platforms>
- <ToolFiles>
- </ToolFiles>
- <Configurations>
- <Configuration
- Name="Blender Debug|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\debug"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\debug"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\sdl;..\..\..\intern;..\..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="1"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\debug\OpenALSoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\debug\"
- ObjectFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\debug\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- DebugInformationFormat="3"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_9\libs\intern\debug\libOpenALSoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="Blender Release|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\sdl;..\..\..\intern;..\..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include"
- PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
- StringPooling="true"
- RuntimeLibrary="0"
- EnableFunctionLevelLinking="true"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\OpenALSoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\"
- ObjectFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_9\libs\intern\libOpenALSoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="3DPlugin Release|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- InlineFunctionExpansion="1"
- AdditionalIncludeDirectories="..\..\..\sdl;..\..\..\intern;..\..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include"
- PreprocessorDefinitions="NDEBUG,WIN32,_LIB"
- StringPooling="true"
- RuntimeLibrary="2"
- EnableFunctionLevelLinking="true"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\OpenALSoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\"
- ObjectFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="NDEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_9\libs\intern\mtdll\libOpenALSoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- <Configuration
- Name="3DPlugin Debug|Win32"
- OutputDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\debug"
- IntermediateDirectory="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\debug"
- ConfigurationType="4"
- InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
- UseOfMFC="0"
- ATLMinimizesCRunTimeLibraryUsage="false"
- CharacterSet="2"
- >
- <Tool
- Name="VCPreBuildEventTool"
- />
- <Tool
- Name="VCCustomBuildTool"
- />
- <Tool
- Name="VCXMLDataGeneratorTool"
- />
- <Tool
- Name="VCWebServiceProxyGeneratorTool"
- />
- <Tool
- Name="VCMIDLTool"
- />
- <Tool
- Name="VCCLCompilerTool"
- Optimization="0"
- AdditionalIncludeDirectories="..\..\..\sdl;..\..\..\intern;..\..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\..\build\msvc_9\intern\soundsystem\include;..\..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\..\build\msvc_9\intern\string\include"
- PreprocessorDefinitions="_DEBUG,WIN32,_LIB"
- BasicRuntimeChecks="3"
- RuntimeLibrary="3"
- DefaultCharIsUnsigned="true"
- UsePrecompiledHeader="0"
- PrecompiledHeaderFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\debug\OpenALSoundSystem.pch"
- AssemblerListingLocation="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\debug\"
- ObjectFile="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\debug\"
- ProgramDataBaseFileName="..\..\..\..\..\..\build\msvc_9\intern\soundsystem\openal\mtdll\debug\"
- WarningLevel="2"
- SuppressStartupBanner="true"
- DebugInformationFormat="3"
- CompileAs="0"
- />
- <Tool
- Name="VCManagedResourceCompilerTool"
- />
- <Tool
- Name="VCResourceCompilerTool"
- PreprocessorDefinitions="_DEBUG"
- Culture="1033"
- />
- <Tool
- Name="VCPreLinkEventTool"
- />
- <Tool
- Name="VCLibrarianTool"
- OutputFile="..\..\..\..\..\..\build\msvc_9\libs\intern\mtdll\debug\libOpenALSoundSystem.lib"
- SuppressStartupBanner="true"
- />
- <Tool
- Name="VCALinkTool"
- />
- <Tool
- Name="VCXDCMakeTool"
- />
- <Tool
- Name="VCBscMakeTool"
- />
- <Tool
- Name="VCFxCopTool"
- />
- <Tool
- Name="VCPostBuildEventTool"
- />
- </Configuration>
- </Configurations>
- <References>
- </References>
- <Files>
- <Filter
- Name="Source Files"
- Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
- >
- <File
- RelativePath="..\..\..\openal\SND_OpenALDevice.cpp"
- >
- </File>
- <File
- RelativePath="..\..\..\sdl\SND_SDLCDDevice.cpp"
- >
- </File>
- </Filter>
- <Filter
- Name="Header Files"
- Filter="h;hpp;hxx;hm;inl"
- >
- <File
- RelativePath="..\..\..\openal\SND_OpenALDevice.h"
- >
- </File>
- <File
- RelativePath="..\..\..\sdl\SND_SDLCDDevice.h"
- >
- </File>
- </Filter>
- </Files>
- <Globals>
- </Globals>
-</VisualStudioProject>
diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.cpp b/intern/SoundSystem/openal/SND_OpenALDevice.cpp
deleted file mode 100644
index 424a05246ac..00000000000
--- a/intern/SoundSystem/openal/SND_OpenALDevice.cpp
+++ /dev/null
@@ -1,864 +0,0 @@
-/*
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- * SND_OpenALDevice derived from SND_IAudioDevice
- */
-
-#ifdef WIN32
-#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
-#endif //WIN32
-
-#include "SND_OpenALDevice.h"
-#ifndef __APPLE__
-#include "SND_SDLCDDevice.h"
-#endif
-#include "SoundDefines.h"
-
-#include "SND_Utils.h"
-
-#ifdef APPLE_FRAMEWORK_FIX
-#include <al.h>
-#include <alc.h>
-#else
-#include <AL/al.h>
-#include <AL/alc.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#if defined(WIN32)
-#include <io.h>
-#else
-#include <unistd.h>
-#endif
-#include <fcntl.h>
-
-#include <signal.h>
-
-/*************************** ALUT replacement *****************************/
-
-/* instead of relying on alut, we just implement our own
- * WAV loading functions, hopefully more reliable */
-
-#include <stdlib.h>
-
-typedef struct /* WAV File-header */
-{
- ALubyte Id[4];
- ALsizei Size;
- ALubyte Type[4];
-} WAVFileHdr_Struct;
-
-typedef struct /* WAV Fmt-header */
-{
- ALushort Format;
- ALushort Channels;
- ALuint SamplesPerSec;
- ALuint BytesPerSec;
- ALushort BlockAlign;
- ALushort BitsPerSample;
-} WAVFmtHdr_Struct;
-
-typedef struct /* WAV FmtEx-header */
-{
- ALushort Size;
- ALushort SamplesPerBlock;
-} WAVFmtExHdr_Struct;
-
-typedef struct /* WAV Smpl-header */
-{
- ALuint Manufacturer;
- ALuint Product;
- ALuint SamplePeriod;
- ALuint Note;
- ALuint FineTune;
- ALuint SMPTEFormat;
- ALuint SMPTEOffest;
- ALuint Loops;
- ALuint SamplerData;
- struct
- {
- ALuint Identifier;
- ALuint Type;
- ALuint Start;
- ALuint End;
- ALuint Fraction;
- ALuint Count;
- } Loop[1];
-} WAVSmplHdr_Struct;
-
-typedef struct /* WAV Chunk-header */
-{
- ALubyte Id[4];
- ALuint Size;
-} WAVChunkHdr_Struct;
-
-static void *SND_loadFileIntoMemory(const char *filename, int *len_r)
-{
- FILE *fp= fopen(filename, "rb");
- void *data;
-
- if (!fp) {
- *len_r= -1;
- return NULL;
- }
-
- fseek(fp, 0L, SEEK_END);
- *len_r= ftell(fp);
- fseek(fp, 0L, SEEK_SET);
-
- data= malloc(*len_r);
- if (!data) {
- *len_r= -1;
- return NULL;
- }
-
- if (fread(data, *len_r, 1, fp)!=1) {
- *len_r= -1;
- free(data);
- return NULL;
- }
-
- return data;
-}
-
-#define TEST_SWITCH_INT(a) if(big_endian) { \
- char s_i, *p_i; \
- p_i= (char *)&(a); \
- s_i=p_i[0]; p_i[0]=p_i[3]; p_i[3]=s_i; \
- s_i=p_i[1]; p_i[1]=p_i[2]; p_i[2]=s_i; }
-
-#define TEST_SWITCH_SHORT(a) if(big_endian) { \
- char s_i, *p_i; \
- p_i= (char *)&(a); \
- s_i=p_i[0]; p_i[0]=p_i[1]; p_i[1]=s_i; }
-
-static int stream_read(void *out, ALbyte **stream, ALsizei size, ALsizei *memsize)
-{
- if(size <= *memsize) {
- memcpy(out, *stream, size);
- return 1;
- }
- else {
- memset(out, 0, size);
- return 0;
- }
-}
-
-static int stream_skip(ALbyte **stream, ALsizei size, ALsizei *memsize)
-{
- if(size <= *memsize) {
- *stream += size;
- *memsize -= size;
- return 1;
- }
- else
- return 0;
-}
-
-ALvoid SND_alutLoadWAVMemory(ALbyte *memory,ALsizei memsize,ALenum *format,ALvoid **data,ALsizei *size,ALsizei *freq,ALboolean *loop)
-{
- WAVChunkHdr_Struct ChunkHdr;
- WAVFmtExHdr_Struct FmtExHdr;
- WAVFileHdr_Struct FileHdr;
- WAVSmplHdr_Struct SmplHdr;
- WAVFmtHdr_Struct FmtHdr;
- ALbyte *Stream= memory;
- int test_endian= 1;
- int big_endian= !((char*)&test_endian)[0];
-
- *format=AL_FORMAT_MONO16;
- *data=NULL;
- *size=0;
- *freq=22050;
- *loop=AL_FALSE;
-
- if(!Stream)
- return;
-
- stream_read(&FileHdr,&Stream,sizeof(WAVFileHdr_Struct),&memsize);
- stream_skip(&Stream,sizeof(WAVFileHdr_Struct),&memsize);
-
- TEST_SWITCH_INT(FileHdr.Size);
- FileHdr.Size=((FileHdr.Size+1)&~1)-4;
-
- while((FileHdr.Size!=0) && stream_read(&ChunkHdr,&Stream,sizeof(WAVChunkHdr_Struct),&memsize))
- {
- TEST_SWITCH_INT(ChunkHdr.Size);
- stream_skip(&Stream,sizeof(WAVChunkHdr_Struct),&memsize);
-
- if (!memcmp(ChunkHdr.Id,"fmt ",4))
- {
- stream_read(&FmtHdr,&Stream,sizeof(WAVFmtHdr_Struct),&memsize);
-
- TEST_SWITCH_SHORT(FmtHdr.Format);
- TEST_SWITCH_SHORT(FmtHdr.Channels);
- TEST_SWITCH_INT(FmtHdr.SamplesPerSec);
- TEST_SWITCH_INT(FmtHdr.BytesPerSec);
- TEST_SWITCH_SHORT(FmtHdr.BlockAlign);
- TEST_SWITCH_SHORT(FmtHdr.BitsPerSample);
-
- if (FmtHdr.Format==0x0001)
- {
- *format=(FmtHdr.Channels==1?
- (FmtHdr.BitsPerSample==8?AL_FORMAT_MONO8:AL_FORMAT_MONO16):
- (FmtHdr.BitsPerSample==8?AL_FORMAT_STEREO8:AL_FORMAT_STEREO16));
- *freq=FmtHdr.SamplesPerSec;
- }
- else
- {
- stream_read(&FmtExHdr,&Stream,sizeof(WAVFmtExHdr_Struct),&memsize);
- TEST_SWITCH_SHORT(FmtExHdr.Size);
- TEST_SWITCH_SHORT(FmtExHdr.SamplesPerBlock);
- }
- }
- else if (!memcmp(ChunkHdr.Id,"data",4))
- {
- if (FmtHdr.Format==0x0001)
- {
- if((ALsizei)ChunkHdr.Size <= memsize)
- {
- *size=ChunkHdr.Size;
- *data=malloc(ChunkHdr.Size+31);
-
- if (*data) {
- stream_read(*data,&Stream,ChunkHdr.Size,&memsize);
- memset(((char *)*data)+ChunkHdr.Size,0,31);
-
- if(FmtHdr.BitsPerSample == 16 && big_endian) {
- int a, len= *size/2;
- short *samples= (short*)*data;
-
- for(a=0; a<len; a++) {
- TEST_SWITCH_SHORT(samples[a])
- }
- }
- }
- }
- }
- else if (FmtHdr.Format==0x0011)
- {
- //IMA ADPCM
- }
- else if (FmtHdr.Format==0x0055)
- {
- //MP3 WAVE
- }
- }
- else if (!memcmp(ChunkHdr.Id,"smpl",4))
- {
- stream_read(&SmplHdr,&Stream,sizeof(WAVSmplHdr_Struct),&memsize);
-
- TEST_SWITCH_INT(SmplHdr.Manufacturer);
- TEST_SWITCH_INT(SmplHdr.Product);
- TEST_SWITCH_INT(SmplHdr.SamplePeriod);
- TEST_SWITCH_INT(SmplHdr.Note);
- TEST_SWITCH_INT(SmplHdr.FineTune);
- TEST_SWITCH_INT(SmplHdr.SMPTEFormat);
- TEST_SWITCH_INT(SmplHdr.SMPTEOffest);
- TEST_SWITCH_INT(SmplHdr.Loops);
- TEST_SWITCH_INT(SmplHdr.SamplerData);
-
- *loop = (SmplHdr.Loops ? AL_TRUE : AL_FALSE);
- }
-
- if(!stream_skip(&Stream, ChunkHdr.Size + (ChunkHdr.Size&1), &memsize))
- break;
-
- FileHdr.Size-=(((ChunkHdr.Size+1)&~1)+8);
- }
-}
-
-ALvoid SND_alutUnloadWAV(ALenum format,ALvoid *data,ALsizei size,ALsizei freq)
-{
- if (data)
- free(data);
-}
-
-/************************ Device Implementation ****************************/
-
-SND_OpenALDevice::SND_OpenALDevice()
- : SND_AudioDevice(),
- m_context(NULL),
- m_device(NULL)
-{
- /* Removed the functionality for checking if noaudio was provided on */
- /* the commandline. */
- m_audio = true;
- m_context = NULL;
- m_buffersinitialized = false;
- m_sourcesinitialized = false;
-
- // let's check if we can get openal to initialize...
- if (m_audio)
- {
- m_audio = false;
-
- ALCdevice *dev = alcOpenDevice(NULL);
- if (dev) {
- m_context = alcCreateContext(dev, NULL);
-
- if (m_context) {
-#ifdef AL_VERSION_1_1
- alcMakeContextCurrent((ALCcontext*)m_context);
-#else
- alcMakeContextCurrent(m_context);
-#endif
- m_audio = true;
- m_device = dev;
-#ifdef __linux__
- /*
- * SIGHUP Hack:
- *
- * On Linux, alcDestroyContext generates a SIGHUP (Hangup) when killing the OpenAL
- * mixer thread, which kills Blender.
- *
- * So we set the signal to ignore....
- *
- * TODO: check if this applies to other platforms.
- *
- */
- signal(SIGHUP, SIG_IGN);
-#endif
- }
- }
-
- }
-
- // then try to generate some buffers
- if (m_audio)
- {
- // let openal generate its buffers
- alGenBuffers(NUM_BUFFERS, m_buffers);
- m_buffersinitialized = true;
-
- for (int i = 0; i < NUM_BUFFERS; i++)
- {
- if (!alIsBuffer(m_buffers[i]))
- {
- //printf("\n\n WARNING: OpenAL returned with an error. Continuing without audio.\n\n");
- m_audio = false;
- break;
- }
- }
- }
-
- // next: the sources
- if (m_audio)
- {
-#ifdef __APPLE__
- ALenum alc_error = ALC_NO_ERROR; // openal_2.12
-#elif defined(_WIN32)
- // alcGetError has no arguments on windows
- ALenum alc_error = alcGetError(); // openal_2.14+
-#else
- ALenum alc_error = alcGetError(NULL); // openal_2.14+
-#endif
-
- // let openal generate its sources
- if (alc_error == ALC_NO_ERROR)
- {
- int i;
-
- for (i=0;i<NUM_SOURCES;i++)
- m_sources[i] = 0;
- alGenSources(NUM_SOURCES, m_sources);
- m_sourcesinitialized = true;
- }
- }
-
- // let's get us a wavecache
- if (m_audio)
- {
- m_wavecache = new SND_WaveCache();
- }
-#ifndef __APPLE__
- m_cdrom = new SND_SDLCDDevice();
-#endif
-}
-
-void SND_OpenALDevice::UseCD(void) const
-{
- // we use SDL for CD, so we create the system
- SND_CDObject::CreateSystem();
-
-}
-
-void SND_OpenALDevice::MakeCurrent() const
-{
-#ifdef WIN32
- alcMakeContextCurrent(m_context);
-#endif
-}
-
-
-
-SND_OpenALDevice::~SND_OpenALDevice()
-{
- MakeCurrent();
-
- if (m_sourcesinitialized)
- {
- for (int i = 0; i < NUM_SOURCES; i++)
- alSourceStop(m_sources[i]);
-
- alDeleteSources(NUM_SOURCES, m_sources);
- m_sourcesinitialized = false;
- }
-
- if (m_buffersinitialized)
- {
- alDeleteBuffers(NUM_BUFFERS, m_buffers);
- m_buffersinitialized = false;
- }
-
- if (m_context) {
- MakeCurrent();
-#ifdef AL_VERSION_1_1
- alcDestroyContext((ALCcontext*)m_context);
-#else
- alcDestroyContext(m_context);
-#endif
- m_context = NULL;
- }
-
-#ifdef __linux__
- // restore the signal state above.
- signal(SIGHUP, SIG_DFL);
-#endif
- // let's see if we used the cd. if not, just leave it alone
- SND_CDObject* pCD = SND_CDObject::Instance();
-
- if (pCD)
- {
- this->StopCD();
- SND_CDObject::DisposeSystem();
- }
-#ifndef __APPLE__
- if (m_cdrom)
- delete m_cdrom;
-#endif
- if (m_device)
- alcCloseDevice((ALCdevice*) m_device);
-}
-
-
-SND_WaveSlot* SND_OpenALDevice::LoadSample(const STR_String& name,
- void* memlocation,
- int size)
-{
- SND_WaveSlot* waveslot = NULL;
- STR_String samplename = name;
-
- if (m_audio)
- {
- /* create the waveslot */
- waveslot = m_wavecache->GetWaveSlot(samplename);
-
- /* do we support this sample? */
- if (SND_IsSampleValid(name, memlocation))
- {
- if (waveslot)
- {
- bool freemem = false;
- int buffer = waveslot->GetBuffer();
- void* data = NULL;
- char loop = 'a';
- int sampleformat, bitrate, numberofchannels;
- ALenum al_error = alGetError();
- ALsizei samplerate, numberofsamples; // openal_2.14+
-
- /* Give them some safe defaults just incase */
- bitrate = numberofchannels = 0;
-
- if (!(size && memlocation)) {
- memlocation = SND_loadFileIntoMemory(samplename.Ptr(), &size);
- freemem = true;
- }
-
- /* load the sample from memory? */
- if (size && memlocation)
- {
- waveslot->SetFileSize(size);
-
- /* what was (our) buffer? */
- int buffer = waveslot->GetBuffer();
-
- /* get some info out of the sample */
- SND_GetSampleInfo((signed char*)memlocation, waveslot);
- numberofchannels = SND_GetNumberOfChannels(memlocation);
- bitrate = SND_GetBitRate(memlocation);
-
- /* load the sample into openal */
- SND_alutLoadWAVMemory((ALbyte*)memlocation, size, &sampleformat, &data, &numberofsamples, &samplerate, &loop);
- /* put it in the buffer */
- alBufferData(m_buffers[buffer], sampleformat, data, numberofsamples, samplerate);
- }
-
- if(freemem)
- free(memlocation);
-
- /* fill the waveslot with info */
- al_error = alGetError();
- if (al_error == AL_NO_ERROR && m_buffers[buffer])
- {
- waveslot->SetData(data);
- waveslot->SetSampleFormat(sampleformat);
- waveslot->SetNumberOfChannels(numberofchannels);
- waveslot->SetSampleRate(samplerate);
- waveslot->SetBitRate(bitrate);
- waveslot->SetNumberOfSamples(numberofsamples);
-
- /* if the loading succeeded, mark the waveslot */
- waveslot->SetLoaded(true);
- }
- else
- {
- /* or when it failed, free the waveslot */
- m_wavecache->RemoveSample(waveslot->GetSampleName(), waveslot->GetBuffer());
- waveslot = NULL;
- }
-
- /* and free the original stuff (copy was made in openal) */
- SND_alutUnloadWAV(sampleformat, data, numberofsamples, samplerate);
- }
- }
- else
- {
- /* sample not supported, remove waveslot */
- m_wavecache->RemoveSample(waveslot->GetSampleName(), waveslot->GetBuffer());
- waveslot = NULL;
- }
- }
- return waveslot;
-}
-
-
-
-// listener's and general stuff //////////////////////////////////////////////////////
-
-
-
-/* sets the global dopplervelocity */
-void SND_OpenALDevice::SetDopplerVelocity(MT_Scalar dopplervelocity) const
-{
- alDopplerVelocity ((float)dopplervelocity);
-}
-
-
-
-/* sets the global dopplerfactor */
-void SND_OpenALDevice::SetDopplerFactor(MT_Scalar dopplerfactor) const
-{
- alDopplerFactor ((float)dopplerfactor);
-}
-
-
-
-/* sets the global rolloff factor */
-void SND_OpenALDevice::SetListenerRollOffFactor(MT_Scalar rollofffactor) const
-{
- // not implemented in openal
-}
-
-
-
-void SND_OpenALDevice::NextFrame() const
-{
- // CD
-#ifndef __APPLE__
- m_cdrom->NextFrame();
-#endif
- // not needed by openal
-}
-
-
-
-// set the gain for the listener
-void SND_OpenALDevice::SetListenerGain(float gain) const
-{
- alListenerf (AL_GAIN, gain);
-}
-
-
-
-void SND_OpenALDevice::InitListener()
-{
- // initialize the listener with these values that won't change
- // (as long as we can have only one listener)
- // now we can superimpose all listeners on each other (for they
- // have the same settings)
- float lispos[3] = {0,0,0};
- float lisvel[3] = {0,0,0};
-#ifdef WIN32
- float lisori[6] = {0,1,0,0,0,1};
-#else
- float lisori[6] = {0,0,1,0,-1,0};
-#endif
-
- alListenerfv(AL_POSITION, lispos);
- alListenerfv(AL_VELOCITY, lisvel);
- alListenerfv(AL_ORIENTATION, lisori);
-}
-
-
-
-// source playstate stuff ////////////////////////////////////////////////////////////
-
-
-
-/* sets the buffer */
-void SND_OpenALDevice::SetObjectBuffer(int id, unsigned int buffer)
-{
- alSourcei (m_sources[id], AL_BUFFER, m_buffers[buffer]);
-}
-
-
-
-// check if the sound's still playing
-int SND_OpenALDevice::GetPlayState(int id)
-{
- int alstate = 0;
- int result = 0;
-
-#ifdef __APPLE__
- alGetSourcei(m_sources[id], AL_SOURCE_STATE, &alstate);
-#else
- alGetSourceiv(m_sources[id], AL_SOURCE_STATE, &alstate);
-#endif
-
- switch(alstate)
- {
- case AL_INITIAL:
- {
- result = SND_INITIAL;
- break;
- }
- case AL_PLAYING:
- {
- result = SND_PLAYING;
- break;
- }
- case AL_PAUSED:
- {
- result = SND_PAUSED;
- break;
- }
- case AL_STOPPED:
- {
- result = SND_STOPPED;
- break;
- }
- default:
- result = SND_UNKNOWN;
- }
-
- return result;
-}
-
-
-
-// make the source play
-void SND_OpenALDevice::PlayObject(int id)
-{
- alSourcePlay(m_sources[id]);
-}
-
-
-
-// make the source stop
-void SND_OpenALDevice::StopObject(int id) const
-{
- float obpos[3] = {0,0,0};
- float obvel[3] = {0,0,0};
-
- alSourcefv(m_sources[id], AL_POSITION, obpos);
- alSourcefv(m_sources[id], AL_VELOCITY, obvel);
-
- alSourcef(m_sources[id], AL_GAIN, 1.0);
- alSourcef(m_sources[id], AL_PITCH, 1.0);
- alSourcei(m_sources[id], AL_LOOPING, AL_FALSE);
- alSourceStop(m_sources[id]);
-}
-
-
-
-// stop all sources
-void SND_OpenALDevice::StopAllObjects()
-{
- alSourceStopv(NUM_SOURCES, m_sources);
-}
-
-
-
-// pause the source
-void SND_OpenALDevice::PauseObject(int id) const
-{
- alSourcePause(m_sources[id]);
-}
-
-
-
-// source properties stuff ////////////////////////////////////////////////////////////
-
-
-
-// give openal the object's pitch
-void SND_OpenALDevice::SetObjectPitch(int id, MT_Scalar pitch) const
-{
- alSourcef (m_sources[id], AL_PITCH, (float)pitch);
-}
-
-
-
-// give openal the object's gain
-void SND_OpenALDevice::SetObjectGain(int id, MT_Scalar gain) const
-{
- alSourcef (m_sources[id], AL_GAIN, (float)gain);
-}
-
-
-
-// give openal the object's looping
-void SND_OpenALDevice::SetObjectLoop(int id, unsigned int loopmode) const
-{
- if (loopmode == SND_LOOP_OFF)
- {
- //printf("%d - ", id);
- alSourcei (m_sources[id], AL_LOOPING, AL_FALSE);
- }
- else
- alSourcei (m_sources[id], AL_LOOPING, AL_TRUE);
-}
-
-void SND_OpenALDevice::SetObjectLoopPoints(int id, unsigned int loopstart, unsigned int loopend) const
-{
-
-
-}
-
-
-void SND_OpenALDevice::SetObjectMinGain(int id, MT_Scalar mingain) const
-{
- alSourcef (m_sources[id], AL_MIN_GAIN, (float)mingain);
-}
-
-
-
-void SND_OpenALDevice::SetObjectMaxGain(int id, MT_Scalar maxgain) const
-{
- alSourcef (m_sources[id], AL_MAX_GAIN, (float)maxgain);
-}
-
-
-
-void SND_OpenALDevice::SetObjectRollOffFactor(int id, MT_Scalar rollofffactor) const
-{
- alSourcef (m_sources[id], AL_ROLLOFF_FACTOR, (float)rollofffactor);
-}
-
-
-
-void SND_OpenALDevice::SetObjectReferenceDistance(int id, MT_Scalar referencedistance) const
-{
- alSourcef (m_sources[id], AL_REFERENCE_DISTANCE, (float)referencedistance);
-}
-
-
-
-// give openal the object's position
-void SND_OpenALDevice::ObjectIs2D(int id) const
-{
- float obpos[3] = {0,0,0};
- float obvel[3] = {0,0,0};
-
- alSourcefv(m_sources[id], AL_POSITION, obpos);
- alSourcefv(m_sources[id], AL_VELOCITY, obvel);
-}
-
-
-
-void SND_OpenALDevice::SetObjectTransform(int id,
- const MT_Vector3& position,
- const MT_Vector3& velocity,
- const MT_Matrix3x3& orientation,
- const MT_Vector3& lisposition,
- const MT_Scalar& rollofffactor) const
-{
- float obpos[3];
- float obvel[3];
-
- obpos[0] = (float)position[0] * (float)rollofffactor; //x (l/r)
- obpos[1] = (float)position[1] * (float)rollofffactor;
- obpos[2] = (float)position[2] * (float)rollofffactor;
-
- alSourcefv(m_sources[id], AL_POSITION, obpos);
-
- velocity.getValue(obvel);
- alSourcefv(m_sources[id], AL_VELOCITY, obvel);
-}
-
-void SND_OpenALDevice::PlayCD(int track) const
-{
-#ifndef __APPLE__
- m_cdrom->PlayCD(track);
-#endif
-}
-
-
-void SND_OpenALDevice::PauseCD(bool pause) const
-{
-#ifndef __APPLE__
- m_cdrom->PauseCD(pause);
-#endif
-}
-
-void SND_OpenALDevice::StopCD() const
-{
-#ifndef __APPLE__
- SND_CDObject* pCD = SND_CDObject::Instance();
-
- if (pCD && pCD->GetUsed())
- {
- m_cdrom->StopCD();
- }
-#endif
-}
-
-void SND_OpenALDevice::SetCDPlaymode(int playmode) const
-{
-#ifndef __APPLE__
- m_cdrom->SetCDPlaymode(playmode);
-#endif
-}
-
-void SND_OpenALDevice::SetCDGain(MT_Scalar gain) const
-{
-#ifndef __APPLE__
- m_cdrom->SetCDGain(gain);
-#endif
-}
diff --git a/intern/SoundSystem/openal/SND_OpenALDevice.h b/intern/SoundSystem/openal/SND_OpenALDevice.h
deleted file mode 100644
index a7b97cc314f..00000000000
--- a/intern/SoundSystem/openal/SND_OpenALDevice.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/**
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef SND_OPENALDEVICE
-#define SND_OPENALDEVICE
-
-#include "SND_AudioDevice.h"
-#include "SoundDefines.h"
-
-struct SDL_CD;
-
-class SND_OpenALDevice : public SND_AudioDevice
-{
-public:
- SND_OpenALDevice();
- virtual ~SND_OpenALDevice();
-
- SND_WaveSlot* LoadSample(const STR_String& samplename,
- void* memlocation,
- int size);
-
- void InitListener();
- void SetListenerGain(float gain) const;
- void SetDopplerVelocity(MT_Scalar dopplervelocity) const;
- void SetDopplerFactor(MT_Scalar dopplerfactor) const;
- void SetListenerRollOffFactor(MT_Scalar rollofffactor) const;
-
- void MakeCurrent() const;
-
- void NextFrame() const;
- void UseCD() const;
-
- void SetObjectBuffer(int id, unsigned int buffer);
-
- int GetPlayState(int id);
- void PlayObject(int id);
- void StopObject(int id) const;
- void StopAllObjects();
- void PauseObject(int id) const;
-
- void SetObjectLoop(int id, unsigned int loopmode) const;
- void SetObjectLoopPoints(int id, unsigned int loopstart, unsigned int loopend) const;
- void SetObjectPitch(int id, MT_Scalar pitch) const;
- void SetObjectGain(int id, MT_Scalar gain) const;
- void SetObjectMinGain(int id, MT_Scalar mingain) const;
- void SetObjectMaxGain(int id, MT_Scalar maxgain) const;
- void SetObjectRollOffFactor(int id, MT_Scalar rolloff) const;
- void SetObjectReferenceDistance(int id, MT_Scalar distance) const;
-
- void SetObjectTransform(int id,
- const MT_Vector3& position,
- const MT_Vector3& velocity,
- const MT_Matrix3x3& orientation,
- const MT_Vector3& lisposition,
- const MT_Scalar& rollofffactor) const;
- void ObjectIs2D(int id) const;
-
- void PlayCD(int track) const;
- void PauseCD(bool pause) const;
- void StopCD() const;
- void SetCDPlaymode(int playmode) const;
- void SetCDGain(MT_Scalar gain) const;
-
- void StartUsingDSP() {};
- float* GetSpectrum() { return NULL; }
- void StopUsingDSP() {};
-
-private:
- void* m_context;
- void* m_device;
-
- unsigned int m_buffers[NUM_BUFFERS];
- unsigned int m_sources[NUM_SOURCES];
- bool m_buffersinitialized;
- bool m_sourcesinitialized;
-#ifndef __APPLE__
- class SND_SDLCDDevice* m_cdrom;
-#endif
-};
-
-#endif //SND_OPENALDEVICE
-
diff --git a/intern/SoundSystem/openal/pthread_cancel.cpp b/intern/SoundSystem/openal/pthread_cancel.cpp
deleted file mode 100644
index bb36d1dd136..00000000000
--- a/intern/SoundSystem/openal/pthread_cancel.cpp
+++ /dev/null
@@ -1,67 +0,0 @@
-/* $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- * FreeBSD 3.4 does not yet have pthread_cancel (3.5 and above do)
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef __FreeBSD__
-
-#include <osreldate.h>
-
-#if (__FreeBSD_version < 350000)
-#include <pthread.h>
-
-#define FD_READ 0x1
-#define _FD_LOCK(_fd,_type,_ts) _thread_fd_lock(_fd, _type, _ts)
-#define _FD_UNLOCK(_fd,_type) _thread_fd_unlock(_fd, _type)
-
-int pthread_cancel(pthread_t pthread) {
- pthread_exit(NULL);
- return 0;
-}
-
-long fpathconf(int fd, int name)
-{
- long ret;
-
- if ((ret = _FD_LOCK(fd, FD_READ, NULL)) == 0) {
- ret = _thread_sys_fpathconf(fd, name);
- _FD_UNLOCK(fd, FD_READ);
- }
- return ret;
-}
-
-#endif
-
-int pthread_atfork(void *a, void *b, void *c) {
- return 0;
-}
-
-#endif
diff --git a/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp b/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp
deleted file mode 100644
index 5054c39e8a1..00000000000
--- a/intern/SoundSystem/sdl/SND_SDLCDDevice.cpp
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- * SND_SDLCDDevice
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#ifdef WIN32
-#pragma warning (disable:4786) // get rid of stupid stl-visual compiler debug warning
-#endif //WIN32
-
-#include "MT_Scalar.h"
-
-#include "SND_SDLCDDevice.h"
-#include "SoundDefines.h"
-
-#ifndef DISABLE_SDL
-#include <SDL.h>
-#else
-#include <stdio.h>
-#endif
-
-SND_SDLCDDevice::SND_SDLCDDevice() :
- m_cdrom(NULL),
- m_cdplaying(false),
- m_cdtrack(0),
- m_cdplaymode(SND_CD_TRACK),
- m_frame(0)
-{
- init();
-}
-
-void SND_SDLCDDevice::init()
-{
-#ifdef DISABLE_SDL
- fprintf(stderr, "Blender compiled without SDL, no CDROM support\n");
- return;
-#else
- if (SDL_InitSubSystem(SDL_INIT_CDROM))
- {
- fprintf(stderr, "Error initializing CDROM\n");
- return;
- }
-
- /* Check for CD drives */
- if(!SDL_CDNumDrives())
- {
- /* None found */
- fprintf(stderr, "No CDROM devices available\n");
- return;
- }
-
- /* Open the default drive */
- m_cdrom = SDL_CDOpen(0);
-
- /* Did if open? Check if cdrom is NULL */
- if(!m_cdrom)
- {
- fprintf(stderr, "Couldn't open drive: %s\n", SDL_GetError());
- return;
- }
-#endif
-}
-
-SND_SDLCDDevice::~SND_SDLCDDevice()
-{
-#ifndef DISABLE_SDL
- StopCD();
- SDL_CDClose(m_cdrom);
-#endif
-}
-
-void SND_SDLCDDevice::NextFrame()
-{
-#ifndef DISABLE_SDL
- m_frame++;
- m_frame &= 127;
-
- if (!m_frame && m_cdrom && m_cdplaying && SDL_CDStatus(m_cdrom) == CD_STOPPED)
- {
- switch (m_cdplaymode)
- {
- case SND_CD_ALL:
- if (m_cdtrack < m_cdrom->numtracks)
- PlayCD(m_cdtrack + 1);
- else
- m_cdplaying = false;
- break;
- default:
- case SND_CD_TRACK:
- m_cdplaying = false;
- break;
- case SND_CD_TRACKLOOP:
- PlayCD(m_cdtrack);
- break;
- }
-
- }
-#endif
-}
-
-void SND_SDLCDDevice::PlayCD(int track)
-{
-#ifndef DISABLE_SDL
- if ( m_cdrom && CD_INDRIVE(SDL_CDStatus(m_cdrom)) ) {
- SDL_CDPlayTracks(m_cdrom, track-1, 0, track, 0);
- m_cdplaying = true;
- m_cdtrack = track;
- }
-#endif
-}
-
-
-void SND_SDLCDDevice::PauseCD(bool pause)
-{
-#ifndef DISABLE_SDL
- if (!m_cdrom)
- return;
-
- if (pause)
- SDL_CDPause(m_cdrom);
- else
- SDL_CDResume(m_cdrom);
-#endif
-}
-
-void SND_SDLCDDevice::StopCD()
-{
-#ifndef DISABLE_SDL
- if (m_cdrom)
- SDL_CDStop(m_cdrom);
- m_cdplaying = false;
-#endif
-}
-
-void SND_SDLCDDevice::SetCDPlaymode(int playmode)
-{
- m_cdplaymode = playmode;
-}
-
-void SND_SDLCDDevice::SetCDGain(MT_Scalar gain)
-{
-
-}
diff --git a/intern/SoundSystem/sdl/SND_SDLCDDevice.h b/intern/SoundSystem/sdl/SND_SDLCDDevice.h
deleted file mode 100644
index 96600d53630..00000000000
--- a/intern/SoundSystem/sdl/SND_SDLCDDevice.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/**
- * $Id$
- *
- * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-#ifndef SND_SDLCDDEVICE
-#define SND_SDLCDDEVICE
-
-struct SDL_CD;
-
-class SND_SDLCDDevice
-{
-public:
- SND_SDLCDDevice();
- ~SND_SDLCDDevice();
-
- void NextFrame();
-
- void PlayCD(int track);
- void PauseCD(bool pause);
- void StopCD();
- void SetCDPlaymode(int playmode);
- void SetCDGain(MT_Scalar gain);
-
-private:
- void init();
- /* CD Audio */
- SDL_CD* m_cdrom;
- bool m_cdplaying;
- int m_cdtrack;
- unsigned char m_cdplaymode;
- unsigned char m_frame;
-};
-
-#endif
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
new file mode 100644
index 00000000000..587ef30979b
--- /dev/null
+++ b/intern/audaspace/CMakeLists.txt
@@ -0,0 +1,64 @@
+# $Id$
+# ***** BEGIN LGPL LICENSE BLOCK *****
+#
+# Copyright 2009 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 Lesser General Public License as published by
+# the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public License
+# along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+#
+# ***** END LGPL LICENSE BLOCK *****
+
+SET(INC . intern FX SRC ${PTHREADS_INC} ${LIBSAMPLERATE_INC})
+
+FILE(GLOB SRC intern/*.cpp intern/*.h FX/*.cpp SRC/*.cpp)
+
+IF(WITH_FFMPEG)
+ SET(INC ${INC} ffmpeg ${FFMPEG_INC})
+ FILE(GLOB FFMPEGSRC ffmpeg/*.cpp)
+ ADD_DEFINITIONS(-DWITH_FFMPEG)
+ENDIF(WITH_FFMPEG)
+
+IF(WITH_SDL)
+ SET(INC ${INC} SDL ${SDL_INCLUDE_DIR})
+ FILE(GLOB SDLSRC SDL/*.cpp)
+ ADD_DEFINITIONS(-DWITH_SDL)
+ENDIF(WITH_SDL)
+
+IF(WITH_OPENAL)
+ SET(INC ${INC} OpenAL ${OPENAL_INCLUDE_DIR})
+ FILE(GLOB OPENALSRC OpenAL/*.cpp)
+ ADD_DEFINITIONS(-DWITH_OPENAL)
+
+ STRING(REGEX MATCH ".*ramework.*" FRAMEWORK ${OPENAL_INCLUDE_DIR})
+ IF(FRAMEWORK)
+ ADD_DEFINITIONS(-DAPPLE_FRAMEWORK_FIX)
+ ENDIF(FRAMEWORK)
+ENDIF(WITH_OPENAL)
+
+IF(WITH_JACK)
+ SET(INC ${INC} jack ${JACK_INC})
+ FILE(GLOB JACKSRC jack/*.cpp)
+ ADD_DEFINITIONS(-DWITH_JACK)
+ENDIF(WITH_JACK)
+
+IF(WITH_SNDFILE)
+ SET(INC ${INC} sndfile ${SNDFILE_INC})
+ FILE(GLOB SNDFILESRC sndfile/*.cpp)
+ ADD_DEFINITIONS(-DWITH_SNDFILE)
+ENDIF(WITH_SNDFILE)
+
+SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC})
+
+BLENDERLIB(bf_audaspace "${SRC}" "${INC}")
diff --git a/intern/audaspace/COPYING b/intern/audaspace/COPYING
new file mode 100644
index 00000000000..94a9ed024d3
--- /dev/null
+++ b/intern/audaspace/COPYING
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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 3 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU 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. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/intern/audaspace/COPYING.LESSER b/intern/audaspace/COPYING.LESSER
new file mode 100644
index 00000000000..cca7fc278f5
--- /dev/null
+++ b/intern/audaspace/COPYING.LESSER
@@ -0,0 +1,165 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser 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
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/intern/audaspace/FX/AUD_DelayFactory.cpp b/intern/audaspace/FX/AUD_DelayFactory.cpp
new file mode 100644
index 00000000000..25ce4faed4c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DelayFactory.cpp
@@ -0,0 +1,58 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_DelayFactory.h"
+#include "AUD_DelayReader.h"
+#include "AUD_Space.h"
+
+AUD_DelayFactory::AUD_DelayFactory(AUD_IFactory* factory, float delay) :
+ AUD_EffectFactory(factory),
+ m_delay(delay) {}
+
+AUD_DelayFactory::AUD_DelayFactory(float delay) :
+ AUD_EffectFactory(0),
+ m_delay(delay) {}
+
+float AUD_DelayFactory::getDelay()
+{
+ return m_delay;
+}
+
+void AUD_DelayFactory::setDelay(float delay)
+{
+ m_delay = delay;
+}
+
+AUD_IReader* AUD_DelayFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_DelayReader(reader, m_delay); AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_DelayFactory.h b/intern/audaspace/FX/AUD_DelayFactory.h
new file mode 100644
index 00000000000..5ad4b9ab996
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DelayFactory.h
@@ -0,0 +1,70 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_DELAYFACTORY
+#define AUD_DELAYFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory plays another factory delayed.
+ */
+class AUD_DelayFactory : public AUD_EffectFactory
+{
+private:
+ /**
+ * The delay in samples.
+ */
+ float m_delay;
+
+public:
+ /**
+ * Creates a new delay factory.
+ * \param factory The input factory.
+ * \param delay The desired delay in seconds.
+ */
+ AUD_DelayFactory(AUD_IFactory* factory = 0, float delay = 0);
+
+ /**
+ * Creates a new delay factory.
+ * \param delay The desired delay in seconds.
+ */
+ AUD_DelayFactory(float delay);
+
+ /**
+ * Returns the delay in seconds.
+ */
+ float getDelay();
+
+ /**
+ * Sets the delay.
+ * \param delay The new delay value in seconds.
+ */
+ void setDelay(float delay);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_DELAYFACTORY
diff --git a/intern/audaspace/FX/AUD_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp
new file mode 100644
index 00000000000..38d3b893b5c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DelayReader.cpp
@@ -0,0 +1,111 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_DelayReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_DelayReader::AUD_DelayReader(AUD_IReader* reader, float delay) :
+ AUD_EffectReader(reader)
+{
+ m_delay = (int)(delay * reader->getSpecs().rate);
+ m_remdelay = m_delay;
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_DelayReader::~AUD_DelayReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+void AUD_DelayReader::seek(int position)
+{
+ if(position < 0)
+ return;
+
+ 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()
+{
+ int len = m_reader->getLength();
+ if(len < 0)
+ return len;
+ return len+m_delay;
+}
+
+int AUD_DelayReader::getPosition()
+{
+ if(m_remdelay > 0)
+ return m_delay-m_remdelay;
+ return m_reader->getPosition() + m_delay;
+}
+
+void AUD_DelayReader::read(int & length, sample_t* & buffer)
+{
+ if(m_remdelay > 0)
+ {
+ int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+
+ if(m_buffer->getSize() < length*samplesize)
+ m_buffer->resize(length*samplesize);
+
+ if(length > m_remdelay)
+ {
+ if(getSpecs().format == AUD_FORMAT_U8)
+ memset(m_buffer->getBuffer(), 0x80, m_remdelay*samplesize);
+ else
+ memset(m_buffer->getBuffer(), 0, m_remdelay*samplesize);
+ int len = length - m_remdelay;
+ m_reader->read(len, buffer);
+ memcpy(m_buffer->getBuffer()+m_remdelay*samplesize,
+ buffer, len*samplesize);
+ if(len < length-m_remdelay)
+ length = m_remdelay + len;
+ m_remdelay = 0;
+ }
+ else
+ {
+ if(getSpecs().format == AUD_FORMAT_U8)
+ memset(m_buffer->getBuffer(), 0x80, length*samplesize);
+ else
+ memset(m_buffer->getBuffer(), 0, length*samplesize);
+ m_remdelay -= length;
+ }
+ buffer = m_buffer->getBuffer();
+ }
+ else
+ m_reader->read(length, buffer);
+}
diff --git a/intern/audaspace/FX/AUD_DelayReader.h b/intern/audaspace/FX/AUD_DelayReader.h
new file mode 100644
index 00000000000..4662b455dfc
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DelayReader.h
@@ -0,0 +1,73 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_DELAYREADER
+#define AUD_DELAYREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class reads another reader and changes it's delay.
+ */
+class AUD_DelayReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The delay level.
+ */
+ int m_delay;
+
+ /**
+ * The remaining delay for playback.
+ */
+ int m_remdelay;
+
+public:
+ /**
+ * Creates a new delay reader.
+ * \param reader The reader to read from.
+ * \param delay The delay in seconds.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_DelayReader(AUD_IReader* reader, float delay);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_DelayReader();
+
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_DELAYREADER
diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp
new file mode 100644
index 00000000000..8d3afbf2f1d
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DoubleReader.cpp
@@ -0,0 +1,158 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_DoubleReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
+ AUD_IReader* reader2) :
+ m_reader1(reader1), m_reader2(reader2)
+{
+ try
+ {
+ if(!reader1)
+ AUD_THROW(AUD_ERROR_READER);
+
+ if(!reader2)
+ AUD_THROW(AUD_ERROR_READER);
+
+ AUD_Specs s1, s2;
+ s1 = reader1->getSpecs();
+ s2 = reader2->getSpecs();
+ if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0)
+ AUD_THROW(AUD_ERROR_READER);
+ }
+
+ catch(AUD_Exception)
+ {
+ if(reader1)
+ {
+ delete reader1; AUD_DELETE("reader")
+ }
+ if(reader2)
+ {
+ delete reader2; AUD_DELETE("reader")
+ }
+
+ throw;
+ }
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+ m_finished1 = false;
+}
+
+AUD_DoubleReader::~AUD_DoubleReader()
+{
+ delete m_reader1; AUD_DELETE("reader")
+ delete m_reader2; AUD_DELETE("reader")
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+bool AUD_DoubleReader::isSeekable()
+{
+ return false;
+}
+
+void AUD_DoubleReader::seek(int position)
+{
+ int length1 = m_reader1->getLength();
+
+ if(position < 0)
+ position = 0;
+
+ if(position < length1)
+ {
+ m_reader1->seek(position);
+ m_reader2->seek(0);
+ m_finished1 = false;
+ }
+ else
+ {
+ m_reader2->seek(position-length1);
+ m_finished1 = true;
+ }
+}
+
+int AUD_DoubleReader::getLength()
+{
+ int len1 = m_reader1->getLength();
+ int len2 = m_reader2->getLength();
+ if(len1 < 0 || len2 < 0)
+ return -1;
+ return len1 + len2;
+}
+
+int AUD_DoubleReader::getPosition()
+{
+ return m_reader1->getPosition() + m_reader2->getPosition();
+}
+
+AUD_Specs AUD_DoubleReader::getSpecs()
+{
+ return m_reader1->getSpecs();
+}
+
+AUD_ReaderType AUD_DoubleReader::getType()
+{
+ if(m_reader1->getType() == AUD_TYPE_BUFFER &&
+ m_reader2->getType() == AUD_TYPE_BUFFER)
+ return AUD_TYPE_BUFFER;
+ return AUD_TYPE_STREAM;
+}
+
+bool AUD_DoubleReader::notify(AUD_Message &message)
+{
+ return m_reader1->notify(message) | m_reader2->notify(message);
+}
+
+void AUD_DoubleReader::read(int & length, sample_t* & buffer)
+{
+ if(!m_finished1)
+ {
+ int len = length;
+ m_reader1->read(len, buffer);
+ if(len < length)
+ {
+ int samplesize = AUD_SAMPLE_SIZE(m_reader1->getSpecs());
+ if(m_buffer->getSize() < length * samplesize)
+ m_buffer->resize(length * samplesize);
+ memcpy(m_buffer->getBuffer(), buffer, len*samplesize);
+ len = length - len;
+ length -= len;
+ m_reader2->read(len, buffer);
+ memcpy(m_buffer->getBuffer() + length*samplesize,
+ buffer, len*samplesize);
+ length += len;
+ buffer = m_buffer->getBuffer();
+ m_finished1 = true;
+ }
+ }
+ else
+ {
+ m_reader2->read(length, buffer);
+ }
+}
diff --git a/intern/audaspace/FX/AUD_DoubleReader.h b/intern/audaspace/FX/AUD_DoubleReader.h
new file mode 100644
index 00000000000..d82b81ec0ba
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DoubleReader.h
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_DOUBLEREADER
+#define AUD_DOUBLEREADER
+
+#include "AUD_IReader.h"
+class AUD_Buffer;
+
+/**
+ * This reader plays two readers with the same specs sequently.
+ */
+class AUD_DoubleReader : public AUD_IReader
+{
+private:
+ /**
+ * The first reader.
+ */
+ AUD_IReader* m_reader1;
+
+ /**
+ * The second reader.
+ */
+ AUD_IReader* m_reader2;
+
+ /**
+ * Whether we've reached the end of the first reader.
+ */
+ bool m_finished1;
+
+ /**
+ * The playback buffer for the intersecting part.
+ */
+ AUD_Buffer* m_buffer;
+
+public:
+ /**
+ * Creates a new ping pong reader.
+ * \param reader1 The first reader to read from.
+ * \param reader2 The second reader to read from.
+ * \exception AUD_Exception Thrown if one of the reader specified is NULL
+ * or the specs from the readers differ.
+ */
+ AUD_DoubleReader(AUD_IReader* reader1, AUD_IReader* reader2);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_DoubleReader();
+
+ virtual bool isSeekable();
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual AUD_ReaderType getType();
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_DOUBLEREADER
diff --git a/intern/audaspace/FX/AUD_EffectFactory.cpp b/intern/audaspace/FX/AUD_EffectFactory.cpp
new file mode 100644
index 00000000000..882499416b7
--- /dev/null
+++ b/intern/audaspace/FX/AUD_EffectFactory.cpp
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_EffectFactory.h"
+#include "AUD_IReader.h"
+
+AUD_IReader* AUD_EffectFactory::getReader()
+{
+ if(m_factory != 0)
+ return m_factory->createReader();
+
+ return 0;
+}
+
+AUD_EffectFactory::AUD_EffectFactory(AUD_IFactory* factory)
+{
+ m_factory = factory;
+}
+
+void AUD_EffectFactory::setFactory(AUD_IFactory* factory)
+{
+ m_factory = factory;
+}
+
+AUD_IFactory* AUD_EffectFactory::getFactory()
+{
+ return m_factory;
+}
diff --git a/intern/audaspace/FX/AUD_EffectFactory.h b/intern/audaspace/FX/AUD_EffectFactory.h
new file mode 100644
index 00000000000..67259b9e6c3
--- /dev/null
+++ b/intern/audaspace/FX/AUD_EffectFactory.h
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_EFFECTFACTORY
+#define AUD_EFFECTFACTORY
+
+#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
+{
+protected:
+ /**
+ * If there is no reader it is created out of this factory.
+ */
+ 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 or NULL if there is none.
+ */
+ AUD_IReader* getReader();
+
+public:
+ /**
+ * Creates a new factory.
+ * \param factory The input factory.
+ */
+ AUD_EffectFactory(AUD_IFactory* factory);
+
+ /**
+ * Destroys the factory.
+ */
+ virtual ~AUD_EffectFactory() {}
+
+ /**
+ * Sets the input factory.
+ * \param factory The input factory.
+ */
+ void setFactory(AUD_IFactory* factory);
+
+ /**
+ * Returns the saved factory.
+ * \return The factory or NULL if there has no factory been saved.
+ */
+ AUD_IFactory* getFactory();
+};
+
+#endif //AUD_EFFECTFACTORY
diff --git a/intern/audaspace/FX/AUD_EffectReader.cpp b/intern/audaspace/FX/AUD_EffectReader.cpp
new file mode 100644
index 00000000000..47026b88440
--- /dev/null
+++ b/intern/audaspace/FX/AUD_EffectReader.cpp
@@ -0,0 +1,78 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_EffectReader.h"
+
+AUD_EffectReader::AUD_EffectReader(AUD_IReader* reader)
+{
+ if(!reader)
+ AUD_THROW(AUD_ERROR_READER);
+ m_reader = reader;
+}
+
+AUD_EffectReader::~AUD_EffectReader()
+{
+ delete m_reader; AUD_DELETE("reader")
+}
+
+bool AUD_EffectReader::isSeekable()
+{
+ return m_reader->isSeekable();
+}
+
+void AUD_EffectReader::seek(int position)
+{
+ m_reader->seek(position);
+}
+
+int AUD_EffectReader::getLength()
+{
+ return m_reader->getLength();
+}
+
+int AUD_EffectReader::getPosition()
+{
+ return m_reader->getPosition();
+}
+
+AUD_Specs AUD_EffectReader::getSpecs()
+{
+ return m_reader->getSpecs();
+}
+
+AUD_ReaderType AUD_EffectReader::getType()
+{
+ return m_reader->getType();
+}
+
+bool AUD_EffectReader::notify(AUD_Message &message)
+{
+ return m_reader->notify(message);
+}
+
+void AUD_EffectReader::read(int & length, sample_t* & buffer)
+{
+ m_reader->read(length, buffer);
+}
diff --git a/intern/audaspace/FX/AUD_EffectReader.h b/intern/audaspace/FX/AUD_EffectReader.h
new file mode 100644
index 00000000000..f64bf34077d
--- /dev/null
+++ b/intern/audaspace/FX/AUD_EffectReader.h
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_EFFECTREADER
+#define AUD_EFFECTREADER
+
+#include "AUD_IReader.h"
+
+/**
+ * This reader is a base class for all effect readers that take one other reader
+ * as input.
+ */
+class AUD_EffectReader : public AUD_IReader
+{
+protected:
+ /**
+ * The reader to read from.
+ */
+ AUD_IReader* m_reader;
+
+public:
+ /**
+ * Creates a new effect reader.
+ * \param reader The reader to read from.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_EffectReader(AUD_IReader* reader);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_EffectReader();
+
+ virtual bool isSeekable();
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual AUD_ReaderType getType();
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_EFFECTREADER
diff --git a/intern/audaspace/FX/AUD_FaderFactory.cpp b/intern/audaspace/FX/AUD_FaderFactory.cpp
new file mode 100644
index 00000000000..4357e11bd43
--- /dev/null
+++ b/intern/audaspace/FX/AUD_FaderFactory.cpp
@@ -0,0 +1,84 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FaderFactory.h"
+#include "AUD_FaderReader.h"
+
+AUD_FaderFactory::AUD_FaderFactory(AUD_IFactory* factory, AUD_FadeType type,
+ float start, float length) :
+ AUD_EffectFactory(factory),
+ m_type(type),
+ m_start(start),
+ m_length(length) {}
+
+AUD_FaderFactory::AUD_FaderFactory(AUD_FadeType type,
+ float start, float length) :
+ AUD_EffectFactory(0),
+ m_type(type),
+ m_start(start),
+ m_length(length) {}
+
+AUD_FadeType AUD_FaderFactory::getType()
+{
+ return m_type;
+}
+
+void AUD_FaderFactory::setType(AUD_FadeType type)
+{
+ m_type = type;
+}
+
+float AUD_FaderFactory::getStart()
+{
+ return m_start;
+}
+
+void AUD_FaderFactory::setStart(float start)
+{
+ m_start = start;
+}
+
+float AUD_FaderFactory::getLength()
+{
+ return m_length;
+}
+
+void AUD_FaderFactory::setLength(float length)
+{
+ m_length = length;
+}
+
+AUD_IReader* AUD_FaderFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_FaderReader(reader, m_type, m_start, m_length);
+ AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_FaderFactory.h b/intern/audaspace/FX/AUD_FaderFactory.h
new file mode 100644
index 00000000000..4999ccac8f1
--- /dev/null
+++ b/intern/audaspace/FX/AUD_FaderFactory.h
@@ -0,0 +1,111 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_FADERFACTORY
+#define AUD_FADERFACTORY
+
+#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.
+ */
+ AUD_FadeType m_type;
+
+ /**
+ * The fading start.
+ */
+ float m_start;
+
+ /**
+ * The fading length.
+ */
+ float m_length;
+
+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(AUD_IFactory* factory = 0,
+ AUD_FadeType type = AUD_FADE_IN,
+ float start = 0.0f, float length = 1.0f);
+
+ /**
+ * Creates a new fader 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(AUD_FadeType type = AUD_FADE_IN,
+ float start = 0.0f, float length = 1.0f);
+
+ /**
+ * Returns the fading type.
+ */
+ AUD_FadeType getType();
+
+ /**
+ * Sets the fading type.
+ * \param type The new fading type: AUD_FADE_IN or AUD_FADE_OUT.
+ */
+ void setType(AUD_FadeType type);
+
+ /**
+ * Returns the fading start.
+ */
+ float getStart();
+
+ /**
+ * Sets the fading start.
+ * \param start The new fading start.
+ */
+ void setStart(float start);
+
+ /**
+ * Returns the fading length.
+ */
+ float getLength();
+
+ /**
+ * Sets the fading length.
+ * \param start The new fading length.
+ */
+ void setLength(float length);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_FADERFACTORY
diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp
new file mode 100644
index 00000000000..d5096e7fae1
--- /dev/null
+++ b/intern/audaspace/FX/AUD_FaderReader.cpp
@@ -0,0 +1,133 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FaderReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+ float start,float length) :
+ AUD_EffectReader(reader),
+ m_type(type),
+ m_start(start),
+ m_length(length)
+{
+ int bigendian = 1;
+ bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
+
+ switch(m_reader->getSpecs().format)
+ {
+ case AUD_FORMAT_S16:
+ m_adjust = AUD_volume_adjust<int16_t>;
+ break;
+ case AUD_FORMAT_S32:
+ m_adjust = AUD_volume_adjust<int32_t>;
+ break;
+ case AUD_FORMAT_FLOAT32:
+ m_adjust = AUD_volume_adjust<float>;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_adjust = AUD_volume_adjust<double>;
+ break;
+ case AUD_FORMAT_U8:
+ m_adjust = AUD_volume_adjust_u8;
+ break;
+ case AUD_FORMAT_S24:
+ m_adjust = bigendian ? AUD_volume_adjust_s24_be :
+ AUD_volume_adjust_s24_le;
+ break;
+ default:
+ delete m_reader;
+ AUD_THROW(AUD_ERROR_READER);
+ }
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_FaderReader::~AUD_FaderReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+bool AUD_FaderReader::notify(AUD_Message &message)
+{
+ return m_reader->notify(message);
+}
+
+void AUD_FaderReader::read(int & length, sample_t* & buffer)
+{
+ int position = m_reader->getPosition();
+ AUD_Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+
+ m_reader->read(length, buffer);
+
+ if(m_buffer->getSize() < length * samplesize)
+ m_buffer->resize(length * samplesize);
+
+ if((position + length) / (float)specs.rate <= m_start)
+ {
+ if(m_type != AUD_FADE_OUT)
+ {
+ buffer = m_buffer->getBuffer();
+ memset(buffer,
+ specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
+ length * samplesize);
+ }
+ }
+ else if(position / (float)specs.rate >= m_start+m_length)
+ {
+ if(m_type == AUD_FADE_OUT)
+ {
+ buffer = m_buffer->getBuffer();
+ memset(buffer,
+ specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
+ length * samplesize);
+ }
+ }
+ else
+ {
+ sample_t* buf = m_buffer->getBuffer();
+ float volume;
+
+ for(int i = 0; i < length; i++)
+ {
+ 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;
+
+ m_adjust(buf + i * samplesize, buffer + i * samplesize,
+ specs.channels, volume);
+ }
+
+ buffer = buf;
+ }
+}
diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h
new file mode 100644
index 00000000000..773643b2f5d
--- /dev/null
+++ b/intern/audaspace/FX/AUD_FaderReader.h
@@ -0,0 +1,86 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_FADERREADER
+#define AUD_FADERREADER
+
+#include "AUD_EffectReader.h"
+#include "AUD_ConverterFunctions.h"
+class AUD_Buffer;
+
+/**
+ * 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 playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The fading type.
+ */
+ AUD_FadeType m_type;
+
+ /**
+ * The fading start.
+ */
+ float m_start;
+
+ /**
+ * The fading length.
+ */
+ float m_length;
+
+ /**
+ * Volume adjustment function.
+ */
+ AUD_volume_adjust_f m_adjust;
+
+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.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+ float start,float length);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_FaderReader();
+
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_FADERREADER
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.cpp b/intern/audaspace/FX/AUD_LimiterFactory.cpp
new file mode 100644
index 00000000000..6f19575240a
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LimiterFactory.cpp
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LimiterFactory.h"
+#include "AUD_LimiterReader.h"
+#include "AUD_Space.h"
+
+AUD_LimiterFactory::AUD_LimiterFactory(AUD_IFactory* factory,
+ float start, float end) :
+ AUD_EffectFactory(factory),
+ m_start(start),
+ m_end(end) {}
+
+float AUD_LimiterFactory::getStart()
+{
+ return m_start;
+}
+
+void AUD_LimiterFactory::setStart(float start)
+{
+ m_start = start;
+}
+
+float AUD_LimiterFactory::getEnd()
+{
+ return m_end;
+}
+
+void AUD_LimiterFactory::setEnd(float end)
+{
+ m_end = end;
+}
+
+AUD_IReader* AUD_LimiterFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_LimiterReader(reader, m_start, m_end);
+ AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.h b/intern/audaspace/FX/AUD_LimiterFactory.h
new file mode 100644
index 00000000000..588fea6eb4b
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LimiterFactory.h
@@ -0,0 +1,84 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LIMITERFACTORY
+#define AUD_LIMITERFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory limits another factory in start and end time.
+ */
+class AUD_LimiterFactory : public AUD_EffectFactory
+{
+private:
+ /**
+ * The start time.
+ */
+ float m_start;
+
+ /**
+ * The end time.
+ */
+ float m_end;
+
+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(AUD_IFactory* factory = 0,
+ float start = 0, float end = -1);
+
+ /**
+ * Returns the start time.
+ */
+ float getStart();
+
+ /**
+ * Sets the start time.
+ * \param start The new start time.
+ */
+ void setStart(float start);
+
+ /**
+ * Returns the end time.
+ */
+ float getEnd();
+
+ /**
+ * Sets the end time.
+ * \param end The new end time, a negative value signals that it should play
+ * to the end.
+ */
+ void setEnd(float end);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_LIMITERFACTORY
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp
new file mode 100644
index 00000000000..05882369001
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LimiterReader.cpp
@@ -0,0 +1,95 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LimiterReader.h"
+#include "AUD_Buffer.h"
+
+#include <iostream>
+
+AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader,
+ float start, float end) :
+ AUD_EffectReader(reader)
+{
+ m_end = (int)(end * reader->getSpecs().rate);
+
+ if(start <= 0)
+ m_start = 0;
+ else
+ {
+ m_start = (int)(start * reader->getSpecs().rate);
+ if(m_reader->isSeekable())
+ m_reader->seek(m_start);
+ else
+ {
+ // skip first m_start samples by reading them
+ int length;
+ sample_t* buffer;
+ for(int i = m_start;
+ i >= AUD_DEFAULT_BUFFER_SIZE;
+ i -= AUD_DEFAULT_BUFFER_SIZE)
+ {
+ length = AUD_DEFAULT_BUFFER_SIZE;
+ m_reader->read(length, buffer);
+ length = i;
+ }
+ m_reader->read(length, buffer);
+ }
+ }
+}
+
+void AUD_LimiterReader::seek(int position)
+{
+ m_reader->seek(position + m_start);
+}
+
+int AUD_LimiterReader::getLength()
+{
+ int len = m_reader->getLength();
+ if(m_reader->getType() != AUD_TYPE_BUFFER || len < 0 ||
+ (len > m_end && m_end >= 0))
+ len = m_end;
+ return len - m_start;
+}
+
+int AUD_LimiterReader::getPosition()
+{
+ return m_reader->getPosition() - m_start;
+}
+
+void AUD_LimiterReader::read(int & length, sample_t* & buffer)
+{
+ if(m_end >= 0)
+ {
+ int position = m_reader->getPosition();
+ if(position+length > m_end)
+ length = m_end - position;
+ if(length < 0)
+ {
+ length = 0;
+ return;
+ }
+ }
+ m_reader->read(length, buffer);
+}
diff --git a/intern/audaspace/FX/AUD_LimiterReader.h b/intern/audaspace/FX/AUD_LimiterReader.h
new file mode 100644
index 00000000000..9921f5ee1b0
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LimiterReader.h
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LIMITERREADER
+#define AUD_LIMITERREADER
+
+#include "AUD_EffectReader.h"
+
+/**
+ * This reader limits another reader in start and end sample.
+ */
+class AUD_LimiterReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The start sample: inclusive.
+ */
+ int m_start;
+
+ /**
+ * The end sample: exlusive.
+ */
+ int m_end;
+
+public:
+ /**
+ * Creates a new limiter reader.
+ * \param reader The reader to read from.
+ * \param start The desired start sample (inclusive).
+ * \param end The desired end sample (exklusive), a negative value signals
+ * that it should play to the end.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_LimiterReader(AUD_IReader* reader, float start = 0, float end = -1);
+
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_LIMITERREADER
diff --git a/intern/audaspace/FX/AUD_LoopFactory.cpp b/intern/audaspace/FX/AUD_LoopFactory.cpp
new file mode 100644
index 00000000000..90186f623ff
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LoopFactory.cpp
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LoopFactory.h"
+#include "AUD_LoopReader.h"
+
+AUD_LoopFactory::AUD_LoopFactory(AUD_IFactory* factory, int loop) :
+ AUD_EffectFactory(factory),
+ m_loop(loop) {}
+
+AUD_LoopFactory::AUD_LoopFactory(int loop) :
+ AUD_EffectFactory(0),
+ m_loop(loop) {}
+
+int AUD_LoopFactory::getLoop()
+{
+ return m_loop;
+}
+
+void AUD_LoopFactory::setLoop(int loop)
+{
+ m_loop = loop;
+}
+
+AUD_IReader* AUD_LoopFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_LoopReader(reader, m_loop); AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_LoopFactory.h b/intern/audaspace/FX/AUD_LoopFactory.h
new file mode 100644
index 00000000000..461d8c9ab69
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LoopFactory.h
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LOOPFACTORY
+#define AUD_LOOPFACTORY
+
+#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.
+ */
+ float m_loop;
+
+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(AUD_IFactory* factory = 0, int loop = -1);
+
+ /**
+ * Creates a new loop factory.
+ * \param loop The desired loop count, negative values result in endless
+ * looping.
+ */
+ AUD_LoopFactory(int loop);
+
+ /**
+ * Returns the loop count.
+ */
+ int getLoop();
+
+ /**
+ * Sets the loop count.
+ * \param loop The desired loop count, negative values result in endless
+ * looping.
+ */
+ void setLoop(int loop);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_LOOPFACTORY
diff --git a/intern/audaspace/FX/AUD_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp
new file mode 100644
index 00000000000..9e270321013
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LoopReader.cpp
@@ -0,0 +1,107 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_LoopReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+#include <stdio.h>
+
+AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
+ AUD_EffectReader(reader), m_loop(loop)
+{
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_LoopReader::~AUD_LoopReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+AUD_ReaderType AUD_LoopReader::getType()
+{
+ if(m_loop < 0)
+ return AUD_TYPE_STREAM;
+ return m_reader->getType();
+}
+
+bool AUD_LoopReader::notify(AUD_Message &message)
+{
+ if(message.type == AUD_MSG_LOOP)
+ {
+ m_loop = message.loopcount;
+
+ m_reader->notify(message);
+
+ return true;
+ }
+ return m_reader->notify(message);
+}
+
+void AUD_LoopReader::read(int & length, sample_t* & buffer)
+{
+ int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+
+ int len = length;
+
+ m_reader->read(len, buffer);
+
+ if(len < length && m_loop != 0)
+ {
+ int pos = 0;
+
+ if(m_buffer->getSize() < length*samplesize)
+ m_buffer->resize(length*samplesize);
+
+ memcpy(m_buffer->getBuffer() + pos * samplesize,
+ buffer, len * samplesize);
+
+ pos += len;
+
+ while(pos < length && m_loop != 0)
+ {
+ if(m_loop > 0)
+ m_loop--;
+
+ m_reader->seek(0);
+
+ len = length - pos;
+ m_reader->read(len, buffer);
+ // prevent endless loop
+ if(!len)
+ break;
+
+ memcpy(m_buffer->getBuffer() + pos * samplesize,
+ buffer, len * samplesize);
+
+ pos += len;
+ }
+
+ length = pos;
+ buffer = m_buffer->getBuffer();
+ }
+ else
+ length = len;
+}
diff --git a/intern/audaspace/FX/AUD_LoopReader.h b/intern/audaspace/FX/AUD_LoopReader.h
new file mode 100644
index 00000000000..621ee3493ab
--- /dev/null
+++ b/intern/audaspace/FX/AUD_LoopReader.h
@@ -0,0 +1,69 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_LOOPREADER
+#define AUD_LOOPREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class reads another reader and loops it.
+ * \note The other reader must be seekable.
+ */
+class AUD_LoopReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The left loop count.
+ */
+ int m_loop;
+
+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.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_LoopReader(AUD_IReader* reader, int loop);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_LoopReader();
+
+ virtual AUD_ReaderType getType();
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_LOOPREADER
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.cpp b/intern/audaspace/FX/AUD_PingPongFactory.cpp
new file mode 100644
index 00000000000..8b72afe05e7
--- /dev/null
+++ b/intern/audaspace/FX/AUD_PingPongFactory.cpp
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_PingPongFactory.h"
+#include "AUD_DoubleReader.h"
+#include "AUD_ReverseFactory.h"
+
+AUD_PingPongFactory::AUD_PingPongFactory(AUD_IFactory* factory) :
+ AUD_EffectFactory(factory) {}
+
+AUD_IReader* AUD_PingPongFactory::createReader()
+{
+ if(m_factory == 0)
+ return 0;
+
+ AUD_IReader* reader = m_factory->createReader();
+
+ if(reader != 0)
+ {
+ AUD_IReader* reader2;
+ AUD_ReverseFactory factory(m_factory);
+
+ try
+ {
+ reader2 = factory.createReader();
+ }
+ catch(AUD_Exception)
+ {
+ reader2 = 0;
+ }
+
+ if(reader2 != 0)
+ {
+ reader = new AUD_DoubleReader(reader, reader2);
+ AUD_NEW("reader")
+ }
+ else
+ {
+ delete reader; AUD_DELETE("reader")
+ reader = 0;
+ }
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.h b/intern/audaspace/FX/AUD_PingPongFactory.h
new file mode 100644
index 00000000000..b8854da550a
--- /dev/null
+++ b/intern/audaspace/FX/AUD_PingPongFactory.h
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_PINGPONGFACTORY
+#define AUD_PINGPONGFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory plays another factory first normal, then reversed.
+ * \note Readers from the underlying factory must be from the buffer type.
+ */
+class AUD_PingPongFactory : public AUD_EffectFactory
+{
+public:
+ /**
+ * Creates a new ping pong factory.
+ * \param factory The input factory.
+ */
+ AUD_PingPongFactory(AUD_IFactory* factory = 0);
+
+ /**
+ * Destroys the factory.
+ */
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_PINGPONGFACTORY
diff --git a/intern/audaspace/FX/AUD_PitchFactory.cpp b/intern/audaspace/FX/AUD_PitchFactory.cpp
new file mode 100644
index 00000000000..5f814283c12
--- /dev/null
+++ b/intern/audaspace/FX/AUD_PitchFactory.cpp
@@ -0,0 +1,48 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_PitchFactory.h"
+#include "AUD_PitchReader.h"
+#include "AUD_Space.h"
+
+AUD_PitchFactory::AUD_PitchFactory(AUD_IFactory* factory, float pitch) :
+ AUD_EffectFactory(factory),
+ m_pitch(pitch) {}
+
+AUD_PitchFactory::AUD_PitchFactory(float pitch) :
+ AUD_EffectFactory(0),
+ m_pitch(pitch) {}
+
+AUD_IReader* AUD_PitchFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_PitchReader(reader, m_pitch); AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_PitchFactory.h b/intern/audaspace/FX/AUD_PitchFactory.h
new file mode 100644
index 00000000000..3209aa46983
--- /dev/null
+++ b/intern/audaspace/FX/AUD_PitchFactory.h
@@ -0,0 +1,70 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_PITCHFACTORY
+#define AUD_PITCHFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory changes the pitch of another factory.
+ */
+class AUD_PitchFactory : public AUD_EffectFactory
+{
+private:
+ /**
+ * The pitch.
+ */
+ float m_pitch;
+
+public:
+ /**
+ * Creates a new pitch factory.
+ * \param factory The input factory.
+ * \param pitch The desired pitch.
+ */
+ AUD_PitchFactory(AUD_IFactory* factory = 0, float pitch = 1.0);
+
+ /**
+ * Creates a new pitch factory.
+ * \param pitch The desired pitch.
+ */
+ AUD_PitchFactory(float pitch);
+
+ /**
+ * Returns the pitch.
+ */
+ float getPitch();
+
+ /**
+ * Sets the pitch.
+ * \param pitch The new pitch value. Should be between 0.0 and 1.0.
+ */
+ void setPitch(float pitch);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_PITCHFACTORY
diff --git a/intern/audaspace/FX/AUD_PitchReader.cpp b/intern/audaspace/FX/AUD_PitchReader.cpp
new file mode 100644
index 00000000000..c53264e1350
--- /dev/null
+++ b/intern/audaspace/FX/AUD_PitchReader.cpp
@@ -0,0 +1,39 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_PitchReader.h"
+
+AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) :
+ AUD_EffectReader(reader)
+{
+ m_pitch = pitch;
+}
+
+AUD_Specs AUD_PitchReader::getSpecs()
+{
+ AUD_Specs specs = m_reader->getSpecs();
+ specs.rate = (AUD_SampleRate)((int)(specs.rate * m_pitch));
+ return specs;
+}
diff --git a/intern/audaspace/FX/AUD_PitchReader.h b/intern/audaspace/FX/AUD_PitchReader.h
new file mode 100644
index 00000000000..440e9cc843c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_PitchReader.h
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_PITCHREADER
+#define AUD_PITCHREADER
+
+#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;
+
+public:
+ /**
+ * Creates a new pitch reader.
+ * \param reader The reader to read from.
+ * \param pitch The size of the buffer.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_PitchReader(AUD_IReader* reader, float pitch);
+
+ virtual AUD_Specs getSpecs();
+};
+
+#endif //AUD_PITCHREADER
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.cpp b/intern/audaspace/FX/AUD_ReverseFactory.cpp
new file mode 100644
index 00000000000..1242641c350
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ReverseFactory.cpp
@@ -0,0 +1,43 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ReverseFactory.h"
+#include "AUD_ReverseReader.h"
+#include "AUD_Space.h"
+
+AUD_ReverseFactory::AUD_ReverseFactory(AUD_IFactory* factory) :
+ AUD_EffectFactory(factory) {}
+
+AUD_IReader* AUD_ReverseFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_ReverseReader(reader); AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.h b/intern/audaspace/FX/AUD_ReverseFactory.h
new file mode 100644
index 00000000000..4b664c47281
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ReverseFactory.h
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_REVERSEFACTORY
+#define AUD_REVERSEFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory reads another factory reverted.
+ * \note Readers from the underlying factory must be from the buffer type.
+ */
+class AUD_ReverseFactory : public AUD_EffectFactory
+{
+public:
+ /**
+ * Creates a new reverse factory.
+ * \param factory The input factory.
+ */
+ AUD_ReverseFactory(AUD_IFactory* factory = 0);
+
+ /**
+ * Destroys the factory.
+ */
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_REVERSEFACTORY
diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp
new file mode 100644
index 00000000000..043480b91b9
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ReverseReader.cpp
@@ -0,0 +1,111 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ReverseReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) :
+ AUD_EffectReader(reader)
+{
+ if(reader->getType() != AUD_TYPE_BUFFER)
+ AUD_THROW(AUD_ERROR_READER);
+
+ m_length = reader->getLength();
+ if(m_length < 0)
+ AUD_THROW(AUD_ERROR_READER);
+
+ m_position = 0;
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_ReverseReader::~AUD_ReverseReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+void AUD_ReverseReader::seek(int position)
+{
+ m_position = position;
+}
+
+int AUD_ReverseReader::getLength()
+{
+ return m_length;
+}
+
+int AUD_ReverseReader::getPosition()
+{
+ return m_position;
+}
+
+void AUD_ReverseReader::read(int & length, sample_t* & buffer)
+{
+ // first correct the length
+ if(m_position+length > m_length)
+ length = m_length-m_position;
+
+ if(length <= 0)
+ {
+ length = 0;
+ return;
+ }
+
+ int samplesize = AUD_SAMPLE_SIZE(getSpecs());
+
+ // resize buffer if needed
+ if(m_buffer->getSize() < length * samplesize)
+ m_buffer->resize(length * samplesize);
+
+ buffer = m_buffer->getBuffer();
+
+ sample_t* buf;
+ int len = length;
+
+ // read from reader
+ m_reader->seek(m_length-m_position-len);
+ m_reader->read(len, buf);
+
+ // set null if reader didn't give enough data
+ if(len < length)
+ {
+ if(getSpecs().format == AUD_FORMAT_U8)
+ memset(buffer, 0x80, (length-len)*samplesize);
+ else
+ memset(buffer, 0, (length-len)*samplesize);
+ buffer += length-len;
+ }
+
+ // copy the samples reverted
+ for(int i = 0; i < len; i++)
+ memcpy(buffer + i * samplesize,
+ buf + (len - 1 - i) * samplesize,
+ samplesize);
+
+ m_position += length;
+
+ buffer = m_buffer->getBuffer();
+}
diff --git a/intern/audaspace/FX/AUD_ReverseReader.h b/intern/audaspace/FX/AUD_ReverseReader.h
new file mode 100644
index 00000000000..045d2ac5a8e
--- /dev/null
+++ b/intern/audaspace/FX/AUD_ReverseReader.h
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_REVERSEREADER
+#define AUD_REVERSEREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class reads another reader from back to front.
+ * \note The underlying reader must be a buffer.
+ */
+class AUD_ReverseReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ /**
+ * The sample count.
+ */
+ int m_length;
+
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer* m_buffer;
+
+public:
+ /**
+ * Creates a new reverse reader.
+ * \param reader The reader to read from.
+ * \exception AUD_Exception Thrown if the reader specified is NULL or not
+ * a buffer.
+ */
+ AUD_ReverseReader(AUD_IReader* reader);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_ReverseReader();
+
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_REVERSEREADER
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.cpp b/intern/audaspace/FX/AUD_VolumeFactory.cpp
new file mode 100644
index 00000000000..fbde608aa12
--- /dev/null
+++ b/intern/audaspace/FX/AUD_VolumeFactory.cpp
@@ -0,0 +1,57 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_VolumeFactory.h"
+#include "AUD_VolumeReader.h"
+
+AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) :
+ AUD_EffectFactory(factory),
+ m_volume(volume) {}
+
+AUD_VolumeFactory::AUD_VolumeFactory(float volume) :
+ AUD_EffectFactory(0),
+ m_volume(volume) {}
+
+float AUD_VolumeFactory::getVolume()
+{
+ return m_volume;
+}
+
+void AUD_VolumeFactory::setVolume(float volume)
+{
+ m_volume = volume;
+}
+
+AUD_IReader* AUD_VolumeFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ reader = new AUD_VolumeReader(reader, m_volume); AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.h b/intern/audaspace/FX/AUD_VolumeFactory.h
new file mode 100644
index 00000000000..d2812536d83
--- /dev/null
+++ b/intern/audaspace/FX/AUD_VolumeFactory.h
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_VOLUMEFACTORY
+#define AUD_VOLUMEFACTORY
+
+#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.
+ */
+ float m_volume;
+
+public:
+ /**
+ * Creates a new volume factory.
+ * \param factory The input factory.
+ * \param volume The desired volume.
+ */
+ AUD_VolumeFactory(AUD_IFactory* factory = 0, float volume = 1.0);
+
+ /**
+ * Creates a new volume factory.
+ * \param volume The desired volume.
+ */
+ AUD_VolumeFactory(float volume);
+
+ /**
+ * Returns the volume.
+ */
+ float getVolume();
+
+ /**
+ * Sets the volume.
+ * \param volume The new volume value. Should be between 0.0 and 1.0.
+ */
+ void setVolume(float volume);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_VOLUMEFACTORY
diff --git a/intern/audaspace/FX/AUD_VolumeReader.cpp b/intern/audaspace/FX/AUD_VolumeReader.cpp
new file mode 100644
index 00000000000..fc3f20152a6
--- /dev/null
+++ b/intern/audaspace/FX/AUD_VolumeReader.cpp
@@ -0,0 +1,97 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_VolumeReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) :
+ AUD_EffectReader(reader),
+ m_volume(volume)
+{
+ int bigendian = 1;
+ bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
+
+ switch(m_reader->getSpecs().format)
+ {
+ case AUD_FORMAT_S16:
+ m_adjust = AUD_volume_adjust<int16_t>;
+ break;
+ case AUD_FORMAT_S32:
+ m_adjust = AUD_volume_adjust<int32_t>;
+ break;
+ case AUD_FORMAT_FLOAT32:
+ m_adjust = AUD_volume_adjust<float>;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_adjust = AUD_volume_adjust<double>;
+ break;
+ case AUD_FORMAT_U8:
+ m_adjust = AUD_volume_adjust_u8;
+ break;
+ case AUD_FORMAT_S24:
+ m_adjust = bigendian ? AUD_volume_adjust_s24_be :
+ AUD_volume_adjust_s24_le;
+ break;
+ default:
+ delete m_reader;
+ AUD_THROW(AUD_ERROR_READER);
+ }
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_VolumeReader::~AUD_VolumeReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+bool AUD_VolumeReader::notify(AUD_Message &message)
+{
+ if(message.type == AUD_MSG_VOLUME)
+ {
+ m_volume = message.volume;
+
+ m_reader->notify(message);
+
+ return true;
+ }
+ return m_reader->notify(message);
+}
+
+void AUD_VolumeReader::read(int & length, sample_t* & buffer)
+{
+ sample_t* buf;
+ AUD_Specs specs = m_reader->getSpecs();
+
+ m_reader->read(length, buf);
+ if(m_buffer->getSize() < length*AUD_SAMPLE_SIZE(specs))
+ m_buffer->resize(length*AUD_SAMPLE_SIZE(specs));
+
+ buffer = m_buffer->getBuffer();
+
+ m_adjust(buffer, buf, length * specs.channels, m_volume);
+}
diff --git a/intern/audaspace/FX/AUD_VolumeReader.h b/intern/audaspace/FX/AUD_VolumeReader.h
new file mode 100644
index 00000000000..f38ae4d265c
--- /dev/null
+++ b/intern/audaspace/FX/AUD_VolumeReader.h
@@ -0,0 +1,72 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_VOLUMEREADER
+#define AUD_VOLUMEREADER
+
+#include "AUD_EffectReader.h"
+#include "AUD_ConverterFunctions.h"
+class AUD_Buffer;
+
+/**
+ * This class reads another reader and changes it's volume.
+ */
+class AUD_VolumeReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The volume level.
+ */
+ float m_volume;
+
+ /**
+ * Volume adjustment function.
+ */
+ AUD_volume_adjust_f m_adjust;
+
+public:
+ /**
+ * Creates a new volume reader.
+ * \param reader The reader to read from.
+ * \param volume The size of the buffer.
+ * \exception AUD_Exception Thrown if the reader specified is NULL.
+ */
+ AUD_VolumeReader(AUD_IReader* reader, float volume);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_VolumeReader();
+
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_VOLUMEREADER
diff --git a/intern/SoundSystem/dummy/Makefile b/intern/audaspace/FX/Makefile
index 829135dde98..bda0e2bdab6 100644
--- a/intern/SoundSystem/dummy/Makefile
+++ b/intern/audaspace/FX/Makefile
@@ -28,15 +28,16 @@
#
#
-LIBNAME = DummySoundSystem
-DIR = $(OCGDIR)/intern/$(LIBNAME)
+LIBNAME = aud_fx
+DIR = $(OCGDIR)/intern/audaspace
include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-CPPFLAGS += -I$(NAN_STRING)/include
-CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I../ffmpeg
CPPFLAGS += -I../intern
+CPPFLAGS += -I../SDL
+CPPFLAGS += -I../SRC
CPPFLAGS += -I..
CPPFLAGS += -I.
diff --git a/intern/audaspace/Makefile b/intern/audaspace/Makefile
new file mode 100644
index 00000000000..474f53f0e0f
--- /dev/null
+++ b/intern/audaspace/Makefile
@@ -0,0 +1,106 @@
+# -*- mode: gnumakefile; tab-width: 8; indent-tabs-mode: t; -*-
+# vim: tabstop=8
+#
+# $Id$
+#
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): GSR
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+include nan_definitions.mk
+
+LIBNAME = audaspace
+SOURCEDIR = intern/audaspace
+DIR = $(OCGDIR)/$(SOURCEDIR)
+DIRS = intern
+DIRS += FX
+DIRS += SDL
+DIRS += SRC
+
+ifeq ($(WITH_FFMPEG),true)
+ DIRS += ffmpeg
+endif
+
+ifeq ($(WITH_OPENAL),true)
+ DIRS += OpenAL
+endif
+
+ifeq ($(WITH_JACK),true)
+ DIRS += jack
+endif
+
+ifeq ($(WITH_SNDFILE),true)
+ DIRS += sndfile
+endif
+
+include nan_subdirs.mk
+
+install: $(ALL_OR_DEBUG)
+ @[ -d $(NAN_AUDASPACE) ] || mkdir $(NAN_AUDASPACE)
+ @[ -d $(NAN_AUDASPACE)/include ] || mkdir $(NAN_AUDASPACE)/include
+ @[ -d $(NAN_AUDASPACE)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaudaspace.a $(DIR)/$(DEBUG_DIR)libaud_sdl.a $(DIR)/$(DEBUG_DIR)libaud_fx.a $(DIR)/$(DEBUG_DIR)libaud_src.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+
+ifeq ($(WITH_FFMPEG),true)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_ffmpeg.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+endif
+
+ifeq ($(WITH_OPENAL),true)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_openal.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+endif
+
+ifeq ($(WITH_JACK),true)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_jack.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+endif
+
+ifeq ($(WITH_SNDFILE),true)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libaud_sndfile.a $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)
+endif
+
+ifeq ($(OS),darwin)
+ ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaudaspace.a
+ ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_src.a
+ ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_fx.a
+ ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sdl.a
+
+ifeq ($(WITH_FFMPEG),true)
+ ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_ffmpeg.a
+endif
+
+ifeq ($(WITH_OPENAL),true)
+ ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_openal.a
+endif
+
+ifeq ($(WITH_JACK),true)
+ ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_jack.a
+endif
+
+ifeq ($(WITH_SNDFILE),true)
+ ranlib $(NAN_AUDASPACE)/lib/$(DEBUG_DIR)libaud_sndfile.a
+endif
+
+endif
+ @../tools/cpifdiff.sh intern/*.h $(NAN_AUDASPACE)/include/
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
new file mode 100644
index 00000000000..b33afa2b955
--- /dev/null
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -0,0 +1,1362 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_OpenALDevice.h"
+#include "AUD_IReader.h"
+#include "AUD_IMixer.h"
+#include "AUD_ConverterFactory.h"
+#include "AUD_SourceCaps.h"
+
+#include <cstring>
+#include <limits>
+
+#ifdef WIN32
+#include <windows.h>
+#else
+#include <unistd.h>
+#endif
+
+#define AUD_OPENAL_CYCLE_BUFFERS 3
+
+/// Saves the data for playback.
+struct AUD_OpenALHandle : AUD_Handle
+{
+ /// Whether it's a buffered or a streamed source.
+ bool isBuffered;
+
+ /// The reader source.
+ AUD_IReader* reader;
+
+ /// Whether to keep the source if end of it is reached.
+ bool keep;
+
+ /// OpenAL sample format.
+ ALenum format;
+
+ /// OpenAL source.
+ ALuint source;
+
+ /// OpenAL buffers.
+ ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS];
+
+ /// The first buffer to be read next.
+ int current;
+
+ /// Whether the stream doesn't return any more data.
+ bool data_end;
+};
+
+struct AUD_OpenALBufferedFactory
+{
+ /// The factory.
+ AUD_IFactory* factory;
+
+ /// The OpenAL buffer.
+ ALuint buffer;
+};
+
+typedef std::list<AUD_OpenALHandle*>::iterator AUD_HandleIterator;
+typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
+
+/******************************************************************************/
+/**************************** Threading Code **********************************/
+/******************************************************************************/
+
+void* AUD_openalRunThread(void* device)
+{
+ AUD_OpenALDevice* dev = (AUD_OpenALDevice*)device;
+ dev->updateStreams();
+ return NULL;
+}
+
+void AUD_OpenALDevice::start()
+{
+ lock();
+
+ if(!m_playing)
+ {
+ 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;
+ }
+
+ unlock();
+}
+
+void AUD_OpenALDevice::updateStreams()
+{
+ AUD_OpenALHandle* sound;
+
+ int length;
+ sample_t* buffer;
+
+ ALint info;
+ AUD_Specs specs;
+
+ while(1)
+ {
+ lock();
+
+ alcSuspendContext(m_context);
+
+ // 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;
+
+ // is it a streamed sound?
+ if(!sound->isBuffered)
+ {
+ // check for buffer refilling
+ alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info);
+
+ if(info)
+ {
+ specs = sound->reader->getSpecs();
+
+ // for all empty buffers
+ while(info--)
+ {
+ // if there's still data to play back
+ if(!sound->data_end)
+ {
+ // read data
+ length = m_buffersize;
+ sound->reader->read(length, buffer);
+
+ // read nothing?
+ if(length == 0)
+ {
+ sound->data_end = true;
+ break;
+ }
+
+ // unqueue buffer
+ alSourceUnqueueBuffers(sound->source, 1,
+ &sound->buffers[sound->current]);
+ ALenum err;
+ if((err = alGetError()) != AL_NO_ERROR)
+ {
+ sound->data_end = true;
+ break;
+ }
+
+ // fill with new data
+ alBufferData(sound->buffers[sound->current],
+ sound->format,
+ buffer,
+ length * AUD_SAMPLE_SIZE(specs),
+ specs.rate);
+
+ if(alGetError() != AL_NO_ERROR)
+ {
+ sound->data_end = true;
+ break;
+ }
+
+ // and queue again
+ alSourceQueueBuffers(sound->source, 1,
+ &sound->buffers[sound->current]);
+ if(alGetError() != AL_NO_ERROR)
+ {
+ sound->data_end = true;
+ break;
+ }
+
+ sound->current = (sound->current+1) %
+ AUD_OPENAL_CYCLE_BUFFERS;
+ }
+ else
+ break;
+ }
+ }
+ }
+
+ // check if the sound has been stopped
+ alGetSourcei(sound->source, AL_SOURCE_STATE, &info);
+
+ if(info != AL_PLAYING)
+ {
+ // if it really stopped
+ if(sound->data_end)
+ {
+ // pause or
+ if(sound->keep)
+ pause(sound);
+ // stop
+ else
+ stop(sound);
+ }
+ // continue playing
+ else
+ alSourcePlay(sound->source);
+ }
+ }
+
+ alcProcessContext(m_context);
+
+ // stop thread
+ if(m_playingSounds->empty())
+ {
+ unlock();
+ m_playing = false;
+ pthread_exit(NULL);
+ }
+
+ unlock();
+
+#ifdef WIN32
+ Sleep(20);
+#else
+ usleep(20000);
+#endif
+ }
+}
+
+/******************************************************************************/
+/**************************** IDevice Code ************************************/
+/******************************************************************************/
+
+bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
+{
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ if(*i == handle)
+ return true;
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ if(*i == handle)
+ return true;
+ return false;
+}
+
+AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize)
+{
+ // cannot determine how many channels or which format OpenAL uses, but
+ // it at least is able to play 16 bit stereo audio
+ specs.channels = AUD_CHANNELS_STEREO;
+ specs.format = AUD_FORMAT_S16;
+
+ m_device = alcOpenDevice(NULL);
+
+ if(!m_device)
+ AUD_THROW(AUD_ERROR_OPENAL);
+
+ // at least try to set the frequency
+ ALCint attribs[] = { ALC_FREQUENCY, 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;
+
+ alGetError();
+
+ m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
+
+ m_specs = specs;
+ m_buffersize = buffersize;
+ m_playing = false;
+
+ m_playingSounds = new std::list<AUD_OpenALHandle*>(); AUD_NEW("list")
+ m_pausedSounds = new std::list<AUD_OpenALHandle*>(); AUD_NEW("list")
+ m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
+ AUD_NEW("list")
+
+ 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_OpenALDevice::~AUD_OpenALDevice()
+{
+ AUD_OpenALHandle* sound;
+
+ lock();
+ alcSuspendContext(m_context);
+
+ // delete all playing sounds
+ while(!m_playingSounds->empty())
+ {
+ sound = *(m_playingSounds->begin());
+ alDeleteSources(1, &sound->source);
+ if(!sound->isBuffered)
+ {
+ delete sound->reader; AUD_DELETE("reader")
+ alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+ }
+ delete sound; AUD_DELETE("handle")
+ m_playingSounds->erase(m_playingSounds->begin());
+ }
+
+ // delete all paused sounds
+ while(!m_pausedSounds->empty())
+ {
+ sound = *(m_pausedSounds->begin());
+ alDeleteSources(1, &sound->source);
+ if(!sound->isBuffered)
+ {
+ delete sound->reader; AUD_DELETE("reader")
+ alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+ }
+ delete sound; AUD_DELETE("handle")
+ m_pausedSounds->erase(m_pausedSounds->begin());
+ }
+
+ // delete all buffered factories
+ while(!m_bufferedFactories->empty())
+ {
+ alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
+ delete *m_bufferedFactories->begin(); AUD_DELETE("bufferedfactory");
+ m_bufferedFactories->erase(m_bufferedFactories->begin());
+ }
+
+ alcProcessContext(m_context);
+
+ // wait for the thread to stop
+ if(m_playing)
+ {
+ unlock();
+ pthread_join(m_thread, NULL);
+ }
+ else
+ unlock();
+
+ delete m_playingSounds; AUD_DELETE("list")
+ delete m_pausedSounds; AUD_DELETE("list")
+ delete m_bufferedFactories; AUD_DELETE("list")
+
+ // quit OpenAL
+ alcMakeContextCurrent(NULL);
+ alcDestroyContext(m_context);
+ alcCloseDevice(m_device);
+
+ delete m_converter; AUD_DELETE("factory")
+
+ pthread_mutex_destroy(&m_mutex);
+}
+
+AUD_Specs AUD_OpenALDevice::getSpecs()
+{
+ return m_specs;
+}
+
+bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
+{
+ bool valid = true;
+ format = 0;
+
+ switch(specs.format)
+ {
+ case AUD_FORMAT_U8:
+ switch(specs.channels)
+ {
+ case AUD_CHANNELS_MONO:
+ format = AL_FORMAT_MONO8;
+ break;
+ case AUD_CHANNELS_STEREO:
+ format = AL_FORMAT_STEREO8;
+ break;
+ case AUD_CHANNELS_SURROUND4:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_QUAD8");
+ break;
+ }
+ case AUD_CHANNELS_SURROUND51:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_51CHN8");
+ break;
+ }
+ case AUD_CHANNELS_SURROUND61:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_61CHN8");
+ break;
+ }
+ case AUD_CHANNELS_SURROUND71:
+ if(m_useMC)
+ {
+ format = alGetEnumValue("AL_FORMAT_71CHN8");
+ break;
+ }
+ default:
+ valid = false;
+ }
+ break;
+ 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;
+}
+
+AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
+{
+ // 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
+ AUD_OpenALHandle* sound = new AUD_OpenALHandle; AUD_NEW("handle")
+ sound->keep = keep;
+ sound->current = -1;
+ sound->isBuffered = true;
+ sound->data_end = true;
+
+ alcSuspendContext(m_context);
+
+ // OpenAL playback code
+ try
+ {
+ alGenSources(1, &sound->source);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL);
+
+ try
+ {
+ alSourcei(sound->source, AL_BUFFER, (*i)->buffer);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL);
+ }
+ catch(AUD_Exception)
+ {
+ alDeleteSources(1, &sound->source);
+ throw;
+ }
+ }
+ catch(AUD_Exception)
+ {
+ delete sound; AUD_DELETE("handle")
+ alcProcessContext(m_context);
+ unlock();
+ throw;
+ }
+
+ // play sound
+ m_playingSounds->push_back(sound);
+
+ alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
+ start();
+
+ alcProcessContext(m_context);
+ unlock();
+
+ return sound;
+ }
+ }
+
+ AUD_IReader* reader = factory->createReader();
+
+ if(reader == NULL)
+ AUD_THROW(AUD_ERROR_READER);
+
+ AUD_Specs specs;
+
+ specs = reader->getSpecs();
+
+ // check format
+ bool valid = true;
+
+ if(specs.format == AUD_FORMAT_INVALID)
+ valid = false;
+ else if(specs.format == AUD_FORMAT_S24 ||
+ specs.format == AUD_FORMAT_S32 ||
+ specs.format == AUD_FORMAT_FLOAT32 ||
+ specs.format == AUD_FORMAT_FLOAT64)
+ {
+ m_converter->setReader(reader);
+ reader = m_converter->createReader();
+ specs = reader->getSpecs();
+ }
+
+ // create the handle
+ AUD_OpenALHandle* sound = new AUD_OpenALHandle; AUD_NEW("handle")
+ sound->keep = keep;
+ sound->reader = reader;
+ sound->current = 0;
+ sound->isBuffered = false;
+ sound->data_end = false;
+
+ valid &= getFormat(sound->format, specs);
+
+ if(!valid)
+ {
+ delete sound; AUD_DELETE("handle")
+ delete reader; AUD_DELETE("reader")
+ return NULL;
+ }
+
+ lock();
+ alcSuspendContext(m_context);
+
+ // OpenAL playback code
+ try
+ {
+ alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL);
+
+ try
+ {
+ sample_t* buf;
+ int length;
+
+ for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
+ {
+ length = m_buffersize;
+ reader->read(length, buf);
+ alBufferData(sound->buffers[i], sound->format, buf,
+ length * AUD_SAMPLE_SIZE(specs), specs.rate);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL);
+ }
+
+ alGenSources(1, &sound->source);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL);
+
+ try
+ {
+ alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS,
+ sound->buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL);
+ }
+ catch(AUD_Exception)
+ {
+ alDeleteSources(1, &sound->source);
+ throw;
+ }
+ }
+ catch(AUD_Exception)
+ {
+ alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+ throw;
+ }
+ }
+ catch(AUD_Exception)
+ {
+ delete sound; AUD_DELETE("handle")
+ delete reader; AUD_DELETE("reader")
+ alcProcessContext(m_context);
+ unlock();
+ throw;
+ }
+
+ // play sound
+ m_playingSounds->push_back(sound);
+ alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
+
+ start();
+
+ alcProcessContext(m_context);
+ unlock();
+
+ return sound;
+}
+
+bool AUD_OpenALDevice::pause(AUD_Handle* handle)
+{
+ // only songs that are played can be paused
+ lock();
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ m_pausedSounds->push_back(*i);
+ alSourcePause((*i)->source);
+ m_playingSounds->erase(i);
+ unlock();
+ return true;
+ }
+ }
+ unlock();
+ return false;
+}
+
+bool AUD_OpenALDevice::resume(AUD_Handle* handle)
+{
+ lock();
+
+ // only songs that are paused can be resumed
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ m_playingSounds->push_back(*i);
+ start();
+ m_pausedSounds->erase(i);
+ unlock();
+ return true;
+ }
+ }
+ unlock();
+ return false;
+}
+
+bool AUD_OpenALDevice::stop(AUD_Handle* handle)
+{
+ AUD_OpenALHandle* sound;
+
+ lock();
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ sound = *i;
+ alDeleteSources(1, &sound->source);
+ if(!sound->isBuffered)
+ {
+ delete sound->reader; AUD_DELETE("reader")
+ alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+ }
+ delete *i; AUD_DELETE("handle")
+ m_playingSounds->erase(i);
+ unlock();
+ return true;
+ }
+ }
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ sound = *i;
+ alDeleteSources(1, &sound->source);
+ if(!sound->isBuffered)
+ {
+ delete sound->reader; AUD_DELETE("reader")
+ alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
+ }
+ delete *i; AUD_DELETE("handle")
+ m_pausedSounds->erase(i);
+ unlock();
+ return true;
+ }
+ }
+ unlock();
+ return false;
+}
+
+bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
+{
+ lock();
+ if(isValid(handle))
+ {
+ ((AUD_OpenALHandle*)handle)->keep = keep;
+ unlock();
+ return true;
+ }
+ unlock();
+ return false;
+}
+
+bool AUD_OpenALDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
+{
+ lock();
+
+ bool result = false;
+
+ if(handle == 0)
+ {
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ if(!(*i)->isBuffered)
+ result |= (*i)->reader->notify(message);
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ if(!(*i)->isBuffered)
+ result |= (*i)->reader->notify(message);
+ }
+ else if(isValid(handle))
+ if(!((AUD_OpenALHandle*)handle)->isBuffered)
+ result = ((AUD_OpenALHandle*)handle)->reader->notify(message);
+ unlock();
+ return result;
+}
+
+bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
+{
+ lock();
+
+ if(isValid(handle))
+ {
+ AUD_OpenALHandle* alhandle = (AUD_OpenALHandle*)handle;
+ if(alhandle->isBuffered)
+ alSourcef(alhandle->source, AL_SEC_OFFSET, position);
+ else
+ {
+ alhandle->reader->seek((int)(position *
+ alhandle->reader->getSpecs().rate));
+ alhandle->data_end = false;
+
+ ALint info;
+
+ alGetSourcei(alhandle->source, AL_SOURCE_STATE, &info);
+
+ if(info != AL_PLAYING)
+ {
+ if(info != AL_STOPPED)
+ alSourceStop(alhandle->source);
+
+ alSourceUnqueueBuffers(alhandle->source,
+ AUD_OPENAL_CYCLE_BUFFERS,
+ alhandle->buffers);
+ if(alGetError() == AL_NO_ERROR)
+ {
+ sample_t* buf;
+ int length;
+ AUD_Specs specs = alhandle->reader->getSpecs();
+
+ for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
+ {
+ length = m_buffersize;
+ alhandle->reader->read(length, buf);
+ alBufferData(alhandle->buffers[i], alhandle->format,
+ buf, length * AUD_SAMPLE_SIZE(specs),
+ specs.rate);
+
+ if(alGetError() != AL_NO_ERROR)
+ break;
+ }
+
+ alSourceQueueBuffers(alhandle->source,
+ AUD_OPENAL_CYCLE_BUFFERS,
+ alhandle->buffers);
+ }
+
+ alSourceRewind(alhandle->source);
+ }
+ }
+ unlock();
+ return true;
+ }
+
+ unlock();
+ return false;
+}
+
+float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
+{
+ lock();
+
+ float position = 0.0;
+
+ if(isValid(handle))
+ {
+ AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
+ if(h->isBuffered)
+ alGetSourcef(h->source, AL_SEC_OFFSET, &position);
+ else
+ position = h->reader->getPosition() /
+ (float)h->reader->getSpecs().rate;
+ }
+
+ unlock();
+ return position;
+}
+
+AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle)
+{
+ lock();
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ unlock();
+ return AUD_STATUS_PLAYING;
+ }
+ }
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ unlock();
+ return AUD_STATUS_PAUSED;
+ }
+ }
+ unlock();
+ return AUD_STATUS_INVALID;
+}
+
+void AUD_OpenALDevice::lock()
+{
+ pthread_mutex_lock(&m_mutex);
+}
+
+void AUD_OpenALDevice::unlock()
+{
+ pthread_mutex_unlock(&m_mutex);
+}
+
+/******************************************************************************/
+/**************************** Capabilities Code *******************************/
+/******************************************************************************/
+
+bool AUD_OpenALDevice::checkCapability(int capability)
+{
+ return capability == AUD_CAPS_3D_DEVICE ||
+ capability == AUD_CAPS_VOLUME ||
+ capability == AUD_CAPS_SOURCE_VOLUME ||
+ capability == AUD_CAPS_SOURCE_PITCH ||
+ capability == AUD_CAPS_BUFFERED_FACTORY;
+}
+
+bool AUD_OpenALDevice::setCapability(int capability, void *value)
+{
+ switch(capability)
+ {
+ case AUD_CAPS_VOLUME:
+ alListenerf(AL_GAIN, *((float*)value));
+ return true;
+ case AUD_CAPS_SOURCE_VOLUME:
+ {
+ AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
+ lock();
+ if(isValid(caps->handle))
+ {
+ alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
+ AL_GAIN, caps->value);
+ unlock();
+ return true;
+ }
+ unlock();
+ }
+ break;
+ case AUD_CAPS_SOURCE_PITCH:
+ {
+ AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
+ lock();
+ if(isValid(caps->handle))
+ {
+ alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
+ AL_PITCH, caps->value);
+ unlock();
+ return true;
+ }
+ unlock();
+ }
+ break;
+ case AUD_CAPS_BUFFERED_FACTORY:
+ {
+ AUD_IFactory* factory = (AUD_IFactory*) value;
+
+ // load the factory into an OpenAL buffer
+ if(factory)
+ {
+ lock();
+ for(AUD_BFIterator i = m_bufferedFactories->begin();
+ i != m_bufferedFactories->end(); i++)
+ {
+ if((*i)->factory == factory)
+ {
+ unlock();
+ return true;
+ }
+ }
+ unlock();
+
+ AUD_IReader* reader = factory->createReader();
+
+ if(reader == NULL)
+ return false;
+
+ AUD_Specs specs;
+
+ specs = reader->getSpecs();
+
+ // determine format
+ bool valid = reader->getType() == AUD_TYPE_BUFFER;
+
+ if(valid)
+ {
+ if(specs.format == AUD_FORMAT_INVALID)
+ valid = false;
+ else if(specs.format == AUD_FORMAT_S24 ||
+ specs.format == AUD_FORMAT_S32 ||
+ specs.format == AUD_FORMAT_FLOAT32 ||
+ specs.format == AUD_FORMAT_FLOAT64)
+ {
+ m_converter->setReader(reader);
+ reader = m_converter->createReader();
+ specs = reader->getSpecs();
+ }
+ }
+
+ ALenum format;
+
+ if(valid)
+ valid = getFormat(format, specs);
+
+ if(!valid)
+ {
+ delete reader; AUD_DELETE("reader")
+ return false;
+ }
+
+ // load into a buffer
+ lock();
+ alcSuspendContext(m_context);
+
+ AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
+ AUD_NEW("bufferedfactory");
+ 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_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; AUD_DELETE("bufferedfactory")
+ delete reader; AUD_DELETE("reader")
+ 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();
+ AUD_DELETE("bufferedfactory");
+ m_bufferedFactories->erase(m_bufferedFactories->begin());
+ }
+ unlock();
+ }
+
+ return true;
+ }
+ break;
+ }
+ return false;
+}
+
+bool AUD_OpenALDevice::getCapability(int capability, void *value)
+{
+ switch(capability)
+ {
+ case AUD_CAPS_VOLUME:
+ alGetListenerf(AL_GAIN, (float*)value);
+ return true;
+ case AUD_CAPS_SOURCE_VOLUME:
+ {
+ AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
+ lock();
+ if(isValid(caps->handle))
+ {
+ alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
+ AL_GAIN, &caps->value);
+ unlock();
+ return true;
+ }
+ unlock();
+ }
+ break;
+ case AUD_CAPS_SOURCE_PITCH:
+ {
+ AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
+ lock();
+ if(isValid(caps->handle))
+ {
+ alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
+ AL_PITCH, &caps->value);
+ unlock();
+ return true;
+ }
+ unlock();
+ }
+ break;
+ }
+ return false;
+}
+
+/******************************************************************************/
+/**************************** 3D Device Code **********************************/
+/******************************************************************************/
+
+AUD_Handle* AUD_OpenALDevice::play3D(AUD_IFactory* factory, bool keep)
+{
+ AUD_OpenALHandle* handle = (AUD_OpenALHandle*)play(factory, keep);
+ if(handle)
+ alSourcei(handle->source, AL_SOURCE_RELATIVE, 0);
+ return handle;
+}
+
+bool AUD_OpenALDevice::updateListener(AUD_3DData &data)
+{
+ alListenerfv(AL_POSITION, (ALfloat*)data.position);
+ alListenerfv(AL_VELOCITY, (ALfloat*)data.velocity);
+ alListenerfv(AL_ORIENTATION, (ALfloat*)&(data.orientation[3]));
+
+ return true;
+}
+
+bool AUD_OpenALDevice::setSetting(AUD_3DSetting setting, float value)
+{
+ switch(setting)
+ {
+ case AUD_3DS_DISTANCE_MODEL:
+ if(value == AUD_DISTANCE_MODEL_NONE)
+ alDistanceModel(AL_NONE);
+ else if(value == AUD_DISTANCE_MODEL_INVERSE)
+ alDistanceModel(AL_INVERSE_DISTANCE);
+ else if(value == AUD_DISTANCE_MODEL_INVERSE_CLAMPED)
+ alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+ else if(value == AUD_DISTANCE_MODEL_LINEAR)
+ alDistanceModel(AL_LINEAR_DISTANCE);
+ else if(value == AUD_DISTANCE_MODEL_LINEAR_CLAMPED)
+ alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
+ else if(value == AUD_DISTANCE_MODEL_EXPONENT)
+ alDistanceModel(AL_EXPONENT_DISTANCE);
+ else if(value == AUD_DISTANCE_MODEL_EXPONENT_CLAMPED)
+ alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
+ else
+ return false;
+ return true;
+ case AUD_3DS_DOPPLER_FACTOR:
+ alDopplerFactor(value);
+ return true;
+ case AUD_3DS_SPEED_OF_SOUND:
+ alSpeedOfSound(value);
+ return true;
+ default:
+ return false;
+ }
+}
+
+float AUD_OpenALDevice::getSetting(AUD_3DSetting setting)
+{
+ switch(setting)
+ {
+ case AUD_3DS_DISTANCE_MODEL:
+ switch(alGetInteger(AL_DISTANCE_MODEL))
+ {
+ case AL_NONE:
+ return AUD_DISTANCE_MODEL_NONE;
+ 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;
+ }
+ case AUD_3DS_DOPPLER_FACTOR:
+ return alGetFloat(AL_DOPPLER_FACTOR);
+ case AUD_3DS_SPEED_OF_SOUND:
+ return alGetFloat(AL_SPEED_OF_SOUND);
+ default:
+ return std::numeric_limits<float>::quiet_NaN();
+ }
+}
+
+bool AUD_OpenALDevice::updateSource(AUD_Handle* handle, AUD_3DData &data)
+{
+ lock();
+
+ if(isValid(handle))
+ {
+ int source = ((AUD_OpenALHandle*)handle)->source;
+ alSourcefv(source, AL_POSITION, (ALfloat*)data.position);
+ alSourcefv(source, AL_VELOCITY, (ALfloat*)data.velocity);
+ alSourcefv(source, AL_DIRECTION, (ALfloat*)&(data.orientation[3]));
+ unlock();
+ return true;
+ }
+
+ unlock();
+ return false;
+}
+
+bool AUD_OpenALDevice::setSourceSetting(AUD_Handle* handle,
+ AUD_3DSourceSetting setting,
+ float value)
+{
+ lock();
+
+ bool result = false;
+
+ if(isValid(handle))
+ {
+ int source = ((AUD_OpenALHandle*)handle)->source;
+
+ switch(setting)
+ {
+ case AUD_3DSS_CONE_INNER_ANGLE:
+ alSourcef(source, AL_CONE_INNER_ANGLE, value);
+ result = true;
+ break;
+ case AUD_3DSS_CONE_OUTER_ANGLE:
+ alSourcef(source, AL_CONE_OUTER_ANGLE, value);
+ result = true;
+ break;
+ case AUD_3DSS_CONE_OUTER_GAIN:
+ alSourcef(source, AL_CONE_OUTER_GAIN, value);
+ result = true;
+ break;
+ case AUD_3DSS_IS_RELATIVE:
+ alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0);
+ result = true;
+ break;
+ case AUD_3DSS_MAX_DISTANCE:
+ alSourcef(source, AL_MAX_DISTANCE, value);
+ result = true;
+ break;
+ case AUD_3DSS_MAX_GAIN:
+ alSourcef(source, AL_MAX_GAIN, value);
+ result = true;
+ break;
+ case AUD_3DSS_MIN_GAIN:
+ alSourcef(source, AL_MIN_GAIN, value);
+ result = true;
+ break;
+ case AUD_3DSS_REFERENCE_DISTANCE:
+ alSourcef(source, AL_REFERENCE_DISTANCE, value);
+ result = true;
+ break;
+ case AUD_3DSS_ROLLOFF_FACTOR:
+ alSourcef(source, AL_ROLLOFF_FACTOR, value);
+ result = true;
+ break;
+ default:
+ break;
+ }
+ }
+
+ unlock();
+ return result;
+}
+
+float AUD_OpenALDevice::getSourceSetting(AUD_Handle* handle,
+ AUD_3DSourceSetting setting)
+{
+ float result = std::numeric_limits<float>::quiet_NaN();;
+
+ lock();
+
+ if(isValid(handle))
+ {
+ int source = ((AUD_OpenALHandle*)handle)->source;
+
+ switch(setting)
+ {
+ case AUD_3DSS_CONE_INNER_ANGLE:
+ alGetSourcef(source, AL_CONE_INNER_ANGLE, &result);
+ break;
+ case AUD_3DSS_CONE_OUTER_ANGLE:
+ alGetSourcef(source, AL_CONE_OUTER_ANGLE, &result);
+ break;
+ case AUD_3DSS_CONE_OUTER_GAIN:
+ alGetSourcef(source, AL_CONE_OUTER_GAIN, &result);
+ break;
+ case AUD_3DSS_IS_RELATIVE:
+ {
+ ALint i;
+ alGetSourcei(source, AL_SOURCE_RELATIVE, &i);
+ result = i ? 1.0 : 0.0;
+ break;
+ }
+ case AUD_3DSS_MAX_DISTANCE:
+ alGetSourcef(source, AL_MAX_DISTANCE, &result);
+ break;
+ case AUD_3DSS_MAX_GAIN:
+ alGetSourcef(source, AL_MAX_GAIN, &result);
+ break;
+ case AUD_3DSS_MIN_GAIN:
+ alGetSourcef(source, AL_MIN_GAIN, &result);
+ break;
+ case AUD_3DSS_REFERENCE_DISTANCE:
+ alGetSourcef(source, AL_REFERENCE_DISTANCE, &result);
+ break;
+ case AUD_3DSS_ROLLOFF_FACTOR:
+ alGetSourcef(source, AL_ROLLOFF_FACTOR, &result);
+ break;
+ default:
+ break;
+ }
+ }
+
+ unlock();
+ return result;
+}
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
new file mode 100644
index 00000000000..074cd3d1924
--- /dev/null
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -0,0 +1,171 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_OPENALDEVICE
+#define AUD_OPENALDEVICE
+
+#include "AUD_IDevice.h"
+#include "AUD_I3DDevice.h"
+struct AUD_OpenALHandle;
+struct AUD_OpenALBufferedFactory;
+class AUD_ConverterFactory;
+
+#include <AL/al.h>
+#include <AL/alc.h>
+#include <list>
+#include <pthread.h>
+
+/**
+ * This device plays through OpenAL.
+ */
+class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice
+{
+private:
+ /**
+ * The OpenAL device handle.
+ */
+ ALCdevice* m_device;
+
+ /**
+ * The OpenAL context.
+ */
+ ALCcontext* m_context;
+
+ /**
+ * The specification of the device.
+ */
+ AUD_Specs m_specs;
+
+ /**
+ * Whether the device has the AL_EXT_MCFORMATS extension.
+ */
+ bool m_useMC;
+
+ /**
+ * The converter factory for readers with wrong input format.
+ */
+ AUD_ConverterFactory* m_converter;
+
+ /**
+ * The list of sounds that are currently playing.
+ */
+ std::list<AUD_OpenALHandle*>* m_playingSounds;
+
+ /**
+ * The list of sounds that are currently paused.
+ */
+ std::list<AUD_OpenALHandle*>* m_pausedSounds;
+
+ /**
+ * The list of buffered factories.
+ */
+ std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
+
+ /**
+ * The mutex for locking.
+ */
+ pthread_mutex_t m_mutex;
+
+ /**
+ * The streaming thread.
+ */
+ pthread_t m_thread;
+
+ /**
+ * The condition for streaming thread wakeup.
+ */
+ bool m_playing;
+
+ /**
+ * Buffer size.
+ */
+ int m_buffersize;
+
+ /**
+ * Starts the streaming thread.
+ */
+ void start();
+
+ /**
+ * Checks if a handle is valid.
+ * \param handle The handle to check.
+ * \return Whether the handle is valid.
+ */
+ bool isValid(AUD_Handle* handle);
+
+ /**
+ * Gets the format according to the specs.
+ * \param format The variable to put the format into.
+ * \param specs The specs to read the format from.
+ * \return Whether the format is valid or not.
+ */
+ bool getFormat(ALenum &format, AUD_Specs specs);
+
+public:
+ /**
+ * Opens the OpenAL 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.
+ * \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_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+
+ /**
+ * Streaming thread main function.
+ */
+ void updateStreams();
+
+ virtual ~AUD_OpenALDevice();
+
+ virtual AUD_Specs getSpecs();
+ virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
+ virtual bool pause(AUD_Handle* handle);
+ virtual bool resume(AUD_Handle* handle);
+ virtual bool stop(AUD_Handle* handle);
+ virtual bool setKeep(AUD_Handle* handle, bool keep);
+ virtual bool sendMessage(AUD_Handle* handle, AUD_Message &message);
+ virtual bool seek(AUD_Handle* handle, float position);
+ virtual float getPosition(AUD_Handle* handle);
+ virtual AUD_Status getStatus(AUD_Handle* handle);
+ virtual void lock();
+ virtual void unlock();
+ virtual bool checkCapability(int capability);
+ virtual bool setCapability(int capability, void *value);
+ virtual bool getCapability(int capability, void *value);
+
+ virtual AUD_Handle* play3D(AUD_IFactory* factory, bool keep = false);
+ virtual bool updateListener(AUD_3DData &data);
+ virtual bool setSetting(AUD_3DSetting setting, float value);
+ virtual float getSetting(AUD_3DSetting setting);
+ virtual bool updateSource(AUD_Handle* handle, AUD_3DData &data);
+ virtual bool setSourceSetting(AUD_Handle* handle,
+ AUD_3DSourceSetting setting, float value);
+ virtual float getSourceSetting(AUD_Handle* handle,
+ AUD_3DSourceSetting setting);
+};
+
+#endif //AUD_OPENALDEVICE
diff --git a/intern/audaspace/OpenAL/Makefile b/intern/audaspace/OpenAL/Makefile
new file mode 100644
index 00000000000..4cf9f66b06c
--- /dev/null
+++ b/intern/audaspace/OpenAL/Makefile
@@ -0,0 +1,39 @@
+#
+# $Id$
+#
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = aud_openal
+DIR = $(OCGDIR)/intern/audaspace
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I../intern
+CPPFLAGS += -I.
diff --git a/intern/audaspace/SConscript b/intern/audaspace/SConscript
new file mode 100644
index 00000000000..025fa5a2379
--- /dev/null
+++ b/intern/audaspace/SConscript
@@ -0,0 +1,34 @@
+#!/usr/bin/python
+
+Import ('env')
+
+sources = env.Glob('intern/*.cpp') + env.Glob('FX/*.cpp') + env.Glob('SRC/*.cpp')
+incs = '. intern FX SRC ' + env['BF_PTHREADS_INC'] + ' ' + env['BF_LIBSAMPLERATE_INC']
+defs = []
+
+if env['WITH_BF_FFMPEG']:
+ sources += env.Glob('ffmpeg/*.cpp')
+ incs += ' ffmpeg ' + env['BF_FFMPEG_INC']
+ defs.append('WITH_FFMPEG')
+
+if env['WITH_BF_SDL']:
+ sources += env.Glob('SDL/*.cpp')
+ incs += ' SDL ' + env['BF_SDL_INC']
+ defs.append('WITH_SDL')
+
+if env['WITH_BF_OPENAL']:
+ sources += env.Glob('OpenAL/*.cpp')
+ incs += ' OpenAL ' + env['BF_OPENAL_INC']
+ defs.append('WITH_OPENAL')
+
+if env['WITH_BF_JACK']:
+ sources += env.Glob('jack/*.cpp')
+ incs += ' jack ' + env['BF_JACK_INC']
+ defs.append('WITH_JACK')
+
+if env['WITH_BF_SNDFILE']:
+ sources += env.Glob('sndfile/*.cpp')
+ incs += ' sndfile ' + env['BF_SNDFILE_INC']
+ defs.append('WITH_SNDFILE')
+
+env.BlenderLib ('bf_audaspace', sources, Split(incs), defs, libtype=['intern','player'], priority = [25,215] )
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.cpp b/intern/audaspace/SDL/AUD_SDLDevice.cpp
new file mode 100644
index 00000000000..dd443e7f5c7
--- /dev/null
+++ b/intern/audaspace/SDL/AUD_SDLDevice.cpp
@@ -0,0 +1,90 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SDLMixer.h"
+#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((sample_t*)buffer, length/AUD_SAMPLE_SIZE(device->m_specs));
+}
+
+AUD_SDLDevice::AUD_SDLDevice(AUD_Specs 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_44100;
+
+ 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);
+
+ 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
+ AUD_THROW(AUD_ERROR_SDL);
+
+ m_mixer = new AUD_SDLMixer(); AUD_NEW("mixer")
+ m_mixer->setSpecs(m_specs);
+
+ 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
new file mode 100644
index 00000000000..e2c6f7631b7
--- /dev/null
+++ b/intern/audaspace/SDL/AUD_SDLDevice.h
@@ -0,0 +1,66 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SDLDEVICE
+#define AUD_SDLDEVICE
+
+#include "AUD_SoftwareDevice.h"
+
+#include <SDL.h>
+
+/**
+ * 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);
+
+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_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+
+ /**
+ * Closes the SDL audio device.
+ */
+ virtual ~AUD_SDLDevice();
+};
+
+#endif //AUD_SDLDEVICE
diff --git a/intern/audaspace/SDL/AUD_SDLMixer.cpp b/intern/audaspace/SDL/AUD_SDLMixer.cpp
new file mode 100644
index 00000000000..cacc0c7063c
--- /dev/null
+++ b/intern/audaspace/SDL/AUD_SDLMixer.cpp
@@ -0,0 +1,83 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SDLMixer.h"
+#include "AUD_SDLMixerFactory.h"
+
+#include <SDL.h>
+
+AUD_SDLMixer::AUD_SDLMixer()
+{
+ m_factory = NULL;
+}
+
+AUD_SDLMixer::~AUD_SDLMixer()
+{
+ if(m_factory)
+ {
+ delete m_factory; AUD_DELETE("factory")
+ }
+}
+
+AUD_IReader* AUD_SDLMixer::prepare(AUD_IReader* reader)
+{
+ m_factory->setReader(reader);
+ return m_factory->createReader();
+}
+
+void AUD_SDLMixer::setSpecs(AUD_Specs specs)
+{
+ m_samplesize = AUD_SAMPLE_SIZE(specs);
+ if(m_factory)
+ {
+ delete m_factory; AUD_DELETE("factory")
+ }
+ m_factory = new AUD_SDLMixerFactory(specs); AUD_NEW("factory")
+}
+
+void AUD_SDLMixer::add(sample_t* buffer, AUD_Specs specs, int length,
+ float volume)
+{
+ AUD_SDLMixerBuffer buf;
+ buf.buffer = buffer;
+ buf.length = length;
+ buf.volume = volume;
+ m_buffers.push_back(buf);
+}
+
+void AUD_SDLMixer::superpose(sample_t* buffer, int length, float volume)
+{
+ AUD_SDLMixerBuffer buf;
+
+ while(!m_buffers.empty())
+ {
+ buf = m_buffers.front();
+ m_buffers.pop_front();
+ SDL_MixAudio((Uint8*)buffer,
+ (Uint8*)buf.buffer,
+ buf.length * m_samplesize,
+ (int)(SDL_MIX_MAXVOLUME * volume * buf.volume));
+ }
+}
diff --git a/intern/audaspace/SDL/AUD_SDLMixer.h b/intern/audaspace/SDL/AUD_SDLMixer.h
new file mode 100644
index 00000000000..2cc4e51f66d
--- /dev/null
+++ b/intern/audaspace/SDL/AUD_SDLMixer.h
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SDLMIXER
+#define AUD_SDLMIXER
+
+#include "AUD_IMixer.h"
+class AUD_SDLMixerFactory;
+#include <list>
+
+struct AUD_SDLMixerBuffer
+{
+ sample_t* buffer;
+ int length;
+ float volume;
+};
+
+/**
+ * This class is able to mix audiosignals with the help of SDL.
+ */
+class AUD_SDLMixer : public AUD_IMixer
+{
+private:
+ /**
+ * The mixer factory that prepares all readers for superposition.
+ */
+ AUD_SDLMixerFactory* m_factory;
+
+ /**
+ * The list of buffers to superpose.
+ */
+ std::list<AUD_SDLMixerBuffer> m_buffers;
+
+ /**
+ * The size of an output sample.
+ */
+ int m_samplesize;
+
+public:
+ /**
+ * Creates the mixer.
+ */
+ AUD_SDLMixer();
+
+ virtual ~AUD_SDLMixer();
+
+ virtual AUD_IReader* prepare(AUD_IReader* reader);
+ virtual void setSpecs(AUD_Specs specs);
+ virtual void add(sample_t* buffer, AUD_Specs specs, int length,
+ float volume);
+ virtual void superpose(sample_t* buffer, int length, float volume);
+};
+
+#endif //AUD_SDLMIXER
diff --git a/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp b/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp
new file mode 100644
index 00000000000..e0b0c7d3603
--- /dev/null
+++ b/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SDLMixerFactory.h"
+#include "AUD_SDLMixerReader.h"
+
+#include <cstring>
+
+AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs) :
+ AUD_MixerFactory(reader, specs) {}
+
+AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs) :
+ AUD_MixerFactory(factory, specs) {}
+
+AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_Specs specs) :
+ AUD_MixerFactory(specs) {}
+
+AUD_IReader* AUD_SDLMixerFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ AUD_Specs specs = reader->getSpecs();
+ if(memcmp(&m_specs, &specs, sizeof(AUD_Specs)) != 0)
+ {
+ try
+ {
+ reader = new AUD_SDLMixerReader(reader, m_specs);
+ AUD_NEW("reader")
+ }
+ catch(AUD_Exception e)
+ {
+ // return 0 in case SDL cannot mix the source
+ if(e.error != AUD_ERROR_SDL)
+ throw;
+ else
+ reader = NULL;
+ }
+ }
+ }
+ return reader;
+}
diff --git a/intern/audaspace/SDL/AUD_SDLMixerFactory.h b/intern/audaspace/SDL/AUD_SDLMixerFactory.h
new file mode 100644
index 00000000000..44b36d06859
--- /dev/null
+++ b/intern/audaspace/SDL/AUD_SDLMixerFactory.h
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SDLMIXERFACTORY
+#define AUD_SDLMIXERFACTORY
+
+#include "AUD_MixerFactory.h"
+
+/**
+ * This factory creates a resampling reader that uses SDL's resampling
+ * functionality which unfortunately is very very very limited.
+ */
+class AUD_SDLMixerFactory : public AUD_MixerFactory
+{
+public:
+ AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs);
+ AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs);
+ AUD_SDLMixerFactory(AUD_Specs specs);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_SDLMIXERFACTORY
diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp b/intern/audaspace/SDL/AUD_SDLMixerReader.cpp
new file mode 100644
index 00000000000..0a47e36533a
--- /dev/null
+++ b/intern/audaspace/SDL/AUD_SDLMixerReader.cpp
@@ -0,0 +1,216 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SDLMixerReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+inline Uint16 AUD_TO_SDL(AUD_SampleFormat format)
+{
+ // SDL only supports 8 and 16 bit audio
+ switch(format)
+ {
+ case AUD_FORMAT_U8:
+ return AUDIO_U8;
+ case AUD_FORMAT_S16:
+ return AUDIO_S16SYS;
+ default:
+ AUD_THROW(AUD_ERROR_SDL);
+ }
+}
+
+// greatest common divisor
+inline int gcd(int a, int b)
+{
+ int c;
+
+ // make sure a is the bigger
+ if(b > a)
+ {
+ c = b;
+ b = a;
+ a = c;
+ }
+
+ // greetings from Euclides
+ while(b != 0)
+ {
+ c = a % b;
+ a = b;
+ b = c;
+ }
+ return a;
+}
+
+AUD_SDLMixerReader::AUD_SDLMixerReader(AUD_IReader* reader,
+ AUD_Specs specs)
+{
+ if(reader == NULL)
+ AUD_THROW(AUD_ERROR_READER);
+
+ m_reader = reader;
+ m_tspecs = specs;
+ m_sspecs = reader->getSpecs();
+
+ try
+ {
+ // SDL only supports 8 and 16 bit sample formats
+ if(SDL_BuildAudioCVT(&m_cvt,
+ AUD_TO_SDL(m_sspecs.format),
+ m_sspecs.channels,
+ m_sspecs.rate,
+ AUD_TO_SDL(specs.format),
+ specs.channels,
+ specs.rate) == -1)
+ AUD_THROW(AUD_ERROR_SDL);
+ }
+ catch(AUD_Exception)
+ {
+ delete m_reader; AUD_DELETE("reader")
+ throw;
+ }
+
+ m_eor = false;
+ m_rsposition = 0;
+ m_rssize = 0;
+ m_ssize = m_sspecs.rate / gcd(specs.rate, m_sspecs.rate);
+ m_tsize = m_tspecs.rate * m_ssize / m_sspecs.rate;
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+ m_rsbuffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_SDLMixerReader::~AUD_SDLMixerReader()
+{
+ delete m_reader; AUD_DELETE("reader")
+ delete m_buffer; AUD_DELETE("buffer")
+ delete m_rsbuffer; AUD_DELETE("buffer")
+}
+
+bool AUD_SDLMixerReader::isSeekable()
+{
+ return m_reader->isSeekable();
+}
+
+void AUD_SDLMixerReader::seek(int position)
+{
+ m_reader->seek(position * m_ssize / m_tsize);
+ m_eor = false;
+}
+
+int AUD_SDLMixerReader::getLength()
+{
+ return m_reader->getLength() * m_tsize / m_ssize;
+}
+
+int AUD_SDLMixerReader::getPosition()
+{
+ return m_reader->getPosition() * m_tsize / m_ssize;
+}
+
+AUD_Specs AUD_SDLMixerReader::getSpecs()
+{
+ return m_tspecs;
+}
+
+AUD_ReaderType AUD_SDLMixerReader::getType()
+{
+ return m_reader->getType();
+}
+
+bool AUD_SDLMixerReader::notify(AUD_Message &message)
+{
+ return m_reader->notify(message);
+}
+
+void AUD_SDLMixerReader::read(int & length, sample_t* & buffer)
+{
+ // sample count for the target buffer without getting a shift
+ int tns = length + m_tsize - length % m_tsize;
+ // sample count for the source buffer without getting a shift
+ int sns = tns * m_ssize / m_tsize;
+ // target sample size
+ int tss = AUD_SAMPLE_SIZE(m_tspecs);
+ // source sample size
+ int sss = AUD_SAMPLE_SIZE(m_sspecs);
+
+ // input is output buffer
+ int buf_size = AUD_MAX(tns*tss, sns*sss);
+
+ // resize if necessary
+ if(m_rsbuffer->getSize() < buf_size)
+ m_rsbuffer->resize(buf_size, true);
+
+ if(m_buffer->getSize() < length*tss)
+ m_buffer->resize(length*tss);
+
+ buffer = m_buffer->getBuffer();
+ int size;
+ int index = 0;
+ sample_t* buf;
+
+ while(index < length)
+ {
+ if(m_rsposition == m_rssize)
+ {
+ // no more data
+ if(m_eor)
+ length = index;
+ // mix
+ else
+ {
+ // read from source
+ size = sns;
+ m_reader->read(size, buf);
+
+ // prepare
+ m_cvt.buf = m_rsbuffer->getBuffer();
+ m_cvt.len = size*sss;
+ memcpy(m_cvt.buf, buf, size*sss);
+
+ // convert
+ SDL_ConvertAudio(&m_cvt);
+
+ // end of reader
+ if(size < sns)
+ m_eor = true;
+
+ m_rsposition = 0;
+ m_rssize = size * m_tsize / m_ssize;
+ }
+ }
+
+ // size to copy
+ size = AUD_MIN(m_rssize-m_rsposition, length-index);
+
+ // copy
+ memcpy(m_buffer->getBuffer() + index * tss,
+ m_rsbuffer->getBuffer() + m_rsposition * tss,
+ size*tss);
+ m_rsposition += size;
+ index += size;
+ }
+}
diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.h b/intern/audaspace/SDL/AUD_SDLMixerReader.h
new file mode 100644
index 00000000000..56668d02171
--- /dev/null
+++ b/intern/audaspace/SDL/AUD_SDLMixerReader.h
@@ -0,0 +1,128 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SDLMIXERREADER
+#define AUD_SDLMIXERREADER
+
+#include "AUD_IReader.h"
+class AUD_Buffer;
+
+#include <SDL.h>
+
+/**
+ * This class mixes a sound source with help of the SDL library.
+ * Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
+ * well as resampling only 2^n sample rate relationships where n is a natural
+ * number.
+ * \warning Although SDL can only resample 2^n sample rate relationships, this
+ * class doesn't check for compliance, so in case of other factors,
+ * the behaviour is undefined.
+ */
+class AUD_SDLMixerReader : public AUD_IReader
+{
+private:
+ /**
+ * The reader that is being mixed.
+ */
+ AUD_IReader* m_reader;
+
+ /**
+ * The current reading position in the resampling buffer.
+ */
+ int m_rsposition;
+
+ /**
+ * The count of mixed samples in the resampling buffer.
+ */
+ int m_rssize;
+
+ /**
+ * The smallest count of source samples to get a fractionless resampling
+ * factor.
+ */
+ int m_ssize;
+
+ /**
+ * The smallest count of target samples to get a fractionless resampling
+ * factor.
+ */
+ int m_tsize;
+
+ /**
+ * The sound output buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The resampling buffer.
+ */
+ AUD_Buffer *m_rsbuffer;
+
+ /**
+ * The target specification.
+ */
+ AUD_Specs m_tspecs;
+
+ /**
+ * The sample specification of the source.
+ */
+ AUD_Specs m_sspecs;
+
+ /**
+ * Saves whether the end of the source has been reached.
+ */
+ bool m_eor;
+
+ /**
+ * The SDL_AudioCVT structure used for resampling.
+ */
+ SDL_AudioCVT m_cvt;
+
+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
+ * mixed to the target specification or if the reader is
+ * NULL.
+ */
+ AUD_SDLMixerReader(AUD_IReader* reader, AUD_Specs specs);
+ /**
+ * Destroys the reader.
+ */
+ ~AUD_SDLMixerReader();
+
+ virtual bool isSeekable();
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual AUD_ReaderType getType();
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SDLMIXERREADER
diff --git a/intern/SoundSystem/sdl/Makefile b/intern/audaspace/SDL/Makefile
index 669d7110797..02a4068f3dc 100644
--- a/intern/SoundSystem/sdl/Makefile
+++ b/intern/audaspace/SDL/Makefile
@@ -28,16 +28,14 @@
#
#
-LIBNAME = SDLSoundSystem
-DIR = $(OCGDIR)/intern/$(LIBNAME)
+LIBNAME = aud_sdl
+DIR = $(OCGDIR)/intern/audaspace
include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
CPPFLAGS += $(NAN_SDLCFLAGS)
-CPPFLAGS += -I$(NAN_STRING)/include
-CPPFLAGS += -I$(NAN_MOTO)/include
CPPFLAGS += -I../intern
CPPFLAGS += -I..
CPPFLAGS += -I.
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
new file mode 100644
index 00000000000..bcace340b24
--- /dev/null
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
@@ -0,0 +1,53 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SRCResampleFactory.h"
+#include "AUD_SRCResampleReader.h"
+
+AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IReader* reader,
+ AUD_Specs specs) :
+ AUD_ResampleFactory(reader, specs) {}
+
+AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
+ AUD_Specs specs) :
+ AUD_ResampleFactory(factory, specs) {}
+
+AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Specs specs) :
+ AUD_ResampleFactory(specs) {}
+
+AUD_IReader* AUD_SRCResampleFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ if(reader->getSpecs().rate != m_specs.rate)
+ {
+ reader = new AUD_SRCResampleReader(reader, m_specs);
+ AUD_NEW("reader")
+ }
+ }
+ return reader;
+}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.h b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
new file mode 100644
index 00000000000..c23c1d2c82e
--- /dev/null
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
@@ -0,0 +1,46 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SRCRESAMPLEFACTORY
+#define AUD_SRCRESAMPLEFACTORY
+
+#include "AUD_ResampleFactory.h"
+
+/**
+ * This factory creates a resampling reader that uses libsamplerate for
+ * resampling.
+ * \note The format of the input must be float.
+ */
+class AUD_SRCResampleFactory : public AUD_ResampleFactory
+{
+public:
+ AUD_SRCResampleFactory(AUD_IReader* reader, AUD_Specs specs);
+ AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_Specs specs);
+ AUD_SRCResampleFactory(AUD_Specs specs);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_SRCRESAMPLEFACTORY
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
new file mode 100644
index 00000000000..f7564d3c010
--- /dev/null
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
@@ -0,0 +1,119 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SRCResampleReader.h"
+#include "AUD_Buffer.h"
+
+#include <math.h>
+#include <cstring>
+#include <stdio.h>
+
+static long src_callback(void *cb_data, float **data)
+{
+ return ((AUD_SRCResampleReader*)cb_data)->doCallback(data);
+}
+
+AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
+ AUD_Specs specs) :
+ AUD_EffectReader(reader)
+{
+ m_sspecs = reader->getSpecs();
+
+ if(m_sspecs.format != AUD_FORMAT_FLOAT32)
+ {
+ delete m_reader; AUD_DELETE("reader")
+ AUD_THROW(AUD_ERROR_READER);
+ }
+
+ m_tspecs = specs;
+ m_tspecs.channels = m_sspecs.channels;
+ m_tspecs.format = m_sspecs.format;
+ m_factor = (double)m_tspecs.rate / (double)m_sspecs.rate;
+
+ int error;
+ m_src = src_callback_new(src_callback,
+ SRC_SINC_MEDIUM_QUALITY,
+ m_sspecs.channels,
+ &error,
+ this);
+
+ if(!m_src)
+ {
+ // XXX printf("%s\n", src_strerror(error));
+ delete m_reader; AUD_DELETE("reader")
+ AUD_THROW(AUD_ERROR_READER);
+ }
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_SRCResampleReader::~AUD_SRCResampleReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+
+ src_delete(m_src);
+}
+
+long AUD_SRCResampleReader::doCallback(float** data)
+{
+ int length = m_buffer->getSize() / 4 / m_tspecs.channels;
+ sample_t* buffer;
+
+ m_reader->read(length, buffer);
+
+ *data = (float*)buffer;
+ return length;
+}
+
+void AUD_SRCResampleReader::seek(int position)
+{
+ m_reader->seek(position / m_factor);
+ src_reset(m_src);
+}
+
+int AUD_SRCResampleReader::getLength()
+{
+ return m_reader->getLength() * m_factor;
+}
+
+int AUD_SRCResampleReader::getPosition()
+{
+ return m_reader->getPosition() * m_factor;
+}
+
+AUD_Specs AUD_SRCResampleReader::getSpecs()
+{
+ return m_tspecs;
+}
+
+void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
+{
+ if(m_buffer->getSize() < length * m_tspecs.channels * 4)
+ m_buffer->resize(length * m_tspecs.channels * 4);
+
+ buffer = m_buffer->getBuffer();
+
+ length = src_callback_read(m_src, m_factor, length, (float*)buffer);
+}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.h b/intern/audaspace/SRC/AUD_SRCResampleReader.h
new file mode 100644
index 00000000000..1bacdb3965c
--- /dev/null
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.h
@@ -0,0 +1,102 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SRCRESAMPLEREADER
+#define AUD_SRCRESAMPLEREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+#include <samplerate.h>
+
+/**
+ * This class mixes a sound source with help of the SDL library.
+ * Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
+ * well as resampling only 2^n sample rate relationships where n is a natural
+ * number.
+ * \warning Although SDL can only resample 2^n sample rate relationships, this
+ * class doesn't check for compliance, so in case of other factors,
+ * the behaviour is undefined.
+ */
+class AUD_SRCResampleReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The resampling factor.
+ */
+ double m_factor;
+
+ /**
+ * The sound output buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The target specification.
+ */
+ AUD_Specs m_tspecs;
+
+ /**
+ * The sample specification of the source.
+ */
+ AUD_Specs m_sspecs;
+
+ /**
+ * The src state structure.
+ */
+ SRC_STATE* m_src;
+
+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
+ * mixed to the target specification or if the reader is
+ * NULL.
+ */
+ AUD_SRCResampleReader(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();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SRCRESAMPLEREADER
diff --git a/intern/SoundSystem/openal/Makefile b/intern/audaspace/SRC/Makefile
index b28ab628d4c..5cf5f55b11f 100644
--- a/intern/SoundSystem/openal/Makefile
+++ b/intern/audaspace/SRC/Makefile
@@ -28,17 +28,17 @@
#
#
-LIBNAME = OpenALSoundSystem
-DIR = $(OCGDIR)/intern/$(LIBNAME)
+LIBNAME = aud_src
+DIR = $(OCGDIR)/intern/audaspace
include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-CPPFLAGS += -I$(NAN_OPENAL)/include
-CPPFLAGS += -I$(NAN_STRING)/include
-CPPFLAGS += -I$(NAN_MOTO)/include
+CPPFLAGS += -I$(LCGDIR)/samplerate/include/
+CPPFLAGS += -I../ffmpeg
+CPPFLAGS += -I../FX
+CPPFLAGS += -I../SDL
CPPFLAGS += -I../intern
CPPFLAGS += -I..
CPPFLAGS += -I.
-CPPFLAGS += -I../sdl
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
new file mode 100644
index 00000000000..f67c819ff10
--- /dev/null
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FFMPEGFactory.h"
+#include "AUD_FFMPEGReader.h"
+#include "AUD_Buffer.h"
+
+AUD_FFMPEGFactory::AUD_FFMPEGFactory(const char* filename)
+{
+ if(filename != NULL)
+ {
+ m_filename = new char[strlen(filename)+1]; AUD_NEW("string")
+ strcpy(m_filename, filename);
+ }
+ else
+ m_filename = NULL;
+}
+
+AUD_FFMPEGFactory::AUD_FFMPEGFactory(unsigned char* buffer, int size)
+{
+ m_filename = NULL;
+ m_buffer = AUD_Reference<AUD_Buffer>(new AUD_Buffer(size));
+ memcpy(m_buffer.get()->getBuffer(), buffer, size);
+}
+
+AUD_FFMPEGFactory::~AUD_FFMPEGFactory()
+{
+ if(m_filename)
+ {
+ delete[] m_filename; AUD_DELETE("string")
+ }
+}
+
+AUD_IReader* AUD_FFMPEGFactory::createReader()
+{
+ AUD_IReader* reader;
+ if(m_filename)
+ reader = new AUD_FFMPEGReader(m_filename);
+ else
+ reader = new AUD_FFMPEGReader(m_buffer);
+ AUD_NEW("reader")
+ return reader;
+}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
new file mode 100644
index 00000000000..22560303a73
--- /dev/null
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
@@ -0,0 +1,73 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_FFMPEGFACTORY
+#define AUD_FFMPEGFACTORY
+
+#include "AUD_IFactory.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+/**
+ * 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.
+ */
+ char* m_filename;
+
+ /**
+ * The buffer to read from.
+ */
+ AUD_Reference<AUD_Buffer> m_buffer;
+
+public:
+ /**
+ * Creates a new factory.
+ * \param filename The sound file path.
+ */
+ AUD_FFMPEGFactory(const char* filename);
+
+ /**
+ * Creates a new factory.
+ * \param buffer The buffer to read from.
+ * \param size The size of the buffer.
+ */
+ AUD_FFMPEGFactory(unsigned char* buffer, int size);
+
+ /**
+ * Destroys the factory.
+ */
+ ~AUD_FFMPEGFactory();
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_FFMPEGFACTORY
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
new file mode 100644
index 00000000000..0384ba5e0e6
--- /dev/null
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -0,0 +1,388 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+// needed for INT64_C
+#define __STDC_CONSTANT_MACROS
+
+#include "AUD_FFMPEGReader.h"
+#include "AUD_Buffer.h"
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+}
+
+// This function transforms a FFMPEG SampleFormat to our own sample format
+static inline AUD_SampleFormat FFMPEG_TO_AUD(SampleFormat fmt)
+{
+ switch(fmt)
+ {
+ case SAMPLE_FMT_U8:
+ return AUD_FORMAT_U8;
+ case SAMPLE_FMT_S16:
+ return AUD_FORMAT_S16;
+ case SAMPLE_FMT_S32:
+ return AUD_FORMAT_S32;
+ case SAMPLE_FMT_FLT:
+ return AUD_FORMAT_FLOAT32;
+ case SAMPLE_FMT_DBL:
+ return AUD_FORMAT_FLOAT64;
+ default:
+ return AUD_FORMAT_INVALID;
+ }
+}
+
+int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
+{
+ // 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;
+
+ // 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;
+ /*read_length = avcodec_decode_audio3(m_codecCtx,
+ (int16_t*)(buffer->getBuffer()+buf_pos),
+ &data_size,
+ packet);*/
+ read_length = avcodec_decode_audio2(m_codecCtx,
+ (int16_t*)(buffer->getBuffer()+buf_pos),
+ &data_size,
+ audio_pkg_data,
+ audio_pkg_size);
+
+ buf_pos += data_size;
+
+ // read error, next packet!
+ if(read_length < 0)
+ break;
+
+ // move packet parameters
+ audio_pkg_data += read_length;
+ audio_pkg_size -= read_length;
+ }
+
+ return buf_pos;
+}
+
+AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
+{
+ m_position = 0;
+ m_pkgbuf_left = 0;
+ m_byteiocontext = NULL;
+
+ // open file
+ if(av_open_input_file(&m_formatCtx, filename, NULL, 0, NULL)!=0)
+ AUD_THROW(AUD_ERROR_FILE);
+
+ try
+ {
+ if(av_find_stream_info(m_formatCtx)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
+
+ // 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 == CODEC_TYPE_AUDIO)
+ && (m_stream < 0))
+ {
+ m_stream=i;
+ break;
+ }
+ if(m_stream == -1)
+ AUD_THROW(AUD_ERROR_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(AUD_ERROR_FFMPEG);
+
+ if(avcodec_open(m_codecCtx, aCodec)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
+
+ // XXX this prints file information to stdout:
+ //dump_format(m_formatCtx, 0, filename, 0);
+
+ m_specs.channels = (AUD_Channels) m_codecCtx->channels;
+ m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
+ m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
+ }
+ catch(AUD_Exception)
+ {
+ av_close_input_file(m_formatCtx);
+ throw;
+ }
+
+ // last but not least if there hasn't been any error, create the buffers
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+ m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
+ AUD_NEW("buffer")
+}
+
+AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
+{
+ m_position = 0;
+ m_pkgbuf_left = 0;
+ m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
+ AUD_NEW("byteiocontext")
+ m_membuffer = buffer;
+
+ if(init_put_byte(m_byteiocontext, buffer.get()->getBuffer(), buffer.get()->getSize(), 0,
+ NULL, NULL, NULL, NULL) != 0)
+ AUD_THROW(AUD_ERROR_FILE);
+
+ AVProbeData probe_data;
+ probe_data.filename = "";
+ probe_data.buf = buffer.get()->getBuffer();
+ probe_data.buf_size = buffer.get()->getSize();
+ AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
+
+ // open stream
+ if(av_open_input_stream(&m_formatCtx, m_byteiocontext, "", fmt, NULL)!=0)
+ AUD_THROW(AUD_ERROR_FILE);
+
+ try
+ {
+ if(av_find_stream_info(m_formatCtx)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
+
+ // 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 == CODEC_TYPE_AUDIO)
+ && (m_stream < 0))
+ {
+ m_stream=i;
+ break;
+ }
+ if(m_stream == -1)
+ AUD_THROW(AUD_ERROR_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(AUD_ERROR_FFMPEG);
+
+ if(avcodec_open(m_codecCtx, aCodec)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
+
+ // XXX this prints stream information to stdout:
+ //dump_format(m_formatCtx, 0, NULL, 0);
+
+ m_specs.channels = (AUD_Channels) m_codecCtx->channels;
+ m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
+ m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
+ }
+ catch(AUD_Exception)
+ {
+ av_close_input_stream(m_formatCtx);
+ av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
+ throw;
+ }
+
+ // last but not least if there hasn't been any error, create the buffers
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+ m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
+ AUD_NEW("buffer")
+}
+
+AUD_FFMPEGReader::~AUD_FFMPEGReader()
+{
+ avcodec_close(m_codecCtx);
+
+ if(m_byteiocontext)
+ {
+ av_close_input_stream(m_formatCtx);
+ av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
+ }
+ else
+ av_close_input_file(m_formatCtx);
+
+ delete m_buffer; AUD_DELETE("buffer")
+ delete m_pkgbuf; AUD_DELETE("buffer")
+}
+
+bool AUD_FFMPEGReader::isSeekable()
+{
+ return true;
+}
+
+void AUD_FFMPEGReader::seek(int position)
+{
+ if(position >= 0)
+ {
+ // a value < 0 tells us that seeking failed
+ if(av_seek_frame(m_formatCtx,
+ -1,
+ (uint64_t)(((uint64_t)position *
+ (uint64_t)AV_TIME_BASE) /
+ (uint64_t)m_specs.rate),
+ 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 *
+ av_q2d(m_formatCtx->streams[m_stream]->time_base) *
+ m_specs.rate;
+
+ if(m_position < position)
+ {
+ sample_t* buf;
+ int length = position - m_position;
+ read(length, buf);
+ }
+ }
+ }
+ av_free_packet(&packet);
+ }
+ }
+ else
+ {
+ // Seeking failed, do nothing.
+ }
+ }
+}
+
+int AUD_FFMPEGReader::getLength()
+{
+ // return approximated remaning size
+ return (int)((m_formatCtx->duration * m_codecCtx->sample_rate)
+ / AV_TIME_BASE)-m_position;
+}
+
+int AUD_FFMPEGReader::getPosition()
+{
+ return m_position;
+}
+
+AUD_Specs AUD_FFMPEGReader::getSpecs()
+{
+ return m_specs;
+}
+
+AUD_ReaderType AUD_FFMPEGReader::getType()
+{
+ return AUD_TYPE_STREAM;
+}
+
+bool AUD_FFMPEGReader::notify(AUD_Message &message)
+{
+ return false;
+}
+
+void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
+{
+ // read packages and decode them
+ AVPacket packet;
+ int data_size = 0;
+ int pkgbuf_pos;
+ int left = length;
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+
+ // resize output buffer if necessary
+ if(m_buffer->getSize() < length*sample_size)
+ m_buffer->resize(length*sample_size);
+
+ buffer = m_buffer->getBuffer();
+ 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);
+ memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
+ buffer += data_size;
+ 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);
+ memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
+ buffer += data_size;
+ 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(), m_pkgbuf->getBuffer()+data_size,
+ pkgbuf_pos-data_size);
+ }
+
+ buffer = m_buffer->getBuffer();
+
+ if(left > 0)
+ length -= left;
+ m_position += length;
+}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
new file mode 100644
index 00000000000..6e303934f36
--- /dev/null
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
@@ -0,0 +1,139 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_FFMPEGREADER
+#define AUD_FFMPEGREADER
+
+#include "AUD_IReader.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+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.
+ * \warning Playback of an ogg with some outdated ffmpeg versions results in a
+ * segfault on windows.
+ */
+class AUD_FFMPEGReader : public AUD_IReader
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The specification of the audio data.
+ */
+ AUD_Specs 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 ByteIOContext to read the data from.
+ */
+ ByteIOContext* m_byteiocontext;
+
+ /**
+ * The stream ID in the file.
+ */
+ int m_stream;
+
+ /**
+ * The memory file to read from, only saved to keep the buffer alive.
+ */
+ AUD_Reference<AUD_Buffer> m_membuffer;
+
+ /**
+ * 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);
+
+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(const char* 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(AUD_Reference<AUD_Buffer> buffer);
+
+ /**
+ * Destroys the reader and closes the file.
+ */
+ virtual ~AUD_FFMPEGReader();
+
+ virtual bool isSeekable();
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual AUD_ReaderType getType();
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_FFMPEGREADER
diff --git a/intern/SoundSystem/intern/Makefile b/intern/audaspace/ffmpeg/Makefile
index 7684b6b0bca..492ac83f532 100644
--- a/intern/SoundSystem/intern/Makefile
+++ b/intern/audaspace/ffmpeg/Makefile
@@ -28,17 +28,14 @@
#
#
-LIBNAME = SoundSystem
-DIR = $(OCGDIR)/intern/SoundSystem
+LIBNAME = aud_ffmpeg
+DIR = $(OCGDIR)/intern/audaspace
include nan_compile.mk
CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
-CPPFLAGS += -I$(NAN_STRING)/include
-CPPFLAGS += -I$(NAN_MOTO)/include
-CPPFLAGS += -I../../../source/blender/include
-CPPFLAGS += -I../dummy
-CPPFLAGS += -I../openal
+CPPFLAGS += $(NAN_FFMPEGCFLAGS)
+CPPFLAGS += -I../intern
CPPFLAGS += -I..
CPPFLAGS += -I.
diff --git a/intern/audaspace/intern/AUD_Buffer.cpp b/intern/audaspace/intern/AUD_Buffer.cpp
new file mode 100644
index 00000000000..71deae0e87e
--- /dev/null
+++ b/intern/audaspace/intern/AUD_Buffer.cpp
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_Buffer.h"
+#include "AUD_Space.h"
+
+#include <cstring>
+#include <stdlib.h>
+
+#define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
+
+AUD_Buffer::AUD_Buffer(int size)
+{
+ m_size = size;
+ m_buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
+}
+
+AUD_Buffer::~AUD_Buffer()
+{
+ free(m_buffer); AUD_DELETE("buffer")
+}
+
+sample_t* AUD_Buffer::getBuffer()
+{
+ return AUD_ALIGN(m_buffer);
+}
+
+int AUD_Buffer::getSize()
+{
+ return m_size;
+}
+
+void AUD_Buffer::resize(int size, bool keep)
+{
+ sample_t* buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
+
+ // copy old data over if wanted
+ if(keep)
+ memcpy(AUD_ALIGN(buffer), AUD_ALIGN(m_buffer), AUD_MIN(size, m_size));
+
+ free(m_buffer); AUD_DELETE("buffer")
+
+ m_buffer = buffer;
+ m_size = size;
+}
diff --git a/intern/audaspace/intern/AUD_Buffer.h b/intern/audaspace/intern/AUD_Buffer.h
new file mode 100644
index 00000000000..64959b03799
--- /dev/null
+++ b/intern/audaspace/intern/AUD_Buffer.h
@@ -0,0 +1,75 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_BUFFER
+#define AUD_BUFFER
+
+#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.
+ sample_t* m_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();
+
+ /**
+ * Returns the size of the buffer in bytes.
+ */
+ int getSize();
+
+ /**
+ * 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);
+};
+
+#endif //AUD_BUFFER
diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp
new file mode 100644
index 00000000000..47bf5d3d171
--- /dev/null
+++ b/intern/audaspace/intern/AUD_BufferReader.cpp
@@ -0,0 +1,91 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_BufferReader.h"
+#include "AUD_Buffer.h"
+#include "AUD_Space.h"
+
+AUD_BufferReader::AUD_BufferReader(AUD_Reference<AUD_Buffer> buffer,
+ AUD_Specs specs)
+{
+ m_position = 0;
+ m_buffer = buffer;
+ m_specs = specs;
+}
+
+bool AUD_BufferReader::isSeekable()
+{
+ return true;
+}
+
+void AUD_BufferReader::seek(int position)
+{
+ if(position < 0)
+ m_position = 0;
+ else if(position > m_buffer.get()->getSize() / AUD_SAMPLE_SIZE(m_specs))
+ m_position = m_buffer.get()->getSize() / AUD_SAMPLE_SIZE(m_specs);
+ else
+ m_position = position;
+}
+
+int AUD_BufferReader::getLength()
+{
+ return m_buffer.get()->getSize()/AUD_SAMPLE_SIZE(m_specs);
+}
+
+int AUD_BufferReader::getPosition()
+{
+ return m_position;
+}
+
+AUD_Specs AUD_BufferReader::getSpecs()
+{
+ return m_specs;
+}
+
+AUD_ReaderType AUD_BufferReader::getType()
+{
+ return AUD_TYPE_BUFFER;
+}
+
+bool AUD_BufferReader::notify(AUD_Message &message)
+{
+ return false;
+}
+
+void AUD_BufferReader::read(int & length, sample_t* & buffer)
+{
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+
+ buffer = m_buffer.get()->getBuffer()+m_position*sample_size;
+
+ // in case the end of the buffer is reach
+ if(m_buffer.get()->getSize() < (m_position+length)*sample_size)
+ length = m_buffer.get()->getSize()/sample_size-m_position;
+
+ if(length < 0)
+ length = 0;
+ m_position += length;
+}
diff --git a/intern/audaspace/intern/AUD_BufferReader.h b/intern/audaspace/intern/AUD_BufferReader.h
new file mode 100644
index 00000000000..f2d8ff6b57d
--- /dev/null
+++ b/intern/audaspace/intern/AUD_BufferReader.h
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_BUFFERREADER
+#define AUD_BUFFERREADER
+
+#include "AUD_IReader.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+/**
+ * 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.
+ */
+ AUD_Reference<AUD_Buffer> m_buffer;
+
+ /**
+ * The specification of the sample data in the buffer.
+ */
+ AUD_Specs m_specs;
+
+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(AUD_Reference<AUD_Buffer> buffer, AUD_Specs specs);
+
+ virtual bool isSeekable();
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual AUD_ReaderType getType();
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_BUFFERREADER
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
new file mode 100644
index 00000000000..afa1568d6dc
--- /dev/null
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -0,0 +1,579 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_NULLDevice.h"
+#include "AUD_I3DDevice.h"
+#include "AUD_FileFactory.h"
+#include "AUD_StreamBufferFactory.h"
+#include "AUD_DelayFactory.h"
+#include "AUD_LimiterFactory.h"
+#include "AUD_PingPongFactory.h"
+#include "AUD_LoopFactory.h"
+#include "AUD_ReadDevice.h"
+#include "AUD_SourceCaps.h"
+#include "AUD_IReader.h"
+
+#ifdef WITH_SDL
+#include "AUD_SDLDevice.h"
+#include "AUD_FloatMixer.h"
+#endif
+
+#ifdef WITH_OPENAL
+#include "AUD_OpenALDevice.h"
+#endif
+
+#ifdef WITH_JACK
+#include "AUD_JackDevice.h"
+#endif
+
+#ifdef WITH_FFMPEG
+extern "C" {
+#include <libavformat/avformat.h>
+}
+#endif
+
+#include <assert.h>
+
+typedef AUD_IFactory AUD_Sound;
+typedef AUD_ReadDevice AUD_Device;
+
+#define AUD_CAPI_IMPLEMENTATION
+#include "AUD_C-API.h"
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+static AUD_IDevice* AUD_device = NULL;
+static int AUD_available_devices[4];
+static AUD_I3DDevice* AUD_3ddevice = NULL;
+
+int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
+{
+#ifdef WITH_FFMPEG
+ av_register_all();
+#endif
+ AUD_IDevice* dev = NULL;
+
+ if(AUD_device)
+ AUD_exit();
+
+ try
+ {
+ switch(device)
+ {
+ case AUD_NULL_DEVICE:
+ dev = new AUD_NULLDevice();
+ break;
+#ifdef WITH_SDL
+ case AUD_SDL_DEVICE:
+ {
+ dev = new AUD_SDLDevice(specs, buffersize);
+ AUD_FloatMixer* mixer = new AUD_FloatMixer();
+ ((AUD_SDLDevice*)dev)->setMixer(mixer);
+ break;
+ }
+#endif
+#ifdef WITH_OPENAL
+ case AUD_OPENAL_DEVICE:
+ dev = new AUD_OpenALDevice(specs, buffersize);
+ break;
+#endif
+#ifdef WITH_JACK
+ case AUD_JACK_DEVICE:
+ dev = new AUD_JackDevice(specs);
+ break;
+#endif
+ default:
+ return false;
+ }
+
+ AUD_device = dev;
+ if(AUD_device->checkCapability(AUD_CAPS_3D_DEVICE))
+ AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
+
+ return true;
+ }
+ catch(AUD_Exception)
+ {
+ return false;
+ }
+}
+
+int* AUD_enumDevices()
+{
+ int i = 0;
+#ifdef WITH_SDL
+ AUD_available_devices[i++] = AUD_SDL_DEVICE;
+#endif
+#ifdef WITH_OPENAL
+ AUD_available_devices[i++] = AUD_OPENAL_DEVICE;
+#endif
+#ifdef WITH_JACK
+ AUD_available_devices[i++] = AUD_JACK_DEVICE;
+#endif
+ AUD_available_devices[i++] = AUD_NULL_DEVICE;
+ return AUD_available_devices;
+}
+
+void AUD_exit()
+{
+ if(AUD_device)
+ {
+ delete AUD_device;
+ AUD_device = NULL;
+ AUD_3ddevice = NULL;
+ }
+}
+
+void AUD_lock()
+{
+ assert(AUD_device);
+ AUD_device->lock();
+}
+
+void AUD_unlock()
+{
+ assert(AUD_device);
+ AUD_device->unlock();
+}
+
+AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
+{
+ assert(sound);
+
+ AUD_IReader* reader = sound->createReader();
+
+ AUD_SoundInfo info;
+
+ if(reader)
+ {
+ info.specs = reader->getSpecs();
+ info.length = reader->getLength() / (float) info.specs.rate;
+ }
+ else
+ {
+ info.specs.channels = AUD_CHANNELS_INVALID;
+ info.specs.format = AUD_FORMAT_INVALID;
+ info.specs.rate = AUD_RATE_INVALID;
+ info.length = 0.0;
+ }
+
+ return info;
+}
+
+AUD_Sound* AUD_load(const char* filename)
+{
+ assert(filename);
+ return new AUD_FileFactory(filename);
+}
+
+AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
+{
+ assert(buffer);
+ return new AUD_FileFactory(buffer, size);
+}
+
+AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_StreamBufferFactory(sound);
+ }
+ catch(AUD_Exception)
+ {
+ return NULL;
+ }
+}
+
+AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_DelayFactory(sound, delay);
+ }
+ catch(AUD_Exception)
+ {
+ return NULL;
+ }
+}
+
+extern AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_LimiterFactory(sound, start, end);
+ }
+ catch(AUD_Exception)
+ {
+ return NULL;
+ }
+}
+
+AUD_Sound* AUD_pingpongSound(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_PingPongFactory(sound);
+ }
+ catch(AUD_Exception)
+ {
+ return NULL;
+ }
+}
+
+AUD_Sound* AUD_loopSound(AUD_Sound* sound)
+{
+ assert(sound);
+
+ try
+ {
+ return new AUD_LoopFactory(sound);
+ }
+ catch(AUD_Exception)
+ {
+ return NULL;
+ }
+}
+
+int AUD_stopLoop(AUD_Handle* handle)
+{
+ if(handle)
+ {
+ AUD_Message message;
+ message.type = AUD_MSG_LOOP;
+ message.loopcount = 0;
+
+ try
+ {
+ return AUD_device->sendMessage(handle, message);
+ }
+ catch(AUD_Exception)
+ {
+ }
+ }
+ return false;
+}
+
+void AUD_unload(AUD_Sound* sound)
+{
+ assert(sound);
+ delete sound;
+}
+
+AUD_Handle* AUD_play(AUD_Sound* sound, int keep)
+{
+ assert(AUD_device);
+ assert(sound);
+ try
+ {
+ return AUD_device->play(sound, keep);
+ }
+ catch(AUD_Exception)
+ {
+ return NULL;
+ }
+}
+
+int AUD_pause(AUD_Handle* handle)
+{
+ assert(AUD_device);
+ return AUD_device->pause(handle);
+}
+
+int AUD_resume(AUD_Handle* handle)
+{
+ assert(AUD_device);
+ return AUD_device->resume(handle);
+}
+
+int AUD_stop(AUD_Handle* handle)
+{
+ if(AUD_device)
+ return AUD_device->stop(handle);
+ return false;
+}
+
+int AUD_setKeep(AUD_Handle* handle, int keep)
+{
+ assert(AUD_device);
+ return AUD_device->setKeep(handle, keep);
+}
+
+int AUD_seek(AUD_Handle* handle, float seekTo)
+{
+ assert(AUD_device);
+ return AUD_device->seek(handle, seekTo);
+}
+
+float AUD_getPosition(AUD_Handle* handle)
+{
+ assert(AUD_device);
+ return AUD_device->getPosition(handle);
+}
+
+AUD_Status AUD_getStatus(AUD_Handle* handle)
+{
+ assert(AUD_device);
+ return AUD_device->getStatus(handle);
+}
+
+AUD_Handle* AUD_play3D(AUD_Sound* sound, int keep)
+{
+ assert(AUD_device);
+ assert(sound);
+
+ try
+ {
+ if(AUD_3ddevice)
+ return AUD_3ddevice->play3D(sound, keep);
+ else
+ return AUD_device->play(sound, keep);
+ }
+ catch(AUD_Exception)
+ {
+ return NULL;
+ }
+}
+
+int AUD_updateListener(AUD_3DData* data)
+{
+ assert(AUD_device);
+ assert(data);
+
+ try
+ {
+ if(AUD_3ddevice)
+ return AUD_3ddevice->updateListener(*data);
+ }
+ catch(AUD_Exception)
+ {
+ }
+ return false;
+}
+
+int AUD_set3DSetting(AUD_3DSetting setting, float value)
+{
+ assert(AUD_device);
+
+ try
+ {
+ if(AUD_3ddevice)
+ return AUD_3ddevice->setSetting(setting, value);
+ }
+ catch(AUD_Exception)
+ {
+ }
+ return false;
+}
+
+float AUD_get3DSetting(AUD_3DSetting setting)
+{
+ assert(AUD_device);
+
+ try
+ {
+ if(AUD_3ddevice)
+ return AUD_3ddevice->getSetting(setting);
+ }
+ catch(AUD_Exception)
+ {
+ }
+ return 0.0;
+}
+
+int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data)
+{
+ if(handle)
+ {
+ assert(AUD_device);
+ assert(data);
+
+ try
+ {
+ if(AUD_3ddevice)
+ return AUD_3ddevice->updateSource(handle, *data);
+ }
+ catch(AUD_Exception)
+ {
+ }
+ }
+ return false;
+}
+
+int AUD_set3DSourceSetting(AUD_Handle* handle,
+ AUD_3DSourceSetting setting, float value)
+{
+ if(handle)
+ {
+ assert(AUD_device);
+
+ try
+ {
+ if(AUD_3ddevice)
+ return AUD_3ddevice->setSourceSetting(handle, setting, value);
+ }
+ catch(AUD_Exception)
+ {
+ }
+ }
+ return false;
+}
+
+float AUD_get3DSourceSetting(AUD_Handle* handle, AUD_3DSourceSetting setting)
+{
+ if(handle)
+ {
+ assert(AUD_device);
+
+ try
+ {
+ if(AUD_3ddevice)
+ return AUD_3ddevice->getSourceSetting(handle, setting);
+ }
+ catch(AUD_Exception)
+ {
+ }
+ }
+ return 0.0;
+}
+
+int AUD_setSoundVolume(AUD_Handle* handle, float volume)
+{
+ if(handle)
+ {
+ assert(AUD_device);
+ AUD_SourceCaps caps;
+ caps.handle = handle;
+ caps.value = volume;
+
+ try
+ {
+ return AUD_device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
+ }
+ catch(AUD_Exception) {}
+ }
+ return false;
+}
+
+int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
+{
+ if(handle)
+ {
+ assert(AUD_device);
+ AUD_SourceCaps caps;
+ caps.handle = handle;
+ caps.value = pitch;
+
+ try
+ {
+ return AUD_device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps);
+ }
+ catch(AUD_Exception) {}
+ }
+ return false;
+}
+
+AUD_Device* AUD_openReadDevice(AUD_Specs specs)
+{
+ try
+ {
+ return new AUD_ReadDevice(specs);
+ }
+ catch(AUD_Exception)
+ {
+ return NULL;
+ }
+}
+
+AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound)
+{
+ assert(device);
+ assert(sound);
+
+ try
+ {
+ return device->play(sound);
+ }
+ catch(AUD_Exception)
+ {
+ return NULL;
+ }
+}
+
+int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,
+ float volume)
+{
+ if(handle)
+ {
+ assert(device);
+ AUD_SourceCaps caps;
+ caps.handle = handle;
+ caps.value = volume;
+
+ try
+ {
+ return device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
+ }
+ catch(AUD_Exception) {}
+ }
+ return false;
+}
+
+int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length)
+{
+ assert(device);
+ assert(buffer);
+
+ try
+ {
+ return device->read(buffer, length);
+ }
+ catch(AUD_Exception)
+ {
+ return false;
+ }
+}
+
+void AUD_closeReadDevice(AUD_Device* device)
+{
+ assert(device);
+
+ try
+ {
+ delete device;
+ }
+ catch(AUD_Exception)
+ {
+ }
+}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
new file mode 100644
index 00000000000..b02b465bff2
--- /dev/null
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -0,0 +1,342 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_CAPI
+#define AUD_CAPI
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "AUD_Space.h"
+
+typedef enum
+{
+ AUD_NULL_DEVICE = 0,
+ AUD_SDL_DEVICE,
+ AUD_OPENAL_DEVICE,
+ AUD_JACK_DEVICE
+} AUD_DeviceType;
+
+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;
+#endif
+
+/**
+ * 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 int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize);
+
+/**
+ * Returns a integer list with available sound devices. The last one is always
+ * AUD_NULL_DEVICE.
+ */
+extern int* AUD_enumDevices();
+
+/**
+ * Unitinitializes an audio device.
+ */
+extern void AUD_exit();
+
+/**
+ * Locks the playback device.
+ */
+extern void AUD_lock();
+
+/**
+ * Unlocks the device.
+ */
+extern void AUD_unlock();
+
+/**
+ * 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_load(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_loadBuffer(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_bufferSound(AUD_Sound* sound);
+
+/**
+ * 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_delaySound(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_limitSound(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_pingpongSound(AUD_Sound* sound);
+
+/**
+ * Loops a sound.
+ * \param sound The sound to loop.
+ * \return A handle of the looped sound.
+ */
+extern AUD_Sound* AUD_loopSound(AUD_Sound* sound);
+
+/**
+ * Stops a looping sound when the current playback finishes.
+ * \param handle The playback handle.
+ * \return Whether the handle is valid.
+ */
+extern int AUD_stopLoop(AUD_Handle* handle);
+
+/**
+ * Unloads a sound of any type.
+ * \param sound The handle of the sound.
+ */
+extern void AUD_unload(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_play(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_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_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_stop(AUD_Handle* handle);
+
+/**
+ * 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_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_seek(AUD_Handle* handle, float seekTo);
+
+/**
+ * Retrieves the playback position of a handle.
+ * \return The current playback position in seconds or 0.0 if the handle is
+ * invalid.
+ */
+extern float AUD_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_getStatus(AUD_Handle* handle);
+
+/**
+ * Plays a 3D sound.
+ * \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.
+ * \note The factory must provide a mono (single channel) source and the device
+ * must support 3D audio, otherwise the sound is played back normally.
+ */
+extern AUD_Handle* AUD_play3D(AUD_Sound* sound, int keep);
+
+/**
+ * Updates the listener 3D data.
+ * \param data The 3D data.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_updateListener(AUD_3DData* data);
+
+/**
+ * Sets a 3D device setting.
+ * \param setting The setting type.
+ * \param value The new setting value.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_set3DSetting(AUD_3DSetting setting, float value);
+
+/**
+ * Retrieves a 3D device setting.
+ * \param setting The setting type.
+ * \return The setting value.
+ */
+extern float AUD_get3DSetting(AUD_3DSetting setting);
+
+/**
+ * Updates a listeners 3D data.
+ * \param handle The source handle.
+ * \param data The 3D data.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_update3DSource(AUD_Handle* handle, AUD_3DData* data);
+
+/**
+ * Sets a 3D source setting.
+ * \param handle The source handle.
+ * \param setting The setting type.
+ * \param value The new setting value.
+ * \return Whether the action succeeded.
+ */
+extern int AUD_set3DSourceSetting(AUD_Handle* handle,
+ AUD_3DSourceSetting setting, float value);
+
+/**
+ * Retrieves a 3D source setting.
+ * \param handle The source handle.
+ * \param setting The setting type.
+ * \return The setting value.
+ */
+extern float AUD_get3DSourceSetting(AUD_Handle* handle,
+ AUD_3DSourceSetting setting);
+
+/**
+ * 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_setSoundVolume(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_setSoundPitch(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_Specs specs);
+
+/**
+ * Plays back a sound file through a read device.
+ * \param device The read device.
+ * \param sound The handle of the sound file.
+ * \return A handle to the played back sound.
+ */
+extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound);
+
+/**
+ * Sets the volume of a played back sound of a read device.
+ * \param device The read device.
+ * \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_setDeviceSoundVolume(AUD_Device* device,
+ AUD_Handle* handle,
+ float volume);
+
+/**
+ * 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_readDevice(AUD_Device* device, sample_t* buffer, int length);
+
+/**
+ * Closes a read device.
+ * \param device The read device.
+ */
+extern void AUD_closeReadDevice(AUD_Device* device);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //AUD_CAPI
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
new file mode 100644
index 00000000000..66205a58015
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
@@ -0,0 +1,125 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ChannelMapperFactory.h"
+#include "AUD_ChannelMapperReader.h"
+
+#include <cstring>
+
+AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IReader* reader,
+ AUD_Specs specs) :
+ AUD_MixerFactory(reader, specs)
+{
+ memset(m_mapping, 0, sizeof(m_mapping));
+}
+
+AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
+ AUD_Specs specs) :
+ AUD_MixerFactory(factory, specs)
+{
+ memset(m_mapping, 0, sizeof(m_mapping));
+}
+
+AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Specs specs) :
+ AUD_MixerFactory(specs)
+{
+ memset(m_mapping, 0, sizeof(m_mapping));
+}
+
+AUD_ChannelMapperFactory::~AUD_ChannelMapperFactory()
+{
+ for(int i = 1; i < 10; i++)
+ deleteMapping(i);
+}
+
+float** AUD_ChannelMapperFactory::getMapping(int ic)
+{
+ ic--;
+ if(ic > 8 || ic < 0)
+ return 0;
+
+ if(m_mapping[ic])
+ {
+ int channels = -1;
+ while(m_mapping[ic][++channels] != 0);
+ if(channels != m_specs.channels)
+ deleteMapping(ic+1);
+ }
+
+ if(!m_mapping[ic])
+ {
+ int channels = m_specs.channels;
+
+ m_mapping[ic] = new float*[channels+1]; AUD_NEW("mapping")
+ m_mapping[ic][channels] = 0;
+
+ for(int i = 0; i < channels; i++)
+ {
+ m_mapping[ic][i] = new float[ic+1]; AUD_NEW("mapping")
+ for(int j = 0; j <= ic; j++)
+ m_mapping[ic][i][j] = ((i == j) || (channels == 1) ||
+ (ic == 0)) ? 1.0f : 0.0f;
+ }
+ }
+
+ return m_mapping[ic];
+}
+
+void AUD_ChannelMapperFactory::deleteMapping(int ic)
+{
+ ic--;
+ if(ic > 8 || ic < 0)
+ return;
+
+ if(m_mapping[ic])
+ {
+ for(int i = 0; 1; i++)
+ {
+ if(m_mapping[ic][i] != 0)
+ {
+ delete[] m_mapping[ic][i]; AUD_DELETE("mapping")
+ }
+ else
+ break;
+ }
+ delete[] m_mapping[ic]; AUD_DELETE("mapping")
+ m_mapping[ic] = 0;
+ }
+}
+
+AUD_IReader* AUD_ChannelMapperFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ int ic = reader->getSpecs().channels;
+
+ reader = new AUD_ChannelMapperReader(reader, getMapping(ic));
+ AUD_NEW("reader")
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.h b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
new file mode 100644
index 00000000000..c2c39f4bdf6
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_CHANNELMAPPERFACTORY
+#define AUD_CHANNELMAPPERFACTORY
+
+#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:
+ /**
+ * The mapping specification.
+ */
+ float **m_mapping[9];
+
+public:
+ AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_Specs specs);
+ AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_Specs specs);
+ AUD_ChannelMapperFactory(AUD_Specs specs);
+
+ virtual ~AUD_ChannelMapperFactory();
+
+ /**
+ * Returns the mapping array for editing.
+ * \param ic The count of input channels the array should have.
+ * \note The count of output channels is read of the desired output specs.
+ */
+ float** getMapping(int ic);
+
+ /**
+ * Deletes the current channel mapping.
+ */
+ void deleteMapping(int ic);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_CHANNELMAPPERFACTORY
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
new file mode 100644
index 00000000000..61f97c08a8e
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
@@ -0,0 +1,108 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ChannelMapperReader.h"
+#include "AUD_Buffer.h"
+
+AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
+ float **mapping) :
+ AUD_EffectReader(reader)
+{
+ m_specs = reader->getSpecs();
+
+ if(m_specs.format != AUD_FORMAT_FLOAT32)
+ {
+ delete m_reader; AUD_DELETE("reader")
+ AUD_THROW(AUD_ERROR_READER);
+ }
+
+ int channels = -1;
+ m_rch = m_specs.channels;
+ while(mapping[++channels] != 0);
+
+ m_mapping = new float*[channels]; AUD_NEW("mapping")
+ m_specs.channels = (AUD_Channels)channels;
+
+ float sum;
+ int i;
+
+ while(channels--)
+ {
+ m_mapping[channels] = new float[m_rch]; AUD_NEW("mapping")
+ sum = 0.0f;
+ for(i=0; i < m_rch; i++)
+ sum += mapping[channels][i];
+ for(i=0; i < m_rch; i++)
+ m_mapping[channels][i] = sum > 0.0 ? mapping[channels][i]/sum : 0.0;
+ }
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_ChannelMapperReader::~AUD_ChannelMapperReader()
+{
+ int channels = m_specs.channels;
+
+ while(channels--)
+ {
+ delete[] m_mapping[channels]; AUD_DELETE("mapping")
+ }
+
+ delete[] m_mapping; AUD_DELETE("mapping")
+
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+AUD_Specs AUD_ChannelMapperReader::getSpecs()
+{
+ return m_specs;
+}
+
+void AUD_ChannelMapperReader::read(int & length, sample_t* & buffer)
+{
+ m_reader->read(length, buffer);
+
+ int channels = m_specs.channels;
+
+ if(m_buffer->getSize() < length * 4 * channels)
+ m_buffer->resize(length * 4 * channels);
+
+ float* in = (float*)buffer;
+ float* out = (float*)m_buffer->getBuffer();
+ float sum;
+
+ for(int i = 0; i < length; i++)
+ {
+ for(int j = 0; j < channels; j++)
+ {
+ sum = 0;
+ for(int k = 0; k < m_rch; k++)
+ sum += m_mapping[j][k] * in[i * m_rch + k];
+ out[i * channels + j] = sum;
+ }
+ }
+
+ buffer = m_buffer->getBuffer();
+}
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.h b/intern/audaspace/intern/AUD_ChannelMapperReader.h
new file mode 100644
index 00000000000..fe79ab6edd6
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.h
@@ -0,0 +1,76 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_CHANNELMAPPERREADER
+#define AUD_CHANNELMAPPERREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * 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 output buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The output specification.
+ */
+ AUD_Specs m_specs;
+
+ /**
+ * The channel count of the reader.
+ */
+ int m_rch;
+
+ /**
+ * The mapping specification.
+ */
+ float **m_mapping;
+
+public:
+ /**
+ * Creates a channel mapper reader.
+ * \param reader The reader to map.
+ * \param mapping The mapping specification as two dimensional float array.
+ * \exception AUD_Exception Thrown if the reader is NULL.
+ */
+ AUD_ChannelMapperReader(AUD_IReader* reader, float **mapping);
+ /**
+ * Destroys the reader.
+ */
+ ~AUD_ChannelMapperReader();
+
+ virtual AUD_Specs getSpecs();
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_CHANNELMAPPERREADER
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.cpp b/intern/audaspace/intern/AUD_ConverterFactory.cpp
new file mode 100644
index 00000000000..a1a86662072
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ConverterFactory.cpp
@@ -0,0 +1,54 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ConverterFactory.h"
+#include "AUD_ConverterReader.h"
+
+AUD_ConverterFactory::AUD_ConverterFactory(AUD_IReader* reader,
+ AUD_Specs specs) :
+ AUD_MixerFactory(reader, specs) {}
+
+AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
+ AUD_Specs specs) :
+ AUD_MixerFactory(factory, specs) {}
+
+AUD_ConverterFactory::AUD_ConverterFactory(AUD_Specs specs) :
+ AUD_MixerFactory(specs) {}
+
+AUD_IReader* AUD_ConverterFactory::createReader()
+{
+ AUD_IReader* reader = getReader();
+
+ if(reader != 0)
+ {
+ if(reader->getSpecs().format != m_specs.format)
+ {
+ reader = new AUD_ConverterReader(reader, m_specs);
+ AUD_NEW("reader")
+ }
+ }
+
+ return reader;
+}
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.h b/intern/audaspace/intern/AUD_ConverterFactory.h
new file mode 100644
index 00000000000..3778e8d8f03
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ConverterFactory.h
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_CONVERTERFACTORY
+#define AUD_CONVERTERFACTORY
+
+#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
+{
+public:
+ AUD_ConverterFactory(AUD_IReader* reader, AUD_Specs specs);
+ AUD_ConverterFactory(AUD_IFactory* factory, AUD_Specs specs);
+ AUD_ConverterFactory(AUD_Specs specs);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_CONVERTERFACTORY
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.cpp b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
new file mode 100644
index 00000000000..b6d5dffa1a2
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
@@ -0,0 +1,502 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ConverterFunctions.h"
+#include "AUD_Buffer.h"
+
+#define AUD_U8_0 0x80
+#define AUD_S16_MAX 0x7FFF
+#define AUD_S16_MIN 0x8000
+#define AUD_S16_FLT 32768.0
+#define AUD_S32_MAX 0x7FFFFFFF
+#define AUD_S32_MIN 0x80000000
+#define AUD_S32_FLT 2147483648.0
+#define AUD_FLT_MAX 1.0
+#define AUD_FLT_MIN -1.0
+
+void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length)
+{
+ int16_t* t = (int16_t*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
+}
+
+void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
+{
+ for(int i = 0; i < length; 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(sample_t* target, sample_t* source, int length)
+{
+ for(int i = 0; i < length; i++)
+ {
+ target[i*3+2] = source[i] - AUD_U8_0;
+ target[i*3+1] = 0;
+ target[i*3] = 0;
+ }
+}
+
+void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
+}
+
+void AUD_convert_u8_float(sample_t* target, sample_t* source, int length)
+{
+ float* t = (float*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
+}
+
+void AUD_convert_u8_double(sample_t* target, sample_t* source, int length)
+{
+ double* t = (double*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
+}
+
+void AUD_convert_s16_u8(sample_t* target, sample_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(sample_t* target, sample_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ for(int i = 0; i < length; i++)
+ {
+ target[i*3] = s[i] >> 8 & 0xFF;
+ target[i*3+1] = s[i] & 0xFF;
+ target[i*3+2] = 0;
+ }
+}
+
+void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ for(int i = 0; i < length; i++)
+ {
+ target[i*3+2] = s[i] >> 8 & 0xFF;
+ target[i*3+1] = s[i] & 0xFF;
+ target[i*3] = 0;
+ }
+}
+
+void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ int32_t* t = (int32_t*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = ((int32_t)s[i]) << 16;
+}
+
+void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ float* t = (float*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i] / AUD_S16_FLT;
+}
+
+void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ double* t = (double*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i] / AUD_S16_FLT;
+}
+
+void AUD_convert_s24_u8_be(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_t* source, int length)
+{
+ memcpy(target, source, length * 3);
+}
+
+void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
+}
+
+void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length)
+{
+ int32_t* t = (int32_t*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
+}
+
+void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
+{
+ float* t = (float*) target;
+ int32_t s;
+ for(int i = 0; i < length; 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(sample_t* target, sample_t* source, int length)
+{
+ float* t = (float*) target;
+ int32_t s;
+ for(int i = 0; i < length; 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(sample_t* target, sample_t* source, int length)
+{
+ double* t = (double*) target;
+ int32_t s;
+ for(int i = 0; i < length; 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(sample_t* target, sample_t* source, int length)
+{
+ double* t = (double*) target;
+ int32_t s;
+ for(int i = 0; i < length; 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(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ for(int i = 0; i < length; i++)
+ {
+ target[i*3] = s[i] >> 24 & 0xFF;
+ target[i*3+1] = s[i] >> 16 & 0xFF;
+ target[i*3+2] = s[i] >> 8 & 0xFF;
+ }
+}
+
+void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
+{
+ int16_t* s = (int16_t*) source;
+ for(int i = 0; i < length; i++)
+ {
+ target[i*3+2] = s[i] >> 24 & 0xFF;
+ target[i*3+1] = s[i] >> 16 & 0xFF;
+ target[i*3] = s[i] >> 8 & 0xFF;
+ }
+}
+
+void AUD_convert_s32_float(sample_t* target, sample_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(sample_t* target, sample_t* source, int length)
+{
+ int32_t* s = (int32_t*) source;
+ double* t = (double*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i] / AUD_S32_FLT;
+}
+
+void AUD_convert_float_u8(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_t* source, int length)
+{
+ float* s = (float*) source;
+ double* t = (double*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i];
+}
+
+void AUD_convert_double_u8(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_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(sample_t* target, sample_t* source, int length)
+{
+ double* s = (double*) source;
+ float* t = (float*) target;
+ for(int i = 0; i < length; i++)
+ t[i] = s[i];
+}
+
+void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
+ int count, float volume)
+{
+ for(int i=0; i<count; i++)
+ target[i] = (unsigned char)((source[i]-0x0080) * volume + 0x80);
+}
+
+void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
+ int count, float volume)
+{
+ count *= 3;
+ int value;
+
+ for(int i=0; i<count; i+=3)
+ {
+ value = source[i+2] << 16 | source[i+1] << 8 | source[i];
+ value |= (((value & 0x800000) >> 23) * 255) << 24;
+ value *= volume;
+ target[i+2] = value >> 16;
+ target[i+1] = value >> 8;
+ target[i] = value;
+ }
+}
+
+void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
+ int count, float volume)
+{
+ count *= 3;
+ int value;
+
+ for(int i=0; i < count; i+=3)
+ {
+ value = source[i] << 16 | source[i+1] << 8 | source[i+2];
+ value |= (((value & 0x800000) >> 23) * 255) << 24;
+ value *= volume;
+ target[i] = value >> 16;
+ target[i+1] = value >> 8;
+ target[i+2] = value;
+ }
+}
+
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.h b/intern/audaspace/intern/AUD_ConverterFunctions.h
new file mode 100644
index 00000000000..c1dd0f4a3a2
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ConverterFunctions.h
@@ -0,0 +1,156 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_CONVERTERFUNCTIONS
+#define AUD_CONVERTERFUNCTIONS
+
+#include "AUD_Space.h"
+
+#include <cstring>
+#ifdef _MSC_VER
+#if (_MSC_VER < 1300)
+ typedef short int16_t;
+ typedef int int32_t;
+#else
+ typedef __int16 int16_t;
+ typedef __int32 int32_t;
+#endif
+#else
+#include <stdint.h>
+#endif
+
+typedef void (*AUD_convert_f)(sample_t* target, sample_t* source, int length);
+
+typedef void (*AUD_volume_adjust_f)(sample_t* target, sample_t* source,
+ int count, float volume);
+
+template <class T>
+void AUD_convert_copy(sample_t* target, sample_t* source, int length)
+{
+ memcpy(target, source, length*sizeof(T));
+}
+
+void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_u8_float(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_u8_double(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s16_float(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s16_double(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s32_float(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_s32_double(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_float_u8(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_float_s16(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_float_s32(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_float_double(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_double_u8(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_double_s16(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_double_s32(sample_t* target, sample_t* source, int length);
+
+void AUD_convert_double_float(sample_t* target, sample_t* source, int length);
+
+template <class T>
+void AUD_volume_adjust(sample_t* target, sample_t* source,
+ int count, float volume)
+{
+ T* t = (T*)target;
+ T* s = (T*)source;
+ for(int i=0; i < count; i++)
+ t[i] = (T)(s[i] * volume);
+}
+
+void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
+ int count, float volume);
+
+void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
+ int count, float volume);
+
+void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
+ int count, float volume);
+
+#endif //AUD_CONVERTERFUNCTIONS
diff --git a/intern/audaspace/intern/AUD_ConverterReader.cpp b/intern/audaspace/intern/AUD_ConverterReader.cpp
new file mode 100644
index 00000000000..da25a2b7460
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ConverterReader.cpp
@@ -0,0 +1,260 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_ConverterReader.h"
+#include "AUD_Buffer.h"
+
+AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs) :
+ AUD_EffectReader(reader)
+{
+ m_specs = reader->getSpecs();
+
+ int bigendian = 1;
+ bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
+
+ switch(m_specs.format)
+ {
+ case AUD_FORMAT_U8:
+ switch(specs.format)
+ {
+ case AUD_FORMAT_U8:
+ m_convert = AUD_convert_copy<unsigned char>;
+ break;
+ case AUD_FORMAT_S16:
+ m_convert = AUD_convert_u8_s16;
+ break;
+ case AUD_FORMAT_S24:
+ if(bigendian)
+ m_convert = AUD_convert_u8_s24_be;
+ else
+ m_convert = AUD_convert_u8_s24_le;
+ break;
+ case AUD_FORMAT_S32:
+ m_convert = AUD_convert_u8_s32;
+ break;
+ case AUD_FORMAT_FLOAT32:
+ m_convert = AUD_convert_u8_float;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_convert = AUD_convert_u8_double;
+ break;
+ default:
+ break;
+ }
+ break;
+ case AUD_FORMAT_S16:
+ switch(specs.format)
+ {
+ case AUD_FORMAT_U8:
+ m_convert = AUD_convert_s16_u8;
+ break;
+ case AUD_FORMAT_S16:
+ m_convert = AUD_convert_copy<int16_t>;
+ break;
+ case AUD_FORMAT_S24:
+ if(bigendian)
+ m_convert = AUD_convert_s16_s24_be;
+ else
+ m_convert = AUD_convert_s16_s24_le;
+ break;
+ case AUD_FORMAT_S32:
+ m_convert = AUD_convert_s16_s32;
+ break;
+ case AUD_FORMAT_FLOAT32:
+ m_convert = AUD_convert_s16_float;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_convert = AUD_convert_s16_double;
+ break;
+ default:
+ break;
+ }
+ break;
+ case AUD_FORMAT_S24:
+ if(bigendian)
+ switch(specs.format)
+ {
+ case AUD_FORMAT_U8:
+ m_convert = AUD_convert_u8_s24_be;
+ break;
+ case AUD_FORMAT_S16:
+ m_convert = AUD_convert_s16_s24_be;
+ break;
+ case AUD_FORMAT_S24:
+ m_convert = AUD_convert_s24_s24;
+ break;
+ case AUD_FORMAT_S32:
+ m_convert = AUD_convert_s32_s24_be;
+ break;
+ case AUD_FORMAT_FLOAT32:
+ m_convert = AUD_convert_float_s24_be;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_convert = AUD_convert_double_s24_be;
+ break;
+ default:
+ break;
+ }
+ else
+ switch(specs.format)
+ {
+ case AUD_FORMAT_U8:
+ m_convert = AUD_convert_u8_s24_le;
+ break;
+ case AUD_FORMAT_S16:
+ m_convert = AUD_convert_s16_s24_le;
+ break;
+ case AUD_FORMAT_S24:
+ m_convert = AUD_convert_s24_s24;
+ break;
+ case AUD_FORMAT_S32:
+ m_convert = AUD_convert_s32_s24_le;
+ break;
+ case AUD_FORMAT_FLOAT32:
+ m_convert = AUD_convert_float_s24_le;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_convert = AUD_convert_double_s24_le;
+ break;
+ default:
+ break;
+ }
+ break;
+ case AUD_FORMAT_S32:
+ switch(specs.format)
+ {
+ case AUD_FORMAT_U8:
+ m_convert = AUD_convert_s32_u8;
+ break;
+ case AUD_FORMAT_S16:
+ m_convert = AUD_convert_s32_s16;
+ break;
+ case AUD_FORMAT_S24:
+ if(bigendian)
+ m_convert = AUD_convert_s32_s24_be;
+ else
+ m_convert = AUD_convert_s32_s24_le;
+ break;
+ case AUD_FORMAT_S32:
+ m_convert = AUD_convert_copy<int32_t>;
+ break;
+ case AUD_FORMAT_FLOAT32:
+ m_convert = AUD_convert_s32_float;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_convert = AUD_convert_s32_double;
+ break;
+ default:
+ break;
+ }
+ break;
+ case AUD_FORMAT_FLOAT32:
+ switch(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:
+ if(bigendian)
+ m_convert = AUD_convert_float_s24_be;
+ else
+ m_convert = AUD_convert_float_s24_le;
+ 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;
+ }
+ break;
+ case AUD_FORMAT_FLOAT64:
+ switch(specs.format)
+ {
+ case AUD_FORMAT_U8:
+ m_convert = AUD_convert_double_u8;
+ break;
+ case AUD_FORMAT_S16:
+ m_convert = AUD_convert_double_s16;
+ break;
+ case AUD_FORMAT_S24:
+ if(bigendian)
+ m_convert = AUD_convert_double_s24_be;
+ else
+ m_convert = AUD_convert_double_s24_le;
+ break;
+ case AUD_FORMAT_S32:
+ m_convert = AUD_convert_double_s32;
+ break;
+ case AUD_FORMAT_FLOAT32:
+ m_convert = AUD_convert_double_float;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_convert = AUD_convert_copy<double>;
+ break;
+ default:
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ m_specs.format = specs.format;
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_ConverterReader::~AUD_ConverterReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+AUD_Specs AUD_ConverterReader::getSpecs()
+{
+ return m_specs;
+}
+
+void AUD_ConverterReader::read(int & length, sample_t* & buffer)
+{
+ m_reader->read(length, buffer);
+
+ int samplesize = AUD_SAMPLE_SIZE(m_specs);
+
+ if(m_buffer->getSize() < length*samplesize)
+ m_buffer->resize(length*samplesize);
+
+ m_convert(m_buffer->getBuffer(), buffer, length*m_specs.channels);
+
+ buffer = m_buffer->getBuffer();
+}
diff --git a/intern/audaspace/intern/AUD_ConverterReader.h b/intern/audaspace/intern/AUD_ConverterReader.h
new file mode 100644
index 00000000000..f855372b636
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ConverterReader.h
@@ -0,0 +1,71 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_CONVERTERREADER
+#define AUD_CONVERTERREADER
+
+#include "AUD_EffectReader.h"
+#include "AUD_ConverterFunctions.h"
+class AUD_Buffer;
+
+/**
+ * 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_Specs m_specs;
+
+ /**
+ * Converter function.
+ */
+ AUD_convert_f m_convert;
+
+public:
+ /**
+ * Creates a converter reader.
+ * \param reader The reader to convert.
+ * \param specs The target specification.
+ * \exception AUD_Exception Thrown if the reader is NULL.
+ */
+ AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs);
+ /**
+ * Destroys the reader.
+ */
+ ~AUD_ConverterReader();
+
+ virtual AUD_Specs getSpecs();
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_CONVERTERREADER
diff --git a/intern/audaspace/intern/AUD_FileFactory.cpp b/intern/audaspace/intern/AUD_FileFactory.cpp
new file mode 100644
index 00000000000..b63390803b1
--- /dev/null
+++ b/intern/audaspace/intern/AUD_FileFactory.cpp
@@ -0,0 +1,95 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FileFactory.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+#ifdef WITH_FFMPEG
+#include "AUD_FFMPEGReader.h"
+#endif
+#ifdef WITH_SNDFILE
+#include "AUD_SndFileReader.h"
+#endif
+
+AUD_FileFactory::AUD_FileFactory(const char* filename)
+{
+ if(filename != NULL)
+ {
+ m_filename = new char[strlen(filename)+1]; AUD_NEW("string")
+ strcpy(m_filename, filename);
+ }
+ else
+ m_filename = NULL;
+}
+
+AUD_FileFactory::AUD_FileFactory(unsigned char* buffer, int size)
+{
+ m_filename = NULL;
+ m_buffer = AUD_Reference<AUD_Buffer>(new AUD_Buffer(size));
+ memcpy(m_buffer.get()->getBuffer(), buffer, size);
+}
+
+AUD_FileFactory::~AUD_FileFactory()
+{
+ if(m_filename)
+ {
+ delete[] m_filename; AUD_DELETE("string")
+ }
+}
+
+AUD_IReader* AUD_FileFactory::createReader()
+{
+ AUD_IReader* reader = 0;
+
+#ifdef WITH_SNDFILE
+ try
+ {
+ if(m_filename)
+ reader = new AUD_SndFileReader(m_filename);
+ else
+ reader = new AUD_SndFileReader(m_buffer);
+ AUD_NEW("reader")
+ return reader;
+ }
+ catch(AUD_Exception e) {}
+#endif
+
+#ifdef WITH_FFMPEG
+ try
+ {
+ if(m_filename)
+ reader = new AUD_FFMPEGReader(m_filename);
+ else
+ reader = new AUD_FFMPEGReader(m_buffer);
+ AUD_NEW("reader")
+ return reader;
+ }
+ catch(AUD_Exception e) {}
+#endif
+
+ return reader;
+}
diff --git a/intern/audaspace/intern/AUD_FileFactory.h b/intern/audaspace/intern/AUD_FileFactory.h
new file mode 100644
index 00000000000..6ab8f280534
--- /dev/null
+++ b/intern/audaspace/intern/AUD_FileFactory.h
@@ -0,0 +1,71 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_FILEFACTORY
+#define AUD_FILEFACTORY
+
+#include "AUD_IFactory.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+/**
+ * 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.
+ */
+ char* m_filename;
+
+ /**
+ * The buffer to read from.
+ */
+ AUD_Reference<AUD_Buffer> m_buffer;
+
+public:
+ /**
+ * Creates a new factory.
+ * \param filename The sound file path.
+ */
+ AUD_FileFactory(const char* filename);
+
+ /**
+ * Creates a new factory.
+ * \param buffer The buffer to read from.
+ * \param size The size of the buffer.
+ */
+ AUD_FileFactory(unsigned char* buffer, int size);
+
+ /**
+ * Destroys the factory.
+ */
+ ~AUD_FileFactory();
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_FILEFACTORY
diff --git a/intern/audaspace/intern/AUD_FloatMixer.cpp b/intern/audaspace/intern/AUD_FloatMixer.cpp
new file mode 100644
index 00000000000..f7133b9c30e
--- /dev/null
+++ b/intern/audaspace/intern/AUD_FloatMixer.cpp
@@ -0,0 +1,172 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FloatMixer.h"
+#include "AUD_ConverterFactory.h"
+#include "AUD_SRCResampleFactory.h"
+#include "AUD_ChannelMapperFactory.h"
+#include "AUD_IReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_FloatMixer::AUD_FloatMixer()
+{
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+
+ m_converter = NULL;
+ m_resampler = NULL;
+ m_mapper = NULL;
+}
+
+AUD_FloatMixer::~AUD_FloatMixer()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+
+ if(m_converter)
+ {
+ delete m_converter; AUD_DELETE("factory")
+ }
+ if(m_resampler)
+ {
+ delete m_resampler; AUD_DELETE("factory")
+ }
+ if(m_mapper)
+ {
+ delete m_mapper; AUD_DELETE("factory")
+ }
+}
+
+AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
+{
+ m_converter->setReader(reader);
+ reader = m_converter->createReader();
+
+ m_resampler->setReader(reader);
+ reader = m_resampler->createReader();
+
+ if(reader->getSpecs().channels != m_specs.channels)
+ {
+ m_mapper->setReader(reader);
+ reader = m_mapper->createReader();
+ }
+
+ return reader;
+}
+
+void AUD_FloatMixer::setSpecs(AUD_Specs specs)
+{
+ m_specs = specs;
+
+ if(m_converter)
+ {
+ delete m_converter; AUD_DELETE("factory")
+ }
+ if(m_resampler)
+ {
+ delete m_resampler; AUD_DELETE("factory")
+ }
+ if(m_mapper)
+ {
+ delete m_mapper; AUD_DELETE("factory")
+ }
+
+ specs.format = AUD_FORMAT_FLOAT32;
+
+ m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
+ m_resampler = new AUD_SRCResampleFactory(specs); AUD_NEW("factory")
+ m_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
+
+ int bigendian = 1;
+ bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
+
+ 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:
+ if(bigendian)
+ m_convert = AUD_convert_float_s24_be;
+ else
+ m_convert = AUD_convert_float_s24_le;
+ 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_FloatMixer::add(sample_t* buffer, AUD_Specs specs, int length,
+ float volume)
+{
+ AUD_FloatMixerBuffer buf;
+ buf.buffer = buffer;
+ buf.length = length;
+ buf.volume = volume;
+ m_buffers.push_back(buf);
+}
+
+void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
+{
+ AUD_FloatMixerBuffer buf;
+
+ int channels = m_specs.channels;
+
+ if(m_buffer->getSize() < length * channels * 4)
+ m_buffer->resize(length * channels * 4);
+
+ float* out = (float*)m_buffer->getBuffer();
+ float* in;
+
+ memset(out, 0, length * channels * 4);
+
+ int end;
+
+ while(!m_buffers.empty())
+ {
+ buf = m_buffers.front();
+ m_buffers.pop_front();
+
+ end = buf.length*channels;
+ in = (float*) buf.buffer;
+
+ for(int i = 0; i < end; i++)
+ out[i] += in[i]*buf.volume * volume;
+ }
+
+ m_convert(buffer, (sample_t*) out, length * channels);
+}
diff --git a/intern/audaspace/intern/AUD_FloatMixer.h b/intern/audaspace/intern/AUD_FloatMixer.h
new file mode 100644
index 00000000000..728a0faf3cb
--- /dev/null
+++ b/intern/audaspace/intern/AUD_FloatMixer.h
@@ -0,0 +1,100 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_FLOATMIXER
+#define AUD_FLOATMIXER
+
+#include "AUD_IMixer.h"
+#include "AUD_ConverterFunctions.h"
+class AUD_ConverterFactory;
+class AUD_SRCResampleFactory;
+class AUD_ChannelMapperFactory;
+class AUD_Buffer;
+#include <list>
+
+struct AUD_FloatMixerBuffer
+{
+ sample_t* buffer;
+ int length;
+ float volume;
+};
+
+/**
+ * This class is able to mix two audiosignals with floats.
+ */
+class AUD_FloatMixer : public AUD_IMixer
+{
+private:
+ /**
+ * The converter factory that converts all readers for superposition.
+ */
+ AUD_ConverterFactory* m_converter;
+
+ /**
+ * The resampling factory that resamples all readers for superposition.
+ */
+ AUD_SRCResampleFactory* m_resampler;
+
+ /**
+ * The channel mapper factory that maps all readers for superposition.
+ */
+ AUD_ChannelMapperFactory* m_mapper;
+
+ /**
+ * The list of buffers to superpose.
+ */
+ std::list<AUD_FloatMixerBuffer> m_buffers;
+
+ /**
+ * The output specification.
+ */
+ AUD_Specs m_specs;
+
+ /**
+ * The temporary mixing buffer.
+ */
+ AUD_Buffer* m_buffer;
+
+ /**
+ * Converter function.
+ */
+ AUD_convert_f m_convert;
+
+public:
+ /**
+ * Creates the mixer.
+ */
+ AUD_FloatMixer();
+
+ virtual ~AUD_FloatMixer();
+
+ virtual AUD_IReader* prepare(AUD_IReader* reader);
+ virtual void setSpecs(AUD_Specs specs);
+ virtual void add(sample_t* buffer, AUD_Specs specs, int length,
+ float volume);
+ virtual void superpose(sample_t* buffer, int length, float volume);
+};
+
+#endif //AUD_FLOATMIXER
diff --git a/intern/audaspace/intern/AUD_I3DDevice.h b/intern/audaspace/intern/AUD_I3DDevice.h
new file mode 100644
index 00000000000..c36924160de
--- /dev/null
+++ b/intern/audaspace/intern/AUD_I3DDevice.h
@@ -0,0 +1,103 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_I3DDEVICE
+#define AUD_I3DDEVICE
+
+#include "AUD_Space.h"
+
+/**
+ * This class represents an output device for 3D sound.
+ * Whether a normal device supports this or not can be checked with the
+ * AUD_CAPS_3D_DEVICE capability.
+ */
+class AUD_I3DDevice
+{
+public:
+ /**
+ * Plays a 3D 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.
+ * \note The factory must provide a mono (single channel) source otherwise
+ * the sound is played back normally.
+ */
+ virtual AUD_Handle* play3D(AUD_IFactory* factory, bool keep = false)=0;
+
+ /**
+ * Updates a listeners 3D data.
+ * \param data The 3D data.
+ * \return Whether the action succeeded.
+ */
+ virtual bool updateListener(AUD_3DData &data)=0;
+
+ /**
+ * Sets a 3D device setting.
+ * \param setting The setting type.
+ * \param value The new setting value.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setSetting(AUD_3DSetting setting, float value)=0;
+
+ /**
+ * Retrieves a 3D device setting.
+ * \param setting The setting type.
+ * \return The setting value.
+ */
+ virtual float getSetting(AUD_3DSetting setting)=0;
+
+ /**
+ * Updates a listeners 3D data.
+ * \param handle The source handle.
+ * \param data The 3D data.
+ * \return Whether the action succeeded.
+ */
+ virtual bool updateSource(AUD_Handle* handle, AUD_3DData &data)=0;
+
+ /**
+ * Sets a 3D source setting.
+ * \param handle The source handle.
+ * \param setting The setting type.
+ * \param value The new setting value.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setSourceSetting(AUD_Handle* handle,
+ AUD_3DSourceSetting setting, float value)=0;
+
+ /**
+ * Retrieves a 3D source setting.
+ * \param handle The source handle.
+ * \param setting The setting type.
+ * \return The setting value.
+ */
+ virtual float getSourceSetting(AUD_Handle* handle,
+ AUD_3DSourceSetting setting)=0;
+};
+
+#endif //AUD_I3DDEVICE
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
new file mode 100644
index 00000000000..af2cae206f3
--- /dev/null
+++ b/intern/audaspace/intern/AUD_IDevice.h
@@ -0,0 +1,191 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_IDEVICE
+#define AUD_IDEVICE
+
+#include "AUD_Space.h"
+class AUD_IFactory;
+
+/// Handle structure, for inherition.
+typedef struct
+{
+} AUD_Handle;
+
+/**
+ * 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:
+ /**
+ * Destroys the device.
+ */
+ virtual ~AUD_IDevice() {}
+
+ /**
+ * Returns the specification of the device.
+ */
+ virtual AUD_Specs getSpecs()=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 AUD_Handle* play(AUD_IFactory* factory, bool keep = false)=0;
+
+ /**
+ * Pauses a played back sound.
+ * \param handle The handle returned by the play function.
+ * \return
+ * - true if the sound has been paused.
+ * - false if the sound isn't playing back or the handle is invalid.
+ */
+ virtual bool pause(AUD_Handle* handle)=0;
+
+ /**
+ * Resumes a paused sound.
+ * \param handle The handle returned by the play function.
+ * \return
+ * - true if the sound has been resumed.
+ * - false if the sound isn't paused or the handle is invalid.
+ */
+ virtual bool resume(AUD_Handle* handle)=0;
+
+ /**
+ * Stops a played back or paused sound. The handle is definitely invalid
+ * afterwards.
+ * \param handle The handle returned by the play function.
+ * \return
+ * - true if the sound has been stopped.
+ * - false if the handle is invalid.
+ */
+ virtual bool stop(AUD_Handle* handle)=0;
+
+ /**
+ * Sets the behaviour of the device for a played back sound when the sound
+ * doesn't return any more samples.
+ * \param handle The handle returned by the play function.
+ * \param keep True when the source should be paused and not deleted.
+ * \return
+ * - true if the behaviour has been changed.
+ * - false if the handle is invalid.
+ */
+ virtual bool setKeep(AUD_Handle* handle, bool keep)=0;
+
+ /**
+ * Sends a message to a sound or all sounds that are currently played or
+ * paused.
+ * \param handle The sound that should receive the message or NULL if all
+ * sounds should receive it.
+ * \param message The message.
+ * \return True if the message has been read by at least one sound.
+ */
+ virtual bool sendMessage(AUD_Handle* handle, AUD_Message &message)=0;
+
+ /**
+ * Seeks in a played back sound.
+ * \param handle The handle returned by the play function.
+ * \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.
+ */
+ virtual bool seek(AUD_Handle* handle, float position)=0;
+
+ /**
+ * Retrieves the current playback position of a sound.
+ * \param handle The handle returned by the play function.
+ * \return The playback position in seconds, or 0.0 if the handle is
+ * invalid.
+ */
+ virtual float getPosition(AUD_Handle* handle)=0;
+
+ /**
+ * Returns the status of a played back sound.
+ * \param handle The handle returned by the play function.
+ * \return
+ * - AUD_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.
+ * \see AUD_Status
+ */
+ virtual AUD_Status getStatus(AUD_Handle* handle)=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;
+
+ /**
+ * Checks if a specific capability as available on a device.
+ * \param capability The capability.
+ * \return Whether it is available or not.
+ */
+ virtual bool checkCapability(int capability)=0;
+
+ /**
+ * Set a value of a capability. The data behind the pointer depends on the
+ * capability.
+ * \param capability The capability.
+ * \param value The value.
+ * \return Whether the action succeeded or not.
+ */
+ virtual bool setCapability(int capability, void *value)=0;
+
+ /**
+ * Retrieves a value of a capability. The data behind the pointer depends on
+ * the capability.
+ * \param capability The capability.
+ * \param value The value.
+ * \return Whether the action succeeded or not.
+ */
+ virtual bool getCapability(int capability, void *value)=0;
+};
+
+#endif //AUD_IDevice
diff --git a/intern/audaspace/intern/AUD_IFactory.h b/intern/audaspace/intern/AUD_IFactory.h
new file mode 100644
index 00000000000..f7f29c9e842
--- /dev/null
+++ b/intern/audaspace/intern/AUD_IFactory.h
@@ -0,0 +1,55 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_IFACTORY
+#define AUD_IFACTORY
+
+#include "AUD_Space.h"
+class AUD_IReader;
+
+/**
+ * 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 AUD_IReader* createReader()=0;
+};
+
+#endif //AUD_IFACTORY
diff --git a/intern/audaspace/intern/AUD_IMixer.h b/intern/audaspace/intern/AUD_IMixer.h
new file mode 100644
index 00000000000..c65e4c69cf7
--- /dev/null
+++ b/intern/audaspace/intern/AUD_IMixer.h
@@ -0,0 +1,77 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_IMIXER
+#define AUD_IMIXER
+
+#include "AUD_Space.h"
+class AUD_IReader;
+
+/**
+ * This class is able to mix audiosignals of different format and channel count.
+ * \note This class doesn't do resampling!
+ */
+class AUD_IMixer
+{
+public:
+ /**
+ * Destroys the mixer.
+ */
+ virtual ~AUD_IMixer(){}
+
+ /**
+ * This funuction prepares a reader for playback.
+ * \param reader The reader to prepare.
+ * \return The reader that should be used for playback.
+ */
+ virtual AUD_IReader* prepare(AUD_IReader* reader)=0;
+
+ /**
+ * Sets the target specification for superposing.
+ * \param specs The target specification.
+ */
+ virtual void setSpecs(AUD_Specs specs)=0;
+
+ /**
+ * Adds a buffer for superposition.
+ * \param buffer The buffer to superpose.
+ * \param specs The specification of the buffer.
+ * \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.
+ */
+ virtual void add(sample_t* buffer, AUD_Specs specs, int length,
+ float volume)=0;
+
+ /**
+ * Superposes all added buffers into an output buffer.
+ * \param buffer The target buffer for superposing.
+ * \param length The length of the buffer in samples.
+ * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
+ */
+ virtual void superpose(sample_t* buffer, int length, float volume)=0;
+};
+
+#endif //AUD_IMIXER
diff --git a/intern/audaspace/intern/AUD_IReader.h b/intern/audaspace/intern/AUD_IReader.h
new file mode 100644
index 00000000000..4b563100659
--- /dev/null
+++ b/intern/audaspace/intern/AUD_IReader.h
@@ -0,0 +1,117 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_IREADER
+#define AUD_IREADER
+
+#include "AUD_Space.h"
+
+/**
+ * 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
+{
+public:
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_IReader(){}
+
+ /**
+ * Tells whether the source provides seeking functionality or not.
+ * \warning This doesn't mean that the seeking always has to succeed.
+ * \return Always returns true for readers of the buffer type.
+ * \see getType
+ */
+ virtual bool isSeekable()=0;
+
+ /**
+ * Seeks to a specific position in the source.
+ * This function must work for buffer type readers.
+ * \param position The position to seek for measured in samples. To get
+ * from a given time to the samples you simply have to multiply the
+ * time value in seconds with the sample rate of the reader.
+ * \warning This may work or not, depending on the actual reader.
+ * \see getType
+ */
+ virtual void seek(int position)=0;
+
+ /**
+ * Returns an aproximated length of the source in samples.
+ * For readers of the type buffer this has to return a correct value!
+ * \return The length as sample count. May be negative if unknown.
+ * \see getType
+ */
+ virtual int getLength()=0;
+
+ /**
+ * Returns the position of the source as a sample count value.
+ * \return The current position in the source. A negative value indicates
+ * that the position is unknown.
+ * \warning The value returned doesn't always have to be correct for readers
+ * of the stream type, especially after seeking, it must though for
+ * the buffer ones.
+ * \see getType
+ */
+ virtual int getPosition()=0;
+
+ /**
+ * Returns the specification of the reader.
+ * \return The AUD_Specs structure.
+ */
+ virtual AUD_Specs getSpecs()=0;
+
+ /**
+ * Returns the type of the reader. There are special conditions for the
+ * readers of the buffer type. Those have to return correct position and
+ * length values as well as they must be seekable.
+ * \return AUD_TYPE_BUFFER or AUD_TYPE_STREAM.
+ */
+ virtual AUD_ReaderType getType()=0;
+
+ /**
+ * Sends a message to this reader and if it has subreaders it broadcasts
+ * the message to them.
+ * \param message The message.
+ * \return Whether the message has been read by the reader or one of his
+ * subreaders.
+ */
+ virtual bool notify(AUD_Message &message)=0;
+
+ /**
+ * Request to read the next length samples out of the source.
+ * The buffer for reading has to stay valid until the next call of this
+ * method or until the reader is deleted.
+ * \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 reader.
+ * \param[out] buffer The pointer to the buffer with the samples.
+ */
+ virtual void read(int & length, sample_t* & buffer)=0;
+};
+
+#endif //AUD_IREADER
diff --git a/intern/audaspace/intern/AUD_MixerFactory.cpp b/intern/audaspace/intern/AUD_MixerFactory.cpp
new file mode 100644
index 00000000000..db38d1004db
--- /dev/null
+++ b/intern/audaspace/intern/AUD_MixerFactory.cpp
@@ -0,0 +1,109 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_MixerFactory.h"
+#include "AUD_IReader.h"
+
+AUD_IReader* AUD_MixerFactory::getReader()
+{
+ AUD_IReader* reader;
+
+ // first check for an existing reader
+ if(m_reader != 0)
+ {
+ reader = m_reader;
+ m_reader = 0;
+ return reader;
+ }
+
+ // otherwise create a reader if there is a factory
+ if(m_factory != 0)
+ {
+ reader = m_factory->createReader();
+ return reader;
+ }
+
+ return 0;
+}
+
+AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
+ AUD_Specs specs)
+{
+ m_specs = specs;
+ m_reader = reader;
+ m_factory = 0;
+}
+
+AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
+ AUD_Specs specs)
+{
+ m_specs = specs;
+ m_reader = 0;
+ m_factory = factory;
+}
+
+AUD_MixerFactory::AUD_MixerFactory(AUD_Specs specs)
+{
+ m_specs = specs;
+ m_reader = 0;
+ m_factory = 0;
+}
+
+AUD_MixerFactory::~AUD_MixerFactory()
+{
+ if(m_reader != 0)
+ {
+ delete m_reader; AUD_DELETE("reader")
+ }
+}
+
+AUD_Specs AUD_MixerFactory::getSpecs()
+{
+ return m_specs;
+}
+
+void AUD_MixerFactory::setSpecs(AUD_Specs specs)
+{
+ m_specs = specs;
+}
+
+void AUD_MixerFactory::setReader(AUD_IReader* reader)
+{
+ if(m_reader != 0)
+ {
+ delete m_reader; AUD_DELETE("reader")
+ }
+ m_reader = reader;
+}
+
+void AUD_MixerFactory::setFactory(AUD_IFactory* factory)
+{
+ m_factory = factory;
+}
+
+AUD_IFactory* AUD_MixerFactory::getFactory()
+{
+ return m_factory;
+}
diff --git a/intern/audaspace/intern/AUD_MixerFactory.h b/intern/audaspace/intern/AUD_MixerFactory.h
new file mode 100644
index 00000000000..c61dd283c67
--- /dev/null
+++ b/intern/audaspace/intern/AUD_MixerFactory.h
@@ -0,0 +1,117 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_MIXERFACTORY
+#define AUD_MIXERFACTORY
+
+#include "AUD_IFactory.h"
+
+/**
+ * This factory is a base class for all mixer factories.
+ */
+class AUD_MixerFactory : public AUD_IFactory
+{
+protected:
+ /**
+ * The reader that should be mixed later.
+ */
+ AUD_IReader* m_reader;
+
+ /**
+ * If there is no reader it is created out of this factory.
+ */
+ AUD_IFactory* m_factory;
+
+ /**
+ * The target specification for resampling.
+ */
+ AUD_Specs m_specs;
+
+ /**
+ * Returns the reader created out of the factory or taken from m_reader.
+ * This method can be used for the createReader function of the implementing
+ * classes.
+ * \return The reader to mix, or NULL if there is no reader or factory.
+ */
+ AUD_IReader* getReader();
+
+public:
+ /**
+ * Creates a new factory.
+ * \param reader The reader to mix.
+ * \param specs The target specification.
+ */
+ AUD_MixerFactory(AUD_IReader* reader, AUD_Specs specs);
+
+ /**
+ * Creates a new factory.
+ * \param factory The factory to create the readers to mix out of.
+ * \param specs The target specification.
+ */
+ AUD_MixerFactory(AUD_IFactory* factory, AUD_Specs specs);
+
+ /**
+ * Creates a new factory.
+ * \param specs The target specification.
+ */
+ AUD_MixerFactory(AUD_Specs specs);
+
+ /**
+ * Destroys the resampling factory.
+ */
+ virtual ~AUD_MixerFactory();
+
+ /**
+ * Returns the target specification for resampling.
+ */
+ AUD_Specs getSpecs();
+
+ /**
+ * Sets the target specification for resampling.
+ * \param specs The specification.
+ */
+ void setSpecs(AUD_Specs specs);
+
+ /**
+ * Sets the reader for resampling.
+ * If there has already been a reader, it will be deleted.
+ * \param reader The reader that should be used as source for resampling.
+ */
+ void setReader(AUD_IReader* reader);
+
+ /**
+ * Sets the factory for resampling.
+ * \param factory The factory that should be used as source for resampling.
+ */
+ void setFactory(AUD_IFactory* factory);
+
+ /**
+ * Returns the saved factory.
+ * \return The factory or NULL if there has no factory been saved.
+ */
+ AUD_IFactory* getFactory();
+};
+
+#endif //AUD_MIXERFACTORY
diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
new file mode 100644
index 00000000000..d237b71b67e
--- /dev/null
+++ b/intern/audaspace/intern/AUD_NULLDevice.cpp
@@ -0,0 +1,108 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_NULLDevice.h"
+#include "AUD_IReader.h"
+#include "AUD_IFactory.h"
+
+AUD_NULLDevice::AUD_NULLDevice()
+{
+ m_specs.channels = AUD_CHANNELS_INVALID;
+ m_specs.format = AUD_FORMAT_INVALID;
+ m_specs.rate = AUD_RATE_INVALID;
+}
+
+AUD_Specs AUD_NULLDevice::getSpecs()
+{
+ return m_specs;
+}
+
+AUD_Handle* AUD_NULLDevice::play(AUD_IFactory* factory, bool keep)
+{
+ return 0;
+}
+
+bool AUD_NULLDevice::pause(AUD_Handle* handle)
+{
+ return false;
+}
+
+bool AUD_NULLDevice::resume(AUD_Handle* handle)
+{
+ return false;
+}
+
+bool AUD_NULLDevice::stop(AUD_Handle* handle)
+{
+ return false;
+}
+
+bool AUD_NULLDevice::setKeep(AUD_Handle* handle, bool keep)
+{
+ return false;
+}
+
+bool AUD_NULLDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
+{
+ return false;
+}
+
+bool AUD_NULLDevice::seek(AUD_Handle* handle, float position)
+{
+ return false;
+}
+
+float AUD_NULLDevice::getPosition(AUD_Handle* handle)
+{
+ return 0.0f;
+}
+
+AUD_Status AUD_NULLDevice::getStatus(AUD_Handle* handle)
+{
+ return AUD_STATUS_INVALID;
+}
+
+void AUD_NULLDevice::lock()
+{
+}
+
+void AUD_NULLDevice::unlock()
+{
+}
+
+bool AUD_NULLDevice::checkCapability(int capability)
+{
+ return false;
+}
+
+bool AUD_NULLDevice::setCapability(int capability, void *value)
+{
+ return false;
+}
+
+bool AUD_NULLDevice::getCapability(int capability, void *value)
+{
+ return false;
+}
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
new file mode 100644
index 00000000000..155f24f8837
--- /dev/null
+++ b/intern/audaspace/intern/AUD_NULLDevice.h
@@ -0,0 +1,65 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_NULLDEVICE
+#define AUD_NULLDEVICE
+
+#include "AUD_IDevice.h"
+
+/**
+ * This device plays nothing.
+ */
+class AUD_NULLDevice : public AUD_IDevice
+{
+private:
+ /**
+ * The specs of the device.
+ */
+ AUD_Specs m_specs;
+
+public:
+ /**
+ * Creates a new NULL device.
+ */
+ AUD_NULLDevice();
+
+ virtual AUD_Specs getSpecs();
+ virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
+ virtual bool pause(AUD_Handle* handle);
+ virtual bool resume(AUD_Handle* handle);
+ virtual bool stop(AUD_Handle* handle);
+ virtual bool setKeep(AUD_Handle* handle, bool keep);
+ virtual bool sendMessage(AUD_Handle* handle, AUD_Message &message);
+ virtual bool seek(AUD_Handle* handle, float position);
+ virtual float getPosition(AUD_Handle* handle);
+ virtual AUD_Status getStatus(AUD_Handle* handle);
+ virtual void lock();
+ virtual void unlock();
+ virtual bool checkCapability(int capability);
+ virtual bool setCapability(int capability, void *value);
+ virtual bool getCapability(int capability, void *value);
+};
+
+#endif //AUD_NULLDEVICE
diff --git a/intern/audaspace/intern/AUD_ReadDevice.cpp b/intern/audaspace/intern/AUD_ReadDevice.cpp
new file mode 100644
index 00000000000..e2c1d2fac81
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ReadDevice.cpp
@@ -0,0 +1,64 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FloatMixer.h"
+#include "AUD_ReadDevice.h"
+#include "AUD_IReader.h"
+
+#include <cstring>
+
+AUD_ReadDevice::AUD_ReadDevice(AUD_Specs specs)
+{
+ m_specs = specs;
+
+ m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
+ m_mixer->setSpecs(m_specs);
+
+ m_playing = false;
+
+ create();
+}
+
+AUD_ReadDevice::~AUD_ReadDevice()
+{
+ destroy();
+}
+
+bool AUD_ReadDevice::read(sample_t* buffer, int length)
+{
+ if(m_playing)
+ mix(buffer, length);
+ else
+ if(m_specs.format == AUD_FORMAT_U8)
+ memset(buffer, 0x80, length * AUD_SAMPLE_SIZE(m_specs));
+ else
+ memset(buffer, 0, length * AUD_SAMPLE_SIZE(m_specs));
+ return m_playing;
+}
+
+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
new file mode 100644
index 00000000000..d69b0c31ea5
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ReadDevice.h
@@ -0,0 +1,68 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_READDEVICE
+#define AUD_READDEVICE
+
+#include "AUD_SoftwareDevice.h"
+
+/**
+ * This device enables to let the user read raw data out of it.
+ */
+class AUD_ReadDevice : public AUD_SoftwareDevice
+{
+protected:
+ virtual void playing(bool playing);
+
+private:
+ /**
+ * Whether the device currently.
+ */
+ bool m_playing;
+
+public:
+ /**
+ * 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(sample_t* buffer, int length);
+};
+
+#endif //AUD_READDEVICE
diff --git a/intern/audaspace/intern/AUD_Reference.h b/intern/audaspace/intern/AUD_Reference.h
new file mode 100644
index 00000000000..9bb9d7440b3
--- /dev/null
+++ b/intern/audaspace/intern/AUD_Reference.h
@@ -0,0 +1,115 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_REFERENCE
+#define AUD_REFERENCE
+
+template <class T>
+/**
+ * This class provides reference counting functionality.
+ */
+class AUD_Reference
+{
+private:
+ /// The reference.
+ T* m_reference;
+ /// The reference counter.
+ int* m_refcount;
+public:
+ /**
+ * Creates a new reference counter.
+ * \param reference The reference.
+ */
+ AUD_Reference(T* reference = 0)
+ {
+ m_reference = reference;
+ m_refcount = new int; AUD_NEW("int")
+ *m_refcount = 1;
+ }
+
+ /**
+ * Copies a AUD_Reference object.
+ * \param ref The AUD_Reference object to copy.
+ */
+ AUD_Reference(const AUD_Reference& ref)
+ {
+ m_reference = ref.m_reference;
+ m_refcount = ref.m_refcount;
+ (*m_refcount)++;
+ }
+
+ /**
+ * Destroys a AUD_Reference object, if there's no furthere reference on the
+ * reference, it is destroyed as well.
+ */
+ ~AUD_Reference()
+ {
+ (*m_refcount)--;
+ if(*m_refcount == 0)
+ {
+ if(m_reference != 0)
+ {
+ delete m_reference; AUD_DELETE("buffer")
+ }
+ delete m_refcount; AUD_DELETE("int")
+ }
+ }
+
+ /**
+ * Copies a AUD_Reference object.
+ * \param ref The AUD_Reference object to copy.
+ */
+ AUD_Reference& operator=(const AUD_Reference& ref)
+ {
+ if(&ref == this)
+ return *this;
+
+ (*m_refcount)--;
+ if(*m_refcount == 0)
+ {
+ if(m_reference != 0)
+ {
+ delete m_reference; AUD_DELETE("buffer")
+ }
+ delete m_refcount; AUD_DELETE("int")
+ }
+
+ m_reference = ref.m_reference;
+ m_refcount = ref.m_refcount;
+ (*m_refcount)++;
+
+ return *this;
+ }
+
+ /**
+ * Returns the reference.
+ */
+ T* get()
+ {
+ return m_reference;
+ }
+};
+
+#endif // AUD_REFERENCE
diff --git a/intern/audaspace/intern/AUD_ResampleFactory.h b/intern/audaspace/intern/AUD_ResampleFactory.h
new file mode 100644
index 00000000000..5493e1005b7
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ResampleFactory.h
@@ -0,0 +1,33 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_RESAMPLEFACTORY
+#define AUD_RESAMPLEFACTORY
+
+#include "AUD_MixerFactory.h"
+
+typedef AUD_MixerFactory AUD_ResampleFactory;
+
+#endif //AUD_RESAMPLEFACTORY
diff --git a/intern/audaspace/intern/AUD_SinusFactory.cpp b/intern/audaspace/intern/AUD_SinusFactory.cpp
new file mode 100644
index 00000000000..ae878b9df60
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SinusFactory.cpp
@@ -0,0 +1,51 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SinusFactory.h"
+#include "AUD_SinusReader.h"
+#include "AUD_Space.h"
+
+AUD_SinusFactory::AUD_SinusFactory(double frequency, AUD_SampleRate sampleRate)
+{
+ m_frequency = frequency;
+ m_sampleRate = sampleRate;
+}
+
+AUD_IReader* AUD_SinusFactory::createReader()
+{
+ AUD_IReader* reader = new AUD_SinusReader(m_frequency, m_sampleRate);
+ AUD_NEW("reader")
+ return reader;
+}
+
+double AUD_SinusFactory::getFrequency()
+{
+ return m_frequency;
+}
+
+void AUD_SinusFactory::setFrequency(double frequency)
+{
+ m_frequency = frequency;
+}
diff --git a/intern/audaspace/intern/AUD_SinusFactory.h b/intern/audaspace/intern/AUD_SinusFactory.h
new file mode 100644
index 00000000000..ffb36e741b9
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SinusFactory.h
@@ -0,0 +1,70 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SINUSFACTORY
+#define AUD_SINUSFACTORY
+
+#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.
+ */
+ double m_frequency;
+
+ /**
+ * The target sample rate for output.
+ */
+ AUD_SampleRate m_sampleRate;
+
+public:
+ /**
+ * Creates a new sine factory.
+ * \param frequency The desired frequency.
+ * \param sampleRate The target sample rate for playback.
+ */
+ AUD_SinusFactory(double frequency,
+ AUD_SampleRate sampleRate = AUD_RATE_44100);
+
+ /**
+ * Returns the frequency of the sine wave.
+ */
+ double getFrequency();
+
+ /**
+ * Sets the frequency.
+ * \param frequency The new frequency.
+ */
+ void setFrequency(double frequency);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_SINUSFACTORY
diff --git a/intern/audaspace/intern/AUD_SinusReader.cpp b/intern/audaspace/intern/AUD_SinusReader.cpp
new file mode 100644
index 00000000000..87e2f789d66
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SinusReader.cpp
@@ -0,0 +1,104 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SinusReader.h"
+#include "AUD_Buffer.h"
+
+#include <math.h>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+AUD_SinusReader::AUD_SinusReader(double frequency, AUD_SampleRate sampleRate)
+{
+ m_frequency = frequency;
+ m_position = 0;
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+ m_sampleRate = sampleRate;
+}
+
+AUD_SinusReader::~AUD_SinusReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+bool AUD_SinusReader::isSeekable()
+{
+ return true;
+}
+
+void AUD_SinusReader::seek(int position)
+{
+ m_position = position;
+}
+
+int AUD_SinusReader::getLength()
+{
+ return -1;
+}
+
+int AUD_SinusReader::getPosition()
+{
+ return m_position;
+}
+
+AUD_Specs AUD_SinusReader::getSpecs()
+{
+ AUD_Specs specs;
+ specs.rate = m_sampleRate;
+ specs.format = AUD_FORMAT_S16;
+ specs.channels = AUD_CHANNELS_STEREO;
+ return specs;
+}
+
+AUD_ReaderType AUD_SinusReader::getType()
+{
+ return AUD_TYPE_STREAM;
+}
+
+bool AUD_SinusReader::notify(AUD_Message &message)
+{
+ return false;
+}
+
+void AUD_SinusReader::read(int & length, sample_t* & buffer)
+{
+ // resize if necessary
+ if(m_buffer->getSize() < length*4)
+ m_buffer->resize(length*4);
+
+ // fill with sine data
+ short* buf = (short*) m_buffer->getBuffer();
+ for(int i=0; i < length; i++)
+ {
+ buf[i*2] = sin((m_position + i) * 2.0 * M_PI * m_frequency /
+ (float)m_sampleRate) * 32700;
+ buf[i*2+1] = buf[i*2];
+ }
+
+ buffer = (sample_t*)buf;
+ m_position += length;
+}
diff --git a/intern/audaspace/intern/AUD_SinusReader.h b/intern/audaspace/intern/AUD_SinusReader.h
new file mode 100644
index 00000000000..cb060dd8a43
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SinusReader.h
@@ -0,0 +1,86 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SINUSREADER
+#define AUD_SINUSREADER
+
+#include "AUD_IReader.h"
+class AUD_Buffer;
+
+/**
+ * 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_SinusReader : public AUD_IReader
+{
+private:
+ /**
+ * The frequency of the sine wave.
+ */
+ double m_frequency;
+
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer* m_buffer;
+
+ /**
+ * The sample rate for the output.
+ */
+ AUD_SampleRate m_sampleRate;
+
+public:
+ /**
+ * Creates a new reader.
+ * \param frequency The frequency of the sine wave.
+ * \param sampleRate The output sample rate.
+ */
+ AUD_SinusReader(double frequency, AUD_SampleRate sampleRate);
+
+ /**
+ * Destroys the reader.
+ */
+ virtual ~AUD_SinusReader();
+
+ virtual bool isSeekable();
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual AUD_ReaderType getType();
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SINUSREADER
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
new file mode 100644
index 00000000000..174ff8c8979
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -0,0 +1,444 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SoftwareDevice.h"
+#include "AUD_IReader.h"
+#include "AUD_IMixer.h"
+#include "AUD_IFactory.h"
+#include "AUD_SourceCaps.h"
+
+#include <cstring>
+
+/// Saves the data for playback.
+struct AUD_SoftwareHandle : AUD_Handle
+{
+ /// The reader source.
+ AUD_IReader* reader;
+
+ /// Whether to keep the source if end of it is reached.
+ bool keep;
+
+ /// The volume of the source.
+ float volume;
+};
+
+typedef std::list<AUD_SoftwareHandle*>::iterator AUD_HandleIterator;
+
+void AUD_SoftwareDevice::create()
+{
+ m_playingSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
+ m_pausedSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
+ m_playback = false;
+ m_volume = 1.0;
+
+ 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);
+
+ delete m_mixer; AUD_DELETE("mixer")
+
+ // delete all playing sounds
+ while(m_playingSounds->begin() != m_playingSounds->end())
+ {
+ delete (*(m_playingSounds->begin()))->reader; AUD_DELETE("reader")
+ delete *(m_playingSounds->begin()); AUD_DELETE("handle")
+ m_playingSounds->erase(m_playingSounds->begin());
+ }
+ delete m_playingSounds; AUD_DELETE("list")
+
+ // delete all paused sounds
+ while(m_pausedSounds->begin() != m_pausedSounds->end())
+ {
+ delete (*(m_pausedSounds->begin()))->reader; AUD_DELETE("reader")
+ delete *(m_pausedSounds->begin()); AUD_DELETE("handle")
+ m_pausedSounds->erase(m_pausedSounds->begin());
+ }
+ delete m_pausedSounds; AUD_DELETE("list")
+
+ pthread_mutex_destroy(&m_mutex);
+}
+
+void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
+{
+ lock();
+
+ AUD_SoftwareHandle* sound;
+ int len;
+ sample_t* buf;
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+ std::list<AUD_SoftwareHandle*> stopSounds;
+
+ // 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
+ len = length;
+ sound->reader->read(len, buf);
+
+ m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume);
+
+ // in case the end of the sound is reached
+ if(len < length)
+ {
+ if(sound->keep)
+ pause(sound);
+ else
+ stopSounds.push_back(sound);
+ }
+ }
+
+ // fill with silence
+ if(m_specs.format == AUD_FORMAT_U8)
+ memset(buffer, 0x80, length * sample_size);
+ else
+ memset(buffer, 0, length * sample_size);
+
+ // superpose
+ m_mixer->superpose(buffer, length, m_volume);
+
+ while(!stopSounds.empty())
+ {
+ sound = stopSounds.front();
+ stopSounds.pop_front();
+ stop(sound);
+ }
+
+ unlock();
+}
+
+bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
+{
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ if(*i == handle)
+ return true;
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ if(*i == handle)
+ return true;
+ return false;
+}
+
+void AUD_SoftwareDevice::setMixer(AUD_IMixer* mixer)
+{
+ delete m_mixer; AUD_DELETE("mixer")
+ m_mixer = mixer;
+ mixer->setSpecs(m_specs);
+}
+
+AUD_Specs AUD_SoftwareDevice::getSpecs()
+{
+ return m_specs;
+}
+
+AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep)
+{
+ AUD_IReader* reader = factory->createReader();
+
+ if(reader == NULL)
+ AUD_THROW(AUD_ERROR_READER);
+
+ // prepare the reader
+ reader = m_mixer->prepare(reader);
+ if(reader == NULL)
+ return NULL;
+
+ AUD_Specs rs = reader->getSpecs();
+
+ // play sound
+ AUD_SoftwareHandle* sound = new AUD_SoftwareHandle; AUD_NEW("handle")
+ sound->keep = keep;
+ sound->reader = reader;
+ sound->volume = 1.0;
+
+ lock();
+ m_playingSounds->push_back(sound);
+
+ if(!m_playback)
+ playing(m_playback = true);
+ unlock();
+
+ return sound;
+}
+
+bool AUD_SoftwareDevice::pause(AUD_Handle* handle)
+{
+ // only songs that are played can be paused
+ lock();
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ m_pausedSounds->push_back(*i);
+ m_playingSounds->erase(i);
+ if(m_playingSounds->empty())
+ playing(m_playback = false);
+ unlock();
+ return true;
+ }
+ }
+ unlock();
+ return false;
+}
+
+bool AUD_SoftwareDevice::resume(AUD_Handle* handle)
+{
+ // only songs that are paused can be resumed
+ lock();
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ m_playingSounds->push_back(*i);
+ m_pausedSounds->erase(i);
+ if(!m_playback)
+ playing(m_playback = true);
+ unlock();
+ return true;
+ }
+ }
+ unlock();
+ return false;
+}
+
+bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
+{
+ lock();
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ delete (*i)->reader; AUD_DELETE("reader")
+ delete *i; AUD_DELETE("handle")
+ m_playingSounds->erase(i);
+ if(m_playingSounds->empty())
+ playing(m_playback = false);
+ unlock();
+ return true;
+ }
+ }
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ delete (*i)->reader; AUD_DELETE("reader")
+ delete *i; AUD_DELETE("handle")
+ m_pausedSounds->erase(i);
+ unlock();
+ return true;
+ }
+ }
+ unlock();
+ return false;
+}
+
+bool AUD_SoftwareDevice::setKeep(AUD_Handle* handle, bool keep)
+{
+ lock();
+ if(isValid(handle))
+ {
+ ((AUD_SoftwareHandle*)handle)->keep = keep;
+ unlock();
+ return true;
+ }
+ unlock();
+ return false;
+}
+
+bool AUD_SoftwareDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
+{
+ lock();
+
+ bool result = false;
+
+ if(handle == 0)
+ {
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ result |= (*i)->reader->notify(message);
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ result |= (*i)->reader->notify(message);
+ }
+ else if(isValid(handle))
+ result = ((AUD_SoftwareHandle*)handle)->reader->notify(message);
+ unlock();
+ return result;
+}
+
+bool AUD_SoftwareDevice::seek(AUD_Handle* handle, float position)
+{
+ lock();
+
+ if(isValid(handle))
+ {
+ AUD_IReader* reader = ((AUD_SoftwareHandle*)handle)->reader;
+ reader->seek((int)(position * reader->getSpecs().rate));
+ unlock();
+ return true;
+ }
+
+ unlock();
+ return false;
+}
+
+float AUD_SoftwareDevice::getPosition(AUD_Handle* handle)
+{
+ lock();
+
+ float position = 0.0f;
+
+ if(isValid(handle))
+ {
+ AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle;
+ position = h->reader->getPosition() / (float)m_specs.rate;
+ }
+
+ unlock();
+ return position;
+}
+
+AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle)
+{
+ lock();
+ for(AUD_HandleIterator i = m_playingSounds->begin();
+ i != m_playingSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ unlock();
+ return AUD_STATUS_PLAYING;
+ }
+ }
+ for(AUD_HandleIterator i = m_pausedSounds->begin();
+ i != m_pausedSounds->end(); i++)
+ {
+ if(*i == handle)
+ {
+ unlock();
+ return AUD_STATUS_PAUSED;
+ }
+ }
+ unlock();
+ return AUD_STATUS_INVALID;
+}
+
+void AUD_SoftwareDevice::lock()
+{
+ pthread_mutex_lock(&m_mutex);
+}
+
+void AUD_SoftwareDevice::unlock()
+{
+ pthread_mutex_unlock(&m_mutex);
+}
+
+bool AUD_SoftwareDevice::checkCapability(int capability)
+{
+ return capability == AUD_CAPS_SOFTWARE_DEVICE ||
+ capability == AUD_CAPS_VOLUME ||
+ capability == AUD_CAPS_SOURCE_VOLUME;
+}
+
+bool AUD_SoftwareDevice::setCapability(int capability, void *value)
+{
+ switch(capability)
+ {
+ case AUD_CAPS_VOLUME:
+ lock();
+ m_volume = *((float*)value);
+ if(m_volume > 1.0)
+ m_volume = 1.0;
+ else if(m_volume < 0.0)
+ m_volume = 0.0;
+ unlock();
+ return true;
+ case AUD_CAPS_SOURCE_VOLUME:
+ {
+ AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
+ lock();
+ if(isValid(caps->handle))
+ {
+ AUD_SoftwareHandle* handle = (AUD_SoftwareHandle*)caps->handle;
+ handle->volume = caps->value;
+ if(handle->volume > 1.0)
+ handle->volume = 1.0;
+ else if(handle->volume < 0.0)
+ handle->volume = 0.0;
+ unlock();
+ return true;
+ }
+ unlock();
+ }
+ break;
+ }
+ return false;
+}
+
+bool AUD_SoftwareDevice::getCapability(int capability, void *value)
+{
+ switch(capability)
+ {
+ case AUD_CAPS_VOLUME:
+ lock();
+ *((float*)value) = m_volume;
+ unlock();
+ return true;
+ case AUD_CAPS_SOURCE_VOLUME:
+ {
+ AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
+ lock();
+ if(isValid(caps->handle))
+ {
+ caps->value = ((AUD_SoftwareHandle*)caps->handle)->volume;
+ unlock();
+ return true;
+ }
+ unlock();
+ }
+ break;
+ }
+ return false;
+}
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h
new file mode 100644
index 00000000000..3768786fa9c
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -0,0 +1,137 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SOFTWAREDEVICE
+#define AUD_SOFTWAREDEVICE
+
+#include "AUD_IDevice.h"
+struct AUD_SoftwareHandle;
+class AUD_IMixer;
+
+#include <list>
+#include <pthread.h>
+
+/**
+ * This device plays is a generic device with software mixing.
+ * 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
+{
+protected:
+ /**
+ * The specification of the device.
+ */
+ AUD_Specs m_specs;
+
+ /**
+ * The mixer. Will be deleted by the destroy function.
+ */
+ AUD_IMixer* m_mixer;
+
+ /**
+ * Initializes member variables.
+ */
+ void create();
+
+ /**
+ * Uninitializes member variables.
+ */
+ void destroy();
+
+ /**
+ * Mixes the next samples into the buffer.
+ * \param buffer The target buffer.
+ * \param length The length in samples to be filled.
+ */
+ void mix(sample_t* buffer, int length);
+
+ /**
+ * This function tells the device, to start or pause playback.
+ * \param playing True if device should playback.
+ */
+ virtual void playing(bool playing)=0;
+
+private:
+ /**
+ * The list of sounds that are currently playing.
+ */
+ std::list<AUD_SoftwareHandle*>* m_playingSounds;
+
+ /**
+ * The list of sounds that are currently paused.
+ */
+ std::list<AUD_SoftwareHandle*>* m_pausedSounds;
+
+ /**
+ * Whether there is currently playback.
+ */
+ bool m_playback;
+
+ /**
+ * The mutex for locking.
+ */
+ pthread_mutex_t m_mutex;
+
+ /**
+ * The overall volume of the device.
+ */
+ float m_volume;
+
+ /**
+ * Checks if a handle is valid.
+ * \param handle The handle to check.
+ * \return Whether the handle is valid.
+ */
+ bool isValid(AUD_Handle* handle);
+
+public:
+ /**
+ * Sets a new mixer.
+ * \param mixer The new mixer.
+ */
+ void setMixer(AUD_IMixer* mixer);
+
+ virtual AUD_Specs getSpecs();
+ virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
+ virtual bool pause(AUD_Handle* handle);
+ virtual bool resume(AUD_Handle* handle);
+ virtual bool stop(AUD_Handle* handle);
+ virtual bool setKeep(AUD_Handle* handle, bool keep);
+ virtual bool sendMessage(AUD_Handle* handle, AUD_Message &message);
+ virtual bool seek(AUD_Handle* handle, float position);
+ virtual float getPosition(AUD_Handle* handle);
+ virtual AUD_Status getStatus(AUD_Handle* handle);
+ virtual void lock();
+ virtual void unlock();
+ virtual bool checkCapability(int capability);
+ virtual bool setCapability(int capability, void *value);
+ virtual bool getCapability(int capability, void *value);
+};
+
+#endif //AUD_SOFTWAREDEVICE
diff --git a/intern/audaspace/intern/AUD_SourceCaps.h b/intern/audaspace/intern/AUD_SourceCaps.h
new file mode 100644
index 00000000000..b1edd2b9b4e
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SourceCaps.h
@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SOURCECAPS
+#define AUD_SOURCECAPS
+
+#include "AUD_IDevice.h"
+
+/// The structure for source capabilities.
+typedef struct
+{
+ /// The source to apply the capability on.
+ AUD_Handle* handle;
+
+ /// The value for the capability.
+ float value;
+} AUD_SourceCaps;
+
+#endif //AUD_SOURCECAPS
diff --git a/intern/audaspace/intern/AUD_Space.h b/intern/audaspace/intern/AUD_Space.h
new file mode 100644
index 00000000000..123d9c272a0
--- /dev/null
+++ b/intern/audaspace/intern/AUD_Space.h
@@ -0,0 +1,295 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SPACE
+#define AUD_SPACE
+
+/// The size of a format in bytes.
+#define AUD_FORMAT_SIZE(format) (format & 0x0F)
+/// The size of a sample in the specified format in bytes.
+#define AUD_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
+/// Throws a AUD_Exception with the provided error code.
+#define AUD_THROW(exception) { AUD_Exception e; e.error = exception; throw e; }
+
+/// 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 * 44100 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 5292000
+
+/// The default playback buffer size of a device.
+#define AUD_DEFAULT_BUFFER_SIZE 1024
+
+// Capability defines
+
+/// This capability checks whether a device is a 3D device. See AUD_I3DDevice.h.
+#define AUD_CAPS_3D_DEVICE 0x0001
+
+/**
+ * This capability checks whether a device is a software device. See
+ * AUD_SoftwareDevice.
+ */
+#define AUD_CAPS_SOFTWARE_DEVICE 0x0002
+
+/**
+ * This capability enables the user to set the overall volume of the device.
+ * You can set and get it with the pointer pointing to a float value between
+ * 0.0 (muted) and 1.0 (maximum volume).
+ */
+#define AUD_CAPS_VOLUME 0x0101
+
+/**
+ * This capability enables the user to set the volume of a source.
+ * You can set and get it with the pointer pointing to a AUD_SourceValue
+ * structure defined in AUD_SourceCaps.h.
+ */
+#define AUD_CAPS_SOURCE_VOLUME 0x1001
+
+/**
+ * This capability enables the user to set the pitch of a source.
+ * You can set and get it with the pointer pointing to a AUD_SourceValue
+ * structure defined in AUD_SourceCaps.h.
+ */
+#define AUD_CAPS_SOURCE_PITCH 0x1002
+
+/**
+ * This capability enables the user to buffer a factory into the device.
+ * Setting with the factory as pointer loads the factory into a device internal
+ * buffer. Play function calls with the buffered factory as argument result in
+ * the internal buffer being played back, so there's no reader created, what
+ * also results in not being able to send messages to that handle.
+ * A repeated call with the same factory doesn't do anything.
+ * A set call with a NULL pointer results in all buffered factories being
+ * deleted.
+ * \note This is only possible with factories that create readers of the buffer
+ * type.
+ */
+#define AUD_CAPS_BUFFERED_FACTORY 0x2001
+
+// Used for debugging memory leaks.
+//#define AUD_DEBUG_MEMORY
+
+#ifdef AUD_DEBUG_MEMORY
+int AUD_References(int count = 0, const char* text = "");
+#define AUD_NEW(text) AUD_References(1, text);
+#define AUD_DELETE(text) AUD_References(-1, text);
+#else
+#define AUD_NEW(text)
+#define AUD_DELETE(text)
+#endif
+
+/**
+ * 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_SURROUND72 = 9 /// 7.2 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_SampleRate;
+
+/**
+ * Type of a reader.
+ * @see AUD_IReader for details.
+ */
+typedef enum
+{
+ AUD_TYPE_INVALID = 0, /// Invalid reader type.
+ AUD_TYPE_BUFFER, /// Reader reads from a buffer.
+ AUD_TYPE_STREAM /// Reader reads from a stream.
+} AUD_ReaderType;
+
+/// 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;
+
+/// Error codes for exceptions (C++ library) or for return values (C API).
+typedef enum
+{
+ AUD_NO_ERROR = 0,
+ AUD_ERROR_READER,
+ AUD_ERROR_FACTORY,
+ AUD_ERROR_FILE,
+ AUD_ERROR_FFMPEG,
+ AUD_ERROR_SDL,
+ AUD_ERROR_OPENAL,
+ AUD_ERROR_JACK
+} AUD_Error;
+
+/// Message codes.
+typedef enum
+{
+ AUD_MSG_INVALID = 0, /// Invalid message.
+ AUD_MSG_LOOP, /// Loop reader message.
+ AUD_MSG_VOLUME /// Volume reader message.
+} AUD_MessageType;
+
+/// Fading types.
+typedef enum
+{
+ AUD_FADE_IN,
+ AUD_FADE_OUT
+} AUD_FadeType;
+
+/// 3D device settings.
+typedef enum
+{
+ AUD_3DS_NONE, /// No setting.
+ AUD_3DS_SPEED_OF_SOUND, /// Speed of sound.
+ AUD_3DS_DOPPLER_FACTOR, /// Doppler factor.
+ AUD_3DS_DISTANCE_MODEL /// Distance model.
+} AUD_3DSetting;
+
+/// Possible distance models for the 3D device.
+#define AUD_DISTANCE_MODEL_NONE 0.0f
+#define AUD_DISTANCE_MODEL_INVERSE 1.0f
+#define AUD_DISTANCE_MODEL_INVERSE_CLAMPED 2.0f
+#define AUD_DISTANCE_MODEL_LINEAR 3.0f
+#define AUD_DISTANCE_MODEL_LINEAR_CLAMPED 4.0f
+#define AUD_DISTANCE_MODEL_EXPONENT 5.0f
+#define AUD_DISTANCE_MODEL_EXPONENT_CLAMPED 6.0f
+
+/// 3D source settings.
+typedef enum
+{
+ AUD_3DSS_NONE, /// No setting.
+ AUD_3DSS_IS_RELATIVE, /// > 0 tells that the sound source is
+ /// relative to the listener
+ AUD_3DSS_MIN_GAIN, /// Minimum gain.
+ AUD_3DSS_MAX_GAIN, /// Maximum gain.
+ AUD_3DSS_REFERENCE_DISTANCE, /// Reference distance.
+ AUD_3DSS_MAX_DISTANCE, /// Maximum distance.
+ AUD_3DSS_ROLLOFF_FACTOR, /// Rolloff factor.
+ AUD_3DSS_CONE_INNER_ANGLE, /// Cone inner angle.
+ AUD_3DSS_CONE_OUTER_ANGLE, /// Cone outer angle.
+ AUD_3DSS_CONE_OUTER_GAIN /// Cone outer gain.
+} AUD_3DSourceSetting;
+
+/// Sample pointer type.
+typedef unsigned char sample_t;
+
+/// Specification of a sound source or device.
+typedef struct
+{
+ /// Sample rate in Hz.
+ AUD_SampleRate rate;
+
+ /// Sample format.
+ AUD_SampleFormat format;
+
+ /// Channel count.
+ AUD_Channels channels;
+} AUD_Specs;
+
+/// Exception structure.
+typedef struct
+{
+ /**
+ * Error code.
+ * \see AUD_Error
+ */
+ AUD_Error error;
+
+ // void* userData; - for the case it is needed someday
+} AUD_Exception;
+
+/// Message structure.
+typedef struct
+{
+ /**
+ * The message type.
+ */
+ AUD_MessageType type;
+
+ union
+ {
+ // loop reader
+ int loopcount;
+
+ // volume reader
+ float volume;
+ };
+} AUD_Message;
+
+/// Handle structure, for inherition.
+typedef struct
+{
+ /// x, y and z coordinates of the object.
+ float position[3];
+
+ /// x, y and z coordinates telling the velocity and direction of the object.
+ float velocity[3];
+
+ /// 3x3 matrix telling the orientation of the object.
+ float orientation[9];
+} AUD_3DData;
+
+#endif //AUD_SPACE
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
new file mode 100644
index 00000000000..11391fa4a08
--- /dev/null
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
@@ -0,0 +1,80 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_StreamBufferFactory.h"
+#include "AUD_BufferReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory)
+{
+ AUD_IReader* reader = factory->createReader();
+
+ if(reader == NULL)
+ AUD_THROW(AUD_ERROR_READER);
+
+ m_specs = reader->getSpecs();
+ m_buffer = AUD_Reference<AUD_Buffer>(new AUD_Buffer()); AUD_NEW("buffer")
+
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+ int length;
+ int index = 0;
+ sample_t* buffer;
+
+ // get an aproximated 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 we fill our buffer to the end
+ while(index == m_buffer.get()->getSize() / sample_size)
+ {
+ // increase
+ m_buffer.get()->resize(size*sample_size, true);
+
+ // read more
+ length = size-index;
+ reader->read(length, buffer);
+ memcpy(m_buffer.get()->getBuffer()+index*sample_size,
+ buffer,
+ length*sample_size);
+ size += AUD_BUFFER_RESIZE_BYTES / sample_size;
+ index += length;
+ }
+
+ m_buffer.get()->resize(index*sample_size, true);
+ delete reader; AUD_DELETE("reader")
+}
+
+AUD_IReader* AUD_StreamBufferFactory::createReader()
+{
+ AUD_IReader* reader = new AUD_BufferReader(m_buffer, m_specs);
+ AUD_NEW("reader")
+ return reader;
+}
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.h b/intern/audaspace/intern/AUD_StreamBufferFactory.h
new file mode 100644
index 00000000000..eda06f6c10c
--- /dev/null
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.h
@@ -0,0 +1,62 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_STREAMBUFFERFACTORY
+#define AUD_STREAMBUFFERFACTORY
+
+#include "AUD_IFactory.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+/**
+ * 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.
+ */
+ AUD_Reference<AUD_Buffer> m_buffer;
+
+ /**
+ * The specification of the samples.
+ */
+ AUD_Specs m_specs;
+
+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(AUD_IFactory* factory);
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_STREAMBUFFERFACTORY
diff --git a/intern/audaspace/intern/Makefile b/intern/audaspace/intern/Makefile
new file mode 100644
index 00000000000..4bdca04c1cb
--- /dev/null
+++ b/intern/audaspace/intern/Makefile
@@ -0,0 +1,70 @@
+#
+# $Id$
+#
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = audaspace
+DIR = $(OCGDIR)/intern/audaspace
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+ifeq ($(WITH_SDL),true)
+ CPPFLAGS += -DWITH_SDL
+ CPPFLAGS += $(NAN_SDLCFLAGS)
+endif
+
+ifeq ($(WITH_OPENAL),true)
+ CPPFLAGS += -DWITH_OPENAL
+ CPPFLAGS += -I../OpenAL
+endif
+
+ifeq ($(WITH_JACK),true)
+ CPPFLAGS += -DWITH_JACK
+ CPPFLAGS += $(NAN_JACKCFLAGS)
+ CPPFLAGS += -I../jack
+endif
+
+ifeq ($(WITH_FFMPEG),true)
+ CPPFLAGS += -DWITH_FFMPEG
+ CPPFLAGS += $(NAN_FFMPEGCFLAGS)
+endif
+
+ifeq ($(WITH_SNDFILE),true)
+ CPPFLAGS += -DWITH_SNDFILE
+ CPPFLAGS += -I../sndfile
+endif
+
+CPPFLAGS += -I$(LCGDIR)/samplerate/include/
+CPPFLAGS += -I../ffmpeg
+CPPFLAGS += -I../FX
+CPPFLAGS += -I../SDL
+CPPFLAGS += -I../SRC
+CPPFLAGS += -I..
+CPPFLAGS += -I.
diff --git a/intern/audaspace/jack/AUD_JackDevice.cpp b/intern/audaspace/jack/AUD_JackDevice.cpp
new file mode 100644
index 00000000000..4d8ab93d672
--- /dev/null
+++ b/intern/audaspace/jack/AUD_JackDevice.cpp
@@ -0,0 +1,149 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_FloatMixer.h"
+#include "AUD_JackDevice.h"
+#include "AUD_IReader.h"
+#include "AUD_Buffer.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+// AUD_XXX this is not realtime suitable!
+int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
+{
+ AUD_JackDevice* device = (AUD_JackDevice*)data;
+ unsigned int samplesize = AUD_SAMPLE_SIZE(device->m_specs);
+ if(device->m_buffer->getSize() < samplesize * length)
+ device->m_buffer->resize(samplesize * length);
+ device->mix(device->m_buffer->getBuffer(), length);
+
+ float* in = (float*) device->m_buffer->getBuffer();
+ float* out;
+ int count = device->m_specs.channels;
+
+ for(unsigned int i = 0; i < count; i++)
+ {
+ out = (float*)jack_port_get_buffer(device->m_ports[i], length);
+ for(unsigned int j = 0; j < length; j++)
+ out[j] = in[j * count + i];
+ }
+
+ return 0;
+}
+
+void AUD_JackDevice::jack_shutdown(void *data)
+{
+ AUD_JackDevice* device = (AUD_JackDevice*)data;
+ device->m_valid = false;
+}
+
+AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
+{
+ 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 = jack_client_open("Blender", options, &status);
+ if(m_client == NULL)
+ AUD_THROW(AUD_ERROR_JACK);
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer");
+
+ // set callbacks
+ jack_set_process_callback(m_client, AUD_JackDevice::jack_mix, this);
+ jack_on_shutdown(m_client, AUD_JackDevice::jack_shutdown, this);
+
+ // register our output channels which are called ports in jack
+ m_ports = new jack_port_t*[m_specs.channels]; AUD_NEW("jack_port")
+
+ try
+ {
+ char portname[64];
+ for(int i = 0; i < m_specs.channels; i++)
+ {
+ sprintf(portname, "out %d", i+1);
+ m_ports[i] = jack_port_register(m_client, portname,
+ JACK_DEFAULT_AUDIO_TYPE,
+ JackPortIsOutput, 0);
+ if(m_ports[i] == NULL)
+ AUD_THROW(AUD_ERROR_JACK);
+ }
+
+ m_specs.rate = (AUD_SampleRate)jack_get_sample_rate(m_client);
+
+ // activate the client
+ if(jack_activate(m_client))
+ AUD_THROW(AUD_ERROR_JACK);
+ }
+ catch(AUD_Exception)
+ {
+ jack_client_close(m_client);
+ delete[] m_ports; AUD_DELETE("jack_port")
+ delete m_buffer; AUD_DELETE("buffer");
+ throw;
+ }
+
+ const char** ports = jack_get_ports(m_client, NULL, NULL,
+ JackPortIsPhysical | JackPortIsInput);
+ if(ports != NULL)
+ {
+ for(int i = 0; i < m_specs.channels && ports[i]; i++)
+ jack_connect(m_client, jack_port_name(m_ports[i]), ports[i]);
+
+ free(ports);
+ }
+
+ m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
+ m_mixer->setSpecs(m_specs);
+
+ m_valid = true;
+
+ create();
+}
+
+AUD_JackDevice::~AUD_JackDevice()
+{
+ lock();
+ if(m_valid)
+ jack_client_close(m_client);
+ delete[] m_ports; AUD_DELETE("jack_port")
+ delete m_buffer; AUD_DELETE("buffer");
+ unlock();
+
+ destroy();
+}
+
+void AUD_JackDevice::playing(bool playing)
+{
+ // Do nothing.
+}
diff --git a/intern/audaspace/jack/AUD_JackDevice.h b/intern/audaspace/jack/AUD_JackDevice.h
new file mode 100644
index 00000000000..f0c887a2f43
--- /dev/null
+++ b/intern/audaspace/jack/AUD_JackDevice.h
@@ -0,0 +1,92 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_JACKDEVICE
+#define AUD_JACKDEVICE
+
+
+#include "AUD_SoftwareDevice.h"
+class AUD_Buffer;
+
+#include <jack.h>
+
+/**
+ * This device plays back through Jack.
+ */
+class AUD_JackDevice : public AUD_SoftwareDevice
+{
+private:
+ /**
+ * The output ports of jack.
+ */
+ jack_port_t** m_ports;
+
+ /**
+ * The jack client.
+ */
+ jack_client_t* m_client;
+
+ /**
+ * The output buffer.
+ */
+ AUD_Buffer* m_buffer;
+
+ /**
+ * Whether the device is valid.
+ */
+ bool m_valid;
+
+ /**
+ * Invalidates the jack device.
+ * \param data The jack device that gets invalidet by jack.
+ */
+ static void jack_shutdown(void *data);
+
+ /**
+ * Mixes the next bytes into the buffer.
+ * \param length The length in samples to be filled.
+ * \param data A pointer to the jack device.
+ * \return 0 what shows success.
+ */
+ static int jack_mix(jack_nframes_t length, void *data);
+
+protected:
+ virtual void playing(bool playing);
+
+public:
+ /**
+ * Creates a Jack client for audio output.
+ * \param specs The wanted audio specification, where only the channel count is important.
+ * \exception AUD_Exception Thrown if the audio device cannot be opened.
+ */
+ AUD_JackDevice(AUD_Specs specs);
+
+ /**
+ * Closes the Jack client.
+ */
+ virtual ~AUD_JackDevice();
+};
+
+#endif //AUD_JACKDEVICE
diff --git a/intern/audaspace/jack/Makefile b/intern/audaspace/jack/Makefile
new file mode 100644
index 00000000000..23cadf559c0
--- /dev/null
+++ b/intern/audaspace/jack/Makefile
@@ -0,0 +1,44 @@
+#
+# $Id$
+#
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): GSR
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = aud_jack
+DIR = $(OCGDIR)/intern/audaspace
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+# If we are here, jack is enable.
+CPPFLAGS += -DWITH_JACK
+CPPFLAGS += $(NAN_JACKCFLAGS)
+
+CPPFLAGS += -I../intern
+CPPFLAGS += -I..
+CPPFLAGS += -I.
diff --git a/intern/audaspace/make/msvc_9_0/audaspace.vcproj b/intern/audaspace/make/msvc_9_0/audaspace.vcproj
new file mode 100644
index 00000000000..93dcdd66628
--- /dev/null
+++ b/intern/audaspace/make/msvc_9_0/audaspace.vcproj
@@ -0,0 +1,768 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="INT_audaspace"
+ ProjectGUID="{87032FD2-9BA0-6B43-BE33-8902BA8F9172}"
+ RootNamespace="audaspace"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Blender Release|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\audaspace"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\audaspace"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
+ PreprocessorDefinitions="WIN32,NDEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\audaspace\audaspace.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\audaspace\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\audaspace\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\audaspace\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\libaudaspace.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Blender Debug|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\audaspace\debug"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\audaspace\debug"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
+ PreprocessorDefinitions="WIN32,_DEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\audaspace\debug\audaspace.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\audaspace\debug\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\audaspace\debug\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\audaspace\debug\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\debug\libaudaspace.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="3DPlugin Release|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="2"
+ AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
+ PreprocessorDefinitions="WIN32,NDEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\audaspace.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\mtdll\libaudaspace.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="3DPlugin Debug|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\debug"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\debug"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..;..\..\ffmpeg;..\..\FX;..\..\intern;..\..\OpenAL;..\..\SDL;..\..\SRC;..\..\sndfile;..\..\..\..\..\lib\windows\pthreads\include;..\..\..\..\..\lib\windows\samplerate\include;..\..\..\..\..\lib\windows\ffmpeg\include;..\..\..\..\..\lib\windows\ffmpeg\include\msvc;..\..\..\..\..\lib\windows\sdl\include;..\..\..\..\..\lib\windows\openal\include;..\..\..\..\..\lib\windows\jack\include;..\..\..\..\..\lib\windows\sndfile\include"
+ PreprocessorDefinitions="WIN32,_DEBUG,_LIB,WITH_FFMPEG,WITH_SDL,WITH_OPENAL"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\debug\audaspace.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\debug\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\debug\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\audaspace\mtdll\debug\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\mtdll\debug\libaudaspace.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="intern"
+ >
+ <File
+ RelativePath="..\..\intern\AUD_Buffer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_Buffer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_BufferReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_BufferReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_C-API.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ChannelMapperFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ChannelMapperFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ChannelMapperReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ChannelMapperReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ConverterFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ConverterFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ConverterFunctions.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ConverterFunctions.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ConverterReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ConverterReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_FileFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_FileFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_FloatMixer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_FloatMixer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_I3DDevice.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_IDevice.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_IFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_IMixer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_IReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_MixerFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_MixerFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_NULLDevice.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_NULLDevice.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ReadDevice.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ReadDevice.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_Reference.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_ResampleFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_SinusFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_SinusFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_SinusReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_SinusReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_SoftwareDevice.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_SoftwareDevice.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_SourceCaps.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_Space.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_StreamBufferFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\AUD_StreamBufferFactory.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="ffmpeg"
+ >
+ <File
+ RelativePath="..\..\ffmpeg\AUD_FFMPEGFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ffmpeg\AUD_FFMPEGFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ffmpeg\AUD_FFMPEGReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ffmpeg\AUD_FFMPEGReader.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="FX"
+ >
+ <File
+ RelativePath="..\..\FX\AUD_DelayFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_DelayFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_DelayReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_DelayReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_DoubleReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_DoubleReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_EffectFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_EffectFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_EffectReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_EffectReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_FaderFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_FaderFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_FaderReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_FaderReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LimiterFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LimiterFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LimiterReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LimiterReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LoopFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LoopFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LoopReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_LoopReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_PingPongFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_PingPongFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_PitchFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_PitchFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_PitchReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_PitchReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_ReverseFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_ReverseFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_ReverseReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_ReverseReader.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_VolumeFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_VolumeFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_VolumeReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FX\AUD_VolumeReader.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="OpenAL"
+ >
+ <File
+ RelativePath="..\..\OpenAL\AUD_OpenALDevice.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\OpenAL\AUD_OpenALDevice.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="SDL"
+ >
+ <File
+ RelativePath="..\..\SDL\AUD_SDLDevice.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SDL\AUD_SDLDevice.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SDL\AUD_SDLMixer.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SDL\AUD_SDLMixer.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SDL\AUD_SDLMixerFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SDL\AUD_SDLMixerFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SDL\AUD_SDLMixerReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SDL\AUD_SDLMixerReader.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="SRC"
+ >
+ <File
+ RelativePath="..\..\SRC\AUD_SRCResampleFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SRC\AUD_SRCResampleFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SRC\AUD_SRCResampleReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\SRC\AUD_SRCResampleReader.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="jack"
+ >
+ <File
+ RelativePath="..\..\jack\AUD_JackDevice.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\jack\AUD_JackDevice.h"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="sndfile"
+ >
+ <File
+ RelativePath="..\..\sndfile\AUD_SndFileFactory.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sndfile\AUD_SndFileFactory.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sndfile\AUD_SndFileReader.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\sndfile\AUD_SndFileReader.h"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\..\AUD_C-API.h"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
new file mode 100644
index 00000000000..bac6dc321f4
--- /dev/null
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SndFileFactory.h"
+#include "AUD_SndFileReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+AUD_SndFileFactory::AUD_SndFileFactory(const char* filename)
+{
+ if(filename != NULL)
+ {
+ m_filename = new char[strlen(filename)+1]; AUD_NEW("string")
+ strcpy(m_filename, filename);
+ }
+ else
+ m_filename = NULL;
+}
+
+AUD_SndFileFactory::AUD_SndFileFactory(unsigned char* buffer, int size)
+{
+ m_filename = NULL;
+ m_buffer = AUD_Reference<AUD_Buffer>(new AUD_Buffer(size));
+ memcpy(m_buffer.get()->getBuffer(), buffer, size);
+}
+
+AUD_SndFileFactory::~AUD_SndFileFactory()
+{
+ if(m_filename)
+ {
+ delete[] m_filename; AUD_DELETE("string")
+ }
+}
+
+AUD_IReader* AUD_SndFileFactory::createReader()
+{
+ AUD_IReader* reader;
+ if(m_filename)
+ reader = new AUD_SndFileReader(m_filename);
+ else
+ reader = new AUD_SndFileReader(m_buffer);
+ AUD_NEW("reader")
+ return reader;
+}
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.h b/intern/audaspace/sndfile/AUD_SndFileFactory.h
new file mode 100644
index 00000000000..98187ff1590
--- /dev/null
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.h
@@ -0,0 +1,71 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SNDFILEFACTORY
+#define AUD_SNDFILEFACTORY
+
+#include "AUD_IFactory.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+/**
+ * This factory reads a sound file via libsndfile.
+ */
+class AUD_SndFileFactory : public AUD_IFactory
+{
+private:
+ /**
+ * The filename of the sound source file.
+ */
+ char* m_filename;
+
+ /**
+ * The buffer to read from.
+ */
+ AUD_Reference<AUD_Buffer> m_buffer;
+
+public:
+ /**
+ * Creates a new factory.
+ * \param filename The sound file path.
+ */
+ AUD_SndFileFactory(const char* filename);
+
+ /**
+ * Creates a new factory.
+ * \param buffer The buffer to read from.
+ * \param size The size of the buffer.
+ */
+ AUD_SndFileFactory(unsigned char* buffer, int size);
+
+ /**
+ * Destroys the factory.
+ */
+ ~AUD_SndFileFactory();
+
+ virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_SNDFILEFACTORY
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.cpp b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
new file mode 100644
index 00000000000..485818552bb
--- /dev/null
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
@@ -0,0 +1,233 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SndFileReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+
+// This function transforms a SampleFormat to our own sample format
+static inline AUD_SampleFormat SNDFILE_TO_AUD(int fmt)
+{
+ switch(fmt & SF_FORMAT_SUBMASK)
+ {
+ // only read s16, s32 and double as they are
+ case SF_FORMAT_PCM_16:
+ return AUD_FORMAT_S16;
+ case SF_FORMAT_PCM_32:
+ return AUD_FORMAT_S32;
+ case SF_FORMAT_DOUBLE:
+ return AUD_FORMAT_FLOAT64;
+ // read all other formats as floats
+ default:
+ return AUD_FORMAT_FLOAT32;
+ }
+}
+
+sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
+{
+ AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
+ return reader->m_membuffer.get()->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.get()->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.get()->getSize())
+ count = reader->m_membuffer.get()->getSize() - reader->m_memoffset;
+
+ memcpy(ptr, reader->m_membuffer.get()->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;
+}
+
+AUD_SndFileReader::AUD_SndFileReader(const char* filename)
+{
+ SF_INFO sfinfo;
+
+ sfinfo.format = 0;
+ m_sndfile = sf_open(filename, SFM_READ, &sfinfo);
+
+ if(!m_sndfile)
+ AUD_THROW(AUD_ERROR_FILE);
+
+ m_specs.channels = (AUD_Channels) sfinfo.channels;
+ m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
+ m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
+ m_length = sfinfo.frames;
+ m_seekable = sfinfo.seekable;
+ m_position = 0;
+
+ switch(m_specs.format)
+ {
+ case AUD_FORMAT_S16:
+ m_read = (sf_read_f) sf_readf_short;
+ break;
+ case AUD_FORMAT_S32:
+ m_read = (sf_read_f) sf_readf_int;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_read = (sf_read_f) sf_readf_double;
+ break;
+ default:
+ m_read = (sf_read_f) sf_readf_float;
+ }
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer)
+{
+ 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);
+
+ m_specs.channels = (AUD_Channels) sfinfo.channels;
+ m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
+ m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
+ m_length = sfinfo.frames;
+ m_seekable = sfinfo.seekable;
+ m_position = 0;
+
+ switch(m_specs.format)
+ {
+ case AUD_FORMAT_S16:
+ m_read = (sf_read_f) sf_readf_short;
+ break;
+ case AUD_FORMAT_S32:
+ m_read = (sf_read_f) sf_readf_int;
+ break;
+ case AUD_FORMAT_FLOAT64:
+ m_read = (sf_read_f) sf_readf_double;
+ break;
+ default:
+ m_read = (sf_read_f) sf_readf_float;
+ }
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+}
+
+AUD_SndFileReader::~AUD_SndFileReader()
+{
+ sf_close(m_sndfile);
+
+ delete m_buffer; AUD_DELETE("buffer")
+}
+
+bool AUD_SndFileReader::isSeekable()
+{
+ 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()
+{
+ return m_length;
+}
+
+int AUD_SndFileReader::getPosition()
+{
+ return m_position;
+}
+
+AUD_Specs AUD_SndFileReader::getSpecs()
+{
+ return m_specs;
+}
+
+AUD_ReaderType AUD_SndFileReader::getType()
+{
+ return AUD_TYPE_STREAM;
+}
+
+bool AUD_SndFileReader::notify(AUD_Message &message)
+{
+ return false;
+}
+
+void AUD_SndFileReader::read(int & length, sample_t* & buffer)
+{
+ int sample_size = AUD_SAMPLE_SIZE(m_specs);
+
+ // resize output buffer if necessary
+ if(m_buffer->getSize() < length*sample_size)
+ m_buffer->resize(length*sample_size);
+
+ buffer = m_buffer->getBuffer();
+
+ length = m_read(m_sndfile, buffer, length);
+
+ m_position += length;
+}
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.h b/intern/audaspace/sndfile/AUD_SndFileReader.h
new file mode 100644
index 00000000000..da890ef53ca
--- /dev/null
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.h
@@ -0,0 +1,131 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SNDFILEREADER
+#define AUD_SNDFILEREADER
+
+#include "AUD_IReader.h"
+#include "AUD_Reference.h"
+class AUD_Buffer;
+
+#include <sndfile.h>
+
+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 playback buffer.
+ */
+ AUD_Buffer* m_buffer;
+
+ /**
+ * The sndfile.
+ */
+ SNDFILE* m_sndfile;
+
+ /**
+ * The reading function.
+ */
+ sf_read_f m_read;
+
+ /**
+ * The virtual IO structure for memory file reading.
+ */
+ SF_VIRTUAL_IO m_vio;
+
+ /**
+ * The pointer to the memory file.
+ */
+ AUD_Reference<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);
+
+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(const char* 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(AUD_Reference<AUD_Buffer> buffer);
+
+ /**
+ * Destroys the reader and closes the file.
+ */
+ virtual ~AUD_SndFileReader();
+
+ virtual bool isSeekable();
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual AUD_ReaderType getType();
+ virtual bool notify(AUD_Message &message);
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SNDFILEREADER
diff --git a/intern/audaspace/sndfile/Makefile b/intern/audaspace/sndfile/Makefile
new file mode 100644
index 00000000000..1cf0b2683fb
--- /dev/null
+++ b/intern/audaspace/sndfile/Makefile
@@ -0,0 +1,40 @@
+#
+# $Id$
+#
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s):
+#
+# ***** END GPL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = aud_sndfile
+DIR = $(OCGDIR)/intern/audaspace
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I../intern
+CPPFLAGS += -I..
+CPPFLAGS += -I.
diff --git a/intern/boolop/make/msvc_9_0/boolop.vcproj b/intern/boolop/make/msvc_9_0/boolop.vcproj
index 7fe83962695..357d189376a 100644
--- a/intern/boolop/make/msvc_9_0/boolop.vcproj
+++ b/intern/boolop/make/msvc_9_0/boolop.vcproj
@@ -119,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\extern;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\container\include;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include;..\..\..\..\source\blender\blenlib;..\..\..\..\source\blender\makesdna;$(NOINHERIT)"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/bsp/make/msvc_9_0/bsplib.vcproj b/intern/bsp/make/msvc_9_0/bsplib.vcproj
index a1b16d5b93f..ed6978b8229 100644
--- a/intern/bsp/make/msvc_9_0/bsplib.vcproj
+++ b/intern/bsp/make/msvc_9_0/bsplib.vcproj
@@ -119,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..;..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\moto\include;..\..\..\..\..\build\msvc_9\intern\container\include"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/container/make/msvc_9_0/container.vcproj b/intern/container/make/msvc_9_0/container.vcproj
index 2b40571672d..76bc56f413f 100644
--- a/intern/container/make/msvc_9_0/container.vcproj
+++ b/intern/container/make/msvc_9_0/container.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
StringPooling="true"
diff --git a/intern/decimation/make/msvc_9_0/decimation.vcproj b/intern/decimation/make/msvc_9_0/decimation.vcproj
index 7d58bf1f4c6..a75332857ad 100644
--- a/intern/decimation/make/msvc_9_0/decimation.vcproj
+++ b/intern/decimation/make/msvc_9_0/decimation.vcproj
@@ -119,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\container\include;..\..\..\..\..\build\msvc_9\intern\moto\include"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/elbeem/CMakeLists.txt b/intern/elbeem/CMakeLists.txt
index 03fd4a3fefc..e541d334086 100644
--- a/intern/elbeem/CMakeLists.txt
+++ b/intern/elbeem/CMakeLists.txt
@@ -24,17 +24,17 @@
#
# ***** END GPL LICENSE BLOCK *****
-SET(INC ${PNG_INC} ${ZLIB_INC} ${SDL_INC} extern)
+SET(INC ${PNG_INC} ${ZLIB_INC} extern)
FILE(GLOB SRC intern/*.cpp)
ADD_DEFINITIONS(-DNOGUI -DELBEEM_BLENDER=1)
IF(WINDOWS)
- ADD_DEFINITIONS(-DUSE_MSVC6FIXES)
+ ADD_DEFINITIONS(-DUSE_MSVC6FIXES)
ENDIF(WINDOWS)
IF(WITH_OPENMP)
- ADD_DEFINITIONS(-DPARALLEL=1)
+ ADD_DEFINITIONS(-DPARALLEL=1)
ENDIF(WITH_OPENMP)
BLENDERLIB_NOLIST(bf_elbeem "${SRC}" "${INC}")
diff --git a/intern/elbeem/SConscript b/intern/elbeem/SConscript
index 92e80c36cea..0900ab1db5c 100644
--- a/intern/elbeem/SConscript
+++ b/intern/elbeem/SConscript
@@ -10,7 +10,7 @@ defs = 'NOGUI ELBEEM_BLENDER=1'
if env['WITH_BF_OPENMP']:
defs += ' PARALLEL'
-if env['OURPLATFORM']=='win32-vc':
+if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'):
defs += ' USE_MSVC6FIXES'
incs = env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC']
incs += ' extern '
diff --git a/intern/elbeem/intern/paraloopend.h b/intern/elbeem/intern/paraloopend.h
index 6bb224b625a..a396e395126 100644
--- a/intern/elbeem/intern/paraloopend.h
+++ b/intern/elbeem/intern/paraloopend.h
@@ -22,9 +22,9 @@
{
if(doReduce) {
// synchronize global vars
- for(int j=0; j<calcListFull.size() ; j++) mListFull.push_back( calcListFull[j] );
- for(int j=0; j<calcListEmpty.size(); j++) mListEmpty.push_back( calcListEmpty[j] );
- for(int j=0; j<calcListParts.size(); j++) mpParticles->addFullParticle( calcListParts[j] );
+ for(size_t j=0; j<calcListFull.size() ; j++) mListFull.push_back( calcListFull[j] );
+ for(size_t j=0; j<calcListEmpty.size(); j++) mListEmpty.push_back( calcListEmpty[j] );
+ for(size_t j=0; j<calcListParts.size(); j++) mpParticles->addFullParticle( calcListParts[j] );
if(calcMaxVlen>mMaxVlen) {
mMxvx = calcMxvx;
mMxvy = calcMxvy;
diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp
index ce54adb48ee..fee011a70ae 100644
--- a/intern/elbeem/intern/solver_init.cpp
+++ b/intern/elbeem/intern/solver_init.cpp
@@ -1464,7 +1464,7 @@ void LbmFsgrSolver::initMovingObstacles(bool staticInit) {
obj->applyTransformation(targetTime, &mMOIVertices,NULL /* no old normals needed */, 0, mMOIVertices.size(), false );
} else {
// only do transform update
- obj->getMovingPoints(mMOIVertices,pNormals);
+ obj->getMovingPoints(mMOIVertices,pNormals); // mMOIVertices = mCachedMovPoints
mMOIVerticesOld = mMOIVertices;
// WARNING - assumes mSimulationTime is global!?
obj->applyTransformation(targetTime, &mMOIVertices,pNormals, 0, mMOIVertices.size(), false );
diff --git a/intern/elbeem/make/msvc_9_0/elbeem.vcproj b/intern/elbeem/make/msvc_9_0/elbeem.vcproj
index 4108e09799d..2369a76fff0 100644
--- a/intern/elbeem/make/msvc_9_0/elbeem.vcproj
+++ b/intern/elbeem/make/msvc_9_0/elbeem.vcproj
@@ -114,6 +114,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
AdditionalIncludeDirectories="..\..\intern;..\..\extern;..\..\..\..\..\lib\windows\png\include;..\..\..\..\..\lib\windows\zlib\include;..\..\..\..\source\kernel\gen_messaging;..\..\..\..\..\lib\windows\sdl\include"
PreprocessorDefinitions="WIN32;NDEBUG;_LIB;NOGUI;ELBEEM_BLENDER=1;LBM_INCLUDE_CONTROL=1"
StringPooling="true"
diff --git a/intern/ghost/CMakeLists.txt b/intern/ghost/CMakeLists.txt
index b559d49958c..9128e923e19 100644
--- a/intern/ghost/CMakeLists.txt
+++ b/intern/ghost/CMakeLists.txt
@@ -24,33 +24,35 @@
#
# ***** END GPL LICENSE BLOCK *****
-SET(INC . ../string ${WINTAB_INC})
+SET(INC . ../string)
FILE(GLOB SRC intern/*.cpp)
IF(APPLE)
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp")
ELSE(APPLE)
- IF(WIN32)
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp")
- ELSE(WIN32)
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
- LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
- ENDIF(WIN32)
+ IF(WIN32)
+ SET(INC ${INC} ${WINTAB_INC})
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerX11.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemX11.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowX11.cpp")
+ ELSE(WIN32)
+ SET(INC ${INC} ${X11_X11_INCLUDE_PATH})
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerWin32.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemWin32.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowWin32.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_DisplayManagerCarbon.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_SystemCarbon.cpp")
+ LIST(REMOVE_ITEM SRC "${CMAKE_CURRENT_SOURCE_DIR}/intern/GHOST_WindowCarbon.cpp")
+ ENDIF(WIN32)
ENDIF(APPLE)
BLENDERLIB(bf_ghost "${SRC}" "${INC}")
diff --git a/intern/ghost/GHOST_C-api.h b/intern/ghost/GHOST_C-api.h
index c3158214830..c0b7077fb53 100644
--- a/intern/ghost/GHOST_C-api.h
+++ b/intern/ghost/GHOST_C-api.h
@@ -367,6 +367,17 @@ extern GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
GHOST_TInt32 x,
GHOST_TInt32 y);
+/**
+ * Grabs the cursor for a modal operation, to keep receiving
+ * events when the mouse is outside the window. X11 only, others
+ * do this automatically.
+ * @param windowhandle The handle to the window
+ * @param grab The new grab state of the cursor.
+ * @return Indication of success.
+ */
+extern GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
+ int grab);
+
/***************************************************************************************
** Access to mouse button and keyboard states.
***************************************************************************************/
diff --git a/intern/ghost/GHOST_IWindow.h b/intern/ghost/GHOST_IWindow.h
index 0861d8b8946..d91995e35ec 100644
--- a/intern/ghost/GHOST_IWindow.h
+++ b/intern/ghost/GHOST_IWindow.h
@@ -252,6 +252,14 @@ public:
* @return Indication of success.
*/
virtual GHOST_TSuccess setCursorVisibility(bool visible) = 0;
+
+ /**
+ * Grabs the cursor for a modal operation.
+ * @param grab The new grab state of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorGrab(bool grab) { return GHOST_kSuccess; };
+
};
#endif // _GHOST_IWINDOW_H_
diff --git a/intern/ghost/GHOST_Types.h b/intern/ghost/GHOST_Types.h
index 2441251dc33..31819f341a0 100644
--- a/intern/ghost/GHOST_Types.h
+++ b/intern/ghost/GHOST_Types.h
@@ -64,8 +64,14 @@ typedef enum
* the pen's angle in 3D space vertically downwards on to the XY plane
* --Matt
*/
+typedef enum {
+ GHOST_kTabletModeNone = 0,
+ GHOST_kTabletModeStylus,
+ GHOST_kTabletModeEraser
+} GHOST_TTabletMode;
+
typedef struct GHOST_TabletData {
- char Active; /* 0=None, 1=Stylus, 2=Eraser */
+ GHOST_TTabletMode Active; /* 0=None, 1=Stylus, 2=Eraser */
float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */
float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */
float Ytilt; /* as above */
@@ -126,6 +132,8 @@ typedef enum {
GHOST_kButtonMaskLeft = 0,
GHOST_kButtonMaskMiddle,
GHOST_kButtonMaskRight,
+ GHOST_kButtonMaskButton4,
+ GHOST_kButtonMaskButton5,
GHOST_kButtonNumMasks
} GHOST_TButtonMask;
diff --git a/intern/ghost/SConscript b/intern/ghost/SConscript
index 9de82ac44fb..48009152699 100644
--- a/intern/ghost/SConscript
+++ b/intern/ghost/SConscript
@@ -29,4 +29,4 @@ else:
incs = '. ../string ' + env['BF_OPENGL_INC']
if window_system in ('win32-vc', 'win32-mingw', 'cygwin', 'linuxcross', 'win64-vc'):
incs = env['BF_WINTAB_INC'] + ' ' + incs
-env.BlenderLib ('bf_ghost', sources, Split(incs), defines=['_USE_MATH_DEFINES'], libtype=['intern'], priority = [40] )
+env.BlenderLib ('bf_ghost', sources, Split(incs), defines=['_USE_MATH_DEFINES'], libtype=['intern','player'], priority = [40,15] )
diff --git a/intern/ghost/intern/GHOST_C-api.cpp b/intern/ghost/intern/GHOST_C-api.cpp
index 401dba8d240..5c23b6c42a3 100644
--- a/intern/ghost/intern/GHOST_C-api.cpp
+++ b/intern/ghost/intern/GHOST_C-api.cpp
@@ -354,6 +354,14 @@ GHOST_TSuccess GHOST_SetCursorPosition(GHOST_SystemHandle systemhandle,
}
+GHOST_TSuccess GHOST_SetCursorGrab(GHOST_WindowHandle windowhandle,
+ int grab)
+{
+ GHOST_IWindow* window = (GHOST_IWindow*) windowhandle;
+
+ return window->setCursorGrab(grab?true:false);
+}
+
GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
GHOST_TModifierKeyMask mask,
diff --git a/intern/ghost/intern/GHOST_EventManager.cpp b/intern/ghost/intern/GHOST_EventManager.cpp
index f9b13115f32..92cea8d8ff7 100644
--- a/intern/ghost/intern/GHOST_EventManager.cpp
+++ b/intern/ghost/intern/GHOST_EventManager.cpp
@@ -51,6 +51,15 @@ GHOST_EventManager::GHOST_EventManager()
GHOST_EventManager::~GHOST_EventManager()
{
disposeEvents();
+
+ TConsumerVector::iterator iter= m_consumers.begin();
+ while (iter != m_consumers.end())
+ {
+ GHOST_IEventConsumer* consumer = *iter;
+ delete consumer;
+ m_consumers.erase(iter);
+ iter = m_consumers.begin();
+ }
}
diff --git a/intern/ghost/intern/GHOST_System.cpp b/intern/ghost/intern/GHOST_System.cpp
index 87e5f375958..84298d3e3ff 100644
--- a/intern/ghost/intern/GHOST_System.cpp
+++ b/intern/ghost/intern/GHOST_System.cpp
@@ -290,7 +290,8 @@ GHOST_TSuccess GHOST_System::init()
#ifdef GHOST_DEBUG
if (m_eventManager) {
- m_eventManager->addConsumer(&m_eventPrinter);
+ m_eventPrinter = new GHOST_EventPrinter();
+ m_eventManager->addConsumer(m_eventPrinter);
}
#endif // GHOST_DEBUG
diff --git a/intern/ghost/intern/GHOST_System.h b/intern/ghost/intern/GHOST_System.h
index 9310e9b2591..066fe4b93d3 100644
--- a/intern/ghost/intern/GHOST_System.h
+++ b/intern/ghost/intern/GHOST_System.h
@@ -335,7 +335,7 @@ protected:
/** Prints all the events. */
#ifdef GHOST_DEBUG
- GHOST_EventPrinter m_eventPrinter;
+ GHOST_EventPrinter* m_eventPrinter;
#endif // GHOST_DEBUG
/** Settings of the display before the display went fullscreen. */
diff --git a/intern/ghost/intern/GHOST_SystemCarbon.cpp b/intern/ghost/intern/GHOST_SystemCarbon.cpp
index fb1b96fcbc7..57d6f6c06cc 100644
--- a/intern/ghost/intern/GHOST_SystemCarbon.cpp
+++ b/intern/ghost/intern/GHOST_SystemCarbon.cpp
@@ -788,21 +788,21 @@ OSStatus GHOST_SystemCarbon::handleTabletEvent(EventRef event)
switch(tabletProximityRecord.pointerType)
{
case 1: /* stylus */
- ct.Active = 1;
+ ct.Active = GHOST_kTabletModeStylus;
break;
case 2: /* puck, not supported so far */
- ct.Active = 0;
+ ct.Active = GHOST_kTabletModeNone;
break;
case 3: /* eraser */
- ct.Active = 2;
+ ct.Active = GHOST_kTabletModeEraser;
break;
default:
- ct.Active = 0;
+ ct.Active = GHOST_kTabletModeNone;
break;
}
} else {
// pointer is leaving - return to mouse
- ct.Active = 0;
+ ct.Active = GHOST_kTabletModeNone;
}
}
}
diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp
index 8513d056795..2e89be40bcb 100644
--- a/intern/ghost/intern/GHOST_SystemWin32.cpp
+++ b/intern/ghost/intern/GHOST_SystemWin32.cpp
@@ -39,7 +39,6 @@
#endif
#include "GHOST_SystemWin32.h"
-//#include <stdio.h> //for printf()
// win64 doesn't define GWL_USERDATA
#ifdef WIN32
@@ -61,6 +60,23 @@
#define WHEEL_DELTA 120 /* Value for rolling one detent, (old convention! MS changed it) */
#endif // WHEEL_DELTA
+/*
+ * Defines for mouse buttons 4 and 5 aka xbutton1 and xbutton2.
+ * MSDN: Declared in Winuser.h, include Windows.h
+ * This does not seem to work with MinGW so we define our own here.
+ */
+#ifndef XBUTTON1
+#define XBUTTON1 0x0001
+#endif // XBUTTON1
+#ifndef XBUTTON2
+#define XBUTTON2 0x0002
+#endif // XBUTTON2
+#ifndef WM_XBUTTONUP
+#define WM_XBUTTONUP 524
+#endif // WM_XBUTTONUP
+#ifndef WM_XBUTTONDOWN
+#define WM_XBUTTONDOWN 523
+#endif // WM_XBUTTONDOWN
#include "GHOST_Debug.h"
#include "GHOST_DisplayManagerWin32.h"
@@ -672,6 +688,14 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
window->registerMouseClickEvent(true);
event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskRight);
break;
+ case WM_XBUTTONDOWN:
+ window->registerMouseClickEvent(true);
+ if ((short) HIWORD(wParam) == XBUTTON1){
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton4);
+ }else if((short) HIWORD(wParam) == XBUTTON2){
+ event = processButtonEvent(GHOST_kEventButtonDown, window, GHOST_kButtonMaskButton5);
+ }
+ break;
case WM_LBUTTONUP:
window->registerMouseClickEvent(false);
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskLeft);
@@ -684,6 +708,14 @@ LRESULT WINAPI GHOST_SystemWin32::s_wndProc(HWND hwnd, UINT msg, WPARAM wParam,
window->registerMouseClickEvent(false);
event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskRight);
break;
+ case WM_XBUTTONUP:
+ window->registerMouseClickEvent(false);
+ if ((short) HIWORD(wParam) == XBUTTON1){
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton4);
+ }else if((short) HIWORD(wParam) == XBUTTON2){
+ event = processButtonEvent(GHOST_kEventButtonUp, window, GHOST_kButtonMaskButton5);
+ }
+ break;
case WM_MOUSEMOVE:
event = processCursorEvent(GHOST_kEventCursorMove, window);
break;
diff --git a/intern/ghost/intern/GHOST_SystemX11.cpp b/intern/ghost/intern/GHOST_SystemX11.cpp
index a975322e9ce..cdbdce9c2ca 100644
--- a/intern/ghost/intern/GHOST_SystemX11.cpp
+++ b/intern/ghost/intern/GHOST_SystemX11.cpp
@@ -148,6 +148,13 @@ GHOST_SystemX11(
}
+GHOST_SystemX11::
+~GHOST_SystemX11()
+{
+ XCloseDisplay(m_display);
+}
+
+
GHOST_TSuccess
GHOST_SystemX11::
init(
@@ -155,11 +162,9 @@ init(
GHOST_TSuccess success = GHOST_System::init();
if (success) {
- m_keyboard_vector = new char[32];
-
m_displayManager = new GHOST_DisplayManagerX11(this);
- if (m_keyboard_vector && m_displayManager) {
+ if (m_displayManager) {
return GHOST_kSuccess;
}
}
@@ -439,10 +444,15 @@ GHOST_SystemX11::processEvent(XEvent *xe)
XButtonEvent & xbe = xe->xbutton;
GHOST_TButtonMask gbmask = GHOST_kButtonMaskLeft;
-
switch (xbe.button) {
case Button1 : gbmask = GHOST_kButtonMaskLeft; break;
case Button3 : gbmask = GHOST_kButtonMaskRight; break;
+ /* It seems events 6 and 7 are for horizontal scrolling.
+ * you can re-order button mapping like this... (swaps 6,7 with 8,9)
+ * xmodmap -e "pointer = 1 2 3 4 5 8 9 6 7"
+ */
+ case 8 : gbmask = GHOST_kButtonMaskButton4; break; /* Button4 is the wheel */
+ case 9 : gbmask = GHOST_kButtonMaskButton5; break; /* Button5 is a wheel too */
default:
case Button2 : gbmask = GHOST_kButtonMaskMiddle; break;
}
@@ -534,11 +544,28 @@ GHOST_SystemX11::processEvent(XEvent *xe)
window, data);
}
} else if (((Atom)xcme.data.l[0]) == m_wm_take_focus) {
+ XWindowAttributes attr;
+ Window fwin;
+ int revert_to;
+
/* as ICCCM say, we need reply this event
* with a SetInputFocus, the data[1] have
* the valid timestamp (send by the wm).
+ *
+ * Some WM send this event before the
+ * window is really mapped (for example
+ * change from virtual desktop), so we need
+ * to be sure that our windows is mapped
+ * or this call fail and close blender.
*/
- XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]);
+ if (XGetWindowAttributes(m_display, xcme.window, &attr) == True) {
+ if (XGetInputFocus(m_display, &fwin, &revert_to) == True) {
+ if (attr.map_state == IsViewable) {
+ if (fwin != xcme.window)
+ XSetInputFocus(m_display, xcme.window, RevertToParent, xcme.data.l[1]);
+ }
+ }
+ }
} else {
/* Unknown client message, ignore */
}
@@ -550,11 +577,26 @@ GHOST_SystemX11::processEvent(XEvent *xe)
// We're not interested in the following things.(yet...)
case NoExpose :
case GraphicsExpose :
+ break;
case EnterNotify:
case LeaveNotify:
+ {
// XCrossingEvents pointer leave enter window.
+ // also do cursor move here, MotionNotify only
+ // happens when motion starts & ends inside window
+ XCrossingEvent &xce = xe->xcrossing;
+
+ g_event = new
+ GHOST_EventCursor(
+ getMilliSeconds(),
+ GHOST_kEventCursorMove,
+ window,
+ xce.x_root,
+ xce.y_root
+ );
break;
+ }
case MapNotify:
/*
* From ICCCM:
@@ -647,12 +689,12 @@ GHOST_SystemX11::processEvent(XEvent *xe)
{
XProximityNotifyEvent* data = (XProximityNotifyEvent*)xe;
if(data->deviceid == window->GetXTablet().StylusID)
- window->GetXTablet().CommonData.Active= 1;
+ window->GetXTablet().CommonData.Active= GHOST_kTabletModeStylus;
else if(data->deviceid == window->GetXTablet().EraserID)
- window->GetXTablet().CommonData.Active= 2;
+ window->GetXTablet().CommonData.Active= GHOST_kTabletModeEraser;
}
else if(xe->type == window->GetXTablet().ProxOutEvent)
- window->GetXTablet().CommonData.Active= 0;
+ window->GetXTablet().CommonData.Active= GHOST_kTabletModeNone;
break;
}
@@ -683,9 +725,9 @@ getModifierKeys(
// analyse the masks retuned from XQueryPointer.
- memset(m_keyboard_vector,0,sizeof(m_keyboard_vector));
+ memset((void *)m_keyboard_vector,0,sizeof(m_keyboard_vector));
- XQueryKeymap(m_display,m_keyboard_vector);
+ XQueryKeymap(m_display,(char *)m_keyboard_vector);
// now translate key symobols into keycodes and
// test with vector.
diff --git a/intern/ghost/intern/GHOST_SystemX11.h b/intern/ghost/intern/GHOST_SystemX11.h
index 711a188ffe9..782f08f6737 100644
--- a/intern/ghost/intern/GHOST_SystemX11.h
+++ b/intern/ghost/intern/GHOST_SystemX11.h
@@ -59,6 +59,12 @@ public:
GHOST_SystemX11(
);
+ /**
+ * Destructor.
+ */
+ virtual ~GHOST_SystemX11();
+
+
GHOST_TSuccess
init(
);
@@ -258,7 +264,7 @@ private :
GHOST_TUns64 m_start_time;
/// A vector of keyboard key masks
- char *m_keyboard_vector;
+ char m_keyboard_vector[32];
/**
* Return the ghost window associated with the
diff --git a/intern/ghost/intern/GHOST_Window.cpp b/intern/ghost/intern/GHOST_Window.cpp
index a35680d1586..dee890830a1 100644
--- a/intern/ghost/intern/GHOST_Window.cpp
+++ b/intern/ghost/intern/GHOST_Window.cpp
@@ -50,6 +50,7 @@ GHOST_Window::GHOST_Window(
:
m_drawingContextType(type),
m_cursorVisible(true),
+ m_cursorGrabbed(true),
m_cursorShape(GHOST_kStandardCursorDefault),
m_stereoVisual(stereoVisual)
{
@@ -93,6 +94,20 @@ GHOST_TSuccess GHOST_Window::setCursorVisibility(bool visible)
}
}
+GHOST_TSuccess GHOST_Window::setCursorGrab(bool grab)
+{
+ if(m_cursorGrabbed == grab)
+ return GHOST_kSuccess;
+
+ if (setWindowCursorGrab(grab)) {
+ m_cursorGrabbed = grab;
+ return GHOST_kSuccess;
+ }
+ else {
+ return GHOST_kFailure;
+ }
+}
+
GHOST_TSuccess GHOST_Window::setCursorShape(GHOST_TStandardCursor cursorShape)
{
if (setWindowCursorShape(cursorShape)) {
diff --git a/intern/ghost/intern/GHOST_Window.h b/intern/ghost/intern/GHOST_Window.h
index 06318613b14..88178bae5b3 100644
--- a/intern/ghost/intern/GHOST_Window.h
+++ b/intern/ghost/intern/GHOST_Window.h
@@ -167,6 +167,13 @@ public:
virtual GHOST_TSuccess setCursorVisibility(bool visible);
/**
+ * Sets the cursor grab.
+ * @param grab The new grab state of the cursor.
+ * @return Indication of success.
+ */
+ virtual GHOST_TSuccess setCursorGrab(bool grab);
+
+ /**
* Returns the type of drawing context used in this window.
* @return The current type of drawing context.
*/
@@ -218,6 +225,12 @@ protected:
* native window system calls.
*/
virtual GHOST_TSuccess setWindowCursorVisibility(bool visible) = 0;
+
+ /**
+ * Sets the cursor grab on the window using
+ * native window system calls.
+ */
+ virtual GHOST_TSuccess setWindowCursorGrab(bool grab) { return GHOST_kSuccess; };
/**
* Sets the cursor shape on the window using
@@ -242,6 +255,9 @@ protected:
/** The current visibility of the cursor */
bool m_cursorVisible;
+
+ /** The current grabbed state of the cursor */
+ bool m_cursorGrabbed;
/** The current shape of the cursor */
GHOST_TStandardCursor m_cursorShape;
diff --git a/intern/ghost/intern/GHOST_WindowCarbon.cpp b/intern/ghost/intern/GHOST_WindowCarbon.cpp
index 87bb86a37e7..362e949a0a4 100644
--- a/intern/ghost/intern/GHOST_WindowCarbon.cpp
+++ b/intern/ghost/intern/GHOST_WindowCarbon.cpp
@@ -183,7 +183,7 @@ GHOST_WindowCarbon::GHOST_WindowCarbon(
updateDrawingContext();
activateDrawingContext();
- m_tablet.Active = 0;
+ m_tablet.Active = GHOST_kTabletModeNone;
}
}
diff --git a/intern/ghost/intern/GHOST_WindowManager.cpp b/intern/ghost/intern/GHOST_WindowManager.cpp
index 2b0809929c5..af96653db13 100644
--- a/intern/ghost/intern/GHOST_WindowManager.cpp
+++ b/intern/ghost/intern/GHOST_WindowManager.cpp
@@ -54,6 +54,7 @@ GHOST_WindowManager::GHOST_WindowManager() :
GHOST_WindowManager::~GHOST_WindowManager()
{
+ /* m_windows is freed by GHOST_System::disposeWindow */
}
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 759951802af..e2caf31edee 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -117,18 +117,34 @@ GHOST_WindowWin32::GHOST_WindowWin32(
m_maxPressure(0)
{
if (state != GHOST_kWindowStateFullScreen) {
- // take taskbar into account
RECT rect;
+ GHOST_TUns32 tw, th;
+
+ width += GetSystemMetrics(SM_CXSIZEFRAME)*2;
+ height += GetSystemMetrics(SM_CYSIZEFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);
+
+ // take taskbar into account
SystemParametersInfo(SPI_GETWORKAREA,0,&rect,0);
- height = rect.bottom - rect.top;
- width = rect.right - rect.left;
+ th = rect.bottom - rect.top;
+ tw = rect.right - rect.left;
+
+ if(tw < width)
+ {
+ width = tw;
+ left = rect.left;
+ }
+ if(th < height)
+ {
+ height = th;
+ top = rect.top;
+ }
m_hWnd = ::CreateWindow(
s_windowClassName, // pointer to registered class name
title, // pointer to window name
WS_OVERLAPPEDWINDOW, // window style
- rect.left, // horizontal position of window
- rect.top, // vertical position of window
+ left, // horizontal position of window
+ top, // vertical position of window
width, // window width
height, // window height
0, // handle to parent or owner window
@@ -228,7 +244,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(
m_tablet = fpWTOpen( m_hWnd, &lc, TRUE );
if (m_tablet) {
m_tabletData = new GHOST_TabletData();
- m_tabletData->Active = 0;
+ m_tabletData->Active = GHOST_kTabletModeNone;
}
}
}
@@ -688,7 +704,7 @@ void GHOST_WindowWin32::processWin32TabletInitEvent()
}
}
- m_tabletData->Active = 0;
+ m_tabletData->Active = GHOST_kTabletModeNone;
}
}
}
@@ -704,15 +720,15 @@ void GHOST_WindowWin32::processWin32TabletEvent(WPARAM wParam, LPARAM lParam)
switch (pkt.pkCursor) {
case 0: /* first device */
case 3: /* second device */
- m_tabletData->Active = 0; /* puck - not yet supported */
+ m_tabletData->Active = GHOST_kTabletModeNone; /* puck - not yet supported */
break;
case 1:
case 4:
- m_tabletData->Active = 1; /* stylus */
+ m_tabletData->Active = GHOST_kTabletModeStylus; /* stylus */
break;
case 2:
case 5:
- m_tabletData->Active = 2; /* eraser */
+ m_tabletData->Active = GHOST_kTabletModeEraser; /* eraser */
break;
}
if (m_maxPressure > 0) {
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index 2cc30aaa5bc..060e9ca6f6c 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -42,6 +42,9 @@
#include <cstring>
#include <cstdio>
+#include <algorithm>
+#include <string>
+
// For obscure full screen mode stuuf
// lifted verbatim from blut.
@@ -187,6 +190,8 @@ GHOST_WindowX11(
printf("%s:%d: X11 glxChooseVisual() failed for OpenGL, verify working openGL system!\n", __FILE__, __LINE__);
return;
}
+
+ memset(&m_xtablet, 0, sizeof(m_xtablet));
// Create a bunch of attributes needed to create an X window.
@@ -289,7 +294,7 @@ GHOST_WindowX11(
}
// Create some hints for the window manager on how
- // we want this window treated.
+ // we want this window treated.
XSizeHints * xsizehints = XAllocSizeHints();
xsizehints->flags = USPosition | USSize;
@@ -409,6 +414,100 @@ static int ApplicationErrorHandler(Display *display, XErrorEvent *theEvent) {
return 0 ;
}
+/* These C functions are copied from Wine 1.1.13's wintab.c */
+#define BOOL int
+#define TRUE 1
+#define FALSE 0
+
+static bool match_token(const char *haystack, const char *needle)
+{
+ const char *p, *q;
+ for (p = haystack; *p; )
+ {
+ while (*p && isspace(*p))
+ p++;
+ if (! *p)
+ break;
+
+ for (q = needle; *q && *p && tolower(*p) == tolower(*q); q++)
+ p++;
+ if (! *q && (isspace(*p) || !*p))
+ return TRUE;
+
+ while (*p && ! isspace(*p))
+ p++;
+ }
+ return FALSE;
+}
+
+/* Determining if an X device is a Tablet style device is an imperfect science.
+** We rely on common conventions around device names as well as the type reported
+** by Wacom tablets. This code will likely need to be expanded for alternate tablet types
+**
+** Wintab refers to any device that interacts with the tablet as a cursor,
+** (stylus, eraser, tablet mouse, airbrush, etc)
+** this is not to be confused with wacom x11 configuration "cursor" device.
+** Wacoms x11 config "cursor" refers to its device slot (which we mirror with
+** our gSysCursors) for puck like devices (tablet mice essentially).
+*/
+#if 0 // unused
+static BOOL is_tablet_cursor(const char *name, const char *type)
+{
+ int i;
+ static const char *tablet_cursor_whitelist[] = {
+ "wacom",
+ "wizardpen",
+ "acecad",
+ "tablet",
+ "cursor",
+ "stylus",
+ "eraser",
+ "pad",
+ NULL
+ };
+
+ for (i=0; tablet_cursor_whitelist[i] != NULL; i++) {
+ if (name && match_token(name, tablet_cursor_whitelist[i]))
+ return TRUE;
+ if (type && match_token(type, tablet_cursor_whitelist[i]))
+ return TRUE;
+ }
+ return FALSE;
+}
+#endif
+static BOOL is_stylus(const char *name, const char *type)
+{
+ int i;
+ static const char* tablet_stylus_whitelist[] = {
+ "stylus",
+ "wizardpen",
+ "acecad",
+ NULL
+ };
+
+ for (i=0; tablet_stylus_whitelist[i] != NULL; i++) {
+ if (name && match_token(name, tablet_stylus_whitelist[i]))
+ return TRUE;
+ if (type && match_token(type, tablet_stylus_whitelist[i]))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL is_eraser(const char *name, const char *type)
+{
+ if (name && match_token(name, "eraser"))
+ return TRUE;
+ if (type && match_token(type, "eraser"))
+ return TRUE;
+ return FALSE;
+}
+#undef BOOL
+#undef TRUE
+#undef FALSE
+/* end code copied from wine */
+
void GHOST_WindowX11::initXInputDevices()
{
static XErrorHandler old_handler = (XErrorHandler) 0 ;
@@ -418,15 +517,21 @@ void GHOST_WindowX11::initXInputDevices()
if(version->present) {
int device_count;
XDeviceInfo* device_info = XListInputDevices(m_display, &device_count);
- m_xtablet.StylusDevice = 0;
- m_xtablet.EraserDevice = 0;
- m_xtablet.CommonData.Active= 0;
+ m_xtablet.StylusDevice = NULL;
+ m_xtablet.EraserDevice = NULL;
+ m_xtablet.CommonData.Active= GHOST_kTabletModeNone;
/* Install our error handler to override Xlib's termination behavior */
old_handler = XSetErrorHandler(ApplicationErrorHandler) ;
for(int i=0; i<device_count; ++i) {
- if(!strcasecmp(device_info[i].name, "stylus")) {
+ char *device_type = device_info[i].type ? XGetAtomName(m_display, device_info[i].type) : NULL;
+
+// printf("Tablet type:'%s', name:'%s', index:%d\n", device_type, device_info[i].name, i);
+
+
+ if(m_xtablet.StylusDevice==NULL && is_stylus(device_info[i].name, device_type)) {
+// printf("\tfound stylus\n");
m_xtablet.StylusID= device_info[i].id;
m_xtablet.StylusDevice = XOpenDevice(m_display, m_xtablet.StylusID);
@@ -435,6 +540,7 @@ void GHOST_WindowX11::initXInputDevices()
XAnyClassPtr ici = device_info[i].inputclassinfo;
for(int j=0; j<m_xtablet.StylusDevice->num_classes; ++j) {
if(ici->c_class==ValuatorClass) {
+// printf("\t\tfound ValuatorClass\n");
XValuatorInfo* xvi = (XValuatorInfo*)ici;
m_xtablet.PressureLevels = xvi->axes[2].max_value;
@@ -451,11 +557,16 @@ void GHOST_WindowX11::initXInputDevices()
m_xtablet.StylusID= 0;
}
}
- if(!strcasecmp(device_info[i].name, "eraser")) {
+ else if(m_xtablet.EraserDevice==NULL && is_eraser(device_info[i].name, device_type)) {
+// printf("\tfound eraser\n");
m_xtablet.EraserID= device_info[i].id;
m_xtablet.EraserDevice = XOpenDevice(m_display, m_xtablet.EraserID);
if (m_xtablet.EraserDevice == NULL) m_xtablet.EraserID= 0;
}
+
+ if(device_type) {
+ XFree((void*)device_type);
+ }
}
/* Restore handler */
@@ -496,7 +607,7 @@ GHOST_WindowX11::
getXWindow(
){
return m_window;
-}
+}
bool
GHOST_WindowX11::
@@ -510,7 +621,17 @@ GHOST_WindowX11::
setTitle(
const STR_String& title
){
+ Atom name = XInternAtom(m_display, "_NET_WM_NAME", 0);
+ Atom utf8str = XInternAtom(m_display, "UTF8_STRING", 0);
+ XChangeProperty(m_display, m_window,
+ name, utf8str, 8, PropModeReplace,
+ (const unsigned char*) title.ReadPtr(),
+ strlen(title.ReadPtr()));
+
+// This should convert to valid x11 string
+// and getTitle would need matching change
XStoreName(m_display,m_window,title);
+
XFlush(m_display);
}
@@ -1097,6 +1218,13 @@ GHOST_WindowX11::
XFreeCursor(m_display, m_custom_cursor);
}
+ /* close tablet devices */
+ if(m_xtablet.StylusDevice)
+ XCloseDevice(m_display, m_xtablet.StylusDevice);
+
+ if(m_xtablet.EraserDevice)
+ XCloseDevice(m_display, m_xtablet.EraserDevice);
+
if (m_context) {
if (m_context == s_firstContext) {
s_firstContext = NULL;
@@ -1271,6 +1399,21 @@ setWindowCursorVisibility(
GHOST_TSuccess
GHOST_WindowX11::
+setWindowCursorGrab(
+ bool grab
+){
+ if(grab)
+ XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
+ else
+ XUngrabPointer(m_display, CurrentTime);
+
+ XFlush(m_display);
+
+ return GHOST_kSuccess;
+}
+
+ GHOST_TSuccess
+GHOST_WindowX11::
setWindowCursorShape(
GHOST_TStandardCursor shape
){
@@ -1308,13 +1451,12 @@ setWindowCustomCursorShape(
int fg_color,
int bg_color
){
+ Colormap colormap= DefaultColormap(m_display, DefaultScreen(m_display));
Pixmap bitmap_pix, mask_pix;
XColor fg, bg;
- if(XAllocNamedColor(m_display, DefaultColormap(m_display, DefaultScreen(m_display)),
- "White", &fg, &fg) == 0) return GHOST_kFailure;
- if(XAllocNamedColor(m_display, DefaultColormap(m_display, DefaultScreen(m_display)),
- "Black", &bg, &bg) == 0) return GHOST_kFailure;
+ if(XAllocNamedColor(m_display, colormap, "White", &fg, &fg) == 0) return GHOST_kFailure;
+ if(XAllocNamedColor(m_display, colormap, "Black", &bg, &bg) == 0) return GHOST_kFailure;
if (m_custom_cursor) {
XFreeCursor(m_display, m_custom_cursor);
@@ -1330,6 +1472,9 @@ setWindowCustomCursorShape(
XFreePixmap(m_display, bitmap_pix);
XFreePixmap(m_display, mask_pix);
+ XFreeColors(m_display, colormap, &fg.pixel, 1, 0L);
+ XFreeColors(m_display, colormap, &bg.pixel, 1, 0L);
+
return GHOST_kSuccess;
}
diff --git a/intern/ghost/intern/GHOST_WindowX11.h b/intern/ghost/intern/GHOST_WindowX11.h
index 1392e2c19a6..6f8940bdcbb 100644
--- a/intern/ghost/intern/GHOST_WindowX11.h
+++ b/intern/ghost/intern/GHOST_WindowX11.h
@@ -250,6 +250,15 @@ protected:
);
/**
+ * Sets the cursor grab on the window using
+ * native window system calls.
+ */
+ GHOST_TSuccess
+ setWindowCursorGrab(
+ bool grab
+ );
+
+ /**
* Sets the cursor shape on the window using
* native window system calls.
*/
diff --git a/intern/ghost/make/msvc_9_0/ghost.vcproj b/intern/ghost/make/msvc_9_0/ghost.vcproj
index fa128786a90..6b3a49cfc9c 100644
--- a/intern/ghost/make/msvc_9_0/ghost.vcproj
+++ b/intern/ghost/make/msvc_9_0/ghost.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..;..\..\..\..\..\build\msvc_9\intern\string\include;..\..\..\..\..\lib\windows\wintab\INCLUDE"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/guardedalloc/BLO_sys_types.h b/intern/guardedalloc/BLO_sys_types.h
index 5ed3117c890..e3c64f9746a 100644
--- a/intern/guardedalloc/BLO_sys_types.h
+++ b/intern/guardedalloc/BLO_sys_types.h
@@ -82,7 +82,7 @@ typedef unsigned long uintptr_t;
#define _UINTPTR_T_DEFINED
#endif
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__NetBSD__)
/* Linux-i386, Linux-Alpha, Linux-ppc */
#include <stdint.h>
diff --git a/intern/guardedalloc/CMakeLists.txt b/intern/guardedalloc/CMakeLists.txt
index af64fb99d58..40ca35632d7 100644
--- a/intern/guardedalloc/CMakeLists.txt
+++ b/intern/guardedalloc/CMakeLists.txt
@@ -29,4 +29,9 @@ SET(INC .)
FILE(GLOB SRC intern/*.c)
BLENDERLIB(bf_guardedalloc "${SRC}" "${INC}")
-#, libtype=['intern', 'player'], priority = [10, 175] )
+
+# Override C++ alloc optional
+IF(WITH_CXX_GUARDEDALLOC)
+ FILE(GLOB SRC cpp/*.cpp)
+ BLENDERLIB(bf_guardedalloc_cpp "${SRC}" "${INC}")
+ENDIF(WITH_CXX_GUARDEDALLOC)
diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h
index 1d4c753802b..9e3927314d3 100644
--- a/intern/guardedalloc/MEM_guardedalloc.h
+++ b/intern/guardedalloc/MEM_guardedalloc.h
@@ -27,8 +27,6 @@
*/
/**
-
- * $Id$
* Copyright (C) 2001 NaN Technologies B.V.
* Guarded memory (de)allocation
*
diff --git a/intern/guardedalloc/SConscript b/intern/guardedalloc/SConscript
index 0184ddd9785..2ee0f84b464 100644
--- a/intern/guardedalloc/SConscript
+++ b/intern/guardedalloc/SConscript
@@ -5,4 +5,4 @@ Import('env')
sources = env.Glob('intern/*.c')
incs = '.'
-env.BlenderLib ('bf_guardedalloc', sources, Split(incs), defines=[], libtype=['intern', 'player'], priority = [5, 175] )
+env.BlenderLib ('bf_guardedalloc', sources, Split(incs), defines=[], libtype=['intern','player'], priority = [5,150] )
diff --git a/intern/SoundSystem/SND_DependKludge.h b/intern/guardedalloc/cpp/mallocn.cpp
index 06d4ec9c0c9..0ee22e734b9 100644
--- a/intern/SoundSystem/SND_DependKludge.h
+++ b/intern/guardedalloc/cpp/mallocn.cpp
@@ -1,10 +1,5 @@
-/*
- * SND_DependKludge.h
- *
- * who needs what?
- *
+/**
* $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -21,30 +16,26 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
- * All rights reserved.
- *
- * The Original Code is: all of this file.
- *
- * Contributor(s): none yet.
+ * Contributor(s): Campbell Barton
*
* ***** END GPL LICENSE BLOCK *****
*/
-#ifndef HAVE_CONFIG_H
-
-#ifndef NO_SOUND
+#include <new>
+#include "../MEM_guardedalloc.h"
-#if defined (_WIN32) && !defined(FREE_WINDOWS)
-# define USE_OPENAL
-#elif defined (__linux__) || (__FreeBSD__) || defined(__APPLE__) || defined(__sun)
-# define USE_OPENAL
-#else
-# ifdef USE_OPENAL
-# undef USE_OPENAL
-# endif
-#endif
+void* operator new (size_t size)
+{
+ return MEM_mallocN(size, "c++/anonymous");
+}
-#endif /* NO_SOUND */
+/* not default but can be used when needing to set a string */
+void* operator new (size_t size, const char *str)
+{
+ return MEM_mallocN(size, str);
+}
-#endif /* HAVE_CONFIG_H */
+void operator delete (void *p)
+{
+ MEM_freeN(p);
+}
diff --git a/intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj b/intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj
index d59b80f7b62..16deb7b71fa 100644
--- a/intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj
+++ b/intern/guardedalloc/make/msvc_9_0/guardedalloc.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\.."
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/iksolver/SConscript b/intern/iksolver/SConscript
index df8c10b7302..7adb2d50893 100644
--- a/intern/iksolver/SConscript
+++ b/intern/iksolver/SConscript
@@ -5,5 +5,5 @@ sources = env.Glob('intern/*.cpp')
incs = 'intern ../moto/include ../memutil'
-env.BlenderLib ('bf_IK', sources, Split(incs), [], libtype=['intern'], priority=[100] )
+env.BlenderLib ('bf_IK', sources, Split(incs), [], libtype=['intern','player'], priority=[100,90] )
diff --git a/intern/iksolver/intern/TNT/tntmath.h b/intern/iksolver/intern/TNT/tntmath.h
index 5773900caf9..55a79e2aba0 100644
--- a/intern/iksolver/intern/TNT/tntmath.h
+++ b/intern/iksolver/intern/TNT/tntmath.h
@@ -35,7 +35,9 @@
// conventional functions required by several matrix algorithms
-
+#ifdef _WIN32
+#define hypot _hypot
+#endif
namespace TNT
{
diff --git a/intern/iksolver/make/msvc_9_0/iksolver.vcproj b/intern/iksolver/make/msvc_9_0/iksolver.vcproj
index 0e87556380b..296a23e57cc 100644
--- a/intern/iksolver/make/msvc_9_0/iksolver.vcproj
+++ b/intern/iksolver/make/msvc_9_0/iksolver.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\moto\include"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/itasc/Armature.cpp b/intern/itasc/Armature.cpp
new file mode 100644
index 00000000000..cd059505b4a
--- /dev/null
+++ b/intern/itasc/Armature.cpp
@@ -0,0 +1,769 @@
+/* $Id: Armature.cpp 21152 2009-06-25 11:57:19Z ben2610 $
+ * Armature.cpp
+ *
+ * Created on: Feb 3, 2009
+ * Author: benoitbolsee
+ */
+
+#include "Armature.hpp"
+#include <algorithm>
+#include <malloc.h>
+#include <string.h>
+
+namespace iTaSC {
+
+// a joint constraint is characterized by 5 values: tolerance, K, alpha, yd, yddot
+static const unsigned int constraintCacheSize = 5;
+std::string Armature::m_root = "root";
+
+Armature::Armature():
+ ControlledObject(),
+ m_tree(),
+ m_njoint(0),
+ m_nconstraint(0),
+ m_noutput(0),
+ m_neffector(0),
+ m_finalized(false),
+ m_cache(NULL),
+ m_buf(NULL),
+ m_qCCh(-1),
+ m_qCTs(0),
+ m_yCCh(-1),
+ m_yCTs(0),
+ m_qKdl(),
+ m_oldqKdl(),
+ m_newqKdl(),
+ m_qdotKdl(),
+ m_jac(NULL),
+ m_jacsolver(NULL),
+ m_fksolver(NULL),
+ m_armlength(0.0)
+{
+}
+
+Armature::~Armature()
+{
+ if (m_jac)
+ delete m_jac;
+ if (m_jacsolver)
+ delete m_jacsolver;
+ if (m_fksolver)
+ delete m_fksolver;
+ for (JointConstraintList::iterator it=m_constraints.begin(); it != m_constraints.end(); it++) {
+ if (*it != NULL)
+ delete (*it);
+ }
+ if (m_buf)
+ delete [] m_buf;
+ m_constraints.clear();
+}
+
+Armature::JointConstraint_struct::JointConstraint_struct(SegmentMap::const_iterator _segment, unsigned int _y_nr, ConstraintCallback _function, void* _param, bool _freeParam, bool _substep):
+ segment(_segment), value(), values(), function(_function), y_nr(_y_nr), param(_param), freeParam(_freeParam), substep(_substep)
+{
+ memset(values, 0, sizeof(values));
+ memset(value, 0, sizeof(value));
+ values[0].feedback = 20.0;
+ values[1].feedback = 20.0;
+ values[2].feedback = 20.0;
+ values[0].tolerance = 1.0;
+ values[1].tolerance = 1.0;
+ values[2].tolerance = 1.0;
+ values[0].values = &value[0];
+ values[1].values = &value[1];
+ values[2].values = &value[2];
+ values[0].number = 1;
+ values[1].number = 1;
+ values[2].number = 1;
+ switch (segment->second.segment.getJoint().getType()) {
+ case Joint::RotX:
+ value[0].id = ID_JOINT_RX;
+ values[0].id = ID_JOINT_RX;
+ v_nr = 1;
+ break;
+ case Joint::RotY:
+ value[0].id = ID_JOINT_RY;
+ values[0].id = ID_JOINT_RY;
+ v_nr = 1;
+ break;
+ case Joint::RotZ:
+ value[0].id = ID_JOINT_RZ;
+ values[0].id = ID_JOINT_RZ;
+ v_nr = 1;
+ break;
+ case Joint::TransX:
+ value[0].id = ID_JOINT_TX;
+ values[0].id = ID_JOINT_TX;
+ v_nr = 1;
+ break;
+ case Joint::TransY:
+ value[0].id = ID_JOINT_TY;
+ values[0].id = ID_JOINT_TY;
+ v_nr = 1;
+ break;
+ case Joint::TransZ:
+ value[0].id = ID_JOINT_TZ;
+ values[0].id = ID_JOINT_TZ;
+ v_nr = 1;
+ break;
+ case Joint::Sphere:
+ values[0].id = value[0].id = ID_JOINT_RX;
+ values[1].id = value[1].id = ID_JOINT_RY;
+ values[2].id = value[2].id = ID_JOINT_RZ;
+ v_nr = 3;
+ break;
+ case Joint::Swing:
+ values[0].id = value[0].id = ID_JOINT_RX;
+ values[1].id = value[1].id = ID_JOINT_RZ;
+ v_nr = 2;
+ break;
+ }
+}
+
+Armature::JointConstraint_struct::~JointConstraint_struct()
+{
+ if (freeParam && param)
+ free(param);
+}
+
+void Armature::initCache(Cache *_cache)
+{
+ m_cache = _cache;
+ m_qCCh = -1;
+ m_yCCh = -1;
+ m_buf = NULL;
+ if (m_cache) {
+ // add a special channel for the joint
+ m_qCCh = m_cache->addChannel(this, "q", m_qKdl.rows()*sizeof(double));
+#if 0
+ // for the constraints, instead of creating many different channels, we will
+ // create a single channel for all the constraints
+ if (m_nconstraint) {
+ m_yCCh = m_cache->addChannel(this, "y", m_nconstraint*constraintCacheSize*sizeof(double));
+ m_buf = new double[m_nconstraint*constraintCacheSize];
+ }
+ // store the initial cache position at timestamp 0
+ pushConstraints(0);
+#endif
+ pushQ(0);
+ }
+}
+
+void Armature::pushQ(CacheTS timestamp)
+{
+ if (m_qCCh >= 0) {
+ // try to keep the cache if the joints are the same
+ m_cache->addCacheVectorIfDifferent(this, m_qCCh, timestamp, &m_qKdl(0), m_qKdl.rows(), KDL::epsilon);
+ m_qCTs = timestamp;
+ }
+}
+
+/* return true if a m_cache position was loaded */
+bool Armature::popQ(CacheTS timestamp)
+{
+ if (m_qCCh >= 0) {
+ double* item;
+ item = (double*)m_cache->getPreviousCacheItem(this, m_qCCh, &timestamp);
+ if (item && m_qCTs != timestamp) {
+ double& q = m_qKdl(0);
+ memcpy(&q, item, m_qKdl.rows()*sizeof(q));
+ m_qCTs = timestamp;
+ // changing the joint => recompute the jacobian
+ updateJacobian();
+ }
+ return (item) ? true : false;
+ }
+ return true;
+}
+#if 0
+void Armature::pushConstraints(CacheTS timestamp)
+{
+ if (m_yCCh >= 0) {
+ double *buf = NULL;
+ if (m_nconstraint) {
+ double *item = m_buf;
+ for (unsigned int i=0; i<m_nconstraint; i++) {
+ JointConstraint_struct* pConstraint = m_constraints[i];
+ *item++ = pConstraint->values.feedback;
+ *item++ = pConstraint->values.tolerance;
+ *item++ = pConstraint->value.yd;
+ *item++ = pConstraint->value.yddot;
+ *item++ = pConstraint->values.alpha;
+ }
+ }
+ m_cache->addCacheVectorIfDifferent(this, m_yCCh, timestamp, m_buf, m_nconstraint*constraintCacheSize, KDL::epsilon);
+ m_yCTs = timestamp;
+ }
+}
+
+/* return true if a cache position was loaded */
+bool Armature::popConstraints(CacheTS timestamp)
+{
+ if (m_yCCh >= 0) {
+ double *item = (double*)m_cache->getPreviousCacheItem(this, m_yCCh, &timestamp);
+ if (item && m_yCTs != timestamp) {
+ for (unsigned int i=0; i<m_nconstraint; i++) {
+ JointConstraint_struct* pConstraint = m_constraints[i];
+ if (pConstraint->function != Joint1DOFLimitCallback) {
+ pConstraint->values.feedback = *item++;
+ pConstraint->values.tolerance = *item++;
+ pConstraint->value.yd = *item++;
+ pConstraint->value.yddot = *item++;
+ pConstraint->values.alpha = *item++;
+ } else {
+ item += constraintCacheSize;
+ }
+ }
+ m_yCTs = timestamp;
+ }
+ return (item) ? true : false;
+ }
+ return true;
+}
+#endif
+
+bool Armature::addSegment(const std::string& segment_name, const std::string& hook_name, const Joint& joint, const double& q_rest, const Frame& f_tip, const Inertia& M)
+{
+ if (m_finalized)
+ return false;
+
+ Segment segment(joint, f_tip, M);
+ if (!m_tree.addSegment(segment, segment_name, hook_name))
+ return false;
+ int ndof = joint.getNDof();
+ for (int dof=0; dof<ndof; dof++) {
+ Joint_struct js(joint.getType(), ndof, (&q_rest)[dof]);
+ m_joints.push_back(js);
+ }
+ m_njoint+=ndof;
+ return true;
+}
+
+bool Armature::getSegment(const std::string& name, const unsigned int q_size, const Joint* &p_joint, double &q_rest, double &q, const Frame* &p_tip)
+{
+ SegmentMap::const_iterator sit = m_tree.getSegment(name);
+ if (sit == m_tree.getSegments().end())
+ return false;
+ p_joint = &sit->second.segment.getJoint();
+ if (q_size < p_joint->getNDof())
+ return false;
+ p_tip = &sit->second.segment.getFrameToTip();
+ for (unsigned int dof=0; dof<p_joint->getNDof(); dof++) {
+ (&q_rest)[dof] = m_joints[sit->second.q_nr+dof].rest;
+ (&q)[dof] = m_qKdl(sit->second.q_nr+dof);
+ }
+ return true;
+}
+
+double Armature::getMaxJointChange()
+{
+ if (!m_finalized)
+ return 0.0;
+ double maxJoint = 0.0;
+ for (unsigned int i=0; i<m_njoint; i++) {
+ // this is a very rough calculation, it doesn't work well for spherical joint
+ double joint = fabs(m_oldqKdl(i)-m_qKdl(i));
+ if (maxJoint < joint)
+ maxJoint = joint;
+ }
+ return maxJoint;
+}
+
+double Armature::getMaxEndEffectorChange()
+{
+ if (!m_finalized)
+ return 0.0;
+ double maxDelta = 0.0;
+ double delta;
+ Twist twist;
+ for (unsigned int i = 0; i<m_neffector; i++) {
+ twist = diff(m_effectors[i].pose, m_effectors[i].oldpose);
+ delta = twist.rot.Norm();
+ if (delta > maxDelta)
+ maxDelta = delta;
+ delta = twist.vel.Norm();
+ if (delta > maxDelta)
+ maxDelta = delta;
+ }
+ return maxDelta;
+}
+
+int Armature::addConstraint(const std::string& segment_name, ConstraintCallback _function, void* _param, bool _freeParam, bool _substep)
+{
+ SegmentMap::const_iterator segment_it = m_tree.getSegment(segment_name);
+ // not suitable for NDof joints
+ if (segment_it == m_tree.getSegments().end()) {
+ if (_freeParam && _param)
+ free(_param);
+ return -1;
+ }
+ JointConstraintList::iterator constraint_it;
+ JointConstraint_struct* pConstraint;
+ int iConstraint;
+ for (iConstraint=0, constraint_it=m_constraints.begin(); constraint_it != m_constraints.end(); constraint_it++, iConstraint++) {
+ pConstraint = *constraint_it;
+ if (pConstraint->segment == segment_it) {
+ // redefining a constraint
+ if (pConstraint->freeParam && pConstraint->param) {
+ free(pConstraint->param);
+ }
+ pConstraint->function = _function;
+ pConstraint->param = _param;
+ pConstraint->freeParam = _freeParam;
+ pConstraint->substep = _substep;
+ return iConstraint;
+ }
+ }
+ if (m_finalized) {
+ if (_freeParam && _param)
+ free(_param);
+ return -1;
+ }
+ // new constraint, append
+ pConstraint = new JointConstraint_struct(segment_it, m_noutput, _function, _param, _freeParam, _substep);
+ m_constraints.push_back(pConstraint);
+ m_noutput += pConstraint->v_nr;
+ return m_nconstraint++;
+}
+
+int Armature::addLimitConstraint(const std::string& segment_name, unsigned int dof, double _min, double _max)
+{
+ SegmentMap::const_iterator segment_it = m_tree.getSegment(segment_name);
+ if (segment_it == m_tree.getSegments().end())
+ return -1;
+ const Joint& joint = segment_it->second.segment.getJoint();
+ if (joint.getNDof() != 1 && joint.getType() != Joint::Swing) {
+ // not suitable for Sphere joints
+ return -1;
+ }
+ if ((joint.getNDof() == 1 && dof > 0) || (joint.getNDof() == 2 && dof > 1))
+ return -1;
+ if (joint.getType() < Joint::TransX || joint.getType() == Joint::Swing) {
+ // for rotation joint, the limit is given in degree, convert to radian
+ _min *= KDL::deg2rad;
+ _max *= KDL::deg2rad;
+ }
+ Joint_struct& p_joint = m_joints[segment_it->second.q_nr+dof];
+ p_joint.min = _min;
+ p_joint.max = _max;
+ p_joint.useLimit = true;
+ return 0;
+}
+
+int Armature::addEndEffector(const std::string& name)
+{
+ const SegmentMap& segments = m_tree.getSegments();
+ if (segments.find(name) == segments.end())
+ return -1;
+
+ EffectorList::const_iterator it;
+ int ee;
+ for (it=m_effectors.begin(), ee=0; it!=m_effectors.end(); it++, ee++) {
+ if (it->name == name)
+ return ee;
+ }
+ if (m_finalized)
+ return -1;
+ Effector_struct effector(name);
+ m_effectors.push_back(effector);
+ return m_neffector++;
+}
+
+void Armature::finalize()
+{
+ unsigned int i, j, c;
+ if (m_finalized)
+ return;
+ initialize(m_njoint, m_noutput, m_neffector);
+ for (i=c=0; i<m_nconstraint; i++) {
+ JointConstraint_struct* pConstraint = m_constraints[i];
+ for (j=0; j<pConstraint->v_nr; j++, c++) {
+ m_Cq(c,pConstraint->segment->second.q_nr+j) = 1.0;
+ m_Wy(c) = pConstraint->values[j].alpha/*/(pConstraint->values.tolerance*pConstraint->values.feedback)*/;
+ }
+ }
+ m_jacsolver= new KDL::TreeJntToJacSolver(m_tree);
+ m_fksolver = new KDL::TreeFkSolverPos_recursive(m_tree);
+ m_jac = new Jacobian(m_njoint);
+ m_qKdl.resize(m_njoint);
+ m_oldqKdl.resize(m_njoint);
+ m_newqKdl.resize(m_njoint);
+ m_qdotKdl.resize(m_njoint);
+ for (i=0; i<m_njoint; i++) {
+ m_newqKdl(i) = m_oldqKdl(i) = m_qKdl(i) = m_joints[i].rest;
+ }
+ updateJacobian();
+ // estimate the maximum size of the robot arms
+ double length;
+ m_armlength = 0.0;
+ for (i=0; i<m_neffector; i++) {
+ length = 0.0;
+ KDL::SegmentMap::const_iterator sit = m_tree.getSegment(m_effectors[i].name);
+ while (sit->first != "root") {
+ Frame tip = sit->second.segment.pose(m_qKdl(sit->second.q_nr));
+ length += tip.p.Norm();
+ sit = sit->second.parent;
+ }
+ if (length > m_armlength)
+ m_armlength = length;
+ }
+ if (m_armlength < KDL::epsilon)
+ m_armlength = KDL::epsilon;
+ m_finalized = true;
+}
+
+void Armature::pushCache(const Timestamp& timestamp)
+{
+ if (!timestamp.substep && timestamp.cache) {
+ pushQ(timestamp.cacheTimestamp);
+ //pushConstraints(timestamp.cacheTimestamp);
+ }
+}
+
+bool Armature::setJointArray(const KDL::JntArray& joints)
+{
+ if (!m_finalized)
+ return false;
+ if (joints.rows() != m_qKdl.rows())
+ return false;
+ m_qKdl = joints;
+ updateJacobian();
+ return true;
+}
+
+const KDL::JntArray& Armature::getJointArray()
+{
+ return m_qKdl;
+}
+
+bool Armature::updateJoint(const Timestamp& timestamp, JointLockCallback& callback)
+{
+ if (!m_finalized)
+ return false;
+
+ // integration and joint limit
+ // for spherical joint we must use a more sophisticated method
+ unsigned int q_nr;
+ double* qdot=&m_qdotKdl(0);
+ double* q=&m_qKdl(0);
+ double* newq=&m_newqKdl(0);
+ double norm, qx, qz, CX, CZ, sx, sz;
+ bool locked = false;
+ int unlocked = 0;
+
+ for (q_nr=0; q_nr<m_nq; ++q_nr)
+ m_qdotKdl(q_nr)=m_qdot(q_nr);
+
+ for (q_nr=0; q_nr<m_nq; ) {
+ Joint_struct* joint = &m_joints[q_nr];
+ if (!joint->locked) {
+ switch (joint->type) {
+ case KDL::Joint::Swing:
+ {
+ KDL::Rotation base = KDL::Rot(KDL::Vector(q[0],0.0,q[1]));
+ (base*KDL::Rot(KDL::Vector(qdot[0],0.0,qdot[1])*timestamp.realTimestep)).GetXZRot().GetValue(newq);
+ if (joint[0].useLimit) {
+ if (joint[1].useLimit) {
+ // elliptical limit
+ sx = sz = 1.0;
+ qx = newq[0];
+ qz = newq[1];
+ // determine in which quadrant we are
+ if (qx > 0.0 && qz > 0.0) {
+ CX = joint[0].max;
+ CZ = joint[1].max;
+ } else if (qx <= 0.0 && qz > 0.0) {
+ CX = -joint[0].min;
+ CZ = joint[1].max;
+ qx = -qx;
+ sx = -1.0;
+ } else if (qx <= 0.0 && qz <= 0.0) {
+ CX = -joint[0].min;
+ CZ = -joint[1].min;
+ qx = -qx;
+ qz = -qz;
+ sx = sz = -1.0;
+ } else {
+ CX = joint[0].max;
+ CZ = -joint[0].min;
+ qz = -qz;
+ sz = -1.0;
+ }
+ if (CX < KDL::epsilon || CZ < KDL::epsilon) {
+ // quadrant is degenerated
+ if (qx > CX) {
+ newq[0] = CX*sx;
+ joint[0].locked = true;
+ }
+ if (qz > CZ) {
+ newq[1] = CZ*sz;
+ joint[0].locked = true;
+ }
+ } else {
+ // general case
+ qx /= CX;
+ qz /= CZ;
+ norm = KDL::sqrt(KDL::sqr(qx)+KDL::sqr(qz));
+ if (norm > 1.0) {
+ norm = 1.0/norm;
+ newq[0] = qx*norm*CX*sx;
+ newq[1] = qz*norm*CZ*sz;
+ joint[0].locked = true;
+ }
+ }
+ } else {
+ // limit on X only
+ qx = newq[0];
+ if (qx > joint[0].max) {
+ newq[0] = joint[0].max;
+ joint[0].locked = true;
+ } else if (qx < joint[0].min) {
+ newq[0] = joint[0].min;
+ joint[0].locked = true;
+ }
+ }
+ } else if (joint[1].useLimit) {
+ // limit on Z only
+ qz = newq[1];
+ if (qz > joint[1].max) {
+ newq[1] = joint[1].max;
+ joint[0].locked = true;
+ } else if (qz < joint[1].min) {
+ newq[1] = joint[1].min;
+ joint[0].locked = true;
+ }
+ }
+ if (joint[0].locked) {
+ // check the difference from previous position
+ locked = true;
+ norm = KDL::sqr(newq[0]-q[0])+KDL::sqr(newq[1]-q[1]);
+ if (norm < KDL::epsilon2) {
+ // joint didn't move, no need to update the jacobian
+ callback.lockJoint(q_nr, 2);
+ } else {
+ // joint moved, compute the corresponding velocity
+ double deltaq[2];
+ (base.Inverse()*KDL::Rot(KDL::Vector(newq[0],0.0,newq[1]))).GetXZRot().GetValue(deltaq);
+ deltaq[0] /= timestamp.realTimestep;
+ deltaq[1] /= timestamp.realTimestep;
+ callback.lockJoint(q_nr, 2, deltaq);
+ // no need to update the other joints, it will be done after next rerun
+ goto end_loop;
+ }
+ } else
+ unlocked++;
+ break;
+ }
+ case KDL::Joint::Sphere:
+ {
+ (KDL::Rot(KDL::Vector(q))*KDL::Rot(KDL::Vector(qdot)*timestamp.realTimestep)).GetRot().GetValue(newq);
+ // no limit on this joint
+ unlocked++;
+ break;
+ }
+ default:
+ for (unsigned int i=0; i<joint->ndof; i++) {
+ newq[i] = q[i]+qdot[i]*timestamp.realTimestep;
+ if (joint[i].useLimit) {
+ if (newq[i] > joint[i].max) {
+ newq[i] = joint[i].max;
+ joint[0].locked = true;
+ } else if (newq[i] < joint[i].min) {
+ newq[i] = joint[i].min;
+ joint[0].locked = true;
+ }
+ }
+ }
+ if (joint[0].locked) {
+ locked = true;
+ norm = 0.0;
+ // compute delta to locked position
+ for (unsigned int i=0; i<joint->ndof; i++) {
+ qdot[i] = newq[i] - q[i];
+ norm += qdot[i]*qdot[i];
+ }
+ if (norm < KDL::epsilon2) {
+ // joint didn't move, no need to update the jacobian
+ callback.lockJoint(q_nr, joint->ndof);
+ } else {
+ // solver needs velocity, compute equivalent velocity
+ for (unsigned int i=0; i<joint->ndof; i++) {
+ qdot[i] /= timestamp.realTimestep;
+ }
+ callback.lockJoint(q_nr, joint->ndof, qdot);
+ goto end_loop;
+ }
+ } else
+ unlocked++;
+ }
+ }
+ qdot += joint->ndof;
+ q += joint->ndof;
+ newq += joint->ndof;
+ q_nr += joint->ndof;
+ }
+end_loop:
+ // check if there any other unlocked joint
+ for ( ; q_nr<m_nq; ) {
+ Joint_struct* joint = &m_joints[q_nr];
+ if (!joint->locked)
+ unlocked++;
+ q_nr += joint->ndof;
+ }
+ // if all joints have been locked no need to run the solver again
+ return (unlocked) ? locked : false;
+}
+
+void Armature::updateKinematics(const Timestamp& timestamp){
+
+ //Integrate m_qdot
+ if (!m_finalized)
+ return;
+
+ // the new joint value have been computed already, just copy
+ memcpy(&m_qKdl(0), &m_newqKdl(0), sizeof(double)*m_qKdl.rows());
+ pushCache(timestamp);
+ updateJacobian();
+ // here update the desired output.
+ // We assume constant desired output for the joint limit constraint, no need to update it.
+}
+
+void Armature::updateJacobian()
+{
+ //calculate pose and jacobian
+ for (unsigned int ee=0; ee<m_nee; ee++) {
+ m_fksolver->JntToCart(m_qKdl,m_effectors[ee].pose,m_effectors[ee].name,m_root);
+ m_jacsolver->JntToJac(m_qKdl,*m_jac,m_effectors[ee].name);
+ // get the jacobian for the base point, to prepare transformation to world reference
+ changeRefPoint(*m_jac,-m_effectors[ee].pose.p,*m_jac);
+ //copy to Jq:
+ e_matrix& Jq = m_JqArray[ee];
+ for(unsigned int i=0;i<6;i++) {
+ for(unsigned int j=0;j<m_nq;j++)
+ Jq(i,j)=(*m_jac)(i,j);
+ }
+ }
+ // remember that this object has moved
+ m_updated = true;
+}
+
+const Frame& Armature::getPose(const unsigned int ee)
+{
+ if (!m_finalized)
+ return F_identity;
+ return (ee >= m_nee) ? F_identity : m_effectors[ee].pose;
+}
+
+bool Armature::getRelativeFrame(Frame& result, const std::string& segment_name, const std::string& base_name)
+{
+ if (!m_finalized)
+ return false;
+ return (m_fksolver->JntToCart(m_qKdl,result,segment_name,base_name) < 0) ? false : true;
+}
+
+void Armature::updateControlOutput(const Timestamp& timestamp)
+{
+ if (!m_finalized)
+ return;
+
+
+ if (!timestamp.substep && !timestamp.reiterate && timestamp.interpolate) {
+ popQ(timestamp.cacheTimestamp);
+ //popConstraints(timestamp.cacheTimestamp);
+ }
+
+ if (!timestamp.substep) {
+ // save previous joint state for getMaxJointChange()
+ memcpy(&m_oldqKdl(0), &m_qKdl(0), sizeof(double)*m_qKdl.rows());
+ for (unsigned int i=0; i<m_neffector; i++) {
+ m_effectors[i].oldpose = m_effectors[i].pose;
+ }
+ }
+
+ // remove all joint lock
+ for (JointList::iterator jit=m_joints.begin(); jit!=m_joints.end(); ++jit) {
+ (*jit).locked = false;
+ }
+
+ JointConstraintList::iterator it;
+ unsigned int iConstraint;
+
+ // scan through the constraints and call the callback functions
+ for (iConstraint=0, it=m_constraints.begin(); it!=m_constraints.end(); it++, iConstraint++) {
+ JointConstraint_struct* pConstraint = *it;
+ unsigned int nr, i;
+ for (i=0, nr = pConstraint->segment->second.q_nr; i<pConstraint->v_nr; i++, nr++) {
+ *(double*)&pConstraint->value[i].y = m_qKdl(nr);
+ *(double*)&pConstraint->value[i].ydot = m_qdotKdl(nr);
+ }
+ if (pConstraint->function && (pConstraint->substep || (!timestamp.reiterate && !timestamp.substep))) {
+ (*pConstraint->function)(timestamp, pConstraint->values, pConstraint->v_nr, pConstraint->param);
+ }
+ // recompute the weight in any case, that's the most likely modification
+ for (i=0, nr=pConstraint->y_nr; i<pConstraint->v_nr; i++, nr++) {
+ m_Wy(nr) = pConstraint->values[i].alpha/*/(pConstraint->values.tolerance*pConstraint->values.feedback)*/;
+ m_ydot(nr)=pConstraint->value[i].yddot+pConstraint->values[i].feedback*(pConstraint->value[i].yd-pConstraint->value[i].y);
+ }
+ }
+}
+
+bool Armature::setControlParameter(unsigned int constraintId, unsigned int valueId, ConstraintAction action, double value, double timestep)
+{
+ unsigned int lastid, i;
+ if (constraintId == CONSTRAINT_ID_ALL) {
+ constraintId = 0;
+ lastid = m_nconstraint;
+ } else if (constraintId < m_nconstraint) {
+ lastid = constraintId+1;
+ } else {
+ return false;
+ }
+ for ( ; constraintId<lastid; ++constraintId) {
+ JointConstraint_struct* pConstraint = m_constraints[constraintId];
+ if (valueId == ID_JOINT) {
+ for (i=0; i<pConstraint->v_nr; i++) {
+ switch (action) {
+ case ACT_TOLERANCE:
+ pConstraint->values[i].tolerance = value;
+ break;
+ case ACT_FEEDBACK:
+ pConstraint->values[i].feedback = value;
+ break;
+ case ACT_ALPHA:
+ pConstraint->values[i].alpha = value;
+ break;
+ }
+ }
+ } else {
+ for (i=0; i<pConstraint->v_nr; i++) {
+ if (valueId == pConstraint->value[i].id) {
+ switch (action) {
+ case ACT_VALUE:
+ pConstraint->value[i].yd = value;
+ break;
+ case ACT_VELOCITY:
+ pConstraint->value[i].yddot = value;
+ break;
+ case ACT_TOLERANCE:
+ pConstraint->values[i].tolerance = value;
+ break;
+ case ACT_FEEDBACK:
+ pConstraint->values[i].feedback = value;
+ break;
+ case ACT_ALPHA:
+ pConstraint->values[i].alpha = value;
+ break;
+ }
+ }
+ }
+ }
+ if (m_finalized) {
+ for (i=0; i<pConstraint->v_nr; i++)
+ m_Wy(pConstraint->y_nr+i) = pConstraint->values[i].alpha/*/(pConstraint->values.tolerance*pConstraint->values.feedback)*/;
+ }
+ }
+ return true;
+}
+
+}
+
diff --git a/intern/itasc/Armature.hpp b/intern/itasc/Armature.hpp
new file mode 100644
index 00000000000..312ca1b28c3
--- /dev/null
+++ b/intern/itasc/Armature.hpp
@@ -0,0 +1,137 @@
+/* $Id: Armature.hpp 20853 2009-06-13 12:29:46Z ben2610 $
+ * Armature.hpp
+ *
+ * Created on: Feb 3, 2009
+ * Author: benoitbolsee
+ */
+
+#ifndef ARMATURE_HPP_
+#define ARMATURE_HPP_
+
+#include "ControlledObject.hpp"
+#include "ConstraintSet.hpp"
+#include "kdl/treejnttojacsolver.hpp"
+#include "kdl/treefksolverpos_recursive.hpp"
+#include <vector>
+
+namespace iTaSC {
+
+class Armature: public iTaSC::ControlledObject {
+public:
+ Armature();
+ virtual ~Armature();
+
+ bool addSegment(const std::string& segment_name, const std::string& hook_name, const Joint& joint, const double& q_rest, const Frame& f_tip=F_identity, const Inertia& M = Inertia::Zero());
+ // general purpose constraint on joint
+ int addConstraint(const std::string& segment_name, ConstraintCallback _function, void* _param=NULL, bool _freeParam=false, bool _substep=false);
+ // specific limit constraint on joint
+ int addLimitConstraint(const std::string& segment_name, unsigned int dof, double _min, double _max);
+ double getMaxJointChange();
+ double getMaxEndEffectorChange();
+ bool getSegment(const std::string& segment_name, const unsigned int q_size, const Joint* &p_joint, double &q_rest, double &q, const Frame* &p_tip);
+ bool getRelativeFrame(Frame& result, const std::string& segment_name, const std::string& base_name=m_root);
+
+ virtual void finalize();
+
+ virtual int addEndEffector(const std::string& name);
+ virtual const Frame& getPose(const unsigned int end_effector);
+ virtual bool updateJoint(const Timestamp& timestamp, JointLockCallback& callback);
+ virtual void updateKinematics(const Timestamp& timestamp);
+ virtual void pushCache(const Timestamp& timestamp);
+ virtual void updateControlOutput(const Timestamp& timestamp);
+ virtual bool setControlParameter(unsigned int constraintId, unsigned int valueId, ConstraintAction action, double value, double timestep=0.0);
+ virtual void initCache(Cache *_cache);
+ virtual bool setJointArray(const KDL::JntArray& joints);
+ virtual const KDL::JntArray& getJointArray();
+
+ virtual double getArmLength()
+ {
+ return m_armlength;
+ }
+
+ struct Effector_struct {
+ std::string name;
+ Frame oldpose;
+ Frame pose;
+ Effector_struct(const std::string& _name) {name = _name; oldpose = pose = F_identity;}
+ };
+ typedef std::vector<Effector_struct> EffectorList;
+
+ enum ID {
+ ID_JOINT=1,
+ ID_JOINT_RX=2,
+ ID_JOINT_RY=3,
+ ID_JOINT_RZ=4,
+ ID_JOINT_TX=2,
+ ID_JOINT_TY=3,
+ ID_JOINT_TZ=4,
+ };
+ struct JointConstraint_struct {
+ SegmentMap::const_iterator segment;
+ ConstraintSingleValue value[3];
+ ConstraintValues values[3];
+ ConstraintCallback function;
+ unsigned int v_nr;
+ unsigned int y_nr; // first coordinate of constraint in Y vector
+ void* param;
+ bool freeParam;
+ bool substep;
+ JointConstraint_struct(SegmentMap::const_iterator _segment, unsigned int _y_nr, ConstraintCallback _function, void* _param, bool _freeParam, bool _substep);
+ ~JointConstraint_struct();
+ };
+ typedef std::vector<JointConstraint_struct*> JointConstraintList;
+
+ struct Joint_struct {
+ KDL::Joint::JointType type;
+ unsigned short ndof;
+ bool useLimit;
+ bool locked;
+ double rest;
+ double min;
+ double max;
+
+ Joint_struct(KDL::Joint::JointType _type, unsigned int _ndof, double _rest) :
+ type(_type), ndof(_ndof), rest(_rest) { useLimit=locked=false; min=0.0; max=0.0; }
+ };
+ typedef std::vector<Joint_struct> JointList;
+
+protected:
+ virtual void updateJacobian();
+
+private:
+ static std::string m_root;
+ Tree m_tree;
+ unsigned int m_njoint;
+ unsigned int m_nconstraint;
+ unsigned int m_noutput;
+ unsigned int m_neffector;
+ bool m_finalized;
+ Cache* m_cache;
+ double *m_buf;
+ int m_qCCh;
+ CacheTS m_qCTs;
+ int m_yCCh;
+ CacheTS m_yCTs;
+ JntArray m_qKdl;
+ JntArray m_oldqKdl;
+ JntArray m_newqKdl;
+ JntArray m_qdotKdl;
+ Jacobian* m_jac;
+ double m_armlength;
+
+ KDL::TreeJntToJacSolver* m_jacsolver;
+ KDL::TreeFkSolverPos_recursive* m_fksolver;
+ EffectorList m_effectors;
+ JointConstraintList m_constraints;
+ JointList m_joints;
+
+ void pushQ(CacheTS timestamp);
+ bool popQ(CacheTS timestamp);
+ //void pushConstraints(CacheTS timestamp);
+ //bool popConstraints(CacheTS timestamp);
+
+};
+
+}
+
+#endif /* ARMATURE_HPP_ */
diff --git a/intern/itasc/CMakeLists.txt b/intern/itasc/CMakeLists.txt
new file mode 100644
index 00000000000..405d74d17ac
--- /dev/null
+++ b/intern/itasc/CMakeLists.txt
@@ -0,0 +1,32 @@
+# $Id: CMakeLists.txt 19905 2009-04-23 13:29:54Z ben2610 $
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Jacques Beaurain.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+SET(INC ../../extern/Eigen2)
+
+FILE(GLOB SRC *.cpp kdl/*.cpp kdl/utilities/*.cpp)
+
+BLENDERLIB(bf_ITASC "${SRC}" "${INC}")
+#, libtype=['blender'], priority = [10] )
diff --git a/intern/itasc/Cache.cpp b/intern/itasc/Cache.cpp
new file mode 100644
index 00000000000..68c281910e3
--- /dev/null
+++ b/intern/itasc/Cache.cpp
@@ -0,0 +1,621 @@
+/* $Id: Cache.cpp 21152 2009-06-25 11:57:19Z ben2610 $
+ * Cache.cpp
+ *
+ * Created on: Feb 24, 2009
+ * Author: benoit bolsee
+ */
+#include <string.h>
+#include <assert.h>
+#include <malloc.h>
+#include "Cache.hpp"
+
+#include <math.h>
+
+namespace iTaSC {
+
+CacheEntry::~CacheEntry()
+{
+ for (unsigned int id=0; id < m_count; id++)
+ m_channelArray[id].clear();
+ if (m_channelArray)
+ free(m_channelArray);
+}
+
+CacheItem *CacheChannel::_findBlock(CacheBuffer *buffer, unsigned short timeOffset, unsigned int *retBlock)
+{
+ // the timestamp is necessarily in this buffer
+ unsigned int lowBlock, highBlock, midBlock;
+ if (timeOffset <= buffer->lookup[0].m_timeOffset) {
+ // special case: the item is in the first block, search from start
+ *retBlock = 0;
+ return &buffer->m_firstItem;
+ }
+ // general case, the item is in the middle of the buffer
+ // before doing a dycotomic search, we will assume that timestamp
+ // are regularly spaced so that we can try to locate the block directly
+ highBlock = buffer->m_lastItemPositionW>>m_positionToBlockShiftW;
+ lowBlock = midBlock = (timeOffset*highBlock)/(buffer->m_lastTimestamp-buffer->m_firstTimestamp);
+ // give some space for security
+ if (lowBlock > 0)
+ lowBlock--;
+ if (timeOffset <= buffer->lookup[lowBlock].m_timeOffset) {
+ // bad guess, but we know this block is a good high block, just use it
+ highBlock = lowBlock;
+ lowBlock = 0;
+ } else {
+ // ok, good guess, now check the high block, give some space
+ if (midBlock < highBlock)
+ midBlock++;
+ if (timeOffset <= buffer->lookup[midBlock].m_timeOffset) {
+ // good guess, keep that block as the high block
+ highBlock = midBlock;
+ }
+ }
+ // the item is in a different block, do a dycotomic search
+ // the timestamp is alway > lowBlock and <= highBlock
+ while (1) {
+ midBlock = (lowBlock+highBlock)/2;
+ if (midBlock == lowBlock) {
+ // low block and high block are contigous, we can start search from the low block
+ break;
+ } else if (timeOffset <= buffer->lookup[midBlock].m_timeOffset) {
+ highBlock = midBlock;
+ } else {
+ lowBlock = midBlock;
+ }
+ }
+ assert (lowBlock != highBlock);
+ *retBlock = highBlock;
+ return CACHE_BLOCK_ITEM_ADDR(this,buffer,lowBlock);
+}
+
+void CacheChannel::clear()
+{
+ CacheBuffer *buffer, *next;
+ for (buffer=m_firstBuffer; buffer != 0; buffer = next) {
+ next = buffer->m_next;
+ free(buffer);
+ }
+ m_firstBuffer = NULL;
+ m_lastBuffer = NULL;
+ if (initItem) {
+ free(initItem);
+ initItem = NULL;
+ }
+}
+
+CacheBuffer* CacheChannel::allocBuffer()
+{
+ CacheBuffer* buffer;
+ if (!m_busy)
+ return NULL;
+ buffer = (CacheBuffer*)malloc(CACHE_BUFFER_HEADER_SIZE+(m_bufferSizeW<<2));
+ if (buffer) {
+ memset(buffer, 0, CACHE_BUFFER_HEADER_SIZE);
+ }
+ return buffer;
+}
+
+CacheItem* CacheChannel::findItemOrLater(unsigned int timestamp, CacheBuffer **rBuffer)
+{
+ CacheBuffer* buffer;
+ CacheItem *item, *limit;
+ if (!m_busy)
+ return NULL;
+ if (timestamp == 0 && initItem) {
+ *rBuffer = NULL;
+ return initItem;
+ }
+ for (buffer=m_firstBuffer; buffer; buffer = buffer->m_next) {
+ if (buffer->m_firstFreePositionW == 0)
+ // buffer is empty, this must be the last and we didn't find the timestamp
+ return NULL;
+ if (timestamp < buffer->m_firstTimestamp) {
+ *rBuffer = buffer;
+ return &buffer->m_firstItem;
+ }
+ if (timestamp <= buffer->m_lastTimestamp) {
+ // the timestamp is necessarily in this buffer
+ unsigned short timeOffset = (unsigned short)(timestamp-buffer->m_firstTimestamp);
+ unsigned int highBlock;
+ item = _findBlock(buffer, timeOffset, &highBlock);
+ // now we do a linear search until we find a timestamp that is equal or higher
+ // we should normally always find an item but let's put a limit just in case
+ limit = CACHE_BLOCK_ITEM_ADDR(this,buffer,highBlock);
+ while (item<=limit && item->m_timeOffset < timeOffset )
+ item = CACHE_NEXT_ITEM(item);
+ assert(item<=limit);
+ *rBuffer = buffer;
+ return item;
+ }
+ // search in next buffer
+ }
+ return NULL;
+}
+
+CacheItem* CacheChannel::findItemEarlier(unsigned int timestamp, CacheBuffer **rBuffer)
+{
+ CacheBuffer *buffer, *prevBuffer;
+ CacheItem *item, *limit, *prevItem;
+ if (!m_busy)
+ return NULL;
+ if (timestamp == 0)
+ return NULL;
+ for (prevBuffer=NULL, buffer=m_firstBuffer; buffer; prevBuffer = buffer, buffer = buffer->m_next) {
+ if (buffer->m_firstFreePositionW == 0)
+ // buffer is empty, this must be the last and we didn't find the timestamp
+ return NULL;
+ if (timestamp <= buffer->m_firstTimestamp) {
+ if (prevBuffer == NULL) {
+ // no item before, except the initial item
+ *rBuffer = NULL;
+ return initItem;
+ }
+ // the item is necessarily the last one of previous buffer
+ *rBuffer = prevBuffer;
+ return CACHE_ITEM_ADDR(prevBuffer,prevBuffer->m_lastItemPositionW);
+ }
+ if (timestamp <= buffer->m_lastTimestamp) {
+ // the timestamp is necessarily in this buffer
+ unsigned short timeOffset = (unsigned short)(timestamp-buffer->m_firstTimestamp);
+ unsigned int highBlock;
+ item = _findBlock(buffer, timeOffset, &highBlock);
+ // now we do a linear search until we find a timestamp that is equal or higher
+ // we should normally always find an item but let's put a limit just in case
+ limit = CACHE_BLOCK_ITEM_ADDR(this,buffer,highBlock);
+ prevItem = NULL;
+ while (item<=limit && item->m_timeOffset < timeOffset) {
+ prevItem = item;
+ item = CACHE_NEXT_ITEM(item);
+ }
+ assert(item<=limit && prevItem!=NULL);
+ *rBuffer = buffer;
+ return prevItem;
+ }
+ // search in next buffer
+ }
+ // pass all buffer, the last item is the last item of the last buffer
+ if (prevBuffer == NULL) {
+ // no item before, except the initial item
+ *rBuffer = NULL;
+ return initItem;
+ }
+ // the item is necessarily the last one of previous buffer
+ *rBuffer = prevBuffer;
+ return CACHE_ITEM_ADDR(prevBuffer,prevBuffer->m_lastItemPositionW);
+}
+
+
+Cache::Cache()
+{
+}
+
+Cache::~Cache()
+{
+ CacheMap::iterator it;
+ for (it=m_cache.begin(); it!=m_cache.end(); it=m_cache.begin()) {
+ deleteDevice(it->first);
+ }
+}
+
+int Cache::addChannel(const void *device, const char *name, unsigned int maxItemSize)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+ CacheChannel *channel;
+ unsigned int id;
+
+ if (maxItemSize > 0x3FFF0)
+ return -1;
+
+ if (it == m_cache.end()) {
+ // device does not exist yet, create a new entry
+ entry = new CacheEntry();
+ if (entry == NULL)
+ return -1;
+ if (!m_cache.insert(CacheMap::value_type(device,entry)).second)
+ return -1;
+ } else {
+ entry = it->second;
+ }
+ // locate a channel with the same name and reuse
+ for (channel=entry->m_channelArray, id=0; id<entry->m_count; id++, channel++) {
+ if (channel->m_busy && !strcmp(name, channel->m_name)) {
+ // make this channel free again
+ deleteChannel(device, id);
+ // there can only be one channel with the same name
+ break;
+ }
+ }
+ for (channel=entry->m_channelArray, id=0; id<entry->m_count; id++, channel++) {
+ // locate a free channel
+ if (!channel->m_busy)
+ break;
+ }
+ if (id == entry->m_count) {
+ // no channel free, create new channels
+ int newcount = entry->m_count + CACHE_CHANNEL_EXTEND_SIZE;
+ channel = (CacheChannel*)realloc(entry->m_channelArray, newcount*sizeof(CacheChannel));
+ if (channel == NULL)
+ return -1;
+ entry->m_channelArray = channel;
+ memset(&entry->m_channelArray[entry->m_count], 0, CACHE_CHANNEL_EXTEND_SIZE*sizeof(CacheChannel));
+ entry->m_count = newcount;
+ channel = &entry->m_channelArray[id];
+ }
+ // compute the optimal buffer size
+ // The buffer size must be selected so that
+ // - it does not contain more than 1630 items (=1s of cache assuming 25 items per second)
+ // - it contains at least one item
+ // - it's not bigger than 256kb and preferably around 32kb
+ // - it a multiple of 4
+ unsigned int bufSize = 1630*(maxItemSize+4);
+ if (bufSize >= CACHE_DEFAULT_BUFFER_SIZE)
+ bufSize = CACHE_DEFAULT_BUFFER_SIZE;
+ if (bufSize < maxItemSize+16)
+ bufSize = maxItemSize+16;
+ bufSize = (bufSize + 3) & ~0x3;
+ // compute block size and offset bit mask
+ // the block size is computed so that
+ // - it is a power of 2
+ // - there is at least one item per block
+ // - there is no more than CACHE_LOOKUP_TABLE_SIZE blocks per buffer
+ unsigned int blockSize = bufSize/CACHE_LOOKUP_TABLE_SIZE;
+ if (blockSize < maxItemSize+12)
+ blockSize = maxItemSize+12;
+ // find the power of 2 that is immediately larger than blockSize
+ unsigned int m;
+ unsigned int pwr2Size = blockSize;
+ while ((m = (pwr2Size & (pwr2Size-1))) != 0)
+ pwr2Size = m;
+ blockSize = (pwr2Size < blockSize) ? pwr2Size<<1 : pwr2Size;
+ // convert byte size to word size because all positions and size are expressed in 32 bit words
+ blockSize >>= 2;
+ channel->m_blockSizeW = blockSize;
+ channel->m_bufferSizeW = bufSize>>2;
+ channel->m_firstBuffer = NULL;
+ channel->m_lastBuffer = NULL;
+ channel->m_busy = 1;
+ channel->initItem = NULL;
+ channel->m_maxItemSizeB = maxItemSize;
+ strncpy(channel->m_name, name, sizeof(channel->m_name));
+ channel->m_name[sizeof(channel->m_name)-1] = 0;
+ channel->m_positionToOffsetMaskW = (blockSize-1);
+ for (m=0; blockSize!=1; m++, blockSize>>=1);
+ channel->m_positionToBlockShiftW = m;
+ return (int)id;
+}
+
+int Cache::deleteChannel(const void *device, int id)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+
+ if (it == m_cache.end()) {
+ // device does not exist
+ return -1;
+ }
+ entry = it->second;
+ if (id < 0 || id >= (int)entry->m_count || !entry->m_channelArray[id].m_busy)
+ return -1;
+ entry->m_channelArray[id].clear();
+ entry->m_channelArray[id].m_busy = 0;
+ return 0;
+}
+
+int Cache::deleteDevice(const void *device)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+
+ if (it == m_cache.end()) {
+ // device does not exist
+ return -1;
+ }
+ entry = it->second;
+ delete entry;
+ m_cache.erase(it);
+ return 0;
+}
+
+void Cache::clearCacheFrom(const void *device, CacheTS timestamp)
+{
+ CacheMap::iterator it = (device) ? m_cache.find(device) : m_cache.begin();
+ CacheEntry *entry;
+ CacheChannel *channel;
+ CacheBuffer *buffer, *nextBuffer, *prevBuffer;
+ CacheItem *item, *prevItem, *nextItem;
+ unsigned int positionW, block;
+
+ while (it != m_cache.end()) {
+ entry = it->second;
+ for (unsigned int ch=0; ch<entry->m_count; ch++) {
+ channel = &entry->m_channelArray[ch];
+ if (channel->m_busy) {
+ item = channel->findItemOrLater(timestamp, &buffer);
+ if (item ) {
+ if (!buffer) {
+ // this is possible if we return the special timestamp=0 item, delete all buffers
+ channel->clear();
+ } else {
+ // this item and all later items will be removed, clear any later buffer
+ while ((nextBuffer = buffer->m_next) != NULL) {
+ buffer->m_next = nextBuffer->m_next;
+ free(nextBuffer);
+ }
+ positionW = CACHE_ITEM_POSITIONW(buffer,item);
+ if (positionW == 0) {
+ // this item is the first one of the buffer, remove the buffer completely
+ // first find the buffer just before it
+ nextBuffer = channel->m_firstBuffer;
+ prevBuffer = NULL;
+ while (nextBuffer != buffer) {
+ prevBuffer = nextBuffer;
+ nextBuffer = nextBuffer->m_next;
+ // we must quit this loop before reaching the end of the list
+ assert(nextBuffer);
+ }
+ free(buffer);
+ buffer = prevBuffer;
+ if (buffer == NULL)
+ // this was also the first buffer
+ channel->m_firstBuffer = NULL;
+ } else {
+ // removing this item means finding the previous item to make it the last one
+ block = positionW>>channel->m_positionToBlockShiftW;
+ if (block == 0) {
+ // start from first item, we know it is not our item because positionW > 0
+ prevItem = &buffer->m_firstItem;
+ } else {
+ // no need to check the current block, it will point to our item or a later one
+ // but the previous block will be a good start for sure.
+ block--;
+ prevItem = CACHE_BLOCK_ITEM_ADDR(channel,buffer,block);
+ }
+ while ((nextItem = CACHE_NEXT_ITEM(prevItem)) < item)
+ prevItem = nextItem;
+ // we must have found our item
+ assert(nextItem==item);
+ // now set the buffer
+ buffer->m_lastItemPositionW = CACHE_ITEM_POSITIONW(buffer,prevItem);
+ buffer->m_firstFreePositionW = positionW;
+ buffer->m_lastTimestamp = buffer->m_firstTimestamp + prevItem->m_timeOffset;
+ block = buffer->m_lastItemPositionW>>channel->m_positionToBlockShiftW;
+ buffer->lookup[block].m_offsetW = buffer->m_lastItemPositionW&channel->m_positionToOffsetMaskW;
+ buffer->lookup[block].m_timeOffset = prevItem->m_timeOffset;
+ }
+ // set the channel
+ channel->m_lastBuffer = buffer;
+ if (buffer) {
+ channel->m_lastTimestamp = buffer->m_lastTimestamp;
+ channel->m_lastItemPositionW = buffer->m_lastItemPositionW;
+ }
+ }
+ }
+ }
+ }
+ if (device)
+ break;
+ ++it;
+ }
+}
+
+void *Cache::addCacheItem(const void *device, int id, unsigned int timestamp, void *data, unsigned int length)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+ CacheChannel *channel;
+ CacheBuffer *buffer, *next;
+ CacheItem *item;
+ unsigned int positionW, sizeW, block;
+
+ if (it == m_cache.end()) {
+ // device does not exist
+ return NULL;
+ }
+ entry = it->second;
+ if (id < 0 || id >= (int) entry->m_count || !entry->m_channelArray[id].m_busy)
+ return NULL;
+ channel = &entry->m_channelArray[id];
+ if (length > channel->m_maxItemSizeB)
+ return NULL;
+ if (timestamp == 0) {
+ // initial item, delete all buffers
+ channel->clear();
+ // and create initial item
+ item = NULL;
+ // we will allocate the memory, which is always pointer aligned => compute size
+ // with NULL will give same result.
+ sizeW = CACHE_ITEM_SIZEW(item,length);
+ item = (CacheItem*)calloc(sizeW, 4);
+ item->m_sizeW = sizeW;
+ channel->initItem = item;
+ } else {
+ if (!channel->m_lastBuffer) {
+ // no item in buffer, insert item at first position of first buffer
+ positionW = 0;
+ if ((buffer = channel->m_firstBuffer) == NULL) {
+ buffer = channel->allocBuffer();
+ channel->m_firstBuffer = buffer;
+ }
+ } else if (timestamp > channel->m_lastTimestamp) {
+ // this is the normal case: we are writing past lastest timestamp
+ buffer = channel->m_lastBuffer;
+ positionW = buffer->m_firstFreePositionW;
+ } else if (timestamp == channel->m_lastTimestamp) {
+ // common case, rewriting the last timestamp, just reuse the last position
+ buffer = channel->m_lastBuffer;
+ positionW = channel->m_lastItemPositionW;
+ } else {
+ // general case, write in the middle of the buffer, locate the timestamp
+ // (or the timestamp just after), clear this item and all future items,
+ // and write at that position
+ item = channel->findItemOrLater(timestamp, &buffer);
+ if (item == NULL) {
+ // this should not happen
+ return NULL;
+ }
+ // this item will become the last one of this channel, clear any later buffer
+ while ((next = buffer->m_next) != NULL) {
+ buffer->m_next = next->m_next;
+ free(next);
+ }
+ // no need to update the buffer, this will be done when the item is written
+ positionW = CACHE_ITEM_POSITIONW(buffer,item);
+ }
+ item = CACHE_ITEM_ADDR(buffer,positionW);
+ sizeW = CACHE_ITEM_SIZEW(item,length);
+ // we have positionW pointing where we can put the item
+ // before we do that we have to check if we can:
+ // - enough room
+ // - timestamp not too late
+ if ((positionW+sizeW > channel->m_bufferSizeW) ||
+ (positionW > 0 && timestamp >= buffer->m_firstTimestamp+0x10000)) {
+ // we must allocate a new buffer to store this item
+ // but before we must make sure that the current buffer is consistent
+ if (positionW != buffer->m_firstFreePositionW) {
+ // This means that we were trying to write in the middle of the buffer.
+ // We must set the buffer right with positionW being the last position
+ // and find the item before positionW to make it the last.
+ block = positionW>>channel->m_positionToBlockShiftW;
+ CacheItem *previousItem, *nextItem;
+ if (block == 0) {
+ // start from first item, we know it is not our item because positionW > 0
+ previousItem = &buffer->m_firstItem;
+ } else {
+ // no need to check the current block, it will point to our item or a later one
+ // but the previous block will be a good start for sure.
+ block--;
+ previousItem = CACHE_BLOCK_ITEM_ADDR(channel,buffer,block);
+ }
+ while ((nextItem = CACHE_NEXT_ITEM(previousItem)) < item)
+ previousItem = nextItem;
+ // we must have found our item
+ assert(nextItem==item);
+ // now set the buffer
+ buffer->m_lastItemPositionW = CACHE_ITEM_POSITIONW(buffer,previousItem);
+ buffer->m_firstFreePositionW = positionW;
+ buffer->m_lastTimestamp = buffer->m_firstTimestamp + previousItem->m_timeOffset;
+ block = buffer->m_lastItemPositionW>>channel->m_positionToBlockShiftW;
+ buffer->lookup[block].m_offsetW = buffer->m_lastItemPositionW&channel->m_positionToOffsetMaskW;
+ buffer->lookup[block].m_timeOffset = previousItem->m_timeOffset;
+ // and also the channel, just in case
+ channel->m_lastBuffer = buffer;
+ channel->m_lastTimestamp = buffer->m_lastTimestamp;
+ channel->m_lastItemPositionW = buffer->m_lastItemPositionW;
+ }
+ // now allocate a new buffer
+ buffer->m_next = channel->allocBuffer();
+ if (buffer->m_next == NULL)
+ return NULL;
+ buffer = buffer->m_next;
+ positionW = 0;
+ item = &buffer->m_firstItem;
+ sizeW = CACHE_ITEM_SIZEW(item,length);
+ }
+ // all check passed, ready to write the item
+ item->m_sizeW = sizeW;
+ if (positionW == 0) {
+ item->m_timeOffset = 0;
+ buffer->m_firstTimestamp = timestamp;
+ } else {
+ item->m_timeOffset = (unsigned short)(timestamp-buffer->m_firstTimestamp);
+ }
+ buffer->m_lastItemPositionW = positionW;
+ buffer->m_firstFreePositionW = positionW+sizeW;
+ buffer->m_lastTimestamp = timestamp;
+ block = positionW>>channel->m_positionToBlockShiftW;
+ buffer->lookup[block].m_offsetW = positionW&channel->m_positionToOffsetMaskW;
+ buffer->lookup[block].m_timeOffset = item->m_timeOffset;
+ buffer->m_lastItemPositionW = CACHE_ITEM_POSITIONW(buffer,item);
+ buffer->m_firstFreePositionW = buffer->m_lastItemPositionW+item->m_sizeW;
+ channel->m_lastBuffer = buffer;
+ channel->m_lastItemPositionW = positionW;
+ channel->m_lastTimestamp = timestamp;
+ }
+ // now copy the item
+ void *itemData = CACHE_ITEM_DATA_POINTER(item);
+ if (data)
+ memcpy(itemData, data, length);
+ return itemData;
+}
+
+const void *Cache::getPreviousCacheItem(const void *device, int id, unsigned int *timestamp)
+{
+ CacheMap::iterator it;
+ CacheEntry *entry;
+ CacheChannel *channel;
+ CacheBuffer *buffer;
+ CacheItem *item;
+
+ if (device) {
+ it = m_cache.find(device);
+ } else {
+ it = m_cache.begin();
+ }
+ if (it == m_cache.end()) {
+ // device does not exist
+ return NULL;
+ }
+ entry = it->second;
+ if (id < 0 || id >= (int) entry->m_count || !entry->m_channelArray[id].m_busy)
+ return NULL;
+ channel = &entry->m_channelArray[id];
+ if ((item = channel->findItemEarlier(*timestamp,&buffer)) == NULL)
+ return NULL;
+ *timestamp = (buffer) ? buffer->m_firstTimestamp+item->m_timeOffset : 0;
+ return CACHE_ITEM_DATA_POINTER(item);
+}
+
+const CacheItem *Cache::getCurrentCacheItemInternal(const void *device, int id, CacheTS timestamp)
+{
+ CacheMap::iterator it = m_cache.find(device);
+ CacheEntry *entry;
+ CacheChannel *channel;
+ CacheBuffer *buffer;
+ CacheItem *item;
+
+ if (it == m_cache.end()) {
+ // device does not exist
+ return NULL;
+ }
+ entry = it->second;
+ if (id < 0 || id >= (int) entry->m_count || !entry->m_channelArray[id].m_busy)
+ return NULL;
+ channel = &entry->m_channelArray[id];
+ if ((item = channel->findItemOrLater(timestamp,&buffer)) == NULL)
+ return NULL;
+ if (buffer && buffer->m_firstTimestamp+item->m_timeOffset != timestamp)
+ return NULL;
+ return item;
+}
+
+const void *Cache::getCurrentCacheItem(const void *device, int channel, unsigned int timestamp)
+{
+ const CacheItem *item = getCurrentCacheItemInternal(device, channel, timestamp);
+ return (item) ? CACHE_ITEM_DATA_POINTER(item) : NULL;
+}
+
+double *Cache::addCacheVectorIfDifferent(const void *device, int channel, CacheTS timestamp, double *newdata, unsigned int length, double threshold)
+{
+ const CacheItem *item = getCurrentCacheItemInternal(device, channel, timestamp);
+ unsigned int sizeW = CACHE_ITEM_SIZEW(item,length*sizeof(double));
+ if (!item || item->m_sizeW != sizeW)
+ return (double*)addCacheItem(device, channel, timestamp, newdata, length*sizeof(double));
+ double *olddata = (double*)CACHE_ITEM_DATA_POINTER(item);
+ if (!length)
+ return olddata;
+ double *ref = olddata;
+ double *v = newdata;
+ unsigned int i;
+ for (i=length; i>0; --i) {
+ if (fabs(*v-*ref) > threshold)
+ break;
+ *ref++ = *v++;
+ }
+ if (i)
+ olddata = (double*)addCacheItem(device, channel, timestamp, newdata, length*sizeof(double));
+ return olddata;
+}
+
+}
diff --git a/intern/itasc/Cache.hpp b/intern/itasc/Cache.hpp
new file mode 100644
index 00000000000..64707782e6f
--- /dev/null
+++ b/intern/itasc/Cache.hpp
@@ -0,0 +1,227 @@
+/* $Id: Cache.hpp 21152 2009-06-25 11:57:19Z ben2610 $
+ * Cache.hpp
+ *
+ * Created on: Feb 24, 2009
+ * Author: benoit tbolsee
+ */
+
+#ifndef CACHE_HPP_
+#define CACHE_HPP_
+
+#include <map>
+
+namespace iTaSC {
+
+#define CACHE_LOOKUP_TABLE_SIZE 128
+#define CACHE_DEFAULT_BUFFER_SIZE 32768
+#define CACHE_CHANNEL_EXTEND_SIZE 10
+#define CACHE_MAX_ITEM_SIZE 0x3FFF0
+
+/* macro to get the alignement gap after an item header */
+#define CACHE_ITEM_GAPB(item) (unsigned int)(((size_t)item+sizeof(CacheItem))&(sizeof(void*)-1))
+/* macro to get item data position, item=CacheItem pointer */
+#define CACHE_ITEM_DATA_POINTER(item) (void*)((unsigned char*)item+sizeof(CacheItem)+CACHE_ITEM_GAPB(item))
+/* macro to get item size in 32bit words from item address and length, item=CacheItem pointer */
+#define CACHE_ITEM_SIZEW(item,length) (unsigned int)((sizeof(CacheItem)+CACHE_ITEM_GAPB(item)+(((length)+3)&~0x3))>>2)
+/* macto to move from one item to the next, item=CacheItem pointer, updated by the macro */
+#define CACHE_NEXT_ITEM(item) ((item)+(item)->m_sizeW)
+#define CACHE_BLOCK_ITEM_ADDR(chan,buf,block) (&(buf)->m_firstItem+(((unsigned int)(block)<<chan->m_positionToBlockShiftW)+(buf)->lookup[block].m_offsetW))
+#define CACHE_ITEM_ADDR(buf,pos) (&(buf)->m_firstItem+(pos))
+#define CACHE_ITEM_POSITIONW(buf,item) (unsigned int)(item-&buf->m_firstItem)
+
+typedef unsigned int CacheTS;
+
+struct Timestamp
+{
+ double realTimestamp;
+ double realTimestep;
+ CacheTS cacheTimestamp;
+ unsigned int numstep:8;
+ unsigned int substep:1;
+ unsigned int reiterate:1;
+ unsigned int cache:1;
+ unsigned int update:1;
+ unsigned int interpolate:1;
+ unsigned int dummy:19;
+
+ Timestamp() { memset(this, 0, sizeof(Timestamp)); }
+};
+
+/* utility function to return second timestamp to millisecond */
+inline void setCacheTimestamp(Timestamp& timestamp)
+{
+ if (timestamp.realTimestamp < 0.0 || timestamp.realTimestamp > 4294967.295)
+ timestamp.cacheTimestamp = 0;
+ else
+ timestamp.cacheTimestamp = (CacheTS)(timestamp.realTimestamp*1000.0+0.5);
+}
+
+
+/*
+class Cache:
+Top level class, only one instance of this class should exists.
+A device (=constraint, object) uses this class to create a cache entry for its data.
+A cache entry is divided into cache channels, each providing a separate buffer for cache items.
+The cache channels must be declared by the devices before they can be used.
+The device must specify the largest cache item (limited to 256Kb) so that the cache
+buffer can be organized optimally.
+Cache channels are identified by small number (starting from 0) allocated by the cache system.
+Cache items are inserted into cache channels ordered by timestamp. Writing is always done
+at the end of the cache buffer: writing an item automatically clears all items with
+higher timestamp.
+A cache item is an array of bytes provided by the device; the format of the cache item is left
+to the device.
+The device can retrieve a cache item associated with a certain timestamp. The cache system
+returns a pointer that points directly in the cache buffer to avoid unnecessary copy.
+The pointer is guaranteed to be pointer aligned so that direct mapping to C structure is possible
+(=32 bit aligned on 32 systems and 64 bit aligned on 64 bits system).
+
+Timestamp = rounded time in millisecond.
+*/
+
+struct CacheEntry;
+struct CacheBuffer;
+struct CacheItem;
+struct CacheChannel;
+
+class Cache
+{
+private:
+ /* map between device and cache entry.
+ Dynamically updated when more devices create cache channels */
+ typedef std::map<const void *, struct CacheEntry*> CacheMap;
+ CacheMap m_cache;
+ const CacheItem *getCurrentCacheItemInternal(const void *device, int channel, CacheTS timestamp);
+
+public:
+ Cache();
+ ~Cache();
+ /* add a cache channel, maxItemSize must be < 256k.
+ name : channel name, truncated at 31 characters
+ msxItemSize : maximum size of item in bytes, items of larger size will be rejected
+ return value >= 0: channel id, -1: error */
+ int addChannel(const void *device, const char *name, unsigned int maxItemSize);
+
+ /* delete a cache channel (and all associated buffers and items) */
+ int deleteChannel(const void *device, int channel);
+ /* delete all channels of a device and remove the device from the map */
+ int deleteDevice(const void *device);
+ /* removes all cache items, leaving the special item at timestamp=0.
+ if device=NULL, apply to all devices. */
+ void clearCacheFrom(const void *device, CacheTS timestamp);
+
+ /* add a new cache item
+ channel: the cache channel (as returned by AddChannel
+ data, length: the cache item and length in bytes
+ If data is NULL, the memory is allocated in the cache but not writen
+ return: error: NULL, success: pointer to item in cache */
+ void *addCacheItem(const void *device, int channel, CacheTS timestamp, void *data, unsigned int length);
+
+ /* specialized function to add a vector of double in the cache
+ It will first check if a vector exist already in the cache for the same timestamp
+ and compared the cached vector with the new values.
+ If all values are within threshold, the vector is updated but the cache is not deleted
+ for the future timestamps. */
+ double *addCacheVectorIfDifferent(const void *device, int channel, CacheTS timestamp, double *data, unsigned int length, double threshold);
+
+ /* returns the cache item with timestamp that is just before the given timestamp.
+ returns the data pointer or NULL if there is no cache item before timestamp.
+ On return, timestamp is updated with the actual timestamp of the item being returned.
+ Note that the length of the item is not returned, it is up to the device to organize
+ the data so that length can be retrieved from the data if needed.
+ Device can NULL, it will then just look the first channel available, useful to
+ test the status of the cache. */
+ const void *getPreviousCacheItem(const void *device, int channel, CacheTS *timestamp);
+
+ /* returns the cache item with the timestamp that is exactly equal to the given timestamp
+ If there is no cache item for this timestamp, returns NULL.*/
+ const void *getCurrentCacheItem(const void *device, int channel, CacheTS timestamp);
+
+};
+
+/* the following structures are not internal use only, they should not be used directly */
+
+struct CacheEntry
+{
+ CacheChannel *m_channelArray; // array of channels, automatically resized if more channels are created
+ unsigned int m_count; // number of channel in channelArray
+ CacheEntry() : m_channelArray(NULL), m_count(0) {}
+ ~CacheEntry();
+};
+
+struct CacheChannel
+{
+ CacheItem* initItem; // item corresponding to timestamp=0
+ struct CacheBuffer *m_firstBuffer; // first buffer of list
+ struct CacheBuffer *m_lastBuffer; // last buffer of list to which an item was written
+ char m_name[32]; // channel name
+ unsigned char m_busy; // =0 if channel is free, !=0 when channel is in use
+ unsigned char m_positionToBlockShiftW; // number of bits to shift a position in word to get the block number
+ unsigned short m_positionToOffsetMaskW; // bit mask to apply on a position in word to get offset in a block
+ unsigned int m_maxItemSizeB; // maximum item size in bytes
+ unsigned int m_bufferSizeW; // size of item buffer in word to allocate when a new buffer must be created
+ unsigned int m_blockSizeW; // block size in words of the lookup table
+ unsigned int m_lastTimestamp; // timestamp of the last item that was written
+ unsigned int m_lastItemPositionW; // position in words in lastBuffer of the last item written
+ void clear();
+ CacheBuffer* allocBuffer();
+ CacheItem* findItemOrLater(unsigned int timestamp, CacheBuffer **rBuffer);
+ CacheItem* findItemEarlier(unsigned int timestamp, CacheBuffer **rBuffer);
+ // Internal function: finds an item in a buffer that is < timeOffset
+ // timeOffset must be a valid offset for the buffer and the buffer must not be empty
+ // on return highBlock contains the block with items above or equal to timeOffset
+ CacheItem *_findBlock(CacheBuffer *buffer, unsigned short timeOffset, unsigned int *highBlock);
+};
+
+struct CacheBlock {
+ unsigned short m_timeOffset; // timestamp relative to m_firstTimestamp
+ unsigned short m_offsetW; // position in words of item relative to start of block
+};
+
+/* CacheItem is the header of each item in the buffer, must be 32bit
+ Items are always 32 bits aligned and size is the number of 32 bit words until the
+ next item header, including an eventual pre and post padding gap for pointer alignment */
+struct CacheItem
+{
+ unsigned short m_timeOffset; // timestamp relative to m_firstTimestamp
+ unsigned short m_sizeW; // size of item in 32 bit words
+ // item data follows header immediately or after a gap if position is not pointer aligned
+};
+
+// Buffer header
+// Defined in a macro to avoid sizeof() potential problem.
+// next for linked list. = NULL for last buffer
+// m_firstTimestamp timestamp of first item in this buffer
+// m_lastTimestamp timestamp of last item in this buffer
+// m_lastTimestamp must be < m_firstTimestamp+65536
+// m_lastItemPositionW position in word of last item written
+// m_firstFreePositionW position in word where a new item can be written, 0 if buffer is empty
+// lookup lookup table for fast access to item by timestamp
+// The buffer is divided in blocks of 2**n bytes with n chosen so that
+// there are no more than CACHE_LOOKUP_TABLE_SIZE blocks and that each
+// block will contain at least one item.
+// Each element of the lookup table gives the timestamp and offset
+// of the last cache item occupying (=starting in) the corresponding block.
+#define CACHE_HEADER \
+ struct CacheBuffer *m_next; \
+ unsigned int m_firstTimestamp; \
+ unsigned int m_lastTimestamp; \
+ \
+ unsigned int m_lastItemPositionW; \
+ unsigned int m_firstFreePositionW;\
+ struct CacheBlock lookup[CACHE_LOOKUP_TABLE_SIZE]
+
+struct CacheBufferHeader {
+ CACHE_HEADER;
+};
+#define CACHE_BUFFER_HEADER_SIZE (sizeof(struct CacheBufferHeader))
+struct CacheBuffer
+{
+ CACHE_HEADER;
+ struct CacheItem m_firstItem; // the address of this field marks the start of the buffer
+};
+
+
+}
+
+#endif /* CACHE_HPP_ */
diff --git a/intern/itasc/ConstraintSet.cpp b/intern/itasc/ConstraintSet.cpp
new file mode 100644
index 00000000000..f47af4246e4
--- /dev/null
+++ b/intern/itasc/ConstraintSet.cpp
@@ -0,0 +1,170 @@
+/* $Id: ConstraintSet.cpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * ConstraintSet.cpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#include "ConstraintSet.hpp"
+#include "kdl/utilities/svd_eigen_HH.hpp"
+
+namespace iTaSC {
+
+ConstraintSet::ConstraintSet(unsigned int _nc,double accuracy,unsigned int maximum_iterations):
+ m_nc(_nc),
+ m_Jf(e_identity_matrix(6,6)),
+ m_Cf(e_zero_matrix(m_nc,6)),
+ m_U(e_identity_matrix(6,6)),m_V(e_identity_matrix(6,6)),m_B(e_zero_matrix(6,6)),
+ m_Jf_inv(e_zero_matrix(6,6)),
+ m_Wy(e_scalar_vector(m_nc,1.0)),
+ m_chi(e_zero_vector(6)),m_y(m_nc),m_ydot(e_zero_vector(m_nc)),
+ m_S(6),m_temp(6),m_tdelta(6),
+ m_internalPose(F_identity), m_externalPose(F_identity),
+ m_constraintCallback(NULL), m_constraintParam(NULL),
+ m_toggle(false),m_substep(false),
+ m_threshold(accuracy),m_maxIter(maximum_iterations)
+{
+ m_maxDeltaChi = e_scalar(0.52);
+}
+
+ConstraintSet::ConstraintSet():
+ m_nc(0),
+ m_internalPose(F_identity), m_externalPose(F_identity),
+ m_constraintCallback(NULL), m_constraintParam(NULL),
+ m_toggle(false),m_substep(false),
+ m_threshold(0.0),m_maxIter(0)
+{
+ m_maxDeltaChi = e_scalar(0.52);
+}
+
+void ConstraintSet::reset(unsigned int _nc,double accuracy,unsigned int maximum_iterations)
+{
+ m_nc = _nc;
+ m_Jf = e_identity_matrix(6,6);
+ m_Cf = e_zero_matrix(m_nc,6);
+ m_U = e_identity_matrix(6,6);
+ m_V = e_identity_matrix(6,6);
+ m_B = e_zero_matrix(6,6);
+ m_Jf_inv = e_zero_matrix(6,6),
+ m_Wy = e_scalar_vector(m_nc,1.0),
+ m_chi = e_zero_vector(6);
+ m_chidot = e_zero_vector(6);
+ m_y = e_zero_vector(m_nc);
+ m_ydot = e_zero_vector(m_nc);
+ m_S = e_zero_vector(6);
+ m_temp = e_zero_vector(6);
+ m_tdelta = e_zero_vector(6);
+ m_threshold = accuracy;
+ m_maxIter = maximum_iterations;
+}
+
+ConstraintSet::~ConstraintSet() {
+
+}
+
+void ConstraintSet::modelUpdate(Frame& _external_pose,const Timestamp& timestamp)
+{
+ m_chi+=m_chidot*timestamp.realTimestep;
+ m_externalPose = _external_pose;
+
+ //update the internal pose and Jf
+ updateJacobian();
+ //check if loop is already closed, if not update the pose and Jf
+ unsigned int iter=0;
+ while(iter<5&&!closeLoop())
+ iter++;
+}
+
+double ConstraintSet::getMaxTimestep(double& timestep)
+{
+ e_scalar maxChidot = m_chidot.cwise().abs().maxCoeff();
+ if (timestep*maxChidot > m_maxDeltaChi) {
+ timestep = m_maxDeltaChi/maxChidot;
+ }
+ return timestep;
+}
+
+bool ConstraintSet::initialise(Frame& init_pose){
+ m_externalPose=init_pose;
+ // get current Jf
+ updateJacobian();
+
+ unsigned int iter=0;
+ while(iter<m_maxIter&&!closeLoop()){
+ iter++;
+ }
+ if (iter<m_maxIter)
+ return true;
+ else
+ return false;
+}
+
+bool ConstraintSet::setControlParameter(int id, ConstraintAction action, double data, double timestep)
+{
+ ConstraintValues values;
+ ConstraintSingleValue value;
+ values.values = &value;
+ values.number = 0;
+ values.action = action;
+ values.id = id;
+ value.action = action;
+ value.id = id;
+ switch (action) {
+ case ACT_NONE:
+ return true;
+ case ACT_VALUE:
+ value.yd = data;
+ values.number = 1;
+ break;
+ case ACT_VELOCITY:
+ value.yddot = data;
+ values.number = 1;
+ break;
+ case ACT_TOLERANCE:
+ values.tolerance = data;
+ break;
+ case ACT_FEEDBACK:
+ values.feedback = data;
+ break;
+ case ACT_ALPHA:
+ values.alpha = data;
+ break;
+ default:
+ assert(action==ACT_NONE);
+ }
+ return setControlParameters(&values, 1, timestep);
+}
+
+bool ConstraintSet::closeLoop(){
+ //Invert Jf
+ //TODO: svd_boost_Macie has problems if Jf contains zero-rows
+ //toggle=!toggle;
+ //svd_boost_Macie(Jf,U,S,V,B,temp,1e-3*threshold,toggle);
+ int ret = KDL::svd_eigen_HH(m_Jf,m_U,m_S,m_V,m_temp);
+ if(ret<0)
+ return false;
+
+ // the reference point and frame of the jacobian is the base frame
+ // m_externalPose-m_internalPose is the twist to extend the end effector
+ // to get the required pose => change the reference point to the base frame
+ Twist twist_delta(diff(m_internalPose,m_externalPose));
+ twist_delta=twist_delta.RefPoint(-m_internalPose.p);
+ for(unsigned int i=0;i<6;i++)
+ m_tdelta(i)=twist_delta(i);
+ //TODO: use damping in constraintset inversion?
+ for(unsigned int i=0;i<6;i++)
+ if(m_S(i)<m_threshold){
+ m_B.row(i).setConstant(0.0);
+ }else
+ m_B.row(i) = m_U.col(i)/m_S(i);
+
+ m_Jf_inv=(m_V*m_B).lazy();
+
+ m_chi+=(m_Jf_inv*m_tdelta).lazy();
+ updateJacobian();
+ // m_externalPose-m_internalPose in end effector frame
+ // this is just to compare the pose, a different formula would work too
+ return Equal(m_internalPose.Inverse()*m_externalPose,F_identity,m_threshold);
+
+}
+}
diff --git a/intern/itasc/ConstraintSet.hpp b/intern/itasc/ConstraintSet.hpp
new file mode 100644
index 00000000000..12bb085c911
--- /dev/null
+++ b/intern/itasc/ConstraintSet.hpp
@@ -0,0 +1,115 @@
+/* $Id: ConstraintSet.hpp 20307 2009-05-20 20:39:18Z ben2610 $
+ * ConstraintSet.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef CONSTRAINTSET_HPP_
+#define CONSTRAINTSET_HPP_
+
+#include "kdl/frames.hpp"
+#include "eigen_types.hpp"
+#include "Cache.hpp"
+#include <vector>
+
+namespace iTaSC {
+
+enum ConstraintAction {
+ ACT_NONE= 0,
+ ACT_VALUE= 1,
+ ACT_VELOCITY= 2,
+ ACT_TOLERANCE= 4,
+ ACT_FEEDBACK= 8,
+ ACT_ALPHA= 16
+};
+
+struct ConstraintSingleValue {
+ unsigned int id; // identifier of constraint value, depends on constraint
+ unsigned int action;// action performed, compbination of ACT_..., set on return
+ const double y; // actual constraint value
+ const double ydot; // actual constraint velocity
+ double yd; // current desired constraint value, changed on return
+ double yddot; // current desired constraint velocity, changed on return
+ ConstraintSingleValue(): id(0), action(0), y(0.0), ydot(0.0) {}
+};
+
+struct ConstraintValues {
+ unsigned int id; // identifier of group of constraint values, depend on constraint
+ unsigned short number; // number of constraints in list
+ unsigned short action; // action performed, ACT_..., set on return
+ double alpha; // constraint activation coefficient, should be [0..1]
+ double tolerance; // current desired tolerance on constraint, same unit than yd, changed on return
+ double feedback; // current desired feedback on error, in 1/sec, changed on return
+ struct ConstraintSingleValue* values;
+ ConstraintValues(): id(0), number(0), action(0), values(NULL) {}
+};
+
+class ConstraintSet;
+typedef bool (*ConstraintCallback)(const Timestamp& timestamp, struct ConstraintValues* const _values, unsigned int _nvalues, void* _param);
+
+class ConstraintSet {
+protected:
+ unsigned int m_nc;
+ e_scalar m_maxDeltaChi;
+ e_matrix m_Cf;
+ e_vector m_Wy,m_y,m_ydot;
+ e_vector6 m_chi,m_chidot,m_S,m_temp,m_tdelta;
+ e_matrix6 m_Jf,m_U,m_V,m_B,m_Jf_inv;
+ KDL::Frame m_internalPose,m_externalPose;
+ ConstraintCallback m_constraintCallback;
+ void* m_constraintParam;
+ void* m_poseParam;
+ bool m_toggle;
+ bool m_substep;
+ double m_threshold;
+ unsigned int m_maxIter;
+
+ friend class Scene;
+ virtual void modelUpdate(KDL::Frame& _external_pose,const Timestamp& timestamp);
+ virtual void updateKinematics(const Timestamp& timestamp)=0;
+ virtual void pushCache(const Timestamp& timestamp)=0;
+ virtual void updateJacobian()=0;
+ virtual void updateControlOutput(const Timestamp& timestamp)=0;
+ virtual void initCache(Cache *_cache) = 0;
+ virtual bool initialise(KDL::Frame& init_pose);
+ virtual void reset(unsigned int nc,double accuracy,unsigned int maximum_iterations);
+ virtual bool closeLoop();
+ virtual double getMaxTimestep(double& timestep);
+
+
+public:
+ ConstraintSet(unsigned int nc,double accuracy,unsigned int maximum_iterations);
+ ConstraintSet();
+ virtual ~ConstraintSet();
+
+ EIGEN_MAKE_ALIGNED_OPERATOR_NEW
+
+ virtual bool registerCallback(ConstraintCallback _function, void* _param)
+ {
+ m_constraintCallback = _function;
+ m_constraintParam = _param;
+ return true;
+ }
+
+ virtual const e_vector& getControlOutput()const{return m_ydot;};
+ virtual const ConstraintValues* getControlParameters(unsigned int* _nvalues) = 0;
+ virtual bool setControlParameters(ConstraintValues* _values, unsigned int _nvalues, double timestep=0.0) = 0;
+ bool setControlParameter(int id, ConstraintAction action, double value, double timestep=0.0);
+
+ virtual const e_matrix6& getJf() const{return m_Jf;};
+ virtual const KDL::Frame& getPose() const{return m_internalPose;};
+ virtual const e_matrix& getCf() const{return m_Cf;};
+
+ virtual const e_vector& getWy() const {return m_Wy;};
+ virtual void setWy(const e_vector& Wy_in){m_Wy = Wy_in;};
+ virtual void setJointVelocity(const e_vector chidot_in){m_chidot = chidot_in;};
+
+ virtual unsigned int getNrOfConstraints(){return m_nc;};
+ void substep(bool _substep) {m_substep=_substep;}
+ bool substep() {return m_substep;}
+};
+
+}
+
+#endif /* CONSTRAINTSET_HPP_ */
diff --git a/intern/itasc/ControlledObject.cpp b/intern/itasc/ControlledObject.cpp
new file mode 100644
index 00000000000..f9e819d2950
--- /dev/null
+++ b/intern/itasc/ControlledObject.cpp
@@ -0,0 +1,61 @@
+/* $Id: ControlledObject.cpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * ControlledObject.cpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#include "ControlledObject.hpp"
+
+
+namespace iTaSC {
+ControlledObject::ControlledObject():
+ Object(Controlled),m_nq(0),m_nc(0),m_nee(0)
+{
+ // max joint variable = 0.52 radian or 0.52 meter in one timestep
+ m_maxDeltaQ = e_scalar(0.52);
+}
+
+void ControlledObject::initialize(unsigned int _nq,unsigned int _nc, unsigned int _nee)
+{
+ assert(_nee >= 1);
+ m_nq = _nq;
+ m_nc = _nc;
+ m_nee = _nee;
+ if (m_nq > 0) {
+ m_Wq = e_identity_matrix(m_nq,m_nq);
+ m_qdot = e_zero_vector(m_nq);
+ }
+ if (m_nc > 0) {
+ m_Wy = e_scalar_vector(m_nc,1.0);
+ m_ydot = e_zero_vector(m_nc);
+ }
+ if (m_nc > 0 && m_nq > 0)
+ m_Cq = e_zero_matrix(m_nc,m_nq);
+ // clear all Jacobian if any
+ m_JqArray.clear();
+ // reserve one more to have a zero matrix handy
+ if (m_nq > 0)
+ m_JqArray.resize(m_nee+1, e_zero_matrix(6,m_nq));
+}
+
+ControlledObject::~ControlledObject() {}
+
+
+
+const e_matrix& ControlledObject::getJq(unsigned int ee) const
+{
+ assert(m_nq > 0);
+ return m_JqArray[(ee>m_nee)?m_nee:ee];
+}
+
+double ControlledObject::getMaxTimestep(double& timestep)
+{
+ e_scalar maxQdot = m_qdot.cwise().abs().maxCoeff();
+ if (timestep*maxQdot > m_maxDeltaQ) {
+ timestep = m_maxDeltaQ/maxQdot;
+ }
+ return timestep;
+}
+
+}
diff --git a/intern/itasc/ControlledObject.hpp b/intern/itasc/ControlledObject.hpp
new file mode 100644
index 00000000000..2370f6594ed
--- /dev/null
+++ b/intern/itasc/ControlledObject.hpp
@@ -0,0 +1,70 @@
+/* $Id: ControlledObject.hpp 20853 2009-06-13 12:29:46Z ben2610 $
+ * ControlledObject.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef CONTROLLEDOBJECT_HPP_
+#define CONTROLLEDOBJECT_HPP_
+
+#include "kdl/frames.hpp"
+#include "eigen_types.hpp"
+
+#include "Object.hpp"
+#include "ConstraintSet.hpp"
+#include <vector>
+
+namespace iTaSC {
+
+#define CONSTRAINT_ID_ALL ((unsigned int)-1)
+
+class ControlledObject : public Object {
+protected:
+ e_scalar m_maxDeltaQ;
+ unsigned int m_nq,m_nc,m_nee;
+ e_matrix m_Wq,m_Cq;
+ e_vector m_Wy,m_ydot,m_qdot;
+ std::vector<e_matrix> m_JqArray;
+public:
+ ControlledObject();
+ virtual ~ControlledObject();
+
+ class JointLockCallback {
+ public:
+ JointLockCallback() {}
+ virtual ~JointLockCallback() {}
+
+ // lock a joint, no need to update output
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof) = 0;
+ // lock a joint and update output in view of reiteration
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof, double* qdot) = 0;
+ };
+
+ virtual void initialize(unsigned int _nq,unsigned int _nc, unsigned int _nee);
+
+ // returns true when a joint has been locked via the callback and the solver must run again
+ virtual bool updateJoint(const Timestamp& timestamp, JointLockCallback& callback) = 0;
+ virtual void updateControlOutput(const Timestamp& timestamp)=0;
+ virtual void setJointVelocity(const e_vector qdot_in){m_qdot = qdot_in;};
+ virtual double getMaxTimestep(double& timestep);
+ virtual bool setControlParameter(unsigned int constraintId, unsigned int valueId, ConstraintAction action, e_scalar value, double timestep=0.0)=0;
+
+ virtual const e_vector& getControlOutput() const{return m_ydot;}
+
+ virtual const e_matrix& getJq(unsigned int ee) const;
+
+ virtual const e_matrix& getCq() const{return m_Cq;};
+
+ virtual e_matrix& getWq() {return m_Wq;};
+ virtual void setWq(const e_matrix& Wq_in){m_Wq = Wq_in;};
+
+ virtual const e_vector& getWy() const {return m_Wy;};
+
+ virtual const unsigned int getNrOfCoordinates(){return m_nq;};
+ virtual const unsigned int getNrOfConstraints(){return m_nc;};
+};
+
+}
+
+#endif /* CONTROLLEDOBJECT_HPP_ */
diff --git a/intern/itasc/CopyPose.cpp b/intern/itasc/CopyPose.cpp
new file mode 100644
index 00000000000..df0bc38b704
--- /dev/null
+++ b/intern/itasc/CopyPose.cpp
@@ -0,0 +1,481 @@
+/* $Id: CopyPose.cpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * CopyPose.cpp
+ *
+ * Created on: Mar 17, 2009
+ * Author: benoit bolsee
+ */
+
+#include "CopyPose.hpp"
+#include "kdl/kinfam_io.hpp"
+#include <math.h>
+#include <malloc.h>
+#include <string.h>
+
+namespace iTaSC
+{
+
+const unsigned int maxPoseCacheSize = (2*(3+3*2));
+CopyPose::CopyPose(unsigned int control_output, unsigned int dynamic_output, double armlength, double accuracy, unsigned int maximum_iterations):
+ ConstraintSet(),
+ m_cache(NULL),
+ m_poseCCh(-1),m_poseCTs(0)
+{
+ m_maxerror = armlength/2.0;
+ m_outputControl = (control_output & CTL_ALL);
+ int _nc = nBitsOn(m_outputControl);
+ if (!_nc)
+ return;
+ // reset the constraint set
+ reset(_nc, accuracy, maximum_iterations);
+ _nc = 0;
+ m_nvalues = 0;
+ int nrot = 0, npos = 0;
+ int nposCache = 0, nrotCache = 0;
+ m_outputDynamic = (dynamic_output & m_outputControl);
+ memset(m_values, 0, sizeof(m_values));
+ memset(m_posData, 0, sizeof(m_posData));
+ memset(m_rotData, 0, sizeof(m_rotData));
+ memset(&m_rot, 0, sizeof(m_rot));
+ memset(&m_pos, 0, sizeof(m_pos));
+ if (m_outputControl & CTL_POSITION) {
+ m_pos.alpha = 1.0;
+ m_pos.K = 20.0;
+ m_pos.tolerance = 0.05;
+ m_values[m_nvalues].alpha = m_pos.alpha;
+ m_values[m_nvalues].feedback = m_pos.K;
+ m_values[m_nvalues].tolerance = m_pos.tolerance;
+ m_values[m_nvalues].id = ID_POSITION;
+ if (m_outputControl & CTL_POSITIONX) {
+ m_Wy(_nc) = m_pos.alpha/*/(m_pos.tolerance*m_pos.K)*/;
+ m_Cf(_nc++,0)=1.0;
+ m_posData[npos++].id = ID_POSITIONX;
+ if (m_outputDynamic & CTL_POSITIONX)
+ nposCache++;
+ }
+ if (m_outputControl & CTL_POSITIONY) {
+ m_Wy(_nc) = m_pos.alpha/*/(m_pos.tolerance*m_pos.K)*/;
+ m_Cf(_nc++,1)=1.0;
+ m_posData[npos++].id = ID_POSITIONY;
+ if (m_outputDynamic & CTL_POSITIONY)
+ nposCache++;
+ }
+ if (m_outputControl & CTL_POSITIONZ) {
+ m_Wy(_nc) = m_pos.alpha/*/(m_pos.tolerance*m_pos.K)*/;
+ m_Cf(_nc++,2)=1.0;
+ m_posData[npos++].id = ID_POSITIONZ;
+ if (m_outputDynamic & CTL_POSITIONZ)
+ nposCache++;
+ }
+ m_values[m_nvalues].number = npos;
+ m_values[m_nvalues++].values = m_posData;
+ m_pos.firsty = 0;
+ m_pos.ny = npos;
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ m_rot.alpha = 1.0;
+ m_rot.K = 20.0;
+ m_rot.tolerance = 0.05;
+ m_values[m_nvalues].alpha = m_rot.alpha;
+ m_values[m_nvalues].feedback = m_rot.K;
+ m_values[m_nvalues].tolerance = m_rot.tolerance;
+ m_values[m_nvalues].id = ID_ROTATION;
+ if (m_outputControl & CTL_ROTATIONX) {
+ m_Wy(_nc) = m_rot.alpha/*/(m_rot.tolerance*m_rot.K)*/;
+ m_Cf(_nc++,3)=1.0;
+ m_rotData[nrot++].id = ID_ROTATIONX;
+ if (m_outputDynamic & CTL_ROTATIONX)
+ nrotCache++;
+ }
+ if (m_outputControl & CTL_ROTATIONY) {
+ m_Wy(_nc) = m_rot.alpha/*/(m_rot.tolerance*m_rot.K)*/;
+ m_Cf(_nc++,4)=1.0;
+ m_rotData[nrot++].id = ID_ROTATIONY;
+ if (m_outputDynamic & CTL_ROTATIONY)
+ nrotCache++;
+ }
+ if (m_outputControl & CTL_ROTATIONZ) {
+ m_Wy(_nc) = m_rot.alpha/*/(m_rot.tolerance*m_rot.K)*/;
+ m_Cf(_nc++,5)=1.0;
+ m_rotData[nrot++].id = ID_ROTATIONZ;
+ if (m_outputDynamic & CTL_ROTATIONZ)
+ nrotCache++;
+ }
+ m_values[m_nvalues].number = nrot;
+ m_values[m_nvalues++].values = m_rotData;
+ m_rot.firsty = npos;
+ m_rot.ny = nrot;
+ }
+ assert(_nc == m_nc);
+ m_Jf=e_identity_matrix(6,6);
+ m_poseCacheSize = ((nrotCache)?(3+nrotCache*2):0)+((nposCache)?(3+nposCache*2):0);
+}
+
+CopyPose::~CopyPose()
+{
+}
+
+bool CopyPose::initialise(Frame& init_pose)
+{
+ m_externalPose = m_internalPose = init_pose;
+ updateJacobian();
+ return true;
+}
+
+void CopyPose::modelUpdate(Frame& _external_pose,const Timestamp& timestamp)
+{
+ m_internalPose = m_externalPose = _external_pose;
+ updateJacobian();
+}
+
+void CopyPose::initCache(Cache *_cache)
+{
+ m_cache = _cache;
+ m_poseCCh = -1;
+ if (m_cache) {
+ // create one channel for the coordinates
+ m_poseCCh = m_cache->addChannel(this, "Xf", m_poseCacheSize*sizeof(double));
+ // don't save initial value, it will be recomputed from external pose
+ //pushPose(0);
+ }
+}
+
+double* CopyPose::pushValues(double* item, ControlState* _state, unsigned int mask)
+{
+ ControlState::ControlValue* _yval;
+ int i;
+
+ *item++ = _state->alpha;
+ *item++ = _state->K;
+ *item++ = _state->tolerance;
+
+ for (i=0, _yval=_state->output; i<_state->ny; mask<<=1) {
+ if (m_outputControl & mask) {
+ if (m_outputDynamic & mask) {
+ *item++ = _yval->yd;
+ *item++ = _yval->yddot;
+ }
+ _yval++;
+ i++;
+ }
+ }
+ return item;
+}
+
+void CopyPose::pushPose(CacheTS timestamp)
+{
+ if (m_poseCCh >= 0) {
+ if (m_poseCacheSize) {
+ double buf[maxPoseCacheSize];
+ double *item = buf;
+ if (m_outputDynamic & CTL_POSITION)
+ item = pushValues(item, &m_pos, CTL_POSITIONX);
+ if (m_outputDynamic & CTL_ROTATION)
+ item = pushValues(item, &m_rot, CTL_ROTATIONX);
+ m_cache->addCacheVectorIfDifferent(this, m_poseCCh, timestamp, buf, m_poseCacheSize, KDL::epsilon);
+ } else
+ m_cache->addCacheVectorIfDifferent(this, m_poseCCh, timestamp, NULL, 0, KDL::epsilon);
+ m_poseCTs = timestamp;
+ }
+}
+
+double* CopyPose::restoreValues(double* item, ConstraintValues* _values, ControlState* _state, unsigned int mask)
+{
+ ConstraintSingleValue* _data;
+ ControlState::ControlValue* _yval;
+ int i, j;
+
+ _values->alpha = _state->alpha = *item++;
+ _values->feedback = _state->K = *item++;
+ _values->tolerance = _state->tolerance = *item++;
+
+ for (i=_state->firsty, j=i+_state->ny, _yval=_state->output, _data=_values->values; i<j; mask<<=1) {
+ if (m_outputControl & mask) {
+ m_Wy(i) = _state->alpha/*/(_state->tolerance*_state->K)*/;
+ if (m_outputDynamic & mask) {
+ _data->yd = _yval->yd = *item++;
+ _data->yddot = _yval->yddot = *item++;
+ }
+ _data++;
+ _yval++;
+ i++;
+ }
+ }
+ return item;
+}
+
+bool CopyPose::popPose(CacheTS timestamp)
+{
+ bool found = false;
+ if (m_poseCCh >= 0) {
+ double *item = (double*)m_cache->getPreviousCacheItem(this, m_poseCCh, &timestamp);
+ if (item) {
+ found = true;
+ if (timestamp != m_poseCTs) {
+ int i=0;
+ if (m_outputControl & CTL_POSITION) {
+ if (m_outputDynamic & CTL_POSITION) {
+ item = restoreValues(item, &m_values[i], &m_pos, CTL_POSITIONX);
+ }
+ i++;
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ if (m_outputDynamic & CTL_ROTATION) {
+ item = restoreValues(item, &m_values[i], &m_rot, CTL_ROTATIONX);
+ }
+ i++;
+ }
+ m_poseCTs = timestamp;
+ item = NULL;
+ }
+ }
+ }
+ return found;
+}
+
+void CopyPose::interpolateOutput(ControlState* _state, unsigned int mask, const Timestamp& timestamp)
+{
+ ControlState::ControlValue* _yval;
+ int i;
+
+ for (i=0, _yval=_state->output; i<_state->ny; mask <<= 1) {
+ if (m_outputControl & mask) {
+ if (m_outputDynamic & mask) {
+ if (timestamp.substep && timestamp.interpolate) {
+ _yval->yd += _yval->yddot*timestamp.realTimestep;
+ } else {
+ _yval->yd = _yval->nextyd;
+ _yval->yddot = _yval->nextyddot;
+ }
+ }
+ i++;
+ _yval++;
+ }
+ }
+}
+
+void CopyPose::pushCache(const Timestamp& timestamp)
+{
+ if (!timestamp.substep && timestamp.cache) {
+ pushPose(timestamp.cacheTimestamp);
+ }
+}
+
+void CopyPose::updateKinematics(const Timestamp& timestamp)
+{
+ if (timestamp.interpolate) {
+ if (m_outputDynamic & CTL_POSITION)
+ interpolateOutput(&m_pos, CTL_POSITIONX, timestamp);
+ if (m_outputDynamic & CTL_ROTATION)
+ interpolateOutput(&m_rot, CTL_ROTATIONX, timestamp);
+ }
+ pushCache(timestamp);
+}
+
+void CopyPose::updateJacobian()
+{
+ //Jacobian is always identity at the start of the constraint chain
+ //instead of going through complicated jacobian operation, implemented direct formula
+ //m_Jf(1,3) = m_internalPose.p.z();
+ //m_Jf(2,3) = -m_internalPose.p.y();
+ //m_Jf(0,4) = -m_internalPose.p.z();
+ //m_Jf(2,4) = m_internalPose.p.x();
+ //m_Jf(0,5) = m_internalPose.p.y();
+ //m_Jf(1,5) = -m_internalPose.p.x();
+}
+
+void CopyPose::updateState(ConstraintValues* _values, ControlState* _state, unsigned int mask, double timestep)
+{
+ int id = (mask == CTL_ROTATIONX) ? ID_ROTATIONX : ID_POSITIONX;
+ ControlState::ControlValue* _yval;
+ ConstraintSingleValue* _data;
+ int i, j, k;
+ int action = 0;
+
+ if ((_values->action & ACT_ALPHA) && _values->alpha >= 0.0) {
+ _state->alpha = _values->alpha;
+ action |= ACT_ALPHA;
+ }
+ if ((_values->action & ACT_TOLERANCE) && _values->tolerance > KDL::epsilon) {
+ _state->tolerance = _values->tolerance;
+ action |= ACT_TOLERANCE;
+ }
+ if ((_values->action & ACT_FEEDBACK) && _values->feedback > KDL::epsilon) {
+ _state->K = _values->feedback;
+ action |= ACT_FEEDBACK;
+ }
+ for (i=_state->firsty, j=_state->firsty+_state->ny, _yval=_state->output; i<j; mask <<= 1, id++) {
+ if (m_outputControl & mask) {
+ if (action)
+ m_Wy(i) = _state->alpha/*/(_state->tolerance*_state->K)*/;
+ // check if this controlled output is provided
+ for (k=0, _data=_values->values; k<_values->number; k++, _data++) {
+ if (_data->id == id) {
+ switch (_data->action & (ACT_VALUE|ACT_VELOCITY)) {
+ case 0:
+ // no indication, keep current values
+ break;
+ case ACT_VELOCITY:
+ // only the velocity is given estimate the new value by integration
+ _data->yd = _yval->yd+_data->yddot*timestep;
+ // walkthrough
+ case ACT_VALUE:
+ _yval->nextyd = _data->yd;
+ // if the user sets the value, we assume future velocity is zero
+ // (until the user changes the value again)
+ _yval->nextyddot = (_data->action & ACT_VALUE) ? 0.0 : _data->yddot;
+ if (timestep>0.0) {
+ _yval->yddot = (_data->yd-_yval->yd)/timestep;
+ } else {
+ // allow the user to change target instantenously when this function
+ // if called from setControlParameter with timestep = 0
+ _yval->yd = _yval->nextyd;
+ _yval->yddot = _yval->nextyddot;
+ }
+ break;
+ case (ACT_VALUE|ACT_VELOCITY):
+ // the user should not set the value and velocity at the same time.
+ // In this case, we will assume that he wants to set the future value
+ // and we compute the current value to match the velocity
+ _yval->yd = _data->yd - _data->yddot*timestep;
+ _yval->nextyd = _data->yd;
+ _yval->nextyddot = _data->yddot;
+ if (timestep>0.0) {
+ _yval->yddot = (_data->yd-_yval->yd)/timestep;
+ } else {
+ _yval->yd = _yval->nextyd;
+ _yval->yddot = _yval->nextyddot;
+ }
+ break;
+ }
+ }
+ }
+ _yval++;
+ i++;
+ }
+ }
+}
+
+
+bool CopyPose::setControlParameters(struct ConstraintValues* _values, unsigned int _nvalues, double timestep)
+{
+ while (_nvalues > 0) {
+ if (_values->id >= ID_POSITION && _values->id <= ID_POSITIONZ && (m_outputControl & CTL_POSITION)) {
+ updateState(_values, &m_pos, CTL_POSITIONX, timestep);
+ }
+ if (_values->id >= ID_ROTATION && _values->id <= ID_ROTATIONZ && (m_outputControl & CTL_ROTATION)) {
+ updateState(_values, &m_rot, CTL_ROTATIONX, timestep);
+ }
+ _values++;
+ _nvalues--;
+ }
+ return true;
+}
+
+void CopyPose::updateValues(Vector& vel, ConstraintValues* _values, ControlState* _state, unsigned int mask)
+{
+ ConstraintSingleValue* _data;
+ ControlState::ControlValue* _yval;
+ int i, j;
+
+ _values->action = 0;
+
+ for (i=_state->firsty, j=0, _yval=_state->output, _data=_values->values; j<3; j++, mask<<=1) {
+ if (m_outputControl & mask) {
+ *(double*)&_data->y = vel(j);
+ *(double*)&_data->ydot = m_ydot(i);
+ _data->yd = _yval->yd;
+ _data->yddot = _yval->yddot;
+ _data->action = 0;
+ i++;
+ _data++;
+ _yval++;
+ }
+ }
+}
+
+void CopyPose::updateOutput(Vector& vel, ControlState* _state, unsigned int mask)
+{
+ ControlState::ControlValue* _yval;
+ int i, j;
+ double coef=1.0;
+ if (mask & CTL_POSITION) {
+ // put a limit on position error
+ double len=0.0;
+ for (j=0, _yval=_state->output; j<3; j++) {
+ if (m_outputControl & (mask<<j)) {
+ len += KDL::sqr(_yval->yd-vel(j));
+ _yval++;
+ }
+ }
+ len = KDL::sqrt(len);
+ if (len > m_maxerror)
+ coef = m_maxerror/len;
+ }
+ for (i=_state->firsty, j=0, _yval=_state->output; j<3; j++) {
+ if (m_outputControl & (mask<<j)) {
+ m_ydot(i)=_yval->yddot+_state->K*coef*(_yval->yd-vel(j));
+ _yval++;
+ i++;
+ }
+ }
+}
+
+void CopyPose::updateControlOutput(const Timestamp& timestamp)
+{
+ //IMO this should be done, no idea if it is enough (wrt Distance impl)
+ Twist y = diff(F_identity, m_internalPose);
+ bool found = true;
+ if (!timestamp.substep) {
+ if (!timestamp.reiterate) {
+ found = popPose(timestamp.cacheTimestamp);
+ }
+ }
+ if (m_constraintCallback && (m_substep || (!timestamp.reiterate && !timestamp.substep))) {
+ // initialize first callback the application to get the current values
+ int i=0;
+ if (m_outputControl & CTL_POSITION) {
+ updateValues(y.vel, &m_values[i++], &m_pos, CTL_POSITIONX);
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ updateValues(y.rot, &m_values[i++], &m_rot, CTL_ROTATIONX);
+ }
+ if ((*m_constraintCallback)(timestamp, m_values, m_nvalues, m_constraintParam)) {
+ setControlParameters(m_values, m_nvalues, (found && timestamp.interpolate)?timestamp.realTimestep:0.0);
+ }
+ }
+ if (m_outputControl & CTL_POSITION) {
+ updateOutput(y.vel, &m_pos, CTL_POSITIONX);
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ updateOutput(y.rot, &m_rot, CTL_ROTATIONX);
+ }
+}
+
+const ConstraintValues* CopyPose::getControlParameters(unsigned int* _nvalues)
+{
+ Twist y = diff(m_internalPose,F_identity);
+ int i=0;
+ if (m_outputControl & CTL_POSITION) {
+ updateValues(y.vel, &m_values[i++], &m_pos, CTL_POSITIONX);
+ }
+ if (m_outputControl & CTL_ROTATION) {
+ updateValues(y.rot, &m_values[i++], &m_rot, CTL_ROTATIONX);
+ }
+ if (_nvalues)
+ *_nvalues=m_nvalues;
+ return m_values;
+}
+
+double CopyPose::getMaxTimestep(double& timestep)
+{
+ // CopyPose should not have any limit on linear velocity:
+ // in case the target is out of reach, this can be very high.
+ // We will simply limit on rotation
+ e_scalar maxChidot = m_chidot.block(3,0,3,1).cwise().abs().maxCoeff();
+ if (timestep*maxChidot > m_maxDeltaChi) {
+ timestep = m_maxDeltaChi/maxChidot;
+ }
+ return timestep;
+}
+
+}
diff --git a/intern/itasc/CopyPose.hpp b/intern/itasc/CopyPose.hpp
new file mode 100644
index 00000000000..3a3f60a9f37
--- /dev/null
+++ b/intern/itasc/CopyPose.hpp
@@ -0,0 +1,99 @@
+/* $Id: CopyPose.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * CopyPose.h
+ *
+ * Created on: Mar 17, 2009
+ * Author: benoit bolsee
+ */
+
+#ifndef COPYPOSE_H_
+#define COPYPOSE_H_
+
+#include "ConstraintSet.hpp"
+namespace iTaSC{
+
+using namespace KDL;
+
+class CopyPose: public iTaSC::ConstraintSet
+{
+protected:
+ virtual void updateKinematics(const Timestamp& timestamp);
+ virtual void pushCache(const Timestamp& timestamp);
+ virtual void updateJacobian();
+ virtual bool initialise(Frame& init_pose);
+ virtual void initCache(Cache *_cache);
+ virtual void updateControlOutput(const Timestamp& timestamp);
+ virtual void modelUpdate(Frame& _external_pose,const Timestamp& timestamp);
+ virtual double getMaxTimestep(double& timestep);
+
+public:
+ enum ID { // constraint ID in callback and setControlParameter
+ ID_POSITION=0,
+ ID_POSITIONX=1,
+ ID_POSITIONY=2,
+ ID_POSITIONZ=3,
+ ID_ROTATION=4,
+ ID_ROTATIONX=5,
+ ID_ROTATIONY=6,
+ ID_ROTATIONZ=7,
+ };
+ enum CTL { // control ID in constructor to specify which output is constrainted
+ CTL_NONE=0x00,
+ CTL_POSITIONX=0x01, // the bit order is important: it matches the y output order
+ CTL_POSITIONY=0x02,
+ CTL_POSITIONZ=0x04,
+ CTL_POSITION=0x07,
+ CTL_ROTATIONX=0x08,
+ CTL_ROTATIONY=0x10,
+ CTL_ROTATIONZ=0x20,
+ CTL_ROTATION=0x38,
+ CTL_ALL=0x3F,
+ };
+
+ // use a combination of CTL_.. in control_output to specify which
+ CopyPose(unsigned int control_output=CTL_ALL, unsigned int dynamic_output=CTL_NONE, double armlength=1.0, double accuracy=1e-6, unsigned int maximum_iterations=100);
+ virtual ~CopyPose();
+
+ virtual bool setControlParameters(struct ConstraintValues* _values, unsigned int _nvalues, double timestep);
+ virtual const ConstraintValues* getControlParameters(unsigned int* _nvalues);
+
+private:
+ struct ConstraintSingleValue m_posData[3]; // index = controlled output in X,Y,Z order
+ struct ConstraintSingleValue m_rotData[3];
+ struct ConstraintValues m_values[2]; // index = group of controlled output, in position, rotation order
+ Cache* m_cache;
+ int m_poseCCh;
+ CacheTS m_poseCTs;
+ unsigned int m_poseCacheSize;
+ unsigned int m_outputDynamic; // combination of CTL_... determine which variables are dynamically controlled by the application
+ unsigned int m_outputControl; // combination of CTL_... determine which output are constrained
+ unsigned int m_nvalues; // number of elements used in m_values[]
+ double m_maxerror;
+
+ struct ControlState {
+ int firsty; // first y index
+ int ny; // number of y in output
+ double alpha;
+ double K;
+ double tolerance;
+ struct ControlValue {
+ double yddot;
+ double yd;
+ double nextyd;
+ double nextyddot;
+ } output[3]; // inded numbex = same as m_rotData
+ } m_rot, m_pos;
+
+ void pushPose(CacheTS timestamp);
+ bool popPose(CacheTS timestamp);
+ int nBitsOn(unsigned int v)
+ { int n=0; while(v) { if (v&1) n++; v>>=1; } return n; }
+ double* restoreValues(double* item, ConstraintValues* _values, ControlState* _state, unsigned int mask);
+ double* pushValues(double* item, ControlState* _state, unsigned int mask);
+ void updateState(ConstraintValues* _values, ControlState* _state, unsigned int mask, double timestep);
+ void updateValues(Vector& vel, ConstraintValues* _values, ControlState* _state, unsigned int mask);
+ void updateOutput(Vector& vel, ControlState* _state, unsigned int mask);
+ void interpolateOutput(ControlState* _state, unsigned int mask, const Timestamp& timestamp);
+
+};
+}
+#endif /* COPYROTATION_H_ */
diff --git a/intern/itasc/Distance.cpp b/intern/itasc/Distance.cpp
new file mode 100644
index 00000000000..03fa1762567
--- /dev/null
+++ b/intern/itasc/Distance.cpp
@@ -0,0 +1,322 @@
+/* $Id: Distance.cpp 20603 2009-06-03 15:17:52Z ben2610 $
+ * Distance.cpp
+ *
+ * Created on: Jan 30, 2009
+ * Author: rsmits
+ */
+
+#include "Distance.hpp"
+#include "kdl/kinfam_io.hpp"
+#include <math.h>
+#include <malloc.h>
+#include <string.h>
+
+namespace iTaSC
+{
+// a distance constraint is characterized by 5 values: alpha, tolerance, K, yd, yddot
+static const unsigned int distanceCacheSize = sizeof(double)*5 + sizeof(e_scalar)*6;
+
+Distance::Distance(double armlength, double accuracy, unsigned int maximum_iterations):
+ ConstraintSet(1,accuracy,maximum_iterations),
+ m_chiKdl(6),m_jac(6),m_cache(NULL),
+ m_distCCh(-1),m_distCTs(0)
+{
+ m_chain.addSegment(Segment(Joint(Joint::RotZ)));
+ m_chain.addSegment(Segment(Joint(Joint::RotX)));
+ m_chain.addSegment(Segment(Joint(Joint::TransY)));
+ m_chain.addSegment(Segment(Joint(Joint::RotZ)));
+ m_chain.addSegment(Segment(Joint(Joint::RotY)));
+ m_chain.addSegment(Segment(Joint(Joint::RotX)));
+
+ m_fksolver = new KDL::ChainFkSolverPos_recursive(m_chain);
+ m_jacsolver = new KDL::ChainJntToJacSolver(m_chain);
+ m_Cf(0,2)=1.0;
+ m_alpha = 1.0;
+ m_tolerance = 0.05;
+ m_maxerror = armlength/2.0;
+ m_K = 20.0;
+ m_Wy(0) = m_alpha/*/(m_tolerance*m_K)*/;
+ m_yddot = m_nextyddot = 0.0;
+ m_yd = m_nextyd = KDL::epsilon;
+ memset(&m_data, 0, sizeof(m_data));
+ // initialize the data with normally fixed values
+ m_data.id = ID_DISTANCE;
+ m_values.id = ID_DISTANCE;
+ m_values.number = 1;
+ m_values.alpha = m_alpha;
+ m_values.feedback = m_K;
+ m_values.tolerance = m_tolerance;
+ m_values.values = &m_data;
+}
+
+Distance::~Distance()
+{
+ delete m_fksolver;
+ delete m_jacsolver;
+}
+
+bool Distance::computeChi(Frame& pose)
+{
+ double dist, alpha, beta, gamma;
+ dist = pose.p.Norm();
+ Rotation basis;
+ if (dist < KDL::epsilon) {
+ // distance is almost 0, no need for initial rotation
+ m_chi(0) = 0.0;
+ m_chi(1) = 0.0;
+ } else {
+ // find the XZ angles that bring the Y axis to point to init_pose.p
+ Vector axis(pose.p/dist);
+ beta = 0.0;
+ if (fabs(axis(2)) > 1-KDL::epsilon) {
+ // direction is aligned on Z axis, just rotation on X
+ alpha = 0.0;
+ gamma = KDL::sign(axis(2))*KDL::PI/2;
+ } else {
+ alpha = -KDL::atan2(axis(0), axis(1));
+ gamma = KDL::atan2(axis(2), KDL::sqrt(KDL::sqr(axis(0))+KDL::sqr(axis(1))));
+ }
+ // rotation after first 2 joints
+ basis = Rotation::EulerZYX(alpha, beta, gamma);
+ m_chi(0) = alpha;
+ m_chi(1) = gamma;
+ }
+ m_chi(2) = dist;
+ basis = basis.Inverse()*pose.M;
+ basis.GetEulerZYX(alpha, beta, gamma);
+ // alpha = rotation on Z
+ // beta = rotation on Y
+ // gamma = rotation on X in that order
+ // it corresponds to the joint order, so just assign
+ m_chi(3) = alpha;
+ m_chi(4) = beta;
+ m_chi(5) = gamma;
+ return true;
+}
+
+bool Distance::initialise(Frame& init_pose)
+{
+ // we will initialize m_chi to values that match the pose
+ m_externalPose=init_pose;
+ computeChi(m_externalPose);
+ // get current Jf and update internal pose
+ updateJacobian();
+ return true;
+}
+
+bool Distance::closeLoop()
+{
+ if (!Equal(m_internalPose.Inverse()*m_externalPose,F_identity,m_threshold)){
+ computeChi(m_externalPose);
+ updateJacobian();
+ }
+ return true;
+}
+
+void Distance::initCache(Cache *_cache)
+{
+ m_cache = _cache;
+ m_distCCh = -1;
+ if (m_cache) {
+ // create one channel for the coordinates
+ m_distCCh = m_cache->addChannel(this, "Xf", distanceCacheSize);
+ // save initial constraint in cache position 0
+ pushDist(0);
+ }
+}
+
+void Distance::pushDist(CacheTS timestamp)
+{
+ if (m_distCCh >= 0) {
+ double *item = (double*)m_cache->addCacheItem(this, m_distCCh, timestamp, NULL, distanceCacheSize);
+ if (item) {
+ *item++ = m_K;
+ *item++ = m_tolerance;
+ *item++ = m_yd;
+ *item++ = m_yddot;
+ *item++ = m_alpha;
+ memcpy(item, &m_chi[0], 6*sizeof(e_scalar));
+ }
+ m_distCTs = timestamp;
+ }
+}
+
+bool Distance::popDist(CacheTS timestamp)
+{
+ if (m_distCCh >= 0) {
+ double *item = (double*)m_cache->getPreviousCacheItem(this, m_distCCh, &timestamp);
+ if (item && timestamp != m_distCTs) {
+ m_values.feedback = m_K = *item++;
+ m_values.tolerance = m_tolerance = *item++;
+ m_yd = *item++;
+ m_yddot = *item++;
+ m_values.alpha = m_alpha = *item++;
+ memcpy(&m_chi[0], item, 6*sizeof(e_scalar));
+ m_distCTs = timestamp;
+ m_Wy(0) = m_alpha/*/(m_tolerance*m_K)*/;
+ updateJacobian();
+ }
+ return (item) ? true : false;
+ }
+ return true;
+}
+
+void Distance::pushCache(const Timestamp& timestamp)
+{
+ if (!timestamp.substep && timestamp.cache)
+ pushDist(timestamp.cacheTimestamp);
+}
+
+void Distance::updateKinematics(const Timestamp& timestamp)
+{
+ if (timestamp.interpolate) {
+ //the internal pose and Jf is already up to date (see model_update)
+ //update the desired output based on yddot
+ if (timestamp.substep) {
+ m_yd += m_yddot*timestamp.realTimestep;
+ if (m_yd < KDL::epsilon)
+ m_yd = KDL::epsilon;
+ } else {
+ m_yd = m_nextyd;
+ m_yddot = m_nextyddot;
+ }
+ }
+ pushCache(timestamp);
+}
+
+void Distance::updateJacobian()
+{
+ for(unsigned int i=0;i<6;i++)
+ m_chiKdl(i)=m_chi(i);
+
+ m_fksolver->JntToCart(m_chiKdl,m_internalPose);
+ m_jacsolver->JntToJac(m_chiKdl,m_jac);
+ changeRefPoint(m_jac,-m_internalPose.p,m_jac);
+ for(unsigned int i=0;i<6;i++)
+ for(unsigned int j=0;j<6;j++)
+ m_Jf(i,j)=m_jac(i,j);
+}
+
+bool Distance::setControlParameters(struct ConstraintValues* _values, unsigned int _nvalues, double timestep)
+{
+ int action = 0;
+ int i;
+ ConstraintSingleValue* _data;
+
+ while (_nvalues > 0) {
+ if (_values->id == ID_DISTANCE) {
+ if ((_values->action & ACT_ALPHA) && _values->alpha >= 0.0) {
+ m_alpha = _values->alpha;
+ action |= ACT_ALPHA;
+ }
+ if ((_values->action & ACT_TOLERANCE) && _values->tolerance > KDL::epsilon) {
+ m_tolerance = _values->tolerance;
+ action |= ACT_TOLERANCE;
+ }
+ if ((_values->action & ACT_FEEDBACK) && _values->feedback > KDL::epsilon) {
+ m_K = _values->feedback;
+ action |= ACT_FEEDBACK;
+ }
+ for (_data = _values->values, i=0; i<_values->number; i++, _data++) {
+ if (_data->id == ID_DISTANCE) {
+ switch (_data->action & (ACT_VALUE|ACT_VELOCITY)) {
+ case 0:
+ // no indication, keep current values
+ break;
+ case ACT_VELOCITY:
+ // only the velocity is given estimate the new value by integration
+ _data->yd = m_yd+_data->yddot*timestep;
+ // walkthrough for negative value correction
+ case ACT_VALUE:
+ // only the value is given, estimate the velocity from previous value
+ if (_data->yd < KDL::epsilon)
+ _data->yd = KDL::epsilon;
+ m_nextyd = _data->yd;
+ // if the user sets the value, we assume future velocity is zero
+ // (until the user changes the value again)
+ m_nextyddot = (_data->action & ACT_VALUE) ? 0.0 : _data->yddot;
+ if (timestep>0.0) {
+ m_yddot = (_data->yd-m_yd)/timestep;
+ } else {
+ // allow the user to change target instantenously when this function
+ // if called from setControlParameter with timestep = 0
+ m_yddot = m_nextyddot;
+ m_yd = m_nextyd;
+ }
+ break;
+ case (ACT_VALUE|ACT_VELOCITY):
+ // the user should not set the value and velocity at the same time.
+ // In this case, we will assume that he want to set the future value
+ // and we compute the current value to match the velocity
+ if (_data->yd < KDL::epsilon)
+ _data->yd = KDL::epsilon;
+ m_yd = _data->yd - _data->yddot*timestep;
+ if (m_yd < KDL::epsilon)
+ m_yd = KDL::epsilon;
+ m_nextyd = _data->yd;
+ m_nextyddot = _data->yddot;
+ if (timestep>0.0) {
+ m_yddot = (_data->yd-m_yd)/timestep;
+ } else {
+ m_yd = m_nextyd;
+ m_yddot = m_nextyddot;
+ }
+ break;
+ }
+ }
+ }
+ }
+ _nvalues--;
+ _values++;
+ }
+ if (action & (ACT_TOLERANCE|ACT_FEEDBACK|ACT_ALPHA)) {
+ // recompute the weight
+ m_Wy(0) = m_alpha/*/(m_tolerance*m_K)*/;
+ }
+ return true;
+}
+
+const ConstraintValues* Distance::getControlParameters(unsigned int* _nvalues)
+{
+ *(double*)&m_data.y = m_chi(2);
+ *(double*)&m_data.ydot = m_ydot(0);
+ m_data.yd = m_yd;
+ m_data.yddot = m_yddot;
+ m_data.action = 0;
+ m_values.action = 0;
+ if (_nvalues)
+ *_nvalues=1;
+ return &m_values;
+}
+
+void Distance::updateControlOutput(const Timestamp& timestamp)
+{
+ bool cacheAvail = true;
+ if (!timestamp.substep) {
+ if (!timestamp.reiterate)
+ cacheAvail = popDist(timestamp.cacheTimestamp);
+ }
+ if (m_constraintCallback && (m_substep || (!timestamp.reiterate && !timestamp.substep))) {
+ // initialize first callback the application to get the current values
+ *(double*)&m_data.y = m_chi(2);
+ *(double*)&m_data.ydot = m_ydot(0);
+ m_data.yd = m_yd;
+ m_data.yddot = m_yddot;
+ m_data.action = 0;
+ m_values.action = 0;
+ if ((*m_constraintCallback)(timestamp, &m_values, 1, m_constraintParam)) {
+ setControlParameters(&m_values, 1, timestamp.realTimestep);
+ }
+ }
+ if (!cacheAvail || !timestamp.interpolate) {
+ // first position in cache: set the desired output immediately as we cannot interpolate
+ m_yd = m_nextyd;
+ m_yddot = m_nextyddot;
+ }
+ double error = m_yd-m_chi(2);
+ if (KDL::Norm(error) > m_maxerror)
+ error = KDL::sign(error)*m_maxerror;
+ m_ydot(0)=m_yddot+m_K*error;
+}
+
+}
diff --git a/intern/itasc/Distance.hpp b/intern/itasc/Distance.hpp
new file mode 100644
index 00000000000..1366693743e
--- /dev/null
+++ b/intern/itasc/Distance.hpp
@@ -0,0 +1,62 @@
+/* $Id: Distance.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * Distance.hpp
+ *
+ * Created on: Jan 30, 2009
+ * Author: rsmits
+ */
+
+#ifndef DISTANCE_HPP_
+#define DISTANCE_HPP_
+
+#include "ConstraintSet.hpp"
+#include "kdl/chain.hpp"
+#include "kdl/chainfksolverpos_recursive.hpp"
+#include "kdl/chainjnttojacsolver.hpp"
+
+namespace iTaSC
+{
+
+class Distance: public iTaSC::ConstraintSet
+{
+protected:
+ virtual void updateKinematics(const Timestamp& timestamp);
+ virtual void pushCache(const Timestamp& timestamp);
+ virtual void updateJacobian();
+ virtual bool initialise(Frame& init_pose);
+ virtual void initCache(Cache *_cache);
+ virtual void updateControlOutput(const Timestamp& timestamp);
+ virtual bool closeLoop();
+
+public:
+ enum ID {
+ ID_DISTANCE=1,
+ };
+ Distance(double armlength=1.0, double accuracy=1e-6, unsigned int maximum_iterations=100);
+ virtual ~Distance();
+
+ virtual bool setControlParameters(struct ConstraintValues* _values, unsigned int _nvalues, double timestep);
+ virtual const ConstraintValues* getControlParameters(unsigned int* _nvalues);
+
+private:
+ bool computeChi(Frame& pose);
+ KDL::Chain m_chain;
+ KDL::ChainFkSolverPos_recursive* m_fksolver;
+ KDL::ChainJntToJacSolver* m_jacsolver;
+ KDL::JntArray m_chiKdl;
+ KDL::Jacobian m_jac;
+ struct ConstraintSingleValue m_data;
+ struct ConstraintValues m_values;
+ Cache* m_cache;
+ int m_distCCh;
+ CacheTS m_distCTs;
+ double m_maxerror;
+
+ void pushDist(CacheTS timestamp);
+ bool popDist(CacheTS timestamp);
+
+ double m_alpha,m_yddot,m_yd,m_nextyd,m_nextyddot,m_K,m_tolerance;
+};
+
+}
+
+#endif /* DISTANCE_HPP_ */
diff --git a/intern/itasc/FixedObject.cpp b/intern/itasc/FixedObject.cpp
new file mode 100644
index 00000000000..1360c3c152b
--- /dev/null
+++ b/intern/itasc/FixedObject.cpp
@@ -0,0 +1,70 @@
+/* $Id: FixedObject.cpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * FixedObject.cpp
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#include "FixedObject.hpp"
+
+namespace iTaSC{
+
+
+FixedObject::FixedObject():UncontrolledObject(),
+ m_finalized(false), m_nframe(0)
+{
+}
+
+FixedObject::~FixedObject()
+{
+ m_frameArray.clear();
+}
+
+int FixedObject::addFrame(const std::string& name, const Frame& frame)
+{
+ if (m_finalized)
+ return -1;
+ FrameList::iterator it;
+ unsigned int i;
+ for (i=0, it=m_frameArray.begin(); i<m_nframe; i++, it++) {
+ if (it->first == name) {
+ // this frame will replace the old frame
+ it->second = frame;
+ return i;
+ }
+ }
+ m_frameArray.push_back(FrameList::value_type(name,frame));
+ return m_nframe++;
+}
+
+int FixedObject::addEndEffector(const std::string& name)
+{
+ // verify that this frame name exist
+ FrameList::iterator it;
+ unsigned int i;
+ for (i=0, it=m_frameArray.begin(); i<m_nframe; i++, it++) {
+ if (it->first == name) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+void FixedObject::finalize()
+{
+ if (m_finalized)
+ return;
+ initialize(0, m_nframe);
+ m_finalized = true;
+}
+
+const Frame& FixedObject::getPose(const unsigned int frameIndex)
+{
+ if (frameIndex < m_nframe) {
+ return m_frameArray[frameIndex].second;
+ } else {
+ return F_identity;
+ }
+}
+
+}
diff --git a/intern/itasc/FixedObject.hpp b/intern/itasc/FixedObject.hpp
new file mode 100644
index 00000000000..01ab3355259
--- /dev/null
+++ b/intern/itasc/FixedObject.hpp
@@ -0,0 +1,45 @@
+/* $Id: FixedObject.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * FixedObject.h
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#ifndef FIXEDOBJECT_HPP_
+#define FIXEDOBJECT_HPP_
+
+#include "UncontrolledObject.hpp"
+#include <vector>
+
+
+namespace iTaSC{
+
+class FixedObject: public UncontrolledObject {
+public:
+ FixedObject();
+ virtual ~FixedObject();
+
+ int addFrame(const std::string& name, const Frame& frame);
+
+ virtual void updateCoordinates(const Timestamp& timestamp) {};
+ virtual int addEndEffector(const std::string& name);
+ virtual void finalize();
+ virtual const Frame& getPose(const unsigned int frameIndex);
+ virtual void updateKinematics(const Timestamp& timestamp) {};
+ virtual void pushCache(const Timestamp& timestamp) {};
+ virtual void initCache(Cache *_cache) {};
+
+protected:
+ virtual void updateJacobian() {}
+private:
+ typedef std::vector<std::pair<std::string, Frame> > FrameList;
+
+ bool m_finalized;
+ unsigned int m_nframe;
+ FrameList m_frameArray;
+
+};
+
+}
+
+#endif /* FIXEDOBJECT_H_ */
diff --git a/intern/itasc/Makefile b/intern/itasc/Makefile
new file mode 100644
index 00000000000..463f7763cd2
--- /dev/null
+++ b/intern/itasc/Makefile
@@ -0,0 +1,53 @@
+#
+# $Id: Makefile 19907 2009-04-23 13:41:59Z ben2610 $
+#
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Hans Lambermont
+#
+# ***** END GPL LICENSE BLOCK *****
+# iksolver main makefile.
+#
+
+
+LIBNAME = itasc
+DIR = $(OCGDIR)/intern/$(SOURCEDIR)
+
+include nan_compile.mk
+
+CPPFLAGS += -I.
+CPPFLAGS += -I../../extern/Eigen2
+
+install: all debug
+ @[ -d $(NAN_ITASC) ] || mkdir $(NAN_ITASC)
+ @[ -d $(NAN_ITASC)/lib ] || mkdir $(NAN_ITASC)/lib
+ @[ -d $(NAN_ITASC)/lib/debug ] || mkdir $(NAN_ITASC)/lib/debug
+ @../tools/cpifdiff.sh $(DIR)/libitasc.a $(NAN_ITASC)/lib/
+ @../tools/cpifdiff.sh $(DIR)/debug/libitasc.a $(NAN_ITASC)/lib/debug/
+ifeq ($(OS),darwin)
+ ranlib $(NAN_ITASC)/lib/libitasc.a
+ ranlib $(NAN_ITASC)/lib/debug/libitasc.a
+endif
+##############################
+DIRS = kdl
+SOURCEDIR = intern/$(LIBNAME)
+include nan_subdirs.mk
diff --git a/intern/itasc/MovingFrame.cpp b/intern/itasc/MovingFrame.cpp
new file mode 100644
index 00000000000..545f9bd38e9
--- /dev/null
+++ b/intern/itasc/MovingFrame.cpp
@@ -0,0 +1,157 @@
+/* $Id: MovingFrame.cpp 20853 2009-06-13 12:29:46Z ben2610 $
+ * MovingFrame.cpp
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#include "MovingFrame.hpp"
+#include <malloc.h>
+#include <string.h>
+namespace iTaSC{
+
+static const unsigned int frameCacheSize = (sizeof(((Frame*)0)->p.data)+sizeof(((Frame*)0)->M.data))/sizeof(double);
+
+MovingFrame::MovingFrame(const Frame& frame):UncontrolledObject(),
+ m_function(NULL), m_param(NULL), m_velocity(), m_poseCCh(-1), m_poseCTs(0)
+{
+ m_internalPose = m_nextPose = frame;
+ initialize(6, 1);
+ e_matrix& Ju = m_JuArray[0];
+ Ju = e_identity_matrix(6,6);
+}
+
+MovingFrame::~MovingFrame()
+{
+}
+
+void MovingFrame::finalize()
+{
+ updateJacobian();
+}
+
+void MovingFrame::initCache(Cache *_cache)
+{
+ m_cache = _cache;
+ m_poseCCh = -1;
+ if (m_cache) {
+ m_poseCCh = m_cache->addChannel(this,"pose",frameCacheSize*sizeof(double));
+ // don't store the initial pose, it's causing unnecessary large velocity on the first step
+ //pushInternalFrame(0);
+ }
+}
+
+void MovingFrame::pushInternalFrame(CacheTS timestamp)
+{
+ if (m_poseCCh >= 0) {
+ double buf[frameCacheSize];
+ memcpy(buf, m_internalPose.p.data, sizeof(m_internalPose.p.data));
+ memcpy(&buf[sizeof(m_internalPose.p.data)/sizeof(double)], m_internalPose.M.data, sizeof(m_internalPose.M.data));
+
+ m_cache->addCacheVectorIfDifferent(this, m_poseCCh, timestamp, buf, frameCacheSize, KDL::epsilon);
+ m_poseCTs = timestamp;
+ }
+}
+
+// load pose just preceeding timestamp
+// return false if no cache position was found
+bool MovingFrame::popInternalFrame(CacheTS timestamp)
+{
+ if (m_poseCCh >= 0) {
+ char *item;
+ item = (char *)m_cache->getPreviousCacheItem(this, m_poseCCh, &timestamp);
+ if (item && m_poseCTs != timestamp) {
+ memcpy(m_internalPose.p.data, item, sizeof(m_internalPose.p.data));
+ item += sizeof(m_internalPose.p.data);
+ memcpy(m_internalPose.M.data, item, sizeof(m_internalPose.M.data));
+ m_poseCTs = timestamp;
+ // changing the starting pose, recompute the jacobian
+ updateJacobian();
+ }
+ return (item) ? true : false;
+ }
+ // in case of no cache, there is always a previous position
+ return true;
+}
+
+bool MovingFrame::setFrame(const Frame& frame)
+{
+ m_internalPose = m_nextPose = frame;
+ return true;
+}
+
+bool MovingFrame::setCallback(MovingFrameCallback _function, void* _param)
+{
+ m_function = _function;
+ m_param = _param;
+ return true;
+}
+
+void MovingFrame::updateCoordinates(const Timestamp& timestamp)
+{
+ // don't compute the velocity during substepping, it is assumed constant.
+ if (!timestamp.substep) {
+ bool cacheAvail = true;
+ if (!timestamp.reiterate) {
+ cacheAvail = popInternalFrame(timestamp.cacheTimestamp);
+ if (m_function)
+ (*m_function)(timestamp, m_internalPose, m_nextPose, m_param);
+ }
+ // only compute velocity if we have a previous pose
+ if (cacheAvail && timestamp.interpolate) {
+ unsigned int iXu;
+ m_velocity = diff(m_internalPose, m_nextPose, timestamp.realTimestep);
+ for (iXu=0; iXu<6; iXu++)
+ m_xudot(iXu) = m_velocity(iXu);
+ } else if (!timestamp.reiterate) {
+ // new position is forced, no velocity as we cannot interpolate
+ m_internalPose = m_nextPose;
+ m_velocity = Twist::Zero();
+ m_xudot = e_zero_vector(6);
+ // recompute the jacobian
+ updateJacobian();
+ }
+ }
+}
+
+void MovingFrame::pushCache(const Timestamp& timestamp)
+{
+ if (!timestamp.substep && timestamp.cache)
+ pushInternalFrame(timestamp.cacheTimestamp);
+}
+
+void MovingFrame::updateKinematics(const Timestamp& timestamp)
+{
+ if (timestamp.interpolate) {
+ if (timestamp.substep) {
+ // during substepping, update the internal pose from velocity information
+ Twist localvel = m_internalPose.M.Inverse(m_velocity);
+ m_internalPose.Integrate(localvel, 1.0/timestamp.realTimestep);
+ } else {
+ m_internalPose = m_nextPose;
+ }
+ // m_internalPose is updated, recompute the jacobian
+ updateJacobian();
+ }
+ pushCache(timestamp);
+}
+
+void MovingFrame::updateJacobian()
+{
+ Twist m_jac;
+ e_matrix& Ju = m_JuArray[0];
+
+ //Jacobian is always identity at position on the object,
+ //we ust change the reference to the world.
+ //instead of going through complicated jacobian operation, implemented direct formula
+ Ju(1,3) = m_internalPose.p.z();
+ Ju(2,3) = -m_internalPose.p.y();
+ Ju(0,4) = -m_internalPose.p.z();
+ Ju(2,4) = m_internalPose.p.x();
+ Ju(0,5) = m_internalPose.p.y();
+ Ju(1,5) = -m_internalPose.p.x();
+ // remember that this object has moved
+ m_updated = true;
+}
+
+}
diff --git a/intern/itasc/MovingFrame.hpp b/intern/itasc/MovingFrame.hpp
new file mode 100644
index 00000000000..edaa3136a13
--- /dev/null
+++ b/intern/itasc/MovingFrame.hpp
@@ -0,0 +1,48 @@
+/* $Id: MovingFrame.hpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * MovingFrame.h
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#ifndef MOVINGFRAME_HPP_
+#define MOVINGFRAME_HPP_
+
+#include "UncontrolledObject.hpp"
+#include <vector>
+
+
+namespace iTaSC{
+
+typedef bool (*MovingFrameCallback)(const Timestamp& timestamp, const Frame& _current, Frame& _next, void *param);
+
+class MovingFrame: public UncontrolledObject {
+public:
+ MovingFrame(const Frame& frame=F_identity);
+ virtual ~MovingFrame();
+
+ bool setFrame(const Frame& frame);
+ bool setCallback(MovingFrameCallback _function, void* _param);
+
+ virtual void updateCoordinates(const Timestamp& timestamp);
+ virtual void updateKinematics(const Timestamp& timestamp);
+ virtual void pushCache(const Timestamp& timestamp);
+ virtual void initCache(Cache *_cache);
+ virtual void finalize();
+protected:
+ virtual void updateJacobian();
+
+private:
+ void pushInternalFrame(CacheTS timestamp);
+ bool popInternalFrame(CacheTS timestamp);
+ MovingFrameCallback m_function;
+ void* m_param;
+ Frame m_nextPose;
+ Twist m_velocity;
+ int m_poseCCh; // cache channel for pose
+ unsigned int m_poseCTs;
+};
+
+}
+
+#endif /* MOVINGFRAME_H_ */
diff --git a/intern/itasc/Object.hpp b/intern/itasc/Object.hpp
new file mode 100644
index 00000000000..5c312cab768
--- /dev/null
+++ b/intern/itasc/Object.hpp
@@ -0,0 +1,48 @@
+/* $Id: Object.hpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * Object.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef OBJECT_HPP_
+#define OBJECT_HPP_
+
+#include "Cache.hpp"
+#include "kdl/frames.hpp"
+#include <string>
+
+namespace iTaSC{
+
+class WorldObject;
+
+class Object {
+public:
+ enum ObjectType {Controlled, UnControlled};
+ static WorldObject world;
+
+private:
+ ObjectType m_type;
+protected:
+ Cache *m_cache;
+ KDL::Frame m_internalPose;
+ bool m_updated;
+ virtual void updateJacobian()=0;
+public:
+ Object(ObjectType _type):m_type(_type), m_cache(NULL), m_internalPose(F_identity), m_updated(false) {};
+ virtual ~Object(){};
+
+ virtual int addEndEffector(const std::string& name){return 0;};
+ virtual void finalize(){};
+ virtual const KDL::Frame& getPose(const unsigned int end_effector=0){return m_internalPose;};
+ virtual const ObjectType getType(){return m_type;};
+ virtual const unsigned int getNrOfCoordinates(){return 0;};
+ virtual void updateKinematics(const Timestamp& timestamp)=0;
+ virtual void pushCache(const Timestamp& timestamp)=0;
+ virtual void initCache(Cache *_cache) = 0;
+ bool updated() {return m_updated;};
+ void updated(bool val) {m_updated=val;};
+};
+
+}
+#endif /* OBJECT_HPP_ */
diff --git a/intern/itasc/SConscript b/intern/itasc/SConscript
new file mode 100644
index 00000000000..9e11b6c7119
--- /dev/null
+++ b/intern/itasc/SConscript
@@ -0,0 +1,11 @@
+#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('*.cpp')
+sources += env.Glob('kdl/*.cpp')
+sources += env.Glob('kdl/utilities/*.cpp')
+
+incs = '. ../../extern/Eigen2'
+
+env.BlenderLib ('bf_ITASC', sources, Split(incs), [], libtype=['intern','player'], priority=[20,100] )
+
diff --git a/intern/itasc/Scene.cpp b/intern/itasc/Scene.cpp
new file mode 100644
index 00000000000..c50769e9c1d
--- /dev/null
+++ b/intern/itasc/Scene.cpp
@@ -0,0 +1,543 @@
+/* $Id: Scene.cpp 20874 2009-06-14 13:50:34Z ben2610 $
+ * Scene.cpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#include "Scene.hpp"
+#include "ControlledObject.hpp"
+#include "kdl/utilities/svd_eigen_HH.hpp"
+#include <cstdio>
+
+namespace iTaSC {
+
+class SceneLock : public ControlledObject::JointLockCallback {
+private:
+ Scene* m_scene;
+ Range m_qrange;
+
+public:
+ SceneLock(Scene* scene) :
+ m_scene(scene), m_qrange(0,0) {}
+ virtual ~SceneLock() {}
+
+ void setRange(Range& range)
+ {
+ m_qrange = range;
+ }
+ // lock a joint, no need to update output
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof)
+ {
+ q_nr += m_qrange.start;
+ project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
+ }
+ // lock a joint and update output in view of reiteration
+ virtual void lockJoint(unsigned int q_nr, unsigned int ndof, double* qdot)
+ {
+ q_nr += m_qrange.start;
+ project(m_scene->m_Wq, Range(q_nr, ndof), m_qrange).setZero();
+ // update the ouput vector so that the movement of this joint will be
+ // taken into account and we can put the joint back in its initial position
+ // which means that the jacobian doesn't need to be changed
+ for (unsigned int i=0 ;i<ndof ; ++i, ++q_nr) {
+ m_scene->m_ydot -= m_scene->m_A.col(q_nr)*qdot[i];
+ }
+ }
+};
+
+Scene::Scene():
+ m_A(), m_B(), m_Atemp(), m_Wq(), m_Jf(), m_Jq(), m_Ju(), m_Cf(), m_Cq(), m_Jf_inv(),
+ m_Vf(),m_Uf(), m_Wy(), m_ydot(), m_qdot(), m_xdot(), m_Sf(),m_tempf(),
+ m_ncTotal(0),m_nqTotal(0),m_nuTotal(0),m_nsets(0),
+ m_solver(NULL),m_cache(NULL)
+{
+ m_minstep = 0.01;
+ m_maxstep = 0.06;
+}
+
+Scene::~Scene()
+{
+ ConstraintMap::iterator constraint_it;
+ while ((constraint_it = constraints.begin()) != constraints.end()) {
+ delete constraint_it->second;
+ constraints.erase(constraint_it);
+ }
+ ObjectMap::iterator object_it;
+ while ((object_it = objects.begin()) != objects.end()) {
+ delete object_it->second;
+ objects.erase(object_it);
+ }
+}
+
+bool Scene::setParam(SceneParam paramId, double value)
+{
+ switch (paramId) {
+ case MIN_TIMESTEP:
+ m_minstep = value;
+ break;
+ case MAX_TIMESTEP:
+ m_maxstep = value;
+ break;
+ default:
+ return false;
+ }
+ return true;
+}
+
+bool Scene::addObject(const std::string& name, Object* object, UncontrolledObject* base, const std::string& baseFrame)
+{
+ // finalize the object before adding
+ object->finalize();
+ //Check if Object is controlled or uncontrolled.
+ if(object->getType()==Object::Controlled){
+ int baseFrameIndex = base->addEndEffector(baseFrame);
+ if (baseFrameIndex < 0)
+ return false;
+ std::pair<ObjectMap::iterator, bool> result;
+ if (base->getNrOfCoordinates() == 0) {
+ // base is fixed object, no coordinate range
+ result = objects.insert(ObjectMap::value_type(
+ name, new Object_struct(object,base,baseFrameIndex,
+ Range(m_nqTotal,object->getNrOfCoordinates()),
+ Range(m_ncTotal,((ControlledObject*)object)->getNrOfConstraints()),
+ Range(0,0))));
+ } else {
+ // base is a moving object, must be in list already
+ ObjectMap::iterator base_it;
+ for (base_it=objects.begin(); base_it != objects.end(); base_it++) {
+ if (base_it->second->object == base)
+ break;
+ }
+ if (base_it == objects.end())
+ return false;
+ result = objects.insert(ObjectMap::value_type(
+ name, new Object_struct(object,base,baseFrameIndex,
+ Range(m_nqTotal,object->getNrOfCoordinates()),
+ Range(m_ncTotal,((ControlledObject*)object)->getNrOfConstraints()),
+ base_it->second->coordinaterange)));
+ }
+ if (!result.second) {
+ return false;
+ }
+ m_nqTotal+=object->getNrOfCoordinates();
+ m_ncTotal+=((ControlledObject*)object)->getNrOfConstraints();
+ return true;
+ }
+ if(object->getType()==Object::UnControlled){
+ if ((WorldObject*)base != &Object::world)
+ return false;
+ std::pair<ObjectMap::iterator,bool> result = objects.insert(ObjectMap::value_type(
+ name,new Object_struct(object,base,0,
+ Range(0,0),
+ Range(0,0),
+ Range(m_nuTotal,object->getNrOfCoordinates()))));
+ if(!result.second)
+ return false;
+ m_nuTotal+=object->getNrOfCoordinates();
+ return true;
+ }
+ return false;
+}
+
+bool Scene::addConstraintSet(const std::string& name,ConstraintSet* task,const std::string& object1,const std::string& object2, const std::string& ee1, const std::string& ee2)
+{
+ //Check if objects exist:
+ ObjectMap::iterator object1_it = objects.find(object1);
+ ObjectMap::iterator object2_it = objects.find(object2);
+ if(object1_it==objects.end()||object2_it==objects.end())
+ return false;
+ int ee1_index = object1_it->second->object->addEndEffector(ee1);
+ int ee2_index = object2_it->second->object->addEndEffector(ee2);
+ if (ee1_index < 0 || ee2_index < 0)
+ return false;
+ std::pair<ConstraintMap::iterator,bool> result =
+ constraints.insert(ConstraintMap::value_type(name,new ConstraintSet_struct(
+ task,object1_it,ee1_index,object2_it,ee2_index,
+ Range(m_ncTotal,task->getNrOfConstraints()),Range(6*m_nsets,6))));
+ if(!result.second)
+ return false;
+ m_ncTotal+=task->getNrOfConstraints();
+ m_nsets+=1;
+ return true;
+}
+
+bool Scene::addSolver(Solver* _solver){
+ if(m_solver==NULL){
+ m_solver=_solver;
+ return true;
+ }
+ else
+ return false;
+}
+
+bool Scene::addCache(Cache* _cache){
+ if(m_cache==NULL){
+ m_cache=_cache;
+ return true;
+ }
+ else
+ return false;
+}
+
+bool Scene::initialize(){
+
+ //prepare all matrices:
+ if (m_ncTotal == 0 || m_nqTotal == 0 || m_nsets == 0)
+ return false;
+
+ m_A = e_zero_matrix(m_ncTotal,m_nqTotal);
+ if (m_nuTotal > 0) {
+ m_B = e_zero_matrix(m_ncTotal,m_nuTotal);
+ m_xdot = e_zero_vector(m_nuTotal);
+ m_Ju = e_zero_matrix(6*m_nsets,m_nuTotal);
+ }
+ m_Atemp = e_zero_matrix(m_ncTotal,6*m_nsets);
+ m_ydot = e_zero_vector(m_ncTotal);
+ m_qdot = e_zero_vector(m_nqTotal);
+ m_Wq = e_zero_matrix(m_nqTotal,m_nqTotal);
+ m_Wy = e_zero_vector(m_ncTotal);
+ m_Jq = e_zero_matrix(6*m_nsets,m_nqTotal);
+ m_Jf = e_zero_matrix(6*m_nsets,6*m_nsets);
+ m_Jf_inv = m_Jf;
+ m_Cf = e_zero_matrix(m_ncTotal,m_Jf.rows());
+ m_Cq = e_zero_matrix(m_ncTotal,m_nqTotal);
+
+ bool result=true;
+ // finalize all objects
+ for (ObjectMap::iterator it=objects.begin(); it!=objects.end(); ++it) {
+ Object_struct* os = it->second;
+
+ os->object->initCache(m_cache);
+ if (os->constraintrange.count > 0)
+ project(m_Cq,os->constraintrange,os->jointrange) = (((ControlledObject*)(os->object))->getCq());
+ }
+
+ m_ytask.resize(m_ncTotal);
+ bool toggle=true;
+ int cnt = 0;
+ //Initialize all ConstraintSets:
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ //Calculate the external pose:
+ ConstraintSet_struct* cs = it->second;
+ Frame external_pose;
+ getConstraintPose(cs->task, cs, external_pose);
+ result&=cs->task->initialise(external_pose);
+ cs->task->initCache(m_cache);
+ for (int i=0; i<cs->constraintrange.count; i++, cnt++) {
+ m_ytask[cnt] = toggle;
+ }
+ toggle = !toggle;
+ project(m_Cf,cs->constraintrange,cs->featurerange)=cs->task->getCf();
+ }
+
+ if(m_solver!=NULL)
+ m_solver->init(m_nqTotal,m_ncTotal,m_ytask);
+ else
+ return false;
+
+
+ return result;
+}
+
+bool Scene::getConstraintPose(ConstraintSet* constraint, void *_param, KDL::Frame& _pose)
+{
+ // function called from constraint when they need to get the external pose
+ ConstraintSet_struct* cs = (ConstraintSet_struct*)_param;
+ // verification, the pointer MUST match
+ assert (constraint == cs->task);
+ Object_struct* ob1 = cs->object1->second;
+ Object_struct* ob2 = cs->object2->second;
+ //Calculate the external pose:
+ _pose=(ob1->base->getPose(ob1->baseFrameIndex)*ob1->object->getPose(cs->ee1index)).Inverse()*(ob2->base->getPose(ob2->baseFrameIndex)*ob2->object->getPose(cs->ee2index));
+ return true;
+}
+
+bool Scene::update(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)
+ return false;
+ Timestamp ts;
+ ts.realTimestamp = timestamp;
+ // initially we start with the full timestep to allow velocity estimation over the full interval
+ ts.realTimestep = timestep;
+ setCacheTimestamp(ts);
+ ts.substep = 0;
+ // for reiteration don't load cache
+ // reiteration=additional iteration with same timestamp if application finds the convergence not good enough
+ ts.reiterate = (reiterate) ? 1 : 0;
+ ts.interpolate = (interpolate) ? 1 : 0;
+ ts.cache = (cache) ? 1 : 0;
+ ts.update = 1;
+ ts.numstep = (numsubstep & 0xFF);
+ bool autosubstep = (numsubstep == 0) ? true : false;
+ if (numsubstep < 1)
+ numsubstep = 1;
+ double timesubstep = timestep/numsubstep;
+ double timeleft = timestep;
+
+ if (timeleft == 0.0) {
+ // this special case correspond to a request to cache data
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it){
+ it->second->object->pushCache(ts);
+ }
+ //Update the Constraints
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ it->second->task->pushCache(ts);
+ }
+ return true;
+ }
+
+ double maxqdot;
+ e_scalar nlcoef;
+ SceneLock lockCallback(this);
+ Frame external_pose;
+ bool locked;
+
+ // initially we keep timestep unchanged so that update function compute the velocity over
+ while (numsubstep > 0) {
+ // get objects
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it) {
+ Object_struct* os = it->second;
+ if (os->object->getType()==Object::Controlled) {
+ ((ControlledObject*)(os->object))->updateControlOutput(ts);
+ if (os->constraintrange.count > 0) {
+ project(m_ydot, os->constraintrange) = ((ControlledObject*)(os->object))->getControlOutput();
+ project(m_Wy, os->constraintrange) = ((ControlledObject*)(os->object))->getWy();
+ // project(m_Cq,os->constraintrange,os->jointrange) = (((ControlledObject*)(os->object))->getCq());
+ }
+ if (os->jointrange.count > 0) {
+ project(m_Wq,os->jointrange,os->jointrange) = ((ControlledObject*)(os->object))->getWq();
+ }
+ }
+ if (os->object->getType()==Object::UnControlled && ((UncontrolledObject*)os->object)->getNrOfCoordinates() != 0) {
+ ((UncontrolledObject*)(os->object))->updateCoordinates(ts);
+ if (!ts.substep) {
+ // velocity of uncontrolled object remains constant during substepping
+ project(m_xdot,os->coordinaterange) = ((UncontrolledObject*)(os->object))->getXudot();
+ }
+ }
+ }
+
+ //get new Constraints values
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it) {
+ ConstraintSet_struct* cs = it->second;
+ Object_struct* ob1 = cs->object1->second;
+ Object_struct* ob2 = cs->object2->second;
+
+ if (ob1->base->updated() || ob1->object->updated() || ob2->base->updated() || ob2->object->updated()) {
+ // the object from which the constraint depends have changed position
+ // recompute the constraint pose
+ getConstraintPose(cs->task, cs, external_pose);
+ cs->task->initialise(external_pose);
+ }
+ cs->task->updateControlOutput(ts);
+ project(m_ydot,cs->constraintrange)=cs->task->getControlOutput();
+ if (!ts.substep || cs->task->substep()) {
+ project(m_Wy,cs->constraintrange)=(cs->task)->getWy();
+ //project(m_Cf,cs->constraintrange,cs->featurerange)=cs->task->getCf();
+ }
+
+ project(m_Jf,cs->featurerange,cs->featurerange)=cs->task->getJf();
+ //std::cout << "Jf = " << Jf << std::endl;
+ //Transform the reference frame of this jacobian to the world reference frame
+ Eigen::Block<e_matrix> Jf_part = project(m_Jf,cs->featurerange,cs->featurerange);
+ changeBase(Jf_part,ob1->base->getPose(ob1->baseFrameIndex)*ob1->object->getPose(cs->ee1index));
+ //std::cout << "Jf_w = " << Jf << std::endl;
+
+ //calculate the inverse of Jf
+ KDL::svd_eigen_HH(project(m_Jf,cs->featurerange,cs->featurerange),m_Uf,m_Sf,m_Vf,m_tempf);
+ for(unsigned int i=0;i<6;++i)
+ if(m_Sf(i)<KDL::epsilon)
+ m_Uf.col(i).setConstant(0.0);
+ else
+ m_Uf.col(i)*=(1/m_Sf(i));
+ project(m_Jf_inv,cs->featurerange,cs->featurerange)=(m_Vf*m_Uf.transpose()).lazy();
+
+ //Get the robotjacobian associated with this constraintset
+ //Each jacobian is expressed in robot base frame => convert to world reference
+ //and negate second robot because it is taken reversed when closing the loop:
+ if(ob1->object->getType()==Object::Controlled){
+ project(m_Jq,cs->featurerange,ob1->jointrange) = (((ControlledObject*)(ob1->object))->getJq(cs->ee1index));
+ //Transform the reference frame of this jacobian to the world reference frame:
+ Eigen::Block<e_matrix> Jq_part = project(m_Jq,cs->featurerange,ob1->jointrange);
+ changeBase(Jq_part,ob1->base->getPose(ob1->baseFrameIndex));
+ // if the base of this object is moving, get the Ju part
+ if (ob1->base->getNrOfCoordinates() != 0) {
+ // Ju is already computed for world reference frame
+ project(m_Ju,cs->featurerange,ob1->coordinaterange)=ob1->base->getJu(ob1->baseFrameIndex);
+ }
+ } else if (ob1->object->getType() == Object::UnControlled && ((UncontrolledObject*)ob1->object)->getNrOfCoordinates() != 0) {
+ // object1 is uncontrolled moving object
+ project(m_Ju,cs->featurerange,ob1->coordinaterange)=((UncontrolledObject*)ob1->object)->getJu(cs->ee1index);
+ }
+ if(ob2->object->getType()==Object::Controlled){
+ //Get the robotjacobian associated with this constraintset
+ // process a special case where object2 and object1 are equal but using different end effector
+ if (ob1->object == ob2->object) {
+ // we must create a temporary matrix
+ e_matrix JqTemp(((ControlledObject*)(ob2->object))->getJq(cs->ee2index));
+ //Transform the reference frame of this jacobian to the world reference frame:
+ changeBase(JqTemp,ob2->base->getPose(ob2->baseFrameIndex));
+ // substract in place
+ project(m_Jq,cs->featurerange,ob2->jointrange) -= JqTemp;
+ } else {
+ project(m_Jq,cs->featurerange,ob2->jointrange) = -(((ControlledObject*)(ob2->object))->getJq(cs->ee2index));
+ //Transform the reference frame of this jacobian to the world reference frame:
+ Eigen::Block<e_matrix> Jq_part = project(m_Jq,cs->featurerange,ob2->jointrange);
+ changeBase(Jq_part,ob2->base->getPose(ob2->baseFrameIndex));
+ }
+ if (ob2->base->getNrOfCoordinates() != 0) {
+ // if base is the same as first object or first object base,
+ // that portion of m_Ju has been set already => substract inplace
+ if (ob2->base == ob1->base || ob2->base == ob1->object) {
+ project(m_Ju,cs->featurerange,ob2->coordinaterange) -= ob2->base->getJu(ob2->baseFrameIndex);
+ } else {
+ project(m_Ju,cs->featurerange,ob2->coordinaterange) = -ob2->base->getJu(ob2->baseFrameIndex);
+ }
+ }
+ } else if (ob2->object->getType() == Object::UnControlled && ((UncontrolledObject*)ob2->object)->getNrOfCoordinates() != 0) {
+ if (ob2->object == ob1->base || ob2->object == ob1->object) {
+ project(m_Ju,cs->featurerange,ob2->coordinaterange) -= ((UncontrolledObject*)ob2->object)->getJu(cs->ee2index);
+ } else {
+ project(m_Ju,cs->featurerange,ob2->coordinaterange) = -((UncontrolledObject*)ob2->object)->getJu(cs->ee2index);
+ }
+ }
+ }
+
+ //Calculate A
+ m_Atemp=(m_Cf*m_Jf_inv).lazy();
+ m_A = m_Cq-(m_Atemp*m_Jq).lazy();
+ if (m_nuTotal > 0) {
+ m_B=(m_Atemp*m_Ju).lazy();
+ m_ydot += (m_B*m_xdot).lazy();
+ }
+
+ //Call the solver with A, Wq, Wy, ydot to solver qdot:
+ if(!m_solver->solve(m_A,m_Wy,m_ydot,m_Wq,m_qdot,nlcoef))
+ // this should never happen
+ return false;
+ //send result to the objects
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it) {
+ Object_struct* os = it->second;
+ if(os->object->getType()==Object::Controlled)
+ ((ControlledObject*)(os->object))->setJointVelocity(project(m_qdot,os->jointrange));
+ }
+ // compute the constraint velocity
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ ConstraintSet_struct* cs = it->second;
+ Object_struct* ob1 = cs->object1->second;
+ Object_struct* ob2 = cs->object2->second;
+ //Calculate the twist of the world reference frame due to the robots (Jq*qdot+Ju*chiudot):
+ e_vector6 external_vel = e_zero_vector(6);
+ if (ob1->jointrange.count > 0)
+ external_vel += (project(m_Jq,cs->featurerange,ob1->jointrange)*project(m_qdot,ob1->jointrange)).lazy();
+ if (ob2->jointrange.count > 0)
+ external_vel += (project(m_Jq,cs->featurerange,ob2->jointrange)*project(m_qdot,ob2->jointrange)).lazy();
+ if (ob1->coordinaterange.count > 0)
+ external_vel += (project(m_Ju,cs->featurerange,ob1->coordinaterange)*project(m_xdot,ob1->coordinaterange)).lazy();
+ if (ob2->coordinaterange.count > 0)
+ external_vel += (project(m_Ju,cs->featurerange,ob2->coordinaterange)*project(m_xdot,ob2->coordinaterange)).lazy();
+ //the twist caused by the constraint must be opposite because of the closed loop
+ //estimate the velocity of the joints using the inverse jacobian
+ e_vector6 estimated_chidot = project(m_Jf_inv,cs->featurerange,cs->featurerange)*(-external_vel);
+ cs->task->setJointVelocity(estimated_chidot);
+ }
+
+ if (autosubstep) {
+ // automatic computing of substep based on maximum joint change
+ // and joint limit gain variation
+ // We will pass the joint velocity to each object and they will recommend a maximum timestep
+ timesubstep = timeleft;
+ // get armature max joint velocity to estimate the maximum duration of integration
+ maxqdot = m_qdot.cwise().abs().maxCoeff();
+ double maxsubstep = nlcoef*m_maxstep;
+ if (maxsubstep < m_minstep)
+ maxsubstep = m_minstep;
+ if (timesubstep > maxsubstep)
+ timesubstep = maxsubstep;
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it){
+ Object_struct* os = it->second;
+ if(os->object->getType()==Object::Controlled)
+ ((ControlledObject*)(os->object))->getMaxTimestep(timesubstep);
+ }
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ ConstraintSet_struct* cs = it->second;
+ cs->task->getMaxTimestep(timesubstep);
+ }
+ // use substep that are even dividers of timestep for more regularity
+ maxsubstep = 2.0*floor(timestep/2.0/timesubstep-0.66666);
+ timesubstep = (maxsubstep < 0.0) ? timestep : timestep/(2.0+maxsubstep);
+ if (timesubstep >= timeleft-(m_minstep/2.0)) {
+ timesubstep = timeleft;
+ numsubstep = 1;
+ timeleft = 0.;
+ } else {
+ numsubstep = 2;
+ timeleft -= timesubstep;
+ }
+ }
+ if (numsubstep > 1) {
+ ts.substep = 1;
+ } else {
+ // set substep to false for last iteration so that controlled output
+ // can be updated in updateKinematics() and model_update)() before next call to Secne::update()
+ ts.substep = 0;
+ }
+ // change timestep so that integration is done correctly
+ ts.realTimestep = timesubstep;
+
+ do {
+ ObjectMap::iterator it;
+ Object_struct* os;
+ locked = false;
+ for(it=objects.begin();it!=objects.end();++it){
+ os = it->second;
+ if (os->object->getType()==Object::Controlled) {
+ lockCallback.setRange(os->jointrange);
+ if (((ControlledObject*)os->object)->updateJoint(ts, lockCallback)) {
+ // this means one of the joint was locked and we must rerun
+ // the solver to update the remaining joints
+ locked = true;
+ break;
+ }
+ }
+ }
+ if (locked) {
+ // Some rows of m_Wq have been cleared so that the corresponding joint will not move
+ if(!m_solver->solve(m_A,m_Wy,m_ydot,m_Wq,m_qdot,nlcoef))
+ // this should never happen
+ return false;
+
+ //send result to the objects
+ for(it=objects.begin();it!=objects.end();++it) {
+ os = it->second;
+ if(os->object->getType()==Object::Controlled)
+ ((ControlledObject*)(os->object))->setJointVelocity(project(m_qdot,os->jointrange));
+ }
+ }
+ } while (locked);
+
+ //Update the Objects
+ for(ObjectMap::iterator it=objects.begin();it!=objects.end();++it){
+ it->second->object->updateKinematics(ts);
+ // mark this object not updated since the constraint will be updated anyway
+ // this flag is only useful to detect external updates
+ it->second->object->updated(false);
+ }
+ //Update the Constraints
+ for(ConstraintMap::iterator it=constraints.begin();it!=constraints.end();++it){
+ ConstraintSet_struct* cs = it->second;
+ //Calculate the external pose:
+ getConstraintPose(cs->task, cs, external_pose);
+ cs->task->modelUpdate(external_pose,ts);
+ // update the constraint output and cache
+ cs->task->updateKinematics(ts);
+ }
+ numsubstep--;
+ }
+ return true;
+}
+
+}
diff --git a/intern/itasc/Scene.hpp b/intern/itasc/Scene.hpp
new file mode 100644
index 00000000000..a2d63361d95
--- /dev/null
+++ b/intern/itasc/Scene.hpp
@@ -0,0 +1,104 @@
+/* $Id: Scene.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * Scene.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef SCENE_HPP_
+#define SCENE_HPP_
+
+#include "eigen_types.hpp"
+
+#include "WorldObject.hpp"
+#include "ConstraintSet.hpp"
+#include "Solver.hpp"
+
+#include <map>
+
+namespace iTaSC {
+
+class SceneLock;
+
+class Scene {
+ friend class SceneLock;
+public:
+ enum SceneParam {
+ MIN_TIMESTEP = 0,
+ MAX_TIMESTEP,
+
+ COUNT
+ };
+
+
+ Scene();
+ virtual ~Scene();
+
+ bool addObject(const std::string& name, Object* object, UncontrolledObject* base=&Object::world, const std::string& baseFrame="");
+ bool addConstraintSet(const std::string& name, ConstraintSet* task,const std::string& object1,const std::string& object2,const std::string& ee1="",const std::string& ee2="");
+ bool addSolver(Solver* _solver);
+ bool addCache(Cache* _cache);
+ bool initialize();
+ bool update(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
+
+private:
+ e_matrix m_A,m_B,m_Atemp,m_Wq,m_Jf,m_Jq,m_Ju,m_Cf,m_Cq,m_Jf_inv;
+ e_matrix6 m_Vf,m_Uf;
+ e_vector m_Wy,m_ydot,m_qdot,m_xdot;
+ e_vector6 m_Sf,m_tempf;
+ double m_minstep;
+ double m_maxstep;
+ unsigned int m_ncTotal,m_nqTotal,m_nuTotal,m_nsets;
+ std::vector<bool> m_ytask;
+
+ Solver* m_solver;
+ Cache* m_cache;
+
+
+ struct Object_struct{
+ Object* object;
+ UncontrolledObject* base;
+ unsigned int baseFrameIndex;
+ Range constraintrange;
+ Range jointrange;
+ Range coordinaterange; // Xu range of base when object is controlled
+ // Xu range of object when object is uncontrolled
+
+ Object_struct(Object* _object,UncontrolledObject* _base,unsigned int _baseFrameIndex,Range nq_range,Range nc_range,Range nu_range):
+ object(_object),base(_base),baseFrameIndex(_baseFrameIndex),constraintrange(nc_range),jointrange(nq_range),coordinaterange(nu_range)
+ {};
+ };
+ typedef std::map<std::string,Object_struct*> ObjectMap;
+
+ struct ConstraintSet_struct{
+ ConstraintSet* task;
+ ObjectMap::iterator object1;
+ ObjectMap::iterator object2;
+ Range constraintrange;
+ Range featurerange;
+ unsigned int ee1index;
+ unsigned int ee2index;
+ ConstraintSet_struct(ConstraintSet* _task,
+ ObjectMap::iterator _object1,unsigned int _ee1index,
+ ObjectMap::iterator _object2,unsigned int _ee2index,
+ Range nc_range,Range coord_range):
+ task(_task),
+ object1(_object1),object2(_object2),
+ constraintrange(nc_range),featurerange(coord_range),
+ ee1index(_ee1index), ee2index(_ee2index)
+ {};
+ };
+ typedef std::map<std::string,ConstraintSet_struct*> ConstraintMap;
+
+ ObjectMap objects;
+ ConstraintMap constraints;
+
+ static bool getConstraintPose(ConstraintSet* constraint, void *_param, KDL::Frame& _pose);
+};
+
+}
+
+#endif /* SCENE_HPP_ */
diff --git a/intern/itasc/Solver.hpp b/intern/itasc/Solver.hpp
new file mode 100644
index 00000000000..e3aa1e1abc8
--- /dev/null
+++ b/intern/itasc/Solver.hpp
@@ -0,0 +1,33 @@
+/* $Id: Solver.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * Solver.hpp
+ *
+ * Created on: Jan 8, 2009
+ * Author: rubensmits
+ */
+
+#ifndef SOLVER_HPP_
+#define SOLVER_HPP_
+
+#include <vector>
+#include "eigen_types.hpp"
+
+namespace iTaSC{
+
+class Solver{
+public:
+ enum SolverParam {
+ DLS_QMAX = 0,
+ DLS_LAMBDA_MAX,
+ DLS_EPSILON
+ };
+ virtual ~Solver(){};
+
+ // gc = grouping of constraint output ,
+ // size of vector = nc, alternance of true / false to indicate the grouping of output
+ virtual bool init(unsigned int nq, unsigned int nc, const std::vector<bool>& gc)=0;
+ virtual bool solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef)=0;
+ virtual void setParam(SolverParam param, double value)=0;
+};
+
+}
+#endif /* SOLVER_HPP_ */
diff --git a/intern/itasc/UncontrolledObject.cpp b/intern/itasc/UncontrolledObject.cpp
new file mode 100644
index 00000000000..e05a8682d20
--- /dev/null
+++ b/intern/itasc/UncontrolledObject.cpp
@@ -0,0 +1,43 @@
+/* $Id: UncontrolledObject.cpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * UncontrolledObject.cpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#include "UncontrolledObject.hpp"
+
+namespace iTaSC{
+
+UncontrolledObject::UncontrolledObject():Object(UnControlled),
+ m_nu(0), m_nf(0), m_xudot()
+{
+}
+
+UncontrolledObject::~UncontrolledObject()
+{
+}
+
+void UncontrolledObject::initialize(unsigned int _nu, unsigned int _nf)
+{
+ assert (_nf >= 1);
+ m_nu = _nu;
+ m_nf = _nf;
+ if (_nu > 0)
+ m_xudot = e_zero_vector(_nu);
+ // clear all Jacobian if any
+ m_JuArray.clear();
+ // reserve one more to have an zero matrix handy
+ if (m_nu > 0)
+ m_JuArray.resize(m_nf+1, e_zero_matrix(6,m_nu));
+}
+
+const e_matrix& UncontrolledObject::getJu(unsigned int frameIndex) const
+{
+ assert (m_nu > 0);
+ return m_JuArray[(frameIndex>m_nf)?m_nf:frameIndex];
+}
+
+
+
+}
diff --git a/intern/itasc/UncontrolledObject.hpp b/intern/itasc/UncontrolledObject.hpp
new file mode 100644
index 00000000000..3b693a0b2ed
--- /dev/null
+++ b/intern/itasc/UncontrolledObject.hpp
@@ -0,0 +1,37 @@
+/* $Id: UncontrolledObject.hpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * UncontrolledObject.h
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef UNCONTROLLEDOBJECT_HPP_
+#define UNCONTROLLEDOBJECT_HPP_
+
+#include "eigen_types.hpp"
+
+#include "Object.hpp"
+namespace iTaSC{
+
+class UncontrolledObject: public Object {
+protected:
+ unsigned int m_nu, m_nf;
+ e_vector m_xudot;
+ std::vector<e_matrix> m_JuArray;
+
+public:
+ UncontrolledObject();
+ virtual ~UncontrolledObject();
+
+ 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(const Timestamp& timestamp)=0;
+ virtual const unsigned int getNrOfCoordinates(){return m_nu;};
+ virtual const unsigned int getNrOfFrames(){return m_nf;};
+
+};
+
+}
+
+#endif /* UNCONTROLLEDOBJECT_H_ */
diff --git a/intern/itasc/WDLSSolver.cpp b/intern/itasc/WDLSSolver.cpp
new file mode 100644
index 00000000000..91278c7ad3b
--- /dev/null
+++ b/intern/itasc/WDLSSolver.cpp
@@ -0,0 +1,85 @@
+/* $Id: WDLSSolver.cpp 20749 2009-06-09 11:27:30Z ben2610 $
+ * WDLSSolver.hpp.cpp
+ *
+ * Created on: Jan 8, 2009
+ * Author: rubensmits
+ */
+
+#include "WDLSSolver.hpp"
+#include "kdl/utilities/svd_eigen_HH.hpp"
+
+namespace iTaSC {
+
+WDLSSolver::WDLSSolver() : m_lambda(0.5), m_epsilon(0.1)
+{
+ // maximum joint velocity
+ m_qmax = 50.0;
+}
+
+WDLSSolver::~WDLSSolver() {
+}
+
+bool WDLSSolver::init(unsigned int nq, unsigned int nc, const std::vector<bool>& gc)
+{
+ m_ns = std::min(nc,nq);
+ m_AWq = e_zero_matrix(nc,nq);
+ m_WyAWq = e_zero_matrix(nc,nq);
+ m_U = e_zero_matrix(nc,nq);
+ m_S = e_zero_vector(std::max(nc,nq));
+ m_temp = e_zero_vector(nq);
+ m_V = e_zero_matrix(nq,nq);
+ m_WqV = e_zero_matrix(nq,nq);
+ m_Wy_ydot = e_zero_vector(nc);
+ return true;
+}
+
+bool WDLSSolver::solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef)
+{
+ double alpha, vmax, norm;
+ // Create the Weighted jacobian
+ m_AWq = A*Wq;
+ for (int i=0; i<Wy.size(); i++)
+ m_WyAWq.row(i) = Wy(i)*m_AWq.row(i);
+
+ // Compute the SVD of the weighted jacobian
+ int ret = KDL::svd_eigen_HH(m_WyAWq,m_U,m_S,m_V,m_temp);
+ if(ret<0)
+ return false;
+
+ m_WqV = (Wq*m_V).lazy();
+
+ //Wy*ydot
+ m_Wy_ydot = Wy.cwise() * ydot;
+ //S^-1*U'*Wy*ydot
+ e_scalar maxDeltaS = e_scalar(0.0);
+ e_scalar prevS = e_scalar(0.0);
+ e_scalar maxS = e_scalar(1.0);
+ e_scalar S, lambda;
+ qdot.setZero();
+ for(int i=0;i<m_ns;++i) {
+ S = m_S(i);
+ if (S <= KDL::epsilon)
+ break;
+ if (i > 0 && (prevS-S) > maxDeltaS) {
+ maxDeltaS = (prevS-S);
+ maxS = prevS;
+ }
+ lambda = (S < m_epsilon) ? (e_scalar(1.0)-KDL::sqr(S/m_epsilon))*m_lambda*m_lambda : e_scalar(0.0);
+ alpha = m_U.col(i).dot(m_Wy_ydot)*S/(S*S+lambda);
+ vmax = m_WqV.col(i).cwise().abs().maxCoeff();
+ norm = fabs(alpha*vmax);
+ if (norm > m_qmax) {
+ qdot += m_WqV.col(i)*(alpha*m_qmax/norm);
+ } else {
+ qdot += m_WqV.col(i)*alpha;
+ }
+ prevS = S;
+ }
+ if (maxDeltaS == e_scalar(0.0))
+ nlcoef = e_scalar(KDL::epsilon);
+ else
+ nlcoef = (maxS-maxDeltaS)/maxS;
+ return true;
+}
+
+}
diff --git a/intern/itasc/WDLSSolver.hpp b/intern/itasc/WDLSSolver.hpp
new file mode 100644
index 00000000000..4418e73675c
--- /dev/null
+++ b/intern/itasc/WDLSSolver.hpp
@@ -0,0 +1,47 @@
+/* $Id: WDLSSolver.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * WDLSSolver.hpp
+ *
+ * Created on: Jan 8, 2009
+ * Author: rubensmits
+ */
+
+#ifndef WDLSSOLVER_HPP_
+#define WDLSSOLVER_HPP_
+
+#include "Solver.hpp"
+
+namespace iTaSC {
+
+class WDLSSolver: public iTaSC::Solver {
+private:
+ e_matrix m_AWq,m_WyAWq,m_U,m_V,m_WqV;
+ e_vector m_S,m_temp,m_Wy_ydot;
+ double m_lambda;
+ double m_epsilon;
+ double m_qmax;
+ int m_ns;
+public:
+ WDLSSolver();
+ virtual ~WDLSSolver();
+
+ virtual bool init(unsigned int nq, unsigned int nc, const std::vector<bool>& gc);
+ virtual bool solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef);
+ virtual void setParam(SolverParam param, double value)
+ {
+ switch (param) {
+ case DLS_QMAX:
+ m_qmax = value;
+ break;
+ case DLS_LAMBDA_MAX:
+ m_lambda = value;
+ break;
+ case DLS_EPSILON:
+ m_epsilon = value;
+ break;
+ }
+ }
+};
+
+}
+
+#endif /* WDLSSOLVER_HPP_ */
diff --git a/intern/itasc/WSDLSSolver.cpp b/intern/itasc/WSDLSSolver.cpp
new file mode 100644
index 00000000000..1f99ad08334
--- /dev/null
+++ b/intern/itasc/WSDLSSolver.cpp
@@ -0,0 +1,122 @@
+/* $Id: WSDLSSolver.cpp 20749 2009-06-09 11:27:30Z ben2610 $
+ * WDLSSolver.hpp.cpp
+ *
+ * Created on: Jan 8, 2009
+ * Author: rubensmits
+ */
+
+#include "WSDLSSolver.hpp"
+#include "kdl/utilities/svd_eigen_HH.hpp"
+#include <cstdio>
+
+namespace iTaSC {
+
+WSDLSSolver::WSDLSSolver() :
+ m_ns(0), m_nc(0), m_nq(0)
+
+{
+ // default maximum speed: 50 rad/s
+ m_qmax = 50.0;
+}
+
+WSDLSSolver::~WSDLSSolver() {
+}
+
+bool WSDLSSolver::init(unsigned int _nq, unsigned int _nc, const std::vector<bool>& gc)
+{
+ if (_nc == 0 || _nq == 0 || gc.size() != _nc)
+ return false;
+ m_nc = _nc;
+ m_nq = _nq;
+ m_ns = std::min(m_nc,m_nq);
+ m_AWq = e_zero_matrix(m_nc,m_nq);
+ m_WyAWq = e_zero_matrix(m_nc,m_nq);
+ m_U = e_zero_matrix(m_nc,m_nq);
+ m_S = e_zero_vector(std::max(m_nc,m_nq));
+ m_temp = e_zero_vector(m_nq);
+ m_V = e_zero_matrix(m_nq,m_nq);
+ m_WqV = e_zero_matrix(m_nq,m_nq);
+ m_Wy_ydot = e_zero_vector(m_nc);
+ m_ytask = gc;
+ return true;
+}
+
+bool WSDLSSolver::solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef)
+{
+ unsigned int i, j, l;
+ e_scalar N, M;
+
+ // Create the Weighted jacobian
+ m_AWq = (A*Wq).lazy();
+ for (i=0; i<m_nc; i++)
+ m_WyAWq.row(i) = Wy(i)*m_AWq.row(i);
+
+ // Compute the SVD of the weighted jacobian
+ int ret = KDL::svd_eigen_HH(m_WyAWq,m_U,m_S,m_V,m_temp);
+ if(ret<0)
+ return false;
+
+ m_Wy_ydot = Wy.cwise() * ydot;
+ m_WqV = (Wq*m_V).lazy();
+ qdot.setZero();
+ e_scalar maxDeltaS = e_scalar(0.0);
+ e_scalar prevS = e_scalar(0.0);
+ e_scalar maxS = e_scalar(1.0);
+ for(i=0;i<m_ns;++i) {
+ e_scalar norm, mag, alpha, _qmax, Sinv, vmax, damp;
+ e_scalar S = m_S(i);
+ bool prev;
+ if (S < KDL::epsilon)
+ break;
+ Sinv = e_scalar(1.)/S;
+ if (i > 0) {
+ if ((prevS-S) > maxDeltaS) {
+ maxDeltaS = (prevS-S);
+ maxS = prevS;
+ }
+ }
+ N = M = e_scalar(0.);
+ for (l=0, prev=m_ytask[0], norm=e_scalar(0.); l<m_nc; l++) {
+ if (prev == m_ytask[l]) {
+ norm += m_U(l,i)*m_U(l,i);
+ } else {
+ N += std::sqrt(norm);
+ norm = m_U(l,i)*m_U(l,i);
+ }
+ prev = m_ytask[l];
+ }
+ N += std::sqrt(norm);
+ for (j=0; j<m_nq; j++) {
+ for (l=0, prev=m_ytask[0], norm=e_scalar(0.), mag=e_scalar(0.); l<m_nc; l++) {
+ if (prev == m_ytask[l]) {
+ norm += m_WyAWq(l,j)*m_WyAWq(l,j);
+ } else {
+ mag += std::sqrt(norm);
+ norm = m_WyAWq(l,j)*m_WyAWq(l,j);
+ }
+ prev = m_ytask[l];
+ }
+ mag += std::sqrt(norm);
+ M += fabs(m_V(j,i))*mag;
+ }
+ M *= Sinv;
+ alpha = m_U.col(i).dot(m_Wy_ydot);
+ _qmax = (N < M) ? m_qmax*N/M : m_qmax;
+ vmax = m_WqV.col(i).cwise().abs().maxCoeff();
+ norm = fabs(Sinv*alpha*vmax);
+ if (norm > _qmax) {
+ damp = Sinv*alpha*_qmax/norm;
+ } else {
+ damp = Sinv*alpha;
+ }
+ qdot += m_WqV.col(i)*damp;
+ prevS = S;
+ }
+ if (maxDeltaS == e_scalar(0.0))
+ nlcoef = e_scalar(KDL::epsilon);
+ else
+ nlcoef = (maxS-maxDeltaS)/maxS;
+ return true;
+}
+
+}
diff --git a/intern/itasc/WSDLSSolver.hpp b/intern/itasc/WSDLSSolver.hpp
new file mode 100644
index 00000000000..90f89f4e853
--- /dev/null
+++ b/intern/itasc/WSDLSSolver.hpp
@@ -0,0 +1,40 @@
+/* $Id: WSDLSSolver.hpp 20622 2009-06-04 12:47:59Z ben2610 $
+ * WSDLSSolver.hpp
+ *
+ * Created on: Mar 26, 2009
+ * Author: benoit bolsee
+ */
+
+#ifndef WSDLSSOLVER_HPP_
+#define WSDLSSOLVER_HPP_
+
+#include "Solver.hpp"
+
+namespace iTaSC {
+
+class WSDLSSolver: public iTaSC::Solver {
+private:
+ e_matrix m_AWq,m_WyAWq,m_U,m_V,m_WqV;
+ e_vector m_S,m_temp,m_Wy_ydot;
+ std::vector<bool> m_ytask;
+ e_scalar m_qmax;
+ unsigned int m_ns, m_nc, m_nq;
+public:
+ WSDLSSolver();
+ virtual ~WSDLSSolver();
+
+ virtual bool init(unsigned int _nq, unsigned int _nc, const std::vector<bool>& gc);
+ virtual bool solve(const e_matrix& A, const e_vector& Wy, const e_vector& ydot, const e_matrix& Wq, e_vector& qdot, e_scalar& nlcoef);
+ virtual void setParam(SolverParam param, double value)
+ {
+ switch (param) {
+ case DLS_QMAX:
+ m_qmax = value;
+ break;
+ }
+ }
+};
+
+}
+
+#endif /* WSDLSSOLVER_HPP_ */
diff --git a/intern/itasc/WorldObject.cpp b/intern/itasc/WorldObject.cpp
new file mode 100644
index 00000000000..ba3f8549f06
--- /dev/null
+++ b/intern/itasc/WorldObject.cpp
@@ -0,0 +1,26 @@
+/* $Id: WorldObject.cpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * WorldObject.cpp
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#include "WorldObject.hpp"
+
+namespace iTaSC{
+
+/* special singleton to be used as base for uncontrolled object */
+WorldObject Object::world;
+
+WorldObject::WorldObject():UncontrolledObject()
+{
+ initialize(0,1);
+ m_internalPose = Frame::Identity();
+}
+
+WorldObject::~WorldObject()
+{
+}
+
+
+}
diff --git a/intern/itasc/WorldObject.hpp b/intern/itasc/WorldObject.hpp
new file mode 100644
index 00000000000..b309545a843
--- /dev/null
+++ b/intern/itasc/WorldObject.hpp
@@ -0,0 +1,30 @@
+/* $Id: WorldObject.hpp 19907 2009-04-23 13:41:59Z ben2610 $
+ * WorldObject.h
+ *
+ * Created on: Feb 10, 2009
+ * Author: benoitbolsee
+ */
+
+#ifndef WORLDOBJECT_HPP_
+#define WORLDOBJECT_HPP_
+
+#include "UncontrolledObject.hpp"
+namespace iTaSC{
+
+class WorldObject: public UncontrolledObject {
+public:
+ WorldObject();
+ virtual ~WorldObject();
+
+ virtual void updateCoordinates(const Timestamp& timestamp) {};
+ virtual void updateKinematics(const Timestamp& timestamp) {};
+ virtual void pushCache(const Timestamp& timestamp) {};
+ virtual void initCache(Cache *_cache) {};
+protected:
+ virtual void updateJacobian() {}
+
+};
+
+}
+
+#endif /* WORLDOBJECT_H_ */
diff --git a/intern/itasc/eigen_types.cpp b/intern/itasc/eigen_types.cpp
new file mode 100644
index 00000000000..a1b28e01210
--- /dev/null
+++ b/intern/itasc/eigen_types.cpp
@@ -0,0 +1,12 @@
+/* $Id: eigen_types.cpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * eigen_types.cpp
+ *
+ * Created on: March 19, 2009
+ * Author: benoit bolsee
+ */
+
+#include "eigen_types.hpp"
+
+const KDL::Frame iTaSC::F_identity(Rotation::Identity(),Vector::Zero());
+
+
diff --git a/intern/itasc/eigen_types.hpp b/intern/itasc/eigen_types.hpp
new file mode 100644
index 00000000000..fe46f8b6bb3
--- /dev/null
+++ b/intern/itasc/eigen_types.hpp
@@ -0,0 +1,84 @@
+/* $Id: eigen_types.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * eigen_types.hpp
+ *
+ * Created on: March 6, 2009
+ * Author: benoit bolsee
+ */
+
+#ifndef EIGEN_TYPES_HPP_
+#define EIGEN_TYPES_HPP_
+
+#include <Eigen/Core>
+#include "kdl/frames.hpp"
+#include "kdl/tree.hpp"
+#include "kdl/chain.hpp"
+#include "kdl/jacobian.hpp"
+#include "kdl/jntarray.hpp"
+
+
+namespace iTaSC{
+
+using KDL::Twist;
+using KDL::Frame;
+using KDL::Joint;
+using KDL::Inertia;
+using KDL::SegmentMap;
+using KDL::Tree;
+using KDL::JntArray;
+using KDL::Jacobian;
+using KDL::Segment;
+using KDL::Rotation;
+using KDL::Vector;
+using KDL::Vector2;
+using KDL::Chain;
+
+extern const Frame F_identity;
+
+#define e_scalar double
+#define e_vector Eigen::Matrix<e_scalar, Eigen::Dynamic, 1>
+#define e_zero_vector Eigen::Matrix<e_scalar, Eigen::Dynamic, 1>::Zero
+#define e_matrix Eigen::Matrix<e_scalar, Eigen::Dynamic, Eigen::Dynamic>
+#define e_matrix6 Eigen::Matrix<e_scalar,6,6>
+#define e_identity_matrix Eigen::Matrix<e_scalar, Eigen::Dynamic, Eigen::Dynamic>::Identity
+#define e_scalar_vector Eigen::Matrix<e_scalar, Eigen::Dynamic, 1>::Constant
+#define e_zero_matrix Eigen::Matrix<e_scalar, Eigen::Dynamic, Eigen::Dynamic>::Zero
+#define e_random_matrix Eigen::Matrix<e_scalar, Eigen::Dynamic, Eigen::Dynamic>::Random
+#define e_vector6 Eigen::Matrix<e_scalar,6,1>
+#define e_vector3 Eigen::Matrix<e_scalar,3,1>
+
+class Range {
+public:
+ int start;
+ int count;
+ Range(int _start, int _count) { start = _start; count=_count; }
+ Range(const Range& other) { start=other.start; count=other.count; }
+};
+
+template<typename MatrixType> inline Eigen::Block<MatrixType> project(MatrixType& m, Range r)
+{
+ return Eigen::Block<MatrixType>(m,r.start,0,r.count,1);
+}
+
+template<typename MatrixType> inline Eigen::Block<MatrixType> project(MatrixType& m, Range r, Range c)
+{
+ return Eigen::Block<MatrixType>(m,r.start,c.start,r.count,c.count);
+}
+
+template<typename Derived> inline static int changeBase(Eigen::MatrixBase<Derived>& J, const Frame& T) {
+
+ if (J.rows() != 6)
+ return -1;
+ for (int j = 0; j < J.cols(); ++j) {
+ typename Derived::ColXpr Jj = J.col(j);
+ Twist arg;
+ for(unsigned int i=0;i<6;++i)
+ arg(i)=Jj[i];
+ Twist tmp(T*arg);
+ for(unsigned int i=0;i<6;++i)
+ Jj[i]=e_scalar(tmp(i));
+ }
+ return 0;
+}
+
+}
+#endif /* UBLAS_TYPES_HPP_ */
diff --git a/intern/itasc/kdl/Makefile b/intern/itasc/kdl/Makefile
new file mode 100644
index 00000000000..e87795fd3b7
--- /dev/null
+++ b/intern/itasc/kdl/Makefile
@@ -0,0 +1,42 @@
+#
+# $Id: Makefile 19905 2009-04-23 13:29:54Z ben2610 $
+#
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Hans Lambermont
+#
+# ***** END GPL LICENSE BLOCK *****
+# iksolver main makefile.
+#
+
+LIBNAME = itasc
+DIR = $(OCGDIR)/intern/$(LIBNAME)
+
+include nan_compile.mk
+
+CPPFLAGS += -I.
+CPPFLAGS += -I../../../extern/Eigen2
+
+##############################
+DIRS = utilities
+SOURCEDIR = intern/$(LIBNAME)/kdl
+include nan_subdirs.mk
diff --git a/intern/itasc/kdl/chain.cpp b/intern/itasc/kdl/chain.cpp
new file mode 100644
index 00000000000..638366c96be
--- /dev/null
+++ b/intern/itasc/kdl/chain.cpp
@@ -0,0 +1,75 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "chain.hpp"
+
+namespace KDL {
+ using namespace std;
+
+ Chain::Chain():
+ segments(0),
+ nrOfJoints(0),
+ nrOfSegments(0)
+ {
+ }
+
+ Chain::Chain(const Chain& in):nrOfJoints(0),
+ nrOfSegments(0)
+ {
+ for(unsigned int i=0;i<in.getNrOfSegments();i++)
+ this->addSegment(in.getSegment(i));
+ }
+
+ Chain& Chain::operator=(const Chain& arg)
+ {
+ nrOfJoints=0;
+ nrOfSegments=0;
+ segments.resize(0);
+ for(unsigned int i=0;i<arg.nrOfSegments;i++)
+ addSegment(arg.getSegment(i));
+ return *this;
+
+ }
+
+ void Chain::addSegment(const Segment& segment)
+ {
+ segments.push_back(segment);
+ nrOfSegments++;
+ nrOfJoints += segment.getJoint().getNDof();
+ }
+
+ void Chain::addChain(const Chain& chain)
+ {
+ for(unsigned int i=0;i<chain.getNrOfSegments();i++)
+ this->addSegment(chain.getSegment(i));
+ }
+
+ const Segment& Chain::getSegment(unsigned int nr) const
+ {
+ return segments[nr];
+ }
+
+ Chain::~Chain()
+ {
+ }
+
+}
+
diff --git a/intern/itasc/kdl/chain.hpp b/intern/itasc/kdl/chain.hpp
new file mode 100644
index 00000000000..0d40690202a
--- /dev/null
+++ b/intern/itasc/kdl/chain.hpp
@@ -0,0 +1,95 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_CHAIN_HPP
+#define KDL_CHAIN_HPP
+
+#include "segment.hpp"
+#include <string>
+
+namespace KDL {
+ /**
+ * \brief This class encapsulates a <strong>serial</strong> kinematic
+ * interconnection structure. It is build out of segments.
+ *
+ * @ingroup KinematicFamily
+ */
+ class Chain {
+ private:
+ std::vector<Segment> segments;
+ unsigned int nrOfJoints;
+ unsigned int nrOfSegments;
+ public:
+ /**
+ * The constructor of a chain, a new chain is always empty.
+ *
+ */
+ Chain();
+ Chain(const Chain& in);
+ Chain& operator = (const Chain& arg);
+
+ /**
+ * Adds a new segment to the <strong>end</strong> of the chain.
+ *
+ * @param segment The segment to add
+ */
+ void addSegment(const Segment& segment);
+ /**
+ * Adds a complete chain to the <strong>end</strong> of the chain
+ * The added chain is copied.
+ *
+ * @param chain The chain to add
+ */
+ void addChain(const Chain& chain);
+
+ /**
+ * Request the total number of joints in the chain.\n
+ * <strong> Important:</strong> It is not the
+ * same as the total number of segments since a segment does not
+ * need to have a joint. This function is important when
+ * creating a KDL::JntArray to use with this chain.
+ * @return total nr of joints
+ */
+ unsigned int getNrOfJoints()const {return nrOfJoints;};
+ /**
+ * Request the total number of segments in the chain.
+ * @return total number of segments
+ */
+ unsigned int getNrOfSegments()const {return nrOfSegments;};
+
+ /**
+ * Request the nr'd segment of the chain. There is no boundary
+ * checking.
+ *
+ * @param nr the nr of the segment starting from 0
+ *
+ * @return a constant reference to the nr'd segment
+ */
+ const Segment& getSegment(unsigned int nr)const;
+
+ virtual ~Chain();
+ };
+
+
+
+}//end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/chainfksolver.hpp b/intern/itasc/kdl/chainfksolver.hpp
new file mode 100644
index 00000000000..fa6f625ee9d
--- /dev/null
+++ b/intern/itasc/kdl/chainfksolver.hpp
@@ -0,0 +1,107 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_CHAIN_FKSOLVER_HPP
+#define KDL_CHAIN_FKSOLVER_HPP
+
+#include "chain.hpp"
+#include "framevel.hpp"
+#include "frameacc.hpp"
+#include "jntarray.hpp"
+#include "jntarrayvel.hpp"
+#include "jntarrayacc.hpp"
+
+namespace KDL {
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a
+ * solver for the forward position kinematics for a KDL::Chain.
+ *
+ * @ingroup KinematicFamily
+ */
+
+ //Forward definition
+ class ChainFkSolverPos {
+ public:
+ /**
+ * Calculate forward position kinematics for a KDL::Chain,
+ * from joint coordinates to cartesian pose.
+ *
+ * @param q_in input joint coordinates
+ * @param p_out reference to output cartesian pose
+ *
+ * @return if < 0 something went wrong
+ */
+ virtual int JntToCart(const JntArray& q_in, Frame& p_out,int segmentNr=-1)=0;
+ virtual ~ChainFkSolverPos(){};
+ };
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a solver
+ * for the forward velocity kinematics for a KDL::Chain.
+ *
+ * @ingroup KinematicFamily
+ */
+ class ChainFkSolverVel {
+ public:
+ /**
+ * Calculate forward position and velocity kinematics, from
+ * joint coordinates to cartesian coordinates.
+ *
+ * @param q_in input joint coordinates (position and velocity)
+ * @param out output cartesian coordinates (position and velocity)
+ *
+ * @return if < 0 something went wrong
+ */
+ virtual int JntToCart(const JntArrayVel& q_in, FrameVel& out,int segmentNr=-1)=0;
+
+ virtual ~ChainFkSolverVel(){};
+ };
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a solver
+ * for the forward acceleration kinematics for a KDL::Chain.
+ *
+ * @ingroup KinematicFamily
+ */
+
+ class ChainFkSolverAcc {
+ public:
+ /**
+ * Calculate forward position, velocity and accelaration
+ * kinematics, from joint coordinates to cartesian coordinates
+ *
+ * @param q_in input joint coordinates (position, velocity and
+ * acceleration
+ @param out output cartesian coordinates (position, velocity
+ * and acceleration
+ *
+ * @return if < 0 something went wrong
+ */
+ virtual int JntToCart(const JntArrayAcc& q_in, FrameAcc& out,int segmentNr=-1)=0;
+
+ virtual ~ChainFkSolverAcc()=0;
+ };
+
+
+}//end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/chainfksolverpos_recursive.cpp b/intern/itasc/kdl/chainfksolverpos_recursive.cpp
new file mode 100644
index 00000000000..46c29c9c6e0
--- /dev/null
+++ b/intern/itasc/kdl/chainfksolverpos_recursive.cpp
@@ -0,0 +1,61 @@
+// Copyright (C) 2007 Francois Cauwe <francois at cauwe dot org>
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "chainfksolverpos_recursive.hpp"
+#include <iostream>
+
+namespace KDL {
+
+ ChainFkSolverPos_recursive::ChainFkSolverPos_recursive(const Chain& _chain):
+ chain(_chain)
+ {
+ }
+
+ int ChainFkSolverPos_recursive::JntToCart(const JntArray& q_in, Frame& p_out, int segmentNr)
+ {
+ unsigned int segNr = (unsigned int)segmentNr;
+ if(segmentNr<0)
+ segNr=chain.getNrOfSegments();
+
+ p_out = Frame::Identity();
+
+ if(q_in.rows()!=chain.getNrOfJoints())
+ return -1;
+ else if(segNr>chain.getNrOfSegments())
+ return -1;
+ else{
+ int j=0;
+ for(unsigned int i=0;i<segNr;i++){
+ p_out = p_out*chain.getSegment(i).pose(((JntArray&)q_in)(j));
+ j+=chain.getSegment(i).getJoint().getNDof();
+ }
+ return 0;
+ }
+ }
+
+
+ ChainFkSolverPos_recursive::~ChainFkSolverPos_recursive()
+ {
+ }
+
+
+}
diff --git a/intern/itasc/kdl/chainfksolverpos_recursive.hpp b/intern/itasc/kdl/chainfksolverpos_recursive.hpp
new file mode 100644
index 00000000000..72cdab0b28b
--- /dev/null
+++ b/intern/itasc/kdl/chainfksolverpos_recursive.hpp
@@ -0,0 +1,50 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDLCHAINFKSOLVERPOS_RECURSIVE_HPP
+#define KDLCHAINFKSOLVERPOS_RECURSIVE_HPP
+
+#include "chainfksolver.hpp"
+
+namespace KDL {
+
+ /**
+ * Implementation of a recursive forward position kinematics
+ * algorithm to calculate the position transformation from joint
+ * space to Cartesian space of a general kinematic chain (KDL::Chain).
+ *
+ * @ingroup KinematicFamily
+ */
+ class ChainFkSolverPos_recursive : public ChainFkSolverPos
+ {
+ public:
+ ChainFkSolverPos_recursive(const Chain& chain);
+ ~ChainFkSolverPos_recursive();
+
+ virtual int JntToCart(const JntArray& q_in, Frame& p_out, int segmentNr=-1);
+
+ private:
+ const Chain chain;
+ };
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/chainjnttojacsolver.cpp b/intern/itasc/kdl/chainjnttojacsolver.cpp
new file mode 100644
index 00000000000..4a801c041f3
--- /dev/null
+++ b/intern/itasc/kdl/chainjnttojacsolver.cpp
@@ -0,0 +1,80 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "chainjnttojacsolver.hpp"
+
+namespace KDL
+{
+ ChainJntToJacSolver::ChainJntToJacSolver(const Chain& _chain):
+ chain(_chain)
+ {
+ }
+
+ ChainJntToJacSolver::~ChainJntToJacSolver()
+ {
+ }
+
+ int ChainJntToJacSolver::JntToJac(const JntArray& q_in,Jacobian& jac)
+ {
+ assert(q_in.rows()==chain.getNrOfJoints()&&
+ q_in.rows()==jac.columns());
+
+
+ Frame T_local, T_joint;
+ T_total = Frame::Identity();
+ SetToZero(t_local);
+
+ int i=chain.getNrOfSegments()-1;
+ unsigned int q_nr = chain.getNrOfJoints();
+
+ //Lets recursively iterate until we are in the root segment
+ while (i >= 0) {
+ const Segment& segment = chain.getSegment(i);
+ int ndof = segment.getJoint().getNDof();
+ q_nr -= ndof;
+
+ //get the pose of the joint.
+ T_joint = segment.getJoint().pose(((JntArray&)q_in)(q_nr));
+ // combine with the tip to have the tip pose
+ T_local = T_joint*segment.getFrameToTip();
+ //calculate new T_end:
+ T_total = T_local * T_total;
+
+ for (int dof=0; dof<ndof; dof++) {
+ // combine joint rotation with tip position to get a reference frame for the joint
+ T_joint.p = T_local.p;
+ // in which the twist can be computed (needed for NDof joint)
+ t_local = segment.twist(T_joint, 1.0, dof);
+ //transform the endpoint of the local twist to the global endpoint:
+ t_local = t_local.RefPoint(T_total.p - T_local.p);
+ //transform the base of the twist to the endpoint
+ t_local = T_total.M.Inverse(t_local);
+ //store the twist in the jacobian:
+ jac.twists[q_nr+dof] = t_local;
+ }
+ i--;
+ }//endwhile
+ //Change the base of the complete jacobian from the endpoint to the base
+ changeBase(jac, T_total.M, jac);
+ return 0;
+ }
+}
+
diff --git a/intern/itasc/kdl/chainjnttojacsolver.hpp b/intern/itasc/kdl/chainjnttojacsolver.hpp
new file mode 100644
index 00000000000..98f9d06ee0d
--- /dev/null
+++ b/intern/itasc/kdl/chainjnttojacsolver.hpp
@@ -0,0 +1,65 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_CHAINJNTTOJACSOLVER_HPP
+#define KDL_CHAINJNTTOJACSOLVER_HPP
+
+#include "frames.hpp"
+#include "jacobian.hpp"
+#include "jntarray.hpp"
+#include "chain.hpp"
+
+namespace KDL
+{
+ /**
+ * @brief Class to calculate the jacobian of a general
+ * KDL::Chain, it is used by other solvers. It should not be used
+ * outside of KDL.
+ *
+ *
+ */
+
+ class ChainJntToJacSolver
+ {
+ public:
+ ChainJntToJacSolver(const Chain& chain);
+ ~ChainJntToJacSolver();
+ /**
+ * Calculate the jacobian expressed in the base frame of the
+ * chain, with reference point at the end effector of the
+ * *chain. The alghoritm is similar to the one used in
+ * KDL::ChainFkSolverVel_recursive
+ *
+ * @param q_in input joint positions
+ * @param jac output jacobian
+ *
+ * @return always returns 0
+ */
+ int JntToJac(const JntArray& q_in,Jacobian& jac);
+
+ private:
+ const Chain chain;
+ Twist t_local;
+ Frame T_total;
+ };
+}
+#endif
+
diff --git a/intern/itasc/kdl/frameacc.cpp b/intern/itasc/kdl/frameacc.cpp
new file mode 100644
index 00000000000..85c4179379a
--- /dev/null
+++ b/intern/itasc/kdl/frameacc.cpp
@@ -0,0 +1,26 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: frameacc.cpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+
+#include "frameacc.hpp"
+
+namespace KDL {
+
+#ifndef KDL_INLINE
+ #include "frameacc.inl"
+#endif
+
+}
+
diff --git a/intern/itasc/kdl/frameacc.hpp b/intern/itasc/kdl/frameacc.hpp
new file mode 100644
index 00000000000..4157237222e
--- /dev/null
+++ b/intern/itasc/kdl/frameacc.hpp
@@ -0,0 +1,259 @@
+/*****************************************************************************
+ * \file
+ * This file contains the definition of classes for a
+ * Rall Algebra of (subset of) the classes defined in frames,
+ * i.e. classes that contain a set (value,derivative,2nd derivative)
+ * and define operations on that set
+ * this classes are usefull for automatic differentiation ( <-> symbolic diff ,
+ * <-> numeric diff).
+ * Defines VectorAcc, RotationAcc, FrameAcc, doubleAcc.
+ * Look at the corresponding classes Vector Rotation Frame Twist and
+ * Wrench for the semantics of the methods.
+ *
+ * It also contains the 2nd derivative <-> RFrames.h
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: frameacc.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+#ifndef RRFRAMES_H
+#define RRFRAMES_H
+
+
+#include "utilities/rall2d.h"
+#include "frames.hpp"
+
+
+
+namespace KDL {
+
+class TwistAcc;
+typedef Rall2d<double,double,double> doubleAcc;
+
+
+class VectorAcc
+{
+public:
+ Vector p; //!< position vector
+ Vector v; //!< velocity vector
+ Vector dv; //!< acceleration vector
+public:
+ VectorAcc():p(),v(),dv() {}
+ explicit VectorAcc(const Vector& _p):p(_p),v(Vector::Zero()),dv(Vector::Zero()) {}
+ VectorAcc(const Vector& _p,const Vector& _v):p(_p),v(_v),dv(Vector::Zero()) {}
+ VectorAcc(const Vector& _p,const Vector& _v,const Vector& _dv):
+ p(_p),v(_v),dv(_dv) {}
+ IMETHOD VectorAcc& operator = (const VectorAcc& arg);
+ IMETHOD VectorAcc& operator = (const Vector& arg);
+ IMETHOD VectorAcc& operator += (const VectorAcc& arg);
+ IMETHOD VectorAcc& operator -= (const VectorAcc& arg);
+ IMETHOD static VectorAcc Zero();
+ IMETHOD void ReverseSign();
+ IMETHOD doubleAcc Norm();
+ IMETHOD friend VectorAcc operator + (const VectorAcc& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator - (const VectorAcc& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator + (const Vector& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator - (const Vector& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator + (const VectorAcc& r1,const Vector& r2);
+ IMETHOD friend VectorAcc operator - (const VectorAcc& r1,const Vector& r2);
+ IMETHOD friend VectorAcc operator * (const VectorAcc& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator * (const VectorAcc& r1,const Vector& r2);
+ IMETHOD friend VectorAcc operator * (const Vector& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator * (const VectorAcc& r1,double r2);
+ IMETHOD friend VectorAcc operator * (double r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator * (const doubleAcc& r1,const VectorAcc& r2);
+ IMETHOD friend VectorAcc operator * (const VectorAcc& r2,const doubleAcc& r1);
+ IMETHOD friend VectorAcc operator*(const Rotation& R,const VectorAcc& x);
+
+ IMETHOD friend VectorAcc operator / (const VectorAcc& r1,double r2);
+ IMETHOD friend VectorAcc operator / (const VectorAcc& r2,const doubleAcc& r1);
+
+
+ IMETHOD friend bool Equal(const VectorAcc& r1,const VectorAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Vector& r1,const VectorAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const VectorAcc& r1,const Vector& r2,double eps=epsilon);
+ IMETHOD friend VectorAcc operator - (const VectorAcc& r);
+ IMETHOD friend doubleAcc dot(const VectorAcc& lhs,const VectorAcc& rhs);
+ IMETHOD friend doubleAcc dot(const VectorAcc& lhs,const Vector& rhs);
+ IMETHOD friend doubleAcc dot(const Vector& lhs,const VectorAcc& rhs);
+};
+
+
+
+class RotationAcc
+{
+public:
+ Rotation R; //!< rotation matrix
+ Vector w; //!< angular velocity vector
+ Vector dw; //!< angular acceration vector
+public:
+ RotationAcc():R(),w() {}
+ explicit RotationAcc(const Rotation& _R):R(_R),w(Vector::Zero()){}
+ RotationAcc(const Rotation& _R,const Vector& _w,const Vector& _dw):
+ R(_R),w(_w),dw(_dw) {}
+ IMETHOD RotationAcc& operator = (const RotationAcc& arg);
+ IMETHOD RotationAcc& operator = (const Rotation& arg);
+ IMETHOD static RotationAcc Identity();
+ IMETHOD RotationAcc Inverse() const;
+ IMETHOD VectorAcc Inverse(const VectorAcc& arg) const;
+ IMETHOD VectorAcc Inverse(const Vector& arg) const;
+ IMETHOD VectorAcc operator*(const VectorAcc& arg) const;
+ IMETHOD VectorAcc operator*(const Vector& arg) const;
+
+ // Rotations
+ // The SetRot.. functions set the value of *this to the appropriate rotation matrix.
+ // The Rot... static functions give the value of the appropriate rotation matrix back.
+ // The DoRot... functions apply a rotation R to *this,such that *this = *this * R.
+ // IMETHOD void DoRotX(const doubleAcc& angle);
+ // IMETHOD void DoRotY(const doubleAcc& angle);
+ // IMETHOD void DoRotZ(const doubleAcc& angle);
+ // IMETHOD static RRotation RotX(const doubleAcc& angle);
+ // IMETHOD static RRotation RotY(const doubleAcc& angle);
+ // IMETHOD static RRotation RotZ(const doubleAcc& angle);
+
+ // IMETHOD void SetRot(const Vector& rotaxis,const doubleAcc& angle);
+ // Along an arbitrary axes. The norm of rotvec is neglected.
+ // IMETHOD static RotationAcc Rot(const Vector& rotvec,const doubleAcc& angle);
+ // rotvec has arbitrary norm
+ // rotation around a constant vector !
+ // IMETHOD static RotationAcc Rot2(const Vector& rotvec,const doubleAcc& angle);
+ // rotvec is normalized.
+ // rotation around a constant vector !
+
+ IMETHOD friend RotationAcc operator* (const RotationAcc& r1,const RotationAcc& r2);
+ IMETHOD friend RotationAcc operator* (const Rotation& r1,const RotationAcc& r2);
+ IMETHOD friend RotationAcc operator* (const RotationAcc& r1,const Rotation& r2);
+ IMETHOD friend bool Equal(const RotationAcc& r1,const RotationAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Rotation& r1,const RotationAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const RotationAcc& r1,const Rotation& r2,double eps=epsilon);
+ IMETHOD TwistAcc Inverse(const TwistAcc& arg) const;
+ IMETHOD TwistAcc Inverse(const Twist& arg) const;
+ IMETHOD TwistAcc operator * (const TwistAcc& arg) const;
+ IMETHOD TwistAcc operator * (const Twist& arg) const;
+};
+
+
+
+
+class FrameAcc
+{
+public:
+ RotationAcc M; //!< Rotation,angular velocity, and angular acceleration of frame.
+ VectorAcc p; //!< Translation, velocity and acceleration of origin.
+public:
+ FrameAcc(){}
+ explicit FrameAcc(const Frame& _T):M(_T.M),p(_T.p) {}
+ FrameAcc(const Frame& _T,const Twist& _t,const Twist& _dt):
+ M(_T.M,_t.rot,_dt.rot),p(_T.p,_t.vel,_dt.vel) {}
+ FrameAcc(const RotationAcc& _M,const VectorAcc& _p):M(_M),p(_p) {}
+
+ IMETHOD FrameAcc& operator = (const FrameAcc& arg);
+ IMETHOD FrameAcc& operator = (const Frame& arg);
+ IMETHOD static FrameAcc Identity();
+ IMETHOD FrameAcc Inverse() const;
+ IMETHOD VectorAcc Inverse(const VectorAcc& arg) const;
+ IMETHOD VectorAcc operator*(const VectorAcc& arg) const;
+ IMETHOD VectorAcc operator*(const Vector& arg) const;
+ IMETHOD VectorAcc Inverse(const Vector& arg) const;
+ IMETHOD Frame GetFrame() const;
+ IMETHOD Twist GetTwist() const;
+ IMETHOD Twist GetAccTwist() const;
+ IMETHOD friend FrameAcc operator * (const FrameAcc& f1,const FrameAcc& f2);
+ IMETHOD friend FrameAcc operator * (const Frame& f1,const FrameAcc& f2);
+ IMETHOD friend FrameAcc operator * (const FrameAcc& f1,const Frame& f2);
+ IMETHOD friend bool Equal(const FrameAcc& r1,const FrameAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Frame& r1,const FrameAcc& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const FrameAcc& r1,const Frame& r2,double eps=epsilon);
+
+ IMETHOD TwistAcc Inverse(const TwistAcc& arg) const;
+ IMETHOD TwistAcc Inverse(const Twist& arg) const;
+ IMETHOD TwistAcc operator * (const TwistAcc& arg) const;
+ IMETHOD TwistAcc operator * (const Twist& arg) const;
+};
+
+
+
+
+
+
+
+
+//very similar to Wrench class.
+class TwistAcc
+{
+public:
+ VectorAcc vel; //!< translational velocity and its 1st and 2nd derivative
+ VectorAcc rot; //!< rotational velocity and its 1st and 2nd derivative
+public:
+
+ TwistAcc():vel(),rot() {};
+ TwistAcc(const VectorAcc& _vel,const VectorAcc& _rot):vel(_vel),rot(_rot) {};
+
+ IMETHOD TwistAcc& operator-=(const TwistAcc& arg);
+ IMETHOD TwistAcc& operator+=(const TwistAcc& arg);
+
+ IMETHOD friend TwistAcc operator*(const TwistAcc& lhs,double rhs);
+ IMETHOD friend TwistAcc operator*(double lhs,const TwistAcc& rhs);
+ IMETHOD friend TwistAcc operator/(const TwistAcc& lhs,double rhs);
+
+ IMETHOD friend TwistAcc operator*(const TwistAcc& lhs,const doubleAcc& rhs);
+ IMETHOD friend TwistAcc operator*(const doubleAcc& lhs,const TwistAcc& rhs);
+ IMETHOD friend TwistAcc operator/(const TwistAcc& lhs,const doubleAcc& rhs);
+
+ IMETHOD friend TwistAcc operator+(const TwistAcc& lhs,const TwistAcc& rhs);
+ IMETHOD friend TwistAcc operator-(const TwistAcc& lhs,const TwistAcc& rhs);
+ IMETHOD friend TwistAcc operator-(const TwistAcc& arg);
+
+ IMETHOD friend void SetToZero(TwistAcc& v);
+
+ static IMETHOD TwistAcc Zero();
+
+ IMETHOD void ReverseSign();
+
+ IMETHOD TwistAcc RefPoint(const VectorAcc& v_base_AB);
+ // Changes the reference point of the RTwist.
+ // The RVector v_base_AB is expressed in the same base as the RTwist
+ // The RVector v_base_AB is a RVector from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+
+ IMETHOD friend bool Equal(const TwistAcc& a,const TwistAcc& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const Twist& a,const TwistAcc& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const TwistAcc& a,const Twist& b,double eps=epsilon);
+
+
+ IMETHOD Twist GetTwist() const;
+ IMETHOD Twist GetTwistDot() const;
+
+ friend class RotationAcc;
+ friend class FrameAcc;
+
+};
+
+
+
+
+
+
+
+#ifdef KDL_INLINE
+#include "frameacc.inl"
+#endif
+
+}
+
+
+
+
+
+#endif
diff --git a/intern/itasc/kdl/frameacc.inl b/intern/itasc/kdl/frameacc.inl
new file mode 100644
index 00000000000..a8ea35ad436
--- /dev/null
+++ b/intern/itasc/kdl/frameacc.inl
@@ -0,0 +1,598 @@
+/*****************************************************************************
+ * \file
+ * provides inline functions of rrframes.h
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: frameacc.inl 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+
+
+
+/////////////////// VectorAcc /////////////////////////////////////
+
+VectorAcc operator + (const VectorAcc& r1,const VectorAcc& r2) {
+ return VectorAcc(r1.p+r2.p,r1.v+r2.v,r1.dv+r2.dv);
+}
+
+VectorAcc operator - (const VectorAcc& r1,const VectorAcc& r2) {
+ return VectorAcc(r1.p-r2.p, r1.v-r2.v, r1.dv-r2.dv);
+}
+VectorAcc operator + (const Vector& r1,const VectorAcc& r2) {
+ return VectorAcc(r1+r2.p,r2.v,r2.dv);
+}
+
+VectorAcc operator - (const Vector& r1,const VectorAcc& r2) {
+ return VectorAcc(r1-r2.p, -r2.v, -r2.dv);
+}
+VectorAcc operator + (const VectorAcc& r1,const Vector& r2) {
+ return VectorAcc(r1.p+r2,r1.v,r1.dv);
+}
+
+VectorAcc operator - (const VectorAcc& r1,const Vector& r2) {
+ return VectorAcc(r1.p-r2, r1.v, r1.dv);
+}
+
+// unary -
+VectorAcc operator - (const VectorAcc& r) {
+ return VectorAcc(-r.p,-r.v,-r.dv);
+}
+
+// cross prod.
+VectorAcc operator * (const VectorAcc& r1,const VectorAcc& r2) {
+ return VectorAcc(r1.p*r2.p,
+ r1.p*r2.v+r1.v*r2.p,
+ r1.dv*r2.p+2*r1.v*r2.v+r1.p*r2.dv
+ );
+}
+
+VectorAcc operator * (const VectorAcc& r1,const Vector& r2) {
+ return VectorAcc(r1.p*r2, r1.v*r2, r1.dv*r2 );
+}
+
+VectorAcc operator * (const Vector& r1,const VectorAcc& r2) {
+ return VectorAcc(r1*r2.p, r1*r2.v, r1*r2.dv );
+}
+
+
+
+// scalar mult.
+VectorAcc operator * (double r1,const VectorAcc& r2) {
+ return VectorAcc(r1*r2.p, r1*r2.v, r1*r2.dv );
+}
+
+VectorAcc operator * (const VectorAcc& r1,double r2) {
+ return VectorAcc(r1.p*r2, r1.v*r2, r1.dv*r2 );
+}
+
+VectorAcc operator * (const doubleAcc& r1,const VectorAcc& r2) {
+ return VectorAcc(r1.t*r2.p,
+ r1.t*r2.v + r1.d*r2.p,
+ r1.t*r2.dv + 2*r1.d*r2.v + r1.dd*r2.p
+ );
+}
+
+VectorAcc operator * (const VectorAcc& r2,const doubleAcc& r1) {
+ return VectorAcc(r1.t*r2.p,
+ r1.t*r2.v + r1.d*r2.p,
+ r1.t*r2.dv + 2*r1.d*r2.v + r1.dd*r2.p
+ );
+}
+
+VectorAcc& VectorAcc::operator = (const VectorAcc& arg) {
+ p=arg.p;
+ v=arg.v;
+ dv=arg.dv;
+ return *this;
+}
+
+VectorAcc& VectorAcc::operator = (const Vector& arg) {
+ p=arg;
+ v=Vector::Zero();
+ dv=Vector::Zero();
+ return *this;
+}
+
+VectorAcc& VectorAcc::operator += (const VectorAcc& arg) {
+ p+=arg.p;
+ v+=arg.v;
+ dv+= arg.dv;
+ return *this;
+}
+VectorAcc& VectorAcc::operator -= (const VectorAcc& arg) {
+ p-=arg.p;
+ v-=arg.v;
+ dv-=arg.dv;
+ return *this;
+}
+
+VectorAcc VectorAcc::Zero() {
+ return VectorAcc(Vector::Zero(),Vector::Zero(),Vector::Zero());
+}
+
+void VectorAcc::ReverseSign() {
+ p.ReverseSign();
+ v.ReverseSign();
+ dv.ReverseSign();
+}
+
+doubleAcc VectorAcc::Norm() {
+ doubleAcc res;
+ res.t = p.Norm();
+ res.d = dot(p,v)/res.t;
+ res.dd = (dot(p,dv)+dot(v,v)-res.d*res.d)/res.t;
+ return res;
+}
+
+doubleAcc dot(const VectorAcc& lhs,const VectorAcc& rhs) {
+ return doubleAcc( dot(lhs.p,rhs.p),
+ dot(lhs.p,rhs.v)+dot(lhs.v,rhs.p),
+ dot(lhs.p,rhs.dv)+2*dot(lhs.v,rhs.v)+dot(lhs.dv,rhs.p)
+ );
+}
+
+doubleAcc dot(const VectorAcc& lhs,const Vector& rhs) {
+ return doubleAcc( dot(lhs.p,rhs),
+ dot(lhs.v,rhs),
+ dot(lhs.dv,rhs)
+ );
+}
+
+doubleAcc dot(const Vector& lhs,const VectorAcc& rhs) {
+ return doubleAcc( dot(lhs,rhs.p),
+ dot(lhs,rhs.v),
+ dot(lhs,rhs.dv)
+ );
+}
+
+
+bool Equal(const VectorAcc& r1,const VectorAcc& r2,double eps) {
+ return (Equal(r1.p,r2.p,eps)
+ && Equal(r1.v,r2.v,eps)
+ && Equal(r1.dv,r2.dv,eps)
+ );
+}
+
+bool Equal(const Vector& r1,const VectorAcc& r2,double eps) {
+ return (Equal(r1,r2.p,eps)
+ && Equal(Vector::Zero(),r2.v,eps)
+ && Equal(Vector::Zero(),r2.dv,eps)
+ );
+}
+
+bool Equal(const VectorAcc& r1,const Vector& r2,double eps) {
+ return (Equal(r1.p,r2,eps)
+ && Equal(r1.v,Vector::Zero(),eps)
+ && Equal(r1.dv,Vector::Zero(),eps)
+ );
+}
+
+VectorAcc operator / (const VectorAcc& r1,double r2) {
+ return r1*(1.0/r2);
+}
+
+VectorAcc operator / (const VectorAcc& r2,const doubleAcc& r1) {
+ return r2*(1.0/r1);
+}
+
+
+
+/////////////////// RotationAcc /////////////////////////////////////
+
+RotationAcc operator* (const RotationAcc& r1,const RotationAcc& r2) {
+ return RotationAcc( r1.R * r2.R,
+ r1.w + r1.R*r2.w,
+ r1.dw + r1.w*(r1.R*r2.w) + r1.R*r2.dw
+ );
+}
+
+RotationAcc operator* (const Rotation& r1,const RotationAcc& r2) {
+ return RotationAcc( r1*r2.R, r1*r2.w, r1*r2.dw);
+}
+
+RotationAcc operator* (const RotationAcc& r1,const Rotation& r2) {
+ return RotationAcc( r1.R*r2, r1.w, r1.dw );
+}
+
+RotationAcc& RotationAcc::operator = (const RotationAcc& arg) {
+ R=arg.R;
+ w=arg.w;
+ dw=arg.dw;
+ return *this;
+}
+RotationAcc& RotationAcc::operator = (const Rotation& arg) {
+ R = arg;
+ w = Vector::Zero();
+ dw = Vector::Zero();
+ return *this;
+}
+
+RotationAcc RotationAcc::Identity() {
+ return RotationAcc(Rotation::Identity(),Vector::Zero(),Vector::Zero());
+}
+
+RotationAcc RotationAcc::Inverse() const {
+ return RotationAcc(R.Inverse(),-R.Inverse(w),-R.Inverse(dw));
+}
+
+VectorAcc RotationAcc::Inverse(const VectorAcc& arg) const {
+ VectorAcc tmp;
+ tmp.p = R.Inverse(arg.p);
+ tmp.v = R.Inverse(arg.v - w * arg.p);
+ tmp.dv = R.Inverse(arg.dv - dw*arg.p - w*(arg.v+R*tmp.v));
+ return tmp;
+}
+
+VectorAcc RotationAcc::Inverse(const Vector& arg) const {
+ VectorAcc tmp;
+ tmp.p = R.Inverse(arg);
+ tmp.v = R.Inverse(-w*arg);
+ tmp.dv = R.Inverse(-dw*arg - w*(R*tmp.v));
+ return tmp;
+}
+
+
+VectorAcc RotationAcc::operator*(const VectorAcc& arg) const {
+ VectorAcc tmp;
+ tmp.p = R*arg.p;
+ tmp.dv = R*arg.v;
+ tmp.v = w*tmp.p + tmp.dv;
+ tmp.dv = dw*tmp.p + w*(tmp.v + tmp.dv) + R*arg.dv;
+ return tmp;
+}
+
+VectorAcc operator*(const Rotation& R,const VectorAcc& x) {
+ return VectorAcc(R*x.p,R*x.v,R*x.dv);
+}
+
+VectorAcc RotationAcc::operator*(const Vector& arg) const {
+ VectorAcc tmp;
+ tmp.p = R*arg;
+ tmp.v = w*tmp.p;
+ tmp.dv = dw*tmp.p + w*tmp.v;
+ return tmp;
+}
+
+/*
+ // = Rotations
+ // The Rot... static functions give the value of the appropriate rotation matrix back.
+ // The DoRot... functions apply a rotation R to *this,such that *this = *this * R.
+
+ void RRotation::DoRotX(const RDouble& angle) {
+ w+=R*Vector(angle.grad,0,0);
+ R.DoRotX(angle.t);
+ }
+RotationAcc RotationAcc::RotX(const doubleAcc& angle) {
+ return RotationAcc(Rotation::RotX(angle.t),
+ Vector(angle.d,0,0),
+ Vector(angle.dd,0,0)
+ );
+}
+
+ void RRotation::DoRotY(const RDouble& angle) {
+ w+=R*Vector(0,angle.grad,0);
+ R.DoRotY(angle.t);
+ }
+RotationAcc RotationAcc::RotY(const doubleAcc& angle) {
+ return RotationAcc(
+ Rotation::RotX(angle.t),
+ Vector(0,angle.d,0),
+ Vector(0,angle.dd,0)
+ );
+}
+
+ void RRotation::DoRotZ(const RDouble& angle) {
+ w+=R*Vector(0,0,angle.grad);
+ R.DoRotZ(angle.t);
+ }
+RotationAcc RotationAcc::RotZ(const doubleAcc& angle) {
+ return RotationAcc(
+ Rotation::RotZ(angle.t),
+ Vector(0,0,angle.d),
+ Vector(0,0,angle.dd)
+ );
+}
+
+
+ RRotation RRotation::Rot(const Vector& rotvec,const RDouble& angle)
+ // rotvec has arbitrary norm
+ // rotation around a constant vector !
+ {
+ Vector v = rotvec.Normalize();
+ return RRotation(Rotation::Rot2(v,angle.t),v*angle.grad);
+ }
+
+ RRotation RRotation::Rot2(const Vector& rotvec,const RDouble& angle)
+ // rotvec is normalized.
+ {
+ return RRotation(Rotation::Rot2(rotvec,angle.t),rotvec*angle.grad);
+ }
+
+*/
+
+bool Equal(const RotationAcc& r1,const RotationAcc& r2,double eps) {
+ return (Equal(r1.w,r2.w,eps) && Equal(r1.R,r2.R,eps) && Equal(r1.dw,r2.dw,eps) );
+}
+bool Equal(const Rotation& r1,const RotationAcc& r2,double eps) {
+ return (Equal(Vector::Zero(),r2.w,eps) && Equal(r1,r2.R,eps) &&
+ Equal(Vector::Zero(),r2.dw,eps) );
+}
+bool Equal(const RotationAcc& r1,const Rotation& r2,double eps) {
+ return (Equal(r1.w,Vector::Zero(),eps) && Equal(r1.R,r2,eps) &&
+ Equal(r1.dw,Vector::Zero(),eps) );
+}
+
+
+// Methods and operators related to FrameAcc
+// They all delegate most of the work to RotationAcc and VectorAcc
+FrameAcc& FrameAcc::operator = (const FrameAcc& arg) {
+ M=arg.M;
+ p=arg.p;
+ return *this;
+}
+
+FrameAcc FrameAcc::Identity() {
+ return FrameAcc(RotationAcc::Identity(),VectorAcc::Zero());
+}
+
+
+FrameAcc operator *(const FrameAcc& lhs,const FrameAcc& rhs)
+{
+ return FrameAcc(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+FrameAcc operator *(const FrameAcc& lhs,const Frame& rhs)
+{
+ return FrameAcc(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+FrameAcc operator *(const Frame& lhs,const FrameAcc& rhs)
+{
+ return FrameAcc(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+
+VectorAcc FrameAcc::operator *(const VectorAcc & arg) const
+{
+ return M*arg+p;
+}
+VectorAcc FrameAcc::operator *(const Vector & arg) const
+{
+ return M*arg+p;
+}
+
+VectorAcc FrameAcc::Inverse(const VectorAcc& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+VectorAcc FrameAcc::Inverse(const Vector& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+FrameAcc FrameAcc::Inverse() const
+{
+ return FrameAcc(M.Inverse(),-M.Inverse(p));
+}
+
+FrameAcc& FrameAcc::operator =(const Frame & arg)
+{
+ M = arg.M;
+ p = arg.p;
+ return *this;
+}
+
+bool Equal(const FrameAcc& r1,const FrameAcc& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+bool Equal(const Frame& r1,const FrameAcc& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+bool Equal(const FrameAcc& r1,const Frame& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+
+
+Frame FrameAcc::GetFrame() const {
+ return Frame(M.R,p.p);
+}
+
+
+Twist FrameAcc::GetTwist() const {
+ return Twist(p.v,M.w);
+}
+
+
+Twist FrameAcc::GetAccTwist() const {
+ return Twist(p.dv,M.dw);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+TwistAcc TwistAcc::Zero()
+{
+ return TwistAcc(VectorAcc::Zero(),VectorAcc::Zero());
+}
+
+
+void TwistAcc::ReverseSign()
+{
+ vel.ReverseSign();
+ rot.ReverseSign();
+}
+
+TwistAcc TwistAcc::RefPoint(const VectorAcc& v_base_AB)
+ // Changes the reference point of the TwistAcc.
+ // The RVector v_base_AB is expressed in the same base as the TwistAcc
+ // The RVector v_base_AB is a RVector from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+{
+ return TwistAcc(this->vel+this->rot*v_base_AB,this->rot);
+}
+
+TwistAcc& TwistAcc::operator-=(const TwistAcc& arg)
+{
+ vel-=arg.vel;
+ rot -=arg.rot;
+ return *this;
+}
+
+TwistAcc& TwistAcc::operator+=(const TwistAcc& arg)
+{
+ vel+=arg.vel;
+ rot +=arg.rot;
+ return *this;
+}
+
+
+TwistAcc operator*(const TwistAcc& lhs,double rhs)
+{
+ return TwistAcc(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+TwistAcc operator*(double lhs,const TwistAcc& rhs)
+{
+ return TwistAcc(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+TwistAcc operator/(const TwistAcc& lhs,double rhs)
+{
+ return TwistAcc(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+
+TwistAcc operator*(const TwistAcc& lhs,const doubleAcc& rhs)
+{
+ return TwistAcc(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+TwistAcc operator*(const doubleAcc& lhs,const TwistAcc& rhs)
+{
+ return TwistAcc(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+TwistAcc operator/(const TwistAcc& lhs,const doubleAcc& rhs)
+{
+ return TwistAcc(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+
+
+// addition of TwistAcc's
+TwistAcc operator+(const TwistAcc& lhs,const TwistAcc& rhs)
+{
+ return TwistAcc(lhs.vel+rhs.vel,lhs.rot+rhs.rot);
+}
+
+TwistAcc operator-(const TwistAcc& lhs,const TwistAcc& rhs)
+{
+ return TwistAcc(lhs.vel-rhs.vel,lhs.rot-rhs.rot);
+}
+
+// unary -
+TwistAcc operator-(const TwistAcc& arg)
+{
+ return TwistAcc(-arg.vel,-arg.rot);
+}
+
+
+
+
+
+TwistAcc RotationAcc::Inverse(const TwistAcc& arg) const
+{
+ return TwistAcc(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+TwistAcc RotationAcc::operator * (const TwistAcc& arg) const
+{
+ return TwistAcc((*this)*arg.vel,(*this)*arg.rot);
+}
+
+TwistAcc RotationAcc::Inverse(const Twist& arg) const
+{
+ return TwistAcc(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+TwistAcc RotationAcc::operator * (const Twist& arg) const
+{
+ return TwistAcc((*this)*arg.vel,(*this)*arg.rot);
+}
+
+
+TwistAcc FrameAcc::operator * (const TwistAcc& arg) const
+{
+ TwistAcc tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+
+TwistAcc FrameAcc::operator * (const Twist& arg) const
+{
+ TwistAcc tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+
+TwistAcc FrameAcc::Inverse(const TwistAcc& arg) const
+{
+ TwistAcc tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+TwistAcc FrameAcc::Inverse(const Twist& arg) const
+{
+ TwistAcc tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+Twist TwistAcc::GetTwist() const {
+ return Twist(vel.p,rot.p);
+}
+
+Twist TwistAcc::GetTwistDot() const {
+ return Twist(vel.v,rot.v);
+}
+
+bool Equal(const TwistAcc& a,const TwistAcc& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+bool Equal(const Twist& a,const TwistAcc& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+bool Equal(const TwistAcc& a,const Twist& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+
diff --git a/intern/itasc/kdl/frames.cpp b/intern/itasc/kdl/frames.cpp
new file mode 100644
index 00000000000..7dcc39f2cd4
--- /dev/null
+++ b/intern/itasc/kdl/frames.cpp
@@ -0,0 +1,389 @@
+/***************************************************************************
+ frames.cxx - description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.ac.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ ***************************************************************************
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+#include "frames.hpp"
+
+namespace KDL {
+
+#ifndef KDL_INLINE
+#include "frames.inl"
+#endif
+
+void Frame::Make4x4(double * d)
+{
+ int i;
+ int j;
+ for (i=0;i<3;i++) {
+ for (j=0;j<3;j++)
+ d[i*4+j]=M(i,j);
+ d[i*4+3] = p(i)/1000;
+ }
+ for (j=0;j<3;j++)
+ d[12+j] = 0.;
+ d[15] = 1;
+}
+
+Frame Frame::DH_Craig1989(double a,double alpha,double d,double theta)
+// returns Modified Denavit-Hartenberg parameters (According to Craig)
+{
+ double ct,st,ca,sa;
+ ct = cos(theta);
+ st = sin(theta);
+ sa = sin(alpha);
+ ca = cos(alpha);
+ return Frame(Rotation(
+ ct, -st, 0,
+ st*ca, ct*ca, -sa,
+ st*sa, ct*sa, ca ),
+ Vector(
+ a, -sa*d, ca*d )
+ );
+}
+
+Frame Frame::DH(double a,double alpha,double d,double theta)
+// returns Denavit-Hartenberg parameters (Non-Modified DH)
+{
+ double ct,st,ca,sa;
+ ct = cos(theta);
+ st = sin(theta);
+ sa = sin(alpha);
+ ca = cos(alpha);
+ return Frame(Rotation(
+ ct, -st*ca, st*sa,
+ st, ct*ca, -ct*sa,
+ 0, sa, ca ),
+ Vector(
+ a*ct, a*st, d )
+ );
+}
+
+double Vector2::Norm() const
+{
+ double tmp0 = fabs(data[0]);
+ double tmp1 = fabs(data[1]);
+ if (tmp0 >= tmp1) {
+ if (tmp1 == 0)
+ return 0;
+ return tmp0*sqrt(1+sqr(tmp1/tmp0));
+ } else {
+ return tmp1*sqrt(1+sqr(tmp0/tmp1));
+ }
+}
+// makes v a unitvector and returns the norm of v.
+// if v is smaller than eps, Vector(1,0,0) is returned with norm 0.
+// if this is not good, check the return value of this method.
+double Vector2::Normalize(double eps) {
+ double v = this->Norm();
+ if (v < eps) {
+ *this = Vector2(1,0);
+ return v;
+ } else {
+ *this = (*this)/v;
+ return v;
+ }
+}
+
+
+// do some effort not to lose precision
+double Vector::Norm() const
+{
+ double tmp1;
+ double tmp2;
+ tmp1 = fabs(data[0]);
+ tmp2 = fabs(data[1]);
+ if (tmp1 >= tmp2) {
+ tmp2=fabs(data[2]);
+ if (tmp1 >= tmp2) {
+ if (tmp1 == 0) {
+ // only to everything exactly zero case, all other are handled correctly
+ return 0;
+ }
+ return tmp1*sqrt(1+sqr(data[1]/data[0])+sqr(data[2]/data[0]));
+ } else {
+ return tmp2*sqrt(1+sqr(data[0]/data[2])+sqr(data[1]/data[2]));
+ }
+ } else {
+ tmp1=fabs(data[2]);
+ if (tmp2 > tmp1) {
+ return tmp2*sqrt(1+sqr(data[0]/data[1])+sqr(data[2]/data[1]));
+ } else {
+ return tmp1*sqrt(1+sqr(data[0]/data[2])+sqr(data[1]/data[2]));
+ }
+ }
+}
+
+// makes v a unitvector and returns the norm of v.
+// if v is smaller than eps, Vector(1,0,0) is returned with norm 0.
+// if this is not good, check the return value of this method.
+double Vector::Normalize(double eps) {
+ double v = this->Norm();
+ if (v < eps) {
+ *this = Vector(1,0,0);
+ return v;
+ } else {
+ *this = (*this)/v;
+ return v;
+ }
+}
+
+
+bool Equal(const Rotation& a,const Rotation& b,double eps) {
+ return (Equal(a.data[0],b.data[0],eps) &&
+ Equal(a.data[1],b.data[1],eps) &&
+ Equal(a.data[2],b.data[2],eps) &&
+ Equal(a.data[3],b.data[3],eps) &&
+ Equal(a.data[4],b.data[4],eps) &&
+ Equal(a.data[5],b.data[5],eps) &&
+ Equal(a.data[6],b.data[6],eps) &&
+ Equal(a.data[7],b.data[7],eps) &&
+ Equal(a.data[8],b.data[8],eps) );
+}
+
+void Rotation::Ortho()
+{
+ double n;
+ n=sqrt(sqr(data[0])+sqr(data[3])+sqr(data[6]));n=(n>1e-10)?1.0/n:0.0;data[0]*=n;data[3]*=n;data[6]*=n;
+ n=sqrt(sqr(data[1])+sqr(data[4])+sqr(data[7]));n=(n>1e-10)?1.0/n:0.0;data[1]*=n;data[4]*=n;data[7]*=n;
+ n=sqrt(sqr(data[2])+sqr(data[5])+sqr(data[8]));n=(n>1e-10)?1.0/n:0.0;data[2]*=n;data[5]*=n;data[8]*=n;
+}
+
+Rotation operator *(const Rotation& lhs,const Rotation& rhs)
+// Complexity : 27M+27A
+{
+ return Rotation(
+ lhs.data[0]*rhs.data[0]+lhs.data[1]*rhs.data[3]+lhs.data[2]*rhs.data[6],
+ lhs.data[0]*rhs.data[1]+lhs.data[1]*rhs.data[4]+lhs.data[2]*rhs.data[7],
+ lhs.data[0]*rhs.data[2]+lhs.data[1]*rhs.data[5]+lhs.data[2]*rhs.data[8],
+ lhs.data[3]*rhs.data[0]+lhs.data[4]*rhs.data[3]+lhs.data[5]*rhs.data[6],
+ lhs.data[3]*rhs.data[1]+lhs.data[4]*rhs.data[4]+lhs.data[5]*rhs.data[7],
+ lhs.data[3]*rhs.data[2]+lhs.data[4]*rhs.data[5]+lhs.data[5]*rhs.data[8],
+ lhs.data[6]*rhs.data[0]+lhs.data[7]*rhs.data[3]+lhs.data[8]*rhs.data[6],
+ lhs.data[6]*rhs.data[1]+lhs.data[7]*rhs.data[4]+lhs.data[8]*rhs.data[7],
+ lhs.data[6]*rhs.data[2]+lhs.data[7]*rhs.data[5]+lhs.data[8]*rhs.data[8]
+ );
+
+}
+
+
+Rotation Rotation::RPY(double roll,double pitch,double yaw)
+ {
+ double ca1,cb1,cc1,sa1,sb1,sc1;
+ ca1 = cos(yaw); sa1 = sin(yaw);
+ cb1 = cos(pitch);sb1 = sin(pitch);
+ cc1 = cos(roll);sc1 = sin(roll);
+ return Rotation(ca1*cb1,ca1*sb1*sc1 - sa1*cc1,ca1*sb1*cc1 + sa1*sc1,
+ sa1*cb1,sa1*sb1*sc1 + ca1*cc1,sa1*sb1*cc1 - ca1*sc1,
+ -sb1,cb1*sc1,cb1*cc1);
+ }
+
+// Gives back a rotation matrix specified with RPY convention
+void Rotation::GetRPY(double& roll,double& pitch,double& yaw) const
+ {
+ if (fabs(data[6]) > 1.0 - epsilon ) {
+ roll = -sign(data[6]) * atan2(data[1], data[4]);
+ pitch= -sign(data[6]) * PI / 2;
+ yaw = 0.0 ;
+ } else {
+ roll = atan2(data[7], data[8]);
+ pitch = atan2(-data[6], sqrt( sqr(data[0]) +sqr(data[3]) ) );
+ yaw = atan2(data[3], data[0]);
+ }
+ }
+
+Rotation Rotation::EulerZYZ(double Alfa,double Beta,double Gamma) {
+ double sa,ca,sb,cb,sg,cg;
+ sa = sin(Alfa);ca = cos(Alfa);
+ sb = sin(Beta);cb = cos(Beta);
+ sg = sin(Gamma);cg = cos(Gamma);
+ return Rotation( ca*cb*cg-sa*sg, -ca*cb*sg-sa*cg, ca*sb,
+ sa*cb*cg+ca*sg, -sa*cb*sg+ca*cg, sa*sb,
+ -sb*cg , sb*sg, cb
+ );
+
+ }
+
+
+void Rotation::GetEulerZYZ(double& alfa,double& beta,double& gamma) const {
+ if (fabs(data[6]) < epsilon ) {
+ alfa=0.0;
+ if (data[8]>0) {
+ beta = 0.0;
+ gamma= atan2(-data[1],data[0]);
+ } else {
+ beta = PI;
+ gamma= atan2(data[1],-data[0]);
+ }
+ } else {
+ alfa=atan2(data[5], data[2]);
+ beta=atan2(sqrt( sqr(data[6]) +sqr(data[7]) ),data[8]);
+ gamma=atan2(data[7], -data[6]);
+ }
+ }
+
+Rotation Rotation::Rot(const Vector& rotaxis,double angle) {
+ // The formula is
+ // V.(V.tr) + st*[V x] + ct*(I-V.(V.tr))
+ // can be found by multiplying it with an arbitrary vector p
+ // and noting that this vector is rotated.
+ double ct = cos(angle);
+ double st = sin(angle);
+ double vt = 1-ct;
+ Vector rotvec = rotaxis;
+ rotvec.Normalize();
+ return Rotation(
+ ct + vt*rotvec(0)*rotvec(0),
+ -rotvec(2)*st + vt*rotvec(0)*rotvec(1),
+ rotvec(1)*st + vt*rotvec(0)*rotvec(2),
+ rotvec(2)*st + vt*rotvec(1)*rotvec(0),
+ ct + vt*rotvec(1)*rotvec(1),
+ -rotvec(0)*st + vt*rotvec(1)*rotvec(2),
+ -rotvec(1)*st + vt*rotvec(2)*rotvec(0),
+ rotvec(0)*st + vt*rotvec(2)*rotvec(1),
+ ct + vt*rotvec(2)*rotvec(2)
+ );
+ }
+
+Rotation Rotation::Rot2(const Vector& rotvec,double angle) {
+ // rotvec should be normalized !
+ // The formula is
+ // V.(V.tr) + st*[V x] + ct*(I-V.(V.tr))
+ // can be found by multiplying it with an arbitrary vector p
+ // and noting that this vector is rotated.
+ double ct = cos(angle);
+ double st = sin(angle);
+ double vt = 1-ct;
+ return Rotation(
+ ct + vt*rotvec(0)*rotvec(0),
+ -rotvec(2)*st + vt*rotvec(0)*rotvec(1),
+ rotvec(1)*st + vt*rotvec(0)*rotvec(2),
+ rotvec(2)*st + vt*rotvec(1)*rotvec(0),
+ ct + vt*rotvec(1)*rotvec(1),
+ -rotvec(0)*st + vt*rotvec(1)*rotvec(2),
+ -rotvec(1)*st + vt*rotvec(2)*rotvec(0),
+ rotvec(0)*st + vt*rotvec(2)*rotvec(1),
+ ct + vt*rotvec(2)*rotvec(2)
+ );
+}
+
+
+
+Vector Rotation::GetRot() const
+ // Returns a vector with the direction of the equiv. axis
+ // and its norm is angle
+ {
+ Vector axis = Vector((data[7]-data[5]),
+ (data[2]-data[6]),
+ (data[3]-data[1]) )/2;
+
+ double sa = axis.Norm();
+ double ca = (data[0]+data[4]+data[8]-1)/2.0;
+ double alfa;
+ if (sa > epsilon)
+ alfa = ::atan2(sa,ca)/sa;
+ else {
+ if (ca < 0.0) {
+ alfa = KDL::PI;
+ axis.data[0] = 0.0;
+ axis.data[1] = 0.0;
+ axis.data[2] = 0.0;
+ if (data[0] > 0.0) {
+ axis.data[0] = 1.0;
+ } else if (data[4] > 0.0) {
+ axis.data[1] = 1.0;
+ } else {
+ axis.data[2] = 1.0;
+ }
+ } else {
+ alfa = 0.0;
+ }
+ }
+ return axis * alfa;
+ }
+
+Vector2 Rotation::GetXZRot() const
+{
+ // [0,1,0] x Y
+ Vector2 axis(data[7], -data[1]);
+ double norm = axis.Normalize();
+ if (norm < epsilon) {
+ norm = (data[4] < 0.0) ? PI : 0.0;
+ } else {
+ norm = acos(data[4]);
+ }
+ return axis*norm;
+}
+
+
+/** Returns the rotation angle around the equiv. axis
+ * @param axis the rotation axis is returned in this variable
+ * @param eps : in the case of angle == 0 : rot axis is undefined and choosen
+ * to be +/- Z-axis
+ * in the case of angle == PI : 2 solutions, positive Z-component
+ * of the axis is choosen.
+ * @result returns the rotation angle (between [0..PI] )
+ * /todo :
+ * Check corresponding routines in rframes and rrframes
+ */
+double Rotation::GetRotAngle(Vector& axis,double eps) const {
+ double ca = (data[0]+data[4]+data[8]-1)/2.0;
+ if (ca>1-eps) {
+ // undefined choose the Z-axis, and angle 0
+ axis = Vector(0,0,1);
+ return 0;
+ }
+ if (ca < -1+eps) {
+ // two solutions, choose a positive Z-component of the axis
+ double z = sqrt( (data[8]+1)/2 );
+ double x = (data[2])/2/z;
+ double y = (data[5])/2/z;
+ axis = Vector( x,y,z );
+ return PI;
+ }
+ double angle = acos(ca);
+ double sa = sin(angle);
+ axis = Vector((data[7]-data[5])/2/sa,
+ (data[2]-data[6])/2/sa,
+ (data[3]-data[1])/2/sa );
+ return angle;
+}
+
+bool operator==(const Rotation& a,const Rotation& b) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return ( a.data[0]==b.data[0] &&
+ a.data[1]==b.data[1] &&
+ a.data[2]==b.data[2] &&
+ a.data[3]==b.data[3] &&
+ a.data[4]==b.data[4] &&
+ a.data[5]==b.data[5] &&
+ a.data[6]==b.data[6] &&
+ a.data[7]==b.data[7] &&
+ a.data[8]==b.data[8] );
+#endif
+}
+}
diff --git a/intern/itasc/kdl/frames.hpp b/intern/itasc/kdl/frames.hpp
new file mode 100644
index 00000000000..20590c5303e
--- /dev/null
+++ b/intern/itasc/kdl/frames.hpp
@@ -0,0 +1,1097 @@
+/***************************************************************************
+ frames.hpp `- description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ ***************************************************************************
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+/**
+ * \file
+ * \warning
+ * Efficienty can be improved by writing p2 = A*(B*(C*p1))) instead of
+ * p2=A*B*C*p1
+ *
+ * \par PROPOSED NAMING CONVENTION FOR FRAME-like OBJECTS
+ *
+ * \verbatim
+ * A naming convention of objects of the type defined in this file :
+ * (1) Frame : F...
+ * Rotation : R ...
+ * (2) Twist : T ...
+ * Wrench : W ...
+ * Vector : V ...
+ * This prefix is followed by :
+ * for category (1) :
+ * F_A_B : w.r.t. frame A, frame B expressed
+ * ( each column of F_A_B corresponds to an axis of B,
+ * expressed w.r.t. frame A )
+ * in mathematical convention :
+ * A
+ * F_A_B == F
+ * B
+ *
+ * for category (2) :
+ * V_B : a vector expressed w.r.t. frame B
+ *
+ * This can also be prepended by a name :
+ * e.g. : temporaryV_B
+ *
+ * With this convention one can write :
+ *
+ * F_A_B = F_B_A.Inverse();
+ * F_A_C = F_A_B * F_B_C;
+ * V_B = F_B_C * V_C; // both translation and rotation
+ * V_B = R_B_C * V_C; // only rotation
+ * \endverbatim
+ *
+ * \par CONVENTIONS FOR WHEN USED WITH ROBOTS :
+ *
+ * \verbatim
+ * world : represents the frame ([1 0 0,0 1 0,0 0 1],[0 0 0]')
+ * mp : represents mounting plate of a robot
+ * (i.e. everything before MP is constructed by robot manufacturer
+ * everything after MP is tool )
+ * tf : represents task frame of a robot
+ * (i.e. frame in which motion and force control is expressed)
+ * sf : represents sensor frame of a robot
+ * (i.e. frame at which the forces measured by the force sensor
+ * are expressed )
+ *
+ * Frame F_world_mp=...;
+ * Frame F_mp_sf(..)
+ * Frame F_mp_tf(,.)
+ *
+ * Wrench are measured in sensor frame SF, so one could write :
+ * Wrench_tf = F_mp_tf.Inverse()* ( F_mp_sf * Wrench_sf );
+ * \endverbatim
+ *
+ * \par CONVENTIONS REGARDING UNITS :
+ * Any consistent series of units can be used, e.g. N,mm,Nmm,..mm/sec
+ *
+ * \par Twist and Wrench transformations
+ * 3 different types of transformations do exist for the twists
+ * and wrenches.
+ *
+ * \verbatim
+ * 1) Frame * Twist or Frame * Wrench :
+ * this transforms both the velocity/force reference point
+ * and the basis to which the twist/wrench are expressed.
+ * 2) Rotation * Twist or Rotation * Wrench :
+ * this transforms the basis to which the twist/wrench are
+ * expressed, but leaves the reference point intact.
+ * 3) Twist.RefPoint(v_base_AB) or Wrench.RefPoint(v_base_AB)
+ * this transforms only the reference point. v is expressed
+ * in the same base as the twist/wrench and points from the
+ * old reference point to the new reference point.
+ * \endverbatim
+ *
+ * \par Complexity
+ * Sometimes the amount of work is given in the documentation
+ * e.g. 6M+3A means 6 multiplications and 3 additions.
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ ****************************************************************************/
+#ifndef KDL_FRAMES_H
+#define KDL_FRAMES_H
+
+
+#include "utilities/kdl-config.h"
+#include "utilities/utility.h"
+
+/////////////////////////////////////////////////////////////
+
+namespace KDL {
+
+
+
+class Vector;
+class Rotation;
+class Frame;
+class Wrench;
+class Twist;
+class Vector2;
+class Rotation2;
+class Frame2;
+
+
+
+/**
+ * \brief A concrete implementation of a 3 dimensional vector class
+ */
+class Vector
+{
+public:
+ double data[3];
+ //! Does not initialise the Vector to zero. use Vector::Zero() or SetToZero for that
+ inline Vector() {data[0]=data[1]=data[2] = 0.0;}
+
+ //! Constructs a vector out of the three values x, y and z
+ inline Vector(double x,double y, double z);
+
+ //! Constructs a vector out of an array of three values x, y and z
+ inline Vector(double* xyz);
+
+ //! Constructs a vector out of an array of three values x, y and z
+ inline Vector(float* xyz);
+
+ //! Assignment operator. The normal copy by value semantics.
+ inline Vector(const Vector& arg);
+
+ //! store vector components in array
+ inline void GetValue(double* xyz) const;
+
+ //! Assignment operator. The normal copy by value semantics.
+ inline Vector& operator = ( const Vector& arg);
+
+ //! Access to elements, range checked when NDEBUG is not set, from 0..2
+ inline double operator()(int index) const;
+
+ //! Access to elements, range checked when NDEBUG is not set, from 0..2
+ inline double& operator() (int index);
+
+ //! Equivalent to double operator()(int index) const
+ double operator[] ( int index ) const
+ {
+ return this->operator() ( index );
+ }
+
+ //! Equivalent to double& operator()(int index)
+ double& operator[] ( int index )
+ {
+ return this->operator() ( index );
+ }
+
+ inline double x() const;
+ inline double y() const;
+ inline double z() const;
+ inline void x(double);
+ inline void y(double);
+ inline void z(double);
+
+ //! Reverses the sign of the Vector object itself
+ inline void ReverseSign();
+
+
+ //! subtracts a vector from the Vector object itself
+ inline Vector& operator-=(const Vector& arg);
+
+
+ //! Adds a vector from the Vector object itself
+ inline Vector& operator +=(const Vector& arg);
+
+ //! Scalar multiplication is defined
+ inline friend Vector operator*(const Vector& lhs,double rhs);
+ //! Scalar multiplication is defined
+ inline friend Vector operator*(double lhs,const Vector& rhs);
+ //! Scalar division is defined
+
+ inline friend Vector operator/(const Vector& lhs,double rhs);
+ inline friend Vector operator+(const Vector& lhs,const Vector& rhs);
+ inline friend Vector operator-(const Vector& lhs,const Vector& rhs);
+ inline friend Vector operator*(const Vector& lhs,const Vector& rhs);
+ inline friend Vector operator-(const Vector& arg);
+ inline friend double dot(const Vector& lhs,const Vector& rhs);
+
+ //! To have a uniform operator to put an element to zero, for scalar values
+ //! and for objects.
+ inline friend void SetToZero(Vector& v);
+
+ //! @return a zero vector
+ inline static Vector Zero();
+
+ /** Normalizes this vector and returns it norm
+ * makes v a unitvector and returns the norm of v.
+ * if v is smaller than eps, Vector(1,0,0) is returned with norm 0.
+ * if this is not good, check the return value of this method.
+ */
+ double Normalize(double eps=epsilon);
+
+ //! @return the norm of the vector
+ double Norm() const;
+
+
+
+ //! a 3D vector where the 2D vector v is put in the XY plane
+ inline void Set2DXY(const Vector2& v);
+ //! a 3D vector where the 2D vector v is put in the YZ plane
+ inline void Set2DYZ(const Vector2& v);
+ //! a 3D vector where the 2D vector v is put in the ZX plane
+ inline void Set2DZX(const Vector2& v);
+ //! a 3D vector where the 2D vector v_XY is put in the XY plane of the frame F_someframe_XY.
+ inline void Set2DPlane(const Frame& F_someframe_XY,const Vector2& v_XY);
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Vector& a,const Vector& b,double eps=epsilon);
+
+ //! return a normalized vector
+ inline friend Vector Normalize(const Vector& a, double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const Vector& a,const Vector& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const Vector& a,const Vector& b);
+
+ friend class Rotation;
+ friend class Frame;
+};
+
+
+/**
+ \brief represents rotations in 3 dimensional space.
+
+ This class represents a rotation matrix with the following
+ conventions :
+ \verbatim
+ Suppose V2 = R*V, (1)
+ V is expressed in frame B
+ V2 is expressed in frame A
+ This matrix R consists of 3 collumns [ X,Y,Z ],
+ X,Y, and Z contain the axes of frame B, expressed in frame A
+ Because of linearity expr(1) is valid.
+ \endverbatim
+ This class only represents rotational_interpolation, not translation
+ Two interpretations are possible for rotation angles.
+ * if you rotate with angle around X frame A to have frame B,
+ then the result of SetRotX is equal to frame B expressed wrt A.
+ In code:
+ \verbatim
+ Rotation R;
+ F_A_B = R.SetRotX(angle);
+ \endverbatim
+ * Secondly, if you take the following code :
+ \verbatim
+ Vector p,p2; Rotation R;
+ R.SetRotX(angle);
+ p2 = R*p;
+ \endverbatim
+ then the frame p2 is rotated around X axis with (-angle).
+ Analogue reasonings can be applyd to SetRotY,SetRotZ,SetRot
+ \par type
+ Concrete implementation
+*/
+class Rotation
+{
+public:
+ double data[9];
+
+ inline Rotation() {
+ *this = Rotation::Identity();
+ }
+ inline Rotation(double Xx,double Yx,double Zx,
+ double Xy,double Yy,double Zy,
+ double Xz,double Yz,double Zz);
+ inline Rotation(const Vector& x,const Vector& y,const Vector& z);
+ // default copy constructor is sufficient
+
+ inline void setValue(float* oglmat);
+ inline void getValue(float* oglmat) const;
+
+ inline Rotation& operator=(const Rotation& arg);
+
+ //! Defines a multiplication R*V between a Rotation R and a Vector V.
+ //! Complexity : 9M+6A
+ inline Vector operator*(const Vector& v) const;
+
+ //! Access to elements 0..2,0..2, bounds are checked when NDEBUG is not set
+ inline double& operator()(int i,int j);
+
+ //! Access to elements 0..2,0..2, bounds are checked when NDEBUG is not set
+ inline double operator() (int i,int j) const;
+
+ friend Rotation operator *(const Rotation& lhs,const Rotation& rhs);
+
+ //! Sets the value of *this to its inverse.
+ inline void SetInverse();
+
+ //! Gives back the inverse rotation matrix of *this.
+ inline Rotation Inverse() const;
+
+ //! The same as R.Inverse()*v but more efficient.
+ inline Vector Inverse(const Vector& v) const;
+
+ //! The same as R.Inverse()*arg but more efficient.
+ inline Wrench Inverse(const Wrench& arg) const;
+
+ //! The same as R.Inverse()*arg but more efficient.
+ inline Twist Inverse(const Twist& arg) const;
+
+ //! Gives back an identity rotaton matrix
+ inline static Rotation Identity();
+
+
+// = Rotations
+ //! The Rot... static functions give the value of the appropriate rotation matrix back.
+ inline static Rotation RotX(double angle);
+ //! The Rot... static functions give the value of the appropriate rotation matrix back.
+ inline static Rotation RotY(double angle);
+ //! The Rot... static functions give the value of the appropriate rotation matrix back.
+ inline static Rotation RotZ(double angle);
+ //! The DoRot... functions apply a rotation R to *this,such that *this = *this * Rot..
+ //! DoRot... functions are only defined when they can be executed more efficiently
+ inline void DoRotX(double angle);
+ //! The DoRot... functions apply a rotation R to *this,such that *this = *this * Rot..
+ //! DoRot... functions are only defined when they can be executed more efficiently
+ inline void DoRotY(double angle);
+ //! The DoRot... functions apply a rotation R to *this,such that *this = *this * Rot..
+ //! DoRot... functions are only defined when they can be executed more efficiently
+ inline void DoRotZ(double angle);
+
+ //! Along an arbitrary axes. It is not necessary to normalize rotaxis.
+ //! returns identity rotation matrix in the case that the norm of rotaxis
+ //! is to small to be used.
+ // @see Rot2 if you want to handle this error in another way.
+ static Rotation Rot(const Vector& rotaxis,double angle);
+
+ //! Along an arbitrary axes. rotvec should be normalized.
+ static Rotation Rot2(const Vector& rotvec,double angle);
+
+ // make sure the matrix is a pure rotation (no scaling)
+ void Ortho();
+
+ //! Returns a vector with the direction of the equiv. axis
+ //! and its norm is angle
+ Vector GetRot() const;
+
+ //! Returns a 2D vector representing the equivalent rotation in the XZ plane that brings the
+ //! Y axis onto the Matrix Y axis and its norm is angle
+ Vector2 GetXZRot() const;
+
+ /** Returns the rotation angle around the equiv. axis
+ * @param axis the rotation axis is returned in this variable
+ * @param eps : in the case of angle == 0 : rot axis is undefined and choosen
+ * to be +/- Z-axis
+ * in the case of angle == PI : 2 solutions, positive Z-component
+ * of the axis is choosen.
+ * @result returns the rotation angle (between [0..PI] )
+ */
+ double GetRotAngle(Vector& axis,double eps=epsilon) const;
+
+
+ //! Gives back a rotation matrix specified with EulerZYZ convention :
+ //! First rotate around Z with alfa,
+ //! then around the new Y with beta, then around
+ //! new Z with gamma.
+ static Rotation EulerZYZ(double Alfa,double Beta,double Gamma);
+
+ //! Gives back the EulerZYZ convention description of the rotation matrix :
+ //! First rotate around Z with alfa,
+ //! then around the new Y with beta, then around
+ //! new Z with gamma.
+ //!
+ //! Variables are bound by
+ //! (-PI <= alfa <= PI),
+ //! (0 <= beta <= PI),
+ //! (-PI <= alfa <= PI)
+ void GetEulerZYZ(double& alfa,double& beta,double& gamma) const;
+
+
+ //! Sets the value of this object to a rotation specified with RPY convention:
+ //! first rotate around X with roll, then around the
+ //! old Y with pitch, then around old Z with alfa
+ static Rotation RPY(double roll,double pitch,double yaw);
+
+ //! Gives back a vector in RPY coordinates, variables are bound by
+ //! -PI <= roll <= PI
+ //! -PI <= Yaw <= PI
+ //! -PI/2 <= PITCH <= PI/2
+ //!
+ //! convention : first rotate around X with roll, then around the
+ //! old Y with pitch, then around old Z with alfa
+ void GetRPY(double& roll,double& pitch,double& yaw) const;
+
+
+ //! Gives back a rotation matrix specified with EulerZYX convention :
+ //! First rotate around Z with alfa,
+ //! then around the new Y with beta, then around
+ //! new X with gamma.
+ //!
+ //! closely related to RPY-convention
+ inline static Rotation EulerZYX(double Alfa,double Beta,double Gamma) {
+ return RPY(Gamma,Beta,Alfa);
+ }
+
+ //! GetEulerZYX gets the euler ZYX parameters of a rotation :
+ //! First rotate around Z with alfa,
+ //! then around the new Y with beta, then around
+ //! new X with gamma.
+ //!
+ //! Range of the results of GetEulerZYX :
+ //! -PI <= alfa <= PI
+ //! -PI <= gamma <= PI
+ //! -PI/2 <= beta <= PI/2
+ //!
+ //! Closely related to RPY-convention.
+ inline void GetEulerZYX(double& Alfa,double& Beta,double& Gamma) const {
+ GetRPY(Gamma,Beta,Alfa);
+ }
+
+ //! Transformation of the base to which the twist is expressed.
+ //! Complexity : 18M+12A
+ //! @see Frame*Twist for a transformation that also transforms
+ //! the velocity reference point.
+ inline Twist operator * (const Twist& arg) const;
+
+ //! Transformation of the base to which the wrench is expressed.
+ //! Complexity : 18M+12A
+ //! @see Frame*Wrench for a transformation that also transforms
+ //! the force reference point.
+ inline Wrench operator * (const Wrench& arg) const;
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline Vector UnitX() const {
+ return Vector(data[0],data[3],data[6]);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline void UnitX(const Vector& X) {
+ data[0] = X(0);
+ data[3] = X(1);
+ data[6] = X(2);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline Vector UnitY() const {
+ return Vector(data[1],data[4],data[7]);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline void UnitY(const Vector& X) {
+ data[1] = X(0);
+ data[4] = X(1);
+ data[7] = X(2);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline Vector UnitZ() const {
+ return Vector(data[2],data[5],data[8]);
+ }
+
+ //! Access to the underlying unitvectors of the rotation matrix
+ inline void UnitZ(const Vector& X) {
+ data[2] = X(0);
+ data[5] = X(1);
+ data[8] = X(2);
+ }
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ friend bool Equal(const Rotation& a,const Rotation& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ friend bool operator==(const Rotation& a,const Rotation& b);
+ //! The literal inequality operator!=()
+ friend bool operator!=(const Rotation& a,const Rotation& b);
+
+ friend class Frame;
+};
+ bool operator==(const Rotation& a,const Rotation& b);
+
+
+
+/**
+ \brief represents a frame transformation in 3D space (rotation + translation)
+
+ if V2 = Frame*V1 (V2 expressed in frame A, V1 expressed in frame B)
+ then V2 = Frame.M*V1+Frame.p
+
+ Frame.M contains columns that represent the axes of frame B wrt frame A
+ Frame.p contains the origin of frame B expressed in frame A.
+*/
+class Frame {
+public:
+ Vector p; //!< origine of the Frame
+ Rotation M; //!< Orientation of the Frame
+
+public:
+
+ inline Frame(const Rotation& R,const Vector& V);
+
+ //! The rotation matrix defaults to identity
+ explicit inline Frame(const Vector& V);
+ //! The position matrix defaults to zero
+ explicit inline Frame(const Rotation& R);
+
+ inline void setValue(float* oglmat);
+ inline void getValue(float* oglmat) const;
+
+ inline Frame() {}
+ //! The copy constructor. Normal copy by value semantics.
+ inline Frame(const Frame& arg);
+
+ //! Reads data from an double array
+ //\TODO should be formulated as a constructor
+ void Make4x4(double* d);
+
+ //! Treats a frame as a 4x4 matrix and returns element i,j
+ //! Access to elements 0..3,0..3, bounds are checked when NDEBUG is not set
+ inline double operator()(int i,int j);
+
+ //! Treats a frame as a 4x4 matrix and returns element i,j
+ //! Access to elements 0..3,0..3, bounds are checked when NDEBUG is not set
+ inline double operator() (int i,int j) const;
+
+ // = Inverse
+ //! Gives back inverse transformation of a Frame
+ inline Frame Inverse() const;
+
+ //! The same as p2=R.Inverse()*p but more efficient.
+ inline Vector Inverse(const Vector& arg) const;
+
+ //! The same as p2=R.Inverse()*p but more efficient.
+ inline Wrench Inverse(const Wrench& arg) const;
+
+ //! The same as p2=R.Inverse()*p but more efficient.
+ inline Twist Inverse(const Twist& arg) const;
+
+ //! Normal copy-by-value semantics.
+ inline Frame& operator = (const Frame& arg);
+
+ //! Transformation of the base to which the vector
+ //! is expressed.
+ inline Vector operator * (const Vector& arg) const;
+
+ //! Transformation of both the force reference point
+ //! and of the base to which the wrench is expressed.
+ //! look at Rotation*Wrench operator for a transformation
+ //! of only the base to which the twist is expressed.
+ //!
+ //! Complexity : 24M+18A
+ inline Wrench operator * (const Wrench& arg) const;
+
+ //! Transformation of both the velocity reference point
+ //! and of the base to which the twist is expressed.
+ //! look at Rotation*Twist for a transformation of only the
+ //! base to which the twist is expressed.
+ //!
+ //! Complexity : 24M+18A
+ inline Twist operator * (const Twist& arg) const;
+
+ //! Composition of two frames.
+ inline friend Frame operator *(const Frame& lhs,const Frame& rhs);
+
+ //! @return the identity transformation Frame(Rotation::Identity(),Vector::Zero()).
+ inline static Frame Identity();
+
+ //! The twist <t_this> is expressed wrt the current
+ //! frame. This frame is integrated into an updated frame with
+ //! <samplefrequency>. Very simple first order integration rule.
+ inline void Integrate(const Twist& t_this,double frequency);
+
+ /*
+ // DH_Craig1989 : constructs a transformationmatrix
+ // T_link(i-1)_link(i) with the Denavit-Hartenberg convention as
+ // described in the Craigs book: Craig, J. J.,Introduction to
+ // Robotics: Mechanics and Control, Addison-Wesley,
+ // isbn:0-201-10326-5, 1986.
+ //
+ // Note that the frame is a redundant way to express the information
+ // in the DH-convention.
+ // \verbatim
+ // Parameters in full : a(i-1),alpha(i-1),d(i),theta(i)
+ //
+ // axis i-1 is connected by link i-1 to axis i numbering axis 1
+ // to axis n link 0 (immobile base) to link n
+ //
+ // link length a(i-1) length of the mutual perpendicular line
+ // (normal) between the 2 axes. This normal runs from (i-1) to
+ // (i) axis.
+ //
+ // link twist alpha(i-1): construct plane perpendicular to the
+ // normal project axis(i-1) and axis(i) into plane angle from
+ // (i-1) to (i) measured in the direction of the normal
+ //
+ // link offset d(i) signed distance between normal (i-1) to (i)
+ // and normal (i) to (i+1) along axis i joint angle theta(i)
+ // signed angle between normal (i-1) to (i) and normal (i) to
+ // (i+1) along axis i
+ //
+ // First and last joints : a(0)= a(n) = 0
+ // alpha(0) = alpha(n) = 0
+ //
+ // PRISMATIC : theta(1) = 0 d(1) arbitrarily
+ //
+ // REVOLUTE : theta(1) arbitrarily d(1) = 0
+ //
+ // Not unique : if intersecting joint axis 2 choices for normal
+ // Frame assignment of the DH convention : Z(i-1) follows axis
+ // (i-1) X(i-1) is the normal between axis(i-1) and axis(i)
+ // Y(i-1) follows out of Z(i-1) and X(i-1)
+ //
+ // a(i-1) = distance from Z(i-1) to Z(i) along X(i-1)
+ // alpha(i-1) = angle between Z(i-1) to Z(i) along X(i-1)
+ // d(i) = distance from X(i-1) to X(i) along Z(i)
+ // theta(i) = angle between X(i-1) to X(i) along X(i)
+ // \endverbatim
+ */
+ static Frame DH_Craig1989(double a,double alpha,double d,double theta);
+
+ // DH : constructs a transformationmatrix T_link(i-1)_link(i) with
+ // the Denavit-Hartenberg convention as described in the original
+ // publictation: Denavit, J. and Hartenberg, R. S., A kinematic
+ // notation for lower-pair mechanisms based on matrices, ASME
+ // Journal of Applied Mechanics, 23:215-221, 1955.
+
+ static Frame DH(double a,double alpha,double d,double theta);
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Frame& a,const Frame& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const Frame& a,const Frame& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const Frame& a,const Frame& b);
+};
+
+/**
+ * \brief represents both translational and rotational velocities.
+ *
+ * This class represents a twist. A twist is the combination of translational
+ * velocity and rotational velocity applied at one point.
+*/
+class Twist {
+public:
+ Vector vel; //!< The velocity of that point
+ Vector rot; //!< The rotational velocity of that point.
+public:
+
+ //! The default constructor initialises to Zero via the constructor of Vector.
+ Twist():vel(),rot() {};
+
+ Twist(const Vector& _vel,const Vector& _rot):vel(_vel),rot(_rot) {};
+
+ inline Twist& operator-=(const Twist& arg);
+ inline Twist& operator+=(const Twist& arg);
+ //! index-based access to components, first vel(0..2), then rot(3..5)
+ inline double& operator()(int i);
+
+ //! index-based access to components, first vel(0..2), then rot(3..5)
+ //! For use with a const Twist
+ inline double operator()(int i) const;
+
+ double operator[] ( int index ) const
+ {
+ return this->operator() ( index );
+ }
+
+ double& operator[] ( int index )
+ {
+ return this->operator() ( index );
+ }
+
+ inline friend Twist operator*(const Twist& lhs,double rhs);
+ inline friend Twist operator*(double lhs,const Twist& rhs);
+ inline friend Twist operator/(const Twist& lhs,double rhs);
+ inline friend Twist operator+(const Twist& lhs,const Twist& rhs);
+ inline friend Twist operator-(const Twist& lhs,const Twist& rhs);
+ inline friend Twist operator-(const Twist& arg);
+ inline friend double dot(const Twist& lhs,const Wrench& rhs);
+ inline friend double dot(const Wrench& rhs,const Twist& lhs);
+ inline friend void SetToZero(Twist& v);
+
+
+ //! @return a zero Twist : Twist(Vector::Zero(),Vector::Zero())
+ static inline Twist Zero();
+
+ //! Reverses the sign of the twist
+ inline void ReverseSign();
+
+ //! Changes the reference point of the twist.
+ //! The vector v_base_AB is expressed in the same base as the twist
+ //! The vector v_base_AB is a vector from the old point to
+ //! the new point.
+ //!
+ //! Complexity : 6M+6A
+ inline Twist RefPoint(const Vector& v_base_AB) const;
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Twist& a,const Twist& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const Twist& a,const Twist& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const Twist& a,const Twist& b);
+
+// = Friends
+ friend class Rotation;
+ friend class Frame;
+
+};
+
+/**
+ * \brief represents both translational and rotational acceleration.
+ *
+ * This class represents an acceleration twist. A acceleration twist is
+ * the combination of translational
+ * acceleration and rotational acceleration applied at one point.
+*/
+/*
+class AccelerationTwist {
+public:
+ Vector trans; //!< The translational acceleration of that point
+ Vector rot; //!< The rotational acceleration of that point.
+public:
+
+ //! The default constructor initialises to Zero via the constructor of Vector.
+ AccelerationTwist():trans(),rot() {};
+
+ AccelerationTwist(const Vector& _trans,const Vector& _rot):trans(_trans),rot(_rot) {};
+
+ inline AccelerationTwist& operator-=(const AccelerationTwist& arg);
+ inline AccelerationTwist& operator+=(const AccelerationTwist& arg);
+ //! index-based access to components, first vel(0..2), then rot(3..5)
+ inline double& operator()(int i);
+
+ //! index-based access to components, first vel(0..2), then rot(3..5)
+ //! For use with a const AccelerationTwist
+ inline double operator()(int i) const;
+
+ double operator[] ( int index ) const
+ {
+ return this->operator() ( index );
+ }
+
+ double& operator[] ( int index )
+ {
+ return this->operator() ( index );
+ }
+
+ inline friend AccelerationTwist operator*(const AccelerationTwist& lhs,double rhs);
+ inline friend AccelerationTwist operator*(double lhs,const AccelerationTwist& rhs);
+ inline friend AccelerationTwist operator/(const AccelerationTwist& lhs,double rhs);
+ inline friend AccelerationTwist operator+(const AccelerationTwist& lhs,const AccelerationTwist& rhs);
+ inline friend AccelerationTwist operator-(const AccelerationTwist& lhs,const AccelerationTwist& rhs);
+ inline friend AccelerationTwist operator-(const AccelerationTwist& arg);
+ //inline friend double dot(const AccelerationTwist& lhs,const Wrench& rhs);
+ //inline friend double dot(const Wrench& rhs,const AccelerationTwist& lhs);
+ inline friend void SetToZero(AccelerationTwist& v);
+
+
+ //! @return a zero AccelerationTwist : AccelerationTwist(Vector::Zero(),Vector::Zero())
+ static inline AccelerationTwist Zero();
+
+ //! Reverses the sign of the AccelerationTwist
+ inline void ReverseSign();
+
+ //! Changes the reference point of the AccelerationTwist.
+ //! The vector v_base_AB is expressed in the same base as the AccelerationTwist
+ //! The vector v_base_AB is a vector from the old point to
+ //! the new point.
+ //!
+ //! Complexity : 6M+6A
+ inline AccelerationTwist RefPoint(const Vector& v_base_AB) const;
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const AccelerationTwist& a,const AccelerationTwist& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const AccelerationTwist& a,const AccelerationTwist& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const AccelerationTwist& a,const AccelerationTwist& b);
+
+// = Friends
+ friend class Rotation;
+ friend class Frame;
+
+};
+*/
+/**
+ * \brief represents the combination of a force and a torque.
+ *
+ * This class represents a Wrench. A Wrench is the force and torque applied at a point
+ */
+class Wrench
+{
+public:
+ Vector force; //!< Force that is applied at the origin of the current ref frame
+ Vector torque; //!< Torque that is applied at the origin of the current ref frame
+public:
+
+ //! Does initialise force and torque to zero via the underlying constructor of Vector
+ Wrench():force(),torque() {};
+ Wrench(const Vector& _force,const Vector& _torque):force(_force),torque(_torque) {};
+
+// = Operators
+ inline Wrench& operator-=(const Wrench& arg);
+ inline Wrench& operator+=(const Wrench& arg);
+
+ //! index-based access to components, first force(0..2), then torque(3..5)
+ inline double& operator()(int i);
+
+ //! index-based access to components, first force(0..2), then torque(3..5)
+ //! for use with a const Wrench
+ inline double operator()(int i) const;
+
+ double operator[] ( int index ) const
+ {
+ return this->operator() ( index );
+ }
+
+ double& operator[] ( int index )
+ {
+ return this->operator() ( index );
+ }
+
+ //! Scalar multiplication
+ inline friend Wrench operator*(const Wrench& lhs,double rhs);
+ //! Scalar multiplication
+ inline friend Wrench operator*(double lhs,const Wrench& rhs);
+ //! Scalar division
+ inline friend Wrench operator/(const Wrench& lhs,double rhs);
+
+ inline friend Wrench operator+(const Wrench& lhs,const Wrench& rhs);
+ inline friend Wrench operator-(const Wrench& lhs,const Wrench& rhs);
+
+ //! An unary - operator
+ inline friend Wrench operator-(const Wrench& arg);
+
+ //! Sets the Wrench to Zero, to have a uniform function that sets an object or
+ //! double to zero.
+ inline friend void SetToZero(Wrench& v);
+
+ //! @return a zero Wrench
+ static inline Wrench Zero();
+
+ //! Reverses the sign of the current Wrench
+ inline void ReverseSign();
+
+ //! Changes the reference point of the wrench.
+ //! The vector v_base_AB is expressed in the same base as the twist
+ //! The vector v_base_AB is a vector from the old point to
+ //! the new point.
+ //!
+ //! Complexity : 6M+6A
+ inline Wrench RefPoint(const Vector& v_base_AB) const;
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Wrench& a,const Wrench& b,double eps=epsilon);
+
+ //! The literal equality operator==(), also identical.
+ inline friend bool operator==(const Wrench& a,const Wrench& b);
+ //! The literal inequality operator!=().
+ inline friend bool operator!=(const Wrench& a,const Wrench& b);
+
+ friend class Rotation;
+ friend class Frame;
+
+
+};
+
+
+//! 2D version of Vector
+class Vector2
+{
+ double data[2];
+public:
+ //! Does not initialise to Zero().
+ Vector2() {data[0]=data[1] = 0.0;}
+ inline Vector2(double x,double y);
+ inline Vector2(const Vector2& arg);
+ inline Vector2(double* xyz);
+ inline Vector2(float* xyz);
+
+ inline Vector2& operator = ( const Vector2& arg);
+
+ //! Access to elements, range checked when NDEBUG is not set, from 0..1
+ inline double operator()(int index) const;
+
+ //! Access to elements, range checked when NDEBUG is not set, from 0..1
+ inline double& operator() (int index);
+
+ //! store vector components in array
+ inline void GetValue(double* xy) const;
+
+ inline void ReverseSign();
+ inline Vector2& operator-=(const Vector2& arg);
+ inline Vector2& operator +=(const Vector2& arg);
+
+
+ inline friend Vector2 operator*(const Vector2& lhs,double rhs);
+ inline friend Vector2 operator*(double lhs,const Vector2& rhs);
+ inline friend Vector2 operator/(const Vector2& lhs,double rhs);
+ inline friend Vector2 operator+(const Vector2& lhs,const Vector2& rhs);
+ inline friend Vector2 operator-(const Vector2& lhs,const Vector2& rhs);
+ inline friend Vector2 operator*(const Vector2& lhs,const Vector2& rhs);
+ inline friend Vector2 operator-(const Vector2& arg);
+ inline friend void SetToZero(Vector2& v);
+
+ //! @return a zero 2D vector.
+ inline static Vector2 Zero();
+
+ /** Normalizes this vector and returns it norm
+ * makes v a unitvector and returns the norm of v.
+ * if v is smaller than eps, Vector(1,0,0) is returned with norm 0.
+ * if this is not good, check the return value of this method.
+ */
+ double Normalize(double eps=epsilon);
+
+ //! @return the norm of the vector
+ inline double Norm() const;
+
+ //! projects v in its XY plane, and sets *this to these values
+ inline void Set3DXY(const Vector& v);
+
+ //! projects v in its YZ plane, and sets *this to these values
+ inline void Set3DYZ(const Vector& v);
+
+ //! projects v in its ZX plane, and sets *this to these values
+ inline void Set3DZX(const Vector& v);
+
+ //! projects v_someframe in the XY plane of F_someframe_XY,
+ //! and sets *this to these values
+ //! expressed wrt someframe.
+ inline void Set3DPlane(const Frame& F_someframe_XY,const Vector& v_someframe);
+
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Vector2& a,const Vector2& b,double eps=epsilon);
+
+ friend class Rotation2;
+};
+
+
+//! A 2D Rotation class, for conventions see Rotation. For further documentation
+//! of the methods see Rotation class.
+class Rotation2
+{
+ double s,c;
+ //! c,s represent cos(angle), sin(angle), this also represents first col. of rot matrix
+ //! from outside, this class behaves as if it would store the complete 2x2 matrix.
+public:
+ //! Default constructor does NOT initialise to Zero().
+ Rotation2() {c=1.0;s=0.0;}
+
+ explicit Rotation2(double angle_rad):s(sin(angle_rad)),c(cos(angle_rad)) {}
+
+ Rotation2(double ca,double sa):s(sa),c(ca){}
+
+ inline Rotation2& operator=(const Rotation2& arg);
+ inline Vector2 operator*(const Vector2& v) const;
+ //! Access to elements 0..1,0..1, bounds are checked when NDEBUG is not set
+ inline double operator() (int i,int j) const;
+
+ inline friend Rotation2 operator *(const Rotation2& lhs,const Rotation2& rhs);
+
+ inline void SetInverse();
+ inline Rotation2 Inverse() const;
+ inline Vector2 Inverse(const Vector2& v) const;
+
+ inline void SetIdentity();
+ inline static Rotation2 Identity();
+
+
+ //! The SetRot.. functions set the value of *this to the appropriate rotation matrix.
+ inline void SetRot(double angle);
+
+ //! The Rot... static functions give the value of the appropriate rotation matrix bac
+ inline static Rotation2 Rot(double angle);
+
+ //! Gets the angle (in radians)
+ inline double GetRot() const;
+
+ //! do not use operator == because the definition of Equal(.,.) is slightly
+ //! different. It compares whether the 2 arguments are equal in an eps-interval
+ inline friend bool Equal(const Rotation2& a,const Rotation2& b,double eps=epsilon);
+};
+
+//! A 2D frame class, for further documentation see the Frames class
+//! for methods with unchanged semantics.
+class Frame2
+ {
+public:
+ Vector2 p; //!< origine of the Frame
+ Rotation2 M; //!< Orientation of the Frame
+
+public:
+
+ inline Frame2(const Rotation2& R,const Vector2& V);
+ explicit inline Frame2(const Vector2& V);
+ explicit inline Frame2(const Rotation2& R);
+ inline Frame2(void);
+ inline Frame2(const Frame2& arg);
+ inline void Make4x4(double* d);
+
+ //! Treats a frame as a 3x3 matrix and returns element i,j
+ //! Access to elements 0..2,0..2, bounds are checked when NDEBUG is not set
+ inline double operator()(int i,int j);
+
+ //! Treats a frame as a 4x4 matrix and returns element i,j
+ //! Access to elements 0..3,0..3, bounds are checked when NDEBUG is not set
+ inline double operator() (int i,int j) const;
+
+ inline void SetInverse();
+ inline Frame2 Inverse() const;
+ inline Vector2 Inverse(const Vector2& arg) const;
+ inline Frame2& operator = (const Frame2& arg);
+ inline Vector2 operator * (const Vector2& arg);
+ inline friend Frame2 operator *(const Frame2& lhs,const Frame2& rhs);
+ inline void SetIdentity();
+ inline void Integrate(const Twist& t_this,double frequency);
+ inline static Frame2 Identity() {
+ Frame2 tmp;
+ tmp.SetIdentity();
+ return tmp;
+ }
+ inline friend bool Equal(const Frame2& a,const Frame2& b,double eps=epsilon);
+};
+
+IMETHOD Vector diff(const Vector& a,const Vector& b,double dt=1);
+IMETHOD Vector diff(const Rotation& R_a_b1,const Rotation& R_a_b2,double dt=1);
+IMETHOD Twist diff(const Frame& F_a_b1,const Frame& F_a_b2,double dt=1);
+IMETHOD Twist diff(const Twist& a,const Twist& b,double dt=1);
+IMETHOD Wrench diff(const Wrench& W_a_p1,const Wrench& W_a_p2,double dt=1);
+IMETHOD Vector addDelta(const Vector& a,const Vector&da,double dt=1);
+IMETHOD Rotation addDelta(const Rotation& a,const Vector&da,double dt=1);
+IMETHOD Frame addDelta(const Frame& a,const Twist& da,double dt=1);
+IMETHOD Twist addDelta(const Twist& a,const Twist&da,double dt=1);
+IMETHOD Wrench addDelta(const Wrench& a,const Wrench&da,double dt=1);
+#ifdef KDL_INLINE
+// #include "vector.inl"
+// #include "wrench.inl"
+ //#include "rotation.inl"
+ //#include "frame.inl"
+ //#include "twist.inl"
+ //#include "vector2.inl"
+ //#include "rotation2.inl"
+ //#include "frame2.inl"
+#include "frames.inl"
+#endif
+
+
+
+}
+
+
+#endif
diff --git a/intern/itasc/kdl/frames.inl b/intern/itasc/kdl/frames.inl
new file mode 100644
index 00000000000..9a176070171
--- /dev/null
+++ b/intern/itasc/kdl/frames.inl
@@ -0,0 +1,1390 @@
+/***************************************************************************
+ frames.inl - description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.ac.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ ***************************************************************************
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+
+IMETHOD Vector::Vector(const Vector & arg)
+{
+ data[0] = arg.data[0];
+ data[1] = arg.data[1];
+ data[2] = arg.data[2];
+}
+
+IMETHOD Vector::Vector(double x,double y, double z)
+{
+ data[0]=x;data[1]=y;data[2]=z;
+}
+
+IMETHOD Vector::Vector(double* xyz)
+{
+ data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2];
+}
+
+IMETHOD Vector::Vector(float* xyz)
+{
+ data[0]=xyz[0];data[1]=xyz[1];data[2]=xyz[2];
+}
+
+IMETHOD void Vector::GetValue(double* xyz) const
+{
+ xyz[0]=data[0];xyz[1]=data[1];xyz[2]=data[2];
+}
+
+
+IMETHOD Vector& Vector::operator =(const Vector & arg)
+{
+ data[0] = arg.data[0];
+ data[1] = arg.data[1];
+ data[2] = arg.data[2];
+ return *this;
+}
+
+IMETHOD Vector operator +(const Vector & lhs,const Vector& rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[0]+rhs.data[0];
+ tmp.data[1] = lhs.data[1]+rhs.data[1];
+ tmp.data[2] = lhs.data[2]+rhs.data[2];
+ return tmp;
+}
+
+IMETHOD Vector operator -(const Vector & lhs,const Vector& rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[0]-rhs.data[0];
+ tmp.data[1] = lhs.data[1]-rhs.data[1];
+ tmp.data[2] = lhs.data[2]-rhs.data[2];
+ return tmp;
+}
+
+IMETHOD double Vector::x() const { return data[0]; }
+IMETHOD double Vector::y() const { return data[1]; }
+IMETHOD double Vector::z() const { return data[2]; }
+
+IMETHOD void Vector::x( double _x ) { data[0] = _x; }
+IMETHOD void Vector::y( double _y ) { data[1] = _y; }
+IMETHOD void Vector::z( double _z ) { data[2] = _z; }
+
+Vector operator *(const Vector& lhs,double rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[0]*rhs;
+ tmp.data[1] = lhs.data[1]*rhs;
+ tmp.data[2] = lhs.data[2]*rhs;
+ return tmp;
+}
+
+Vector operator *(double lhs,const Vector& rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs*rhs.data[0];
+ tmp.data[1] = lhs*rhs.data[1];
+ tmp.data[2] = lhs*rhs.data[2];
+ return tmp;
+}
+
+Vector operator /(const Vector& lhs,double rhs)
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[0]/rhs;
+ tmp.data[1] = lhs.data[1]/rhs;
+ tmp.data[2] = lhs.data[2]/rhs;
+ return tmp;
+}
+
+Vector operator *(const Vector & lhs,const Vector& rhs)
+// Complexity : 6M+3A
+{
+ Vector tmp;
+ tmp.data[0] = lhs.data[1]*rhs.data[2]-lhs.data[2]*rhs.data[1];
+ tmp.data[1] = lhs.data[2]*rhs.data[0]-lhs.data[0]*rhs.data[2];
+ tmp.data[2] = lhs.data[0]*rhs.data[1]-lhs.data[1]*rhs.data[0];
+ return tmp;
+}
+
+Vector& Vector::operator +=(const Vector & arg)
+// Complexity : 3A
+{
+ data[0]+=arg.data[0];
+ data[1]+=arg.data[1];
+ data[2]+=arg.data[2];
+ return *this;
+}
+
+Vector& Vector::operator -=(const Vector & arg)
+// Complexity : 3A
+{
+ data[0]-=arg.data[0];
+ data[1]-=arg.data[1];
+ data[2]-=arg.data[2];
+ return *this;
+}
+
+Vector Vector::Zero()
+{
+ return Vector(0,0,0);
+}
+
+double Vector::operator()(int index) const {
+ FRAMES_CHECKI((0<=index)&&(index<=2));
+ return data[index];
+}
+
+double& Vector::operator () (int index)
+{
+ FRAMES_CHECKI((0<=index)&&(index<=2));
+ return data[index];
+}
+
+IMETHOD Vector Normalize(const Vector& a, double eps)
+{
+ double l=a.Norm();
+ return (l<eps) ? Vector(0.0,0.0,0.0) : a/l;
+}
+
+Wrench Frame::operator * (const Wrench& arg) const
+// Complexity : 24M+18A
+{
+ Wrench tmp;
+ tmp.force = M*arg.force;
+ tmp.torque = M*arg.torque + p*tmp.force;
+ return tmp;
+}
+
+Wrench Frame::Inverse(const Wrench& arg) const
+{
+ Wrench tmp;
+ tmp.force = M.Inverse(arg.force);
+ tmp.torque = M.Inverse(arg.torque-p*arg.force);
+ return tmp;
+}
+
+
+
+Wrench Rotation::Inverse(const Wrench& arg) const
+{
+ return Wrench(Inverse(arg.force),Inverse(arg.torque));
+}
+
+Twist Rotation::Inverse(const Twist& arg) const
+{
+ return Twist(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+Wrench Wrench::Zero()
+{
+ return Wrench(Vector::Zero(),Vector::Zero());
+}
+
+
+void Wrench::ReverseSign()
+{
+ torque.ReverseSign();
+ force.ReverseSign();
+}
+
+Wrench Wrench::RefPoint(const Vector& v_base_AB) const
+ // Changes the reference point of the Wrench.
+ // The vector v_base_AB is expressed in the same base as the twist
+ // The vector v_base_AB is a vector from the old point to
+ // the new point.
+{
+ return Wrench(this->force,
+ this->torque+this->force*v_base_AB
+ );
+}
+
+
+Wrench& Wrench::operator-=(const Wrench& arg)
+{
+ torque-=arg.torque;
+ force -=arg.force;
+ return *this;
+}
+
+Wrench& Wrench::operator+=(const Wrench& arg)
+{
+ torque+=arg.torque;
+ force +=arg.force;
+ return *this;
+}
+
+double& Wrench::operator()(int i)
+{
+ // assert((0<=i)&&(i<6)); done by underlying routines
+ if (i<3)
+ return force(i);
+ else
+ return torque(i-3);
+}
+
+double Wrench::operator()(int i) const
+{
+ // assert((0<=i)&&(i<6)); done by underlying routines
+ if (i<3)
+ return force(i);
+ else
+ return torque(i-3);
+}
+
+
+Wrench operator*(const Wrench& lhs,double rhs)
+{
+ return Wrench(lhs.force*rhs,lhs.torque*rhs);
+}
+
+Wrench operator*(double lhs,const Wrench& rhs)
+{
+ return Wrench(lhs*rhs.force,lhs*rhs.torque);
+}
+
+Wrench operator/(const Wrench& lhs,double rhs)
+{
+ return Wrench(lhs.force/rhs,lhs.torque/rhs);
+}
+
+// addition of Wrench's
+Wrench operator+(const Wrench& lhs,const Wrench& rhs)
+{
+ return Wrench(lhs.force+rhs.force,lhs.torque+rhs.torque);
+}
+
+Wrench operator-(const Wrench& lhs,const Wrench& rhs)
+{
+ return Wrench(lhs.force-rhs.force,lhs.torque-rhs.torque);
+}
+
+// unary -
+Wrench operator-(const Wrench& arg)
+{
+ return Wrench(-arg.force,-arg.torque);
+}
+
+Twist Frame::operator * (const Twist& arg) const
+// Complexity : 24M+18A
+{
+ Twist tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+Twist Frame::Inverse(const Twist& arg) const
+{
+ Twist tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+Twist Twist::Zero()
+{
+ return Twist(Vector::Zero(),Vector::Zero());
+}
+
+
+void Twist::ReverseSign()
+{
+ vel.ReverseSign();
+ rot.ReverseSign();
+}
+
+Twist Twist::RefPoint(const Vector& v_base_AB) const
+ // Changes the reference point of the twist.
+ // The vector v_base_AB is expressed in the same base as the twist
+ // The vector v_base_AB is a vector from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+{
+ return Twist(this->vel+this->rot*v_base_AB,this->rot);
+}
+
+Twist& Twist::operator-=(const Twist& arg)
+{
+ vel-=arg.vel;
+ rot -=arg.rot;
+ return *this;
+}
+
+Twist& Twist::operator+=(const Twist& arg)
+{
+ vel+=arg.vel;
+ rot +=arg.rot;
+ return *this;
+}
+
+double& Twist::operator()(int i)
+{
+ // assert((0<=i)&&(i<6)); done by underlying routines
+ if (i<3)
+ return vel(i);
+ else
+ return rot(i-3);
+}
+
+double Twist::operator()(int i) const
+{
+ // assert((0<=i)&&(i<6)); done by underlying routines
+ if (i<3)
+ return vel(i);
+ else
+ return rot(i-3);
+}
+
+
+Twist operator*(const Twist& lhs,double rhs)
+{
+ return Twist(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+Twist operator*(double lhs,const Twist& rhs)
+{
+ return Twist(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+Twist operator/(const Twist& lhs,double rhs)
+{
+ return Twist(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+// addition of Twist's
+Twist operator+(const Twist& lhs,const Twist& rhs)
+{
+ return Twist(lhs.vel+rhs.vel,lhs.rot+rhs.rot);
+}
+
+Twist operator-(const Twist& lhs,const Twist& rhs)
+{
+ return Twist(lhs.vel-rhs.vel,lhs.rot-rhs.rot);
+}
+
+// unary -
+Twist operator-(const Twist& arg)
+{
+ return Twist(-arg.vel,-arg.rot);
+}
+
+Frame::Frame(const Rotation & R)
+{
+ M=R;
+ p=Vector::Zero();
+}
+
+Frame::Frame(const Vector & V)
+{
+ M = Rotation::Identity();
+ p = V;
+}
+
+Frame::Frame(const Rotation & R, const Vector & V)
+{
+ M = R;
+ p = V;
+}
+
+ Frame operator *(const Frame& lhs,const Frame& rhs)
+// Complexity : 36M+36A
+{
+ return Frame(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+
+Vector Frame::operator *(const Vector & arg) const
+{
+ return M*arg+p;
+}
+
+Vector Frame::Inverse(const Vector& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+Frame Frame::Inverse() const
+{
+ return Frame(M.Inverse(),-M.Inverse(p));
+}
+
+
+Frame& Frame::operator =(const Frame & arg)
+{
+ M = arg.M;
+ p = arg.p;
+ return *this;
+}
+
+Frame::Frame(const Frame & arg) :
+ p(arg.p),M(arg.M)
+{}
+
+
+void Vector::ReverseSign()
+{
+ data[0] = -data[0];
+ data[1] = -data[1];
+ data[2] = -data[2];
+}
+
+
+
+Vector operator-(const Vector & arg)
+{
+ Vector tmp;
+ tmp.data[0]=-arg.data[0];
+ tmp.data[1]=-arg.data[1];
+ tmp.data[2]=-arg.data[2];
+ return tmp;
+}
+
+void Vector::Set2DXY(const Vector2& v)
+// a 3D vector where the 2D vector v is put in the XY plane
+{
+ data[0]=v(0);
+ data[1]=v(1);
+ data[2]=0;
+
+}
+void Vector::Set2DYZ(const Vector2& v)
+// a 3D vector where the 2D vector v is put in the YZ plane
+{
+ data[1]=v(0);
+ data[2]=v(1);
+ data[0]=0;
+
+}
+
+void Vector::Set2DZX(const Vector2& v)
+// a 3D vector where the 2D vector v is put in the ZX plane
+{
+ data[2]=v(0);
+ data[0]=v(1);
+ data[1]=0;
+
+}
+
+
+
+
+
+double& Rotation::operator()(int i,int j) {
+ FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
+ return data[i*3+j];
+}
+
+double Rotation::operator()(int i,int j) const {
+ FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
+ return data[i*3+j];
+}
+
+Rotation::Rotation( double Xx,double Yx,double Zx,
+ double Xy,double Yy,double Zy,
+ double Xz,double Yz,double Zz)
+{
+ data[0] = Xx;data[1]=Yx;data[2]=Zx;
+ data[3] = Xy;data[4]=Yy;data[5]=Zy;
+ data[6] = Xz;data[7]=Yz;data[8]=Zz;
+}
+
+
+Rotation::Rotation(const Vector& x,const Vector& y,const Vector& z)
+{
+ data[0] = x.data[0];data[3] = x.data[1];data[6] = x.data[2];
+ data[1] = y.data[0];data[4] = y.data[1];data[7] = y.data[2];
+ data[2] = z.data[0];data[5] = z.data[1];data[8] = z.data[2];
+}
+
+Rotation& Rotation::operator=(const Rotation& arg) {
+ int count=9;
+ while (count--) data[count] = arg.data[count];
+ return *this;
+}
+
+Vector Rotation::operator*(const Vector& v) const {
+// Complexity : 9M+6A
+ return Vector(
+ data[0]*v.data[0] + data[1]*v.data[1] + data[2]*v.data[2],
+ data[3]*v.data[0] + data[4]*v.data[1] + data[5]*v.data[2],
+ data[6]*v.data[0] + data[7]*v.data[1] + data[8]*v.data[2]
+ );
+}
+
+Twist Rotation::operator * (const Twist& arg) const
+ // Transformation of the base to which the twist is expressed.
+ // look at Frame*Twist for a transformation that also transforms
+ // the velocity reference point.
+ // Complexity : 18M+12A
+{
+ return Twist((*this)*arg.vel,(*this)*arg.rot);
+}
+
+Wrench Rotation::operator * (const Wrench& arg) const
+ // Transformation of the base to which the wrench is expressed.
+ // look at Frame*Twist for a transformation that also transforms
+ // the force reference point.
+{
+ return Wrench((*this)*arg.force,(*this)*arg.torque);
+}
+
+Rotation Rotation::Identity() {
+ return Rotation(1,0,0,0,1,0,0,0,1);
+}
+// *this = *this * ROT(X,angle)
+void Rotation::DoRotX(double angle)
+{
+ double cs = cos(angle);
+ double sn = sin(angle);
+ double x1,x2,x3;
+ x1 = cs* (*this)(0,1) + sn* (*this)(0,2);
+ x2 = cs* (*this)(1,1) + sn* (*this)(1,2);
+ x3 = cs* (*this)(2,1) + sn* (*this)(2,2);
+ (*this)(0,2) = -sn* (*this)(0,1) + cs* (*this)(0,2);
+ (*this)(1,2) = -sn* (*this)(1,1) + cs* (*this)(1,2);
+ (*this)(2,2) = -sn* (*this)(2,1) + cs* (*this)(2,2);
+ (*this)(0,1) = x1;
+ (*this)(1,1) = x2;
+ (*this)(2,1) = x3;
+}
+
+void Rotation::DoRotY(double angle)
+{
+ double cs = cos(angle);
+ double sn = sin(angle);
+ double x1,x2,x3;
+ x1 = cs* (*this)(0,0) - sn* (*this)(0,2);
+ x2 = cs* (*this)(1,0) - sn* (*this)(1,2);
+ x3 = cs* (*this)(2,0) - sn* (*this)(2,2);
+ (*this)(0,2) = sn* (*this)(0,0) + cs* (*this)(0,2);
+ (*this)(1,2) = sn* (*this)(1,0) + cs* (*this)(1,2);
+ (*this)(2,2) = sn* (*this)(2,0) + cs* (*this)(2,2);
+ (*this)(0,0) = x1;
+ (*this)(1,0) = x2;
+ (*this)(2,0) = x3;
+}
+
+void Rotation::DoRotZ(double angle)
+{
+ double cs = cos(angle);
+ double sn = sin(angle);
+ double x1,x2,x3;
+ x1 = cs* (*this)(0,0) + sn* (*this)(0,1);
+ x2 = cs* (*this)(1,0) + sn* (*this)(1,1);
+ x3 = cs* (*this)(2,0) + sn* (*this)(2,1);
+ (*this)(0,1) = -sn* (*this)(0,0) + cs* (*this)(0,1);
+ (*this)(1,1) = -sn* (*this)(1,0) + cs* (*this)(1,1);
+ (*this)(2,1) = -sn* (*this)(2,0) + cs* (*this)(2,1);
+ (*this)(0,0) = x1;
+ (*this)(1,0) = x2;
+ (*this)(2,0) = x3;
+}
+
+
+Rotation Rotation::RotX(double angle) {
+ double cs=cos(angle);
+ double sn=sin(angle);
+ return Rotation(1,0,0,0,cs,-sn,0,sn,cs);
+}
+Rotation Rotation::RotY(double angle) {
+ double cs=cos(angle);
+ double sn=sin(angle);
+ return Rotation(cs,0,sn,0,1,0,-sn,0,cs);
+}
+Rotation Rotation::RotZ(double angle) {
+ double cs=cos(angle);
+ double sn=sin(angle);
+ return Rotation(cs,-sn,0,sn,cs,0,0,0,1);
+}
+
+
+
+
+void Frame::Integrate(const Twist& t_this,double samplefrequency)
+{
+ double n = t_this.rot.Norm()/samplefrequency;
+ if (n<epsilon) {
+ p += M*(t_this.vel/samplefrequency);
+ } else {
+ (*this) = (*this) *
+ Frame ( Rotation::Rot( t_this.rot, n ),
+ t_this.vel/samplefrequency
+ );
+ }
+}
+
+Rotation Rotation::Inverse() const
+{
+ Rotation tmp(*this);
+ tmp.SetInverse();
+ return tmp;
+}
+
+Vector Rotation::Inverse(const Vector& v) const {
+ return Vector(
+ data[0]*v.data[0] + data[3]*v.data[1] + data[6]*v.data[2],
+ data[1]*v.data[0] + data[4]*v.data[1] + data[7]*v.data[2],
+ data[2]*v.data[0] + data[5]*v.data[1] + data[8]*v.data[2]
+ );
+}
+
+void Rotation::setValue(float* oglmat)
+{
+ data[0] = *oglmat++; data[3] = *oglmat++; data[6] = *oglmat++; oglmat++;
+ data[1] = *oglmat++; data[4] = *oglmat++; data[7] = *oglmat++; oglmat++;
+ data[2] = *oglmat++; data[5] = *oglmat++; data[8] = *oglmat;
+ Ortho();
+}
+
+void Rotation::getValue(float* oglmat) const
+{
+ *oglmat++ = (float)data[0]; *oglmat++ = (float)data[3]; *oglmat++ = (float)data[6]; *oglmat++ = 0.f;
+ *oglmat++ = (float)data[1]; *oglmat++ = (float)data[4]; *oglmat++ = (float)data[7]; *oglmat++ = 0.f;
+ *oglmat++ = (float)data[2]; *oglmat++ = (float)data[5]; *oglmat++ = (float)data[8]; *oglmat++ = 0.f;
+ *oglmat++ = 0.f; *oglmat++ = 0.f; *oglmat++ = 0.f; *oglmat = 1.f;
+}
+
+void Rotation::SetInverse()
+{
+ double tmp;
+ tmp = data[1];data[1]=data[3];data[3]=tmp;
+ tmp = data[2];data[2]=data[6];data[6]=tmp;
+ tmp = data[5];data[5]=data[7];data[7]=tmp;
+}
+
+
+
+
+
+
+
+double Frame::operator()(int i,int j) {
+ FRAMES_CHECKI((0<=i)&&(i<=3)&&(0<=j)&&(j<=3));
+ if (i==3) {
+ if (j==3)
+ return 1.0;
+ else
+ return 0.0;
+ } else {
+ if (j==3)
+ return p(i);
+ else
+ return M(i,j);
+
+ }
+}
+
+double Frame::operator()(int i,int j) const {
+ FRAMES_CHECKI((0<=i)&&(i<=3)&&(0<=j)&&(j<=3));
+ if (i==3) {
+ if (j==3)
+ return 1;
+ else
+ return 0;
+ } else {
+ if (j==3)
+ return p(i);
+ else
+ return M(i,j);
+
+ }
+}
+
+
+Frame Frame::Identity() {
+ return Frame(Rotation::Identity(),Vector::Zero());
+}
+
+
+void Frame::setValue(float* oglmat)
+{
+ M.setValue(oglmat);
+ p.data[0] = oglmat[12];
+ p.data[1] = oglmat[13];
+ p.data[2] = oglmat[14];
+}
+
+void Frame::getValue(float* oglmat) const
+{
+ M.getValue(oglmat);
+ oglmat[12] = (float)p.data[0];
+ oglmat[13] = (float)p.data[1];
+ oglmat[14] = (float)p.data[2];
+}
+
+void Vector::Set2DPlane(const Frame& F_someframe_XY,const Vector2& v_XY)
+// a 3D vector where the 2D vector v is put in the XY plane of the frame
+// F_someframe_XY.
+{
+Vector tmp_XY;
+tmp_XY.Set2DXY(v_XY);
+tmp_XY = F_someframe_XY*(tmp_XY);
+}
+
+
+
+
+
+
+
+
+
+//============ 2 dimensional version of the frames objects =============
+IMETHOD Vector2::Vector2(const Vector2 & arg)
+{
+ data[0] = arg.data[0];
+ data[1] = arg.data[1];
+}
+
+IMETHOD Vector2::Vector2(double x,double y)
+{
+ data[0]=x;data[1]=y;
+}
+
+IMETHOD Vector2::Vector2(double* xy)
+{
+ data[0]=xy[0];data[1]=xy[1];
+}
+
+IMETHOD Vector2::Vector2(float* xy)
+{
+ data[0]=xy[0];data[1]=xy[1];
+}
+
+IMETHOD Vector2& Vector2::operator =(const Vector2 & arg)
+{
+ data[0] = arg.data[0];
+ data[1] = arg.data[1];
+ return *this;
+}
+
+IMETHOD void Vector2::GetValue(double* xy) const
+{
+ xy[0]=data[0];xy[1]=data[1];
+}
+
+IMETHOD Vector2 operator +(const Vector2 & lhs,const Vector2& rhs)
+{
+ return Vector2(lhs.data[0]+rhs.data[0],lhs.data[1]+rhs.data[1]);
+}
+
+IMETHOD Vector2 operator -(const Vector2 & lhs,const Vector2& rhs)
+{
+ return Vector2(lhs.data[0]-rhs.data[0],lhs.data[1]-rhs.data[1]);
+}
+
+IMETHOD Vector2 operator *(const Vector2& lhs,double rhs)
+{
+ return Vector2(lhs.data[0]*rhs,lhs.data[1]*rhs);
+}
+
+IMETHOD Vector2 operator *(double lhs,const Vector2& rhs)
+{
+ return Vector2(lhs*rhs.data[0],lhs*rhs.data[1]);
+}
+
+IMETHOD Vector2 operator /(const Vector2& lhs,double rhs)
+{
+ return Vector2(lhs.data[0]/rhs,lhs.data[1]/rhs);
+}
+
+IMETHOD Vector2& Vector2::operator +=(const Vector2 & arg)
+{
+ data[0]+=arg.data[0];
+ data[1]+=arg.data[1];
+ return *this;
+}
+
+IMETHOD Vector2& Vector2::operator -=(const Vector2 & arg)
+{
+ data[0]-=arg.data[0];
+ data[1]-=arg.data[1];
+ return *this;
+}
+
+IMETHOD Vector2 Vector2::Zero() {
+ return Vector2(0,0);
+}
+
+IMETHOD double Vector2::operator()(int index) const {
+ FRAMES_CHECKI((0<=index)&&(index<=1));
+ return data[index];
+}
+
+IMETHOD double& Vector2::operator () (int index)
+{
+ FRAMES_CHECKI((0<=index)&&(index<=1));
+ return data[index];
+}
+IMETHOD void Vector2::ReverseSign()
+{
+ data[0] = -data[0];
+ data[1] = -data[1];
+}
+
+
+IMETHOD Vector2 operator-(const Vector2 & arg)
+{
+ return Vector2(-arg.data[0],-arg.data[1]);
+}
+
+
+IMETHOD void Vector2::Set3DXY(const Vector& v)
+// projects v in its XY plane, and sets *this to these values
+{
+ data[0]=v(0);
+ data[1]=v(1);
+}
+IMETHOD void Vector2::Set3DYZ(const Vector& v)
+// projects v in its XY plane, and sets *this to these values
+{
+ data[0]=v(1);
+ data[1]=v(2);
+}
+IMETHOD void Vector2::Set3DZX(const Vector& v)
+// projects v in its XY plane, and and sets *this to these values
+{
+ data[0]=v(2);
+ data[1]=v(0);
+}
+
+IMETHOD void Vector2::Set3DPlane(const Frame& F_someframe_XY,const Vector& v_someframe)
+// projects v in the XY plane of F_someframe_XY, and sets *this to these values
+// expressed wrt someframe.
+{
+ Vector tmp = F_someframe_XY.Inverse(v_someframe);
+ data[0]=tmp(0);
+ data[1]=tmp(1);
+}
+
+
+
+IMETHOD Rotation2& Rotation2::operator=(const Rotation2& arg) {
+ c=arg.c;s=arg.s;
+ return *this;
+}
+
+IMETHOD Vector2 Rotation2::operator*(const Vector2& v) const {
+ return Vector2(v.data[0]*c-v.data[1]*s,v.data[0]*s+v.data[1]*c);
+}
+
+IMETHOD double Rotation2::operator()(int i,int j) const {
+ FRAMES_CHECKI((0<=i)&&(i<=1)&&(0<=j)&&(j<=1));
+ if (i==j) return c;
+ if (i==0)
+ return s;
+ else
+ return -s;
+}
+
+
+IMETHOD Rotation2 operator *(const Rotation2& lhs,const Rotation2& rhs) {
+ return Rotation2(lhs.c*rhs.c-lhs.s*rhs.s,lhs.s*rhs.c+lhs.c*rhs.s);
+}
+
+IMETHOD void Rotation2::SetInverse() {
+ s=-s;
+}
+
+IMETHOD Rotation2 Rotation2::Inverse() const {
+ return Rotation2(c,-s);
+}
+
+IMETHOD Vector2 Rotation2::Inverse(const Vector2& v) const {
+ return Vector2(v.data[0]*c+v.data[1]*s,-v.data[0]*s+v.data[1]*c);
+}
+
+IMETHOD Rotation2 Rotation2::Identity() {
+ return Rotation2(1,0);
+}
+
+IMETHOD void Rotation2::SetIdentity()
+{
+ c = 1;
+ s = 0;
+}
+
+IMETHOD void Rotation2::SetRot(double angle) {
+ c=cos(angle);s=sin(angle);
+}
+
+IMETHOD Rotation2 Rotation2::Rot(double angle) {
+ return Rotation2(cos(angle),sin(angle));
+}
+
+IMETHOD double Rotation2::GetRot() const {
+ return atan2(s,c);
+}
+
+
+IMETHOD Frame2::Frame2() {
+}
+
+IMETHOD Frame2::Frame2(const Rotation2 & R)
+{
+ M=R;
+ p=Vector2::Zero();
+}
+
+IMETHOD Frame2::Frame2(const Vector2 & V)
+{
+ M = Rotation2::Identity();
+ p = V;
+}
+
+IMETHOD Frame2::Frame2(const Rotation2 & R, const Vector2 & V)
+{
+ M = R;
+ p = V;
+}
+
+IMETHOD Frame2 operator *(const Frame2& lhs,const Frame2& rhs)
+{
+ return Frame2(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+
+IMETHOD Vector2 Frame2::operator *(const Vector2 & arg)
+{
+ return M*arg+p;
+}
+
+IMETHOD Vector2 Frame2::Inverse(const Vector2& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+IMETHOD void Frame2::SetIdentity()
+{
+ M.SetIdentity();
+ p = Vector2::Zero();
+}
+
+IMETHOD void Frame2::SetInverse()
+{
+ M.SetInverse();
+ p = M*p;
+ p.ReverseSign();
+}
+
+
+IMETHOD Frame2 Frame2::Inverse() const
+{
+ Frame2 tmp(*this);
+ tmp.SetInverse();
+ return tmp;
+}
+
+IMETHOD Frame2& Frame2::operator =(const Frame2 & arg)
+{
+ M = arg.M;
+ p = arg.p;
+ return *this;
+}
+
+IMETHOD Frame2::Frame2(const Frame2 & arg) :
+ p(arg.p), M(arg.M)
+{}
+
+
+IMETHOD double Frame2::operator()(int i,int j) {
+ FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
+ if (i==2) {
+ if (j==2)
+ return 1;
+ else
+ return 0;
+ } else {
+ if (j==2)
+ return p(i);
+ else
+ return M(i,j);
+
+ }
+}
+
+IMETHOD double Frame2::operator()(int i,int j) const {
+ FRAMES_CHECKI((0<=i)&&(i<=2)&&(0<=j)&&(j<=2));
+ if (i==2) {
+ if (j==2)
+ return 1;
+ else
+ return 0;
+ } else {
+ if (j==2)
+ return p(i);
+ else
+ return M(i,j);
+
+ }
+}
+
+// Scalar products.
+
+IMETHOD double dot(const Vector& lhs,const Vector& rhs) {
+ return rhs(0)*lhs(0)+rhs(1)*lhs(1)+rhs(2)*lhs(2);
+}
+
+IMETHOD double dot(const Twist& lhs,const Wrench& rhs) {
+ return dot(lhs.vel,rhs.force)+dot(lhs.rot,rhs.torque);
+}
+
+IMETHOD double dot(const Wrench& rhs,const Twist& lhs) {
+ return dot(lhs.vel,rhs.force)+dot(lhs.rot,rhs.torque);
+}
+
+
+
+
+
+// Equality operators
+
+
+
+IMETHOD bool Equal(const Vector& a,const Vector& b,double eps) {
+ return (Equal(a.data[0],b.data[0],eps)&&
+ Equal(a.data[1],b.data[1],eps)&&
+ Equal(a.data[2],b.data[2],eps) );
+ }
+
+
+IMETHOD bool Equal(const Frame& a,const Frame& b,double eps) {
+ return (Equal(a.p,b.p,eps)&&
+ Equal(a.M,b.M,eps) );
+}
+
+IMETHOD bool Equal(const Wrench& a,const Wrench& b,double eps) {
+ return (Equal(a.force,b.force,eps)&&
+ Equal(a.torque,b.torque,eps) );
+}
+
+IMETHOD bool Equal(const Twist& a,const Twist& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+
+IMETHOD bool Equal(const Vector2& a,const Vector2& b,double eps) {
+ return (Equal(a.data[0],b.data[0],eps)&&
+ Equal(a.data[1],b.data[1],eps) );
+ }
+
+IMETHOD bool Equal(const Rotation2& a,const Rotation2& b,double eps) {
+ return ( Equal(a.c,b.c,eps) && Equal(a.s,b.s,eps) );
+}
+
+IMETHOD bool Equal(const Frame2& a,const Frame2& b,double eps) {
+ return (Equal(a.p,b.p,eps)&&
+ Equal(a.M,b.M,eps) );
+}
+
+IMETHOD void SetToZero(Vector& v) {
+ v=Vector::Zero();
+}
+IMETHOD void SetToZero(Twist& v) {
+ SetToZero(v.rot);
+ SetToZero(v.vel);
+}
+IMETHOD void SetToZero(Wrench& v) {
+ SetToZero(v.force);
+ SetToZero(v.torque);
+}
+
+IMETHOD void SetToZero(Vector2& v) {
+ v = Vector2::Zero();
+}
+
+
+////////////////////////////////////////////////////////////////
+// The following defines the operations
+// diff
+// addDelta
+// random
+// posrandom
+// on all the types defined in this library.
+// (mostly for uniform integration, differentiation and testing).
+// Defined as functions because double is not a class and a method
+// would brake uniformity when defined for a double.
+////////////////////////////////////////////////////////////////
+
+
+
+
+
+
+/**
+ * axis_a_b is a rotation vector, its norm is a rotation angle
+ * axis_a_b rotates the a frame towards the b frame.
+ * This routine returns the rotation matrix R_a_b
+ */
+IMETHOD Rotation Rot(const Vector& axis_a_b) {
+ // The formula is
+ // V.(V.tr) + st*[V x] + ct*(I-V.(V.tr))
+ // can be found by multiplying it with an arbitrary vector p
+ // and noting that this vector is rotated.
+ Vector rotvec = axis_a_b;
+ double angle = rotvec.Normalize(1E-10);
+ double ct = ::cos(angle);
+ double st = ::sin(angle);
+ double vt = 1-ct;
+ return Rotation(
+ ct + vt*rotvec(0)*rotvec(0),
+ -rotvec(2)*st + vt*rotvec(0)*rotvec(1),
+ rotvec(1)*st + vt*rotvec(0)*rotvec(2),
+ rotvec(2)*st + vt*rotvec(1)*rotvec(0),
+ ct + vt*rotvec(1)*rotvec(1),
+ -rotvec(0)*st + vt*rotvec(1)*rotvec(2),
+ -rotvec(1)*st + vt*rotvec(2)*rotvec(0),
+ rotvec(0)*st + vt*rotvec(2)*rotvec(1),
+ ct + vt*rotvec(2)*rotvec(2)
+ );
+ }
+
+IMETHOD Vector diff(const Vector& a,const Vector& b,double dt) {
+ return (b-a)/dt;
+}
+
+/**
+ * \brief diff operator for displacement rotational velocity.
+ *
+ * The Vector arguments here represent a displacement rotational velocity. i.e. a rotation
+ * around a fixed axis for a certain angle. For this representation you cannot use diff() but
+ * have to use diff_displ().
+ *
+ * \TODO represent a displacement twist and displacement rotational velocity with another
+ * class, instead of Vector and Twist.
+ * \warning do not confuse displacement rotational velocities and velocities
+ * \warning do not confuse displacement twist and twist.
+ *
+IMETHOD Vector diff_displ(const Vector& a,const Vector& b,double dt) {
+ return diff(Rot(a),Rot(b),dt);
+}*/
+
+/**
+ * \brief diff operator for displacement twist.
+ *
+ * The Twist arguments here represent a displacement twist. i.e. a rotation
+ * around a fixed axis for a certain angle. For this representation you cannot use diff() but
+ * have to use diff_displ().
+ *
+ * \warning do not confuse displacement rotational velocities and velocities
+ * \warning do not confuse displacement twist and twist.
+ *
+
+IMETHOD Twist diff_displ(const Twist& a,const Twist& b,double dt) {
+ return Twist(diff(a.vel,b.vel,dt),diff(Rot(a.rot),Rot(b.rot),dt));
+}
+*/
+
+IMETHOD Vector diff(const Rotation& R_a_b1,const Rotation& R_a_b2,double dt) {
+ Rotation R_b1_b2(R_a_b1.Inverse()*R_a_b2);
+ return R_a_b1 * R_b1_b2.GetRot() / dt;
+}
+IMETHOD Twist diff(const Frame& F_a_b1,const Frame& F_a_b2,double dt) {
+ return Twist(
+ diff(F_a_b1.p,F_a_b2.p,dt),
+ diff(F_a_b1.M,F_a_b2.M,dt)
+ );
+}
+IMETHOD Twist diff(const Twist& a,const Twist& b,double dt) {
+ return Twist(diff(a.vel,b.vel,dt),diff(a.rot,b.rot,dt));
+}
+
+IMETHOD Wrench diff(const Wrench& a,const Wrench& b,double dt) {
+ return Wrench(
+ diff(a.force,b.force,dt),
+ diff(a.torque,b.torque,dt)
+ );
+}
+
+
+IMETHOD Vector addDelta(const Vector& a,const Vector&da,double dt) {
+ return a+da*dt;
+}
+
+IMETHOD Rotation addDelta(const Rotation& a,const Vector&da,double dt) {
+ return a*Rot(a.Inverse(da)*dt);
+}
+IMETHOD Frame addDelta(const Frame& a,const Twist& da,double dt) {
+ return Frame(
+ addDelta(a.M,da.rot,dt),
+ addDelta(a.p,da.vel,dt)
+ );
+}
+IMETHOD Twist addDelta(const Twist& a,const Twist&da,double dt) {
+ return Twist(addDelta(a.vel,da.vel,dt),addDelta(a.rot,da.rot,dt));
+}
+IMETHOD Wrench addDelta(const Wrench& a,const Wrench&da,double dt) {
+ return Wrench(addDelta(a.force,da.force,dt),addDelta(a.torque,da.torque,dt));
+}
+
+
+/**
+ * \brief addDelta operator for displacement rotational velocity.
+ *
+ * The Vector arguments here represent a displacement rotational velocity. i.e. a rotation
+ * around a fixed axis for a certain angle. For this representation you cannot use diff() but
+ * have to use diff_displ().
+ *
+ * \param a : displacement rotational velocity
+ * \param da : rotational velocity
+ * \return displacement rotational velocity
+ *
+ * \warning do not confuse displacement rotational velocities and velocities
+ * \warning do not confuse displacement twist and twist.
+ *
+IMETHOD Vector addDelta_displ(const Vector& a,const Vector&da,double dt) {
+ return getRot(addDelta(Rot(a),da,dt));
+}*/
+
+/**
+ * \brief addDelta operator for displacement twist.
+ *
+ * The Vector arguments here represent a displacement rotational velocity. i.e. a rotation
+ * around a fixed axis for a certain angle. For this representation you cannot use diff() but
+ * have to use diff_displ().
+ *
+ * \param a : displacement twist
+ * \param da : twist
+ * \return displacement twist
+ *
+ * \warning do not confuse displacement rotational velocities and velocities
+ * \warning do not confuse displacement twist and twist.
+ *
+IMETHOD Twist addDelta_displ(const Twist& a,const Twist&da,double dt) {
+ return Twist(addDelta(a.vel,da.vel,dt),addDelta_displ(a.rot,da.rot,dt));
+}*/
+
+
+IMETHOD void random(Vector& a) {
+ random(a[0]);
+ random(a[1]);
+ random(a[2]);
+}
+IMETHOD void random(Twist& a) {
+ random(a.rot);
+ random(a.vel);
+}
+IMETHOD void random(Wrench& a) {
+ random(a.torque);
+ random(a.force);
+}
+
+IMETHOD void random(Rotation& R) {
+ double alfa;
+ double beta;
+ double gamma;
+ random(alfa);
+ random(beta);
+ random(gamma);
+ R = Rotation::EulerZYX(alfa,beta,gamma);
+}
+
+IMETHOD void random(Frame& F) {
+ random(F.M);
+ random(F.p);
+}
+
+IMETHOD void posrandom(Vector& a) {
+ posrandom(a[0]);
+ posrandom(a[1]);
+ posrandom(a[2]);
+}
+IMETHOD void posrandom(Twist& a) {
+ posrandom(a.rot);
+ posrandom(a.vel);
+}
+IMETHOD void posrandom(Wrench& a) {
+ posrandom(a.torque);
+ posrandom(a.force);
+}
+
+IMETHOD void posrandom(Rotation& R) {
+ double alfa;
+ double beta;
+ double gamma;
+ posrandom(alfa);
+ posrandom(beta);
+ posrandom(gamma);
+ R = Rotation::EulerZYX(alfa,beta,gamma);
+}
+
+IMETHOD void posrandom(Frame& F) {
+ random(F.M);
+ random(F.p);
+}
+
+
+
+
+IMETHOD bool operator==(const Frame& a,const Frame& b ) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return (a.p == b.p &&
+ a.M == b.M );
+#endif
+}
+
+IMETHOD bool operator!=(const Frame& a,const Frame& b) {
+ return !operator==(a,b);
+}
+
+IMETHOD bool operator==(const Vector& a,const Vector& b) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return (a.data[0]==b.data[0]&&
+ a.data[1]==b.data[1]&&
+ a.data[2]==b.data[2] );
+#endif
+ }
+
+IMETHOD bool operator!=(const Vector& a,const Vector& b) {
+ return !operator==(a,b);
+}
+
+IMETHOD bool operator==(const Twist& a,const Twist& b) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return (a.rot==b.rot &&
+ a.vel==b.vel );
+#endif
+}
+
+IMETHOD bool operator!=(const Twist& a,const Twist& b) {
+ return !operator==(a,b);
+}
+
+IMETHOD bool operator==(const Wrench& a,const Wrench& b ) {
+#ifdef KDL_USE_EQUAL
+ return Equal(a,b);
+#else
+ return (a.force==b.force &&
+ a.torque==b.torque );
+#endif
+}
+
+IMETHOD bool operator!=(const Wrench& a,const Wrench& b) {
+ return !operator==(a,b);
+}
+IMETHOD bool operator!=(const Rotation& a,const Rotation& b) {
+ return !operator==(a,b);
+}
+
diff --git a/intern/itasc/kdl/frames_io.cpp b/intern/itasc/kdl/frames_io.cpp
new file mode 100644
index 00000000000..0af50bb0e07
--- /dev/null
+++ b/intern/itasc/kdl/frames_io.cpp
@@ -0,0 +1,310 @@
+
+/***************************************************************************
+ frames_io.h - description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.ac.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ ***************************************************************************
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+#include "utilities/error.h"
+#include "utilities/error_stack.h"
+#include "frames.hpp"
+#include "frames_io.hpp"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <iostream>
+
+namespace KDL {
+
+
+std::ostream& operator << (std::ostream& os,const Vector& v) {
+ os << "[" << std::setw(KDL_FRAME_WIDTH) << v(0) << "," << std::setw(KDL_FRAME_WIDTH)<<v(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v(2) << "]";
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os,const Twist& v) {
+ os << "[" << std::setw(KDL_FRAME_WIDTH) << v.vel(0)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.vel(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.vel(2)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.rot(0)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.rot(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.rot(2)
+ << "]";
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os,const Wrench& v) {
+ os << "[" << std::setw(KDL_FRAME_WIDTH) << v.force(0)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.force(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.force(2)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.torque(0)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.torque(1)
+ << "," << std::setw(KDL_FRAME_WIDTH) << v.torque(2)
+ << "]";
+ return os;
+}
+
+
+std::ostream& operator << (std::ostream& os,const Rotation& R) {
+#ifdef KDL_ROTATION_PROPERTIES_RPY
+ double r,p,y;
+ R.GetRPY(r,p,y);
+ os << "[RPY]"<<endl;
+ os << "[";
+ os << std::setw(KDL_FRAME_WIDTH) << r << ",";
+ os << std::setw(KDL_FRAME_WIDTH) << p << ",";
+ os << std::setw(KDL_FRAME_WIDTH) << y << "]";
+#else
+# ifdef KDL_ROTATION_PROPERTIES_EULER
+ double z,y,x;
+ R.GetEulerZYX(z,y,x);
+ os << "[EULERZYX]"<<endl;
+ os << "[";
+ os << std::setw(KDL_FRAME_WIDTH) << z << ",";
+ os << std::setw(KDL_FRAME_WIDTH) << y << ",";
+ os << std::setw(KDL_FRAME_WIDTH) << x << "]";
+# else
+ os << "[";
+ for (int i=0;i<=2;i++) {
+ os << std::setw(KDL_FRAME_WIDTH) << R(i,0) << "," <<
+ std::setw(KDL_FRAME_WIDTH) << R(i,1) << "," <<
+ std::setw(KDL_FRAME_WIDTH) << R(i,2);
+ if (i<2)
+ os << ";"<< std::endl << " ";
+ else
+ os << "]";
+ }
+# endif
+#endif
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os, const Frame& T)
+{
+ os << "[" << T.M << std::endl<< T.p << "]";
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os,const Vector2& v) {
+ os << "[" << std::setw(KDL_FRAME_WIDTH) << v(0) << "," << std::setw(KDL_FRAME_WIDTH)<<v(1)
+ << "]";
+ return os;
+}
+
+// Rotation2 gives back an angle in degrees with the << and >> operators.
+std::ostream& operator << (std::ostream& os,const Rotation2& R) {
+ os << "[" << R.GetRot()*rad2deg << "]";
+ return os;
+}
+
+std::ostream& operator << (std::ostream& os, const Frame2& T)
+{
+ os << T.M << T.p;
+ return os;
+}
+
+std::istream& operator >> (std::istream& is,Vector& v)
+{ IOTrace("Stream input Vector (vector or ZERO)");
+ char storage[10];
+ EatWord(is,"[]",storage,10);
+ if (strlen(storage)==0) {
+ Eat(is,'[');
+ is >> v(0);
+ Eat(is,',');
+ is >> v(1);
+ Eat(is,',');
+ is >> v(2);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"ZERO")==0) {
+ v = Vector::Zero();
+ IOTracePop();
+ return is;
+ }
+ throw Error_Frame_Vector_Unexpected_id();
+}
+
+std::istream& operator >> (std::istream& is,Twist& v)
+{ IOTrace("Stream input Twist");
+ Eat(is,'[');
+ is >> v.vel(0);
+ Eat(is,',');
+ is >> v.vel(1);
+ Eat(is,',');
+ is >> v.vel(2);
+ Eat(is,',');
+ is >> v.rot(0);
+ Eat(is,',');
+ is >> v.rot(1);
+ Eat(is,',');
+ is >> v.rot(2);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+}
+
+std::istream& operator >> (std::istream& is,Wrench& v)
+{ IOTrace("Stream input Wrench");
+ Eat(is,'[');
+ is >> v.force(0);
+ Eat(is,',');
+ is >> v.force(1);
+ Eat(is,',');
+ is >> v.force(2);
+ Eat(is,',');
+ is >> v.torque(0);
+ Eat(is,',');
+ is >> v.torque(1);
+ Eat(is,',');
+ is >> v.torque(2);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+}
+
+std::istream& operator >> (std::istream& is,Rotation& r)
+{ IOTrace("Stream input Rotation (Matrix or EULERZYX, EULERZYZ,RPY, ROT, IDENTITY)");
+ char storage[10];
+ EatWord(is,"[]",storage,10);
+ if (strlen(storage)==0) {
+ Eat(is,'[');
+ for (int i=0;i<3;i++) {
+ is >> r(i,0);
+ Eat(is,',') ;
+ is >> r(i,1);
+ Eat(is,',');
+ is >> r(i,2);
+ if (i<2)
+ Eat(is,';');
+ else
+ EatEnd(is,']');
+ }
+ IOTracePop();
+ return is;
+ }
+ Vector v;
+ if (strcmp(storage,"EULERZYX")==0) {
+ is >> v;
+ v=v*deg2rad;
+ r = Rotation::EulerZYX(v(0),v(1),v(2));
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"EULERZYZ")==0) {
+ is >> v;
+ v=v*deg2rad;
+ r = Rotation::EulerZYZ(v(0),v(1),v(2));
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"RPY")==0) {
+ is >> v;
+ v=v*deg2rad;
+ r = Rotation::RPY(v(0),v(1),v(2));
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"ROT")==0) {
+ is >> v;
+ double angle;
+ Eat(is,'[');
+ is >> angle;
+ EatEnd(is,']');
+ r = Rotation::Rot(v,angle*deg2rad);
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"IDENTITY")==0) {
+ r = Rotation::Identity();
+ IOTracePop();
+ return is;
+ }
+ throw Error_Frame_Rotation_Unexpected_id();
+ return is;
+}
+
+std::istream& operator >> (std::istream& is,Frame& T)
+{ IOTrace("Stream input Frame (Rotation,Vector) or DH[...]");
+ char storage[10];
+ EatWord(is,"[",storage,10);
+ if (strlen(storage)==0) {
+ Eat(is,'[');
+ is >> T.M;
+ is >> T.p;
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+ }
+ if (strcmp(storage,"DH")==0) {
+ double a,alpha,d,theta;
+ Eat(is,'[');
+ is >> a;
+ Eat(is,',');
+ is >> alpha;
+ Eat(is,',');
+ is >> d;
+ Eat(is,',');
+ is >> theta;
+ EatEnd(is,']');
+ T = Frame::DH(a,alpha*deg2rad,d,theta*deg2rad);
+ IOTracePop();
+ return is;
+ }
+ throw Error_Frame_Frame_Unexpected_id();
+ return is;
+}
+
+std::istream& operator >> (std::istream& is,Vector2& v)
+{ IOTrace("Stream input Vector2");
+ Eat(is,'[');
+ is >> v(0);
+ Eat(is,',');
+ is >> v(1);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+}
+std::istream& operator >> (std::istream& is,Rotation2& r)
+{ IOTrace("Stream input Rotation2");
+ Eat(is,'[');
+ double val;
+ is >> val;
+ r.Rot(val*deg2rad);
+ EatEnd(is,']');
+ IOTracePop();
+ return is;
+}
+std::istream& operator >> (std::istream& is,Frame2& T)
+{ IOTrace("Stream input Frame2");
+ is >> T.M;
+ is >> T.p;
+ IOTracePop();
+ return is;
+}
+
+} // namespace Frame
diff --git a/intern/itasc/kdl/frames_io.hpp b/intern/itasc/kdl/frames_io.hpp
new file mode 100644
index 00000000000..a358d27383f
--- /dev/null
+++ b/intern/itasc/kdl/frames_io.hpp
@@ -0,0 +1,114 @@
+/***************************************************************************
+ frames_io.h - description
+ -------------------------
+ begin : June 2006
+ copyright : (C) 2006 Erwin Aertbelien
+ email : firstname.lastname@mech.kuleuven.ac.be
+
+ History (only major changes)( AUTHOR-Description ) :
+
+ Ruben Smits - Added output for jacobian and jntarray 06/2007
+
+ ***************************************************************************
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+/**
+//
+// \file
+// Defines routines for I/O of Frame and related objects.
+// \verbatim
+// Spaces, tabs and newlines do not have any importance.
+// Comments are allowed C-style,C++-style, make/perl/csh -style
+// Description of the I/O :
+// Vector : OUTPUT : e.g. [10,20,30]
+// INPUT :
+// 1) [10,20,30]
+// 2) Zero
+// Twist : e.g. [1,2,3,4,5,6]
+// where [1,2,3] is velocity vector
+// where [4,5,6] is rotational velocity vector
+// Wrench : e.g. [1,2,3,4,5,6]
+// where [1,2,3] represents a force vector
+// where [4,5,6] represents a torque vector
+// Rotation : output :
+// [1,2,3;
+// 4,5,6;
+// 7,8,9] cfr definition of Rotation object.
+// input :
+// 1) like the output
+// 2) EulerZYX,EulerZYZ,RPY word followed by a vector, e.g. :
+// Eulerzyx[10,20,30]
+// (ANGLES are always expressed in DEGREES for I/O)
+// (ANGELS are always expressed in RADIANS for internal representation)
+// 3) Rot [1,2,3] [20] Rotates around axis [1,2,3] with an angle
+// of 20 degrees.
+// 4) Identity returns identity rotation matrix.
+// Frames : output : [ Rotationmatrix positionvector ]
+// e.g. [ [1,0,0;0,1,0;0,0,1] [1,2,3] ]
+// Input :
+// 1) [ Rotationmatrix positionvector ]
+// 2) DH [ 10,10,50,30] Denavit-Hartenberg representation
+// ( is in fact not the representation of a Frame, but more
+// limited, cfr. documentation of Frame object.)
+// \endverbatim
+//
+// \warning
+// You can use iostream.h or iostream header files for file I/O,
+// if one declares the define WANT_STD_IOSTREAM then the standard C++
+// iostreams headers are included instead of the compiler-dependent version
+//
+ *
+ ****************************************************************************/
+#ifndef FRAMES_IO_H
+#define FRAMES_IO_H
+
+#include "utilities/utility_io.h"
+#include "frames.hpp"
+#include "jntarray.hpp"
+#include "jacobian.hpp"
+
+namespace KDL {
+
+ //! width to be used when printing variables out with frames_io.h
+ //! global variable, can be changed.
+
+
+ // I/O to C++ stream.
+ std::ostream& operator << (std::ostream& os,const Vector& v);
+ std::ostream& operator << (std::ostream& os,const Rotation& R);
+ std::ostream& operator << (std::ostream& os,const Frame& T);
+ std::ostream& operator << (std::ostream& os,const Twist& T);
+ std::ostream& operator << (std::ostream& os,const Wrench& T);
+ std::ostream& operator << (std::ostream& os,const Vector2& v);
+ std::ostream& operator << (std::ostream& os,const Rotation2& R);
+ std::ostream& operator << (std::ostream& os,const Frame2& T);
+
+
+
+ std::istream& operator >> (std::istream& is,Vector& v);
+ std::istream& operator >> (std::istream& is,Rotation& R);
+ std::istream& operator >> (std::istream& is,Frame& T);
+ std::istream& operator >> (std::istream& os,Twist& T);
+ std::istream& operator >> (std::istream& os,Wrench& T);
+ std::istream& operator >> (std::istream& is,Vector2& v);
+ std::istream& operator >> (std::istream& is,Rotation2& R);
+ std::istream& operator >> (std::istream& is,Frame2& T);
+
+
+} // namespace Frame
+
+#endif
diff --git a/intern/itasc/kdl/framevel.cpp b/intern/itasc/kdl/framevel.cpp
new file mode 100644
index 00000000000..c0a94d64947
--- /dev/null
+++ b/intern/itasc/kdl/framevel.cpp
@@ -0,0 +1,27 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: framevel.cpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+
+#include "framevel.hpp"
+
+namespace KDL {
+
+#ifndef KDL_INLINE
+ #include "framevel.inl"
+#endif
+
+
+
+}
diff --git a/intern/itasc/kdl/framevel.hpp b/intern/itasc/kdl/framevel.hpp
new file mode 100644
index 00000000000..21a7844f522
--- /dev/null
+++ b/intern/itasc/kdl/framevel.hpp
@@ -0,0 +1,382 @@
+/*****************************************************************************
+ * \file
+ * This file contains the definition of classes for a
+ * Rall Algebra of (subset of) the classes defined in frames,
+ * i.e. classes that contain a pair (value,derivative) and define operations on that pair
+ * this classes are usefull for automatic differentiation ( <-> symbolic diff , <-> numeric diff)
+ * Defines VectorVel, RotationVel, FrameVel. Look at Frames.h for details on how to work
+ * with Frame objects.
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: framevel.hpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+#ifndef KDL_FRAMEVEL_H
+#define KDL_FRAMEVEL_H
+
+#include "utilities/utility.h"
+#include "utilities/rall1d.h"
+#include "utilities/traits.h"
+
+#include "frames.hpp"
+
+
+
+namespace KDL {
+
+typedef Rall1d<double> doubleVel;
+
+IMETHOD doubleVel diff(const doubleVel& a,const doubleVel& b,double dt=1.0) {
+ return doubleVel((b.t-a.t)/dt,(b.grad-a.grad)/dt);
+}
+
+IMETHOD doubleVel addDelta(const doubleVel& a,const doubleVel&da,double dt=1.0) {
+ return doubleVel(a.t+da.t*dt,a.grad+da.grad*dt);
+}
+
+IMETHOD void random(doubleVel& F) {
+ random(F.t);
+ random(F.grad);
+}
+IMETHOD void posrandom(doubleVel& F) {
+ posrandom(F.t);
+ posrandom(F.grad);
+}
+
+}
+
+template <>
+struct Traits<KDL::doubleVel> {
+ typedef double valueType;
+ typedef KDL::doubleVel derivType;
+};
+
+namespace KDL {
+
+class TwistVel;
+class VectorVel;
+class FrameVel;
+class RotationVel;
+
+class VectorVel
+// = TITLE
+// An VectorVel is a Vector and its first derivative
+// = CLASS TYPE
+// Concrete
+{
+public:
+ Vector p; // position vector
+ Vector v; // velocity vector
+public:
+ VectorVel():p(),v(){}
+ VectorVel(const Vector& _p,const Vector& _v):p(_p),v(_v) {}
+ explicit VectorVel(const Vector& _p):p(_p),v(Vector::Zero()) {}
+
+ Vector value() const { return p;}
+ Vector deriv() const { return v;}
+
+ IMETHOD VectorVel& operator = (const VectorVel& arg);
+ IMETHOD VectorVel& operator = (const Vector& arg);
+ IMETHOD VectorVel& operator += (const VectorVel& arg);
+ IMETHOD VectorVel& operator -= (const VectorVel& arg);
+ IMETHOD static VectorVel Zero();
+ IMETHOD void ReverseSign();
+ IMETHOD doubleVel Norm() const;
+ IMETHOD friend VectorVel operator + (const VectorVel& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator - (const VectorVel& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator + (const Vector& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator - (const Vector& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator + (const VectorVel& r1,const Vector& r2);
+ IMETHOD friend VectorVel operator - (const VectorVel& r1,const Vector& r2);
+ IMETHOD friend VectorVel operator * (const VectorVel& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator * (const VectorVel& r1,const Vector& r2);
+ IMETHOD friend VectorVel operator * (const Vector& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator * (const VectorVel& r1,double r2);
+ IMETHOD friend VectorVel operator * (double r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator * (const doubleVel& r1,const VectorVel& r2);
+ IMETHOD friend VectorVel operator * (const VectorVel& r2,const doubleVel& r1);
+ IMETHOD friend VectorVel operator*(const Rotation& R,const VectorVel& x);
+
+ IMETHOD friend VectorVel operator / (const VectorVel& r1,double r2);
+ IMETHOD friend VectorVel operator / (const VectorVel& r2,const doubleVel& r1);
+ IMETHOD friend void SetToZero(VectorVel& v);
+
+
+ IMETHOD friend bool Equal(const VectorVel& r1,const VectorVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Vector& r1,const VectorVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const VectorVel& r1,const Vector& r2,double eps=epsilon);
+ IMETHOD friend VectorVel operator - (const VectorVel& r);
+ IMETHOD friend doubleVel dot(const VectorVel& lhs,const VectorVel& rhs);
+ IMETHOD friend doubleVel dot(const VectorVel& lhs,const Vector& rhs);
+ IMETHOD friend doubleVel dot(const Vector& lhs,const VectorVel& rhs);
+};
+
+
+
+class RotationVel
+// = TITLE
+// An RotationVel is a Rotation and its first derivative, a rotation vector
+// = CLASS TYPE
+// Concrete
+{
+public:
+ Rotation R; // Rotation matrix
+ Vector w; // rotation vector
+public:
+ RotationVel():R(),w() {}
+ explicit RotationVel(const Rotation& _R):R(_R),w(Vector::Zero()){}
+ RotationVel(const Rotation& _R,const Vector& _w):R(_R),w(_w){}
+
+
+ Rotation value() const { return R;}
+ Vector deriv() const { return w;}
+
+
+ IMETHOD RotationVel& operator = (const RotationVel& arg);
+ IMETHOD RotationVel& operator = (const Rotation& arg);
+ IMETHOD VectorVel UnitX() const;
+ IMETHOD VectorVel UnitY() const;
+ IMETHOD VectorVel UnitZ() const;
+ IMETHOD static RotationVel Identity();
+ IMETHOD RotationVel Inverse() const;
+ IMETHOD VectorVel Inverse(const VectorVel& arg) const;
+ IMETHOD VectorVel Inverse(const Vector& arg) const;
+ IMETHOD VectorVel operator*(const VectorVel& arg) const;
+ IMETHOD VectorVel operator*(const Vector& arg) const;
+ IMETHOD void DoRotX(const doubleVel& angle);
+ IMETHOD void DoRotY(const doubleVel& angle);
+ IMETHOD void DoRotZ(const doubleVel& angle);
+ IMETHOD static RotationVel RotX(const doubleVel& angle);
+ IMETHOD static RotationVel RotY(const doubleVel& angle);
+ IMETHOD static RotationVel RotZ(const doubleVel& angle);
+ IMETHOD static RotationVel Rot(const Vector& rotvec,const doubleVel& angle);
+ // rotvec has arbitrary norm
+ // rotation around a constant vector !
+ IMETHOD static RotationVel Rot2(const Vector& rotvec,const doubleVel& angle);
+ // rotvec is normalized.
+ // rotation around a constant vector !
+ IMETHOD friend RotationVel operator* (const RotationVel& r1,const RotationVel& r2);
+ IMETHOD friend RotationVel operator* (const Rotation& r1,const RotationVel& r2);
+ IMETHOD friend RotationVel operator* (const RotationVel& r1,const Rotation& r2);
+ IMETHOD friend bool Equal(const RotationVel& r1,const RotationVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Rotation& r1,const RotationVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const RotationVel& r1,const Rotation& r2,double eps=epsilon);
+
+ IMETHOD TwistVel Inverse(const TwistVel& arg) const;
+ IMETHOD TwistVel Inverse(const Twist& arg) const;
+ IMETHOD TwistVel operator * (const TwistVel& arg) const;
+ IMETHOD TwistVel operator * (const Twist& arg) const;
+};
+
+
+
+
+class FrameVel
+// = TITLE
+// An FrameVel is a Frame and its first derivative, a Twist vector
+// = CLASS TYPE
+// Concrete
+// = CAVEATS
+//
+{
+public:
+ RotationVel M;
+ VectorVel p;
+public:
+ FrameVel(){}
+
+ explicit FrameVel(const Frame& _T):
+ M(_T.M),p(_T.p) {}
+
+ FrameVel(const Frame& _T,const Twist& _t):
+ M(_T.M,_t.rot),p(_T.p,_t.vel) {}
+
+ FrameVel(const RotationVel& _M,const VectorVel& _p):
+ M(_M),p(_p) {}
+
+
+ Frame value() const { return Frame(M.value(),p.value());}
+ Twist deriv() const { return Twist(p.deriv(),M.deriv());}
+
+
+ IMETHOD FrameVel& operator = (const Frame& arg);
+ IMETHOD FrameVel& operator = (const FrameVel& arg);
+ IMETHOD static FrameVel Identity();
+ IMETHOD FrameVel Inverse() const;
+ IMETHOD VectorVel Inverse(const VectorVel& arg) const;
+ IMETHOD VectorVel operator*(const VectorVel& arg) const;
+ IMETHOD VectorVel operator*(const Vector& arg) const;
+ IMETHOD VectorVel Inverse(const Vector& arg) const;
+ IMETHOD Frame GetFrame() const;
+ IMETHOD Twist GetTwist() const;
+ IMETHOD friend FrameVel operator * (const FrameVel& f1,const FrameVel& f2);
+ IMETHOD friend FrameVel operator * (const Frame& f1,const FrameVel& f2);
+ IMETHOD friend FrameVel operator * (const FrameVel& f1,const Frame& f2);
+ IMETHOD friend bool Equal(const FrameVel& r1,const FrameVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const Frame& r1,const FrameVel& r2,double eps=epsilon);
+ IMETHOD friend bool Equal(const FrameVel& r1,const Frame& r2,double eps=epsilon);
+
+ IMETHOD TwistVel Inverse(const TwistVel& arg) const;
+ IMETHOD TwistVel Inverse(const Twist& arg) const;
+ IMETHOD TwistVel operator * (const TwistVel& arg) const;
+ IMETHOD TwistVel operator * (const Twist& arg) const;
+};
+
+
+
+
+
+//very similar to Wrench class.
+class TwistVel
+// = TITLE
+// This class represents a TwistVel. This is a velocity and rotational velocity together
+{
+public:
+ VectorVel vel;
+ VectorVel rot;
+public:
+
+// = Constructors
+ TwistVel():vel(),rot() {};
+ TwistVel(const VectorVel& _vel,const VectorVel& _rot):vel(_vel),rot(_rot) {};
+ TwistVel(const Twist& p,const Twist& v):vel(p.vel, v.vel), rot( p.rot, v.rot) {};
+ TwistVel(const Twist& p):vel(p.vel), rot( p.rot) {};
+
+ Twist value() const {
+ return Twist(vel.value(),rot.value());
+ }
+ Twist deriv() const {
+ return Twist(vel.deriv(),rot.deriv());
+ }
+// = Operators
+ IMETHOD TwistVel& operator-=(const TwistVel& arg);
+ IMETHOD TwistVel& operator+=(const TwistVel& arg);
+
+// = External operators
+ IMETHOD friend TwistVel operator*(const TwistVel& lhs,double rhs);
+ IMETHOD friend TwistVel operator*(double lhs,const TwistVel& rhs);
+ IMETHOD friend TwistVel operator/(const TwistVel& lhs,double rhs);
+
+ IMETHOD friend TwistVel operator*(const TwistVel& lhs,const doubleVel& rhs);
+ IMETHOD friend TwistVel operator*(const doubleVel& lhs,const TwistVel& rhs);
+ IMETHOD friend TwistVel operator/(const TwistVel& lhs,const doubleVel& rhs);
+
+ IMETHOD friend TwistVel operator+(const TwistVel& lhs,const TwistVel& rhs);
+ IMETHOD friend TwistVel operator-(const TwistVel& lhs,const TwistVel& rhs);
+ IMETHOD friend TwistVel operator-(const TwistVel& arg);
+ IMETHOD friend void SetToZero(TwistVel& v);
+
+
+// = Zero
+ static IMETHOD TwistVel Zero();
+
+// = Reverse Sign
+ IMETHOD void ReverseSign();
+
+// = Change Reference point
+ IMETHOD TwistVel RefPoint(const VectorVel& v_base_AB);
+ // Changes the reference point of the TwistVel.
+ // The VectorVel v_base_AB is expressed in the same base as the TwistVel
+ // The VectorVel v_base_AB is a VectorVel from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+
+ // = Equality operators
+ // do not use operator == because the definition of Equal(.,.) is slightly
+ // different. It compares whether the 2 arguments are equal in an eps-interval
+ IMETHOD friend bool Equal(const TwistVel& a,const TwistVel& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const Twist& a,const TwistVel& b,double eps=epsilon);
+ IMETHOD friend bool Equal(const TwistVel& a,const Twist& b,double eps=epsilon);
+
+// = Conversion to other entities
+ IMETHOD Twist GetTwist() const;
+ IMETHOD Twist GetTwistDot() const;
+// = Friends
+ friend class RotationVel;
+ friend class FrameVel;
+
+};
+
+IMETHOD VectorVel diff(const VectorVel& a,const VectorVel& b,double dt=1.0) {
+ return VectorVel(diff(a.p,b.p,dt),diff(a.v,b.v,dt));
+}
+
+IMETHOD VectorVel addDelta(const VectorVel& a,const VectorVel&da,double dt=1.0) {
+ return VectorVel(addDelta(a.p,da.p,dt),addDelta(a.v,da.v,dt));
+}
+IMETHOD VectorVel diff(const RotationVel& a,const RotationVel& b,double dt = 1.0) {
+ return VectorVel(diff(a.R,b.R,dt),diff(a.w,b.w,dt));
+}
+
+IMETHOD RotationVel addDelta(const RotationVel& a,const VectorVel&da,double dt=1.0) {
+ return RotationVel(addDelta(a.R,da.p,dt),addDelta(a.w,da.v,dt));
+}
+
+IMETHOD TwistVel diff(const FrameVel& a,const FrameVel& b,double dt=1.0) {
+ return TwistVel(diff(a.M,b.M,dt),diff(a.p,b.p,dt));
+}
+
+IMETHOD FrameVel addDelta(const FrameVel& a,const TwistVel& da,double dt=1.0) {
+ return FrameVel(
+ addDelta(a.M,da.rot,dt),
+ addDelta(a.p,da.vel,dt)
+ );
+}
+
+IMETHOD void random(VectorVel& a) {
+ random(a.p);
+ random(a.v);
+}
+IMETHOD void random(TwistVel& a) {
+ random(a.vel);
+ random(a.rot);
+}
+
+IMETHOD void random(RotationVel& R) {
+ random(R.R);
+ random(R.w);
+}
+
+IMETHOD void random(FrameVel& F) {
+ random(F.M);
+ random(F.p);
+}
+IMETHOD void posrandom(VectorVel& a) {
+ posrandom(a.p);
+ posrandom(a.v);
+}
+IMETHOD void posrandom(TwistVel& a) {
+ posrandom(a.vel);
+ posrandom(a.rot);
+}
+
+IMETHOD void posrandom(RotationVel& R) {
+ posrandom(R.R);
+ posrandom(R.w);
+}
+
+IMETHOD void posrandom(FrameVel& F) {
+ posrandom(F.M);
+ posrandom(F.p);
+}
+
+#ifdef KDL_INLINE
+#include "framevel.inl"
+#endif
+
+} // namespace
+
+#endif
+
+
+
+
diff --git a/intern/itasc/kdl/framevel.inl b/intern/itasc/kdl/framevel.inl
new file mode 100644
index 00000000000..994b3d2028e
--- /dev/null
+++ b/intern/itasc/kdl/framevel.inl
@@ -0,0 +1,534 @@
+/*****************************************************************************
+ * \file
+ * provides inline functions of rframes.h
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: framevel.inl 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+
+// Methods and operators related to FrameVelVel
+// They all delegate most of the work to RotationVelVel and VectorVelVel
+FrameVel& FrameVel::operator = (const FrameVel& arg) {
+ M=arg.M;
+ p=arg.p;
+ return *this;
+}
+
+FrameVel FrameVel::Identity() {
+ return FrameVel(RotationVel::Identity(),VectorVel::Zero());
+}
+
+
+FrameVel operator *(const FrameVel& lhs,const FrameVel& rhs)
+{
+ return FrameVel(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+FrameVel operator *(const FrameVel& lhs,const Frame& rhs)
+{
+ return FrameVel(lhs.M*rhs.M,lhs.M*rhs.p+lhs.p);
+}
+FrameVel operator *(const Frame& lhs,const FrameVel& rhs)
+{
+ return FrameVel(lhs.M*rhs.M , lhs.M*rhs.p+lhs.p );
+}
+
+VectorVel FrameVel::operator *(const VectorVel & arg) const
+{
+ return M*arg+p;
+}
+VectorVel FrameVel::operator *(const Vector & arg) const
+{
+ return M*arg+p;
+}
+
+VectorVel FrameVel::Inverse(const VectorVel& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+VectorVel FrameVel::Inverse(const Vector& arg) const
+{
+ return M.Inverse(arg-p);
+}
+
+FrameVel FrameVel::Inverse() const
+{
+ return FrameVel(M.Inverse(),-M.Inverse(p));
+}
+
+FrameVel& FrameVel::operator = (const Frame& arg) {
+ M = arg.M;
+ p = arg.p;
+ return *this;
+}
+bool Equal(const FrameVel& r1,const FrameVel& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+bool Equal(const Frame& r1,const FrameVel& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+bool Equal(const FrameVel& r1,const Frame& r2,double eps) {
+ return (Equal(r1.M,r2.M,eps) && Equal(r1.p,r2.p,eps));
+}
+
+Frame FrameVel::GetFrame() const {
+ return Frame(M.R,p.p);
+}
+
+Twist FrameVel::GetTwist() const {
+ return Twist(p.v,M.w);
+}
+
+
+RotationVel operator* (const RotationVel& r1,const RotationVel& r2) {
+ return RotationVel( r1.R*r2.R, r1.w + r1.R*r2.w );
+}
+
+RotationVel operator* (const Rotation& r1,const RotationVel& r2) {
+ return RotationVel( r1*r2.R, r1*r2.w );
+}
+
+RotationVel operator* (const RotationVel& r1,const Rotation& r2) {
+ return RotationVel( r1.R*r2, r1.w );
+}
+
+RotationVel& RotationVel::operator = (const RotationVel& arg) {
+ R=arg.R;
+ w=arg.w;
+ return *this;
+ }
+RotationVel& RotationVel::operator = (const Rotation& arg) {
+ R=arg;
+ w=Vector::Zero();
+ return *this;
+}
+
+VectorVel RotationVel::UnitX() const {
+ return VectorVel(R.UnitX(),w*R.UnitX());
+}
+
+VectorVel RotationVel::UnitY() const {
+ return VectorVel(R.UnitY(),w*R.UnitY());
+}
+
+VectorVel RotationVel::UnitZ() const {
+ return VectorVel(R.UnitZ(),w*R.UnitZ());
+}
+
+
+
+RotationVel RotationVel::Identity() {
+ return RotationVel(Rotation::Identity(),Vector::Zero());
+}
+
+RotationVel RotationVel::Inverse() const {
+ return RotationVel(R.Inverse(),-R.Inverse(w));
+}
+
+VectorVel RotationVel::Inverse(const VectorVel& arg) const {
+ Vector tmp=R.Inverse(arg.p);
+ return VectorVel(tmp,
+ R.Inverse(arg.v-w*arg.p)
+ );
+}
+
+VectorVel RotationVel::Inverse(const Vector& arg) const {
+ Vector tmp=R.Inverse(arg);
+ return VectorVel(tmp,
+ R.Inverse(-w*arg)
+ );
+}
+
+
+VectorVel RotationVel::operator*(const VectorVel& arg) const {
+ Vector tmp=R*arg.p;
+ return VectorVel(tmp,w*tmp+R*arg.v);
+}
+
+VectorVel RotationVel::operator*(const Vector& arg) const {
+ Vector tmp=R*arg;
+ return VectorVel(tmp,w*tmp);
+}
+
+
+// = Rotations
+// The Rot... static functions give the value of the appropriate rotation matrix back.
+// The DoRot... functions apply a rotation R to *this,such that *this = *this * R.
+
+void RotationVel::DoRotX(const doubleVel& angle) {
+ w+=R*Vector(angle.grad,0,0);
+ R.DoRotX(angle.t);
+}
+RotationVel RotationVel::RotX(const doubleVel& angle) {
+ return RotationVel(Rotation::RotX(angle.t),Vector(angle.grad,0,0));
+}
+
+void RotationVel::DoRotY(const doubleVel& angle) {
+ w+=R*Vector(0,angle.grad,0);
+ R.DoRotY(angle.t);
+}
+RotationVel RotationVel::RotY(const doubleVel& angle) {
+ return RotationVel(Rotation::RotX(angle.t),Vector(0,angle.grad,0));
+}
+
+void RotationVel::DoRotZ(const doubleVel& angle) {
+ w+=R*Vector(0,0,angle.grad);
+ R.DoRotZ(angle.t);
+}
+RotationVel RotationVel::RotZ(const doubleVel& angle) {
+ return RotationVel(Rotation::RotZ(angle.t),Vector(0,0,angle.grad));
+}
+
+
+RotationVel RotationVel::Rot(const Vector& rotvec,const doubleVel& angle)
+// rotvec has arbitrary norm
+// rotation around a constant vector !
+{
+ Vector v(rotvec);
+ v.Normalize();
+ return RotationVel(Rotation::Rot2(v,angle.t),v*angle.grad);
+}
+
+RotationVel RotationVel::Rot2(const Vector& rotvec,const doubleVel& angle)
+ // rotvec is normalized.
+{
+ return RotationVel(Rotation::Rot2(rotvec,angle.t),rotvec*angle.grad);
+}
+
+
+VectorVel operator + (const VectorVel& r1,const VectorVel& r2) {
+ return VectorVel(r1.p+r2.p,r1.v+r2.v);
+}
+
+VectorVel operator - (const VectorVel& r1,const VectorVel& r2) {
+ return VectorVel(r1.p-r2.p,r1.v-r2.v);
+}
+
+VectorVel operator + (const VectorVel& r1,const Vector& r2) {
+ return VectorVel(r1.p+r2,r1.v);
+}
+
+VectorVel operator - (const VectorVel& r1,const Vector& r2) {
+ return VectorVel(r1.p-r2,r1.v);
+}
+
+VectorVel operator + (const Vector& r1,const VectorVel& r2) {
+ return VectorVel(r1+r2.p,r2.v);
+}
+
+VectorVel operator - (const Vector& r1,const VectorVel& r2) {
+ return VectorVel(r1-r2.p,-r2.v);
+}
+
+// unary -
+VectorVel operator - (const VectorVel& r) {
+ return VectorVel(-r.p,-r.v);
+}
+
+void SetToZero(VectorVel& v){
+ SetToZero(v.p);
+ SetToZero(v.v);
+}
+
+// cross prod.
+VectorVel operator * (const VectorVel& r1,const VectorVel& r2) {
+ return VectorVel(r1.p*r2.p, r1.p*r2.v+r1.v*r2.p);
+}
+
+VectorVel operator * (const VectorVel& r1,const Vector& r2) {
+ return VectorVel(r1.p*r2, r1.v*r2);
+}
+
+VectorVel operator * (const Vector& r1,const VectorVel& r2) {
+ return VectorVel(r1*r2.p, r1*r2.v);
+}
+
+
+
+// scalar mult.
+VectorVel operator * (double r1,const VectorVel& r2) {
+ return VectorVel(r1*r2.p, r1*r2.v);
+}
+
+VectorVel operator * (const VectorVel& r1,double r2) {
+ return VectorVel(r1.p*r2, r1.v*r2);
+}
+
+
+
+VectorVel operator * (const doubleVel& r1,const VectorVel& r2) {
+ return VectorVel(r1.t*r2.p, r1.t*r2.v + r1.grad*r2.p);
+}
+
+VectorVel operator * (const VectorVel& r2,const doubleVel& r1) {
+ return VectorVel(r1.t*r2.p, r1.t*r2.v + r1.grad*r2.p);
+}
+
+VectorVel operator / (const VectorVel& r1,double r2) {
+ return VectorVel(r1.p/r2, r1.v/r2);
+}
+
+VectorVel operator / (const VectorVel& r2,const doubleVel& r1) {
+ return VectorVel(r2.p/r1.t, r2.v/r1.t - r2.p*r1.grad/r1.t/r1.t);
+}
+
+VectorVel operator*(const Rotation& R,const VectorVel& x) {
+ return VectorVel(R*x.p,R*x.v);
+}
+
+VectorVel& VectorVel::operator = (const VectorVel& arg) {
+ p=arg.p;
+ v=arg.v;
+ return *this;
+}
+VectorVel& VectorVel::operator = (const Vector& arg) {
+ p=arg;
+ v=Vector::Zero();
+ return *this;
+}
+VectorVel& VectorVel::operator += (const VectorVel& arg) {
+ p+=arg.p;
+ v+=arg.v;
+ return *this;
+}
+VectorVel& VectorVel::operator -= (const VectorVel& arg) {
+ p-=arg.p;
+ v-=arg.v;
+ return *this;
+}
+
+VectorVel VectorVel::Zero() {
+ return VectorVel(Vector::Zero(),Vector::Zero());
+}
+void VectorVel::ReverseSign() {
+ p.ReverseSign();
+ v.ReverseSign();
+}
+doubleVel VectorVel::Norm() const {
+ double n = p.Norm();
+ return doubleVel(n,dot(p,v)/n);
+}
+
+bool Equal(const VectorVel& r1,const VectorVel& r2,double eps) {
+ return (Equal(r1.p,r2.p,eps) && Equal(r1.v,r2.v,eps));
+}
+bool Equal(const Vector& r1,const VectorVel& r2,double eps) {
+ return (Equal(r1,r2.p,eps) && Equal(Vector::Zero(),r2.v,eps));
+}
+bool Equal(const VectorVel& r1,const Vector& r2,double eps) {
+ return (Equal(r1.p,r2,eps) && Equal(r1.v,Vector::Zero(),eps));
+}
+
+bool Equal(const RotationVel& r1,const RotationVel& r2,double eps) {
+ return (Equal(r1.w,r2.w,eps) && Equal(r1.R,r2.R,eps));
+}
+bool Equal(const Rotation& r1,const RotationVel& r2,double eps) {
+ return (Equal(Vector::Zero(),r2.w,eps) && Equal(r1,r2.R,eps));
+}
+bool Equal(const RotationVel& r1,const Rotation& r2,double eps) {
+ return (Equal(r1.w,Vector::Zero(),eps) && Equal(r1.R,r2,eps));
+}
+bool Equal(const TwistVel& a,const TwistVel& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+bool Equal(const Twist& a,const TwistVel& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+bool Equal(const TwistVel& a,const Twist& b,double eps) {
+ return (Equal(a.rot,b.rot,eps)&&
+ Equal(a.vel,b.vel,eps) );
+}
+
+
+
+IMETHOD doubleVel dot(const VectorVel& lhs,const VectorVel& rhs) {
+ return doubleVel(dot(lhs.p,rhs.p),dot(lhs.p,rhs.v)+dot(lhs.v,rhs.p));
+}
+IMETHOD doubleVel dot(const VectorVel& lhs,const Vector& rhs) {
+ return doubleVel(dot(lhs.p,rhs),dot(lhs.v,rhs));
+}
+IMETHOD doubleVel dot(const Vector& lhs,const VectorVel& rhs) {
+ return doubleVel(dot(lhs,rhs.p),dot(lhs,rhs.v));
+}
+
+
+
+
+
+
+
+
+
+
+
+
+TwistVel TwistVel::Zero()
+{
+ return TwistVel(VectorVel::Zero(),VectorVel::Zero());
+}
+
+
+void TwistVel::ReverseSign()
+{
+ vel.ReverseSign();
+ rot.ReverseSign();
+}
+
+TwistVel TwistVel::RefPoint(const VectorVel& v_base_AB)
+ // Changes the reference point of the TwistVel.
+ // The VectorVel v_base_AB is expressed in the same base as the TwistVel
+ // The VectorVel v_base_AB is a VectorVel from the old point to
+ // the new point.
+ // Complexity : 6M+6A
+{
+ return TwistVel(this->vel+this->rot*v_base_AB,this->rot);
+}
+
+TwistVel& TwistVel::operator-=(const TwistVel& arg)
+{
+ vel-=arg.vel;
+ rot -=arg.rot;
+ return *this;
+}
+
+TwistVel& TwistVel::operator+=(const TwistVel& arg)
+{
+ vel+=arg.vel;
+ rot +=arg.rot;
+ return *this;
+}
+
+
+TwistVel operator*(const TwistVel& lhs,double rhs)
+{
+ return TwistVel(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+TwistVel operator*(double lhs,const TwistVel& rhs)
+{
+ return TwistVel(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+TwistVel operator/(const TwistVel& lhs,double rhs)
+{
+ return TwistVel(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+
+TwistVel operator*(const TwistVel& lhs,const doubleVel& rhs)
+{
+ return TwistVel(lhs.vel*rhs,lhs.rot*rhs);
+}
+
+TwistVel operator*(const doubleVel& lhs,const TwistVel& rhs)
+{
+ return TwistVel(lhs*rhs.vel,lhs*rhs.rot);
+}
+
+TwistVel operator/(const TwistVel& lhs,const doubleVel& rhs)
+{
+ return TwistVel(lhs.vel/rhs,lhs.rot/rhs);
+}
+
+
+
+// addition of TwistVel's
+TwistVel operator+(const TwistVel& lhs,const TwistVel& rhs)
+{
+ return TwistVel(lhs.vel+rhs.vel,lhs.rot+rhs.rot);
+}
+
+TwistVel operator-(const TwistVel& lhs,const TwistVel& rhs)
+{
+ return TwistVel(lhs.vel-rhs.vel,lhs.rot-rhs.rot);
+}
+
+// unary -
+TwistVel operator-(const TwistVel& arg)
+{
+ return TwistVel(-arg.vel,-arg.rot);
+}
+
+void SetToZero(TwistVel& v)
+{
+ SetToZero(v.vel);
+ SetToZero(v.rot);
+}
+
+
+
+
+
+TwistVel RotationVel::Inverse(const TwistVel& arg) const
+{
+ return TwistVel(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+TwistVel RotationVel::operator * (const TwistVel& arg) const
+{
+ return TwistVel((*this)*arg.vel,(*this)*arg.rot);
+}
+
+TwistVel RotationVel::Inverse(const Twist& arg) const
+{
+ return TwistVel(Inverse(arg.vel),Inverse(arg.rot));
+}
+
+TwistVel RotationVel::operator * (const Twist& arg) const
+{
+ return TwistVel((*this)*arg.vel,(*this)*arg.rot);
+}
+
+
+TwistVel FrameVel::operator * (const TwistVel& arg) const
+{
+ TwistVel tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+
+TwistVel FrameVel::operator * (const Twist& arg) const
+{
+ TwistVel tmp;
+ tmp.rot = M*arg.rot;
+ tmp.vel = M*arg.vel+p*tmp.rot;
+ return tmp;
+}
+
+TwistVel FrameVel::Inverse(const TwistVel& arg) const
+{
+ TwistVel tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+TwistVel FrameVel::Inverse(const Twist& arg) const
+{
+ TwistVel tmp;
+ tmp.rot = M.Inverse(arg.rot);
+ tmp.vel = M.Inverse(arg.vel-p*arg.rot);
+ return tmp;
+}
+
+Twist TwistVel::GetTwist() const {
+ return Twist(vel.p,rot.p);
+}
+
+Twist TwistVel::GetTwistDot() const {
+ return Twist(vel.v,rot.v);
+}
diff --git a/intern/itasc/kdl/inertia.cpp b/intern/itasc/kdl/inertia.cpp
new file mode 100644
index 00000000000..6c7337d0dc4
--- /dev/null
+++ b/intern/itasc/kdl/inertia.cpp
@@ -0,0 +1,48 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "inertia.hpp"
+
+#include <Eigen/Array>
+
+namespace KDL {
+using namespace Eigen;
+
+Inertia::Inertia(double m,double Ixx,double Iyy,double Izz,double Ixy,double Ixz,double Iyz):
+data(Matrix<double,6,6>::Zero())
+{
+ data(0,0)=Ixx;
+ data(1,1)=Iyy;
+ data(2,2)=Izz;
+ data(2,1)=data(1,2)=Ixy;
+ data(3,1)=data(1,3)=Ixz;
+ data(3,2)=data(2,3)=Iyz;
+
+ data.block(3,3,3,3)=m*Matrix<double,3,3>::Identity();
+}
+
+Inertia::~Inertia()
+{
+}
+
+
+
+}
diff --git a/intern/itasc/kdl/inertia.hpp b/intern/itasc/kdl/inertia.hpp
new file mode 100644
index 00000000000..9f33859671c
--- /dev/null
+++ b/intern/itasc/kdl/inertia.hpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDLINERTIA_HPP
+#define KDLINERTIA_HPP
+
+#include <Eigen/Array>
+#include "frames.hpp"
+
+namespace KDL {
+
+using namespace Eigen;
+
+/**
+ * This class offers the inertia-structure of a body
+ * An inertia is defined in a certain reference point and a certain reference base.
+ * The reference point does not have to coincide with the origin of the reference frame.
+ */
+class Inertia{
+public:
+
+ /**
+ * This constructor creates a cartesian space inertia matrix,
+ * the arguments are the mass and the inertia moments in the cog.
+ */
+ Inertia(double m=0,double Ixx=0,double Iyy=0,double Izz=0,double Ixy=0,double Ixz=0,double Iyz=0);
+
+ static inline Inertia Zero(){
+ return Inertia(0,0,0,0,0,0,0);
+ };
+
+ friend class Rotation;
+ friend class Frame;
+
+ /**
+ * F = m*a
+ */
+ // Wrench operator* (const AccelerationTwist& acc);
+
+
+ ~Inertia();
+private:
+ Matrix<double,6,6,RowMajor> data;
+
+};
+
+
+
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/jacobian.cpp b/intern/itasc/kdl/jacobian.cpp
new file mode 100644
index 00000000000..4166a341fe7
--- /dev/null
+++ b/intern/itasc/kdl/jacobian.cpp
@@ -0,0 +1,129 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "jacobian.hpp"
+
+namespace KDL
+{
+ Jacobian::Jacobian(unsigned int _size,unsigned int _nr_blocks):
+ size(_size),nr_blocks(_nr_blocks)
+ {
+ twists = new Twist[size*nr_blocks];
+ }
+
+ Jacobian::Jacobian(const Jacobian& arg):
+ size(arg.columns()),
+ nr_blocks(arg.nr_blocks)
+ {
+ twists = new Twist[size*nr_blocks];
+ for(unsigned int i=0;i<size*nr_blocks;i++)
+ twists[i] = arg.twists[i];
+ }
+
+ Jacobian& Jacobian::operator = (const Jacobian& arg)
+ {
+ assert(size==arg.size);
+ assert(nr_blocks==arg.nr_blocks);
+ for(unsigned int i=0;i<size;i++)
+ twists[i]=arg.twists[i];
+ return *this;
+ }
+
+
+ Jacobian::~Jacobian()
+ {
+ delete [] twists;
+ }
+
+ double Jacobian::operator()(int i,int j)const
+ {
+ assert(i<6*nr_blocks&&j<size);
+ return twists[j+6*(int)(floor((double)i/6))](i%6);
+ }
+
+ double& Jacobian::operator()(int i,int j)
+ {
+ assert(i<6*nr_blocks&&j<size);
+ return twists[j+6*(int)(floor((double)i/6))](i%6);
+ }
+
+ unsigned int Jacobian::rows()const
+ {
+ return 6*nr_blocks;
+ }
+
+ unsigned int Jacobian::columns()const
+ {
+ return size;
+ }
+
+ void SetToZero(Jacobian& jac)
+ {
+ for(unsigned int i=0;i<jac.size*jac.nr_blocks;i++)
+ SetToZero(jac.twists[i]);
+ }
+
+ void changeRefPoint(const Jacobian& src1, const Vector& base_AB, Jacobian& dest)
+ {
+ assert(src1.size==dest.size);
+ assert(src1.nr_blocks==dest.nr_blocks);
+ for(unsigned int i=0;i<src1.size*src1.nr_blocks;i++)
+ dest.twists[i]=src1.twists[i].RefPoint(base_AB);
+ }
+
+ void changeBase(const Jacobian& src1, const Rotation& rot, Jacobian& dest)
+ {
+ assert(src1.size==dest.size);
+ assert(src1.nr_blocks==dest.nr_blocks);
+ for(unsigned int i=0;i<src1.size*src1.nr_blocks;i++)
+ dest.twists[i]=rot*src1.twists[i];
+ }
+
+ void changeRefFrame(const Jacobian& src1,const Frame& frame, Jacobian& dest)
+ {
+ assert(src1.size==dest.size);
+ assert(src1.nr_blocks==dest.nr_blocks);
+ for(unsigned int i=0;i<src1.size*src1.nr_blocks;i++)
+ dest.twists[i]=frame*src1.twists[i];
+ }
+
+ bool Jacobian::operator ==(const Jacobian& arg)
+ {
+ return Equal((*this),arg);
+ }
+
+ bool Jacobian::operator!=(const Jacobian& arg)
+ {
+ return !Equal((*this),arg);
+ }
+
+ bool Equal(const Jacobian& a,const Jacobian& b,double eps)
+ {
+ if(a.rows()==b.rows()&&a.columns()==b.columns()){
+ bool rc=true;
+ for(unsigned int i=0;i<a.columns();i++)
+ rc&=Equal(a.twists[i],b.twists[i],eps);
+ return rc;
+ }else
+ return false;
+ }
+
+}
diff --git a/intern/itasc/kdl/jacobian.hpp b/intern/itasc/kdl/jacobian.hpp
new file mode 100644
index 00000000000..e9057451c9f
--- /dev/null
+++ b/intern/itasc/kdl/jacobian.hpp
@@ -0,0 +1,68 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JACOBIAN_HPP
+#define KDL_JACOBIAN_HPP
+
+#include "frames.hpp"
+
+namespace KDL
+{
+ //Forward declaration
+ class ChainJntToJacSolver;
+
+ class Jacobian
+ {
+ friend class ChainJntToJacSolver;
+ private:
+ unsigned int size;
+ unsigned int nr_blocks;
+ public:
+ Twist* twists;
+ Jacobian(unsigned int size,unsigned int nr=1);
+ Jacobian(const Jacobian& arg);
+
+ Jacobian& operator=(const Jacobian& arg);
+
+ bool operator ==(const Jacobian& arg);
+ bool operator !=(const Jacobian& arg);
+
+ friend bool Equal(const Jacobian& a,const Jacobian& b,double eps=epsilon);
+
+
+ ~Jacobian();
+
+ double operator()(int i,int j)const;
+ double& operator()(int i,int j);
+ unsigned int rows()const;
+ unsigned int columns()const;
+
+ friend void SetToZero(Jacobian& jac);
+
+ friend void changeRefPoint(const Jacobian& src1, const Vector& base_AB, Jacobian& dest);
+ friend void changeBase(const Jacobian& src1, const Rotation& rot, Jacobian& dest);
+ friend void changeRefFrame(const Jacobian& src1,const Frame& frame, Jacobian& dest);
+
+
+ };
+}
+
+#endif
diff --git a/intern/itasc/kdl/jntarray.cpp b/intern/itasc/kdl/jntarray.cpp
new file mode 100644
index 00000000000..2adb76081f3
--- /dev/null
+++ b/intern/itasc/kdl/jntarray.cpp
@@ -0,0 +1,152 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "jntarray.hpp"
+
+namespace KDL
+{
+ JntArray::JntArray():
+ size(0),
+ data(NULL)
+ {
+ }
+
+ JntArray::JntArray(unsigned int _size):
+ size(_size)
+ {
+ assert(0 < size);
+ data = new double[size];
+ SetToZero(*this);
+ }
+
+
+ JntArray::JntArray(const JntArray& arg):
+ size(arg.size)
+ {
+ data = ((0 < size) ? new double[size] : NULL);
+ for(unsigned int i=0;i<size;i++)
+ data[i]=arg.data[i];
+ }
+
+ JntArray& JntArray::operator = (const JntArray& arg)
+ {
+ assert(size==arg.size);
+ for(unsigned int i=0;i<size;i++)
+ data[i]=arg.data[i];
+ return *this;
+ }
+
+
+ JntArray::~JntArray()
+ {
+ delete [] data;
+ }
+
+ void JntArray::resize(unsigned int newSize)
+ {
+ delete [] data;
+ size = newSize;
+ data = new double[size];
+ SetToZero(*this);
+ }
+
+ double JntArray::operator()(unsigned int i,unsigned int j)const
+ {
+ assert(i<size&&j==0);
+ assert(0 != size); // found JntArray containing no data
+ return data[i];
+ }
+
+ double& JntArray::operator()(unsigned int i,unsigned int j)
+ {
+ assert(i<size&&j==0);
+ assert(0 != size); // found JntArray containing no data
+ return data[i];
+ }
+
+ unsigned int JntArray::rows()const
+ {
+ return size;
+ }
+
+ unsigned int JntArray::columns()const
+ {
+ return 0;
+ }
+
+ void Add(const JntArray& src1,const JntArray& src2,JntArray& dest)
+ {
+ assert(src1.size==src2.size&&src1.size==dest.size);
+ for(unsigned int i=0;i<dest.size;i++)
+ dest.data[i]=src1.data[i]+src2.data[i];
+ }
+
+ void Subtract(const JntArray& src1,const JntArray& src2,JntArray& dest)
+ {
+ assert(src1.size==src2.size&&src1.size==dest.size);
+ for(unsigned int i=0;i<dest.size;i++)
+ dest.data[i]=src1.data[i]-src2.data[i];
+ }
+
+ void Multiply(const JntArray& src,const double& factor,JntArray& dest)
+ {
+ assert(src.size==dest.size);
+ for(unsigned int i=0;i<dest.size;i++)
+ dest.data[i]=factor*src.data[i];
+ }
+
+ void Divide(const JntArray& src,const double& factor,JntArray& dest)
+ {
+ assert(src.rows()==dest.size);
+ for(unsigned int i=0;i<dest.size;i++)
+ dest.data[i]=src.data[i]/factor;
+ }
+
+ void MultiplyJacobian(const Jacobian& jac, const JntArray& src, Twist& dest)
+ {
+ assert(jac.columns()==src.size);
+ SetToZero(dest);
+ for(unsigned int i=0;i<6;i++)
+ for(unsigned int j=0;j<src.size;j++)
+ dest(i)+=jac(i,j)*src.data[j];
+ }
+
+ void SetToZero(JntArray& array)
+ {
+ for(unsigned int i=0;i<array.size;i++)
+ array.data[i]=0;
+ }
+
+ bool Equal(const JntArray& src1, const JntArray& src2,double eps)
+ {
+ assert(src1.size==src2.size);
+ bool ret = true;
+ for(unsigned int i=0;i<src1.size;i++)
+ ret = ret && Equal(src1.data[i],src2.data[i],eps);
+ return ret;
+ }
+
+ bool operator==(const JntArray& src1,const JntArray& src2){return Equal(src1,src2);};
+ //bool operator!=(const JntArray& src1,const JntArray& src2){return Equal(src1,src2);};
+
+}
+
+
diff --git a/intern/itasc/kdl/jntarray.hpp b/intern/itasc/kdl/jntarray.hpp
new file mode 100644
index 00000000000..19ffa4343e3
--- /dev/null
+++ b/intern/itasc/kdl/jntarray.hpp
@@ -0,0 +1,217 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JNTARRAY_HPP
+#define KDL_JNTARRAY_HPP
+
+#include "frames.hpp"
+#include "jacobian.hpp"
+
+namespace KDL
+{
+ /**
+ * @brief This class represents an fixed size array containing
+ * joint values of a KDL::Chain.
+ *
+ * \warning An object constructed with the default constructor provides
+ * a valid, but inert, object. Many of the member functions will do
+ * the correct thing and have no affect on this object, but some
+ * member functions can _NOT_ deal with an inert/empty object. These
+ * functions will assert() and exit the program instead. The intended use
+ * case for the default constructor (in an RTT/OCL setting) is outlined in
+ * code below - the default constructor plus the resize() function allow
+ * use of JntArray objects whose size is set within a configureHook() call
+ * (typically based on a size determined from a property).
+
+\code
+class MyTask : public RTT::TaskContext
+{
+ JntArray j;
+ MyTask()
+ {} // invokes j's default constructor
+
+ bool configureHook()
+ {
+ unsigned int size = some_property.rvalue();
+ j.resize(size)
+ ...
+ }
+
+ void updateHook()
+ {
+ ** use j here
+ }
+};
+/endcode
+
+ */
+
+ class JntArray
+ {
+ private:
+ unsigned int size;
+ double* data;
+ public:
+ /** Construct with _no_ data array
+ * @post NULL == data
+ * @post 0 == rows()
+ * @warning use of an object constructed like this, without
+ * a resize() first, may result in program exit! See class
+ * documentation.
+ */
+ JntArray();
+ /**
+ * Constructor of the joint array
+ *
+ * @param size size of the array, this cannot be changed
+ * afterwards.
+ * @pre 0 < size
+ * @post NULL != data
+ * @post 0 < rows()
+ * @post all elements in data have 0 value
+ */
+ JntArray(unsigned int size);
+ /** Copy constructor
+ * @note Will correctly copy an empty object
+ */
+ JntArray(const JntArray& arg);
+ ~JntArray();
+ /** Resize the array
+ * @warning This causes a dynamic allocation (and potentially
+ * also a dynamic deallocation). This _will_ negatively affect
+ * real-time performance!
+ *
+ * @post newSize == rows()
+ * @post NULL != data
+ * @post all elements in data have 0 value
+ */
+ void resize(unsigned int newSize);
+
+ JntArray& operator = ( const JntArray& arg);
+ /**
+ * get_item operator for the joint array, if a second value is
+ * given it should be zero, since a JntArray resembles a column.
+ *
+ *
+ * @return the joint value at position i, starting from 0
+ * @pre 0 != size (ie non-default constructor or resize() called)
+ */
+ double operator()(unsigned int i,unsigned int j=0)const;
+ /**
+ * set_item operator, again if a second value is given it
+ *should be zero.
+ *
+ * @return reference to the joint value at position i,starting
+ *from zero.
+ * @pre 0 != size (ie non-default constructor or resize() called)
+ */
+ double& operator()(unsigned int i,unsigned int j=0);
+ /**
+ * Returns the number of rows (size) of the array
+ *
+ */
+ unsigned int rows()const;
+ /**
+ * Returns the number of columns of the array, always 1.
+ */
+ unsigned int columns()const;
+
+ /**
+ * Function to add two joint arrays, all the arguments must
+ * have the same size: A + B = C. This function is
+ * aliasing-safe, A or B can be the same array as C.
+ *
+ * @param src1 A
+ * @param src2 B
+ * @param dest C
+ */
+ friend void Add(const JntArray& src1,const JntArray& src2,JntArray& dest);
+ /**
+ * Function to subtract two joint arrays, all the arguments must
+ * have the same size: A - B = C. This function is
+ * aliasing-safe, A or B can be the same array as C.
+ *
+ * @param src1 A
+ * @param src2 B
+ * @param dest C
+ */
+ friend void Subtract(const JntArray& src1,const JntArray& src2,JntArray& dest);
+ /**
+ * Function to multiply all the array values with a scalar
+ * factor: A*b=C. This function is aliasing-safe, A can be the
+ * same array as C.
+ *
+ * @param src A
+ * @param factor b
+ * @param dest C
+ */
+ friend void Multiply(const JntArray& src,const double& factor,JntArray& dest);
+ /**
+ * Function to divide all the array values with a scalar
+ * factor: A/b=C. This function is aliasing-safe, A can be the
+ * same array as C.
+ *
+ * @param src A
+ * @param factor b
+ * @param dest C
+ */
+ friend void Divide(const JntArray& src,const double& factor,JntArray& dest);
+ /**
+ * Function to multiply a KDL::Jacobian with a KDL::JntArray
+ * to get a KDL::Twist, it should not be used to calculate the
+ * forward velocity kinematics, the solver classes are built
+ * for this purpose.
+ * J*q = t
+ *
+ * @param jac J
+ * @param src q
+ * @param dest t
+ * @post dest==Twist::Zero() if 0==src.rows() (ie src is empty)
+ */
+ friend void MultiplyJacobian(const Jacobian& jac, const JntArray& src, Twist& dest);
+ /**
+ * Function to set all the values of the array to 0
+ *
+ * @param array
+ */
+ friend void SetToZero(JntArray& array);
+ /**
+ * Function to check if two arrays are the same with a
+ *precision of eps
+ *
+ * @param src1
+ * @param src2
+ * @param eps default: epsilon
+ * @return true if each element of src1 is within eps of the same
+ * element in src2, or if both src1 and src2 have no data (ie 0==rows())
+ */
+ friend bool Equal(const JntArray& src1,const JntArray& src2,double eps=epsilon);
+
+ friend bool operator==(const JntArray& src1,const JntArray& src2);
+ //friend bool operator!=(const JntArray& src1,const JntArray& src2);
+ };
+
+ bool operator==(const JntArray& src1,const JntArray& src2);
+ //bool operator!=(const JntArray& src1,const JntArray& src2);
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/jntarrayacc.cpp b/intern/itasc/kdl/jntarrayacc.cpp
new file mode 100644
index 00000000000..3c9c67d9ef9
--- /dev/null
+++ b/intern/itasc/kdl/jntarrayacc.cpp
@@ -0,0 +1,170 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "jntarrayacc.hpp"
+
+namespace KDL
+{
+ JntArrayAcc::JntArrayAcc(unsigned int size):
+ q(size),qdot(size),qdotdot(size)
+ {
+ }
+ JntArrayAcc::JntArrayAcc(const JntArray& qin, const JntArray& qdotin,const JntArray& qdotdotin):
+ q(qin),qdot(qdotin),qdotdot(qdotdotin)
+ {
+ assert(q.rows()==qdot.rows()&&qdot.rows()==qdotdot.rows());
+ }
+ JntArrayAcc::JntArrayAcc(const JntArray& qin, const JntArray& qdotin):
+ q(qin),qdot(qdotin),qdotdot(q.rows())
+ {
+ assert(q.rows()==qdot.rows());
+ }
+ JntArrayAcc::JntArrayAcc(const JntArray& qin):
+ q(qin),qdot(q.rows()),qdotdot(q.rows())
+ {
+ }
+
+ JntArray JntArrayAcc::value()const
+ {
+ return q;
+ }
+
+ JntArray JntArrayAcc::deriv()const
+ {
+ return qdot;
+ }
+ JntArray JntArrayAcc::dderiv()const
+ {
+ return qdotdot;
+ }
+
+ void Add(const JntArrayAcc& src1,const JntArrayAcc& src2,JntArrayAcc& dest)
+ {
+ Add(src1.q,src2.q,dest.q);
+ Add(src1.qdot,src2.qdot,dest.qdot);
+ Add(src1.qdotdot,src2.qdotdot,dest.qdotdot);
+ }
+ void Add(const JntArrayAcc& src1,const JntArrayVel& src2,JntArrayAcc& dest)
+ {
+ Add(src1.q,src2.q,dest.q);
+ Add(src1.qdot,src2.qdot,dest.qdot);
+ dest.qdotdot=src1.qdotdot;
+ }
+ void Add(const JntArrayAcc& src1,const JntArray& src2,JntArrayAcc& dest)
+ {
+ Add(src1.q,src2,dest.q);
+ dest.qdot=src1.qdot;
+ dest.qdotdot=src1.qdotdot;
+ }
+
+ void Subtract(const JntArrayAcc& src1,const JntArrayAcc& src2,JntArrayAcc& dest)
+ {
+ Subtract(src1.q,src2.q,dest.q);
+ Subtract(src1.qdot,src2.qdot,dest.qdot);
+ Subtract(src1.qdotdot,src2.qdotdot,dest.qdotdot);
+ }
+ void Subtract(const JntArrayAcc& src1,const JntArrayVel& src2,JntArrayAcc& dest)
+ {
+ Subtract(src1.q,src2.q,dest.q);
+ Subtract(src1.qdot,src2.qdot,dest.qdot);
+ dest.qdotdot=src1.qdotdot;
+ }
+ void Subtract(const JntArrayAcc& src1,const JntArray& src2,JntArrayAcc& dest)
+ {
+ Subtract(src1.q,src2,dest.q);
+ dest.qdot=src1.qdot;
+ dest.qdotdot=src1.qdotdot;
+ }
+
+ void Multiply(const JntArrayAcc& src,const double& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.q,factor,dest.q);
+ Multiply(src.qdot,factor,dest.qdot);
+ Multiply(src.qdotdot,factor,dest.qdotdot);
+ }
+ void Multiply(const JntArrayAcc& src,const doubleVel& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.qdot,factor.grad*2,dest.qdot);
+ Multiply(src.qdotdot,factor.t,dest.qdotdot);
+ Add(dest.qdot,dest.qdotdot,dest.qdotdot);
+ Multiply(src.q,factor.grad,dest.q);
+ Multiply(src.qdot,factor.t,dest.qdot);
+ Add(dest.qdot,dest.q,dest.qdot);
+ Multiply(src.q,factor.t,dest.q);
+ }
+ void Multiply(const JntArrayAcc& src,const doubleAcc& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.q,factor.dd,dest.q);
+ Multiply(src.qdot,factor.d*2,dest.qdot);
+ Multiply(src.qdotdot,factor.t,dest.qdotdot);
+ Add(dest.qdotdot,dest.qdot,dest.qdotdot);
+ Add(dest.qdotdot,dest.q,dest.qdotdot);
+ Multiply(src.q,factor.d,dest.q);
+ Multiply(src.qdot,factor.t,dest.qdot);
+ Add(dest.qdot,dest.q,dest.qdot);
+ Multiply(src.q,factor.t,dest.q);
+ }
+
+ void Divide(const JntArrayAcc& src,const double& factor,JntArrayAcc& dest)
+ {
+ Divide(src.q,factor,dest.q);
+ Divide(src.qdot,factor,dest.qdot);
+ Divide(src.qdotdot,factor,dest.qdotdot);
+ }
+ void Divide(const JntArrayAcc& src,const doubleVel& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.q,(2*factor.grad*factor.grad)/(factor.t*factor.t*factor.t),dest.q);
+ Multiply(src.qdot,(2*factor.grad)/(factor.t*factor.t),dest.qdot);
+ Divide(src.qdotdot,factor.t,dest.qdotdot);
+ Subtract(dest.qdotdot,dest.qdot,dest.qdotdot);
+ Add(dest.qdotdot,dest.q,dest.qdotdot);
+ Multiply(src.q,factor.grad/(factor.t*factor.t),dest.q);
+ Divide(src.qdot,factor.t,dest.qdot);
+ Subtract(dest.qdot,dest.q,dest.qdot);
+ Divide(src.q,factor.t,dest.q);
+ }
+ void Divide(const JntArrayAcc& src,const doubleAcc& factor,JntArrayAcc& dest)
+ {
+ Multiply(src.q,(2*factor.d*factor.d)/(factor.t*factor.t*factor.t)-factor.dd/(factor.t*factor.t),dest.q);
+ Multiply(src.qdot,(2*factor.d)/(factor.t*factor.t),dest.qdot);
+ Divide(src.qdotdot,factor.t,dest.qdotdot);
+ Subtract(dest.qdotdot,dest.qdot,dest.qdotdot);
+ Add(dest.qdotdot,dest.q,dest.qdotdot);
+ Multiply(src.q,factor.d/(factor.t*factor.t),dest.q);
+ Divide(src.qdot,factor.t,dest.qdot);
+ Subtract(dest.qdot,dest.q,dest.qdot);
+ Divide(src.q,factor.t,dest.q);
+ }
+
+ void SetToZero(JntArrayAcc& array)
+ {
+ SetToZero(array.q);
+ SetToZero(array.qdot);
+ SetToZero(array.qdotdot);
+ }
+
+ bool Equal(const JntArrayAcc& src1,const JntArrayAcc& src2,double eps)
+ {
+ return (Equal(src1.q,src2.q,eps)&&Equal(src1.qdot,src2.qdot,eps)&&Equal(src1.qdotdot,src2.qdotdot,eps));
+ }
+}
+
+
diff --git a/intern/itasc/kdl/jntarrayacc.hpp b/intern/itasc/kdl/jntarrayacc.hpp
new file mode 100644
index 00000000000..275aa58f21e
--- /dev/null
+++ b/intern/itasc/kdl/jntarrayacc.hpp
@@ -0,0 +1,66 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JNTARRAYACC_HPP
+#define KDL_JNTARRAYACC_HPP
+
+#include "utilities/utility.h"
+#include "jntarray.hpp"
+#include "jntarrayvel.hpp"
+#include "frameacc.hpp"
+
+namespace KDL
+{
+ class JntArrayAcc
+ {
+ public:
+ JntArray q;
+ JntArray qdot;
+ JntArray qdotdot;
+ public:
+ JntArrayAcc(unsigned int size);
+ JntArrayAcc(const JntArray& q,const JntArray& qdot,const JntArray& qdotdot);
+ JntArrayAcc(const JntArray& q,const JntArray& qdot);
+ JntArrayAcc(const JntArray& q);
+
+ JntArray value()const;
+ JntArray deriv()const;
+ JntArray dderiv()const;
+
+ friend void Add(const JntArrayAcc& src1,const JntArrayAcc& src2,JntArrayAcc& dest);
+ friend void Add(const JntArrayAcc& src1,const JntArrayVel& src2,JntArrayAcc& dest);
+ friend void Add(const JntArrayAcc& src1,const JntArray& src2,JntArrayAcc& dest);
+ friend void Subtract(const JntArrayAcc& src1,const JntArrayAcc& src2,JntArrayAcc& dest);
+ friend void Subtract(const JntArrayAcc& src1,const JntArrayVel& src2,JntArrayAcc& dest);
+ friend void Subtract(const JntArrayAcc& src1,const JntArray& src2,JntArrayAcc& dest);
+ friend void Multiply(const JntArrayAcc& src,const double& factor,JntArrayAcc& dest);
+ friend void Multiply(const JntArrayAcc& src,const doubleVel& factor,JntArrayAcc& dest);
+ friend void Multiply(const JntArrayAcc& src,const doubleAcc& factor,JntArrayAcc& dest);
+ friend void Divide(const JntArrayAcc& src,const double& factor,JntArrayAcc& dest);
+ friend void Divide(const JntArrayAcc& src,const doubleVel& factor,JntArrayAcc& dest);
+ friend void Divide(const JntArrayAcc& src,const doubleAcc& factor,JntArrayAcc& dest);
+ friend void SetToZero(JntArrayAcc& array);
+ friend bool Equal(const JntArrayAcc& src1,const JntArrayAcc& src2,double eps=epsilon);
+
+ };
+}
+
+#endif
diff --git a/intern/itasc/kdl/jntarrayvel.cpp b/intern/itasc/kdl/jntarrayvel.cpp
new file mode 100644
index 00000000000..df5c7fb0fb3
--- /dev/null
+++ b/intern/itasc/kdl/jntarrayvel.cpp
@@ -0,0 +1,111 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+#include "jntarrayacc.hpp"
+
+namespace KDL
+{
+ JntArrayVel::JntArrayVel(unsigned int size):
+ q(size),qdot(size)
+ {
+ }
+ JntArrayVel::JntArrayVel(const JntArray& qin, const JntArray& qdotin):
+ q(qin),qdot(qdotin)
+ {
+ assert(q.rows()==qdot.rows());
+ }
+ JntArrayVel::JntArrayVel(const JntArray& qin):
+ q(qin),qdot(q.rows())
+ {
+ }
+
+ JntArray JntArrayVel::value()const
+ {
+ return q;
+ }
+
+ JntArray JntArrayVel::deriv()const
+ {
+ return qdot;
+ }
+
+ void Add(const JntArrayVel& src1,const JntArrayVel& src2,JntArrayVel& dest)
+ {
+ Add(src1.q,src2.q,dest.q);
+ Add(src1.qdot,src2.qdot,dest.qdot);
+ }
+ void Add(const JntArrayVel& src1,const JntArray& src2,JntArrayVel& dest)
+ {
+ Add(src1.q,src2,dest.q);
+ dest.qdot=src1.qdot;
+ }
+
+ void Subtract(const JntArrayVel& src1,const JntArrayVel& src2,JntArrayVel& dest)
+ {
+ Subtract(src1.q,src2.q,dest.q);
+ Subtract(src1.qdot,src2.qdot,dest.qdot);
+ }
+ void Subtract(const JntArrayVel& src1,const JntArray& src2,JntArrayVel& dest)
+ {
+ Subtract(src1.q,src2,dest.q);
+ dest.qdot=src1.qdot;
+ }
+
+ void Multiply(const JntArrayVel& src,const double& factor,JntArrayVel& dest)
+ {
+ Multiply(src.q,factor,dest.q);
+ Multiply(src.qdot,factor,dest.qdot);
+ }
+ void Multiply(const JntArrayVel& src,const doubleVel& factor,JntArrayVel& dest)
+ {
+ Multiply(src.q,factor.grad,dest.q);
+ Multiply(src.qdot,factor.t,dest.qdot);
+ Add(dest.qdot,dest.q,dest.qdot);
+ Multiply(src.q,factor.t,dest.q);
+ }
+
+ void Divide(const JntArrayVel& src,const double& factor,JntArrayVel& dest)
+ {
+ Divide(src.q,factor,dest.q);
+ Divide(src.qdot,factor,dest.qdot);
+ }
+ void Divide(const JntArrayVel& src,const doubleVel& factor,JntArrayVel& dest)
+ {
+ Multiply(src.q,(factor.grad/factor.t/factor.t),dest.q);
+ Divide(src.qdot,factor.t,dest.qdot);
+ Subtract(dest.qdot,dest.q,dest.qdot);
+ Divide(src.q,factor.t,dest.q);
+ }
+
+ void SetToZero(JntArrayVel& array)
+ {
+ SetToZero(array.q);
+ SetToZero(array.qdot);
+ }
+
+ bool Equal(const JntArrayVel& src1,const JntArrayVel& src2,double eps)
+ {
+ return Equal(src1.q,src2.q,eps)&&Equal(src1.qdot,src2.qdot,eps);
+ }
+}
+
+
diff --git a/intern/itasc/kdl/jntarrayvel.hpp b/intern/itasc/kdl/jntarrayvel.hpp
new file mode 100644
index 00000000000..faa82076ebb
--- /dev/null
+++ b/intern/itasc/kdl/jntarrayvel.hpp
@@ -0,0 +1,59 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JNTARRAYVEL_HPP
+#define KDL_JNTARRAYVEL_HPP
+
+#include "utilities/utility.h"
+#include "jntarray.hpp"
+#include "framevel.hpp"
+
+namespace KDL
+{
+
+ class JntArrayVel
+ {
+ public:
+ JntArray q;
+ JntArray qdot;
+ public:
+ JntArrayVel(unsigned int size);
+ JntArrayVel(const JntArray& q,const JntArray& qdot);
+ JntArrayVel(const JntArray& q);
+
+ JntArray value()const;
+ JntArray deriv()const;
+
+ friend void Add(const JntArrayVel& src1,const JntArrayVel& src2,JntArrayVel& dest);
+ friend void Add(const JntArrayVel& src1,const JntArray& src2,JntArrayVel& dest);
+ friend void Subtract(const JntArrayVel& src1,const JntArrayVel& src2,JntArrayVel& dest);
+ friend void Subtract(const JntArrayVel& src1,const JntArray& src2,JntArrayVel& dest);
+ friend void Multiply(const JntArrayVel& src,const double& factor,JntArrayVel& dest);
+ friend void Multiply(const JntArrayVel& src,const doubleVel& factor,JntArrayVel& dest);
+ friend void Divide(const JntArrayVel& src,const double& factor,JntArrayVel& dest);
+ friend void Divide(const JntArrayVel& src,const doubleVel& factor,JntArrayVel& dest);
+ friend void SetToZero(JntArrayVel& array);
+ friend bool Equal(const JntArrayVel& src1,const JntArrayVel& src2,double eps=epsilon);
+
+ };
+}
+
+#endif
diff --git a/intern/itasc/kdl/joint.cpp b/intern/itasc/kdl/joint.cpp
new file mode 100644
index 00000000000..dc5f17e5bf7
--- /dev/null
+++ b/intern/itasc/kdl/joint.cpp
@@ -0,0 +1,153 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "joint.hpp"
+
+namespace KDL {
+
+ Joint::Joint(const JointType& _type, const double& _scale, const double& _offset,
+ const double& _inertia, const double& _damping, const double& _stiffness):
+ type(_type),scale(_scale),offset(_offset),inertia(_inertia),damping(_damping),stiffness(_stiffness)
+ {
+ // for sphere and swing, offset is not used, assume no offset
+ }
+
+ Joint::Joint(const Joint& in):
+ type(in.type),scale(in.scale),offset(in.offset),
+ inertia(in.inertia),damping(in.damping),stiffness(in.stiffness)
+ {
+ }
+
+ Joint& Joint::operator=(const Joint& in)
+ {
+ type=in.type;
+ scale=in.scale;
+ offset=in.offset;
+ inertia=in.inertia;
+ damping=in.damping;
+ stiffness=in.stiffness;
+ return *this;
+ }
+
+
+ Joint::~Joint()
+ {
+ }
+
+ Frame Joint::pose(const double& q)const
+ {
+
+ switch(type){
+ case RotX:
+ return Frame(Rotation::RotX(scale*q+offset));
+ break;
+ case RotY:
+ return Frame(Rotation::RotY(scale*q+offset));
+ break;
+ case RotZ:
+ return Frame(Rotation::RotZ(scale*q+offset));
+ break;
+ case TransX:
+ return Frame(Vector(scale*q+offset,0.0,0.0));
+ break;
+ case TransY:
+ return Frame(Vector(0.0,scale*q+offset,0.0));
+ break;
+ case TransZ:
+ return Frame(Vector(0.0,0.0,scale*q+offset));
+ break;
+ case Sphere:
+ // the joint angles represent a rotation vector expressed in the base frame of the joint
+ // (= the frame you get when there is no offset nor rotation)
+ return Frame(Rot(Vector((&q)[0], (&q)[1], (&q)[2])));
+ break;
+ case Swing:
+ // the joint angles represent a 2D rotation vector in the XZ planee of the base frame of the joint
+ // (= the frame you get when there is no offset nor rotation)
+ return Frame(Rot(Vector((&q)[0], 0.0, (&q)[1])));
+ break;
+ default:
+ return Frame::Identity();
+ break;
+ }
+ }
+
+ Twist Joint::twist(const double& qdot, int dof)const
+ {
+ switch(type){
+ case RotX:
+ return Twist(Vector(0.0,0.0,0.0),Vector(scale*qdot,0.0,0.0));
+ break;
+ case RotY:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,scale*qdot,0.0));
+ break;
+ case RotZ:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,0.0,scale*qdot));
+ break;
+ case TransX:
+ return Twist(Vector(scale*qdot,0.0,0.0),Vector(0.0,0.0,0.0));
+ break;
+ case TransY:
+ return Twist(Vector(0.0,scale*qdot,0.0),Vector(0.0,0.0,0.0));
+ break;
+ case TransZ:
+ return Twist(Vector(0.0,0.0,scale*qdot),Vector(0.0,0.0,0.0));
+ break;
+ case Swing:
+ switch (dof) {
+ case 0:
+ return Twist(Vector(0.0,0.0,0.0),Vector(scale*qdot,0.0,0.0));
+ case 1:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,0.0,scale*qdot));
+ }
+ return Twist::Zero();
+ case Sphere:
+ switch (dof) {
+ case 0:
+ return Twist(Vector(0.0,0.0,0.0),Vector(scale*qdot,0.0,0.0));
+ case 1:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,scale*qdot,0.0));
+ case 2:
+ return Twist(Vector(0.0,0.0,0.0),Vector(0.0,0.0,scale*qdot));
+ }
+ return Twist::Zero();
+ default:
+ return Twist::Zero();
+ break;
+ }
+ }
+
+ unsigned int Joint::getNDof() const
+ {
+ switch (type) {
+ case Sphere:
+ return 3;
+ case Swing:
+ return 2;
+ case None:
+ return 0;
+ default:
+ return 1;
+ }
+ }
+
+} // end of namespace KDL
+
diff --git a/intern/itasc/kdl/joint.hpp b/intern/itasc/kdl/joint.hpp
new file mode 100644
index 00000000000..a1291509f0f
--- /dev/null
+++ b/intern/itasc/kdl/joint.hpp
@@ -0,0 +1,138 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_JOINT_HPP
+#define KDL_JOINT_HPP
+
+#include "frames.hpp"
+#include <string>
+
+namespace KDL {
+
+ /**
+ * \brief This class encapsulates a simple joint, that is with one
+ * parameterized degree of freedom and with scalar dynamic properties.
+ *
+ * A simple joint is described by the following properties :
+ * - scale: ratio between motion input and motion output
+ * - offset: between the "physical" and the "logical" zero position.
+ * - type: revolute or translational, along one of the basic frame axes
+ * - inertia, stiffness and damping: scalars representing the physical
+ * effects along/about the joint axis only.
+ *
+ * @ingroup KinematicFamily
+ */
+ class Joint {
+ public:
+ typedef enum { RotX,RotY,RotZ,TransX,TransY,TransZ,Sphere,Swing,None} JointType;
+ /**
+ * Constructor of a joint.
+ *
+ * @param type type of the joint, default: Joint::None
+ * @param scale scale between joint input and actual geometric
+ * movement, default: 1
+ * @param offset offset between joint input and actual
+ * geometric input, default: 0
+ * @param inertia 1D inertia along the joint axis, default: 0
+ * @param damping 1D damping along the joint axis, default: 0
+ * @param stiffness 1D stiffness along the joint axis,
+ * default: 0
+ */
+ Joint(const JointType& type=None,const double& scale=1,const double& offset=0,
+ const double& inertia=0,const double& damping=0,const double& stiffness=0);
+ Joint(const Joint& in);
+
+ Joint& operator=(const Joint& arg);
+
+ /**
+ * Request the 6D-pose between the beginning and the end of
+ * the joint at joint position q
+ *
+ * @param q the 1D joint position
+ *
+ * @return the resulting 6D-pose
+ */
+ Frame pose(const double& q)const;
+ /**
+ * Request the resulting 6D-velocity with a joint velocity qdot
+ *
+ * @param qdot the 1D joint velocity
+ *
+ * @return the resulting 6D-velocity
+ */
+ Twist twist(const double& qdot, int dof=0)const;
+
+ /**
+ * Request the type of the joint.
+ *
+ * @return const reference to the type
+ */
+ const JointType& getType() const
+ {
+ return type;
+ };
+
+ /**
+ * Request the stringified type of the joint.
+ *
+ * @return const string
+ */
+ const std::string getTypeName() const
+ {
+ switch (type) {
+ case RotX:
+ return "RotX";
+ case RotY:
+ return "RotY";
+ case RotZ:
+ return "RotZ";
+ case TransX:
+ return "TransX";
+ case TransY:
+ return "TransY";
+ case TransZ:
+ return "TransZ";
+ case Sphere:
+ return "Sphere";
+ case Swing:
+ return "Swing";
+ case None:
+ return "None";
+ default:
+ return "None";
+ }
+ };
+ unsigned int getNDof() const;
+
+ virtual ~Joint();
+
+ private:
+ Joint::JointType type;
+ double scale;
+ double offset;
+ double inertia;
+ double damping;
+ double stiffness;
+ };
+
+} // end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/kinfam_io.cpp b/intern/itasc/kdl/kinfam_io.cpp
new file mode 100644
index 00000000000..900e2e101a9
--- /dev/null
+++ b/intern/itasc/kdl/kinfam_io.cpp
@@ -0,0 +1,101 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "kinfam_io.hpp"
+#include "frames_io.hpp"
+
+namespace KDL {
+std::ostream& operator <<(std::ostream& os, const Joint& joint) {
+ return os << joint.getTypeName();
+}
+
+std::istream& operator >>(std::istream& is, Joint& joint) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const Segment& segment) {
+ os << "[" << segment.getJoint() << ",\n" << segment.getFrameToTip() << "]";
+ return os;
+}
+
+std::istream& operator >>(std::istream& is, Segment& segment) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const Chain& chain) {
+ os << "[";
+ for (unsigned int i = 0; i < chain.getNrOfSegments(); i++)
+ os << chain.getSegment(i) << "\n";
+ os << "]";
+ return os;
+}
+
+std::istream& operator >>(std::istream& is, Chain& chain) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const Tree& tree) {
+ SegmentMap::const_iterator root = tree.getSegment("root");
+ return os << root;
+}
+
+std::ostream& operator <<(std::ostream& os, SegmentMap::const_iterator root) {
+ //os<<root->first<<": "<<root->second.segment<<"\n";
+ os << root->first<<"(q_nr: "<<root->second.q_nr<<")"<<"\n \t";
+ for (unsigned int i = 0; i < root->second.children.size(); i++) {
+ os <<(root->second.children[i])<<"\t";
+ }
+ return os << "\n";
+}
+
+std::istream& operator >>(std::istream& is, Tree& tree) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const JntArray& array) {
+ os << "[";
+ for (unsigned int i = 0; i < array.rows(); i++)
+ os << std::setw(KDL_FRAME_WIDTH) << array(i);
+ os << "]";
+ return os;
+}
+
+std::istream& operator >>(std::istream& is, JntArray& array) {
+ return is;
+}
+
+std::ostream& operator <<(std::ostream& os, const Jacobian& jac) {
+ os << "[";
+ for (unsigned int i = 0; i < jac.rows(); i++) {
+ for (unsigned int j = 0; j < jac.columns(); j++)
+ os << std::setw(KDL_FRAME_WIDTH) << jac(i, j);
+ os << std::endl;
+ }
+ os << "]";
+ return os;
+}
+
+std::istream& operator >>(std::istream& is, Jacobian& jac) {
+ return is;
+}
+
+}
+
diff --git a/intern/itasc/kdl/kinfam_io.hpp b/intern/itasc/kdl/kinfam_io.hpp
new file mode 100644
index 00000000000..a8dbfd1c5dc
--- /dev/null
+++ b/intern/itasc/kdl/kinfam_io.hpp
@@ -0,0 +1,70 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_KINFAM_IO_HPP
+#define KDL_KINFAM_IO_HPP
+
+#include <iostream>
+#include <fstream>
+
+#include "joint.hpp"
+#include "segment.hpp"
+#include "chain.hpp"
+#include "jntarray.hpp"
+#include "jacobian.hpp"
+#include "tree.hpp"
+
+namespace KDL {
+std::ostream& operator <<(std::ostream& os, const Joint& joint);
+std::istream& operator >>(std::istream& is, Joint& joint);
+std::ostream& operator <<(std::ostream& os, const Segment& segment);
+std::istream& operator >>(std::istream& is, Segment& segment);
+std::ostream& operator <<(std::ostream& os, const Chain& chain);
+std::istream& operator >>(std::istream& is, Chain& chain);
+
+std::ostream& operator <<(std::ostream& os, const Tree& tree);
+std::istream& operator >>(std::istream& is, Tree& tree);
+
+std::ostream& operator <<(std::ostream& os, SegmentMap::const_iterator it);
+
+std::ostream& operator <<(std::ostream& os, const JntArray& array);
+std::istream& operator >>(std::istream& is, JntArray& array);
+std::ostream& operator <<(std::ostream& os, const Jacobian& jac);
+std::istream& operator >>(std::istream& is, Jacobian& jac);
+
+template<typename T>
+std::ostream& operator<<(std::ostream& os, const std::vector<T>& vec) {
+ os << "[";
+ for (unsigned int i = 0; i < vec.size(); i++)
+ os << vec[i] << " ";
+ os << "]";
+ return os;
+}
+;
+
+template<typename T>
+std::istream& operator >>(std::istream& is, std::vector<T>& vec) {
+ return is;
+}
+;
+}
+#endif
+
diff --git a/intern/itasc/kdl/segment.cpp b/intern/itasc/kdl/segment.cpp
new file mode 100644
index 00000000000..02f71d5e9f1
--- /dev/null
+++ b/intern/itasc/kdl/segment.cpp
@@ -0,0 +1,68 @@
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "segment.hpp"
+
+namespace KDL {
+
+ Segment::Segment(const Joint& _joint, const Frame& _f_tip, const Inertia& _M):
+ joint(_joint),M(_M),
+ f_tip(_f_tip)
+ {
+ }
+
+ Segment::Segment(const Segment& in):
+ joint(in.joint),M(in.M),
+ f_tip(in.f_tip)
+ {
+ }
+
+ Segment& Segment::operator=(const Segment& arg)
+ {
+ joint=arg.joint;
+ M=arg.M;
+ f_tip=arg.f_tip;
+ return *this;
+ }
+
+ Segment::~Segment()
+ {
+ }
+
+ Frame Segment::pose(const double& q)const
+ {
+ return joint.pose(q)*f_tip;
+ }
+
+ Twist Segment::twist(const double& q, const double& qdot, int dof)const
+ {
+ return joint.twist(qdot, dof).RefPoint(pose(q).p);
+ }
+
+ Twist Segment::twist(const Vector& p, const double& qdot, int dof)const
+ {
+ return joint.twist(qdot, dof).RefPoint(p);
+ }
+
+ Twist Segment::twist(const Frame& f, const double& qdot, int dof)const
+ {
+ return (f.M*joint.twist(qdot, dof)).RefPoint(f.p);
+ }
+}//end of namespace KDL
+
diff --git a/intern/itasc/kdl/segment.hpp b/intern/itasc/kdl/segment.hpp
new file mode 100644
index 00000000000..7c82ab418fa
--- /dev/null
+++ b/intern/itasc/kdl/segment.hpp
@@ -0,0 +1,149 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+#ifndef KDL_SEGMENT_HPP
+#define KDL_SEGMENT_HPP
+
+#include "frames.hpp"
+#include "inertia.hpp"
+#include "joint.hpp"
+#include <vector>
+
+namespace KDL {
+
+ /**
+ * \brief This class encapsulates a simple segment, that is a "rigid
+ * body" (i.e., a frame and an inertia) with a joint and with
+ * "handles", root and tip to connect to other segments.
+ *
+ * A simple segment is described by the following properties :
+ * - Joint
+ * - inertia: of the rigid body part of the Segment
+ * - Offset from the end of the joint to the tip of the segment:
+ * the joint is located at the root of the segment.
+ *
+ * @ingroup KinematicFamily
+ */
+ class Segment {
+ friend class Chain;
+ private:
+ Joint joint;
+ Inertia M;
+ Frame f_tip;
+
+ public:
+ /**
+ * Constructor of the segment
+ *
+ * @param joint joint of the segment, default:
+ * Joint(Joint::None)
+ * @param f_tip frame from the end of the joint to the tip of
+ * the segment, default: Frame::Identity()
+ * @param M rigid body inertia of the segment, default: Inertia::Zero()
+ */
+ Segment(const Joint& joint=Joint(), const Frame& f_tip=Frame::Identity(),const Inertia& M = Inertia::Zero());
+ Segment(const Segment& in);
+ Segment& operator=(const Segment& arg);
+
+ virtual ~Segment();
+
+ /**
+ * Request the pose of the segment, given the joint position q.
+ *
+ * @param q 1D position of the joint
+ *
+ * @return pose from the root to the tip of the segment
+ */
+ Frame pose(const double& q)const;
+ /**
+ * Request the 6D-velocity of the tip of the segment, given
+ * the joint position q and the joint velocity qdot.
+ *
+ * @param q ND position of the joint
+ * @param qdot ND velocity of the joint
+ *
+ * @return 6D-velocity of the tip of the segment, expressed
+ *in the base-frame of the segment(root) and with the tip of
+ *the segment as reference point.
+ */
+ Twist twist(const double& q,const double& qdot, int dof=0)const;
+
+ /**
+ * Request the 6D-velocity at a given point p, relative to base frame of the segment
+ * givven the joint velocity qdot.
+ *
+ * @param p reference point
+ * @param qdot ND velocity of the joint
+ *
+ * @return 6D-velocity at a given point p, expressed
+ * in the base-frame of the segment(root)
+ */
+ Twist twist(const Vector& p, const double& qdot, int dof=0)const;
+
+ /**
+ * Request the 6D-velocity at a given frame origin, relative to base frame of the segment
+ * assuming the frame rotation is the rotation of the joint.
+ *
+ * @param f joint pose frame + reference point
+ * @param qdot ND velocity of the joint
+ *
+ * @return 6D-velocity at frame reference point, expressed
+ * in the base-frame of the segment(root)
+ */
+ Twist twist(const Frame& f, const double& qdot, int dof)const;
+
+ /**
+ * Request the joint of the segment
+ *
+ *
+ * @return const reference to the joint of the segment
+ */
+ const Joint& getJoint()const
+ {
+ return joint;
+ }
+ /**
+ * Request the inertia of the segment
+ *
+ *
+ * @return const reference to the inertia of the segment
+ */
+ const Inertia& getInertia()const
+ {
+ return M;
+ }
+
+ /**
+ * Request the pose from the joint end to the tip of the
+ *segment.
+ *
+ * @return const reference to the joint end - segment tip pose.
+ */
+ const Frame& getFrameToTip()const
+ {
+ return f_tip;
+ }
+
+ };
+}//end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/tree.cpp b/intern/itasc/kdl/tree.cpp
new file mode 100644
index 00000000000..f117e54959b
--- /dev/null
+++ b/intern/itasc/kdl/tree.cpp
@@ -0,0 +1,117 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "tree.hpp"
+#include <sstream>
+namespace KDL {
+using namespace std;
+
+Tree::Tree() :
+ nrOfJoints(0), nrOfSegments(0) {
+ segments.insert(make_pair("root", TreeElement::Root()));
+}
+
+Tree::Tree(const Tree& in) {
+ segments.clear();
+ nrOfSegments = 0;
+ nrOfJoints = 0;
+
+ segments.insert(make_pair("root", TreeElement::Root()));
+ this->addTree(in, "", "root");
+
+}
+
+Tree& Tree::operator=(const Tree& in) {
+ segments.clear();
+ nrOfSegments = 0;
+ nrOfJoints = 0;
+
+ segments.insert(make_pair("root", TreeElement::Root()));
+ this->addTree(in, "", "root");
+ return *this;
+}
+
+bool Tree::addSegment(const Segment& segment, const std::string& segment_name,
+ const std::string& hook_name) {
+ SegmentMap::iterator parent = segments.find(hook_name);
+ //check if parent exists
+ if (parent == segments.end())
+ return false;
+ pair<SegmentMap::iterator, bool> retval;
+ //insert new element
+ retval = segments.insert(make_pair(segment_name, TreeElement(segment,
+ parent, nrOfJoints)));
+ //check if insertion succeeded
+ if (!retval.second)
+ return false;
+ //add iterator to new element in parents children list
+ parent->second.children.push_back(retval.first);
+ //increase number of segments
+ nrOfSegments++;
+ //increase number of joints
+ nrOfJoints += segment.getJoint().getNDof();
+ return true;
+}
+
+bool Tree::addChain(const Chain& chain, const std::string& chain_name,
+ const std::string& hook_name) {
+ string parent_name = hook_name;
+ for (unsigned int i = 0; i < chain.getNrOfSegments(); i++) {
+ ostringstream segment_name;
+ segment_name << chain_name << "Segment" << i;
+ if (this->addSegment(chain.getSegment(i), segment_name.str(),
+ parent_name))
+ parent_name = segment_name.str();
+ else
+ return false;
+ }
+ return true;
+}
+
+bool Tree::addTree(const Tree& tree, const std::string& tree_name,
+ const std::string& hook_name) {
+ return this->addTreeRecursive(tree.getSegment("root"), tree_name, hook_name);
+}
+
+bool Tree::addTreeRecursive(SegmentMap::const_iterator root,
+ const std::string& tree_name, const std::string& hook_name) {
+ //get iterator for root-segment
+ SegmentMap::const_iterator child;
+ //try to add all of root's children
+ for (unsigned int i = 0; i < root->second.children.size(); i++) {
+ child = root->second.children[i];
+ //Try to add the child
+ if (this->addSegment(child->second.segment, tree_name + child->first,
+ hook_name)) {
+ //if child is added, add all the child's children
+ if (!(this->addTreeRecursive(child, tree_name, tree_name
+ + child->first)))
+ //if it didn't work, return false
+ return false;
+ } else
+ //If the child could not be added, return false
+ return false;
+ }
+ return true;
+}
+
+}
+
diff --git a/intern/itasc/kdl/tree.hpp b/intern/itasc/kdl/tree.hpp
new file mode 100644
index 00000000000..bdd3aa94572
--- /dev/null
+++ b/intern/itasc/kdl/tree.hpp
@@ -0,0 +1,167 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_TREE_HPP
+#define KDL_TREE_HPP
+
+#include "segment.hpp"
+#include "chain.hpp"
+
+#include <string>
+#include <map>
+
+namespace KDL
+{
+ //Forward declaration
+ class TreeElement;
+ typedef std::map<std::string,TreeElement> SegmentMap;
+
+ class TreeElement
+ {
+ private:
+ TreeElement():q_nr(0)
+ {};
+ public:
+ Segment segment;
+ unsigned int q_nr;
+ SegmentMap::const_iterator parent;
+ std::vector<SegmentMap::const_iterator > children;
+ TreeElement(const Segment& segment_in,const SegmentMap::const_iterator& parent_in,unsigned int q_nr_in)
+ {
+ q_nr=q_nr_in;
+ segment=segment_in;
+ parent=parent_in;
+ };
+ static TreeElement Root()
+ {
+ return TreeElement();
+ };
+ };
+
+ /**
+ * \brief This class encapsulates a <strong>tree</strong>
+ * kinematic interconnection structure. It is build out of segments.
+ *
+ * @ingroup KinematicFamily
+ */
+ class Tree
+ {
+ private:
+ SegmentMap segments;
+ unsigned int nrOfJoints;
+ unsigned int nrOfSegments;
+
+ bool addTreeRecursive(SegmentMap::const_iterator root, const std::string& tree_name, const std::string& hook_name);
+
+ public:
+ /**
+ * The constructor of a tree, a new tree is always empty
+ */
+ Tree();
+ Tree(const Tree& in);
+ Tree& operator= (const Tree& arg);
+
+ /**
+ * Adds a new segment to the end of the segment with
+ * hook_name as segment_name
+ *
+ * @param segment new segment to add
+ * @param segment_name name of the new segment
+ * @param hook_name name of the segment to connect this
+ * segment with.
+ *
+ * @return false if hook_name could not be found.
+ */
+ bool addSegment(const Segment& segment, const std::string& segment_name, const std::string& hook_name);
+
+ /**
+ * Adds a complete chain to the end of the segment with
+ * hook_name as segment_name. Segment i of
+ * the chain will get chain_name+".Segment"+i as segment_name.
+ *
+ * @param chain Chain to add
+ * @param chain_name name of the chain
+ * @param hook_name name of the segment to connect the chain with.
+ *
+ * @return false if hook_name could not be found.
+ */
+ bool addChain(const Chain& chain, const std::string& chain_name, const std::string& hook_name);
+
+ /**
+ * Adds a complete tree to the end of the segment with
+ * hookname as segment_name. The segments of the tree will get
+ * tree_name+segment_name as segment_name.
+ *
+ * @param tree Tree to add
+ * @param tree_name name of the tree
+ * @param hook_name name of the segment to connect the tree with
+ *
+ * @return false if hook_name could not be found
+ */
+ bool addTree(const Tree& tree, const std::string& tree_name,const std::string& hook_name);
+
+ /**
+ * Request the total number of joints in the tree.\n
+ * <strong> Important:</strong> It is not the same as the
+ * total number of segments since a segment does not need to have
+ * a joint.
+ *
+ * @return total nr of joints
+ */
+ unsigned int getNrOfJoints()const
+ {
+ return nrOfJoints;
+ };
+
+ /**
+ * Request the total number of segments in the tree.
+ * @return total number of segments
+ */
+ unsigned int getNrOfSegments()const {return nrOfSegments;};
+
+ /**
+ * Request the segment of the tree with name segment_name.
+ *
+ * @param segment_name the name of the requested segment
+ *
+ * @return constant iterator pointing to the requested segment
+ */
+ SegmentMap::const_iterator getSegment(const std::string& segment_name)const
+ {
+ return segments.find(segment_name);
+ };
+
+
+
+ const SegmentMap& getSegments()const
+ {
+ return segments;
+ }
+
+ virtual ~Tree(){};
+ };
+}
+#endif
+
+
+
+
+
diff --git a/intern/itasc/kdl/treefksolver.hpp b/intern/itasc/kdl/treefksolver.hpp
new file mode 100644
index 00000000000..22d5400ab0a
--- /dev/null
+++ b/intern/itasc/kdl/treefksolver.hpp
@@ -0,0 +1,110 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Copyright (C) 2008 Julia Jesse
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDL_TREE_FKSOLVER_HPP
+#define KDL_TREE_FKSOLVER_HPP
+
+#include <string>
+
+#include "tree.hpp"
+//#include "framevel.hpp"
+//#include "frameacc.hpp"
+#include "jntarray.hpp"
+//#include "jntarrayvel.hpp"
+//#include "jntarrayacc.hpp"
+
+namespace KDL {
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a
+ * solver for the forward position kinematics for a KDL::Tree.
+ *
+ * @ingroup KinematicFamily
+ */
+
+ //Forward definition
+ class TreeFkSolverPos {
+ public:
+ /**
+ * Calculate forward position kinematics for a KDL::Tree,
+ * from joint coordinates to cartesian pose.
+ *
+ * @param q_in input joint coordinates
+ * @param p_out reference to output cartesian pose
+ *
+ * @return if < 0 something went wrong
+ */
+ virtual int JntToCart(const JntArray& q_in, Frame& p_out, const std::string& segmentName, const std::string& baseName)=0;
+ virtual ~TreeFkSolverPos(){};
+ };
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a solver
+ * for the forward velocity kinematics for a KDL::Tree.
+ *
+ * @ingroup KinematicFamily
+ */
+// class TreeFkSolverVel {
+// public:
+ /**
+ * Calculate forward position and velocity kinematics, from
+ * joint coordinates to cartesian coordinates.
+ *
+ * @param q_in input joint coordinates (position and velocity)
+ * @param out output cartesian coordinates (position and velocity)
+ *
+ * @return if < 0 something went wrong
+ */
+// virtual int JntToCart(const JntArrayVel& q_in, FrameVel& out,int segmentNr=-1)=0;
+
+// virtual ~TreeFkSolverVel(){};
+// };
+
+ /**
+ * \brief This <strong>abstract</strong> class encapsulates a solver
+ * for the forward acceleration kinematics for a KDL::Tree.
+ *
+ * @ingroup KinematicFamily
+ */
+
+// class TreeFkSolverAcc {
+// public:
+ /**
+ * Calculate forward position, velocity and accelaration
+ * kinematics, from joint coordinates to cartesian coordinates
+ *
+ * @param q_in input joint coordinates (position, velocity and
+ * acceleration
+ @param out output cartesian coordinates (position, velocity
+ * and acceleration
+ *
+ * @return if < 0 something went wrong
+ */
+// virtual int JntToCart(const JntArrayAcc& q_in, FrameAcc& out,int segmentNr=-1)=0;
+
+// virtual ~TreeFkSolverAcc()=0;
+// };
+
+
+}//end of namespace KDL
+
+#endif
diff --git a/intern/itasc/kdl/treefksolverpos_recursive.cpp b/intern/itasc/kdl/treefksolverpos_recursive.cpp
new file mode 100644
index 00000000000..8c54906dcf4
--- /dev/null
+++ b/intern/itasc/kdl/treefksolverpos_recursive.cpp
@@ -0,0 +1,71 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Copyright (C) 2008 Julia Jesse
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "treefksolverpos_recursive.hpp"
+#include <iostream>
+
+namespace KDL {
+
+ TreeFkSolverPos_recursive::TreeFkSolverPos_recursive(const Tree& _tree):
+ tree(_tree)
+ {
+ }
+
+ int TreeFkSolverPos_recursive::JntToCart(const JntArray& q_in, Frame& p_out, const std::string& segmentName, const std::string& baseName)
+ {
+ SegmentMap::const_iterator it = tree.getSegment(segmentName);
+ SegmentMap::const_iterator baseit = tree.getSegment(baseName);
+
+ if(q_in.rows() != tree.getNrOfJoints())
+ return -1;
+ else if(it == tree.getSegments().end()) //if the segment name is not found
+ return -2;
+ else if(baseit == tree.getSegments().end()) //if the base segment name is not found
+ return -3;
+ else{
+ const TreeElement& currentElement = it->second;
+ p_out = recursiveFk(q_in, it, baseit);
+ return 0;
+ }
+ }
+
+ Frame TreeFkSolverPos_recursive::recursiveFk(const JntArray& q_in, const SegmentMap::const_iterator& it, const SegmentMap::const_iterator& baseit)
+ {
+ //gets the frame for the current element (segment)
+ const TreeElement& currentElement = it->second;
+
+ if(it == baseit){
+ return KDL::Frame::Identity();
+ }
+ else{
+ Frame currentFrame = currentElement.segment.pose(((JntArray&)q_in)(currentElement.q_nr));
+ SegmentMap::const_iterator parentIt = currentElement.parent;
+ return recursiveFk(q_in, parentIt, baseit) * currentFrame;
+ }
+ }
+
+ TreeFkSolverPos_recursive::~TreeFkSolverPos_recursive()
+ {
+ }
+
+
+}
diff --git a/intern/itasc/kdl/treefksolverpos_recursive.hpp b/intern/itasc/kdl/treefksolverpos_recursive.hpp
new file mode 100644
index 00000000000..c22fe4af75b
--- /dev/null
+++ b/intern/itasc/kdl/treefksolverpos_recursive.hpp
@@ -0,0 +1,53 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Copyright (C) 2008 Julia Jesse
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+#ifndef KDLTREEFKSOLVERPOS_RECURSIVE_HPP
+#define KDLTREEFKSOLVERPOS_RECURSIVE_HPP
+
+#include "treefksolver.hpp"
+
+namespace KDL {
+
+ /**
+ * Implementation of a recursive forward position kinematics
+ * algorithm to calculate the position transformation from joint
+ * space to Cartesian space of a general kinematic tree (KDL::Tree).
+ *
+ * @ingroup KinematicFamily
+ */
+ class TreeFkSolverPos_recursive : public TreeFkSolverPos
+ {
+ public:
+ TreeFkSolverPos_recursive(const Tree& tree);
+ ~TreeFkSolverPos_recursive();
+
+ virtual int JntToCart(const JntArray& q_in, Frame& p_out, const std::string& segmentName, const std::string& baseName);
+
+ private:
+ const Tree tree;
+
+ Frame recursiveFk(const JntArray& q_in, const SegmentMap::const_iterator& it, const SegmentMap::const_iterator& baseit);
+ };
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/treejnttojacsolver.cpp b/intern/itasc/kdl/treejnttojacsolver.cpp
new file mode 100644
index 00000000000..194f18eb959
--- /dev/null
+++ b/intern/itasc/kdl/treejnttojacsolver.cpp
@@ -0,0 +1,78 @@
+/*
+ * TreeJntToJacSolver.cpp
+ *
+ * Created on: Nov 27, 2008
+ * Author: rubensmits
+ */
+
+#include "treejnttojacsolver.hpp"
+#include <iostream>
+
+namespace KDL {
+
+TreeJntToJacSolver::TreeJntToJacSolver(const Tree& tree_in) :
+ tree(tree_in) {
+}
+
+TreeJntToJacSolver::~TreeJntToJacSolver() {
+}
+
+int TreeJntToJacSolver::JntToJac(const JntArray& q_in, Jacobian& jac,
+ const std::string& segmentname) {
+ //First we check all the sizes:
+ if (q_in.rows() != tree.getNrOfJoints() || jac.columns()
+ != tree.getNrOfJoints())
+ return -1;
+
+ //Lets search the tree-element
+ SegmentMap::const_iterator it = tree.getSegments().find(segmentname);
+
+ //If segmentname is not inside the tree, back out:
+ if (it == tree.getSegments().end())
+ return -2;
+
+ //Let's make the jacobian zero:
+ SetToZero(jac);
+
+ SegmentMap::const_iterator root = tree.getSegments().find("root");
+
+ Frame T_total = Frame::Identity();
+ Frame T_local, T_joint;
+ Twist t_local;
+ //Lets recursively iterate until we are in the root segment
+ while (it != root) {
+ //get the corresponding q_nr for this TreeElement:
+ unsigned int q_nr = it->second.q_nr;
+
+ //get the pose of the joint.
+ T_joint = it->second.segment.getJoint().pose(((JntArray&)q_in)(q_nr));
+ // combine with the tip to have the tip pose
+ T_local = T_joint*it->second.segment.getFrameToTip();
+ //calculate new T_end:
+ T_total = T_local * T_total;
+
+ //get the twist of the segment:
+ int ndof = it->second.segment.getJoint().getNDof();
+ for (int dof=0; dof<ndof; dof++) {
+ // combine joint rotation with tip position to get a reference frame for the joint
+ T_joint.p = T_local.p;
+ // in which the twist can be computed (needed for NDof joint)
+ t_local = it->second.segment.twist(T_joint, 1.0, dof);
+ //transform the endpoint of the local twist to the global endpoint:
+ t_local = t_local.RefPoint(T_total.p - T_local.p);
+ //transform the base of the twist to the endpoint
+ t_local = T_total.M.Inverse(t_local);
+ //store the twist in the jacobian:
+ jac.twists[q_nr+dof] = t_local;
+ }
+ //goto the parent
+ it = it->second.parent;
+ }//endwhile
+ //Change the base of the complete jacobian from the endpoint to the base
+ changeBase(jac, T_total.M, jac);
+
+ return 0;
+
+}//end JntToJac
+}//end namespace
+
diff --git a/intern/itasc/kdl/treejnttojacsolver.hpp b/intern/itasc/kdl/treejnttojacsolver.hpp
new file mode 100644
index 00000000000..40977dcd577
--- /dev/null
+++ b/intern/itasc/kdl/treejnttojacsolver.hpp
@@ -0,0 +1,38 @@
+/*
+ * TreeJntToJacSolver.hpp
+ *
+ * Created on: Nov 27, 2008
+ * Author: rubensmits
+ */
+
+#ifndef TREEJNTTOJACSOLVER_HPP_
+#define TREEJNTTOJACSOLVER_HPP_
+
+#include "tree.hpp"
+#include "jacobian.hpp"
+#include "jntarray.hpp"
+
+namespace KDL {
+
+class TreeJntToJacSolver {
+public:
+ TreeJntToJacSolver(const Tree& tree);
+
+ virtual ~TreeJntToJacSolver();
+
+ /*
+ * Calculate the jacobian for a part of the tree: from a certain segment, given by segmentname to the root.
+ * The resulting jacobian is expressed in the baseframe of the tree ("root"), the reference point is in the end-segment
+ */
+
+ int JntToJac(const JntArray& q_in, Jacobian& jac,
+ const std::string& segmentname);
+
+private:
+ KDL::Tree tree;
+
+};
+
+}//End of namespace
+
+#endif /* TREEJNTTOJACSOLVER_H_ */
diff --git a/intern/itasc/kdl/utilities/Makefile b/intern/itasc/kdl/utilities/Makefile
new file mode 100644
index 00000000000..26bd7cfb470
--- /dev/null
+++ b/intern/itasc/kdl/utilities/Makefile
@@ -0,0 +1,37 @@
+#
+# $Id: Makefile 19905 2009-04-23 13:29:54Z ben2610 $
+#
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Hans Lambermont
+#
+# ***** END GPL LICENSE BLOCK *****
+# iksolver main makefile.
+#
+
+LIBNAME = itasc
+DIR = $(OCGDIR)/intern/$(LIBNAME)
+
+include nan_compile.mk
+
+CPPFLAGS += -I.
+CPPFLAGS += -I../../../../extern/Eigen2
diff --git a/intern/itasc/kdl/utilities/error.h b/intern/itasc/kdl/utilities/error.h
new file mode 100644
index 00000000000..c6cf916c151
--- /dev/null
+++ b/intern/itasc/kdl/utilities/error.h
@@ -0,0 +1,245 @@
+/***************************************************************************
+ tag: Erwin Aertbelien Mon Jan 10 16:38:38 CET 2005 error.h
+
+ error.h - description
+ -------------------
+ begin : Mon January 10 2005
+ copyright : (C) 2005 Erwin Aertbelien
+ email : erwin.aertbelien@mech.kuleuven.ac.be
+
+ ***************************************************************************
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+
+/*****************************************************************************
+ * \file
+ * Defines the exception classes that can be thrown
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: error.h 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+#ifndef ERROR_H_84822 // to make it unique, a random number
+#define ERROR_H_84822
+
+#include "utility.h"
+#include <string>
+
+namespace KDL {
+
+/**
+ * Base class for errors generated by ORO_Geometry
+ */
+class Error {
+public:
+ /** Returns a description string describing the error.
+ * the returned pointer only garanteed to exists as long as
+ * the Error object exists.
+ */
+ virtual ~Error() {}
+ virtual const char* Description() const {return "Unspecified Error\n";}
+
+ virtual int GetType() const {return 0;}
+};
+
+
+class Error_IO : public Error {
+ std::string msg;
+ int typenr;
+public:
+ Error_IO(const std::string& _msg="Unspecified I/O Error",int typenr=0):msg(_msg) {}
+ virtual const char* Description() const {return msg.c_str();}
+ virtual int GetType() const {return typenr;}
+};
+class Error_BasicIO : public Error_IO {};
+class Error_BasicIO_File : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Error while reading stream";}
+ virtual int GetType() const {return 1;}
+};
+class Error_BasicIO_Exp_Delim : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Expected Delimiter not encountered";}
+ virtual int GetType() const {return 2;}
+};
+class Error_BasicIO_Not_A_Space : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Expected space,tab or newline not encountered";}
+ virtual int GetType() const {return 3;}
+};
+class Error_BasicIO_Unexpected : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Unexpected character";}
+ virtual int GetType() const {return 4;}
+};
+
+class Error_BasicIO_ToBig : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "Word that is read out of stream is bigger than maxsize";}
+ virtual int GetType() const {return 5;}
+};
+
+class Error_BasicIO_Not_Opened : public Error_BasicIO {
+public:
+ virtual const char* Description() const {return "File cannot be opened";}
+ virtual int GetType() const {return 6;}
+};
+class Error_FrameIO : public Error_IO {};
+class Error_Frame_Vector_Unexpected_id : public Error_FrameIO {
+public:
+ virtual const char* Description() const {return "Unexpected identifier, expecting a vector (explicit or ZERO)";}
+ virtual int GetType() const {return 101;}
+};
+class Error_Frame_Frame_Unexpected_id : public Error_FrameIO {
+public:
+ virtual const char* Description() const {return "Unexpected identifier, expecting a Frame (explicit or DH)";}
+ virtual int GetType() const {return 102;}
+};
+class Error_Frame_Rotation_Unexpected_id : public Error_FrameIO {
+public:
+ virtual const char* Description() const {return "Unexpected identifier, expecting a Rotation (explicit or EULERZYX, EULERZYZ, RPY,ROT,IDENTITY)";}
+ virtual int GetType() const {return 103;}
+};
+class Error_ChainIO : public Error {};
+class Error_Chain_Unexpected_id : public Error_ChainIO {
+public:
+ virtual const char* Description() const {return "Unexpected identifier, expecting TRANS or ROT";}
+ virtual int GetType() const {return 201;}
+};
+//! Error_Redundancy indicates an error that occured during solving for redundancy.
+class Error_RedundancyIO:public Error_IO {};
+class Error_Redundancy_Illegal_Resolutiontype : public Error_RedundancyIO {
+public:
+ virtual const char* Description() const {return "Illegal Resolutiontype is used in I/O with ResolutionTask";}
+ virtual int GetType() const {return 301;}
+};
+class Error_Redundancy:public Error {};
+class Error_Redundancy_Unavoidable : public Error_Redundancy {
+public:
+ virtual const char* Description() const {return "Joint limits cannot be avoided";}
+ virtual int GetType() const {return 1002;}
+};
+class Error_Redundancy_Low_Manip: public Error_Redundancy {
+public:
+ virtual const char* Description() const {return "Manipulability is very low";}
+ virtual int GetType() const {return 1003;}
+};
+class Error_MotionIO : public Error {};
+class Error_MotionIO_Unexpected_MotProf : public Error_MotionIO {
+public:
+ virtual const char* Description() const { return "Wrong keyword while reading motion profile";}
+ virtual int GetType() const {return 2001;}
+};
+class Error_MotionIO_Unexpected_Traj : public Error_MotionIO {
+public:
+ virtual const char* Description() const { return "Trajectory type keyword not known";}
+ virtual int GetType() const {return 2002;}
+};
+
+class Error_MotionPlanning : public Error {};
+
+class Error_MotionPlanning_Circle_ToSmall : public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Circle : radius is to small";}
+ virtual int GetType() const {return 3001;}
+};
+
+class Error_MotionPlanning_Circle_No_Plane : public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Circle : Plane for motion is not properly defined";}
+ virtual int GetType() const {return 3002;}
+};
+
+class Error_MotionPlanning_Incompatible: public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Acceleration of a rectangular velocityprofile cannot be used";}
+ virtual int GetType() const {return 3003;}
+};
+
+class Error_MotionPlanning_Not_Feasible: public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Motion Profile with requested parameters is not feasible";}
+ virtual int GetType() const {return 3004;}
+};
+
+class Error_MotionPlanning_Not_Applicable: public Error_MotionPlanning {
+public:
+ virtual const char* Description() const { return "Method is not applicable for this derived object";}
+ virtual int GetType() const {return 3004;}
+};
+//! Abstract subclass of all errors that can be thrown by Adaptive_Integrator
+class Error_Integrator : public Error {};
+
+//! Error_Stepsize_Underflow is thrown if the stepsize becomes to small
+class Error_Stepsize_Underflow : public Error_Integrator {
+public:
+ virtual const char* Description() const { return "Stepsize Underflow";}
+ virtual int GetType() const {return 4001;}
+};
+
+//! Error_To_Many_Steps is thrown if the number of steps needed to
+//! integrate to the desired accuracy becomes to big.
+class Error_To_Many_Steps : public Error_Integrator {
+public:
+ virtual const char* Description() const { return "To many steps"; }
+ virtual int GetType() const {return 4002;}
+};
+
+//! Error_Stepsize_To_Small is thrown if the stepsize becomes to small
+class Error_Stepsize_To_Small : public Error_Integrator {
+public:
+ virtual const char* Description() const { return "Stepsize to small"; }
+ virtual int GetType() const {return 4003;}
+};
+
+class Error_Criterium : public Error {};
+
+class Error_Criterium_Unexpected_id: public Error_Criterium {
+public:
+ virtual const char* Description() const { return "Unexpected identifier while reading a criterium"; }
+ virtual int GetType() const {return 5001;}
+};
+
+class Error_Limits : public Error {};
+
+class Error_Limits_Unexpected_id: public Error_Limits {
+public:
+ virtual const char* Description() const { return "Unexpected identifier while reading a jointlimits"; }
+ virtual int GetType() const {return 6001;}
+};
+
+
+class Error_Not_Implemented: public Error {
+public:
+ virtual const char* Description() const { return "The requested object/method/function is not implemented"; }
+ virtual int GetType() const {return 7000;}
+};
+
+
+
+}
+
+#endif
diff --git a/intern/itasc/kdl/utilities/error_stack.cpp b/intern/itasc/kdl/utilities/error_stack.cpp
new file mode 100644
index 00000000000..aabf47ad191
--- /dev/null
+++ b/intern/itasc/kdl/utilities/error_stack.cpp
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: error_stack.cpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+
+#include "error_stack.h"
+#include <stack>
+#include <vector>
+#include <string>
+#include <cstring>
+
+namespace KDL {
+
+// Trace of the call stack of the I/O routines to help user
+// interprete error messages from I/O
+typedef std::stack<std::string> ErrorStack;
+
+ErrorStack errorstack;
+// should be in Thread Local Storage if this gets multithreaded one day...
+
+
+void IOTrace(const std::string& description) {
+ errorstack.push(description);
+}
+
+
+void IOTracePop() {
+ errorstack.pop();
+}
+
+void IOTraceOutput(std::ostream& os) {
+ while (!errorstack.empty()) {
+ os << errorstack.top().c_str() << std::endl;
+ errorstack.pop();
+ }
+}
+
+
+void IOTracePopStr(char* buffer,int size) {
+ if (errorstack.empty()) {
+ *buffer = 0;
+ return;
+ }
+ strncpy(buffer,errorstack.top().c_str(),size);
+ errorstack.pop();
+}
+
+}
diff --git a/intern/itasc/kdl/utilities/error_stack.h b/intern/itasc/kdl/utilities/error_stack.h
new file mode 100644
index 00000000000..918bc0786a6
--- /dev/null
+++ b/intern/itasc/kdl/utilities/error_stack.h
@@ -0,0 +1,70 @@
+/***************************************************************************
+ tag: Erwin Aertbelien Mon Jan 10 16:38:39 CET 2005 error_stack.h
+
+ error_stack.h - description
+ -------------------
+ begin : Mon January 10 2005
+ copyright : (C) 2005 Erwin Aertbelien
+ email : erwin.aertbelien@mech.kuleuven.ac.be
+
+ ***************************************************************************
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2.1 of the License, or (at your option) any later version. *
+ * *
+ * This library is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with this library; if not, write to the Free Software *
+ * Foundation, Inc., 59 Temple Place, *
+ * Suite 330, Boston, MA 02111-1307 USA *
+ * *
+ ***************************************************************************/
+
+
+/**
+ * \file
+ * \author Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par history
+ * - changed layout of the comments to accomodate doxygen
+ */
+#ifndef ERROR_STACK_H
+#define ERROR_STACK_H
+
+#include "utility.h"
+#include "utility_io.h"
+#include <string>
+
+
+namespace KDL {
+
+/*
+ * \todo
+ * IOTrace-routines store in static memory, should be in thread-local memory.
+ * pushes a description of the current routine on the IO-stack trace
+ */
+void IOTrace(const std::string& description);
+
+//! pops a description of the IO-stack
+void IOTracePop();
+
+
+//! outputs the IO-stack to a stream to provide a better errormessage.
+void IOTraceOutput(std::ostream& os);
+
+//! outputs one element of the IO-stack to the buffer (maximally size chars)
+//! returns empty string if no elements on the stack.
+void IOTracePopStr(char* buffer,int size);
+
+
+}
+
+#endif
+
diff --git a/intern/itasc/kdl/utilities/kdl-config.h b/intern/itasc/kdl/utilities/kdl-config.h
new file mode 100644
index 00000000000..4d2df2df6c5
--- /dev/null
+++ b/intern/itasc/kdl/utilities/kdl-config.h
@@ -0,0 +1,33 @@
+/* Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be> */
+
+/* Version: 1.0 */
+/* Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be> */
+/* Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be> */
+/* URL: http://www.orocos.org/kdl */
+
+/* This library is free software; you can redistribute it and/or */
+/* modify it under the terms of the GNU Lesser General Public */
+/* License as published by the Free Software Foundation; either */
+/* version 2.1 of the License, or (at your option) any later version. */
+
+/* This library is distributed in the hope that it will be useful, */
+/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
+/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* Lesser General Public License for more details. */
+
+/* You should have received a copy of the GNU Lesser General Public */
+/* License along with this library; if not, write to the Free Software */
+/* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+
+/* Methods are inlined */
+#define KDL_INLINE 1
+
+/* Column width that is used form printing frames */
+#define KDL_FRAME_WIDTH 12
+
+/* Indices are checked when accessing members of the objects */
+#define KDL_INDEX_CHECK 1
+
+/* use KDL implementation for == operator */
+#define KDL_USE_EQUAL 1
diff --git a/intern/itasc/kdl/utilities/rall1d.h b/intern/itasc/kdl/utilities/rall1d.h
new file mode 100644
index 00000000000..617683ffce6
--- /dev/null
+++ b/intern/itasc/kdl/utilities/rall1d.h
@@ -0,0 +1,478 @@
+
+/*****************************************************************************
+ * \file
+ * class for automatic differentiation on scalar values and 1st
+ * derivatives .
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par Note
+ * VC6++ contains a bug, concerning the use of inlined friend functions
+ * in combination with namespaces. So, try to avoid inlined friend
+ * functions !
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: rall1d.h 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+#ifndef Rall1D_H
+#define Rall1D_H
+#include <assert.h>
+#include "utility.h"
+
+namespace KDL {
+/**
+ * Rall1d contains a value, and its gradient, and defines an algebraic structure on this pair.
+ * This template class has 3 template parameters :
+ * - T contains the type of the value.
+ * - V contains the type of the gradient (can be a vector-like type).
+ * - S defines a scalar type that can operate on Rall1d. This is the type that
+ * is used to give back values of Norm() etc.
+ *
+ * S is usefull when you recurse a Rall1d object into itself to create a 2nd, 3th, 4th,..
+ * derivatives. (e.g. Rall1d< Rall1d<double>, Rall1d<double>, double> ).
+ *
+ * S is always passed by value.
+ *
+ * \par Class Type
+ * Concrete implementation
+ */
+template <typename T,typename V=T,typename S=T>
+class Rall1d
+ {
+ public:
+ typedef T valuetype;
+ typedef V gradienttype;
+ typedef S scalartype;
+ public :
+ T t; //!< value
+ V grad; //!< gradient
+ public :
+ INLINE Rall1d() {}
+
+ T value() const {
+ return t;
+ }
+ V deriv() const {
+ return grad;
+ }
+
+ explicit INLINE Rall1d(typename TI<T>::Arg c)
+ {t=T(c);SetToZero(grad);}
+
+ INLINE Rall1d(typename TI<T>::Arg tn, typename TI<V>::Arg afg):t(tn),grad(afg) {}
+
+ INLINE Rall1d(const Rall1d<T,V,S>& r):t(r.t),grad(r.grad) {}
+ //if one defines this constructor, it's better optimized then the
+ //automatically generated one ( this one set's up a loop to copy
+ // word by word.
+
+ INLINE T& Value() {
+ return t;
+ }
+
+ INLINE V& Gradient() {
+ return grad;
+ }
+
+ INLINE static Rall1d<T,V,S> Zero() {
+ Rall1d<T,V,S> tmp;
+ SetToZero(tmp);
+ return tmp;
+ }
+ INLINE static Rall1d<T,V,S> Identity() {
+ Rall1d<T,V,S> tmp;
+ SetToIdentity(tmp);
+ return tmp;
+ }
+
+ INLINE Rall1d<T,V,S>& operator =(S c)
+ {t=c;SetToZero(grad);return *this;}
+
+ INLINE Rall1d<T,V,S>& operator =(const Rall1d<T,V,S>& r)
+ {t=r.t;grad=r.grad;return *this;}
+
+ INLINE Rall1d<T,V,S>& operator /=(const Rall1d<T,V,S>& rhs)
+ {
+ grad = LinComb(rhs.t,grad,-t,rhs.grad) / (rhs.t*rhs.t);
+ t /= rhs.t;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator *=(const Rall1d<T,V,S>& rhs)
+ {
+ LinCombR(rhs.t,grad,t,rhs.grad,grad);
+ t *= rhs.t;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator +=(const Rall1d<T,V,S>& rhs)
+ {
+ grad +=rhs.grad;
+ t +=rhs.t;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator -=(const Rall1d<T,V,S>& rhs)
+ {
+ grad -= rhs.grad;
+ t -= rhs.t;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator /=(S rhs)
+ {
+ grad /= rhs;
+ t /= rhs;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator *=(S rhs)
+ {
+ grad *= rhs;
+ t *= rhs;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator +=(S rhs)
+ {
+ t += rhs;
+ return *this;
+ }
+
+ INLINE Rall1d<T,V,S>& operator -=(S rhs)
+ {
+ t -= rhs;
+ return *this;
+ }
+
+
+
+ // = operators
+ /* gives warnings on cygwin
+
+ template <class T2,class V2,class S2>
+ friend INLINE Rall1d<T2,V2,S2> operator /(const Rall1d<T2,V2,S2>& lhs,const Rall1d<T2,V2,S2>& rhs);
+
+ friend INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs);
+ friend INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs);
+ friend INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs);
+ friend INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> operator *(S s,const Rall1d<T,V,S>& v);
+ friend INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& v,S s);
+ friend INLINE Rall1d<T,V,S> operator +(S s,const Rall1d<T,V,S>& v);
+ friend INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& v,S s);
+ friend INLINE Rall1d<T,V,S> operator -(S s,const Rall1d<T,V,S>& v);
+ friend INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& v,S s);
+ friend INLINE Rall1d<T,V,S> operator /(S s,const Rall1d<T,V,S>& v);
+ friend INLINE Rall1d<T,V,S> operator /(const Rall1d<T,V,S>& v,S s);
+
+ // = Mathematical functions that operate on Rall1d objects
+ friend INLINE Rall1d<T,V,S> exp(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> log(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> sin(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> cos(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> tan(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> sinh(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> cosh(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> sqr(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> pow(const Rall1d<T,V,S>& arg,double m) ;
+ friend INLINE Rall1d<T,V,S> sqrt(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> atan(const Rall1d<T,V,S>& x);
+ friend INLINE Rall1d<T,V,S> hypot(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x);
+ friend INLINE Rall1d<T,V,S> asin(const Rall1d<T,V,S>& x);
+ friend INLINE Rall1d<T,V,S> acos(const Rall1d<T,V,S>& x);
+ friend INLINE Rall1d<T,V,S> abs(const Rall1d<T,V,S>& x);
+ friend INLINE S Norm(const Rall1d<T,V,S>& value) ;
+ friend INLINE Rall1d<T,V,S> tanh(const Rall1d<T,V,S>& arg);
+ friend INLINE Rall1d<T,V,S> atan2(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x);
+
+ // = Utility functions to improve performance
+
+ friend INLINE Rall1d<T,V,S> LinComb(S alfa,const Rall1d<T,V,S>& a,
+ const T& beta,const Rall1d<T,V,S>& b );
+
+ friend INLINE void LinCombR(S alfa,const Rall1d<T,V,S>& a,
+ const T& beta,const Rall1d<T,V,S>& b,Rall1d<T,V,S>& result );
+
+ // = Setting value of a Rall1d object to 0 or 1
+
+ friend INLINE void SetToZero(Rall1d<T,V,S>& value);
+ friend INLINE void SetToOne(Rall1d<T,V,S>& value);
+ // = Equality in an eps-interval
+ friend INLINE bool Equal(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x,double eps);
+ */
+ };
+
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator /(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs)
+ {
+ return Rall1d<T,V,S>(lhs.t/rhs.t,(lhs.grad*rhs.t-lhs.t*rhs.grad)/(rhs.t*rhs.t));
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs)
+ {
+ return Rall1d<T,V,S>(lhs.t*rhs.t,rhs.t*lhs.grad+lhs.t*rhs.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs)
+ {
+ return Rall1d<T,V,S>(lhs.t+rhs.t,lhs.grad+rhs.grad);
+ }
+
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& lhs,const Rall1d<T,V,S>& rhs)
+ {
+ return Rall1d<T,V,S>(lhs.t-rhs.t,lhs.grad-rhs.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& arg)
+ {
+ return Rall1d<T,V,S>(-arg.t,-arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator *(S s,const Rall1d<T,V,S>& v)
+ {
+ return Rall1d<T,V,S>(s*v.t,s*v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator *(const Rall1d<T,V,S>& v,S s)
+ {
+ return Rall1d<T,V,S>(v.t*s,v.grad*s);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator +(S s,const Rall1d<T,V,S>& v)
+ {
+ return Rall1d<T,V,S>(s+v.t,v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator +(const Rall1d<T,V,S>& v,S s)
+ {
+ return Rall1d<T,V,S>(v.t+s,v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator -(S s,const Rall1d<T,V,S>& v)
+ {
+ return Rall1d<T,V,S>(s-v.t,-v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator -(const Rall1d<T,V,S>& v,S s)
+ {
+ return Rall1d<T,V,S>(v.t-s,v.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator /(S s,const Rall1d<T,V,S>& v)
+ {
+ return Rall1d<T,V,S>(s/v.t,(-s*v.grad)/(v.t*v.t));
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> operator /(const Rall1d<T,V,S>& v,S s)
+ {
+ return Rall1d<T,V,S>(v.t/s,v.grad/s);
+ }
+
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> exp(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v= (exp(arg.t));
+ return Rall1d<T,V,S>(v,v*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> log(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(log(arg.t));
+ return Rall1d<T,V,S>(v,arg.grad/arg.t);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> sin(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(sin(arg.t));
+ return Rall1d<T,V,S>(v,cos(arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> cos(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(cos(arg.t));
+ return Rall1d<T,V,S>(v,-sin(arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> tan(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(tan(arg.t));
+ return Rall1d<T,V,S>(v,arg.grad/sqr(cos(arg.t)));
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> sinh(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(sinh(arg.t));
+ return Rall1d<T,V,S>(v,cosh(arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> cosh(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(cosh(arg.t));
+ return Rall1d<T,V,S>(v,sinh(arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> sqr(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=(arg.t*arg.t);
+ return Rall1d<T,V,S>(v,(2.0*arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> pow(const Rall1d<T,V,S>& arg,double m)
+ {
+ T v;
+ v=(pow(arg.t,m));
+ return Rall1d<T,V,S>(v,(m*v/arg.t)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> sqrt(const Rall1d<T,V,S>& arg)
+ {
+ T v;
+ v=sqrt(arg.t);
+ return Rall1d<T,V,S>(v, (0.5/v)*arg.grad);
+ }
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> atan(const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(atan(x.t));
+ return Rall1d<T,V,S>(v,x.grad/(1.0+sqr(x.t)));
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> hypot(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(hypot(y.t,x.t));
+ return Rall1d<T,V,S>(v,(x.t/v)*x.grad+(y.t/v)*y.grad);
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> asin(const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(asin(x.t));
+ return Rall1d<T,V,S>(v,x.grad/sqrt(1.0-sqr(x.t)));
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> acos(const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(acos(x.t));
+ return Rall1d<T,V,S>(v,-x.grad/sqrt(1.0-sqr(x.t)));
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> abs(const Rall1d<T,V,S>& x)
+{
+ T v;
+ v=(Sign(x));
+ return Rall1d<T,V,S>(v*x,v*x.grad);
+}
+
+
+template <class T,class V,class S>
+INLINE S Norm(const Rall1d<T,V,S>& value)
+{
+ return Norm(value.t);
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> tanh(const Rall1d<T,V,S>& arg)
+{
+ T v(tanh(arg.t));
+ return Rall1d<T,V,S>(v,arg.grad/sqr(cosh(arg.t)));
+}
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> atan2(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x)
+{
+ T v(x.t*x.t+y.t*y.t);
+ return Rall1d<T,V,S>(atan2(y.t,x.t),(x.t*y.grad-y.t*x.grad)/v);
+}
+
+
+template <class T,class V,class S>
+INLINE Rall1d<T,V,S> LinComb(S alfa,const Rall1d<T,V,S>& a,
+ const T& beta,const Rall1d<T,V,S>& b ) {
+ return Rall1d<T,V,S>(
+ LinComb(alfa,a.t,beta,b.t),
+ LinComb(alfa,a.grad,beta,b.grad)
+ );
+}
+
+template <class T,class V,class S>
+INLINE void LinCombR(S alfa,const Rall1d<T,V,S>& a,
+ const T& beta,const Rall1d<T,V,S>& b,Rall1d<T,V,S>& result ) {
+ LinCombR(alfa, a.t, beta, b.t, result.t);
+ LinCombR(alfa, a.grad, beta, b.grad, result.grad);
+}
+
+
+template <class T,class V,class S>
+INLINE void SetToZero(Rall1d<T,V,S>& value)
+ {
+ SetToZero(value.grad);
+ SetToZero(value.t);
+ }
+template <class T,class V,class S>
+INLINE void SetToIdentity(Rall1d<T,V,S>& value)
+ {
+ SetToIdentity(value.t);
+ SetToZero(value.grad);
+ }
+
+template <class T,class V,class S>
+INLINE bool Equal(const Rall1d<T,V,S>& y,const Rall1d<T,V,S>& x,double eps=epsilon)
+{
+ return (Equal(x.t,y.t,eps)&&Equal(x.grad,y.grad,eps));
+}
+
+}
+
+
+
+#endif
diff --git a/intern/itasc/kdl/utilities/rall2d.h b/intern/itasc/kdl/utilities/rall2d.h
new file mode 100644
index 00000000000..ca4c67319f5
--- /dev/null
+++ b/intern/itasc/kdl/utilities/rall2d.h
@@ -0,0 +1,538 @@
+
+/*****************************************************************************
+ * \file
+ * class for automatic differentiation on scalar values and 1st
+ * derivatives and 2nd derivative.
+ *
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par Note
+ * VC6++ contains a bug, concerning the use of inlined friend functions
+ * in combination with namespaces. So, try to avoid inlined friend
+ * functions !
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: rall2d.h 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ ****************************************************************************/
+
+#ifndef Rall2D_H
+#define Rall2D_H
+
+#include <math.h>
+#include <assert.h>
+#include "utility.h"
+
+
+namespace KDL {
+
+/**
+ * Rall2d contains a value, and its gradient and its 2nd derivative, and defines an algebraic
+ * structure on this pair.
+ * This template class has 3 template parameters :
+ * - T contains the type of the value.
+ * - V contains the type of the gradient (can be a vector-like type).
+ * - S defines a scalar type that can operate on Rall1d. This is the type that
+ * is used to give back values of Norm() etc.
+ *
+ * S is usefull when you recurse a Rall1d object into itself to create a 2nd, 3th, 4th,..
+ * derivatives. (e.g. Rall1d< Rall1d<double>, Rall1d<double>, double> ).
+ *
+ * S is always passed by value.
+ *
+ * \par Class Type
+ * Concrete implementation
+ */
+template <class T,class V=T,class S=T>
+class Rall2d
+ {
+ public :
+ T t; //!< value
+ V d; //!< 1st derivative
+ V dd; //!< 2nd derivative
+ public :
+ // = Constructors
+ INLINE Rall2d() {}
+
+ explicit INLINE Rall2d(typename TI<T>::Arg c)
+ {t=c;SetToZero(d);SetToZero(dd);}
+
+ INLINE Rall2d(typename TI<T>::Arg tn,const V& afg):t(tn),d(afg) {SetToZero(dd);}
+
+ INLINE Rall2d(typename TI<T>::Arg tn,const V& afg,const V& afg2):t(tn),d(afg),dd(afg2) {}
+
+ // = Copy Constructor
+ INLINE Rall2d(const Rall2d<T,V,S>& r):t(r.t),d(r.d),dd(r.dd) {}
+ //if one defines this constructor, it's better optimized then the
+ //automatically generated one ( that one set's up a loop to copy
+ // word by word.
+
+ // = Member functions to access internal structures :
+ INLINE T& Value() {
+ return t;
+ }
+
+ INLINE V& D() {
+ return d;
+ }
+
+ INLINE V& DD() {
+ return dd;
+ }
+ INLINE static Rall2d<T,V,S> Zero() {
+ Rall2d<T,V,S> tmp;
+ SetToZero(tmp);
+ return tmp;
+ }
+ INLINE static Rall2d<T,V,S> Identity() {
+ Rall2d<T,V,S> tmp;
+ SetToIdentity(tmp);
+ return tmp;
+ }
+
+ // = assignment operators
+ INLINE Rall2d<T,V,S>& operator =(S c)
+ {t=c;SetToZero(d);SetToZero(dd);return *this;}
+
+ INLINE Rall2d<T,V,S>& operator =(const Rall2d<T,V,S>& r)
+ {t=r.t;d=r.d;dd=r.dd;return *this;}
+
+ INLINE Rall2d<T,V,S>& operator /=(const Rall2d<T,V,S>& rhs)
+ {
+ t /= rhs.t;
+ d = (d-t*rhs.d)/rhs.t;
+ dd= (dd - S(2)*d*rhs.d-t*rhs.dd)/rhs.t;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator *=(const Rall2d<T,V,S>& rhs)
+ {
+ t *= rhs.t;
+ d = (d*rhs.t+t*rhs.d);
+ dd = (dd*rhs.t+S(2)*d*rhs.d+t*rhs.dd);
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator +=(const Rall2d<T,V,S>& rhs)
+ {
+ t +=rhs.t;
+ d +=rhs.d;
+ dd+=rhs.dd;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator -=(const Rall2d<T,V,S>& rhs)
+ {
+ t -= rhs.t;
+ d -= rhs.d;
+ dd -= rhs.dd;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator /=(S rhs)
+ {
+ t /= rhs;
+ d /= rhs;
+ dd /= rhs;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator *=(S rhs)
+ {
+ t *= rhs;
+ d *= rhs;
+ dd *= rhs;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator -=(S rhs)
+ {
+ t -= rhs;
+ return *this;
+ }
+
+ INLINE Rall2d<T,V,S>& operator +=(S rhs)
+ {
+ t += rhs;
+ return *this;
+ }
+
+ // = Operators between Rall2d objects
+/*
+ friend INLINE Rall2d<T,V,S> operator /(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs);
+ friend INLINE Rall2d<T,V,S> operator *(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs);
+ friend INLINE Rall2d<T,V,S> operator +(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs);
+ friend INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs);
+ friend INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> operator *(S s,const Rall2d<T,V,S>& v);
+ friend INLINE Rall2d<T,V,S> operator *(const Rall2d<T,V,S>& v,S s);
+ friend INLINE Rall2d<T,V,S> operator +(S s,const Rall2d<T,V,S>& v);
+ friend INLINE Rall2d<T,V,S> operator +(const Rall2d<T,V,S>& v,S s);
+ friend INLINE Rall2d<T,V,S> operator -(S s,const Rall2d<T,V,S>& v);
+ friend INLINE INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& v,S s);
+ friend INLINE Rall2d<T,V,S> operator /(S s,const Rall2d<T,V,S>& v);
+ friend INLINE Rall2d<T,V,S> operator /(const Rall2d<T,V,S>& v,S s);
+
+ // = Mathematical functions that operate on Rall2d objects
+
+ friend INLINE Rall2d<T,V,S> exp(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> log(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> sin(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> cos(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> tan(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> sinh(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> cosh(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> tanh(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> sqr(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> pow(const Rall2d<T,V,S>& arg,double m) ;
+ friend INLINE Rall2d<T,V,S> sqrt(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> asin(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> acos(const Rall2d<T,V,S>& arg);
+ friend INLINE Rall2d<T,V,S> atan(const Rall2d<T,V,S>& x);
+ friend INLINE Rall2d<T,V,S> atan2(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x);
+ friend INLINE Rall2d<T,V,S> abs(const Rall2d<T,V,S>& x);
+ friend INLINE Rall2d<T,V,S> hypot(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x);
+ // returns sqrt(y*y+x*x), but is optimized for accuracy and speed.
+ friend INLINE S Norm(const Rall2d<T,V,S>& value) ;
+ // returns Norm( value.Value() ).
+
+ // = Some utility functions to improve performance
+ // (should also be declared on primitive types to improve uniformity
+ friend INLINE Rall2d<T,V,S> LinComb(S alfa,const Rall2d<T,V,S>& a,
+ TI<T>::Arg beta,const Rall2d<T,V,S>& b );
+ friend INLINE void LinCombR(S alfa,const Rall2d<T,V,S>& a,
+ TI<T>::Arg beta,const Rall2d<T,V,S>& b,Rall2d<T,V,S>& result );
+ // = Setting value of a Rall2d object to 0 or 1
+ friend INLINE void SetToZero(Rall2d<T,V,S>& value);
+ friend INLINE void SetToOne(Rall2d<T,V,S>& value);
+ // = Equality in an eps-interval
+ friend INLINE bool Equal(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x,double eps);
+ */
+ };
+
+
+
+
+
+// = Operators between Rall2d objects
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator /(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = lhs.t/rhs.t;
+ tmp.d = (lhs.d-tmp.t*rhs.d)/rhs.t;
+ tmp.dd= (lhs.dd-S(2)*tmp.d*rhs.d-tmp.t*rhs.dd)/rhs.t;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator *(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = lhs.t*rhs.t;
+ tmp.d = (lhs.d*rhs.t+lhs.t*rhs.d);
+ tmp.dd = (lhs.dd*rhs.t+S(2)*lhs.d*rhs.d+lhs.t*rhs.dd);
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator +(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs)
+ {
+ return Rall2d<T,V,S>(lhs.t+rhs.t,lhs.d+rhs.d,lhs.dd+rhs.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& lhs,const Rall2d<T,V,S>& rhs)
+ {
+ return Rall2d<T,V,S>(lhs.t-rhs.t,lhs.d-rhs.d,lhs.dd-rhs.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& arg)
+ {
+ return Rall2d<T,V,S>(-arg.t,-arg.d,-arg.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator *(S s,const Rall2d<T,V,S>& v)
+ {
+ return Rall2d<T,V,S>(s*v.t,s*v.d,s*v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator *(const Rall2d<T,V,S>& v,S s)
+ {
+ return Rall2d<T,V,S>(v.t*s,v.d*s,v.dd*s);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator +(S s,const Rall2d<T,V,S>& v)
+ {
+ return Rall2d<T,V,S>(s+v.t,v.d,v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator +(const Rall2d<T,V,S>& v,S s)
+ {
+ return Rall2d<T,V,S>(v.t+s,v.d,v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator -(S s,const Rall2d<T,V,S>& v)
+ {
+ return Rall2d<T,V,S>(s-v.t,-v.d,-v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator -(const Rall2d<T,V,S>& v,S s)
+ {
+ return Rall2d<T,V,S>(v.t-s,v.d,v.dd);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator /(S s,const Rall2d<T,V,S>& rhs)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = s/rhs.t;
+ tmp.d = (-tmp.t*rhs.d)/rhs.t;
+ tmp.dd= (-S(2)*tmp.d*rhs.d-tmp.t*rhs.dd)/rhs.t;
+ return tmp;
+}
+
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> operator /(const Rall2d<T,V,S>& v,S s)
+ {
+ return Rall2d<T,V,S>(v.t/s,v.d/s,v.dd/s);
+ }
+
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> exp(const Rall2d<T,V,S>& arg)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = exp(arg.t);
+ tmp.d = tmp.t*arg.d;
+ tmp.dd = tmp.d*arg.d+tmp.t*arg.dd;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> log(const Rall2d<T,V,S>& arg)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = log(arg.t);
+ tmp.d = arg.d/arg.t;
+ tmp.dd = (arg.dd-tmp.d*arg.d)/arg.t;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> sin(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = sin(arg.t);
+ T v2 = cos(arg.t);
+ return Rall2d<T,V,S>(v1,v2*arg.d,v2*arg.dd - (v1*arg.d)*arg.d );
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> cos(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = cos(arg.t);
+ T v2 = -sin(arg.t);
+ return Rall2d<T,V,S>(v1,v2*arg.d, v2*arg.dd - (v1*arg.d)*arg.d);
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> tan(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = tan(arg.t);
+ T v2 = S(1)+sqr(v1);
+ return Rall2d<T,V,S>(v1,v2*arg.d, v2*(arg.dd+(S(2)*v1*sqr(arg.d))));
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> sinh(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = sinh(arg.t);
+ T v2 = cosh(arg.t);
+ return Rall2d<T,V,S>(v1,v2*arg.d,v2*arg.dd + (v1*arg.d)*arg.d );
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> cosh(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = cosh(arg.t);
+ T v2 = sinh(arg.t);
+ return Rall2d<T,V,S>(v1,v2*arg.d,v2*arg.dd + (v1*arg.d)*arg.d );
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> tanh(const Rall2d<T,V,S>& arg)
+ {
+ T v1 = tanh(arg.t);
+ T v2 = S(1)-sqr(v1);
+ return Rall2d<T,V,S>(v1,v2*arg.d, v2*(arg.dd-(S(2)*v1*sqr(arg.d))));
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> sqr(const Rall2d<T,V,S>& arg)
+ {
+ return Rall2d<T,V,S>(arg.t*arg.t,
+ (S(2)*arg.t)*arg.d,
+ S(2)*(sqr(arg.d)+arg.t*arg.dd)
+ );
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> pow(const Rall2d<T,V,S>& arg,double m)
+ {
+ Rall2d<T,V,S> tmp;
+ tmp.t = pow(arg.t,m);
+ T v2 = (m/arg.t)*tmp.t;
+ tmp.d = v2*arg.d;
+ tmp.dd = (S((m-1))/arg.t)*tmp.d*arg.d + v2*arg.dd;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> sqrt(const Rall2d<T,V,S>& arg)
+ {
+ /* By inversion of sqr(x) :*/
+ Rall2d<T,V,S> tmp;
+ tmp.t = sqrt(arg.t);
+ tmp.d = (S(0.5)/tmp.t)*arg.d;
+ tmp.dd = (S(0.5)*arg.dd-sqr(tmp.d))/tmp.t;
+ return tmp;
+ }
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> asin(const Rall2d<T,V,S>& arg)
+{
+ /* By inversion of sin(x) */
+ Rall2d<T,V,S> tmp;
+ tmp.t = asin(arg.t);
+ T v = cos(tmp.t);
+ tmp.d = arg.d/v;
+ tmp.dd = (arg.dd+arg.t*sqr(tmp.d))/v;
+ return tmp;
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> acos(const Rall2d<T,V,S>& arg)
+{
+ /* By inversion of cos(x) */
+ Rall2d<T,V,S> tmp;
+ tmp.t = acos(arg.t);
+ T v = -sin(tmp.t);
+ tmp.d = arg.d/v;
+ tmp.dd = (arg.dd+arg.t*sqr(tmp.d))/v;
+ return tmp;
+
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> atan(const Rall2d<T,V,S>& x)
+{
+ /* By inversion of tan(x) */
+ Rall2d<T,V,S> tmp;
+ tmp.t = atan(x.t);
+ T v = S(1)+sqr(x.t);
+ tmp.d = x.d/v;
+ tmp.dd = x.dd/v-(S(2)*x.t)*sqr(tmp.d);
+ return tmp;
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> atan2(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x)
+{
+ Rall2d<T,V,S> tmp;
+ tmp.t = atan2(y.t,x.t);
+ T v = sqr(y.t)+sqr(x.t);
+ tmp.d = (x.t*y.d-x.d*y.t)/v;
+ tmp.dd = ( x.t*y.dd-x.dd*y.t-S(2)*(x.t*x.d+y.t*y.d)*tmp.d ) / v;
+ return tmp;
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> abs(const Rall2d<T,V,S>& x)
+{
+ T v(Sign(x));
+ return Rall2d<T,V,S>(v*x,v*x.d,v*x.dd);
+}
+
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> hypot(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x)
+{
+ Rall2d<T,V,S> tmp;
+ tmp.t = hypot(y.t,x.t);
+ tmp.d = (x.t*x.d+y.t*y.d)/tmp.t;
+ tmp.dd = (sqr(x.d)+x.t*x.dd+sqr(y.d)+y.t*y.dd-sqr(tmp.d))/tmp.t;
+ return tmp;
+}
+// returns sqrt(y*y+x*x), but is optimized for accuracy and speed.
+
+template <class T,class V,class S>
+INLINE S Norm(const Rall2d<T,V,S>& value)
+{
+ return Norm(value.t);
+}
+// returns Norm( value.Value() ).
+
+
+// (should also be declared on primitive types to improve uniformity
+template <class T,class V,class S>
+INLINE Rall2d<T,V,S> LinComb(S alfa,const Rall2d<T,V,S>& a,
+ const T& beta,const Rall2d<T,V,S>& b ) {
+ return Rall2d<T,V,S>(
+ LinComb(alfa,a.t,beta,b.t),
+ LinComb(alfa,a.d,beta,b.d),
+ LinComb(alfa,a.dd,beta,b.dd)
+ );
+}
+
+template <class T,class V,class S>
+INLINE void LinCombR(S alfa,const Rall2d<T,V,S>& a,
+ const T& beta,const Rall2d<T,V,S>& b,Rall2d<T,V,S>& result ) {
+ LinCombR(alfa, a.t, beta, b.t, result.t);
+ LinCombR(alfa, a.d, beta, b.d, result.d);
+ LinCombR(alfa, a.dd, beta, b.dd, result.dd);
+}
+
+template <class T,class V,class S>
+INLINE void SetToZero(Rall2d<T,V,S>& value)
+ {
+ SetToZero(value.t);
+ SetToZero(value.d);
+ SetToZero(value.dd);
+ }
+
+template <class T,class V,class S>
+INLINE void SetToIdentity(Rall2d<T,V,S>& value)
+ {
+ SetToZero(value.d);
+ SetToIdentity(value.t);
+ SetToZero(value.dd);
+ }
+
+template <class T,class V,class S>
+INLINE bool Equal(const Rall2d<T,V,S>& y,const Rall2d<T,V,S>& x,double eps=epsilon)
+{
+ return (Equal(x.t,y.t,eps)&&
+ Equal(x.d,y.d,eps)&&
+ Equal(x.dd,y.dd,eps)
+ );
+}
+
+
+}
+
+
+#endif
diff --git a/intern/itasc/kdl/utilities/svd_eigen_HH.hpp b/intern/itasc/kdl/utilities/svd_eigen_HH.hpp
new file mode 100644
index 00000000000..2bbb8df521f
--- /dev/null
+++ b/intern/itasc/kdl/utilities/svd_eigen_HH.hpp
@@ -0,0 +1,309 @@
+// Copyright (C) 2007 Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+
+// Version: 1.0
+// Author: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// Maintainer: Ruben Smits <ruben dot smits at mech dot kuleuven dot be>
+// URL: http://www.orocos.org/kdl
+
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// Lesser General Public License for more details.
+
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+//Based on the svd of the KDL-0.2 library by Erwin Aertbelien
+#ifndef SVD_EIGEN_HH_HPP
+#define SVD_EIGEN_HH_HPP
+
+
+#include <Eigen/Array>
+#include <algorithm>
+
+namespace KDL
+{
+ template<typename Scalar> inline Scalar PYTHAG(Scalar a,Scalar b) {
+ double at,bt,ct;
+ at = fabs(a);
+ bt = fabs(b);
+ if (at > bt ) {
+ ct=bt/at;
+ return Scalar(at*sqrt(1.0+ct*ct));
+ } else {
+ if (bt==0)
+ return Scalar(0.0);
+ else {
+ ct=at/bt;
+ return Scalar(bt*sqrt(1.0+ct*ct));
+ }
+ }
+ }
+
+
+ template<typename Scalar> inline Scalar SIGN(Scalar a,Scalar b) {
+ return ((b) >= Scalar(0.0) ? fabs(a) : -fabs(a));
+ }
+
+ /**
+ * svd calculation of boost ublas matrices
+ *
+ * @param A matrix<double>(mxn)
+ * @param U matrix<double>(mxn)
+ * @param S vector<double> n
+ * @param V matrix<double>(nxn)
+ * @param tmp vector<double> n
+ * @param maxiter defaults to 150
+ *
+ * @return -2 if maxiter exceeded, 0 otherwise
+ */
+ template<typename MatrixA, typename MatrixUV, typename VectorS>
+ int svd_eigen_HH(
+ const Eigen::MatrixBase<MatrixA>& A,
+ Eigen::MatrixBase<MatrixUV>& U,
+ Eigen::MatrixBase<VectorS>& S,
+ Eigen::MatrixBase<MatrixUV>& V,
+ Eigen::MatrixBase<VectorS>& tmp,
+ int maxiter=150)
+ {
+ //get the rows/columns of the matrix
+ const int rows = A.rows();
+ const int cols = A.cols();
+
+ U = A;
+
+ int i(-1),its(-1),j(-1),jj(-1),k(-1),nm=0;
+ int ppi(0);
+ bool flag;
+ e_scalar maxarg1,maxarg2,anorm(0),c(0),f(0),h(0),s(0),scale(0),x(0),y(0),z(0),g(0);
+
+ g=scale=anorm=e_scalar(0.0);
+
+ /* Householder reduction to bidiagonal form. */
+ for (i=0;i<cols;i++) {
+ ppi=i+1;
+ tmp(i)=scale*g;
+ g=s=scale=e_scalar(0.0);
+ if (i<rows) {
+ // compute the sum of the i-th column, starting from the i-th row
+ for (k=i;k<rows;k++) scale += fabs(U(k,i));
+ if (scale!=0) {
+ // multiply the i-th column by 1.0/scale, start from the i-th element
+ // sum of squares of column i, start from the i-th element
+ for (k=i;k<rows;k++) {
+ U(k,i) /= scale;
+ s += U(k,i)*U(k,i);
+ }
+ f=U(i,i); // f is the diag elem
+ g = -SIGN(e_scalar(sqrt(s)),f);
+ h=f*g-s;
+ U(i,i)=f-g;
+ for (j=ppi;j<cols;j++) {
+ // dot product of columns i and j, starting from the i-th row
+ for (s=0.0,k=i;k<rows;k++) s += U(k,i)*U(k,j);
+ f=s/h;
+ // copy the scaled i-th column into the j-th column
+ for (k=i;k<rows;k++) U(k,j) += f*U(k,i);
+ }
+ for (k=i;k<rows;k++) U(k,i) *= scale;
+ }
+ }
+ // save singular value
+ S(i)=scale*g;
+ g=s=scale=e_scalar(0.0);
+ if ((i <rows) && (i+1 != cols)) {
+ // sum of row i, start from columns i+1
+ for (k=ppi;k<cols;k++) scale += fabs(U(i,k));
+ if (scale!=0) {
+ for (k=ppi;k<cols;k++) {
+ U(i,k) /= scale;
+ s += U(i,k)*U(i,k);
+ }
+ f=U(i,ppi);
+ g = -SIGN(e_scalar(sqrt(s)),f);
+ h=f*g-s;
+ U(i,ppi)=f-g;
+ for (k=ppi;k<cols;k++) tmp(k)=U(i,k)/h;
+ for (j=ppi;j<rows;j++) {
+ for (s=0.0,k=ppi;k<cols;k++) s += U(j,k)*U(i,k);
+ for (k=ppi;k<cols;k++) U(j,k) += s*tmp(k);
+ }
+ for (k=ppi;k<cols;k++) U(i,k) *= scale;
+ }
+ }
+ maxarg1=anorm;
+ maxarg2=(fabs(S(i))+fabs(tmp(i)));
+ anorm = maxarg1 > maxarg2 ? maxarg1 : maxarg2;
+ }
+ /* Accumulation of right-hand transformations. */
+ for (i=cols-1;i>=0;i--) {
+ if (i<cols-1) {
+ if (g) {
+ for (j=ppi;j<cols;j++) V(j,i)=(U(i,j)/U(i,ppi))/g;
+ for (j=ppi;j<cols;j++) {
+ for (s=0.0,k=ppi;k<cols;k++) s += U(i,k)*V(k,j);
+ for (k=ppi;k<cols;k++) V(k,j) += s*V(k,i);
+ }
+ }
+ for (j=ppi;j<cols;j++) V(i,j)=V(j,i)=0.0;
+ }
+ V(i,i)=1.0;
+ g=tmp(i);
+ ppi=i;
+ }
+ /* Accumulation of left-hand transformations. */
+ for (i=cols-1<rows-1 ? cols-1:rows-1;i>=0;i--) {
+ ppi=i+1;
+ g=S(i);
+ for (j=ppi;j<cols;j++) U(i,j)=0.0;
+ if (g) {
+ g=e_scalar(1.0)/g;
+ for (j=ppi;j<cols;j++) {
+ for (s=0.0,k=ppi;k<rows;k++) s += U(k,i)*U(k,j);
+ f=(s/U(i,i))*g;
+ for (k=i;k<rows;k++) U(k,j) += f*U(k,i);
+ }
+ for (j=i;j<rows;j++) U(j,i) *= g;
+ } else {
+ for (j=i;j<rows;j++) U(j,i)=0.0;
+ }
+ ++U(i,i);
+ }
+
+ /* Diagonalization of the bidiagonal form. */
+ for (k=cols-1;k>=0;k--) { /* Loop over singular values. */
+ for (its=1;its<=maxiter;its++) { /* Loop over allowed iterations. */
+ flag=true;
+ for (ppi=k;ppi>=0;ppi--) { /* Test for splitting. */
+ nm=ppi-1; /* Note that tmp(1) is always zero. */
+ if ((fabs(tmp(ppi))+anorm) == anorm) {
+ flag=false;
+ break;
+ }
+ if ((fabs(S(nm)+anorm) == anorm)) break;
+ }
+ if (flag) {
+ c=e_scalar(0.0); /* Cancellation of tmp(l), if l>1: */
+ s=e_scalar(1.);
+ for (i=ppi;i<=k;i++) {
+ f=s*tmp(i);
+ tmp(i)=c*tmp(i);
+ if ((fabs(f)+anorm) == anorm) break;
+ g=S(i);
+ h=PYTHAG(f,g);
+ S(i)=h;
+ h=e_scalar(1.0)/h;
+ c=g*h;
+ s=(-f*h);
+ for (j=0;j<rows;j++) {
+ y=U(j,nm);
+ z=U(j,i);
+ U(j,nm)=y*c+z*s;
+ U(j,i)=z*c-y*s;
+ }
+ }
+ }
+ z=S(k);
+
+ if (ppi == k) { /* Convergence. */
+ if (z < e_scalar(0.0)) { /* Singular value is made nonnegative. */
+ S(k) = -z;
+ for (j=0;j<cols;j++) V(j,k)=-V(j,k);
+ }
+ break;
+ }
+
+ x=S(ppi); /* Shift from bottom 2-by-2 minor: */
+ nm=k-1;
+ y=S(nm);
+ g=tmp(nm);
+ h=tmp(k);
+ f=((y-z)*(y+z)+(g-h)*(g+h))/(e_scalar(2.0)*h*y);
+
+ g=PYTHAG(f,e_scalar(1.0));
+ f=((x-z)*(x+z)+h*((y/(f+SIGN(g,f)))-h))/x;
+
+ /* Next QR transformation: */
+ c=s=1.0;
+ for (j=ppi;j<=nm;j++) {
+ i=j+1;
+ g=tmp(i);
+ y=S(i);
+ h=s*g;
+ g=c*g;
+ z=PYTHAG(f,h);
+ tmp(j)=z;
+ c=f/z;
+ s=h/z;
+ f=x*c+g*s;
+ g=g*c-x*s;
+ h=y*s;
+ y=y*c;
+ for (jj=0;jj<cols;jj++) {
+ x=V(jj,j);
+ z=V(jj,i);
+ V(jj,j)=x*c+z*s;
+ V(jj,i)=z*c-x*s;
+ }
+ z=PYTHAG(f,h);
+ S(j)=z;
+ if (z) {
+ z=e_scalar(1.0)/z;
+ c=f*z;
+ s=h*z;
+ }
+ f=(c*g)+(s*y);
+ x=(c*y)-(s*g);
+ for (jj=0;jj<rows;jj++) {
+ y=U(jj,j);
+ z=U(jj,i);
+ U(jj,j)=y*c+z*s;
+ U(jj,i)=z*c-y*s;
+ }
+ }
+ tmp(ppi)=0.0;
+ tmp(k)=f;
+ S(k)=x;
+ }
+ }
+
+ //Sort eigen values:
+ for (i=0; i<cols; i++){
+
+ double S_max = S(i);
+ int i_max = i;
+ for (j=i+1; j<cols; j++){
+ double Sj = S(j);
+ if (Sj > S_max){
+ S_max = Sj;
+ i_max = j;
+ }
+ }
+ if (i_max != i){
+ /* swap eigenvalues */
+ e_scalar tmp = S(i);
+ S(i)=S(i_max);
+ S(i_max)=tmp;
+
+ /* swap eigenvectors */
+ U.col(i).swap(U.col(i_max));
+ V.col(i).swap(V.col(i_max));
+ }
+ }
+
+
+ if (its == maxiter)
+ return (-2);
+ else
+ return (0);
+ }
+
+}
+#endif
diff --git a/intern/itasc/kdl/utilities/traits.h b/intern/itasc/kdl/utilities/traits.h
new file mode 100644
index 00000000000..2656d633653
--- /dev/null
+++ b/intern/itasc/kdl/utilities/traits.h
@@ -0,0 +1,111 @@
+#ifndef KDLPV_TRAITS_H
+#define KDLPV_TRAITS_H
+
+#include "utility.h"
+
+
+// forwards declarations :
+namespace KDL {
+ class Frame;
+ class Rotation;
+ class Vector;
+ class Twist;
+ class Wrench;
+ class FrameVel;
+ class RotationVel;
+ class VectorVel;
+ class TwistVel;
+}
+
+
+/**
+ * @brief Traits are traits classes to determine the type of a derivative of another type.
+ *
+ * For geometric objects the "geometric" derivative is chosen. For example the derivative of a Rotation
+ * matrix is NOT a 3x3 matrix containing the derivative of the elements of a rotation matrix. The derivative
+ * of the rotation matrix is a Vector corresponding the rotational velocity. Mostly used in template classes
+ * and routines to derive a correct type when needed.
+ *
+ * You can see this as a compile-time lookuptable to find the type of the derivative.
+ *
+ * Example
+ * \verbatim
+ Rotation R;
+ Traits<Rotation> dR;
+ \endverbatim
+ */
+template <typename T>
+struct Traits {
+ typedef T valueType;
+ typedef T derivType;
+};
+
+template <>
+struct Traits<KDL::Frame> {
+ typedef KDL::Frame valueType;
+ typedef KDL::Twist derivType;
+};
+template <>
+struct Traits<KDL::Twist> {
+ typedef KDL::Twist valueType;
+ typedef KDL::Twist derivType;
+};
+template <>
+struct Traits<KDL::Wrench> {
+ typedef KDL::Wrench valueType;
+ typedef KDL::Wrench derivType;
+};
+
+template <>
+struct Traits<KDL::Rotation> {
+ typedef KDL::Rotation valueType;
+ typedef KDL::Vector derivType;
+};
+
+template <>
+struct Traits<KDL::Vector> {
+ typedef KDL::Vector valueType;
+ typedef KDL::Vector derivType;
+};
+
+template <>
+struct Traits<double> {
+ typedef double valueType;
+ typedef double derivType;
+};
+
+template <>
+struct Traits<float> {
+ typedef float valueType;
+ typedef float derivType;
+};
+
+template <>
+struct Traits<KDL::FrameVel> {
+ typedef KDL::Frame valueType;
+ typedef KDL::TwistVel derivType;
+};
+template <>
+struct Traits<KDL::TwistVel> {
+ typedef KDL::Twist valueType;
+ typedef KDL::TwistVel derivType;
+};
+
+template <>
+struct Traits<KDL::RotationVel> {
+ typedef KDL::Rotation valueType;
+ typedef KDL::VectorVel derivType;
+};
+
+template <>
+struct Traits<KDL::VectorVel> {
+ typedef KDL::Vector valueType;
+ typedef KDL::VectorVel derivType;
+};
+
+
+
+#endif
+
+
+
diff --git a/intern/itasc/kdl/utilities/utility.cpp b/intern/itasc/kdl/utilities/utility.cpp
new file mode 100644
index 00000000000..1ab9cb6f83d
--- /dev/null
+++ b/intern/itasc/kdl/utilities/utility.cpp
@@ -0,0 +1,21 @@
+/** @file utility.cpp
+ * @author Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ * @version
+ * ORO_Geometry V0.2
+ *
+ * @par history
+ * - changed layout of the comments to accomodate doxygen
+ */
+
+#include "utility.h"
+
+namespace KDL {
+
+int STREAMBUFFERSIZE=10000;
+int MAXLENFILENAME = 255;
+const double PI= 3.1415926535897932384626433832795;
+const double deg2rad = 0.01745329251994329576923690768488;
+const double rad2deg = 57.2957795130823208767981548141052;
+double epsilon = 0.000001;
+double epsilon2 = 0.000001*0.000001;
+}
diff --git a/intern/itasc/kdl/utilities/utility.h b/intern/itasc/kdl/utilities/utility.h
new file mode 100644
index 00000000000..e7dcc55d8a8
--- /dev/null
+++ b/intern/itasc/kdl/utilities/utility.h
@@ -0,0 +1,298 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: utility.h 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ * \file
+ * Included by most lrl-files to provide some general
+ * functions and macro definitions.
+ *
+ * \par history
+ * - changed layout of the comments to accomodate doxygen
+ */
+
+
+#ifndef KDL_UTILITY_H
+#define KDL_UTILITY_H
+
+#include "kdl-config.h"
+#include <cstdlib>
+#include <cassert>
+#include <cmath>
+
+
+/////////////////////////////////////////////////////////////
+// configurable options for the frames library.
+
+#ifdef KDL_INLINE
+ #ifdef _MSC_VER
+ // Microsoft Visual C
+ #define IMETHOD __forceinline
+ #else
+ // Some other compiler, e.g. gcc
+ #define IMETHOD inline
+ #endif
+#else
+ #define IMETHOD
+#endif
+
+
+
+//! turn on or off frames bounds checking. If turned on, assert() can still
+//! be turned off with -DNDEBUG.
+#ifdef KDL_INDEX_CHECK
+ #define FRAMES_CHECKI(a) assert(a)
+#else
+ #define FRAMES_CHECKI(a)
+#endif
+
+
+namespace KDL {
+
+#ifdef __GNUC__
+ // so that sin,cos can be overloaded and complete
+ // resolution of overloaded functions work.
+ using ::sin;
+ using ::cos;
+ using ::exp;
+ using ::log;
+ using ::sin;
+ using ::cos;
+ using ::tan;
+ using ::sinh;
+ using ::cosh;
+ using ::pow;
+ using ::sqrt;
+ using ::atan;
+ using ::hypot;
+ using ::asin;
+ using ::acos;
+ using ::tanh;
+ using ::atan2;
+#endif
+#ifndef __GNUC__
+ //only real solution : get Rall1d and varia out of namespaces.
+ #pragma warning (disable:4786)
+
+ inline double sin(double a) {
+ return ::sin(a);
+ }
+
+ inline double cos(double a) {
+ return ::cos(a);
+ }
+ inline double exp(double a) {
+ return ::exp(a);
+ }
+ inline double log(double a) {
+ return ::log(a);
+ }
+ inline double tan(double a) {
+ return ::tan(a);
+ }
+ inline double cosh(double a) {
+ return ::cosh(a);
+ }
+ inline double sinh(double a) {
+ return ::sinh(a);
+ }
+ inline double sqrt(double a) {
+ return ::sqrt(a);
+ }
+ inline double atan(double a) {
+ return ::atan(a);
+ }
+ inline double acos(double a) {
+ return ::acos(a);
+ }
+ inline double asin(double a) {
+ return ::asin(a);
+ }
+ inline double tanh(double a) {
+ return ::tanh(a);
+ }
+ inline double pow(double a,double b) {
+ return ::pow(a,b);
+ }
+ inline double atan2(double a,double b) {
+ return ::atan2(a,b);
+ }
+#endif
+
+
+
+
+
+/**
+ * Auxiliary class for argument types (Trait-template class )
+ *
+ * Is used to pass doubles by value, and arbitrary objects by const reference.
+ * This is TWICE as fast (2 x less memory access) and avoids bugs in VC6++ concerning
+ * the assignment of the result of intrinsic functions to const double&-typed variables,
+ * and optimization on.
+ */
+template <class T>
+class TI
+{
+ public:
+ typedef const T& Arg; //!< Arg is used for passing the element to a function.
+};
+
+template <>
+class TI<double> {
+public:
+ typedef double Arg;
+};
+
+template <>
+class TI<int> {
+public:
+ typedef int Arg;
+};
+
+
+
+
+
+/**
+ * /note linkage
+ * Something fishy about the difference between C++ and C
+ * in C++ const values default to INTERNAL linkage, in C they default
+ * to EXTERNAL linkage. Here the constants should have EXTERNAL linkage
+ * because they, for at least some of them, can be changed by the user.
+ * If you want to explicitly declare internal linkage, use "static".
+ */
+//!
+extern int STREAMBUFFERSIZE;
+
+//! maximal length of a file name
+extern int MAXLENFILENAME;
+
+//! the value of pi
+extern const double PI;
+
+//! the value pi/180
+extern const double deg2rad;
+
+//! the value 180/pi
+extern const double rad2deg;
+
+//! default precision while comparing with Equal(..,..) functions. Initialized at 0.0000001.
+extern double epsilon;
+
+//! power or 2 of epsilon
+extern double epsilon2;
+
+//! the number of derivatives used in the RN-... objects.
+extern int VSIZE;
+
+
+
+#ifndef _MFC_VER
+#undef max
+inline double max(double a,double b) {
+ if (b<a)
+ return a;
+ else
+ return b;
+}
+
+#undef min
+inline double min(double a,double b) {
+ if (b<a)
+ return b;
+ else
+ return a;
+}
+#endif
+
+
+#ifdef _MSC_VER
+ //#pragma inline_depth( 255 )
+ //#pragma inline_recursion( on )
+ #define INLINE __forceinline
+ //#define INLINE inline
+#else
+ #define INLINE inline
+#endif
+
+
+inline double LinComb(double alfa,double a,
+ double beta,double b ) {
+ return alfa*a+beta*b;
+}
+
+inline void LinCombR(double alfa,double a,
+ double beta,double b,double& result ) {
+ result=alfa*a+beta*b;
+ }
+
+//! to uniformly set double, RNDouble,Vector,... objects to zero in template-classes
+inline void SetToZero(double& arg) {
+ arg=0;
+}
+
+//! to uniformly set double, RNDouble,Vector,... objects to the identity element in template-classes
+inline void SetToIdentity(double& arg) {
+ arg=1;
+}
+
+inline double sign(double arg) {
+ return (arg<0)?(-1):(1);
+}
+
+inline double sqr(double arg) { return arg*arg;}
+inline double Norm(double arg) {
+ return fabs( (double)arg );
+}
+
+#ifdef __WIN32__
+inline double hypot(double y,double x) { return ::_hypot(y,x);}
+inline double abs(double x) { return ::fabs(x);}
+#endif
+
+// compares whether 2 doubles are equal in an eps-interval.
+// Does not check whether a or b represents numbers
+// On VC6, if a/b is -INF, it returns false;
+inline bool Equal(double a,double b,double eps=epsilon)
+{
+ double tmp=(a-b);
+ return ((eps>tmp)&& (tmp>-eps) );
+}
+
+inline void random(double& a) {
+ a = 1.98*rand()/(double)RAND_MAX -0.99;
+}
+
+inline void posrandom(double& a) {
+ a = 0.001+0.99*rand()/(double)RAND_MAX;
+}
+
+inline double diff(double a,double b,double dt) {
+ return (b-a)/dt;
+}
+//inline float diff(float a,float b,double dt) {
+//return (b-a)/dt;
+//}
+inline double addDelta(double a,double da,double dt) {
+ return a+da*dt;
+}
+
+//inline float addDelta(float a,float da,double dt) {
+// return a+da*dt;
+//}
+
+
+}
+
+
+
+#endif
diff --git a/intern/itasc/kdl/utilities/utility_io.cpp b/intern/itasc/kdl/utilities/utility_io.cpp
new file mode 100644
index 00000000000..ae65047fdbc
--- /dev/null
+++ b/intern/itasc/kdl/utilities/utility_io.cpp
@@ -0,0 +1,208 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: utility_io.cpp 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ * \todo
+ * make IO routines more robust against the differences between DOS/UNIX end-of-line style.
+ ****************************************************************************/
+
+
+#include "utility_io.h"
+#include "error.h"
+
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+
+namespace KDL {
+
+//
+// _functions are private functions
+//
+
+ void _check_istream(std::istream& is)
+ {
+ if ((!is.good())&&(is.eof()) )
+ {
+ throw Error_BasicIO_File();
+ }
+ }
+// Eats until the end of the line
+ int _EatUntilEndOfLine( std::istream& is, int* countp=NULL) {
+ int ch;
+ int count;
+ count = 0;
+ do {
+ ch = is.get();
+ count++;
+ _check_istream(is);
+ } while (ch!='\n');
+ if (countp!=NULL) *countp = count;
+ return ch;
+}
+
+// Eats until the end of the comment
+ int _EatUntilEndOfComment( std::istream& is, int* countp=NULL) {
+ int ch;
+ int count;
+ count = 0;
+ int prevch;
+ ch = 0;
+ do {
+ prevch = ch;
+ ch = is.get();
+ count++;
+ _check_istream(is);
+ if ((prevch=='*')&&(ch=='/')) {
+ break;
+ }
+ } while (true);
+ if (countp!=NULL) *countp = count;
+ ch = is.get();
+ return ch;
+}
+
+// Eats space-like characters and comments
+// possibly returns the number of space-like characters eaten.
+int _EatSpace( std::istream& is,int* countp=NULL) {
+ int ch;
+ int count;
+ count=-1;
+ do {
+ _check_istream(is);
+
+ ch = is.get();
+ count++;
+ if (ch == '#') {
+ ch = _EatUntilEndOfLine(is,&count);
+ }
+ if (ch == '/') {
+ ch = is.get();
+ if (ch == '/') {
+ ch = _EatUntilEndOfLine(is,&count);
+ } else if (ch == '*') {
+ ch = _EatUntilEndOfComment(is,&count);
+ } else {
+ is.putback(ch);
+ ch = '/';
+ }
+ }
+ } while ((ch==' ')||(ch=='\n')||(ch=='\t'));
+ if (countp!=NULL) *countp = count;
+ return ch;
+}
+
+
+
+// Eats whites, returns, tabs and the delim character
+// Checks wether delim char. is encountered.
+void Eat( std::istream& is, int delim )
+{
+ int ch;
+ ch=_EatSpace(is);
+ if (ch != delim) {
+ throw Error_BasicIO_Exp_Delim();
+ }
+ ch=_EatSpace(is);
+ is.putback(ch);
+}
+
+// Eats whites, returns, tabs and the delim character
+// Checks wether delim char. is encountered.
+// EatEnd does not eat all space-like char's at the end.
+void EatEnd( std::istream& is, int delim )
+{
+ int ch;
+ ch=_EatSpace(is);
+ if (ch != delim) {
+ throw Error_BasicIO_Exp_Delim();
+ }
+}
+
+
+
+// For each space in descript, this routine eats whites,tabs, and newlines (at least one)
+// There should be no consecutive spaces in the description.
+// for each letter in descript, its reads the corresponding letter in the output
+// the routine is case insensitive.
+
+
+// Simple routine, enough for our purposes.
+// works with ASCII chars
+inline char Upper(char ch)
+{
+ /*if (('a'<=ch)&&(ch<='z'))
+ return (ch-'a'+'A');
+ else
+ return ch;
+ */
+ return toupper(ch);
+}
+
+void Eat(std::istream& is,const char* descript)
+{
+ // eats whites before word
+ char ch;
+ char chdescr;
+ ch=_EatSpace(is);
+ is.putback(ch);
+ const char* p;
+ p = descript;
+ while ((*p)!=0) {
+ chdescr = (char)Upper(*p);
+ if (chdescr==' ') {
+ int count=0;
+ ch=_EatSpace(is,&count);
+ is.putback(ch);
+ if (count==0) {
+ throw Error_BasicIO_Not_A_Space();
+ }
+ } else {
+ ch=(char)is.get();
+ if (chdescr!=Upper(ch)) {
+ throw Error_BasicIO_Unexpected();
+ }
+ }
+ p++;
+ }
+
+}
+
+
+
+void EatWord(std::istream& is,const char* delim,char* storage,int maxsize)
+{
+ int ch;
+ char* p;
+ int size;
+ // eat white before word
+ ch=_EatSpace(is);
+ p = storage;
+ size=0;
+ int count = 0;
+ while ((count==0)&&(strchr(delim,ch)==NULL)) {
+ *p = (char) toupper(ch);
+ ++p;
+ if (size==maxsize) {
+ throw Error_BasicIO_ToBig();
+ }
+ _check_istream(is);
+ ++size;
+ //ch = is.get();
+ ch =_EatSpace(is,&count);
+ }
+ *p=0;
+ is.putback(ch);
+}
+
+
+}
diff --git a/intern/itasc/kdl/utilities/utility_io.h b/intern/itasc/kdl/utilities/utility_io.h
new file mode 100644
index 00000000000..7c3d4f91296
--- /dev/null
+++ b/intern/itasc/kdl/utilities/utility_io.h
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ * \author
+ * Erwin Aertbelien, Div. PMA, Dep. of Mech. Eng., K.U.Leuven
+ *
+ * \version
+ * ORO_Geometry V0.2
+ *
+ * \par History
+ * - $log$
+ *
+ * \par Release
+ * $Id: utility_io.h 19905 2009-04-23 13:29:54Z ben2610 $
+ * $Name: $
+ *
+ * \file utility_io.h
+ * Included by most lrl-files to provide some general
+ * functions and macro definitions related to file/stream I/O.
+ */
+
+#ifndef KDL_UTILITY_IO_H_84822
+#define KDL_UTILITY_IO_H_84822
+
+//#include <kdl/kdl-config.h>
+
+
+// Standard includes
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+
+
+namespace KDL {
+
+
+/**
+ * checks validity of basic io of is
+ */
+void _check_istream(std::istream& is);
+
+
+/**
+ * Eats characters of the stream until the character delim is encountered
+ * @param is a stream
+ * @param delim eat until this character is encountered
+ */
+void Eat(std::istream& is, int delim );
+
+/**
+ * Eats characters of the stream as long as they satisfy the description in descript
+ * @param is a stream
+ * @param descript description string. A sequence of spaces, tabs,
+ * new-lines and comments is regarded as 1 space in the description string.
+ */
+void Eat(std::istream& is,const char* descript);
+
+/**
+ * Eats a word of the stream delimited by the letters in delim or space(tabs...)
+ * @param is a stream
+ * @param delim a string containing the delimmiting characters
+ * @param storage for returning the word
+ * @param maxsize a word can be maximally maxsize-1 long.
+ */
+void EatWord(std::istream& is,const char* delim,char* storage,int maxsize);
+
+/**
+ * Eats characters of the stream until the character delim is encountered
+ * similar to Eat(is,delim) but spaces at the end are not read.
+ * @param is a stream
+ * @param delim eat until this character is encountered
+ */
+void EatEnd( std::istream& is, int delim );
+
+
+
+
+}
+
+
+#endif
diff --git a/intern/itasc/make/msvc_9_0/itasc.vcproj b/intern/itasc/make/msvc_9_0/itasc.vcproj
new file mode 100644
index 00000000000..f4a81079da0
--- /dev/null
+++ b/intern/itasc/make/msvc_9_0/itasc.vcproj
@@ -0,0 +1,539 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="INT_itasc"
+ ProjectGUID="{59567A5B-F63A-4A5C-B33A-0A45C300F4DC}"
+ RootNamespace="itasc"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="196613"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Blender Debug|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\itasc\debug"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\itasc\debug"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\..\..\extern\Eigen2"
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB"
+ MinimalRebuild="false"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="0"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\itasc\debug\itasc.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\itasc\debug\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\itasc\debug\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\itasc\debug\"
+ WarningLevel="3"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\debug\libitasc.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Blender Release|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\itasc"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\itasc"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ WholeProgramOptimization="1"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ EnableIntrinsicFunctions="true"
+ AdditionalIncludeDirectories="..\..\..\..\extern\Eigen2"
+ PreprocessorDefinitions="WIN32;NDEBUG;_LIB"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ AssemblerListingLocation="$(IntDir)\"
+ WarningLevel="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\libitasc.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="kdl"
+ >
+ <Filter
+ Name="Header Files"
+ >
+ <File
+ RelativePath="..\..\kdl\chain.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainfksolver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainfksolverpos_recursive.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainjnttojacsolver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frameacc.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frameacc.inl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames.inl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames_io.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\framevel.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\framevel.inl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\inertia.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jacobian.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarray.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarrayacc.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarrayvel.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\joint.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\kinfam_io.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\segment.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\tree.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treefksolver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treefksolverpos_recursive.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treejnttojacsolver.hpp"
+ >
+ </File>
+ <Filter
+ Name="Utilities"
+ >
+ <File
+ RelativePath="..\..\kdl\utilities\error.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\error_stack.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\kdl-config.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\rall1d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\rall2d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\svd_eigen_HH.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\traits.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\utility.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\utility_io.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ >
+ <File
+ RelativePath="..\..\kdl\chain.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainfksolverpos_recursive.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\chainjnttojacsolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frameacc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\frames_io.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\framevel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\inertia.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jacobian.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarray.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarrayacc.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\jntarrayvel.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\joint.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\kinfam_io.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\segment.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\tree.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treefksolverpos_recursive.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\treejnttojacsolver.cpp"
+ >
+ </File>
+ <Filter
+ Name="Utilities"
+ >
+ <File
+ RelativePath="..\..\kdl\utilities\error_stack.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\utility.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\kdl\utilities\utility_io.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="itasc"
+ >
+ <Filter
+ Name="Header Files"
+ Filter="h;hpp;hxx;hm;inl;inc;xsd"
+ UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
+ >
+ <File
+ RelativePath="..\..\Armature.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Cache.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ConstraintSet.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ControlledObject.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\CopyPose.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Distance.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\eigen_types.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FixedObject.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\MovingFrame.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Object.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Scene.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Solver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\UncontrolledObject.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WDLSSolver.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WorldObject.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WSDLSSolver.hpp"
+ >
+ </File>
+ </Filter>
+ <Filter
+ Name="Source Files"
+ Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
+ UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
+ >
+ <File
+ RelativePath="..\..\Armature.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Cache.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ConstraintSet.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\ControlledObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\CopyPose.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Distance.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\eigen_types.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\FixedObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\MovingFrame.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\Scene.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\UncontrolledObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WDLSSolver.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WorldObject.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\WSDLSSolver.cpp"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/intern/itasc/ublas_types.hpp b/intern/itasc/ublas_types.hpp
new file mode 100644
index 00000000000..bf9bdcc26f2
--- /dev/null
+++ b/intern/itasc/ublas_types.hpp
@@ -0,0 +1,82 @@
+/*
+ * ublas_types.hpp
+ *
+ * Created on: Jan 5, 2009
+ * Author: rubensmits
+ */
+
+#ifndef UBLAS_TYPES_HPP_
+#define UBLAS_TYPES_HPP_
+
+#include <boost/numeric/ublas/matrix.hpp>
+#include <boost/numeric/ublas/vector.hpp>
+#include <boost/numeric/ublas/matrix_proxy.hpp>
+#include <boost/numeric/ublas/vector_proxy.hpp>
+#include "kdl/frames.hpp"
+#include "kdl/tree.hpp"
+#include "kdl/chain.hpp"
+#include "kdl/jacobian.hpp"
+#include "kdl/jntarray.hpp"
+
+
+namespace iTaSC{
+
+namespace ublas = boost::numeric::ublas;
+using KDL::Twist;
+using KDL::Frame;
+using KDL::Joint;
+using KDL::Inertia;
+using KDL::SegmentMap;
+using KDL::Tree;
+using KDL::JntArray;
+using KDL::Jacobian;
+using KDL::Segment;
+using KDL::Rotation;
+using KDL::Vector;
+using KDL::Chain;
+
+#define u_scalar double
+#define u_vector ublas::vector<u_scalar>
+#define u_zero_vector ublas::zero_vector<u_scalar>
+#define u_matrix ublas::matrix<u_scalar>
+#define u_matrix6 ublas::matrix<u_scalar,6,6>
+#define u_identity_matrix ublas::identity_matrix<u_scalar>
+#define u_scalar_vector ublas::scalar_vector<u_scalar>
+#define u_zero_matrix ublas::zero_matrix<u_scalar>
+#define u_vector6 ublas::bounded_vector<u_scalar,6>
+
+inline static int changeBase(const u_matrix& J_in, const Frame& T, u_matrix& J_out) {
+
+ if (J_out.size1() != 6 || J_in.size1() != 6 || J_in.size2() != J_out.size2())
+ return -1;
+ for (unsigned int j = 0; j < J_in.size2(); ++j) {
+ ublas::matrix_column<const u_matrix > Jj_in = column(J_in,j);
+ ublas::matrix_column<u_matrix > Jj_out = column(J_out,j);
+ Twist arg;
+ for(unsigned int i=0;i<6;++i)
+ arg(i)=Jj_in(i);
+ Twist tmp(T*arg);
+ for(unsigned int i=0;i<6;++i)
+ Jj_out(i)=tmp(i);
+ }
+ return 0;
+}
+inline static int changeBase(const ublas::matrix_range<u_matrix >& J_in, const Frame& T, ublas::matrix_range<u_matrix >& J_out) {
+
+ if (J_out.size1() != 6 || J_in.size1() != 6 || J_in.size2() != J_out.size2())
+ return -1;
+ for (unsigned int j = 0; j < J_in.size2(); ++j) {
+ ublas::matrix_column<const ublas::matrix_range<u_matrix > > Jj_in = column(J_in,j);
+ ublas::matrix_column<ublas::matrix_range<u_matrix > > Jj_out = column(J_out,j);
+ Twist arg;
+ for(unsigned int i=0;i<6;++i)
+ arg(i)=Jj_in(i);
+ Twist tmp(T*arg);
+ for(unsigned int i=0;i<6;++i)
+ Jj_out(i)=tmp(i);
+ }
+ return 0;
+}
+
+}
+#endif /* UBLAS_TYPES_HPP_ */
diff --git a/intern/memutil/SConscript b/intern/memutil/SConscript
index 4528de814f3..318d4a3997e 100644
--- a/intern/memutil/SConscript
+++ b/intern/memutil/SConscript
@@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp')
incs = '. ..'
-env.BlenderLib ('bf_memutil', sources, Split(incs), [], libtype=['intern', 'player'], priority = [0, 180] )
+env.BlenderLib ('bf_memutil', sources, Split(incs), [], libtype=['intern','player'], priority = [0,155] )
diff --git a/intern/memutil/make/msvc_9_0/memutil.vcproj b/intern/memutil/make/msvc_9_0/memutil.vcproj
index 6f642fb16bc..0b8251f0d7e 100644
--- a/intern/memutil/make/msvc_9_0/memutil.vcproj
+++ b/intern/memutil/make/msvc_9_0/memutil.vcproj
@@ -119,6 +119,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\..\..\intern;..\..\..\memutil"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/moto/SConscript b/intern/moto/SConscript
index a730e6de535..d9bbafe4623 100644
--- a/intern/moto/SConscript
+++ b/intern/moto/SConscript
@@ -5,4 +5,4 @@ sources = env.Glob('intern/*.cpp')
incs = 'include'
-env.BlenderLib ('bf_moto', sources, Split(incs), [], libtype=['intern'], priority = [130] )
+env.BlenderLib ('bf_moto', sources, Split(incs), [], libtype=['intern','player'], priority = [130,95] )
diff --git a/intern/moto/make/msvc_9_0/moto.vcproj b/intern/moto/make/msvc_9_0/moto.vcproj
index b33bb165a75..34c5705e2f2 100644
--- a/intern/moto/make/msvc_9_0/moto.vcproj
+++ b/intern/moto/make/msvc_9_0/moto.vcproj
@@ -42,6 +42,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="2"
AdditionalIncludeDirectories="..\..\include\"
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
diff --git a/intern/opennl/superlu/BLO_sys_types.h b/intern/opennl/superlu/BLO_sys_types.h
index 411a8582f96..56a27ec17ce 100644
--- a/intern/opennl/superlu/BLO_sys_types.h
+++ b/intern/opennl/superlu/BLO_sys_types.h
@@ -83,7 +83,7 @@ typedef unsigned long uintptr_t;
#define _UINTPTR_T_DEFINED
#endif
-#elif defined(__linux__)
+#elif defined(__linux__) || defined(__NetBSD__)
/* Linux-i386, Linux-Alpha, Linux-ppc */
#include <stdint.h>
diff --git a/intern/smoke/CMakeLists.txt b/intern/smoke/CMakeLists.txt
new file mode 100644
index 00000000000..8ed7a7c9115
--- /dev/null
+++ b/intern/smoke/CMakeLists.txt
@@ -0,0 +1,42 @@
+# $Id$
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2006, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Daniel Genrich
+#
+# ***** END GPL LICENSE BLOCK *****
+
+SET(INC ${PNG_INC} ${ZLIB_INC} intern ../../extern/bullet2/src ../memutil ../guardealloc)
+
+FILE(GLOB SRC intern/*.cpp)
+
+IF(WITH_OPENMP)
+ ADD_DEFINITIONS(-DPARALLEL=1)
+ENDIF(WITH_OPENMP)
+
+IF(WITH_FFTW3)
+ ADD_DEFINITIONS(-DFFTW3=1)
+ SET(INC ${INC} ${FFTW3_INC})
+ENDIF(WITH_FFTW3)
+
+
+BLENDERLIB(bf_smoke "${SRC}" "${INC}")
+#, libtype='blender', priority = 0 )
diff --git a/intern/SoundSystem/Makefile b/intern/smoke/Makefile
index 4d346f65138..e5144a9c3f8 100644
--- a/intern/SoundSystem/Makefile
+++ b/intern/smoke/Makefile
@@ -24,47 +24,31 @@
#
# The Original Code is: all of this file.
#
-# Contributor(s): GSR
+# Contributor(s): Hans Lambermont, GSR
#
# ***** END GPL LICENSE BLOCK *****
-#
+# smoke main makefile.
#
include nan_definitions.mk
-LIBNAME = SoundSystem
-SOURCEDIR = intern/SoundSystem
+unexport NAN_QUIET
+
+LIBNAME = smoke
+SOURCEDIR = intern/$(LIBNAME)
DIR = $(OCGDIR)/$(SOURCEDIR)
DIRS = intern
-DIRS += dummy
-
-ifneq ($(NAN_NO_OPENAL),true)
- ifeq ($(OS),windows)
- DIRS += openal sdl
- endif
- ifeq ($(OS),darwin)
- DIRS += openal
- endif
- ifeq ($(OS),$(findstring $(OS), "linux freebsd solaris"))
- DIRS += openal sdl
- endif
- ifeq ($(OS), irix)
- DIRS += sdl
- endif
-else
- export CPPFLAGS += -DNO_SOUND
-endif
+#not ready yet TESTDIRS = test
include nan_subdirs.mk
install: $(ALL_OR_DEBUG)
- @[ -d $(NAN_SOUNDSYSTEM) ] || mkdir $(NAN_SOUNDSYSTEM)
- @[ -d $(NAN_SOUNDSYSTEM)/include ] || mkdir $(NAN_SOUNDSYSTEM)/include
- @[ -d $(NAN_SOUNDSYSTEM)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_SOUNDSYSTEM)/lib/$(DEBUG_DIR)
- @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)libSoundSystem.a $(NAN_SOUNDSYSTEM)/lib/$(DEBUG_DIR)
+ @[ -d $(NAN_SMOKE) ] || mkdir $(NAN_SMOKE)
+ @[ -d $(NAN_SMOKE)/include ] || mkdir $(NAN_SMOKE)/include
+ @[ -d $(NAN_SMOKE)/lib/$(DEBUG_DIR) ] || mkdir $(NAN_SMOKE)/lib/$(DEBUG_DIR)
+ @../tools/cpifdiff.sh $(DIR)/$(DEBUG_DIR)lib$(LIBNAME).a $(NAN_SMOKE)/lib/$(DEBUG_DIR)
ifeq ($(OS),darwin)
- ranlib $(NAN_SOUNDSYSTEM)/lib/$(DEBUG_DIR)libSoundSystem.a
+ ranlib $(NAN_SMOKE)/lib/$(DEBUG_DIR)lib$(LIBNAME).a
endif
- @../tools/cpifdiff.sh *.h $(NAN_SOUNDSYSTEM)/include/
-
+ @../tools/cpifdiff.sh extern/*.h $(NAN_SMOKE)/include/
diff --git a/intern/smoke/SConscript b/intern/smoke/SConscript
new file mode 100644
index 00000000000..af5bf1aeb20
--- /dev/null
+++ b/intern/smoke/SConscript
@@ -0,0 +1,18 @@
+#!/usr/bin/python
+Import ('env')
+
+sources = env.Glob('intern/*.cpp')
+
+defs = ''
+
+if env['WITH_BF_OPENMP']:
+ defs += ' PARALLEL=1'
+
+incs = env['BF_PNG_INC'] + ' ' + env['BF_ZLIB_INC']
+incs += ' intern ../../extern/bullet2/src ../memutil ../guardealloc '
+
+if env['WITH_BF_FFTW3']:
+ defs += ' FFTW3=1'
+ incs += env['BF_FFTW3_INC']
+
+env.BlenderLib ('bf_smoke', sources, Split(incs), Split(defs), libtype=['intern'], priority=[40] )
diff --git a/intern/smoke/extern/smoke_API.h b/intern/smoke/extern/smoke_API.h
new file mode 100644
index 00000000000..5607df70cf3
--- /dev/null
+++ b/intern/smoke/extern/smoke_API.h
@@ -0,0 +1,79 @@
+/**
+ * $Id$
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 by Daniel Genrich
+ * All rights reserved.
+ *
+ * Contributor(s): Daniel Genrich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef SMOKE_API_H_
+#define SMOKE_API_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct FLUID_3D;
+
+// export
+void smoke_export(struct FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles);
+
+// low res
+struct FLUID_3D *smoke_init(int *res, float *p0, float dt);
+void smoke_free(struct FLUID_3D *fluid);
+
+void smoke_initBlenderRNA(struct FLUID_3D *fluid, float *alpha, float *beta);
+void smoke_step(struct FLUID_3D *fluid, size_t framenr);
+
+float *smoke_get_density(struct FLUID_3D *fluid);
+float *smoke_get_heat(struct FLUID_3D *fluid);
+float *smoke_get_velocity_x(struct FLUID_3D *fluid);
+float *smoke_get_velocity_y(struct FLUID_3D *fluid);
+float *smoke_get_velocity_z(struct FLUID_3D *fluid);
+
+unsigned char *smoke_get_obstacle(struct FLUID_3D *fluid);
+
+size_t smoke_get_index(int x, int max_x, int y, int max_y, int z);
+size_t smoke_get_index2d(int x, int max_x, int y);
+
+void smoke_dissolve(struct FLUID_3D *fluid, int speed, int log);
+
+// wavelet turbulence functions
+struct WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype);
+void smoke_turbulence_free(struct WTURBULENCE *wt);
+void smoke_turbulence_step(struct WTURBULENCE *wt, struct FLUID_3D *fluid);
+
+float *smoke_turbulence_get_density(struct WTURBULENCE *wt);
+void smoke_turbulence_get_res(struct WTURBULENCE *wt, int *res);
+void smoke_turbulence_set_noise(struct WTURBULENCE *wt, int type);
+void smoke_initWaveletBlenderRNA(struct WTURBULENCE *wt, float *strength);
+
+void smoke_dissolve_wavelet(struct WTURBULENCE *wt, int speed, int log);
+
+// export
+void smoke_turbulence_export(struct WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SMOKE_API_H_ */
diff --git a/intern/smoke/intern/EIGENVALUE_HELPER.h b/intern/smoke/intern/EIGENVALUE_HELPER.h
new file mode 100644
index 00000000000..6ff61c5ca8e
--- /dev/null
+++ b/intern/smoke/intern/EIGENVALUE_HELPER.h
@@ -0,0 +1,47 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+//////////////////////////////////////////////////////////////////////
+// Helper function, compute eigenvalues of 3x3 matrix
+//////////////////////////////////////////////////////////////////////
+
+#include "tnt/jama_eig.h"
+
+//////////////////////////////////////////////////////////////////////
+// eigenvalues of 3x3 non-symmetric matrix
+//////////////////////////////////////////////////////////////////////
+int inline computeEigenvalues3x3(
+ float dout[3],
+ float a[3][3])
+{
+ TNT::Array2D<float> A = TNT::Array2D<float>(3,3, &a[0][0]);
+ TNT::Array1D<float> eig = TNT::Array1D<float>(3);
+ TNT::Array1D<float> eigImag = TNT::Array1D<float>(3);
+ JAMA::Eigenvalue<float> jeig = JAMA::Eigenvalue<float>(A);
+ jeig.getRealEigenvalues(eig);
+
+ // complex ones
+ jeig.getImagEigenvalues(eigImag);
+ dout[0] = sqrt(eig[0]*eig[0] + eigImag[0]*eigImag[0]);
+ dout[1] = sqrt(eig[1]*eig[1] + eigImag[1]*eigImag[1]);
+ dout[2] = sqrt(eig[2]*eig[2] + eigImag[2]*eigImag[2]);
+ return 0;
+}
+
+#undef rfabs
+#undef ROT
diff --git a/intern/smoke/intern/FFT_NOISE.h b/intern/smoke/intern/FFT_NOISE.h
new file mode 100644
index 00000000000..2c278cdc4fc
--- /dev/null
+++ b/intern/smoke/intern/FFT_NOISE.h
@@ -0,0 +1,178 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+/////////////////////////////////////////////////////////////////////////
+//
+
+#ifndef FFT_NOISE_H_
+#define FFT_NOISE_H_
+
+#if FFTW3==1
+#include <iostream>
+#include <fftw3.h>
+#include <MERSENNETWISTER.h>
+
+#include "WAVELET_NOISE.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
+/////////////////////////////////////////////////////////////////////////
+// shift spectrum to the format that FFTW expects
+/////////////////////////////////////////////////////////////////////////
+static void shift3D(float*& field, int xRes, int yRes, int zRes)
+{
+ int xHalf = xRes / 2;
+ int yHalf = yRes / 2;
+ int zHalf = zRes / 2;
+ // int slabSize = xRes * yRes;
+ for (int z = 0; z < zHalf; z++)
+ for (int y = 0; y < yHalf; y++)
+ for (int x = 0; x < xHalf; x++)
+ {
+ int index = x + y * xRes + z * xRes * yRes;
+ float temp;
+ int xSwap = xHalf;
+ int ySwap = yHalf * xRes;
+ int zSwap = zHalf * xRes * yRes;
+
+ // [0,0,0] to [1,1,1]
+ temp = field[index];
+ field[index] = field[index + xSwap + ySwap + zSwap];
+ field[index + xSwap + ySwap + zSwap] = temp;
+
+ // [1,0,0] to [0,1,1]
+ temp = field[index + xSwap];
+ field[index + xSwap] = field[index + ySwap + zSwap];
+ field[index + ySwap + zSwap] = temp;
+
+ // [0,1,0] to [1,0,1]
+ temp = field[index + ySwap];
+ field[index + ySwap] = field[index + xSwap + zSwap];
+ field[index + xSwap + zSwap] = temp;
+
+ // [0,0,1] to [1,1,0]
+ temp = field[index + zSwap];
+ field[index + zSwap] = field[index + xSwap + ySwap];
+ field[index + xSwap + ySwap] = temp;
+ }
+}
+
+static void generatTile_FFT(float* const noiseTileData, std::string filename)
+{
+ if (loadTile(noiseTileData, filename)) return;
+
+ int res = NOISE_TILE_SIZE;
+ int xRes = res;
+ int yRes = res;
+ int zRes = res;
+ int totalCells = xRes * yRes * zRes;
+
+ // create and shift the filter
+ float* filter = new float[totalCells];
+ for (int z = 0; z < zRes; z++)
+ for (int y = 0; y < yRes; y++)
+ for (int x = 0; x < xRes; x++)
+ {
+ int index = x + y * xRes + z * xRes * yRes;
+ float diff[] = {abs(x - xRes/2),
+ abs(y - yRes/2),
+ abs(z - zRes/2)};
+ float radius = sqrtf(diff[0] * diff[0] +
+ diff[1] * diff[1] +
+ diff[2] * diff[2]) / (xRes / 2);
+ radius *= M_PI;
+ float H = cos((M_PI / 2.0f) * log(4.0f * radius / M_PI) / log(2.0f));
+ H = H * H;
+ float filtered = H;
+
+ // clamp everything outside the wanted band
+ if (radius >= M_PI / 2.0f)
+ filtered = 0.0f;
+
+ // make sure to capture all low frequencies
+ if (radius <= M_PI / 4.0f)
+ filtered = 1.0f;
+
+ filter[index] = filtered;
+ }
+ shift3D(filter, xRes, yRes, zRes);
+
+ // create the noise
+ float* noise = new float[totalCells];
+ int index = 0;
+ MTRand twister;
+ for (int z = 0; z < zRes; z++)
+ for (int y = 0; y < yRes; y++)
+ for (int x = 0; x < xRes; x++, index++)
+ noise[index] = twister.randNorm();
+
+ // create padded field
+ fftw_complex* forward = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * totalCells);
+
+ // init padded field
+ index = 0;
+ for (int z = 0; z < zRes; z++)
+ for (int y = 0; y < yRes; y++)
+ for (int x = 0; x < xRes; x++, index++)
+ {
+ forward[index][0] = noise[index];
+ forward[index][1] = 0.0f;
+ }
+
+ // forward FFT
+ fftw_complex* backward = (fftw_complex*)fftw_malloc(sizeof(fftw_complex) * totalCells);
+ fftw_plan forwardPlan = fftw_plan_dft_3d(xRes, yRes, zRes, forward, backward, FFTW_FORWARD, FFTW_ESTIMATE);
+ fftw_execute(forwardPlan);
+ fftw_destroy_plan(forwardPlan);
+
+ // apply filter
+ index = 0;
+ for (int z = 0; z < zRes; z++)
+ for (int y = 0; y < yRes; y++)
+ for (int x = 0; x < xRes; x++, index++)
+ {
+ backward[index][0] *= filter[index];
+ backward[index][1] *= filter[index];
+ }
+
+ // backward FFT
+ fftw_plan backwardPlan = fftw_plan_dft_3d(xRes, yRes, zRes, backward, forward, FFTW_BACKWARD, FFTW_ESTIMATE);
+ fftw_execute(backwardPlan);
+ fftw_destroy_plan(backwardPlan);
+
+ // subtract out the low frequency components
+ index = 0;
+ for (int z = 0; z < zRes; z++)
+ for (int y = 0; y < yRes; y++)
+ for (int x = 0; x < xRes; x++, index++)
+ noise[index] -= forward[index][0] / totalCells;
+
+ // save out the noise tile
+ saveTile(noise, filename);
+
+ fftw_free(forward);
+ fftw_free(backward);
+ delete[] filter;
+ delete[] noise;
+}
+
+#endif
+
+#endif /* FFT_NOISE_H_ */
diff --git a/intern/smoke/intern/FLUID_3D.cpp b/intern/smoke/intern/FLUID_3D.cpp
new file mode 100644
index 00000000000..8a32eaa2e68
--- /dev/null
+++ b/intern/smoke/intern/FLUID_3D.cpp
@@ -0,0 +1,717 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+// FLUID_3D.cpp: implementation of the FLUID_3D class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "FLUID_3D.h"
+#include "IMAGE.h"
+#include <INTERPOLATE.h>
+#include "SPHERE.h"
+#include <zlib.h>
+
+// boundary conditions of the fluid domain
+#define DOMAIN_BC_FRONT 0 // z
+#define DOMAIN_BC_TOP 1 // y
+#define DOMAIN_BC_LEFT 1 // x
+#define DOMAIN_BC_BACK DOMAIN_BC_FRONT
+#define DOMAIN_BC_BOTTOM DOMAIN_BC_TOP
+#define DOMAIN_BC_RIGHT DOMAIN_BC_LEFT
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+FLUID_3D::FLUID_3D(int *res, float *p0, float dt) :
+ _xRes(res[0]), _yRes(res[1]), _zRes(res[2]), _res(0.0f), _dt(dt)
+{
+ // set simulation consts
+ // _dt = dt; // 0.10
+
+ // start point of array
+ _p0[0] = p0[0];
+ _p0[1] = p0[1];
+ _p0[2] = p0[2];
+
+ _iterations = 100;
+ _tempAmb = 0;
+ _heatDiffusion = 1e-3;
+ _vorticityEps = 2.0;
+ _totalTime = 0.0f;
+ _totalSteps = 0;
+ _res = Vec3Int(_xRes,_yRes,_zRes);
+ _maxRes = MAX3(_xRes, _yRes, _zRes);
+
+ // initialize wavelet turbulence
+ /*
+ if(amplify)
+ _wTurbulence = new WTURBULENCE(_res[0],_res[1],_res[2], amplify, noisetype);
+ else
+ _wTurbulence = NULL;
+ */
+
+ // scale the constants according to the refinement of the grid
+ _dx = 1.0f / (float)_maxRes;
+ float scaling = 64.0f / _maxRes;
+ scaling = (scaling < 1.0f) ? 1.0f : scaling;
+ _vorticityEps /= scaling;
+
+ // allocate arrays
+ _totalCells = _xRes * _yRes * _zRes;
+ _slabSize = _xRes * _yRes;
+ _xVelocity = new float[_totalCells];
+ _yVelocity = new float[_totalCells];
+ _zVelocity = new float[_totalCells];
+ _xVelocityOld = new float[_totalCells];
+ _yVelocityOld = new float[_totalCells];
+ _zVelocityOld = new float[_totalCells];
+ _xForce = new float[_totalCells];
+ _yForce = new float[_totalCells];
+ _zForce = new float[_totalCells];
+ _density = new float[_totalCells];
+ _densityOld = new float[_totalCells];
+ _heat = new float[_totalCells];
+ _heatOld = new float[_totalCells];
+ _obstacles = new unsigned char[_totalCells]; // set 0 at end of step
+
+ // DG TODO: check if alloc went fine
+
+ for (int x = 0; x < _totalCells; x++)
+ {
+ _density[x] = 0.0f;
+ _densityOld[x] = 0.0f;
+ _heat[x] = 0.0f;
+ _heatOld[x] = 0.0f;
+ _xVelocity[x] = 0.0f;
+ _yVelocity[x] = 0.0f;
+ _zVelocity[x] = 0.0f;
+ _xVelocityOld[x] = 0.0f;
+ _yVelocityOld[x] = 0.0f;
+ _zVelocityOld[x] = 0.0f;
+ _xForce[x] = 0.0f;
+ _yForce[x] = 0.0f;
+ _zForce[x] = 0.0f;
+ _obstacles[x] = false;
+ }
+
+ // set side obstacles
+ int index;
+ for (int y = 0; y < _yRes; y++)
+ for (int x = 0; x < _xRes; x++)
+ {
+ // front slab
+ index = x + y * _xRes;
+ if(DOMAIN_BC_FRONT==1) _obstacles[index] = 1;
+
+ // back slab
+ index += _totalCells - _slabSize;
+ if(DOMAIN_BC_BACK==1) _obstacles[index] = 1;
+ }
+
+ for (int z = 0; z < _zRes; z++)
+ for (int x = 0; x < _xRes; x++)
+ {
+ // bottom slab
+ index = x + z * _slabSize;
+ if(DOMAIN_BC_BOTTOM==1) _obstacles[index] = 1;
+
+ // top slab
+ index += _slabSize - _xRes;
+ if(DOMAIN_BC_TOP==1) _obstacles[index] = 1;
+ }
+
+ for (int z = 0; z < _zRes; z++)
+ for (int y = 0; y < _yRes; y++)
+ {
+ // left slab
+ index = y * _xRes + z * _slabSize;
+ if(DOMAIN_BC_LEFT==1) _obstacles[index] = 1;
+
+ // right slab
+ index += _xRes - 1;
+ if(DOMAIN_BC_RIGHT==1) _obstacles[index] = 1;
+ }
+}
+
+FLUID_3D::~FLUID_3D()
+{
+ if (_xVelocity) delete[] _xVelocity;
+ if (_yVelocity) delete[] _yVelocity;
+ if (_zVelocity) delete[] _zVelocity;
+ if (_xVelocityOld) delete[] _xVelocityOld;
+ if (_yVelocityOld) delete[] _yVelocityOld;
+ if (_zVelocityOld) delete[] _zVelocityOld;
+ if (_xForce) delete[] _xForce;
+ if (_yForce) delete[] _yForce;
+ if (_zForce) delete[] _zForce;
+ if (_density) delete[] _density;
+ if (_densityOld) delete[] _densityOld;
+ if (_heat) delete[] _heat;
+ if (_heatOld) delete[] _heatOld;
+ if (_obstacles) delete[] _obstacles;
+ // if (_wTurbulence) delete _wTurbulence;
+
+ // printf("deleted fluid\n");
+}
+
+// init direct access functions from blender
+void FLUID_3D::initBlenderRNA(float *alpha, float *beta)
+{
+ _alpha = alpha;
+ _beta = beta;
+}
+
+//////////////////////////////////////////////////////////////////////
+// step simulation once
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::step()
+{
+ // addSmokeTestCase(_density, _res);
+ // addSmokeTestCase(_heat, _res);
+
+ // wipe forces
+ for (int i = 0; i < _totalCells; i++)
+ {
+ _xForce[i] = _yForce[i] = _zForce[i] = 0.0f;
+ // _obstacles[i] &= ~2;
+ }
+
+ wipeBoundaries();
+
+ // run the solvers
+ addVorticity();
+ addBuoyancy(_heat, _density);
+ addForce();
+ project();
+ diffuseHeat();
+
+ // advect everything
+ advectMacCormack();
+
+ // if(_wTurbulence) {
+ // _wTurbulence->stepTurbulenceFull(_dt/_dx,
+ // _xVelocity, _yVelocity, _zVelocity, _obstacles);
+ // _wTurbulence->stepTurbulenceReadable(_dt/_dx,
+ // _xVelocity, _yVelocity, _zVelocity, _obstacles);
+ // }
+/*
+ // no file output
+ float *src = _density;
+ string prefix = string("./original.preview/density_fullxy_");
+ writeImageSliceXY(src,_res, _res[2]/2, prefix, _totalSteps);
+*/
+ // artificial damping -- this is necessary because we use a
+ // collated grid, and at very coarse grid resolutions, banding
+ // artifacts can occur
+ artificialDamping(_xVelocity);
+ artificialDamping(_yVelocity);
+ artificialDamping(_zVelocity);
+/*
+// no file output
+ string pbrtPrefix = string("./pbrt/density_small_");
+ IMAGE::dumpPBRT(_totalSteps, pbrtPrefix, _density, _res[0],_res[1],_res[2]);
+ */
+ _totalTime += _dt;
+ _totalSteps++;
+
+ // todo xxx dg: only clear obstacles, not boundaries
+ // memset(_obstacles, 0, sizeof(unsigned char)*_xRes*_yRes*_zRes);
+}
+
+//////////////////////////////////////////////////////////////////////
+// helper function to dampen co-located grid artifacts of given arrays in intervals
+// (only needed for velocity, strength (w) depends on testcase...
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::artificialDamping(float* field) {
+ const float w = 0.9;
+ if(_totalSteps % 4 == 1) {
+ for (int z = 1; z < _res[2]-1; z++)
+ for (int y = 1; y < _res[1]-1; y++)
+ for (int x = 1+(y+z)%2; x < _res[0]-1; x+=2) {
+ const int index = x + y*_res[0] + z * _slabSize;
+ field[index] = (1-w)*field[index] + 1./6. * w*(
+ field[index+1] + field[index-1] +
+ field[index+_res[0]] + field[index-_res[0]] +
+ field[index+_slabSize] + field[index-_slabSize] );
+ }
+ }
+ if(_totalSteps % 4 == 3) {
+ for (int z = 1; z < _res[2]-1; z++)
+ for (int y = 1; y < _res[1]-1; y++)
+ for (int x = 1+(y+z+1)%2; x < _res[0]-1; x+=2) {
+ const int index = x + y*_res[0] + z * _slabSize;
+ field[index] = (1-w)*field[index] + 1./6. * w*(
+ field[index+1] + field[index-1] +
+ field[index+_res[0]] + field[index-_res[0]] +
+ field[index+_slabSize] + field[index-_slabSize] );
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// copy out the boundary in all directions
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::copyBorderAll(float* field)
+{
+ int index;
+ for (int y = 0; y < _yRes; y++)
+ for (int x = 0; x < _xRes; x++)
+ {
+ // front slab
+ index = x + y * _xRes;
+ field[index] = field[index + _slabSize];
+
+ // back slab
+ index += _totalCells - _slabSize;
+ field[index] = field[index - _slabSize];
+ }
+
+ for (int z = 0; z < _zRes; z++)
+ for (int x = 0; x < _xRes; x++)
+ {
+ // bottom slab
+ index = x + z * _slabSize;
+ field[index] = field[index + _xRes];
+
+ // top slab
+ index += _slabSize - _xRes;
+ field[index] = field[index - _xRes];
+ }
+
+ for (int z = 0; z < _zRes; z++)
+ for (int y = 0; y < _yRes; y++)
+ {
+ // left slab
+ index = y * _xRes + z * _slabSize;
+ field[index] = field[index + 1];
+
+ // right slab
+ index += _xRes - 1;
+ field[index] = field[index - 1];
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// wipe boundaries of velocity and density
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::wipeBoundaries()
+{
+ setZeroBorder(_xVelocity, _res);
+ setZeroBorder(_yVelocity, _res);
+ setZeroBorder(_zVelocity, _res);
+ setZeroBorder(_density, _res);
+}
+
+//////////////////////////////////////////////////////////////////////
+// add forces to velocity field
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::addForce()
+{
+ for (int i = 0; i < _totalCells; i++)
+ {
+ _xVelocity[i] += _dt * _xForce[i];
+ _yVelocity[i] += _dt * _yForce[i];
+ _zVelocity[i] += _dt * _zForce[i];
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// project into divergence free field
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::project()
+{
+ int x, y, z;
+ size_t index;
+
+ float *_pressure = new float[_totalCells];
+ float *_divergence = new float[_totalCells];
+
+ memset(_pressure, 0, sizeof(float)*_totalCells);
+ memset(_divergence, 0, sizeof(float)*_totalCells);
+
+ setObstacleBoundaries(_pressure);
+
+ // copy out the boundaries
+ if(DOMAIN_BC_LEFT == 0) setNeumannX(_xVelocity, _res);
+ else setZeroX(_xVelocity, _res);
+
+ if(DOMAIN_BC_TOP == 0) setNeumannY(_yVelocity, _res);
+ else setZeroY(_yVelocity, _res);
+
+ if(DOMAIN_BC_FRONT == 0) setNeumannZ(_zVelocity, _res);
+ else setZeroZ(_zVelocity, _res);
+
+ // calculate divergence
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ float xright = _xVelocity[index + 1];
+ float xleft = _xVelocity[index - 1];
+ float yup = _yVelocity[index + _xRes];
+ float ydown = _yVelocity[index - _xRes];
+ float ztop = _zVelocity[index + _slabSize];
+ float zbottom = _zVelocity[index - _slabSize];
+
+ if(_obstacles[index+1]) xright = - _xVelocity[index];
+ if(_obstacles[index-1]) xleft = - _xVelocity[index];
+ if(_obstacles[index+_xRes]) yup = - _yVelocity[index];
+ if(_obstacles[index-_xRes]) ydown = - _yVelocity[index];
+ if(_obstacles[index+_slabSize]) ztop = - _zVelocity[index];
+ if(_obstacles[index-_slabSize]) zbottom = - _zVelocity[index];
+
+ _divergence[index] = -_dx * 0.5f * (
+ xright - xleft +
+ yup - ydown +
+ ztop - zbottom );
+
+ // DG: commenting this helps CG to get a better start, 10-20% speed improvement
+ // _pressure[index] = 0.0f;
+ }
+ copyBorderAll(_pressure);
+
+ // solve Poisson equation
+ solvePressurePre(_pressure, _divergence, _obstacles);
+
+ setObstaclePressure(_pressure);
+
+ // project out solution
+ float invDx = 1.0f / _dx;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ // if(!_obstacles[index])
+ {
+ _xVelocity[index] -= 0.5f * (_pressure[index + 1] - _pressure[index - 1]) * invDx;
+ _yVelocity[index] -= 0.5f * (_pressure[index + _xRes] - _pressure[index - _xRes]) * invDx;
+ _zVelocity[index] -= 0.5f * (_pressure[index + _slabSize] - _pressure[index - _slabSize]) * invDx;
+ }/*
+ else
+ {
+ _xVelocity[index] = _yVelocity[index] = _zVelocity[index] = 0.0f;
+ }*/
+ }
+
+ if (_pressure) delete[] _pressure;
+ if (_divergence) delete[] _divergence;
+}
+
+//////////////////////////////////////////////////////////////////////
+// diffuse heat
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::diffuseHeat()
+{
+ SWAP_POINTERS(_heat, _heatOld);
+
+ copyBorderAll(_heatOld);
+ solveHeat(_heat, _heatOld, _obstacles);
+
+ // zero out inside obstacles
+ for (int x = 0; x < _totalCells; x++)
+ if (_obstacles[x])
+ _heat[x] = 0.0f;
+}
+
+//////////////////////////////////////////////////////////////////////
+// stamp an obstacle in the _obstacles field
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::addObstacle(OBSTACLE* obstacle)
+{
+ int index = 0;
+ for (int z = 0; z < _zRes; z++)
+ for (int y = 0; y < _yRes; y++)
+ for (int x = 0; x < _xRes; x++, index++)
+ if (obstacle->inside(x * _dx, y * _dx, z * _dx)) {
+ _obstacles[index] = true;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// calculate the obstacle directional types
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::setObstaclePressure(float *_pressure)
+{
+ // tag remaining obstacle blocks
+ for (int z = 1, index = _slabSize + _xRes + 1;
+ z < _zRes - 1; z++, index += 2 * _xRes)
+ for (int y = 1; y < _yRes - 1; y++, index += 2)
+ for (int x = 1; x < _xRes - 1; x++, index++)
+ {
+ // could do cascade of ifs, but they are a pain
+ if (_obstacles[index])
+ {
+ const int top = _obstacles[index + _slabSize];
+ const int bottom= _obstacles[index - _slabSize];
+ const int up = _obstacles[index + _xRes];
+ const int down = _obstacles[index - _xRes];
+ const int left = _obstacles[index - 1];
+ const int right = _obstacles[index + 1];
+
+ // unused
+ // const bool fullz = (top && bottom);
+ // const bool fully = (up && down);
+ //const bool fullx = (left && right);
+
+ _xVelocity[index] =
+ _yVelocity[index] =
+ _zVelocity[index] = 0.0f;
+ _pressure[index] = 0.0f;
+
+ // average pressure neighbors
+ float pcnt = 0.;
+ if (left && !right) {
+ _pressure[index] += _pressure[index + 1];
+ pcnt += 1.;
+ }
+ if (!left && right) {
+ _pressure[index] += _pressure[index - 1];
+ pcnt += 1.;
+ }
+ if (up && !down) {
+ _pressure[index] += _pressure[index - _xRes];
+ pcnt += 1.;
+ }
+ if (!up && down) {
+ _pressure[index] += _pressure[index + _xRes];
+ pcnt += 1.;
+ }
+ if (top && !bottom) {
+ _pressure[index] += _pressure[index - _slabSize];
+ pcnt += 1.;
+ // _zVelocity[index] += - _zVelocity[index - _slabSize];
+ // vp += 1.0;
+ }
+ if (!top && bottom) {
+ _pressure[index] += _pressure[index + _slabSize];
+ pcnt += 1.;
+ // _zVelocity[index] += - _zVelocity[index + _slabSize];
+ // vp += 1.0;
+ }
+
+ if(pcnt > 0.000001f)
+ _pressure[index] /= pcnt;
+
+ // test - dg
+ // if(vp > 0.000001f)
+ // _zVelocity[index] /= vp;
+
+ // TODO? set correct velocity bc's
+ // velocities are only set to zero right now
+ // this means it's not a full no-slip boundary condition
+ // but a "half-slip" - still looks ok right now
+ }
+ }
+}
+
+void FLUID_3D::setObstacleBoundaries(float *_pressure)
+{
+ // cull degenerate obstacles , move to addObstacle?
+ for (int z = 1, index = _slabSize + _xRes + 1;
+ z < _zRes - 1; z++, index += 2 * _xRes)
+ for (int y = 1; y < _yRes - 1; y++, index += 2)
+ for (int x = 1; x < _xRes - 1; x++, index++)
+ {
+ if (_obstacles[index] != EMPTY)
+ {
+ const int top = _obstacles[index + _slabSize];
+ const int bottom= _obstacles[index - _slabSize];
+ const int up = _obstacles[index + _xRes];
+ const int down = _obstacles[index - _xRes];
+ const int left = _obstacles[index - 1];
+ const int right = _obstacles[index + 1];
+
+ int counter = 0;
+ if (up) counter++;
+ if (down) counter++;
+ if (left) counter++;
+ if (right) counter++;
+ if (top) counter++;
+ if (bottom) counter++;
+
+ if (counter < 3)
+ _obstacles[index] = EMPTY;
+ }
+ if (_obstacles[index])
+ {
+ _xVelocity[index] =
+ _yVelocity[index] =
+ _zVelocity[index] = 0.0f;
+ _pressure[index] = 0.0f;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// add buoyancy forces
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::addBuoyancy(float *heat, float *density)
+{
+ int index = 0;
+
+ for (int z = 0; z < _zRes; z++)
+ for (int y = 0; y < _yRes; y++)
+ for (int x = 0; x < _xRes; x++, index++)
+ {
+ _zForce[index] += *_alpha * density[index] + (*_beta * (heat[index] - _tempAmb)); // DG: was _yForce, changed for Blender
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// add vorticity to the force field
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::addVorticity()
+{
+ int x,y,z,index;
+ if(_vorticityEps<=0.) return;
+
+ float *_xVorticity, *_yVorticity, *_zVorticity, *_vorticity;
+
+ _xVorticity = new float[_totalCells];
+ _yVorticity = new float[_totalCells];
+ _zVorticity = new float[_totalCells];
+ _vorticity = new float[_totalCells];
+
+ memset(_xVorticity, 0, sizeof(float)*_totalCells);
+ memset(_yVorticity, 0, sizeof(float)*_totalCells);
+ memset(_zVorticity, 0, sizeof(float)*_totalCells);
+ memset(_vorticity, 0, sizeof(float)*_totalCells);
+
+ // calculate vorticity
+ float gridSize = 0.5f / _dx;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ int up = _obstacles[index + _xRes] ? index : index + _xRes;
+ int down = _obstacles[index - _xRes] ? index : index - _xRes;
+ float dy = (up == index || down == index) ? 1.0f / _dx : gridSize;
+ int out = _obstacles[index + _slabSize] ? index : index + _slabSize;
+ int in = _obstacles[index - _slabSize] ? index : index - _slabSize;
+ float dz = (out == index || in == index) ? 1.0f / _dx : gridSize;
+ int right = _obstacles[index + 1] ? index : index + 1;
+ int left = _obstacles[index - 1] ? index : index - 1;
+ float dx = (right == index || right == index) ? 1.0f / _dx : gridSize;
+
+ _xVorticity[index] = (_zVelocity[up] - _zVelocity[down]) * dy + (-_yVelocity[out] + _yVelocity[in]) * dz;
+ _yVorticity[index] = (_xVelocity[out] - _xVelocity[in]) * dz + (-_zVelocity[right] + _zVelocity[left]) * dx;
+ _zVorticity[index] = (_yVelocity[right] - _yVelocity[left]) * dx + (-_xVelocity[up] + _xVelocity[down])* dy;
+
+ _vorticity[index] = sqrtf(_xVorticity[index] * _xVorticity[index] +
+ _yVorticity[index] * _yVorticity[index] +
+ _zVorticity[index] * _zVorticity[index]);
+ }
+
+ // calculate normalized vorticity vectors
+ float eps = _vorticityEps;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ if (!_obstacles[index])
+ {
+ float N[3];
+
+ int up = _obstacles[index + _xRes] ? index : index + _xRes;
+ int down = _obstacles[index - _xRes] ? index : index - _xRes;
+ float dy = (up == index || down == index) ? 1.0f / _dx : gridSize;
+ int out = _obstacles[index + _slabSize] ? index : index + _slabSize;
+ int in = _obstacles[index - _slabSize] ? index : index - _slabSize;
+ float dz = (out == index || in == index) ? 1.0f / _dx : gridSize;
+ int right = _obstacles[index + 1] ? index : index + 1;
+ int left = _obstacles[index - 1] ? index : index - 1;
+ float dx = (right == index || right == index) ? 1.0f / _dx : gridSize;
+ N[0] = (_vorticity[right] - _vorticity[left]) * dx;
+ N[1] = (_vorticity[up] - _vorticity[down]) * dy;
+ N[2] = (_vorticity[out] - _vorticity[in]) * dz;
+
+ float magnitude = sqrtf(N[0] * N[0] + N[1] * N[1] + N[2] * N[2]);
+ if (magnitude > 0.0f)
+ {
+ magnitude = 1.0f / magnitude;
+ N[0] *= magnitude;
+ N[1] *= magnitude;
+ N[2] *= magnitude;
+
+ _xForce[index] += (N[1] * _zVorticity[index] - N[2] * _yVorticity[index]) * _dx * eps;
+ _yForce[index] -= (N[0] * _zVorticity[index] - N[2] * _xVorticity[index]) * _dx * eps;
+ _zForce[index] += (N[0] * _yVorticity[index] - N[1] * _xVorticity[index]) * _dx * eps;
+ }
+ }
+
+ if (_xVorticity) delete[] _xVorticity;
+ if (_yVorticity) delete[] _yVorticity;
+ if (_zVorticity) delete[] _zVorticity;
+ if (_vorticity) delete[] _vorticity;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Advect using the MacCormack method from the Selle paper
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::advectMacCormack()
+{
+ Vec3Int res = Vec3Int(_xRes,_yRes,_zRes);
+
+ if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
+ else setZeroX(_xVelocity, res);
+
+ if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
+ else setZeroY(_yVelocity, res);
+
+ if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
+ else setZeroZ(_zVelocity, res);
+
+ SWAP_POINTERS(_xVelocity, _xVelocityOld);
+ SWAP_POINTERS(_yVelocity, _yVelocityOld);
+ SWAP_POINTERS(_zVelocity, _zVelocityOld);
+ SWAP_POINTERS(_density, _densityOld);
+ SWAP_POINTERS(_heat, _heatOld);
+
+ const float dt0 = _dt / _dx;
+ // use force arrays as temp arrays
+ for (int x = 0; x < _totalCells; x++)
+ _xForce[x] = _yForce[x] = 0.0;
+
+ float* t1 = _xForce;
+ float* t2 = _yForce;
+
+ advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _densityOld, _density, t1,t2, res, _obstacles);
+ advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _heatOld, _heat, t1,t2, res, _obstacles);
+ advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _xVelocityOld, _xVelocity, t1,t2, res, _obstacles);
+ advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _yVelocityOld, _yVelocity, t1,t2, res, _obstacles);
+ advectFieldMacCormack(dt0, _xVelocityOld, _yVelocityOld, _zVelocityOld, _zVelocityOld, _zVelocity, t1,t2, res, _obstacles);
+
+ if(DOMAIN_BC_LEFT == 0) copyBorderX(_xVelocity, res);
+ else setZeroX(_xVelocity, res);
+
+ if(DOMAIN_BC_TOP == 0) copyBorderY(_yVelocity, res);
+ else setZeroY(_yVelocity, res);
+
+ if(DOMAIN_BC_FRONT == 0) copyBorderZ(_zVelocity, res);
+ else setZeroZ(_zVelocity, res);
+
+ setZeroBorder(_density, res);
+ setZeroBorder(_heat, res);
+
+ for (int x = 0; x < _totalCells; x++)
+ t1[x] = t2[x] = 0.0;
+}
diff --git a/intern/smoke/intern/FLUID_3D.h b/intern/smoke/intern/FLUID_3D.h
new file mode 100644
index 00000000000..a7be7f58335
--- /dev/null
+++ b/intern/smoke/intern/FLUID_3D.h
@@ -0,0 +1,168 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+// FLUID_3D.h: interface for the FLUID_3D class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef FLUID_3D_H
+#define FLUID_3D_H
+
+#include <cstdlib>
+#include <cmath>
+#include <iostream>
+#include "OBSTACLE.h"
+// #include "WTURBULENCE.h"
+#include "VEC3.h"
+
+using namespace std;
+using namespace BasicVector;
+class WTURBULENCE;
+
+class FLUID_3D
+{
+ public:
+ FLUID_3D(int *res, /* int amplify, */ float *p0, float dt);
+ FLUID_3D() {};
+ virtual ~FLUID_3D();
+
+ void initBlenderRNA(float *alpha, float *beta);
+
+ // create & allocate vector noise advection
+ void initVectorNoise(int amplify);
+
+ void addSmokeColumn();
+ static void addSmokeTestCase(float* field, Vec3Int res);
+
+ void step();
+ void addObstacle(OBSTACLE* obstacle);
+
+ const float* xVelocity() { return _xVelocity; };
+ const float* yVelocity() { return _yVelocity; };
+ const float* zVelocity() { return _zVelocity; };
+
+ int xRes() const { return _xRes; };
+ int yRes() const { return _yRes; };
+ int zRes() const { return _zRes; };
+
+ public:
+ // dimensions
+ int _xRes, _yRes, _zRes, _maxRes;
+ Vec3Int _res;
+ size_t _totalCells;
+ int _slabSize;
+ float _dx;
+ float _p0[3];
+ float _p1[3];
+ float _totalTime;
+ int _totalSteps;
+ int _totalImgDumps;
+ int _totalVelDumps;
+
+ void artificialDamping(float* field);
+
+ // fields
+ float* _density;
+ float* _densityOld;
+ float* _heat;
+ float* _heatOld;
+ float* _xVelocity;
+ float* _yVelocity;
+ float* _zVelocity;
+ float* _xVelocityOld;
+ float* _yVelocityOld;
+ float* _zVelocityOld;
+ float* _xForce;
+ float* _yForce;
+ float* _zForce;
+ unsigned char* _obstacles;
+
+ // CG fields
+ int _iterations;
+
+ // simulation constants
+ float _dt;
+ float _vorticityEps;
+ float _heatDiffusion;
+ float *_alpha; // for the buoyancy density term <-- as pointer to get blender RNA in here
+ float *_beta; // was _buoyancy <-- as pointer to get blender RNA in here
+ float _tempAmb; /* ambient temperature */
+
+ // WTURBULENCE object, if active
+ // WTURBULENCE* _wTurbulence;
+
+ // boundary setting functions
+ void copyBorderAll(float* field);
+
+ // timestepping functions
+ void wipeBoundaries();
+ void addForce();
+ void addVorticity();
+ void addBuoyancy(float *heat, float *density);
+
+ // solver stuff
+ void project();
+ void diffuseHeat();
+ void solvePressure(float* field, float* b, unsigned char* skip);
+ void solvePressurePre(float* field, float* b, unsigned char* skip);
+ void solveHeat(float* field, float* b, unsigned char* skip);
+
+ // handle obstacle boundaries
+ void setObstacleBoundaries(float *_pressure);
+ void setObstaclePressure(float *_pressure);
+
+ public:
+ // advection, accessed e.g. by WTURBULENCE class
+ void advectMacCormack();
+
+ // boundary setting functions
+ static void copyBorderX(float* field, Vec3Int res);
+ static void copyBorderY(float* field, Vec3Int res);
+ static void copyBorderZ(float* field, Vec3Int res);
+ static void setNeumannX(float* field, Vec3Int res);
+ static void setNeumannY(float* field, Vec3Int res);
+ static void setNeumannZ(float* field, Vec3Int res);
+ static void setZeroX(float* field, Vec3Int res);
+ static void setZeroY(float* field, Vec3Int res);
+ static void setZeroZ(float* field, Vec3Int res);
+ static void setZeroBorder(float* field, Vec3Int res) {
+ setZeroX(field, res);
+ setZeroY(field, res);
+ setZeroZ(field, res);
+ };
+
+ // static advection functions, also used by WTURBULENCE
+ static void advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz,
+ float* oldField, float* newField, Vec3Int res);
+ static void advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
+ float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles);
+
+ // maccormack helper functions
+ static void clampExtrema(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
+ float* oldField, float* newField, Vec3Int res);
+ static void clampOutsideRays(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
+ float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection);
+
+ // output helper functions
+ // static void writeImageSliceXY(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.);
+ // static void writeImageSliceYZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.);
+ // static void writeImageSliceXZ(const float *field, Vec3Int res, int slice, string prefix, int picCnt, float scale=1.);
+ // static void writeProjectedIntern(const float *field, Vec3Int res, int dir1, int dir2, string prefix, int picCnt, float scale=1.);
+};
+
+#endif
diff --git a/intern/smoke/intern/FLUID_3D_SOLVERS.cpp b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp
new file mode 100644
index 00000000000..7d078d86d61
--- /dev/null
+++ b/intern/smoke/intern/FLUID_3D_SOLVERS.cpp
@@ -0,0 +1,524 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+// FLUID_3D.cpp: implementation of the FLUID_3D class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "FLUID_3D.h"
+#include <cstring>
+#define SOLVER_ACCURACY 1e-06
+
+void FLUID_3D::solvePressurePre(float* field, float* b, unsigned char* skip)
+{
+ int x, y, z;
+ size_t index;
+ float *_q, *_Precond, *_h, *_residual, *_direction;
+
+ // i = 0
+ int i = 0;
+
+ _residual = new float[_totalCells]; // set 0
+ _direction = new float[_totalCells]; // set 0
+ _q = new float[_totalCells]; // set 0
+ _h = new float[_totalCells]; // set 0
+ _Precond = new float[_totalCells]; // set 0
+
+ memset(_residual, 0, sizeof(float)*_xRes*_yRes*_zRes);
+ memset(_q, 0, sizeof(float)*_xRes*_yRes*_zRes);
+ memset(_direction, 0, sizeof(float)*_xRes*_yRes*_zRes);
+ memset(_h, 0, sizeof(float)*_xRes*_yRes*_zRes);
+ memset(_Precond, 0, sizeof(float)*_xRes*_yRes*_zRes);
+
+ // r = b - Ax
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ // if the cell is a variable
+ float Acenter = 0.0f;
+ if (!skip[index])
+ {
+ // set the matrix to the Poisson stencil in order
+ if (!skip[index + 1]) Acenter += 1.;
+ if (!skip[index - 1]) Acenter += 1.;
+ if (!skip[index + _xRes]) Acenter += 1.;
+ if (!skip[index - _xRes]) Acenter += 1.;
+ if (!skip[index + _slabSize]) Acenter += 1.;
+ if (!skip[index - _slabSize]) Acenter += 1.;
+ }
+
+ _residual[index] = b[index] - (Acenter * field[index] +
+ field[index - 1] * (skip[index - 1] ? 0.0 : -1.0f)+
+ field[index + 1] * (skip[index + 1] ? 0.0 : -1.0f)+
+ field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f)+
+ field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
+ field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f)+
+ field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f) );
+ _residual[index] = (skip[index]) ? 0.0f : _residual[index];
+
+ // P^-1
+ if(Acenter < 1.0)
+ _Precond[index] = 0.0;
+ else
+ _Precond[index] = 1.0 / Acenter;
+
+ // p = P^-1 * r
+ _direction[index] = _residual[index] * _Precond[index];
+ }
+
+ // deltaNew = transpose(r) * p
+ float deltaNew = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ deltaNew += _residual[index] * _direction[index];
+
+ // delta0 = deltaNew
+ // float delta0 = deltaNew;
+
+ // While deltaNew > (eps^2) * delta0
+ const float eps = SOLVER_ACCURACY;
+ //while ((i < _iterations) && (deltaNew > eps*delta0))
+ float maxR = 2.0f * eps;
+ // while (i < _iterations)
+ while ((i < _iterations) && (maxR > 0.001*eps))
+ {
+ // (s) q = Ad (p)
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ // if the cell is a variable
+ float Acenter = 0.0f;
+ if (!skip[index])
+ {
+ // set the matrix to the Poisson stencil in order
+ if (!skip[index + 1]) Acenter += 1.;
+ if (!skip[index - 1]) Acenter += 1.;
+ if (!skip[index + _xRes]) Acenter += 1.;
+ if (!skip[index - _xRes]) Acenter += 1.;
+ if (!skip[index + _slabSize]) Acenter += 1.;
+ if (!skip[index - _slabSize]) Acenter += 1.;
+ }
+
+ _q[index] = Acenter * _direction[index] +
+ _direction[index - 1] * (skip[index - 1] ? 0.0 : -1.0f) +
+ _direction[index + 1] * (skip[index + 1] ? 0.0 : -1.0f) +
+ _direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f) +
+ _direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
+ _direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f) +
+ _direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f);
+ _q[index] = (skip[index]) ? 0.0f : _q[index];
+ }
+
+ // alpha = deltaNew / (transpose(d) * q)
+ float alpha = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ alpha += _direction[index] * _q[index];
+ if (fabs(alpha) > 0.0f)
+ alpha = deltaNew / alpha;
+
+ // x = x + alpha * d
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ field[index] += alpha * _direction[index];
+
+ // r = r - alpha * q
+ maxR = 0.0;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ _residual[index] -= alpha * _q[index];
+ // maxR = (_residual[index] > maxR) ? _residual[index] : maxR;
+ }
+
+ // if(maxR <= eps)
+ // break;
+
+ // h = P^-1 * r
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ _h[index] = _Precond[index] * _residual[index];
+ }
+
+ // deltaOld = deltaNew
+ float deltaOld = deltaNew;
+
+ // deltaNew = transpose(r) * h
+ deltaNew = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ deltaNew += _residual[index] * _h[index];
+ maxR = (_residual[index]* _h[index] > maxR) ? _residual[index]* _h[index] : maxR;
+ }
+
+ // beta = deltaNew / deltaOld
+ float beta = deltaNew / deltaOld;
+
+ // d = h + beta * d
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ _direction[index] = _h[index] + beta * _direction[index];
+
+ // i = i + 1
+ i++;
+ }
+ // cout << i << " iterations converged to " << sqrt(maxR) << endl;
+
+ if (_h) delete[] _h;
+ if (_Precond) delete[] _Precond;
+ if (_residual) delete[] _residual;
+ if (_direction) delete[] _direction;
+ if (_q) delete[] _q;
+}
+
+//////////////////////////////////////////////////////////////////////
+// solve the poisson equation with CG
+//////////////////////////////////////////////////////////////////////
+#if 0
+void FLUID_3D::solvePressure(float* field, float* b, unsigned char* skip)
+{
+ int x, y, z;
+ size_t index;
+
+ // i = 0
+ int i = 0;
+
+ memset(_residual, 0, sizeof(float)*_xRes*_yRes*_zRes);
+ memset(_q, 0, sizeof(float)*_xRes*_yRes*_zRes);
+ memset(_direction, 0, sizeof(float)*_xRes*_yRes*_zRes);
+
+ // r = b - Ax
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ // if the cell is a variable
+ float Acenter = 0.0f;
+ if (!skip[index])
+ {
+ // set the matrix to the Poisson stencil in order
+ if (!skip[index + 1]) Acenter += 1.;
+ if (!skip[index - 1]) Acenter += 1.;
+ if (!skip[index + _xRes]) Acenter += 1.;
+ if (!skip[index - _xRes]) Acenter += 1.;
+ if (!skip[index + _slabSize]) Acenter += 1.;
+ if (!skip[index - _slabSize]) Acenter += 1.;
+ }
+
+ _residual[index] = b[index] - (Acenter * field[index] +
+ field[index - 1] * (skip[index - 1] ? 0.0 : -1.0f)+
+ field[index + 1] * (skip[index + 1] ? 0.0 : -1.0f)+
+ field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f)+
+ field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
+ field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f)+
+ field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f) );
+ _residual[index] = (skip[index]) ? 0.0f : _residual[index];
+ }
+
+
+ // d = r
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ _direction[index] = _residual[index];
+
+ // deltaNew = transpose(r) * r
+ float deltaNew = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ deltaNew += _residual[index] * _residual[index];
+
+ // delta0 = deltaNew
+ // float delta0 = deltaNew;
+
+ // While deltaNew > (eps^2) * delta0
+ const float eps = SOLVER_ACCURACY;
+ float maxR = 2.0f * eps;
+ while ((i < _iterations) && (maxR > eps))
+ {
+ // q = Ad
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ // if the cell is a variable
+ float Acenter = 0.0f;
+ if (!skip[index])
+ {
+ // set the matrix to the Poisson stencil in order
+ if (!skip[index + 1]) Acenter += 1.;
+ if (!skip[index - 1]) Acenter += 1.;
+ if (!skip[index + _xRes]) Acenter += 1.;
+ if (!skip[index - _xRes]) Acenter += 1.;
+ if (!skip[index + _slabSize]) Acenter += 1.;
+ if (!skip[index - _slabSize]) Acenter += 1.;
+ }
+
+ _q[index] = Acenter * _direction[index] +
+ _direction[index - 1] * (skip[index - 1] ? 0.0 : -1.0f) +
+ _direction[index + 1] * (skip[index + 1] ? 0.0 : -1.0f) +
+ _direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -1.0f) +
+ _direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -1.0f)+
+ _direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -1.0f) +
+ _direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -1.0f);
+ _q[index] = (skip[index]) ? 0.0f : _q[index];
+ }
+
+ // alpha = deltaNew / (transpose(d) * q)
+ float alpha = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ alpha += _direction[index] * _q[index];
+ if (fabs(alpha) > 0.0f)
+ alpha = deltaNew / alpha;
+
+ // x = x + alpha * d
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ field[index] += alpha * _direction[index];
+
+ // r = r - alpha * q
+ maxR = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ _residual[index] -= alpha * _q[index];
+ maxR = (_residual[index] > maxR) ? _residual[index] : maxR;
+ }
+
+ // deltaOld = deltaNew
+ float deltaOld = deltaNew;
+
+ // deltaNew = transpose(r) * r
+ deltaNew = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ deltaNew += _residual[index] * _residual[index];
+
+ // beta = deltaNew / deltaOld
+ float beta = deltaNew / deltaOld;
+
+ // d = r + beta * d
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ _direction[index] = _residual[index] + beta * _direction[index];
+
+ // i = i + 1
+ i++;
+ }
+ // cout << i << " iterations converged to " << maxR << endl;
+}
+#endif
+
+//////////////////////////////////////////////////////////////////////
+// solve the heat equation with CG
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::solveHeat(float* field, float* b, unsigned char* skip)
+{
+ int x, y, z;
+ size_t index;
+ const float heatConst = _dt * _heatDiffusion / (_dx * _dx);
+ float *_q, *_residual, *_direction;
+
+ // i = 0
+ int i = 0;
+
+ _residual = new float[_totalCells]; // set 0
+ _direction = new float[_totalCells]; // set 0
+ _q = new float[_totalCells]; // set 0
+
+ memset(_residual, 0, sizeof(float)*_xRes*_yRes*_zRes);
+ memset(_q, 0, sizeof(float)*_xRes*_yRes*_zRes);
+ memset(_direction, 0, sizeof(float)*_xRes*_yRes*_zRes);
+
+ // r = b - Ax
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ // if the cell is a variable
+ float Acenter = 1.0f;
+ if (!skip[index])
+ {
+ // set the matrix to the Poisson stencil in order
+ if (!skip[index + 1]) Acenter += heatConst;
+ if (!skip[index - 1]) Acenter += heatConst;
+ if (!skip[index + _xRes]) Acenter += heatConst;
+ if (!skip[index - _xRes]) Acenter += heatConst;
+ if (!skip[index + _slabSize]) Acenter += heatConst;
+ if (!skip[index - _slabSize]) Acenter += heatConst;
+ }
+
+ _residual[index] = b[index] - (Acenter * field[index] +
+ field[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
+ field[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
+ field[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
+ field[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
+ field[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
+ field[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
+ _residual[index] = (skip[index]) ? 0.0f : _residual[index];
+ }
+
+ // d = r
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ _direction[index] = _residual[index];
+
+ // deltaNew = transpose(r) * r
+ float deltaNew = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ deltaNew += _residual[index] * _residual[index];
+
+ // delta0 = deltaNew
+ // float delta0 = deltaNew;
+
+ // While deltaNew > (eps^2) * delta0
+ const float eps = SOLVER_ACCURACY;
+ float maxR = 2.0f * eps;
+ while ((i < _iterations) && (maxR > eps))
+ {
+ // q = Ad
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ // if the cell is a variable
+ float Acenter = 1.0f;
+ if (!skip[index])
+ {
+ // set the matrix to the Poisson stencil in order
+ if (!skip[index + 1]) Acenter += heatConst;
+ if (!skip[index - 1]) Acenter += heatConst;
+ if (!skip[index + _xRes]) Acenter += heatConst;
+ if (!skip[index - _xRes]) Acenter += heatConst;
+ if (!skip[index + _slabSize]) Acenter += heatConst;
+ if (!skip[index - _slabSize]) Acenter += heatConst;
+ }
+
+ _q[index] = (Acenter * _direction[index] +
+ _direction[index - 1] * (skip[index - 1] ? 0.0 : -heatConst) +
+ _direction[index + 1] * (skip[index + 1] ? 0.0 : -heatConst) +
+ _direction[index - _xRes] * (skip[index - _xRes] ? 0.0 : -heatConst) +
+ _direction[index + _xRes] * (skip[index + _xRes] ? 0.0 : -heatConst) +
+ _direction[index - _slabSize] * (skip[index - _slabSize] ? 0.0 : -heatConst) +
+ _direction[index + _slabSize] * (skip[index + _slabSize] ? 0.0 : -heatConst));
+
+ _q[index] = (skip[index]) ? 0.0f : _q[index];
+ }
+
+ // alpha = deltaNew / (transpose(d) * q)
+ float alpha = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ alpha += _direction[index] * _q[index];
+ if (fabs(alpha) > 0.0f)
+ alpha = deltaNew / alpha;
+
+ // x = x + alpha * d
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ field[index] += alpha * _direction[index];
+
+ // r = r - alpha * q
+ maxR = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ {
+ _residual[index] -= alpha * _q[index];
+ maxR = (_residual[index] > maxR) ? _residual[index] : maxR;
+ }
+
+ // deltaOld = deltaNew
+ float deltaOld = deltaNew;
+
+ // deltaNew = transpose(r) * r
+ deltaNew = 0.0f;
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ deltaNew += _residual[index] * _residual[index];
+
+ // beta = deltaNew / deltaOld
+ float beta = deltaNew / deltaOld;
+
+ // d = r + beta * d
+ index = _slabSize + _xRes + 1;
+ for (z = 1; z < _zRes - 1; z++, index += 2 * _xRes)
+ for (y = 1; y < _yRes - 1; y++, index += 2)
+ for (x = 1; x < _xRes - 1; x++, index++)
+ _direction[index] = _residual[index] + beta * _direction[index];
+
+ // i = i + 1
+ i++;
+ }
+ // cout << i << " iterations converged to " << maxR << endl;
+
+ if (_residual) delete[] _residual;
+ if (_direction) delete[] _direction;
+ if (_q) delete[] _q;
+}
+
diff --git a/intern/smoke/intern/FLUID_3D_STATIC.cpp b/intern/smoke/intern/FLUID_3D_STATIC.cpp
new file mode 100644
index 00000000000..0215dfc417f
--- /dev/null
+++ b/intern/smoke/intern/FLUID_3D_STATIC.cpp
@@ -0,0 +1,610 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+// FLUID_3D.cpp: implementation of the static functions of the FLUID_3D class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include <zlib.h>
+#include "FLUID_3D.h"
+#include "IMAGE.h"
+#include "WTURBULENCE.h"
+#include "INTERPOLATE.h"
+
+//////////////////////////////////////////////////////////////////////
+// add a test cube of density to the center
+//////////////////////////////////////////////////////////////////////
+/*
+void FLUID_3D::addSmokeColumn() {
+ addSmokeTestCase(_density, _res, 1.0);
+ // addSmokeTestCase(_zVelocity, _res, 1.0);
+ addSmokeTestCase(_heat, _res, 1.0);
+ if (_wTurbulence) {
+ addSmokeTestCase(_wTurbulence->getDensityBig(), _wTurbulence->getResBig(), 1.0);
+ }
+}
+*/
+
+//////////////////////////////////////////////////////////////////////
+// generic static version, so that it can be applied to the
+// WTURBULENCE grid as well
+//////////////////////////////////////////////////////////////////////
+
+void FLUID_3D::addSmokeTestCase(float* field, Vec3Int res)
+{
+ const int slabSize = res[0]*res[1]; int maxRes = (int)MAX3V(res);
+ float dx = 1.0f / (float)maxRes;
+
+ float xTotal = dx * res[0];
+ float yTotal = dx * res[1];
+ float zTotal = dx * res[2];
+
+ float heighMin = 0.05;
+ float heighMax = 0.10;
+
+ for (int y = 0; y < res[2]; y++)
+ for (int z = (int)(heighMin*res[2]); z <= (int)(heighMax * res[2]); z++)
+ for (int x = 0; x < res[0]; x++) {
+ float xLength = x * dx - xTotal * 0.4f;
+ float yLength = y * dx - yTotal * 0.5f;
+ float radius = sqrtf(xLength * xLength + yLength * yLength);
+
+ if (radius < 0.075f * xTotal) {
+ int index = x + y * res[0] + z * slabSize;
+ field[index] = 1.0f;
+ }
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// set x direction to Neumann boundary conditions
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::setNeumannX(float* field, Vec3Int res)
+{
+ const int slabSize = res[0] * res[1];
+ int index;
+ for (int z = 0; z < res[2]; z++)
+ for (int y = 0; y < res[1]; y++)
+ {
+ // left slab
+ index = y * res[0] + z * slabSize;
+ field[index] = field[index + 2];
+
+ // right slab
+ index += res[0] - 1;
+ field[index] = field[index - 2];
+ }
+
+ // fix, force top slab to only allow outwards flux
+ for (int y = 0; y < res[1]; y++)
+ for (int z = 0; z < res[2]; z++)
+ {
+ // top slab
+ index = y * res[0] + z * slabSize;
+ index += res[0] - 1;
+ if(field[index]<0.) field[index] = 0.;
+ index -= 1;
+ if(field[index]<0.) field[index] = 0.;
+ }
+ }
+
+//////////////////////////////////////////////////////////////////////
+// set y direction to Neumann boundary conditions
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::setNeumannY(float* field, Vec3Int res)
+{
+ const int slabSize = res[0] * res[1];
+ int index;
+ for (int z = 0; z < res[2]; z++)
+ for (int x = 0; x < res[0]; x++)
+ {
+ // bottom slab
+ index = x + z * slabSize;
+ field[index] = field[index + 2 * res[0]];
+
+ // top slab
+ index += slabSize - res[0];
+ field[index] = field[index - 2 * res[0]];
+ }
+
+ // fix, force top slab to only allow outwards flux
+ for (int z = 0; z < res[2]; z++)
+ for (int x = 0; x < res[0]; x++)
+ {
+ // top slab
+ index = x + z * slabSize;
+ index += slabSize - res[0];
+ if(field[index]<0.) field[index] = 0.;
+ index -= res[0];
+ if(field[index]<0.) field[index] = 0.;
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// set z direction to Neumann boundary conditions
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::setNeumannZ(float* field, Vec3Int res)
+{
+ const int slabSize = res[0] * res[1];
+ const int totalCells = res[0] * res[1] * res[2];
+ int index;
+ for (int y = 0; y < res[1]; y++)
+ for (int x = 0; x < res[0]; x++)
+ {
+ // front slab
+ index = x + y * res[0];
+ field[index] = field[index + 2 * slabSize];
+
+ // back slab
+ index += totalCells - slabSize;
+ field[index] = field[index - 2 * slabSize];
+ }
+
+ // fix, force top slab to only allow outwards flux
+ for (int y = 0; y < res[1]; y++)
+ for (int x = 0; x < res[0]; x++)
+ {
+ // top slab
+ index = x + y * res[0];
+ index += totalCells - slabSize;
+ if(field[index]<0.) field[index] = 0.;
+ index -= slabSize;
+ if(field[index]<0.) field[index] = 0.;
+ }
+
+}
+
+//////////////////////////////////////////////////////////////////////
+// set x direction to zero
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::setZeroX(float* field, Vec3Int res)
+{
+ const int slabSize = res[0] * res[1];
+ int index;
+ for (int z = 0; z < res[2]; z++)
+ for (int y = 0; y < res[1]; y++)
+ {
+ // left slab
+ index = y * res[0] + z * slabSize;
+ field[index] = 0.0f;
+
+ // right slab
+ index += res[0] - 1;
+ field[index] = 0.0f;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// set y direction to zero
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::setZeroY(float* field, Vec3Int res)
+{
+ const int slabSize = res[0] * res[1];
+ int index;
+ for (int z = 0; z < res[2]; z++)
+ for (int x = 0; x < res[0]; x++)
+ {
+ // bottom slab
+ index = x + z * slabSize;
+ field[index] = 0.0f;
+
+ // top slab
+ index += slabSize - res[0];
+ field[index] = 0.0f;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// set z direction to zero
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::setZeroZ(float* field, Vec3Int res)
+{
+ const int slabSize = res[0] * res[1];
+ const int totalCells = res[0] * res[1] * res[2];
+ int index;
+ for (int y = 0; y < res[1]; y++)
+ for (int x = 0; x < res[0]; x++)
+ {
+ // front slab
+ index = x + y * res[0];
+ field[index] = 0.0f;
+
+ // back slab
+ index += totalCells - slabSize;
+ field[index] = 0.0f;
+ }
+ }
+
+//////////////////////////////////////////////////////////////////////
+// copy grid boundary
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::copyBorderX(float* field, Vec3Int res)
+{
+ const int slabSize = res[0] * res[1];
+ int index;
+ for (int z = 0; z < res[2]; z++)
+ for (int y = 0; y < res[1]; y++)
+ {
+ // left slab
+ index = y * res[0] + z * slabSize;
+ field[index] = field[index + 1];
+
+ // right slab
+ index += res[0] - 1;
+ field[index] = field[index - 1];
+ }
+}
+void FLUID_3D::copyBorderY(float* field, Vec3Int res)
+{
+ const int slabSize = res[0] * res[1];
+ const int totalCells = res[0] * res[1] * res[2];
+ int index;
+ for (int z = 0; z < res[2]; z++)
+ for (int x = 0; x < res[0]; x++)
+ {
+ // bottom slab
+ index = x + z * slabSize;
+ field[index] = field[index + res[0]];
+ // top slab
+ index += slabSize - res[0];
+ field[index] = field[index - res[0]];
+ }
+}
+void FLUID_3D::copyBorderZ(float* field, Vec3Int res)
+{
+ const int slabSize = res[0] * res[1];
+ const int totalCells = res[0] * res[1] * res[2];
+ int index;
+ for (int y = 0; y < res[1]; y++)
+ for (int x = 0; x < res[0]; x++)
+ {
+ // front slab
+ index = x + y * res[0];
+ field[index] = field[index + slabSize];
+ // back slab
+ index += totalCells - slabSize;
+ field[index] = field[index - slabSize];
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// advect field with the semi lagrangian method
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::advectFieldSemiLagrange(const float dt, const float* velx, const float* vely, const float* velz,
+ float* oldField, float* newField, Vec3Int res)
+{
+ const int xres = res[0];
+ const int yres = res[1];
+ const int zres = res[2];
+ const int slabSize = res[0] * res[1];
+
+ // scale dt up to grid resolution
+#if PARALLEL==1
+#pragma omp parallel
+#pragma omp for schedule(static)
+#endif
+ for (int z = 0; z < zres; z++)
+ for (int y = 0; y < yres; y++)
+ for (int x = 0; x < xres; x++)
+ {
+ const int index = x + y * xres + z * xres*yres;
+
+ // backtrace
+ float xTrace = x - dt * velx[index];
+ float yTrace = y - dt * vely[index];
+ float zTrace = z - dt * velz[index];
+
+ // clamp backtrace to grid boundaries
+ if (xTrace < 0.5) xTrace = 0.5;
+ if (xTrace > xres - 1.5) xTrace = xres - 1.5;
+ if (yTrace < 0.5) yTrace = 0.5;
+ if (yTrace > yres - 1.5) yTrace = yres - 1.5;
+ if (zTrace < 0.5) zTrace = 0.5;
+ if (zTrace > zres - 1.5) zTrace = zres - 1.5;
+
+ // locate neighbors to interpolate
+ const int x0 = (int)xTrace;
+ const int x1 = x0 + 1;
+ const int y0 = (int)yTrace;
+ const int y1 = y0 + 1;
+ const int z0 = (int)zTrace;
+ const int z1 = z0 + 1;
+
+ // get interpolation weights
+ const float s1 = xTrace - x0;
+ const float s0 = 1.0f - s1;
+ const float t1 = yTrace - y0;
+ const float t0 = 1.0f - t1;
+ const float u1 = zTrace - z0;
+ const float u0 = 1.0f - u1;
+
+ const int i000 = x0 + y0 * xres + z0 * slabSize;
+ const int i010 = x0 + y1 * xres + z0 * slabSize;
+ const int i100 = x1 + y0 * xres + z0 * slabSize;
+ const int i110 = x1 + y1 * xres + z0 * slabSize;
+ const int i001 = x0 + y0 * xres + z1 * slabSize;
+ const int i011 = x0 + y1 * xres + z1 * slabSize;
+ const int i101 = x1 + y0 * xres + z1 * slabSize;
+ const int i111 = x1 + y1 * xres + z1 * slabSize;
+
+ // interpolate
+ // (indices could be computed once)
+ newField[index] = u0 * (s0 * (t0 * oldField[i000] +
+ t1 * oldField[i010]) +
+ s1 * (t0 * oldField[i100] +
+ t1 * oldField[i110])) +
+ u1 * (s0 * (t0 * oldField[i001] +
+ t1 * oldField[i011]) +
+ s1 * (t0 * oldField[i101] +
+ t1 * oldField[i111]));
+ }
+}
+
+/////////////////////////////////////////////////////////////////////
+// advect field with the maccormack method
+//
+// comments are the pseudocode from selle's paper
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::advectFieldMacCormack(const float dt, const float* xVelocity, const float* yVelocity, const float* zVelocity,
+ float* oldField, float* newField, float* temp1, float* temp2, Vec3Int res, const unsigned char* obstacles)
+{
+ float* phiHatN = temp1;
+ float* phiHatN1 = temp2;
+ const int sx= res[0];
+ const int sy= res[1];
+ const int sz= res[2];
+
+ for (int x = 0; x < sx * sy * sz; x++)
+ phiHatN[x] = phiHatN1[x] = oldField[x];
+
+ float*& phiN = oldField;
+ float*& phiN1 = newField;
+
+ // phiHatN1 = A(phiN)
+ advectFieldSemiLagrange( dt, xVelocity, yVelocity, zVelocity, phiN, phiHatN1, res);
+
+ // phiHatN = A^R(phiHatN1)
+ advectFieldSemiLagrange( -1.0*dt, xVelocity, yVelocity, zVelocity, phiHatN1, phiHatN, res);
+
+ // phiN1 = phiHatN1 + (phiN - phiHatN) / 2
+ const int border = 0;
+ for (int z = border; z < sz-border; z++)
+ for (int y = border; y < sy-border; y++)
+ for (int x = border; x < sx-border; x++) {
+ int index = x + y * sx + z * sx*sy;
+ phiN1[index] = phiHatN1[index] + (phiN[index] - phiHatN[index]) * 0.50f;
+ //phiN1[index] = phiHatN1[index]; // debug, correction off
+ }
+ copyBorderX(phiN1, res);
+ copyBorderY(phiN1, res);
+ copyBorderZ(phiN1, res);
+
+ // clamp any newly created extrema
+ clampExtrema(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res);
+
+ // if the error estimate was bad, revert to first order
+ clampOutsideRays(dt, xVelocity, yVelocity, zVelocity, oldField, newField, res, obstacles, phiHatN1);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Clamp the extrema generated by the BFECC error correction
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::clampExtrema(const float dt, const float* velx, const float* vely, const float* velz,
+ float* oldField, float* newField, Vec3Int res)
+{
+ const int xres= res[0];
+ const int yres= res[1];
+ const int zres= res[2];
+ const int slabSize = res[0] * res[1];
+ for (int z = 1; z < zres-1; z++)
+ for (int y = 1; y < yres-1; y++)
+ for (int x = 1; x < xres-1; x++)
+ {
+ const int index = x + y * xres+ z * xres*yres;
+ // backtrace
+ float xTrace = x - dt * velx[index];
+ float yTrace = y - dt * vely[index];
+ float zTrace = z - dt * velz[index];
+
+ // clamp backtrace to grid boundaries
+ if (xTrace < 0.5) xTrace = 0.5;
+ if (xTrace > xres - 1.5) xTrace = xres - 1.5;
+ if (yTrace < 0.5) yTrace = 0.5;
+ if (yTrace > yres - 1.5) yTrace = yres - 1.5;
+ if (zTrace < 0.5) zTrace = 0.5;
+ if (zTrace > zres - 1.5) zTrace = zres - 1.5;
+
+ // locate neighbors to interpolate
+ const int x0 = (int)xTrace;
+ const int x1 = x0 + 1;
+ const int y0 = (int)yTrace;
+ const int y1 = y0 + 1;
+ const int z0 = (int)zTrace;
+ const int z1 = z0 + 1;
+
+ const int i000 = x0 + y0 * xres + z0 * slabSize;
+ const int i010 = x0 + y1 * xres + z0 * slabSize;
+ const int i100 = x1 + y0 * xres + z0 * slabSize;
+ const int i110 = x1 + y1 * xres + z0 * slabSize;
+ const int i001 = x0 + y0 * xres + z1 * slabSize;
+ const int i011 = x0 + y1 * xres + z1 * slabSize;
+ const int i101 = x1 + y0 * xres + z1 * slabSize;
+ const int i111 = x1 + y1 * xres + z1 * slabSize;
+
+ float minField = oldField[i000];
+ float maxField = oldField[i000];
+
+ minField = (oldField[i010] < minField) ? oldField[i010] : minField;
+ maxField = (oldField[i010] > maxField) ? oldField[i010] : maxField;
+
+ minField = (oldField[i100] < minField) ? oldField[i100] : minField;
+ maxField = (oldField[i100] > maxField) ? oldField[i100] : maxField;
+
+ minField = (oldField[i110] < minField) ? oldField[i110] : minField;
+ maxField = (oldField[i110] > maxField) ? oldField[i110] : maxField;
+
+ minField = (oldField[i001] < minField) ? oldField[i001] : minField;
+ maxField = (oldField[i001] > maxField) ? oldField[i001] : maxField;
+
+ minField = (oldField[i011] < minField) ? oldField[i011] : minField;
+ maxField = (oldField[i011] > maxField) ? oldField[i011] : maxField;
+
+ minField = (oldField[i101] < minField) ? oldField[i101] : minField;
+ maxField = (oldField[i101] > maxField) ? oldField[i101] : maxField;
+
+ minField = (oldField[i111] < minField) ? oldField[i111] : minField;
+ maxField = (oldField[i111] > maxField) ? oldField[i111] : maxField;
+
+ newField[index] = (newField[index] > maxField) ? maxField : newField[index];
+ newField[index] = (newField[index] < minField) ? minField : newField[index];
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// Reverts any backtraces that go into boundaries back to first
+// order -- in this case the error correction term was totally
+// incorrect
+//////////////////////////////////////////////////////////////////////
+void FLUID_3D::clampOutsideRays(const float dt, const float* velx, const float* vely, const float* velz,
+ float* oldField, float* newField, Vec3Int res, const unsigned char* obstacles, const float *oldAdvection)
+{
+ const int sx= res[0];
+ const int sy= res[1];
+ const int sz= res[2];
+ const int slabSize = res[0] * res[1];
+
+ for (int z = 1; z < sz-1; z++)
+ for (int y = 1; y < sy-1; y++)
+ for (int x = 1; x < sx-1; x++)
+ {
+ const int index = x + y * sx+ z * slabSize;
+ // backtrace
+ float xBackward = x + dt * velx[index];
+ float yBackward = y + dt * vely[index];
+ float zBackward = z + dt * velz[index];
+ float xTrace = x - dt * velx[index];
+ float yTrace = y - dt * vely[index];
+ float zTrace = z - dt * velz[index];
+
+ // see if it goes outside the boundaries
+ bool hasObstacle =
+ (zTrace < 1.0f) || (zTrace > sz - 2.0f) ||
+ (yTrace < 1.0f) || (yTrace > sy - 2.0f) ||
+ (xTrace < 1.0f) || (xTrace > sx - 2.0f) ||
+ (zBackward < 1.0f) || (zBackward > sz - 2.0f) ||
+ (yBackward < 1.0f) || (yBackward > sy - 2.0f) ||
+ (xBackward < 1.0f) || (xBackward > sx - 2.0f);
+ // reuse old advection instead of doing another one...
+ if(hasObstacle) { newField[index] = oldAdvection[index]; continue; }
+
+ // clamp to prevent an out of bounds access when looking into
+ // the _obstacles array
+ zTrace = (zTrace < 0.5f) ? 0.5f : zTrace;
+ zTrace = (zTrace > sz - 1.5f) ? sz - 1.5f : zTrace;
+ yTrace = (yTrace < 0.5f) ? 0.5f : yTrace;
+ yTrace = (yTrace > sy - 1.5f) ? sy - 1.5f : yTrace;
+ xTrace = (xTrace < 0.5f) ? 0.5f : xTrace;
+ xTrace = (xTrace > sx - 1.5f) ? sx - 1.5f : xTrace;
+
+ // locate neighbors to interpolate,
+ // do backward first since we will use the forward indices if a
+ // reversion is actually necessary
+ zBackward = (zBackward < 0.5f) ? 0.5f : zBackward;
+ zBackward = (zBackward > sz - 1.5f) ? sz - 1.5f : zBackward;
+ yBackward = (yBackward < 0.5f) ? 0.5f : yBackward;
+ yBackward = (yBackward > sy - 1.5f) ? sy - 1.5f : yBackward;
+ xBackward = (xBackward < 0.5f) ? 0.5f : xBackward;
+ xBackward = (xBackward > sx - 1.5f) ? sx - 1.5f : xBackward;
+
+ int x0 = (int)xBackward;
+ int x1 = x0 + 1;
+ int y0 = (int)yBackward;
+ int y1 = y0 + 1;
+ int z0 = (int)zBackward;
+ int z1 = z0 + 1;
+ if(obstacles && !hasObstacle) {
+ hasObstacle = hasObstacle ||
+ obstacles[x0 + y0 * sx + z0*slabSize] ||
+ obstacles[x0 + y1 * sx + z0*slabSize] ||
+ obstacles[x1 + y0 * sx + z0*slabSize] ||
+ obstacles[x1 + y1 * sx + z0*slabSize] ||
+ obstacles[x0 + y0 * sx + z1*slabSize] ||
+ obstacles[x0 + y1 * sx + z1*slabSize] ||
+ obstacles[x1 + y0 * sx + z1*slabSize] ||
+ obstacles[x1 + y1 * sx + z1*slabSize] ;
+ }
+ // reuse old advection instead of doing another one...
+ if(hasObstacle) { newField[index] = oldAdvection[index]; continue; }
+
+ x0 = (int)xTrace;
+ x1 = x0 + 1;
+ y0 = (int)yTrace;
+ y1 = y0 + 1;
+ z0 = (int)zTrace;
+ z1 = z0 + 1;
+ if(obstacles && !hasObstacle) {
+ hasObstacle = hasObstacle ||
+ obstacles[x0 + y0 * sx + z0*slabSize] ||
+ obstacles[x0 + y1 * sx + z0*slabSize] ||
+ obstacles[x1 + y0 * sx + z0*slabSize] ||
+ obstacles[x1 + y1 * sx + z0*slabSize] ||
+ obstacles[x0 + y0 * sx + z1*slabSize] ||
+ obstacles[x0 + y1 * sx + z1*slabSize] ||
+ obstacles[x1 + y0 * sx + z1*slabSize] ||
+ obstacles[x1 + y1 * sx + z1*slabSize] ;
+ } // obstacle array
+ // reuse old advection instead of doing another one...
+ if(hasObstacle) { newField[index] = oldAdvection[index]; continue; }
+
+ // see if either the forward or backward ray went into
+ // a boundary
+ if (hasObstacle) {
+ // get interpolation weights
+ float s1 = xTrace - x0;
+ float s0 = 1.0f - s1;
+ float t1 = yTrace - y0;
+ float t0 = 1.0f - t1;
+ float u1 = zTrace - z0;
+ float u0 = 1.0f - u1;
+
+ const int i000 = x0 + y0 * sx + z0 * slabSize;
+ const int i010 = x0 + y1 * sx + z0 * slabSize;
+ const int i100 = x1 + y0 * sx + z0 * slabSize;
+ const int i110 = x1 + y1 * sx + z0 * slabSize;
+ const int i001 = x0 + y0 * sx + z1 * slabSize;
+ const int i011 = x0 + y1 * sx + z1 * slabSize;
+ const int i101 = x1 + y0 * sx + z1 * slabSize;
+ const int i111 = x1 + y1 * sx + z1 * slabSize;
+
+ // interpolate, (indices could be computed once)
+ newField[index] = u0 * (s0 * (
+ t0 * oldField[i000] +
+ t1 * oldField[i010]) +
+ s1 * (t0 * oldField[i100] +
+ t1 * oldField[i110])) +
+ u1 * (s0 * (t0 * oldField[i001] +
+ t1 * oldField[i011]) +
+ s1 * (t0 * oldField[i101] +
+ t1 * oldField[i111]));
+ }
+ } // xyz
+}
+
diff --git a/intern/smoke/intern/IMAGE.h b/intern/smoke/intern/IMAGE.h
new file mode 100644
index 00000000000..a57f164509e
--- /dev/null
+++ b/intern/smoke/intern/IMAGE.h
@@ -0,0 +1,277 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+//////////////////////////////////////////////////////////////////////
+//
+#ifndef IMAGE_H
+#define IMAGE_H
+
+#include <stdlib.h>
+#include <string>
+#include <fstream>
+#include <sstream>
+#include <zlib.h>
+
+//////////////////////////////////////////////////////////////////////
+// NT helper functions
+//////////////////////////////////////////////////////////////////////
+template < class T > inline T ABS( T a ) {
+ return (0 < a) ? a : -a ;
+}
+
+template < class T > inline void SWAP_POINTERS( T &a, T &b ) {
+ T temp = a;
+ a = b;
+ b = temp;
+}
+
+template < class T > inline void CLAMP( T &a, T b=0., T c=1.) {
+ if(a<b) { a=b; return; }
+ if(a>c) { a=c; return; }
+}
+
+template < class T > inline T MIN( T a, T b) {
+ return (a < b) ? a : b;
+}
+
+template < class T > inline T MAX( T a, T b) {
+ return (a > b) ? a : b;
+}
+
+template < class T > inline T MAX3( T a, T b, T c) {
+ T max = (a > b) ? a : b;
+ max = (max > c) ? max : c;
+ return max;
+}
+
+template < class T > inline float MAX3V( T vec) {
+ float max = (vec[0] > vec[1]) ? vec[0] : vec[1];
+ max = (max > vec[2]) ? max : vec[2];
+ return max;
+}
+
+template < class T > inline float MIN3V( T vec) {
+ float min = (vec[0] < vec[1]) ? vec[0] : vec[1];
+ min = (min < vec[2]) ? min : vec[2];
+ return min;
+}
+
+//////////////////////////////////////////////////////////////////////
+// PNG, POV-Ray, and PBRT output functions
+//////////////////////////////////////////////////////////////////////
+#include <png.h>
+
+namespace IMAGE {
+ /*
+ static int writePng(const char *fileName, unsigned char **rowsp, int w, int h)
+ {
+ // defaults
+ const int colortype = PNG_COLOR_TYPE_RGBA;
+ const int bitdepth = 8;
+ png_structp png_ptr = NULL;
+ png_infop info_ptr = NULL;
+ png_bytep *rows = rowsp;
+
+ FILE *fp = NULL;
+ std::string doing = "open for writing";
+ if (!(fp = fopen(fileName, "wb"))) goto fail;
+
+ if(!png_ptr) {
+ doing = "create png write struct";
+ if (!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL))) goto fail;
+ }
+ if(!info_ptr) {
+ doing = "create png info struct";
+ if (!(info_ptr = png_create_info_struct(png_ptr))) goto fail;
+ }
+
+ if (setjmp(png_jmpbuf(png_ptr))) goto fail;
+ doing = "init IO";
+ png_init_io(png_ptr, fp);
+ doing = "write header";
+ png_set_IHDR(png_ptr, info_ptr, w, h, bitdepth, colortype, PNG_INTERLACE_NONE,
+ PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
+ doing = "write info";
+ png_write_info(png_ptr, info_ptr);
+ doing = "write image";
+ png_write_image(png_ptr, rows);
+ doing = "write end";
+ png_write_end(png_ptr, NULL);
+ doing = "write destroy structs";
+ png_destroy_write_struct(&png_ptr, &info_ptr);
+
+ fclose( fp );
+ return 0;
+
+ fail:
+ std::cerr << "writePng: could not "<<doing<<" !\n";
+ if(fp) fclose( fp );
+ if(png_ptr || info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
+ return -1;
+ }
+ */
+
+ /////////////////////////////////////////////////////////////////////////////////
+ // write a numbered PNG file out, padded with zeros up to three zeros
+ /////////////////////////////////////////////////////////////////////////////////
+ /*
+ static void dumpNumberedPNG(int counter, std::string prefix, float* field, int xRes, int yRes)
+ {
+ char buffer[256];
+ sprintf(buffer,"%04i", counter);
+ std::string number = std::string(buffer);
+
+ unsigned char pngbuf[xRes*yRes*4];
+ unsigned char *rows[yRes];
+ float *pfield = field;
+ for (int j=0; j<yRes; j++) {
+ for (int i=0; i<xRes; i++) {
+ float val = *pfield;
+ if(val>1.) val=1.;
+ if(val<0.) val=0.;
+ pngbuf[(j*xRes+i)*4+0] = (unsigned char)(val*255.);
+ pngbuf[(j*xRes+i)*4+1] = (unsigned char)(val*255.);
+ pngbuf[(j*xRes+i)*4+2] = (unsigned char)(val*255.);
+ pfield++;
+ pngbuf[(j*xRes+i)*4+3] = 255;
+ }
+ rows[j] = &pngbuf[(yRes-j-1)*xRes*4];
+ }
+ std::string filenamePNG = prefix + number + std::string(".png");
+ writePng(filenamePNG.c_str(), rows, xRes, yRes, false);
+ printf("Writing %s\n", filenamePNG.c_str());
+
+ }
+*/
+ /////////////////////////////////////////////////////////////////////////////////
+ // export pbrt volumegrid geometry object
+ /////////////////////////////////////////////////////////////////////////////////
+ /*
+ static void dumpPBRT(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes)
+ {
+ char buffer[256];
+ sprintf(buffer,"%04i", counter);
+ std::string number = std::string(buffer);
+
+ std::string filenamePbrt = prefix + number + std::string(".pbrt.gz");
+ printf("Writing PBRT %s\n", filenamePbrt.c_str());
+
+ float *field = new float[xRes*yRes*zRes];
+ // normalize values
+ float maxDensVal = ABS(fieldOrg[0]);
+ float targetNorm = 0.5;
+ for (int i = 0; i < xRes * yRes * zRes; i++) {
+ if(ABS(fieldOrg[i])>maxDensVal) maxDensVal = ABS(fieldOrg[i]);
+ field[i] = 0.;
+ }
+ if(maxDensVal>0.) {
+ for (int i = 0; i < xRes * yRes * zRes; i++) {
+ field[i] = ABS(fieldOrg[i]) / maxDensVal * targetNorm;
+ }
+ }
+
+ std::fstream fout;
+ fout.open(filenamePbrt.c_str(), std::ios::out);
+
+ int maxRes = (xRes > yRes) ? xRes : yRes;
+ maxRes = (maxRes > zRes) ? maxRes : zRes;
+
+ const float xSize = 1.0 / (float)maxRes * (float)xRes;
+ const float ySize = 1.0 / (float)maxRes * (float)yRes;
+ const float zSize = 1.0 / (float)maxRes * (float)zRes;
+
+ gzFile file;
+ file = gzopen(filenamePbrt.c_str(), "wb1");
+ if (file == NULL) {
+ std::cerr << " Couldn't write file " << filenamePbrt << "!!!" << std::endl;
+ return;
+ }
+
+ // dimensions
+ gzprintf(file, "Volume \"volumegrid\" \n");
+ gzprintf(file, " \"integer nx\" %i\n", xRes);
+ gzprintf(file, " \"integer ny\" %i\n", yRes);
+ gzprintf(file, " \"integer nz\" %i\n", zRes);
+ gzprintf(file, " \"point p0\" [ 0.0 0.0 0.0 ] \"point p1\" [%f %f %f ] \n", xSize, ySize, zSize);
+ gzprintf(file, " \"float density\" [ \n");
+ for (int i = 0; i < xRes * yRes * zRes; i++)
+ gzprintf(file, "%f ", field[i]);
+ gzprintf(file, "] \n \n");
+
+ gzclose(file);
+ delete[] field;
+ }
+ */
+
+ /////////////////////////////////////////////////////////////////////////////////
+ // 3D df3 export
+ /////////////////////////////////////////////////////////////////////////////////
+/*
+ static void dumpDF3(int counter, std::string prefix, float* fieldOrg, int xRes, int yRes, int zRes)
+ {
+ char buffer[256];
+
+ // do deferred copying to final directory, better for network directories
+ sprintf(buffer,"%04i", counter);
+ std::string number = std::string(buffer);
+ std::string filenameDf3 = prefix + number + std::string(".df3.gz");
+ printf("Writing DF3 %s\n", filenameDf3.c_str());
+
+ gzFile file;
+ file = gzopen(filenameDf3.c_str(), "wb1");
+ if (file == NULL) {
+ std::cerr << " Couldn't write file " << filenameDf3 << "!!!" << std::endl;
+ return;
+ }
+
+ // dimensions
+ const int byteSize = 2;
+ const unsigned short int onx=xRes,ony=yRes,onz=zRes;
+ unsigned short int nx,ny,nz;
+ nx = onx >> 8;
+ ny = ony >> 8;
+ nz = onz >> 8;
+ nx += (onx << 8);
+ ny += (ony << 8);
+ nz += (onz << 8);
+ gzwrite(file, (void*)&nx, sizeof(short));
+ gzwrite(file, (void*)&ny, sizeof(short));
+ gzwrite(file, (void*)&nz, sizeof(short));
+ const int nitems = onx*ony*onz;
+ const float mul = (float)( (1<<(8*byteSize))-1);
+
+ unsigned short int *buf = new unsigned short int[nitems];
+ for (int k = 0; k < onz; k++)
+ for (int j = 0; j < ony; j++)
+ for (int i = 0; i < onx; i++) {
+ float val = fieldOrg[k*(onx*ony)+j*onx+i] ;
+ CLAMP(val);
+ buf[k*(onx*ony)+j*onx+i] = (short int)(val*mul);
+ }
+ gzwrite(file, (void*)buf, sizeof(unsigned short int)* nitems);
+
+ gzclose(file);
+ delete[] buf;
+ }
+ */
+
+};
+
+
+#endif
+
diff --git a/intern/smoke/intern/INTERPOLATE.h b/intern/smoke/intern/INTERPOLATE.h
new file mode 100644
index 00000000000..6800c3b84b0
--- /dev/null
+++ b/intern/smoke/intern/INTERPOLATE.h
@@ -0,0 +1,227 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+//////////////////////////////////////////////////////////////////////
+#ifndef INTERPOLATE_H
+#define INTERPOLATE_H
+
+#include <iostream>
+#include <VEC3.h>
+
+namespace INTERPOLATE {
+
+//////////////////////////////////////////////////////////////////////
+// linear interpolators
+//////////////////////////////////////////////////////////////////////
+static inline float lerp(float t, float a, float b) {
+ return ( a + t * (b - a) );
+}
+
+static inline float lerp(float* field, float x, float y, int res) {
+ // clamp backtrace to grid boundaries
+ if (x < 0.5f) x = 0.5f;
+ if (x > res - 1.5f) x = res - 1.5f;
+ if (y < 0.5f) y = 0.5f;
+ if (y > res - 1.5f) y = res - 1.5f;
+
+ const int x0 = (int)x;
+ const int y0 = (int)y;
+ x -= x0;
+ y -= y0;
+ float d00, d10, d01, d11;
+
+ // lerp the velocities
+ d00 = field[x0 + y0 * res];
+ d10 = field[(x0 + 1) + y0 * res];
+ d01 = field[x0 + (y0 + 1) * res];
+ d11 = field[(x0 + 1) + (y0 + 1) * res];
+ return lerp(y, lerp(x, d00, d10),
+ lerp(x, d01, d11));
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// 3d linear interpolation
+//////////////////////////////////////////////////////////////////////////////////////////
+static inline float lerp3d(float* field, float x, float y, float z, int xres, int yres, int zres) {
+ // clamp pos to grid boundaries
+ if (x < 0.5) x = 0.5;
+ if (x > xres - 1.5) x = xres - 1.5;
+ if (y < 0.5) y = 0.5;
+ if (y > yres - 1.5) y = yres - 1.5;
+ if (z < 0.5) z = 0.5;
+ if (z > zres - 1.5) z = zres - 1.5;
+
+ // locate neighbors to interpolate
+ const int x0 = (int)x;
+ const int x1 = x0 + 1;
+ const int y0 = (int)y;
+ const int y1 = y0 + 1;
+ const int z0 = (int)z;
+ const int z1 = z0 + 1;
+
+ // get interpolation weights
+ const float s1 = x - (float)x0;
+ const float s0 = 1.0f - s1;
+ const float t1 = y - (float)y0;
+ const float t0 = 1.0f - t1;
+ const float u1 = z - (float)z0;
+ const float u0 = 1.0f - u1;
+
+ const int slabSize = xres*yres;
+ const int i000 = x0 + y0 * xres + z0 * slabSize;
+ const int i010 = x0 + y1 * xres + z0 * slabSize;
+ const int i100 = x1 + y0 * xres + z0 * slabSize;
+ const int i110 = x1 + y1 * xres + z0 * slabSize;
+ const int i001 = x0 + y0 * xres + z1 * slabSize;
+ const int i011 = x0 + y1 * xres + z1 * slabSize;
+ const int i101 = x1 + y0 * xres + z1 * slabSize;
+ const int i111 = x1 + y1 * xres + z1 * slabSize;
+
+ // interpolate (indices could be computed once)
+ return ( u0 * (s0 * (t0 * field[i000] +
+ t1 * field[i010]) +
+ s1 * (t0 * field[i100] +
+ t1 * field[i110])) +
+ u1 * (s0 * (t0 * field[i001] +
+ t1 * field[i011]) +
+ s1 * (t0 * field[i101] +
+ t1 * field[i111])) );
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// convert field entries of type T to floats, then interpolate
+//////////////////////////////////////////////////////////////////////////////////////////
+template <class T>
+static inline float lerp3dToFloat(T* field1,
+ float x, float y, float z, int xres, int yres, int zres) {
+ // clamp pos to grid boundaries
+ if (x < 0.5) x = 0.5;
+ if (x > xres - 1.5) x = xres - 1.5;
+ if (y < 0.5) y = 0.5;
+ if (y > yres - 1.5) y = yres - 1.5;
+ if (z < 0.5) z = 0.5;
+ if (z > zres - 1.5) z = zres - 1.5;
+
+ // locate neighbors to interpolate
+ const int x0 = (int)x;
+ const int x1 = x0 + 1;
+ const int y0 = (int)y;
+ const int y1 = y0 + 1;
+ const int z0 = (int)z;
+ const int z1 = z0 + 1;
+
+ // get interpolation weights
+ const float s1 = x - (float)x0;
+ const float s0 = 1.0f - s1;
+ const float t1 = y - (float)y0;
+ const float t0 = 1.0f - t1;
+ const float u1 = z - (float)z0;
+ const float u0 = 1.0f - u1;
+
+ const int slabSize = xres*yres;
+ const int i000 = x0 + y0 * xres + z0 * slabSize;
+ const int i010 = x0 + y1 * xres + z0 * slabSize;
+ const int i100 = x1 + y0 * xres + z0 * slabSize;
+ const int i110 = x1 + y1 * xres + z0 * slabSize;
+ const int i001 = x0 + y0 * xres + z1 * slabSize;
+ const int i011 = x0 + y1 * xres + z1 * slabSize;
+ const int i101 = x1 + y0 * xres + z1 * slabSize;
+ const int i111 = x1 + y1 * xres + z1 * slabSize;
+
+ // interpolate (indices could be computed once)
+ return (float)(
+ ( u0 * (s0 * (t0 * (float)field1[i000] +
+ t1 * (float)field1[i010]) +
+ s1 * (t0 * (float)field1[i100] +
+ t1 * (float)field1[i110])) +
+ u1 * (s0 * (t0 * (float)field1[i001] +
+ t1 * (float)field1[i011]) +
+ s1 * (t0 * (float)field1[i101] +
+ t1 * (float)field1[i111])) ) );
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// interpolate a vector from 3 fields
+//////////////////////////////////////////////////////////////////////////////////////////
+static inline Vec3 lerp3dVec(float* field1, float* field2, float* field3,
+ float x, float y, float z, int xres, int yres, int zres) {
+ // clamp pos to grid boundaries
+ if (x < 0.5) x = 0.5;
+ if (x > xres - 1.5) x = xres - 1.5;
+ if (y < 0.5) y = 0.5;
+ if (y > yres - 1.5) y = yres - 1.5;
+ if (z < 0.5) z = 0.5;
+ if (z > zres - 1.5) z = zres - 1.5;
+
+ // locate neighbors to interpolate
+ const int x0 = (int)x;
+ const int x1 = x0 + 1;
+ const int y0 = (int)y;
+ const int y1 = y0 + 1;
+ const int z0 = (int)z;
+ const int z1 = z0 + 1;
+
+ // get interpolation weights
+ const float s1 = x - (float)x0;
+ const float s0 = 1.0f - s1;
+ const float t1 = y - (float)y0;
+ const float t0 = 1.0f - t1;
+ const float u1 = z - (float)z0;
+ const float u0 = 1.0f - u1;
+
+ const int slabSize = xres*yres;
+ const int i000 = x0 + y0 * xres + z0 * slabSize;
+ const int i010 = x0 + y1 * xres + z0 * slabSize;
+ const int i100 = x1 + y0 * xres + z0 * slabSize;
+ const int i110 = x1 + y1 * xres + z0 * slabSize;
+ const int i001 = x0 + y0 * xres + z1 * slabSize;
+ const int i011 = x0 + y1 * xres + z1 * slabSize;
+ const int i101 = x1 + y0 * xres + z1 * slabSize;
+ const int i111 = x1 + y1 * xres + z1 * slabSize;
+
+ // interpolate (indices could be computed once)
+ return Vec3(
+ ( u0 * (s0 * (t0 * field1[i000] +
+ t1 * field1[i010]) +
+ s1 * (t0 * field1[i100] +
+ t1 * field1[i110])) +
+ u1 * (s0 * (t0 * field1[i001] +
+ t1 * field1[i011]) +
+ s1 * (t0 * field1[i101] +
+ t1 * field1[i111])) ) ,
+ ( u0 * (s0 * (t0 * field2[i000] +
+ t1 * field2[i010]) +
+ s1 * (t0 * field2[i100] +
+ t1 * field2[i110])) +
+ u1 * (s0 * (t0 * field2[i001] +
+ t1 * field2[i011]) +
+ s1 * (t0 * field2[i101] +
+ t1 * field2[i111])) ) ,
+ ( u0 * (s0 * (t0 * field3[i000] +
+ t1 * field3[i010]) +
+ s1 * (t0 * field3[i100] +
+ t1 * field3[i110])) +
+ u1 * (s0 * (t0 * field3[i001] +
+ t1 * field3[i011]) +
+ s1 * (t0 * field3[i101] +
+ t1 * field3[i111])) )
+ );
+}
+
+};
+#endif
diff --git a/intern/smoke/intern/LICENSE.txt b/intern/smoke/intern/LICENSE.txt
new file mode 100644
index 00000000000..94a9ed024d3
--- /dev/null
+++ b/intern/smoke/intern/LICENSE.txt
@@ -0,0 +1,674 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+ The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works. By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users. We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors. 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
+them 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 prevent others from denying you
+these rights or asking you to surrender the rights. Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received. 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.
+
+ Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+ For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software. For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+ Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so. This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software. The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable. Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products. If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+ Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary. To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ TERMS AND CONDITIONS
+
+ 0. Definitions.
+
+ "This License" refers to version 3 of the GNU General Public License.
+
+ "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+ "The Program" refers to any copyrightable work licensed under this
+License. Each licensee is addressed as "you". "Licensees" and
+"recipients" may be individuals or organizations.
+
+ To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy. The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+ A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+ To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy. Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+ To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies. Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+ An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License. If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+ 1. Source Code.
+
+ The "source code" for a work means the preferred form of the work
+for making modifications to it. "Object code" means any non-source
+form of a work.
+
+ A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+ The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form. A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+ The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities. However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work. For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+ The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+ The Corresponding Source for a work in source code form is that
+same work.
+
+ 2. Basic Permissions.
+
+ All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met. This License explicitly affirms your unlimited
+permission to run the unmodified Program. The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work. This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+ You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force. You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright. Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+ Conveying under any other circumstances is permitted solely under
+the conditions stated below. Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+ No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+ When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+ 4. Conveying Verbatim Copies.
+
+ You may convey 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;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+ You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+ 5. Conveying Modified Source Versions.
+
+ You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+ a) The work must carry prominent notices stating that you modified
+ it, and giving a relevant date.
+
+ b) The work must carry prominent notices stating that it is
+ released under this License and any conditions added under section
+ 7. This requirement modifies the requirement in section 4 to
+ "keep intact all notices".
+
+ c) You must license the entire work, as a whole, under this
+ License to anyone who comes into possession of a copy. This
+ License will therefore apply, along with any applicable section 7
+ additional terms, to the whole of the work, and all its parts,
+ regardless of how they are packaged. This License gives no
+ permission to license the work in any other way, but it does not
+ invalidate such permission if you have separately received it.
+
+ d) If the work has interactive user interfaces, each must display
+ Appropriate Legal Notices; however, if the Program has interactive
+ interfaces that do not display Appropriate Legal Notices, your
+ work need not make them do so.
+
+ A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit. Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+ 6. Conveying Non-Source Forms.
+
+ You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+ a) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by the
+ Corresponding Source fixed on a durable physical medium
+ customarily used for software interchange.
+
+ b) Convey the object code in, or embodied in, a physical product
+ (including a physical distribution medium), accompanied by a
+ written offer, valid for at least three years and valid for as
+ long as you offer spare parts or customer support for that product
+ model, to give anyone who possesses the object code either (1) a
+ copy of the Corresponding Source for all the software in the
+ product that is covered by this License, on a durable physical
+ medium customarily used for software interchange, for a price no
+ more than your reasonable cost of physically performing this
+ conveying of source, or (2) access to copy the
+ Corresponding Source from a network server at no charge.
+
+ c) Convey individual copies of the object code with a copy of the
+ written offer to provide the Corresponding Source. This
+ alternative is allowed only occasionally and noncommercially, and
+ only if you received the object code with such an offer, in accord
+ with subsection 6b.
+
+ d) Convey the object code by offering access from a designated
+ place (gratis or for a charge), and offer equivalent access to the
+ Corresponding Source in the same way through the same place at no
+ further charge. You need not require recipients to copy the
+ Corresponding Source along with the object code. If the place to
+ copy the object code is a network server, the Corresponding Source
+ may be on a different server (operated by you or a third party)
+ that supports equivalent copying facilities, provided you maintain
+ clear directions next to the object code saying where to find the
+ Corresponding Source. Regardless of what server hosts the
+ Corresponding Source, you remain obligated to ensure that it is
+ available for as long as needed to satisfy these requirements.
+
+ e) Convey the object code using peer-to-peer transmission, provided
+ you inform other peers where the object code and Corresponding
+ Source of the work are being offered to the general public at no
+ charge under subsection 6d.
+
+ A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+ A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling. In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage. For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product. A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+ "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source. The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+ If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information. But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+ The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed. Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+ Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+ 7. Additional Terms.
+
+ "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law. If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+ When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it. (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.) You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+ Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+ a) Disclaiming warranty or limiting liability differently from the
+ terms of sections 15 and 16 of this License; or
+
+ b) Requiring preservation of specified reasonable legal notices or
+ author attributions in that material or in the Appropriate Legal
+ Notices displayed by works containing it; or
+
+ c) Prohibiting misrepresentation of the origin of that material, or
+ requiring that modified versions of such material be marked in
+ reasonable ways as different from the original version; or
+
+ d) Limiting the use for publicity purposes of names of licensors or
+ authors of the material; or
+
+ e) Declining to grant rights under trademark law for use of some
+ trade names, trademarks, or service marks; or
+
+ f) Requiring indemnification of licensors and authors of that
+ material by anyone who conveys the material (or modified versions of
+ it) with contractual assumptions of liability to the recipient, for
+ any liability that these contractual assumptions directly impose on
+ those licensors and authors.
+
+ All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10. If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term. If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+ If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+ Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+ 8. Termination.
+
+ You may not propagate or modify a covered work except as expressly
+provided under this License. Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+ However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+ Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+ Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License. If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+ 9. Acceptance Not Required for Having Copies.
+
+ You are not required to accept this License in order to receive or
+run a copy of the Program. Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance. However,
+nothing other than this License grants you permission to propagate or
+modify any covered work. These actions infringe copyright if you do
+not accept this License. Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+ 10. Automatic Licensing of Downstream Recipients.
+
+ Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License. You are not responsible
+for enforcing compliance by third parties with this License.
+
+ An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations. If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+ You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License. For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+ 11. Patents.
+
+ A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based. The
+work thus licensed is called the contributor's "contributor version".
+
+ A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version. For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+ Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+ In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement). To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+ If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients. "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+ If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+ A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License. You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+ Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+ 12. No Surrender of Others' Freedom.
+
+ If 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 convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all. For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+ 13. Use with the GNU Affero General Public License.
+
+ Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work. The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+ 14. Revised Versions of this License.
+
+ The Free Software Foundation may publish revised and/or new versions of
+the GNU 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 that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation. If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+ If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+ Later license versions may give you additional or different
+permissions. However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+ 15. Disclaimer of Warranty.
+
+ 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.
+
+ 16. Limitation of Liability.
+
+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+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.
+
+ 17. Interpretation of Sections 15 and 16.
+
+ If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+ 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
+state 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 3 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, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+ If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+ <program> Copyright (C) <year> <name of author>
+ This program 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, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+ You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+ The GNU 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. But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/intern/smoke/intern/LU_HELPER.h b/intern/smoke/intern/LU_HELPER.h
new file mode 100644
index 00000000000..b3f3c5a1cb4
--- /dev/null
+++ b/intern/smoke/intern/LU_HELPER.h
@@ -0,0 +1,56 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef LU_HELPER_H
+#define LU_HELPER_H
+
+//////////////////////////////////////////////////////////////////////
+// Helper function, compute eigenvalues of 3x3 matrix
+//////////////////////////////////////////////////////////////////////
+
+#include "tnt/jama_lu.h"
+
+//////////////////////////////////////////////////////////////////////
+// LU decomposition of 3x3 non-symmetric matrix
+//////////////////////////////////////////////////////////////////////
+JAMA::LU<float> inline computeLU3x3(
+ float a[3][3])
+{
+ TNT::Array2D<float> A = TNT::Array2D<float>(3,3, &a[0][0]);
+ JAMA::LU<float> jLU= JAMA::LU<float>(A);
+ return jLU;
+}
+
+//////////////////////////////////////////////////////////////////////
+// LU decomposition of 3x3 non-symmetric matrix
+//////////////////////////////////////////////////////////////////////
+void inline solveLU3x3(
+ JAMA::LU<float>& A,
+ float x[3],
+ float b[3])
+{
+ TNT::Array1D<float> jamaB = TNT::Array1D<float>(3, &b[0]);
+ TNT::Array1D<float> jamaX = A.solve(jamaB);
+
+ x[0] = jamaX[0];
+ x[1] = jamaX[1];
+ x[2] = jamaX[2];
+}
+#endif
diff --git a/intern/smoke/intern/MERSENNETWISTER.h b/intern/smoke/intern/MERSENNETWISTER.h
new file mode 100644
index 00000000000..8ad00d8b9c2
--- /dev/null
+++ b/intern/smoke/intern/MERSENNETWISTER.h
@@ -0,0 +1,429 @@
+// MersenneTwister.h
+// Mersenne Twister random number generator -- a C++ class MTRand
+// Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
+// Richard J. Wagner v1.0 15 May 2003 rjwagner@writeme.com
+
+// The Mersenne Twister is an algorithm for generating random numbers. It
+// was designed with consideration of the flaws in various other generators.
+// The period, 2^19937-1, and the order of equidistribution, 623 dimensions,
+// are far greater. The generator is also fast; it avoids multiplication and
+// division, and it benefits from caches and pipelines. For more information
+// see the inventors' web page at http://www.math.keio.ac.jp/~matumoto/emt.html
+
+// Reference
+// M. Matsumoto and T. Nishimura, "Mersenne Twister: A 623-Dimensionally
+// Equidistributed Uniform Pseudo-Random Number Generator", ACM Transactions on
+// Modeling and Computer Simulation, Vol. 8, No. 1, January 1998, pp 3-30.
+
+// Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura,
+// Copyright (C) 2000 - 2003, Richard J. Wagner
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions
+// are met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// 3. The names of its contributors may not be used to endorse or promote
+// products derived from this software without specific prior written
+// permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// The original code included the following notice:
+//
+// When you use this, send an email to: matumoto@math.keio.ac.jp
+// with an appropriate reference to your work.
+//
+// It would be nice to CC: rjwagner@writeme.com and Cokus@math.washington.edu
+// when you write.
+
+#ifndef MERSENNETWISTER_H
+#define MERSENNETWISTER_H
+
+// Not thread safe (unless auto-initialization is avoided and each thread has
+// its own MTRand object)
+
+#include <iostream>
+#include <limits.h>
+#include <stdio.h>
+#include <time.h>
+#include <math.h>
+
+class MTRand {
+// Data
+public:
+ typedef unsigned long uint32; // unsigned integer type, at least 32 bits
+
+ enum { N = 624 }; // length of state vector
+ enum { SAVE = N + 1 }; // length of array for save()
+
+protected:
+ enum { M = 397 }; // period parameter
+
+ uint32 state[N]; // internal state
+ uint32 *pNext; // next value to get from state
+ int left; // number of values left before reload needed
+
+
+//Methods
+public:
+ MTRand( const uint32& oneSeed ); // initialize with a simple uint32
+ MTRand( uint32 *const bigSeed, uint32 const seedLength = N ); // or an array
+ MTRand(); // auto-initialize with /dev/urandom or time() and clock()
+
+ // Do NOT use for CRYPTOGRAPHY without securely hashing several returned
+ // values together, otherwise the generator state can be learned after
+ // reading 624 consecutive values.
+
+ // Access to 32-bit random numbers
+ double rand(); // real number in [0,1]
+ double rand( const double& n ); // real number in [0,n]
+ double randExc(); // real number in [0,1)
+ double randExc( const double& n ); // real number in [0,n)
+ double randDblExc(); // real number in (0,1)
+ double randDblExc( const double& n ); // real number in (0,n)
+ uint32 randInt(); // integer in [0,2^32-1]
+ uint32 randInt( const uint32& n ); // integer in [0,n] for n < 2^32
+ double operator()() { return rand(); } // same as rand()
+
+ // Access to 53-bit random numbers (capacity of IEEE double precision)
+ double rand53(); // real number in [0,1)
+
+ // Access to nonuniform random number distributions
+ double randNorm( const double& mean = 0.0, const double& variance = 1.0 );
+
+ // Re-seeding functions with same behavior as initializers
+ void seed( const uint32 oneSeed );
+ void seed( uint32 *const bigSeed, const uint32 seedLength = N );
+ void seed();
+
+ // Saving and loading generator state
+ void save( uint32* saveArray ) const; // to array of size SAVE
+ void load( uint32 *const loadArray ); // from such array
+ friend std::ostream& operator<<( std::ostream& os, const MTRand& mtrand );
+ friend std::istream& operator>>( std::istream& is, MTRand& mtrand );
+
+protected:
+ void initialize( const uint32 oneSeed );
+ void reload();
+ uint32 hiBit( const uint32& u ) const { return u & 0x80000000UL; }
+ uint32 loBit( const uint32& u ) const { return u & 0x00000001UL; }
+ uint32 loBits( const uint32& u ) const { return u & 0x7fffffffUL; }
+ uint32 mixBits( const uint32& u, const uint32& v ) const
+ { return hiBit(u) | loBits(v); }
+ uint32 twist( const uint32& m, const uint32& s0, const uint32& s1 ) const
+ { return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL); }
+ static uint32 hash( time_t t, clock_t c );
+};
+
+
+inline MTRand::MTRand( const uint32& oneSeed )
+ { seed(oneSeed); }
+
+inline MTRand::MTRand( uint32 *const bigSeed, const uint32 seedLength )
+ { seed(bigSeed,seedLength); }
+
+inline MTRand::MTRand()
+ { seed(); }
+
+inline double MTRand::rand()
+ { return double(randInt()) * (1.0/4294967295.0); }
+
+inline double MTRand::rand( const double& n )
+ { return rand() * n; }
+
+inline double MTRand::randExc()
+ { return double(randInt()) * (1.0/4294967296.0); }
+
+inline double MTRand::randExc( const double& n )
+ { return randExc() * n; }
+
+inline double MTRand::randDblExc()
+ { return ( double(randInt()) + 0.5 ) * (1.0/4294967296.0); }
+
+inline double MTRand::randDblExc( const double& n )
+ { return randDblExc() * n; }
+
+inline double MTRand::rand53()
+{
+ uint32 a = randInt() >> 5, b = randInt() >> 6;
+ return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0); // by Isaku Wada
+}
+
+inline double MTRand::randNorm( const double& mean, const double& variance )
+{
+ // Return a real number from a normal (Gaussian) distribution with given
+ // mean and variance by Box-Muller method
+ double r = sqrt( -2.0 * log( 1.0-randDblExc()) ) * variance;
+ double phi = 2.0 * 3.14159265358979323846264338328 * randExc();
+ return mean + r * cos(phi);
+}
+
+inline MTRand::uint32 MTRand::randInt()
+{
+ // Pull a 32-bit integer from the generator state
+ // Every other access function simply transforms the numbers extracted here
+
+ if( left == 0 ) reload();
+ --left;
+
+ register uint32 s1;
+ s1 = *pNext++;
+ s1 ^= (s1 >> 11);
+ s1 ^= (s1 << 7) & 0x9d2c5680UL;
+ s1 ^= (s1 << 15) & 0xefc60000UL;
+ return ( s1 ^ (s1 >> 18) );
+}
+
+inline MTRand::uint32 MTRand::randInt( const uint32& n )
+{
+ // Find which bits are used in n
+ // Optimized by Magnus Jonsson (magnus@smartelectronix.com)
+ uint32 used = n;
+ used |= used >> 1;
+ used |= used >> 2;
+ used |= used >> 4;
+ used |= used >> 8;
+ used |= used >> 16;
+
+ // Draw numbers until one is found in [0,n]
+ uint32 i;
+ do
+ i = randInt() & used; // toss unused bits to shorten search
+ while( i > n );
+ return i;
+}
+
+
+inline void MTRand::seed( const uint32 oneSeed )
+{
+ // Seed the generator with a simple uint32
+ initialize(oneSeed);
+ reload();
+}
+
+
+inline void MTRand::seed( uint32 *const bigSeed, const uint32 seedLength )
+{
+ // Seed the generator with an array of uint32's
+ // There are 2^19937-1 possible initial states. This function allows
+ // all of those to be accessed by providing at least 19937 bits (with a
+ // default seed length of N = 624 uint32's). Any bits above the lower 32
+ // in each element are discarded.
+ // Just call seed() if you want to get array from /dev/urandom
+ initialize(19650218UL);
+ register int i = 1;
+ register uint32 j = 0;
+ register int k = ( N > seedLength ? N : seedLength );
+ for( ; k; --k )
+ {
+ state[i] =
+ state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
+ state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
+ state[i] &= 0xffffffffUL;
+ ++i; ++j;
+ if( i >= N ) { state[0] = state[N-1]; i = 1; }
+ if( j >= seedLength ) j = 0;
+ }
+ for( k = N - 1; k; --k )
+ {
+ state[i] =
+ state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
+ state[i] -= i;
+ state[i] &= 0xffffffffUL;
+ ++i;
+ if( i >= N ) { state[0] = state[N-1]; i = 1; }
+ }
+ state[0] = 0x80000000UL; // MSB is 1, assuring non-zero initial array
+ reload();
+}
+
+
+inline void MTRand::seed()
+{
+ // seed deterministically to produce reproducible runs
+ seed(123456);
+
+ /*
+ // Seed the generator with an array from /dev/urandom if available
+ // Otherwise use a hash of time() and clock() values
+
+ // First try getting an array from /dev/urandom
+ FILE* urandom = fopen( "/dev/urandom", "rb" );
+ if( urandom )
+ {
+ uint32 bigSeed[N];
+ register uint32 *s = bigSeed;
+ register int i = N;
+ register bool success = true;
+ while( success && i-- )
+ success = fread( s++, sizeof(uint32), 1, urandom );
+ fclose(urandom);
+ if( success ) { seed( bigSeed, N ); return; }
+ }
+
+ // Was not successful, so use time() and clock() instead
+ seed( hash( time(NULL), clock() ) );
+ */
+}
+
+
+inline void MTRand::initialize( const uint32 seed )
+{
+ // Initialize generator state with seed
+ // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
+ // In previous versions, most significant bits (MSBs) of the seed affect
+ // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
+ register uint32 *s = state;
+ register uint32 *r = state;
+ register int i = 1;
+ *s++ = seed & 0xffffffffUL;
+ for( ; i < N; ++i )
+ {
+ *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
+ r++;
+ }
+}
+
+
+inline void MTRand::reload()
+{
+ // Generate N new values in state
+ // Made clearer and faster by Matthew Bellew (matthew.bellew@home.com)
+ register uint32 *p = state;
+ register int i;
+ for( i = N - M; i--; ++p )
+ *p = twist( p[M], p[0], p[1] );
+ for( i = M; --i; ++p )
+ *p = twist( p[M-N], p[0], p[1] );
+ *p = twist( p[M-N], p[0], state[0] );
+
+ left = N, pNext = state;
+}
+
+
+inline MTRand::uint32 MTRand::hash( time_t t, clock_t c )
+{
+ // Get a uint32 from t and c
+ // Better than uint32(x) in case x is floating point in [0,1]
+ // Based on code by Lawrence Kirby (fred@genesis.demon.co.uk)
+
+ static uint32 differ = 0; // guarantee time-based seeds will change
+
+ uint32 h1 = 0;
+ unsigned char *p = (unsigned char *) &t;
+ for( size_t i = 0; i < sizeof(t); ++i )
+ {
+ h1 *= UCHAR_MAX + 2U;
+ h1 += p[i];
+ }
+ uint32 h2 = 0;
+ p = (unsigned char *) &c;
+ for( size_t j = 0; j < sizeof(c); ++j )
+ {
+ h2 *= UCHAR_MAX + 2U;
+ h2 += p[j];
+ }
+ return ( h1 + differ++ ) ^ h2;
+}
+
+
+inline void MTRand::save( uint32* saveArray ) const
+{
+ register uint32 *sa = saveArray;
+ register const uint32 *s = state;
+ register int i = N;
+ for( ; i--; *sa++ = *s++ ) {}
+ *sa = left;
+}
+
+
+inline void MTRand::load( uint32 *const loadArray )
+{
+ register uint32 *s = state;
+ register uint32 *la = loadArray;
+ register int i = N;
+ for( ; i--; *s++ = *la++ ) {}
+ left = *la;
+ pNext = &state[N-left];
+}
+
+
+inline std::ostream& operator<<( std::ostream& os, const MTRand& mtrand )
+{
+ register const MTRand::uint32 *s = mtrand.state;
+ register int i = mtrand.N;
+ for( ; i--; os << *s++ << "\t" ) {}
+ return os << mtrand.left;
+}
+
+
+inline std::istream& operator>>( std::istream& is, MTRand& mtrand )
+{
+ register MTRand::uint32 *s = mtrand.state;
+ register int i = mtrand.N;
+ for( ; i--; is >> *s++ ) {}
+ is >> mtrand.left;
+ mtrand.pNext = &mtrand.state[mtrand.N-mtrand.left];
+ return is;
+}
+
+#endif // MERSENNETWISTER_H
+
+// Change log:
+//
+// v0.1 - First release on 15 May 2000
+// - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
+// - Translated from C to C++
+// - Made completely ANSI compliant
+// - Designed convenient interface for initialization, seeding, and
+// obtaining numbers in default or user-defined ranges
+// - Added automatic seeding from /dev/urandom or time() and clock()
+// - Provided functions for saving and loading generator state
+//
+// v0.2 - Fixed bug which reloaded generator one step too late
+//
+// v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
+//
+// v0.4 - Removed trailing newline in saved generator format to be consistent
+// with output format of built-in types
+//
+// v0.5 - Improved portability by replacing static const int's with enum's and
+// clarifying return values in seed(); suggested by Eric Heimburg
+// - Removed MAXINT constant; use 0xffffffffUL instead
+//
+// v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
+// - Changed integer [0,n] generator to give better uniformity
+//
+// v0.7 - Fixed operator precedence ambiguity in reload()
+// - Added access for real numbers in (0,1) and (0,n)
+//
+// v0.8 - Included time.h header to properly support time_t and clock_t
+//
+// v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
+// - Allowed for seeding with arrays of any length
+// - Added access for real numbers in [0,1) with 53-bit resolution
+// - Added access for real numbers from normal (Gaussian) distributions
+// - Increased overall speed by optimizing twist()
+// - Doubled speed of integer [0,n] generation
+// - Fixed out-of-range number generation on 64-bit machines
+// - Improved portability by substituting literal constants for long enum's
+// - Changed license from GNU LGPL to BSD
+
diff --git a/intern/smoke/intern/Makefile b/intern/smoke/intern/Makefile
new file mode 100644
index 00000000000..2cdd7d3853e
--- /dev/null
+++ b/intern/smoke/intern/Makefile
@@ -0,0 +1,52 @@
+#
+# $Id$
+#
+# ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL LICENSE BLOCK *****
+# smoke intern Makefile
+#
+
+LIBNAME = smoke
+DIR = $(OCGDIR)/intern/$(LIBNAME)
+
+include nan_compile.mk
+
+unexport NAN_QUIET
+
+CCFLAGS += $(LEVEL_2_CPP_WARNINGS)
+
+ifeq ($(WITH_BF_OPENMP),true)
+ CPPFLAGS += -DPARALLEL
+endif
+
+CPPFLAGS += -I.
+CPPFLAGS += -I../extern
+CPPFLAGS += -I$(NAN_PNG)/include
+CPPFLAGS += -I$(NAN_PNG)/include/libpng
+
+# zlib
+ifeq ($(OS),$(findstring $(OS), "solaris windows"))
+ CPPFLAGS += -I$(NAN_ZLIB)/include
+endif
diff --git a/intern/smoke/intern/Makefile.FFT b/intern/smoke/intern/Makefile.FFT
new file mode 100644
index 00000000000..e45af1df29b
--- /dev/null
+++ b/intern/smoke/intern/Makefile.FFT
@@ -0,0 +1,22 @@
+# common stuff
+LDFLAGS_COMMON = -lfftw3 #-lglut -lglu32 -lopengl32 -lz -lpng
+CFLAGS_COMMON = -c -Wall -I./ #-I/cygdrive/c/lib/glvu/include -D_WIN32
+
+CC = g++
+CFLAGS = ${CFLAGS_COMMON} -O3 -Wno-unused
+LDFLAGS = ${LDFLAGS_COMMON}
+EXECUTABLE = noiseFFT
+
+SOURCES = noiseFFT.cpp
+OBJECTS = $(SOURCES:.cpp=.o)
+
+all: $(SOURCES) $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
+
+.cpp.o:
+ $(CC) $(CFLAGS) $< -o $@
+
+clean:
+ rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
diff --git a/intern/smoke/intern/Makefile.cygwin b/intern/smoke/intern/Makefile.cygwin
new file mode 100644
index 00000000000..c93753a67fe
--- /dev/null
+++ b/intern/smoke/intern/Makefile.cygwin
@@ -0,0 +1,23 @@
+CC = g++
+LDFLAGS = -lz -lpng
+CFLAGS = -O3 -Wno-unused -c -Wall -I./ -D_WIN32
+EXECUTABLE = FLUID_3D
+
+SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
+OBJECTS = $(SOURCES:.cpp=.o)
+
+all: $(SOURCES) $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
+
+.cpp.o:
+ $(CC) $(CFLAGS) $< -o $@
+
+SPHERE.o: SPHERE.h
+FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
+FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
+main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
+
+clean:
+ rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
diff --git a/intern/smoke/intern/Makefile.linux b/intern/smoke/intern/Makefile.linux
new file mode 100644
index 00000000000..8e71af465dd
--- /dev/null
+++ b/intern/smoke/intern/Makefile.linux
@@ -0,0 +1,23 @@
+CC = g++
+LDFLAGS = -lz -lpng -fopenmp -lgomp
+CFLAGS = -c -Wall -I./ -fopenmp -DPARALLEL=1 -O3 -Wno-unused
+EXECUTABLE = FLUID_3D
+
+SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
+OBJECTS = $(SOURCES:.cpp=.o)
+
+all: $(SOURCES) $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
+
+.cpp.o:
+ $(CC) $(CFLAGS) $< -o $@
+
+SPHERE.o: SPHERE.h
+FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
+FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
+main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
+
+clean:
+ rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
diff --git a/intern/smoke/intern/Makefile.mac b/intern/smoke/intern/Makefile.mac
new file mode 100644
index 00000000000..227aaa10a16
--- /dev/null
+++ b/intern/smoke/intern/Makefile.mac
@@ -0,0 +1,35 @@
+CC = g++
+
+# uncomment the other two OPENMP_... lines, if your gcc supports OpenMP
+#OPENMP_FLAGS = -fopenmp -DPARALLEL=1 -I/opt/gcc-4.3/usr/local/include
+#OPENMPLD_FLAGS = -fopenmp -lgomp -I/opt/gcc-4.3/usr/local/lib
+OPENMP_FLAGS =
+OPENMPLD_FLAGS =
+
+# assumes MacPorts libpng installation
+PNG_INCLUDE = -I/opt/local/include
+PNG_LIBS = -I/opt/local/lib
+
+LDFLAGS = $(PNG_LIBS)-lz -lpng $(OPENMPLD_FLAGS)
+CFLAGS = -c -Wall -I./ $(PNG_INCLUDE) $(OPENMP_FLAGS) -O3 -Wno-unused
+EXECUTABLE = FLUID_3D
+
+SOURCES = main.cpp FLUID_3D.cpp FLUID_3D_SOLVERS.cpp FLUID_3D_STATIC.cpp SPHERE.cpp WTURBULENCE.cpp
+OBJECTS = $(SOURCES:.cpp=.o)
+
+all: $(SOURCES) $(EXECUTABLE)
+
+$(EXECUTABLE): $(OBJECTS)
+ $(CC) $(OBJECTS) $(LDFLAGS) -o $@
+
+.cpp.o:
+ $(CC) $(CFLAGS) $< -o $@
+
+SPHERE.o: SPHERE.h
+FLUID_3D.o: FLUID_3D.h FLUID_3D.cpp
+FLUID_3D_SOLVERS.o: FLUID_3D.h FLUID_3D_SOLVERS.cpp
+main.o: FLUID_3D.h FLUID_3D.cpp FLUID_3D_SOLVERS.cpp
+
+clean:
+ rm -f *.o $(EXECUTABLE_LOADER) $(EXECUTABLE)
+
diff --git a/intern/smoke/intern/OBSTACLE.h b/intern/smoke/intern/OBSTACLE.h
new file mode 100644
index 00000000000..54e824d275d
--- /dev/null
+++ b/intern/smoke/intern/OBSTACLE.h
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+// OBSTACLE.h: interface for the OBSTACLE class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef OBSTACLE_H
+#define OBSTACLE_H
+
+enum OBSTACLE_FLAGS {
+ EMPTY = 0,
+ MARCHED = 2,
+ RETIRED = 4
+};
+
+class OBSTACLE
+{
+public:
+ OBSTACLE() {};
+ virtual ~OBSTACLE() {};
+
+ virtual bool inside(float x, float y, float z) = 0;
+};
+
+#endif
diff --git a/intern/smoke/intern/SPHERE.cpp b/intern/smoke/intern/SPHERE.cpp
new file mode 100644
index 00000000000..4bb18fb81c0
--- /dev/null
+++ b/intern/smoke/intern/SPHERE.cpp
@@ -0,0 +1,50 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+// SPHERE.cpp: implementation of the SPHERE class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#include "SPHERE.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+SPHERE::SPHERE(float x, float y, float z, float radius) :
+ _radius(radius)
+{
+ _center[0] = x;
+ _center[1] = y;
+ _center[2] = z;
+}
+
+SPHERE::~SPHERE()
+{
+
+}
+
+bool SPHERE::inside(float x, float y, float z)
+{
+ float translate[] = {x - _center[0], y - _center[1], z - _center[2]};
+ float magnitude = translate[0] * translate[0] +
+ translate[1] * translate[1] +
+ translate[2] * translate[2];
+
+ return (magnitude < _radius * _radius) ? true : false;
+}
diff --git a/intern/smoke/intern/SPHERE.h b/intern/smoke/intern/SPHERE.h
new file mode 100644
index 00000000000..13bd6e9493c
--- /dev/null
+++ b/intern/smoke/intern/SPHERE.h
@@ -0,0 +1,41 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+// SPHERE.h: interface for the SPHERE class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#ifndef SPHERE_H
+#define SPHERE_H
+
+#include "OBSTACLE.h"
+
+class SPHERE : public OBSTACLE
+{
+public:
+ SPHERE(float x, float y, float z, float radius);
+ virtual ~SPHERE();
+
+ bool inside(float x, float y, float z);
+
+private:
+ float _center[3];
+ float _radius;
+};
+
+#endif
diff --git a/intern/smoke/intern/VEC3.h b/intern/smoke/intern/VEC3.h
new file mode 100644
index 00000000000..98c4555ac5f
--- /dev/null
+++ b/intern/smoke/intern/VEC3.h
@@ -0,0 +1,986 @@
+/******************************************************************************
+ * Copyright 2007 Nils Thuerey
+ * Basic vector class
+ *****************************************************************************/
+#ifndef BASICVECTOR_H
+#define BASICVECTOR_H
+
+#include <math.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <iostream>
+#include <sstream>
+
+// use which fp-precision? 1=float, 2=double
+#ifndef FLOATINGPOINT_PRECISION
+#if DDF_DEBUG==1
+#define FLOATINGPOINT_PRECISION 2
+#else // DDF_DEBUG==1
+#define FLOATINGPOINT_PRECISION 1
+#endif // DDF_DEBUG==1
+#endif
+
+// VECTOR_EPSILON is the minimal vector length
+// In order to be able to discriminate floating point values near zero, and
+// to be sure not to fail a comparison because of roundoff errors, use this
+// value as a threshold.
+
+#if FLOATINGPOINT_PRECISION==1
+typedef float Real;
+#define FP_REAL_MAX __FLT_MAX__
+#define VECTOR_EPSILON (1e-5f)
+#else
+typedef double Real;
+#define FP_REAL_MAX __DBL_MAX__
+#define VECTOR_EPSILON (1e-10)
+#endif
+
+
+// hardcoded limits for now...
+// for e.g. MSVC compiler...
+// some of these defines can be needed
+// for linux systems as well (e.g. FLT_MAX)
+#ifndef __FLT_MAX__
+# ifdef FLT_MAX // try to use it instead
+# define __FLT_MAX__ FLT_MAX
+# else // FLT_MAX
+# define __FLT_MAX__ 3.402823466e+38f
+# endif // FLT_MAX
+#endif // __FLT_MAX__
+#ifndef __DBL_MAX__
+# ifdef DBL_MAX // try to use it instead
+# define __DBL_MAX__ DBL_MAX
+# else // DBL_MAX
+# define __DBL_MAX__ 1.7976931348623158e+308
+# endif // DBL_MAX
+#endif // __DBL_MAX__
+
+#ifndef FLT_MAX
+#define FLT_MAX __FLT_MAX__
+#endif
+
+#ifndef DBL_MAX
+#define DBL_MAX __DBL_MAX__
+#endif
+
+#ifndef M_PI
+# define M_PI 3.1415926536
+# define M_E 2.7182818284
+#endif
+
+
+
+namespace BasicVector {
+
+
+// basic inlined vector class
+template<class Scalar>
+class Vector3Dim
+{
+public:
+ // Constructor
+ inline Vector3Dim();
+ // Copy-Constructor
+ inline Vector3Dim(const Vector3Dim<Scalar> &v );
+ inline Vector3Dim(const float *);
+ inline Vector3Dim(const double *);
+ // construct a vector from one Scalar
+ inline Vector3Dim(Scalar);
+ // construct a vector from three Scalars
+ inline Vector3Dim(Scalar, Scalar, Scalar);
+
+ // get address of array for OpenGL
+ Scalar *getAddress() { return value; }
+
+ // Assignment operator
+ inline const Vector3Dim<Scalar>& operator= (const Vector3Dim<Scalar>& v);
+ // Assignment operator
+ inline const Vector3Dim<Scalar>& operator= (Scalar s);
+ // Assign and add operator
+ inline const Vector3Dim<Scalar>& operator+= (const Vector3Dim<Scalar>& v);
+ // Assign and add operator
+ inline const Vector3Dim<Scalar>& operator+= (Scalar s);
+ // Assign and sub operator
+ inline const Vector3Dim<Scalar>& operator-= (const Vector3Dim<Scalar>& v);
+ // Assign and sub operator
+ inline const Vector3Dim<Scalar>& operator-= (Scalar s);
+ // Assign and mult operator
+ inline const Vector3Dim<Scalar>& operator*= (const Vector3Dim<Scalar>& v);
+ // Assign and mult operator
+ inline const Vector3Dim<Scalar>& operator*= (Scalar s);
+ // Assign and div operator
+ inline const Vector3Dim<Scalar>& operator/= (const Vector3Dim<Scalar>& v);
+ // Assign and div operator
+ inline const Vector3Dim<Scalar>& operator/= (Scalar s);
+
+
+ // unary operator
+ inline Vector3Dim<Scalar> operator- () const;
+
+ // binary operator add
+ inline Vector3Dim<Scalar> operator+ (const Vector3Dim<Scalar>&) const;
+ // binary operator add
+ inline Vector3Dim<Scalar> operator+ (Scalar) const;
+ // binary operator sub
+ inline Vector3Dim<Scalar> operator- (const Vector3Dim<Scalar>&) const;
+ // binary operator sub
+ inline Vector3Dim<Scalar> operator- (Scalar) const;
+ // binary operator mult
+ inline Vector3Dim<Scalar> operator* (const Vector3Dim<Scalar>&) const;
+ // binary operator mult
+ inline Vector3Dim<Scalar> operator* (Scalar) const;
+ // binary operator div
+ inline Vector3Dim<Scalar> operator/ (const Vector3Dim<Scalar>&) const;
+ // binary operator div
+ inline Vector3Dim<Scalar> operator/ (Scalar) const;
+
+ // Projection normal to a vector
+ inline Vector3Dim<Scalar> getOrthogonalntlVector3Dim() const;
+ // Project into a plane
+ inline const Vector3Dim<Scalar>& projectNormalTo(const Vector3Dim<Scalar> &v);
+
+ // minimize
+ inline const Vector3Dim<Scalar> &minimize(const Vector3Dim<Scalar> &);
+ // maximize
+ inline const Vector3Dim<Scalar> &maximize(const Vector3Dim<Scalar> &);
+
+ // access operator
+ inline Scalar& operator[](unsigned int i);
+ // access operator
+ inline const Scalar& operator[](unsigned int i) const;
+
+ //! actual values
+ union {
+ struct {
+ Scalar value[3];
+ };
+ struct {
+ Scalar x;
+ Scalar y;
+ Scalar z;
+ };
+ struct {
+ Scalar X;
+ Scalar Y;
+ Scalar Z;
+ };
+ };
+protected:
+
+};
+
+
+
+
+
+//------------------------------------------------------------------------------
+// VECTOR inline FUNCTIONS
+//------------------------------------------------------------------------------
+
+
+
+/*************************************************************************
+ Constructor.
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>::Vector3Dim( void )
+{
+ value[0] = value[1] = value[2] = 0;
+}
+
+
+
+/*************************************************************************
+ Copy-Constructor.
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>::Vector3Dim( const Vector3Dim<Scalar> &v )
+{
+ value[0] = v.value[0];
+ value[1] = v.value[1];
+ value[2] = v.value[2];
+}
+template<class Scalar>
+inline Vector3Dim<Scalar>::Vector3Dim( const float *fvalue)
+{
+ value[0] = (Scalar)fvalue[0];
+ value[1] = (Scalar)fvalue[1];
+ value[2] = (Scalar)fvalue[2];
+}
+template<class Scalar>
+inline Vector3Dim<Scalar>::Vector3Dim( const double *fvalue)
+{
+ value[0] = (Scalar)fvalue[0];
+ value[1] = (Scalar)fvalue[1];
+ value[2] = (Scalar)fvalue[2];
+}
+
+
+
+/*************************************************************************
+ Constructor for a vector from a single Scalar. All components of
+ the vector get the same value.
+ \param s The value to set
+ \return The new vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>::Vector3Dim(Scalar s )
+{
+ value[0]= s;
+ value[1]= s;
+ value[2]= s;
+}
+
+
+/*************************************************************************
+ Constructor for a vector from three Scalars.
+ \param s1 The value for the first vector component
+ \param s2 The value for the second vector component
+ \param s3 The value for the third vector component
+ \return The new vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>::Vector3Dim(Scalar s1, Scalar s2, Scalar s3)
+{
+ value[0]= s1;
+ value[1]= s2;
+ value[2]= s3;
+}
+
+
+
+/*************************************************************************
+ Copy a Vector3Dim componentwise.
+ \param v vector with values to be copied
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator=( const Vector3Dim<Scalar> &v )
+{
+ value[0] = v.value[0];
+ value[1] = v.value[1];
+ value[2] = v.value[2];
+ return *this;
+}
+
+
+/*************************************************************************
+ Copy a Scalar to each component.
+ \param s The value to copy
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator=(Scalar s)
+{
+ value[0] = s;
+ value[1] = s;
+ value[2] = s;
+ return *this;
+}
+
+
+/*************************************************************************
+ Add another Vector3Dim componentwise.
+ \param v vector with values to be added
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator+=( const Vector3Dim<Scalar> &v )
+{
+ value[0] += v.value[0];
+ value[1] += v.value[1];
+ value[2] += v.value[2];
+ return *this;
+}
+
+
+/*************************************************************************
+ Add a Scalar value to each component.
+ \param s Value to add
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator+=(Scalar s)
+{
+ value[0] += s;
+ value[1] += s;
+ value[2] += s;
+ return *this;
+}
+
+
+/*************************************************************************
+ Subtract another vector componentwise.
+ \param v vector of values to subtract
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator-=( const Vector3Dim<Scalar> &v )
+{
+ value[0] -= v.value[0];
+ value[1] -= v.value[1];
+ value[2] -= v.value[2];
+ return *this;
+}
+
+
+/*************************************************************************
+ Subtract a Scalar value from each component.
+ \param s Value to subtract
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator-=(Scalar s)
+{
+ value[0]-= s;
+ value[1]-= s;
+ value[2]-= s;
+ return *this;
+}
+
+
+/*************************************************************************
+ Multiply with another vector componentwise.
+ \param v vector of values to multiply with
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator*=( const Vector3Dim<Scalar> &v )
+{
+ value[0] *= v.value[0];
+ value[1] *= v.value[1];
+ value[2] *= v.value[2];
+ return *this;
+}
+
+
+/*************************************************************************
+ Multiply each component with a Scalar value.
+ \param s Value to multiply with
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator*=(Scalar s)
+{
+ value[0] *= s;
+ value[1] *= s;
+ value[2] *= s;
+ return *this;
+}
+
+
+/*************************************************************************
+ Divide by another Vector3Dim componentwise.
+ \param v vector of values to divide by
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator/=( const Vector3Dim<Scalar> &v )
+{
+ value[0] /= v.value[0];
+ value[1] /= v.value[1];
+ value[2] /= v.value[2];
+ return *this;
+}
+
+
+/*************************************************************************
+ Divide each component by a Scalar value.
+ \param s Value to divide by
+ \return Reference to self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::operator/=(Scalar s)
+{
+ value[0] /= s;
+ value[1] /= s;
+ value[2] /= s;
+ return *this;
+}
+
+
+//------------------------------------------------------------------------------
+// unary operators
+//------------------------------------------------------------------------------
+
+
+/*************************************************************************
+ Build componentwise the negative this vector.
+ \return The new (negative) vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>
+Vector3Dim<Scalar>::operator-() const
+{
+ return Vector3Dim<Scalar>(-value[0], -value[1], -value[2]);
+}
+
+
+
+//------------------------------------------------------------------------------
+// binary operators
+//------------------------------------------------------------------------------
+
+
+/*************************************************************************
+ Build a vector with another vector added componentwise.
+ \param v The second vector to add
+ \return The sum vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>
+Vector3Dim<Scalar>::operator+( const Vector3Dim<Scalar> &v ) const
+{
+ return Vector3Dim<Scalar>(value[0]+v.value[0],
+ value[1]+v.value[1],
+ value[2]+v.value[2]);
+}
+
+
+/*************************************************************************
+ Build a vector with a Scalar value added to each component.
+ \param s The Scalar value to add
+ \return The sum vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>
+Vector3Dim<Scalar>::operator+(Scalar s) const
+{
+ return Vector3Dim<Scalar>(value[0]+s,
+ value[1]+s,
+ value[2]+s);
+}
+
+
+/*************************************************************************
+ Build a vector with another vector subtracted componentwise.
+ \param v The second vector to subtract
+ \return The difference vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>
+Vector3Dim<Scalar>::operator-( const Vector3Dim<Scalar> &v ) const
+{
+ return Vector3Dim<Scalar>(value[0]-v.value[0],
+ value[1]-v.value[1],
+ value[2]-v.value[2]);
+}
+
+
+/*************************************************************************
+ Build a vector with a Scalar value subtracted componentwise.
+ \param s The Scalar value to subtract
+ \return The difference vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>
+Vector3Dim<Scalar>::operator-(Scalar s ) const
+{
+ return Vector3Dim<Scalar>(value[0]-s,
+ value[1]-s,
+ value[2]-s);
+}
+
+
+
+/*************************************************************************
+ Build a vector with another vector multiplied by componentwise.
+ \param v The second vector to muliply with
+ \return The product vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>
+Vector3Dim<Scalar>::operator*( const Vector3Dim<Scalar>& v) const
+{
+ return Vector3Dim<Scalar>(value[0]*v.value[0],
+ value[1]*v.value[1],
+ value[2]*v.value[2]);
+}
+
+
+/*************************************************************************
+ Build a Vector3Dim with a Scalar value multiplied to each component.
+ \param s The Scalar value to multiply with
+ \return The product vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>
+Vector3Dim<Scalar>::operator*(Scalar s) const
+{
+ return Vector3Dim<Scalar>(value[0]*s, value[1]*s, value[2]*s);
+}
+
+
+/*************************************************************************
+ Build a vector divided componentwise by another vector.
+ \param v The second vector to divide by
+ \return The ratio vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>
+Vector3Dim<Scalar>::operator/(const Vector3Dim<Scalar>& v) const
+{
+ return Vector3Dim<Scalar>(value[0]/v.value[0],
+ value[1]/v.value[1],
+ value[2]/v.value[2]);
+}
+
+
+
+/*************************************************************************
+ Build a vector divided componentwise by a Scalar value.
+ \param s The Scalar value to divide by
+ \return The ratio vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar>
+Vector3Dim<Scalar>::operator/(Scalar s) const
+{
+ return Vector3Dim<Scalar>(value[0]/s,
+ value[1]/s,
+ value[2]/s);
+}
+
+
+
+
+
+/*************************************************************************
+ Get a particular component of the vector.
+ \param i Number of Scalar to get
+ \return Reference to the component
+ */
+template<class Scalar>
+inline Scalar&
+Vector3Dim<Scalar>::operator[]( unsigned int i )
+{
+ return value[i];
+}
+
+
+/*************************************************************************
+ Get a particular component of a constant vector.
+ \param i Number of Scalar to get
+ \return Reference to the component
+ */
+template<class Scalar>
+inline const Scalar&
+Vector3Dim<Scalar>::operator[]( unsigned int i ) const
+{
+ return value[i];
+}
+
+
+
+//------------------------------------------------------------------------------
+// BLITZ compatibility functions
+//------------------------------------------------------------------------------
+
+
+
+/*************************************************************************
+ Compute the scalar product with another vector.
+ \param v The second vector to work with
+ \return The value of the scalar product
+ */
+template<class Scalar>
+inline Scalar dot(const Vector3Dim<Scalar> &t, const Vector3Dim<Scalar> &v )
+{
+ //return t.value[0]*v.value[0] + t.value[1]*v.value[1] + t.value[2]*v.value[2];
+ return ((t[0]*v[0]) + (t[1]*v[1]) + (t[2]*v[2]));
+}
+
+
+/*************************************************************************
+ Calculate the cross product of this and another vector
+ */
+template<class Scalar>
+inline Vector3Dim<Scalar> cross(const Vector3Dim<Scalar> &t, const Vector3Dim<Scalar> &v)
+{
+ Vector3Dim<Scalar> cp(
+ ((t[1]*v[2]) - (t[2]*v[1])),
+ ((t[2]*v[0]) - (t[0]*v[2])),
+ ((t[0]*v[1]) - (t[1]*v[0])) );
+ return cp;
+}
+
+
+
+
+/*************************************************************************
+ Compute a vector that is orthonormal to self. Nothing else can be assumed
+ for the direction of the new vector.
+ \return The orthonormal vector
+ */
+template<class Scalar>
+Vector3Dim<Scalar>
+Vector3Dim<Scalar>::getOrthogonalntlVector3Dim() const
+{
+ // Determine the component with max. absolute value
+ int max= (fabs(value[0]) > fabs(value[1])) ? 0 : 1;
+ max= (fabs(value[max]) > fabs(value[2])) ? max : 2;
+
+ /*************************************************************************
+ Choose another axis than the one with max. component and project
+ orthogonal to self
+ */
+ Vector3Dim<Scalar> vec(0.0);
+ vec[(max+1)%3]= 1;
+ vec.normalize();
+ vec.projectNormalTo(this->getNormalized());
+ return vec;
+}
+
+
+/*************************************************************************
+ Projects the vector into a plane normal to the given vector, which must
+ have unit length. Self is modified.
+ \param v The plane normal
+ \return The projected vector
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar>&
+Vector3Dim<Scalar>::projectNormalTo(const Vector3Dim<Scalar> &v)
+{
+ Scalar sprod = dot(*this,v);
+ value[0]= value[0] - v.value[0] * sprod;
+ value[1]= value[1] - v.value[1] * sprod;
+ value[2]= value[2] - v.value[2] * sprod;
+ return *this;
+}
+
+
+
+//------------------------------------------------------------------------------
+// Other helper functions
+//------------------------------------------------------------------------------
+
+
+
+/*************************************************************************
+ Minimize the vector, i.e. set each entry of the vector to the minimum
+ of both values.
+ \param pnt The second vector to compare with
+ \return Reference to the modified self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar> &
+Vector3Dim<Scalar>::minimize(const Vector3Dim<Scalar> &pnt)
+{
+ for (unsigned int i = 0; i < 3; i++)
+ value[i] = MIN(value[i],pnt[i]);
+ return *this;
+}
+
+
+
+/*************************************************************************
+ Maximize the vector, i.e. set each entry of the vector to the maximum
+ of both values.
+ \param pnt The second vector to compare with
+ \return Reference to the modified self
+ */
+template<class Scalar>
+inline const Vector3Dim<Scalar> &
+Vector3Dim<Scalar>::maximize(const Vector3Dim<Scalar> &pnt)
+{
+ for (unsigned int i = 0; i < 3; i++)
+ value[i] = MAX(value[i],pnt[i]);
+ return *this;
+}
+
+
+
+
+
+
+/************************************************************************/
+// HELPER FUNCTIONS, independent of implementation
+/************************************************************************/
+
+#define VECTOR_TYPE Vector3Dim<Scalar>
+
+
+/*************************************************************************
+ Compute the length (norm) of the vector.
+ \return The value of the norm
+ */
+template<class Scalar>
+inline Scalar norm( const VECTOR_TYPE &v)
+{
+ Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
+ return (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) ? 1. : sqrt(l);
+}
+
+// for e.g. min max operator
+inline Real normHelper(const Vector3Dim<Real> &v) {
+ return norm(v);
+}
+inline Real normHelper(const Real &v) {
+ return (0. < v) ? v : -v ;
+}
+inline Real normHelper(const int &v) {
+ return (0 < v) ? (Real)(v) : (Real)(-v) ;
+}
+
+
+/*************************************************************************
+ Same as getNorm but doesnt sqrt
+ */
+template<class Scalar>
+inline Scalar normNoSqrt( const VECTOR_TYPE &v)
+{
+ return v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
+}
+
+
+/*************************************************************************
+ Compute a normalized vector based on this vector.
+ \return The new normalized vector
+ */
+template<class Scalar>
+inline VECTOR_TYPE getNormalized( const VECTOR_TYPE &v)
+{
+ Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
+ if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON)
+ return v; /* normalized "enough"... */
+ else if (l > VECTOR_EPSILON*VECTOR_EPSILON)
+ {
+ Scalar fac = 1./sqrt(l);
+ return VECTOR_TYPE(v[0]*fac, v[1]*fac, v[2]*fac);
+ }
+ else
+ return VECTOR_TYPE((Scalar)0);
+}
+
+
+/*************************************************************************
+ Compute the norm of the vector and normalize it.
+ \return The value of the norm
+ */
+template<class Scalar>
+inline Scalar normalize( VECTOR_TYPE &v)
+{
+ Scalar norm;
+ Scalar l = v[0]*v[0] + v[1]*v[1] + v[2]*v[2];
+ if (fabs(l-1.) < VECTOR_EPSILON*VECTOR_EPSILON) {
+ norm = 1.;
+ } else if (l > VECTOR_EPSILON*VECTOR_EPSILON) {
+ norm = sqrt(l);
+ Scalar fac = 1./norm;
+ v[0] *= fac;
+ v[1] *= fac;
+ v[2] *= fac;
+ } else {
+ v[0]= v[1]= v[2]= 0;
+ norm = 0.;
+ }
+ return (Scalar)norm;
+}
+
+
+/*************************************************************************
+ Compute a vector, that is self (as an incoming
+ vector) reflected at a surface with a distinct normal vector. Note
+ that the normal is reversed, if the scalar product with it is positive.
+ \param n The surface normal
+ \return The new reflected vector
+ */
+template<class Scalar>
+inline VECTOR_TYPE reflectVector(const VECTOR_TYPE &t, const VECTOR_TYPE &n)
+{
+ VECTOR_TYPE nn= (dot(t, n) > 0.0) ? (n*-1.0) : n;
+ return ( t - nn * (2.0 * dot(nn, t)) );
+}
+
+
+
+/*************************************************************************
+ * My own refraction calculation
+ * Taken from Glassner's book, section 5.2 (Heckberts method)
+ */
+template<class Scalar>
+inline VECTOR_TYPE refractVector(const VECTOR_TYPE &t, const VECTOR_TYPE &normal, Scalar nt, Scalar nair, int &refRefl)
+{
+ Scalar eta = nair / nt;
+ Scalar n = -dot(t, normal);
+ Scalar tt = 1.0 + eta*eta* (n*n-1.0);
+ if(tt<0.0) {
+ // we have total reflection!
+ refRefl = 1;
+ } else {
+ // normal reflection
+ tt = eta*n - sqrt(tt);
+ return( t*eta + normal*tt );
+ }
+ return t;
+}
+
+
+/*************************************************************************
+ Test two ntlVector3Dims for equality based on the equality of their
+ values within a small threshold.
+ \param c The second vector to compare
+ \return TRUE if both are equal
+ \sa getEpsilon()
+ */
+template<class Scalar>
+inline bool equal(const VECTOR_TYPE &v, const VECTOR_TYPE &c)
+{
+ return (ABS(v[0]-c[0]) +
+ ABS(v[1]-c[1]) +
+ ABS(v[2]-c[2]) < VECTOR_EPSILON);
+}
+
+
+/*************************************************************************
+ * Assume this vector is an RGB color, and convert it to HSV
+ */
+template<class Scalar>
+inline void rgbToHsv( VECTOR_TYPE &V )
+{
+ Scalar h=0,s=0,v=0;
+ Scalar maxrgb, minrgb, delta;
+ // convert to hsv...
+ maxrgb = V[0];
+ int maxindex = 1;
+ if(V[2] > maxrgb){ maxrgb = V[2]; maxindex = 2; }
+ if(V[1] > maxrgb){ maxrgb = V[1]; maxindex = 3; }
+ minrgb = V[0];
+ if(V[2] < minrgb) minrgb = V[2];
+ if(V[1] < minrgb) minrgb = V[1];
+
+ v = maxrgb;
+ delta = maxrgb-minrgb;
+
+ if(maxrgb > 0) s = delta/maxrgb;
+ else s = 0;
+
+ h = 0;
+ if(s > 0) {
+ if(maxindex == 1) {
+ h = ((V[1]-V[2])/delta) + 0.0; }
+ if(maxindex == 2) {
+ h = ((V[2]-V[0])/delta) + 2.0; }
+ if(maxindex == 3) {
+ h = ((V[0]-V[1])/delta) + 4.0; }
+ h *= 60.0;
+ if(h < 0.0) h += 360.0;
+ }
+
+ V[0] = h;
+ V[1] = s;
+ V[2] = v;
+}
+
+/*************************************************************************
+ * Assume this vector is HSV and convert to RGB
+ */
+template<class Scalar>
+inline void hsvToRgb( VECTOR_TYPE &V )
+{
+ Scalar h = V[0], s = V[1], v = V[2];
+ Scalar r=0,g=0,b=0;
+ Scalar p,q,t, fracth;
+ int floorh;
+ // ...and back to rgb
+ if(s == 0) {
+ r = g = b = v; }
+ else {
+ h /= 60.0;
+ floorh = (int)h;
+ fracth = h - floorh;
+ p = v * (1.0 - s);
+ q = v * (1.0 - (s * fracth));
+ t = v * (1.0 - (s * (1.0 - fracth)));
+ switch (floorh) {
+ case 0: r = v; g = t; b = p; break;
+ case 1: r = q; g = v; b = p; break;
+ case 2: r = p; g = v; b = t; break;
+ case 3: r = p; g = q; b = v; break;
+ case 4: r = t; g = p; b = v; break;
+ case 5: r = v; g = p; b = q; break;
+ }
+ }
+
+ V[0] = r;
+ V[1] = g;
+ V[2] = b;
+}
+
+//------------------------------------------------------------------------------
+// STREAM FUNCTIONS
+//------------------------------------------------------------------------------
+
+
+
+//! global string for formatting vector output in utilities.cpp
+//extern const char *globVecFormatStr;
+#if 0
+static const char *globVecFormatStr = "[%6.4f,%6.4f,%6.4f]";
+#endif
+
+/*************************************************************************
+ Outputs the object in human readable form using the format
+ [x,y,z]
+ */
+template<class Scalar>
+std::ostream&
+operator<<( std::ostream& os, const BasicVector::Vector3Dim<Scalar>& i )
+{
+ char buf[256];
+#if 0
+#if _WIN32
+ sprintf(buf,globVecFormatStr, (double)i[0],(double)i[1],(double)i[2]);
+#else
+ snprintf(buf,256,globVecFormatStr, (double)i[0],(double)i[1],(double)i[2]);
+#endif
+ os << std::string(buf);
+#endif
+ return os;
+}
+
+
+/*************************************************************************
+ Reads the contents of the object from a stream using the same format
+ as the output operator.
+ */
+template<class Scalar>
+std::istream&
+operator>>( std::istream& is, BasicVector::Vector3Dim<Scalar>& i )
+{
+ char c;
+ char dummy[3];
+ is >> c >> i[0] >> dummy >> i[1] >> dummy >> i[2] >> c;
+ return is;
+}
+
+
+/**************************************************************************/
+// typedefs!
+/**************************************************************************/
+
+/* get minimal vector length value that can be discriminated. */
+inline Real getVecEpsilon() { return (Real)VECTOR_EPSILON; }
+
+// a 3D integer vector
+typedef Vector3Dim<int> Vec3Int;
+
+// a 3D vector
+typedef Vector3Dim<Real> Vec3;
+
+
+}; // namespace
+
+
+#endif /* BASICVECTOR_H */
diff --git a/intern/smoke/intern/WAVELET_NOISE.h b/intern/smoke/intern/WAVELET_NOISE.h
new file mode 100644
index 00000000000..4c2e7514af7
--- /dev/null
+++ b/intern/smoke/intern/WAVELET_NOISE.h
@@ -0,0 +1,458 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+//////////////////////////////////////////////////////////////////////////////////////////
+// Wavelet noise functions
+//
+// This code is based on the C code provided in the appendices of:
+//
+// @article{1073264,
+// author = {Robert L. Cook and Tony DeRose},
+// title = {Wavelet noise},
+// journal = {ACM Trans. Graph.},
+// volume = {24},
+// number = {3},
+// year = {2005},
+// issn = {0730-0301},
+// pages = {803--811},
+// doi = {http://doi.acm.org/10.1145/1073204.1073264},
+// publisher = {ACM},
+// address = {New York, NY, USA},
+// }
+//
+//////////////////////////////////////////////////////////////////////////////////////////
+
+#ifndef WAVELET_NOISE_H
+#define WAVELET_NOISE_H
+
+#include <MERSENNETWISTER.h>
+
+#define NOISE_TILE_SIZE 128
+static const int noiseTileSize = NOISE_TILE_SIZE;
+
+// warning - noiseTileSize has to be 128^3!
+#define modFast128(x) ((x) & 127)
+#define modFast64(x) ((x) & 63)
+#define DOWNCOEFFS 0.000334f,-0.001528f, 0.000410f, 0.003545f,-0.000938f,-0.008233f, 0.002172f, 0.019120f, \
+ -0.005040f,-0.044412f, 0.011655f, 0.103311f,-0.025936f,-0.243780f, 0.033979f, 0.655340f, \
+ 0.655340f, 0.033979f,-0.243780f,-0.025936f, 0.103311f, 0.011655f,-0.044412f,-0.005040f, \
+ 0.019120f, 0.002172f,-0.008233f,-0.000938f, 0.003546f, 0.000410f,-0.001528f, 0.000334f
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Wavelet downsampling -- periodic boundary conditions
+//////////////////////////////////////////////////////////////////////////////////////////
+static void downsampleX(float *from, float *to, int n){
+ // if these values are not local incorrect results are generated
+ float downCoeffs[32] = { DOWNCOEFFS };
+ const float *a = &downCoeffs[16];
+ for (int i = 0; i < n / 2; i++) {
+ to[i] = 0;
+ for (int k = 2 * i - 16; k <= 2 * i + 16; k++)
+ to[i] += a[k - 2 * i] * from[modFast128(k)];
+ }
+}
+static void downsampleY(float *from, float *to, int n){
+ // if these values are not local incorrect results are generated
+ float downCoeffs[32] = { DOWNCOEFFS };
+ const float *a = &downCoeffs[16];
+ for (int i = 0; i < n / 2; i++) {
+ to[i * n] = 0;
+ for (int k = 2 * i - 16; k <= 2 * i + 16; k++)
+ to[i * n] += a[k - 2 * i] * from[modFast128(k) * n];
+ }
+}
+static void downsampleZ(float *from, float *to, int n){
+ // if these values are not local incorrect results are generated
+ float downCoeffs[32] = { DOWNCOEFFS };
+ const float *a = &downCoeffs[16];
+ for (int i = 0; i < n / 2; i++) {
+ to[i * n * n] = 0;
+ for (int k = 2 * i - 16; k <= 2 * i + 16; k++)
+ to[i * n * n] += a[k - 2 * i] * from[modFast128(k) * n * n];
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Wavelet downsampling -- Neumann boundary conditions
+//////////////////////////////////////////////////////////////////////////////////////////
+static void downsampleNeumann(const float *from, float *to, int n, int stride)
+{
+ // if these values are not local incorrect results are generated
+ float downCoeffs[32] = { DOWNCOEFFS };
+ static const float *const aCoCenter= &downCoeffs[16];
+ for (int i = 0; i < n / 2; i++) {
+ to[i * stride] = 0;
+ for (int k = 2 * i - 16; k < 2 * i + 16; k++) {
+ // handle boundary
+ float fromval;
+ if (k < 0) {
+ fromval = from[0];
+ } else if(k > n - 1) {
+ fromval = from[(n - 1) * stride];
+ } else {
+ fromval = from[k * stride];
+ }
+ to[i * stride] += aCoCenter[k - 2 * i] * fromval;
+ }
+ }
+}
+static void downsampleXNeumann(float* to, const float* from, int sx,int sy, int sz) {
+ for (int iy = 0; iy < sy; iy++)
+ for (int iz = 0; iz < sz; iz++) {
+ const int i = iy * sx + iz*sx*sy;
+ downsampleNeumann(&from[i], &to[i], sx, 1);
+ }
+}
+static void downsampleYNeumann(float* to, const float* from, int sx,int sy, int sz) {
+ for (int ix = 0; ix < sx; ix++)
+ for (int iz = 0; iz < sz; iz++) {
+ const int i = ix + iz*sx*sy;
+ downsampleNeumann(&from[i], &to[i], sy, sx);
+ }
+}
+static void downsampleZNeumann(float* to, const float* from, int sx,int sy, int sz) {
+ for (int ix = 0; ix < sx; ix++)
+ for (int iy = 0; iy < sy; iy++) {
+ const int i = ix + iy*sx;
+ downsampleNeumann(&from[i], &to[i], sz, sx*sy);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Wavelet upsampling - periodic boundary conditions
+//////////////////////////////////////////////////////////////////////////////////////////
+static float _upCoeffs[4] = {0.25f, 0.75f, 0.75f, 0.25f};
+static void upsampleX(float *from, float *to, int n) {
+ const float *p = &_upCoeffs[2];
+
+ for (int i = 0; i < n; i++) {
+ to[i] = 0;
+ for (int k = i / 2; k <= i / 2 + 1; k++)
+ to[i] += p[i - 2 * k] * from[modFast64(k)];
+ }
+}
+static void upsampleY(float *from, float *to, int n) {
+ const float *p = &_upCoeffs[2];
+
+ for (int i = 0; i < n; i++) {
+ to[i * n] = 0;
+ for (int k = i / 2; k <= i / 2 + 1; k++)
+ to[i * n] += p[i - 2 * k] * from[modFast64(k) * n];
+ }
+}
+static void upsampleZ(float *from, float *to, int n) {
+ const float *p = &_upCoeffs[2];
+
+ for (int i = 0; i < n; i++) {
+ to[i * n * n] = 0;
+ for (int k = i / 2; k <= i / 2 + 1; k++)
+ to[i * n * n] += p[i - 2 * k] * from[modFast64(k) * n * n];
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Wavelet upsampling - Neumann boundary conditions
+//////////////////////////////////////////////////////////////////////////////////////////
+static void upsampleNeumann(const float *from, float *to, int n, int stride) {
+ static const float *const pCoCenter = &_upCoeffs[2];
+ for (int i = 0; i < n; i++) {
+ to[i * stride] = 0;
+ for (int k = i / 2; k <= i / 2 + 1; k++) {
+ float fromval;
+ if(k>n/2) {
+ fromval = from[(n/2) * stride];
+ } else {
+ fromval = from[k * stride];
+ }
+ to[i * stride] += pCoCenter[i - 2 * k] * fromval;
+ }
+ }
+}
+static void upsampleXNeumann(float* to, const float* from, int sx, int sy, int sz) {
+ for (int iy = 0; iy < sy; iy++)
+ for (int iz = 0; iz < sz; iz++) {
+ const int i = iy * sx + iz*sx*sy;
+ upsampleNeumann(&from[i], &to[i], sx, 1);
+ }
+}
+static void upsampleYNeumann(float* to, const float* from, int sx, int sy, int sz) {
+ for (int ix = 0; ix < sx; ix++)
+ for (int iz = 0; iz < sz; iz++) {
+ const int i = ix + iz*sx*sy;
+ upsampleNeumann(&from[i], &to[i], sy, sx);
+ }
+}
+static void upsampleZNeumann(float* to, const float* from, int sx, int sy, int sz) {
+ for (int ix = 0; ix < sx; ix++)
+ for (int iy = 0; iy < sy; iy++) {
+ const int i = ix + iy*sx;
+ upsampleNeumann(&from[i], &to[i], sz, sx*sy);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// load in an existing noise tile
+//////////////////////////////////////////////////////////////////////////////////////////
+static bool loadTile(float* const noiseTileData, std::string filename)
+{
+ FILE* file;
+ file = fopen(filename.c_str(), "rb");
+
+ if (file == NULL) {
+ printf("loadTile: No noise tile '%s' found.\n", filename.c_str());
+ return false;
+ }
+
+ // dimensions
+ size_t gridSize = noiseTileSize * noiseTileSize * noiseTileSize;
+
+ // noiseTileData memory is managed by caller
+ size_t bread = fread((void*)noiseTileData, sizeof(float), gridSize, file);
+ fclose(file);
+ printf("Noise tile file '%s' loaded.\n", filename.c_str());
+
+ if (bread != gridSize) {
+ printf("loadTile: Noise tile '%s' is wrong size %d.\n", filename.c_str(), (int)bread);
+ return false;
+ }
+ return true;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// write out an existing noise tile
+//////////////////////////////////////////////////////////////////////////////////////////
+static void saveTile(float* const noiseTileData, std::string filename)
+{
+ FILE* file;
+ file = fopen(filename.c_str(), "wb");
+
+ if (file == NULL) {
+ printf("saveTile: Noise tile '%s' could not be saved.\n", filename.c_str());
+ return;
+ }
+
+ fwrite((void*)noiseTileData, sizeof(float), noiseTileSize * noiseTileSize * noiseTileSize, file);
+ fclose(file);
+
+ printf("saveTile: Noise tile file '%s' saved.\n", filename.c_str());
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// create a new noise tile if necessary
+//////////////////////////////////////////////////////////////////////////////////////////
+static void generateTile_WAVELET(float* const noiseTileData, std::string filename) {
+ // if a tile already exists, just use that
+ if (loadTile(noiseTileData, filename)) return;
+
+ const int n = noiseTileSize;
+ const int n3 = n*n*n;
+ std::cout <<"Generating new 3d noise tile size="<<n<<"^3 \n";
+ MTRand twister;
+
+ float *temp13 = new float[n3];
+ float *temp23 = new float[n3];
+ float *noise3 = new float[n3];
+
+ // initialize
+ for (int i = 0; i < n3; i++) {
+ temp13[i] = temp23[i] = noise3[i] = 0.;
+ }
+
+ // Step 1. Fill the tile with random numbers in the range -1 to 1.
+ for (int i = 0; i < n3; i++)
+ noise3[i] = twister.randNorm();
+
+ // Steps 2 and 3. Downsample and upsample the tile
+ for (int iy = 0; iy < n; iy++)
+ for (int iz = 0; iz < n; iz++) {
+ const int i = iy * n + iz*n*n;
+ downsampleX(&noise3[i], &temp13[i], n);
+ upsampleX (&temp13[i], &temp23[i], n);
+ }
+ for (int ix = 0; ix < n; ix++)
+ for (int iz = 0; iz < n; iz++) {
+ const int i = ix + iz*n*n;
+ downsampleY(&temp23[i], &temp13[i], n);
+ upsampleY (&temp13[i], &temp23[i], n);
+ }
+ for (int ix = 0; ix < n; ix++)
+ for (int iy = 0; iy < n; iy++) {
+ const int i = ix + iy*n;
+ downsampleZ(&temp23[i], &temp13[i], n);
+ upsampleZ (&temp13[i], &temp23[i], n);
+ }
+
+ // Step 4. Subtract out the coarse-scale contribution
+ for (int i = 0; i < n3; i++)
+ noise3[i] -= temp23[i];
+
+ // Avoid even/odd variance difference by adding odd-offset version of noise to itself.
+ int offset = n / 2;
+ if (offset % 2 == 0) offset++;
+
+ int icnt=0;
+ for (int ix = 0; ix < n; ix++)
+ for (int iy = 0; iy < n; iy++)
+ for (int iz = 0; iz < n; iz++) {
+ temp13[icnt] = noise3[modFast128(ix+offset) + modFast128(iy+offset)*n + modFast128(iz+offset)*n*n];
+ icnt++;
+ }
+
+ for (int i = 0; i < n3; i++)
+ noise3[i] += temp13[i];
+
+ for (int i = 0; i < n3; i++)
+ noiseTileData[i] = noise3[i];
+
+ saveTile(noise3, filename);
+ delete[] temp13;
+ delete[] temp23;
+ delete[] noise3;
+ std::cout <<"Generating new 3d noise done\n";
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// x derivative of noise
+//////////////////////////////////////////////////////////////////////////////////////////
+static inline float WNoiseDx(Vec3 p, float* data) {
+ int c[3], mid[3], n = noiseTileSize;
+ float w[3][3], t, result = 0;
+
+ mid[0] = (int)ceil(p[0] - 0.5);
+ t = mid[0] - (p[0] - 0.5);
+ w[0][0] = -t;
+ w[0][2] = (1.f - t);
+ w[0][1] = 2.0f * t - 1.0f;
+
+ mid[1] = (int)ceil(p[1] - 0.5);
+ t = mid[1] - (p[1] - 0.5);
+ w[1][0] = t * t / 2;
+ w[1][2] = (1 - t) * (1 - t) / 2;
+ w[1][1] = 1 - w[1][0] - w[1][2];
+
+ mid[2] = (int)ceil(p[2] - 0.5);
+ t = mid[2] - (p[2] - 0.5);
+ w[2][0] = t * t / 2;
+ w[2][2] = (1 - t) * (1 - t)/2;
+ w[2][1] = 1 - w[2][0] - w[2][2];
+
+ // to optimize, explicitly unroll this loop
+ for (int z = -1; z <=1; z++)
+ for (int y = -1; y <=1; y++)
+ for (int x = -1; x <=1; x++)
+ {
+ float weight = 1.0f;
+ c[0] = modFast128(mid[0] + x);
+ weight *= w[0][x+1];
+ c[1] = modFast128(mid[1] + y);
+ weight *= w[1][y+1];
+ c[2] = modFast128(mid[2] + z);
+ weight *= w[2][z+1];
+ result += weight * data[c[2]*n*n+c[1]*n+c[0]];
+ }
+ return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// y derivative of noise
+//////////////////////////////////////////////////////////////////////////////////////////
+static inline float WNoiseDy(Vec3 p, float* data) {
+ int c[3], mid[3], n=noiseTileSize;
+ float w[3][3], t, result =0;
+
+ mid[0] = (int)ceil(p[0] - 0.5);
+ t = mid[0]-(p[0] - 0.5);
+ w[0][0] = t * t / 2;
+ w[0][2] = (1 - t) * (1 - t) / 2;
+ w[0][1] = 1 - w[0][0] - w[0][2];
+
+ mid[1] = (int)ceil(p[1] - 0.5);
+ t = mid[1]-(p[1] - 0.5);
+ w[1][0] = -t;
+ w[1][2] = (1.f - t);
+ w[1][1] = 2.0f * t - 1.0f;
+
+ mid[2] = (int)ceil(p[2] - 0.5);
+ t = mid[2] - (p[2] - 0.5);
+ w[2][0] = t * t / 2;
+ w[2][2] = (1 - t) * (1 - t)/2;
+ w[2][1] = 1 - w[2][0] - w[2][2];
+
+ // to optimize, explicitly unroll this loop
+ for (int z = -1; z <=1; z++)
+ for (int y = -1; y <=1; y++)
+ for (int x = -1; x <=1; x++)
+ {
+ float weight = 1.0f;
+ c[0] = modFast128(mid[0] + x);
+ weight *= w[0][x+1];
+ c[1] = modFast128(mid[1] + y);
+ weight *= w[1][y+1];
+ c[2] = modFast128(mid[2] + z);
+ weight *= w[2][z+1];
+ result += weight * data[c[2]*n*n+c[1]*n+c[0]];
+ }
+
+ return result;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// z derivative of noise
+//////////////////////////////////////////////////////////////////////////////////////////
+static inline float WNoiseDz(Vec3 p, float* data) {
+ int c[3], mid[3], n=noiseTileSize;
+ float w[3][3], t, result =0;
+
+ mid[0] = (int)ceil(p[0] - 0.5);
+ t = mid[0]-(p[0] - 0.5);
+ w[0][0] = t * t / 2;
+ w[0][2] = (1 - t) * (1 - t) / 2;
+ w[0][1] = 1 - w[0][0] - w[0][2];
+
+ mid[1] = (int)ceil(p[1] - 0.5);
+ t = mid[1]-(p[1] - 0.5);
+ w[1][0] = t * t / 2;
+ w[1][2] = (1 - t) * (1 - t) / 2;
+ w[1][1] = 1 - w[1][0] - w[1][2];
+
+ mid[2] = (int)ceil(p[2] - 0.5);
+ t = mid[2] - (p[2] - 0.5);
+ w[2][0] = -t;
+ w[2][2] = (1.f - t);
+ w[2][1] = 2.0f * t - 1.0f;
+
+ // to optimize, explicitly unroll this loop
+ for (int z = -1; z <=1; z++)
+ for (int y = -1; y <=1; y++)
+ for (int x = -1; x <=1; x++)
+ {
+ float weight = 1.0f;
+ c[0] = modFast128(mid[0] + x);
+ weight *= w[0][x+1];
+ c[1] = modFast128(mid[1] + y);
+ weight *= w[1][y+1];
+ c[2] = modFast128(mid[2] + z);
+ weight *= w[2][z+1];
+ result += weight * data[c[2]*n*n+c[1]*n+c[0]];
+ }
+ return result;
+}
+
+#endif
+
diff --git a/intern/smoke/intern/WTURBULENCE.cpp b/intern/smoke/intern/WTURBULENCE.cpp
new file mode 100644
index 00000000000..bcfc61856af
--- /dev/null
+++ b/intern/smoke/intern/WTURBULENCE.cpp
@@ -0,0 +1,988 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+// WTURBULENCE handling
+///////////////////////////////////////////////////////////////////////////////////
+
+#include "WTURBULENCE.h"
+#include "INTERPOLATE.h"
+#include "IMAGE.h"
+#include <MERSENNETWISTER.h>
+#include "WAVELET_NOISE.h"
+#include "FFT_NOISE.h"
+#include "EIGENVALUE_HELPER.h"
+#include "LU_HELPER.h"
+#include "SPHERE.h"
+#include <zlib.h>
+
+// needed to access static advection functions
+#include "FLUID_3D.h"
+
+#if PARALLEL==1
+#include <omp.h>
+#endif // PARALLEL
+
+// 2^ {-5/6}
+static const float persistence = 0.56123f;
+
+//////////////////////////////////////////////////////////////////////
+// constructor
+//////////////////////////////////////////////////////////////////////
+WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype)
+{
+ // if noise magnitude is below this threshold, its contribution
+ // is negilgible, so stop evaluating new octaves
+ _cullingThreshold = 1e-3;
+
+ // factor by which to increase the simulation resolution
+ _amplify = amplify;
+
+ // manually adjust the overall amount of turbulence
+ // DG - RNA-fied _strength = 2.;
+
+ // add the corresponding octaves of noise
+ _octaves = (int)(log((float)_amplify) / log(2.0f) + 0.5); // XXX DEBUG/ TODO: int casting correct? - dg
+
+ // noise resolution
+ _xResBig = _amplify * xResSm;
+ _yResBig = _amplify * yResSm;
+ _zResBig = _amplify * zResSm;
+ _resBig = Vec3Int(_xResBig, _yResBig, _zResBig);
+ _invResBig = Vec3(1./(float)_resBig[0], 1./(float)_resBig[1], 1./(float)_resBig[2]);
+ _slabSizeBig = _xResBig*_yResBig;
+ _totalCellsBig = _slabSizeBig * _zResBig;
+
+ // original / small resolution
+ _xResSm = xResSm;
+ _yResSm = yResSm;
+ _zResSm = zResSm;
+ _resSm = Vec3Int(xResSm, yResSm, zResSm);
+ _invResSm = Vec3(1./(float)_resSm[0], 1./(float)_resSm[1], 1./(float)_resSm[2] );
+ _slabSizeSm = _xResSm*_yResSm;
+ _totalCellsSm = _slabSizeSm * _zResSm;
+
+ // allocate high resolution density field
+ _totalStepsBig = 0;
+ _densityBig = new float[_totalCellsBig];
+ _densityBigOld = new float[_totalCellsBig];
+
+ for(int i = 0; i < _totalCellsBig; i++) {
+ _densityBig[i] =
+ _densityBigOld[i] = 0.;
+ }
+
+ // allocate & init texture coordinates
+ _tcU = new float[_totalCellsSm];
+ _tcV = new float[_totalCellsSm];
+ _tcW = new float[_totalCellsSm];
+ _tcTemp = new float[_totalCellsSm];
+
+ // map all
+ const float dx = 1./(float)(_resSm[0]);
+ const float dy = 1./(float)(_resSm[1]);
+ const float dz = 1./(float)(_resSm[2]);
+ int index = 0;
+ for (int z = 0; z < _zResSm; z++)
+ for (int y = 0; y < _yResSm; y++)
+ for (int x = 0; x < _xResSm; x++, index++)
+ {
+ _tcU[index] = x*dx;
+ _tcV[index] = y*dy;
+ _tcW[index] = z*dz;
+ _tcTemp[index] = 0.;
+ }
+
+ // noise tiles
+ _noiseTile = new float[noiseTileSize * noiseTileSize * noiseTileSize];
+ /*
+ std::string noiseTileFilename = std::string("noise.wavelets");
+ generateTile_WAVELET(_noiseTile, noiseTileFilename);
+ */
+ setNoise(noisetype);
+ /*
+ std::string noiseTileFilename = std::string("noise.fft");
+ generatTile_FFT(_noiseTile, noiseTileFilename);
+ */
+}
+
+//////////////////////////////////////////////////////////////////////
+// destructor
+//////////////////////////////////////////////////////////////////////
+WTURBULENCE::~WTURBULENCE() {
+ delete[] _densityBig;
+ delete[] _densityBigOld;
+
+ delete[] _tcU;
+ delete[] _tcV;
+ delete[] _tcW;
+ delete[] _tcTemp;
+
+ delete[] _noiseTile;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Change noise type
+//
+// type (1<<0) = wavelet / 2
+// type (1<<1) = FFT / 4
+// type (1<<2) = curl / 8
+//////////////////////////////////////////////////////////////////////
+void WTURBULENCE::setNoise(int type)
+{
+ if(type == (1<<1)) // FFT
+ {
+ // needs fft
+ #if FFTW3==1
+ std::string noiseTileFilename = std::string("noise.fft");
+ generatTile_FFT(_noiseTile, noiseTileFilename);
+ #endif
+ }
+ else if(type == (1<<2)) // curl
+ {
+ // TODO: not supported yet
+ }
+ else // standard - wavelet
+ {
+ std::string noiseTileFilename = std::string("noise.wavelets");
+ generateTile_WAVELET(_noiseTile, noiseTileFilename);
+ }
+}
+
+// init direct access functions from blender
+void WTURBULENCE::initBlenderRNA(float *strength)
+{
+ _strength = strength;
+}
+
+//////////////////////////////////////////////////////////////////////
+// Get the smallest valid x derivative
+//
+// Takes the one-sided finite difference in both directions and
+// selects the smaller of the two
+//////////////////////////////////////////////////////////////////////
+static float minDx(int x, int y, int z, float* input, Vec3Int res)
+{
+ const int index = x + y * res[0] + z * res[0] * res[1];
+ const int maxx = res[0]-2;
+
+ // get grid values
+ float center = input[index];
+ float left = (x <= 1) ? FLT_MAX : input[index - 1];
+ float right = (x >= maxx) ? FLT_MAX : input[index + 1];
+
+ const float dx = res[0];
+
+ // get all the derivative estimates
+ float dLeft = (x <= 1) ? FLT_MAX : (center - left) * dx;
+ float dRight = (x >= maxx) ? FLT_MAX : (right - center) * dx;
+ float dCenter = (x <= 1 || x >= maxx) ? FLT_MAX : (right - left) * dx * 0.5f;
+
+ // if it's on a boundary, only one estimate is valid
+ if (x <= 1) return dRight;
+ if (x >= maxx) return dLeft;
+
+ // if it's not on a boundary, get the smallest one
+ float finalD;
+ finalD = (fabs(dCenter) < fabs(dRight)) ? dCenter : dRight;
+ finalD = (fabs(finalD) < fabs(dLeft)) ? finalD : dLeft;
+
+ return finalD;
+}
+
+//////////////////////////////////////////////////////////////////////
+// get the smallest valid y derivative
+//
+// Takes the one-sided finite difference in both directions and
+// selects the smaller of the two
+//////////////////////////////////////////////////////////////////////
+static float minDy(int x, int y, int z, float* input, Vec3Int res)
+{
+ const int index = x + y * res[0] + z * res[0] * res[1];
+ const int maxy = res[1]-2;
+
+ // get grid values
+ float center = input[index];
+ float down = (y <= 1) ? FLT_MAX : input[index - res[0]];
+ float up = (y >= maxy) ? FLT_MAX : input[index + res[0]];
+
+ const float dx = res[1]; // only for square domains
+
+ // get all the derivative estimates
+ float dDown = (y <= 1) ? FLT_MAX : (center - down) * dx;
+ float dUp = (y >= maxy) ? FLT_MAX : (up - center) * dx;
+ float dCenter = (y <= 1 || y >= maxy) ? FLT_MAX : (up - down) * dx * 0.5f;
+
+ // if it's on a boundary, only one estimate is valid
+ if (y <= 1) return dUp;
+ if (y >= maxy) return dDown;
+
+ // if it's not on a boundary, get the smallest one
+ float finalD = (fabs(dCenter) < fabs(dUp)) ? dCenter : dUp;
+ finalD = (fabs(finalD) < fabs(dDown)) ? finalD : dDown;
+
+ return finalD;
+}
+
+//////////////////////////////////////////////////////////////////////
+// get the smallest valid z derivative
+//
+// Takes the one-sided finite difference in both directions and
+// selects the smaller of the two
+//////////////////////////////////////////////////////////////////////
+static float minDz(int x, int y, int z, float* input, Vec3Int res)
+{
+ const int slab = res[0]*res[1];
+ const int index = x + y * res[0] + z * slab;
+ const int maxz = res[2]-2;
+
+ // get grid values
+ float center = input[index];
+ float front = (z <= 1) ? FLT_MAX : input[index - slab];
+ float back = (z >= maxz) ? FLT_MAX : input[index + slab];
+
+ const float dx = res[2]; // only for square domains
+
+ // get all the derivative estimates
+ float dfront = (z <= 1) ? FLT_MAX : (center - front) * dx;
+ float dback = (z >= maxz) ? FLT_MAX : (back - center) * dx;
+ float dCenter = (z <= 1 || z >= maxz) ? FLT_MAX : (back - front) * dx * 0.5f;
+
+ // if it's on a boundary, only one estimate is valid
+ if (z <= 1) return dback;
+ if (z >= maxz) return dfront;
+
+ // if it's not on a boundary, get the smallest one
+ float finalD = (fabs(dCenter) < fabs(dback)) ? dCenter : dback;
+ finalD = (fabs(finalD) < fabs(dfront)) ? finalD : dfront;
+
+ return finalD;
+}
+
+//////////////////////////////////////////////////////////////////////
+// handle texture coordinates (advection, reset, eigenvalues),
+// Beware -- uses big density maccormack as temporary arrays
+//////////////////////////////////////////////////////////////////////
+void WTURBULENCE::advectTextureCoordinates (float dtOrg, float* xvel, float* yvel, float* zvel, float *tempBig1, float *tempBig2) {
+ // advection
+ SWAP_POINTERS(_tcTemp, _tcU);
+ FLUID_3D::copyBorderX(_tcTemp, _resSm);
+ FLUID_3D::copyBorderY(_tcTemp, _resSm);
+ FLUID_3D::copyBorderZ(_tcTemp, _resSm);
+ FLUID_3D::advectFieldMacCormack(dtOrg, xvel, yvel, zvel,
+ _tcTemp, _tcU, tempBig1, tempBig2, _resSm, NULL);
+
+ SWAP_POINTERS(_tcTemp, _tcV);
+ FLUID_3D::copyBorderX(_tcTemp, _resSm);
+ FLUID_3D::copyBorderY(_tcTemp, _resSm);
+ FLUID_3D::copyBorderZ(_tcTemp, _resSm);
+ FLUID_3D::advectFieldMacCormack(dtOrg, xvel, yvel, zvel,
+ _tcTemp, _tcV, tempBig1, tempBig2, _resSm, NULL);
+
+ SWAP_POINTERS(_tcTemp, _tcW);
+ FLUID_3D::copyBorderX(_tcTemp, _resSm);
+ FLUID_3D::copyBorderY(_tcTemp, _resSm);
+ FLUID_3D::copyBorderZ(_tcTemp, _resSm);
+ FLUID_3D::advectFieldMacCormack(dtOrg, xvel, yvel, zvel,
+ _tcTemp, _tcW, tempBig1, tempBig2, _resSm, NULL);
+}
+
+//////////////////////////////////////////////////////////////////////
+// Compute the eigenvalues of the advected texture
+//////////////////////////////////////////////////////////////////////
+void WTURBULENCE::computeEigenvalues(float *_eigMin, float *_eigMax) {
+ // stats
+ float maxeig = -1.;
+ float mineig = 10.;
+
+ // texture coordinate eigenvalues
+ for (int z = 1; z < _zResSm-1; z++) {
+ for (int y = 1; y < _yResSm-1; y++)
+ for (int x = 1; x < _xResSm-1; x++)
+ {
+ const int index = x+ y *_resSm[0] + z*_slabSizeSm;
+
+ // compute jacobian
+ float jacobian[3][3] = {
+ { minDx(x, y, z, _tcU, _resSm), minDx(x, y, z, _tcV, _resSm), minDx(x, y, z, _tcW, _resSm) } ,
+ { minDy(x, y, z, _tcU, _resSm), minDy(x, y, z, _tcV, _resSm), minDy(x, y, z, _tcW, _resSm) } ,
+ { minDz(x, y, z, _tcU, _resSm), minDz(x, y, z, _tcV, _resSm), minDz(x, y, z, _tcW, _resSm) }
+ };
+
+ // ONLY compute the eigenvalues after checking that the matrix
+ // is nonsingular
+ JAMA::LU<float> LU = computeLU3x3(jacobian);
+
+ if (LU.isNonsingular())
+ {
+ // get the analytic eigenvalues, quite slow right now...
+ Vec3 eigenvalues = Vec3(1.);
+ computeEigenvalues3x3( &eigenvalues[0], jacobian);
+ _eigMax[index] = MAX3V(eigenvalues);
+ _eigMin[index] = MIN3V(eigenvalues);
+ maxeig = MAX(_eigMax[index],maxeig);
+ mineig = MIN(_eigMin[index],mineig);
+ }
+ else
+ {
+ _eigMax[index] = 10.0f;
+ _eigMin[index] = 0.1;
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// advect & reset texture coordinates based on eigenvalues
+//////////////////////////////////////////////////////////////////////
+void WTURBULENCE::resetTextureCoordinates(float *_eigMin, float *_eigMax)
+{
+ // allowed deformation of the textures
+ const float limit = 2.f;
+ const float limitInv = 1./limit;
+
+ // standard reset
+ int resets = 0;
+ const float dx = 1./(float)(_resSm[0]);
+ const float dy = 1./(float)(_resSm[1]);
+ const float dz = 1./(float)(_resSm[2]);
+
+ for (int z = 1; z < _zResSm-1; z++)
+ for (int y = 1; y < _yResSm-1; y++)
+ for (int x = 1; x < _xResSm-1; x++)
+ {
+ const int index = x+ y *_resSm[0] + z*_slabSizeSm;
+ if (_eigMax[index] > limit || _eigMin[index] < limitInv)
+ {
+ _tcU[index] = (float)x * dx;
+ _tcV[index] = (float)y * dy;
+ _tcW[index] = (float)z * dz;
+ resets++;
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// Compute the highest frequency component of the wavelet
+// decomposition
+//////////////////////////////////////////////////////////////////////
+void WTURBULENCE::decomposeEnergy(float *_energy, float *_highFreqEnergy)
+{
+ // do the decomposition -- the goal here is to have
+ // the energy with the high frequency component stomped out
+ // stored in _tcTemp when it is done. _highFreqEnergy is only used
+ // as an additional temp array
+
+ // downsample input
+ downsampleXNeumann(_highFreqEnergy, _energy, _xResSm, _yResSm, _zResSm);
+ downsampleYNeumann(_tcTemp, _highFreqEnergy, _xResSm, _yResSm, _zResSm);
+ downsampleZNeumann(_highFreqEnergy, _tcTemp, _xResSm, _yResSm, _zResSm);
+
+ // upsample input
+ upsampleZNeumann(_tcTemp, _highFreqEnergy, _xResSm, _yResSm, _zResSm);
+ upsampleYNeumann(_highFreqEnergy, _tcTemp, _xResSm, _yResSm, _zResSm);
+ upsampleXNeumann(_tcTemp, _highFreqEnergy, _xResSm, _yResSm, _zResSm);
+
+ // subtract the down and upsampled field from the original field --
+ // what should be left over is solely the high frequency component
+ int index = 0;
+ for (int z = 0; z < _zResSm; z++)
+ for (int y = 0; y < _yResSm; y++) {
+ for (int x = 0; x < _xResSm; x++, index++) {
+ // brute force reset of boundaries
+ if(z >= _zResSm - 1 || x >= _xResSm - 1 || y >= _yResSm - 1 || z <= 0 || y <= 0 || x <= 0)
+ _highFreqEnergy[index] = 0.;
+ else
+ _highFreqEnergy[index] = _energy[index] - _tcTemp[index];
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////
+// compute velocity from energies and march into obstacles
+// for wavelet decomposition
+//////////////////////////////////////////////////////////////////////
+void WTURBULENCE::computeEnergy(float *_energy, float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
+{
+ // compute everywhere
+ for (int x = 0; x < _totalCellsSm; x++)
+ _energy[x] = 0.5f * (xvel[x] * xvel[x] + yvel[x] * yvel[x] + zvel[x] * zvel[x]);
+
+ FLUID_3D::copyBorderX(_energy, _resSm);
+ FLUID_3D::copyBorderY(_energy, _resSm);
+ FLUID_3D::copyBorderZ(_energy, _resSm);
+
+ // pseudo-march the values into the obstacles
+ // the wavelet upsampler only uses a 3x3 support neighborhood, so
+ // propagating the values in by 4 should be sufficient
+ int index;
+
+ // iterate
+ for (int iter = 0; iter < 4; iter++)
+ {
+ index = _slabSizeSm + _xResSm + 1;
+ for (int z = 1; z < _zResSm - 1; z++, index += 2 * _xResSm)
+ for (int y = 1; y < _yResSm - 1; y++, index += 2)
+ for (int x = 1; x < _xResSm - 1; x++, index++)
+ if (obstacles[index] && obstacles[index] != RETIRED)
+ {
+ float sum = 0.0f;
+ int valid = 0;
+
+ if (!obstacles[index + 1] || obstacles[index + 1] == RETIRED)
+ {
+ sum += _energy[index + 1];
+ valid++;
+ }
+ if (!obstacles[index - 1] || obstacles[index - 1] == RETIRED)
+ {
+ sum += _energy[index - 1];
+ valid++;
+ }
+ if (!obstacles[index + _xResSm] || obstacles[index + _xResSm] == RETIRED)
+ {
+ sum += _energy[index + _xResSm];
+ valid++;
+ }
+ if (!obstacles[index - _xResSm] || obstacles[index - _xResSm] == RETIRED)
+ {
+ sum += _energy[index - _xResSm];
+ valid++;
+ }
+ if (!obstacles[index + _slabSizeSm] || obstacles[index + _slabSizeSm] == RETIRED)
+ {
+ sum += _energy[index + _slabSizeSm];
+ valid++;
+ }
+ if (!obstacles[index - _slabSizeSm] || obstacles[index - _slabSizeSm] == RETIRED)
+ {
+ sum += _energy[index - _slabSizeSm];
+ valid++;
+ }
+ if (valid > 0)
+ {
+ _energy[index] = sum / (float)valid;
+ obstacles[index] = MARCHED;
+ }
+ }
+ index = _slabSizeSm + _xResSm + 1;
+ for (int z = 1; z < _zResSm - 1; z++, index += 2 * _xResSm)
+ for (int y = 1; y < _yResSm - 1; y++, index += 2)
+ for (int x = 1; x < _xResSm - 1; x++, index++)
+ if (obstacles[index] == MARCHED)
+ obstacles[index] = RETIRED;
+ }
+ index = _slabSizeSm + _xResSm + 1;
+ for (int z = 1; z < _zResSm - 1; z++, index += 2 * _xResSm)
+ for (int y = 1; y < _yResSm - 1; y++, index += 2)
+ for (int x = 1; x < _xResSm - 1; x++, index++)
+ if (obstacles[index])
+ obstacles[index] = 1;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Evaluate derivatives
+//////////////////////////////////////////////////////////////////////////////////////////
+Vec3 WTURBULENCE::WVelocity(Vec3 orgPos)
+{
+ // arbitrarily offset evaluation points
+ const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2.0,0,0);
+ const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2.0,0);
+ const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2.0);
+
+ const float f1y = WNoiseDy(p1, _noiseTile);
+ const float f1z = WNoiseDz(p1, _noiseTile);
+
+ const float f2x = WNoiseDx(p2, _noiseTile);
+ const float f2z = WNoiseDz(p2, _noiseTile);
+
+ const float f3x = WNoiseDx(p3, _noiseTile);
+ const float f3y = WNoiseDy(p3, _noiseTile);
+
+ Vec3 ret = Vec3(
+ f3y - f2z,
+ f1z - f3x,
+ f2x - f1y );
+ return ret;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// Evaluate derivatives with Jacobian
+//////////////////////////////////////////////////////////////////////////////////////////
+Vec3 WTURBULENCE::WVelocityWithJacobian(Vec3 orgPos, float* xUnwarped, float* yUnwarped, float* zUnwarped)
+{
+ // arbitrarily offset evaluation points
+ const Vec3 p1 = orgPos + Vec3(NOISE_TILE_SIZE/2.0,0,0);
+ const Vec3 p2 = orgPos + Vec3(0,NOISE_TILE_SIZE/2.0,0);
+ const Vec3 p3 = orgPos + Vec3(0,0,NOISE_TILE_SIZE/2.0);
+
+ Vec3 final;
+ final[0] = WNoiseDx(p1, _noiseTile);
+ final[1] = WNoiseDy(p1, _noiseTile);
+ final[2] = WNoiseDz(p1, _noiseTile);
+ // UNUSED const float f1x = xUnwarped[0] * final[0] + xUnwarped[1] * final[1] + xUnwarped[2] * final[2];
+ const float f1y = yUnwarped[0] * final[0] + yUnwarped[1] * final[1] + yUnwarped[2] * final[2];
+ const float f1z = zUnwarped[0] * final[0] + zUnwarped[1] * final[1] + zUnwarped[2] * final[2];
+
+ final[0] = WNoiseDx(p2, _noiseTile);
+ final[1] = WNoiseDy(p2, _noiseTile);
+ final[2] = WNoiseDz(p2, _noiseTile);
+ const float f2x = xUnwarped[0] * final[0] + xUnwarped[1] * final[1] + xUnwarped[2] * final[2];
+ // UNUSED const float f2y = yUnwarped[0] * final[0] + yUnwarped[1] * final[1] + yUnwarped[2] * final[2];
+ const float f2z = zUnwarped[0] * final[0] + zUnwarped[1] * final[1] + zUnwarped[2] * final[2];
+
+ final[0] = WNoiseDx(p3, _noiseTile);
+ final[1] = WNoiseDy(p3, _noiseTile);
+ final[2] = WNoiseDz(p3, _noiseTile);
+ const float f3x = xUnwarped[0] * final[0] + xUnwarped[1] * final[1] + xUnwarped[2] * final[2];
+ const float f3y = yUnwarped[0] * final[0] + yUnwarped[1] * final[1] + yUnwarped[2] * final[2];
+ // UNUSED const float f3z = zUnwarped[0] * final[0] + zUnwarped[1] * final[1] + zUnwarped[2] * final[2];
+
+ Vec3 ret = Vec3(
+ f3y - f2z,
+ f1z - f3x,
+ f2x - f1y );
+ return ret;
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// perform an actual noise advection step
+//////////////////////////////////////////////////////////////////////
+void WTURBULENCE::stepTurbulenceReadable(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
+{
+ // enlarge timestep to match grid
+ const float dt = dtOrg * _amplify;
+ const float invAmp = 1.0f / _amplify;
+ float *tempBig1 = new float[_totalCellsBig];
+ float *tempBig2 = new float[_totalCellsBig];
+ float *bigUx = new float[_totalCellsBig];
+ float *bigUy = new float[_totalCellsBig];
+ float *bigUz = new float[_totalCellsBig];
+ float *_energy = new float[_totalCellsSm];
+ float *highFreqEnergy = new float[_totalCellsSm];
+ float *eigMin = new float[_totalCellsSm];
+ float *eigMax = new float[_totalCellsSm];
+
+ memset(tempBig1, 0, sizeof(float)*_totalCellsBig);
+ memset(tempBig2, 0, sizeof(float)*_totalCellsBig);
+ memset(highFreqEnergy, 0, sizeof(float)*_totalCellsSm);
+ memset(eigMin, 0, sizeof(float)*_totalCellsSm);
+ memset(eigMax, 0, sizeof(float)*_totalCellsSm);
+
+ // prepare textures
+ advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2);
+
+ // compute eigenvalues of the texture coordinates
+ computeEigenvalues(eigMin, eigMax);
+
+ // do wavelet decomposition of energy
+ computeEnergy(_energy, xvel, yvel, zvel, obstacles);
+ decomposeEnergy(_energy, highFreqEnergy);
+
+ // zero out coefficients inside of the obstacle
+ for (int x = 0; x < _totalCellsSm; x++)
+ if (obstacles[x]) _energy[x] = 0.f;
+
+ float maxVelocity = 0.;
+ for (int z = 1; z < _zResBig - 1; z++)
+ for (int y = 1; y < _yResBig - 1; y++)
+ for (int x = 1; x < _xResBig - 1; x++)
+ {
+ // get unit position for both fine and coarse grid
+ const Vec3 pos = Vec3(x,y,z);
+ const Vec3 posSm = pos * invAmp;
+
+ // get grid index for both fine and coarse grid
+ const int index = x + y *_xResBig + z *_slabSizeBig;
+ const int indexSmall = (int)posSm[0] + (int)posSm[1] * _xResSm + (int)posSm[2] * _slabSizeSm;
+
+ // get a linearly interpolated velocity and texcoords
+ // from the coarse grid
+ Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel,
+ posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
+ Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW,
+ posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
+
+ // multiply the texture coordinate by _resSm so that turbulence
+ // synthesis begins at the first octave that the coarse grid
+ // cannot capture
+ Vec3 texCoord = Vec3(uvw[0] * _resSm[0],
+ uvw[1] * _resSm[1],
+ uvw[2] * _resSm[2]);
+
+ // retrieve wavelet energy at highest frequency
+ float energy = INTERPOLATE::lerp3d(
+ highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm);
+
+ // base amplitude for octave 0
+ float coefficient = sqrtf(2.0f * fabs(energy));
+ const float amplitude = *_strength * fabs(0.5 * coefficient) * persistence;
+
+ // add noise to velocity, but only if the turbulence is
+ // sufficiently undeformed, and the energy is large enough
+ // to make a difference
+ const bool addNoise = eigMax[indexSmall] < 2. &&
+ eigMin[indexSmall] > 0.5;
+ if (addNoise && amplitude > _cullingThreshold) {
+ // base amplitude for octave 0
+ float amplitudeScaled = amplitude;
+
+ for (int octave = 0; octave < _octaves; octave++)
+ {
+ // multiply the vector noise times the maximum allowed
+ // noise amplitude at this octave, and add it to the total
+ vel += WVelocity(texCoord) * amplitudeScaled;
+
+ // scale coefficient for next octave
+ amplitudeScaled *= persistence;
+ texCoord *= 2.0f;
+ }
+ }
+
+ // Store velocity + turbulence in big grid for maccormack step
+ //
+ // If you wanted to save memory, you would instead perform a
+ // semi-Lagrangian backtrace for the current grid cell here. Then
+ // you could just throw the velocity away.
+ bigUx[index] = vel[0];
+ bigUy[index] = vel[1];
+ bigUz[index] = vel[2];
+
+ // compute the velocity magnitude for substepping later
+ const float velMag = bigUx[index] * bigUx[index] +
+ bigUy[index] * bigUy[index] +
+ bigUz[index] * bigUz[index];
+ if (velMag > maxVelocity) maxVelocity = velMag;
+
+ // zero out velocity inside obstacles
+ float obsCheck = INTERPOLATE::lerp3dToFloat(
+ obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm);
+ if (obsCheck > 0.95)
+ bigUx[index] = bigUy[index] = bigUz[index] = 0.;
+ }
+
+ // prepare density for an advection
+ SWAP_POINTERS(_densityBig, _densityBigOld);
+
+ // based on the maximum velocity present, see if we need to substep,
+ // but cap the maximum number of substeps to 5
+ const int maxSubSteps = 5;
+ maxVelocity = sqrt(maxVelocity) * dt;
+ int totalSubsteps = (int)(maxVelocity / (float)maxSubSteps);
+ totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps;
+ totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps;
+ const float dtSubdiv = dt / (float)totalSubsteps;
+
+ // set boundaries of big velocity grid
+ FLUID_3D::setZeroX(bigUx, _resBig);
+ FLUID_3D::setZeroY(bigUy, _resBig);
+ FLUID_3D::setZeroZ(bigUz, _resBig);
+
+ // do the MacCormack advection, with substepping if necessary
+ for(int substep = 0; substep < totalSubsteps; substep++)
+ {
+ FLUID_3D::advectFieldMacCormack(dtSubdiv, bigUx, bigUy, bigUz,
+ _densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL);
+
+ if (substep < totalSubsteps - 1)
+ SWAP_POINTERS(_densityBig, _densityBigOld);
+ } // substep
+
+ // wipe the density borders
+ FLUID_3D::setZeroBorder(_densityBig, _resBig);
+
+ // reset texture coordinates now in preparation for next timestep
+ // Shouldn't do this before generating the noise because then the
+ // eigenvalues stored do not reflect the underlying texture coordinates
+ resetTextureCoordinates(eigMin, eigMax);
+
+ delete[] tempBig1;
+ delete[] tempBig2;
+ delete[] bigUx;
+ delete[] bigUy;
+ delete[] bigUz;
+ delete[] _energy;
+ delete[] highFreqEnergy;
+
+ delete[] eigMin;
+ delete[] eigMax;
+
+
+ _totalStepsBig++;
+}
+
+//////////////////////////////////////////////////////////////////////
+// perform the full turbulence algorithm, including OpenMP
+// if available
+//////////////////////////////////////////////////////////////////////
+void WTURBULENCE::stepTurbulenceFull(float dtOrg, float* xvel, float* yvel, float* zvel, unsigned char *obstacles)
+{
+ // enlarge timestep to match grid
+ const float dt = dtOrg * _amplify;
+ const float invAmp = 1.0f / _amplify;
+ float *tempBig1 = new float[_totalCellsBig];
+ float *tempBig2 = new float[_totalCellsBig];
+ float *bigUx = new float[_totalCellsBig];
+ float *bigUy = new float[_totalCellsBig];
+ float *bigUz = new float[_totalCellsBig];
+ float *_energy = new float[_totalCellsSm];
+ float *highFreqEnergy = new float[_totalCellsSm];
+ float *eigMin = new float[_totalCellsSm];
+ float *eigMax = new float[_totalCellsSm];
+
+ memset(highFreqEnergy, 0, sizeof(float)*_totalCellsSm);
+ memset(eigMin, 0, sizeof(float)*_totalCellsSm);
+ memset(eigMax, 0, sizeof(float)*_totalCellsSm);
+
+ // prepare textures
+ advectTextureCoordinates(dtOrg, xvel,yvel,zvel, tempBig1, tempBig2);
+
+ // do wavelet decomposition of energy
+ computeEnergy(_energy, xvel, yvel, zvel, obstacles);
+
+ for (int x = 0; x < _totalCellsSm; x++)
+ if (obstacles[x]) _energy[x] = 0.f;
+
+ decomposeEnergy(_energy, highFreqEnergy);
+
+ // zero out coefficients inside of the obstacle
+ for (int x = 0; x < _totalCellsSm; x++)
+ if (obstacles[x]) highFreqEnergy[x] = 0.f;
+
+ Vec3Int ressm(_xResSm, _yResSm, _zResSm);
+ FLUID_3D::setNeumannX(highFreqEnergy, ressm);
+ FLUID_3D::setNeumannY(highFreqEnergy, ressm);
+ FLUID_3D::setNeumannZ(highFreqEnergy, ressm);
+
+ // parallel region setup
+ float maxVelMagThreads[8] = { -1., -1., -1., -1., -1., -1., -1., -1. };
+#if PARALLEL==1
+#pragma omp parallel
+#endif
+ { float maxVelMag1 = 0.;
+#if PARALLEL==1
+ const int id = omp_get_thread_num(); /*, num = omp_get_num_threads(); */
+#endif
+
+ // vector noise main loop
+#if PARALLEL==1
+#pragma omp for schedule(static)
+#endif
+ for (int zSmall = 0; zSmall < _zResSm; zSmall++)
+ for (int ySmall = 0; ySmall < _yResSm; ySmall++)
+ for (int xSmall = 0; xSmall < _xResSm; xSmall++)
+ {
+ const int indexSmall = xSmall + ySmall * _xResSm + zSmall * _slabSizeSm;
+
+ // compute jacobian
+ float jacobian[3][3] = {
+ { minDx(xSmall, ySmall, zSmall, _tcU, _resSm), minDx(xSmall, ySmall, zSmall, _tcV, _resSm), minDx(xSmall, ySmall, zSmall, _tcW, _resSm) } ,
+ { minDy(xSmall, ySmall, zSmall, _tcU, _resSm), minDy(xSmall, ySmall, zSmall, _tcV, _resSm), minDy(xSmall, ySmall, zSmall, _tcW, _resSm) } ,
+ { minDz(xSmall, ySmall, zSmall, _tcU, _resSm), minDz(xSmall, ySmall, zSmall, _tcV, _resSm), minDz(xSmall, ySmall, zSmall, _tcW, _resSm) }
+ };
+
+ // get LU factorization of texture jacobian and apply
+ // it to unit vectors
+ JAMA::LU<float> LU = computeLU3x3(jacobian);
+ float xUnwarped[] = {1.0f, 0.0f, 0.0f};
+ float yUnwarped[] = {0.0f, 1.0f, 0.0f};
+ float zUnwarped[] = {0.0f, 0.0f, 1.0f};
+ float xWarped[] = {1.0f, 0.0f, 0.0f};
+ float yWarped[] = {0.0f, 1.0f, 0.0f};
+ float zWarped[] = {0.0f, 0.0f, 1.0f};
+ bool nonSingular = LU.isNonsingular();
+#if 0
+ // UNUSED
+ float eigMax = 10.0f;
+ float eigMin = 0.1f;
+#endif
+ if (nonSingular)
+ {
+ solveLU3x3(LU, xUnwarped, xWarped);
+ solveLU3x3(LU, yUnwarped, yWarped);
+ solveLU3x3(LU, zUnwarped, zWarped);
+
+ // compute the eigenvalues while we have the Jacobian available
+ Vec3 eigenvalues = Vec3(1.);
+ computeEigenvalues3x3( &eigenvalues[0], jacobian);
+ eigMax[indexSmall] = MAX3V(eigenvalues);
+ eigMin[indexSmall] = MIN3V(eigenvalues);
+ }
+
+ // make sure to skip one on the beginning and end
+ int xStart = (xSmall == 0) ? 1 : 0;
+ int xEnd = (xSmall == _xResSm - 1) ? _amplify - 1 : _amplify;
+ int yStart = (ySmall == 0) ? 1 : 0;
+ int yEnd = (ySmall == _yResSm - 1) ? _amplify - 1 : _amplify;
+ int zStart = (zSmall == 0) ? 1 : 0;
+ int zEnd = (zSmall == _zResSm - 1) ? _amplify - 1 : _amplify;
+
+ for (int zBig = zStart; zBig < zEnd; zBig++)
+ for (int yBig = yStart; yBig < yEnd; yBig++)
+ for (int xBig = xStart; xBig < xEnd; xBig++)
+ {
+ const int x = xSmall * _amplify + xBig;
+ const int y = ySmall * _amplify + yBig;
+ const int z = zSmall * _amplify + zBig;
+
+ // get unit position for both fine and coarse grid
+ const Vec3 pos = Vec3(x,y,z);
+ const Vec3 posSm = pos * invAmp;
+
+ // get grid index for both fine and coarse grid
+ const int index = x + y *_xResBig + z *_slabSizeBig;
+
+ // get a linearly interpolated velocity and texcoords
+ // from the coarse grid
+ Vec3 vel = INTERPOLATE::lerp3dVec( xvel,yvel,zvel,
+ posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
+ Vec3 uvw = INTERPOLATE::lerp3dVec( _tcU,_tcV,_tcW,
+ posSm[0], posSm[1], posSm[2], _xResSm,_yResSm,_zResSm);
+
+ // multiply the texture coordinate by _resSm so that turbulence
+ // synthesis begins at the first octave that the coarse grid
+ // cannot capture
+ Vec3 texCoord = Vec3(uvw[0] * _resSm[0],
+ uvw[1] * _resSm[1],
+ uvw[2] * _resSm[2]);
+
+ // retrieve wavelet energy at highest frequency
+ float energy = INTERPOLATE::lerp3d(
+ highFreqEnergy, posSm[0],posSm[1],posSm[2], _xResSm, _yResSm, _zResSm);
+
+ // base amplitude for octave 0
+ float coefficient = sqrtf(2.0f * fabs(energy));
+ const float amplitude = *_strength * fabs(0.5 * coefficient) * persistence;
+
+ // add noise to velocity, but only if the turbulence is
+ // sufficiently undeformed, and the energy is large enough
+ // to make a difference
+ const bool addNoise = eigMax[indexSmall] < 2. &&
+ eigMin[indexSmall] > 0.5;
+ if (addNoise && amplitude > _cullingThreshold) {
+ // base amplitude for octave 0
+ float amplitudeScaled = amplitude;
+
+ for (int octave = 0; octave < _octaves; octave++)
+ {
+ // multiply the vector noise times the maximum allowed
+ // noise amplitude at this octave, and add it to the total
+ vel += WVelocityWithJacobian(texCoord, &xUnwarped[0], &yUnwarped[0], &zUnwarped[0]) * amplitudeScaled;
+
+ // scale coefficient for next octave
+ amplitudeScaled *= persistence;
+ texCoord *= 2.0f;
+ }
+ }
+
+ // Store velocity + turbulence in big grid for maccormack step
+ //
+ // If you wanted to save memory, you would instead perform a
+ // semi-Lagrangian backtrace for the current grid cell here. Then
+ // you could just throw the velocity away.
+ bigUx[index] = vel[0];
+ bigUy[index] = vel[1];
+ bigUz[index] = vel[2];
+
+ // compute the velocity magnitude for substepping later
+ const float velMag = bigUx[index] * bigUx[index] +
+ bigUy[index] * bigUy[index] +
+ bigUz[index] * bigUz[index];
+ if (velMag > maxVelMag1) maxVelMag1 = velMag;
+
+ // zero out velocity inside obstacles
+ float obsCheck = INTERPOLATE::lerp3dToFloat(
+ obstacles, posSm[0], posSm[1], posSm[2], _xResSm, _yResSm, _zResSm);
+ if (obsCheck > 0.95)
+ bigUx[index] = bigUy[index] = bigUz[index] = 0.;
+ } // xyz
+
+#if PARALLEL==1
+ maxVelMagThreads[id] = maxVelMag1;
+#else
+ maxVelMagThreads[0] = maxVelMag1;
+#endif
+ }
+ } // omp
+
+ // compute maximum over threads
+ float maxVelMag = maxVelMagThreads[0];
+#if PARALLEL==1
+ for (int i = 1; i < 8; i++)
+ if (maxVelMag < maxVelMagThreads[i])
+ maxVelMag = maxVelMagThreads[i];
+#endif
+
+ // prepare density for an advection
+ SWAP_POINTERS(_densityBig, _densityBigOld);
+
+ // based on the maximum velocity present, see if we need to substep,
+ // but cap the maximum number of substeps to 5
+ const int maxSubSteps = 25;
+ const int maxVel = 5;
+ maxVelMag = sqrt(maxVelMag) * dt;
+ int totalSubsteps = (int)(maxVelMag / (float)maxVel);
+ totalSubsteps = (totalSubsteps < 1) ? 1 : totalSubsteps;
+ // printf("totalSubsteps: %d\n", totalSubsteps);
+ totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps;
+ const float dtSubdiv = dt / (float)totalSubsteps;
+
+ // set boundaries of big velocity grid
+ FLUID_3D::setZeroX(bigUx, _resBig);
+ FLUID_3D::setZeroY(bigUy, _resBig);
+ FLUID_3D::setZeroZ(bigUz, _resBig);
+
+ // do the MacCormack advection, with substepping if necessary
+ for(int substep = 0; substep < totalSubsteps; substep++)
+ {
+ FLUID_3D::advectFieldMacCormack(dtSubdiv, bigUx, bigUy, bigUz,
+ _densityBigOld, _densityBig, tempBig1, tempBig2, _resBig, NULL);
+
+ if (substep < totalSubsteps - 1)
+ SWAP_POINTERS(_densityBig, _densityBigOld);
+ } // substep
+
+ delete[] tempBig1;
+ delete[] tempBig2;
+ delete[] bigUx;
+ delete[] bigUy;
+ delete[] bigUz;
+ delete[] _energy;
+ delete[] highFreqEnergy;
+
+ // wipe the density borders
+ FLUID_3D::setZeroBorder(_densityBig, _resBig);
+
+ // reset texture coordinates now in preparation for next timestep
+ // Shouldn't do this before generating the noise because then the
+ // eigenvalues stored do not reflect the underlying texture coordinates
+ resetTextureCoordinates(eigMin, eigMax);
+
+ delete[] eigMin;
+ delete[] eigMax;
+
+ // output files
+ // string prefix = string("./amplified.preview/density_bigxy_");
+ // FLUID_3D::writeImageSliceXY(_densityBig, _resBig, _resBig[2]/2, prefix, _totalStepsBig, 1.0f);
+ //string df3prefix = string("./df3/density_big_");
+ //IMAGE::dumpDF3(_totalStepsBig, df3prefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
+ // string pbrtPrefix = string("./pbrt/density_big_");
+ // IMAGE::dumpPBRT(_totalStepsBig, pbrtPrefix, _densityBig, _resBig[0],_resBig[1],_resBig[2]);
+
+ _totalStepsBig++;
+}
diff --git a/intern/smoke/intern/WTURBULENCE.h b/intern/smoke/intern/WTURBULENCE.h
new file mode 100644
index 00000000000..0aa978e9e52
--- /dev/null
+++ b/intern/smoke/intern/WTURBULENCE.h
@@ -0,0 +1,130 @@
+//////////////////////////////////////////////////////////////////////
+// This file is part of Wavelet Turbulence.
+//
+// Wavelet Turbulence is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Wavelet Turbulence is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Wavelet Turbulence. If not, see <http://www.gnu.org/licenses/>.
+//
+// Copyright 2008 Theodore Kim and Nils Thuerey
+//
+// WTURBULENCE handling
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef WTURBULENCE_H
+#define WTURBULENCE_H
+
+#include "VEC3.h"
+using namespace BasicVector;
+class SIMPLE_PARSER;
+
+///////////////////////////////////////////////////////////////////////////////
+/// Main WTURBULENCE class, stores large density array etc.
+///////////////////////////////////////////////////////////////////////////////
+class WTURBULENCE
+{
+ public:
+ // both config files can be NULL, altCfg might override values from noiseCfg
+ WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype);
+
+ /// destructor
+ virtual ~WTURBULENCE();
+
+ void setNoise(int type);
+ void initBlenderRNA(float *strength);
+
+ // step more readable version -- no rotation correction
+ void stepTurbulenceReadable(float dt, float* xvel, float* yvel, float* zvel, unsigned char *obstacles);
+
+ // step more complete version -- include rotation correction
+ // and use OpenMP if available
+ void stepTurbulenceFull(float dt, float* xvel, float* yvel, float* zvel, unsigned char *obstacles);
+
+ // texcoord functions
+ void advectTextureCoordinates(float dtOrg, float* xvel, float* yvel, float* zvel, float *tempBig1, float *tempBig2);
+ void resetTextureCoordinates(float *_eigMin, float *_eigMax);
+
+ void computeEnergy(float *energy, float* xvel, float* yvel, float* zvel, unsigned char *obstacles);
+
+ // evaluate wavelet noise function
+ Vec3 WVelocity(Vec3 p);
+ Vec3 WVelocityWithJacobian(Vec3 p, float* xUnwarped, float* yUnwarped, float* zUnwarped);
+
+ // access functions
+ inline float* getDensityBig() { return _densityBig; }
+ inline float* getArrayTcU() { return _tcU; }
+ inline float* getArrayTcV() { return _tcV; }
+ inline float* getArrayTcW() { return _tcW; }
+
+ inline Vec3Int getResSm() { return _resSm; } // small resolution
+ inline Vec3Int getResBig() { return _resBig; }
+ inline int getOctaves() { return _octaves; }
+
+ // is accessed on through rna gui
+ float *_strength;
+
+ // protected:
+ // enlargement factor from original velocity field / simulation
+ // _Big = _amplify * _Sm
+ int _amplify;
+ int _octaves;
+
+ // noise settings
+ float _cullingThreshold;
+ // float _noiseStrength;
+ // float _noiseSizeScale;
+ // bool _uvwAdvection;
+ // bool _uvwReset;
+ // float _noiseTimeanimSpeed;
+ // int _dumpInterval;
+ // nt _noiseControlType;
+ // debug, scale density for projections output images
+ // float _outputScale;
+
+ // noise resolution
+ int _xResBig;
+ int _yResBig;
+ int _zResBig;
+ Vec3Int _resBig;
+ Vec3 _invResBig;
+ int _totalCellsBig;
+ int _slabSizeBig;
+ // original / small resolution
+ int _xResSm;
+ int _yResSm;
+ int _zResSm;
+ Vec3Int _resSm;
+ Vec3 _invResSm;
+ int _totalCellsSm;
+ int _slabSizeSm;
+
+ float* _densityBig;
+ float* _densityBigOld;
+
+ // texture coordinates for noise
+ float* _tcU;
+ float* _tcV;
+ float* _tcW;
+ float* _tcTemp;
+
+ // noise data
+ float* _noiseTile;
+ //float* _noiseTileExt;
+
+ // step counter
+ int _totalStepsBig;
+
+ void computeEigenvalues(float *_eigMin, float *_eigMax);
+ void decomposeEnergy(float *energy, float *_highFreqEnergy);
+};
+
+#endif // WTURBULENCE_H
+
diff --git a/intern/smoke/intern/smoke_API.cpp b/intern/smoke/intern/smoke_API.cpp
new file mode 100644
index 00000000000..67df6e805d8
--- /dev/null
+++ b/intern/smoke/intern/smoke_API.cpp
@@ -0,0 +1,262 @@
+/**
+ * $Id$
+ *
+ * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 by Daniel Genrich
+ * All rights reserved.
+ *
+ * Contributor(s): Daniel Genrich
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "FLUID_3D.h"
+#include "WTURBULENCE.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+
+// y in smoke is z in blender
+extern "C" FLUID_3D *smoke_init(int *res, float *p0, float dt)
+{
+ // smoke lib uses y as top-bottom/vertical axis where blender uses z
+ FLUID_3D *fluid = new FLUID_3D(res, p0, dt);
+
+ // printf("xres: %d, yres: %d, zres: %d\n", res[0], res[1], res[2]);
+
+ return fluid;
+}
+
+extern "C" WTURBULENCE *smoke_turbulence_init(int *res, int amplify, int noisetype)
+{
+ // initialize wavelet turbulence
+ if(amplify)
+ return new WTURBULENCE(res[0],res[1],res[2], amplify, noisetype);
+ else
+ return NULL;
+}
+
+extern "C" void smoke_free(FLUID_3D *fluid)
+{
+ delete fluid;
+ fluid = NULL;
+}
+
+extern "C" void smoke_turbulence_free(WTURBULENCE *wt)
+{
+ delete wt;
+ wt = NULL;
+}
+
+extern "C" size_t smoke_get_index(int x, int max_x, int y, int max_y, int z /*, int max_z */)
+{
+ // // const int index = x + y * smd->res[0] + z * smd->res[0]*smd->res[1];
+ return x + y * max_x + z * max_x*max_y;
+}
+
+extern "C" size_t smoke_get_index2d(int x, int max_x, int y /*, int max_y, int z, int max_z */)
+{
+ return x + y * max_x;
+}
+
+extern "C" void smoke_step(FLUID_3D *fluid, size_t framenr)
+{
+ fluid->step();
+}
+
+extern "C" void smoke_turbulence_step(WTURBULENCE *wt, FLUID_3D *fluid)
+{
+ wt->stepTurbulenceFull(fluid->_dt/fluid->_dx, fluid->_xVelocity, fluid->_yVelocity, fluid->_zVelocity, fluid->_obstacles);
+}
+
+extern "C" void smoke_initBlenderRNA(FLUID_3D *fluid, float *alpha, float *beta)
+{
+ fluid->initBlenderRNA(alpha, beta);
+}
+
+extern "C" void smoke_dissolve(FLUID_3D *fluid, int speed, int log)
+{
+ float *density = fluid->_density;
+ //float *densityOld = fluid->_densityOld;
+ float *heat = fluid->_heat;
+
+ if(log)
+ {
+ /* max density/speed = dydx */
+ float dydx = 1.0 / (float)speed;
+ size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
+
+ for(size_t i = 0; i < size; i++)
+ {
+ density[i] *= (1.0 - dydx);
+
+ if(density[i] < 0.0f)
+ density[i] = 0.0f;
+
+ heat[i] *= (1.0 - dydx);
+
+ if(heat[i] < 0.0f)
+ heat[i] = 0.0f;
+ }
+ }
+ else // linear falloff
+ {
+ /* max density/speed = dydx */
+ float dydx = 1.0 / (float)speed;
+ size_t size= fluid->_xRes * fluid->_yRes * fluid->_zRes;
+
+ for(size_t i = 0; i < size; i++)
+ {
+ density[i] -= dydx;
+
+ if(density[i] < 0.0f)
+ density[i] = 0.0f;
+
+ heat[i] -= dydx;
+
+ if(heat[i] < 0.0f)
+ heat[i] = 0.0f;
+
+ }
+ }
+}
+
+extern "C" void smoke_dissolve_wavelet(WTURBULENCE *wt, int speed, int log)
+{
+ float *density = wt->getDensityBig();
+ Vec3Int r = wt->getResBig();
+
+ if(log)
+ {
+ /* max density/speed = dydx */
+ float dydx = 1.0 / (float)speed;
+ size_t size= r[0] * r[1] * r[2];
+
+ for(size_t i = 0; i < size; i++)
+ {
+ density[i] *= (1.0 - dydx);
+
+ if(density[i] < 0.0f)
+ density[i] = 0.0f;
+ }
+ }
+ else // linear falloff
+ {
+ /* max density/speed = dydx */
+ float dydx = 1.0 / (float)speed;
+ size_t size= r[0] * r[1] * r[2];
+
+ for(size_t i = 0; i < size; i++)
+ {
+ density[i] -= dydx;
+
+ if(density[i] < 0.0f)
+ density[i] = 0.0f;
+ }
+ }
+}
+
+extern "C" void smoke_initWaveletBlenderRNA(WTURBULENCE *wt, float *strength)
+{
+ wt->initBlenderRNA(strength);
+}
+
+template < class T > inline T ABS( T a ) {
+ return (0 < a) ? a : -a ;
+}
+
+extern "C" void smoke_export(FLUID_3D *fluid, float *dt, float *dx, float **dens, float **densold, float **heat, float **heatold, float **vx, float **vy, float **vz, float **vxold, float **vyold, float **vzold, unsigned char **obstacles)
+{
+ *dens = fluid->_density;
+ *densold = fluid->_densityOld;
+ *heat = fluid->_heat;
+ *heatold = fluid->_heatOld;
+ *vx = fluid->_xVelocity;
+ *vy = fluid->_yVelocity;
+ *vz = fluid->_zVelocity;
+ *vxold = fluid->_xVelocityOld;
+ *vyold = fluid->_yVelocityOld;
+ *vzold = fluid->_zVelocityOld;
+ *obstacles = fluid->_obstacles;
+ dt = &(fluid->_dt);
+ dx = &(fluid->_dx);
+
+}
+
+extern "C" void smoke_turbulence_export(WTURBULENCE *wt, float **dens, float **densold, float **tcu, float **tcv, float **tcw)
+{
+ if(!wt)
+ return;
+
+ *dens = wt->_densityBig;
+ *densold = wt->_densityBigOld;
+ *tcu = wt->_tcU;
+ *tcv = wt->_tcV;
+ *tcw = wt->_tcW;
+}
+
+extern "C" float *smoke_get_density(FLUID_3D *fluid)
+{
+ return fluid->_density;
+}
+
+extern "C" float *smoke_get_heat(FLUID_3D *fluid)
+{
+ return fluid->_heat;
+}
+
+extern "C" float *smoke_get_velocity_x(FLUID_3D *fluid)
+{
+ return fluid->_xVelocity;
+}
+
+extern "C" float *smoke_get_velocity_y(FLUID_3D *fluid)
+{
+ return fluid->_yVelocity;
+}
+
+extern "C" float *smoke_get_velocity_z(FLUID_3D *fluid)
+{
+ return fluid->_zVelocity;
+}
+
+extern "C" float *smoke_turbulence_get_density(WTURBULENCE *wt)
+{
+ return wt ? wt->getDensityBig() : NULL;
+}
+
+extern "C" void smoke_turbulence_get_res(WTURBULENCE *wt, int *res)
+{
+ if(wt)
+ {
+ Vec3Int r = wt->getResBig();
+ res[0] = r[0];
+ res[1] = r[1];
+ res[2] = r[2];
+ }
+}
+
+extern "C" unsigned char *smoke_get_obstacle(FLUID_3D *fluid)
+{
+ return fluid->_obstacles;
+}
+
+extern "C" void smoke_turbulence_set_noise(WTURBULENCE *wt, int type)
+{
+ wt->setNoise(type);
+}
diff --git a/intern/smoke/intern/tnt/jama_eig.h b/intern/smoke/intern/tnt/jama_eig.h
new file mode 100644
index 00000000000..0d833be56de
--- /dev/null
+++ b/intern/smoke/intern/tnt/jama_eig.h
@@ -0,0 +1,1050 @@
+#ifndef JAMA_EIG_H
+#define JAMA_EIG_H
+
+
+#include "tnt_array1d.h"
+#include "tnt_array2d.h"
+#include "tnt_math_utils.h"
+
+#include <algorithm>
+// for min(), max() below
+
+#include <cmath>
+// for fabs() below
+
+using namespace TNT;
+using namespace std;
+
+// NT debugging
+//static int gEigenDebug=0;
+//if(gEigenDebug) std::cerr<<"n="<<n<<" m="<<m<<" l="<<l<<"\n";
+// m has to be smaller l! in line 262
+// gcc can get confused with abs calls, replaced by fabs
+
+namespace JAMA
+{
+
+/**
+
+ Computes eigenvalues and eigenvectors of a real (non-complex)
+ matrix.
+<P>
+ If A is symmetric, then A = V*D*V' where the eigenvalue matrix D is
+ diagonal and the eigenvector matrix V is orthogonal. That is,
+ the diagonal values of D are the eigenvalues, and
+ V*V' = I, where I is the identity matrix. The columns of V
+ represent the eigenvectors in the sense that A*V = V*D.
+
+<P>
+ If A is not symmetric, then the eigenvalue matrix D is block diagonal
+ with the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,
+ a + i*b, in 2-by-2 blocks, [a, b; -b, a]. That is, if the complex
+ eigenvalues look like
+<pre>
+
+ u + iv . . . . .
+ . u - iv . . . .
+ . . a + ib . . .
+ . . . a - ib . .
+ . . . . x .
+ . . . . . y
+</pre>
+ then D looks like
+<pre>
+
+ u v . . . .
+ -v u . . . .
+ . . a b . .
+ . . -b a . .
+ . . . . x .
+ . . . . . y
+</pre>
+ This keeps V a real matrix in both symmetric and non-symmetric
+ cases, and A*V = V*D.
+
+
+
+ <p>
+ The matrix V may be badly
+ conditioned, or even singular, so the validity of the equation
+ A = V*D*inverse(V) depends upon the condition number of V.
+
+ <p>
+ (Adapted from JAMA, a Java Matrix Library, developed by jointly
+ by the Mathworks and NIST; see http://math.nist.gov/javanumerics/jama).
+**/
+
+template <class Real>
+class Eigenvalue
+{
+
+
+ /** Row and column dimension (square matrix). */
+ int n;
+
+ int issymmetric; /* boolean*/
+
+ /** Arrays for internal storage of eigenvalues. */
+
+ TNT::Array1D<Real> d; /* real part */
+ TNT::Array1D<Real> e; /* img part */
+
+ /** Array for internal storage of eigenvectors. */
+ TNT::Array2D<Real> V;
+
+ /** Array for internal storage of nonsymmetric Hessenberg form.
+ @serial internal storage of nonsymmetric Hessenberg form.
+ */
+ TNT::Array2D<Real> H;
+
+
+ /** Working storage for nonsymmetric algorithm.
+ @serial working storage for nonsymmetric algorithm.
+ */
+ TNT::Array1D<Real> ort;
+
+
+ // Symmetric Householder reduction to tridiagonal form.
+
+ void tred2() {
+
+ // This is derived from the Algol procedures tred2 by
+ // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+ // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutine in EISPACK.
+
+ for (int j = 0; j < n; j++) {
+ d[j] = V[n-1][j];
+ }
+
+ // Householder reduction to tridiagonal form.
+
+ for (int i = n-1; i > 0; i--) {
+
+ // Scale to avoid under/overflow.
+
+ Real scale = 0.0;
+ Real h = 0.0;
+ for (int k = 0; k < i; k++) {
+ scale = scale + fabs(d[k]);
+ }
+ if (scale == 0.0) {
+ e[i] = d[i-1];
+ for (int j = 0; j < i; j++) {
+ d[j] = V[i-1][j];
+ V[i][j] = 0.0;
+ V[j][i] = 0.0;
+ }
+ } else {
+
+ // Generate Householder vector.
+
+ for (int k = 0; k < i; k++) {
+ d[k] /= scale;
+ h += d[k] * d[k];
+ }
+ Real f = d[i-1];
+ Real g = sqrt(h);
+ if (f > 0) {
+ g = -g;
+ }
+ e[i] = scale * g;
+ h = h - f * g;
+ d[i-1] = f - g;
+ for (int j = 0; j < i; j++) {
+ e[j] = 0.0;
+ }
+
+ // Apply similarity transformation to remaining columns.
+
+ for (int j = 0; j < i; j++) {
+ f = d[j];
+ V[j][i] = f;
+ g = e[j] + V[j][j] * f;
+ for (int k = j+1; k <= i-1; k++) {
+ g += V[k][j] * d[k];
+ e[k] += V[k][j] * f;
+ }
+ e[j] = g;
+ }
+ f = 0.0;
+ for (int j = 0; j < i; j++) {
+ e[j] /= h;
+ f += e[j] * d[j];
+ }
+ Real hh = f / (h + h);
+ for (int j = 0; j < i; j++) {
+ e[j] -= hh * d[j];
+ }
+ for (int j = 0; j < i; j++) {
+ f = d[j];
+ g = e[j];
+ for (int k = j; k <= i-1; k++) {
+ V[k][j] -= (f * e[k] + g * d[k]);
+ }
+ d[j] = V[i-1][j];
+ V[i][j] = 0.0;
+ }
+ }
+ d[i] = h;
+ }
+
+ // Accumulate transformations.
+
+ for (int i = 0; i < n-1; i++) {
+ V[n-1][i] = V[i][i];
+ V[i][i] = 1.0;
+ Real h = d[i+1];
+ if (h != 0.0) {
+ for (int k = 0; k <= i; k++) {
+ d[k] = V[k][i+1] / h;
+ }
+ for (int j = 0; j <= i; j++) {
+ Real g = 0.0;
+ for (int k = 0; k <= i; k++) {
+ g += V[k][i+1] * V[k][j];
+ }
+ for (int k = 0; k <= i; k++) {
+ V[k][j] -= g * d[k];
+ }
+ }
+ }
+ for (int k = 0; k <= i; k++) {
+ V[k][i+1] = 0.0;
+ }
+ }
+ for (int j = 0; j < n; j++) {
+ d[j] = V[n-1][j];
+ V[n-1][j] = 0.0;
+ }
+ V[n-1][n-1] = 1.0;
+ e[0] = 0.0;
+ }
+
+ // Symmetric tridiagonal QL algorithm.
+
+ void tql2 () {
+
+ // This is derived from the Algol procedures tql2, by
+ // Bowdler, Martin, Reinsch, and Wilkinson, Handbook for
+ // Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutine in EISPACK.
+
+ for (int i = 1; i < n; i++) {
+ e[i-1] = e[i];
+ }
+ e[n-1] = 0.0;
+
+ Real f = 0.0;
+ Real tst1 = 0.0;
+ Real eps = pow(2.0,-52.0);
+ for (int l = 0; l < n; l++) {
+
+ // Find small subdiagonal element
+
+ tst1 = max(tst1,fabs(d[l]) + fabs(e[l]));
+ int m = l;
+
+ // Original while-loop from Java code
+ while (m < n) {
+ if (fabs(e[m]) <= eps*tst1) {
+ break;
+ }
+ m++;
+ }
+
+
+ // If m == l, d[l] is an eigenvalue,
+ // otherwise, iterate.
+
+ if (m > l) {
+ int iter = 0;
+ do {
+ iter = iter + 1; // (Could check iteration count here.)
+
+ // Compute implicit shift
+
+ Real g = d[l];
+ Real p = (d[l+1] - g) / (2.0 * e[l]);
+ Real r = hypot(p,1.0);
+ if (p < 0) {
+ r = -r;
+ }
+ d[l] = e[l] / (p + r);
+ d[l+1] = e[l] * (p + r);
+ Real dl1 = d[l+1];
+ Real h = g - d[l];
+ for (int i = l+2; i < n; i++) {
+ d[i] -= h;
+ }
+ f = f + h;
+
+ // Implicit QL transformation.
+
+ p = d[m];
+ Real c = 1.0;
+ Real c2 = c;
+ Real c3 = c;
+ Real el1 = e[l+1];
+ Real s = 0.0;
+ Real s2 = 0.0;
+ for (int i = m-1; i >= l; i--) {
+ c3 = c2;
+ c2 = c;
+ s2 = s;
+ g = c * e[i];
+ h = c * p;
+ r = hypot(p,e[i]);
+ e[i+1] = s * r;
+ s = e[i] / r;
+ c = p / r;
+ p = c * d[i] - s * g;
+ d[i+1] = h + s * (c * g + s * d[i]);
+
+ // Accumulate transformation.
+
+ for (int k = 0; k < n; k++) {
+ h = V[k][i+1];
+ V[k][i+1] = s * V[k][i] + c * h;
+ V[k][i] = c * V[k][i] - s * h;
+ }
+ }
+ p = -s * s2 * c3 * el1 * e[l] / dl1;
+ e[l] = s * p;
+ d[l] = c * p;
+
+ // Check for convergence.
+
+ } while (fabs(e[l]) > eps*tst1);
+ }
+ d[l] = d[l] + f;
+ e[l] = 0.0;
+ }
+
+ // Sort eigenvalues and corresponding vectors.
+
+ for (int i = 0; i < n-1; i++) {
+ int k = i;
+ Real p = d[i];
+ for (int j = i+1; j < n; j++) {
+ if (d[j] < p) {
+ k = j;
+ p = d[j];
+ }
+ }
+ if (k != i) {
+ d[k] = d[i];
+ d[i] = p;
+ for (int j = 0; j < n; j++) {
+ p = V[j][i];
+ V[j][i] = V[j][k];
+ V[j][k] = p;
+ }
+ }
+ }
+ }
+
+ // Nonsymmetric reduction to Hessenberg form.
+
+ void orthes () {
+
+ // This is derived from the Algol procedures orthes and ortran,
+ // by Martin and Wilkinson, Handbook for Auto. Comp.,
+ // Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutines in EISPACK.
+
+ int low = 0;
+ int high = n-1;
+
+ for (int m = low+1; m <= high-1; m++) {
+
+ // Scale column.
+
+ Real scale = 0.0;
+ for (int i = m; i <= high; i++) {
+ scale = scale + fabs(H[i][m-1]);
+ }
+ if (scale != 0.0) {
+
+ // Compute Householder transformation.
+
+ Real h = 0.0;
+ for (int i = high; i >= m; i--) {
+ ort[i] = H[i][m-1]/scale;
+ h += ort[i] * ort[i];
+ }
+ Real g = sqrt(h);
+ if (ort[m] > 0) {
+ g = -g;
+ }
+ h = h - ort[m] * g;
+ ort[m] = ort[m] - g;
+
+ // Apply Householder similarity transformation
+ // H = (I-u*u'/h)*H*(I-u*u')/h)
+
+ for (int j = m; j < n; j++) {
+ Real f = 0.0;
+ for (int i = high; i >= m; i--) {
+ f += ort[i]*H[i][j];
+ }
+ f = f/h;
+ for (int i = m; i <= high; i++) {
+ H[i][j] -= f*ort[i];
+ }
+ }
+
+ for (int i = 0; i <= high; i++) {
+ Real f = 0.0;
+ for (int j = high; j >= m; j--) {
+ f += ort[j]*H[i][j];
+ }
+ f = f/h;
+ for (int j = m; j <= high; j++) {
+ H[i][j] -= f*ort[j];
+ }
+ }
+ ort[m] = scale*ort[m];
+ H[m][m-1] = scale*g;
+ }
+ }
+
+ // Accumulate transformations (Algol's ortran).
+
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ V[i][j] = (i == j ? 1.0 : 0.0);
+ }
+ }
+
+ for (int m = high-1; m >= low+1; m--) {
+ if (H[m][m-1] != 0.0) {
+ for (int i = m+1; i <= high; i++) {
+ ort[i] = H[i][m-1];
+ }
+ for (int j = m; j <= high; j++) {
+ Real g = 0.0;
+ for (int i = m; i <= high; i++) {
+ g += ort[i] * V[i][j];
+ }
+ // Double division avoids possible underflow
+ g = (g / ort[m]) / H[m][m-1];
+ for (int i = m; i <= high; i++) {
+ V[i][j] += g * ort[i];
+ }
+ }
+ }
+ }
+ }
+
+
+ // Complex scalar division.
+
+ Real cdivr, cdivi;
+ void cdiv(Real xr, Real xi, Real yr, Real yi) {
+ Real r,d;
+ if (fabs(yr) > fabs(yi)) {
+ r = yi/yr;
+ d = yr + r*yi;
+ cdivr = (xr + r*xi)/d;
+ cdivi = (xi - r*xr)/d;
+ } else {
+ r = yr/yi;
+ d = yi + r*yr;
+ cdivr = (r*xr + xi)/d;
+ cdivi = (r*xi - xr)/d;
+ }
+ }
+
+
+ // Nonsymmetric reduction from Hessenberg to real Schur form.
+
+ void hqr2 () {
+
+ // This is derived from the Algol procedure hqr2,
+ // by Martin and Wilkinson, Handbook for Auto. Comp.,
+ // Vol.ii-Linear Algebra, and the corresponding
+ // Fortran subroutine in EISPACK.
+
+ // Initialize
+
+ int nn = this->n;
+ int n = nn-1;
+ int low = 0;
+ int high = nn-1;
+ Real eps = pow(2.0,-52.0);
+ Real exshift = 0.0;
+ Real p=0,q=0,r=0,s=0,z=0,t,w,x,y;
+
+ // Store roots isolated by balanc and compute matrix norm
+
+ Real norm = 0.0;
+ for (int i = 0; i < nn; i++) {
+ if ((i < low) || (i > high)) {
+ d[i] = H[i][i];
+ e[i] = 0.0;
+ }
+ for (int j = max(i-1,0); j < nn; j++) {
+ norm = norm + fabs(H[i][j]);
+ }
+ }
+
+ // Outer loop over eigenvalue index
+
+ int iter = 0;
+ int totIter = 0;
+ while (n >= low) {
+
+ // NT limit no. of iterations
+ totIter++;
+ if(totIter>100) {
+ //if(totIter>15) std::cout<<"!!!!iter ABORT !!!!!!! "<<totIter<<"\n";
+ // NT hack/fix, return large eigenvalues
+ for (int i = 0; i < nn; i++) {
+ d[i] = 10000.;
+ e[i] = 10000.;
+ }
+ return;
+ }
+
+ // Look for single small sub-diagonal element
+
+ int l = n;
+ while (l > low) {
+ s = fabs(H[l-1][l-1]) + fabs(H[l][l]);
+ if (s == 0.0) {
+ s = norm;
+ }
+ if (fabs(H[l][l-1]) < eps * s) {
+ break;
+ }
+ l--;
+ }
+
+ // Check for convergence
+ // One root found
+
+ if (l == n) {
+ H[n][n] = H[n][n] + exshift;
+ d[n] = H[n][n];
+ e[n] = 0.0;
+ n--;
+ iter = 0;
+
+ // Two roots found
+
+ } else if (l == n-1) {
+ w = H[n][n-1] * H[n-1][n];
+ p = (H[n-1][n-1] - H[n][n]) / 2.0;
+ q = p * p + w;
+ z = sqrt(fabs(q));
+ H[n][n] = H[n][n] + exshift;
+ H[n-1][n-1] = H[n-1][n-1] + exshift;
+ x = H[n][n];
+
+ // Real pair
+
+ if (q >= 0) {
+ if (p >= 0) {
+ z = p + z;
+ } else {
+ z = p - z;
+ }
+ d[n-1] = x + z;
+ d[n] = d[n-1];
+ if (z != 0.0) {
+ d[n] = x - w / z;
+ }
+ e[n-1] = 0.0;
+ e[n] = 0.0;
+ x = H[n][n-1];
+ s = fabs(x) + fabs(z);
+ p = x / s;
+ q = z / s;
+ r = sqrt(p * p+q * q);
+ p = p / r;
+ q = q / r;
+
+ // Row modification
+
+ for (int j = n-1; j < nn; j++) {
+ z = H[n-1][j];
+ H[n-1][j] = q * z + p * H[n][j];
+ H[n][j] = q * H[n][j] - p * z;
+ }
+
+ // Column modification
+
+ for (int i = 0; i <= n; i++) {
+ z = H[i][n-1];
+ H[i][n-1] = q * z + p * H[i][n];
+ H[i][n] = q * H[i][n] - p * z;
+ }
+
+ // Accumulate transformations
+
+ for (int i = low; i <= high; i++) {
+ z = V[i][n-1];
+ V[i][n-1] = q * z + p * V[i][n];
+ V[i][n] = q * V[i][n] - p * z;
+ }
+
+ // Complex pair
+
+ } else {
+ d[n-1] = x + p;
+ d[n] = x + p;
+ e[n-1] = z;
+ e[n] = -z;
+ }
+ n = n - 2;
+ iter = 0;
+
+ // No convergence yet
+
+ } else {
+
+ // Form shift
+
+ x = H[n][n];
+ y = 0.0;
+ w = 0.0;
+ if (l < n) {
+ y = H[n-1][n-1];
+ w = H[n][n-1] * H[n-1][n];
+ }
+
+ // Wilkinson's original ad hoc shift
+
+ if (iter == 10) {
+ exshift += x;
+ for (int i = low; i <= n; i++) {
+ H[i][i] -= x;
+ }
+ s = fabs(H[n][n-1]) + fabs(H[n-1][n-2]);
+ x = y = 0.75 * s;
+ w = -0.4375 * s * s;
+ }
+
+ // MATLAB's new ad hoc shift
+
+ if (iter == 30) {
+ s = (y - x) / 2.0;
+ s = s * s + w;
+ if (s > 0) {
+ s = sqrt(s);
+ if (y < x) {
+ s = -s;
+ }
+ s = x - w / ((y - x) / 2.0 + s);
+ for (int i = low; i <= n; i++) {
+ H[i][i] -= s;
+ }
+ exshift += s;
+ x = y = w = 0.964;
+ }
+ }
+
+ iter = iter + 1; // (Could check iteration count here.)
+
+ // Look for two consecutive small sub-diagonal elements
+
+ int m = n-2;
+ while (m >= l) {
+ z = H[m][m];
+ r = x - z;
+ s = y - z;
+ p = (r * s - w) / H[m+1][m] + H[m][m+1];
+ q = H[m+1][m+1] - z - r - s;
+ r = H[m+2][m+1];
+ s = fabs(p) + fabs(q) + fabs(r);
+ p = p / s;
+ q = q / s;
+ r = r / s;
+ if (m == l) {
+ break;
+ }
+ if (fabs(H[m][m-1]) * (fabs(q) + fabs(r)) <
+ eps * (fabs(p) * (fabs(H[m-1][m-1]) + fabs(z) +
+ fabs(H[m+1][m+1])))) {
+ break;
+ }
+ m--;
+ }
+
+ for (int i = m+2; i <= n; i++) {
+ H[i][i-2] = 0.0;
+ if (i > m+2) {
+ H[i][i-3] = 0.0;
+ }
+ }
+
+ // Double QR step involving rows l:n and columns m:n
+
+ for (int k = m; k <= n-1; k++) {
+ int notlast = (k != n-1);
+ if (k != m) {
+ p = H[k][k-1];
+ q = H[k+1][k-1];
+ r = (notlast ? H[k+2][k-1] : 0.0);
+ x = fabs(p) + fabs(q) + fabs(r);
+ if (x != 0.0) {
+ p = p / x;
+ q = q / x;
+ r = r / x;
+ }
+ }
+ if (x == 0.0) {
+ break;
+ }
+ s = sqrt(p * p + q * q + r * r);
+ if (p < 0) {
+ s = -s;
+ }
+ if (s != 0) {
+ if (k != m) {
+ H[k][k-1] = -s * x;
+ } else if (l != m) {
+ H[k][k-1] = -H[k][k-1];
+ }
+ p = p + s;
+ x = p / s;
+ y = q / s;
+ z = r / s;
+ q = q / p;
+ r = r / p;
+
+ // Row modification
+
+ for (int j = k; j < nn; j++) {
+ p = H[k][j] + q * H[k+1][j];
+ if (notlast) {
+ p = p + r * H[k+2][j];
+ H[k+2][j] = H[k+2][j] - p * z;
+ }
+ H[k][j] = H[k][j] - p * x;
+ H[k+1][j] = H[k+1][j] - p * y;
+ }
+
+ // Column modification
+
+ for (int i = 0; i <= min(n,k+3); i++) {
+ p = x * H[i][k] + y * H[i][k+1];
+ if (notlast) {
+ p = p + z * H[i][k+2];
+ H[i][k+2] = H[i][k+2] - p * r;
+ }
+ H[i][k] = H[i][k] - p;
+ H[i][k+1] = H[i][k+1] - p * q;
+ }
+
+ // Accumulate transformations
+
+ for (int i = low; i <= high; i++) {
+ p = x * V[i][k] + y * V[i][k+1];
+ if (notlast) {
+ p = p + z * V[i][k+2];
+ V[i][k+2] = V[i][k+2] - p * r;
+ }
+ V[i][k] = V[i][k] - p;
+ V[i][k+1] = V[i][k+1] - p * q;
+ }
+ } // (s != 0)
+ } // k loop
+ } // check convergence
+ } // while (n >= low)
+ //if(totIter>15) std::cout<<"!!!!iter "<<totIter<<"\n";
+
+ // Backsubstitute to find vectors of upper triangular form
+
+ if (norm == 0.0) {
+ return;
+ }
+
+ for (n = nn-1; n >= 0; n--) {
+ p = d[n];
+ q = e[n];
+
+ // Real vector
+
+ if (q == 0) {
+ int l = n;
+ H[n][n] = 1.0;
+ for (int i = n-1; i >= 0; i--) {
+ w = H[i][i] - p;
+ r = 0.0;
+ for (int j = l; j <= n; j++) {
+ r = r + H[i][j] * H[j][n];
+ }
+ if (e[i] < 0.0) {
+ z = w;
+ s = r;
+ } else {
+ l = i;
+ if (e[i] == 0.0) {
+ if (w != 0.0) {
+ H[i][n] = -r / w;
+ } else {
+ H[i][n] = -r / (eps * norm);
+ }
+
+ // Solve real equations
+
+ } else {
+ x = H[i][i+1];
+ y = H[i+1][i];
+ q = (d[i] - p) * (d[i] - p) + e[i] * e[i];
+ t = (x * s - z * r) / q;
+ H[i][n] = t;
+ if (fabs(x) > fabs(z)) {
+ H[i+1][n] = (-r - w * t) / x;
+ } else {
+ H[i+1][n] = (-s - y * t) / z;
+ }
+ }
+
+ // Overflow control
+
+ t = fabs(H[i][n]);
+ if ((eps * t) * t > 1) {
+ for (int j = i; j <= n; j++) {
+ H[j][n] = H[j][n] / t;
+ }
+ }
+ }
+ }
+
+ // Complex vector
+
+ } else if (q < 0) {
+ int l = n-1;
+
+ // Last vector component imaginary so matrix is triangular
+
+ if (fabs(H[n][n-1]) > fabs(H[n-1][n])) {
+ H[n-1][n-1] = q / H[n][n-1];
+ H[n-1][n] = -(H[n][n] - p) / H[n][n-1];
+ } else {
+ cdiv(0.0,-H[n-1][n],H[n-1][n-1]-p,q);
+ H[n-1][n-1] = cdivr;
+ H[n-1][n] = cdivi;
+ }
+ H[n][n-1] = 0.0;
+ H[n][n] = 1.0;
+ for (int i = n-2; i >= 0; i--) {
+ Real ra,sa,vr,vi;
+ ra = 0.0;
+ sa = 0.0;
+ for (int j = l; j <= n; j++) {
+ ra = ra + H[i][j] * H[j][n-1];
+ sa = sa + H[i][j] * H[j][n];
+ }
+ w = H[i][i] - p;
+
+ if (e[i] < 0.0) {
+ z = w;
+ r = ra;
+ s = sa;
+ } else {
+ l = i;
+ if (e[i] == 0) {
+ cdiv(-ra,-sa,w,q);
+ H[i][n-1] = cdivr;
+ H[i][n] = cdivi;
+ } else {
+
+ // Solve complex equations
+
+ x = H[i][i+1];
+ y = H[i+1][i];
+ vr = (d[i] - p) * (d[i] - p) + e[i] * e[i] - q * q;
+ vi = (d[i] - p) * 2.0 * q;
+ if ((vr == 0.0) && (vi == 0.0)) {
+ vr = eps * norm * (fabs(w) + fabs(q) +
+ fabs(x) + fabs(y) + fabs(z));
+ }
+ cdiv(x*r-z*ra+q*sa,x*s-z*sa-q*ra,vr,vi);
+ H[i][n-1] = cdivr;
+ H[i][n] = cdivi;
+ if (fabs(x) > (fabs(z) + fabs(q))) {
+ H[i+1][n-1] = (-ra - w * H[i][n-1] + q * H[i][n]) / x;
+ H[i+1][n] = (-sa - w * H[i][n] - q * H[i][n-1]) / x;
+ } else {
+ cdiv(-r-y*H[i][n-1],-s-y*H[i][n],z,q);
+ H[i+1][n-1] = cdivr;
+ H[i+1][n] = cdivi;
+ }
+ }
+
+ // Overflow control
+
+ t = max(fabs(H[i][n-1]),fabs(H[i][n]));
+ if ((eps * t) * t > 1) {
+ for (int j = i; j <= n; j++) {
+ H[j][n-1] = H[j][n-1] / t;
+ H[j][n] = H[j][n] / t;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Vectors of isolated roots
+
+ for (int i = 0; i < nn; i++) {
+ if (i < low || i > high) {
+ for (int j = i; j < nn; j++) {
+ V[i][j] = H[i][j];
+ }
+ }
+ }
+
+ // Back transformation to get eigenvectors of original matrix
+
+ for (int j = nn-1; j >= low; j--) {
+ for (int i = low; i <= high; i++) {
+ z = 0.0;
+ for (int k = low; k <= min(j,high); k++) {
+ z = z + V[i][k] * H[k][j];
+ }
+ V[i][j] = z;
+ }
+ }
+ }
+
+public:
+
+
+ /** Check for symmetry, then construct the eigenvalue decomposition
+ @param A Square real (non-complex) matrix
+ */
+
+ Eigenvalue(const TNT::Array2D<Real> &A) {
+ n = A.dim2();
+ V = Array2D<Real>(n,n);
+ d = Array1D<Real>(n);
+ e = Array1D<Real>(n);
+
+ issymmetric = 1;
+ for (int j = 0; (j < n) && issymmetric; j++) {
+ for (int i = 0; (i < n) && issymmetric; i++) {
+ issymmetric = (A[i][j] == A[j][i]);
+ }
+ }
+
+ if (issymmetric) {
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ V[i][j] = A[i][j];
+ }
+ }
+
+ // Tridiagonalize.
+ tred2();
+
+ // Diagonalize.
+ tql2();
+
+ } else {
+ H = TNT::Array2D<Real>(n,n);
+ ort = TNT::Array1D<Real>(n);
+
+ for (int j = 0; j < n; j++) {
+ for (int i = 0; i < n; i++) {
+ H[i][j] = A[i][j];
+ }
+ }
+
+ // Reduce to Hessenberg form.
+ orthes();
+
+ // Reduce Hessenberg to real Schur form.
+ hqr2();
+ }
+ }
+
+
+ /** Return the eigenvector matrix
+ @return V
+ */
+
+ void getV (TNT::Array2D<Real> &V_) {
+ V_ = V;
+ return;
+ }
+
+ /** Return the real parts of the eigenvalues
+ @return real(diag(D))
+ */
+
+ void getRealEigenvalues (TNT::Array1D<Real> &d_) {
+ d_ = d;
+ return ;
+ }
+
+ /** Return the imaginary parts of the eigenvalues
+ in parameter e_.
+
+ @pararm e_: new matrix with imaginary parts of the eigenvalues.
+ */
+ void getImagEigenvalues (TNT::Array1D<Real> &e_) {
+ e_ = e;
+ return;
+ }
+
+
+/**
+ Computes the block diagonal eigenvalue matrix.
+ If the original matrix A is not symmetric, then the eigenvalue
+ matrix D is block diagonal with the real eigenvalues in 1-by-1
+ blocks and any complex eigenvalues,
+ a + i*b, in 2-by-2 blocks, [a, b; -b, a]. That is, if the complex
+ eigenvalues look like
+<pre>
+
+ u + iv . . . . .
+ . u - iv . . . .
+ . . a + ib . . .
+ . . . a - ib . .
+ . . . . x .
+ . . . . . y
+</pre>
+ then D looks like
+<pre>
+
+ u v . . . .
+ -v u . . . .
+ . . a b . .
+ . . -b a . .
+ . . . . x .
+ . . . . . y
+</pre>
+ This keeps V a real matrix in both symmetric and non-symmetric
+ cases, and A*V = V*D.
+
+ @param D: upon return, the matrix is filled with the block diagonal
+ eigenvalue matrix.
+
+*/
+ void getD (TNT::Array2D<Real> &D) {
+ D = Array2D<Real>(n,n);
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ D[i][j] = 0.0;
+ }
+ D[i][i] = d[i];
+ if (e[i] > 0) {
+ D[i][i+1] = e[i];
+ } else if (e[i] < 0) {
+ D[i][i-1] = e[i];
+ }
+ }
+ }
+};
+
+} //namespace JAMA
+
+
+#endif
+// JAMA_EIG_H
diff --git a/intern/smoke/intern/tnt/jama_lu.h b/intern/smoke/intern/tnt/jama_lu.h
new file mode 100644
index 00000000000..a4f96b11502
--- /dev/null
+++ b/intern/smoke/intern/tnt/jama_lu.h
@@ -0,0 +1,319 @@
+#ifndef JAMA_LU_H
+#define JAMA_LU_H
+
+#include "tnt.h"
+#include <algorithm>
+//for min(), max() below
+
+using namespace TNT;
+using namespace std;
+
+namespace JAMA
+{
+
+ /** LU Decomposition.
+ <P>
+ For an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n
+ unit lower triangular matrix L, an n-by-n upper triangular matrix U,
+ and a permutation vector piv of length m so that A(piv,:) = L*U.
+ If m < n, then L is m-by-m and U is m-by-n.
+ <P>
+ The LU decompostion with pivoting always exists, even if the matrix is
+ singular, so the constructor will never fail. The primary use of the
+ LU decomposition is in the solution of square systems of simultaneous
+ linear equations. This will fail if isNonsingular() returns false.
+ */
+template <class Real>
+class LU
+{
+
+
+
+ /* Array for internal storage of decomposition. */
+ Array2D<Real> LU_;
+ int m, n, pivsign;
+ Array1D<int> piv;
+
+
+ Array2D<Real> permute_copy(const Array2D<Real> &A,
+ const Array1D<int> &piv, int j0, int j1)
+ {
+ int piv_length = piv.dim();
+
+ Array2D<Real> X(piv_length, j1-j0+1);
+
+
+ for (int i = 0; i < piv_length; i++)
+ for (int j = j0; j <= j1; j++)
+ X[i][j-j0] = A[piv[i]][j];
+
+ return X;
+ }
+
+ Array1D<Real> permute_copy(const Array1D<Real> &A,
+ const Array1D<int> &piv)
+ {
+ int piv_length = piv.dim();
+ if (piv_length != A.dim())
+ return Array1D<Real>();
+
+ Array1D<Real> x(piv_length);
+
+
+ for (int i = 0; i < piv_length; i++)
+ x[i] = A[piv[i]];
+
+ return x;
+ }
+
+
+ public :
+
+ /** LU Decomposition
+ @param A Rectangular matrix
+ @return LU Decomposition object to access L, U and piv.
+ */
+
+ LU (const Array2D<Real> &A) : LU_(A.copy()), m(A.dim1()), n(A.dim2()),
+ piv(A.dim1())
+
+ {
+
+ // Use a "left-looking", dot-product, Crout/Doolittle algorithm.
+
+
+ for (int i = 0; i < m; i++) {
+ piv[i] = i;
+ }
+ pivsign = 1;
+ Real *LUrowi = 0;;
+ Array1D<Real> LUcolj(m);
+
+ // Outer loop.
+
+ for (int j = 0; j < n; j++) {
+
+ // Make a copy of the j-th column to localize references.
+
+ for (int i = 0; i < m; i++) {
+ LUcolj[i] = LU_[i][j];
+ }
+
+ // Apply previous transformations.
+
+ for (int i = 0; i < m; i++) {
+ LUrowi = LU_[i];
+
+ // Most of the time is spent in the following dot product.
+
+ int kmax = min(i,j);
+ double s = 0.0;
+ for (int k = 0; k < kmax; k++) {
+ s += LUrowi[k]*LUcolj[k];
+ }
+
+ LUrowi[j] = LUcolj[i] -= s;
+ }
+
+ // Find pivot and exchange if necessary.
+
+ int p = j;
+ for (int i = j+1; i < m; i++) {
+ if (abs(LUcolj[i]) > abs(LUcolj[p])) {
+ p = i;
+ }
+ }
+ if (p != j) {
+ int k=0;
+ for (k = 0; k < n; k++) {
+ double t = LU_[p][k];
+ LU_[p][k] = LU_[j][k];
+ LU_[j][k] = t;
+ }
+ k = piv[p];
+ piv[p] = piv[j];
+ piv[j] = k;
+ pivsign = -pivsign;
+ }
+
+ // Compute multipliers.
+
+ if ((j < m) && (LU_[j][j] != 0.0)) {
+ for (int i = j+1; i < m; i++) {
+ LU_[i][j] /= LU_[j][j];
+ }
+ }
+ }
+ }
+
+
+ /** Is the matrix nonsingular?
+ @return 1 (true) if upper triangular factor U (and hence A)
+ is nonsingular, 0 otherwise.
+ */
+
+ int isNonsingular () {
+ for (int j = 0; j < n; j++) {
+ if (LU_[j][j] == 0)
+ return 0;
+ }
+ return 1;
+ }
+
+ /** Return lower triangular factor
+ @return L
+ */
+
+ Array2D<Real> getL () {
+ Array2D<Real> L_(m,n);
+ for (int i = 0; i < m; i++) {
+ for (int j = 0; j < n; j++) {
+ if (i > j) {
+ L_[i][j] = LU_[i][j];
+ } else if (i == j) {
+ L_[i][j] = 1.0;
+ } else {
+ L_[i][j] = 0.0;
+ }
+ }
+ }
+ return L_;
+ }
+
+ /** Return upper triangular factor
+ @return U portion of LU factorization.
+ */
+
+ Array2D<Real> getU () {
+ Array2D<Real> U_(n,n);
+ for (int i = 0; i < n; i++) {
+ for (int j = 0; j < n; j++) {
+ if (i <= j) {
+ U_[i][j] = LU_[i][j];
+ } else {
+ U_[i][j] = 0.0;
+ }
+ }
+ }
+ return U_;
+ }
+
+ /** Return pivot permutation vector
+ @return piv
+ */
+
+ Array1D<int> getPivot () {
+ return piv;
+ }
+
+
+ /** Compute determinant using LU factors.
+ @return determinant of A, or 0 if A is not square.
+ */
+
+ Real det () {
+ if (m != n) {
+ return Real(0);
+ }
+ Real d = Real(pivsign);
+ for (int j = 0; j < n; j++) {
+ d *= LU_[j][j];
+ }
+ return d;
+ }
+
+ /** Solve A*X = B
+ @param B A Matrix with as many rows as A and any number of columns.
+ @return X so that L*U*X = B(piv,:), if B is nonconformant, returns
+ 0x0 (null) array.
+ */
+
+ Array2D<Real> solve (const Array2D<Real> &B)
+ {
+
+ /* Dimensions: A is mxn, X is nxk, B is mxk */
+
+ if (B.dim1() != m) {
+ return Array2D<Real>(0,0);
+ }
+ if (!isNonsingular()) {
+ return Array2D<Real>(0,0);
+ }
+
+ // Copy right hand side with pivoting
+ int nx = B.dim2();
+
+
+ Array2D<Real> X = permute_copy(B, piv, 0, nx-1);
+
+ // Solve L*Y = B(piv,:)
+ for (int k = 0; k < n; k++) {
+ for (int i = k+1; i < n; i++) {
+ for (int j = 0; j < nx; j++) {
+ X[i][j] -= X[k][j]*LU_[i][k];
+ }
+ }
+ }
+ // Solve U*X = Y;
+ for (int k = n-1; k >= 0; k--) {
+ for (int j = 0; j < nx; j++) {
+ X[k][j] /= LU_[k][k];
+ }
+ for (int i = 0; i < k; i++) {
+ for (int j = 0; j < nx; j++) {
+ X[i][j] -= X[k][j]*LU_[i][k];
+ }
+ }
+ }
+ return X;
+ }
+
+
+ /** Solve A*x = b, where x and b are vectors of length equal
+ to the number of rows in A.
+
+ @param b a vector (Array1D> of length equal to the first dimension
+ of A.
+ @return x a vector (Array1D> so that L*U*x = b(piv), if B is nonconformant,
+ returns 0x0 (null) array.
+ */
+
+ Array1D<Real> solve (const Array1D<Real> &b)
+ {
+
+ /* Dimensions: A is mxn, X is nxk, B is mxk */
+
+ if (b.dim1() != m) {
+ return Array1D<Real>();
+ }
+ if (!isNonsingular()) {
+ return Array1D<Real>();
+ }
+
+
+ Array1D<Real> x = permute_copy(b, piv);
+
+ // Solve L*Y = B(piv)
+ for (int k = 0; k < n; k++) {
+ for (int i = k+1; i < n; i++) {
+ x[i] -= x[k]*LU_[i][k];
+ }
+ }
+
+ // Solve U*X = Y;
+ for (int k = n-1; k >= 0; k--) {
+ x[k] /= LU_[k][k];
+ for (int i = 0; i < k; i++)
+ x[i] -= x[k]*LU_[i][k];
+ }
+
+
+ return x;
+ }
+
+}; /* class LU */
+
+} /* namespace JAMA */
+
+#endif
+/* JAMA_LU_H */
diff --git a/intern/smoke/intern/tnt/tnt.h b/intern/smoke/intern/tnt/tnt.h
new file mode 100644
index 00000000000..92463e08a06
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt.h
@@ -0,0 +1,64 @@
+/*
+*
+* Template Numerical Toolkit (TNT): Linear Algebra Module
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+#ifndef TNT_H
+#define TNT_H
+
+
+
+//---------------------------------------------------------------------
+// Define this macro if you want TNT to track some of the out-of-bounds
+// indexing. This can encur a small run-time overhead, but is recommended
+// while developing code. It can be turned off for production runs.
+//
+// #define TNT_BOUNDS_CHECK
+//---------------------------------------------------------------------
+//
+
+//#define TNT_BOUNDS_CHECK
+
+
+
+#include "tnt_version.h"
+#include "tnt_math_utils.h"
+#include "tnt_array1d.h"
+#include "tnt_array2d.h"
+#include "tnt_array3d.h"
+#include "tnt_array1d_utils.h"
+#include "tnt_array2d_utils.h"
+#include "tnt_array3d_utils.h"
+
+#include "tnt_fortran_array1d.h"
+#include "tnt_fortran_array2d.h"
+#include "tnt_fortran_array3d.h"
+#include "tnt_fortran_array1d_utils.h"
+#include "tnt_fortran_array2d_utils.h"
+#include "tnt_fortran_array3d_utils.h"
+
+#include "tnt_sparse_matrix_csr.h"
+
+#include "tnt_stopwatch.h"
+#include "tnt_subscript.h"
+#include "tnt_vec.h"
+#include "tnt_cmat.h"
+
+
+#endif
+// TNT_H
diff --git a/intern/smoke/intern/tnt/tnt_array1d.h b/intern/smoke/intern/tnt/tnt_array1d.h
new file mode 100644
index 00000000000..858df579863
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_array1d.h
@@ -0,0 +1,278 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+
+#ifndef TNT_ARRAY1D_H
+#define TNT_ARRAY1D_H
+
+//#include <cstdlib>
+#include <iostream>
+
+#ifdef TNT_BOUNDS_CHECK
+#include <assert.h>
+#endif
+
+
+#include "tnt_i_refvec.h"
+
+namespace TNT
+{
+
+template <class T>
+class Array1D
+{
+
+ private:
+
+ /* ... */
+ i_refvec<T> v_;
+ int n_;
+ T* data_; /* this normally points to v_.begin(), but
+ * could also point to a portion (subvector)
+ * of v_.
+ */
+
+ void copy_(T* p, const T* q, int len) const;
+ void set_(T* begin, T* end, const T& val);
+
+
+ public:
+
+ typedef T value_type;
+
+
+ Array1D();
+ explicit Array1D(int n);
+ Array1D(int n, const T &a);
+ Array1D(int n, T *a);
+ inline Array1D(const Array1D &A);
+ inline operator T*();
+ inline operator const T*();
+ inline Array1D & operator=(const T &a);
+ inline Array1D & operator=(const Array1D &A);
+ inline Array1D & ref(const Array1D &A);
+ Array1D copy() const;
+ Array1D & inject(const Array1D & A);
+ inline T& operator[](int i);
+ inline const T& operator[](int i) const;
+ inline int dim1() const;
+ inline int dim() const;
+ ~Array1D();
+
+
+ /* ... extended interface ... */
+
+ inline int ref_count() const;
+ inline Array1D<T> subarray(int i0, int i1);
+
+};
+
+
+
+
+template <class T>
+Array1D<T>::Array1D() : v_(), n_(0), data_(0) {}
+
+template <class T>
+Array1D<T>::Array1D(const Array1D<T> &A) : v_(A.v_), n_(A.n_),
+ data_(A.data_)
+{
+#ifdef TNT_DEBUG
+ std::cout << "Created Array1D(const Array1D<T> &A) \n";
+#endif
+
+}
+
+
+template <class T>
+Array1D<T>::Array1D(int n) : v_(n), n_(n), data_(v_.begin())
+{
+#ifdef TNT_DEBUG
+ std::cout << "Created Array1D(int n) \n";
+#endif
+}
+
+template <class T>
+Array1D<T>::Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin())
+{
+#ifdef TNT_DEBUG
+ std::cout << "Created Array1D(int n, const T& val) \n";
+#endif
+ set_(data_, data_+ n, val);
+
+}
+
+template <class T>
+Array1D<T>::Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin())
+{
+#ifdef TNT_DEBUG
+ std::cout << "Created Array1D(int n, T* a) \n";
+#endif
+}
+
+template <class T>
+inline Array1D<T>::operator T*()
+{
+ return &(v_[0]);
+}
+
+
+template <class T>
+inline Array1D<T>::operator const T*()
+{
+ return &(v_[0]);
+}
+
+
+
+template <class T>
+inline T& Array1D<T>::operator[](int i)
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i>= 0);
+ assert(i < n_);
+#endif
+ return data_[i];
+}
+
+template <class T>
+inline const T& Array1D<T>::operator[](int i) const
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i>= 0);
+ assert(i < n_);
+#endif
+ return data_[i];
+}
+
+
+
+
+template <class T>
+Array1D<T> & Array1D<T>::operator=(const T &a)
+{
+ set_(data_, data_+n_, a);
+ return *this;
+}
+
+template <class T>
+Array1D<T> Array1D<T>::copy() const
+{
+ Array1D A( n_);
+ copy_(A.data_, data_, n_);
+
+ return A;
+}
+
+
+template <class T>
+Array1D<T> & Array1D<T>::inject(const Array1D &A)
+{
+ if (A.n_ == n_)
+ copy_(data_, A.data_, n_);
+
+ return *this;
+}
+
+
+
+
+
+template <class T>
+Array1D<T> & Array1D<T>::ref(const Array1D<T> &A)
+{
+ if (this != &A)
+ {
+ v_ = A.v_; /* operator= handles the reference counting. */
+ n_ = A.n_;
+ data_ = A.data_;
+
+ }
+ return *this;
+}
+
+template <class T>
+Array1D<T> & Array1D<T>::operator=(const Array1D<T> &A)
+{
+ return ref(A);
+}
+
+template <class T>
+inline int Array1D<T>::dim1() const { return n_; }
+
+template <class T>
+inline int Array1D<T>::dim() const { return n_; }
+
+template <class T>
+Array1D<T>::~Array1D() {}
+
+
+/* ............................ exented interface ......................*/
+
+template <class T>
+inline int Array1D<T>::ref_count() const
+{
+ return v_.ref_count();
+}
+
+template <class T>
+inline Array1D<T> Array1D<T>::subarray(int i0, int i1)
+{
+ if ((i0 > 0) && (i1 < n_) || (i0 <= i1))
+ {
+ Array1D<T> X(*this); /* create a new instance of this array. */
+ X.n_ = i1-i0+1;
+ X.data_ += i0;
+
+ return X;
+ }
+ else
+ {
+ return Array1D<T>();
+ }
+}
+
+
+/* private internal functions */
+
+
+template <class T>
+void Array1D<T>::set_(T* begin, T* end, const T& a)
+{
+ for (T* p=begin; p<end; p++)
+ *p = a;
+
+}
+
+template <class T>
+void Array1D<T>::copy_(T* p, const T* q, int len) const
+{
+ T *end = p + len;
+ while (p<end )
+ *p++ = *q++;
+
+}
+
+
+} /* namespace TNT */
+
+#endif
+/* TNT_ARRAY1D_H */
+
diff --git a/intern/smoke/intern/tnt/tnt_array1d_utils.h b/intern/smoke/intern/tnt/tnt_array1d_utils.h
new file mode 100644
index 00000000000..683e0e2d856
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_array1d_utils.h
@@ -0,0 +1,230 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+#ifndef TNT_ARRAY1D_UTILS_H
+#define TNT_ARRAY1D_UTILS_H
+
+#include <cstdlib>
+#include <cassert>
+
+namespace TNT
+{
+
+
+template <class T>
+std::ostream& operator<<(std::ostream &s, const Array1D<T> &A)
+{
+ int N=A.dim1();
+
+#ifdef TNT_DEBUG
+ s << "addr: " << (void *) &A[0] << "\n";
+#endif
+ s << N << "\n";
+ for (int j=0; j<N; j++)
+ {
+ s << A[j] << "\n";
+ }
+ s << "\n";
+
+ return s;
+}
+
+template <class T>
+std::istream& operator>>(std::istream &s, Array1D<T> &A)
+{
+ int N;
+ s >> N;
+
+ Array1D<T> B(N);
+ for (int i=0; i<N; i++)
+ s >> B[i];
+ A = B;
+ return s;
+}
+
+
+
+template <class T>
+Array1D<T> operator+(const Array1D<T> &A, const Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() != n )
+ return Array1D<T>();
+
+ else
+ {
+ Array1D<T> C(n);
+
+ for (int i=0; i<n; i++)
+ {
+ C[i] = A[i] + B[i];
+ }
+ return C;
+ }
+}
+
+
+
+template <class T>
+Array1D<T> operator-(const Array1D<T> &A, const Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() != n )
+ return Array1D<T>();
+
+ else
+ {
+ Array1D<T> C(n);
+
+ for (int i=0; i<n; i++)
+ {
+ C[i] = A[i] - B[i];
+ }
+ return C;
+ }
+}
+
+
+template <class T>
+Array1D<T> operator*(const Array1D<T> &A, const Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() != n )
+ return Array1D<T>();
+
+ else
+ {
+ Array1D<T> C(n);
+
+ for (int i=0; i<n; i++)
+ {
+ C[i] = A[i] * B[i];
+ }
+ return C;
+ }
+}
+
+
+template <class T>
+Array1D<T> operator/(const Array1D<T> &A, const Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() != n )
+ return Array1D<T>();
+
+ else
+ {
+ Array1D<T> C(n);
+
+ for (int i=0; i<n; i++)
+ {
+ C[i] = A[i] / B[i];
+ }
+ return C;
+ }
+}
+
+
+
+
+
+
+
+
+
+template <class T>
+Array1D<T>& operator+=(Array1D<T> &A, const Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() == n)
+ {
+ for (int i=0; i<n; i++)
+ {
+ A[i] += B[i];
+ }
+ }
+ return A;
+}
+
+
+
+
+template <class T>
+Array1D<T>& operator-=(Array1D<T> &A, const Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() == n)
+ {
+ for (int i=0; i<n; i++)
+ {
+ A[i] -= B[i];
+ }
+ }
+ return A;
+}
+
+
+
+template <class T>
+Array1D<T>& operator*=(Array1D<T> &A, const Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() == n)
+ {
+ for (int i=0; i<n; i++)
+ {
+ A[i] *= B[i];
+ }
+ }
+ return A;
+}
+
+
+
+
+template <class T>
+Array1D<T>& operator/=(Array1D<T> &A, const Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() == n)
+ {
+ for (int i=0; i<n; i++)
+ {
+ A[i] /= B[i];
+ }
+ }
+ return A;
+}
+
+
+
+
+
+
+} // namespace TNT
+
+#endif
diff --git a/intern/smoke/intern/tnt/tnt_array2d.h b/intern/smoke/intern/tnt/tnt_array2d.h
new file mode 100644
index 00000000000..c791575ebfb
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_array2d.h
@@ -0,0 +1,315 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+
+#ifndef TNT_ARRAY2D_H
+#define TNT_ARRAY2D_H
+
+#include <cstdlib>
+#include <iostream>
+#ifdef TNT_BOUNDS_CHECK
+#include <assert.h>
+#endif
+
+#include "tnt_array1d.h"
+
+namespace TNT
+{
+
+template <class T>
+class Array2D
+{
+
+
+ private:
+
+
+
+ Array1D<T> data_;
+ Array1D<T*> v_;
+ int m_;
+ int n_;
+
+ public:
+
+ typedef T value_type;
+ Array2D();
+ Array2D(int m, int n);
+ Array2D(int m, int n, T *a);
+ Array2D(int m, int n, const T &a);
+ inline Array2D(const Array2D &A);
+ inline operator T**();
+ inline operator const T**();
+ inline Array2D & operator=(const T &a);
+ inline Array2D & operator=(const Array2D &A);
+ inline Array2D & ref(const Array2D &A);
+ Array2D copy() const;
+ Array2D & inject(const Array2D & A);
+ inline T* operator[](int i);
+ inline const T* operator[](int i) const;
+ inline int dim1() const;
+ inline int dim2() const;
+ ~Array2D();
+
+ /* extended interface (not part of the standard) */
+
+
+ inline int ref_count();
+ inline int ref_count_data();
+ inline int ref_count_dim1();
+ Array2D subarray(int i0, int i1, int j0, int j1);
+
+};
+
+
+template <class T>
+Array2D<T>::Array2D() : data_(), v_(), m_(0), n_(0) {}
+
+template <class T>
+Array2D<T>::Array2D(const Array2D<T> &A) : data_(A.data_), v_(A.v_),
+ m_(A.m_), n_(A.n_) {}
+
+
+
+
+template <class T>
+Array2D<T>::Array2D(int m, int n) : data_(m*n), v_(m), m_(m), n_(n)
+{
+ if (m>0 && n>0)
+ {
+ T* p = &(data_[0]);
+ for (int i=0; i<m; i++)
+ {
+ v_[i] = p;
+ p += n;
+ }
+ }
+}
+
+
+
+template <class T>
+Array2D<T>::Array2D(int m, int n, const T &val) : data_(m*n), v_(m),
+ m_(m), n_(n)
+{
+ if (m>0 && n>0)
+ {
+ data_ = val;
+ T* p = &(data_[0]);
+ for (int i=0; i<m; i++)
+ {
+ v_[i] = p;
+ p += n;
+ }
+ }
+}
+
+template <class T>
+Array2D<T>::Array2D(int m, int n, T *a) : data_(m*n, a), v_(m), m_(m), n_(n)
+{
+ if (m>0 && n>0)
+ {
+ T* p = &(data_[0]);
+
+ for (int i=0; i<m; i++)
+ {
+ v_[i] = p;
+ p += n;
+ }
+ }
+}
+
+
+template <class T>
+inline T* Array2D<T>::operator[](int i)
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i >= 0);
+ assert(i < m_);
+#endif
+
+return v_[i];
+
+}
+
+
+template <class T>
+inline const T* Array2D<T>::operator[](int i) const
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i >= 0);
+ assert(i < m_);
+#endif
+
+return v_[i];
+
+}
+
+template <class T>
+Array2D<T> & Array2D<T>::operator=(const T &a)
+{
+ /* non-optimzied, but will work with subarrays in future verions */
+
+ for (int i=0; i<m_; i++)
+ for (int j=0; j<n_; j++)
+ v_[i][j] = a;
+ return *this;
+}
+
+
+
+
+template <class T>
+Array2D<T> Array2D<T>::copy() const
+{
+ Array2D A(m_, n_);
+
+ for (int i=0; i<m_; i++)
+ for (int j=0; j<n_; j++)
+ A[i][j] = v_[i][j];
+
+
+ return A;
+}
+
+
+template <class T>
+Array2D<T> & Array2D<T>::inject(const Array2D &A)
+{
+ if (A.m_ == m_ && A.n_ == n_)
+ {
+ for (int i=0; i<m_; i++)
+ for (int j=0; j<n_; j++)
+ v_[i][j] = A[i][j];
+ }
+ return *this;
+}
+
+
+
+
+template <class T>
+Array2D<T> & Array2D<T>::ref(const Array2D<T> &A)
+{
+ if (this != &A)
+ {
+ v_ = A.v_;
+ data_ = A.data_;
+ m_ = A.m_;
+ n_ = A.n_;
+
+ }
+ return *this;
+}
+
+
+
+template <class T>
+Array2D<T> & Array2D<T>::operator=(const Array2D<T> &A)
+{
+ return ref(A);
+}
+
+template <class T>
+inline int Array2D<T>::dim1() const { return m_; }
+
+template <class T>
+inline int Array2D<T>::dim2() const { return n_; }
+
+
+template <class T>
+Array2D<T>::~Array2D() {}
+
+
+
+
+template <class T>
+inline Array2D<T>::operator T**()
+{
+ return &(v_[0]);
+}
+template <class T>
+inline Array2D<T>::operator const T**()
+{
+ return &(v_[0]);
+}
+
+/* ............... extended interface ............... */
+/**
+ Create a new view to a subarray defined by the boundaries
+ [i0][i0] and [i1][j1]. The size of the subarray is
+ (i1-i0) by (j1-j0). If either of these lengths are zero
+ or negative, the subarray view is null.
+
+*/
+template <class T>
+Array2D<T> Array2D<T>::subarray(int i0, int i1, int j0, int j1)
+{
+ Array2D<T> A;
+ int m = i1-i0+1;
+ int n = j1-j0+1;
+
+ /* if either length is zero or negative, this is an invalide
+ subarray. return a null view.
+ */
+ if (m<1 || n<1)
+ return A;
+
+ A.data_ = data_;
+ A.m_ = m;
+ A.n_ = n;
+ A.v_ = Array1D<T*>(m);
+ T* p = &(data_[0]) + i0 * n_ + j0;
+ for (int i=0; i<m; i++)
+ {
+ A.v_[i] = p + i*n_;
+
+ }
+ return A;
+}
+
+template <class T>
+inline int Array2D<T>::ref_count()
+{
+ return ref_count_data();
+}
+
+
+
+template <class T>
+inline int Array2D<T>::ref_count_data()
+{
+ return data_.ref_count();
+}
+
+template <class T>
+inline int Array2D<T>::ref_count_dim1()
+{
+ return v_.ref_count();
+}
+
+
+
+
+} /* namespace TNT */
+
+#endif
+/* TNT_ARRAY2D_H */
+
diff --git a/intern/smoke/intern/tnt/tnt_array2d_utils.h b/intern/smoke/intern/tnt/tnt_array2d_utils.h
new file mode 100644
index 00000000000..7041ed37857
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_array2d_utils.h
@@ -0,0 +1,287 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+#ifndef TNT_ARRAY2D_UTILS_H
+#define TNT_ARRAY2D_UTILS_H
+
+#include <cstdlib>
+#include <cassert>
+
+namespace TNT
+{
+
+
+template <class T>
+std::ostream& operator<<(std::ostream &s, const Array2D<T> &A)
+{
+ int M=A.dim1();
+ int N=A.dim2();
+
+ s << M << " " << N << "\n";
+
+ for (int i=0; i<M; i++)
+ {
+ for (int j=0; j<N; j++)
+ {
+ s << A[i][j] << " ";
+ }
+ s << "\n";
+ }
+
+
+ return s;
+}
+
+template <class T>
+std::istream& operator>>(std::istream &s, Array2D<T> &A)
+{
+
+ int M, N;
+
+ s >> M >> N;
+
+ Array2D<T> B(M,N);
+
+ for (int i=0; i<M; i++)
+ for (int j=0; j<N; j++)
+ {
+ s >> B[i][j];
+ }
+
+ A = B;
+ return s;
+}
+
+
+template <class T>
+Array2D<T> operator+(const Array2D<T> &A, const Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() != m || B.dim2() != n )
+ return Array2D<T>();
+
+ else
+ {
+ Array2D<T> C(m,n);
+
+ for (int i=0; i<m; i++)
+ {
+ for (int j=0; j<n; j++)
+ C[i][j] = A[i][j] + B[i][j];
+ }
+ return C;
+ }
+}
+
+template <class T>
+Array2D<T> operator-(const Array2D<T> &A, const Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() != m || B.dim2() != n )
+ return Array2D<T>();
+
+ else
+ {
+ Array2D<T> C(m,n);
+
+ for (int i=0; i<m; i++)
+ {
+ for (int j=0; j<n; j++)
+ C[i][j] = A[i][j] - B[i][j];
+ }
+ return C;
+ }
+}
+
+
+template <class T>
+Array2D<T> operator*(const Array2D<T> &A, const Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() != m || B.dim2() != n )
+ return Array2D<T>();
+
+ else
+ {
+ Array2D<T> C(m,n);
+
+ for (int i=0; i<m; i++)
+ {
+ for (int j=0; j<n; j++)
+ C[i][j] = A[i][j] * B[i][j];
+ }
+ return C;
+ }
+}
+
+
+
+
+template <class T>
+Array2D<T> operator/(const Array2D<T> &A, const Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() != m || B.dim2() != n )
+ return Array2D<T>();
+
+ else
+ {
+ Array2D<T> C(m,n);
+
+ for (int i=0; i<m; i++)
+ {
+ for (int j=0; j<n; j++)
+ C[i][j] = A[i][j] / B[i][j];
+ }
+ return C;
+ }
+}
+
+
+
+
+
+template <class T>
+Array2D<T>& operator+=(Array2D<T> &A, const Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() == m || B.dim2() == n )
+ {
+ for (int i=0; i<m; i++)
+ {
+ for (int j=0; j<n; j++)
+ A[i][j] += B[i][j];
+ }
+ }
+ return A;
+}
+
+
+
+template <class T>
+Array2D<T>& operator-=(Array2D<T> &A, const Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() == m || B.dim2() == n )
+ {
+ for (int i=0; i<m; i++)
+ {
+ for (int j=0; j<n; j++)
+ A[i][j] -= B[i][j];
+ }
+ }
+ return A;
+}
+
+
+
+template <class T>
+Array2D<T>& operator*=(Array2D<T> &A, const Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() == m || B.dim2() == n )
+ {
+ for (int i=0; i<m; i++)
+ {
+ for (int j=0; j<n; j++)
+ A[i][j] *= B[i][j];
+ }
+ }
+ return A;
+}
+
+
+
+
+
+template <class T>
+Array2D<T>& operator/=(Array2D<T> &A, const Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() == m || B.dim2() == n )
+ {
+ for (int i=0; i<m; i++)
+ {
+ for (int j=0; j<n; j++)
+ A[i][j] /= B[i][j];
+ }
+ }
+ return A;
+}
+
+/**
+ Matrix Multiply: compute C = A*B, where C[i][j]
+ is the dot-product of row i of A and column j of B.
+
+
+ @param A an (m x n) array
+ @param B an (n x k) array
+ @return the (m x k) array A*B, or a null array (0x0)
+ if the matrices are non-conformant (i.e. the number
+ of columns of A are different than the number of rows of B.)
+
+
+*/
+template <class T>
+Array2D<T> matmult(const Array2D<T> &A, const Array2D<T> &B)
+{
+ if (A.dim2() != B.dim1())
+ return Array2D<T>();
+
+ int M = A.dim1();
+ int N = A.dim2();
+ int K = B.dim2();
+
+ Array2D<T> C(M,K);
+
+ for (int i=0; i<M; i++)
+ for (int j=0; j<K; j++)
+ {
+ T sum = 0;
+
+ for (int k=0; k<N; k++)
+ sum += A[i][k] * B [k][j];
+
+ C[i][j] = sum;
+ }
+
+ return C;
+
+}
+
+} // namespace TNT
+
+#endif
diff --git a/intern/smoke/intern/tnt/tnt_array3d.h b/intern/smoke/intern/tnt/tnt_array3d.h
new file mode 100644
index 00000000000..c210d2ed598
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_array3d.h
@@ -0,0 +1,296 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+
+#ifndef TNT_ARRAY3D_H
+#define TNT_ARRAY3D_H
+
+#include <cstdlib>
+#include <iostream>
+#ifdef TNT_BOUNDS_CHECK
+#include <assert.h>
+#endif
+
+#include "tnt_array1d.h"
+#include "tnt_array2d.h"
+
+namespace TNT
+{
+
+template <class T>
+class Array3D
+{
+
+
+ private:
+ Array1D<T> data_;
+ Array2D<T*> v_;
+ int m_;
+ int n_;
+ int g_;
+
+
+ public:
+
+ typedef T value_type;
+
+ Array3D();
+ Array3D(int m, int n, int g);
+ Array3D(int m, int n, int g, T val);
+ Array3D(int m, int n, int g, T *a);
+
+ inline operator T***();
+ inline operator const T***();
+ inline Array3D(const Array3D &A);
+ inline Array3D & operator=(const T &a);
+ inline Array3D & operator=(const Array3D &A);
+ inline Array3D & ref(const Array3D &A);
+ Array3D copy() const;
+ Array3D & inject(const Array3D & A);
+
+ inline T** operator[](int i);
+ inline const T* const * operator[](int i) const;
+ inline int dim1() const;
+ inline int dim2() const;
+ inline int dim3() const;
+ ~Array3D();
+
+ /* extended interface */
+
+ inline int ref_count(){ return data_.ref_count(); }
+ Array3D subarray(int i0, int i1, int j0, int j1,
+ int k0, int k1);
+};
+
+template <class T>
+Array3D<T>::Array3D() : data_(), v_(), m_(0), n_(0) {}
+
+template <class T>
+Array3D<T>::Array3D(const Array3D<T> &A) : data_(A.data_),
+ v_(A.v_), m_(A.m_), n_(A.n_), g_(A.g_)
+{
+}
+
+
+
+template <class T>
+Array3D<T>::Array3D(int m, int n, int g) : data_(m*n*g), v_(m,n),
+ m_(m), n_(n), g_(g)
+{
+
+ if (m>0 && n>0 && g>0)
+ {
+ T* p = & (data_[0]);
+ int ng = n_*g_;
+
+ for (int i=0; i<m_; i++)
+ {
+ T* ping = p+ i*ng;
+ for (int j=0; j<n; j++)
+ v_[i][j] = ping + j*g_;
+ }
+ }
+}
+
+
+
+template <class T>
+Array3D<T>::Array3D(int m, int n, int g, T val) : data_(m*n*g, val),
+ v_(m,n), m_(m), n_(n), g_(g)
+{
+ if (m>0 && n>0 && g>0)
+ {
+
+ T* p = & (data_[0]);
+ int ng = n_*g_;
+
+ for (int i=0; i<m_; i++)
+ {
+ T* ping = p+ i*ng;
+ for (int j=0; j<n; j++)
+ v_[i][j] = ping + j*g_;
+ }
+ }
+}
+
+
+
+template <class T>
+Array3D<T>::Array3D(int m, int n, int g, T* a) :
+ data_(m*n*g, a), v_(m,n), m_(m), n_(n), g_(g)
+{
+
+ if (m>0 && n>0 && g>0)
+ {
+ T* p = & (data_[0]);
+ int ng = n_*g_;
+
+ for (int i=0; i<m_; i++)
+ {
+ T* ping = p+ i*ng;
+ for (int j=0; j<n; j++)
+ v_[i][j] = ping + j*g_;
+ }
+ }
+}
+
+
+
+template <class T>
+inline T** Array3D<T>::operator[](int i)
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i >= 0);
+ assert(i < m_);
+#endif
+
+return v_[i];
+
+}
+
+template <class T>
+inline const T* const * Array3D<T>::operator[](int i) const
+{ return v_[i]; }
+
+template <class T>
+Array3D<T> & Array3D<T>::operator=(const T &a)
+{
+ for (int i=0; i<m_; i++)
+ for (int j=0; j<n_; j++)
+ for (int k=0; k<g_; k++)
+ v_[i][j][k] = a;
+
+ return *this;
+}
+
+template <class T>
+Array3D<T> Array3D<T>::copy() const
+{
+ Array3D A(m_, n_, g_);
+ for (int i=0; i<m_; i++)
+ for (int j=0; j<n_; j++)
+ for (int k=0; k<g_; k++)
+ A.v_[i][j][k] = v_[i][j][k];
+
+ return A;
+}
+
+
+template <class T>
+Array3D<T> & Array3D<T>::inject(const Array3D &A)
+{
+ if (A.m_ == m_ && A.n_ == n_ && A.g_ == g_)
+
+ for (int i=0; i<m_; i++)
+ for (int j=0; j<n_; j++)
+ for (int k=0; k<g_; k++)
+ v_[i][j][k] = A.v_[i][j][k];
+
+ return *this;
+}
+
+
+
+template <class T>
+Array3D<T> & Array3D<T>::ref(const Array3D<T> &A)
+{
+ if (this != &A)
+ {
+ m_ = A.m_;
+ n_ = A.n_;
+ g_ = A.g_;
+ v_ = A.v_;
+ data_ = A.data_;
+ }
+ return *this;
+}
+
+template <class T>
+Array3D<T> & Array3D<T>::operator=(const Array3D<T> &A)
+{
+ return ref(A);
+}
+
+
+template <class T>
+inline int Array3D<T>::dim1() const { return m_; }
+
+template <class T>
+inline int Array3D<T>::dim2() const { return n_; }
+
+template <class T>
+inline int Array3D<T>::dim3() const { return g_; }
+
+
+
+template <class T>
+Array3D<T>::~Array3D() {}
+
+template <class T>
+inline Array3D<T>::operator T***()
+{
+ return v_;
+}
+
+
+template <class T>
+inline Array3D<T>::operator const T***()
+{
+ return v_;
+}
+
+/* extended interface */
+template <class T>
+Array3D<T> Array3D<T>::subarray(int i0, int i1, int j0,
+ int j1, int k0, int k1)
+{
+
+ /* check that ranges are valid. */
+ if (!( 0 <= i0 && i0 <= i1 && i1 < m_ &&
+ 0 <= j0 && j0 <= j1 && j1 < n_ &&
+ 0 <= k0 && k0 <= k1 && k1 < g_))
+ return Array3D<T>(); /* null array */
+
+
+ Array3D<T> A;
+ A.data_ = data_;
+ A.m_ = i1-i0+1;
+ A.n_ = j1-j0+1;
+ A.g_ = k1-k0+1;
+ A.v_ = Array2D<T*>(A.m_,A.n_);
+ T* p = &(data_[0]) + i0*n_*g_ + j0*g_ + k0;
+
+ for (int i=0; i<A.m_; i++)
+ {
+ T* ping = p + i*n_*g_;
+ for (int j=0; j<A.n_; j++)
+ A.v_[i][j] = ping + j*g_ ;
+ }
+
+ return A;
+}
+
+
+
+} /* namespace TNT */
+
+#endif
+/* TNT_ARRAY3D_H */
+
diff --git a/intern/smoke/intern/tnt/tnt_array3d_utils.h b/intern/smoke/intern/tnt/tnt_array3d_utils.h
new file mode 100644
index 00000000000..5acdc1d5dd2
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_array3d_utils.h
@@ -0,0 +1,236 @@
+
+
+#ifndef TNT_ARRAY3D_UTILS_H
+#define TNT_ARRAY3D_UTILS_H
+
+#include <cstdlib>
+#include <cassert>
+
+namespace TNT
+{
+
+
+template <class T>
+std::ostream& operator<<(std::ostream &s, const Array3D<T> &A)
+{
+ int M=A.dim1();
+ int N=A.dim2();
+ int K=A.dim3();
+
+ s << M << " " << N << " " << K << "\n";
+
+ for (int i=0; i<M; i++)
+ {
+ for (int j=0; j<N; j++)
+ {
+ for (int k=0; k<K; k++)
+ s << A[i][j][k] << " ";
+ s << "\n";
+ }
+ s << "\n";
+ }
+
+
+ return s;
+}
+
+template <class T>
+std::istream& operator>>(std::istream &s, Array3D<T> &A)
+{
+
+ int M, N, K;
+
+ s >> M >> N >> K;
+
+ Array3D<T> B(M,N,K);
+
+ for (int i=0; i<M; i++)
+ for (int j=0; j<N; j++)
+ for (int k=0; k<K; k++)
+ s >> B[i][j][k];
+
+ A = B;
+ return s;
+}
+
+
+
+template <class T>
+Array3D<T> operator+(const Array3D<T> &A, const Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
+ return Array3D<T>();
+
+ else
+ {
+ Array3D<T> C(m,n,p);
+
+ for (int i=0; i<m; i++)
+ for (int j=0; j<n; j++)
+ for (int k=0; k<p; k++)
+ C[i][j][k] = A[i][j][k] + B[i][j][k];
+
+ return C;
+ }
+}
+
+
+template <class T>
+Array3D<T> operator-(const Array3D<T> &A, const Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
+ return Array3D<T>();
+
+ else
+ {
+ Array3D<T> C(m,n,p);
+
+ for (int i=0; i<m; i++)
+ for (int j=0; j<n; j++)
+ for (int k=0; k<p; k++)
+ C[i][j][k] = A[i][j][k] - B[i][j][k];
+
+ return C;
+ }
+}
+
+
+
+
+template <class T>
+Array3D<T> operator*(const Array3D<T> &A, const Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
+ return Array3D<T>();
+
+ else
+ {
+ Array3D<T> C(m,n,p);
+
+ for (int i=0; i<m; i++)
+ for (int j=0; j<n; j++)
+ for (int k=0; k<p; k++)
+ C[i][j][k] = A[i][j][k] * B[i][j][k];
+
+ return C;
+ }
+}
+
+
+template <class T>
+Array3D<T> operator/(const Array3D<T> &A, const Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
+ return Array3D<T>();
+
+ else
+ {
+ Array3D<T> C(m,n,p);
+
+ for (int i=0; i<m; i++)
+ for (int j=0; j<n; j++)
+ for (int k=0; k<p; k++)
+ C[i][j][k] = A[i][j][k] / B[i][j][k];
+
+ return C;
+ }
+}
+
+
+
+template <class T>
+Array3D<T>& operator+=(Array3D<T> &A, const Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
+ {
+ for (int i=0; i<m; i++)
+ for (int j=0; j<n; j++)
+ for (int k=0; k<p; k++)
+ A[i][j][k] += B[i][j][k];
+ }
+
+ return A;
+}
+
+template <class T>
+Array3D<T>& operator-=(Array3D<T> &A, const Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
+ {
+ for (int i=0; i<m; i++)
+ for (int j=0; j<n; j++)
+ for (int k=0; k<p; k++)
+ A[i][j][k] -= B[i][j][k];
+ }
+
+ return A;
+}
+
+template <class T>
+Array3D<T>& operator*=(Array3D<T> &A, const Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
+ {
+ for (int i=0; i<m; i++)
+ for (int j=0; j<n; j++)
+ for (int k=0; k<p; k++)
+ A[i][j][k] *= B[i][j][k];
+ }
+
+ return A;
+}
+
+
+template <class T>
+Array3D<T>& operator/=(Array3D<T> &A, const Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
+ {
+ for (int i=0; i<m; i++)
+ for (int j=0; j<n; j++)
+ for (int k=0; k<p; k++)
+ A[i][j][k] /= B[i][j][k];
+ }
+
+ return A;
+}
+
+
+
+
+
+} // namespace TNT
+
+#endif
diff --git a/intern/smoke/intern/tnt/tnt_cmat.h b/intern/smoke/intern/tnt/tnt_cmat.h
new file mode 100644
index 00000000000..5ff4c4898c3
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_cmat.h
@@ -0,0 +1,580 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+// C compatible matrix: row-oriented, 0-based [i][j] and 1-based (i,j) indexing
+//
+
+#ifndef TNT_CMAT_H
+#define TNT_CMAT_H
+
+#include "tnt_subscript.h"
+#include "tnt_vec.h"
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <sstream>
+
+namespace TNT
+{
+
+
+template <class T>
+class Matrix
+{
+
+
+ public:
+
+ typedef Subscript size_type;
+ typedef T value_type;
+ typedef T element_type;
+ typedef T* pointer;
+ typedef T* iterator;
+ typedef T& reference;
+ typedef const T* const_iterator;
+ typedef const T& const_reference;
+
+ Subscript lbound() const { return 1;}
+
+ protected:
+ Subscript m_;
+ Subscript n_;
+ Subscript mn_; // total size
+ T* v_;
+ T** row_;
+ T* vm1_ ; // these point to the same data, but are 1-based
+ T** rowm1_;
+
+ // internal helper function to create the array
+ // of row pointers
+
+ void initialize(Subscript M, Subscript N)
+ {
+ mn_ = M*N;
+ m_ = M;
+ n_ = N;
+
+ v_ = new T[mn_];
+ row_ = new T*[M];
+ rowm1_ = new T*[M];
+
+ assert(v_ != NULL);
+ assert(row_ != NULL);
+ assert(rowm1_ != NULL);
+
+ T* p = v_;
+ vm1_ = v_ - 1;
+ for (Subscript i=0; i<M; i++)
+ {
+ row_[i] = p;
+ rowm1_[i] = p-1;
+ p += N ;
+
+ }
+
+ rowm1_ -- ; // compensate for 1-based offset
+ }
+
+ void copy(const T* v)
+ {
+ Subscript N = m_ * n_;
+ Subscript i;
+
+#ifdef TNT_UNROLL_LOOPS
+ Subscript Nmod4 = N & 3;
+ Subscript N4 = N - Nmod4;
+
+ for (i=0; i<N4; i+=4)
+ {
+ v_[i] = v[i];
+ v_[i+1] = v[i+1];
+ v_[i+2] = v[i+2];
+ v_[i+3] = v[i+3];
+ }
+
+ for (i=N4; i< N; i++)
+ v_[i] = v[i];
+#else
+
+ for (i=0; i< N; i++)
+ v_[i] = v[i];
+#endif
+ }
+
+ void set(const T& val)
+ {
+ Subscript N = m_ * n_;
+ Subscript i;
+
+#ifdef TNT_UNROLL_LOOPS
+ Subscript Nmod4 = N & 3;
+ Subscript N4 = N - Nmod4;
+
+ for (i=0; i<N4; i+=4)
+ {
+ v_[i] = val;
+ v_[i+1] = val;
+ v_[i+2] = val;
+ v_[i+3] = val;
+ }
+
+ for (i=N4; i< N; i++)
+ v_[i] = val;
+#else
+
+ for (i=0; i< N; i++)
+ v_[i] = val;
+
+#endif
+ }
+
+
+
+ void destroy()
+ {
+ /* do nothing, if no memory has been previously allocated */
+ if (v_ == NULL) return ;
+
+ /* if we are here, then matrix was previously allocated */
+ if (v_ != NULL) delete [] (v_);
+ if (row_ != NULL) delete [] (row_);
+
+ /* return rowm1_ back to original value */
+ rowm1_ ++;
+ if (rowm1_ != NULL ) delete [] (rowm1_);
+ }
+
+
+ public:
+
+ operator T**(){ return row_; }
+ operator T**() const { return row_; }
+
+
+ Subscript size() const { return mn_; }
+
+ // constructors
+
+ Matrix() : m_(0), n_(0), mn_(0), v_(0), row_(0), vm1_(0), rowm1_(0) {};
+
+ Matrix(const Matrix<T> &A)
+ {
+ initialize(A.m_, A.n_);
+ copy(A.v_);
+ }
+
+ Matrix(Subscript M, Subscript N, const T& value = T())
+ {
+ initialize(M,N);
+ set(value);
+ }
+
+ Matrix(Subscript M, Subscript N, const T* v)
+ {
+ initialize(M,N);
+ copy(v);
+ }
+
+ Matrix(Subscript M, Subscript N, const char *s)
+ {
+ initialize(M,N);
+ //std::istrstream ins(s);
+ std::istringstream ins(s);
+
+ Subscript i, j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ ins >> row_[i][j];
+ }
+
+ // destructor
+ //
+ ~Matrix()
+ {
+ destroy();
+ }
+
+
+ // reallocating
+ //
+ Matrix<T>& newsize(Subscript M, Subscript N)
+ {
+ if (num_rows() == M && num_cols() == N)
+ return *this;
+
+ destroy();
+ initialize(M,N);
+
+ return *this;
+ }
+
+
+
+
+ // assignments
+ //
+ Matrix<T>& operator=(const Matrix<T> &A)
+ {
+ if (v_ == A.v_)
+ return *this;
+
+ if (m_ == A.m_ && n_ == A.n_) // no need to re-alloc
+ copy(A.v_);
+
+ else
+ {
+ destroy();
+ initialize(A.m_, A.n_);
+ copy(A.v_);
+ }
+
+ return *this;
+ }
+
+ Matrix<T>& operator=(const T& scalar)
+ {
+ set(scalar);
+ return *this;
+ }
+
+
+ Subscript dim(Subscript d) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert( d >= 1);
+ assert( d <= 2);
+#endif
+ return (d==1) ? m_ : ((d==2) ? n_ : 0);
+ }
+
+ Subscript num_rows() const { return m_; }
+ Subscript num_cols() const { return n_; }
+
+
+
+
+ inline T* operator[](Subscript i)
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(0<=i);
+ assert(i < m_) ;
+#endif
+ return row_[i];
+ }
+
+ inline const T* operator[](Subscript i) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(0<=i);
+ assert(i < m_) ;
+#endif
+ return row_[i];
+ }
+
+ inline reference operator()(Subscript i)
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= mn_) ;
+#endif
+ return vm1_[i];
+ }
+
+ inline const_reference operator()(Subscript i) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= mn_) ;
+#endif
+ return vm1_[i];
+ }
+
+
+
+ inline reference operator()(Subscript i, Subscript j)
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= m_) ;
+ assert(1<=j);
+ assert(j <= n_);
+#endif
+ return rowm1_[i][j];
+ }
+
+
+
+ inline const_reference operator() (Subscript i, Subscript j) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= m_) ;
+ assert(1<=j);
+ assert(j <= n_);
+#endif
+ return rowm1_[i][j];
+ }
+
+
+
+
+};
+
+
+/* *************************** I/O ********************************/
+
+template <class T>
+std::ostream& operator<<(std::ostream &s, const Matrix<T> &A)
+{
+ Subscript M=A.num_rows();
+ Subscript N=A.num_cols();
+
+ s << M << " " << N << "\n";
+
+ for (Subscript i=0; i<M; i++)
+ {
+ for (Subscript j=0; j<N; j++)
+ {
+ s << A[i][j] << " ";
+ }
+ s << "\n";
+ }
+
+
+ return s;
+}
+
+template <class T>
+std::istream& operator>>(std::istream &s, Matrix<T> &A)
+{
+
+ Subscript M, N;
+
+ s >> M >> N;
+
+ if ( !(M == A.num_rows() && N == A.num_cols() ))
+ {
+ A.newsize(M,N);
+ }
+
+
+ for (Subscript i=0; i<M; i++)
+ for (Subscript j=0; j<N; j++)
+ {
+ s >> A[i][j];
+ }
+
+
+ return s;
+}
+
+// *******************[ basic matrix algorithms ]***************************
+
+
+template <class T>
+Matrix<T> operator+(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ assert(M==B.num_rows());
+ assert(N==B.num_cols());
+
+ Matrix<T> tmp(M,N);
+ Subscript i,j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ tmp[i][j] = A[i][j] + B[i][j];
+
+ return tmp;
+}
+
+template <class T>
+Matrix<T> operator-(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ assert(M==B.num_rows());
+ assert(N==B.num_cols());
+
+ Matrix<T> tmp(M,N);
+ Subscript i,j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ tmp[i][j] = A[i][j] - B[i][j];
+
+ return tmp;
+}
+
+template <class T>
+Matrix<T> mult_element(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ assert(M==B.num_rows());
+ assert(N==B.num_cols());
+
+ Matrix<T> tmp(M,N);
+ Subscript i,j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ tmp[i][j] = A[i][j] * B[i][j];
+
+ return tmp;
+}
+
+
+template <class T>
+Matrix<T> transpose(const Matrix<T> &A)
+{
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ Matrix<T> S(N,M);
+ Subscript i, j;
+
+ for (i=0; i<M; i++)
+ for (j=0; j<N; j++)
+ S[j][i] = A[i][j];
+
+ return S;
+}
+
+
+
+template <class T>
+inline Matrix<T> matmult(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+
+#ifdef TNT_BOUNDS_CHECK
+ assert(A.num_cols() == B.num_rows());
+#endif
+
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+ Subscript K = B.num_cols();
+
+ Matrix<T> tmp(M,K);
+ T sum;
+
+ for (Subscript i=0; i<M; i++)
+ for (Subscript k=0; k<K; k++)
+ {
+ sum = 0;
+ for (Subscript j=0; j<N; j++)
+ sum = sum + A[i][j] * B[j][k];
+
+ tmp[i][k] = sum;
+ }
+
+ return tmp;
+}
+
+template <class T>
+inline Matrix<T> operator*(const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+ return matmult(A,B);
+}
+
+template <class T>
+inline int matmult(Matrix<T>& C, const Matrix<T> &A,
+ const Matrix<T> &B)
+{
+
+ assert(A.num_cols() == B.num_rows());
+
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+ Subscript K = B.num_cols();
+
+ C.newsize(M,K);
+
+ T sum;
+
+ const T* row_i;
+ const T* col_k;
+
+ for (Subscript i=0; i<M; i++)
+ for (Subscript k=0; k<K; k++)
+ {
+ row_i = &(A[i][0]);
+ col_k = &(B[0][k]);
+ sum = 0;
+ for (Subscript j=0; j<N; j++)
+ {
+ sum += *row_i * *col_k;
+ row_i++;
+ col_k += K;
+ }
+ C[i][k] = sum;
+ }
+
+ return 0;
+}
+
+
+template <class T>
+Vector<T> matmult(const Matrix<T> &A, const Vector<T> &x)
+{
+
+#ifdef TNT_BOUNDS_CHECK
+ assert(A.num_cols() == x.dim());
+#endif
+
+ Subscript M = A.num_rows();
+ Subscript N = A.num_cols();
+
+ Vector<T> tmp(M);
+ T sum;
+
+ for (Subscript i=0; i<M; i++)
+ {
+ sum = 0;
+ const T* rowi = A[i];
+ for (Subscript j=0; j<N; j++)
+ sum = sum + rowi[j] * x[j];
+
+ tmp[i] = sum;
+ }
+
+ return tmp;
+}
+
+template <class T>
+inline Vector<T> operator*(const Matrix<T> &A, const Vector<T> &x)
+{
+ return matmult(A,x);
+}
+
+} // namespace TNT
+
+#endif
+// CMAT_H
diff --git a/intern/smoke/intern/tnt/tnt_fortran_array1d.h b/intern/smoke/intern/tnt/tnt_fortran_array1d.h
new file mode 100644
index 00000000000..ad3bba0c0a7
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_fortran_array1d.h
@@ -0,0 +1,267 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+
+#ifndef TNT_FORTRAN_ARRAY1D_H
+#define TNT_FORTRAN_ARRAY1D_H
+
+#include <cstdlib>
+#include <iostream>
+
+#ifdef TNT_BOUNDS_CHECK
+#include <assert.h>
+#endif
+
+
+#include "tnt_i_refvec.h"
+
+namespace TNT
+{
+
+template <class T>
+class Fortran_Array1D
+{
+
+ private:
+
+ i_refvec<T> v_;
+ int n_;
+ T* data_; /* this normally points to v_.begin(), but
+ * could also point to a portion (subvector)
+ * of v_.
+ */
+
+ void initialize_(int n);
+ void copy_(T* p, const T* q, int len) const;
+ void set_(T* begin, T* end, const T& val);
+
+
+ public:
+
+ typedef T value_type;
+
+
+ Fortran_Array1D();
+ explicit Fortran_Array1D(int n);
+ Fortran_Array1D(int n, const T &a);
+ Fortran_Array1D(int n, T *a);
+ inline Fortran_Array1D(const Fortran_Array1D &A);
+ inline Fortran_Array1D & operator=(const T &a);
+ inline Fortran_Array1D & operator=(const Fortran_Array1D &A);
+ inline Fortran_Array1D & ref(const Fortran_Array1D &A);
+ Fortran_Array1D copy() const;
+ Fortran_Array1D & inject(const Fortran_Array1D & A);
+ inline T& operator()(int i);
+ inline const T& operator()(int i) const;
+ inline int dim1() const;
+ inline int dim() const;
+ ~Fortran_Array1D();
+
+
+ /* ... extended interface ... */
+
+ inline int ref_count() const;
+ inline Fortran_Array1D<T> subarray(int i0, int i1);
+
+};
+
+
+
+
+template <class T>
+Fortran_Array1D<T>::Fortran_Array1D() : v_(), n_(0), data_(0) {}
+
+template <class T>
+Fortran_Array1D<T>::Fortran_Array1D(const Fortran_Array1D<T> &A) : v_(A.v_), n_(A.n_),
+ data_(A.data_)
+{
+#ifdef TNT_DEBUG
+ std::cout << "Created Fortran_Array1D(const Fortran_Array1D<T> &A) \n";
+#endif
+
+}
+
+
+template <class T>
+Fortran_Array1D<T>::Fortran_Array1D(int n) : v_(n), n_(n), data_(v_.begin())
+{
+#ifdef TNT_DEBUG
+ std::cout << "Created Fortran_Array1D(int n) \n";
+#endif
+}
+
+template <class T>
+Fortran_Array1D<T>::Fortran_Array1D(int n, const T &val) : v_(n), n_(n), data_(v_.begin())
+{
+#ifdef TNT_DEBUG
+ std::cout << "Created Fortran_Array1D(int n, const T& val) \n";
+#endif
+ set_(data_, data_+ n, val);
+
+}
+
+template <class T>
+Fortran_Array1D<T>::Fortran_Array1D(int n, T *a) : v_(a), n_(n) , data_(v_.begin())
+{
+#ifdef TNT_DEBUG
+ std::cout << "Created Fortran_Array1D(int n, T* a) \n";
+#endif
+}
+
+template <class T>
+inline T& Fortran_Array1D<T>::operator()(int i)
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i>= 1);
+ assert(i <= n_);
+#endif
+ return data_[i-1];
+}
+
+template <class T>
+inline const T& Fortran_Array1D<T>::operator()(int i) const
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i>= 1);
+ assert(i <= n_);
+#endif
+ return data_[i-1];
+}
+
+
+
+
+template <class T>
+Fortran_Array1D<T> & Fortran_Array1D<T>::operator=(const T &a)
+{
+ set_(data_, data_+n_, a);
+ return *this;
+}
+
+template <class T>
+Fortran_Array1D<T> Fortran_Array1D<T>::copy() const
+{
+ Fortran_Array1D A( n_);
+ copy_(A.data_, data_, n_);
+
+ return A;
+}
+
+
+template <class T>
+Fortran_Array1D<T> & Fortran_Array1D<T>::inject(const Fortran_Array1D &A)
+{
+ if (A.n_ == n_)
+ copy_(data_, A.data_, n_);
+
+ return *this;
+}
+
+
+
+
+
+template <class T>
+Fortran_Array1D<T> & Fortran_Array1D<T>::ref(const Fortran_Array1D<T> &A)
+{
+ if (this != &A)
+ {
+ v_ = A.v_; /* operator= handles the reference counting. */
+ n_ = A.n_;
+ data_ = A.data_;
+
+ }
+ return *this;
+}
+
+template <class T>
+Fortran_Array1D<T> & Fortran_Array1D<T>::operator=(const Fortran_Array1D<T> &A)
+{
+ return ref(A);
+}
+
+template <class T>
+inline int Fortran_Array1D<T>::dim1() const { return n_; }
+
+template <class T>
+inline int Fortran_Array1D<T>::dim() const { return n_; }
+
+template <class T>
+Fortran_Array1D<T>::~Fortran_Array1D() {}
+
+
+/* ............................ exented interface ......................*/
+
+template <class T>
+inline int Fortran_Array1D<T>::ref_count() const
+{
+ return v_.ref_count();
+}
+
+template <class T>
+inline Fortran_Array1D<T> Fortran_Array1D<T>::subarray(int i0, int i1)
+{
+#ifdef TNT_DEBUG
+ std::cout << "entered subarray. \n";
+#endif
+ if ((i0 > 0) && (i1 < n_) || (i0 <= i1))
+ {
+ Fortran_Array1D<T> X(*this); /* create a new instance of this array. */
+ X.n_ = i1-i0+1;
+ X.data_ += i0;
+
+ return X;
+ }
+ else
+ {
+#ifdef TNT_DEBUG
+ std::cout << "subarray: null return.\n";
+#endif
+ return Fortran_Array1D<T>();
+ }
+}
+
+
+/* private internal functions */
+
+
+template <class T>
+void Fortran_Array1D<T>::set_(T* begin, T* end, const T& a)
+{
+ for (T* p=begin; p<end; p++)
+ *p = a;
+
+}
+
+template <class T>
+void Fortran_Array1D<T>::copy_(T* p, const T* q, int len) const
+{
+ T *end = p + len;
+ while (p<end )
+ *p++ = *q++;
+
+}
+
+
+} /* namespace TNT */
+
+#endif
+/* TNT_FORTRAN_ARRAY1D_H */
+
diff --git a/intern/smoke/intern/tnt/tnt_fortran_array1d_utils.h b/intern/smoke/intern/tnt/tnt_fortran_array1d_utils.h
new file mode 100644
index 00000000000..b037b173f77
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_fortran_array1d_utils.h
@@ -0,0 +1,242 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+#ifndef TNT_FORTRAN_ARRAY1D_UTILS_H
+#define TNT_FORTRAN_ARRAY1D_UTILS_H
+
+#include <iostream>
+
+namespace TNT
+{
+
+
+/**
+ Write an array to a character outstream. Output format is one that can
+ be read back in via the in-stream operator: one integer
+ denoting the array dimension (n), followed by n elements,
+ one per line.
+
+*/
+template <class T>
+std::ostream& operator<<(std::ostream &s, const Fortran_Array1D<T> &A)
+{
+ int N=A.dim1();
+
+ s << N << "\n";
+ for (int j=1; j<=N; j++)
+ {
+ s << A(j) << "\n";
+ }
+ s << "\n";
+
+ return s;
+}
+
+/**
+ Read an array from a character stream. Input format
+ is one integer, denoting the dimension (n), followed
+ by n whitespace-separated elments. Newlines are ignored
+
+ <p>
+ Note: the array being read into references new memory
+ storage. If the intent is to fill an existing conformant
+ array, use <code> cin >> B; A.inject(B) ); </code>
+ instead or read the elements in one-a-time by hand.
+
+ @param s the charater to read from (typically <code>std::in</code>)
+ @param A the array to read into.
+*/
+template <class T>
+std::istream& operator>>(std::istream &s, Fortran_Array1D<T> &A)
+{
+ int N;
+ s >> N;
+
+ Fortran_Array1D<T> B(N);
+ for (int i=1; i<=N; i++)
+ s >> B(i);
+ A = B;
+ return s;
+}
+
+
+template <class T>
+Fortran_Array1D<T> operator+(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() != n )
+ return Fortran_Array1D<T>();
+
+ else
+ {
+ Fortran_Array1D<T> C(n);
+
+ for (int i=1; i<=n; i++)
+ {
+ C(i) = A(i) + B(i);
+ }
+ return C;
+ }
+}
+
+
+
+template <class T>
+Fortran_Array1D<T> operator-(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() != n )
+ return Fortran_Array1D<T>();
+
+ else
+ {
+ Fortran_Array1D<T> C(n);
+
+ for (int i=1; i<=n; i++)
+ {
+ C(i) = A(i) - B(i);
+ }
+ return C;
+ }
+}
+
+
+template <class T>
+Fortran_Array1D<T> operator*(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() != n )
+ return Fortran_Array1D<T>();
+
+ else
+ {
+ Fortran_Array1D<T> C(n);
+
+ for (int i=1; i<=n; i++)
+ {
+ C(i) = A(i) * B(i);
+ }
+ return C;
+ }
+}
+
+
+template <class T>
+Fortran_Array1D<T> operator/(const Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() != n )
+ return Fortran_Array1D<T>();
+
+ else
+ {
+ Fortran_Array1D<T> C(n);
+
+ for (int i=1; i<=n; i++)
+ {
+ C(i) = A(i) / B(i);
+ }
+ return C;
+ }
+}
+
+
+
+
+
+
+
+
+
+template <class T>
+Fortran_Array1D<T>& operator+=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() == n)
+ {
+ for (int i=1; i<=n; i++)
+ {
+ A(i) += B(i);
+ }
+ }
+ return A;
+}
+
+
+
+
+template <class T>
+Fortran_Array1D<T>& operator-=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() == n)
+ {
+ for (int i=1; i<=n; i++)
+ {
+ A(i) -= B(i);
+ }
+ }
+ return A;
+}
+
+
+
+template <class T>
+Fortran_Array1D<T>& operator*=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() == n)
+ {
+ for (int i=1; i<=n; i++)
+ {
+ A(i) *= B(i);
+ }
+ }
+ return A;
+}
+
+
+
+
+template <class T>
+Fortran_Array1D<T>& operator/=(Fortran_Array1D<T> &A, const Fortran_Array1D<T> &B)
+{
+ int n = A.dim1();
+
+ if (B.dim1() == n)
+ {
+ for (int i=1; i<=n; i++)
+ {
+ A(i) /= B(i);
+ }
+ }
+ return A;
+}
+
+
+} // namespace TNT
+
+#endif
diff --git a/intern/smoke/intern/tnt/tnt_fortran_array2d.h b/intern/smoke/intern/tnt/tnt_fortran_array2d.h
new file mode 100644
index 00000000000..f3075366d37
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_fortran_array2d.h
@@ -0,0 +1,225 @@
+/*
+*
+* Template Numerical Toolkit (TNT): Two-dimensional Fortran numerical array
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+
+#ifndef TNT_FORTRAN_ARRAY2D_H
+#define TNT_FORTRAN_ARRAY2D_H
+
+#include <cstdlib>
+#include <iostream>
+
+#ifdef TNT_BOUNDS_CHECK
+#include <assert.h>
+#endif
+
+#include "tnt_i_refvec.h"
+
+namespace TNT
+{
+
+template <class T>
+class Fortran_Array2D
+{
+
+
+ private:
+ i_refvec<T> v_;
+ int m_;
+ int n_;
+ T* data_;
+
+
+ void initialize_(int n);
+ void copy_(T* p, const T* q, int len);
+ void set_(T* begin, T* end, const T& val);
+
+ public:
+
+ typedef T value_type;
+
+ Fortran_Array2D();
+ Fortran_Array2D(int m, int n);
+ Fortran_Array2D(int m, int n, T *a);
+ Fortran_Array2D(int m, int n, const T &a);
+ inline Fortran_Array2D(const Fortran_Array2D &A);
+ inline Fortran_Array2D & operator=(const T &a);
+ inline Fortran_Array2D & operator=(const Fortran_Array2D &A);
+ inline Fortran_Array2D & ref(const Fortran_Array2D &A);
+ Fortran_Array2D copy() const;
+ Fortran_Array2D & inject(const Fortran_Array2D & A);
+ inline T& operator()(int i, int j);
+ inline const T& operator()(int i, int j) const ;
+ inline int dim1() const;
+ inline int dim2() const;
+ ~Fortran_Array2D();
+
+ /* extended interface */
+
+ inline int ref_count() const;
+
+};
+
+template <class T>
+Fortran_Array2D<T>::Fortran_Array2D() : v_(), m_(0), n_(0), data_(0) {}
+
+
+template <class T>
+Fortran_Array2D<T>::Fortran_Array2D(const Fortran_Array2D<T> &A) : v_(A.v_),
+ m_(A.m_), n_(A.n_), data_(A.data_) {}
+
+
+
+template <class T>
+Fortran_Array2D<T>::Fortran_Array2D(int m, int n) : v_(m*n), m_(m), n_(n),
+ data_(v_.begin()) {}
+
+template <class T>
+Fortran_Array2D<T>::Fortran_Array2D(int m, int n, const T &val) :
+ v_(m*n), m_(m), n_(n), data_(v_.begin())
+{
+ set_(data_, data_+m*n, val);
+}
+
+
+template <class T>
+Fortran_Array2D<T>::Fortran_Array2D(int m, int n, T *a) : v_(a),
+ m_(m), n_(n), data_(v_.begin()) {}
+
+
+
+
+template <class T>
+inline T& Fortran_Array2D<T>::operator()(int i, int j)
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i >= 1);
+ assert(i <= m_);
+ assert(j >= 1);
+ assert(j <= n_);
+#endif
+
+ return v_[ (j-1)*m_ + (i-1) ];
+
+}
+
+template <class T>
+inline const T& Fortran_Array2D<T>::operator()(int i, int j) const
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i >= 1);
+ assert(i <= m_);
+ assert(j >= 1);
+ assert(j <= n_);
+#endif
+
+ return v_[ (j-1)*m_ + (i-1) ];
+
+}
+
+
+template <class T>
+Fortran_Array2D<T> & Fortran_Array2D<T>::operator=(const T &a)
+{
+ set_(data_, data_+m_*n_, a);
+ return *this;
+}
+
+template <class T>
+Fortran_Array2D<T> Fortran_Array2D<T>::copy() const
+{
+
+ Fortran_Array2D B(m_,n_);
+
+ B.inject(*this);
+ return B;
+}
+
+
+template <class T>
+Fortran_Array2D<T> & Fortran_Array2D<T>::inject(const Fortran_Array2D &A)
+{
+ if (m_ == A.m_ && n_ == A.n_)
+ copy_(data_, A.data_, m_*n_);
+
+ return *this;
+}
+
+
+
+template <class T>
+Fortran_Array2D<T> & Fortran_Array2D<T>::ref(const Fortran_Array2D<T> &A)
+{
+ if (this != &A)
+ {
+ v_ = A.v_;
+ m_ = A.m_;
+ n_ = A.n_;
+ data_ = A.data_;
+ }
+ return *this;
+}
+
+template <class T>
+Fortran_Array2D<T> & Fortran_Array2D<T>::operator=(const Fortran_Array2D<T> &A)
+{
+ return ref(A);
+}
+
+template <class T>
+inline int Fortran_Array2D<T>::dim1() const { return m_; }
+
+template <class T>
+inline int Fortran_Array2D<T>::dim2() const { return n_; }
+
+
+template <class T>
+Fortran_Array2D<T>::~Fortran_Array2D()
+{
+}
+
+template <class T>
+inline int Fortran_Array2D<T>::ref_count() const { return v_.ref_count(); }
+
+
+
+
+template <class T>
+void Fortran_Array2D<T>::set_(T* begin, T* end, const T& a)
+{
+ for (T* p=begin; p<end; p++)
+ *p = a;
+
+}
+
+template <class T>
+void Fortran_Array2D<T>::copy_(T* p, const T* q, int len)
+{
+ T *end = p + len;
+ while (p<end )
+ *p++ = *q++;
+
+}
+
+
+} /* namespace TNT */
+
+#endif
+/* TNT_FORTRAN_ARRAY2D_H */
+
diff --git a/intern/smoke/intern/tnt/tnt_fortran_array2d_utils.h b/intern/smoke/intern/tnt/tnt_fortran_array2d_utils.h
new file mode 100644
index 00000000000..bb6867368cf
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_fortran_array2d_utils.h
@@ -0,0 +1,236 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+#ifndef TNT_FORTRAN_ARRAY2D_UTILS_H
+#define TNT_FORTRAN_ARRAY2D_UTILS_H
+
+#include <iostream>
+
+namespace TNT
+{
+
+
+template <class T>
+std::ostream& operator<<(std::ostream &s, const Fortran_Array2D<T> &A)
+{
+ int M=A.dim1();
+ int N=A.dim2();
+
+ s << M << " " << N << "\n";
+
+ for (int i=1; i<=M; i++)
+ {
+ for (int j=1; j<=N; j++)
+ {
+ s << A(i,j) << " ";
+ }
+ s << "\n";
+ }
+
+
+ return s;
+}
+
+template <class T>
+std::istream& operator>>(std::istream &s, Fortran_Array2D<T> &A)
+{
+
+ int M, N;
+
+ s >> M >> N;
+
+ Fortran_Array2D<T> B(M,N);
+
+ for (int i=1; i<=M; i++)
+ for (int j=1; j<=N; j++)
+ {
+ s >> B(i,j);
+ }
+
+ A = B;
+ return s;
+}
+
+
+
+
+template <class T>
+Fortran_Array2D<T> operator+(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() != m || B.dim2() != n )
+ return Fortran_Array2D<T>();
+
+ else
+ {
+ Fortran_Array2D<T> C(m,n);
+
+ for (int i=1; i<=m; i++)
+ {
+ for (int j=1; j<=n; j++)
+ C(i,j) = A(i,j) + B(i,j);
+ }
+ return C;
+ }
+}
+
+template <class T>
+Fortran_Array2D<T> operator-(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() != m || B.dim2() != n )
+ return Fortran_Array2D<T>();
+
+ else
+ {
+ Fortran_Array2D<T> C(m,n);
+
+ for (int i=1; i<=m; i++)
+ {
+ for (int j=1; j<=n; j++)
+ C(i,j) = A(i,j) - B(i,j);
+ }
+ return C;
+ }
+}
+
+
+template <class T>
+Fortran_Array2D<T> operator*(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() != m || B.dim2() != n )
+ return Fortran_Array2D<T>();
+
+ else
+ {
+ Fortran_Array2D<T> C(m,n);
+
+ for (int i=1; i<=m; i++)
+ {
+ for (int j=1; j<=n; j++)
+ C(i,j) = A(i,j) * B(i,j);
+ }
+ return C;
+ }
+}
+
+
+template <class T>
+Fortran_Array2D<T> operator/(const Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() != m || B.dim2() != n )
+ return Fortran_Array2D<T>();
+
+ else
+ {
+ Fortran_Array2D<T> C(m,n);
+
+ for (int i=1; i<=m; i++)
+ {
+ for (int j=1; j<=n; j++)
+ C(i,j) = A(i,j) / B(i,j);
+ }
+ return C;
+ }
+}
+
+
+
+template <class T>
+Fortran_Array2D<T>& operator+=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() == m || B.dim2() == n )
+ {
+ for (int i=1; i<=m; i++)
+ {
+ for (int j=1; j<=n; j++)
+ A(i,j) += B(i,j);
+ }
+ }
+ return A;
+}
+
+template <class T>
+Fortran_Array2D<T>& operator-=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() == m || B.dim2() == n )
+ {
+ for (int i=1; i<=m; i++)
+ {
+ for (int j=1; j<=n; j++)
+ A(i,j) -= B(i,j);
+ }
+ }
+ return A;
+}
+
+template <class T>
+Fortran_Array2D<T>& operator*=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() == m || B.dim2() == n )
+ {
+ for (int i=1; i<=m; i++)
+ {
+ for (int j=1; j<=n; j++)
+ A(i,j) *= B(i,j);
+ }
+ }
+ return A;
+}
+
+template <class T>
+Fortran_Array2D<T>& operator/=(Fortran_Array2D<T> &A, const Fortran_Array2D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+
+ if (B.dim1() == m || B.dim2() == n )
+ {
+ for (int i=1; i<=m; i++)
+ {
+ for (int j=1; j<=n; j++)
+ A(i,j) /= B(i,j);
+ }
+ }
+ return A;
+}
+
+} // namespace TNT
+
+#endif
diff --git a/intern/smoke/intern/tnt/tnt_fortran_array3d.h b/intern/smoke/intern/tnt/tnt_fortran_array3d.h
new file mode 100644
index 00000000000..e51affba4ea
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_fortran_array3d.h
@@ -0,0 +1,223 @@
+/*
+*
+* Template Numerical Toolkit (TNT): Three-dimensional Fortran numerical array
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+
+#ifndef TNT_FORTRAN_ARRAY3D_H
+#define TNT_FORTRAN_ARRAY3D_H
+
+#include <cstdlib>
+#include <iostream>
+#ifdef TNT_BOUNDS_CHECK
+#include <assert.h>
+#endif
+#include "tnt_i_refvec.h"
+
+namespace TNT
+{
+
+template <class T>
+class Fortran_Array3D
+{
+
+
+ private:
+
+
+ i_refvec<T> v_;
+ int m_;
+ int n_;
+ int k_;
+ T* data_;
+
+ public:
+
+ typedef T value_type;
+
+ Fortran_Array3D();
+ Fortran_Array3D(int m, int n, int k);
+ Fortran_Array3D(int m, int n, int k, T *a);
+ Fortran_Array3D(int m, int n, int k, const T &a);
+ inline Fortran_Array3D(const Fortran_Array3D &A);
+ inline Fortran_Array3D & operator=(const T &a);
+ inline Fortran_Array3D & operator=(const Fortran_Array3D &A);
+ inline Fortran_Array3D & ref(const Fortran_Array3D &A);
+ Fortran_Array3D copy() const;
+ Fortran_Array3D & inject(const Fortran_Array3D & A);
+ inline T& operator()(int i, int j, int k);
+ inline const T& operator()(int i, int j, int k) const ;
+ inline int dim1() const;
+ inline int dim2() const;
+ inline int dim3() const;
+ inline int ref_count() const;
+ ~Fortran_Array3D();
+
+
+};
+
+template <class T>
+Fortran_Array3D<T>::Fortran_Array3D() : v_(), m_(0), n_(0), k_(0), data_(0) {}
+
+
+template <class T>
+Fortran_Array3D<T>::Fortran_Array3D(const Fortran_Array3D<T> &A) :
+ v_(A.v_), m_(A.m_), n_(A.n_), k_(A.k_), data_(A.data_) {}
+
+
+
+template <class T>
+Fortran_Array3D<T>::Fortran_Array3D(int m, int n, int k) :
+ v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin()) {}
+
+
+
+template <class T>
+Fortran_Array3D<T>::Fortran_Array3D(int m, int n, int k, const T &val) :
+ v_(m*n*k), m_(m), n_(n), k_(k), data_(v_.begin())
+{
+ for (T* p = data_; p < data_ + m*n*k; p++)
+ *p = val;
+}
+
+template <class T>
+Fortran_Array3D<T>::Fortran_Array3D(int m, int n, int k, T *a) :
+ v_(a), m_(m), n_(n), k_(k), data_(v_.begin()) {}
+
+
+
+
+template <class T>
+inline T& Fortran_Array3D<T>::operator()(int i, int j, int k)
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i >= 1);
+ assert(i <= m_);
+ assert(j >= 1);
+ assert(j <= n_);
+ assert(k >= 1);
+ assert(k <= k_);
+#endif
+
+ return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1];
+
+}
+
+template <class T>
+inline const T& Fortran_Array3D<T>::operator()(int i, int j, int k) const
+{
+#ifdef TNT_BOUNDS_CHECK
+ assert(i >= 1);
+ assert(i <= m_);
+ assert(j >= 1);
+ assert(j <= n_);
+ assert(k >= 1);
+ assert(k <= k_);
+#endif
+
+ return data_[(k-1)*m_*n_ + (j-1) * m_ + i-1];
+}
+
+
+template <class T>
+Fortran_Array3D<T> & Fortran_Array3D<T>::operator=(const T &a)
+{
+
+ T *end = data_ + m_*n_*k_;
+
+ for (T *p=data_; p != end; *p++ = a);
+
+ return *this;
+}
+
+template <class T>
+Fortran_Array3D<T> Fortran_Array3D<T>::copy() const
+{
+
+ Fortran_Array3D B(m_, n_, k_);
+ B.inject(*this);
+ return B;
+
+}
+
+
+template <class T>
+Fortran_Array3D<T> & Fortran_Array3D<T>::inject(const Fortran_Array3D &A)
+{
+
+ if (m_ == A.m_ && n_ == A.n_ && k_ == A.k_)
+ {
+ T *p = data_;
+ T *end = data_ + m_*n_*k_;
+ const T* q = A.data_;
+ for (; p < end; *p++ = *q++);
+ }
+ return *this;
+}
+
+
+
+
+template <class T>
+Fortran_Array3D<T> & Fortran_Array3D<T>::ref(const Fortran_Array3D<T> &A)
+{
+
+ if (this != &A)
+ {
+ v_ = A.v_;
+ m_ = A.m_;
+ n_ = A.n_;
+ k_ = A.k_;
+ data_ = A.data_;
+ }
+ return *this;
+}
+
+template <class T>
+Fortran_Array3D<T> & Fortran_Array3D<T>::operator=(const Fortran_Array3D<T> &A)
+{
+ return ref(A);
+}
+
+template <class T>
+inline int Fortran_Array3D<T>::dim1() const { return m_; }
+
+template <class T>
+inline int Fortran_Array3D<T>::dim2() const { return n_; }
+
+template <class T>
+inline int Fortran_Array3D<T>::dim3() const { return k_; }
+
+
+template <class T>
+inline int Fortran_Array3D<T>::ref_count() const
+{
+ return v_.ref_count();
+}
+
+template <class T>
+Fortran_Array3D<T>::~Fortran_Array3D()
+{
+}
+
+
+} /* namespace TNT */
+
+#endif
+/* TNT_FORTRAN_ARRAY3D_H */
+
diff --git a/intern/smoke/intern/tnt/tnt_fortran_array3d_utils.h b/intern/smoke/intern/tnt/tnt_fortran_array3d_utils.h
new file mode 100644
index 00000000000..a13a275dc0d
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_fortran_array3d_utils.h
@@ -0,0 +1,249 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+#ifndef TNT_FORTRAN_ARRAY3D_UTILS_H
+#define TNT_FORTRAN_ARRAY3D_UTILS_H
+
+#include <cstdlib>
+#include <cassert>
+
+namespace TNT
+{
+
+
+template <class T>
+std::ostream& operator<<(std::ostream &s, const Fortran_Array3D<T> &A)
+{
+ int M=A.dim1();
+ int N=A.dim2();
+ int K=A.dim3();
+
+ s << M << " " << N << " " << K << "\n";
+
+ for (int i=1; i<=M; i++)
+ {
+ for (int j=1; j<=N; j++)
+ {
+ for (int k=1; k<=K; k++)
+ s << A(i,j,k) << " ";
+ s << "\n";
+ }
+ s << "\n";
+ }
+
+
+ return s;
+}
+
+template <class T>
+std::istream& operator>>(std::istream &s, Fortran_Array3D<T> &A)
+{
+
+ int M, N, K;
+
+ s >> M >> N >> K;
+
+ Fortran_Array3D<T> B(M,N,K);
+
+ for (int i=1; i<=M; i++)
+ for (int j=1; j<=N; j++)
+ for (int k=1; k<=K; k++)
+ s >> B(i,j,k);
+
+ A = B;
+ return s;
+}
+
+
+template <class T>
+Fortran_Array3D<T> operator+(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
+ return Fortran_Array3D<T>();
+
+ else
+ {
+ Fortran_Array3D<T> C(m,n,p);
+
+ for (int i=1; i<=m; i++)
+ for (int j=1; j<=n; j++)
+ for (int k=1; k<=p; k++)
+ C(i,j,k) = A(i,j,k)+ B(i,j,k);
+
+ return C;
+ }
+}
+
+
+template <class T>
+Fortran_Array3D<T> operator-(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
+ return Fortran_Array3D<T>();
+
+ else
+ {
+ Fortran_Array3D<T> C(m,n,p);
+
+ for (int i=1; i<=m; i++)
+ for (int j=1; j<=n; j++)
+ for (int k=1; k<=p; k++)
+ C(i,j,k) = A(i,j,k)- B(i,j,k);
+
+ return C;
+ }
+}
+
+
+template <class T>
+Fortran_Array3D<T> operator*(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
+ return Fortran_Array3D<T>();
+
+ else
+ {
+ Fortran_Array3D<T> C(m,n,p);
+
+ for (int i=1; i<=m; i++)
+ for (int j=1; j<=n; j++)
+ for (int k=1; k<=p; k++)
+ C(i,j,k) = A(i,j,k)* B(i,j,k);
+
+ return C;
+ }
+}
+
+
+template <class T>
+Fortran_Array3D<T> operator/(const Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() != m || B.dim2() != n || B.dim3() != p )
+ return Fortran_Array3D<T>();
+
+ else
+ {
+ Fortran_Array3D<T> C(m,n,p);
+
+ for (int i=1; i<=m; i++)
+ for (int j=1; j<=n; j++)
+ for (int k=1; k<=p; k++)
+ C(i,j,k) = A(i,j,k)/ B(i,j,k);
+
+ return C;
+ }
+}
+
+
+template <class T>
+Fortran_Array3D<T>& operator+=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
+ {
+ for (int i=1; i<=m; i++)
+ for (int j=1; j<=n; j++)
+ for (int k=1; k<=p; k++)
+ A(i,j,k) += B(i,j,k);
+ }
+
+ return A;
+}
+
+
+template <class T>
+Fortran_Array3D<T>& operator-=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
+ {
+ for (int i=1; i<=m; i++)
+ for (int j=1; j<=n; j++)
+ for (int k=1; k<=p; k++)
+ A(i,j,k) -= B(i,j,k);
+ }
+
+ return A;
+}
+
+
+template <class T>
+Fortran_Array3D<T>& operator*=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
+ {
+ for (int i=1; i<=m; i++)
+ for (int j=1; j<=n; j++)
+ for (int k=1; k<=p; k++)
+ A(i,j,k) *= B(i,j,k);
+ }
+
+ return A;
+}
+
+
+template <class T>
+Fortran_Array3D<T>& operator/=(Fortran_Array3D<T> &A, const Fortran_Array3D<T> &B)
+{
+ int m = A.dim1();
+ int n = A.dim2();
+ int p = A.dim3();
+
+ if (B.dim1() == m && B.dim2() == n && B.dim3() == p )
+ {
+ for (int i=1; i<=m; i++)
+ for (int j=1; j<=n; j++)
+ for (int k=1; k<=p; k++)
+ A(i,j,k) /= B(i,j,k);
+ }
+
+ return A;
+}
+
+
+} // namespace TNT
+
+#endif
diff --git a/intern/smoke/intern/tnt/tnt_i_refvec.h b/intern/smoke/intern/tnt/tnt_i_refvec.h
new file mode 100644
index 00000000000..5a67eb57896
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_i_refvec.h
@@ -0,0 +1,243 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+
+#ifndef TNT_I_REFVEC_H
+#define TNT_I_REFVEC_H
+
+#include <cstdlib>
+#include <iostream>
+
+#ifdef TNT_BOUNDS_CHECK
+#include <assert.h>
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+namespace TNT
+{
+/*
+ Internal representation of ref-counted array. The TNT
+ arrays all use this building block.
+
+ <p>
+ If an array block is created by TNT, then every time
+ an assignment is made, the left-hand-side reference
+ is decreased by one, and the right-hand-side refernce
+ count is increased by one. If the array block was
+ external to TNT, the refernce count is a NULL pointer
+ regardless of how many references are made, since the
+ memory is not freed by TNT.
+
+
+
+*/
+template <class T>
+class i_refvec
+{
+
+
+ private:
+ T* data_;
+ int *ref_count_;
+
+
+ public:
+
+ i_refvec();
+ explicit i_refvec(int n);
+ inline i_refvec(T* data);
+ inline i_refvec(const i_refvec &v);
+ inline T* begin();
+ inline const T* begin() const;
+ inline T& operator[](int i);
+ inline const T& operator[](int i) const;
+ inline i_refvec<T> & operator=(const i_refvec<T> &V);
+ void copy_(T* p, const T* q, const T* e);
+ void set_(T* p, const T* b, const T* e);
+ inline int ref_count() const;
+ inline int is_null() const;
+ inline void destroy();
+ ~i_refvec();
+
+};
+
+template <class T>
+void i_refvec<T>::copy_(T* p, const T* q, const T* e)
+{
+ for (T* t=p; q<e; t++, q++)
+ *t= *q;
+}
+
+template <class T>
+i_refvec<T>::i_refvec() : data_(NULL), ref_count_(NULL) {}
+
+/**
+ In case n is 0 or negative, it does NOT call new.
+*/
+template <class T>
+i_refvec<T>::i_refvec(int n) : data_(NULL), ref_count_(NULL)
+{
+ if (n >= 1)
+ {
+#ifdef TNT_DEBUG
+ std::cout << "new data storage.\n";
+#endif
+ data_ = new T[n];
+ ref_count_ = new int;
+ *ref_count_ = 1;
+ }
+}
+
+template <class T>
+inline i_refvec<T>::i_refvec(const i_refvec<T> &V): data_(V.data_),
+ ref_count_(V.ref_count_)
+{
+ if (V.ref_count_ != NULL)
+ (*(V.ref_count_))++;
+}
+
+
+template <class T>
+i_refvec<T>::i_refvec(T* data) : data_(data), ref_count_(NULL) {}
+
+template <class T>
+inline T* i_refvec<T>::begin()
+{
+ return data_;
+}
+
+template <class T>
+inline const T& i_refvec<T>::operator[](int i) const
+{
+ return data_[i];
+}
+
+template <class T>
+inline T& i_refvec<T>::operator[](int i)
+{
+ return data_[i];
+}
+
+
+template <class T>
+inline const T* i_refvec<T>::begin() const
+{
+ return data_;
+}
+
+
+
+template <class T>
+i_refvec<T> & i_refvec<T>::operator=(const i_refvec<T> &V)
+{
+ if (this == &V)
+ return *this;
+
+
+ if (ref_count_ != NULL)
+ {
+ (*ref_count_) --;
+ if ((*ref_count_) == 0)
+ destroy();
+ }
+
+ data_ = V.data_;
+ ref_count_ = V.ref_count_;
+
+ if (V.ref_count_ != NULL)
+ (*(V.ref_count_))++;
+
+ return *this;
+}
+
+template <class T>
+void i_refvec<T>::destroy()
+{
+ if (ref_count_ != NULL)
+ {
+#ifdef TNT_DEBUG
+ std::cout << "destorying data... \n";
+#endif
+ delete ref_count_;
+
+#ifdef TNT_DEBUG
+ std::cout << "deleted ref_count_ ...\n";
+#endif
+ if (data_ != NULL)
+ delete []data_;
+#ifdef TNT_DEBUG
+ std::cout << "deleted data_[] ...\n";
+#endif
+ data_ = NULL;
+ }
+}
+
+/*
+* return 1 is vector is empty, 0 otherwise
+*
+* if is_null() is false and ref_count() is 0, then
+*
+*/
+template<class T>
+int i_refvec<T>::is_null() const
+{
+ return (data_ == NULL ? 1 : 0);
+}
+
+/*
+* returns -1 if data is external,
+* returns 0 if a is NULL array,
+* otherwise returns the positive number of vectors sharing
+* this data space.
+*/
+template <class T>
+int i_refvec<T>::ref_count() const
+{
+ if (data_ == NULL)
+ return 0;
+ else
+ return (ref_count_ != NULL ? *ref_count_ : -1) ;
+}
+
+template <class T>
+i_refvec<T>::~i_refvec()
+{
+ if (ref_count_ != NULL)
+ {
+ (*ref_count_)--;
+
+ if (*ref_count_ == 0)
+ destroy();
+ }
+}
+
+
+} /* namespace TNT */
+
+
+
+
+
+#endif
+/* TNT_I_REFVEC_H */
+
diff --git a/intern/smoke/intern/tnt/tnt_math_utils.h b/intern/smoke/intern/tnt/tnt_math_utils.h
new file mode 100644
index 00000000000..f6aad8eaf38
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_math_utils.h
@@ -0,0 +1,36 @@
+#ifndef MATH_UTILS_H
+#define MATH_UTILS_H
+
+/* needed for fabs, sqrt() below */
+#include <cmath>
+
+#ifdef _WIN32
+#define hypot _hypot
+#endif
+
+namespace TNT
+{
+/**
+ @returns hypotenuse of real (non-complex) scalars a and b by
+ avoiding underflow/overflow
+ using (a * sqrt( 1 + (b/a) * (b/a))), rather than
+ sqrt(a*a + b*b).
+*/
+template <class Real>
+Real hypot(const Real &a, const Real &b)
+{
+
+ if (a== 0)
+ return fabs(b);
+ else
+ {
+ Real c = b/a;
+ return fabs(a) * sqrt(1 + c*c);
+ }
+}
+} /* TNT namespace */
+
+
+
+#endif
+/* MATH_UTILS_H */
diff --git a/intern/smoke/intern/tnt/tnt_sparse_matrix_csr.h b/intern/smoke/intern/tnt/tnt_sparse_matrix_csr.h
new file mode 100644
index 00000000000..0d4fde1c207
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_sparse_matrix_csr.h
@@ -0,0 +1,103 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+#ifndef TNT_SPARSE_MATRIX_CSR_H
+#define TNT_SPARSE_MATRIX_CSR_H
+
+#include "tnt_array1d.h"
+
+namespace TNT
+{
+
+
+/**
+ Read-only view of a sparse matrix in compressed-row storage
+ format. Neither array elements (nonzeros) nor sparsity
+ structure can be modified. If modifications are required,
+ create a new view.
+
+ <p>
+ Index values begin at 0.
+
+ <p>
+ <b>Storage requirements:</b> An (m x n) matrix with
+ nz nonzeros requires no more than ((T+I)*nz + M*I)
+ bytes, where T is the size of data elements and
+ I is the size of integers.
+
+
+*/
+template <class T>
+class Sparse_Matrix_CompRow {
+
+private:
+ Array1D<T> val_; // data values (nz_ elements)
+ Array1D<int> rowptr_; // row_ptr (dim_[0]+1 elements)
+ Array1D<int> colind_; // col_ind (nz_ elements)
+
+ int dim1_; // number of rows
+ int dim2_; // number of cols
+
+public:
+
+ Sparse_Matrix_CompRow(const Sparse_Matrix_CompRow &S);
+ Sparse_Matrix_CompRow(int M, int N, int nz, const T *val,
+ const int *r, const int *c);
+
+
+
+ inline const T& val(int i) const { return val_[i]; }
+ inline const int& row_ptr(int i) const { return rowptr_[i]; }
+ inline const int& col_ind(int i) const { return colind_[i];}
+
+ inline int dim1() const {return dim1_;}
+ inline int dim2() const {return dim2_;}
+ int NumNonzeros() const {return val_.dim1();}
+
+
+ Sparse_Matrix_CompRow& operator=(
+ const Sparse_Matrix_CompRow &R);
+
+
+
+};
+
+/**
+ Construct a read-only view of existing sparse matrix in
+ compressed-row storage format.
+
+ @param M the number of rows of sparse matrix
+ @param N the number of columns of sparse matrix
+ @param nz the number of nonzeros
+ @param val a contiguous list of nonzero values
+ @param r row-pointers: r[i] denotes the begining position of row i
+ (i.e. the ith row begins at val[row[i]]).
+ @param c column-indices: c[i] denotes the column location of val[i]
+*/
+template <class T>
+Sparse_Matrix_CompRow<T>::Sparse_Matrix_CompRow(int M, int N, int nz,
+ const T *val, const int *r, const int *c) : val_(nz,val),
+ rowptr_(M, r), colind_(nz, c), dim1_(M), dim2_(N) {}
+
+
+}
+// namespace TNT
+
+#endif
diff --git a/intern/smoke/intern/tnt/tnt_stopwatch.h b/intern/smoke/intern/tnt/tnt_stopwatch.h
new file mode 100644
index 00000000000..8dc5d23ac1e
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_stopwatch.h
@@ -0,0 +1,95 @@
+/*
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+
+#ifndef STOPWATCH_H
+#define STOPWATCH_H
+
+// for clock() and CLOCKS_PER_SEC
+#include <time.h>
+
+
+namespace TNT
+{
+
+inline static double seconds(void)
+{
+ const double secs_per_tick = 1.0 / CLOCKS_PER_SEC;
+ return ( (double) clock() ) * secs_per_tick;
+}
+
+class Stopwatch {
+ private:
+ int running_;
+ double start_time_;
+ double total_;
+
+ public:
+ inline Stopwatch();
+ inline void start();
+ inline double stop();
+ inline double read();
+ inline void resume();
+ inline int running();
+};
+
+inline Stopwatch::Stopwatch() : running_(0), start_time_(0.0), total_(0.0) {}
+
+void Stopwatch::start()
+{
+ running_ = 1;
+ total_ = 0.0;
+ start_time_ = seconds();
+}
+
+double Stopwatch::stop()
+{
+ if (running_)
+ {
+ total_ += (seconds() - start_time_);
+ running_ = 0;
+ }
+ return total_;
+}
+
+inline void Stopwatch::resume()
+{
+ if (!running_)
+ {
+ start_time_ = seconds();
+ running_ = 1;
+ }
+}
+
+
+inline double Stopwatch::read()
+{
+ if (running_)
+ {
+ stop();
+ resume();
+ }
+ return total_;
+}
+
+
+} /* TNT namespace */
+#endif
+
+
+
diff --git a/intern/smoke/intern/tnt/tnt_subscript.h b/intern/smoke/intern/tnt/tnt_subscript.h
new file mode 100644
index 00000000000..d8fe1200eeb
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_subscript.h
@@ -0,0 +1,54 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+#ifndef TNT_SUBSCRPT_H
+#define TNT_SUBSCRPT_H
+
+
+//---------------------------------------------------------------------
+// This definition describes the default TNT data type used for
+// indexing into TNT matrices and vectors. The data type should
+// be wide enough to index into large arrays. It defaults to an
+// "int", but can be overriden at compile time redefining TNT_SUBSCRIPT_TYPE,
+// e.g.
+//
+// c++ -DTNT_SUBSCRIPT_TYPE='unsigned int' ...
+//
+//---------------------------------------------------------------------
+//
+
+#ifndef TNT_SUBSCRIPT_TYPE
+#define TNT_SUBSCRIPT_TYPE int
+#endif
+
+namespace TNT
+{
+ typedef TNT_SUBSCRIPT_TYPE Subscript;
+} /* namespace TNT */
+
+
+// () indexing in TNT means 1-offset, i.e. x(1) and A(1,1) are the
+// first elements. This offset is left as a macro for future
+// purposes, but should not be changed in the current release.
+//
+//
+#define TNT_BASE_OFFSET (1)
+
+#endif
diff --git a/intern/smoke/intern/tnt/tnt_vec.h b/intern/smoke/intern/tnt/tnt_vec.h
new file mode 100644
index 00000000000..a0f614b5cbd
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_vec.h
@@ -0,0 +1,404 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+
+
+#ifndef TNT_VEC_H
+#define TNT_VEC_H
+
+#include "tnt_subscript.h"
+#include <cstdlib>
+#include <cassert>
+#include <iostream>
+#include <sstream>
+
+namespace TNT
+{
+
+/**
+ <b>[Deprecatred]</b> Value-based vector class from pre-1.0
+ TNT version. Kept here for backward compatiblity, but should
+ use the newer TNT::Array1D classes instead.
+
+*/
+
+template <class T>
+class Vector
+{
+
+
+ public:
+
+ typedef Subscript size_type;
+ typedef T value_type;
+ typedef T element_type;
+ typedef T* pointer;
+ typedef T* iterator;
+ typedef T& reference;
+ typedef const T* const_iterator;
+ typedef const T& const_reference;
+
+ Subscript lbound() const { return 1;}
+
+ protected:
+ T* v_;
+ T* vm1_; // pointer adjustment for optimzied 1-offset indexing
+ Subscript n_;
+
+ // internal helper function to create the array
+ // of row pointers
+
+ void initialize(Subscript N)
+ {
+ // adjust pointers so that they are 1-offset:
+ // v_[] is the internal contiguous array, it is still 0-offset
+ //
+ assert(v_ == NULL);
+ v_ = new T[N];
+ assert(v_ != NULL);
+ vm1_ = v_-1;
+ n_ = N;
+ }
+
+ void copy(const T* v)
+ {
+ Subscript N = n_;
+ Subscript i;
+
+#ifdef TNT_UNROLL_LOOPS
+ Subscript Nmod4 = N & 3;
+ Subscript N4 = N - Nmod4;
+
+ for (i=0; i<N4; i+=4)
+ {
+ v_[i] = v[i];
+ v_[i+1] = v[i+1];
+ v_[i+2] = v[i+2];
+ v_[i+3] = v[i+3];
+ }
+
+ for (i=N4; i< N; i++)
+ v_[i] = v[i];
+#else
+
+ for (i=0; i< N; i++)
+ v_[i] = v[i];
+#endif
+ }
+
+ void set(const T& val)
+ {
+ Subscript N = n_;
+ Subscript i;
+
+#ifdef TNT_UNROLL_LOOPS
+ Subscript Nmod4 = N & 3;
+ Subscript N4 = N - Nmod4;
+
+ for (i=0; i<N4; i+=4)
+ {
+ v_[i] = val;
+ v_[i+1] = val;
+ v_[i+2] = val;
+ v_[i+3] = val;
+ }
+
+ for (i=N4; i< N; i++)
+ v_[i] = val;
+#else
+
+ for (i=0; i< N; i++)
+ v_[i] = val;
+
+#endif
+ }
+
+
+
+ void destroy()
+ {
+ /* do nothing, if no memory has been previously allocated */
+ if (v_ == NULL) return ;
+
+ /* if we are here, then matrix was previously allocated */
+ delete [] (v_);
+
+ v_ = NULL;
+ vm1_ = NULL;
+ }
+
+
+ public:
+
+ // access
+
+ iterator begin() { return v_;}
+ iterator end() { return v_ + n_; }
+ iterator begin() const { return v_;}
+ iterator end() const { return v_ + n_; }
+
+ // destructor
+
+ ~Vector()
+ {
+ destroy();
+ }
+
+ // constructors
+
+ Vector() : v_(0), vm1_(0), n_(0) {};
+
+ Vector(const Vector<T> &A) : v_(0), vm1_(0), n_(0)
+ {
+ initialize(A.n_);
+ copy(A.v_);
+ }
+
+ Vector(Subscript N, const T& value = T()) : v_(0), vm1_(0), n_(0)
+ {
+ initialize(N);
+ set(value);
+ }
+
+ Vector(Subscript N, const T* v) : v_(0), vm1_(0), n_(0)
+ {
+ initialize(N);
+ copy(v);
+ }
+
+ Vector(Subscript N, char *s) : v_(0), vm1_(0), n_(0)
+ {
+ initialize(N);
+ std::istringstream ins(s);
+
+ Subscript i;
+
+ for (i=0; i<N; i++)
+ ins >> v_[i];
+ }
+
+
+ // methods
+ //
+ Vector<T>& newsize(Subscript N)
+ {
+ if (n_ == N) return *this;
+
+ destroy();
+ initialize(N);
+
+ return *this;
+ }
+
+
+ // assignments
+ //
+ Vector<T>& operator=(const Vector<T> &A)
+ {
+ if (v_ == A.v_)
+ return *this;
+
+ if (n_ == A.n_) // no need to re-alloc
+ copy(A.v_);
+
+ else
+ {
+ destroy();
+ initialize(A.n_);
+ copy(A.v_);
+ }
+
+ return *this;
+ }
+
+ Vector<T>& operator=(const T& scalar)
+ {
+ set(scalar);
+ return *this;
+ }
+
+ inline Subscript dim() const
+ {
+ return n_;
+ }
+
+ inline Subscript size() const
+ {
+ return n_;
+ }
+
+
+ inline reference operator()(Subscript i)
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= n_) ;
+#endif
+ return vm1_[i];
+ }
+
+ inline const_reference operator() (Subscript i) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(1<=i);
+ assert(i <= n_) ;
+#endif
+ return vm1_[i];
+ }
+
+ inline reference operator[](Subscript i)
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(0<=i);
+ assert(i < n_) ;
+#endif
+ return v_[i];
+ }
+
+ inline const_reference operator[](Subscript i) const
+ {
+#ifdef TNT_BOUNDS_CHECK
+ assert(0<=i);
+
+
+
+
+
+
+ assert(i < n_) ;
+#endif
+ return v_[i];
+ }
+
+
+
+};
+
+
+/* *************************** I/O ********************************/
+
+template <class T>
+std::ostream& operator<<(std::ostream &s, const Vector<T> &A)
+{
+ Subscript N=A.dim();
+
+ s << N << "\n";
+
+ for (Subscript i=0; i<N; i++)
+ s << A[i] << " " << "\n";
+ s << "\n";
+
+ return s;
+}
+
+template <class T>
+std::istream & operator>>(std::istream &s, Vector<T> &A)
+{
+
+ Subscript N;
+
+ s >> N;
+
+ if ( !(N == A.size() ))
+ {
+ A.newsize(N);
+ }
+
+
+ for (Subscript i=0; i<N; i++)
+ s >> A[i];
+
+
+ return s;
+}
+
+// *******************[ basic matrix algorithms ]***************************
+
+
+template <class T>
+Vector<T> operator+(const Vector<T> &A,
+ const Vector<T> &B)
+{
+ Subscript N = A.dim();
+
+ assert(N==B.dim());
+
+ Vector<T> tmp(N);
+ Subscript i;
+
+ for (i=0; i<N; i++)
+ tmp[i] = A[i] + B[i];
+
+ return tmp;
+}
+
+template <class T>
+Vector<T> operator-(const Vector<T> &A,
+ const Vector<T> &B)
+{
+ Subscript N = A.dim();
+
+ assert(N==B.dim());
+
+ Vector<T> tmp(N);
+ Subscript i;
+
+ for (i=0; i<N; i++)
+ tmp[i] = A[i] - B[i];
+
+ return tmp;
+}
+
+template <class T>
+Vector<T> operator*(const Vector<T> &A,
+ const Vector<T> &B)
+{
+ Subscript N = A.dim();
+
+ assert(N==B.dim());
+
+ Vector<T> tmp(N);
+ Subscript i;
+
+ for (i=0; i<N; i++)
+ tmp[i] = A[i] * B[i];
+
+ return tmp;
+}
+
+
+template <class T>
+T dot_prod(const Vector<T> &A, const Vector<T> &B)
+{
+ Subscript N = A.dim();
+ assert(N == B.dim());
+
+ Subscript i;
+ T sum = 0;
+
+ for (i=0; i<N; i++)
+ sum += A[i] * B[i];
+
+ return sum;
+}
+
+} /* namespace TNT */
+
+#endif
+// TNT_VEC_H
diff --git a/intern/smoke/intern/tnt/tnt_version.h b/intern/smoke/intern/tnt/tnt_version.h
new file mode 100644
index 00000000000..047e7d37042
--- /dev/null
+++ b/intern/smoke/intern/tnt/tnt_version.h
@@ -0,0 +1,39 @@
+/*
+*
+* Template Numerical Toolkit (TNT)
+*
+* Mathematical and Computational Sciences Division
+* National Institute of Technology,
+* Gaithersburg, MD USA
+*
+*
+* This software was developed at the National Institute of Standards and
+* Technology (NIST) by employees of the Federal Government in the course
+* of their official duties. Pursuant to title 17 Section 105 of the
+* United States Code, this software is not subject to copyright protection
+* and is in the public domain. NIST assumes no responsibility whatsoever for
+* its use by other parties, and makes no guarantees, expressed or implied,
+* about its quality, reliability, or any other characteristic.
+*
+*/
+
+#ifndef TNT_VERSION_H
+#define TNT_VERSION_H
+
+
+//---------------------------------------------------------------------
+// current version
+//---------------------------------------------------------------------
+
+
+#define TNT_MAJOR_VERSION '1'
+#define TNT_MINOR_VERSION '2'
+#define TNT_SUBMINOR_VERSION '6'
+#define TNT_VERSION_STRING "1.2.6"
+
+
+
+
+
+#endif
+// TNT_VERSION_H
diff --git a/intern/smoke/make/msvc_9_0/smoke.vcproj b/intern/smoke/make/msvc_9_0/smoke.vcproj
new file mode 100644
index 00000000000..38a761d5d82
--- /dev/null
+++ b/intern/smoke/make/msvc_9_0/smoke.vcproj
@@ -0,0 +1,512 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9,00"
+ Name="INT_smoke"
+ ProjectGUID="{E8904FB3-F8F7-BC21-87A6-029A57B901F4}"
+ RootNamespace="smoke"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Blender Release|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\smoke"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\smoke"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="2"
+ InlineFunctionExpansion="2"
+ AdditionalIncludeDirectories="..\..\intern;..\..\..\..\..\lib\windows\zlib\include;..\..\..\..\..\lib\windows\png\include;..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include"
+ PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
+ StringPooling="true"
+ RuntimeLibrary="0"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\smoke\smoke.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\smoke\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\smoke\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\smoke\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\libsmoke.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copying IK files library to lib tree."
+ CommandLine="ECHO Copying header files&#x0D;&#x0A;IF NOT EXIST ..\..\..\..\..\build\msvc_9\intern\smoke\include MKDIR ..\..\..\..\..\build\msvc_9\intern\smoke\include&#x0D;&#x0A;XCOPY /Y ..\..\extern\*.h ..\..\..\..\..\build\msvc_9\intern\smoke\include&#x0D;&#x0A;ECHO Done&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="Blender Debug|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\smoke\debug"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\smoke\debug"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\intern;..\..\..\..\..\lib\windows\zlib\include;..\..\..\..\..\lib\windows\png\include;..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include"
+ PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="1"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\smoke\debug\smoke.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\smoke\debug\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\smoke\debug\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\smoke\debug\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\debug\libsmoke.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copying IK files library (debug target) to lib tree."
+ CommandLine="ECHO Copying header files&#x0D;&#x0A;IF NOT EXIST ..\..\..\..\..\build\msvc_9\intern\smoke\include MKDIR ..\..\..\..\..\build\msvc_9\intern\smoke\include&#x0D;&#x0A;XCOPY /Y ..\..\extern\*.h ..\..\..\..\..\build\msvc_9\intern\smoke\include&#x0D;&#x0A;ECHO Done&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="3DPlugin Release|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ InlineFunctionExpansion="2"
+ AdditionalIncludeDirectories="..\..\intern;..\..\..\..\..\lib\windows\zlib\include;..\..\..\..\..\lib\windows\png\include;..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include"
+ PreprocessorDefinitions="WIN32,NDEBUG,_LIB"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ EnableFunctionLevelLinking="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\smoke.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="NDEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\mtdll\libsmoke.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copying IK files library to lib tree."
+ CommandLine="ECHO Copying header files&#x0D;&#x0A;IF NOT EXIST ..\..\..\..\..\build\msvc_9\intern\smoke\include MKDIR ..\..\..\..\..\build\msvc_9\intern\smoke\include&#x0D;&#x0A;XCOPY /Y ..\..\extern\*.h ..\..\..\..\..\build\msvc_9\intern\smoke\include&#x0D;&#x0A;ECHO Done&#x0D;&#x0A;"
+ />
+ </Configuration>
+ <Configuration
+ Name="3DPlugin Debug|Win32"
+ OutputDirectory="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\debug"
+ IntermediateDirectory="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\debug"
+ ConfigurationType="4"
+ InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
+ UseOfMFC="0"
+ ATLMinimizesCRunTimeLibraryUsage="false"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories="..\..\intern;..\..\..\..\..\lib\windows\zlib\include;..\..\..\..\..\lib\windows\png\include;..\..\..\..\..\build\msvc_9\extern\bullet\include;..\..\..\..\..\build\msvc_9\intern\memutil\include;..\..\..\..\..\build\msvc_9\intern\guardedalloc\include"
+ PreprocessorDefinitions="WIN32,_DEBUG,_LIB"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ BufferSecurityCheck="true"
+ UsePrecompiledHeader="0"
+ PrecompiledHeaderFile="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\debug\smoke.pch"
+ AssemblerListingLocation="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\debug\"
+ ObjectFile="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\debug\"
+ ProgramDataBaseFileName="..\..\..\..\..\build\msvc_9\intern\smoke\mtdll\debug\"
+ WarningLevel="2"
+ SuppressStartupBanner="true"
+ DebugInformationFormat="3"
+ CompileAs="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ PreprocessorDefinitions="_DEBUG"
+ Culture="1043"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ OutputFile="..\..\..\..\..\build\msvc_9\libs\intern\mtdll\debug\libsmoke.lib"
+ SuppressStartupBanner="true"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ Description="Copying IK files library (debug target) to lib tree."
+ CommandLine="ECHO Copying header files&#x0D;&#x0A;IF NOT EXIST ..\..\..\..\..\build\msvc_9\intern\smoke\include MKDIR ..\..\..\..\..\build\msvc_9\intern\smoke\include&#x0D;&#x0A;XCOPY /Y ..\..\extern\*.h ..\..\..\..\..\build\msvc_9\intern\smoke\include&#x0D;&#x0A;ECHO Done&#x0D;&#x0A;"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="intern"
+ >
+ <File
+ RelativePath="..\..\intern\EIGENVALUE_HELPER.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\FFT_NOISE.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\FLUID_3D.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\FLUID_3D.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\FLUID_3D_SOLVERS.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\FLUID_3D_STATIC.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\IMAGE.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\INTERPOLATE.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\LU_HELPER.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\MERSENNETWISTER.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\OBSTACLE.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\smoke_API.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\SPHERE.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\SPHERE.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\VEC3.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\WAVELET_NOISE.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\WTURBULENCE.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\WTURBULENCE.h"
+ >
+ </File>
+ <Filter
+ Name="TNT"
+ >
+ <File
+ RelativePath="..\..\intern\tnt\jama_eig.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\jama_lu.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_array1d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_array1d_utils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_array2d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_array2d_utils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_array3d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_array3d_utils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_cmat.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_fortran_array1d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_fortran_array1d_utils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_fortran_array2d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_fortran_array2d_utils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_fortran_array3d.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_fortran_array3d_utils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_i_refvec.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_math_utils.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_sparse_matrix_csr.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_stopwatch.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_subscript.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_vec.h"
+ >
+ </File>
+ <File
+ RelativePath="..\..\intern\tnt\tnt_version.h"
+ >
+ </File>
+ </Filter>
+ </Filter>
+ <Filter
+ Name="extern"
+ >
+ <File
+ RelativePath="..\..\extern\smoke_API.h"
+ >
+ </File>
+ </Filter>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/intern/string/SConscript b/intern/string/SConscript
index 8973ac88a66..4aca220183c 100644
--- a/intern/string/SConscript
+++ b/intern/string/SConscript
@@ -4,4 +4,4 @@ Import ('env')
sources = env.Glob('intern/*.cpp')
incs = '.'
-env.BlenderLib ('bf_string', sources, Split(incs), [], libtype=['intern'], priority = [50] )
+env.BlenderLib ('bf_string', sources, Split(incs), [], libtype=['intern','player'], priority = [50,10] )
diff --git a/intern/string/STR_String.h b/intern/string/STR_String.h
index 941430fd976..d8023a06f81 100644
--- a/intern/string/STR_String.h
+++ b/intern/string/STR_String.h
@@ -50,6 +50,13 @@
using namespace std;
+#ifdef WITH_CXX_GUARDEDALLOC
+#include "MEM_guardedalloc.h"
+#endif
+
+#ifdef _WIN32
+#define stricmp _stricmp
+#endif
class STR_String;
@@ -191,6 +198,13 @@ protected:
char *pData; // -> STR_String data
int Len; // Data length
int Max; // Space in data buffer
+
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new( unsigned int num_bytes) { return MEM_mallocN(num_bytes, "CXX:STR_String"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
};
inline STR_String operator+(rcSTR_String lhs, rcSTR_String rhs) { return STR_String(lhs.ReadPtr(), lhs.Length(), rhs.ReadPtr(), rhs.Length()); }
diff --git a/intern/string/intern/STR_String.cpp b/intern/string/intern/STR_String.cpp
index dcc52e2a3e7..646b1a853dc 100644
--- a/intern/string/intern/STR_String.cpp
+++ b/intern/string/intern/STR_String.cpp
@@ -559,7 +559,8 @@ STR_String& STR_String::TrimLeft()
{
int skip;
assertd(pData != NULL);
- for (skip=0; isSpace(pData[skip]); skip++, Len--);
+ for (skip=0; isSpace(pData[skip]); skip++, Len--)
+ {};
memmove(pData, pData+skip, Len+1);
return *this;
}
@@ -598,7 +599,8 @@ STR_String& STR_String::TrimLeft(char *set)
{
int skip;
assertd(pData != NULL);
- for (skip=0; Len && strchr(set, pData[skip]); skip++, Len--);
+ for (skip=0; Len && strchr(set, pData[skip]); skip++, Len--)
+ {};
memmove(pData, pData+skip, Len+1);
return *this;
}
diff --git a/intern/string/make/msvc_9_0/string.vcproj b/intern/string/make/msvc_9_0/string.vcproj
index 16df974ff9c..512d67623b6 100644
--- a/intern/string/make/msvc_9_0/string.vcproj
+++ b/intern/string/make/msvc_9_0/string.vcproj
@@ -118,6 +118,7 @@
/>
<Tool
Name="VCCLCompilerTool"
+ Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\.."
PreprocessorDefinitions="WIN32,NDEBUG,_LIB"