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:
authorMiika Hamalainen <blender@miikah.org>2011-09-05 21:06:09 +0400
committerMiika Hamalainen <blender@miikah.org>2011-09-05 21:06:09 +0400
commit42faf7ae41d807c2f9a94f40b774038af0c065ec (patch)
tree8460e4d70cf287da04b656748297521d0d3ef381 /source/blender/blenkernel
parent79ef35889f850aa7173800bcf67918c14f3b1291 (diff)
parent59dbd53e72ae25edf247e49ea1e291af277fecc4 (diff)
Merge with trunk r39928
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h3
-rw-r--r--source/blender/blenkernel/BKE_action.h2
-rw-r--r--source/blender/blenkernel/BKE_anim.h2
-rw-r--r--source/blender/blenkernel/BKE_animsys.h10
-rw-r--r--source/blender/blenkernel/BKE_armature.h2
-rw-r--r--source/blender/blenkernel/BKE_blender.h2
-rw-r--r--source/blender/blenkernel/BKE_constraint.h3
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h2
-rw-r--r--source/blender/blenkernel/BKE_library.h3
-rw-r--r--source/blender/blenkernel/BKE_main.h1
-rw-r--r--source/blender/blenkernel/BKE_nla.h5
-rw-r--r--source/blender/blenkernel/BKE_sequencer.h7
-rw-r--r--source/blender/blenkernel/BKE_sound.h42
-rw-r--r--source/blender/blenkernel/BKE_speaker.h43
-rw-r--r--source/blender/blenkernel/CMakeLists.txt2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c6
-rw-r--r--source/blender/blenkernel/intern/action.c97
-rw-r--r--source/blender/blenkernel/intern/anim.c13
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c112
-rw-r--r--source/blender/blenkernel/intern/armature.c2
-rw-r--r--source/blender/blenkernel/intern/blender.c8
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c31
-rw-r--r--source/blender/blenkernel/intern/collision.c6
-rw-r--r--source/blender/blenkernel/intern/constraint.c60
-rw-r--r--source/blender/blenkernel/intern/curve.c20
-rw-r--r--source/blender/blenkernel/intern/customdata.c28
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c19
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c30
-rw-r--r--source/blender/blenkernel/intern/fcurve.c140
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c94
-rw-r--r--source/blender/blenkernel/intern/gpencil.c2
-rw-r--r--source/blender/blenkernel/intern/idcode.c3
-rw-r--r--source/blender/blenkernel/intern/ipo.c18
-rw-r--r--source/blender/blenkernel/intern/key.c2
-rw-r--r--source/blender/blenkernel/intern/library.c49
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c2
-rw-r--r--source/blender/blenkernel/intern/nla.c86
-rw-r--r--source/blender/blenkernel/intern/object.c10
-rw-r--r--source/blender/blenkernel/intern/particle_system.c19
-rw-r--r--source/blender/blenkernel/intern/pointcache.c20
-rw-r--r--source/blender/blenkernel/intern/report.c6
-rw-r--r--source/blender/blenkernel/intern/scene.c23
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c2
-rw-r--r--source/blender/blenkernel/intern/sequencer.c82
-rw-r--r--source/blender/blenkernel/intern/sound.c353
-rw-r--r--source/blender/blenkernel/intern/speaker.c139
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c6
-rw-r--r--source/blender/blenkernel/intern/unit.c11
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c27
49 files changed, 1277 insertions, 378 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 46b533f33fd..6e17b056685 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -283,7 +283,8 @@ struct DerivedMesh {
int (*setDrawOptions)(void *userData, int index,
int *drawSmooth_r),
void *userData, int useColors,
- int (*setMaterial)(int, void *attribs));
+ int (*setMaterial)(int, void *attribs),
+ int (*compareDrawOptions)(void *userData, int cur_index, int next_index));
/* Draw mapped faces using MTFace
* o Drawing options too complicated to enumerate, look at code.
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 7d3de68c005..67efb7752ea 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
diff --git a/source/blender/blenkernel/BKE_anim.h b/source/blender/blenkernel/BKE_anim.h
index 25165eeaee7..44aebdf6205 100644
--- a/source/blender/blenkernel/BKE_anim.h
+++ b/source/blender/blenkernel/BKE_anim.h
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 348b967f9c4..98f9ee14c7e 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -41,6 +39,7 @@ struct KeyingSet;
struct KS_Path;
struct PointerRNA;
+struct ReportList;
struct bAction;
struct bActionGroup;
struct AnimMapper;
@@ -57,6 +56,9 @@ struct AnimData *BKE_animdata_from_id(struct ID *id);
/* Add AnimData to the given ID-block */
struct AnimData *BKE_id_add_animdata(struct ID *id);
+/* Set active action used by AnimData from the given ID-block */
+short BKE_animdata_set_action(struct ReportList *reports, struct ID *id, struct bAction *act);
+
/* Free AnimData */
void BKE_free_animdata(struct ID *id);
@@ -136,10 +138,10 @@ void BKE_animdata_main_cb(struct Main *main, ID_AnimData_Edit_Callback func, voi
/* In general, these ones should be called to do all animation evaluation */
/* Evaluation loop for evaluating animation data */
-void BKE_animsys_evaluate_animdata(struct ID *id, struct AnimData *adt, float ctime, short recalc);
+void BKE_animsys_evaluate_animdata(struct Scene *scene, struct ID *id, struct AnimData *adt, float ctime, short recalc);
/* Evaluation of all ID-blocks with Animation Data blocks - Animation Data Only */
-void BKE_animsys_evaluate_all_animation(struct Main *main, float ctime);
+void BKE_animsys_evaluate_all_animation(struct Main *main, struct Scene *scene, float ctime);
/* ------------ Specialised API --------------- */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index efa87532859..7d60c00156d 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index 162b0de1d5a..0f19cfbc481 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -44,7 +44,7 @@ extern "C" {
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 259
-#define BLENDER_SUBVERSION 0
+#define BLENDER_SUBVERSION 1
#define BLENDER_MINVERSION 250
#define BLENDER_MINSUBVERSION 0
diff --git a/source/blender/blenkernel/BKE_constraint.h b/source/blender/blenkernel/BKE_constraint.h
index 7c0e7050a9f..925d1180dbd 100644
--- a/source/blender/blenkernel/BKE_constraint.h
+++ b/source/blender/blenkernel/BKE_constraint.h
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -154,6 +152,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_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index b791e29a38e..244fda33a52 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -199,7 +199,7 @@ struct FCurve *list_find_fcurve(ListBase *list, const char rna_path[], const int
struct FCurve *iter_step_fcurve (struct FCurve *fcu_iter, const char rna_path[]);
/* high level function to get an fcurve from C without having the rna */
-struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, const char *prop_name, int index);
+struct FCurve *id_data_find_fcurve(ID *id, void *data, struct StructRNA *type, const char *prop_name, int index, char *driven);
/* Get list of LinkData's containing pointers to the F-Curves which control the types of data indicated
* e.g. numMatches = list_find_data_fcurves(matches, &act->curves, "pose.bones[", "MyFancyBone");
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 871a78bbab3..0d6d41109b4 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -44,6 +44,8 @@ struct Main;
struct Library;
struct wmWindowManager;
struct bContext;
+struct PointerRNA;
+struct PropertyRNA;
void *alloc_libblock(struct ListBase *lb, short type, const char *name);
void *copy_libblock(void *rt);
@@ -53,6 +55,7 @@ void id_lib_extern(struct ID *id);
void id_us_plus(struct ID *id);
void id_us_min(struct ID *id);
int id_make_local(struct ID *id, int test);
+int id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
int id_copy(struct ID *id, struct ID **newid, int test);
int id_unlink(struct ID *id, int test);
diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h
index df6a304f0b3..c25882d1dd6 100644
--- a/source/blender/blenkernel/BKE_main.h
+++ b/source/blender/blenkernel/BKE_main.h
@@ -77,6 +77,7 @@ typedef struct Main {
ListBase script;
ListBase vfont;
ListBase text;
+ ListBase speaker;
ListBase sound;
ListBase group;
ListBase armature;
diff --git a/source/blender/blenkernel/BKE_nla.h b/source/blender/blenkernel/BKE_nla.h
index 0206756a1ad..773c5ced1cb 100644
--- a/source/blender/blenkernel/BKE_nla.h
+++ b/source/blender/blenkernel/BKE_nla.h
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -39,6 +37,8 @@ struct AnimData;
struct NlaStrip;
struct NlaTrack;
struct bAction;
+struct Scene;
+struct Speaker;
/* ----------------------------- */
/* Data Management */
@@ -54,6 +54,7 @@ void copy_nladata(ListBase *dst, ListBase *src);
struct NlaTrack *add_nlatrack(struct AnimData *adt, struct NlaTrack *prev);
struct NlaStrip *add_nlastrip(struct bAction *act);
struct NlaStrip *add_nlastrip_to_stack(struct AnimData *adt, struct bAction *act);
+struct NlaStrip *add_nla_soundstrip(struct Scene *scene, struct Speaker *spk);
/* ----------------------------- */
/* API */
diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h
index b20811724f4..cf68e5795b4 100644
--- a/source/blender/blenkernel/BKE_sequencer.h
+++ b/source/blender/blenkernel/BKE_sequencer.h
@@ -43,6 +43,7 @@ struct Scene;
struct Sequence;
struct Strip;
struct StripElem;
+struct bSound;
#define MAXSEQ 32
@@ -287,8 +288,10 @@ void free_imbuf_seq(struct Scene *scene, struct ListBase * seqbasep, int check_m
struct Sequence *seq_dupli_recursive(struct Scene *scene, struct Scene *scene_to, struct Sequence * seq, int dupe_flag);
int seq_swap(struct Sequence *seq_a, struct Sequence *seq_b, const char **error_str);
-void seq_update_sound(struct Scene* scene, struct Sequence *seq);
-void seq_update_muting(struct Scene* scene, struct Editing *ed);
+void seq_update_sound_bounds_all(struct Scene *scene);
+void seq_update_sound_bounds(struct Scene* scene, struct Sequence *seq);
+void seq_update_muting(struct Editing *ed);
+void seq_update_sound(struct Scene *scene, struct bSound *sound);
void seqbase_sound_reload(struct Scene *scene, ListBase *seqbase);
void seqbase_unique_name_recursive(ListBase *seqbasep, struct Sequence *seq);
void seqbase_dupli_recursive(struct Scene *scene, struct Scene *scene_to, ListBase *nseqbase, ListBase *seqbase, int dupe_flag);
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 04597fd666e..fac5bf1cfd2 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -35,6 +35,8 @@
* \author nzc
*/
+#define SOUND_WAVE_SAMPLES_PER_SECOND 250
+
struct PackedFile;
struct bSound;
struct bContext;
@@ -42,10 +44,18 @@ struct ListBase;
struct Main;
struct Sequence;
+typedef struct SoundWaveform
+{
+ int length;
+ float *data;
+} SoundWaveform;
+
void sound_init_once(void);
void sound_init(struct Main *main);
+void sound_init_main(struct Main *bmain);
+
void sound_exit(void);
void sound_force_device(int device);
@@ -62,7 +72,9 @@ struct bSound* sound_new_limiter(struct bContext *C, struct bSound *source, floa
void sound_delete(struct bContext *C, struct bSound* sound);
-void sound_cache(struct bSound* sound, int ignore);
+void sound_cache(struct bSound* sound);
+
+void sound_cache_notifying(struct Main* main, struct bSound* sound);
void sound_delete_cache(struct bSound* sound);
@@ -80,16 +92,34 @@ void sound_destroy_scene(struct Scene *scene);
void sound_mute_scene(struct Scene *scene, int muted);
+void sound_update_fps(struct Scene *scene);
+
+void sound_update_scene_listener(struct Scene *scene);
+
void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip);
void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip);
void sound_remove_scene_sound(struct Scene *scene, void* handle);
-void sound_mute_scene_sound(struct Scene *scene, void* handle, char mute);
+void sound_mute_scene_sound(void* handle, char mute);
void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip);
+void sound_update_scene_sound(void* handle, struct bSound* sound);
+
+void sound_set_cfra(int cfra);
+
+void sound_set_scene_volume(struct Scene *scene, float volume);
+
+void sound_set_scene_sound_volume(void* handle, float volume, char animated);
+
+void sound_set_scene_sound_pitch(void* handle, float pitch, char animated);
+
+void sound_set_scene_sound_pan(void* handle, float pan, char animated);
+
+void sound_update_sequencer(struct Main* main, struct bSound* sound);
+
void sound_play_scene(struct Scene *scene);
void sound_stop_scene(struct Scene *scene);
@@ -100,8 +130,12 @@ float sound_sync_scene(struct Scene *scene);
int sound_scene_playing(struct Scene *scene);
-int sound_read_sound_buffer(struct bSound* sound, float* buffer, int length, float start, float end);
+void sound_free_waveform(struct bSound* sound);
+
+void sound_read_waveform(struct bSound* sound);
+
+void sound_update_scene(struct Scene* scene);
-int sound_get_channels(struct bSound* sound);
+void* sound_get_factory(void* sound);
#endif
diff --git a/source/blender/blenkernel/BKE_speaker.h b/source/blender/blenkernel/BKE_speaker.h
new file mode 100644
index 00000000000..111bd86fdd3
--- /dev/null
+++ b/source/blender/blenkernel/BKE_speaker.h
@@ -0,0 +1,43 @@
+/*
+ * $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): Jörg Müller.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef BKE_SPEAKER_H
+#define BKE_SPEAKER_H
+
+/** \file BKE_speaker.h
+ * \ingroup bke
+ * \brief General operations for speakers.
+ */
+
+void *add_speaker(const char *name);
+struct Speaker *copy_speaker(struct Speaker *spk);
+void make_local_speaker(struct Speaker *spk);
+void free_speaker(struct Speaker *spk);
+
+#endif
diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt
index a869c23f868..18216f03873 100644
--- a/source/blender/blenkernel/CMakeLists.txt
+++ b/source/blender/blenkernel/CMakeLists.txt
@@ -141,6 +141,7 @@ set(SRC
intern/smoke.c
intern/softbody.c
intern/sound.c
+ intern/speaker.c
intern/subsurf_ccg.c
intern/suggestions.c
intern/text.c
@@ -221,6 +222,7 @@ set(SRC
BKE_smoke.h
BKE_softbody.h
BKE_sound.h
+ BKE_speaker.h
BKE_subsurf.h
BKE_suggestions.h
BKE_text.h
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 00cf03712ea..04c5bf0e1e0 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -637,7 +637,8 @@ static void emDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *use
}
/* note, material function is ignored for now. */
-static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int UNUSED(useColors), int (*setMaterial)(int, void *attribs))
+static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int UNUSED(useColors), int (*setMaterial)(int, void *attribs),
+ int (*compareDrawOptions)(void *userData, int cur_index, int next_index))
{
EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
EditFace *efa;
@@ -645,6 +646,9 @@ static void emDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
(void)setMaterial; /* unused */
+ /* currently unused -- each original face is handled separately */
+ (void)compareDrawOptions;
+
if (emdm->vertexCos) {
EditVert *eve;
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index f7086c81756..9c2467505cd 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -85,66 +83,84 @@ 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;
}
+/* .................................. */
+
+/* temp data for make_local_action */
+typedef struct tMakeLocalActionContext {
+ bAction *act; /* original action */
+ bAction *actn; /* new action */
+
+ int lib; /* some action users were libraries */
+ int local; /* some action users were not libraries */
+} tMakeLocalActionContext;
+
+/* helper function for make_local_action() - local/lib init step */
+static void make_localact_init_cb(ID *id, AnimData *adt, void *mlac_ptr)
+{
+ tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr;
+
+ if (adt->action == mlac->act) {
+ if (id->lib)
+ mlac->lib = 1;
+ else
+ mlac->local = 1;
+ }
+}
+
+/* helper function for make_local_action() - change references */
+static void make_localact_apply_cb(ID *id, AnimData *adt, void *mlac_ptr)
+{
+ tMakeLocalActionContext *mlac = (tMakeLocalActionContext *)mlac_ptr;
+
+ if (adt->action == mlac->act) {
+ if (id->lib==0) {
+ adt->action = mlac->actn;
+
+ id_us_plus(&mlac->actn->id);
+ id_us_min(&mlac->act->id);
+ }
+ }
+}
+
// does copy_fcurve...
void make_local_action(bAction *act)
{
- // Object *ob;
+ tMakeLocalActionContext mlac = {act, NULL, 0, 0};
Main *bmain= G.main;
- bAction *actn;
- int local=0, lib=0;
- if (act->id.lib==NULL) return;
- if (act->id.us==1) {
+ if (act->id.lib==NULL)
+ return;
+
+ // XXX: double-check this; it used to be just single-user check, but that was when fake-users were still default
+ if ((act->id.flag & LIB_FAKEUSER) && (act->id.us<=1)) {
act->id.lib= NULL;
act->id.flag= LIB_LOCAL;
new_id(&bmain->action, (ID *)act, NULL);
return;
}
-#if 0 // XXX old animation system
- ob= G.main->object.first;
- while(ob) {
- if(ob->action==act) {
- if(ob->id.lib) lib= 1;
- else local= 1;
- }
- ob= ob->id.next;
- }
-#endif
+ BKE_animdata_main_cb(bmain, make_localact_init_cb, &mlac);
- if(local && lib==0) {
+ if (mlac.local && mlac.lib==0) {
act->id.lib= NULL;
act->id.flag= LIB_LOCAL;
//make_local_action_channels(act);
new_id(&bmain->action, (ID *)act, NULL);
}
- else if(local && lib) {
- actn= copy_action(act);
- actn->id.us= 0;
+ else if (mlac.local && mlac.lib) {
+ mlac.actn= copy_action(act);
+ mlac.actn->id.us= 0;
-#if 0 // XXX old animation system
- ob= G.main->object.first;
- while(ob) {
- if(ob->action==act) {
-
- if(ob->id.lib==0) {
- ob->action = actn;
- actn->id.us++;
- act->id.us--;
- }
- }
- ob= ob->id.next;
- }
-#endif // XXX old animation system
+ BKE_animdata_main_cb(bmain, make_localact_apply_cb, &mlac);
}
}
+/* .................................. */
+
void free_action (bAction *act)
{
/* sanity check */
@@ -163,6 +179,8 @@ void free_action (bAction *act)
BLI_freelistN(&act->markers);
}
+/* .................................. */
+
bAction *copy_action (bAction *src)
{
bAction *dst = NULL;
@@ -200,9 +218,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;
}
@@ -1180,7 +1195,7 @@ void what_does_obaction (Object *ob, Object *workob, bPose *pose, bAction *act,
adt.action= act;
/* execute effects of Action on to workob (or it's PoseChannels) */
- BKE_animsys_evaluate_animdata(&workob->id, &adt, cframe, ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(NULL, &workob->id, &adt, cframe, ADT_RECALC_ANIM);
}
}
diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c
index fcb8da48962..9ca11db7fce 100644
--- a/source/blender/blenkernel/intern/anim.c
+++ b/source/blender/blenkernel/intern/anim.c
@@ -1,8 +1,4 @@
-/* anim.c
- *
- *
- * $Id$
- *
+/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -173,7 +169,7 @@ bMotionPath *animviz_verify_motionpaths(Scene *scene, Object *ob, bPoseChannel *
}
/* avoid 0 size allocs */
- if(avs->path_sf >= avs->path_ef) {
+ if (avs->path_sf >= avs->path_ef) {
return NULL;
}
@@ -231,6 +227,7 @@ typedef struct MPathTarget {
/* get list of motion paths to be baked for the given object
* - assumes the given list is ready to be used
*/
+// TODO: it would be nice in future to be able to update objects dependant on these bones too?
void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
{
MPathTarget *mpt;
@@ -795,7 +792,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level,
* and/or other objects which may affect this object's transforms are not updated either.
* However, this has always been the way that this worked (i.e. pre 2.5), so I guess that it'll be fine!
*/
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */
where_is_object_time(scene, ob, (float)scene->r.cfra);
dob= new_dupli_object(lb, ob, ob->obmat, ob->lay, scene->r.cfra, OB_DUPLIFRAMES, animated);
@@ -810,7 +807,7 @@ static void frames_duplilist(ListBase *lb, Scene *scene, Object *ob, int level,
*/
scene->r.cfra= cfrao;
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, (float)scene->r.cfra, ADT_RECALC_ANIM); /* ob-eval will do drivers, so we don't need to do them */
where_is_object_time(scene, ob, (float)scene->r.cfra);
/* but, to make sure unkeyed object transforms are still sane,
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index fdc102bf779..b690c9b4a91 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -56,6 +54,7 @@
#include "BKE_global.h"
#include "BKE_main.h"
#include "BKE_library.h"
+#include "BKE_report.h"
#include "BKE_utildefines.h"
#include "RNA_access.h"
@@ -84,6 +83,7 @@ short id_type_can_have_animdata (ID *id)
case ID_PA:
case ID_MA: case ID_TE: case ID_NT:
case ID_LA: case ID_CA: case ID_WO:
+ case ID_SPK:
case ID_SCE:
{
return 1;
@@ -144,6 +144,59 @@ AnimData *BKE_id_add_animdata (ID *id)
return NULL;
}
+/* Action Setter --------------------------------------- */
+
+/* Called when user tries to change the active action of an AnimData block (via RNA, Outliner, etc.) */
+short BKE_animdata_set_action (ReportList *reports, ID *id, bAction *act)
+{
+ AnimData *adt = BKE_animdata_from_id(id);
+ short ok = 0;
+
+ /* animdata validity check */
+ if (adt == NULL) {
+ BKE_report(reports, RPT_WARNING, "No AnimData to set action on");
+ return ok;
+ }
+
+ /* active action is only editable when it is not a tweaking strip
+ * see rna_AnimData_action_editable() in rna_animation.c
+ */
+ if ((adt->flag & ADT_NLA_EDIT_ON) || (adt->actstrip) || (adt->tmpact)) {
+ /* cannot remove, otherwise things turn to custard */
+ BKE_report(reports, RPT_ERROR, "Cannot change action, as it is still being edited in NLA");
+ return ok;
+ }
+
+ /* 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 (act) {
+ /* action must have same type as owner */
+ if (ELEM(act->idroot, 0, GS(id->name))) {
+ /* can set */
+ adt->action = act;
+ id_us_plus((ID*)adt->action);
+ ok = 1;
+ }
+ else {
+ /* cannot set */
+ BKE_reportf(reports, RPT_ERROR,
+ "Couldn't set Action '%s' onto ID '%s', as it doesn't have suitably rooted paths for this purpose",
+ act->id.name+2, id->name);
+ //ok = 0;
+ }
+ }
+ else {
+ /* just clearing the action... */
+ adt->action = NULL;
+ ok = 1;
+ }
+
+ return ok;
+}
+
/* Freeing -------------------------------------------- */
/* Free AnimData used by the nominated ID-block, and clear ID-block's AnimData pointer */
@@ -234,7 +287,7 @@ int BKE_copy_animdata_id (ID *id_to, ID *id_from, const short do_action)
return 1;
}
-void BKE_copy_animdata_id_action(struct ID *id)
+void BKE_copy_animdata_id_action(ID *id)
{
AnimData *adt= BKE_animdata_from_id(id);
if (adt) {
@@ -733,7 +786,10 @@ void BKE_animdata_main_cb (Main *mainptr, ID_AnimData_Edit_Callback func, void *
/* particles */
ANIMDATA_IDS_CB(mainptr->particle.first);
-
+
+ /* speakers */
+ ANIMDATA_IDS_CB(mainptr->speaker.first);
+
/* objects */
ANIMDATA_IDS_CB(mainptr->object.first);
@@ -811,7 +867,10 @@ void BKE_all_animdata_fix_paths_rename (char *prefix, char *oldName, char *newNa
/* particles */
RENAMEFIX_ANIM_IDS(mainptr->particle.first);
-
+
+ /* speakers */
+ RENAMEFIX_ANIM_IDS(mainptr->speaker.first);
+
/* objects */
RENAMEFIX_ANIM_IDS(mainptr->object.first);
@@ -1062,7 +1121,7 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
{
int array_len= RNA_property_array_length(&new_ptr, prop);
- if(array_len && array_index >= array_len)
+ if (array_len && array_index >= array_len)
{
if (G.f & G_DEBUG) {
printf("Animato: Invalid array index. ID = '%s', '%s[%d]', array length is %d \n",
@@ -1100,6 +1159,23 @@ static short animsys_write_rna_setting (PointerRNA *ptr, char *path, int array_i
/* nothing can be done here... so it is unsuccessful? */
return 0;
}
+
+ /* buffer property update for later flushing */
+ if (RNA_property_update_check(prop)) {
+ short skip_updates_hack = 0;
+
+ /* optimisation hacks: skip property updates for those properties
+ * for we know that which the updates in RNA were really just for
+ * flushing property editing via UI/Py
+ */
+ if (new_ptr.type == &RNA_PoseBone) {
+ /* bone transforms - update pose (i.e. tag depsgraph) */
+ skip_updates_hack = 1;
+ }
+
+ if (skip_updates_hack == 0)
+ RNA_property_update_cache_add(&new_ptr, prop);
+ }
}
/* successful */
@@ -1843,6 +1919,9 @@ void nlastrip_evaluate (PointerRNA *ptr, ListBase *channels, ListBase *modifiers
case NLASTRIP_TYPE_META: /* meta */
nlastrip_evaluate_meta(ptr, channels, modifiers, nes);
break;
+
+ default: /* do nothing */
+ break;
}
/* clear temp recursion safe-check */
@@ -2078,7 +2157,7 @@ static void animsys_evaluate_overrides (PointerRNA *ptr, AnimData *adt)
* and that the flags for which parts of the anim-data settings need to be recalculated
* have been set already by the depsgraph. Now, we use the recalc
*/
-void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short recalc)
+void BKE_animsys_evaluate_animdata (Scene *scene, ID *id, AnimData *adt, float ctime, short recalc)
{
PointerRNA id_ptr;
@@ -2130,6 +2209,14 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re
*/
animsys_evaluate_overrides(&id_ptr, adt);
+ /* execute and clear all cached property update functions */
+ if (scene)
+ {
+ Main *bmain = G.main; // xxx - to get passed in!
+ RNA_property_update_cache_flush(bmain, scene);
+ RNA_property_update_cache_free();
+ }
+
/* clear recalc flag now */
adt->recalc= 0;
}
@@ -2141,7 +2228,7 @@ void BKE_animsys_evaluate_animdata (ID *id, AnimData *adt, float ctime, short re
* 'local' (i.e. belonging in the nearest ID-block that setting is related to, not a
* standard 'root') block are overridden by a larger 'user'
*/
-void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
+void BKE_animsys_evaluate_all_animation (Main *main, Scene *scene, float ctime)
{
ID *id;
@@ -2157,7 +2244,7 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
for (id= first; id; id= id->next) { \
if (ID_REAL_USERS(id) > 0) { \
AnimData *adt= BKE_animdata_from_id(id); \
- BKE_animsys_evaluate_animdata(id, adt, ctime, aflag); \
+ BKE_animsys_evaluate_animdata(scene, id, adt, ctime, aflag); \
} \
}
/* another macro for the "embedded" nodetree cases
@@ -2173,9 +2260,9 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
NtId_Type *ntp= (NtId_Type *)id; \
if (ntp->nodetree) { \
AnimData *adt2= BKE_animdata_from_id((ID *)ntp->nodetree); \
- BKE_animsys_evaluate_animdata((ID *)ntp->nodetree, adt2, ctime, ADT_RECALC_ANIM); \
+ BKE_animsys_evaluate_animdata(scene, (ID *)ntp->nodetree, adt2, ctime, ADT_RECALC_ANIM); \
} \
- BKE_animsys_evaluate_animdata(id, adt, ctime, aflag); \
+ BKE_animsys_evaluate_animdata(scene, id, adt, ctime, aflag); \
} \
}
@@ -2230,6 +2317,9 @@ void BKE_animsys_evaluate_all_animation (Main *main, float ctime)
/* particles */
EVAL_ANIM_IDS(main->particle.first, ADT_RECALC_ANIM);
+ /* lamps */
+ EVAL_ANIM_IDS(main->speaker.first, ADT_RECALC_ANIM);
+
/* objects */
/* ADT_RECALC_ANIM doesn't need to be supplied here, since object AnimData gets
* this tagged by Depsgraph on framechange. This optimisation means that objects
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 0b31e51d62e..62ce184a2d7 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 7e2097d1233..5f33059e117 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -82,6 +82,7 @@
#include "BKE_scene.h"
#include "BKE_screen.h"
#include "BKE_sequencer.h"
+#include "BKE_sound.h"
#include "BLO_undofile.h"
@@ -90,6 +91,8 @@
#include "BKE_utildefines.h"
+#include "RNA_access.h"
+
#include "WM_api.h" // XXXXX BAD, very BAD dependency (bad level call) - remove asap, elubie
Global G;
@@ -239,9 +242,14 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath
// CTX_wm_manager_set(C, NULL);
clear_global();
+ /* clear old property update cache, in case some old references are left dangling */
+ RNA_property_update_cache_free();
+
G.main= bfd->main;
CTX_data_main_set(C, G.main);
+
+ sound_init_main(G.main);
if (bfd->user) {
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 95f46a822f6..5e2f0aa5b7a 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -843,7 +843,8 @@ static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tfa
cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
}
-static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs))
+static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
+ int (*compareDrawOptions)(void *userData, int cur_index, int next_index))
{
CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
MVert *mv = cddm->mvert;
@@ -960,6 +961,7 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
MFace *mface= mf + actualFace;
int drawSmooth= (mface->flag & ME_SMOOTH);
int draw = 1;
+ int flush = 0;
if(i != tottri-1)
next_actualFace= dm->drawObject->triangle_to_mface[i+1];
@@ -974,11 +976,28 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us
/* Goal is to draw as long of a contiguous triangle
array as possible, so draw when we hit either an
invisible triangle or at the end of the array */
- if(!draw || i == tottri - 1 || mf[actualFace].mat_nr != mf[next_actualFace].mat_nr) {
- if(prevstart != i)
- /* Add one to the length (via `draw')
- if we're drawing at the end of the array */
- glDrawArrays(GL_TRIANGLES,prevstart*3, (i-prevstart+draw)*3);
+
+ /* flush buffer if current triangle isn't drawable or it's last triangle... */
+ flush= !draw || i == tottri - 1;
+
+ /* ... or when material setting is dissferent */
+ flush|= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
+
+ if(!flush && compareDrawOptions) {
+ int next_orig= (index==NULL) ? next_actualFace : index[next_actualFace];
+
+ /* also compare draw options and flush buffer if they're different
+ need for face selection highlight in edit mode */
+ flush|= compareDrawOptions(userData, orig, next_orig) == 0;
+ }
+
+ if(flush) {
+ int first= prevstart*3;
+ int count= (i-prevstart+(draw ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
+
+ if(count)
+ glDrawArrays(GL_TRIANGLES, first, count);
+
prevstart = i + 1;
}
}
diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c
index e2a1b0dfb33..ed073f03270 100644
--- a/source/blender/blenkernel/intern/collision.c
+++ b/source/blender/blenkernel/intern/collision.c
@@ -1091,7 +1091,7 @@ static int cloth_collision_response_moving ( ClothModifierData *clmd, CollisionM
VECADDMUL(cloth1->verts[collpair->ap1].impulse, pimpulse, w1*2.0);
VECADDMUL(cloth1->verts[collpair->ap2].impulse, pimpulse, w2*2.0);
- VECADDMUL(cloth1->verts[collpair->ap3].impulse, pimpulse, w3*2.0);;
+ VECADDMUL(cloth1->verts[collpair->ap3].impulse, pimpulse, w3*2.0);
cloth1->verts[collpair->ap1].impulse_count++;
cloth1->verts[collpair->ap2].impulse_count++;
cloth1->verts[collpair->ap3].impulse_count++;
@@ -1487,8 +1487,8 @@ static CollPair* cloth_collision ( ModifierData *md1, ModifierData *md2,
sdis = clmd->coll_parms->distance_repel + epsilon2 + FLT_EPSILON;
- /*apply a repulsion force, to help the solver along.
- this is kindof crude, it only tests one vert of the triangle*/
+ /* apply a repulsion force, to help the solver along.
+ * this is kindof crude, it only tests one vert of the triangle */
if (isect_ray_plane_v3(cloth->verts[collpair->ap1].tx, n2, collmd->current_xnew[collpair->bp1].co,
collmd->current_xnew[collpair->bp2].co,
collmd->current_xnew[collpair->bp3].co, &l, 0))
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 7be4744a224..91091d3880f 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -2641,7 +2639,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) {
@@ -2654,14 +2652,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;
}
@@ -2670,7 +2668,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;
}
}
@@ -4420,6 +4418,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 ----------- */
@@ -4464,27 +4490,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/curve.c b/source/blender/blenkernel/intern/curve.c
index eb364af6ff8..b1beb6c449a 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -2473,7 +2473,7 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
if(len2==0.0f) len2=1.0f;
- if(bezt->h1==HD_AUTO || bezt->h2==HD_AUTO) { /* auto */
+ if(ELEM(bezt->h1,HD_AUTO,HD_AUTO_ANIM) || ELEM(bezt->h2,HD_AUTO,HD_AUTO_ANIM)) { /* auto */
vx= dx1/len2 + dx/len1;
vy= dy1/len2 + dy/len1;
vz= dz1/len2 + dz/len1;
@@ -2484,13 +2484,13 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
if(len1>5.0f*len2) len1= 5.0f*len2;
if(len2>5.0f*len1) len2= 5.0f*len1;
- if(bezt->h1==HD_AUTO) {
+ if(ELEM(bezt->h1,HD_AUTO,HD_AUTO_ANIM)) {
len1/=len;
*(p2-3)= *p2-vx*len1;
*(p2-2)= *(p2+1)-vy*len1;
*(p2-1)= *(p2+2)-vz*len1;
- if(mode==2 && next && prev) { // keep horizontal if extrema
+ if((bezt->h1==HD_AUTO_ANIM) && next && prev) { // keep horizontal if extrema
float ydiff1= prev->vec[1][1] - bezt->vec[1][1];
float ydiff2= next->vec[1][1] - bezt->vec[1][1];
if( (ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f) ) {
@@ -2512,13 +2512,13 @@ void calchandleNurb(BezTriple *bezt, BezTriple *prev, BezTriple *next, int mode)
}
}
}
- if(bezt->h2==HD_AUTO) {
+ if(ELEM(bezt->h2,HD_AUTO,HD_AUTO_ANIM)) {
len2/=len;
*(p2+3)= *p2+vx*len2;
*(p2+4)= *(p2+1)+vy*len2;
*(p2+5)= *(p2+2)+vz*len2;
- if(mode==2 && next && prev) { // keep horizontal if extrema
+ if((bezt->h2==HD_AUTO_ANIM) && next && prev) { // keep horizontal if extrema
float ydiff1= prev->vec[1][1] - bezt->vec[1][1];
float ydiff2= next->vec[1][1] - bezt->vec[1][1];
if( (ydiff1 <= 0.0f && ydiff2 <= 0.0f) || (ydiff1 >= 0.0f && ydiff2 >= 0.0f) ) {
@@ -2674,15 +2674,15 @@ void testhandlesNurb(Nurb *nu)
if(bezt->f1 & SELECT) flag++;
if(bezt->f2 & SELECT) flag += 2;
if(bezt->f3 & SELECT) flag += 4;
-
+
if( !(flag==0 || flag==7) ) {
- if(bezt->h1==HD_AUTO) { /* auto */
+ if(ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM)) { /* auto */
bezt->h1= HD_ALIGN;
}
- if(bezt->h2==HD_AUTO) { /* auto */
+ if(ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) { /* auto */
bezt->h2= HD_ALIGN;
}
-
+
if(bezt->h1==HD_VECT) { /* vector */
if(flag < 4) bezt->h1= 0;
}
@@ -2692,7 +2692,7 @@ void testhandlesNurb(Nurb *nu)
}
bezt++;
}
-
+
calchandlesNurb(nu);
}
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 8d19322c0db..c342bbc917f 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -808,41 +808,65 @@ static void layerDefault_mcol(void *data, int count)
static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
+ /* 0: CD_MVERT */
{sizeof(MVert), "MVert", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 1: CD_MSTICKY */
{sizeof(MSticky), "MSticky", 1, NULL, NULL, NULL, layerInterp_msticky, NULL,
NULL},
+ /* 2: CD_MDEFORMVERT */
{sizeof(MDeformVert), "MDeformVert", 1, NULL, layerCopy_mdeformvert,
layerFree_mdeformvert, layerInterp_mdeformvert, NULL, NULL},
+ /* 3: CD_MEDGE */
{sizeof(MEdge), "MEdge", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 4: CD_MFACE */
{sizeof(MFace), "MFace", 1, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 5: CD_MTFACE */
{sizeof(MTFace), "MTFace", 1, "UVTex", layerCopy_tface, NULL,
layerInterp_tface, layerSwap_tface, layerDefault_tface},
+ /* 6: CD_MCOL */
/* 4 MCol structs per face */
{sizeof(MCol)*4, "MCol", 4, "Col", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
+ /* 7: CD_ORIGINDEX */
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 8: CD_NORMAL */
/* 3 floats per normal vector */
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 9: CD_FLAGS */
{sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 10: CD_PROP_FLT */
{sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
+ /* 11: CD_PROP_INT */
{sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
+ /* 12: CD_PROP_STR */
{sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
+ /* 13: CD_ORIGSPACE */
{sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
+ /* 14: CD_ORCO */
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 15: CD_MTEXPOLY */
{sizeof(MTexPoly), "MTexPoly", 1, "Face Texture", NULL, NULL, NULL, NULL, NULL},
+ /* 16: CD_MLOOPUV */
{sizeof(MLoopUV), "MLoopUV", 1, "UV coord", NULL, NULL, layerInterp_mloopuv, NULL, NULL},
+ /* 17: CD_MLOOPCOL */
{sizeof(MLoopCol), "MLoopCol", 1, "Col", NULL, NULL, layerInterp_mloopcol, NULL, layerDefault_mloopcol},
+ /* 18: CD_TANGENT */
{sizeof(float)*4*4, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
+ /* 19: CD_MDISPS */
{sizeof(MDisps), "MDisps", 1, NULL, layerCopy_mdisps,
layerFree_mdisps, layerInterp_mdisps, layerSwap_mdisps, NULL, layerRead_mdisps, layerWrite_mdisps,
layerFilesize_mdisps, layerValidate_mdisps},
+ /* 20: CD_WEIGHT_MCOL */
{sizeof(MCol)*4, "MCol", 4, "WeightCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
- {sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
+ /* 21: CD_ID_MCOL */
+ {sizeof(MCol)*4, "MCol", 4, "IDCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
- {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol,
+ /* 22: CD_TEXTURE_MCOL */
+ {sizeof(MCol)*4, "MCol", 4, "TexturedCol", NULL, NULL, layerInterp_mcol,
layerSwap_mcol, layerDefault_mcol},
+ /* 23: CD_CLOTH_ORCO */
{sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL}
};
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 667e0850111..6f27a104144 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -2062,6 +2062,23 @@ static short animdata_use_time(AnimData *adt)
return 1;
}
+ /* If we have drivers, more likely than not, on a frame change
+ * they'll need updating because their owner changed
+ *
+ * This is kindof a hack to get around a whole host of problems
+ * involving drivers using non-object datablock data (which the
+ * depsgraph currently has no way of representing let alone correctly
+ * dependency sort+tagging). By doing this, at least we ensure that
+ * some commonly attempted drivers (such as scene -> current frame;
+ * see "Driver updates fail" thread on Bf-committers dated July 2)
+ * will work correctly, and that other non-object datablocks will have
+ * their drivers update at least on frame change.
+ *
+ * -- Aligorith, July 4 2011
+ */
+ if (adt->drivers.first)
+ return 1;
+
return 0;
}
@@ -2378,7 +2395,7 @@ static void dag_id_flush_update(Scene *sce, ID *id)
if(id) {
idtype= GS(id->name);
- if(ELEM7(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR)) {
+ if(ELEM8(idtype, ID_ME, ID_CU, ID_MB, ID_LA, ID_LT, ID_CA, ID_AR, ID_SPK)) {
for(obt=bmain->object.first; obt; obt= obt->id.next) {
if(!(ob && obt == ob) && obt->data == id) {
obt->recalc |= OB_RECALC_DATA;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index 10731faf3ad..54613508a8a 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -25,6 +25,16 @@
/* Platform independend time */
#include "PIL_time.h"
+#include "DNA_anim_types.h"
+#include "DNA_dynamicpaint_types.h"
+#include "DNA_group_types.h" /*GroupObject*/
+#include "DNA_mesh_types.h"
+#include "DNA_meshdata_types.h"
+#include "DNA_modifier_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_userdef_types.h" /* to get temp file path */
+
#include "BKE_animsys.h"
#include "BKE_bvhutils.h" /* bvh tree */
#include "BKE_blender.h"
@@ -48,16 +58,6 @@
#include "BKE_scene.h"
#include "BKE_texture.h"
-#include "DNA_anim_types.h"
-#include "DNA_dynamicpaint_types.h"
-#include "DNA_group_types.h" /*GroupObject*/
-#include "DNA_mesh_types.h"
-#include "DNA_meshdata_types.h"
-#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_userdef_types.h" /* to get temp file path */
-
#include "RNA_access.h"
#include "RNA_define.h"
#include "RNA_enum_types.h"
@@ -447,7 +447,7 @@ static void subframe_updateObject(Scene *scene, Object *ob, int flags, float fra
/* for curve */
if(ob->type==OB_CURVE) {
Curve *cu= ob->data;
- BKE_animsys_evaluate_animdata(&cu->id, cu->adt, frame, ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(scene, &cu->id, cu->adt, frame, ADT_RECALC_ANIM);
}
/* backup object flags */
@@ -455,7 +455,7 @@ static void subframe_updateObject(Scene *scene, Object *ob, int flags, float fra
ob->recalc |= OB_RECALC_ALL;
ob->recalc |= OB_RECALC_DATA;
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, frame, ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, frame, ADT_RECALC_ANIM);
if (flags & UPDATE_MESH) {
/* ignore cache clear during subframe updates
* to not mess up cache validity */
@@ -2756,7 +2756,7 @@ static void dynamicPaint_copyUpdatedMaterial(Material *orig_mat, Scene *scene, M
if (orig_mat == NULL) return;
/* update material anims */
- BKE_animsys_evaluate_animdata(&orig_mat->id, orig_mat->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(scene, &orig_mat->id, orig_mat->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
/* copy material */
mat = MEM_callocN(sizeof(Material), "Temp Brush Material");
@@ -2810,7 +2810,7 @@ static void dynamicPaint_copyUpdatedMaterial(Material *orig_mat, Scene *scene, M
}
/* update texture anims */
- BKE_animsys_evaluate_animdata(&tex->id, tex->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(scene, &tex->id, tex->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
/* if texture type requires caching, create a copy of texture/data too
* to be able to re-cache safely.
@@ -5148,7 +5148,7 @@ static int dynamicPaint_doStep(Scene *scene, Object *ob, DynamicPaintSurface *su
psys_check_enabled(brushObj, brush->psys)) {
/* Paint a particle system */
- BKE_animsys_evaluate_animdata(&brush->psys->part->id, brush->psys->part->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(scene, &brush->psys->part->id, brush->psys->part->adt, BKE_curframe(scene), ADT_RECALC_ANIM);
dynamicPaint_paintParticles(surface, brush->psys, brush, ob, timescale);
}
}
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 13e13fbc3ff..3916d0ca701 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -42,6 +40,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 +51,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"
@@ -172,7 +172,7 @@ void copy_fcurves (ListBase *dst, ListBase *src)
/* ----------------- Finding F-Curves -------------------------- */
/* high level function to get an fcurve from C without having the rna */
-FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, const char *prop_name, int index)
+FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, const char *prop_name, int index, char *driven)
{
/* anim vars */
AnimData *adt= BKE_animdata_from_id(id);
@@ -182,6 +182,9 @@ FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, const char *pro
PointerRNA ptr;
PropertyRNA *prop;
char *path;
+
+ if(driven)
+ *driven = 0;
/* only use the current action ??? */
if (ELEM(NULL, adt, adt->action))
@@ -199,11 +202,12 @@ FCurve *id_data_find_fcurve(ID *id, void *data, StructRNA *type, const char *pro
fcu= list_find_fcurve(&adt->action->curves, path, index);
/* if not animated, check if driven */
-#if 0
if ((fcu == NULL) && (adt->drivers.first)) {
- fcu= list_find_fcurve(&adt->drivers, path, but->rnaindex);
+ fcu= list_find_fcurve(&adt->drivers, path, index);
+ if(fcu && driven)
+ *driven = 1;
+ fcu = NULL;
}
-#endif
MEM_freeN(path);
}
@@ -786,13 +790,10 @@ void calchandles_fcurve (FCurve *fcu)
if (bezt->vec[2][0] < bezt->vec[1][0]) bezt->vec[2][0]= bezt->vec[1][0];
/* calculate auto-handles */
- if (fcu->flag & FCURVE_AUTO_HANDLES)
- calchandleNurb(bezt, prev, next, 2); /* 2==special autohandle && keep extrema horizontal */
- else
- calchandleNurb(bezt, prev, next, 1); /* 1==special autohandle */
+ calchandleNurb(bezt, prev, next, 1); /* 1==special autohandle */
/* for automatic ease in and out */
- if ((bezt->h1==HD_AUTO) && (bezt->h2==HD_AUTO)) {
+ if (ELEM(bezt->h1,HD_AUTO,HD_AUTO_ANIM) && ELEM(bezt->h2,HD_AUTO,HD_AUTO_ANIM)) {
/* only do this on first or last beztriple */
if ((a == 0) || (a == fcu->totvert-1)) {
/* set both handles to have same horizontal value as keyframe */
@@ -840,9 +841,9 @@ void testhandles_fcurve (FCurve *fcu)
/* one or two handles selected only */
if (ELEM(flag, 0, 7)==0) {
/* auto handles become aligned */
- if (bezt->h1==HD_AUTO)
+ if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM))
bezt->h1= HD_ALIGN;
- if (bezt->h2==HD_AUTO)
+ if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM))
bezt->h2= HD_ALIGN;
/* vector handles become 'free' when only one half selected */
@@ -1151,25 +1152,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 +1223,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 +1236,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 +1307,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..95c0aa60991 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -606,7 +604,7 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float UNUSED(cvalue),
/* calculate the 'number' of the cycle */
cycle= ((float)side * (evaltime - ofs) / cycdx);
-
+
/* calculate the time inside the cycle */
cyct= fmod(evaltime - ofs, cycdx);
@@ -631,11 +629,11 @@ static float fcm_cycles_time (FCurve *fcu, FModifier *fcm, float UNUSED(cvalue),
cycyofs = (float)ceil((evaltime - ofs) / cycdx);
cycyofs *= cycdy;
}
-
+
/* special case for cycle start/end */
if(cyct == 0.0f) {
evaltime = (side == 1 ? lastkey[0] : prevkey[0]);
-
+
if((mode == FCM_EXTRAPOLATE_MIRROR) && ((int)cycle % 2))
evaltime = (side == 1 ? prevkey[0] : lastkey[0]);
}
@@ -1013,6 +1011,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 +1199,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 +1270,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 +1310,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/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index db0c9d2735f..c2e94cc97db 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
diff --git a/source/blender/blenkernel/intern/idcode.c b/source/blender/blenkernel/intern/idcode.c
index 8c8a693e6e7..e84a2a04ded 100644
--- a/source/blender/blenkernel/intern/idcode.c
+++ b/source/blender/blenkernel/intern/idcode.c
@@ -73,7 +73,8 @@ static IDType idtypes[]= {
{ ID_SCE, "Scene", "scenes", IDTYPE_FLAGS_ISLINKABLE},
{ ID_SCR, "Screen", "screens", 0},
{ ID_SEQ, "Sequence", "sequences", 0}, /* not actually ID data */
- { ID_SO, "Sound", "sounds", IDTYPE_FLAGS_ISLINKABLE},
+ { ID_SPK, "Speaker", "speakers", IDTYPE_FLAGS_ISLINKABLE},
+ { ID_SO, "Sound", "sounds", IDTYPE_FLAGS_ISLINKABLE},
{ ID_TE, "Texture", "textures", IDTYPE_FLAGS_ISLINKABLE},
{ ID_TXT, "Text", "texts", IDTYPE_FLAGS_ISLINKABLE},
{ ID_VF, "VFont", "fonts", IDTYPE_FLAGS_ISLINKABLE},
diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c
index 104ce2b3b32..0d3f3cc5ae4 100644
--- a/source/blender/blenkernel/intern/ipo.c
+++ b/source/blender/blenkernel/intern/ipo.c
@@ -1,7 +1,4 @@
-/* ipo.c
- *
- * $Id$
- *
+/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -1157,7 +1154,6 @@ static void icu_to_fcurves (ID *id, ListBase *groups, ListBase *list, IpoCurve *
if (icu->flag & IPO_ACTIVE) fcu->flag |= FCURVE_ACTIVE;
if (icu->flag & IPO_MUTE) fcu->flag |= FCURVE_MUTED;
if (icu->flag & IPO_PROTECT) fcu->flag |= FCURVE_PROTECTED;
- if (icu->flag & IPO_AUTO_HORIZ) fcu->flag |= FCURVE_AUTO_HANDLES;
/* set extrapolation */
switch (icu->extrap) {
@@ -1242,6 +1238,12 @@ static void icu_to_fcurves (ID *id, ListBase *groups, ListBase *list, IpoCurve *
/* 'hide' flag is now used for keytype - only 'keyframes' existed before */
dst->hide= BEZT_KEYTYPE_KEYFRAME;
+ /* auto-handles - per curve to per handle */
+ if (icu->flag & IPO_AUTO_HORIZ) {
+ if (dst->h1 == HD_AUTO) dst->h1 = HD_AUTO_ANIM;
+ if (dst->h2 == HD_AUTO) dst->h2 = HD_AUTO_ANIM;
+ }
+
/* correct values, by checking if the flag of interest is set */
if ( ((int)(dst->vec[1][1])) & (abp->bit) )
dst->vec[0][1]= dst->vec[1][1]= dst->vec[2][1] = 1.0f;
@@ -1292,6 +1294,12 @@ static void icu_to_fcurves (ID *id, ListBase *groups, ListBase *list, IpoCurve *
/* 'hide' flag is now used for keytype - only 'keyframes' existed before */
dst->hide= BEZT_KEYTYPE_KEYFRAME;
+
+ /* auto-handles - per curve to per handle */
+ if (icu->flag & IPO_AUTO_HORIZ) {
+ if (dst->h1 == HD_AUTO) dst->h1 = HD_AUTO_ANIM;
+ if (dst->h2 == HD_AUTO) dst->h2 = HD_AUTO_ANIM;
+ }
/* correct values for euler rotation curves
* - they were degrees/10
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 0964c66fecd..2aef5b39c71 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -1400,7 +1400,7 @@ float *do_ob_key(Scene *scene, Object *ob)
/* do shapekey local drivers */
float ctime= (float)scene->r.cfra; // XXX this needs to be checked
- BKE_animsys_evaluate_animdata(&key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
+ BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
if(ob->type==OB_MESH) do_mesh_key(scene, ob, key, out, tot);
else if(ob->type==OB_LATTICE) do_latt_key(scene, ob, key, out, tot);
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 4d158a6c26c..677a2922666 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -65,6 +65,7 @@
#include "DNA_node_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
+#include "DNA_speaker_types.h"
#include "DNA_sound_types.h"
#include "DNA_text_types.h"
#include "DNA_vfont_types.h"
@@ -108,6 +109,9 @@
#include "BKE_particle.h"
#include "BKE_gpencil.h"
#include "BKE_fcurve.h"
+#include "BKE_speaker.h"
+
+#include "RNA_access.h"
#ifdef WITH_PYTHON
#include "BPY_extern.h"
@@ -205,6 +209,9 @@ int id_make_local(ID *id, int test)
case ID_CA:
if(!test) make_local_camera((Camera*)id);
return 1;
+ case ID_SPK:
+ if(!test) make_local_speaker((Speaker*)id);
+ return 1;
case ID_IP:
return 0; /* deprecated */
case ID_KE:
@@ -287,6 +294,9 @@ int id_copy(ID *id, ID **newid, int test)
case ID_LA:
if(!test) *newid= (ID*)copy_lamp((Lamp*)id);
return 1;
+ case ID_SPK:
+ if(!test) *newid= (ID*)copy_speaker((Speaker*)id);
+ return 1;
case ID_CA:
if(!test) *newid= (ID*)copy_camera((Camera*)id);
return 1;
@@ -368,6 +378,34 @@ int id_unlink(ID *id, int test)
return 0;
}
+int id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
+{
+ ID *newid = NULL;
+ PointerRNA idptr;
+
+ if (id) {
+ /* if property isn't editable, we're going to have an extra block hanging around until we save */
+ if (RNA_property_editable(ptr, prop)) {
+ if (id_copy(id, &newid, 0) && newid) {
+ /* copy animation actions too */
+ BKE_copy_animdata_id_action(id);
+ /* us is 1 by convention, but RNA_property_pointer_set
+ will also incremement it, so set it to zero */
+ newid->us= 0;
+
+ /* assign copy */
+ RNA_id_pointer_create(newid, &idptr);
+ RNA_property_pointer_set(ptr, prop, idptr);
+ RNA_property_update(C, ptr, prop);
+
+ return 1;
+ }
+ }
+ }
+
+ return 0;
+}
+
ListBase *which_libbase(Main *mainlib, short type)
{
switch( type ) {
@@ -409,6 +447,8 @@ ListBase *which_libbase(Main *mainlib, short type)
return &(mainlib->text);
case ID_SCRIPT:
return &(mainlib->script);
+ case ID_SPK:
+ return &(mainlib->speaker);
case ID_SO:
return &(mainlib->sound);
case ID_GR:
@@ -493,13 +533,14 @@ int set_listbasepointers(Main *main, ListBase **lb)
lb[a++]= &(main->latt);
lb[a++]= &(main->lamp);
lb[a++]= &(main->camera);
-
+
lb[a++]= &(main->text);
lb[a++]= &(main->sound);
lb[a++]= &(main->group);
lb[a++]= &(main->brush);
lb[a++]= &(main->script);
lb[a++]= &(main->particle);
+ lb[a++]= &(main->speaker);
lb[a++]= &(main->world);
lb[a++]= &(main->screen);
@@ -585,6 +626,9 @@ static ID *alloc_libblock_notest(short type)
case ID_SCRIPT:
//XXX id= MEM_callocN(sizeof(Script), "script");
break;
+ case ID_SPK:
+ id= MEM_callocN(sizeof(Speaker), "speaker");
+ break;
case ID_SO:
id= MEM_callocN(sizeof(bSound), "sound");
break;
@@ -788,6 +832,9 @@ void free_libblock(ListBase *lb, void *idv)
case ID_SCRIPT:
//XXX free_script((Script *)id);
break;
+ case ID_SPK:
+ free_speaker((Speaker *)id);
+ break;
case ID_SO:
sound_free((bSound*)id);
break;
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index 9c916d517c5..70398594872 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -166,7 +166,7 @@ int BKE_mesh_validate_arrays(Mesh *me, MVert *UNUSED(mverts), unsigned int totve
}
if(BLI_edgehash_haskey(edge_hash, med->v1, med->v2)) {
- PRINT(" edge %u: is a duplicate of, %u\n", i, GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, med->v1, med->v2)));
+ PRINT(" edge %u: is a duplicate of, %d\n", i, GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, med->v1, med->v2)));
remove= do_fixes;
}
diff --git a/source/blender/blenkernel/intern/nla.c b/source/blender/blenkernel/intern/nla.c
index bd238e72d0c..6ce80342dd6 100644
--- a/source/blender/blenkernel/intern/nla.c
+++ b/source/blender/blenkernel/intern/nla.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -46,6 +44,8 @@
#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_speaker_types.h"
#include "BKE_action.h"
#include "BKE_fcurve.h"
@@ -53,6 +53,9 @@
#include "BKE_global.h"
#include "BKE_library.h"
+#ifdef WITH_AUDASPACE
+# include "AUD_C-API.h"
+#endif
#include "RNA_access.h"
#include "nla_private.h"
@@ -337,6 +340,44 @@ NlaStrip *add_nlastrip_to_stack (AnimData *adt, bAction *act)
return strip;
}
+/* Add a NLA Strip referencing the given speaker's sound */
+NlaStrip *add_nla_soundstrip (Scene *scene, Speaker *speaker)
+{
+ NlaStrip *strip = MEM_callocN(sizeof(NlaStrip), "NlaSoundStrip");
+
+ /* if speaker has a sound, set the strip length to the length of the sound,
+ * otherwise default to length of 10 frames
+ */
+#ifdef WITH_AUDASPACE
+ if (speaker->sound)
+ {
+ AUD_SoundInfo info = AUD_getInfo(speaker->sound->playback_handle);
+
+ strip->end = ceil(info.length * FPS);
+ }
+ else
+#endif
+ {
+ strip->end = 10.0f;
+ /* quiet compiler warnings */
+ (void)scene;
+ (void)speaker;
+ }
+
+ /* general settings */
+ strip->type = NLASTRIP_TYPE_SOUND;
+
+ strip->flag = NLASTRIP_FLAG_SELECT;
+ strip->extendmode = NLASTRIP_EXTEND_NOTHING; /* nothing to extend... */
+
+ /* strip should be referenced as-is */
+ strip->scale= 1.0f;
+ strip->repeat = 1.0f;
+
+ /* return this strip */
+ return strip;
+}
+
/* *************************************************** */
/* NLA Evaluation <-> Editing Stuff */
@@ -813,34 +854,35 @@ void BKE_nlameta_flush_transforms (NlaStrip *mstrip)
/* for each child-strip, calculate new start/end points based on this new info */
for (strip= mstrip->strips.first; strip; strip= strip->next) {
if (scaleChanged) {
- PointerRNA ptr;
- float p1, p2, nStart, nEnd;
+ float p1, p2;
/* compute positions of endpoints relative to old extents of strip */
p1= (strip->start - oStart) / oLen;
p2= (strip->end - oStart) / oLen;
- /* compute the new strip endpoints using the proportions */
- nStart= (p1 * nLen) + mstrip->start;
- nEnd= (p2 * nLen) + mstrip->start;
-
- /* firstly, apply the new positions manually, then apply using RNA
- * - first time is to make sure no truncation errors from one endpoint not being
- * set yet occur
- * - second time is to make sure scale is computed properly...
- */
- strip->start= nStart;
- strip->end= nEnd;
-
- RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &ptr);
- RNA_float_set(&ptr, "frame_start", nStart);
- RNA_float_set(&ptr, "frame_end", nEnd);
+ /* apply new strip endpoints using the proportions, then wait for second pass to flush scale properly */
+ strip->start= (p1 * nLen) + mstrip->start;
+ strip->end= (p2 * nLen) + mstrip->start;
}
else {
/* just apply the changes in offset to both ends of the strip */
strip->start += offset;
strip->end += offset;
}
+ }
+
+ /* apply a second pass over child strips, to finish up unfinished business */
+ for (strip= mstrip->strips.first; strip; strip= strip->next) {
+ /* only if scale changed, need to perform RNA updates */
+ if (scaleChanged) {
+ PointerRNA ptr;
+
+ /* use RNA updates to compute scale properly */
+ RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &ptr);
+
+ RNA_float_set(&ptr, "frame_start", strip->start);
+ RNA_float_set(&ptr, "frame_end", strip->end);
+ }
/* finally, make sure the strip's children (if it is a meta-itself), get updated */
BKE_nlameta_flush_transforms(strip);
@@ -1185,7 +1227,7 @@ void BKE_nlastrip_validate_fcurves (NlaStrip *strip)
BLI_addtail(&strip->fcurves, fcu);
/* set default flags */
- fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
+ fcu->flag = (FCURVE_VISIBLE|FCURVE_SELECTED);
/* store path - make copy, and store that */
fcu->rna_path= BLI_strdupn("influence", 9);
@@ -1206,7 +1248,7 @@ void BKE_nlastrip_validate_fcurves (NlaStrip *strip)
BLI_addtail(&strip->fcurves, fcu);
/* set default flags */
- fcu->flag = (FCURVE_VISIBLE|FCURVE_AUTO_HANDLES|FCURVE_SELECTED);
+ fcu->flag = (FCURVE_VISIBLE|FCURVE_SELECTED);
/* store path - make copy, and store that */
fcu->rna_path= BLI_strdupn("strip_time", 10);
@@ -1242,7 +1284,7 @@ void BKE_nlastrip_validate_name (AnimData *adt, NlaStrip *strip)
if (strip->name[0]==0) {
switch (strip->type) {
case NLASTRIP_TYPE_CLIP: /* act-clip */
- sprintf(strip->name, "Act: %s", (strip->act)?(strip->act->id.name+2):("<None>"));
+ sprintf(strip->name, "%s", (strip->act)?(strip->act->id.name+2):("<No Action>"));
break;
case NLASTRIP_TYPE_TRANSITION: /* transition */
sprintf(strip->name, "Transition");
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 5bdda8d5867..0dc83084c90 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -54,6 +54,7 @@
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "DNA_sequence_types.h"
+#include "DNA_sound_types.h"
#include "DNA_space_types.h"
#include "DNA_view3d_types.h"
#include "DNA_world_types.h"
@@ -96,6 +97,7 @@
#include "BKE_sca.h"
#include "BKE_scene.h"
#include "BKE_sequencer.h"
+#include "BKE_speaker.h"
#include "BKE_softbody.h"
#include "BKE_material.h"
@@ -989,6 +991,7 @@ static void *add_obdata_from_type(int type)
case OB_LAMP: return add_lamp("Lamp");
case OB_LATTICE: return add_lattice("Lattice");
case OB_ARMATURE: return add_armature("Armature");
+ case OB_SPEAKER: return add_speaker("Speaker");
case OB_EMPTY: return NULL;
default:
printf("add_obdata_from_type: Internal error, bad type: %d\n", type);
@@ -1008,6 +1011,7 @@ static const char *get_obdata_defname(int type)
case OB_LAMP: return "Lamp";
case OB_LATTICE: return "Lattice";
case OB_ARMATURE: return "Armature";
+ case OB_SPEAKER: return "Speaker";
case OB_EMPTY: return "Empty";
default:
printf("get_obdata_defname: Internal error, bad type: %d\n", type);
@@ -1051,7 +1055,7 @@ Object *add_only_object(int type, const char *name)
ob->empty_drawtype= OB_PLAINAXES;
ob->empty_drawsize= 1.0;
- if(type==OB_CAMERA || type==OB_LAMP) {
+ if(type==OB_CAMERA || type==OB_LAMP || type==OB_SPEAKER) {
ob->trackflag= OB_NEGZ;
ob->upflag= OB_POSY;
}
@@ -2084,7 +2088,7 @@ void where_is_object_time(Scene *scene, Object *ob, float ctime)
if(ob==NULL) return;
/* execute drivers only, as animation has already been done */
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS);
if(ob->parent) {
Object *par= ob->parent;
@@ -2623,7 +2627,7 @@ void object_handle_update(Scene *scene, Object *ob)
if(adt) {
/* evaluate drivers */
// XXX: for mesh types, should we push this to derivedmesh instead?
- BKE_animsys_evaluate_animdata(data_id, adt, ctime, ADT_RECALC_DRIVERS);
+ BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS);
}
/* includes all keys and modifiers */
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 1423f520b95..e1ea6e419d3 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -69,6 +69,7 @@
#include "BLI_listbase.h"
#include "BLI_threads.h"
#include "BLI_storage.h" /* For _LARGEFILE64_SOURCE; zlib needs this on some systems */
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_main.h"
@@ -104,12 +105,6 @@
#include <zlib.h>
#include <string.h>
-#ifdef WIN32
-#ifndef snprintf
-#define snprintf _snprintf
-#endif
-#endif
-
#endif // DISABLE_ELBEEM
/************************************************/
@@ -1801,7 +1796,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
if(part->type!=PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) {
/* we have to force RECALC_ANIM here since where_is_objec_time only does drivers */
while(ob) {
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, pa->time, ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(sim->scene, &ob->id, ob->adt, pa->time, ADT_RECALC_ANIM);
ob = ob->parent;
}
ob = sim->ob;
@@ -3876,7 +3871,7 @@ static void particles_fluid_step(ParticleSimulationData *sim, int UNUSED(cfra))
gzf = gzopen(filename, "rb");
if (!gzf) {
- snprintf(debugStrBuffer,256,"readFsPartData::error - Unable to open file for reading '%s' \n", filename);
+ BLI_snprintf(debugStrBuffer, sizeof(debugStrBuffer),"readFsPartData::error - Unable to open file for reading '%s' \n", filename);
// XXX bad level call elbeemDebugOut(debugStrBuffer);
return;
}
@@ -3937,7 +3932,7 @@ static void particles_fluid_step(ParticleSimulationData *sim, int UNUSED(cfra))
gzclose( gzf );
totpart = psys->totpart = activeParts;
- snprintf(debugStrBuffer,256,"readFsPartData::done - particles:%d, active:%d, file:%d, mask:%d \n", psys->totpart,activeParts,fileParts,readMask);
+ BLI_snprintf(debugStrBuffer,sizeof(debugStrBuffer),"readFsPartData::done - particles:%d, active:%d, file:%d, mask:%d \n", psys->totpart,activeParts,fileParts,readMask);
// bad level call
// XXX elbeemDebugOut(debugStrBuffer);
@@ -4253,7 +4248,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
return;
/* execute drivers only, as animation has already been done */
- BKE_animsys_evaluate_animdata(&part->id, part->adt, cfra, ADT_RECALC_DRIVERS);
+ BKE_animsys_evaluate_animdata(scene, &part->id, part->adt, cfra, ADT_RECALC_DRIVERS);
if(psys->recalc & PSYS_RECALC_TYPE)
psys_changed_type(&sim);
@@ -4291,7 +4286,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
for(i=0; i<=part->hair_step; i++){
hcfra=100.0f*(float)i/(float)psys->part->hair_step;
if((part->flag & PART_HAIR_REGROW)==0)
- BKE_animsys_evaluate_animdata(&part->id, part->adt, hcfra, ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(scene, &part->id, part->adt, hcfra, ADT_RECALC_ANIM);
system_step(&sim, hcfra);
psys->cfra = hcfra;
psys->recalc = 0;
@@ -4369,7 +4364,7 @@ void particle_system_update(Scene *scene, Object *ob, ParticleSystem *psys)
if(psys->cfra < cfra) {
/* make sure emitter is left at correct time (particle emission can change this) */
while(ob) {
- BKE_animsys_evaluate_animdata(&ob->id, ob->adt, cfra, ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(scene, &ob->id, ob->adt, cfra, ADT_RECALC_ANIM);
ob = ob->parent;
}
ob = sim.ob;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index d761923859e..86606dd66bc 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -1046,14 +1046,14 @@ static int ptcache_path(PTCacheID *pid, char *filename)
if (i > 6)
file[i-6] = '\0';
- snprintf(filename, MAX_PTCACHE_PATH, "//"PTCACHE_PATH"%s", file); /* add blend file name to pointcache dir */
+ BLI_snprintf(filename, MAX_PTCACHE_PATH, "//"PTCACHE_PATH"%s", file); /* add blend file name to pointcache dir */
BLI_path_abs(filename, blendfilename);
return BLI_add_slash(filename); /* new strlen() */
}
/* use the temp path. this is weak but better then not using point cache at all */
/* btempdir is assumed to exist and ALWAYS has a trailing slash */
- snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH"%d", btempdir, abs(getpid()));
+ BLI_snprintf(filename, MAX_PTCACHE_PATH, "%s"PTCACHE_PATH"%d", btempdir, abs(getpid()));
return BLI_add_slash(filename); /* new strlen() */
}
@@ -1077,7 +1077,7 @@ static int ptcache_filename(PTCacheID *pid, char *filename, int cfra, short do_p
idname = (pid->ob->id.name+2);
/* convert chars to hex so they are always a valid filename */
while('\0' != *idname) {
- snprintf(newname, MAX_PTCACHE_FILE, "%02X", (char)(*idname++));
+ BLI_snprintf(newname, MAX_PTCACHE_FILE, "%02X", (char)(*idname++));
newname+=2;
len += 2;
}
@@ -1096,12 +1096,12 @@ static int ptcache_filename(PTCacheID *pid, char *filename, int cfra, short do_p
if(pid->cache->flag & PTCACHE_EXTERNAL) {
if(pid->cache->index >= 0)
- snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02u"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
+ BLI_snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02u"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
else
- snprintf(newname, MAX_PTCACHE_FILE, "_%06d"PTCACHE_EXT, cfra); /* always 6 chars */
+ BLI_snprintf(newname, MAX_PTCACHE_FILE, "_%06d"PTCACHE_EXT, cfra); /* always 6 chars */
}
else {
- snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02u"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
+ BLI_snprintf(newname, MAX_PTCACHE_FILE, "_%06d_%02u"PTCACHE_EXT, cfra, pid->stack_index); /* always 6 chars */
}
len += 16;
}
@@ -2141,7 +2141,7 @@ void BKE_ptcache_id_clear(PTCacheID *pid, int mode, unsigned int cfra)
if (dir==NULL)
return;
- snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index);
+ BLI_snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index);
while ((de = readdir(dir)) != NULL) {
if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
@@ -2343,7 +2343,7 @@ void BKE_ptcache_id_time(PTCacheID *pid, Scene *scene, float cfra, int *startfra
if (dir==NULL)
return;
- snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index);
+ BLI_snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index);
while ((de = readdir(dir)) != NULL) {
if (strstr(de->d_name, ext)) { /* do we have the right extension?*/
@@ -3057,7 +3057,7 @@ void BKE_ptcache_disk_cache_rename(PTCacheID *pid, char *from, char *to)
return;
}
- snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index);
+ BLI_snprintf(ext, sizeof(ext), "_%02u"PTCACHE_EXT, pid->stack_index);
/* put new name into cache */
strcpy(pid->cache->name, to);
@@ -3113,7 +3113,7 @@ void BKE_ptcache_load_external(PTCacheID *pid)
return;
if(cache->index >= 0)
- snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, cache->index);
+ BLI_snprintf(ext, sizeof(ext), "_%02d"PTCACHE_EXT, cache->index);
else
strcpy(ext, PTCACHE_EXT);
diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c
index f84d98a31b4..4926edaeec2 100644
--- a/source/blender/blenkernel/intern/report.c
+++ b/source/blender/blenkernel/intern/report.c
@@ -44,12 +44,6 @@
#include <stdio.h>
#include <string.h>
-#ifdef _WIN32
-#ifndef vsnprintf
-#define vsnprintf _vsnprintf
-#endif
-#endif
-
static const char *report_type_str(int type)
{
switch(type) {
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 51eaba3c05b..d6003a44a7d 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -469,12 +469,14 @@ Scene *add_scene(const char *name)
sce->r.ffcodecdata.audio_mixrate = 44100;
sce->r.ffcodecdata.audio_volume = 1.0f;
sce->r.ffcodecdata.audio_bitrate = 192;
+ sce->r.ffcodecdata.audio_channels = 2;
BLI_strncpy(sce->r.engine, "BLENDER_RENDER", sizeof(sce->r.engine));
- sce->audio.distance_model = 2.0;
- sce->audio.doppler_factor = 1.0;
- sce->audio.speed_of_sound = 343.3;
+ sce->audio.distance_model = 2.0f;
+ sce->audio.doppler_factor = 1.0f;
+ sce->audio.speed_of_sound = 343.3f;
+ sce->audio.volume = 1.0f;
BLI_strncpy(sce->r.pic, U.renderdir, sizeof(sce->r.pic));
@@ -914,7 +916,7 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
/* scene itself */
if (scene->adt && scene->adt->drivers.first) {
- BKE_animsys_evaluate_animdata(&scene->id, scene->adt, ctime, ADT_RECALC_DRIVERS);
+ BKE_animsys_evaluate_animdata(scene, &scene->id, scene->adt, ctime, ADT_RECALC_DRIVERS);
}
/* world */
@@ -924,7 +926,7 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
AnimData *adt= BKE_animdata_from_id(wid);
if (adt && adt->drivers.first)
- BKE_animsys_evaluate_animdata(wid, adt, ctime, ADT_RECALC_DRIVERS);
+ BKE_animsys_evaluate_animdata(scene, wid, adt, ctime, ADT_RECALC_DRIVERS);
}
/* nodes */
@@ -933,7 +935,7 @@ static void scene_update_drivers(Main *UNUSED(bmain), Scene *scene)
AnimData *adt= BKE_animdata_from_id(nid);
if (adt && adt->drivers.first)
- BKE_animsys_evaluate_animdata(nid, adt, ctime, ADT_RECALC_DRIVERS);
+ BKE_animsys_evaluate_animdata(scene, nid, adt, ctime, ADT_RECALC_DRIVERS);
}
}
@@ -964,6 +966,9 @@ static void scene_update_tagged_recursive(Main *bmain, Scene *scene, Scene *scen
/* scene drivers... */
scene_update_drivers(bmain, scene);
+
+ /* update sound system animation */
+ sound_update_scene(scene);
}
/* this is called in main loop, doing tagged updates before redraw */
@@ -984,7 +989,7 @@ void scene_update_tagged(Main *bmain, Scene *scene)
float ctime = BKE_curframe(scene);
if (adt && (adt->recalc & ADT_RECALC_ANIM))
- BKE_animsys_evaluate_animdata(&scene->id, adt, ctime, 0);
+ BKE_animsys_evaluate_animdata(scene, &scene->id, adt, ctime, 0);
}
if (scene->physics_settings.quick_cache_step)
@@ -999,6 +1004,8 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
{
float ctime = BKE_curframe(sce);
Scene *sce_iter;
+
+ sound_set_cfra(sce->r.cfra);
/* clear animation overrides */
// XXX TODO...
@@ -1019,7 +1026,7 @@ void scene_update_for_newframe(Main *bmain, Scene *sce, unsigned int lay)
* can be overridden by settings from Scene, which owns the Texture through a hierarchy
* such as Scene->World->MTex/Texture) can still get correctly overridden.
*/
- BKE_animsys_evaluate_all_animation(bmain, ctime);
+ BKE_animsys_evaluate_all_animation(bmain, sce, ctime);
/*...done with recusrive funcs */
/* object_handle_update() on all objects, groups and sets */
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 8b50ad2b042..43747fde729 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -3031,7 +3031,7 @@ void sequence_effect_speed_rebuild_map(Scene *scene, Sequence * seq, int force)
/* XXX - new in 2.5x. should we use the animation system this way?
* The fcurve is needed because many frames need evaluating at once - campbell */
- fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0);
+ fcu= id_data_find_fcurve(&scene->id, seq, &RNA_Sequence, "speed_factor", 0, NULL);
if (!v->frameMap || v->length != seq->len) {
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 60479da64a9..9ef30bdd49b 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -78,11 +78,6 @@
# include "AUD_C-API.h"
#endif
-#ifdef WIN32
-#define snprintf _snprintf
-#endif
-
-
static ImBuf* seq_render_strip_stack(
SeqRenderData context, ListBase *seqbasep, float cfra, int chanshown);
@@ -545,7 +540,7 @@ void calc_sequence_disp(Scene *scene, Sequence *seq)
seq->handsize= (float)((seq->enddisp-seq->startdisp)/25);
}
- seq_update_sound(scene, seq);
+ seq_update_sound_bounds(scene, seq);
}
static void seq_update_sound_bounds_recursive(Scene *scene, Sequence *metaseq)
@@ -1193,7 +1188,7 @@ static void seq_open_anim_file(Sequence * seq)
static int seq_proxy_get_fname(SeqRenderData context, Sequence * seq, int cfra, char * name)
{
int frameno;
- char dir[FILE_MAXDIR];
+ char dir[PROXY_MAXFILE];
int render_size = context.preview_render_size;
if (!seq->strip->proxy) {
@@ -1211,7 +1206,7 @@ static int seq_proxy_get_fname(SeqRenderData context, Sequence * seq, int cfra,
if (seq->flag & (SEQ_USE_PROXY_CUSTOM_DIR|SEQ_USE_PROXY_CUSTOM_FILE)) {
strcpy(dir, seq->strip->proxy->dir);
} else if (seq->type == SEQ_IMAGE) {
- snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
+ BLI_snprintf(dir, PROXY_MAXFILE, "%s/BL_proxy", seq->strip->dir);
} else {
return FALSE;
}
@@ -1232,14 +1227,14 @@ static int seq_proxy_get_fname(SeqRenderData context, Sequence * seq, int cfra,
/* generate a separate proxy directory for each preview size */
if (seq->type == SEQ_IMAGE) {
- snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir,
+ BLI_snprintf(name, PROXY_MAXFILE, "%s/images/%d/%s_proxy", dir,
context.preview_render_size,
give_stripelem(seq, cfra)->name);
frameno = 1;
} else {
frameno = (int) give_stripelem_index(seq, cfra)
+ seq->anim_startofs;
- snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
+ BLI_snprintf(name, PROXY_MAXFILE, "%s/proxy_misc/%d/####", dir,
context.preview_render_size);
}
@@ -1834,7 +1829,7 @@ static ImBuf* seq_render_effect_strip_impl(
facf= fac;
}
else {
- fcu = id_data_find_fcurve(&context.scene->id, seq, &RNA_Sequence, "effect_fader", 0);
+ fcu = id_data_find_fcurve(&context.scene->id, seq, &RNA_Sequence, "effect_fader", 0, NULL);
if (fcu) {
fac = facf = evaluate_fcurve(fcu, cfra);
if( context.scene->r.mode & R_FIELDS ) {
@@ -2185,7 +2180,7 @@ static ImBuf * seq_render_strip(SeqRenderData context, Sequence * seq, float cfr
ibuf = seq_render_scene_strip_impl(context, seq, nr);
/* Scene strips update all animation, so we need to restore original state.*/
- BKE_animsys_evaluate_all_animation(context.bmain, cfra);
+ BKE_animsys_evaluate_all_animation(context.bmain, context.scene, cfra);
copy_to_ibuf_still(context, seq, nr, ibuf);
break;
@@ -2262,7 +2257,7 @@ static ImBuf* seq_render_strip_stack(
if(scene->r.cfra != cfra) {
// XXX for prefetch and overlay offset!..., very bad!!!
AnimData *adt= BKE_animdata_from_id(&scene->id);
- BKE_animsys_evaluate_animdata(&scene->id, adt, cfra, ADT_RECALC_ANIM);
+ BKE_animsys_evaluate_animdata(scene, &scene->id, adt, cfra, ADT_RECALC_ANIM);
}
#endif
@@ -3207,16 +3202,33 @@ int shuffle_seq_time(ListBase * seqbasep, Scene *evil_scene)
return offset? 0:1;
}
-void seq_update_sound(Scene* scene, Sequence *seq)
+void seq_update_sound_bounds_all(Scene *scene)
{
- if(seq->scene_sound)
- {
+ Editing *ed = scene->ed;
+
+ if(ed) {
+ Sequence *seq;
+
+ for(seq = ed->seqbase.first; seq; seq = seq->next) {
+ if(seq->type == SEQ_META) {
+ seq_update_sound_bounds_recursive(scene, seq);
+ }
+ else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
+ seq_update_sound_bounds(scene, seq);
+ }
+ }
+ }
+}
+
+void seq_update_sound_bounds(Scene* scene, Sequence *seq)
+{
+ if(seq->scene_sound) {
sound_move_scene_sound(scene, seq->scene_sound, seq->startdisp, seq->enddisp, seq->startofs + seq->anim_startofs);
/* mute is set in seq_update_muting_recursive */
}
}
-static void seq_update_muting_recursive(Scene *scene, ListBase *seqbasep, Sequence *metaseq, int mute)
+static void seq_update_muting_recursive(ListBase *seqbasep, Sequence *metaseq, int mute)
{
Sequence *seq;
int seqmute;
@@ -3232,26 +3244,49 @@ static void seq_update_muting_recursive(Scene *scene, ListBase *seqbasep, Sequen
if(seq == metaseq)
seqmute= 0;
- seq_update_muting_recursive(scene, &seq->seqbase, metaseq, seqmute);
+ seq_update_muting_recursive(&seq->seqbase, metaseq, seqmute);
}
else if(ELEM(seq->type, SEQ_SOUND, SEQ_SCENE)) {
if(seq->scene_sound) {
- sound_mute_scene_sound(scene, seq->scene_sound, seqmute);
+ sound_mute_scene_sound(seq->scene_sound, seqmute);
}
}
}
}
-void seq_update_muting(Scene *scene, Editing *ed)
+void seq_update_muting(Editing *ed)
{
if(ed) {
/* mute all sounds up to current metastack list */
MetaStack *ms= ed->metastack.last;
if(ms)
- seq_update_muting_recursive(scene, &ed->seqbase, ms->parseq, 1);
+ seq_update_muting_recursive(&ed->seqbase, ms->parseq, 1);
else
- seq_update_muting_recursive(scene, &ed->seqbase, NULL, 0);
+ seq_update_muting_recursive(&ed->seqbase, NULL, 0);
+ }
+}
+
+static void seq_update_sound_recursive(Scene *scene, ListBase *seqbasep, bSound *sound)
+{
+ Sequence *seq;
+
+ for(seq=seqbasep->first; seq; seq=seq->next) {
+ if(seq->type == SEQ_META) {
+ seq_update_sound_recursive(scene, &seq->seqbase, sound);
+ }
+ else if(seq->type == SEQ_SOUND) {
+ if(seq->scene_sound && sound == seq->sound) {
+ sound_update_scene_sound(seq->scene_sound, sound);
+ }
+ }
+ }
+}
+
+void seq_update_sound(struct Scene *scene, struct bSound *sound)
+{
+ if(scene->ed) {
+ seq_update_sound_recursive(scene, &scene->ed->seqbase, sound);
}
}
@@ -3508,7 +3543,7 @@ void seq_load_apply(Scene *scene, Sequence *seq, SeqLoadInfo *seq_load)
if(seq_load->flag & SEQ_LOAD_SOUND_CACHE) {
if(seq->sound)
- sound_cache(seq->sound, 0);
+ sound_cache(seq->sound);
}
seq_load->tot_success++;
@@ -3535,6 +3570,7 @@ Sequence *alloc_sequence(ListBase *lb, int cfra, int machine)
seq->mul= 1.0;
seq->blend_opacity = 100.0;
seq->volume = 1.0f;
+ seq->pitch = 1.0f;
seq->scene_sound = NULL;
return seq;
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 1c61646a3d8..74f4830b86c 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -13,13 +13,16 @@
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_math.h"
#include "DNA_anim_types.h"
+#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "DNA_sequence_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_screen_types.h"
#include "DNA_sound_types.h"
+#include "DNA_speaker_types.h"
#ifdef WITH_AUDASPACE
# include "AUD_C-API.h"
@@ -32,9 +35,14 @@
#include "BKE_context.h"
#include "BKE_library.h"
#include "BKE_packedFile.h"
-#include "BKE_fcurve.h"
#include "BKE_animsys.h"
+#include "BKE_sequencer.h"
+#include "BKE_scene.h"
+#ifdef WITH_AUDASPACE
+// evil global ;-)
+static int sound_cfra;
+#endif
struct bSound* sound_new_file(struct Main *bmain, const char *filename)
{
@@ -85,10 +93,17 @@ void sound_free(struct bSound* sound)
sound->handle = NULL;
sound->playback_handle = NULL;
}
+
+ if(sound->cache)
+ {
+ AUD_unload(sound->cache);
+ sound->cache = NULL;
+ }
+
+ sound_free_waveform(sound);
#endif // WITH_AUDASPACE
}
-
#ifdef WITH_AUDASPACE
static int force_device = -1;
@@ -108,7 +123,8 @@ static void sound_sync_callback(void* data, int mode, float time)
sound_play_scene(scene);
else
sound_stop_scene(scene);
- AUD_seek(scene->sound_scene_handle, time);
+ if(scene->sound_scene_handle)
+ AUD_seek(scene->sound_scene_handle, time);
}
scene = scene->id.next;
}
@@ -167,7 +183,12 @@ void sound_init(struct Main *bmain)
if(!AUD_init(device, specs, buffersize))
AUD_init(AUD_NULL_DEVICE, specs, buffersize);
-
+
+ sound_init_main(bmain);
+}
+
+void sound_init_main(struct Main *bmain)
+{
#ifdef WITH_JACK
AUD_setSyncCallback(sound_sync_callback, bmain);
#else
@@ -243,17 +264,25 @@ void sound_delete(struct bContext *C, struct bSound* sound)
}
}
-void sound_cache(struct bSound* sound, int ignore)
+void sound_cache(struct bSound* sound)
{
- if(sound->cache && !ignore)
+ sound->flags |= SOUND_FLAGS_CACHING;
+ if(sound->cache)
AUD_unload(sound->cache);
sound->cache = AUD_bufferSound(sound->handle);
sound->playback_handle = sound->cache;
}
+void sound_cache_notifying(struct Main* main, struct bSound* sound)
+{
+ sound_cache(sound);
+ sound_update_sequencer(main, sound);
+}
+
void sound_delete_cache(struct bSound* sound)
{
+ sound->flags &= ~SOUND_FLAGS_CACHING;
if(sound->cache)
{
AUD_unload(sound->cache);
@@ -266,6 +295,12 @@ void sound_load(struct Main *bmain, struct bSound* sound)
{
if(sound)
{
+ if(sound->cache)
+ {
+ AUD_unload(sound->cache);
+ sound->cache = NULL;
+ }
+
if(sound->handle)
{
AUD_unload(sound->handle);
@@ -317,52 +352,52 @@ void sound_load(struct Main *bmain, struct bSound* sound)
break;
}
#endif
+ if(sound->flags & SOUND_FLAGS_MONO)
+ {
+ void* handle = AUD_monoSound(sound->handle);
+ AUD_unload(sound->handle);
+ sound->handle = handle;
+ }
+
+ if(sound->flags & SOUND_FLAGS_CACHING)
+ {
+ sound->cache = AUD_bufferSound(sound->handle);
+ }
+
if(sound->cache)
sound->playback_handle = sound->cache;
else
sound->playback_handle = sound->handle;
- }
-}
-static float sound_get_volume(Scene* scene, Sequence* sequence, float time)
-{
- AnimData *adt= BKE_animdata_from_id(&scene->id);
- FCurve *fcu = NULL;
- char buf[64];
-
- /* NOTE: this manually constructed path needs to be used here to avoid problems with RNA crashes */
- sprintf(buf, "sequence_editor.sequences_all[\"%s\"].volume", sequence->name+2);
- if (adt && adt->action && adt->action->curves.first)
- fcu= list_find_fcurve(&adt->action->curves, buf, 0);
-
- if(fcu)
- return evaluate_fcurve(fcu, time * (float)FPS);
- else
- return sequence->volume;
+ sound_update_sequencer(bmain, sound);
+ }
}
AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, float volume)
{
- AUD_Device* mixdown = AUD_openReadDevice(specs);
-
- AUD_setDeviceVolume(mixdown, volume);
-
- AUD_playDevice(mixdown, scene->sound_scene, start / FPS);
-
- return mixdown;
+ return AUD_openMixdownDevice(specs, scene->sound_scene, volume, start / FPS);
}
void sound_create_scene(struct Scene *scene)
{
- scene->sound_scene = AUD_createSequencer(scene->audio.flag & AUDIO_MUTE, scene, (AUD_volumeFunction)&sound_get_volume);
+ scene->sound_scene = AUD_createSequencer(FPS, scene->audio.flag & AUDIO_MUTE);
+ AUD_updateSequencerData(scene->sound_scene, scene->audio.speed_of_sound,
+ scene->audio.doppler_factor, scene->audio.distance_model);
+ scene->sound_scene_handle = NULL;
+ scene->sound_scrub_handle = NULL;
+ scene->speaker_handles = NULL;
}
void sound_destroy_scene(struct Scene *scene)
{
if(scene->sound_scene_handle)
AUD_stop(scene->sound_scene_handle);
+ if(scene->sound_scrub_handle)
+ AUD_stop(scene->sound_scrub_handle);
if(scene->sound_scene)
AUD_destroySequencer(scene->sound_scene);
+ if(scene->speaker_handles)
+ AUD_destroySet(scene->speaker_handles);
}
void sound_mute_scene(struct Scene *scene, int muted)
@@ -371,37 +406,97 @@ void sound_mute_scene(struct Scene *scene, int muted)
AUD_setSequencerMuted(scene->sound_scene, muted);
}
+void sound_update_fps(struct Scene *scene)
+{
+ if(scene->sound_scene)
+ AUD_setSequencerFPS(scene->sound_scene, FPS);
+}
+
+void sound_update_scene_listener(struct Scene *scene)
+{
+ AUD_updateSequencerData(scene->sound_scene, scene->audio.speed_of_sound,
+ scene->audio.doppler_factor, scene->audio.distance_model);
+}
+
void* sound_scene_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
{
if(scene != sequence->scene)
- return AUD_addSequencer(scene->sound_scene, &(sequence->scene->sound_scene), startframe / FPS, endframe / FPS, frameskip / FPS, sequence);
+ return AUD_addSequence(scene->sound_scene, sequence->scene->sound_scene, startframe / FPS, endframe / FPS, frameskip / FPS);
return NULL;
}
void* sound_add_scene_sound(struct Scene *scene, struct Sequence* sequence, int startframe, int endframe, int frameskip)
{
- return AUD_addSequencer(scene->sound_scene, &(sequence->sound->playback_handle), startframe / FPS, endframe / FPS, frameskip / FPS, sequence);
+ void* handle = AUD_addSequence(scene->sound_scene, sequence->sound->playback_handle, startframe / FPS, endframe / FPS, frameskip / FPS);
+ AUD_muteSequence(handle, (sequence->flag & SEQ_MUTE) != 0);
+ AUD_setSequenceAnimData(handle, AUD_AP_VOLUME, CFRA, &sequence->volume, 0);
+ AUD_setSequenceAnimData(handle, AUD_AP_PITCH, CFRA, &sequence->pitch, 0);
+ AUD_setSequenceAnimData(handle, AUD_AP_PANNING, CFRA, &sequence->pan, 0);
+ return handle;
}
void sound_remove_scene_sound(struct Scene *scene, void* handle)
{
- AUD_removeSequencer(scene->sound_scene, handle);
+ AUD_removeSequence(scene->sound_scene, handle);
}
-void sound_mute_scene_sound(struct Scene *scene, void* handle, char mute)
+void sound_mute_scene_sound(void* handle, char mute)
{
- AUD_muteSequencer(scene->sound_scene, handle, mute);
+ AUD_muteSequence(handle, mute);
}
void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, int endframe, int frameskip)
{
- AUD_moveSequencer(scene->sound_scene, handle, startframe / FPS, endframe / FPS, frameskip / FPS);
+ AUD_moveSequence(handle, startframe / FPS, endframe / FPS, frameskip / FPS);
+}
+
+void sound_update_scene_sound(void* handle, struct bSound* sound)
+{
+ AUD_updateSequenceSound(handle, sound->playback_handle);
+}
+
+void sound_set_cfra(int cfra)
+{
+ sound_cfra = cfra;
+}
+
+void sound_set_scene_volume(struct Scene *scene, float volume)
+{
+ AUD_setSequencerAnimData(scene->sound_scene, AUD_AP_VOLUME, CFRA, &volume, (scene->audio.flag & AUDIO_VOLUME_ANIMATED) != 0);
+}
+
+void sound_set_scene_sound_volume(void* handle, float volume, char animated)
+{
+ AUD_setSequenceAnimData(handle, AUD_AP_VOLUME, sound_cfra, &volume, animated);
+}
+
+void sound_set_scene_sound_pitch(void* handle, float pitch, char animated)
+{
+ AUD_setSequenceAnimData(handle, AUD_AP_PITCH, sound_cfra, &pitch, animated);
+}
+
+void sound_set_scene_sound_pan(void* handle, float pan, char animated)
+{
+ AUD_setSequenceAnimData(handle, AUD_AP_PANNING, sound_cfra, &pan, animated);
+}
+
+void sound_update_sequencer(struct Main* main, struct bSound* sound)
+{
+ struct Scene* scene;
+
+ for(scene = main->scene.first; scene; scene = scene->id.next)
+ seq_update_sound(scene, sound);
}
static void sound_start_play_scene(struct Scene *scene)
{
- scene->sound_scene_handle = AUD_play(scene->sound_scene, 1);
- AUD_setLoop(scene->sound_scene_handle, -1);
+ if(scene->sound_scene_handle)
+ AUD_stop(scene->sound_scene_handle);
+
+ AUD_setSequencerDeviceSpecs(scene->sound_scene);
+
+ if((scene->sound_scene_handle = AUD_play(scene->sound_scene, 1)))
+ AUD_setLoop(scene->sound_scene_handle, -1);
}
void sound_play_scene(struct Scene *scene)
@@ -409,11 +504,17 @@ void sound_play_scene(struct Scene *scene)
AUD_Status status;
AUD_lock();
- status = AUD_getStatus(scene->sound_scene_handle);
+ status = scene->sound_scene_handle ? AUD_getStatus(scene->sound_scene_handle) : AUD_STATUS_INVALID;
if(status == AUD_STATUS_INVALID)
sound_start_play_scene(scene);
+ if(!scene->sound_scene_handle)
+ {
+ AUD_unlock();
+ return;
+ }
+
if(status != AUD_STATUS_PLAYING)
{
AUD_seek(scene->sound_scene_handle, CFRA / FPS);
@@ -428,10 +529,13 @@ void sound_play_scene(struct Scene *scene)
void sound_stop_scene(struct Scene *scene)
{
- AUD_pause(scene->sound_scene_handle);
+ if(scene->sound_scene_handle)
+ {
+ AUD_pause(scene->sound_scene_handle);
- if(scene->audio.flag & AUDIO_SYNC)
- AUD_stopPlayback();
+ if(scene->audio.flag & AUDIO_SYNC)
+ AUD_stopPlayback();
+ }
}
void sound_seek_scene(struct bContext *C)
@@ -441,11 +545,18 @@ void sound_seek_scene(struct bContext *C)
AUD_lock();
- status = AUD_getStatus(scene->sound_scene_handle);
+ status = scene->sound_scene_handle ? AUD_getStatus(scene->sound_scene_handle) : AUD_STATUS_INVALID;
if(status == AUD_STATUS_INVALID)
{
sound_start_play_scene(scene);
+
+ if(!scene->sound_scene_handle)
+ {
+ AUD_unlock();
+ return;
+ }
+
AUD_pause(scene->sound_scene_handle);
}
@@ -459,10 +570,14 @@ void sound_seek_scene(struct bContext *C)
else
AUD_seek(scene->sound_scene_handle, CFRA / FPS);
AUD_resume(scene->sound_scene_handle);
- if(AUD_getStatus(scene->sound_scrub_handle) != AUD_STATUS_INVALID)
+ if(scene->sound_scrub_handle && AUD_getStatus(scene->sound_scrub_handle) != AUD_STATUS_INVALID)
AUD_seek(scene->sound_scrub_handle, 0);
else
+ {
+ if(scene->sound_scrub_handle)
+ AUD_stop(scene->sound_scrub_handle);
scene->sound_scrub_handle = AUD_pauseAfter(scene->sound_scene_handle, 1 / FPS);
+ }
}
else
{
@@ -480,10 +595,14 @@ void sound_seek_scene(struct bContext *C)
float sound_sync_scene(struct Scene *scene)
{
- if(scene->audio.flag & AUDIO_SYNC)
- return AUD_getSequencerPosition(scene->sound_scene_handle);
- else
- return AUD_getPosition(scene->sound_scene_handle);
+ if(scene->sound_scene_handle)
+ {
+ if(scene->audio.flag & AUDIO_SYNC)
+ return AUD_getSequencerPosition(scene->sound_scene_handle);
+ else
+ return AUD_getPosition(scene->sound_scene_handle);
+ }
+ return 0.0f;
}
int sound_scene_playing(struct Scene *scene)
@@ -494,21 +613,126 @@ int sound_scene_playing(struct Scene *scene)
return -1;
}
-int sound_read_sound_buffer(struct bSound* sound, float* buffer, int length, float start, float end)
+void sound_free_waveform(struct bSound* sound)
{
- AUD_Sound* limiter = AUD_limitSound(sound->cache, start, end);
- int ret= AUD_readSound(limiter, buffer, length);
- AUD_unload(limiter);
- return ret;
+ if(sound->waveform)
+ {
+ MEM_freeN(((SoundWaveform*)sound->waveform)->data);
+ MEM_freeN(sound->waveform);
+ }
+
+ sound->waveform = NULL;
}
-int sound_get_channels(struct bSound* sound)
+void sound_read_waveform(struct bSound* sound)
{
AUD_SoundInfo info;
info = AUD_getInfo(sound->playback_handle);
- return info.specs.channels;
+ if(info.length > 0)
+ {
+ SoundWaveform* waveform = MEM_mallocN(sizeof(SoundWaveform), "SoundWaveform");
+ int length = info.length * SOUND_WAVE_SAMPLES_PER_SECOND;
+
+ waveform->data = MEM_mallocN(length * sizeof(float) * 3, "SoundWaveform.samples");
+ waveform->length = AUD_readSound(sound->playback_handle, waveform->data, length, SOUND_WAVE_SAMPLES_PER_SECOND);
+
+ sound_free_waveform(sound);
+ sound->waveform = waveform;
+ }
+}
+
+void sound_update_scene(struct Scene* scene)
+{
+ Object* ob;
+ Base* base;
+ NlaTrack* track;
+ NlaStrip* strip;
+ Speaker* speaker;
+ Scene* sce_it;
+
+ void* new_set = AUD_createSet();
+ void* handle;
+ float quat[4];
+
+ for(SETLOOPER(scene, sce_it, base))
+ {
+ ob = base->object;
+ if(ob->type == OB_SPEAKER)
+ {
+ if(ob->adt)
+ {
+ for(track = ob->adt->nla_tracks.first; track; track = track->next)
+ {
+ for(strip = track->strips.first; strip; strip = strip->next)
+ {
+ if(strip->type == NLASTRIP_TYPE_SOUND)
+ {
+ speaker = (Speaker*)ob->data;
+
+ if(AUD_removeSet(scene->speaker_handles, strip->speaker_handle))
+ {
+ if(speaker->sound)
+ AUD_moveSequence(strip->speaker_handle, strip->start / FPS, -1, 0);
+ else
+ {
+ AUD_removeSequence(scene->sound_scene, strip->speaker_handle);
+ strip->speaker_handle = NULL;
+ }
+ }
+ else
+ {
+ if(speaker->sound)
+ {
+ strip->speaker_handle = AUD_addSequence(scene->sound_scene, speaker->sound->playback_handle, strip->start / FPS, -1, 0);
+ AUD_setRelativeSequence(strip->speaker_handle, 0);
+ }
+ }
+
+ if(strip->speaker_handle)
+ {
+ AUD_addSet(new_set, strip->speaker_handle);
+ AUD_updateSequenceData(strip->speaker_handle, speaker->volume_max,
+ speaker->volume_min, speaker->distance_max,
+ speaker->distance_reference, speaker->attenuation,
+ speaker->cone_angle_outer, speaker->cone_angle_inner,
+ speaker->cone_volume_outer);
+
+ mat4_to_quat(quat, ob->obmat);
+ AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_LOCATION, CFRA, ob->obmat[3], 1);
+ AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_ORIENTATION, CFRA, quat, 1);
+ AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_VOLUME, CFRA, &speaker->volume, 1);
+ AUD_setSequenceAnimData(strip->speaker_handle, AUD_AP_PITCH, CFRA, &speaker->pitch, 1);
+ AUD_updateSequenceSound(strip->speaker_handle, speaker->sound->playback_handle);
+ AUD_muteSequence(strip->speaker_handle, ((strip->flag & NLASTRIP_FLAG_MUTED) != 0) || ((speaker->flag & SPK_MUTED) != 0));
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ while((handle = AUD_getSet(scene->speaker_handles)))
+ {
+ AUD_removeSequence(scene->sound_scene, handle);
+ }
+
+ if(scene->camera)
+ {
+ mat4_to_quat(quat, scene->camera->obmat);
+ AUD_setSequencerAnimData(scene->sound_scene, AUD_AP_LOCATION, CFRA, scene->camera->obmat[3], 1);
+ AUD_setSequencerAnimData(scene->sound_scene, AUD_AP_ORIENTATION, CFRA, quat, 1);
+ }
+
+ AUD_destroySet(scene->speaker_handles);
+ scene->speaker_handles = new_set;
+}
+
+void* sound_get_factory(void* sound)
+{
+ return ((struct bSound*) sound)->playback_handle;
}
#else // WITH_AUDASPACE
@@ -520,7 +744,7 @@ void sound_force_device(int UNUSED(device)) {}
void sound_init_once(void) {}
void sound_init(struct Main *UNUSED(bmain)) {}
void sound_exit(void) {}
-void sound_cache(struct bSound* UNUSED(sound), int UNUSED(ignore)) { }
+void sound_cache(struct bSound* UNUSED(sound)) { }
void sound_delete_cache(struct bSound* UNUSED(sound)) {}
void sound_load(struct Main *UNUSED(bmain), struct bSound* UNUSED(sound)) {}
void sound_create_scene(struct Scene *UNUSED(scene)) {}
@@ -529,7 +753,7 @@ void sound_mute_scene(struct Scene *UNUSED(scene), int UNUSED(muted)) {}
void* sound_scene_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
void* sound_add_scene_sound(struct Scene *UNUSED(scene), struct Sequence* UNUSED(sequence), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) { return NULL; }
void sound_remove_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle)) {}
-void sound_mute_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), char UNUSED(mute)) {}
+void sound_mute_scene_sound(void* UNUSED(handle), char UNUSED(mute)) {}
void sound_move_scene_sound(struct Scene *UNUSED(scene), void* UNUSED(handle), int UNUSED(startframe), int UNUSED(endframe), int UNUSED(frameskip)) {}
static void sound_start_play_scene(struct Scene *UNUSED(scene)) {}
void sound_play_scene(struct Scene *UNUSED(scene)) {}
@@ -538,6 +762,17 @@ void sound_seek_scene(struct bContext *UNUSED(C)) {}
float sound_sync_scene(struct Scene *UNUSED(scene)) { return 0.0f; }
int sound_scene_playing(struct Scene *UNUSED(scene)) { return -1; }
int sound_read_sound_buffer(struct bSound* UNUSED(sound), float* UNUSED(buffer), int UNUSED(length), float UNUSED(start), float UNUSED(end)) { return 0; }
-int sound_get_channels(struct bSound* UNUSED(sound)) { return 1; }
+void sound_read_waveform(struct bSound* sound) { (void)sound; }
+void sound_init_main(struct Main *bmain) { (void)bmain; }
+void sound_set_cfra(int cfra) { (void)cfra; }
+void sound_update_sequencer(struct Main* main, struct bSound* sound) { (void)main; (void)sound; }
+void sound_update_scene(struct Scene* scene) { (void)scene; }
+void sound_update_scene_sound(void* handle, struct bSound* sound) { (void)handle; (void)sound; }
+void sound_update_scene_listener(struct Scene *scene) { (void)scene; }
+void sound_update_fps(struct Scene *scene) { (void)scene; }
+void sound_set_scene_sound_volume(void* handle, float volume, char animated) { (void)handle; (void)volume; (void)animated; }
+void sound_set_scene_sound_pan(void* handle, float pan, char animated) { (void)handle; (void)pan; (void)animated; }
+void sound_set_scene_volume(struct Scene *scene, float volume) { (void)scene; (void)volume; }
+void sound_set_scene_sound_pitch(void* handle, float pitch, char animated) { (void)handle; (void)pitch; (void)animated; }
#endif // WITH_AUDASPACE
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
new file mode 100644
index 00000000000..200dbd41899
--- /dev/null
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -0,0 +1,139 @@
+/* speaker.c
+ *
+ *
+ * $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): Jörg Müller.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/blenkernel/intern/speaker.c
+ * \ingroup bke
+ */
+
+#include "DNA_object_types.h"
+#include "DNA_sound_types.h"
+#include "DNA_speaker_types.h"
+
+#include "BLI_math.h"
+
+#include "BKE_animsys.h"
+#include "BKE_global.h"
+#include "BKE_library.h"
+#include "BKE_main.h"
+#include "BKE_speaker.h"
+
+void *add_speaker(const char *name)
+{
+ Speaker *spk;
+
+ spk= alloc_libblock(&G.main->speaker, ID_SPK, name);
+
+ spk->attenuation = 1.0f;
+ spk->cone_angle_inner = 360.0f;
+ spk->cone_angle_outer = 360.0f;
+ spk->cone_volume_outer = 1.0f;
+ spk->distance_max = FLT_MAX;
+ spk->distance_reference = 1.0f;
+ spk->flag = 0;
+ spk->pitch = 1.0f;
+ spk->sound = NULL;
+ spk->volume = 1.0f;
+ spk->volume_max = 1.0f;
+ spk->volume_min = 0.0f;
+
+ return spk;
+}
+
+Speaker *copy_speaker(Speaker *spk)
+{
+ Speaker *spkn;
+
+ spkn= copy_libblock(spk);
+ if(spkn->sound)
+ spkn->sound->id.us++;
+
+ return spkn;
+}
+
+void make_local_speaker(Speaker *spk)
+{
+ Main *bmain= G.main;
+ Object *ob;
+ int local=0, lib=0;
+
+ /* - only lib users: do nothing
+ * - only local users: set flag
+ * - mixed: make copy
+ */
+
+ if(spk->id.lib==NULL) return;
+ if(spk->id.us==1) {
+ spk->id.lib= NULL;
+ spk->id.flag= LIB_LOCAL;
+ new_id(&bmain->speaker, (ID *)spk, NULL);
+ return;
+ }
+
+ ob= bmain->object.first;
+ while(ob) {
+ if(ob->data==spk) {
+ if(ob->id.lib) lib= 1;
+ else local= 1;
+ }
+ ob= ob->id.next;
+ }
+
+ if(local && lib==0) {
+ spk->id.lib= NULL;
+ spk->id.flag= LIB_LOCAL;
+ new_id(&bmain->speaker, (ID *)spk, NULL);
+ }
+ else if(local && lib) {
+ Speaker *spkn= copy_speaker(spk);
+ spkn->id.us= 0;
+
+ ob= bmain->object.first;
+ while(ob) {
+ if(ob->data==spk) {
+
+ if(ob->id.lib==NULL) {
+ ob->data= spkn;
+ spkn->id.us++;
+ spk->id.us--;
+ }
+ }
+ ob= ob->id.next;
+ }
+ }
+}
+
+void free_speaker(Speaker *spk)
+{
+ if(spk->sound)
+ spk->sound->id.us--;
+
+ BKE_free_animdata((ID *)spk);
+}
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index f66f7ca023e..bcba812fe24 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -1779,7 +1779,8 @@ static void ccgDM_drawUVEdges(DerivedMesh *dm)
}
}
-static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs)) {
+static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
+ int (*compareDrawOptions)(void *userData, int cur_index, int next_index)) {
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm;
CCGSubSurf *ss = ccgdm->ss;
MCol *mcol= NULL;
@@ -1787,6 +1788,9 @@ static void ccgDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *u
char *faceFlags = ccgdm->faceFlags;
int gridFaces = gridSize - 1, totface;
+ /* currently unused -- each original face is handled separately */
+ (void)compareDrawOptions;
+
if(useColors) {
mcol = dm->getFaceDataArray(dm, CD_WEIGHT_MCOL);
if(!mcol)
diff --git a/source/blender/blenkernel/intern/unit.c b/source/blender/blenkernel/intern/unit.c
index a9792bc44fa..72fe1c19884 100644
--- a/source/blender/blenkernel/intern/unit.c
+++ b/source/blender/blenkernel/intern/unit.c
@@ -34,6 +34,7 @@
#include "BKE_unit.h"
#include "BLI_math.h"
+#include "BLI_string.h"
#include "BLI_winstuff.h"
@@ -344,7 +345,7 @@ static int unit_as_string(char *str, int len_max, double value, int prec, bUnitC
/* Convert to a string */
{
- len= snprintf(str, len_max, "%.*lf", prec, value_conv);
+ len= BLI_snprintf(str, len_max, "%.*lf", prec, value_conv);
if(len >= len_max)
len= len_max;
@@ -495,7 +496,7 @@ static int unit_scale_str(char *str, int len_max, char *str_tmp, double scale_pr
len_name = strlen(replace_str);
len_move= (len - (found_ofs+len_name)) + 1; /* 1+ to copy the string terminator */
- len_num= snprintf(str_tmp, TEMP_STR_SIZE, "*%lg"SEP_STR, unit->scalar/scale_pref); /* # removed later */
+ len_num= BLI_snprintf(str_tmp, TEMP_STR_SIZE, "*%lg"SEP_STR, unit->scalar/scale_pref); /* # removed later */
if(len_num > len_max)
len_num= len_max;
@@ -629,12 +630,12 @@ int bUnit_ReplaceString(char *str, int len_max, char *str_prev, double scale_pre
/* add the unit prefix and re-run, use brackets incase there was an expression given */
- if(snprintf(str_tmp, sizeof(str_tmp), "(%s)%s", str, unit->name) < sizeof(str_tmp)) {
+ if(BLI_snprintf(str_tmp, sizeof(str_tmp), "(%s)%s", str, unit->name) < sizeof(str_tmp)) {
strncpy(str, str_tmp, len_max);
return bUnit_ReplaceString(str, len_max, NULL, scale_pref, system, type);
}
else {
- /* snprintf would not fit into str_tmp, cant do much in this case
+ /* BLI_snprintf would not fit into str_tmp, cant do much in this case
* check for this because otherwise bUnit_ReplaceString could call its self forever */
return 0;
}
@@ -705,7 +706,7 @@ void bUnit_ToUnitAltName(char *str, int len_max, char *orig_str, int system, int
/* print the alt_name */
if(unit->name_alt)
- len_name= snprintf(str, len_max, "%s", unit->name_alt);
+ len_name= BLI_snprintf(str, len_max, "%s", unit->name_alt);
else
len_name= 0;
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index fe7a7a18177..13875ff19f7 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -39,10 +39,6 @@
#include <libswscale/swscale.h>
#include <libavcodec/opt.h>
-#if defined(WIN32) && (!(defined snprintf))
-#define snprintf _snprintf
-#endif
-
#include "MEM_guardedalloc.h"
#include "DNA_scene_types.h"
@@ -555,7 +551,7 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
c->sample_rate = rd->ffcodecdata.audio_mixrate;
c->bit_rate = ffmpeg_audio_bitrate*1000;
c->sample_fmt = SAMPLE_FMT_S16;
- c->channels = 2;
+ c->channels = rd->ffcodecdata.audio_channels;
codec = avcodec_find_encoder(c->codec_id);
if (!codec) {
//XXX error("Couldn't find a valid audio codec");
@@ -580,12 +576,11 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
audio_outbuf_size = c->frame_size * c->channels * sizeof(int16_t) * 4;
}
- audio_output_buffer = (uint8_t*)MEM_mallocN(
- audio_outbuf_size, "FFMPEG audio encoder input buffer");
+ audio_output_buffer = (uint8_t*)av_malloc(
+ audio_outbuf_size);
- audio_input_buffer = (uint8_t*)MEM_mallocN(
- audio_input_samples * c->channels * sizeof(int16_t),
- "FFMPEG audio encoder output buffer");
+ audio_input_buffer = (uint8_t*)av_malloc(
+ audio_input_samples * c->channels * sizeof(int16_t));
audio_time = 0.0f;
@@ -653,7 +648,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
fmt->audio_codec = ffmpeg_audio_codec;
- snprintf(of->filename, sizeof(of->filename), "%s", name);
+ BLI_snprintf(of->filename, sizeof(of->filename), "%s", name);
/* set the codec to the user's selection */
switch(ffmpeg_type) {
case FFMPEG_AVI:
@@ -709,7 +704,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
if (ffmpeg_type == FFMPEG_DV) {
fmt->audio_codec = CODEC_ID_PCM_S16LE;
- if (ffmpeg_audio_codec != CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000) {
+ if (ffmpeg_audio_codec != CODEC_ID_NONE && rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2) {
BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!");
return 0;
}
@@ -868,6 +863,10 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo
specs.format = AUD_FORMAT_S16;
specs.rate = rd->ffcodecdata.audio_mixrate;
audio_mixdown_device = sound_mixdown(scene, specs, rd->sfra, rd->ffcodecdata.audio_volume);
+#ifdef FFMPEG_CODEC_TIME_BASE
+ c->time_base.den = specs.rate;
+ c->time_base.num = 1;
+#endif
}
#endif
return success;
@@ -984,11 +983,11 @@ void end_ffmpeg(void)
video_buffer = 0;
}
if (audio_output_buffer) {
- MEM_freeN(audio_output_buffer);
+ av_free(audio_output_buffer);
audio_output_buffer = 0;
}
if (audio_input_buffer) {
- MEM_freeN(audio_input_buffer);
+ av_free(audio_input_buffer);
audio_input_buffer = 0;
}