Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Fri, 20 Jul 2018 10:13:58 +0000 (12:13 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Fri, 20 Jul 2018 10:13:58 +0000 (12:13 +0200)
source/blender/blenkernel/intern/constraint.c
source/blender/blenkernel/intern/sound.c
source/blender/blenlib/BLI_math_vector.h
source/blender/blenlib/intern/math_vector_inline.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/space_sequencer/sequencer_draw.c
source/blender/editors/space_sequencer/sequencer_preview.c
source/blender/makesdna/DNA_sound_types.h

index 4f772673e1de6e62f6c1a19690a025d2428bb734..5aa192d527ab729d04866bd449dfd8fc6d506167 100644 (file)
@@ -3641,7 +3641,7 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
                 *      - the min/max wrappers around (obvec . tarvec) result (stored temporarily in rangle)
                 *        are used to ensure that the smallest angle is chosen
                 */
-               cross_v3_v3v3(raxis, obvec, tarvec);
+               cross_v3_v3v3_hi_prec(raxis, obvec, tarvec);
 
                rangle = dot_v3v3(obvec, tarvec);
                rangle = acosf(max_ff(-1.0f, min_ff(1.0f, rangle)));
@@ -3649,7 +3649,35 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
                /* construct rotation matrix from the axis-angle rotation found above
                 *      - this call takes care to make sure that the axis provided is a unit vector first
                 */
-               axis_angle_to_mat3(rmat, raxis, rangle);
+               float norm = normalize_v3(raxis);
+
+               if (norm < FLT_EPSILON) {
+                       /* if dot product is nonzero, while cross is zero, we have two opposite vectors!
+                        *  - this is an ambiguity in the math that needs to be resolved arbitrarily,
+                        *    or there will be a case where damped track strangely does nothing
+                        *  - to do that, rotate around a different local axis
+                        */
+                       float tmpvec[3];
+
+                       if (fabsf(rangle) < M_PI - 0.01f) {
+                               return;
+                       }
+
+                       rangle = M_PI;
+                       copy_v3_v3(tmpvec, track_dir_vecs[(data->trackflag + 1) % 6]);
+                       mul_mat3_m4_v3(cob->matrix, tmpvec);
+                       cross_v3_v3v3(raxis, obvec, tmpvec);
+
+                       if (normalize_v3(raxis) == 0.0f) {
+                               return;
+                       }
+               }
+               else if (norm < 0.1f) {
+                       /* near 0 and Pi arcsin has way better precision than arccos */
+                       rangle = (rangle > M_PI_2) ? M_PI - asinf(norm) : asinf(norm);
+               }
+
+               axis_angle_normalized_to_mat3(rmat, raxis, rangle);
 
                /* rotate the owner in the way defined by this rotation matrix, then reapply the location since
                 * we may have destroyed that in the process of multiplying the matrix
index ebb23f8d5c63c1e11d50ecc8ff18be24350004f2..5135362bd695b2553fed7e4bd17617f170bc410c 100644 (file)
@@ -756,15 +756,19 @@ int BKE_sound_scene_playing(struct Scene *scene)
 
 void BKE_sound_free_waveform(bSound *sound)
 {
-       SoundWaveform *waveform = sound->waveform;
-       if (waveform) {
-               if (waveform->data) {
-                       MEM_freeN(waveform->data);
+       if ((sound->tags & SOUND_TAGS_WAVEFORM_NO_RELOAD) == 0) {
+               SoundWaveform *waveform = sound->waveform;
+               if (waveform) {
+                       if (waveform->data) {
+                               MEM_freeN(waveform->data);
+                       }
+                       MEM_freeN(waveform);
                }
-               MEM_freeN(waveform);
-       }
 
-       sound->waveform = NULL;
+               sound->waveform = NULL;
+       }
+       /* This tag is only valid once. */
+       sound->tags &= ~SOUND_TAGS_WAVEFORM_NO_RELOAD;
 }
 
 void BKE_sound_read_waveform(bSound *sound, short *stop)
@@ -793,7 +797,7 @@ void BKE_sound_read_waveform(bSound *sound, short *stop)
                }
                MEM_freeN(waveform);
                BLI_spin_lock(sound->spinlock);
-               sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+               sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
                BLI_spin_unlock(sound->spinlock);
                return;
        }
@@ -802,7 +806,7 @@ void BKE_sound_read_waveform(bSound *sound, short *stop)
 
        BLI_spin_lock(sound->spinlock);
        sound->waveform = waveform;
-       sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+       sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
        BLI_spin_unlock(sound->spinlock);
 }
 
index 20852f8fc824c144df24896434c87fb58c82dff5..ec16a6854c4a79658dfc6d5d882d6f122509c625 100644 (file)
@@ -169,6 +169,7 @@ MINLINE double dot_v3db_v3fl(const double a[3], const float b[3]) ATTR_WARN_UNUS
 
 MINLINE float cross_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT;
 MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3]);
+MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3]);
 
 MINLINE void add_newell_cross_v3_v3v3(float n[3], const float v_prev[3], const float v_curr[3]);
 
