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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.h2
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.h2
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.h2
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.cpp18
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.cpp8
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.h7
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.cpp3
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.h5
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.h2
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.h2
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.h2
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.h2
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.cpp18
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.h2
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.h2
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.cpp17
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.cpp24
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.h7
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.h4
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp17
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h4
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp172
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.h13
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.cpp6
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.h4
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.cpp2
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.h2
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp10
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h2
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp8
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.cpp8
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp273
-rw-r--r--intern/audaspace/intern/AUD_C-API.h10
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.h4
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.h2
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.h4
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.cpp68
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.h2
-rw-r--r--intern/audaspace/intern/AUD_DefaultMixer.cpp2
-rw-r--r--intern/audaspace/intern/AUD_DefaultMixer.h2
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.cpp16
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.h2
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h5
-rw-r--r--intern/audaspace/intern/AUD_IFactory.h3
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.h4
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.cpp2
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.h2
-rw-r--r--intern/audaspace/intern/AUD_Mixer.h3
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.h8
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp4
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h5
-rw-r--r--intern/audaspace/intern/AUD_Reference.h68
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.cpp45
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.h23
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.cpp85
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.h20
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.cpp2
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.h2
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.cpp2
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.h2
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp16
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.h8
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.cpp15
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.h4
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.cpp10
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.h2
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.cpp10
-rw-r--r--release/scripts/modules/bpy_types.py10
-rw-r--r--release/scripts/modules/mocap_tools.py451
-rw-r--r--release/scripts/modules/retarget.py198
-rw-r--r--release/scripts/startup/bl_operators/nla.py34
-rw-r--r--release/scripts/startup/bl_operators/object.py41
-rw-r--r--release/scripts/startup/bl_ui/properties_object_constraint.py5
-rw-r--r--release/scripts/startup/bl_ui/properties_scene.py39
-rw-r--r--release/scripts/startup/bl_ui/space_userpref.py1
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py4
-rw-r--r--source/blender/blenkernel/BKE_constraint.h1
-rw-r--r--source/blender/blenkernel/BKE_sound.h2
-rw-r--r--source/blender/blenkernel/intern/action.c5
-rw-r--r--source/blender/blenkernel/intern/constraint.c58
-rw-r--r--source/blender/blenkernel/intern/fcurve.c115
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c86
-rw-r--r--source/blender/blenkernel/intern/sound.c5
-rw-r--r--source/blender/collada/AnimationExporter.cpp800
-rw-r--r--source/blender/collada/AnimationExporter.h142
-rw-r--r--source/blender/collada/CMakeLists.txt2
-rw-r--r--source/blender/collada/DocumentExporter.cpp631
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c34
-rw-r--r--source/blender/editors/animation/anim_markers.c11
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c44
-rw-r--r--source/blender/editors/animation/keyframes_general.c4
-rw-r--r--source/blender/editors/animation/keyingsets.c9
-rw-r--r--source/blender/editors/armature/poseobject.c10
-rw-r--r--source/blender/editors/include/ED_markers.h4
-rw-r--r--source/blender/editors/interface/resources.c2
-rw-r--r--source/blender/editors/object/object_constraint.c3
-rw-r--r--source/blender/editors/space_action/action_ops.c6
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c12
-rw-r--r--source/blender/editors/space_graph/graph_edit.c2
-rw-r--r--source/blender/editors/space_graph/graph_ops.c6
-rw-r--r--source/blender/editors/space_logic/logic_window.c7
-rw-r--r--source/blender/editors/space_nla/nla_ops.c4
-rw-r--r--source/blender/editors/space_text/text_draw.c9
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c105
-rw-r--r--source/blender/editors/transform/transform.c31
-rw-r--r--source/blender/editors/transform/transform_conversions.c10
-rw-r--r--source/blender/editors/transform/transform_ops.c2
-rw-r--r--source/blender/makesdna/DNA_actuator_types.h2
-rw-r--r--source/blender/makesdna/DNA_anim_types.h23
-rw-r--r--source/blender/makesdna/DNA_armature_types.h3
-rw-r--r--source/blender/makesdna/DNA_constraint_types.h5
-rw-r--r--source/blender/makesdna/DNA_userdef_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_access.c2
-rw-r--r--source/blender/makesrna/intern/rna_actuator.c9
-rw-r--r--source/blender/makesrna/intern/rna_animation.c6
-rw-r--r--source/blender/makesrna/intern/rna_armature.c1
-rw-r--r--source/blender/makesrna/intern/rna_constraint.c7
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c82
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c6
-rw-r--r--source/blender/windowmanager/intern/wm_files.c7
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.cpp81
-rw-r--r--source/gameengine/Converter/BL_ActionActuator.h5
-rw-r--r--source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp6
-rw-r--r--source/gameengine/Converter/KX_BlenderScalarInterpolator.h2
-rw-r--r--source/gameengine/Converter/KX_ConvertActuators.cpp43
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.cpp210
-rw-r--r--source/gameengine/Converter/KX_IpoConvert.h4
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h5
-rw-r--r--source/gameengine/Ketsji/BL_Action.cpp266
-rw-r--r--source/gameengine/Ketsji/BL_Action.h110
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.cpp98
-rw-r--r--source/gameengine/Ketsji/BL_ActionManager.h69
-rw-r--r--source/gameengine/Ketsji/CMakeLists.txt19
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.cpp96
-rw-r--r--source/gameengine/Ketsji/KX_GameObject.h53
-rw-r--r--source/gameengine/Ketsji/KX_Scene.cpp3
-rw-r--r--source/gameengine/Ketsji/SConscript4
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.cpp12
-rw-r--r--source/gameengine/SceneGraph/SG_IObject.h10
190 files changed, 3903 insertions, 1614 deletions
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
index d60924958b1..207c2ee502b 100644
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
+++ b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
@@ -52,14 +52,14 @@ sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
return out;
}
-AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
+AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_Reference<AUD_IFactory> factory,
bool additive) :
AUD_EffectFactory(factory),
m_additive(additive)
{
}
-AUD_IReader* AUD_AccumulatorFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_AccumulatorFactory::createReader() const
{
return new AUD_CallbackIIRFilterReader(getReader(), 2, 2,
m_additive ? accumulatorFilterAdditive : accumulatorFilter);
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.h b/intern/audaspace/FX/AUD_AccumulatorFactory.h
index 3c3b32ce071..becd5d9aaee 100644
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.h
+++ b/intern/audaspace/FX/AUD_AccumulatorFactory.h
@@ -55,9 +55,9 @@ public:
* \param factory The input factory.
* \param additive Whether the accumulator is additive.
*/
- AUD_AccumulatorFactory(AUD_IFactory* factory, bool additive = false);
+ AUD_AccumulatorFactory(AUD_Reference<AUD_IFactory> factory, bool additive = false);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_ACCUMULATORFACTORY
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
index 563722d9213..5ad5903141b 100644
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
@@ -35,7 +35,7 @@
#define CC m_channels + m_channel
-AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_IReader* reader, int in,
+AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in,
int out) :
AUD_EffectReader(reader),
m_channels(reader->getSpecs().channels),
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
index 436e6469a58..9f81e2d8a25 100644
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
@@ -97,7 +97,7 @@ protected:
* \param in The count of past input samples needed.
* \param out The count of past output samples needed.
*/
- AUD_BaseIIRFilterReader(AUD_IReader* reader, int in, int out);
+ AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in, int out);
public:
inline sample_t x(int pos)
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
index ea957c81ed3..1161a485fb1 100644
--- a/intern/audaspace/FX/AUD_ButterworthFactory.cpp
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
@@ -41,16 +41,16 @@
#define BWPB41 0.76536686473
#define BWPB42 1.84775906502
-AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
+AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory,
float frequency) :
AUD_EffectFactory(factory),
m_frequency(frequency)
{
}
-AUD_IReader* AUD_ButterworthFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_ButterworthFactory::createReader() const
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
// calculate coefficients
float omega = 2 * tan(m_frequency * M_PI / reader->getSpecs().rate);
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h
index c8b731449c4..c211a6df246 100644
--- a/intern/audaspace/FX/AUD_ButterworthFactory.h
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.h
@@ -55,9 +55,9 @@ public:
* \param factory The input factory.
* \param frequency The cutoff frequency.
*/
- AUD_ButterworthFactory(AUD_IFactory* factory, float frequency);
+ AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory, float frequency);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_BUTTERWORTHFACTORY
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
index 2f9bb7762a0..e6c83322435 100644
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
@@ -31,7 +31,7 @@
#include "AUD_CallbackIIRFilterReader.h"
-AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_IReader* reader,
+AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_Reference<AUD_IReader> reader,
int in, int out,
doFilterIIR doFilter,
endFilterIIR endFilter,
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
index a969db7297e..6d53edeecc2 100644
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
@@ -76,7 +76,7 @@ public:
* \param endFilter The finishing callback.
* \param data Data pointer for the callbacks.
*/
- AUD_CallbackIIRFilterReader(AUD_IReader* reader, int in, int out,
+ AUD_CallbackIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in, int out,
doFilterIIR doFilter,
endFilterIIR endFilter = 0,
void* data = 0);
diff --git a/intern/audaspace/FX/AUD_DelayFactory.cpp b/intern/audaspace/FX/AUD_DelayFactory.cpp
index 1d2d99adc03..ceecd7a63c9 100644
--- a/intern/audaspace/FX/AUD_DelayFactory.cpp
+++ b/intern/audaspace/FX/AUD_DelayFactory.cpp
@@ -33,7 +33,7 @@
#include "AUD_DelayReader.h"
#include "AUD_Space.h"
-AUD_DelayFactory::AUD_DelayFactory(AUD_IFactory* factory, float delay) :
+AUD_DelayFactory::AUD_DelayFactory(AUD_Reference<AUD_IFactory> factory, float delay) :
AUD_EffectFactory(factory),
m_delay(delay)
{
@@ -44,7 +44,7 @@ float AUD_DelayFactory::getDelay() const
return m_delay;
}
-AUD_IReader* AUD_DelayFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_DelayFactory::createReader() const
{
return new AUD_DelayReader(getReader(), m_delay);
}
diff --git a/intern/audaspace/FX/AUD_DelayFactory.h b/intern/audaspace/FX/AUD_DelayFactory.h
index 1e67cd68990..6362bd19a70 100644
--- a/intern/audaspace/FX/AUD_DelayFactory.h
+++ b/intern/audaspace/FX/AUD_DelayFactory.h
@@ -55,14 +55,14 @@ public:
* \param factory The input factory.
* \param delay The desired delay in seconds.
*/
- AUD_DelayFactory(AUD_IFactory* factory, float delay = 0);
+ AUD_DelayFactory(AUD_Reference<AUD_IFactory> factory, float delay = 0);
/**
* Returns the delay in seconds.
*/
float getDelay() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_DELAYFACTORY
diff --git a/intern/audaspace/FX/AUD_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp
index 374b876455d..a2224caf288 100644
--- a/intern/audaspace/FX/AUD_DelayReader.cpp
+++ b/intern/audaspace/FX/AUD_DelayReader.cpp
@@ -33,7 +33,7 @@
#include <cstring>
-AUD_DelayReader::AUD_DelayReader(AUD_IReader* reader, float delay) :
+AUD_DelayReader::AUD_DelayReader(AUD_Reference<AUD_IReader> reader, float delay) :
AUD_EffectReader(reader),
m_delay(int(delay * reader->getSpecs().rate)),
m_remdelay(int(delay * reader->getSpecs().rate)),
diff --git a/intern/audaspace/FX/AUD_DelayReader.h b/intern/audaspace/FX/AUD_DelayReader.h
index 5f0af660bdf..695003a8c43 100644
--- a/intern/audaspace/FX/AUD_DelayReader.h
+++ b/intern/audaspace/FX/AUD_DelayReader.h
@@ -71,7 +71,7 @@ public:
* \param reader The reader to read from.
* \param delay The delay in seconds.
*/
- AUD_DelayReader(AUD_IReader* reader, float delay);
+ AUD_DelayReader(AUD_Reference<AUD_IReader> reader, float delay);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.cpp b/intern/audaspace/FX/AUD_DoubleFactory.cpp
index 7a40f1f8c96..5b72082f520 100644
--- a/intern/audaspace/FX/AUD_DoubleFactory.cpp
+++ b/intern/audaspace/FX/AUD_DoubleFactory.cpp
@@ -32,25 +32,15 @@
#include "AUD_DoubleFactory.h"
#include "AUD_DoubleReader.h"
-AUD_DoubleFactory::AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+AUD_DoubleFactory::AUD_DoubleFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2) :
m_factory1(factory1), m_factory2(factory2)
{
}
-AUD_IReader* AUD_DoubleFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_DoubleFactory::createReader() const
{
- AUD_IReader* reader1 = m_factory1->createReader();
- AUD_IReader* reader2;
-
- try
- {
- reader2 = m_factory2->createReader();
- }
- catch(AUD_Exception&)
- {
- delete reader1;
- throw;
- }
+ AUD_Reference<AUD_IReader> reader1 = m_factory1->createReader();
+ AUD_Reference<AUD_IReader> reader2 = m_factory2->createReader();
return new AUD_DoubleReader(reader1, reader2);
}
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.h b/intern/audaspace/FX/AUD_DoubleFactory.h
index 52a299c7157..acc9997deea 100644
--- a/intern/audaspace/FX/AUD_DoubleFactory.h
+++ b/intern/audaspace/FX/AUD_DoubleFactory.h
@@ -44,12 +44,12 @@ private:
/**
* First played factory.
*/
- AUD_IFactory* m_factory1;
+ AUD_Reference<AUD_IFactory> m_factory1;
/**
* Second played factory.
*/
- AUD_IFactory* m_factory2;
+ AUD_Reference<AUD_IFactory> m_factory2;
// hide copy constructor and operator=
AUD_DoubleFactory(const AUD_DoubleFactory&);
@@ -61,9 +61,9 @@ public:
* \param factory1 The first input factory.
* \param factory2 The second input factory.
*/
- AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+ AUD_DoubleFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_DOUBLEFACTORY
diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp
index 113bed14ce3..bf1c770a2ed 100644
--- a/intern/audaspace/FX/AUD_DoubleReader.cpp
+++ b/intern/audaspace/FX/AUD_DoubleReader.cpp
@@ -36,8 +36,8 @@
static const char* specs_error = "AUD_DoubleReader: Both readers have to have "
"the same specs.";
-AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
- AUD_IReader* reader2) :
+AUD_DoubleReader::AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1,
+ AUD_Reference<AUD_IReader> reader2) :
m_reader1(reader1), m_reader2(reader2), m_finished1(false)
{
AUD_Specs s1, s2;
@@ -45,16 +45,12 @@ AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
s2 = reader2->getSpecs();
if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0)
{
- delete reader1;
- delete reader2;
AUD_THROW(AUD_ERROR_SPECS, specs_error);
}
}
AUD_DoubleReader::~AUD_DoubleReader()
{
- delete m_reader1;
- delete m_reader2;
}
bool AUD_DoubleReader::isSeekable() const
diff --git a/intern/audaspace/FX/AUD_DoubleReader.h b/intern/audaspace/FX/AUD_DoubleReader.h
index 7b3b812ef80..4f01c47d052 100644
--- a/intern/audaspace/FX/AUD_DoubleReader.h
+++ b/intern/audaspace/FX/AUD_DoubleReader.h
@@ -34,6 +34,7 @@
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
+#include "AUD_Reference.h"
/**
* This reader plays two readers with the same specs sequently.
@@ -44,12 +45,12 @@ private:
/**
* The first reader.
*/
- AUD_IReader* m_reader1;
+ AUD_Reference<AUD_IReader> m_reader1;
/**
* The second reader.
*/
- AUD_IReader* m_reader2;
+ AUD_Reference<AUD_IReader> m_reader2;
/**
* Whether we've reached the end of the first reader.
@@ -72,7 +73,7 @@ public:
* \param reader2 The second reader to read from.
* \exception AUD_Exception Thrown if the specs from the readers differ.
*/
- AUD_DoubleReader(AUD_IReader* reader1, AUD_IReader* reader2);
+ AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2);
/**
* Destroys the reader.
diff --git a/intern/audaspace/FX/AUD_EffectFactory.cpp b/intern/audaspace/FX/AUD_EffectFactory.cpp
index a0d9256e691..6173ffb5a97 100644
--- a/intern/audaspace/FX/AUD_EffectFactory.cpp
+++ b/intern/audaspace/FX/AUD_EffectFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_EffectFactory.h"
#include "AUD_IReader.h"
-AUD_EffectFactory::AUD_EffectFactory(AUD_IFactory* factory)
+AUD_EffectFactory::AUD_EffectFactory(AUD_Reference<AUD_IFactory> factory)
{
m_factory = factory;
}
@@ -41,7 +41,7 @@ AUD_EffectFactory::~AUD_EffectFactory()
{
}
-AUD_IFactory* AUD_EffectFactory::getFactory() const
+AUD_Reference<AUD_IFactory> AUD_EffectFactory::getFactory() const
{
return m_factory;
}
diff --git a/intern/audaspace/FX/AUD_EffectFactory.h b/intern/audaspace/FX/AUD_EffectFactory.h
index a6a28eea577..72fdb3f0833 100644
--- a/intern/audaspace/FX/AUD_EffectFactory.h
+++ b/intern/audaspace/FX/AUD_EffectFactory.h
@@ -49,7 +49,7 @@ protected:
/**
* If there is no reader it is created out of this factory.
*/
- AUD_IFactory* m_factory;
+ AUD_Reference<AUD_IFactory> m_factory;
/**
* Returns the reader created out of the factory.
@@ -57,7 +57,7 @@ protected:
* classes.
* \return The reader created out of the factory.
*/
- inline AUD_IReader* getReader() const
+ inline AUD_Reference<AUD_IReader> getReader() const
{
return m_factory->createReader();
}
@@ -67,7 +67,7 @@ public:
* Creates a new factory.
* \param factory The input factory.
*/
- AUD_EffectFactory(AUD_IFactory* factory);
+ AUD_EffectFactory(AUD_Reference<AUD_IFactory> factory);
/**
* Destroys the factory.
@@ -78,7 +78,7 @@ public:
* Returns the saved factory.
* \return The factory or NULL if there has no factory been saved.
*/
- AUD_IFactory* getFactory() const;
+ AUD_Reference<AUD_IFactory> getFactory() const;
};
#endif //AUD_EFFECTFACTORY
diff --git a/intern/audaspace/FX/AUD_EffectReader.cpp b/intern/audaspace/FX/AUD_EffectReader.cpp
index 3ad9f67bfd6..d7c4eeb2ee1 100644
--- a/intern/audaspace/FX/AUD_EffectReader.cpp
+++ b/intern/audaspace/FX/AUD_EffectReader.cpp
@@ -31,14 +31,13 @@
#include "AUD_EffectReader.h"
-AUD_EffectReader::AUD_EffectReader(AUD_IReader* reader)
+AUD_EffectReader::AUD_EffectReader(AUD_Reference<AUD_IReader> reader)
{
m_reader = reader;
}
AUD_EffectReader::~AUD_EffectReader()
{
- delete m_reader;
}
bool AUD_EffectReader::isSeekable() const
diff --git a/intern/audaspace/FX/AUD_EffectReader.h b/intern/audaspace/FX/AUD_EffectReader.h
index fb8066f36d8..6aa185edcd0 100644
--- a/intern/audaspace/FX/AUD_EffectReader.h
+++ b/intern/audaspace/FX/AUD_EffectReader.h
@@ -33,6 +33,7 @@
#define AUD_EFFECTREADER
#include "AUD_IReader.h"
+#include "AUD_Reference.h"
/**
* This reader is a base class for all effect readers that take one other reader
@@ -49,14 +50,14 @@ protected:
/**
* The reader to read from.
*/
- AUD_IReader* m_reader;
+ AUD_Reference<AUD_IReader> m_reader;
public:
/**
* Creates a new effect reader.
* \param reader The reader to read from.
*/
- AUD_EffectReader(AUD_IReader* reader);
+ AUD_EffectReader(AUD_Reference<AUD_IReader> reader);
/**
* Destroys the reader.
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
index 069317d1c8b..e36091950a5 100644
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
+++ b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
@@ -56,7 +56,7 @@ void endEnvelopeFilter(EnvelopeParameters* param)
delete param;
}
-AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
+AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, float attack,
float release, float threshold,
float arthreshold) :
AUD_EffectFactory(factory),
@@ -67,9 +67,9 @@ AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
{
}
-AUD_IReader* AUD_EnvelopeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_EnvelopeFactory::createReader() const
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
EnvelopeParameters* param = new EnvelopeParameters();
param->arthreshold = m_arthreshold;
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.h b/intern/audaspace/FX/AUD_EnvelopeFactory.h
index 45ee811b6e0..0a803f77aaf 100644
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.h
+++ b/intern/audaspace/FX/AUD_EnvelopeFactory.h
@@ -73,10 +73,10 @@ public:
* \param threshold The threshold value.
* \param arthreshold The attack/release threshold value.
*/
- AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, float release,
+ AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, float attack, float release,
float threshold, float arthreshold);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_ENVELOPEFACTORY
diff --git a/intern/audaspace/FX/AUD_FaderFactory.cpp b/intern/audaspace/FX/AUD_FaderFactory.cpp
index d887e9e68d9..e7fe5098d76 100644
--- a/intern/audaspace/FX/AUD_FaderFactory.cpp
+++ b/intern/audaspace/FX/AUD_FaderFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_FaderFactory.h"
#include "AUD_FaderReader.h"
-AUD_FaderFactory::AUD_FaderFactory(AUD_IFactory* factory, AUD_FadeType type,
+AUD_FaderFactory::AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory, AUD_FadeType type,
float start, float length) :
AUD_EffectFactory(factory),
m_type(type),
@@ -56,7 +56,7 @@ float AUD_FaderFactory::getLength() const
return m_length;
}
-AUD_IReader* AUD_FaderFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_FaderFactory::createReader() const
{
return new AUD_FaderReader(getReader(), m_type, m_start, m_length);
}
diff --git a/intern/audaspace/FX/AUD_FaderFactory.h b/intern/audaspace/FX/AUD_FaderFactory.h
index b85475bc534..cc20245a267 100644
--- a/intern/audaspace/FX/AUD_FaderFactory.h
+++ b/intern/audaspace/FX/AUD_FaderFactory.h
@@ -69,7 +69,7 @@ public:
* \param start The time where fading should start in seconds.
* \param length How long fading should last in seconds.
*/
- AUD_FaderFactory(AUD_IFactory* factory,
+ AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory,
AUD_FadeType type = AUD_FADE_IN,
float start = 0.0f, float length = 1.0f);
@@ -88,7 +88,7 @@ public:
*/
float getLength() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_FADERFACTORY
diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp
index 6114bb486fc..e319e205e5f 100644
--- a/intern/audaspace/FX/AUD_FaderReader.cpp
+++ b/intern/audaspace/FX/AUD_FaderReader.cpp
@@ -33,7 +33,7 @@
#include <cstring>
-AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+AUD_FaderReader::AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType type,
float start,float length) :
AUD_EffectReader(reader),
m_type(type),
diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h
index fb927192b45..b088477bce0 100644
--- a/intern/audaspace/FX/AUD_FaderReader.h
+++ b/intern/audaspace/FX/AUD_FaderReader.h
@@ -79,7 +79,7 @@ public:
* \param start The time where fading should start in seconds.
* \param length How long fading should last in seconds.
*/
- AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+ AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType type,
float start,float length);
virtual void read(int & length, sample_t* & buffer);
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
index 61008eea44e..b8bfa6545ac 100644
--- a/intern/audaspace/FX/AUD_HighpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_HighpassFactory.cpp
@@ -38,7 +38,7 @@
#define M_PI 3.14159265358979323846
#endif
-AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
+AUD_HighpassFactory::AUD_HighpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency,
float Q) :
AUD_EffectFactory(factory),
m_frequency(frequency),
@@ -46,9 +46,9 @@ AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
{
}
-AUD_IReader* AUD_HighpassFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_HighpassFactory::createReader() const
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
// calculate coefficients
float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h
index 48f4c1baefc..0089cc2c139 100644
--- a/intern/audaspace/FX/AUD_HighpassFactory.h
+++ b/intern/audaspace/FX/AUD_HighpassFactory.h
@@ -61,9 +61,9 @@ public:
* \param frequency The cutoff frequency.
* \param Q The Q factor.
*/
- AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+ AUD_HighpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency, float Q = 1.0f);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_HIGHPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
index ff90ce62739..e24a10266c9 100644
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
+++ b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
@@ -32,14 +32,14 @@
#include "AUD_IIRFilterFactory.h"
#include "AUD_IIRFilterReader.h"
-AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_IFactory* factory,
+AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_Reference<AUD_IFactory> factory,
std::vector<float> b,
std::vector<float> a) :
AUD_EffectFactory(factory), m_a(a), m_b(b)
{
}
-AUD_IReader* AUD_IIRFilterFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_IIRFilterFactory::createReader() const
{
return new AUD_IIRFilterReader(getReader(), m_b, m_a);
}
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.h b/intern/audaspace/FX/AUD_IIRFilterFactory.h
index d48ad453ee4..ffcc70a8ecb 100644
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.h
+++ b/intern/audaspace/FX/AUD_IIRFilterFactory.h
@@ -63,10 +63,10 @@ public:
* \param b The input filter coefficients.
* \param a The output filter coefficients.
*/
- AUD_IIRFilterFactory(AUD_IFactory* factory, std::vector<float> b,
+ AUD_IIRFilterFactory(AUD_Reference<AUD_IFactory> factory, std::vector<float> b,
std::vector<float> a);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_IIRFILTERFACTORY
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.cpp b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
index 0d55421d2b4..80252e68ce8 100644
--- a/intern/audaspace/FX/AUD_IIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
@@ -31,7 +31,7 @@
#include "AUD_IIRFilterReader.h"
-AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_IReader* reader,
+AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_Reference<AUD_IReader> reader,
std::vector<float> b,
std::vector<float> a) :
AUD_BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b)
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.h
index af50b6f1cdc..db813d6bab6 100644
--- a/intern/audaspace/FX/AUD_IIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_IIRFilterReader.h
@@ -63,7 +63,7 @@ public:
* \param b The input filter coefficients.
* \param a The output filter coefficients.
*/
- AUD_IIRFilterReader(AUD_IReader* reader, std::vector<float> b,
+ AUD_IIRFilterReader(AUD_Reference<AUD_IReader> reader, std::vector<float> b,
std::vector<float> a);
virtual sample_t filter();
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.cpp b/intern/audaspace/FX/AUD_LimiterFactory.cpp
index 62ea01bb761..e52cdd75d4d 100644
--- a/intern/audaspace/FX/AUD_LimiterFactory.cpp
+++ b/intern/audaspace/FX/AUD_LimiterFactory.cpp
@@ -33,7 +33,7 @@
#include "AUD_LimiterReader.h"
#include "AUD_Space.h"
-AUD_LimiterFactory::AUD_LimiterFactory(AUD_IFactory* factory,
+AUD_LimiterFactory::AUD_LimiterFactory(AUD_Reference<AUD_IFactory> factory,
float start, float end) :
AUD_EffectFactory(factory),
m_start(start),
@@ -51,7 +51,7 @@ float AUD_LimiterFactory::getEnd() const
return m_end;
}
-AUD_IReader* AUD_LimiterFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LimiterFactory::createReader() const
{
return new AUD_LimiterReader(getReader(), m_start, m_end);
}
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.h b/intern/audaspace/FX/AUD_LimiterFactory.h
index f93f4b3276c..c45b9da65fe 100644
--- a/intern/audaspace/FX/AUD_LimiterFactory.h
+++ b/intern/audaspace/FX/AUD_LimiterFactory.h
@@ -62,7 +62,7 @@ public:
* \param end The desired end time, a negative value signals that it should
* play to the end.
*/
- AUD_LimiterFactory(AUD_IFactory* factory,
+ AUD_LimiterFactory(AUD_Reference<AUD_IFactory> factory,
float start = 0, float end = -1);
/**
@@ -75,7 +75,7 @@ public:
*/
float getEnd() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_LIMITERFACTORY
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp
index d67fbb4d0e5..d5a46568b3e 100644
--- a/intern/audaspace/FX/AUD_LimiterReader.cpp
+++ b/intern/audaspace/FX/AUD_LimiterReader.cpp
@@ -34,7 +34,7 @@
#include <iostream>
-AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader,
+AUD_LimiterReader::AUD_LimiterReader(AUD_Reference<AUD_IReader> reader,
float start, float end) :
AUD_EffectReader(reader),
m_start(int(start * reader->getSpecs().rate)),
diff --git a/intern/audaspace/FX/AUD_LimiterReader.h b/intern/audaspace/FX/AUD_LimiterReader.h
index 4375ed9e10d..f4502c33ae0 100644
--- a/intern/audaspace/FX/AUD_LimiterReader.h
+++ b/intern/audaspace/FX/AUD_LimiterReader.h
@@ -62,7 +62,7 @@ public:
* \param end The desired end sample (exklusive), a negative value signals
* that it should play to the end.
*/
- AUD_LimiterReader(AUD_IReader* reader, float start = 0, float end = -1);
+ AUD_LimiterReader(AUD_Reference<AUD_IReader> reader, float start = 0, float end = -1);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/FX/AUD_LoopFactory.cpp b/intern/audaspace/FX/AUD_LoopFactory.cpp
index 49d3481757f..021e69901b2 100644
--- a/intern/audaspace/FX/AUD_LoopFactory.cpp
+++ b/intern/audaspace/FX/AUD_LoopFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_LoopFactory.h"
#include "AUD_LoopReader.h"
-AUD_LoopFactory::AUD_LoopFactory(AUD_IFactory* factory, int loop) :
+AUD_LoopFactory::AUD_LoopFactory(AUD_Reference<AUD_IFactory> factory, int loop) :
AUD_EffectFactory(factory),
m_loop(loop)
{
@@ -43,7 +43,7 @@ int AUD_LoopFactory::getLoop() const
return m_loop;
}
-AUD_IReader* AUD_LoopFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LoopFactory::createReader() const
{
return new AUD_LoopReader(getReader(), m_loop);
}
diff --git a/intern/audaspace/FX/AUD_LoopFactory.h b/intern/audaspace/FX/AUD_LoopFactory.h
index dfbbbe4fd20..4d601d5a605 100644
--- a/intern/audaspace/FX/AUD_LoopFactory.h
+++ b/intern/audaspace/FX/AUD_LoopFactory.h
@@ -57,14 +57,14 @@ public:
* \param loop The desired loop count, negative values result in endless
* looping.
*/
- AUD_LoopFactory(AUD_IFactory* factory, int loop = -1);
+ AUD_LoopFactory(AUD_Reference<AUD_IFactory> factory, int loop = -1);
/**
* Returns the loop count.
*/
int getLoop() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_LOOPFACTORY
diff --git a/intern/audaspace/FX/AUD_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp
index b2e8e97a602..b7b8937abb8 100644
--- a/intern/audaspace/FX/AUD_LoopReader.cpp
+++ b/intern/audaspace/FX/AUD_LoopReader.cpp
@@ -34,7 +34,7 @@
#include <cstring>
-AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
+AUD_LoopReader::AUD_LoopReader(AUD_Reference<AUD_IReader> reader, int loop) :
AUD_EffectReader(reader), m_count(loop), m_left(loop)
{
}
diff --git a/intern/audaspace/FX/AUD_LoopReader.h b/intern/audaspace/FX/AUD_LoopReader.h
index 45017901c56..866d6f7885f 100644
--- a/intern/audaspace/FX/AUD_LoopReader.h
+++ b/intern/audaspace/FX/AUD_LoopReader.h
@@ -68,7 +68,7 @@ public:
* \param loop The desired loop count, negative values result in endless
* looping.
*/
- AUD_LoopReader(AUD_IReader* reader, int loop);
+ AUD_LoopReader(AUD_Reference<AUD_IReader> reader, int loop);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
index d24a04b5a94..d0f33c120d9 100644
--- a/intern/audaspace/FX/AUD_LowpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_LowpassFactory.cpp
@@ -38,7 +38,7 @@
#define M_PI 3.14159265358979323846
#endif
-AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
+AUD_LowpassFactory::AUD_LowpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency,
float Q) :
AUD_EffectFactory(factory),
m_frequency(frequency),
@@ -46,9 +46,9 @@ AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
{
}
-AUD_IReader* AUD_LowpassFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LowpassFactory::createReader() const
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
// calculate coefficients
float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h
index d60c0bd22d1..efe4dafc4e1 100644
--- a/intern/audaspace/FX/AUD_LowpassFactory.h
+++ b/intern/audaspace/FX/AUD_LowpassFactory.h
@@ -61,9 +61,9 @@ public:
* \param frequency The cutoff frequency.
* \param Q The Q factor.
*/
- AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+ AUD_LowpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency, float Q = 1.0f);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_LOWPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.cpp b/intern/audaspace/FX/AUD_PingPongFactory.cpp
index fa140555943..4f0d2a207ac 100644
--- a/intern/audaspace/FX/AUD_PingPongFactory.cpp
+++ b/intern/audaspace/FX/AUD_PingPongFactory.cpp
@@ -33,26 +33,16 @@
#include "AUD_DoubleReader.h"
#include "AUD_ReverseFactory.h"
-AUD_PingPongFactory::AUD_PingPongFactory(AUD_IFactory* factory) :
+AUD_PingPongFactory::AUD_PingPongFactory(AUD_Reference<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_IReader* AUD_PingPongFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_PingPongFactory::createReader() const
{
- AUD_IReader* reader = getReader();
- AUD_IReader* reader2;
+ AUD_Reference<AUD_IReader> reader = getReader();
AUD_ReverseFactory factory(m_factory);
-
- try
- {
- reader2 = factory.createReader();
- }
- catch(AUD_Exception&)
- {
- delete reader;
- throw;
- }
+ AUD_Reference<AUD_IReader> reader2 = factory.createReader();
return new AUD_DoubleReader(reader, reader2);
}
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.h b/intern/audaspace/FX/AUD_PingPongFactory.h
index 4ae0c494eb7..1c88a5a7114 100644
--- a/intern/audaspace/FX/AUD_PingPongFactory.h
+++ b/intern/audaspace/FX/AUD_PingPongFactory.h
@@ -50,9 +50,9 @@ public:
* Creates a new ping pong factory.
* \param factory The input factory.
*/
- AUD_PingPongFactory(AUD_IFactory* factory);
+ AUD_PingPongFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_PINGPONGFACTORY
diff --git a/intern/audaspace/FX/AUD_PitchFactory.cpp b/intern/audaspace/FX/AUD_PitchFactory.cpp
index b4ae8582caf..94a3fb8034e 100644
--- a/intern/audaspace/FX/AUD_PitchFactory.cpp
+++ b/intern/audaspace/FX/AUD_PitchFactory.cpp
@@ -33,13 +33,13 @@
#include "AUD_PitchReader.h"
#include "AUD_Space.h"
-AUD_PitchFactory::AUD_PitchFactory(AUD_IFactory* factory, float pitch) :
+AUD_PitchFactory::AUD_PitchFactory(AUD_Reference<AUD_IFactory> factory, float pitch) :
AUD_EffectFactory(factory),
m_pitch(pitch)
{
}
-AUD_IReader* AUD_PitchFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_PitchFactory::createReader() const
{
return new AUD_PitchReader(getReader(), m_pitch);
}
diff --git a/intern/audaspace/FX/AUD_PitchFactory.h b/intern/audaspace/FX/AUD_PitchFactory.h
index 8fa5be9293f..bbf08ef5993 100644
--- a/intern/audaspace/FX/AUD_PitchFactory.h
+++ b/intern/audaspace/FX/AUD_PitchFactory.h
@@ -55,9 +55,9 @@ public:
* \param factory The input factory.
* \param pitch The desired pitch.
*/
- AUD_PitchFactory(AUD_IFactory* factory, float pitch);
+ AUD_PitchFactory(AUD_Reference<AUD_IFactory> factory, float pitch);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_PITCHFACTORY
diff --git a/intern/audaspace/FX/AUD_PitchReader.cpp b/intern/audaspace/FX/AUD_PitchReader.cpp
index e2e89e2c457..7f8b8b53105 100644
--- a/intern/audaspace/FX/AUD_PitchReader.cpp
+++ b/intern/audaspace/FX/AUD_PitchReader.cpp
@@ -31,7 +31,7 @@
#include "AUD_PitchReader.h"
-AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) :
+AUD_PitchReader::AUD_PitchReader(AUD_Reference<AUD_IReader> reader, float pitch) :
AUD_EffectReader(reader), m_pitch(pitch)
{
}
diff --git a/intern/audaspace/FX/AUD_PitchReader.h b/intern/audaspace/FX/AUD_PitchReader.h
index 120cebc58be..7939027dca9 100644
--- a/intern/audaspace/FX/AUD_PitchReader.h
+++ b/intern/audaspace/FX/AUD_PitchReader.h
@@ -55,7 +55,7 @@ public:
* \param reader The reader to read from.
* \param pitch The size of the buffer.
*/
- AUD_PitchReader(AUD_IReader* reader, float pitch);
+ AUD_PitchReader(AUD_Reference<AUD_IReader> reader, float pitch);
virtual AUD_Specs getSpecs() const;
};
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.cpp b/intern/audaspace/FX/AUD_RectifyFactory.cpp
index 609d827cce4..3bacd033eb3 100644
--- a/intern/audaspace/FX/AUD_RectifyFactory.cpp
+++ b/intern/audaspace/FX/AUD_RectifyFactory.cpp
@@ -39,12 +39,12 @@ sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
return fabs(reader->x(0));
}
-AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
+AUD_RectifyFactory::AUD_RectifyFactory(AUD_Reference<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_IReader* AUD_RectifyFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_RectifyFactory::createReader() const
{
return new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter);
}
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.h b/intern/audaspace/FX/AUD_RectifyFactory.h
index c3529c7beef..d8411186001 100644
--- a/intern/audaspace/FX/AUD_RectifyFactory.h
+++ b/intern/audaspace/FX/AUD_RectifyFactory.h
@@ -49,9 +49,9 @@ public:
* Creates a new rectify factory.
* \param factory The input factory.
*/
- AUD_RectifyFactory(AUD_IFactory* factory);
+ AUD_RectifyFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_RECTIFYFACTORY
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.cpp b/intern/audaspace/FX/AUD_ReverseFactory.cpp
index 22b12e31420..88d812d7f2a 100644
--- a/intern/audaspace/FX/AUD_ReverseFactory.cpp
+++ b/intern/audaspace/FX/AUD_ReverseFactory.cpp
@@ -33,12 +33,12 @@
#include "AUD_ReverseReader.h"
#include "AUD_Space.h"
-AUD_ReverseFactory::AUD_ReverseFactory(AUD_IFactory* factory) :
+AUD_ReverseFactory::AUD_ReverseFactory(AUD_Reference<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_IReader* AUD_ReverseFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_ReverseFactory::createReader() const
{
return new AUD_ReverseReader(getReader());
}
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.h b/intern/audaspace/FX/AUD_ReverseFactory.h
index 7b20546302e..ae1fdd5a233 100644
--- a/intern/audaspace/FX/AUD_ReverseFactory.h
+++ b/intern/audaspace/FX/AUD_ReverseFactory.h
@@ -50,9 +50,9 @@ public:
* Creates a new reverse factory.
* \param factory The input factory.
*/
- AUD_ReverseFactory(AUD_IFactory* factory);
+ AUD_ReverseFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_REVERSEFACTORY
diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp
index a4a03936c76..8ca9f8609bb 100644
--- a/intern/audaspace/FX/AUD_ReverseReader.cpp
+++ b/intern/audaspace/FX/AUD_ReverseReader.cpp
@@ -36,7 +36,7 @@
static const char* props_error = "AUD_ReverseReader: The reader has to be "
"seekable and a finite length.";
-AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) :
+AUD_ReverseReader::AUD_ReverseReader(AUD_Reference<AUD_IReader> reader) :
AUD_EffectReader(reader),
m_length(reader->getLength()),
m_position(0)
diff --git a/intern/audaspace/FX/AUD_ReverseReader.h b/intern/audaspace/FX/AUD_ReverseReader.h
index e12f2b21191..d8086e08534 100644
--- a/intern/audaspace/FX/AUD_ReverseReader.h
+++ b/intern/audaspace/FX/AUD_ReverseReader.h
@@ -68,7 +68,7 @@ public:
* \exception AUD_Exception Thrown if the reader specified has an
* undeterminable/infinite length or is not seekable.
*/
- AUD_ReverseReader(AUD_IReader* reader);
+ AUD_ReverseReader(AUD_Reference<AUD_IReader> reader);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/FX/AUD_SquareFactory.cpp b/intern/audaspace/FX/AUD_SquareFactory.cpp
index a075773d2cb..a3ea088a258 100644
--- a/intern/audaspace/FX/AUD_SquareFactory.cpp
+++ b/intern/audaspace/FX/AUD_SquareFactory.cpp
@@ -48,7 +48,7 @@ void endSquareFilter(float* threshold)
delete threshold;
}
-AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) :
+AUD_SquareFactory::AUD_SquareFactory(AUD_Reference<AUD_IFactory> factory, float threshold) :
AUD_EffectFactory(factory),
m_threshold(threshold)
{
@@ -59,7 +59,7 @@ float AUD_SquareFactory::getThreshold() const
return m_threshold;
}
-AUD_IReader* AUD_SquareFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SquareFactory::createReader() const
{
return new AUD_CallbackIIRFilterReader(getReader(), 1, 1,
(doFilterIIR) squareFilter,
diff --git a/intern/audaspace/FX/AUD_SquareFactory.h b/intern/audaspace/FX/AUD_SquareFactory.h
index 8060e98e281..60db49c48e5 100644
--- a/intern/audaspace/FX/AUD_SquareFactory.h
+++ b/intern/audaspace/FX/AUD_SquareFactory.h
@@ -55,14 +55,14 @@ public:
* \param factory The input factory.
* \param threshold The threshold.
*/
- AUD_SquareFactory(AUD_IFactory* factory, float threshold = 0.0f);
+ AUD_SquareFactory(AUD_Reference<AUD_IFactory> factory, float threshold = 0.0f);
/**
* Returns the threshold.
*/
float getThreshold() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_SQUAREFACTORY
diff --git a/intern/audaspace/FX/AUD_SumFactory.cpp b/intern/audaspace/FX/AUD_SumFactory.cpp
index 6d8368d6e35..582e2d75b7f 100644
--- a/intern/audaspace/FX/AUD_SumFactory.cpp
+++ b/intern/audaspace/FX/AUD_SumFactory.cpp
@@ -32,12 +32,12 @@
#include "AUD_SumFactory.h"
#include "AUD_IIRFilterReader.h"
-AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
+AUD_SumFactory::AUD_SumFactory(AUD_Reference<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_IReader* AUD_SumFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SumFactory::createReader() const
{
std::vector<float> a, b;
a.push_back(1);
diff --git a/intern/audaspace/FX/AUD_SumFactory.h b/intern/audaspace/FX/AUD_SumFactory.h
index ed19a0f258a..948355e50fd 100644
--- a/intern/audaspace/FX/AUD_SumFactory.h
+++ b/intern/audaspace/FX/AUD_SumFactory.h
@@ -49,9 +49,9 @@ public:
* Creates a new sum factory.
* \param factory The input factory.
*/
- AUD_SumFactory(AUD_IFactory* factory);
+ AUD_SumFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_SUMFACTORY
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.cpp b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
index c13a0d0dd95..b5e816f66a8 100644
--- a/intern/audaspace/FX/AUD_SuperposeFactory.cpp
+++ b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
@@ -32,24 +32,15 @@
#include "AUD_SuperposeFactory.h"
#include "AUD_SuperposeReader.h"
-AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2) :
m_factory1(factory1), m_factory2(factory2)
{
}
-AUD_IReader* AUD_SuperposeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SuperposeFactory::createReader() const
{
- AUD_IReader* reader1 = m_factory1->createReader();
- AUD_IReader* reader2;
- try
- {
- reader2 = m_factory2->createReader();
- }
- catch(AUD_Exception&)
- {
- delete reader1;
- throw;
- }
+ AUD_Reference<AUD_IReader> reader1 = m_factory1->createReader();
+ AUD_Reference<AUD_IReader> reader2 = m_factory2->createReader();
return new AUD_SuperposeReader(reader1, reader2);
}
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.h b/intern/audaspace/FX/AUD_SuperposeFactory.h
index 32232012e4e..d302658097e 100644
--- a/intern/audaspace/FX/AUD_SuperposeFactory.h
+++ b/intern/audaspace/FX/AUD_SuperposeFactory.h
@@ -44,12 +44,12 @@ private:
/**
* First played factory.
*/
- AUD_IFactory* m_factory1;
+ AUD_Reference<AUD_IFactory> m_factory1;
/**
* Second played factory.
*/
- AUD_IFactory* m_factory2;
+ AUD_Reference<AUD_IFactory> m_factory2;
// hide copy constructor and operator=
AUD_SuperposeFactory(const AUD_SuperposeFactory&);
@@ -61,9 +61,9 @@ public:
* \param factory1 The first input factory.
* \param factory2 The second input factory.
*/
- AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+ AUD_SuperposeFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_SUPERPOSEFACTORY
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp
index e64cf79188e..6f39dcadf40 100644
--- a/intern/audaspace/FX/AUD_SuperposeReader.cpp
+++ b/intern/audaspace/FX/AUD_SuperposeReader.cpp
@@ -36,30 +36,18 @@
static const char* specs_error = "AUD_SuperposeReader: Both readers have to "
"have the same specs.";
-AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2) :
+AUD_SuperposeReader::AUD_SuperposeReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2) :
m_reader1(reader1), m_reader2(reader2)
{
- try
- {
- AUD_Specs s1, s2;
- s1 = reader1->getSpecs();
- s2 = reader2->getSpecs();
- if(memcmp(&s1, &s2, sizeof(AUD_Specs)))
- AUD_THROW(AUD_ERROR_SPECS, specs_error);
- }
- catch(AUD_Exception&)
- {
- delete reader1;
- delete reader2;
-
- throw;
- }
+ AUD_Specs s1, s2;
+ s1 = reader1->getSpecs();
+ s2 = reader2->getSpecs();
+ if(memcmp(&s1, &s2, sizeof(AUD_Specs)))
+ AUD_THROW(AUD_ERROR_SPECS, specs_error);
}
AUD_SuperposeReader::~AUD_SuperposeReader()
{
- delete m_reader1;
- delete m_reader2;
}
bool AUD_SuperposeReader::isSeekable() const
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h
index b256aade7ba..26e4b138dfa 100644
--- a/intern/audaspace/FX/AUD_SuperposeReader.h
+++ b/intern/audaspace/FX/AUD_SuperposeReader.h
@@ -34,6 +34,7 @@
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
+#include "AUD_Reference.h"
/**
* This reader plays two readers with the same specs sequently.
@@ -44,12 +45,12 @@ private:
/**
* The first reader.
*/
- AUD_IReader* m_reader1;
+ AUD_Reference<AUD_IReader> m_reader1;
/**
* The second reader.
*/
- AUD_IReader* m_reader2;
+ AUD_Reference<AUD_IReader> m_reader2;
/**
* The playback buffer for the intersecting part.
@@ -67,7 +68,7 @@ public:
* \param reader2 The second reader to read from.
* \exception AUD_Exception Thrown if the specs from the readers differ.
*/
- AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2);
+ AUD_SuperposeReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2);
/**
* Destroys the reader.
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.cpp b/intern/audaspace/FX/AUD_VolumeFactory.cpp
index 166fbf61512..1249c4ab9bd 100644
--- a/intern/audaspace/FX/AUD_VolumeFactory.cpp
+++ b/intern/audaspace/FX/AUD_VolumeFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_VolumeFactory.h"
#include "AUD_IIRFilterReader.h"
-AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) :
+AUD_VolumeFactory::AUD_VolumeFactory(AUD_Reference<AUD_IFactory> factory, float volume) :
AUD_EffectFactory(factory),
m_volume(volume)
{
@@ -43,7 +43,7 @@ float AUD_VolumeFactory::getVolume() const
return m_volume;
}
-AUD_IReader* AUD_VolumeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_VolumeFactory::createReader() const
{
std::vector<float> a, b;
a.push_back(1);
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.h b/intern/audaspace/FX/AUD_VolumeFactory.h
index fa40ca11082..3cb8bc1da17 100644
--- a/intern/audaspace/FX/AUD_VolumeFactory.h
+++ b/intern/audaspace/FX/AUD_VolumeFactory.h
@@ -57,14 +57,14 @@ public:
* \param factory The input factory.
* \param volume The desired volume.
*/
- AUD_VolumeFactory(AUD_IFactory* factory, float volume);
+ AUD_VolumeFactory(AUD_Reference<AUD_IFactory> factory, float volume);
/**
* Returns the volume.
*/
float getVolume() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_VOLUMEFACTORY
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index b9e30bbf62a..a3b0bff316e 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -52,7 +52,7 @@ struct AUD_OpenALHandle : AUD_Handle
bool isBuffered;
/// The reader source.
- AUD_IReader* reader;
+ AUD_Reference<AUD_IReader> reader;
/// Whether to keep the source if end of it is reached.
bool keep;
@@ -382,7 +382,6 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
alDeleteSources(1, &sound->source);
if(!sound->isBuffered)
{
- delete sound->reader;
alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
}
delete sound;
@@ -396,7 +395,6 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
alDeleteSources(1, &sound->source);
if(!sound->isBuffered)
{
- delete sound->reader;
alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
}
delete sound;
@@ -539,7 +537,7 @@ static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
"filled with data.";
-AUD_Handle* AUD_OpenALDevice::play(AUD_IReader* reader, bool keep)
+AUD_Handle* AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
AUD_OpenALHandle* sound = NULL;
@@ -568,7 +566,6 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IReader* reader, bool keep)
if(!valid)
{
delete sound;
- delete reader;
return NULL;
}
@@ -624,7 +621,6 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IReader* reader, bool keep)
catch(AUD_Exception&)
{
delete sound;
- delete reader;
alcProcessContext(m_context);
unlock();
throw;
@@ -642,8 +638,9 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IReader* reader, bool keep)
return sound;
}
-AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
+AUD_Handle* AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
+ /* AUD_XXX disabled
AUD_OpenALHandle* sound = NULL;
lock();
@@ -713,7 +710,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
unlock();
if(sound)
- return sound;
+ return sound;*/
return play(factory->createReader(), keep);
}
@@ -785,7 +782,6 @@ bool AUD_OpenALDevice::stop(AUD_Handle* handle)
alDeleteSources(1, &sound->source);
if(!sound->isBuffered)
{
- delete sound->reader;
alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
}
delete *i;
@@ -805,7 +801,6 @@ bool AUD_OpenALDevice::stop(AUD_Handle* handle)
alDeleteSources(1, &sound->source);
if(!sound->isBuffered)
{
- delete sound->reader;
alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
}
delete *i;
@@ -1109,7 +1104,6 @@ bool AUD_OpenALDevice::bufferFactory(void *value)
if(!getFormat(format, specs.specs))
{
- delete reader;
return false;
}
@@ -1147,7 +1141,6 @@ bool AUD_OpenALDevice::bufferFactory(void *value)
catch(AUD_Exception&)
{
delete bf;
- delete reader;
alcProcessContext(m_context);
unlock();
return false;
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
index 3bbbe85d7e6..3bca47f1805 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -147,8 +147,8 @@ public:
virtual ~AUD_OpenALDevice();
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false);
- virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
+ virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+ virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
virtual bool stop(AUD_Handle* handle);
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
index 22376a2fcd1..ac25ab34a69 100644
--- a/intern/audaspace/Python/AUD_PyAPI.cpp
+++ b/intern/audaspace/Python/AUD_PyAPI.cpp
@@ -91,7 +91,7 @@ static void
Factory_dealloc(Factory* self)
{
if(self->factory)
- delete self->factory;
+ delete reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory);
Py_XDECREF(self->child_list);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -115,7 +115,7 @@ Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
try
{
- self->factory = new AUD_FileFactory(filename);
+ self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
}
catch(AUD_Exception& e)
{
@@ -155,7 +155,7 @@ Factory_sine(PyTypeObject* type, PyObject* args)
{
try
{
- self->factory = new AUD_SinusFactory(frequency, (AUD_SampleRate)rate);
+ self->factory = new AUD_Reference<AUD_IFactory>(new AUD_SinusFactory(frequency, (AUD_SampleRate)rate));
}
catch(AUD_Exception& e)
{
@@ -194,7 +194,7 @@ Factory_file(PyTypeObject* type, PyObject* args)
{
try
{
- self->factory = new AUD_FileFactory(filename);
+ self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
}
catch(AUD_Exception& e)
{
@@ -237,7 +237,7 @@ Factory_lowpass(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_LowpassFactory(self->factory, frequency, Q);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LowpassFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), frequency, Q));
}
catch(AUD_Exception& e)
{
@@ -278,7 +278,7 @@ Factory_delay(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_DelayFactory(self->factory, delay);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_DelayFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), delay));
}
catch(AUD_Exception& e)
{
@@ -322,7 +322,7 @@ Factory_join(Factory* self, PyObject* object)
try
{
- parent->factory = new AUD_DoubleFactory(self->factory, child->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_DoubleFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), *reinterpret_cast<AUD_Reference<AUD_IFactory>*>(child->factory)));
}
catch(AUD_Exception& e)
{
@@ -365,7 +365,7 @@ Factory_highpass(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_HighpassFactory(self->factory, frequency, Q);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_HighpassFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), frequency, Q));
}
catch(AUD_Exception& e)
{
@@ -406,7 +406,7 @@ Factory_limit(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_LimiterFactory(self->factory, start, end);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LimiterFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), start, end));
}
catch(AUD_Exception& e)
{
@@ -450,7 +450,7 @@ Factory_pitch(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_PitchFactory(self->factory, factor);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_PitchFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), factor));
}
catch(AUD_Exception& e)
{
@@ -492,7 +492,7 @@ Factory_volume(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_VolumeFactory(self->factory, volume);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_VolumeFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), volume));
}
catch(AUD_Exception& e)
{
@@ -535,7 +535,7 @@ Factory_fadein(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_IN, start, length);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), AUD_FADE_IN, start, length));
}
catch(AUD_Exception& e)
{
@@ -579,7 +579,7 @@ Factory_fadeout(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_OUT, start, length);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), AUD_FADE_OUT, start, length));
}
catch(AUD_Exception& e)
{
@@ -621,7 +621,7 @@ Factory_loop(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_LoopFactory(self->factory, loop);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LoopFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), loop));
}
catch(AUD_Exception& e)
{
@@ -664,7 +664,7 @@ Factory_mix(Factory* self, PyObject* object)
try
{
- parent->factory = new AUD_SuperposeFactory(self->factory, child->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_SuperposeFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), *reinterpret_cast<AUD_Reference<AUD_IFactory>*>(child->factory)));
}
catch(AUD_Exception& e)
{
@@ -697,7 +697,7 @@ Factory_pingpong(Factory* self)
try
{
- parent->factory = new AUD_PingPongFactory(self->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_PingPongFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory)));
}
catch(AUD_Exception& e)
{
@@ -736,7 +736,7 @@ Factory_reverse(Factory* self)
try
{
- parent->factory = new AUD_ReverseFactory(self->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_ReverseFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory)));
}
catch(AUD_Exception& e)
{
@@ -771,7 +771,7 @@ Factory_buffer(Factory* self)
{
try
{
- parent->factory = new AUD_StreamBufferFactory(self->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_StreamBufferFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory)));
}
catch(AUD_Exception& e)
{
@@ -813,7 +813,7 @@ Factory_square(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_SquareFactory(self->factory, threshold);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_SquareFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), threshold));
}
catch(AUD_Exception& e)
{
@@ -910,7 +910,7 @@ Factory_filter(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_IIRFilterFactory(self->factory, b, a);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_IIRFilterFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), b, a));
}
catch(AUD_Exception& e)
{
@@ -1050,7 +1050,7 @@ Handle_pause(Handle *self)
try
{
- return PyBool_FromLong((long)device->device->pause(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->pause(self->handle));
}
catch(AUD_Exception& e)
{
@@ -1072,7 +1072,7 @@ Handle_resume(Handle *self)
try
{
- return PyBool_FromLong((long)device->device->resume(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->resume(self->handle));
}
catch(AUD_Exception& e)
{
@@ -1095,7 +1095,7 @@ Handle_stop(Handle *self)
try
{
- return PyBool_FromLong((long)device->device->stop(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->stop(self->handle));
}
catch(AUD_Exception& e)
{
@@ -1127,7 +1127,7 @@ Handle_get_position(Handle *self, void* nothing)
try
{
- return Py_BuildValue("f", device->device->getPosition(self->handle));
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getPosition(self->handle));
}
catch(AUD_Exception& e)
{
@@ -1148,7 +1148,7 @@ Handle_set_position(Handle *self, PyObject* args, void* nothing)
try
{
- if(device->device->seek(self->handle, position))
+ if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->seek(self->handle, position))
return 0;
PyErr_SetString(AUDError, "Couldn't seek the sound!");
}
@@ -1176,7 +1176,7 @@ Handle_get_keep(Handle *self, void* nothing)
try
{
- return PyBool_FromLong((long)device->device->getKeep(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getKeep(self->handle));
}
catch(AUD_Exception& e)
{
@@ -1199,7 +1199,7 @@ Handle_set_keep(Handle *self, PyObject* args, void* nothing)
try
{
- if(device->device->setKeep(self->handle, keep))
+ if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setKeep(self->handle, keep))
return 0;
PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
}
@@ -1221,7 +1221,7 @@ Handle_get_status(Handle *self, void* nothing)
try
{
- return PyBool_FromLong((long)device->device->getStatus(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getStatus(self->handle));
}
catch(AUD_Exception& e)
{
@@ -1240,7 +1240,7 @@ Handle_get_volume(Handle *self, void* nothing)
try
{
- return Py_BuildValue("f", device->device->getVolume(self->handle));
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getVolume(self->handle));
}
catch(AUD_Exception& e)
{
@@ -1261,7 +1261,7 @@ Handle_set_volume(Handle *self, PyObject* args, void* nothing)
try
{
- if(device->device->setVolume(self->handle, volume))
+ if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setVolume(self->handle, volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound volume!");
}
@@ -1283,7 +1283,7 @@ Handle_get_pitch(Handle *self, void* nothing)
try
{
- return Py_BuildValue("f", device->device->getPitch(self->handle));
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getPitch(self->handle));
}
catch(AUD_Exception& e)
{
@@ -1304,7 +1304,7 @@ Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
try
{
- if(device->device->setPitch(self->handle, pitch))
+ if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setPitch(self->handle, pitch))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
}
@@ -1326,7 +1326,7 @@ Handle_get_loop_count(Handle *self, void* nothing)
try
{
- return Py_BuildValue("i", device->device->getLoopCount(self->handle));
+ return Py_BuildValue("i", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getLoopCount(self->handle));
}
catch(AUD_Exception& e)
{
@@ -1347,7 +1347,7 @@ Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
try
{
- if(device->device->setLoopCount(self->handle, loops))
+ if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setLoopCount(self->handle, loops))
return 0;
PyErr_SetString(AUDError, "Couldn't set the loop count!");
}
@@ -1369,7 +1369,7 @@ Handle_get_location(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
AUD_Vector3 v = device->getSourceLocation(self->handle);
@@ -1400,7 +1400,7 @@ Handle_set_location(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
AUD_Vector3 location(x, y, z);
@@ -1429,7 +1429,7 @@ Handle_get_velocity(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
AUD_Vector3 v = device->getSourceVelocity(self->handle);
@@ -1460,7 +1460,7 @@ Handle_set_velocity(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
AUD_Vector3 velocity(x, y, z);
@@ -1489,7 +1489,7 @@ Handle_get_orientation(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
AUD_Quaternion o = device->getSourceOrientation(self->handle);
@@ -1520,7 +1520,7 @@ Handle_set_orientation(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
AUD_Quaternion orientation(w, x, y, z);
@@ -1549,7 +1549,7 @@ Handle_get_relative(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
return PyBool_FromLong((long)device->isRelative(self->handle));
@@ -1581,7 +1581,7 @@ Handle_set_relative(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
if(device->setRelative(self->handle, relative))
@@ -1610,7 +1610,7 @@ Handle_get_volume_minimum(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
return Py_BuildValue("f", device->getVolumeMinimum(self->handle));
@@ -1640,7 +1640,7 @@ Handle_set_volume_minimum(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
if(device->setVolumeMinimum(self->handle, volume))
@@ -1669,7 +1669,7 @@ Handle_get_volume_maximum(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
return Py_BuildValue("f", device->getVolumeMaximum(self->handle));
@@ -1699,7 +1699,7 @@ Handle_set_volume_maximum(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
if(device->setVolumeMaximum(self->handle, volume))
@@ -1729,7 +1729,7 @@ Handle_get_distance_reference(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
return Py_BuildValue("f", device->getDistanceReference(self->handle));
@@ -1759,7 +1759,7 @@ Handle_set_distance_reference(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
if(device->setDistanceReference(self->handle, distance))
@@ -1789,7 +1789,7 @@ Handle_get_distance_maximum(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
return Py_BuildValue("f", device->getDistanceMaximum(self->handle));
@@ -1819,7 +1819,7 @@ Handle_set_distance_maximum(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
if(device->setDistanceMaximum(self->handle, distance))
@@ -1849,7 +1849,7 @@ Handle_get_attenuation(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
return Py_BuildValue("f", device->getAttenuation(self->handle));
@@ -1879,7 +1879,7 @@ Handle_set_attenuation(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
if(device->setAttenuation(self->handle, factor))
@@ -1914,7 +1914,7 @@ Handle_get_cone_angle_inner(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
return Py_BuildValue("f", device->getConeAngleInner(self->handle));
@@ -1944,7 +1944,7 @@ Handle_set_cone_angle_inner(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
if(device->setConeAngleInner(self->handle, angle))
@@ -1973,7 +1973,7 @@ Handle_get_cone_angle_outer(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
return Py_BuildValue("f", device->getConeAngleOuter(self->handle));
@@ -2003,7 +2003,7 @@ Handle_set_cone_angle_outer(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
if(device->setConeAngleOuter(self->handle, angle))
@@ -2032,7 +2032,7 @@ Handle_get_cone_volume_outer(Handle *self, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
return Py_BuildValue("f", device->getConeVolumeOuter(self->handle));
@@ -2062,7 +2062,7 @@ Handle_set_cone_volume_outer(Handle *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
{
if(device->setConeVolumeOuter(self->handle, volume))
@@ -2172,7 +2172,7 @@ static void
Device_dealloc(Device* self)
{
if(self->device)
- delete self->device;
+ delete reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -2215,21 +2215,21 @@ Device_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
case AUD_DEVICE_NULL:
(void)specs; /* quiet warning when others disabled */
- self->device = new AUD_NULLDevice();
+ self->device = new AUD_Reference<AUD_IDevice>(new AUD_NULLDevice());
break;
case AUD_DEVICE_OPENAL:
#ifdef WITH_OPENAL
- self->device = new AUD_OpenALDevice(specs, buffersize);
+ self->device = new AUD_Reference<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
#endif
break;
case AUD_DEVICE_SDL:
#ifdef WITH_SDL
- self->device = new AUD_SDLDevice(specs, buffersize);
+ self->device = new AUD_Reference<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
#endif
break;
case AUD_DEVICE_JACK:
#ifdef WITH_JACK
- self->device = new AUD_JackDevice(name, specs, buffersize);
+ self->device = new AUD_Reference<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
#endif
break;
case AUD_DEVICE_READ:
@@ -2307,7 +2307,7 @@ Device_play(Device *self, PyObject *args, PyObject *kwds)
try
{
- handle->handle = self->device->play(sound->factory, keep);
+ handle->handle = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(sound->factory), keep);
}
catch(AUD_Exception& e)
{
@@ -2336,7 +2336,7 @@ Device_lock(Device *self)
{
try
{
- self->device->lock();
+ (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->lock();
Py_RETURN_NONE;
}
catch(AUD_Exception& e)
@@ -2356,7 +2356,7 @@ Device_unlock(Device *self)
{
try
{
- self->device->unlock();
+ (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->unlock();
Py_RETURN_NONE;
}
catch(AUD_Exception& e)
@@ -2387,7 +2387,7 @@ Device_get_rate(Device *self, void* nothing)
{
try
{
- AUD_DeviceSpecs specs = self->device->getSpecs();
+ AUD_DeviceSpecs specs = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getSpecs();
return Py_BuildValue("i", specs.rate);
}
catch(AUD_Exception& e)
@@ -2405,7 +2405,7 @@ Device_get_format(Device *self, void* nothing)
{
try
{
- AUD_DeviceSpecs specs = self->device->getSpecs();
+ AUD_DeviceSpecs specs = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getSpecs();
return Py_BuildValue("i", specs.format);
}
catch(AUD_Exception& e)
@@ -2423,7 +2423,7 @@ Device_get_channels(Device *self, void* nothing)
{
try
{
- AUD_DeviceSpecs specs = self->device->getSpecs();
+ AUD_DeviceSpecs specs = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getSpecs();
return Py_BuildValue("i", specs.channels);
}
catch(AUD_Exception& e)
@@ -2441,7 +2441,7 @@ Device_get_volume(Device *self, void* nothing)
{
try
{
- return Py_BuildValue("f", self->device->getVolume());
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getVolume());
}
catch(AUD_Exception& e)
{
@@ -2460,7 +2460,7 @@ Device_set_volume(Device *self, PyObject* args, void* nothing)
try
{
- self->device->setVolume(volume);
+ (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->setVolume(volume);
return 0;
}
catch(AUD_Exception& e)
@@ -2478,7 +2478,7 @@ Device_get_listener_location(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 v = device->getListenerLocation();
@@ -2507,7 +2507,7 @@ Device_set_listener_location(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 location(x, y, z);
@@ -2533,7 +2533,7 @@ Device_get_listener_velocity(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 v = device->getListenerVelocity();
@@ -2562,7 +2562,7 @@ Device_set_listener_velocity(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 velocity(x, y, z);
@@ -2588,7 +2588,7 @@ Device_get_listener_orientation(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Quaternion o = device->getListenerOrientation();
@@ -2617,7 +2617,7 @@ Device_set_listener_orientation(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Quaternion orientation(w, x, y, z);
@@ -2644,7 +2644,7 @@ Device_get_speed_of_sound(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
return Py_BuildValue("f", device->getSpeedOfSound());
@@ -2672,7 +2672,7 @@ Device_set_speed_of_sound(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
device->setSpeedOfSound(speed);
@@ -2700,7 +2700,7 @@ Device_get_doppler_factor(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
return Py_BuildValue("f", device->getDopplerFactor());
@@ -2728,7 +2728,7 @@ Device_set_doppler_factor(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
device->setDopplerFactor(factor);
@@ -2754,7 +2754,7 @@ Device_get_distance_model(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
return Py_BuildValue("i", int(device->getDistanceModel()));
@@ -2782,7 +2782,7 @@ Device_set_distance_model(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
device->setDistanceModel(AUD_DistanceModel(model));
@@ -2875,6 +2875,12 @@ Device_empty()
return DeviceType.tp_alloc(&DeviceType, 0);
}
+PyObject *
+Factory_empty()
+{
+ return FactoryType.tp_alloc(&FactoryType, 0);
+}
+
// ====================================================================
PyDoc_STRVAR(M_aud_doc,
diff --git a/intern/audaspace/Python/AUD_PyAPI.h b/intern/audaspace/Python/AUD_PyAPI.h
index 6e217b07213..97e1e63b6eb 100644
--- a/intern/audaspace/Python/AUD_PyAPI.h
+++ b/intern/audaspace/Python/AUD_PyAPI.h
@@ -36,17 +36,20 @@
#ifdef __cplusplus
extern "C" {
-#include "AUD_IDevice.h"
+struct AUD_Handle;
#else
typedef void AUD_IFactory;
typedef void AUD_IDevice;
typedef void AUD_Handle;
#endif
+typedef void AUD_Reference_AUD_IFactory;
+typedef void AUD_Reference_AUD_IDevice;
+
typedef struct {
PyObject_HEAD
PyObject* child_list;
- AUD_IFactory* factory;
+ AUD_Reference_AUD_IFactory* factory;
} Factory;
typedef struct {
@@ -57,14 +60,14 @@ typedef struct {
typedef struct {
PyObject_HEAD
- AUD_IDevice* device;
+ AUD_Reference_AUD_IDevice* device;
} Device;
PyMODINIT_FUNC
PyInit_aud(void);
-extern PyObject *
-Device_empty();
+extern PyObject* Device_empty();
+extern PyObject* Factory_empty();
#ifdef __cplusplus
}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
index 17cf09efc1d..ca9c71e73b8 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
@@ -32,15 +32,15 @@
#include "AUD_SRCResampleFactory.h"
#include "AUD_SRCResampleReader.h"
-AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
+AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_ResampleFactory(factory, specs)
{
}
-AUD_IReader* AUD_SRCResampleFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SRCResampleFactory::createReader() const
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
if(reader->getSpecs().rate != m_specs.rate)
reader = new AUD_SRCResampleReader(reader, m_specs.specs);
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.h b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
index 716def960fd..5d21584b4dc 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.h
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
@@ -46,9 +46,9 @@ private:
AUD_SRCResampleFactory& operator=(const AUD_SRCResampleFactory&);
public:
- AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_SRCResampleFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_SRCRESAMPLEFACTORY
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
index 1026514a9b8..e9a94418b60 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
@@ -43,7 +43,7 @@ static long src_callback(void *cb_data, float **data)
static const char* state_error = "AUD_SRCResampleReader: SRC State couldn't be "
"created.";
-AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
+AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader,
AUD_Specs specs) :
AUD_EffectReader(reader),
m_sspecs(reader->getSpecs()),
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.h b/intern/audaspace/SRC/AUD_SRCResampleReader.h
index 27019c0ed9f..21193661911 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.h
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.h
@@ -85,7 +85,7 @@ public:
* \exception AUD_Exception Thrown if the source specification cannot be
* resampled to the target specification.
*/
- AUD_SRCResampleReader(AUD_IReader* reader, AUD_Specs specs);
+ AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs);
/**
* Destroys the reader.
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
index 38de3e8867a..4e1eedd29ee 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
@@ -46,13 +46,13 @@ AUD_FFMPEGFactory::AUD_FFMPEGFactory(std::string filename) :
AUD_FFMPEGFactory::AUD_FFMPEGFactory(const data_t* buffer, int size) :
m_buffer(new AUD_Buffer(size))
{
- memcpy(m_buffer.get()->getBuffer(), buffer, size);
+ memcpy(m_buffer->getBuffer(), buffer, size);
}
-AUD_IReader* AUD_FFMPEGFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_FFMPEGFactory::createReader() const
{
- if(m_buffer.get())
- return new AUD_FFMPEGReader(m_buffer);
- else
+ if(m_buffer.isNull())
return new AUD_FFMPEGReader(m_filename);
+ else
+ return new AUD_FFMPEGReader(m_buffer);
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
index 12687402fb6..8033836e80b 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
@@ -74,7 +74,7 @@ public:
*/
AUD_FFMPEGFactory(const data_t* buffer, int size);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_FFMPEGFACTORY
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 4597432e7d1..ed6ca5d142f 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -255,12 +255,12 @@ int AUD_FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
{
AUD_FFMPEGReader* reader = reinterpret_cast<AUD_FFMPEGReader*>(opaque);
- int size = AUD_MIN(buf_size, reader->m_membuffer.get()->getSize() - reader->m_membufferpos);
+ int size = AUD_MIN(buf_size, reader->m_membuffer->getSize() - reader->m_membufferpos);
if(size < 0)
return -1;
- memcpy(buf, ((data_t*)reader->m_membuffer.get()->getBuffer()) + reader->m_membufferpos, size);
+ memcpy(buf, ((data_t*)reader->m_membuffer->getBuffer()) + reader->m_membufferpos, size);
reader->m_membufferpos += size;
return size;
@@ -276,10 +276,10 @@ int64_t AUD_FFMPEGReader::seek_packet(void* opaque, int64_t offset, int whence)
reader->m_membufferpos = 0;
break;
case SEEK_END:
- reader->m_membufferpos = reader->m_membuffer.get()->getSize();
+ reader->m_membufferpos = reader->m_membuffer->getSize();
break;
case AVSEEK_SIZE:
- return reader->m_membuffer.get()->getSize();
+ return reader->m_membuffer->getSize();
}
return (reader->m_membufferpos += offset);
diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp
index 78111ba104c..0ac967b29b0 100644
--- a/intern/audaspace/intern/AUD_BufferReader.cpp
+++ b/intern/audaspace/intern/AUD_BufferReader.cpp
@@ -51,7 +51,7 @@ void AUD_BufferReader::seek(int position)
int AUD_BufferReader::getLength() const
{
- return m_buffer.get()->getSize() / AUD_SAMPLE_SIZE(m_specs);
+ return m_buffer->getSize() / AUD_SAMPLE_SIZE(m_specs);
}
int AUD_BufferReader::getPosition() const
@@ -68,11 +68,11 @@ void AUD_BufferReader::read(int & length, sample_t* & buffer)
{
int sample_size = AUD_SAMPLE_SIZE(m_specs);
- buffer = m_buffer.get()->getBuffer() + m_position * m_specs.channels;
+ buffer = m_buffer->getBuffer() + m_position * m_specs.channels;
// in case the end of the buffer is reached
- if(m_buffer.get()->getSize() < (m_position + length) * sample_size)
- length = m_buffer.get()->getSize() / sample_size - m_position;
+ if(m_buffer->getSize() < (m_position + length) * sample_size)
+ length = m_buffer->getSize() / sample_size - m_position;
if(length < 0)
length = 0;
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 0119bb105d8..08fb55f7605 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -37,9 +37,6 @@
#ifdef WITH_PYTHON
#include "AUD_PyInit.h"
#include "AUD_PyAPI.h"
-
-Device* g_device;
-bool g_pyinitialized = false;
#endif
#include <cstdlib>
@@ -90,9 +87,10 @@ extern "C" {
#include <cassert>
-typedef AUD_IFactory AUD_Sound;
-typedef AUD_ReadDevice AUD_Device;
+typedef AUD_Reference<AUD_IFactory> AUD_Sound;
+typedef AUD_Reference<AUD_ReadDevice> AUD_Device;
typedef AUD_Handle AUD_Channel;
+typedef AUD_Reference<AUD_SequencerEntry> AUD_SEntry;
#define AUD_CAPI_IMPLEMENTATION
#include "AUD_C-API.h"
@@ -101,8 +99,8 @@ typedef AUD_Handle AUD_Channel;
#define NULL 0
#endif
-static AUD_IDevice* AUD_device = NULL;
-static AUD_I3DDevice* AUD_3ddevice = NULL;
+static AUD_Reference<AUD_IDevice> AUD_device;
+static AUD_I3DDevice* AUD_3ddevice;
void AUD_initOnce()
{
@@ -113,9 +111,9 @@ void AUD_initOnce()
int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
{
- AUD_IDevice* dev = NULL;
+ AUD_Reference<AUD_IDevice> dev = NULL;
- if(AUD_device)
+ if(!AUD_device.isNull())
AUD_exit();
try
@@ -145,18 +143,7 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
}
AUD_device = dev;
- AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
-
-#ifdef WITH_PYTHON
- if(g_pyinitialized)
- {
- g_device = (Device*)Device_empty();
- if(g_device != NULL)
- {
- g_device->device = dev;
- }
- }
-#endif
+ AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device.get());
return true;
}
@@ -168,16 +155,6 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
void AUD_exit()
{
-#ifdef WITH_PYTHON
- if(g_device)
- {
- Py_XDECREF(g_device);
- g_device = NULL;
- }
- else
-#endif
- if(AUD_device)
- delete AUD_device;
AUD_device = NULL;
AUD_3ddevice = NULL;
}
@@ -185,11 +162,16 @@ void AUD_exit()
#ifdef WITH_PYTHON
static PyObject* AUD_getCDevice(PyObject* self)
{
- if(g_device)
+ if(!AUD_device.isNull())
{
- Py_INCREF(g_device);
- return (PyObject*)g_device;
+ Device* device = (Device*)Device_empty();
+ if(device != NULL)
+ {
+ device->device = new AUD_Reference<AUD_IDevice>(AUD_device);
+ return (PyObject*)device;
+ }
}
+
Py_RETURN_NONE;
}
@@ -199,20 +181,49 @@ static PyMethodDef meth_getcdevice[] = {{ "device", (PyCFunction)AUD_getCDevice,
":return: The application's :class:`Device`.\n"
":rtype: :class:`Device`"}};
-PyObject* AUD_initPython()
+extern "C" {
+extern void* sound_get_factory(void* sound);
+}
+
+static PyObject* AUD_getSoundFromPointer(PyObject* self, PyObject* args)
{
- PyObject* module = PyInit_aud();
- PyModule_AddObject(module, "device", (PyObject *)PyCFunction_New(meth_getcdevice, NULL));
- PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
- if(AUD_device)
+ long int lptr;
+
+ if(PyArg_Parse(args, "l:_sound_from_pointer", &lptr))
{
- g_device = (Device*)Device_empty();
- if(g_device != NULL)
+ if(lptr)
{
- g_device->device = AUD_device;
+ AUD_Reference<AUD_IFactory>* factory = (AUD_Reference<AUD_IFactory>*) sound_get_factory((void*) lptr);
+
+ if(factory)
+ {
+ Factory* obj = (Factory*) Factory_empty();
+ if(obj)
+ {
+ obj->factory = new AUD_Reference<AUD_IFactory>(*factory);
+ return (PyObject*) obj;
+ }
+ }
}
}
- g_pyinitialized = true;
+
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef meth_sound_from_pointer[] = {{ "_sound_from_pointer", (PyCFunction)AUD_getSoundFromPointer, METH_O,
+ "_sound_from_pointer(pointer)\n\n"
+ "Returns the corresponding :class:`Factory` object.\n\n"
+ ":arg pointer: The pointer to the bSound object as long.\n"
+ ":type pointer: long\n"
+ ":return: The corresponding :class:`Factory` object.\n"
+ ":rtype: :class:`Factory`"}};
+
+PyObject* AUD_initPython()
+{
+ PyObject* module = PyInit_aud();
+ PyModule_AddObject(module, "device", (PyObject*)PyCFunction_New(meth_getcdevice, NULL));
+ PyModule_AddObject(module, "_sound_from_pointer", (PyObject*)PyCFunction_New(meth_sound_from_pointer, NULL));
+ PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
return module;
}
@@ -220,13 +231,11 @@ PyObject* AUD_initPython()
void AUD_lock()
{
- assert(AUD_device);
AUD_device->lock();
}
void AUD_unlock()
{
- assert(AUD_device);
AUD_device->unlock();
}
@@ -241,13 +250,12 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
try
{
- AUD_IReader* reader = sound->createReader();
+ AUD_Reference<AUD_IReader> reader = (*sound)->createReader();
- if(reader)
+ if(!reader.isNull())
{
info.specs = reader->getSpecs();
info.length = reader->getLength() / (float) info.specs.rate;
- delete reader;
}
}
catch(AUD_Exception&)
@@ -260,13 +268,13 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
AUD_Sound* AUD_load(const char* filename)
{
assert(filename);
- return new AUD_FileFactory(filename);
+ return new AUD_Sound(new AUD_FileFactory(filename));
}
AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
{
assert(buffer);
- return new AUD_FileFactory(buffer, size);
+ return new AUD_Sound(new AUD_FileFactory(buffer, size));
}
AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
@@ -275,7 +283,7 @@ AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
try
{
- return new AUD_StreamBufferFactory(sound);
+ return new AUD_Sound(new AUD_StreamBufferFactory(*sound));
}
catch(AUD_Exception&)
{
@@ -289,7 +297,7 @@ AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
try
{
- return new AUD_DelayFactory(sound, delay);
+ return new AUD_Sound(new AUD_DelayFactory(*sound, delay));
}
catch(AUD_Exception&)
{
@@ -303,7 +311,7 @@ AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
try
{
- return new AUD_LimiterFactory(sound, start, end);
+ return new AUD_Sound(new AUD_LimiterFactory(*sound, start, end));
}
catch(AUD_Exception&)
{
@@ -317,7 +325,7 @@ AUD_Sound* AUD_pingpongSound(AUD_Sound* sound)
try
{
- return new AUD_PingPongFactory(sound);
+ return new AUD_Sound(new AUD_PingPongFactory(*sound));
}
catch(AUD_Exception&)
{
@@ -331,7 +339,7 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound)
try
{
- return new AUD_LoopFactory(sound);
+ return new AUD_Sound(new AUD_LoopFactory(*sound));
}
catch(AUD_Exception&)
{
@@ -360,7 +368,7 @@ AUD_Sound* AUD_rectifySound(AUD_Sound* sound)
try
{
- return new AUD_RectifyFactory(sound);
+ return new AUD_Sound(new AUD_RectifyFactory(*sound));
}
catch(AUD_Exception&)
{
@@ -376,11 +384,10 @@ void AUD_unload(AUD_Sound* sound)
AUD_Channel* AUD_play(AUD_Sound* sound, int keep)
{
- assert(AUD_device);
assert(sound);
try
{
- return AUD_device->play(sound, keep);
+ return AUD_device->play(*sound, keep);
}
catch(AUD_Exception&)
{
@@ -390,51 +397,43 @@ AUD_Channel* AUD_play(AUD_Sound* sound, int keep)
int AUD_pause(AUD_Channel* handle)
{
- assert(AUD_device);
return AUD_device->pause(handle);
}
int AUD_resume(AUD_Channel* handle)
{
- assert(AUD_device);
return AUD_device->resume(handle);
}
int AUD_stop(AUD_Channel* handle)
{
- if(AUD_device)
+ if(!AUD_device.isNull())
return AUD_device->stop(handle);
return false;
}
int AUD_setKeep(AUD_Channel* handle, int keep)
{
- assert(AUD_device);
return AUD_device->setKeep(handle, keep);
}
int AUD_seek(AUD_Channel* handle, float seekTo)
{
- assert(AUD_device);
return AUD_device->seek(handle, seekTo);
}
float AUD_getPosition(AUD_Channel* handle)
{
- assert(AUD_device);
return AUD_device->getPosition(handle);
}
AUD_Status AUD_getStatus(AUD_Channel* handle)
{
- assert(AUD_device);
return AUD_device->getStatus(handle);
}
int AUD_setListenerLocation(const float* location)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_Vector3 v(location[0], location[1], location[2]);
@@ -447,8 +446,6 @@ int AUD_setListenerLocation(const float* location)
int AUD_setListenerVelocity(const float* velocity)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
@@ -461,8 +458,6 @@ int AUD_setListenerVelocity(const float* velocity)
int AUD_setListenerOrientation(const float* orientation)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
@@ -475,8 +470,6 @@ int AUD_setListenerOrientation(const float* orientation)
int AUD_setSpeedOfSound(float speed)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_3ddevice->setSpeedOfSound(speed);
@@ -488,8 +481,6 @@ int AUD_setSpeedOfSound(float speed)
int AUD_setDopplerFactor(float factor)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_3ddevice->setDopplerFactor(factor);
@@ -501,8 +492,6 @@ int AUD_setDopplerFactor(float factor)
int AUD_setDistanceModel(AUD_DistanceModel model)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_3ddevice->setDistanceModel(model);
@@ -514,8 +503,6 @@ int AUD_setDistanceModel(AUD_DistanceModel model)
int AUD_setSourceLocation(AUD_Channel* handle, const float* location)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_Vector3 v(location[0], location[1], location[2]);
@@ -527,8 +514,6 @@ int AUD_setSourceLocation(AUD_Channel* handle, const float* location)
int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
@@ -540,8 +525,6 @@ int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity)
int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
@@ -553,8 +536,6 @@ int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation)
int AUD_setRelative(AUD_Channel* handle, int relative)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
return AUD_3ddevice->setRelative(handle, relative);
@@ -565,8 +546,6 @@ int AUD_setRelative(AUD_Channel* handle, int relative)
int AUD_setVolumeMaximum(AUD_Channel* handle, float volume)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
return AUD_3ddevice->setVolumeMaximum(handle, volume);
@@ -577,8 +556,6 @@ int AUD_setVolumeMaximum(AUD_Channel* handle, float volume)
int AUD_setVolumeMinimum(AUD_Channel* handle, float volume)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
return AUD_3ddevice->setVolumeMinimum(handle, volume);
@@ -589,8 +566,6 @@ int AUD_setVolumeMinimum(AUD_Channel* handle, float volume)
int AUD_setDistanceMaximum(AUD_Channel* handle, float distance)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
return AUD_3ddevice->setDistanceMaximum(handle, distance);
@@ -601,8 +576,6 @@ int AUD_setDistanceMaximum(AUD_Channel* handle, float distance)
int AUD_setDistanceReference(AUD_Channel* handle, float distance)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
return AUD_3ddevice->setDistanceReference(handle, distance);
@@ -613,8 +586,6 @@ int AUD_setDistanceReference(AUD_Channel* handle, float distance)
int AUD_setAttenuation(AUD_Channel* handle, float factor)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
return AUD_3ddevice->setAttenuation(handle, factor);
@@ -625,8 +596,6 @@ int AUD_setAttenuation(AUD_Channel* handle, float factor)
int AUD_setConeAngleOuter(AUD_Channel* handle, float angle)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
return AUD_3ddevice->setConeAngleOuter(handle, angle);
@@ -637,8 +606,6 @@ int AUD_setConeAngleOuter(AUD_Channel* handle, float angle)
int AUD_setConeAngleInner(AUD_Channel* handle, float angle)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
return AUD_3ddevice->setConeAngleInner(handle, angle);
@@ -649,8 +616,6 @@ int AUD_setConeAngleInner(AUD_Channel* handle, float angle)
int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
return AUD_3ddevice->setConeVolumeOuter(handle, volume);
@@ -663,8 +628,6 @@ int AUD_setSoundVolume(AUD_Channel* handle, float volume)
{
if(handle)
{
- assert(AUD_device);
-
try
{
return AUD_device->setVolume(handle, volume);
@@ -678,8 +641,6 @@ int AUD_setSoundPitch(AUD_Channel* handle, float pitch)
{
if(handle)
{
- assert(AUD_device);
-
try
{
return AUD_device->setPitch(handle, pitch);
@@ -693,7 +654,7 @@ AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
{
try
{
- return new AUD_ReadDevice(specs);
+ return new AUD_Device(new AUD_ReadDevice(specs));
}
catch(AUD_Exception&)
{
@@ -708,8 +669,8 @@ AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
try
{
- AUD_Channel* handle = device->play(sound);
- device->seek(handle, seek);
+ AUD_Channel* handle = (*device)->play(*sound);
+ (*device)->seek(handle, seek);
return handle;
}
catch(AUD_Exception&)
@@ -724,7 +685,7 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume)
try
{
- device->setVolume(volume);
+ (*device)->setVolume(volume);
return true;
}
catch(AUD_Exception&) {}
@@ -741,7 +702,7 @@ int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Channel* handle,
try
{
- return device->setVolume(handle, volume);
+ return (*device)->setVolume(handle, volume);
}
catch(AUD_Exception&) {}
}
@@ -755,7 +716,7 @@ int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
try
{
- return device->read(buffer, length);
+ return (*device)->read(buffer, length);
}
catch(AUD_Exception&)
{
@@ -785,38 +746,34 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high,
AUD_DeviceSpecs specs;
specs.channels = AUD_CHANNELS_MONO;
specs.rate = (AUD_SampleRate)samplerate;
- AUD_Sound* sound;
+ AUD_Reference<AUD_IFactory> sound;
- AUD_FileFactory file(filename);
+ AUD_Reference<AUD_IFactory> file = new AUD_FileFactory(filename);
- AUD_IReader* reader = file.createReader();
+ AUD_Reference<AUD_IReader> reader = file->createReader();
AUD_SampleRate rate = reader->getSpecs().rate;
- delete reader;
- AUD_ChannelMapperFactory mapper(&file, specs);
- sound = &mapper;
- AUD_LowpassFactory lowpass(sound, high);
+ sound = new AUD_ChannelMapperFactory(file, specs);
+
if(high < rate)
- sound = &lowpass;
- AUD_HighpassFactory highpass(sound, low);
+ sound = new AUD_LowpassFactory(sound, high);
if(low > 0)
- sound = &highpass;
- AUD_EnvelopeFactory envelope(sound, attack, release, threshold, 0.1f);
- AUD_LinearResampleFactory resampler(&envelope, specs);
- sound = &resampler;
- AUD_SquareFactory squaref(sound, sthreshold);
+ sound = new AUD_HighpassFactory(sound, low);;
+
+ sound = new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f);
+ sound = new AUD_LinearResampleFactory(sound, specs);
+
if(square)
- sound = &squaref;
- AUD_AccumulatorFactory accumulator(sound, additive);
- AUD_SumFactory sum(sound);
+ sound = new AUD_SquareFactory(sound, sthreshold);
+
if(accumulate)
- sound = &accumulator;
+ sound = new AUD_AccumulatorFactory(sound, additive);
else if(additive)
- sound = &sum;
+ sound = new AUD_SumFactory(sound);
reader = sound->createReader();
- if(reader == NULL)
+ if(reader.isNull())
return NULL;
int len;
@@ -830,7 +787,6 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high,
memcpy(buffer.getBuffer() + position, readbuffer, len * sizeof(float));
position += len;
} while(len != 0);
- delete reader;
float* result = (float*)malloc(position * sizeof(float));
memcpy(result, buffer.getBuffer(), position * sizeof(float));
@@ -840,21 +796,17 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high,
static void pauseSound(AUD_Channel* handle)
{
- assert(AUD_device);
-
AUD_device->pause(handle);
}
AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds)
{
- assert(AUD_device);
-
- AUD_SilenceFactory silence;
- AUD_LimiterFactory limiter(&silence, 0, seconds);
+ AUD_Reference<AUD_IFactory> silence = new AUD_SilenceFactory;
+ AUD_Reference<AUD_IFactory> limiter = new AUD_LimiterFactory(silence, 0, seconds);
try
{
- AUD_Channel* channel = AUD_device->play(&limiter);
+ AUD_Channel* channel = AUD_device->play(limiter);
AUD_device->setStopCallback(channel, (stopCallback)pauseSound, handle);
return channel;
}
@@ -874,39 +826,42 @@ AUD_Sound* AUD_createSequencer(int muted, void* data, AUD_volumeFunction volume)
AUD_Specs specs;
specs.channels = AUD_CHANNELS_STEREO;
specs.rate = AUD_RATE_44100;
- return new AUD_SequencerFactory(specs, muted, data, volume);
+ AUD_Reference<AUD_SequencerFactory>* sequencer = new AUD_Reference<AUD_SequencerFactory>(new AUD_SequencerFactory(specs, muted, data, volume));
+ (*sequencer)->setThis(sequencer);
+ return reinterpret_cast<AUD_Sound*>(sequencer);
}
void AUD_destroySequencer(AUD_Sound* sequencer)
{
- delete ((AUD_SequencerFactory*)sequencer);
+ delete sequencer;
}
void AUD_setSequencerMuted(AUD_Sound* sequencer, int muted)
{
- ((AUD_SequencerFactory*)sequencer)->mute(muted);
+ ((AUD_SequencerFactory*)sequencer->get())->mute(muted);
}
-AUD_SequencerEntry* AUD_addSequencer(AUD_Sound** sequencer, AUD_Sound* sound,
+AUD_Reference<AUD_SequencerEntry>* AUD_addSequencer(AUD_Sound* sequencer, AUD_Sound** sound,
float begin, float end, float skip, void* data)
{
- return ((AUD_SequencerFactory*)sequencer)->add((AUD_IFactory**) sound, begin, end, skip, data);
+ return new AUD_Reference<AUD_SequencerEntry>(((AUD_SequencerFactory*)sequencer->get())->add(sound, begin, end, skip, data));
}
-void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry)
+void AUD_removeSequencer(AUD_Sound* sequencer, AUD_Reference<AUD_SequencerEntry>* entry)
{
- ((AUD_SequencerFactory*)sequencer)->remove(entry);
+ ((AUD_SequencerFactory*)sequencer->get())->remove(*entry);
+ delete entry;
}
-void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
+void AUD_moveSequencer(AUD_Sound* sequencer, AUD_Reference<AUD_SequencerEntry>* entry,
float begin, float end, float skip)
{
- ((AUD_SequencerFactory*)sequencer)->move(entry, begin, end, skip);
+ ((AUD_SequencerFactory*)sequencer->get())->move(*entry, begin, end, skip);
}
-void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry, char mute)
+void AUD_muteSequencer(AUD_Sound* sequencer, AUD_Reference<AUD_SequencerEntry>* entry, char mute)
{
- ((AUD_SequencerFactory*)sequencer)->mute(entry, mute);
+ ((AUD_SequencerFactory*)sequencer->get())->mute(*entry, mute);
}
int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
@@ -918,9 +873,7 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
specs.channels = AUD_CHANNELS_MONO;
specs.format = AUD_FORMAT_INVALID;
- AUD_ChannelMapperFactory mapper(sound, specs);
-
- AUD_IReader* reader = mapper.createReader();
+ AUD_Reference<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();
int len = reader->getLength();
float samplejump = (float)len / (float)length;
@@ -949,15 +902,13 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
}
}
- delete reader;
-
return length;
}
void AUD_startPlayback()
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
device->startPlayback();
#endif
@@ -966,7 +917,7 @@ void AUD_startPlayback()
void AUD_stopPlayback()
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
device->stopPlayback();
#endif
@@ -975,7 +926,7 @@ void AUD_stopPlayback()
void AUD_seekSequencer(AUD_Channel* handle, float time)
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
device->seekPlayback(time);
else
@@ -988,7 +939,7 @@ void AUD_seekSequencer(AUD_Channel* handle, float time)
float AUD_getSequencerPosition(AUD_Channel* handle)
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
return device->getPlaybackPosition();
else
@@ -1001,7 +952,7 @@ float AUD_getSequencerPosition(AUD_Channel* handle)
#ifdef WITH_JACK
void AUD_setSyncCallback(AUD_syncFunction function, void* data)
{
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
device->setSyncCallback(function, data);
}
@@ -1010,7 +961,7 @@ void AUD_setSyncCallback(AUD_syncFunction function, void* data)
int AUD_doesPlayback()
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
return device->doesPlayback();
#endif
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index b2242f09547..47dadd05555 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -55,7 +55,7 @@ typedef struct
typedef void AUD_Sound;
typedef void AUD_Channel;
typedef void AUD_Device;
- typedef void AUD_SequencerEntry;
+ typedef void AUD_SEntry;
typedef float (*AUD_volumeFunction)(void*, void*, float);
typedef void (*AUD_syncFunction)(void*, int, float);
#endif
@@ -465,15 +465,15 @@ extern void AUD_destroySequencer(AUD_Sound* sequencer);
extern void AUD_setSequencerMuted(AUD_Sound* sequencer, int muted);
-extern AUD_SequencerEntry* AUD_addSequencer(AUD_Sound** sequencer, AUD_Sound* sound,
+extern AUD_SEntry* AUD_addSequencer(AUD_Sound* sequencer, AUD_Sound** sound,
float begin, float end, float skip, void* data);
-extern void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry);
+extern void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SEntry* entry);
-extern void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
+extern void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SEntry* entry,
float begin, float end, float skip);
-extern void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
+extern void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SEntry* entry,
char mute);
extern int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length);
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
index b474fbad444..ea5e9519729 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
@@ -34,7 +34,7 @@
#include <cstring>
-AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
+AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
@@ -102,9 +102,9 @@ void AUD_ChannelMapperFactory::deleteMapping(int ic)
}
}
-AUD_IReader* AUD_ChannelMapperFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_ChannelMapperFactory::createReader() const
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
int ic = reader->getSpecs().channels;
return new AUD_ChannelMapperReader(reader,
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.h b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
index 9d622f5e322..25b3e091d8d 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.h
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
@@ -51,7 +51,7 @@ private:
AUD_ChannelMapperFactory& operator=(const AUD_ChannelMapperFactory&);
public:
- AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_ChannelMapperFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
virtual ~AUD_ChannelMapperFactory();
@@ -67,7 +67,7 @@ public:
*/
void deleteMapping(int ic);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_CHANNELMAPPERFACTORY
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
index dec70aaecf6..3079d31c9e9 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
@@ -31,7 +31,7 @@
#include "AUD_ChannelMapperReader.h"
-AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
+AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader,
float **mapping) :
AUD_EffectReader(reader)
{
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.h b/intern/audaspace/intern/AUD_ChannelMapperReader.h
index 091ed06db15..1c7dba1df7c 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.h
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.h
@@ -72,7 +72,7 @@ public:
* \param reader The reader to map.
* \param mapping The mapping specification as two dimensional float array.
*/
- AUD_ChannelMapperReader(AUD_IReader* reader, float **mapping);
+ AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader, float **mapping);
/**
* Destroys the reader.
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.cpp b/intern/audaspace/intern/AUD_ConverterFactory.cpp
index cce0f273616..78602d2cfa9 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.cpp
+++ b/intern/audaspace/intern/AUD_ConverterFactory.cpp
@@ -32,15 +32,15 @@
#include "AUD_ConverterFactory.h"
#include "AUD_ConverterReader.h"
-AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
+AUD_ConverterFactory::AUD_ConverterFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
}
-AUD_IReader* AUD_ConverterFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_ConverterFactory::createReader() const
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
if(m_specs.format != AUD_FORMAT_FLOAT32)
reader = new AUD_ConverterReader(reader, m_specs);
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.h b/intern/audaspace/intern/AUD_ConverterFactory.h
index b9eac94de40..cc1fedb2a10 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.h
+++ b/intern/audaspace/intern/AUD_ConverterFactory.h
@@ -46,9 +46,9 @@ private:
AUD_ConverterFactory& operator=(const AUD_ConverterFactory&);
public:
- AUD_ConverterFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_ConverterFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_CONVERTERFACTORY
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.cpp b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
index d3cc9fa8202..8f2ac21acd6 100644
--- a/intern/audaspace/intern/AUD_ConverterFunctions.cpp
+++ b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
@@ -45,13 +45,13 @@
void AUD_convert_u8_s16(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
}
void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length)
{
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
{
target[i*3] = source[i] - AUD_U8_0;
target[i*3+1] = 0;
@@ -61,7 +61,7 @@ void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length)
void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length)
{
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
{
target[i*3+2] = source[i] - AUD_U8_0;
target[i*3+1] = 0;
@@ -72,21 +72,21 @@ void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length)
void AUD_convert_u8_s32(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
}
void AUD_convert_u8_float(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
}
void AUD_convert_u8_double(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
}
@@ -100,10 +100,12 @@ void AUD_convert_s16_u8(data_t* target, data_t* source, int length)
void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
- for(int i = 0; i < length; i++)
+ int16_t t;
+ for(int i = length - 1; i >= 0; i++)
{
- target[i*3] = s[i] >> 8 & 0xFF;
- target[i*3+1] = s[i] & 0xFF;
+ t = s[i];
+ target[i*3] = t >> 8 & 0xFF;
+ target[i*3+1] = t & 0xFF;
target[i*3+2] = 0;
}
}
@@ -111,10 +113,12 @@ void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length)
void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
- for(int i = 0; i < length; i++)
+ int16_t t;
+ for(int i = length - 1; i >= 0; i++)
{
- target[i*3+2] = s[i] >> 8 & 0xFF;
- target[i*3+1] = s[i] & 0xFF;
+ t = s[i];
+ target[i*3+2] = t >> 8 & 0xFF;
+ target[i*3+1] = t & 0xFF;
target[i*3] = 0;
}
}
@@ -123,7 +127,7 @@ void AUD_convert_s16_s32(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
int32_t* t = (int32_t*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = ((int32_t)s[i]) << 16;
}
@@ -131,7 +135,7 @@ void AUD_convert_s16_float(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
float* t = (float*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = s[i] / AUD_S16_FLT;
}
@@ -139,7 +143,7 @@ void AUD_convert_s16_double(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
double* t = (double*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = s[i] / AUD_S16_FLT;
}
@@ -177,14 +181,14 @@ void AUD_convert_s24_s24(data_t* target, data_t* source, int length)
void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
}
void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
}
@@ -192,7 +196,7 @@ void AUD_convert_s24_float_be(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
int32_t s;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
{
s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
t[i] = s / AUD_S32_FLT;
@@ -203,7 +207,7 @@ void AUD_convert_s24_float_le(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
int32_t s;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
{
s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
t[i] = s / AUD_S32_FLT;
@@ -214,7 +218,7 @@ void AUD_convert_s24_double_be(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
int32_t s;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
{
s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
t[i] = s / AUD_S32_FLT;
@@ -225,7 +229,7 @@ void AUD_convert_s24_double_le(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
int32_t s;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
{
s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
t[i] = s / AUD_S32_FLT;
@@ -250,22 +254,26 @@ void AUD_convert_s32_s16(data_t* target, data_t* source, int length)
void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
+ int32_t t;
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;
+ t = s[i];
+ target[i*3] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3+2] = t >> 8 & 0xFF;
}
}
void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length)
{
- int16_t* s = (int16_t*) source;
+ int32_t* s = (int32_t*) source;
+ int32_t t;
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;
+ t = s[i];
+ target[i*3+2] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3] = t >> 8 & 0xFF;
}
}
@@ -281,7 +289,7 @@ void AUD_convert_s32_double(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
double* t = (double*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = s[i] / AUD_S32_FLT;
}
@@ -371,7 +379,7 @@ void AUD_convert_float_double(data_t* target, data_t* source, int length)
{
float* s = (float*) source;
double* t = (double*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = s[i];
}
diff --git a/intern/audaspace/intern/AUD_ConverterReader.cpp b/intern/audaspace/intern/AUD_ConverterReader.cpp
index 70297b8f5e8..6927f3e969c 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.cpp
+++ b/intern/audaspace/intern/AUD_ConverterReader.cpp
@@ -31,7 +31,7 @@
#include "AUD_ConverterReader.h"
-AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader,
+AUD_ConverterReader::AUD_ConverterReader(AUD_Reference<AUD_IReader> reader,
AUD_DeviceSpecs specs) :
AUD_EffectReader(reader)
{
diff --git a/intern/audaspace/intern/AUD_ConverterReader.h b/intern/audaspace/intern/AUD_ConverterReader.h
index a7a425adc54..6f252b5f9f9 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.h
+++ b/intern/audaspace/intern/AUD_ConverterReader.h
@@ -67,7 +67,7 @@ public:
* \param reader The reader to convert.
* \param specs The target specification.
*/
- AUD_ConverterReader(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_ConverterReader(AUD_Reference<AUD_IReader> reader, AUD_DeviceSpecs specs);
virtual AUD_Specs getSpecs() const;
virtual void read(int & length, sample_t* & buffer);
diff --git a/intern/audaspace/intern/AUD_DefaultMixer.cpp b/intern/audaspace/intern/AUD_DefaultMixer.cpp
index 20471d6e874..24fea6527ba 100644
--- a/intern/audaspace/intern/AUD_DefaultMixer.cpp
+++ b/intern/audaspace/intern/AUD_DefaultMixer.cpp
@@ -45,7 +45,7 @@ AUD_DefaultMixer::AUD_DefaultMixer(AUD_DeviceSpecs specs) :
{
}
-AUD_IReader* AUD_DefaultMixer::prepare(AUD_IReader* reader)
+AUD_Reference<AUD_IReader> AUD_DefaultMixer::prepare(AUD_Reference<AUD_IReader> reader)
{
// hacky for now, until a better channel mapper reader is available
AUD_ChannelMapperFactory cmf(NULL, m_specs);
diff --git a/intern/audaspace/intern/AUD_DefaultMixer.h b/intern/audaspace/intern/AUD_DefaultMixer.h
index a347141b5e0..2600a6fc05d 100644
--- a/intern/audaspace/intern/AUD_DefaultMixer.h
+++ b/intern/audaspace/intern/AUD_DefaultMixer.h
@@ -53,7 +53,7 @@ public:
* \param reader The reader to prepare.
* \return The reader that should be used for playback.
*/
- virtual AUD_IReader* prepare(AUD_IReader* reader);
+ virtual AUD_Reference<AUD_IReader> prepare(AUD_Reference<AUD_IReader> reader);
};
#endif //AUD_DEFAULTMIXER
diff --git a/intern/audaspace/intern/AUD_FileFactory.cpp b/intern/audaspace/intern/AUD_FileFactory.cpp
index 1c8bb03bc92..2f02d4a55e1 100644
--- a/intern/audaspace/intern/AUD_FileFactory.cpp
+++ b/intern/audaspace/intern/AUD_FileFactory.cpp
@@ -54,20 +54,20 @@ AUD_FileFactory::AUD_FileFactory(std::string filename) :
AUD_FileFactory::AUD_FileFactory(const data_t* buffer, int size) :
m_buffer(new AUD_Buffer(size))
{
- memcpy(m_buffer.get()->getBuffer(), buffer, size);
+ memcpy(m_buffer->getBuffer(), buffer, size);
}
static const char* read_error = "AUD_FileFactory: File couldn't be read.";
-AUD_IReader* AUD_FileFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_FileFactory::createReader() const
{
#ifdef WITH_SNDFILE
try
{
- if(m_buffer.get())
- return new AUD_SndFileReader(m_buffer);
- else
+ if(m_buffer.isNull())
return new AUD_SndFileReader(m_filename);
+ else
+ return new AUD_SndFileReader(m_buffer);
}
catch(AUD_Exception&) {}
#endif
@@ -75,10 +75,10 @@ AUD_IReader* AUD_FileFactory::createReader() const
#ifdef WITH_FFMPEG
try
{
- if(m_buffer.get())
- return new AUD_FFMPEGReader(m_buffer);
- else
+ if(m_buffer.isNull())
return new AUD_FFMPEGReader(m_filename);
+ else
+ return new AUD_FFMPEGReader(m_buffer);
}
catch(AUD_Exception&) {}
#endif
diff --git a/intern/audaspace/intern/AUD_FileFactory.h b/intern/audaspace/intern/AUD_FileFactory.h
index a2ab94ae148..c63e50b3b0d 100644
--- a/intern/audaspace/intern/AUD_FileFactory.h
+++ b/intern/audaspace/intern/AUD_FileFactory.h
@@ -72,7 +72,7 @@ public:
*/
AUD_FileFactory(const data_t* buffer, int size);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_FILEFACTORY
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
index 4856b913b38..88c9aa5e8d9 100644
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ b/intern/audaspace/intern/AUD_IDevice.h
@@ -33,6 +33,7 @@
#define AUD_IDEVICE
#include "AUD_Space.h"
+#include "AUD_Reference.h"
class AUD_IFactory;
class AUD_IReader;
@@ -74,7 +75,7 @@ public:
* \exception AUD_Exception Thrown if there's an unexpected (from the
* device side) error during creation of the reader.
*/
- virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false)=0;
+ virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false)=0;
/**
* Plays a sound source.
@@ -86,7 +87,7 @@ public:
* \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;
+ virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false)=0;
/**
* Pauses a played back sound.
diff --git a/intern/audaspace/intern/AUD_IFactory.h b/intern/audaspace/intern/AUD_IFactory.h
index 40a61279a55..48f2802f871 100644
--- a/intern/audaspace/intern/AUD_IFactory.h
+++ b/intern/audaspace/intern/AUD_IFactory.h
@@ -33,6 +33,7 @@
#define AUD_IFACTORY
#include "AUD_Space.h"
+#include "AUD_Reference.h"
class AUD_IReader;
/**
@@ -55,7 +56,7 @@ public:
* \exception AUD_Exception An exception may be thrown if there has been
* a more unexpected error during reader creation.
*/
- virtual AUD_IReader* createReader() const=0;
+ virtual AUD_Reference<AUD_IReader> createReader() const=0;
};
#endif //AUD_IFACTORY
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
index a90dc5cb860..f7ac9e1e83e 100644
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
@@ -32,15 +32,15 @@
#include "AUD_LinearResampleFactory.h"
#include "AUD_LinearResampleReader.h"
-AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IFactory* factory,
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_ResampleFactory(factory, specs)
{
}
-AUD_IReader* AUD_LinearResampleFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LinearResampleFactory::createReader() const
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
if(reader->getSpecs().rate != m_specs.rate)
reader = new AUD_LinearResampleReader(reader, m_specs.specs);
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.h b/intern/audaspace/intern/AUD_LinearResampleFactory.h
index 678aa0b80cb..6a593b11f28 100644
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.h
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.h
@@ -45,9 +45,9 @@ private:
AUD_LinearResampleFactory& operator=(const AUD_LinearResampleFactory&);
public:
- AUD_LinearResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_LinearResampleFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_LINEARRESAMPLEFACTORY
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
index 05fb39b2cca..6217826eeec 100644
--- a/intern/audaspace/intern/AUD_LinearResampleReader.cpp
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
@@ -36,7 +36,7 @@
#define CC channels + channel
-AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_IReader* reader,
+AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_Reference<AUD_IReader> reader,
AUD_Specs specs) :
AUD_EffectReader(reader),
m_sspecs(reader->getSpecs()),
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.h b/intern/audaspace/intern/AUD_LinearResampleReader.h
index 419c96be2fa..fdf7858f97f 100644
--- a/intern/audaspace/intern/AUD_LinearResampleReader.h
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.h
@@ -86,7 +86,7 @@ public:
* \param reader The reader to mix.
* \param specs The target specification.
*/
- AUD_LinearResampleReader(AUD_IReader* reader, AUD_Specs specs);
+ AUD_LinearResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs);
virtual void seek(int position);
virtual int getLength() const;
diff --git a/intern/audaspace/intern/AUD_Mixer.h b/intern/audaspace/intern/AUD_Mixer.h
index 277d5bfe2bd..d8c4dde2685 100644
--- a/intern/audaspace/intern/AUD_Mixer.h
+++ b/intern/audaspace/intern/AUD_Mixer.h
@@ -34,6 +34,7 @@
#include "AUD_ConverterFunctions.h"
#include "AUD_Buffer.h"
+#include "AUD_Reference.h"
class AUD_IReader;
#include <list>
@@ -94,7 +95,7 @@ public:
* \param reader The reader to prepare.
* \return The reader that should be used for playback.
*/
- virtual AUD_IReader* prepare(AUD_IReader* reader)=0;
+ virtual AUD_Reference<AUD_IReader> prepare(AUD_Reference<AUD_IReader> reader)=0;
/**
* Adds a buffer for superposition.
diff --git a/intern/audaspace/intern/AUD_MixerFactory.cpp b/intern/audaspace/intern/AUD_MixerFactory.cpp
index e65b149b94c..c3bf6b4fa99 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.cpp
+++ b/intern/audaspace/intern/AUD_MixerFactory.cpp
@@ -32,12 +32,12 @@
#include "AUD_MixerFactory.h"
#include "AUD_IReader.h"
-AUD_IReader* AUD_MixerFactory::getReader() const
+AUD_Reference<AUD_IReader> AUD_MixerFactory::getReader() const
{
return m_factory->createReader();
}
-AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
+AUD_MixerFactory::AUD_MixerFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
m_specs(specs), m_factory(factory)
{
@@ -48,7 +48,7 @@ AUD_DeviceSpecs AUD_MixerFactory::getSpecs() const
return m_specs;
}
-AUD_IFactory* AUD_MixerFactory::getFactory() const
+AUD_Reference<AUD_IFactory> AUD_MixerFactory::getFactory() const
{
return m_factory;
}
diff --git a/intern/audaspace/intern/AUD_MixerFactory.h b/intern/audaspace/intern/AUD_MixerFactory.h
index 2adabbd13ca..27c703b1898 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.h
+++ b/intern/audaspace/intern/AUD_MixerFactory.h
@@ -48,7 +48,7 @@ protected:
/**
* If there is no reader it is created out of this factory.
*/
- AUD_IFactory* m_factory;
+ AUD_Reference<AUD_IFactory> m_factory;
/**
* Returns the reader created out of the factory.
@@ -56,7 +56,7 @@ protected:
* classes.
* \return The reader to mix.
*/
- AUD_IReader* getReader() const;
+ AUD_Reference<AUD_IReader> getReader() const;
public:
/**
@@ -64,7 +64,7 @@ public:
* \param factory The factory to create the readers to mix out of.
* \param specs The target specification.
*/
- AUD_MixerFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_MixerFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
/**
* Returns the target specification for resampling.
@@ -75,7 +75,7 @@ public:
* Returns the saved factory.
* \return The factory.
*/
- AUD_IFactory* getFactory() const;
+ AUD_Reference<AUD_IFactory> getFactory() const;
};
#endif //AUD_MIXERFACTORY
diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
index ab824799d88..09fc4835978 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ b/intern/audaspace/intern/AUD_NULLDevice.cpp
@@ -48,12 +48,12 @@ AUD_DeviceSpecs AUD_NULLDevice::getSpecs() const
return specs;
}
-AUD_Handle* AUD_NULLDevice::play(AUD_IReader* reader, bool keep)
+AUD_Handle* AUD_NULLDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
return 0;
}
-AUD_Handle* AUD_NULLDevice::play(AUD_IFactory* factory, bool keep)
+AUD_Handle* AUD_NULLDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
return 0;
}
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
index f700bea477b..6a10267bbe0 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ b/intern/audaspace/intern/AUD_NULLDevice.h
@@ -32,6 +32,7 @@
#ifndef AUD_NULLDEVICE
#define AUD_NULLDEVICE
+#include "AUD_IReader.h"
#include "AUD_IDevice.h"
/**
@@ -46,8 +47,8 @@ public:
AUD_NULLDevice();
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false);
- virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
+ virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+ virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
virtual bool stop(AUD_Handle* handle);
diff --git a/intern/audaspace/intern/AUD_Reference.h b/intern/audaspace/intern/AUD_Reference.h
index 3232ca3b609..22abb29bdbb 100644
--- a/intern/audaspace/intern/AUD_Reference.h
+++ b/intern/audaspace/intern/AUD_Reference.h
@@ -75,10 +75,7 @@ public:
(*m_refcount)--;
if(*m_refcount == 0)
{
- if(m_reference)
- {
- delete m_reference;
- }
+ delete m_reference;
delete m_refcount;
}
}
@@ -95,10 +92,7 @@ public:
(*m_refcount)--;
if(*m_refcount == 0)
{
- if(m_reference)
- {
- delete m_reference;
- }
+ delete m_reference;
delete m_refcount;
}
@@ -110,12 +104,70 @@ public:
}
/**
+ * Returns whether the reference is NULL.
+ */
+ bool isNull() const
+ {
+ return m_reference == 0;
+ }
+
+ /**
* Returns the reference.
*/
T* get() const
{
return m_reference;
}
+
+ /**
+ * Returns the reference.
+ */
+ T& operator*() const
+ {
+ return *m_reference;
+ }
+
+ /**
+ * Returns the reference.
+ */
+ T* operator->() const
+ {
+ return m_reference;
+ }
+
+ template <class U>
+ explicit AUD_Reference(U* reference, int* refcount)
+ {
+ m_reference = dynamic_cast<T*>(reference);
+ if(m_reference)
+ {
+ m_refcount = refcount;
+ (*m_refcount)++;
+ }
+ else
+ {
+ m_refcount = new int;
+ *m_refcount = 1;
+ }
+ }
+
+ template <class U>
+ AUD_Reference<U> convert()
+ {
+ return AUD_Reference<U>(m_reference, m_refcount);
+ }
};
+template<class T, class U>
+bool operator==(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
+{
+ return a.get() == b.get();
+}
+
+template<class T, class U>
+bool operator!=(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
+{
+ return a.get() == b.get();
+}
+
#endif // AUD_REFERENCE
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.cpp b/intern/audaspace/intern/AUD_SequencerFactory.cpp
index f49dd94fe11..ee0af900b04 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.cpp
+++ b/intern/audaspace/intern/AUD_SequencerFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_SequencerFactory.h"
#include "AUD_SequencerReader.h"
-typedef std::list<AUD_SequencerReader*>::iterator AUD_ReaderIterator;
+typedef std::list<AUD_Reference<AUD_SequencerReader> >::iterator AUD_ReaderIterator;
AUD_SequencerFactory::AUD_SequencerFactory(AUD_Specs specs, bool muted,
void* data,
@@ -46,22 +46,11 @@ AUD_SequencerFactory::AUD_SequencerFactory(AUD_Specs specs, bool muted,
AUD_SequencerFactory::~AUD_SequencerFactory()
{
- AUD_SequencerReader* reader;
- AUD_SequencerEntry* entry;
-
- while(!m_readers.empty())
- {
- reader = m_readers.front();
- m_readers.pop_front();
- reader->destroy();
- }
-
- while(!m_entries.empty())
- {
- entry = m_entries.front();
- m_entries.pop_front();
- delete entry;
- }
+}
+
+void AUD_SequencerFactory::setThis(AUD_Reference<AUD_SequencerFactory>* self)
+{
+ m_this = self;
}
void AUD_SequencerFactory::mute(bool muted)
@@ -74,19 +63,19 @@ bool AUD_SequencerFactory::getMute() const
return m_muted;
}
-AUD_IReader* AUD_SequencerFactory::newReader()
+AUD_Reference<AUD_IReader> AUD_SequencerFactory::newReader()
{
- AUD_SequencerReader* reader = new AUD_SequencerReader(this, m_entries,
+ AUD_Reference<AUD_SequencerReader> reader = new AUD_SequencerReader(*m_this, m_entries,
m_specs, m_data,
m_volume);
m_readers.push_front(reader);
- return reader;
+ return reader.convert<AUD_IReader>();
}
-AUD_SequencerEntry* AUD_SequencerFactory::add(AUD_IFactory** sound, float begin, float end, float skip, void* data)
+AUD_Reference<AUD_SequencerEntry> AUD_SequencerFactory::add(AUD_Reference<AUD_IFactory>** sound, float begin, float end, float skip, void* data)
{
- AUD_SequencerEntry* entry = new AUD_SequencerEntry;
+ AUD_Reference<AUD_SequencerEntry> entry = new AUD_SequencerEntry;
entry->sound = sound;
entry->begin = begin;
entry->skip = skip;
@@ -102,34 +91,32 @@ AUD_SequencerEntry* AUD_SequencerFactory::add(AUD_IFactory** sound, float begin,
return entry;
}
-void AUD_SequencerFactory::remove(AUD_SequencerEntry* entry)
+void AUD_SequencerFactory::remove(AUD_Reference<AUD_SequencerEntry> entry)
{
for(AUD_ReaderIterator i = m_readers.begin(); i != m_readers.end(); i++)
(*i)->remove(entry);
m_entries.remove(entry);
-
- delete entry;
}
-void AUD_SequencerFactory::move(AUD_SequencerEntry* entry, float begin, float end, float skip)
+void AUD_SequencerFactory::move(AUD_Reference<AUD_SequencerEntry> entry, float begin, float end, float skip)
{
entry->begin = begin;
entry->skip = skip;
entry->end = end;
}
-void AUD_SequencerFactory::mute(AUD_SequencerEntry* entry, bool mute)
+void AUD_SequencerFactory::mute(AUD_Reference<AUD_SequencerEntry> entry, bool mute)
{
entry->muted = mute;
}
-AUD_IReader* AUD_SequencerFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SequencerFactory::createReader() const
{
return const_cast<AUD_SequencerFactory*>(this)->newReader();
}
-void AUD_SequencerFactory::removeReader(AUD_SequencerReader* reader)
+void AUD_SequencerFactory::removeReader(AUD_Reference<AUD_SequencerReader> reader)
{
m_readers.remove(reader);
}
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.h b/intern/audaspace/intern/AUD_SequencerFactory.h
index 8f3466f75ce..b0393297622 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.h
+++ b/intern/audaspace/intern/AUD_SequencerFactory.h
@@ -40,7 +40,7 @@ typedef float (*AUD_volumeFunction)(void*, void*, float);
struct AUD_SequencerEntry
{
- AUD_IFactory** sound;
+ AUD_Reference<AUD_IFactory>** sound;
float begin;
float end;
float skip;
@@ -61,13 +61,14 @@ private:
*/
AUD_Specs m_specs;
- std::list<AUD_SequencerEntry*> m_entries;
- std::list<AUD_SequencerReader*> m_readers;
+ std::list<AUD_Reference<AUD_SequencerEntry> > m_entries;
+ std::list<AUD_Reference<AUD_SequencerReader> > m_readers;
bool m_muted;
void* m_data;
AUD_volumeFunction m_volume;
+ AUD_Reference<AUD_SequencerFactory>* m_this;
- AUD_IReader* newReader();
+ AUD_Reference<AUD_IReader> newReader();
// hide copy constructor and operator=
AUD_SequencerFactory(const AUD_SequencerFactory&);
@@ -77,16 +78,18 @@ public:
AUD_SequencerFactory(AUD_Specs specs, bool muted, void* data, AUD_volumeFunction volume);
~AUD_SequencerFactory();
+ void setThis(AUD_Reference<AUD_SequencerFactory>* self);
+
void mute(bool muted);
bool getMute() const;
- AUD_SequencerEntry* add(AUD_IFactory** sound, float begin, float end, float skip, void* data);
- void remove(AUD_SequencerEntry* entry);
- void move(AUD_SequencerEntry* entry, float begin, float end, float skip);
- void mute(AUD_SequencerEntry* entry, bool mute);
+ AUD_Reference<AUD_SequencerEntry> add(AUD_Reference<AUD_IFactory>** sound, float begin, float end, float skip, void* data);
+ void remove(AUD_Reference<AUD_SequencerEntry> entry);
+ void move(AUD_Reference<AUD_SequencerEntry> entry, float begin, float end, float skip);
+ void mute(AUD_Reference<AUD_SequencerEntry> entry, bool mute);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
- void removeReader(AUD_SequencerReader* reader);
+ void removeReader(AUD_Reference<AUD_SequencerReader> reader);
};
#endif //AUD_SEQUENCERFACTORY
diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp
index 95e0dca6323..b7cbdda544e 100644
--- a/intern/audaspace/intern/AUD_SequencerReader.cpp
+++ b/intern/audaspace/intern/AUD_SequencerReader.cpp
@@ -34,23 +34,21 @@
#include <math.h>
-typedef std::list<AUD_SequencerStrip*>::iterator AUD_StripIterator;
-typedef std::list<AUD_SequencerEntry*>::iterator AUD_EntryIterator;
+typedef std::list<AUD_Reference<AUD_SequencerStrip> >::iterator AUD_StripIterator;
+typedef std::list<AUD_Reference<AUD_SequencerEntry> >::iterator AUD_EntryIterator;
-AUD_SequencerReader::AUD_SequencerReader(AUD_SequencerFactory* factory,
- std::list<AUD_SequencerEntry*> &entries, AUD_Specs specs,
- void* data, AUD_volumeFunction volume)
+AUD_SequencerReader::AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory,
+ std::list<AUD_Reference<AUD_SequencerEntry> > &entries, AUD_Specs specs,
+ void* data, AUD_volumeFunction volume) :
+ m_position(0), m_factory(factory), m_data(data), m_volume(volume)
{
AUD_DeviceSpecs dspecs;
dspecs.specs = specs;
dspecs.format = AUD_FORMAT_FLOAT32;
m_mixer = new AUD_DefaultMixer(dspecs);
- m_factory = factory;
- m_data = data;
- m_volume = volume;
- AUD_SequencerStrip* strip;
+ AUD_Reference<AUD_SequencerStrip> strip;
for(AUD_EntryIterator i = entries.begin(); i != entries.end(); i++)
{
@@ -58,84 +56,33 @@ AUD_SequencerReader::AUD_SequencerReader(AUD_SequencerFactory* factory,
strip->entry = *i;
strip->old_sound = NULL;
- if(strip->old_sound)
- strip->reader = m_mixer->prepare(strip->old_sound->createReader());
- else
- strip->reader = NULL;
-
m_strips.push_front(strip);
}
-
- m_position = 0;
}
AUD_SequencerReader::~AUD_SequencerReader()
{
- if(m_factory != NULL)
- m_factory->removeReader(this);
-
- AUD_SequencerStrip* strip;
-
- while(!m_strips.empty())
- {
- strip = m_strips.front();
- m_strips.pop_front();
- if(strip->reader)
- {
- delete strip->reader;
- }
- delete strip;
- }
-
- delete m_mixer;
-}
-
-void AUD_SequencerReader::destroy()
-{
- m_factory = NULL;
- AUD_SequencerStrip* strip;
-
- while(!m_strips.empty())
- {
- strip = m_strips.front();
- m_strips.pop_front();
- delete strip;
- }
+ m_factory->removeReader(this);
}
-void AUD_SequencerReader::add(AUD_SequencerEntry* entry)
+void AUD_SequencerReader::add(AUD_Reference<AUD_SequencerEntry> entry)
{
- AUD_SequencerStrip* strip = new AUD_SequencerStrip;
+ AUD_Reference<AUD_SequencerStrip> strip = new AUD_SequencerStrip;
strip->entry = entry;
- if(*strip->entry->sound)
- {
- strip->old_sound = *strip->entry->sound;
- strip->reader = m_mixer->prepare(strip->old_sound->createReader());
- }
- else
- {
- strip->reader = NULL;
- strip->old_sound = NULL;
- }
m_strips.push_front(strip);
}
-void AUD_SequencerReader::remove(AUD_SequencerEntry* entry)
+void AUD_SequencerReader::remove(AUD_Reference<AUD_SequencerEntry> entry)
{
- AUD_SequencerStrip* strip;
+ AUD_Reference<AUD_SequencerStrip> strip;
for(AUD_StripIterator i = m_strips.begin(); i != m_strips.end(); i++)
{
strip = *i;
if(strip->entry == entry)
{
i++;
- if(strip->reader)
- {
- delete strip->reader;
- }
m_strips.remove(strip);
- delete strip;
return;
}
}
@@ -175,7 +122,7 @@ void AUD_SequencerReader::read(int & length, sample_t* & buffer)
int size = length * samplesize;
int start, end, current, skip, len;
- AUD_SequencerStrip* strip;
+ AUD_Reference<AUD_SequencerStrip> strip;
sample_t* buf;
if(m_buffer.getSize() < size)
@@ -192,14 +139,12 @@ void AUD_SequencerReader::read(int & length, sample_t* & buffer)
if(strip->old_sound != *strip->entry->sound)
{
strip->old_sound = *strip->entry->sound;
- if(strip->reader)
- delete strip->reader;
if(strip->old_sound)
{
try
{
- strip->reader = m_mixer->prepare(strip->old_sound->createReader());
+ strip->reader = m_mixer->prepare((*strip->old_sound)->createReader());
}
catch(AUD_Exception)
{
@@ -210,7 +155,7 @@ void AUD_SequencerReader::read(int & length, sample_t* & buffer)
strip->reader = NULL;
}
- if(strip->reader)
+ if(!strip->reader.isNull())
{
end = floor(strip->entry->end * rate);
if(m_position < end)
diff --git a/intern/audaspace/intern/AUD_SequencerReader.h b/intern/audaspace/intern/AUD_SequencerReader.h
index 53baf521acc..2efb94aa1fb 100644
--- a/intern/audaspace/intern/AUD_SequencerReader.h
+++ b/intern/audaspace/intern/AUD_SequencerReader.h
@@ -39,9 +39,9 @@ class AUD_Mixer;
struct AUD_SequencerStrip
{
- AUD_IFactory* old_sound;
- AUD_IReader* reader;
- AUD_SequencerEntry* entry;
+ AUD_Reference<AUD_IReader> reader;
+ AUD_Reference<AUD_SequencerEntry> entry;
+ AUD_Reference<AUD_IFactory>* old_sound;
};
/**
@@ -63,14 +63,14 @@ private:
/**
* The target specification.
*/
- AUD_Mixer* m_mixer;
+ AUD_Reference<AUD_Mixer> m_mixer;
/**
* Saves the SequencerFactory the reader belongs to.
*/
- AUD_SequencerFactory* m_factory;
+ AUD_Reference<AUD_SequencerFactory> m_factory;
- std::list<AUD_SequencerStrip*> m_strips;
+ std::list<AUD_Reference<AUD_SequencerStrip> > m_strips;
void* m_data;
AUD_volumeFunction m_volume;
@@ -85,17 +85,15 @@ public:
* \param reader The reader to mix.
* \param specs The target specification.
*/
- AUD_SequencerReader(AUD_SequencerFactory* factory, std::list<AUD_SequencerEntry*> &entries, const AUD_Specs specs, void* data, AUD_volumeFunction volume);
+ AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory, std::list<AUD_Reference<AUD_SequencerEntry> > &entries, const AUD_Specs specs, void* data, AUD_volumeFunction volume);
/**
* Destroys the reader.
*/
~AUD_SequencerReader();
- void destroy();
-
- void add(AUD_SequencerEntry* entry);
- void remove(AUD_SequencerEntry* entry);
+ void add(AUD_Reference<AUD_SequencerEntry> entry);
+ void remove(AUD_Reference<AUD_SequencerEntry> entry);
virtual bool isSeekable() const;
virtual void seek(int position);
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.cpp b/intern/audaspace/intern/AUD_SilenceFactory.cpp
index dc3f0626591..f1eae1889a2 100644
--- a/intern/audaspace/intern/AUD_SilenceFactory.cpp
+++ b/intern/audaspace/intern/AUD_SilenceFactory.cpp
@@ -37,7 +37,7 @@ AUD_SilenceFactory::AUD_SilenceFactory()
{
}
-AUD_IReader* AUD_SilenceFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SilenceFactory::createReader() const
{
return new AUD_SilenceReader();
}
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.h b/intern/audaspace/intern/AUD_SilenceFactory.h
index fb6afc34189..0920c1267ab 100644
--- a/intern/audaspace/intern/AUD_SilenceFactory.h
+++ b/intern/audaspace/intern/AUD_SilenceFactory.h
@@ -50,7 +50,7 @@ public:
*/
AUD_SilenceFactory();
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_SILENCEFACTORY
diff --git a/intern/audaspace/intern/AUD_SinusFactory.cpp b/intern/audaspace/intern/AUD_SinusFactory.cpp
index 9ea7a031b16..8276856b9e2 100644
--- a/intern/audaspace/intern/AUD_SinusFactory.cpp
+++ b/intern/audaspace/intern/AUD_SinusFactory.cpp
@@ -44,7 +44,7 @@ float AUD_SinusFactory::getFrequency() const
return m_frequency;
}
-AUD_IReader* AUD_SinusFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SinusFactory::createReader() const
{
return new AUD_SinusReader(m_frequency, m_sampleRate);
}
diff --git a/intern/audaspace/intern/AUD_SinusFactory.h b/intern/audaspace/intern/AUD_SinusFactory.h
index 6d8b355784b..a440d7b7535 100644
--- a/intern/audaspace/intern/AUD_SinusFactory.h
+++ b/intern/audaspace/intern/AUD_SinusFactory.h
@@ -68,7 +68,7 @@ public:
*/
float getFrequency() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_SINUSFACTORY
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index b44b2f02d29..82bb5841580 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -41,7 +41,7 @@
struct AUD_SoftwareHandle : AUD_Handle
{
/// The reader source.
- AUD_IReader* reader;
+ AUD_Reference<AUD_IReader> reader;
/// Whether to keep the source if end of it is reached.
bool keep;
@@ -81,8 +81,6 @@ void AUD_SoftwareDevice::destroy()
if(m_playback)
playing(m_playback = false);
- delete m_mixer;
-
AUD_SoftwareHandle* handle;
// delete all playing sounds
@@ -90,7 +88,6 @@ void AUD_SoftwareDevice::destroy()
{
handle = m_playingSounds.front();
m_playingSounds.pop_front();
- delete handle->reader;
delete handle;
}
@@ -99,7 +96,6 @@ void AUD_SoftwareDevice::destroy()
{
handle = m_pausedSounds.front();
m_pausedSounds.pop_front();
- delete handle->reader;
delete handle;
}
@@ -213,11 +209,11 @@ AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const
return m_specs;
}
-AUD_Handle* AUD_SoftwareDevice::play(AUD_IReader* reader, bool keep)
+AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
// prepare the reader
reader = m_mixer->prepare(reader);
- if(reader == NULL)
+ if(reader.isNull())
return NULL;
// play sound
@@ -239,7 +235,7 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_IReader* reader, bool keep)
return sound;
}
-AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep)
+AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
return play(factory->createReader(), keep);
}
@@ -307,7 +303,6 @@ bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
{
if(*i == handle)
{
- delete (*i)->reader;
delete *i;
m_playingSounds.erase(i);
if(m_playingSounds.empty())
@@ -323,7 +318,6 @@ bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
{
if(*i == handle)
{
- delete (*i)->reader;
delete *i;
m_pausedSounds.erase(i);
result = true;
@@ -376,7 +370,7 @@ bool AUD_SoftwareDevice::seek(AUD_Handle* handle, float position)
if(isValid(handle))
{
- AUD_IReader* reader = ((AUD_SoftwareHandle*)handle)->reader;
+ AUD_Reference<AUD_IReader> reader = ((AUD_SoftwareHandle*)handle)->reader;
reader->seek((int)(position * reader->getSpecs().rate));
result = true;
}
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h
index 1f6a5ead6e0..6cbc6e3ddc6 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -33,8 +33,8 @@
#define AUD_SOFTWAREDEVICE
#include "AUD_IDevice.h"
+#include "AUD_Mixer.h"
struct AUD_SoftwareHandle;
-class AUD_Mixer;
class AUD_Buffer;
#include <list>
@@ -59,7 +59,7 @@ protected:
/**
* The mixer.
*/
- AUD_Mixer* m_mixer;
+ AUD_Reference<AUD_Mixer> m_mixer;
/**
* Initializes member variables.
@@ -119,8 +119,8 @@ private:
public:
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false);
- virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
+ virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+ virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
virtual bool stop(AUD_Handle* handle);
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
index c25442b6f26..5c4e024917b 100644
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
@@ -35,10 +35,10 @@
#include <cstring>
-AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory) :
+AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_Reference<AUD_IFactory> factory) :
m_buffer(new AUD_Buffer())
{
- AUD_IReader* reader = factory->createReader();
+ AUD_Reference<AUD_IReader> reader = factory->createReader();
m_specs = reader->getSpecs();
@@ -56,26 +56,25 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory) :
size += m_specs.rate;
// as long as we fill our buffer to the end
- while(index == m_buffer.get()->getSize() / sample_size)
+ while(index == m_buffer->getSize() / sample_size)
{
// increase
- m_buffer.get()->resize(size*sample_size, true);
+ m_buffer->resize(size*sample_size, true);
// read more
length = size-index;
reader->read(length, buffer);
- memcpy(m_buffer.get()->getBuffer() + index * m_specs.channels,
+ memcpy(m_buffer->getBuffer() + index * m_specs.channels,
buffer,
length * sample_size);
size += AUD_BUFFER_RESIZE_BYTES / sample_size;
index += length;
}
- m_buffer.get()->resize(index * sample_size, true);
- delete reader;
+ m_buffer->resize(index * sample_size, true);
}
-AUD_IReader* AUD_StreamBufferFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_StreamBufferFactory::createReader() const
{
return new AUD_BufferReader(m_buffer, m_specs);
}
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.h b/intern/audaspace/intern/AUD_StreamBufferFactory.h
index b6a44d95744..fc5f103d99b 100644
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.h
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.h
@@ -64,9 +64,9 @@ public:
* \param factory The factory that creates the reader for buffering.
* \exception AUD_Exception Thrown if the reader cannot be created.
*/
- AUD_StreamBufferFactory(AUD_IFactory* factory);
+ AUD_StreamBufferFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_STREAMBUFFERFACTORY
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
index 2d1d29e50f5..7ab3308f01b 100644
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
@@ -43,13 +43,13 @@ AUD_SndFileFactory::AUD_SndFileFactory(std::string filename) :
AUD_SndFileFactory::AUD_SndFileFactory(const data_t* buffer, int size) :
m_buffer(new AUD_Buffer(size))
{
- memcpy(m_buffer.get()->getBuffer(), buffer, size);
+ memcpy(m_buffer->getBuffer(), buffer, size);
}
-AUD_IReader* AUD_SndFileFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SndFileFactory::createReader() const
{
- if(m_buffer.get())
- return new AUD_SndFileReader(m_buffer);
- else
+ if(m_buffer.isNull())
return new AUD_SndFileReader(m_filename);
+ else
+ return new AUD_SndFileReader(m_buffer);
}
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.h b/intern/audaspace/sndfile/AUD_SndFileFactory.h
index 9c747e1df01..3a1037e5587 100644
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.h
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.h
@@ -72,7 +72,7 @@ public:
*/
AUD_SndFileFactory(const data_t* buffer, int size);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader() const;
};
#endif //AUD_SNDFILEFACTORY
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.cpp b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
index f226d2eee4d..7b5fd7b0f45 100644
--- a/intern/audaspace/sndfile/AUD_SndFileReader.cpp
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
@@ -36,7 +36,7 @@
sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
{
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
- return reader->m_membuffer.get()->getSize();
+ return reader->m_membuffer->getSize();
}
sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
@@ -53,7 +53,7 @@ sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
reader->m_memoffset = reader->m_memoffset + offset;
break;
case SEEK_END:
- reader->m_memoffset = reader->m_membuffer.get()->getSize() + offset;
+ reader->m_memoffset = reader->m_membuffer->getSize() + offset;
break;
}
@@ -65,10 +65,10 @@ sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count,
{
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;
+ if(reader->m_memoffset + count > reader->m_membuffer->getSize())
+ count = reader->m_membuffer->getSize() - reader->m_memoffset;
- memcpy(ptr, ((data_t*)reader->m_membuffer.get()->getBuffer()) +
+ memcpy(ptr, ((data_t*)reader->m_membuffer->getBuffer()) +
reader->m_memoffset, count);
reader->m_memoffset += count;
diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py
index 3c1b454e72e..c30c893c9cc 100644
--- a/release/scripts/modules/bpy_types.py
+++ b/release/scripts/modules/bpy_types.py
@@ -409,6 +409,16 @@ class Text(bpy_types.ID):
TypeMap = {}
+class Sound(bpy_types.ID):
+ __slots__ = ()
+
+ @property
+ def factory(self):
+ """The aud.Factory object of the sound."""
+ import aud
+ return aud._sound_from_pointer(self.as_pointer())
+
+
class RNAMeta(type):
def __new__(cls, name, bases, classdict, **args):
result = type.__new__(cls, name, bases, classdict)
diff --git a/release/scripts/modules/mocap_tools.py b/release/scripts/modules/mocap_tools.py
new file mode 100644
index 00000000000..739dc40b272
--- /dev/null
+++ b/release/scripts/modules/mocap_tools.py
@@ -0,0 +1,451 @@
+from math import hypot, sqrt, isfinite
+import bpy
+import time
+from mathutils import Vector
+
+#Vector utility functions
+class NdVector:
+ vec = []
+
+ def __init__(self,vec):
+ self.vec = vec[:]
+
+ def __len__(self):
+ return len(self.vec)
+
+ def __mul__(self,otherMember):
+ if type(otherMember)==type(1) or type(otherMember)==type(1.0):
+ return NdVector([otherMember*x for x in self.vec])
+ else:
+ a = self.vec
+ b = otherMember.vec
+ n = len(self)
+ return sum([a[i]*b[i] for i in range(n)])
+
+ def __sub__(self,otherVec):
+ a = self.vec
+ b = otherVec.vec
+ n = len(self)
+ return NdVector([a[i]-b[i] for i in range(n)])
+
+ def __add__(self,otherVec):
+ a = self.vec
+ b = otherVec.vec
+ n = len(self)
+ return NdVector([a[i]+b[i] for i in range(n)])
+
+ def vecLength(self):
+ return sqrt(self * self)
+
+ def vecLengthSq(self):
+ return (self * self)
+
+ def __getitem__(self,i):
+ return self.vec[i]
+
+ length = property(vecLength)
+ lengthSq = property(vecLengthSq)
+
+class dataPoint:
+ index = 0
+ co = Vector((0,0,0,0)) # x,y1,y2,y3 coordinate of original point
+ u = 0 #position according to parametric view of original data, [0,1] range
+ temp = 0 #use this for anything
+
+ def __init__(self,index,co,u=0):
+ self.index = index
+ self.co = co
+ self.u = u
+
+def autoloop_anim():
+ context = bpy.context
+ obj = context.active_object
+ fcurves = [x for x in obj.animation_data.action.fcurves if x.select]
+
+ data = []
+ end = len(fcurves[0].keyframe_points)
+
+ for i in range(1,end):
+ vec = []
+ for fcurve in fcurves:
+ vec.append(fcurve.evaluate(i))
+ data.append(NdVector(vec))
+
+ def comp(a,b):
+ return a*b
+
+ N = len(data)
+ Rxy = [0.0] * N
+ for i in range(N):
+ for j in range(i,min(i+N,N)):
+ Rxy[i]+=comp(data[j],data[j-i])
+ for j in range(i):
+ Rxy[i]+=comp(data[j],data[j-i+N])
+ Rxy[i]/=float(N)
+
+ def bestLocalMaximum(Rxy):
+ Rxyd = [Rxy[i]-Rxy[i-1] for i in range(1,len(Rxy))]
+ maxs = []
+ for i in range(1,len(Rxyd)-1):
+ a = Rxyd[i-1]
+ b = Rxyd[i]
+ print(a,b)
+ if (a>=0 and b<0) or (a<0 and b>=0): #sign change (zerocrossing) at point i, denoting max point (only)
+ maxs.append((i,max(Rxy[i],Rxy[i-1])))
+ return max(maxs,key=lambda x: x[1])[0]
+ flm = bestLocalMaximum(Rxy[0:int(len(Rxy))])
+
+ diff = []
+
+ for i in range(len(data)-flm):
+ diff.append((data[i]-data[i+flm]).lengthSq)
+
+ def lowerErrorSlice(diff,e):
+ bestSlice = (0,100000) #index, error at index
+ for i in range(e,len(diff)-e):
+ errorSlice = sum(diff[i-e:i+e+1])
+ if errorSlice<bestSlice[1]:
+ bestSlice = (i,errorSlice)
+ return bestSlice[0]
+
+ margin = 2
+
+ s = lowerErrorSlice(diff,margin)
+
+ print(flm,s)
+ loop = data[s:s+flm+margin]
+
+ #find *all* loops, s:s+flm, s+flm:s+2flm, etc... and interpolate between all
+ # to find "the perfect loop". Maybe before finding s? interp(i,i+flm,i+2flm)....
+ for i in range(1,margin+1):
+ w1 = sqrt(float(i)/margin)
+ loop[-i] = (loop[-i]*w1)+(loop[0]*(1-w1))
+
+
+ for curve in fcurves:
+ pts = curve.keyframe_points
+ for i in range(len(pts)-1,-1,-1):
+ pts.remove(pts[i])
+
+ for c,curve in enumerate(fcurves):
+ pts = curve.keyframe_points
+ for i in range(len(loop)):
+ pts.insert(i+1,loop[i][c])
+
+ context.scene.frame_end = flm+1
+
+
+
+
+
+
+def simplifyCurves(curveGroup, error, reparaError, maxIterations, group_mode):
+
+ def unitTangent(v,data_pts):
+ tang = Vector((0,0,0,0)) #
+ if v!=0:
+ #If it's not the first point, we can calculate a leftside tangent
+ tang+= data_pts[v].co-data_pts[v-1].co
+ if v!=len(data_pts)-1:
+ #If it's not the last point, we can calculate a rightside tangent
+ tang+= data_pts[v+1].co-data_pts[v].co
+ tang.normalize()
+ return tang
+
+ #assign parametric u value for each point in original data
+ def chordLength(data_pts,s,e):
+ totalLength = 0
+ for pt in data_pts[s:e+1]:
+ i = pt.index
+ if i==s:
+ chordLength = 0
+ else:
+ chordLength = (data_pts[i].co-data_pts[i-1].co).length
+ totalLength+= chordLength
+ pt.temp = totalLength
+ for pt in data_pts[s:e+1]:
+ if totalLength==0:
+ print(s,e)
+ pt.u = (pt.temp/totalLength)
+
+ # get binomial coefficient, this function/table is only called with args (3,0),(3,1),(3,2),(3,3),(2,0),(2,1),(2,2)!
+ binomDict = {(3,0): 1, (3,1): 3, (3,2): 3, (3,3): 1, (2,0): 1, (2,1): 2, (2,2): 1}
+ #value at pt t of a single bernstein Polynomial
+
+ def bernsteinPoly(n,i,t):
+ binomCoeff = binomDict[(n,i)]
+ return binomCoeff * pow(t,i) * pow(1-t,n-i)
+
+ # fit a single cubic to data points in range [s(tart),e(nd)].
+ def fitSingleCubic(data_pts,s,e):
+
+ # A - matrix used for calculating C matrices for fitting
+ def A(i,j,s,e,t1,t2):
+ if j==1:
+ t = t1
+ if j==2:
+ t = t2
+ u = data_pts[i].u
+ return t * bernsteinPoly(3,j,u)
+
+ # X component, used for calculating X matrices for fitting
+ def xComponent(i,s,e):
+ di = data_pts[i].co
+ u = data_pts[i].u
+ v0 = data_pts[s].co
+ v3 = data_pts[e].co
+ a = v0*bernsteinPoly(3,0,u)
+ b = v0*bernsteinPoly(3,1,u) #
+ c = v3*bernsteinPoly(3,2,u)
+ d = v3*bernsteinPoly(3,3,u)
+ return (di -(a+b+c+d))
+
+ t1 = unitTangent(s,data_pts)
+ t2 = unitTangent(e,data_pts)
+ c11 = sum([A(i,1,s,e,t1,t2)*A(i,1,s,e,t1,t2) for i in range(s,e+1)])
+ c12 = sum([A(i,1,s,e,t1,t2)*A(i,2,s,e,t1,t2) for i in range(s,e+1)])
+ c21 = c12
+ c22 = sum([A(i,2,s,e,t1,t2)*A(i,2,s,e,t1,t2) for i in range(s,e+1)])
+
+ x1 = sum([xComponent(i,s,e)*A(i,1,s,e,t1,t2) for i in range(s,e+1)])
+ x2 = sum([xComponent(i,s,e)*A(i,2,s,e,t1,t2) for i in range(s,e+1)])
+
+ # calculate Determinate of the 3 matrices
+ det_cc = c11 * c22 - c21 * c12
+ det_cx = c11 * x2 - c12 * x1
+ det_xc = x1 * c22 - x2 * c12
+
+ # if matrix is not homogenous, fudge the data a bit
+ if det_cc == 0:
+ det_cc=0.01
+
+ # alpha's are the correct offset for bezier handles
+ alpha0 = det_xc / det_cc #offset from right (first) point
+ alpha1 = det_cx / det_cc #offset from left (last) point
+
+ sRightHandle = data_pts[s].co.copy()
+ sTangent = t1*abs(alpha0)
+ sRightHandle+= sTangent #position of first pt's handle
+ eLeftHandle = data_pts[e].co.copy()
+ eTangent = t2*abs(alpha1)
+ eLeftHandle+= eTangent #position of last pt's handle.
+
+ #return a 4 member tuple representing the bezier
+ return (data_pts[s].co,
+ sRightHandle,
+ eLeftHandle,
+ data_pts[e].co)
+
+ # convert 2 given data points into a cubic bezier.
+ # handles are offset along the tangent at a 3rd of the length between the points.
+ def fitSingleCubic2Pts(data_pts,s,e):
+ alpha0 = alpha1 = (data_pts[s].co-data_pts[e].co).length / 3
+
+ sRightHandle = data_pts[s].co.copy()
+ sTangent = unitTangent(s,data_pts)*abs(alpha0)
+ sRightHandle+= sTangent #position of first pt's handle
+ eLeftHandle = data_pts[e].co.copy()
+ eTangent = unitTangent(e,data_pts)*abs(alpha1)
+ eLeftHandle+= eTangent #position of last pt's handle.
+
+ #return a 4 member tuple representing the bezier
+ return (data_pts[s].co,
+ sRightHandle,
+ eLeftHandle,
+ data_pts[e].co)
+
+ #evaluate bezier, represented by a 4 member tuple (pts) at point t.
+ def bezierEval(pts,t):
+ sumVec = Vector((0,0,0,0))
+ for i in range(4):
+ sumVec+=pts[i]*bernsteinPoly(3,i,t)
+ return sumVec
+
+ #calculate the highest error between bezier and original data
+ #returns the distance and the index of the point where max error occurs.
+ def maxErrorAmount(data_pts,bez,s,e):
+ maxError = 0
+ maxErrorPt = s
+ if e-s<3: return 0, None
+ for pt in data_pts[s:e+1]:
+ bezVal = bezierEval(bez,pt.u)
+ tmpError = (pt.co-bezVal).length/pt.co.length
+ if tmpError >= maxError:
+ maxError = tmpError
+ maxErrorPt = pt.index
+ return maxError,maxErrorPt
+
+
+ #calculated bezier derivative at point t.
+ #That is, tangent of point t.
+ def getBezDerivative(bez,t):
+ n = len(bez)-1
+ sumVec = Vector((0,0,0,0))
+ for i in range(n-1):
+ sumVec+=bernsteinPoly(n-1,i,t)*(bez[i+1]-bez[i])
+ return sumVec
+
+
+ #use Newton-Raphson to find a better paramterization of datapoints,
+ #one that minimizes the distance (or error) between bezier and original data.
+ def newtonRaphson(data_pts,s,e,bez):
+ for pt in data_pts[s:e+1]:
+ if pt.index==s:
+ pt.u=0
+ elif pt.index==e:
+ pt.u=1
+ else:
+ u = pt.u
+ qu = bezierEval(bez,pt.u)
+ qud = getBezDerivative(bez,u)
+ #we wish to minimize f(u), the squared distance between curve and data
+ fu = (qu-pt.co).length**2
+ fud = (2*(qu.x-pt.co.x)*(qud.x))-(2*(qu.y-pt.co.y)*(qud.y))
+ if fud==0:
+ fu = 0
+ fud = 1
+ pt.u=pt.u-(fu/fud)
+
+ def createDataPts(curveGroup, group_mode):
+ data_pts = []
+ if group_mode:
+ for i in range(len(curveGroup[0].keyframe_points)):
+ x = curveGroup[0].keyframe_points[i].co.x
+ y1 = curveGroup[0].keyframe_points[i].co.y
+ y2 = curveGroup[1].keyframe_points[i].co.y
+ y3 = curveGroup[2].keyframe_points[i].co.y
+ data_pts.append(dataPoint(i,Vector((x,y1,y2,y3))))
+ else:
+ for i in range(len(curveGroup.keyframe_points)):
+ x = curveGroup.keyframe_points[i].co.x
+ y1 = curveGroup.keyframe_points[i].co.y
+ y2 = 0
+ y3 = 0
+ data_pts.append(dataPoint(i,Vector((x,y1,y2,y3))))
+ return data_pts
+
+ def fitCubic(data_pts,s,e):
+
+ if e-s<3: # if there are less than 3 points, fit a single basic bezier
+ bez = fitSingleCubic2Pts(data_pts,s,e)
+ else:
+ #if there are more, parameterize the points and fit a single cubic bezier
+ chordLength(data_pts,s,e)
+ bez = fitSingleCubic(data_pts,s,e)
+
+ #calculate max error and point where it occurs
+ maxError,maxErrorPt = maxErrorAmount(data_pts,bez,s,e)
+ #if error is small enough, reparameterization might be enough
+ if maxError<reparaError and maxError>error:
+ for i in range(maxIterations):
+ newtonRaphson(data_pts,s,e,bez)
+ if e-s<3:
+ bez = fitSingleCubic2Pts(data_pts,s,e)
+ else:
+ bez = fitSingleCubic(data_pts,s,e)
+
+
+ #recalculate max error and point where it occurs
+ maxError,maxErrorPt = maxErrorAmount(data_pts,bez,s,e)
+
+ #repara wasn't enough, we need 2 beziers for this range.
+ #Split the bezier at point of maximum error
+ if maxError>error:
+ fitCubic(data_pts,s,maxErrorPt)
+ fitCubic(data_pts,maxErrorPt,e)
+ else:
+ #error is small enough, return the beziers.
+ beziers.append(bez)
+ return
+
+ def createNewCurves(curveGroup,beziers,group_mode):
+ #remove all existing data points
+ if group_mode:
+ for fcurve in curveGroup:
+ for i in range(len(fcurve.keyframe_points)-1,0,-1):
+ fcurve.keyframe_points.remove(fcurve.keyframe_points[i])
+ else:
+ fcurve = curveGroup
+ for i in range(len(fcurve.keyframe_points)-1,0,-1):
+ fcurve.keyframe_points.remove(fcurve.keyframe_points[i])
+
+ #insert the calculated beziers to blender data.\
+ if group_mode:
+ for fullbez in beziers:
+ for i,fcurve in enumerate(curveGroup):
+ bez = [Vector((vec[0],vec[i+1])) for vec in fullbez]
+ newKey = fcurve.keyframe_points.insert(frame=bez[0].x,value=bez[0].y)
+ newKey.handle_right = (bez[1].x,bez[1].y)
+
+ newKey = fcurve.keyframe_points.insert(frame=bez[3].x,value=bez[3].y)
+ newKey.handle_left= (bez[2].x,bez[2].y)
+ else:
+ for bez in beziers:
+ for vec in bez:
+ vec.resize_2d()
+ newKey = fcurve.keyframe_points.insert(frame=bez[0].x,value=bez[0].y)
+ newKey.handle_right = (bez[1].x,bez[1].y)
+
+ newKey = fcurve.keyframe_points.insert(frame=bez[3].x,value=bez[3].y)
+ newKey.handle_left= (bez[2].x,bez[2].y)
+
+ #indices are detached from data point's frame (x) value and stored in the dataPoint object, represent a range
+
+ data_pts = createDataPts(curveGroup,group_mode)
+
+ s = 0 #start
+ e = len(data_pts)-1 #end
+
+ beziers = []
+
+ #begin the recursive fitting algorithm.
+ fitCubic(data_pts,s,e)
+ #remove old Fcurves and insert the new ones
+ createNewCurves(curveGroup,beziers,group_mode)
+
+#Main function of simplification
+#sel_opt: either "sel" or "all" for which curves to effect
+#error: maximum error allowed, in fraction (20% = 0.0020), i.e. divide by 10000 from percentage wanted.
+#group_mode: boolean, to analyze each curve seperately or in groups, where group is all curves that effect the same property (e.g. a bone's x,y,z rotation)
+
+def fcurves_simplify(sel_opt="all", error=0.002, group_mode=True):
+ # main vars
+ context = bpy.context
+ obj = context.active_object
+ fcurves = obj.animation_data.action.fcurves
+
+ if sel_opt=="sel":
+ sel_fcurves = [fcurve for fcurve in fcurves if fcurve.select]
+ else:
+ sel_fcurves = fcurves[:]
+
+ #Error threshold for Newton Raphson reparamatizing
+ reparaError = error*32
+ maxIterations = 16
+
+ if group_mode:
+ fcurveDict = {}
+ #this loop sorts all the fcurves into groups of 3, based on their RNA Data path, which corresponds to which property they effect
+ for curve in sel_fcurves:
+ if curve.data_path in fcurveDict: #if this bone has been added, append the curve to its list
+ fcurveDict[curve.data_path].append(curve)
+ else:
+ fcurveDict[curve.data_path] = [curve] #new bone, add a new dict value with this first curve
+ fcurveGroups = fcurveDict.values()
+ else:
+ fcurveGroups = sel_fcurves
+
+ if error>0.00000:
+ #simplify every selected curve.
+ totalt = 0
+ for i,fcurveGroup in enumerate(fcurveGroups):
+ print("Processing curve "+str(i+1)+"/"+str(len(fcurveGroups)))
+ t = time.clock()
+ simplifyCurves(fcurveGroup,error,reparaError,maxIterations,group_mode)
+ t = time.clock() - t
+ print(str(t)[:5]+" seconds to process last curve")
+ totalt+=t
+ print(str(totalt)[:5]+" seconds, total time elapsed")
+
+ return
+
diff --git a/release/scripts/modules/retarget.py b/release/scripts/modules/retarget.py
new file mode 100644
index 00000000000..b081191d9a6
--- /dev/null
+++ b/release/scripts/modules/retarget.py
@@ -0,0 +1,198 @@
+import bpy
+from mathutils import *
+from math import radians, acos
+performer_obj = bpy.data.objects["performer"]
+enduser_obj = bpy.data.objects["enduser"]
+end_arm = bpy.data.armatures["enduser_arm"]
+scene = bpy.context.scene
+
+#TODO: Only selected bones get retargeted.
+# Selected Bones/chains get original pos empties, if ppl want IK instead of FK
+# Some "magic" numbers - frame start and end, eulers of all orders instead of just quats keyframed
+
+
+
+# dictionary of mapping
+# this is currently manuall input'ed, but will
+# be created from a more comfortable UI in the future
+bonemap = { "LeftFoot": ("DEF_Foot.L","DEF_Toes.L"),
+ "LeftUpLeg": "DEF_Thigh.L",
+ "Hips": "DEF_Hip",
+ "LowerBack": "DEF_Spine",
+ "Spine": "DEF_Torso",
+ "Neck": "DEF_Neck",
+ "Neck1": "DEF_Neck",
+ "Head": "DEF_Head",
+ "LeftShoulder": "DEF_Shoulder.L",
+ "LeftArm": "DEF_Forearm.L",
+ "LeftForeArm": "DEF_Arm.L",
+ "LeftHand": "DEF_Hand.L",
+ "RightShoulder": "DEF_Shoulder.R",
+ "RightArm": "DEF_Forearm.R",
+ "RightForeArm": "DEF_Arm.R",
+ "RightHand": "DEF_Hand.R",
+ "RightFoot": ("DEF_Foot.R","DEF_Toes.R"),
+ "RightUpLeg": "DEF_Thigh.R",
+ "RightLeg": "DEF_Shin.R",
+ "LeftLeg": "DEF_Shin.L"}
+
+# creation of a reverse map
+# multiple keys get mapped to list values
+bonemapr = {}
+for key in bonemap.keys():
+ if not bonemap[key] in bonemapr:
+ if type(bonemap[key])==type((0,0)):
+ for key_x in bonemap[key]:
+ bonemapr[key_x] = [key]
+ else:
+ bonemapr[bonemap[key]] = [key]
+ else:
+ bonemapr[bonemap[key]].append(key)
+
+# list of empties created to keep track of "original"
+# position data
+# in final product, these locations can be stored as custom props
+# these help with constraining, etc.
+
+constraints = []
+
+
+#creation of intermediate armature
+# the intermediate armature has the hiearchy of the end user,
+# does not have rotation inheritence
+# and bone roll is identical to the performer
+# its purpose is to copy over the rotations
+# easily while concentrating on the hierarchy changes
+def createIntermediate():
+
+ #creates and keyframes an empty with its location
+ #the original position of the tail bone
+ #useful for storing the important data in the original motion
+ #i.e. using this empty to IK the chain to that pos.
+ def locOfOriginal(inter_bone,perf_bone):
+ if not perf_bone.name+"Org" in bpy.data.objects:
+ bpy.ops.object.add()
+ empty = bpy.context.active_object
+ empty.name = perf_bone.name+"Org"
+ empty = bpy.data.objects[perf_bone.name+"Org"]
+ offset = perf_bone.vector
+ scaling = perf_bone.length / inter_bone.length
+ offset/=scaling
+ empty.location = inter_bone.head + offset
+ empty.keyframe_insert("location")
+
+ #Simple 1to1 retarget of a bone
+ def singleBoneRetarget(inter_bone,perf_bone):
+ perf_world_rotation = perf_bone.matrix * performer_obj.matrix_world
+ inter_world_base_rotation = inter_bone.bone.matrix_local * inter_obj.matrix_world
+ inter_world_base_inv = Matrix(inter_world_base_rotation)
+ inter_world_base_inv.invert()
+ return (inter_world_base_inv.to_3x3() * perf_world_rotation.to_3x3()).to_4x4()
+
+ #uses 1to1 and interpolation/averaging to match many to 1 retarget
+ def manyPerfToSingleInterRetarget(inter_bone,performer_bones_s):
+ retarget_matrices = [singleBoneRetarget(inter_bone,perf_bone) for perf_bone in performer_bones_s]
+ lerp_matrix = Matrix()
+ for i in range(len(retarget_matrices)-1):
+ first_mat = retarget_matrices[i]
+ next_mat = retarget_matrices[i+1]
+ lerp_matrix = first_mat.lerp(next_mat,0.5)
+ return lerp_matrix
+
+ #determines the type of hierachy change needed and calls the
+ #right function
+ def retargetPerfToInter(inter_bone):
+ if inter_bone.name in bonemapr.keys():
+ perf_bone_name = bonemapr[inter_bone.name]
+ #is it a 1 to many?
+ if type(bonemap[perf_bone_name[0]])==type((0,0)):
+ perf_bone = performer_bones[perf_bone_name[0]]
+ if inter_bone.name == bonemap[perf_bone_name[0]][0]:
+ locOfOriginal(inter_bone,perf_bone)
+ else:
+ # then its either a many to 1 or 1 to 1
+
+ if len(perf_bone_name) > 1:
+ performer_bones_s = [performer_bones[name] for name in perf_bone_name]
+ #we need to map several performance bone to a single
+ for perf_bone in performer_bones_s:
+ locOfOriginal(inter_bone,perf_bone)
+ inter_bone.matrix_basis = manyPerfToSingleInterRetarget(inter_bone,performer_bones_s)
+ else:
+ perf_bone = performer_bones[perf_bone_name[0]]
+ locOfOriginal(inter_bone,perf_bone)
+ inter_bone.matrix_basis = singleBoneRetarget(inter_bone,perf_bone)
+
+ inter_bone.keyframe_insert("rotation_quaternion")
+ for child in inter_bone.children:
+ retargetPerfToInter(child)
+
+ #creates the intermediate armature object
+ bpy.ops.object.select_name(name="enduser",extend=False)
+ bpy.ops.object.duplicate(linked=False)
+ bpy.context.active_object.name = "intermediate"
+ inter_obj = bpy.context.active_object
+ bpy.ops.object.mode_set(mode='EDIT')
+ #resets roll
+ bpy.ops.armature.calculate_roll(type='Z')
+ bpy.ops.object.mode_set(mode="OBJECT")
+ inter_arm = bpy.data.armatures["enduser_arm.001"]
+ inter_arm.name = "inter_arm"
+ performer_bones = performer_obj.pose.bones
+ inter_bones = inter_obj.pose.bones
+
+ #clears inheritance
+ for inter_bone in inter_bones:
+ inter_bone.bone.use_inherit_rotation = False
+
+ for t in range(1,150):
+ scene.frame_set(t)
+ inter_bone = inter_bones["DEF_Hip"]
+ retargetPerfToInter(inter_bone)
+
+ return inter_obj,inter_arm
+
+# this procedure copies the rotations over from the intermediate
+# armature to the end user one.
+# As the hierarchies are 1 to 1, this is a simple matter of
+# copying the rotation, while keeping in mind bone roll, parenting, etc.
+# TODO: Control Bones: If a certain bone is constrained in a way
+# that its rotation is determined by another (a control bone)
+# We should determine the right pos of the control bone.
+# Scale: ? Should work but needs testing.
+def retargetEnduser():
+ inter_bones = inter_obj.pose.bones
+ end_bones = enduser_obj.pose.bones
+
+ def bakeTransform(end_bone):
+ src_bone = inter_bones[end_bone.name]
+ trg_bone = end_bone
+ bake_matrix = src_bone.matrix
+ rest_matrix = trg_bone.bone.matrix_local
+
+ if trg_bone.parent and trg_bone.bone.use_inherit_rotation:
+ parent_mat = src_bone.parent.matrix
+ parent_rest = trg_bone.parent.bone.matrix_local
+ parent_rest_inv = parent_rest.copy()
+ parent_rest_inv.invert()
+ parent_mat_inv = parent_mat.copy()
+ parent_mat_inv.invert()
+ bake_matrix = parent_mat_inv * bake_matrix
+ rest_matrix = parent_rest_inv * rest_matrix
+
+ rest_matrix_inv = rest_matrix.copy()
+ rest_matrix_inv.invert()
+ bake_matrix = rest_matrix_inv * bake_matrix
+ trg_bone.matrix_basis = bake_matrix
+ end_bone.keyframe_insert("rotation_quaternion")
+
+ for bone in end_bone.children:
+ bakeTransform(bone)
+
+ for t in range(1,150):
+ scene.frame_set(t)
+ end_bone = end_bones["DEF_Hip"]
+ bakeTransform(end_bone)
+
+inter_obj, inter_arm = createIntermediate()
+retargetEnduser() \ No newline at end of file
diff --git a/release/scripts/startup/bl_operators/nla.py b/release/scripts/startup/bl_operators/nla.py
index 923ca92a162..82849cca2cc 100644
--- a/release/scripts/startup/bl_operators/nla.py
+++ b/release/scripts/startup/bl_operators/nla.py
@@ -168,3 +168,37 @@ class BakeAction(bpy.types.Operator):
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
+
+#################################
+
+class ClearUselessActions(bpy.types.Operator):
+ '''Mark actions with no F-Curves for deletion after save+reload of file preserving "action libraries"'''
+ bl_idname = "anim.clear_useless_actions"
+ bl_label = "Clear Useless Actions"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ only_unused = BoolProperty(name="Only Unused",
+ description="Only unused (Fake User only) actions get considered",
+ default=True)
+
+ @classmethod
+ def poll(cls, context):
+ return len(bpy.data.actions) != 0
+
+ def execute(self, context):
+ removed = 0
+
+ for action in bpy.data.actions:
+ # if only user is "fake" user...
+ if ((self.only_unused is False) or
+ (action.use_fake_user and action.users == 1)):
+
+ # if it has F-Curves, then it's a "action library" (i.e. walk, wave, jump, etc.)
+ # and should be left alone as that's what fake users are for!
+ if not action.fcurves:
+ # mark action for deletion
+ action.user_clear()
+ removed += 1
+
+ self.report({'INFO'}, "Removed %d empty and/or fake-user only Actions" % (removed))
+ return {'FINISHED'}
diff --git a/release/scripts/startup/bl_operators/object.py b/release/scripts/startup/bl_operators/object.py
index 0342a14a1b2..7a9a9d41939 100644
--- a/release/scripts/startup/bl_operators/object.py
+++ b/release/scripts/startup/bl_operators/object.py
@@ -564,3 +564,44 @@ class ClearAllRestrictRender(bpy.types.Operator):
for obj in context.scene.objects:
obj.hide_render = False
return {'FINISHED'}
+
+class TransformsToDeltasAnim(bpy.types.Operator):
+ '''Convert object animation for normal transforms to delta transforms'''
+ bl_idname = "object.anim_transforms_to_deltas"
+ bl_label = "Animated Transforms to Deltas"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(cls, context):
+ obs = context.selected_editable_objects
+ return (obs is not None)
+
+ def execute(self, context):
+ for obj in context.selected_editable_objects:
+ # get animation data
+ adt = obj.animation_data
+ if (adt is None) or (adt.action is None):
+ self.report({'WARNING'}, "No animation data to convert on object: " + obj.name)
+ continue
+
+ # if F-Curve uses standard transform path, just append "delta_" to this path
+ for fcu in adt.action.fcurves:
+ if fcu.data_path == "location":
+ fcu.data_path = "delta_location"
+ obj.location.zero()
+ elif fcu.data_path == "rotation_euler":
+ fcu.data_path = "delta_rotation_euler"
+ obj.rotation_euler.zero()
+ elif fcu.data_path == "rotation_quaternion":
+ fcu.data_path = "delta_rotation_quaternion"
+ obj.rotation_quaternion.identity()
+ #elif fcu.data_path == "rotation_axis_angle": # XXX: currently not implemented
+ # fcu.data_path = "delta_rotation_axis_angle"
+ elif fcu.data_path == "scale":
+ fcu.data_path = "delta_scale"
+ obj.scale = (1, 1, 1)
+
+ # hack: force animsys flush by changing frame, so that deltas get run
+ context.scene.frame_set(context.scene.frame_current)
+
+ return {'FINISHED'}
diff --git a/release/scripts/startup/bl_ui/properties_object_constraint.py b/release/scripts/startup/bl_ui/properties_object_constraint.py
index 03823ad7345..8e175244216 100644
--- a/release/scripts/startup/bl_ui/properties_object_constraint.py
+++ b/release/scripts/startup/bl_ui/properties_object_constraint.py
@@ -476,6 +476,11 @@ class ConstraintButtonsPanel():
row.label(text="Clamp Region:")
row.prop(con, "limit_mode", text="")
+ row = layout.row()
+ row.prop(con, "use_transform_limit")
+ row.label()
+
+
def STRETCH_TO(self, context, layout, con):
self.target_template(layout, con)
diff --git a/release/scripts/startup/bl_ui/properties_scene.py b/release/scripts/startup/bl_ui/properties_scene.py
index 7725f661693..e2dc9de064f 100644
--- a/release/scripts/startup/bl_ui/properties_scene.py
+++ b/release/scripts/startup/bl_ui/properties_scene.py
@@ -76,6 +76,7 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, bpy.types.Panel):
col = row.column(align=True)
col.operator("anim.keying_set_add", icon='ZOOMIN', text="")
col.operator("anim.keying_set_remove", icon='ZOOMOUT', text="")
+ col.menu("SCENE_MT_keying_set_specials", icon='DOWNARROW_HLT', text="")
ks = scene.keying_sets.active
if ks and ks.is_path_absolute:
@@ -94,6 +95,14 @@ class SCENE_PT_keying_sets(SceneButtonsPanel, bpy.types.Panel):
col.prop(ks, "bl_options")
+class SCENE_MT_keying_set_specials(bpy.types.Menu):
+ bl_label = "Keying Set Specials"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("anim.keying_set_import", text="Import From File")
+
class SCENE_PT_keying_set_paths(SceneButtonsPanel, bpy.types.Panel):
bl_label = "Active Keying Set"
@@ -198,6 +207,36 @@ class SCENE_PT_custom_props(SceneButtonsPanel, PropertyPanel, bpy.types.Panel):
# XXX, move operator to op/ dir
+class ANIM_OT_keying_set_import(bpy.types.Operator):
+ "Import Keying Set from a python script."
+ bl_idname = "anim.keying_set_import"
+ bl_label = "Import Keying Set from File"
+
+ filepath = bpy.props.StringProperty(name="File Path", description="Filepath to read file from.")
+ filter_folder = bpy.props.BoolProperty(name="Filter folders", description="", default=True, options={'HIDDEN'})
+ filter_text = bpy.props.BoolProperty(name="Filter text", description="", default=True, options={'HIDDEN'})
+ filter_python = bpy.props.BoolProperty(name="Filter python", description="", default=True, options={'HIDDEN'})
+
+ def execute(self, context):
+ if not self.filepath:
+ raise Exception("Filepath not set.")
+
+ f = open(self.filepath, "r")
+ if not f:
+ raise Exception("Could not open file.")
+
+ # lazy way of loading and running this file...
+ exec(compile(f.read(), self.filepath, 'exec'))
+
+ f.close()
+
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ wm.fileselect_add(self)
+ return {'RUNNING_MODAL'}
+
class ANIM_OT_keying_set_export(bpy.types.Operator):
"Export Keying Set to a python script."
bl_idname = "anim.keying_set_export"
diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py
index 2e9448cca27..222f2735a3e 100644
--- a/release/scripts/startup/bl_ui/space_userpref.py
+++ b/release/scripts/startup/bl_ui/space_userpref.py
@@ -743,6 +743,7 @@ class USERPREF_PT_file(bpy.types.Panel):
col.prop(paths, "save_version")
col.prop(paths, "recent_files")
+ col.prop(paths, "use_update_recent_files_on_load")
col.prop(paths, "use_save_preview_images")
col.label(text="Auto Save:")
col.prop(paths, "use_auto_save_temporary_files")
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 02004283264..6d1caa5111d 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -181,6 +181,10 @@ class VIEW3D_MT_transform(bpy.types.Menu):
layout.operator("object.randomize_transform")
layout.operator("object.align")
+
+ layout.separator()
+
+ layout.operator("object.anim_transforms_to_deltas")
class VIEW3D_MT_mirror(bpy.types.Menu):
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 7c0e7050a9f..ddff45c5422 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -154,6 +154,7 @@ void constraints_clear_evalob(struct bConstraintOb *cob);
void constraint_mat_convertspace(struct Object *ob, struct bPoseChannel *pchan, float mat[][4], short from, short to);
void get_constraint_target_matrix(struct Scene *scene, struct bConstraint *con, int n, short ownertype, void *ownerdata, float mat[][4], float ctime);
+void get_constraint_targets_for_solving(struct bConstraint *con, struct bConstraintOb *ob, struct ListBase *targets, float ctime);
void solve_constraints(struct ListBase *conlist, struct bConstraintOb *cob, float ctime);
#ifdef __cplusplus
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 04597fd666e..7402d501120 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -104,4 +104,6 @@ int sound_read_sound_buffer(struct bSound* sound, float* buffer, int length, flo
int sound_get_channels(struct bSound* sound);
+void* sound_get_factory(void* sound);
+
#endif
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 77f56058a4f..21d9701004b 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -85,8 +85,6 @@ bAction *add_empty_action(const char name[])
bAction *act;
act= alloc_libblock(&G.main->action, ID_AC, name);
- act->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
- act->id.us++;
return act;
}
@@ -200,9 +198,6 @@ bAction *copy_action (bAction *src)
}
}
- dst->id.flag |= LIB_FAKEUSER; // XXX this is nasty for new users... maybe we don't want this anymore
- dst->id.us++;
-
return dst;
}
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index d3c14a9dd12..fe3286dcc2b 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -2648,7 +2648,7 @@ static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
/* if inside, then move to surface */
if (dist <= data->dist) {
clamp_surf= 1;
- sfac= data->dist / dist;
+ if (dist != 0.0f) sfac= data->dist / dist;
}
/* if soft-distance is enabled, start fading once owner is dist+softdist from the target */
else if (data->flag & LIMITDIST_USESOFT) {
@@ -2661,14 +2661,14 @@ static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
/* if outside, then move to surface */
if (dist >= data->dist) {
clamp_surf= 1;
- sfac= data->dist / dist;
+ if (dist != 0.0f) sfac= data->dist / dist;
}
/* if soft-distance is enabled, start fading once owner is dist-soft from the target */
else if (data->flag & LIMITDIST_USESOFT) {
// FIXME: there's a problem with "jumping" when this kicks in
if (dist >= (data->dist - data->soft)) {
sfac = (float)( data->soft*(1.0f - expf(-(dist - data->dist)/data->soft)) + data->dist );
- sfac /= dist;
+ if (dist != 0.0f) sfac /= dist;
clamp_surf= 1;
}
@@ -2677,7 +2677,7 @@ static void distlimit_evaluate (bConstraint *con, bConstraintOb *cob, ListBase *
else {
if (IS_EQF(dist, data->dist)==0) {
clamp_surf= 1;
- sfac= data->dist / dist;
+ if (dist != 0.0f) sfac= data->dist / dist;
}
}
@@ -4427,6 +4427,34 @@ void get_constraint_target_matrix (struct Scene *scene, bConstraint *con, int n,
unit_m4(mat);
}
}
+
+/* Get the list of targets required for solving a constraint */
+void get_constraint_targets_for_solving (bConstraint *con, bConstraintOb *cob, ListBase *targets, float ctime)
+{
+ bConstraintTypeInfo *cti= constraint_get_typeinfo(con);
+
+ if (cti && cti->get_constraint_targets) {
+ bConstraintTarget *ct;
+
+ /* get targets
+ * - constraints should use ct->matrix, not directly accessing values
+ * - ct->matrix members have not yet been calculated here!
+ */
+ cti->get_constraint_targets(con, targets);
+
+ /* set matrices
+ * - calculate if possible, otherwise just initialise as identity matrix
+ */
+ if (cti->get_target_matrix) {
+ for (ct= targets->first; ct; ct= ct->next)
+ cti->get_target_matrix(con, cob, ct, ctime);
+ }
+ else {
+ for (ct= targets->first; ct; ct= ct->next)
+ unit_m4(ct->matrix);
+ }
+ }
+}
/* ---------- Evaluation ----------- */
@@ -4471,27 +4499,7 @@ void solve_constraints (ListBase *conlist, bConstraintOb *cob, float ctime)
constraint_mat_convertspace(cob->ob, cob->pchan, cob->matrix, CONSTRAINT_SPACE_WORLD, con->ownspace);
/* prepare targets for constraint solving */
- if (cti->get_constraint_targets) {
- bConstraintTarget *ct;
-
- /* get targets
- * - constraints should use ct->matrix, not directly accessing values
- * - ct->matrix members have not yet been calculated here!
- */
- cti->get_constraint_targets(con, &targets);
-
- /* set matrices
- * - calculate if possible, otherwise just initialise as identity matrix
- */
- if (cti->get_target_matrix) {
- for (ct= targets.first; ct; ct= ct->next)
- cti->get_target_matrix(con, cob, ct, ctime);
- }
- else {
- for (ct= targets.first; ct; ct= ct->next)
- unit_m4(ct->matrix);
- }
- }
+ get_constraint_targets_for_solving(con, cob, &targets, ctime);
/* Solve the constraint and put result in cob->matrix */
cti->evaluate_constraint(con, cob, &targets);
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index d6a9d950015..1f45cc56117 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -42,6 +42,7 @@
#include "MEM_guardedalloc.h"
#include "DNA_anim_types.h"
+#include "DNA_constraint_types.h"
#include "DNA_object_types.h"
#include "BLI_blenlib.h"
@@ -52,6 +53,7 @@
#include "BKE_animsys.h"
#include "BKE_action.h"
#include "BKE_armature.h"
+#include "BKE_constraint.h"
#include "BKE_curve.h"
#include "BKE_global.h"
#include "BKE_object.h"
@@ -1151,25 +1153,50 @@ static float dvar_eval_locDiff (ChannelDriver *driver, DriverVar *dvar)
/* check if object or bone */
if (pchan) {
/* bone */
- if ((dtar->flag & DTAR_FLAG_LOCALSPACE) == 0) {
+ if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
+ if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
+ float mat[4][4];
+
+ /* extract transform just like how the constraints do it! */
+ copy_m4_m4(mat, pchan->pose_mat);
+ constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+
+ /* ... and from that, we get our transform */
+ VECCOPY(tmp_loc, mat[3]);
+ }
+ else {
+ /* transform space (use transform values directly) */
+ VECCOPY(tmp_loc, pchan->loc);
+ }
+ }
+ else {
/* convert to worldspace */
VECCOPY(tmp_loc, pchan->pose_head);
mul_m4_v3(ob->obmat, tmp_loc);
}
- else {
- /* local (use transform values directly) */
- VECCOPY(tmp_loc, pchan->loc);
- }
}
else {
/* object */
- if ((dtar->flag & DTAR_FLAG_LOCALSPACE) == 0) {
- /* worldspace */
- VECCOPY(tmp_loc, ob->obmat[3]);
+ if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
+ if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
+ // XXX: this should practically be the same as transform space...
+ float mat[4][4];
+
+ /* extract transform just like how the constraints do it! */
+ copy_m4_m4(mat, ob->obmat);
+ constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+
+ /* ... and from that, we get our transform */
+ VECCOPY(tmp_loc, mat[3]);
+ }
+ else {
+ /* transform space (use transform values directly) */
+ VECCOPY(tmp_loc, ob->loc);
+ }
}
else {
- /* local (use transform values directly) */
- VECCOPY(tmp_loc, ob->loc);
+ /* worldspace */
+ VECCOPY(tmp_loc, ob->obmat[3]);
}
}
@@ -1197,7 +1224,7 @@ static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
Object *ob= (Object *)dtar_id_ensure_proxy_from(dtar->id);
bPoseChannel *pchan;
float mat[4][4];
- float eul[3] = {0.0f,0.0f,0.0f};
+ float oldEul[3] = {0.0f,0.0f,0.0f};
short useEulers=0, rotOrder=ROT_MODE_EUL;
/* check if this target has valid data */
@@ -1210,36 +1237,62 @@ static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
/* try to get posechannel */
pchan= get_pose_channel(ob->pose, dtar->pchan_name);
- /* check if object or bone, and get transform matrix accordingly */
+ /* check if object or bone, and get transform matrix accordingly
+ * - "useEulers" code is used to prevent the problems associated with non-uniqueness
+ * of euler decomposition from matrices [#20870]
+ * - localspace is for [#21384], where parent results are not wanted
+ * but local-consts is for all the common "corrective-shapes-for-limbs" situations
+ */
if (pchan) {
/* bone */
if (pchan->rotmode > 0) {
- VECCOPY(eul, pchan->eul);
+ VECCOPY(oldEul, pchan->eul);
rotOrder= pchan->rotmode;
useEulers = 1;
}
if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
- /* specially calculate local matrix, since chan_mat is not valid
- * since it stores delta transform of pose_mat so that deforms work
- */
- pchan_to_mat4(pchan, mat);
+ if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
+ /* just like how the constraints do it! */
+ copy_m4_m4(mat, pchan->pose_mat);
+ constraint_mat_convertspace(ob, pchan, mat, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_LOCAL);
+ }
+ else {
+ /* specially calculate local matrix, since chan_mat is not valid
+ * since it stores delta transform of pose_mat so that deforms work
+ * so it cannot be used here for "transform" space
+ */
+ pchan_to_mat4(pchan, mat);
+ }
}
- else
+ else {
+ /* worldspace matrix */
mul_m4_m4m4(mat, pchan->pose_mat, ob->obmat);
+ }
}
else {
/* object */
if (ob->rotmode > 0) {
- VECCOPY(eul, ob->rot);
+ VECCOPY(oldEul, ob->rot);
rotOrder= ob->rotmode;
useEulers = 1;
}
- if (dtar->flag & DTAR_FLAG_LOCALSPACE)
- object_to_mat4(ob, mat);
- else
+ if (dtar->flag & DTAR_FLAG_LOCALSPACE) {
+ if (dtar->flag & DTAR_FLAG_LOCAL_CONSTS) {
+ /* just like how the constraints do it! */
+ copy_m4_m4(mat, ob->obmat);
+ constraint_mat_convertspace(ob, NULL, mat, CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL);
+ }
+ else {
+ /* transforms to matrix */
+ object_to_mat4(ob, mat);
+ }
+ }
+ else {
+ /* worldspace matrix - just the good-old one */
copy_m4_m4(mat, ob->obmat);
+ }
}
/* check which transform */
@@ -1255,9 +1308,21 @@ static float dvar_eval_transChan (ChannelDriver *driver, DriverVar *dvar)
return scale[dtar->transChan - DTAR_TRANSCHAN_SCALEX];
}
else if (dtar->transChan >= DTAR_TRANSCHAN_ROTX) {
- /* extract euler rotation (if needed), and choose the right axis */
- if ((dtar->flag & DTAR_FLAG_LOCALSPACE)==0 || (useEulers == 0))
- mat4_to_eulO(eul, rotOrder, mat);
+ /* extract rotation as eulers (if needed)
+ * - definitely if rotation order isn't eulers already
+ * - if eulers, then we have 2 options:
+ * a) decompose transform matrix as required, then try to make eulers from
+ * there compatible with original values
+ * b) [NOT USED] directly use the original values (no decomposition)
+ * - only an option for "transform space", if quality is really bad with a)
+ */
+ float eul[3];
+
+ mat4_to_eulO(eul, rotOrder, mat);
+
+ if (useEulers) {
+ compatible_eul(eul, oldEul);
+ }
return eul[dtar->transChan - DTAR_TRANSCHAN_ROTX];
}
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 844f25e6d21..dcf81c19479 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -1013,6 +1013,7 @@ FModifier *add_fmodifier (ListBase *modifiers, int type)
fcm= MEM_callocN(sizeof(FModifier), "F-Curve Modifier");
fcm->type = type;
fcm->flag = FMODIFIER_FLAG_EXPANDED;
+ fcm->influence = 1.0f;
BLI_addtail(modifiers, fcm);
/* tag modifier as "active" if no other modifiers exist in the stack yet */
@@ -1200,6 +1201,47 @@ short list_has_suitable_fmodifier (ListBase *modifiers, int mtype, short acttype
/* Evaluation API --------------------------- */
+/* helper function - calculate influence of FModifier */
+static float eval_fmodifier_influence (FModifier *fcm, float evaltime)
+{
+ float influence;
+
+ /* sanity check */
+ if (fcm == NULL)
+ return 0.0f;
+
+ /* should we use influence stored in modifier or not
+ * NOTE: this is really just a hack so that we don't need to version patch old files ;)
+ */
+ if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE)
+ influence = fcm->influence;
+ else
+ influence = 1.0f;
+
+ /* restricted range or full range? */
+ if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
+ if ((evaltime <= fcm->sfra) || (evaltime >= fcm->efra)) {
+ /* out of range */
+ return 0.0f;
+ }
+ else if ((evaltime > fcm->sfra) && (evaltime < fcm->sfra + fcm->blendin)) {
+ /* blend in range */
+ float a = fcm->sfra;
+ float b = fcm->sfra + fcm->blendin;
+ return influence * (evaltime - a) / (b - a);
+ }
+ else if ((evaltime < fcm->efra) && (evaltime > fcm->efra - fcm->blendout)) {
+ /* blend out range */
+ float a = fcm->efra;
+ float b = fcm->efra - fcm->blendout;
+ return influence * (evaltime - a) / (b - a);
+ }
+ }
+
+ /* just return the influence of the modifier */
+ return influence;
+}
+
/* evaluate time modifications imposed by some F-Curve Modifiers
* - this step acts as an optimisation to prevent the F-Curve stack being evaluated
* several times by modifiers requesting the time be modified, as the final result
@@ -1230,11 +1272,24 @@ float evaluate_time_fmodifiers (ListBase *modifiers, FCurve *fcu, float cvalue,
for (fcm= modifiers->last; fcm; fcm= fcm->prev) {
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
- /* only evaluate if there's a callback for this */
- // TODO: implement the 'influence' control feature...
- if (fmi && fmi->evaluate_modifier_time) {
- if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
- evaltime= fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
+ if (fmi == NULL)
+ continue;
+
+ /* if modifier cannot be applied on this frame (whatever scale it is on, it won't affect the results)
+ * hence we shouldn't bother seeing what it would do given the chance
+ */
+ if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT)==0 ||
+ ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) )
+ {
+ /* only evaluate if there's a callback for this */
+ if (fmi->evaluate_modifier_time) {
+ if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0) {
+ float influence = eval_fmodifier_influence(fcm, evaltime);
+ float nval = fmi->evaluate_modifier_time(fcu, fcm, cvalue, evaltime);
+
+ evaltime = interpf(nval, evaltime, influence);
+ }
+ }
}
}
@@ -1257,11 +1312,22 @@ void evaluate_value_fmodifiers (ListBase *modifiers, FCurve *fcu, float *cvalue,
for (fcm= modifiers->first; fcm; fcm= fcm->next) {
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
- /* only evaluate if there's a callback for this */
- // TODO: implement the 'influence' control feature...
- if (fmi && fmi->evaluate_modifier) {
- if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0)
- fmi->evaluate_modifier(fcu, fcm, cvalue, evaltime);
+ if (fmi == NULL)
+ continue;
+
+ /* only evaluate if there's a callback for this, and if F-Modifier can be evaluated on this frame */
+ if ((fcm->flag & FMODIFIER_FLAG_RANGERESTRICT)==0 ||
+ ((fcm->sfra <= evaltime) && (fcm->efra >= evaltime)) )
+ {
+ if (fmi->evaluate_modifier) {
+ if ((fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED)) == 0) {
+ float influence = eval_fmodifier_influence(fcm, evaltime);
+ float nval = *cvalue;
+
+ fmi->evaluate_modifier(fcu, fcm, &nval, evaltime);
+ *cvalue = interpf(nval, *cvalue, influence);
+ }
+ }
}
}
}
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index e0e456a371e..f42492ef713 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -502,3 +502,8 @@ int sound_get_channels(struct bSound* sound)
return info.specs.channels;
}
+
+void* sound_get_factory(void* sound)
+{
+ return ((struct bSound*) sound)->playback_handle;
+}
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
new file mode 100644
index 00000000000..98699e22030
--- /dev/null
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -0,0 +1,800 @@
+/*
+ * $Id: DocumentExporter.cpp 36898 2011-05-25 17:14:31Z phabtar $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "GeometryExporter.h"
+#include "AnimationExporter.h"
+
+template<class Functor>
+void forEachObjectInScene(Scene *sce, Functor &f)
+{
+ Base *base= (Base*) sce->base.first;
+ while(base) {
+ Object *ob = base->object;
+
+ f(ob);
+
+ base= base->next;
+ }
+}
+
+void AnimationExporter::exportAnimations(Scene *sce)
+ {
+ if(hasAnimations(sce)) {
+ this->scene = sce;
+
+ openLibrary();
+
+ forEachObjectInScene(sce, *this);
+
+ closeLibrary();
+ }
+ }
+
+ // called for each exported object
+ void AnimationExporter::operator() (Object *ob)
+ {
+ if (!ob->adt || !ob->adt->action) return; //this is already checked in hasAnimations()
+ FCurve *fcu = (FCurve*)ob->adt->action->curves.first;
+ char * transformName = extract_transform_name( fcu->rna_path );
+
+ //if (ob->type == OB_ARMATURE) {
+ // if (!ob->data) return;
+ // bArmature *arm = (bArmature*)ob->data;
+ // while(fcu)
+ // {
+ // transformName = extract_transform_name( fcu->rna_path );
+ // // std::string ob_name = getObjectBoneName( ob , fcu);
+ // // for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next)
+ // // write_bone_animation(ob, bone);
+ // dae_animation(ob, fcu, ob_name, transformName);
+ // fcu = fcu->next;
+ // }
+ //}
+ //else {
+ while (fcu) {
+ transformName = extract_transform_name( fcu->rna_path );
+ printf("fcu -> rna _path : %s \n transformName : %s\n", fcu->rna_path, transformName);
+ if ((!strcmp(transformName, "location") || !strcmp(transformName, "scale")) ||
+ (!strcmp(transformName, "rotation_euler") && ob->rotmode == ROT_MODE_EUL)||
+ (!strcmp(transformName, "rotation_quaternion")))
+ dae_animation(ob ,fcu,/* id_name(ob),*/ transformName);
+
+ fcu = fcu->next;
+ }
+ //}
+ }
+
+ std::string AnimationExporter::getObjectBoneName( Object* ob,const FCurve* fcu )
+ {
+ //hard-way to derive the bone name from rna_path. Must find more compact method
+ std::string rna_path = std::string(fcu->rna_path);
+
+ char* boneName = strtok((char *)rna_path.c_str(), "\"");
+ boneName = strtok(NULL,"\"");
+
+ if( boneName != NULL )
+ return id_name(ob) + "_" + std::string(boneName);
+ else
+ return id_name(ob);
+ }
+
+ void AnimationExporter::dae_animation(Object* ob, FCurve *fcu/*, std::string ob_name*/ , char* transformName)
+ {
+ printf("in dae animation\n");
+ const char *axis_name = NULL;
+ char anim_id[200];
+ bool has_tangents = false;
+
+ if ( !strcmp(transformName, "rotation_quaternion") )
+ {
+ const char *axis_names[] = {"W", "X", "Y", "Z"};
+ if (fcu->array_index < 4)
+ axis_name = axis_names[fcu->array_index];
+ }
+
+ else
+ {
+ const char *axis_names[] = {"X", "Y", "Z"};
+ if (fcu->array_index < 3)
+ axis_name = axis_names[fcu->array_index];
+
+
+ }
+ std::string ob_name = std::string("null");
+ if (ob->type == OB_ARMATURE)
+ {
+ ob_name = getObjectBoneName( ob , fcu);
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s.%s", (char*)translate_id(ob_name).c_str(),
+ transformName, axis_name);
+ }
+ else
+ {
+ ob_name = id_name(ob);
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(),
+ fcu->rna_path, axis_name);
+ }
+
+ // check rna_path is one of: rotation, scale, location
+
+ openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
+
+ // create input source
+ std::string input_id = create_source_from_fcurve(COLLADASW::InputSemantic::INPUT, fcu, anim_id, axis_name);
+
+ // create output source
+ std::string output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name);
+
+ // create interpolations source
+ std::string interpolation_id = create_interpolation_source(fcu, anim_id, axis_name, &has_tangents);
+
+ // handle tangents (if required)
+ std::string intangent_id;
+ std::string outtangent_id;
+
+ if (has_tangents) {
+ // create in_tangent source
+ intangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::IN_TANGENT, fcu, anim_id, axis_name);
+
+ // create out_tangent source
+ outtangent_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUT_TANGENT, fcu, anim_id, axis_name);
+ }
+
+
+ std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+ COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
+ std::string empty;
+ sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
+ sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
+
+ // this input is required
+ sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+ if (has_tangents) {
+ sampler.addInput(COLLADASW::InputSemantic::IN_TANGENT, COLLADABU::URI(empty, intangent_id));
+ sampler.addInput(COLLADASW::InputSemantic::OUT_TANGENT, COLLADABU::URI(empty, outtangent_id));
+ }
+
+ addSampler(sampler);
+
+ std::string target = translate_id(ob_name)
+ + "/" + get_transform_sid(fcu->rna_path, -1, axis_name, true);
+ addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+ closeAnimation();
+ }
+
+ void AnimationExporter::write_bone_animation(Object *ob_arm, Bone *bone)
+ {
+ if (!ob_arm->adt)
+ return;
+
+ //write bone animations for 3 transform types
+ //i=0 --> rotations
+ //i=1 --> scale
+ //i=2 --> location
+ for (int i = 0; i < 3; i++)
+ sample_and_write_bone_animation(ob_arm, bone, i);
+
+ for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next)
+ write_bone_animation(ob_arm, child);
+ }
+
+ void AnimationExporter::sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type)
+ {
+ bArmature *arm = (bArmature*)ob_arm->data;
+ int flag = arm->flag;
+ std::vector<float> fra;
+ char prefix[256];
+
+ BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone->name);
+
+ bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);
+ if (!pchan)
+ return;
+ //Fill frame array with key frame values framed at @param:transform_type
+ switch (transform_type) {
+ case 0:
+ find_rotation_frames(ob_arm, fra, prefix, pchan->rotmode);
+ break;
+ case 1:
+ find_frames(ob_arm, fra, prefix, "scale");
+ break;
+ case 2:
+ find_frames(ob_arm, fra, prefix, "location");
+ break;
+ default:
+ return;
+ }
+
+ // exit rest position
+ if (flag & ARM_RESTPOS) {
+ arm->flag &= ~ARM_RESTPOS;
+ where_is_pose(scene, ob_arm);
+ }
+ //v array will hold all values which will be exported.
+ if (fra.size()) {
+ float *values = (float*)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
+ sample_animation(values, fra, transform_type, bone, ob_arm, pchan);
+
+ if (transform_type == 0) {
+ // write x, y, z curves separately if it is rotation
+ float *axisValues = (float*)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames");
+
+ for (int i = 0; i < 3; i++) {
+ for (unsigned int j = 0; j < fra.size(); j++)
+ axisValues[j] = values[j * 3 + i];
+
+ dae_bone_animation(fra, axisValues, transform_type, i, id_name(ob_arm), bone->name);
+ }
+ MEM_freeN(axisValues);
+ }
+ else {
+ // write xyz at once if it is location or scale
+ dae_bone_animation(fra, values, transform_type, -1, id_name(ob_arm), bone->name);
+ }
+
+ MEM_freeN(values);
+ }
+
+ // restore restpos
+ if (flag & ARM_RESTPOS)
+ arm->flag = flag;
+ where_is_pose(scene, ob_arm);
+ }
+
+ void AnimationExporter::sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm, bPoseChannel *pchan)
+ {
+ bPoseChannel *parchan = NULL;
+ bPose *pose = ob_arm->pose;
+
+ pchan = get_pose_channel(pose, bone->name);
+
+ if (!pchan)
+ return;
+
+ parchan = pchan->parent;
+
+ enable_fcurves(ob_arm->adt->action, bone->name);
+
+ std::vector<float>::iterator it;
+ for (it = frames.begin(); it != frames.end(); it++) {
+ float mat[4][4], ipar[4][4];
+
+ float ctime = bsystem_time(scene, ob_arm, *it, 0.0f);
+
+ BKE_animsys_evaluate_animdata(&ob_arm->id, ob_arm->adt, *it, ADT_RECALC_ANIM);
+ where_is_pose_bone(scene, ob_arm, pchan, ctime, 1);
+
+ // compute bone local mat
+ if (bone->parent) {
+ invert_m4_m4(ipar, parchan->pose_mat);
+ mul_m4_m4m4(mat, pchan->pose_mat, ipar);
+ }
+ else
+ copy_m4_m4(mat, pchan->pose_mat);
+
+ switch (type) {
+ case 0:
+ mat4_to_eul(v, mat);
+ break;
+ case 1:
+ mat4_to_size(v, mat);
+ break;
+ case 2:
+ copy_v3_v3(v, mat[3]);
+ break;
+ }
+
+ v += 3;
+ }
+
+ enable_fcurves(ob_arm->adt->action, NULL);
+ }
+
+ // dae_bone_animation -> add_bone_animation
+ // (blend this into dae_bone_animation)
+ void AnimationExporter::dae_bone_animation(std::vector<float> &fra, float *values, int tm_type, int axis, std::string ob_name, std::string bone_name)
+ {
+ const char *axis_names[] = {"X", "Y", "Z"};
+ const char *axis_name = NULL;
+ char anim_id[200];
+ bool is_rot = tm_type == 0;
+
+ if (!fra.size())
+ return;
+
+ char rna_path[200];
+ BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].%s", bone_name.c_str(),
+ tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location"));
+
+ if (axis > -1)
+ axis_name = axis_names[axis];
+
+ std::string transform_sid = get_transform_sid(NULL, tm_type, axis_name, false);
+
+ BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(),
+ (char*)translate_id(bone_name).c_str(), (char*)transform_sid.c_str());
+
+ openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
+
+ // create input source
+ std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, is_rot, anim_id, axis_name);
+
+ // create output source
+ std::string output_id;
+ if (axis == -1)
+ output_id = create_xyz_source(values, fra.size(), anim_id);
+ else
+ output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, values, fra.size(), is_rot, anim_id, axis_name);
+
+ // create interpolations source
+ std::string interpolation_id = fake_interpolation_source(fra.size(), anim_id, axis_name);
+
+ std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
+ COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
+ std::string empty;
+ sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
+ sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
+
+ // TODO create in/out tangents source
+
+ // this input is required
+ sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
+
+ addSampler(sampler);
+
+ std::string target = translate_id(ob_name + "_" + bone_name) + "/" + transform_sid;
+ addChannel(COLLADABU::URI(empty, sampler_id), target);
+
+ closeAnimation();
+ }
+
+ float AnimationExporter::convert_time(float frame)
+ {
+ return FRA2TIME(frame);
+ }
+
+ float AnimationExporter::convert_angle(float angle)
+ {
+ return COLLADABU::Math::Utils::radToDegF(angle);
+ }
+
+ std::string AnimationExporter::get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic)
+ {
+ switch(semantic) {
+ case COLLADASW::InputSemantic::INPUT:
+ return INPUT_SOURCE_ID_SUFFIX;
+ case COLLADASW::InputSemantic::OUTPUT:
+ return OUTPUT_SOURCE_ID_SUFFIX;
+ case COLLADASW::InputSemantic::INTERPOLATION:
+ return INTERPOLATION_SOURCE_ID_SUFFIX;
+ case COLLADASW::InputSemantic::IN_TANGENT:
+ return INTANGENT_SOURCE_ID_SUFFIX;
+ case COLLADASW::InputSemantic::OUT_TANGENT:
+ return OUTTANGENT_SOURCE_ID_SUFFIX;
+ default:
+ break;
+ }
+ return "";
+ }
+
+ void AnimationExporter::add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
+ COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis)
+ {
+ switch(semantic) {
+ case COLLADASW::InputSemantic::INPUT:
+ param.push_back("TIME");
+ break;
+ case COLLADASW::InputSemantic::OUTPUT:
+ if (is_rot) {
+ param.push_back("ANGLE");
+ }
+ else {
+ if (axis) {
+ param.push_back(axis);
+ }
+ else { //assumes if axis isn't specified all axi are added
+ param.push_back("X");
+ param.push_back("Y");
+ param.push_back("Z");
+ }
+ }
+ break;
+ case COLLADASW::InputSemantic::IN_TANGENT:
+ case COLLADASW::InputSemantic::OUT_TANGENT:
+ param.push_back("X");
+ param.push_back("Y");
+ break;
+ default:
+ break;
+ }
+ }
+
+ void AnimationExporter::get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length)
+ {
+ switch (semantic) {
+ case COLLADASW::InputSemantic::INPUT:
+ *length = 1;
+ values[0] = convert_time(bezt->vec[1][0]);
+ break;
+ case COLLADASW::InputSemantic::OUTPUT:
+ *length = 1;
+ if (rotation) {
+ values[0] = convert_angle(bezt->vec[1][1]);
+ }
+ else {
+ values[0] = bezt->vec[1][1];
+ }
+ break;
+
+ case COLLADASW::InputSemantic::IN_TANGENT:
+ *length = 2;
+ values[0] = convert_time(bezt->vec[0][0]);
+ if (bezt->ipo != BEZT_IPO_BEZ) {
+ // We're in a mixed interpolation scenario, set zero as it's irrelevant but value might contain unused data
+ values[0] = 0;
+ values[1] = 0;
+ } else if (rotation) {
+ values[1] = convert_angle(bezt->vec[0][1]);
+ } else {
+ values[1] = bezt->vec[0][1];
+ }
+ break;
+
+ case COLLADASW::InputSemantic::OUT_TANGENT:
+ *length = 2;
+ values[0] = convert_time(bezt->vec[2][0]);
+ if (bezt->ipo != BEZT_IPO_BEZ) {
+ // We're in a mixed interpolation scenario, set zero as it's irrelevant but value might contain unused data
+ values[0] = 0;
+ values[1] = 0;
+ } else if (rotation) {
+ values[1] = convert_angle(bezt->vec[2][1]);
+ } else {
+ values[1] = bezt->vec[2][1];
+ }
+ break;
+ break;
+ default:
+ *length = 0;
+ break;
+ }
+ }
+
+ std::string AnimationExporter::create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name)
+ {
+ std::string source_id = anim_id + get_semantic_suffix(semantic);
+
+ //bool is_rotation = !strcmp(fcu->rna_path, "rotation");
+ bool is_rotation = false;
+
+ if (strstr(fcu->rna_path, "rotation")) is_rotation = true;
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(fcu->totvert);
+
+ switch (semantic) {
+ case COLLADASW::InputSemantic::INPUT:
+ case COLLADASW::InputSemantic::OUTPUT:
+ source.setAccessorStride(1);
+ break;
+ case COLLADASW::InputSemantic::IN_TANGENT:
+ case COLLADASW::InputSemantic::OUT_TANGENT:
+ source.setAccessorStride(2);
+ break;
+ }
+
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, is_rotation, axis_name);
+
+ source.prepareToAppendValues();
+
+ for (unsigned int i = 0; i < fcu->totvert; i++) {
+ float values[3]; // be careful!
+ int length = 0;
+
+ get_source_values(&fcu->bezt[i], semantic, is_rotation, values, &length);
+ for (int j = 0; j < length; j++)
+ source.appendValues(values[j]);
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+ //Currently called only to get OUTPUT source values ( if rotation and hence the axis is also specified )
+ std::string AnimationExporter::create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name)
+ {
+ std::string source_id = anim_id + get_semantic_suffix(semantic);
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(tot);
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, is_rot, axis_name);
+
+ source.prepareToAppendValues();
+
+ for (int i = 0; i < tot; i++) {
+ float val = v[i];
+ ////if (semantic == COLLADASW::InputSemantic::INPUT)
+ // val = convert_time(val);
+ //else
+ if (is_rot)
+ val = convert_angle(val);
+ source.appendValues(val);
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+// only used for sources with INPUT semantic
+ std::string AnimationExporter::create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name)
+ {
+ std::string source_id = anim_id + get_semantic_suffix(semantic);
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(fra.size());
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, is_rot, axis_name);
+
+ source.prepareToAppendValues();
+
+ std::vector<float>::iterator it;
+ for (it = fra.begin(); it != fra.end(); it++) {
+ float val = *it;
+ //if (semantic == COLLADASW::InputSemantic::INPUT)
+ val = convert_time(val);
+ /*else if (is_rot)
+ val = convert_angle(val);*/
+ source.appendValues(val);
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+
+ // only used for sources with OUTPUT semantic ( locations and scale)
+ std::string AnimationExporter::create_xyz_source(float *v, int tot, const std::string& anim_id)
+ {
+ COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
+ std::string source_id = anim_id + get_semantic_suffix(semantic);
+
+ COLLADASW::FloatSourceF source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(tot);
+ source.setAccessorStride(3);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ add_source_parameters(param, semantic, false, NULL);
+
+ source.prepareToAppendValues();
+
+ for (int i = 0; i < tot; i++) {
+ source.appendValues(*v, *(v + 1), *(v + 2));
+ v += 3;
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+
+ std::string AnimationExporter::create_interpolation_source(FCurve *fcu, const std::string& anim_id, const char *axis_name, bool *has_tangents)
+ {
+ std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
+
+ COLLADASW::NameSource source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(fcu->totvert);
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("INTERPOLATION");
+
+ source.prepareToAppendValues();
+
+ *has_tangents = false;
+
+ for (unsigned int i = 0; i < fcu->totvert; i++) {
+ if (fcu->bezt[i].ipo==BEZT_IPO_BEZ) {
+ source.appendValues(BEZIER_NAME);
+ *has_tangents = true;
+ } else if (fcu->bezt[i].ipo==BEZT_IPO_CONST) {
+ source.appendValues(STEP_NAME);
+ } else { // BEZT_IPO_LIN
+ source.appendValues(LINEAR_NAME);
+ }
+ }
+ // unsupported? -- HERMITE, CARDINAL, BSPLINE, NURBS
+
+ source.finish();
+
+ return source_id;
+ }
+
+ std::string AnimationExporter::fake_interpolation_source(int tot, const std::string& anim_id, const char *axis_name)
+ {
+ std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
+
+ COLLADASW::NameSource source(mSW);
+ source.setId(source_id);
+ source.setArrayId(source_id + ARRAY_ID_SUFFIX);
+ source.setAccessorCount(tot);
+ source.setAccessorStride(1);
+
+ COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
+ param.push_back("INTERPOLATION");
+
+ source.prepareToAppendValues();
+
+ for (int i = 0; i < tot; i++) {
+ source.appendValues(LINEAR_NAME);
+ }
+
+ source.finish();
+
+ return source_id;
+ }
+
+ // for rotation, axis name is always appended and the value of append_axis is ignored
+ std::string AnimationExporter::get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
+ {
+ std::string tm_name;
+
+ // when given rna_path, determine tm_type from it
+ if (rna_path) {
+ char *name = extract_transform_name(rna_path);
+
+ if (!strcmp(name, "rotation_euler"))
+ tm_type = 0;
+ else if (!strcmp(name, "rotation_quaternion"))
+ tm_type = 1;
+ else if (!strcmp(name, "scale"))
+ tm_type = 2;
+ else if (!strcmp(name, "location"))
+ tm_type = 3;
+ else
+ tm_type = -1;
+ }
+
+ switch (tm_type) {
+ case 0:
+ return std::string("rotation_euler.") + std::string(axis_name) + ".ANGLE";
+ case 1:
+ return std::string("rotation_quaternion.") + std::string(axis_name) + ".ANGLE";
+ case 2:
+ tm_name = "scale";
+ break;
+ case 3:
+ tm_name = "location";
+ break;
+ default:
+ tm_name = "";
+ break;
+ }
+
+ if (tm_name.size()) {
+ if (append_axis)
+ return tm_name + std::string(".") + std::string(axis_name);
+ else
+ return tm_name;
+ }
+
+ return std::string("");
+ }
+
+ char* AnimationExporter::extract_transform_name(char *rna_path)
+ {
+ char *dot = strrchr(rna_path, '.');
+ return dot ? (dot + 1) : rna_path;
+ }
+
+ void AnimationExporter::find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name)
+ {
+ FCurve *fcu= (FCurve*)ob->adt->action->curves.first;
+
+ for (; fcu; fcu = fcu->next) {
+ if (prefix && strncmp(prefix, fcu->rna_path, strlen(prefix)))
+ continue;
+
+ char *name = extract_transform_name(fcu->rna_path);
+ if (!strcmp(name, tm_name)) {
+ for (unsigned int i = 0; i < fcu->totvert; i++) {
+ float f = fcu->bezt[i].vec[1][0]; //
+ if (std::find(fra.begin(), fra.end(), f) == fra.end())
+ fra.push_back(f);
+ }
+ }
+ }
+
+ // keep the keys in ascending order
+ std::sort(fra.begin(), fra.end());
+ }
+
+ void AnimationExporter::find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode)
+ {
+ if (rotmode > 0)
+ find_frames(ob, fra, prefix, "rotation_euler");
+ else if (rotmode == ROT_MODE_QUAT)
+ find_frames(ob, fra, prefix, "rotation_quaternion");
+ /*else if (rotmode == ROT_MODE_AXISANGLE)
+ ;*/
+ }
+
+ // enable fcurves driving a specific bone, disable all the rest
+ // if bone_name = NULL enable all fcurves
+ void AnimationExporter::enable_fcurves(bAction *act, char *bone_name)
+ {
+ FCurve *fcu;
+ char prefix[200];
+
+ if (bone_name)
+ BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name);
+
+ for (fcu = (FCurve*)act->curves.first; fcu; fcu = fcu->next) {
+ if (bone_name) {
+ if (!strncmp(fcu->rna_path, prefix, strlen(prefix)))
+ fcu->flag &= ~FCURVE_DISABLED;
+ else
+ fcu->flag |= FCURVE_DISABLED;
+ }
+ else {
+ fcu->flag &= ~FCURVE_DISABLED;
+ }
+ }
+ }
+
+ bool AnimationExporter::hasAnimations(Scene *sce)
+ {
+ Base *base= (Base*) sce->base.first;
+ while(base) {
+ Object *ob = base->object;
+
+ FCurve *fcu = 0;
+ if(ob->adt && ob->adt->action)
+ fcu = (FCurve*)ob->adt->action->curves.first;
+
+ //The Scene has animations if object type is armature or object has f-curve
+ if ((ob->type == OB_ARMATURE && ob->data) || fcu) {
+ return true;
+ }
+ base= base->next;
+ }
+ return false;
+ }
diff --git a/source/blender/collada/AnimationExporter.h b/source/blender/collada/AnimationExporter.h
new file mode 100644
index 00000000000..0368e34dc42
--- /dev/null
+++ b/source/blender/collada/AnimationExporter.h
@@ -0,0 +1,142 @@
+/*
+ * $Id: DocumentExporter.cpp 36898 2011-05-25 17:14:31Z phabtar $
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Jan Diederich, Tod Liverseed.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+extern "C"
+{
+#include "DNA_scene_types.h"
+#include "DNA_object_types.h"
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_curve_types.h"
+#include "DNA_armature_types.h"
+
+#include "BKE_DerivedMesh.h"
+#include "BKE_fcurve.h"
+#include "BKE_animsys.h"
+#ifdef NAN_BUILDINFO
+extern char build_rev[];
+#endif
+}
+
+#include "MEM_guardedalloc.h"
+
+#include "BKE_action.h" // pose functions
+#include "BKE_armature.h"
+#include "BKE_object.h"
+
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_listbase.h"
+
+#include "RNA_access.h"
+
+#include "COLLADASWSource.h"
+#include "COLLADASWInstanceGeometry.h"
+#include "COLLADASWInputList.h"
+#include "COLLADASWPrimitves.h"
+#include "COLLADASWVertices.h"
+#include "COLLADASWLibraryAnimations.h"
+#include "COLLADASWParamTemplate.h"
+#include "COLLADASWParamBase.h"
+#include "COLLADASWSampler.h"
+#include "COLLADASWConstants.h"
+#include "COLLADASWBaseInputElement.h"
+
+#include "collada_internal.h"
+
+#include <vector>
+#include <algorithm> // std::find
+
+class AnimationExporter: COLLADASW::LibraryAnimations
+{
+private:
+ Scene *scene;
+ COLLADASW::StreamWriter *sw;
+
+public:
+
+ AnimationExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryAnimations(sw) { this->sw = sw; }
+
+
+ void exportAnimations(Scene *sce);
+
+ // called for each exported object
+ void operator() (Object *ob);
+
+protected:
+
+ void dae_animation(Object* ob, FCurve *fcu, char* transformName);
+
+ void write_bone_animation(Object *ob_arm, Bone *bone);
+
+ void sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type);
+
+ void sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm, bPoseChannel *pChan);
+
+ // dae_bone_animation -> add_bone_animation
+ // (blend this into dae_bone_animation)
+ void dae_bone_animation(std::vector<float> &fra, float *v, int tm_type, int axis, std::string ob_name, std::string bone_name);
+
+ float convert_time(float frame);
+
+ float convert_angle(float angle);
+
+ std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic);
+
+ void add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
+ COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis);
+
+ void get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length);
+
+ std::string create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name);
+
+ std::string create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name);
+
+ std::string create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name);
+
+ std::string create_xyz_source(float *v, int tot, const std::string& anim_id);
+
+ std::string create_interpolation_source(FCurve *fcu, const std::string& anim_id, const char *axis_name, bool *has_tangents);
+
+ std::string fake_interpolation_source(int tot, const std::string& anim_id, const char *axis_name);
+ // for rotation, axis name is always appended and the value of append_axis is ignored
+ std::string get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis);
+
+ void find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name);
+
+ void find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode);
+
+ // enable fcurves driving a specific bone, disable all the rest
+ // if bone_name = NULL enable all fcurves
+ void enable_fcurves(bAction *act, char *bone_name);
+
+ bool hasAnimations(Scene *sce);
+
+ char* extract_transform_name(char *rna_path);
+
+ std::string getObjectBoneName ( Object *ob,const FCurve * fcu);
+}; \ No newline at end of file
diff --git a/source/blender/collada/CMakeLists.txt b/source/blender/collada/CMakeLists.txt
index a7e7c973f36..7c43c09bc12 100644
--- a/source/blender/collada/CMakeLists.txt
+++ b/source/blender/collada/CMakeLists.txt
@@ -62,6 +62,7 @@ endif()
set(SRC
AnimationImporter.cpp
+ AnimationExporter.cpp
ArmatureExporter.cpp
ArmatureImporter.cpp
CameraExporter.cpp
@@ -84,6 +85,7 @@ set(SRC
collada_utils.cpp
AnimationImporter.h
+ AnimationExporter.h
ArmatureExporter.h
ArmatureImporter.h
CameraExporter.h
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index 00daac60281..0bdf41f15eb 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -114,6 +114,7 @@ extern char build_rev[];
#include "TransformWriter.h"
#include "ArmatureExporter.h"
+#include "AnimationExporter.h"
#include "CameraExporter.h"
#include "EffectExporter.h"
#include "GeometryExporter.h"
@@ -298,636 +299,6 @@ public:
// TODO: it would be better to instantiate animations rather than create a new one per object
// COLLADA allows this through multiple <channel>s in <animation>.
// For this to work, we need to know objects that use a certain action.
-class AnimationExporter: COLLADASW::LibraryAnimations
-{
- Scene *scene;
- COLLADASW::StreamWriter *sw;
-
-public:
-
- AnimationExporter(COLLADASW::StreamWriter *sw): COLLADASW::LibraryAnimations(sw) { this->sw = sw; }
-
-
-
- void exportAnimations(Scene *sce)
- {
- if(hasAnimations(sce)) {
- this->scene = sce;
-
- openLibrary();
-
- forEachObjectInScene(sce, *this);
-
- closeLibrary();
- }
- }
-
- // called for each exported object
- void operator() (Object *ob)
- {
- if (!ob->adt || !ob->adt->action) return;
-
- FCurve *fcu = (FCurve*)ob->adt->action->curves.first;
-
- if (ob->type == OB_ARMATURE) {
- if (!ob->data) return;
-
- bArmature *arm = (bArmature*)ob->data;
- for (Bone *bone = (Bone*)arm->bonebase.first; bone; bone = bone->next)
- write_bone_animation(ob, bone);
- }
- else {
- while (fcu) {
- // TODO "rotation_quaternion" is also possible for objects (although euler is default)
- if ((!strcmp(fcu->rna_path, "location") || !strcmp(fcu->rna_path, "scale")) ||
- (!strcmp(fcu->rna_path, "rotation_euler") && ob->rotmode == ROT_MODE_EUL))
- dae_animation(fcu, id_name(ob));
-
- fcu = fcu->next;
- }
- }
- }
-
-protected:
-
- void dae_animation(FCurve *fcu, std::string ob_name)
- {
- const char *axis_names[] = {"X", "Y", "Z"};
- const char *axis_name = NULL;
- char anim_id[200];
-
- if (fcu->array_index < 3)
- axis_name = axis_names[fcu->array_index];
-
- BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(),
- fcu->rna_path, axis_names[fcu->array_index]);
-
- // check rna_path is one of: rotation, scale, location
-
- openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
-
- // create input source
- std::string input_id = create_source_from_fcurve(COLLADASW::InputSemantic::INPUT, fcu, anim_id, axis_name);
-
- // create output source
- std::string output_id = create_source_from_fcurve(COLLADASW::InputSemantic::OUTPUT, fcu, anim_id, axis_name);
-
- // create interpolations source
- std::string interpolation_id = create_interpolation_source(fcu->totvert, anim_id, axis_name);
-
- std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
- COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
- std::string empty;
- sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
- sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
-
- // this input is required
- sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
-
- addSampler(sampler);
-
- std::string target = translate_id(ob_name)
- + "/" + get_transform_sid(fcu->rna_path, -1, axis_name, true);
- addChannel(COLLADABU::URI(empty, sampler_id), target);
-
- closeAnimation();
- }
-
- void write_bone_animation(Object *ob_arm, Bone *bone)
- {
- if (!ob_arm->adt)
- return;
-
- for (int i = 0; i < 3; i++)
- sample_and_write_bone_animation(ob_arm, bone, i);
-
- for (Bone *child = (Bone*)bone->childbase.first; child; child = child->next)
- write_bone_animation(ob_arm, child);
- }
-
- void sample_and_write_bone_animation(Object *ob_arm, Bone *bone, int transform_type)
- {
- bArmature *arm = (bArmature*)ob_arm->data;
- int flag = arm->flag;
- std::vector<float> fra;
- char prefix[256];
-
- BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone->name);
-
- bPoseChannel *pchan = get_pose_channel(ob_arm->pose, bone->name);
- if (!pchan)
- return;
-
- switch (transform_type) {
- case 0:
- find_rotation_frames(ob_arm, fra, prefix, pchan->rotmode);
- break;
- case 1:
- find_frames(ob_arm, fra, prefix, "scale");
- break;
- case 2:
- find_frames(ob_arm, fra, prefix, "location");
- break;
- default:
- return;
- }
-
- // exit rest position
- if (flag & ARM_RESTPOS) {
- arm->flag &= ~ARM_RESTPOS;
- where_is_pose(scene, ob_arm);
- }
-
- if (fra.size()) {
- float *v = (float*)MEM_callocN(sizeof(float) * 3 * fra.size(), "temp. anim frames");
- sample_animation(v, fra, transform_type, bone, ob_arm);
-
- if (transform_type == 0) {
- // write x, y, z curves separately if it is rotation
- float *c = (float*)MEM_callocN(sizeof(float) * fra.size(), "temp. anim frames");
- for (int i = 0; i < 3; i++) {
- for (unsigned int j = 0; j < fra.size(); j++)
- c[j] = v[j * 3 + i];
-
- dae_bone_animation(fra, c, transform_type, i, id_name(ob_arm), bone->name);
- }
- MEM_freeN(c);
- }
- else {
- // write xyz at once if it is location or scale
- dae_bone_animation(fra, v, transform_type, -1, id_name(ob_arm), bone->name);
- }
-
- MEM_freeN(v);
- }
-
- // restore restpos
- if (flag & ARM_RESTPOS)
- arm->flag = flag;
- where_is_pose(scene, ob_arm);
- }
-
- void sample_animation(float *v, std::vector<float> &frames, int type, Bone *bone, Object *ob_arm)
- {
- bPoseChannel *pchan, *parchan = NULL;
- bPose *pose = ob_arm->pose;
-
- pchan = get_pose_channel(pose, bone->name);
-
- if (!pchan)
- return;
-
- parchan = pchan->parent;
-
- enable_fcurves(ob_arm->adt->action, bone->name);
-
- std::vector<float>::iterator it;
- for (it = frames.begin(); it != frames.end(); it++) {
- float mat[4][4], ipar[4][4];
-
- float ctime = bsystem_time(scene, ob_arm, *it, 0.0f);
-
- BKE_animsys_evaluate_animdata(&ob_arm->id, ob_arm->adt, *it, ADT_RECALC_ANIM);
- where_is_pose_bone(scene, ob_arm, pchan, ctime, 1);
-
- // compute bone local mat
- if (bone->parent) {
- invert_m4_m4(ipar, parchan->pose_mat);
- mul_m4_m4m4(mat, pchan->pose_mat, ipar);
- }
- else
- copy_m4_m4(mat, pchan->pose_mat);
-
- switch (type) {
- case 0:
- mat4_to_eul(v, mat);
- break;
- case 1:
- mat4_to_size(v, mat);
- break;
- case 2:
- copy_v3_v3(v, mat[3]);
- break;
- }
-
- v += 3;
- }
-
- enable_fcurves(ob_arm->adt->action, NULL);
- }
-
- // dae_bone_animation -> add_bone_animation
- // (blend this into dae_bone_animation)
- void dae_bone_animation(std::vector<float> &fra, float *v, int tm_type, int axis, std::string ob_name, std::string bone_name)
- {
- const char *axis_names[] = {"X", "Y", "Z"};
- const char *axis_name = NULL;
- char anim_id[200];
- bool is_rot = tm_type == 0;
-
- if (!fra.size())
- return;
-
- char rna_path[200];
- BLI_snprintf(rna_path, sizeof(rna_path), "pose.bones[\"%s\"].%s", bone_name.c_str(),
- tm_type == 0 ? "rotation_quaternion" : (tm_type == 1 ? "scale" : "location"));
-
- if (axis > -1)
- axis_name = axis_names[axis];
-
- std::string transform_sid = get_transform_sid(NULL, tm_type, axis_name, false);
-
- BLI_snprintf(anim_id, sizeof(anim_id), "%s_%s_%s", (char*)translate_id(ob_name).c_str(),
- (char*)translate_id(bone_name).c_str(), (char*)transform_sid.c_str());
-
- openAnimation(anim_id, COLLADABU::Utils::EMPTY_STRING);
-
- // create input source
- std::string input_id = create_source_from_vector(COLLADASW::InputSemantic::INPUT, fra, is_rot, anim_id, axis_name);
-
- // create output source
- std::string output_id;
- if (axis == -1)
- output_id = create_xyz_source(v, fra.size(), anim_id);
- else
- output_id = create_source_from_array(COLLADASW::InputSemantic::OUTPUT, v, fra.size(), is_rot, anim_id, axis_name);
-
- // create interpolations source
- std::string interpolation_id = create_interpolation_source(fra.size(), anim_id, axis_name);
-
- std::string sampler_id = std::string(anim_id) + SAMPLER_ID_SUFFIX;
- COLLADASW::LibraryAnimations::Sampler sampler(sw, sampler_id);
- std::string empty;
- sampler.addInput(COLLADASW::InputSemantic::INPUT, COLLADABU::URI(empty, input_id));
- sampler.addInput(COLLADASW::InputSemantic::OUTPUT, COLLADABU::URI(empty, output_id));
-
- // TODO create in/out tangents source
-
- // this input is required
- sampler.addInput(COLLADASW::InputSemantic::INTERPOLATION, COLLADABU::URI(empty, interpolation_id));
-
- addSampler(sampler);
-
- std::string target = translate_id(ob_name + "_" + bone_name) + "/" + transform_sid;
- addChannel(COLLADABU::URI(empty, sampler_id), target);
-
- closeAnimation();
- }
-
- float convert_time(float frame)
- {
- return FRA2TIME(frame);
- }
-
- float convert_angle(float angle)
- {
- return COLLADABU::Math::Utils::radToDegF(angle);
- }
-
- std::string get_semantic_suffix(COLLADASW::InputSemantic::Semantics semantic)
- {
- switch(semantic) {
- case COLLADASW::InputSemantic::INPUT:
- return INPUT_SOURCE_ID_SUFFIX;
- case COLLADASW::InputSemantic::OUTPUT:
- return OUTPUT_SOURCE_ID_SUFFIX;
- case COLLADASW::InputSemantic::INTERPOLATION:
- return INTERPOLATION_SOURCE_ID_SUFFIX;
- case COLLADASW::InputSemantic::IN_TANGENT:
- return INTANGENT_SOURCE_ID_SUFFIX;
- case COLLADASW::InputSemantic::OUT_TANGENT:
- return OUTTANGENT_SOURCE_ID_SUFFIX;
- default:
- break;
- }
- return "";
- }
-
- void add_source_parameters(COLLADASW::SourceBase::ParameterNameList& param,
- COLLADASW::InputSemantic::Semantics semantic, bool is_rot, const char *axis)
- {
- switch(semantic) {
- case COLLADASW::InputSemantic::INPUT:
- param.push_back("TIME");
- break;
- case COLLADASW::InputSemantic::OUTPUT:
- if (is_rot) {
- param.push_back("ANGLE");
- }
- else {
- if (axis) {
- param.push_back(axis);
- }
- else {
- param.push_back("X");
- param.push_back("Y");
- param.push_back("Z");
- }
- }
- break;
- case COLLADASW::InputSemantic::IN_TANGENT:
- case COLLADASW::InputSemantic::OUT_TANGENT:
- param.push_back("X");
- param.push_back("Y");
- break;
- default:
- break;
- }
- }
-
- void get_source_values(BezTriple *bezt, COLLADASW::InputSemantic::Semantics semantic, bool rotation, float *values, int *length)
- {
- switch (semantic) {
- case COLLADASW::InputSemantic::INPUT:
- *length = 1;
- values[0] = convert_time(bezt->vec[1][0]);
- break;
- case COLLADASW::InputSemantic::OUTPUT:
- *length = 1;
- if (rotation) {
- values[0] = convert_angle(bezt->vec[1][1]);
- }
- else {
- values[0] = bezt->vec[1][1];
- }
- break;
- case COLLADASW::InputSemantic::IN_TANGENT:
- case COLLADASW::InputSemantic::OUT_TANGENT:
- // XXX
- *length = 2;
- break;
- default:
- *length = 0;
- break;
- }
- }
-
- std::string create_source_from_fcurve(COLLADASW::InputSemantic::Semantics semantic, FCurve *fcu, const std::string& anim_id, const char *axis_name)
- {
- std::string source_id = anim_id + get_semantic_suffix(semantic);
-
- //bool is_rotation = !strcmp(fcu->rna_path, "rotation");
- bool is_rotation = false;
-
- if (strstr(fcu->rna_path, "rotation")) is_rotation = true;
-
- COLLADASW::FloatSourceF source(mSW);
- source.setId(source_id);
- source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(fcu->totvert);
- source.setAccessorStride(1);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- add_source_parameters(param, semantic, is_rotation, axis_name);
-
- source.prepareToAppendValues();
-
- for (unsigned int i = 0; i < fcu->totvert; i++) {
- float values[3]; // be careful!
- int length = 0;
-
- get_source_values(&fcu->bezt[i], semantic, is_rotation, values, &length);
- for (int j = 0; j < length; j++)
- source.appendValues(values[j]);
- }
-
- source.finish();
-
- return source_id;
- }
-
- std::string create_source_from_array(COLLADASW::InputSemantic::Semantics semantic, float *v, int tot, bool is_rot, const std::string& anim_id, const char *axis_name)
- {
- std::string source_id = anim_id + get_semantic_suffix(semantic);
-
- COLLADASW::FloatSourceF source(mSW);
- source.setId(source_id);
- source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(tot);
- source.setAccessorStride(1);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- add_source_parameters(param, semantic, is_rot, axis_name);
-
- source.prepareToAppendValues();
-
- for (int i = 0; i < tot; i++) {
- float val = v[i];
- if (semantic == COLLADASW::InputSemantic::INPUT)
- val = convert_time(val);
- else if (is_rot)
- val = convert_angle(val);
- source.appendValues(val);
- }
-
- source.finish();
-
- return source_id;
- }
-
- std::string create_source_from_vector(COLLADASW::InputSemantic::Semantics semantic, std::vector<float> &fra, bool is_rot, const std::string& anim_id, const char *axis_name)
- {
- std::string source_id = anim_id + get_semantic_suffix(semantic);
-
- COLLADASW::FloatSourceF source(mSW);
- source.setId(source_id);
- source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(fra.size());
- source.setAccessorStride(1);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- add_source_parameters(param, semantic, is_rot, axis_name);
-
- source.prepareToAppendValues();
-
- std::vector<float>::iterator it;
- for (it = fra.begin(); it != fra.end(); it++) {
- float val = *it;
- if (semantic == COLLADASW::InputSemantic::INPUT)
- val = convert_time(val);
- else if (is_rot)
- val = convert_angle(val);
- source.appendValues(val);
- }
-
- source.finish();
-
- return source_id;
- }
-
- // only used for sources with OUTPUT semantic
- std::string create_xyz_source(float *v, int tot, const std::string& anim_id)
- {
- COLLADASW::InputSemantic::Semantics semantic = COLLADASW::InputSemantic::OUTPUT;
- std::string source_id = anim_id + get_semantic_suffix(semantic);
-
- COLLADASW::FloatSourceF source(mSW);
- source.setId(source_id);
- source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(tot);
- source.setAccessorStride(3);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- add_source_parameters(param, semantic, false, NULL);
-
- source.prepareToAppendValues();
-
- for (int i = 0; i < tot; i++) {
- source.appendValues(*v, *(v + 1), *(v + 2));
- v += 3;
- }
-
- source.finish();
-
- return source_id;
- }
-
- std::string create_interpolation_source(int tot, const std::string& anim_id, const char *axis_name)
- {
- std::string source_id = anim_id + get_semantic_suffix(COLLADASW::InputSemantic::INTERPOLATION);
-
- COLLADASW::NameSource source(mSW);
- source.setId(source_id);
- source.setArrayId(source_id + ARRAY_ID_SUFFIX);
- source.setAccessorCount(tot);
- source.setAccessorStride(1);
-
- COLLADASW::SourceBase::ParameterNameList &param = source.getParameterNameList();
- param.push_back("INTERPOLATION");
-
- source.prepareToAppendValues();
-
- for (int i = 0; i < tot; i++) {
- source.appendValues(LINEAR_NAME);
- }
-
- source.finish();
-
- return source_id;
- }
-
- // for rotation, axis name is always appended and the value of append_axis is ignored
- std::string get_transform_sid(char *rna_path, int tm_type, const char *axis_name, bool append_axis)
- {
- std::string tm_name;
-
- // when given rna_path, determine tm_type from it
- if (rna_path) {
- char *name = extract_transform_name(rna_path);
-
- if (strstr(name, "rotation"))
- tm_type = 0;
- else if (!strcmp(name, "scale"))
- tm_type = 1;
- else if (!strcmp(name, "location"))
- tm_type = 2;
- else
- tm_type = -1;
- }
-
- switch (tm_type) {
- case 0:
- return std::string("rotation") + std::string(axis_name) + ".ANGLE";
- case 1:
- tm_name = "scale";
- break;
- case 2:
- tm_name = "location";
- break;
- default:
- tm_name = "";
- break;
- }
-
- if (tm_name.size()) {
- if (append_axis)
- return tm_name + std::string(".") + std::string(axis_name);
- else
- return tm_name;
- }
-
- return std::string("");
- }
-
- char *extract_transform_name(char *rna_path)
- {
- char *dot = strrchr(rna_path, '.');
- return dot ? (dot + 1) : rna_path;
- }
-
- void find_frames(Object *ob, std::vector<float> &fra, const char *prefix, const char *tm_name)
- {
- FCurve *fcu= (FCurve*)ob->adt->action->curves.first;
-
- for (; fcu; fcu = fcu->next) {
- if (prefix && strncmp(prefix, fcu->rna_path, strlen(prefix)))
- continue;
-
- char *name = extract_transform_name(fcu->rna_path);
- if (!strcmp(name, tm_name)) {
- for (unsigned int i = 0; i < fcu->totvert; i++) {
- float f = fcu->bezt[i].vec[1][0];
- if (std::find(fra.begin(), fra.end(), f) == fra.end())
- fra.push_back(f);
- }
- }
- }
-
- // keep the keys in ascending order
- std::sort(fra.begin(), fra.end());
- }
-
- void find_rotation_frames(Object *ob, std::vector<float> &fra, const char *prefix, int rotmode)
- {
- if (rotmode > 0)
- find_frames(ob, fra, prefix, "rotation_euler");
- else if (rotmode == ROT_MODE_QUAT)
- find_frames(ob, fra, prefix, "rotation_quaternion");
- /*else if (rotmode == ROT_MODE_AXISANGLE)
- ;*/
- }
-
- // enable fcurves driving a specific bone, disable all the rest
- // if bone_name = NULL enable all fcurves
- void enable_fcurves(bAction *act, char *bone_name)
- {
- FCurve *fcu;
- char prefix[200];
-
- if (bone_name)
- BLI_snprintf(prefix, sizeof(prefix), "pose.bones[\"%s\"]", bone_name);
-
- for (fcu = (FCurve*)act->curves.first; fcu; fcu = fcu->next) {
- if (bone_name) {
- if (!strncmp(fcu->rna_path, prefix, strlen(prefix)))
- fcu->flag &= ~FCURVE_DISABLED;
- else
- fcu->flag |= FCURVE_DISABLED;
- }
- else {
- fcu->flag &= ~FCURVE_DISABLED;
- }
- }
- }
-
- bool hasAnimations(Scene *sce)
- {
- Base *base= (Base*) sce->base.first;
- while(base) {
- Object *ob = base->object;
-
- FCurve *fcu = 0;
- if(ob->adt && ob->adt->action)
- fcu = (FCurve*)ob->adt->action->curves.first;
-
- if ((ob->type == OB_ARMATURE && ob->data) || fcu) {
- return true;
- }
- base= base->next;
- }
- return false;
- }
-};
void DocumentExporter::exportCurrentScene(Scene *sce, const char* filename)
{
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 9145cc2b79d..9eb9e3ecd9a 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -38,7 +38,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-
+#include "BKE_library.h"
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
@@ -515,12 +515,34 @@ void ANIM_fcurve_delete_from_animdata (bAnimContext *ac, AnimData *adt, FCurve *
* - Drivers
* - TODO... some others?
*/
- if (fcu->grp)
- action_groups_remove_channel(adt->action, fcu);
- else if ((ac) && (ac->datatype == ANIMCONT_DRIVERS))
+ if ((ac) && (ac->datatype == ANIMCONT_DRIVERS)) {
+ /* driver F-Curve */
BLI_remlink(&adt->drivers, fcu);
- else if (adt->action)
- BLI_remlink(&adt->action->curves, fcu);
+ }
+ else if (adt->action) {
+ /* remove from group or action, whichever one "owns" the F-Curve */
+ if (fcu->grp)
+ action_groups_remove_channel(adt->action, fcu);
+ else
+ BLI_remlink(&adt->action->curves, fcu);
+
+ /* if action has no more F-Curves as a result of this, unlink it from
+ * AnimData if it did not come from a NLA Strip being tweaked.
+ *
+ * This is done so that we don't have dangling Object+Action entries in
+ * channel list that are empty, and linger around long after the data they
+ * are for has disappeared (and probably won't come back).
+ */
+ // XXX: does everybody always want this?
+ /* XXX: there's a problem where many actions could build up in the file if multiple
+ * full add/delete cycles are performed on the same objects, but assume that this is rare
+ */
+ if ((adt->action->curves.first == NULL) && (adt->flag & ADT_NLA_EDIT_ON)==0)
+ {
+ id_us_min(&adt->action->id);
+ adt->action = NULL;
+ }
+ }
/* free the F-Curve itself */
free_fcurve(fcu);
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index c6e55427034..1fb2317cdbb 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -1500,3 +1500,14 @@ void ED_marker_keymap(wmKeyConfig *keyconf)
WM_keymap_add_item(keymap, "MARKER_OT_camera_bind", BKEY, KM_PRESS, KM_CTRL, 0);
#endif
}
+
+/* to be called from animation editor keymaps, see note below */
+void ED_marker_keymap_animedit_conflictfree(wmKeyMap *keymap)
+{
+ /* duplicate of some marker-hotkeys but without the bounds checking
+ * since these are handy to be able to do unrestricted and won't conflict
+ * with primary function hotkeys (Usability tweak [#27469])
+ */
+ WM_keymap_add_item(keymap, "MARKER_OT_add", MKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "MARKER_OT_rename", MKEY, KM_PRESS, KM_CTRL, 0);
+}
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index 954928fc486..8197d6b25dd 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -604,7 +604,7 @@ static void draw_modifier__stepped(uiLayout *layout, ID *id, FModifier *fcm, sho
void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifiers, FModifier *fcm)
{
FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
- uiLayout *box, *row, *subrow;
+ uiLayout *box, *row, *subrow, *col;
uiBlock *block;
uiBut *but;
short width= 314;
@@ -622,7 +622,7 @@ void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifie
block= uiLayoutGetBlock(row); // err...
/* left-align -------------------------------------------- */
- subrow= uiLayoutRow(row, 0);
+ subrow= uiLayoutRow(row, 1);
uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_LEFT);
uiBlockSetEmboss(block, UI_EMBOSSN);
@@ -640,7 +640,7 @@ void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifie
uiItemL(subrow, "<Unknown Modifier>", ICON_NONE);
/* right-align ------------------------------------------- */
- subrow= uiLayoutRow(row, 0);
+ subrow= uiLayoutRow(row, 1);
uiLayoutSetAlignment(subrow, UI_LAYOUT_ALIGN_RIGHT);
@@ -694,6 +694,44 @@ void ANIM_uiTemplate_fmodifier_draw (uiLayout *layout, ID *id, ListBase *modifie
default: /* unknown type */
break;
}
+
+ /* one last panel below this: FModifier range */
+ // TODO: experiment with placement of this
+ {
+ box = uiLayoutBox(layout);
+
+ /* restricted range ----------------------------------------------------- */
+ col = uiLayoutColumn(box, 1);
+
+ /* top row: use restricted range */
+ row= uiLayoutRow(col, 1);
+ uiItemR(row, &ptr, "use_restricted_range", 0, NULL, ICON_NONE);
+
+ if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
+ /* second row: settings */
+ row = uiLayoutRow(col, 1);
+
+ uiItemR(row, &ptr, "frame_start", 0, "Start", ICON_NONE);
+ uiItemR(row, &ptr, "frame_end", 0, "End", ICON_NONE);
+
+ /* third row: blending influence */
+ row = uiLayoutRow(col, 1);
+
+ uiItemR(row, &ptr, "blend_in", 0, "In", ICON_NONE);
+ uiItemR(row, &ptr, "blend_out", 0, "Out", ICON_NONE);
+ }
+
+ /* influence -------------------------------------------------------------- */
+ col = uiLayoutColumn(box, 1);
+
+ /* top row: use influence */
+ uiItemR(col, &ptr, "use_influence", 0, NULL, ICON_NONE);
+
+ if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) {
+ /* second row: influence value */
+ uiItemR(col, &ptr, "influence", 0, NULL, ICON_NONE);
+ }
+ }
}
}
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index f111339b963..e2afda04d30 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -111,7 +111,7 @@ void delete_fcurve_keys(FCurve *fcu)
{
int i;
- if(fcu->bezt==NULL) /* ignore baked curves */
+ if (fcu->bezt==NULL) /* ignore baked curves */
return;
/* Delete selected BezTriples */
@@ -124,7 +124,7 @@ void delete_fcurve_keys(FCurve *fcu)
}
/* Free the array of BezTriples if there are not keyframes */
- if(fcu->totvert == 0)
+ if (fcu->totvert == 0)
clear_fcurve_keys(fcu);
}
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index c525c9af626..69e7c4eb73a 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -224,6 +224,7 @@ static int add_empty_ks_path_exec (bContext *C, wmOperator *op)
ksp->groupmode= KSP_GROUP_KSNAME; // XXX?
ksp->idtype= ID_OB;
+ ksp->flag= KSP_FLAG_WHOLE_ARRAY;
return OPERATOR_FINISHED;
}
@@ -782,19 +783,19 @@ void ANIM_keying_sets_menu_setup (bContext *C, const char title[], const char op
* - these are listed in the order in which they were defined for the active scene
*/
if (scene->keyingsets.first) {
- for (ks= scene->keyingsets.first; ks; ks= ks->next) {
+ for (ks= scene->keyingsets.first; ks; ks=ks->next, i++) {
if (ANIM_keyingset_context_ok_poll(C, ks))
- uiItemIntO(layout, ks->name, ICON_NONE, op_name, "type", i++);
+ uiItemIntO(layout, ks->name, ICON_NONE, op_name, "type", i);
}
uiItemS(layout);
}
/* builtin Keying Sets */
i= -1;
- for (ks= builtin_keyingsets.first; ks; ks= ks->next) {
+ for (ks= builtin_keyingsets.first; ks; ks=ks->next, i--) {
/* only show KeyingSet if context is suitable */
if (ANIM_keyingset_context_ok_poll(C, ks))
- uiItemEnumO_value(layout, ks->name, ICON_NONE, op_name, "type", i--);
+ uiItemEnumO_value(layout, ks->name, ICON_NONE, op_name, "type", i);
}
uiPupMenuEnd(C, pup);
diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c
index 8176aa5893b..fa5fecbd9d0 100644
--- a/source/blender/editors/armature/poseobject.c
+++ b/source/blender/editors/armature/poseobject.c
@@ -1002,6 +1002,14 @@ static int pose_paste_exec (bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
+ /* if selOnly option is enabled, if user hasn't selected any bones,
+ * just go back to default behaviour to be more in line with other pose tools
+ */
+ if (selOnly) {
+ if (CTX_DATA_COUNT(C, selected_pose_bones) == 0)
+ selOnly = 0;
+ }
+
/* Safely merge all of the channels in the buffer pose into any existing pose */
for (chan= g_posebuf->chanbase.first; chan; chan=chan->next) {
if (chan->flag & POSE_KEY) {
@@ -1169,7 +1177,7 @@ void POSE_OT_paste (wmOperatorType *ot)
/* properties */
RNA_def_boolean(ot->srna, "flipped", 0, "Flipped on X-Axis", "Paste the stored pose flipped on to current pose");
- RNA_def_boolean(ot->srna, "selected_mask", 0, "On Selected Only", "Only paste the stored pose on to selected bones in the current pose");
+ RNA_def_boolean(ot->srna, "selected_mask", 1, "On Selected Only", "Only paste the stored pose on to selected bones in the current pose");
}
/* ********************************************** */
diff --git a/source/blender/editors/include/ED_markers.h b/source/blender/editors/include/ED_markers.h
index f804e052301..a8e91add348 100644
--- a/source/blender/editors/include/ED_markers.h
+++ b/source/blender/editors/include/ED_markers.h
@@ -34,6 +34,7 @@
#define ED_MARKERS_H
struct wmKeyConfig;
+struct wmKeyMap;
struct bContext;
struct bAnimContext;
struct Scene;
@@ -72,6 +73,9 @@ void ED_operatortypes_marker(void);
/* called in screen_ops.c:ED_keymap_screen() */
void ED_marker_keymap(struct wmKeyConfig *keyconf);
+/* called in animation editors - keymap defines */
+void ED_marker_keymap_animedit_conflictfree(struct wmKeyMap *keymap);
+
/* debugging only */
void debug_markers_print_list(struct ListBase *markers);
diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c
index 6527e0140b8..bbabe968bb2 100644
--- a/source/blender/editors/interface/resources.c
+++ b/source/blender/editors/interface/resources.c
@@ -663,7 +663,7 @@ void ui_theme_init_default(void)
SETCOL(btheme->tipo.handle_vertex, 0, 0, 0, 255);
SETCOL(btheme->tipo.handle_vertex_select, 255, 133, 0, 255);
- btheme->tipo.handle_vertex_size= 3;
+ btheme->tipo.handle_vertex_size= 4;
SETCOL(btheme->tipo.ds_channel, 82, 96, 110, 255);
SETCOL(btheme->tipo.ds_subchannel, 124, 137, 150, 255);
diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c
index 450bd70a568..a3df25824a4 100644
--- a/source/blender/editors/object/object_constraint.c
+++ b/source/blender/editors/object/object_constraint.c
@@ -567,7 +567,8 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int
}
con = constraints_findByName(list, constraint_name);
- printf("constraint found = %p, %s\n", (void *)con, (con)?con->name:"<Not found>");
+ //if (G.f & G_DEBUG)
+ //printf("constraint found = %p, %s\n", (void *)con, (con)?con->name:"<Not found>");
if (con && (type != 0) && (con->type != type))
con = NULL;
diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c
index 6c3f80cda41..2ccad308676 100644
--- a/source/blender/editors/space_action/action_ops.c
+++ b/source/blender/editors/space_action/action_ops.c
@@ -40,6 +40,7 @@
#include "BLI_blenlib.h"
#include "ED_anim_api.h"
+#include "ED_markers.h"
#include "ED_transform.h"
#include "action_intern.h"
@@ -162,7 +163,7 @@ static void action_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap)
/* menu + set setting */
WM_keymap_add_item(keymap, "ACTION_OT_handle_type", VKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "ACTION_OT_interpolation_type", TKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "ACTION_OT_interpolation_type", TKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "ACTION_OT_extrapolation_type", EKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "ACTION_OT_keyframe_type", RKEY, KM_PRESS, 0, 0);
@@ -193,6 +194,9 @@ static void action_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap)
/* transform system */
transform_keymap_for_space(keyconf, keymap, SPACE_ACTION);
+
+ /* special markers hotkeys for anim editors: see note in definition of this function */
+ ED_marker_keymap_animedit_conflictfree(keymap);
}
/* --------------- */
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index fb1144b4fa8..3073ff13075 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -472,7 +472,7 @@ static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar *
uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
}
- uiItemR(col, &dtar_ptr, "use_local_space_transform", 0, NULL, ICON_NONE);
+ uiItemR(col, &dtar_ptr, "transform_space", 0, NULL, ICON_NONE);
col= uiLayoutColumn(layout, 1);
uiTemplateAnyID(col, &dtar2_ptr, "id", "id_type", "Ob/Bone 2:");
@@ -484,7 +484,7 @@ static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar *
uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
}
- uiItemR(col, &dtar2_ptr, "use_local_space_transform", 0, NULL, ICON_NONE);
+ uiItemR(col, &dtar2_ptr, "transform_space", 0, NULL, ICON_NONE);
}
/* settings for 'transform channel' driver variable type */
@@ -493,7 +493,7 @@ static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar
DriverTarget *dtar= &dvar->targets[0];
Object *ob = (Object *)dtar->id;
PointerRNA dtar_ptr;
- uiLayout *col, *row;
+ uiLayout *col, *subcol;
/* initialise RNA pointer to the target */
RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
@@ -509,9 +509,9 @@ static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar
uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
}
- row= uiLayoutRow(layout, 1);
- uiItemR(row, &dtar_ptr, "transform_type", 0, "", ICON_NONE);
- uiItemR(row, &dtar_ptr, "use_local_space_transform", 0, NULL, ICON_NONE);
+ subcol= uiLayoutColumn(layout, 1);
+ uiItemR(subcol, &dtar_ptr, "transform_type", 0, NULL, ICON_NONE);
+ uiItemR(subcol, &dtar_ptr, "transform_space", 0, "Space", ICON_NONE);
}
/* driver settings for active F-Curve (only for 'Drivers' mode) */
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 962cadba1f3..0da03832d15 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -2248,7 +2248,7 @@ void GRAPH_OT_fmodifier_paste (wmOperatorType *ot)
/* api callbacks */
ot->exec= graph_fmodifier_paste_exec;
- ot->poll= graphop_editable_keyframes_poll;
+ ot->poll= graphop_active_fcurve_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 03cc8bb9e80..0d7cdf94bc7 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -46,6 +46,7 @@
#include "UI_view2d.h"
#include "ED_anim_api.h"
+#include "ED_markers.h"
#include "ED_screen.h"
#include "ED_transform.h"
@@ -361,7 +362,7 @@ static void graphedit_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap)
WM_keymap_add_item(keymap, "GRAPH_OT_handle_type", VKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "GRAPH_OT_interpolation_type", TKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_interpolation_type", TKEY, KM_PRESS, 0, 0);
/* destructive */
WM_keymap_add_item(keymap, "GRAPH_OT_clean", OKEY, KM_PRESS, 0, 0);
@@ -399,6 +400,9 @@ static void graphedit_keymap_keyframes (wmKeyConfig *keyconf, wmKeyMap *keymap)
/* transform system */
transform_keymap_for_space(keyconf, keymap, SPACE_IPO);
+
+ /* special markers hotkeys for anim editors: see note in definition of this function */
+ ED_marker_keymap_animedit_conflictfree(keymap);
}
/* --------------- */
diff --git a/source/blender/editors/space_logic/logic_window.c b/source/blender/editors/space_logic/logic_window.c
index 019ce2a714a..a45e7d39c76 100644
--- a/source/blender/editors/space_logic/logic_window.c
+++ b/source/blender/editors/space_logic/logic_window.c
@@ -3679,10 +3679,6 @@ static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
PointerRNA settings_ptr;
uiLayout *row;
- if(ob->type != OB_ARMATURE){
- uiItemL(layout, "Actuator only available for armatures", ICON_NONE);
- return;
- }
RNA_pointer_create((ID *)ob, &RNA_GameObjectSettings, ob, &settings_ptr);
row= uiLayoutRow(layout, 0);
@@ -3704,6 +3700,9 @@ static void draw_actuator_action(uiLayout *layout, PointerRNA *ptr)
uiItemR(row, ptr, "priority", 0, NULL, ICON_NONE);
row= uiLayoutRow(layout, 0);
+ uiItemR(row, ptr, "layer", 0, NULL, ICON_NONE);
+
+ row= uiLayoutRow(layout, 0);
uiItemPointerR(layout, ptr, "frame_property", &settings_ptr, "properties", NULL, ICON_NONE);
#ifdef __NLA_ACTION_BY_MOTION_ACTUATOR
diff --git a/source/blender/editors/space_nla/nla_ops.c b/source/blender/editors/space_nla/nla_ops.c
index 85dcf14adac..ea8e8961f02 100644
--- a/source/blender/editors/space_nla/nla_ops.c
+++ b/source/blender/editors/space_nla/nla_ops.c
@@ -45,6 +45,7 @@
#include "BKE_screen.h"
#include "ED_anim_api.h"
+#include "ED_markers.h"
#include "ED_screen.h"
#include "ED_transform.h"
@@ -262,6 +263,9 @@ static void nla_keymap_main (wmKeyConfig *keyconf, wmKeyMap *keymap)
/* transform system */
transform_keymap_for_space(keyconf, keymap, SPACE_NLA);
+
+ /* special markers hotkeys for anim editors: see note in definition of this function */
+ ED_marker_keymap_animedit_conflictfree(keymap);
}
/* --------------- */
diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c
index 625e5561389..28230b7a48b 100644
--- a/source/blender/editors/space_text/text_draw.c
+++ b/source/blender/editors/space_text/text_draw.c
@@ -907,9 +907,12 @@ static void text_update_drawcache(SpaceText *st, ARegion *ar)
void text_drawcache_tag_update(SpaceText *st, int full)
{
- DrawCache *drawcache= (DrawCache *)st->drawcache;
-
- if(drawcache) {
+ /* this happens if text editor ops are caled from python */
+ if (st == NULL)
+ return;
+
+ if(st->drawcache) {
+ DrawCache *drawcache= (DrawCache *)st->drawcache;
Text *txt= st->text;
if(drawcache->update_flag) {
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 7c66cec5730..f42fd461510 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -1217,6 +1217,87 @@ static void draw_b_bone(int dt, int armflag, int boneflag, int constflag, unsign
}
}
+static void draw_wire_bone_segments(bPoseChannel *pchan, Mat4 *bbones, float length, int segments)
+{
+ if ((segments > 1) && (pchan)) {
+ float dlen= length/(float)segments;
+ Mat4 *bbone = bbones;
+ int a;
+
+ for (a=0; a<segments; a++, bbone++) {
+ glPushMatrix();
+ glMultMatrixf(bbone->mat);
+
+ glBegin(GL_LINES);
+ glVertex3f(0.0f, 0.0f, 0.0f);
+ glVertex3f(0.0f, dlen, 0.0f);
+ glEnd(); // GL_LINES
+
+ glPopMatrix();
+ }
+ }
+ else {
+ glPushMatrix();
+
+ glBegin(GL_LINES);
+ glVertex3f(0.0f, 0.0f, 0.0f);
+ glVertex3f(0.0f, length, 0.0f);
+ glEnd();
+
+ glPopMatrix();
+ }
+}
+
+static void draw_wire_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, bPoseChannel *pchan, EditBone *ebone)
+{
+ Mat4 *bbones = NULL;
+ int segments = 0;
+ float length;
+
+ if (pchan) {
+ segments= pchan->bone->segments;
+ length= pchan->bone->length;
+
+ if (segments > 1)
+ bbones = b_bone_spline_setup(pchan, 0);
+ }
+ else
+ length= ebone->length;
+
+ /* draw points only if... */
+ if (armflag & ARM_EDITMODE) {
+ /* move to unitspace */
+ glPushMatrix();
+ glScalef(length, length, length);
+ draw_bone_points(dt, armflag, boneflag, id);
+ glPopMatrix();
+ length *= 0.95f; // make vertices visible
+ }
+
+ /* this chunk not in object mode */
+ if (armflag & (ARM_EDITMODE|ARM_POSEMODE)) {
+ if (id != -1)
+ glLoadName((GLuint) id|BONESEL_BONE);
+
+ draw_wire_bone_segments(pchan, bbones, length, segments);
+
+ /* further we send no names */
+ if (id != -1)
+ glLoadName(id & 0xFFFF); /* object tag, for bordersel optim */
+ }
+
+ /* colors for modes */
+ if (armflag & ARM_POSEMODE) {
+ set_pchan_glColor(PCHAN_COLOR_NORMAL, boneflag, constflag);
+ }
+ else if (armflag & ARM_EDITMODE) {
+ set_ebone_glColor(boneflag);
+ }
+
+ /* draw normal */
+ draw_wire_bone_segments(pchan, bbones, length, segments);
+}
+
static void draw_bone(int dt, int armflag, int boneflag, int constflag, unsigned int id, float length)
{
@@ -1656,7 +1737,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
int use_custom = (pchan->custom) && !(arm->flag & ARM_NO_CUSTOM);
glPushMatrix();
- if(use_custom && pchan->custom_tx) {
+ if (use_custom && pchan->custom_tx) {
glMultMatrixf(pchan->custom_tx->pose_mat);
}
else {
@@ -1684,6 +1765,8 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
else if (arm->drawtype==ARM_LINE)
; /* nothing in solid */
+ else if (arm->drawtype==ARM_WIRE)
+ ; /* nothing in solid */
else if (arm->drawtype==ARM_ENVELOPE)
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, pchan, NULL);
else if (arm->drawtype==ARM_B_BONE)
@@ -1702,7 +1785,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* very very confusing... but in object mode, solid draw, we cannot do glLoadName yet,
* stick bones and/or wire custom-shapes are drawn in next loop
*/
- if ((arm->drawtype != ARM_LINE) && (draw_wire == 0)) {
+ if (ELEM(arm->drawtype,ARM_LINE,ARM_WIRE)==0 && (draw_wire == 0)) {
/* object tag, for bordersel optim */
glLoadName(index & 0xFFFF);
index= -1;
@@ -1773,8 +1856,8 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
if (index != -1)
index+= 0x10000; // pose bones count in higher 2 bytes only
}
- /* stick bones have not been drawn yet so dont clear object selection in this case */
- if ((arm->drawtype != ARM_LINE) && draw_wire) {
+ /* stick or wire bones have not been drawn yet so dont clear object selection in this case */
+ if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)==0 && draw_wire) {
/* object tag, for bordersel optim */
glLoadName(index & 0xFFFF);
index= -1;
@@ -1784,7 +1867,7 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
/* wire draw over solid only in posemode */
if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || (arm->drawtype==ARM_LINE)) {
/* draw line check first. we do selection indices */
- if (arm->drawtype==ARM_LINE) {
+ if ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) {
if (arm->flag & ARM_POSEMODE)
index= base->selcol;
}
@@ -1879,6 +1962,8 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
else if (arm->drawtype==ARM_LINE)
draw_line_bone(arm->flag, flag, constflag, index, pchan, NULL);
+ else if (arm->drawtype==ARM_WIRE)
+ draw_wire_bone(dt, arm->flag, flag, constflag, index, pchan, NULL);
else if (arm->drawtype==ARM_B_BONE)
draw_b_bone(OB_WIRE, arm->flag, flag, constflag, index, pchan, NULL);
else
@@ -2013,7 +2098,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt)
}
/* if solid we draw it first */
- if ((dt > OB_WIRE) && (arm->drawtype!=ARM_LINE)) {
+ if ((dt > OB_WIRE) && (arm->drawtype != ARM_LINE)) {
for (eBone=arm->edbo->first, index=0; eBone; eBone=eBone->next, index++) {
if (eBone->layer & arm->layer) {
if ((eBone->flag & BONE_HIDDEN_A)==0) {
@@ -2034,6 +2119,8 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt)
draw_sphere_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
else if(arm->drawtype==ARM_B_BONE)
draw_b_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
+ else if (arm->drawtype==ARM_WIRE)
+ draw_wire_bone(OB_SOLID, arm->flag, flag, 0, index, NULL, eBone);
else {
draw_bone(OB_SOLID, arm->flag, flag, 0, index, eBone->length);
}
@@ -2047,7 +2134,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt)
/* if wire over solid, set offset */
index= -1;
glLoadName(-1);
- if (arm->drawtype==ARM_LINE) {
+ if ELEM(arm->drawtype, ARM_LINE, ARM_WIRE) {
if(G.f & G_PICKSEL)
index= 0;
}
@@ -2081,6 +2168,8 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt)
if (arm->drawtype == ARM_LINE)
draw_line_bone(arm->flag, flag, 0, index, NULL, eBone);
+ else if (arm->drawtype==ARM_WIRE)
+ draw_wire_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
else if (arm->drawtype == ARM_B_BONE)
draw_b_bone(OB_WIRE, arm->flag, flag, 0, index, NULL, eBone);
else
@@ -2109,7 +2198,7 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, int dt)
/* restore */
if(index!=-1) glLoadName(-1);
- if (arm->drawtype==ARM_LINE);
+ if ELEM(arm->drawtype,ARM_LINE,ARM_WIRE);
else if (dt>OB_WIRE) bglPolygonOffset(rv3d->dist, 0.0f);
/* finally names and axes */
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 181fb0f0aac..b8369d8cbff 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1982,12 +1982,15 @@ static void protectedQuaternionBits(short protectflag, float *quat, float *oldqu
/* ******************* TRANSFORM LIMITS ********************** */
-static void constraintTransLim(TransInfo *UNUSED(t), TransData *td)
+static void constraintTransLim(TransInfo *t, TransData *td)
{
if (td->con) {
- bConstraintTypeInfo *cti= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
+ bConstraintTypeInfo *ctiLoc= get_constraint_typeinfo(CONSTRAINT_TYPE_LOCLIMIT);
+ bConstraintTypeInfo *ctiDist= get_constraint_typeinfo(CONSTRAINT_TYPE_DISTLIMIT);
+
bConstraintOb cob= {NULL};
bConstraint *con;
+ float ctime = (float)(t->scene->r.cfra);
/* Make a temporary bConstraintOb for using these limit constraints
* - they only care that cob->matrix is correctly set ;-)
@@ -1998,6 +2001,8 @@ static void constraintTransLim(TransInfo *UNUSED(t), TransData *td)
/* Evaluate valid constraints */
for (con= td->con; con; con= con->next) {
+ bConstraintTypeInfo *cti = NULL;
+ ListBase targets = {NULL, NULL};
float tmat[4][4];
/* only consider constraint if enabled */
@@ -2010,7 +2015,17 @@ static void constraintTransLim(TransInfo *UNUSED(t), TransData *td)
if ((data->flag2 & LIMIT_TRANSFORM)==0)
continue;
+ cti = ctiLoc;
+ }
+ else if (con->type == CONSTRAINT_TYPE_DISTLIMIT) {
+ bDistLimitConstraint *data= con->data;
+ if ((data->flag & LIMITDIST_TRANSFORM)==0)
+ continue;
+ cti = ctiDist;
+ }
+
+ if (cti) {
/* do space conversions */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
/* just multiply by td->mtx (this should be ok) */
@@ -2022,8 +2037,11 @@ static void constraintTransLim(TransInfo *UNUSED(t), TransData *td)
continue;
}
+ /* get constraint targets if needed */
+ get_constraint_targets_for_solving(con, &cob, &targets, ctime);
+
/* do constraint */
- cti->evaluate_constraint(con, &cob, NULL);
+ cti->evaluate_constraint(con, &cob, &targets);
/* convert spaces again */
if (con->ownspace == CONSTRAINT_SPACE_WORLD) {
@@ -2031,6 +2049,9 @@ static void constraintTransLim(TransInfo *UNUSED(t), TransData *td)
copy_m4_m4(tmat, cob.matrix);
mul_m4_m3m4(cob.matrix, td->smtx, tmat);
}
+
+ /* free targets list */
+ BLI_freelistN(&targets);
}
}
@@ -5783,8 +5804,8 @@ int TimeSlide(TransInfo *t, const int mval[2])
char str[200];
/* calculate mouse co-ordinates */
- UI_view2d_region_to_view(v2d, mval[0], mval[0], &cval[0], &cval[1]);
- UI_view2d_region_to_view(v2d, t->imval[0], t->imval[0], &sval[0], &sval[1]);
+ UI_view2d_region_to_view(v2d, mval[0], mval[1], &cval[0], &cval[1]);
+ UI_view2d_region_to_view(v2d, t->imval[0], t->imval[1], &sval[0], &sval[1]);
/* t->values[0] stores cval[0], which is the current mouse-pointer location (in frames) */
// XXX Need to be able to repeat this
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 68aa27a7b62..e0250829a66 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -3131,12 +3131,18 @@ static void createTransActionData(bContext *C, TransInfo *t)
float min=999999999.0f, max=-999999999.0f;
int i;
- td= (t->data + 1);
- for (i=1; i < count; i+=3, td+=3) {
+ td= t->data;
+ for (i=0; i < count; i++, td++) {
if (min > *(td->val)) min= *(td->val);
if (max < *(td->val)) max= *(td->val);
}
+ if (min == max) {
+ /* just use the current frame ranges */
+ min = (float)PSFRA;
+ max = (float)PEFRA;
+ }
+
/* minx/maxx values used by TimeSlide are stored as a
* calloced 2-float array in t->customData. This gets freed
* in postTrans (T_FREE_CUSTOMDATA).
diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c
index 7bdf6c909d9..4b0a734a98e 100644
--- a/source/blender/editors/transform/transform_ops.c
+++ b/source/blender/editors/transform/transform_ops.c
@@ -897,7 +897,7 @@ void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spac
km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0);
RNA_enum_set(km->ptr, "mode", TFM_TIME_SCALE);
- km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, 0, 0);
+ km= WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, KM_SHIFT, 0);
RNA_enum_set(km->ptr, "mode", TFM_TIME_SLIDE);
break;
case SPACE_IPO:
diff --git a/source/blender/makesdna/DNA_actuator_types.h b/source/blender/makesdna/DNA_actuator_types.h
index 887a0300ee2..b368aadf4c2 100644
--- a/source/blender/makesdna/DNA_actuator_types.h
+++ b/source/blender/makesdna/DNA_actuator_types.h
@@ -56,8 +56,10 @@ typedef struct bActionActuator {
char frameProp[32]; /* Set this property to the actions current frame */
short blendin; /* Number of frames of blending */
short priority; /* Execution priority */
+ short layer; /* Animation layer */
short end_reset; /* Ending the actuator (negative pulse) wont reset the the action to its starting frame */
short strideaxis; /* Displacement axis */
+ short pad[3];
float stridelength; /* Displacement incurred by cycle */ // not in use
} bActionActuator;
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 4b649031f97..00a9786fc6f 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -62,6 +62,11 @@ typedef struct FModifier {
short flag; /* settings for the modifier */
float influence; /* the amount that the modifier should influence the value */
+
+ float sfra; /* start frame of restricted frame-range */
+ float efra; /* end frame of restricted frame-range */
+ float blendin; /* number of frames from sfra before modifier takes full influence */
+ float blendout; /* number of frames from efra before modifier fades out */
} FModifier;
/* Types of F-Curve modifier
@@ -86,13 +91,17 @@ typedef enum eFModifier_Types {
/* F-Curve Modifier Settings */
typedef enum eFModifier_Flags {
/* modifier is not able to be evaluated for some reason, and should be skipped (internal) */
- FMODIFIER_FLAG_DISABLED = (1<<0),
+ FMODIFIER_FLAG_DISABLED = (1<<0),
/* modifier's data is expanded (in UI) */
- FMODIFIER_FLAG_EXPANDED = (1<<1),
+ FMODIFIER_FLAG_EXPANDED = (1<<1),
/* modifier is active one (in UI) for editing purposes */
- FMODIFIER_FLAG_ACTIVE = (1<<2),
+ FMODIFIER_FLAG_ACTIVE = (1<<2),
/* user wants modifier to be skipped */
- FMODIFIER_FLAG_MUTED = (1<<3)
+ FMODIFIER_FLAG_MUTED = (1<<3),
+ /* restrict range that F-Modifier can be considered over */
+ FMODIFIER_FLAG_RANGERESTRICT = (1<<4),
+ /* use influence control */
+ FMODIFIER_FLAG_USEINFLUENCE = (1<<5)
} eFModifier_Flags;
/* --- */
@@ -280,8 +289,12 @@ typedef enum eDriverTarget_Flag {
DTAR_FLAG_STRUCT_REF = (1<<0),
/* idtype can only be 'Object' */
DTAR_FLAG_ID_OB_ONLY = (1<<1),
- /* toggles localspace (where transforms are manually obtained) */
+
+ /* "localspace" flags */
+ /* base flag - basically "pre parent+constraints" */
DTAR_FLAG_LOCALSPACE = (1<<2),
+ /* include constraints transformed to space including parents */
+ DTAR_FLAG_LOCAL_CONSTS = (1<<3),
} eDriverTarget_Flag;
/* Transform Channels for Driver Targets */
diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h
index 3547101612f..808db1f4843 100644
--- a/source/blender/makesdna/DNA_armature_types.h
+++ b/source/blender/makesdna/DNA_armature_types.h
@@ -136,7 +136,8 @@ typedef enum eArmature_Drawtype {
ARM_OCTA = 0,
ARM_LINE,
ARM_B_BONE,
- ARM_ENVELOPE
+ ARM_ENVELOPE,
+ ARM_WIRE
} eArmature_Drawtype;
/* armature->deformflag */
diff --git a/source/blender/makesdna/DNA_constraint_types.h b/source/blender/makesdna/DNA_constraint_types.h
index 1d752fce4ef..c2c0c6f1611 100644
--- a/source/blender/makesdna/DNA_constraint_types.h
+++ b/source/blender/makesdna/DNA_constraint_types.h
@@ -677,7 +677,10 @@ typedef enum eRotLimit_Flags {
/* distance limit constraint */
/* bDistLimitConstraint->flag */
typedef enum eDistLimit_Flag {
- LIMITDIST_USESOFT = (1<<0)
+ /* "soft" cushion effect when reaching the limit sphere */ // NOT IMPLEMENTED!
+ LIMITDIST_USESOFT = (1<<0),
+ /* as for all Limit constraints - allow to be used during transform? */
+ LIMITDIST_TRANSFORM = (1<<1)
} eDistLimit_Flag;
/* bDistLimitConstraint->mode */
diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h
index 907710ae4cd..cf416bf9d5b 100644
--- a/source/blender/makesdna/DNA_userdef_types.h
+++ b/source/blender/makesdna/DNA_userdef_types.h
@@ -436,6 +436,7 @@ extern UserDef U; /* from blenkernel blender.c */
#define USER_NONEGFRAMES (1 << 24)
#define USER_TXT_TABSTOSPACES_DISABLE (1 << 25)
#define USER_TOOLTIPS_PYTHON (1 << 26)
+#define USER_NO_RECENTLOAD_UPDATE (1 << 27)
/* helper macro for checking frame clamping */
#define FRAMENUMBER_MIN_CLAMP(cfra) \
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index ab11f88e0f6..91f88a26987 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -3114,7 +3114,7 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int
/* 2 kinds of lookups now, quoted or unquoted */
quote= *p;
- if(quote != '"')
+ if(quote != '"') /* " - this comment is hack for Aligorith's text editor's sanity */
quote= 0;
if(quote==0) {
diff --git a/source/blender/makesrna/intern/rna_actuator.c b/source/blender/makesrna/intern/rna_actuator.c
index cddba59f979..75c884a5fbb 100644
--- a/source/blender/makesrna/intern/rna_actuator.c
+++ b/source/blender/makesrna/intern/rna_actuator.c
@@ -426,11 +426,11 @@ EnumPropertyItem *rna_Actuator_type_itemf(bContext *C, PointerRNA *ptr, Property
if (ob != NULL) {
if (ob->type==OB_ARMATURE) {
- RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_ACTION);
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_ARMATURE);
}
}
-
+
+ RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_ACTION);
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_CAMERA);
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_CONSTRAINT);
RNA_enum_items_add_value(&item, &totitem, actuator_type_items, ACT_EDIT_OBJECT);
@@ -616,6 +616,11 @@ static void rna_def_action_actuator(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Priority", "Execution priority - lower numbers will override actions with higher numbers. With 2 or more actions at once, the overriding channels must be lower in the stack");
RNA_def_property_update(prop, NC_LOGIC, NULL);
+ prop= RNA_def_property(srna, "layer", PROP_INT, PROP_NONE);
+ RNA_def_property_range(prop, 0, 4); /* This should match BL_ActionManager::MAX_ACTION_LAYERS */
+ RNA_def_property_ui_text(prop, "Layer", "The animation layer to play the action on");
+ RNA_def_property_update(prop, NC_LOGIC, NULL);
+
prop= RNA_def_property(srna, "frame_property", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "frameProp");
RNA_def_property_ui_text(prop, "Frame Property", "Assign the action's current frame number to this property");
diff --git a/source/blender/makesrna/intern/rna_animation.c b/source/blender/makesrna/intern/rna_animation.c
index 7f817aa5b4b..d523a01dc2c 100644
--- a/source/blender/makesrna/intern/rna_animation.c
+++ b/source/blender/makesrna/intern/rna_animation.c
@@ -76,6 +76,10 @@ static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value)
ID *ownerId = (ID *)ptr->id.data;
AnimData *adt = (AnimData *)ptr->data;
+ /* manage usercount for current action */
+ if (adt->action)
+ id_us_min((ID*)adt->action);
+
/* assume that AnimData's action can in fact be edited... */
if ((value.data) && (ownerId)) {
bAction *act = (bAction *)value.data;
@@ -85,6 +89,7 @@ static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value)
if (ELEM(act->idroot, 0, GS(ownerId->name))) {
/* can set */
adt->action = act;
+ id_us_plus((ID*)adt->action);
}
else {
/* cannot set */
@@ -98,6 +103,7 @@ static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value)
act->id.name+2);
adt->action = act;
+ id_us_plus((ID*)adt->action);
}
}
else {
diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c
index 2060f75f9de..41d169a8870 100644
--- a/source/blender/makesrna/intern/rna_armature.c
+++ b/source/blender/makesrna/intern/rna_armature.c
@@ -814,6 +814,7 @@ static void rna_def_armature(BlenderRNA *brna)
{ARM_LINE, "STICK", 0, "Stick", "Display bones as simple 2D lines with dots"},
{ARM_B_BONE, "BBONE", 0, "B-Bone", "Display bones as boxes, showing subdivision and B-Splines"},
{ARM_ENVELOPE, "ENVELOPE", 0, "Envelope", "Display bones as extruded spheres, showing deformation influence volume"},
+ {ARM_WIRE, "WIRE", 0, "Wire", "Display bones as thin wires, showing subdivision and B-Splines"},
{0, NULL, 0, NULL, NULL}};
static EnumPropertyItem prop_ghost_type_items[] = {
{ARM_GHOST_CUR, "CURRENT_FRAME", 0, "Around Frame", "Display Ghosts of poses within a fixed number of frames around the current frame"},
diff --git a/source/blender/makesrna/intern/rna_constraint.c b/source/blender/makesrna/intern/rna_constraint.c
index a75ff601d08..4e178e77fd9 100644
--- a/source/blender/makesrna/intern/rna_constraint.c
+++ b/source/blender/makesrna/intern/rna_constraint.c
@@ -85,7 +85,7 @@ static EnumPropertyItem target_space_pchan_items[] = {
static EnumPropertyItem owner_space_pchan_items[] = {
{0, "WORLD", 0, "World Space", "The constraint is applied relative to the world coordinate system"},
{2, "POSE", 0, "Pose Space", "The constraint is applied in Pose Space, the object transformation is ignored"},
- {3, "LOCAL_WITH_PARENT", 0, "The constraint is applied relative to the local coordinate system of the object, with the parent transformation added"},
+ {3, "LOCAL_WITH_PARENT", 0, "Local With Parent", "The constraint is applied relative to the local coordinate system of the object, with the parent transformation added"},
{1, "LOCAL", 0, "Local Space", "The constraint is applied relative to the local coordinate sytem of the object"},
{0, NULL, 0, NULL, NULL}};
@@ -1787,6 +1787,11 @@ static void rna_def_constraint_distance_limit(BlenderRNA *brna)
RNA_def_property_enum_items(prop, constraint_distance_items);
RNA_def_property_ui_text(prop, "Limit Mode", "Distances in relation to sphere of influence to allow");
RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
+
+ prop= RNA_def_property(srna, "use_transform_limit", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", LIMITDIST_TRANSFORM);
+ RNA_def_property_ui_text(prop, "For Transform", "Transforms are affected by this constraint as well");
+ RNA_def_property_update(prop, NC_OBJECT|ND_CONSTRAINT, "rna_Constraint_update");
}
static void rna_def_constraint_shrinkwrap(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index a46f84a22d2..ab3665fb8ff 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -454,6 +454,30 @@ static void rna_FModifier_active_set(PointerRNA *ptr, int UNUSED(value))
fm->flag |= FMODIFIER_FLAG_ACTIVE;
}
+static void rna_FModifier_start_frame_range(PointerRNA *ptr, float *min, float *max)
+{
+ FModifier *fcm= (FModifier*)ptr->data;
+
+ *min= MINAFRAMEF;
+ *max= (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT)? fcm->efra : MAXFRAMEF;
+}
+
+static void rna_FModifier_end_frame_range(PointerRNA *ptr, float *min, float *max)
+{
+ FModifier *fcm= (FModifier*)ptr->data;
+
+ *min= (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT)? fcm->sfra : MINAFRAMEF;
+ *max= MAXFRAMEF;
+}
+
+static void rna_FModifier_blending_range(PointerRNA *ptr, float *min, float *max)
+{
+ FModifier *fcm= (FModifier*)ptr->data;
+
+ *min= 0.0f;
+ *max= fcm->efra - fcm->sfra;
+}
+
static void rna_FModifier_active_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
FModifier *fm, *fmo= (FModifier*)ptr->data;
@@ -1015,6 +1039,51 @@ static void rna_def_fmodifier(BlenderRNA *brna)
RNA_def_property_boolean_funcs(prop, NULL, "rna_FModifier_active_set");
RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, "rna_FModifier_active_update");
RNA_def_property_ui_icon(prop, ICON_RADIOBUT_OFF, 1);
+
+ /* restricted range */
+ prop= RNA_def_property(srna, "use_restricted_range", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_RANGERESTRICT);
+ RNA_def_property_ui_text(prop, "Restrict Frame Range", "F-Curve Modifier is only applied for the specified frame range to help mask off effects in order to chain them");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+ RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1); // XXX: depends on UI implementation
+
+ prop= RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "sfra");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_start_frame_range");
+ RNA_def_property_ui_text(prop, "Start Frame", "Frame that modifier's influence starts (if Restrict Frame Range is in use)");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop= RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "efra");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_end_frame_range");
+ RNA_def_property_ui_text(prop, "End Frame", "Frame that modifier's influence ends (if Restrict Frame Range is in use)");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop= RNA_def_property(srna, "blend_in", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "blendin");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_blending_range");
+ RNA_def_property_ui_text(prop, "Blend In", "Number of frames from start frame for influence to take effect");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ prop= RNA_def_property(srna, "blend_out", PROP_FLOAT, PROP_NONE);
+ RNA_def_property_float_sdna(prop, NULL, "blendout");
+ RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifier_blending_range");
+ RNA_def_property_ui_text(prop, "Blend Out", "Number of frames from start frame for influence to fade out");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+
+ /* influence */
+ prop= RNA_def_property(srna, "use_influence", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_USEINFLUENCE);
+ RNA_def_property_ui_text(prop, "Use Influence", "F-Curve Modifier's effects will be tempered by a default factor");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
+ RNA_def_property_ui_icon(prop, ICON_TRIA_RIGHT, 1); // XXX: depends on UI implementation
+
+ prop= RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR);
+ RNA_def_property_float_sdna(prop, NULL, "influence");
+ RNA_def_property_range(prop, 0.0f, 1.0f);
+ RNA_def_property_float_default(prop, 1.0f);
+ RNA_def_property_ui_text(prop, "Influence", "Amount of influence F-Curve Modifier will have when not fading in/out");
+ RNA_def_property_update(prop, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
}
/* *********************** */
@@ -1035,6 +1104,12 @@ static void rna_def_drivertarget(BlenderRNA *brna)
{DTAR_TRANSCHAN_SCALEY, "SCALE_Y", 0, "Y Scale", ""},
{DTAR_TRANSCHAN_SCALEZ, "SCALE_Z", 0, "Z Scale", ""},
{0, NULL, 0, NULL, NULL}};
+
+ static EnumPropertyItem prop_local_space_items[] = {
+ {0, "WORLD_SPACE", 0, "World Space", "Transforms include effects of parenting/restpose and constraints"},
+ {DTAR_FLAG_LOCALSPACE, "TRANSFORM_SPACE", 0, "Transform Space", "Transforms don't include parenting/restpose or constraints"},
+ {DTAR_FLAG_LOCALSPACE|DTAR_FLAG_LOCAL_CONSTS, "LOCAL_SPACE", 0, "Local Space", "Transforms include effects of constraints but not parenting/restpose"},
+ {0, NULL, 0, NULL, NULL}};
srna= RNA_def_struct(brna, "DriverTarget", NULL);
RNA_def_struct_ui_text(srna, "Driver Target", "Source of input values for driver variables");
@@ -1075,9 +1150,10 @@ static void rna_def_drivertarget(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Type", "Driver variable type");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
- prop= RNA_def_property(srna, "use_local_space_transform", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", DTAR_FLAG_LOCALSPACE);
- RNA_def_property_ui_text(prop, "Local Space", "Use transforms in Local Space (as opposed to the worldspace default)");
+ prop= RNA_def_property(srna, "transform_space", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag");
+ RNA_def_property_enum_items(prop, prop_local_space_items);
+ RNA_def_property_ui_text(prop, "Transform Space", "Space in which transforms are used");
RNA_def_property_update(prop, 0, "rna_DriverTarget_update_data");
}
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 14af5ed7a3f..cb50b99c05d 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -2878,7 +2878,11 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
prop= RNA_def_property(srna, "recent_files", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 30);
RNA_def_property_ui_text(prop, "Recent Files", "Maximum number of recently opened files to remember");
-
+
+ prop= RNA_def_property(srna, "use_update_recent_files_on_load", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_NO_RECENTLOAD_UPDATE);
+ RNA_def_property_ui_text(prop, "Update Recent on Load", "When enabled, opening files will update the recent files list. Otherwise, updates only occur when saving");
+
prop= RNA_def_property(srna, "use_save_preview_images", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_SAVE_PREVIEWS);
RNA_def_property_ui_text(prop, "Save Preview Images", "Enables automatic saving of preview images in the .blend file");
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index c088d0d2d43..79ec0360ac6 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -376,7 +376,12 @@ void WM_read_file(bContext *C, const char *filepath, ReportList *reports)
if (retval != BKE_READ_FILE_FAIL) {
G.relbase_valid = 1;
- if(!G.background) /* assume automated tasks with background, dont write recent file list */
+
+ /* dont write recent file list if:
+ * 1) assuming automated tasks with background
+ * 2) user preference to not do this is enabled (i.e. developer testing mode)
+ */
+ if (!G.background && !(U.flag & USER_NO_RECENTLOAD_UPDATE))
write_history();
}
diff --git a/source/gameengine/Converter/BL_ActionActuator.cpp b/source/gameengine/Converter/BL_ActionActuator.cpp
index c00e7ec7e29..6230f03c4ed 100644
--- a/source/gameengine/Converter/BL_ActionActuator.cpp
+++ b/source/gameengine/Converter/BL_ActionActuator.cpp
@@ -36,6 +36,7 @@
#include "BL_ActionActuator.h"
#include "BL_ArmatureObject.h"
#include "BL_SkinDeformer.h"
+#include "BL_Action.h"
#include "KX_GameObject.h"
#include "STR_HashedString.h"
#include "MEM_guardedalloc.h"
@@ -143,7 +144,86 @@ void BL_ActionActuator::SetLocalTime(float curtime)
m_localtime = m_endframe - delta_time;
}
+bool BL_ActionActuator::Update(double curtime, bool frame)
+{
+ bool bNegativeEvent = false;
+ bool bPositiveEvent = false;
+ KX_GameObject *obj = (KX_GameObject*)GetParent();
+ short play_mode = BL_Action::ACT_MODE_PLAY;
+ float start = m_startframe, end = m_endframe;
+
+ // Don't do anything if we're not "active"
+ if (!frame)
+ return true;
+
+ // Convert playmode
+ if (m_playtype == ACT_ACTION_LOOP_END)
+ play_mode = BL_Action::ACT_MODE_LOOP;
+ else if (m_playtype == ACT_ACTION_LOOP_STOP)
+ play_mode = BL_Action::ACT_MODE_LOOP;
+ else if (m_playtype == ACT_ACTION_PINGPONG)
+ play_mode = BL_Action::ACT_MODE_PING_PONG;
+ else if (m_playtype == ACT_ACTION_FROM_PROP)
+ {
+ CValue* prop = GetParent()->GetProperty(m_propname);
+
+ play_mode = BL_Action::ACT_MODE_PLAY;
+ start = end = prop->GetNumber();
+ m_is_going = false;
+ }
+
+ // Handle events
+ bNegativeEvent = m_negevent;
+ bPositiveEvent = m_posevent;
+ RemoveAllEvents();
+
+ if (!m_is_going && bPositiveEvent)
+ {
+ m_is_going = true;
+ obj->PlayAction(m_action->id.name+2, start, end, m_layer, m_blendin, play_mode);
+ if (m_end_reset)
+ obj->SetActionFrame(m_layer, m_localtime);
+ }
+ else if (m_is_going && bNegativeEvent)
+ {
+ m_is_going = false;
+
+ if (!m_end_reset)
+ {
+ obj->StopAction(m_layer);
+ return false;
+ }
+
+ m_localtime = obj->GetActionFrame(m_layer);
+ obj->StopAction(m_layer); // Stop the action after getting the frame
+ }
+
+ // Handle a frame property if it's defined
+ if (m_framepropname[0] != 0)
+ {
+ CValue* oldprop = obj->GetProperty(m_framepropname);
+ CValue* newval = new CFloatValue(obj->GetActionFrame(m_layer));
+ if (oldprop)
+ oldprop->SetValue(newval);
+ else
+ obj->SetProperty(m_framepropname, newval);
+
+ newval->Release();
+ }
+ if (m_playtype == ACT_ACTION_FROM_PROP)
+ {
+ return true;
+ }
+ // Handle a finished animation
+ else if (m_is_going && obj->IsActionDone(m_layer))
+ {
+ return false;
+ }
+ return true;
+}
+
+#if 0 // Kept around as reference for now
bool BL_ActionActuator::Update(double curtime, bool frame)
{
bool bNegativeEvent = false;
@@ -449,6 +529,7 @@ bool BL_ActionActuator::Update(double curtime, bool frame)
}
return keepgoing;
};
+#endif
#ifdef WITH_PYTHON
diff --git a/source/gameengine/Converter/BL_ActionActuator.h b/source/gameengine/Converter/BL_ActionActuator.h
index ff4ca785a96..6daf412d9a3 100644
--- a/source/gameengine/Converter/BL_ActionActuator.h
+++ b/source/gameengine/Converter/BL_ActionActuator.h
@@ -52,6 +52,7 @@ public:
short playtype,
short blendin,
short priority,
+ short layer,
short end_reset,
float stride)
: SCA_IActuator(gameobj, KX_ACT_ACTION),
@@ -69,7 +70,9 @@ public:
m_stridelength(stride),
m_playtype(playtype),
m_priority(priority),
+ m_layer(layer),
m_end_reset(end_reset),
+ m_is_going(false),
m_pose(NULL),
m_blendpose(NULL),
m_userpose(NULL),
@@ -162,7 +165,9 @@ protected:
float m_stridelength;
short m_playtype;
short m_priority;
+ short m_layer;
bool m_end_reset;
+ bool m_is_going;
struct bPose* m_pose;
struct bPose* m_blendpose;
struct bPose* m_userpose;
diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
index a9a3e66f996..75c0e012226 100644
--- a/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
+++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.cpp
@@ -47,11 +47,11 @@ float BL_ScalarInterpolator::GetValue(float currentTime) const {
return evaluate_fcurve(m_fcu, currentTime);
}
-BL_InterpolatorList::BL_InterpolatorList(struct AnimData *adt) {
- if(adt->action==NULL)
+BL_InterpolatorList::BL_InterpolatorList(bAction *action) {
+ if(action==NULL)
return;
- for(FCurve *fcu= (FCurve *)adt->action->curves.first; fcu; fcu= (FCurve *)fcu->next) {
+ for(FCurve *fcu= (FCurve *)action->curves.first; fcu; fcu= (FCurve *)fcu->next) {
if(fcu->rna_path) {
BL_ScalarInterpolator *new_ipo = new BL_ScalarInterpolator(fcu);
//assert(new_ipo);
diff --git a/source/gameengine/Converter/KX_BlenderScalarInterpolator.h b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h
index bd786bae969..cca66b3771c 100644
--- a/source/gameengine/Converter/KX_BlenderScalarInterpolator.h
+++ b/source/gameengine/Converter/KX_BlenderScalarInterpolator.h
@@ -66,7 +66,7 @@ public:
class BL_InterpolatorList : public std::vector<KX_IScalarInterpolator *> {
public:
- BL_InterpolatorList(struct AnimData *adt);
+ BL_InterpolatorList(struct bAction *action);
~BL_InterpolatorList();
KX_IScalarInterpolator *GetScalarInterpolator(const char *rna_path, int array_index);
diff --git a/source/gameengine/Converter/KX_ConvertActuators.cpp b/source/gameengine/Converter/KX_ConvertActuators.cpp
index 7da474241a0..1a8368a12fa 100644
--- a/source/gameengine/Converter/KX_ConvertActuators.cpp
+++ b/source/gameengine/Converter/KX_ConvertActuators.cpp
@@ -192,30 +192,27 @@ void BL_ConvertActuators(char* maggiename,
}
case ACT_ACTION:
{
- if (blenderobject->type==OB_ARMATURE){
- bActionActuator* actact = (bActionActuator*) bact->data;
- STR_String propname = (actact->name ? actact->name : "");
- STR_String propframe = (actact->frameProp ? actact->frameProp : "");
+ bActionActuator* actact = (bActionActuator*) bact->data;
+ STR_String propname = (actact->name ? actact->name : "");
+ STR_String propframe = (actact->frameProp ? actact->frameProp : "");
- BL_ActionActuator* tmpbaseact = new BL_ActionActuator(
- gameobj,
- propname,
- propframe,
- actact->sta,
- actact->end,
- actact->act,
- actact->type, // + 1, because Blender starts to count at zero,
- actact->blendin,
- actact->priority,
- actact->end_reset,
- actact->stridelength
- // Ketsji at 1, because zero is reserved for "NoDef"
- );
- baseact= tmpbaseact;
- break;
- }
- else
- printf ("Discarded action actuator from non-armature object [%s]\n", blenderobject->id.name+2);
+ BL_ActionActuator* tmpbaseact = new BL_ActionActuator(
+ gameobj,
+ propname,
+ propframe,
+ actact->sta,
+ actact->end,
+ actact->act,
+ actact->type, // + 1, because Blender starts to count at zero,
+ actact->blendin,
+ actact->priority,
+ actact->layer,
+ actact->end_reset,
+ actact->stridelength
+ // Ketsji at 1, because zero is reserved for "NoDef"
+ );
+ baseact= tmpbaseact;
+ break;
}
case ACT_SHAPEACTION:
{
diff --git a/source/gameengine/Converter/KX_IpoConvert.cpp b/source/gameengine/Converter/KX_IpoConvert.cpp
index 2ad56717e26..27ae857f45c 100644
--- a/source/gameengine/Converter/KX_IpoConvert.cpp
+++ b/source/gameengine/Converter/KX_IpoConvert.cpp
@@ -54,6 +54,7 @@
#include "DNA_object_types.h"
#include "DNA_action_types.h"
+#include "DNA_anim_types.h"
#include "DNA_ipo_types.h"
#include "DNA_lamp_types.h"
#include "DNA_world_types.h"
@@ -76,133 +77,134 @@ static BL_InterpolatorList *GetAdtList(struct AnimData *for_adt, KX_BlenderScene
BL_InterpolatorList *adtList= converter->FindInterpolatorList(for_adt);
if (!adtList) {
- adtList = new BL_InterpolatorList(for_adt);
+ adtList = new BL_InterpolatorList(for_adt->action);
converter->RegisterInterpolatorList(adtList, for_adt);
}
return adtList;
}
-void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_BlenderSceneConverter *converter)
+SG_Controller *BL_CreateIPO(struct bAction *action, KX_GameObject* gameobj, KX_BlenderSceneConverter *converter)
{
- if (blenderobject->adt) {
-
- KX_IpoSGController* ipocontr = new KX_IpoSGController();
- gameobj->GetSGNode()->AddSGController(ipocontr);
- ipocontr->SetObject(gameobj->GetSGNode());
-
- // For ipo_as_force, we need to know which SM object and Scene the
- // object associated with this ipo is in. Is this already known here?
- // I think not.... then it must be done later :(
-// ipocontr->SetSumoReference(gameobj->GetSumoScene(),
-// gameobj->GetSumoObject());
-
- ipocontr->SetGameObject(gameobj);
-
- ipocontr->GetIPOTransform().SetPosition(
- MT_Point3(
- blenderobject->loc[0]/*+blenderobject->dloc[0]*/,
- blenderobject->loc[1]/*+blenderobject->dloc[1]*/,
- blenderobject->loc[2]/*+blenderobject->dloc[2]*/
- )
- );
- ipocontr->GetIPOTransform().SetEulerAngles(
- MT_Vector3(
- blenderobject->rot[0],
- blenderobject->rot[1],
- blenderobject->rot[2]
- )
- );
- ipocontr->GetIPOTransform().SetScaling(
- MT_Vector3(
- blenderobject->size[0],
- blenderobject->size[1],
- blenderobject->size[2]
- )
- );
-
- const char *rotmode, *drotmode;
-
- switch(blenderobject->rotmode)
- {
- case ROT_MODE_AXISANGLE:
- rotmode = "rotation_axis_angle";
- drotmode = "delta_rotation_axis_angle";
- case ROT_MODE_QUAT:
- rotmode = "rotation_quaternion";
- drotmode = "delta_rotation_quaternion";
- default:
- rotmode = "rotation_euler";
- drotmode = "delta_rotation_euler";
- }
+ KX_IpoSGController* ipocontr = new KX_IpoSGController();
+ ipocontr->SetGameObject(gameobj);
+
+ Object* blenderobject = gameobj->GetBlenderObject();
+
+ ipocontr->GetIPOTransform().SetPosition(
+ MT_Point3(
+ blenderobject->loc[0]/*+blenderobject->dloc[0]*/,
+ blenderobject->loc[1]/*+blenderobject->dloc[1]*/,
+ blenderobject->loc[2]/*+blenderobject->dloc[2]*/
+ )
+ );
+ ipocontr->GetIPOTransform().SetEulerAngles(
+ MT_Vector3(
+ blenderobject->rot[0],
+ blenderobject->rot[1],
+ blenderobject->rot[2]
+ )
+ );
+ ipocontr->GetIPOTransform().SetScaling(
+ MT_Vector3(
+ blenderobject->size[0],
+ blenderobject->size[1],
+ blenderobject->size[2]
+ )
+ );
+
+ const char *rotmode, *drotmode;
+
+ switch(blenderobject->rotmode)
+ {
+ case ROT_MODE_AXISANGLE:
+ rotmode = "rotation_axis_angle";
+ drotmode = "delta_rotation_axis_angle";
+ case ROT_MODE_QUAT:
+ rotmode = "rotation_quaternion";
+ drotmode = "delta_rotation_quaternion";
+ default:
+ rotmode = "rotation_euler";
+ drotmode = "delta_rotation_euler";
+ }
- BL_InterpolatorList *adtList= GetAdtList(blenderobject->adt, converter);
+ BL_InterpolatorList *adtList= GetAdtList(blenderobject->adt, converter);
- // For each active channel in the adtList add an
- // interpolator to the game object.
+ // For each active channel in the adtList add an
+ // interpolator to the game object.
- KX_IInterpolator *interpolator;
- KX_IScalarInterpolator *interp;
+ KX_IInterpolator *interpolator;
+ KX_IScalarInterpolator *interp;
- for(int i=0; i<3; i++) {
- if ((interp = adtList->GetScalarInterpolator("location", i))) {
- interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetPosition()[i]), interp);
- ipocontr->AddInterpolator(interpolator);
- ipocontr->SetIPOChannelActive(OB_LOC_X+i, true);
- }
+ for(int i=0; i<3; i++) {
+ if ((interp = adtList->GetScalarInterpolator("location", i))) {
+ interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetPosition()[i]), interp);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetIPOChannelActive(OB_LOC_X+i, true);
}
- for(int i=0; i<3; i++) {
- if ((interp = adtList->GetScalarInterpolator("delta_location", i))) {
- interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaPosition()[i]), interp);
- ipocontr->AddInterpolator(interpolator);
- ipocontr->SetIPOChannelActive(OB_DLOC_X+i, true);
- }
+ }
+ for(int i=0; i<3; i++) {
+ if ((interp = adtList->GetScalarInterpolator("delta_location", i))) {
+ interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaPosition()[i]), interp);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetIPOChannelActive(OB_DLOC_X+i, true);
}
- for(int i=0; i<3; i++) {
- if ((interp = adtList->GetScalarInterpolator(rotmode, i))) {
- interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetEulerAngles()[i]), interp);
- ipocontr->AddInterpolator(interpolator);
- ipocontr->SetIPOChannelActive(OB_ROT_X+i, true);
- }
+ }
+ for(int i=0; i<3; i++) {
+ if ((interp = adtList->GetScalarInterpolator(rotmode, i))) {
+ interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetEulerAngles()[i]), interp);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetIPOChannelActive(OB_ROT_X+i, true);
}
- for(int i=0; i<3; i++) {
- if ((interp = adtList->GetScalarInterpolator(drotmode, i))) {
- interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[i]), interp);
- ipocontr->AddInterpolator(interpolator);
- ipocontr->SetIPOChannelActive(OB_DROT_X+i, true);
- }
+ }
+ for(int i=0; i<3; i++) {
+ if ((interp = adtList->GetScalarInterpolator(drotmode, i))) {
+ interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaEulerAngles()[i]), interp);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetIPOChannelActive(OB_DROT_X+i, true);
}
- for(int i=0; i<3; i++) {
- if ((interp = adtList->GetScalarInterpolator("scale", i))) {
- interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetScaling()[i]), interp);
- ipocontr->AddInterpolator(interpolator);
- ipocontr->SetIPOChannelActive(OB_SIZE_X+i, true);
- }
+ }
+ for(int i=0; i<3; i++) {
+ if ((interp = adtList->GetScalarInterpolator("scale", i))) {
+ interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetScaling()[i]), interp);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetIPOChannelActive(OB_SIZE_X+i, true);
}
- for(int i=0; i<3; i++) {
- if ((interp = adtList->GetScalarInterpolator("delta_scale", i))) {
- interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaScaling()[i]), interp);
- ipocontr->AddInterpolator(interpolator);
- ipocontr->SetIPOChannelActive(OB_DSIZE_X+i, true);
- }
+ }
+ for(int i=0; i<3; i++) {
+ if ((interp = adtList->GetScalarInterpolator("delta_scale", i))) {
+ interpolator= new KX_ScalarInterpolator(&(ipocontr->GetIPOTransform().GetDeltaScaling()[i]), interp);
+ ipocontr->AddInterpolator(interpolator);
+ ipocontr->SetIPOChannelActive(OB_DSIZE_X+i, true);
}
+ }
- {
- KX_ObColorIpoSGController* ipocontr_obcol=NULL;
+ {
+ KX_ObColorIpoSGController* ipocontr_obcol=NULL;
- for(int i=0; i<4; i++) {
- if ((interp = adtList->GetScalarInterpolator("color", i))) {
- if (!ipocontr_obcol) {
- ipocontr_obcol = new KX_ObColorIpoSGController();
- gameobj->GetSGNode()->AddSGController(ipocontr_obcol);
- ipocontr_obcol->SetObject(gameobj->GetSGNode());
- }
- interpolator= new KX_ScalarInterpolator(&ipocontr_obcol->m_rgba[i], interp);
- ipocontr_obcol->AddInterpolator(interpolator);
+ for(int i=0; i<4; i++) {
+ if ((interp = adtList->GetScalarInterpolator("color", i))) {
+ if (!ipocontr_obcol) {
+ ipocontr_obcol = new KX_ObColorIpoSGController();
+ gameobj->GetSGNode()->AddSGController(ipocontr_obcol);
+ ipocontr_obcol->SetObject(gameobj->GetSGNode());
}
+ interpolator= new KX_ScalarInterpolator(&ipocontr_obcol->m_rgba[i], interp);
+ ipocontr_obcol->AddInterpolator(interpolator);
}
}
}
+
+ return ipocontr;
+}
+
+void BL_ConvertIpos(struct Object* blenderobject,KX_GameObject* gameobj,KX_BlenderSceneConverter *converter)
+{
+ if (blenderobject->adt) {
+ SG_Controller *ipocontr = BL_CreateIPO(blenderobject->adt->action, gameobj, converter);
+ gameobj->GetSGNode()->AddSGController(ipocontr);
+ ipocontr->SetObject(gameobj->GetSGNode());
+ }
}
void BL_ConvertLampIpos(struct Lamp* blenderlamp, KX_GameObject *lightobj,KX_BlenderSceneConverter *converter)
diff --git a/source/gameengine/Converter/KX_IpoConvert.h b/source/gameengine/Converter/KX_IpoConvert.h
index d77a72a82e2..914422ba83f 100644
--- a/source/gameengine/Converter/KX_IpoConvert.h
+++ b/source/gameengine/Converter/KX_IpoConvert.h
@@ -36,6 +36,10 @@
struct Object;
+class SG_Controller *BL_CreateIPO(struct bAction *action,
+ class KX_GameObject* gameobj,
+ class KX_BlenderSceneConverter *converter);
+
void BL_ConvertIpos(struct Object* blenderobject,
class KX_GameObject* gameobj,
class KX_BlenderSceneConverter *converter);
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
index 157124ebc81..88a9f3afd7d 100644
--- a/source/gameengine/Expressions/PyObjectPlus.h
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -254,12 +254,15 @@ typedef struct PyObjectPlus_Proxy {
#define KX_PYMETHODTABLE_NOARGS(class_name, method_name) \
{#method_name , (PyCFunction) class_name::sPy##method_name, METH_NOARGS, (const char *)class_name::method_name##_doc}
+#define KX_PYMETHODTABLE_KEYWORDS(class_name, method_name) \
+ {#method_name , (PyCFunction) class_name::sPy##method_name, METH_VARARGS|METH_KEYWORDS, (const char *)class_name::method_name##_doc}
+
/**
* Function implementation macro
*/
#define KX_PYMETHODDEF_DOC(class_name, method_name, doc_string) \
const char class_name::method_name##_doc[] = doc_string; \
-PyObject* class_name::Py##method_name(PyObject* args, PyObject*)
+PyObject* class_name::Py##method_name(PyObject* args, PyObject* kwds)
#define KX_PYMETHODDEF_DOC_VARARGS(class_name, method_name, doc_string) \
const char class_name::method_name##_doc[] = doc_string; \
diff --git a/source/gameengine/Ketsji/BL_Action.cpp b/source/gameengine/Ketsji/BL_Action.cpp
new file mode 100644
index 00000000000..bd65c7d45d8
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Action.cpp
@@ -0,0 +1,266 @@
+/**
+ * $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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <cstdlib>
+
+#include "BL_Action.h"
+#include "BL_ArmatureObject.h"
+#include "KX_IpoConvert.h"
+#include "KX_GameObject.h"
+
+// These three are for getting the action from the logic manager
+#include "KX_Scene.h"
+#include "KX_PythonInit.h"
+#include "SCA_LogicManager.h"
+
+extern "C" {
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "RNA_access.h"
+#include "RNA_define.h"
+}
+
+BL_Action::BL_Action(class KX_GameObject* gameobj)
+:
+ m_obj(gameobj),
+ m_startframe(0.f),
+ m_endframe(0.f),
+ m_blendin(0.f),
+ m_playmode(0),
+ m_endtime(0.f),
+ m_localtime(0.f),
+ m_blendframe(0.f),
+ m_blendstart(0.f),
+ m_speed(0.f),
+ m_pose(NULL),
+ m_blendpose(NULL),
+ m_sg_contr(NULL),
+ m_done(true)
+{
+
+}
+
+BL_Action::~BL_Action()
+{
+ if (m_pose)
+ game_free_pose(m_pose);
+ if (m_blendpose)
+ game_free_pose(m_blendpose);
+ if (m_sg_contr)
+ {
+ m_obj->GetSGNode()->RemoveSGController(m_sg_contr);
+ delete m_sg_contr;
+ }
+}
+
+void BL_Action::Play(const char* name,
+ float start,
+ float end,
+ float blendin,
+ short play_mode,
+ short blend_mode,
+ float playback_speed)
+{
+ bAction* prev_action = m_action;
+
+ // First try to load the action
+ m_action = (bAction*)KX_GetActiveScene()->GetLogicManager()->GetActionByName(name);
+ if (!m_action)
+ {
+ printf("Failed to load action: %s\n", name);
+ m_done = true;
+ return;
+ }
+
+ //if (m_obj->GetGameObjectType() != SCA_IObject::OBJ_ARMATURE)
+ if (prev_action != m_action)
+ {
+ // Create an SG_Controller
+ m_sg_contr = BL_CreateIPO(m_action, m_obj, KX_GetActiveScene()->GetSceneConverter());
+ m_obj->GetSGNode()->AddSGController(m_sg_contr);
+ m_sg_contr->SetObject(m_obj->GetSGNode());
+ InitIPO();
+ }
+
+ // Now that we have an action, we have something we can play
+ m_starttime = KX_GetActiveEngine()->GetFrameTime();
+ m_startframe = m_localtime = start;
+ m_endframe = end;
+ m_blendin = blendin;
+ m_playmode = play_mode;
+ m_endtime = 0.f;
+ m_blendframe = 0.f;
+ m_blendstart = 0.f;
+ m_speed = playback_speed;
+
+ m_done = false;
+}
+
+void BL_Action::Stop()
+{
+ m_done = true;
+}
+
+void BL_Action::InitIPO()
+{
+ // Initialize the IPO
+ m_sg_contr->SetOption(SG_Controller::SG_CONTR_IPO_RESET, true);
+ m_sg_contr->SetOption(SG_Controller::SG_CONTR_IPO_IPO_AS_FORCE, false);
+ m_sg_contr->SetOption(SG_Controller::SG_CONTR_IPO_IPO_ADD, false);
+ m_sg_contr->SetOption(SG_Controller::SG_CONTR_IPO_LOCAL, false);
+}
+
+float BL_Action::GetFrame()
+{
+ return m_localtime;
+}
+
+void BL_Action::SetFrame(float frame)
+{
+ float dt;
+
+ // Clamp the frame to the start and end frame
+ if (frame < min(m_startframe, m_endframe))
+ frame = min(m_startframe, m_endframe);
+ else if (frame > max(m_startframe, m_endframe))
+ frame = max(m_startframe, m_endframe);
+
+ // We don't set m_localtime directly since it's recalculated
+ // in the next update. So, we modify the value (m_starttime)
+ // used to calculate m_localtime the next time SetLocalTime() is called.
+
+ dt = frame-m_startframe;
+
+ if (m_endframe < m_startframe)
+ dt = -dt;
+
+ m_starttime -= dt / (KX_KetsjiEngine::GetAnimFrameRate()*m_speed);
+}
+
+void BL_Action::SetLocalTime(float curtime)
+{
+ float dt = (curtime-m_starttime)*KX_KetsjiEngine::GetAnimFrameRate()*m_speed;
+
+ if (m_endframe < m_startframe)
+ dt = -dt;
+
+ m_localtime = m_startframe + dt;
+}
+
+void BL_Action::Update(float curtime)
+{
+ // Don't bother if we're done with the animation
+ if (m_done)
+ return;
+
+ curtime -= KX_KetsjiEngine::GetSuspendedDelta();
+
+ SetLocalTime(curtime);
+
+ // Handle wrap around
+ if (m_localtime < min(m_startframe, m_endframe) || m_localtime > max(m_startframe, m_endframe))
+ {
+ switch(m_playmode)
+ {
+ case ACT_MODE_PLAY:
+ // Clamp
+ m_localtime = m_endframe;
+ m_done = true;
+ break;
+ case ACT_MODE_LOOP:
+ // Put the time back to the beginning
+ m_localtime = m_startframe;
+ m_starttime = curtime;
+ break;
+ case ACT_MODE_PING_PONG:
+ // Swap the start and end frames
+ float temp = m_startframe;
+ m_startframe = m_endframe;
+ m_endframe = temp;
+
+ m_starttime = curtime;
+
+ break;
+ }
+
+ if (!m_done && m_sg_contr)
+ InitIPO();
+ }
+
+ if (m_obj->GetGameObjectType() == SCA_IObject::OBJ_ARMATURE)
+ {
+ BL_ArmatureObject *obj = (BL_ArmatureObject*)m_obj;
+ obj->GetPose(&m_pose);
+
+ // Extract the pose from the action
+ {
+ struct PointerRNA id_ptr;
+ Object *arm = obj->GetArmatureObject();
+ bPose *temp = arm->pose;
+
+ arm->pose = m_pose;
+ RNA_id_pointer_create((ID*)arm, &id_ptr);
+ animsys_evaluate_action(&id_ptr, m_action, NULL, m_localtime);
+
+ arm->pose = temp;
+ }
+
+ // Handle blending between actions
+ if (m_blendin && m_blendframe<m_blendin)
+ {
+ if (!m_blendpose)
+ {
+ obj->GetMRDPose(&m_blendpose);
+ m_blendstart = curtime;
+ }
+
+ // Calculate weight
+ float weight = 1.f - (m_blendframe/m_blendin);
+ game_blend_poses(m_pose, m_blendpose, weight);
+
+ // Bump the blend frame
+ m_blendframe = (curtime - m_blendstart)*KX_KetsjiEngine::GetAnimFrameRate();
+
+ // Clamp
+ if (m_blendframe>m_blendin)
+ m_blendframe = m_blendin;
+ }
+
+ obj->SetPose(m_pose);
+
+ obj->SetActiveAction(NULL, 0, curtime);
+ }
+ else
+ {
+ InitIPO();
+ m_sg_contr->SetSimulatedTime(m_localtime);
+ m_obj->GetSGNode()->UpdateWorldData(m_localtime);
+ m_obj->UpdateTransform();
+ }
+}
diff --git a/source/gameengine/Ketsji/BL_Action.h b/source/gameengine/Ketsji/BL_Action.h
new file mode 100644
index 00000000000..1eb4483eb37
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_Action.h
@@ -0,0 +1,110 @@
+/**
+ * $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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BL_ACTION
+#define __BL_ACTION
+
+#ifdef WITH_CXX_GUARDEDALLOC
+#include "MEM_guardedalloc.h"
+#endif
+
+
+class BL_Action
+{
+private:
+ struct bAction* m_action;
+ struct bPose* m_pose;
+ struct bPose* m_blendpose;
+ struct PointerRNA *m_ptrrna;
+ class SG_Controller *m_sg_contr;
+ class KX_GameObject* m_obj;
+
+ float m_startframe;
+ float m_endframe;
+ float m_starttime;
+ float m_endtime;
+ float m_localtime;
+
+ float m_blendin;
+ float m_blendframe;
+ float m_blendstart;
+
+ float m_speed;
+
+ short m_playmode;
+ short m_blendmode;
+
+ bool m_done;
+
+ void InitIPO();
+ void SetLocalTime(float curtime);
+public:
+ BL_Action(class KX_GameObject* gameobj);
+ ~BL_Action();
+
+ void Play(const char* name,
+ float start,
+ float end,
+ float blendin,
+ short play_mode,
+ short blend_mode,
+ float playback_speed);
+ void Stop();
+ bool IsDone() {return m_done;}
+ void Update(float curtime);
+
+ // Accessors
+ float GetFrame();
+
+ // Mutators
+ void SetFrame(float frame);
+
+ enum
+ {
+ ACT_MODE_PLAY = 0,
+ ACT_MODE_LOOP,
+ ACT_MODE_PING_PONG,
+ ACT_MODE_MAX,
+ };
+
+ enum
+ {
+ ACT_BLEND_NONE = 0,
+ ACT_BLEND_MIX,
+ ACT_BLEND_MAX,
+ };
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_Action"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //BL_ACTION
+
diff --git a/source/gameengine/Ketsji/BL_ActionManager.cpp b/source/gameengine/Ketsji/BL_ActionManager.cpp
new file mode 100644
index 00000000000..0a99a5a43a9
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_ActionManager.cpp
@@ -0,0 +1,98 @@
+/**
+ * $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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "BL_ActionManager.h"
+
+BL_ActionManager::BL_ActionManager(class KX_GameObject *obj)
+{
+ for (int i=0; i<MAX_ACTION_LAYERS; ++i)
+ m_layers[i] = new BL_Action(obj);
+}
+
+BL_ActionManager::~BL_ActionManager()
+{
+ for (int i=0; i<MAX_ACTION_LAYERS; ++i)
+ if (m_layers[i])
+ delete m_layers[i];
+}
+
+float BL_ActionManager::GetActionFrame(short layer)
+{
+ if (m_layers[layer])
+ return m_layers[layer]->GetFrame();
+
+ return 0.f;
+}
+
+void BL_ActionManager::SetActionFrame(short layer, float frame)
+{
+ if (m_layers[layer])
+ m_layers[layer]->SetFrame(frame);
+}
+
+void BL_ActionManager::PlayAction(const char* name,
+ float start,
+ float end,
+ short layer,
+ float blendin,
+ short play_mode,
+ short blend_mode,
+ float playback_speed)
+{
+ // Remove a currently running action on this layer if there is one
+ if (m_layers[layer])
+ StopAction(layer);
+
+ // Create a new action
+ m_layers[layer]->Play(name, start, end, blendin, play_mode, blend_mode, playback_speed);
+}
+
+void BL_ActionManager::StopAction(short layer)
+{
+ m_layers[layer]->Stop();
+}
+
+bool BL_ActionManager::IsActionDone(short layer)
+{
+ if (m_layers[layer])
+ return m_layers[layer]->IsDone();
+
+ return true;
+}
+
+void BL_ActionManager::Update(float curtime)
+{
+ for (int i=0; i<MAX_ACTION_LAYERS; ++i)
+ {
+ if (!m_layers[i]->IsDone())
+ {
+ m_layers[i]->Update(curtime);
+ }
+ }
+}
diff --git a/source/gameengine/Ketsji/BL_ActionManager.h b/source/gameengine/Ketsji/BL_ActionManager.h
new file mode 100644
index 00000000000..b769db02bf9
--- /dev/null
+++ b/source/gameengine/Ketsji/BL_ActionManager.h
@@ -0,0 +1,69 @@
+/**
+ * $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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+#ifndef __BL_ACTIONMANAGER
+#define __BL_ACTIONMANAGER
+
+#include "BL_Action.h"
+
+#define MAX_ACTION_LAYERS 4
+
+class BL_ActionManager
+{
+private:
+ BL_Action* m_layers[MAX_ACTION_LAYERS];
+
+public:
+ BL_ActionManager(class KX_GameObject* obj);
+ ~BL_ActionManager();
+
+ void PlayAction(const char* name,
+ float start,
+ float end,
+ short layer=0,
+ float blendin=0.f,
+ short play_mode=0,
+ short blend_mode=0,
+ float playback_speed=1.f);
+
+ float GetActionFrame(short layer);
+ void SetActionFrame(short layer, float frame);
+
+ void StopAction(short layer);
+ bool IsActionDone(short layer);
+ void Update(float);
+
+#ifdef WITH_CXX_GUARDEDALLOC
+public:
+ void *operator new(size_t num_bytes) { return MEM_mallocN(num_bytes, "GE:BL_ActionManager"); }
+ void operator delete( void *mem ) { MEM_freeN(mem); }
+#endif
+};
+
+#endif //BL_ACTIONMANAGER
+
diff --git a/source/gameengine/Ketsji/CMakeLists.txt b/source/gameengine/Ketsji/CMakeLists.txt
index a6339439bea..6fe793bd475 100644
--- a/source/gameengine/Ketsji/CMakeLists.txt
+++ b/source/gameengine/Ketsji/CMakeLists.txt
@@ -29,25 +29,26 @@ set(INC
../../../intern/string
../../../intern/guardedalloc
../../../intern/container
- ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer
+ ../../../source/gameengine/Rasterizer/RAS_OpenGLRasterizer
../../../source/gameengine/Converter
../../../source/gameengine/BlenderRoutines
../../../source/blender/imbuf
../../../intern/moto/include
- ../../../source/gameengine/Ketsji
+ ../../../source/gameengine/Ketsji
../../../source/blender/blenlib
../../../source/blender/blenfont
../../../source/blender/blenkernel
../../../source/blender/python
../../../source/blender/python/generic
- ../../../source/blender
- ../../../source/blender/makesdna
- ../../../source/gameengine/Rasterizer
+ ../../../source/blender
+ ../../../source/blender/makesdna
+ ../../../source/blender/makesrna
+ ../../../source/gameengine/Rasterizer
../../../source/gameengine/GameLogic
- ../../../source/gameengine/Expressions
+ ../../../source/gameengine/Expressions
../../../source/gameengine/Ketsji/KXNetwork
../../../source/gameengine/Network
- ../../../source/gameengine/SceneGraph
+ ../../../source/gameengine/SceneGraph
../../../source/gameengine/Physics/common
../../../source/gameengine/Network/LoopBackNetwork
../../../intern/audaspace/intern
@@ -60,6 +61,8 @@ set(INC_SYS
)
set(SRC
+ BL_Action.cpp
+ BL_ActionManager.cpp
BL_BlenderShader.cpp
BL_Material.cpp
BL_Shader.cpp
@@ -129,6 +132,8 @@ set(SRC
KX_WorldInfo.cpp
KX_WorldIpoController.cpp
+ BL_Action.h
+ BL_ActionManager.h
KX_ArmatureSensor.h
KX_BlenderMaterial.h
KX_BulletPhysicsController.h
diff --git a/source/gameengine/Ketsji/KX_GameObject.cpp b/source/gameengine/Ketsji/KX_GameObject.cpp
index 47d83c16659..27f4a72ccdf 100644
--- a/source/gameengine/Ketsji/KX_GameObject.cpp
+++ b/source/gameengine/Ketsji/KX_GameObject.cpp
@@ -74,6 +74,8 @@ typedef unsigned long uint_ptr;
#include "SCA_IController.h"
#include "NG_NetworkScene.h" //Needed for sendMessage()
+#include "BL_ActionManager.h"
+
#include "PyObjectPlus.h" /* python stuff */
// This file defines relationships between parents and children
@@ -107,7 +109,8 @@ KX_GameObject::KX_GameObject(
m_pGraphicController(NULL),
m_xray(false),
m_pHitObject(NULL),
- m_isDeformable(false)
+ m_isDeformable(false),
+ m_actionManager(NULL)
#ifdef WITH_PYTHON
, m_attr_dict(NULL)
#endif
@@ -154,6 +157,10 @@ KX_GameObject::~KX_GameObject()
{
delete m_pGraphicController;
}
+ if (m_actionManager)
+ {
+ delete m_actionManager;
+ }
#ifdef WITH_PYTHON
if (m_attr_dict) {
PyDict_Clear(m_attr_dict); /* incase of circular refs or other weird cases */
@@ -344,6 +351,52 @@ void KX_GameObject::RemoveParent(KX_Scene *scene)
}
}
+BL_ActionManager* KX_GameObject::GetActionManager()
+{
+ // We only want to create an action manager if we need it
+ if (!m_actionManager)
+ m_actionManager = new BL_ActionManager(this);
+
+ return m_actionManager;
+}
+
+void KX_GameObject::PlayAction(const char* name,
+ float start,
+ float end,
+ short layer,
+ float blendin,
+ short play_mode,
+ short blend_mode,
+ float playback_speed)
+{
+ GetActionManager()->PlayAction(name, start, end, layer, blendin, play_mode, blend_mode, playback_speed);
+}
+
+void KX_GameObject::StopAction(short layer)
+{
+ GetActionManager()->StopAction(layer);
+}
+
+bool KX_GameObject::IsActionDone(short layer)
+{
+ return GetActionManager()->IsActionDone(layer);
+}
+
+void KX_GameObject::UpdateActionManager(float curtime)
+{
+ GetActionManager()->Update(curtime);
+}
+
+float KX_GameObject::GetActionFrame(short layer)
+{
+ return GetActionManager()->GetActionFrame(layer);
+}
+
+void KX_GameObject::SetActionFrame(short layer, float frame)
+{
+ GetActionManager()->SetActionFrame(layer, frame);
+}
+
void KX_GameObject::ProcessReplica()
{
SCA_IObject::ProcessReplica();
@@ -353,6 +406,8 @@ void KX_GameObject::ProcessReplica()
m_pSGNode = NULL;
m_pClient_info = new KX_ClientObjectInfo(*m_pClient_info);
m_pClient_info->m_gameobject = this;
+ if (m_actionManager)
+ m_actionManager = new BL_ActionManager(this);
m_state = 0;
#ifdef WITH_PYTHON
@@ -1497,6 +1552,8 @@ PyMethodDef KX_GameObject::Methods[] = {
KX_PYMETHODTABLE_O(KX_GameObject, getDistanceTo),
KX_PYMETHODTABLE_O(KX_GameObject, getVectTo),
KX_PYMETHODTABLE(KX_GameObject, sendMessage),
+
+ KX_PYMETHODTABLE_KEYWORDS(KX_GameObject, playAction),
// dict style access for props
{"get",(PyCFunction) KX_GameObject::sPyget, METH_VARARGS},
@@ -2975,6 +3032,43 @@ KX_PYMETHODDEF_DOC_VARARGS(KX_GameObject, sendMessage,
Py_RETURN_NONE;
}
+KX_PYMETHODDEF_DOC(KX_GameObject, playAction,
+ "playAction(name, start_frame, end_frame, layer=0, blendin=0, play_mode=ACT_MODE_PLAY, blend_mode=ACT_BLEND_NONE, speed=1.0)\n"
+ "plays an action\n")
+{
+ const char* name;
+ float start, end, blendin=0.f, speed=1.f;
+ short layer=0;
+ short play_mode=0, blend_mode=0;
+
+ static const char *kwlist[] = {"name", "start_frame", "end_frame", "layer", "blendin", "play_mode", "blend_mode", "speed", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "sff|hfhhf", const_cast<char**>(kwlist),
+ &name, &start, &end, &layer, &blendin, &play_mode, &blend_mode, &speed))
+ return NULL;
+
+ if (layer < 0 || layer > MAX_ACTION_LAYERS)
+ {
+ printf("KX_GameObject.playAction(): given layer (%d) is out of range (0 - %d), setting to 0", layer, MAX_ACTION_LAYERS-1);
+ layer = 0;
+ }
+
+ if (play_mode < 0 || play_mode > BL_Action::ACT_MODE_MAX)
+ {
+ printf("KX_GameObject.playAction(): given play_mode (%d) is out of range (0 - %d), setting to ACT_MODE_PLAY", play_mode, BL_Action::ACT_MODE_MAX-1);
+ play_mode = BL_Action::ACT_MODE_MAX;
+ }
+
+ if (blend_mode < 0 || blend_mode > BL_Action::ACT_BLEND_MAX)
+ {
+ printf("KX_GameObject.playAction(): given blend_mode (%d) is out of range (0 - %d), setting to ACT_BLEND_NONE", blend_mode, BL_Action::ACT_BLEND_MAX-1);
+ blend_mode = BL_Action::ACT_BLEND_NONE;
+ }
+
+ PlayAction(name, start, end, layer, blendin, play_mode, blend_mode, speed);
+
+ Py_RETURN_NONE;
+}
/* dict style access */
diff --git a/source/gameengine/Ketsji/KX_GameObject.h b/source/gameengine/Ketsji/KX_GameObject.h
index 50fbebe1341..0ff0ec84529 100644
--- a/source/gameengine/Ketsji/KX_GameObject.h
+++ b/source/gameengine/Ketsji/KX_GameObject.h
@@ -63,6 +63,7 @@ class RAS_MeshObject;
class KX_IPhysicsController;
class PHY_IGraphicController;
class PHY_IPhysicsEnvironment;
+class BL_ActionManager;
struct Object;
#ifdef WITH_PYTHON
@@ -112,6 +113,11 @@ protected:
SG_Node* m_pSGNode;
MT_CmMatrix4x4 m_OpenGL_4x4Matrix;
+
+ // The action manager is used to play/stop/update actions
+ BL_ActionManager* m_actionManager;
+
+ BL_ActionManager* GetActionManager();
public:
bool m_isDeformable;
@@ -198,6 +204,51 @@ public:
*/
void RemoveParent(KX_Scene *scene);
+ /*********************************
+ * Animation API
+ *********************************/
+
+ /**
+ * Adds an action to the object's action manager
+ */
+ void PlayAction(const char* name,
+ float start,
+ float end,
+ short layer=0,
+ float blendin=0.f,
+ short play_mode=0,
+ short blend_mode=0,
+ float playback_speed=1.f);
+
+ /**
+ * Gets the current frame of an action
+ */
+ float GetActionFrame(short layer);
+
+ /**
+ * Sets the current frame of an action
+ */
+ void SetActionFrame(short layer, float frame);
+
+ /**
+ * Remove an action from the object's action manager
+ */
+ void StopAction(short layer);
+
+ /**
+ * Check if an action has finished playing
+ */
+ bool IsActionDone(short layer);
+
+ /**
+ * Kick the object's action manager
+ */
+ void UpdateActionManager(float curtime);
+
+ /*********************************
+ * End Animation API
+ *********************************/
+
/**
* Construct a game object. This class also inherits the
* default constructors - use those with care!
@@ -853,6 +904,8 @@ public:
KX_PYMETHOD_DOC_O(KX_GameObject,getVectTo);
KX_PYMETHOD_DOC_VARARGS(KX_GameObject, sendMessage);
KX_PYMETHOD_VARARGS(KX_GameObject, ReinstancePhysicsMesh);
+
+ KX_PYMETHOD_DOC(KX_GameObject, playAction);
/* Dict access */
KX_PYMETHOD_VARARGS(KX_GameObject,get);
diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp
index 28dc660037c..27bf5d19b14 100644
--- a/source/gameengine/Ketsji/KX_Scene.cpp
+++ b/source/gameengine/Ketsji/KX_Scene.cpp
@@ -1506,6 +1506,9 @@ void KX_Scene::LogicBeginFrame(double curtime)
void KX_Scene::LogicUpdateFrame(double curtime, bool frame)
{
+ // Update any animations
+ for (int i=0; i<GetObjectList()->GetCount(); ++i)
+ ((KX_GameObject*)GetObjectList()->GetValue(i))->UpdateActionManager(curtime);
m_logicmgr->UpdateFrame(curtime, frame);
}
diff --git a/source/gameengine/Ketsji/SConscript b/source/gameengine/Ketsji/SConscript
index 08642262724..da6361952e0 100644
--- a/source/gameengine/Ketsji/SConscript
+++ b/source/gameengine/Ketsji/SConscript
@@ -14,7 +14,7 @@ incs += ' #intern/audaspace/intern #source/gameengine/Converter'
incs += ' #source/gameengine/BlenderRoutines #source/blender/imbuf #intern/moto/include'
incs += ' #source/gameengine/Ketsji #source/gameengine/Ketsji/KXNetwork #source/blender/blenlib #source/blender/blenfont'
incs += ' #source/blender/blenkernel #source/blender #source/blender/editors/include'
-incs += ' #source/blender/makesdna #source/blender/python #source/gameengine/Rasterizer'
+incs += ' #source/blender/makesdna #source/blender/makesrna #source/blender/python #source/gameengine/Rasterizer'
incs += ' #source/gameengine/GameLogic #source/gameengine/Expressions #source/gameengine/Network'
incs += ' #source/gameengine/SceneGraph #source/gameengine/Physics/common'
incs += ' #source/gameengine/Physics/Dummy'
@@ -34,7 +34,7 @@ if env['WITH_BF_PYTHON']:
if env['WITH_BF_FFMPEG']:
defs.append('WITH_FFMPEG')
-
+
if env['OURPLATFORM'] in ('win32-vc', 'win64-vc', 'win32-mingw'):
if env['BF_DEBUG']:
defs.append('_DEBUG') # for Python
diff --git a/source/gameengine/SceneGraph/SG_IObject.cpp b/source/gameengine/SceneGraph/SG_IObject.cpp
index 3064e6662b9..b22d210984d 100644
--- a/source/gameengine/SceneGraph/SG_IObject.cpp
+++ b/source/gameengine/SceneGraph/SG_IObject.cpp
@@ -34,6 +34,8 @@
#include "SG_IObject.h"
#include "SG_Controller.h"
+#include <algorithm>
+
SG_Stage gSG_Stage = SG_STAGE_UNKNOWN;
SG_IObject::
@@ -71,6 +73,16 @@ AddSGController(
void
SG_IObject::
+RemoveSGController(
+ SG_Controller* cont
+) {
+ SGControllerList::iterator contit;
+
+ m_SGcontrollers.erase(std::remove(m_SGcontrollers.begin(), m_SGcontrollers.end(), cont));
+}
+
+ void
+SG_IObject::
RemoveAllControllers(
) {
m_SGcontrollers.clear();
diff --git a/source/gameengine/SceneGraph/SG_IObject.h b/source/gameengine/SceneGraph/SG_IObject.h
index 26e317bdcd9..e709699c08a 100644
--- a/source/gameengine/SceneGraph/SG_IObject.h
+++ b/source/gameengine/SceneGraph/SG_IObject.h
@@ -180,6 +180,16 @@ public:
SG_Controller* cont
);
+ /**
+ * Remove a pointer to a controller from this node.
+ * This does not delete the controller itself! Be careful to
+ * avoid memory leaks.
+ */
+ void
+ RemoveSGController(
+ SG_Controller* cont
+ );
+
/**
* Clear the array of pointers to controllers associated with
* this node. This does not delete the controllers themselves!