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:
Diffstat (limited to 'source/blender/editors/transform/transform_generics.c')
-rw-r--r--source/blender/editors/transform/transform_generics.c176
1 files changed, 130 insertions, 46 deletions
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index e228dc2b13a..9928aea21d0 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -340,67 +340,151 @@ void recalcData(TransInfo *t)
}
}
else if (t->spacetype == SPACE_NLA) {
- TransData *td= t->data;
+ TransDataNla *tdn= (TransDataNla *)t->customData;
int i;
- /* for each point we've captured, look at its 'extra' data, which is basically a wrapper around the strip
- * it is for + some extra storage for the values that get set, and use RNA to set this value (performing validation
- * work so that we don't need to repeat it here)
+ /* for each strip we've got, perform some additional validation of the values that got set before
+ * using RNA to set the value (which does some special operations when setting these values to make
+ * sure that everything works ok)
*/
- for (i = 0; i < t->total; i++, td++)
- {
- if (td->extra)
- {
- TransDataNla *tdn= td->extra;
- NlaStrip *strip= tdn->strip;
+ for (i = 0; i < t->total; i++, tdn++) {
+ NlaStrip *strip= tdn->strip;
+ PointerRNA strip_ptr;
+ short pExceeded, nExceeded, iter;
+ int delta_y1, delta_y2;
+
+ /* if this tdn has no handles, that means it is just a dummy that should be skipped */
+ if (tdn->handle == 0)
+ continue;
- /* if we're just cancelling (i.e. the user aborted the transform),
- * just restore the data by directly overwriting the values with the original
- * ones (i.e. don't go through RNA), as we get some artifacts...
+ /* if cancelling transform, just write the values without validating, then move on */
+ if (t->state == TRANS_CANCEL) {
+ /* clear the values by directly overwriting the originals, but also need to restore
+ * endpoints of neighboring transition-strips
*/
- if (t->state == TRANS_CANCEL) {
- /* clear the values by directly overwriting the originals, but also need to restore
- * endpoints of neighboring transition-strips
+
+ /* start */
+ strip->start= tdn->h1[0];
+
+ if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION))
+ strip->prev->end= tdn->h1[0];
+
+ /* end */
+ strip->end= tdn->h2[0];
+
+ if ((strip->next) && (strip->next->type == NLASTRIP_TYPE_TRANSITION))
+ strip->next->start= tdn->h2[0];
+
+ /* restore to original track (if needed) */
+ if (tdn->oldTrack != tdn->nlt) {
+ /* just append to end of list for now, since strips get sorted in special_aftertrans_update() */
+ BLI_remlink(&tdn->nlt->strips, strip);
+ BLI_addtail(&tdn->oldTrack->strips, strip);
+ }
+
+ continue;
+ }
+
+ /* firstly, check if the proposed transform locations would overlap with any neighbouring strips
+ * (barring transitions) which are absolute barriers since they are not being moved
+ *
+ * this is done as a iterative procedure (done 5 times max for now)
+ */
+ for (iter=0; iter < 5; iter++) {
+ pExceeded= ((strip->prev) && (strip->prev->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h1[0] < strip->prev->end));
+ nExceeded= ((strip->next) && (strip->next->type != NLASTRIP_TYPE_TRANSITION) && (tdn->h2[0] > strip->next->start));
+
+ if ((pExceeded && nExceeded) || (iter == 4) ) {
+ /* both endpoints exceeded (or iteration ping-pong'd meaning that we need a compromise)
+ * - simply crop strip to fit within the bounds of the strips bounding it
+ * - if there were no neighbours, clear the transforms (make it default to the strip's current values)
*/
- if (tdn->handle) {
- strip->end= tdn->val;
-
- if ((strip->next) && (strip->next->type == NLASTRIP_TYPE_TRANSITION))
- strip->next->start= tdn->val;
+ if (strip->prev && strip->next) {
+ tdn->h1[0]= strip->prev->end;
+ tdn->h2[0]= strip->next->start;
}
else {
- strip->start= tdn->val;
-
- if ((strip->prev) && (strip->prev->type == NLASTRIP_TYPE_TRANSITION))
- strip->prev->end= tdn->val;
+ tdn->h1[0]= strip->start;
+ tdn->h2[0]= strip->end;
}
}
- else {
- PointerRNA strip_ptr;
+ else if (nExceeded) {
+ /* move backwards */
+ float offset= tdn->h2[0] - strip->next->start;
- /* make RNA-pointer */
- RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
+ tdn->h1[0] -= offset;
+ tdn->h2[0] -= offset;
+ }
+ else if (pExceeded) {
+ /* more forwards */
+ float offset= strip->prev->end - tdn->h1[0];
- /* write the value set by the transform tools to the appropriate property using RNA */
- if (tdn->handle)
- RNA_float_set(&strip_ptr, "end_frame", tdn->val);
- else
- RNA_float_set(&strip_ptr, "start_frame", tdn->val);
+ tdn->h1[0] += offset;
+ tdn->h2[0] += offset;
}
+ else /* all is fine and well */
+ break;
}
- }
-
- /* loop over the TransDataNla again, flushing the transforms (since we use Metas to make transforms easier) */
- td= t->data;
- for (i = 0; i < t->total; i++, td++)
- {
- if (td->extra)
- {
- TransDataNla *tdn= td->extra;
- NlaStrip *strip= tdn->strip;
+
+ /* use RNA to write the values... */
+ // TODO: do we need to write in 2 passes to make sure that no truncation goes on?
+ RNA_pointer_create(NULL, &RNA_NlaStrip, strip, &strip_ptr);
+
+ RNA_float_set(&strip_ptr, "start_frame", tdn->h1[0]);
+ RNA_float_set(&strip_ptr, "end_frame", tdn->h2[0]);
+
+ /* flush transforms to child strips (since this should be a meta) */
+ BKE_nlameta_flush_transforms(strip);
+
+
+ /* now, check if we need to try and move track
+ * - we need to calculate both, as only one may have been altered by transform if only 1 handle moved
+ */
+ // FIXME: the conversion from vertical distance to track index needs work!
+ delta_y1= ((int)tdn->h1[0] / NLACHANNEL_SKIP - tdn->trackIndex);
+ delta_y2= ((int)tdn->h2[0] / NLACHANNEL_SKIP - tdn->trackIndex);
+
+ if (delta_y1 || delta_y2) {
+ NlaTrack *track;
+ int delta = (delta_y2) ? delta_y2 : delta_y1;
+ int n;
- // TODO: this may flush some things twice, but that's fine as there's no impact from that
- BKE_nlameta_flush_transforms(strip);
+ /* move in the requested direction, checking at each layer if there's space for strip to pass through,
+ * stopping on the last track available or that we're able to fit in
+ */
+ if (delta > 0) {
+ for (track=tdn->nlt->next, n=0; (track) && (n < delta); track=track->next, n++) {
+ /* check if space in this track for the strip */
+ if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
+ /* move strip to this track */
+ BLI_remlink(&tdn->nlt->strips, strip);
+ BKE_nlatrack_add_strip(track, strip);
+
+ tdn->nlt= track;
+ tdn->trackIndex += (n + 1); /* + 1, since n==0 would mean that we didn't change track */
+ }
+ else /* can't move any further */
+ break;
+ }
+ }
+ else {
+ /* make delta 'positive' before using it, since we now know to go backwards */
+ delta= -delta;
+
+ for (track=tdn->nlt->prev, n=0; (track) && (n < delta); track=track->prev, n++) {
+ /* check if space in this track for the strip */
+ if (BKE_nlatrack_has_space(track, strip->start, strip->end)) {
+ /* move strip to this track */
+ BLI_remlink(&tdn->nlt->strips, strip);
+ BKE_nlatrack_add_strip(track, strip);
+
+ tdn->nlt= track;
+ tdn->trackIndex -= (n - 1); /* - 1, since n==0 would mean that we didn't change track */
+ }
+ else /* can't move any further */
+ break;
+ }
+ }
}
}
}