index 4c40921edb6e2c39d0c39bc8b5a2e1ecf9612a06..189b94a6f1311abdaba75383b4c7357123832e0e 100644 (file)
@@ -753,6 +753,16 @@ MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
        r[2] = a[0] * b[1] - a[1] * b[0];
 }
 
+/* cross product suffers from severe precision loss when vectors are
+ * nearly parallel or opposite; doing the computation in double helps a lot */
+MINLINE void cross_v3_v3v3_hi_prec(float r[3], const float a[3], const float b[3])
+{
+       BLI_assert(r != a && r != b);
+       r[0] = (float)((double)a[1] * (double)b[2] - (double)a[2] * (double)b[1]);
+       r[1] = (float)((double)a[2] * (double)b[0] - (double)a[0] * (double)b[2]);
+       r[2] = (float)((double)a[0] * (double)b[1] - (double)a[1] * (double)b[0]);
+}
+
 /* Newell's Method */
 /* excuse this fairly specific function,
  * its used for polygon normals all over the place
index b878932e3dd7b02273aa6eb71baab602461cef71..d76a2fc2cd09af64d991b3a030f379f51f8adba8 100644 (file)
@@ -7707,6 +7707,7 @@ static void direct_link_speaker(FileData *fd, Speaker *spk)
 
 static void direct_link_sound(FileData *fd, bSound *sound)
 {
+       sound->tags = 0;
        sound->handle = NULL;
        sound->playback_handle = NULL;
 
@@ -7718,6 +7719,7 @@ static void direct_link_sound(FileData *fd, bSound *sound)
 
        if (fd->soundmap) {
                sound->waveform = newsoundadr(fd, sound->waveform);
+               sound->tags |= SOUND_TAGS_WAVEFORM_NO_RELOAD;
        }
        else {
                sound->waveform = NULL;
@@ -7728,7 +7730,7 @@ static void direct_link_sound(FileData *fd, bSound *sound)
                BLI_spin_init(sound->spinlock);
        }
        /* clear waveform loading flag */
-       sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+       sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
 
        sound->packedfile = direct_link_packedfile(fd, sound->packedfile);
        sound->newpackedfile = direct_link_packedfile(fd, sound->newpackedfile);
index 47059d659452a3e656a5a976357b8ca1d0ba9796..864609e41576bfe1cf4f4e9184d1bbf81386478a 100644 (file)
@@ -232,9 +232,9 @@ static void drawseqwave(View2D *v2d, const bContext *C, SpaceSeq *sseq, Scene *s
 
                BLI_spin_lock(sound->spinlock);
                if (!sound->waveform) {
-                       if (!(sound->flags & SOUND_FLAGS_WAVEFORM_LOADING)) {
+                       if (!(sound->tags & SOUND_TAGS_WAVEFORM_LOADING)) {
                                /* prevent sounds from reloading */
-                               sound->flags |= SOUND_FLAGS_WAVEFORM_LOADING;
+                               sound->tags |= SOUND_TAGS_WAVEFORM_LOADING;
                                BLI_spin_unlock(sound->spinlock);
                                sequencer_preview_add_sound(C, seq);
                        }
index c58c05b67c09c1baa7b1b5646f3bad1595c472d3..ae011e48538d329e79d104521fbae4191527ba2f 100644 (file)
@@ -96,7 +96,7 @@ static void preview_startjob(void *data, short *stop, short *do_update, float *p
 
                                /* make sure we cleanup the loading flag! */
                                BLI_spin_lock(sound->spinlock);
-                               sound->flags &= ~SOUND_FLAGS_WAVEFORM_LOADING;
+                               sound->tags &= ~SOUND_TAGS_WAVEFORM_LOADING;
                                BLI_spin_unlock(sound->spinlock);
 
                                BLI_mutex_lock(pj->mutex);
index aefe1a7d5a3f4d090740fff30788e357b95eec23..02d3aa928c78cecccc3e841592b027863fd04d39 100644 (file)
@@ -65,13 +65,15 @@ typedef struct bSound {
         */
        struct PackedFile *newpackedfile;
        struct Ipo *ipo;
+
        float volume;
        float attenuation;
        float pitch;
        float min_gain;
        float max_gain;
        float distance;
-       int flags;
+       short flags;
+       short tags;  /* Runtime only, always reset in readfile. */
        int pad;
 
        /* unused currently
@@ -116,13 +118,19 @@ enum {
        SND_CFRA_NUM    = 2,
 };
 
+/* bSound->flags */
 enum {
 #ifdef DNA_DEPRECATED
        SOUND_FLAGS_3D                   = (1 << 3),  /* deprecated! used for sound actuator loading */
 #endif
        SOUND_FLAGS_CACHING              = (1 << 4),
        SOUND_FLAGS_MONO                 = (1 << 5),
-       SOUND_FLAGS_WAVEFORM_LOADING     = (1 << 6),
+};
+
+/* bSound->tags */
+enum {
+       SOUND_TAGS_WAVEFORM_NO_RELOAD    = 1 << 0,  /* Do not free/reset waveform on sound load, only used by undo code. */
+       SOUND_TAGS_WAVEFORM_LOADING     = (1 << 6),
 };
 
 /* to DNA_sound_types.h*/