[gimp-gap] implemented acceleration charactersitics for MovePath #607927
- From: Wolfgang Hofer <wolfgangh src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [gimp-gap] implemented acceleration charactersitics for MovePath #607927
- Date: Sun, 7 Feb 2010 11:33:56 +0000 (UTC)
commit 78e398d7fa7a98c9315d589fbde636e17e0925cb
Author: Wolfgang Hofer <wolfgangh svn gnome org>
Date: Sun Feb 7 12:34:20 2010 +0100
implemented acceleration charactersitics for MovePath #607927
ChangeLog | 13 +
gap/Makefile.am | 4 +
gap/gap_accel_char.c | 82 +++++
gap/gap_accel_char.h | 48 +++
gap/gap_accel_da.c | 224 +++++++++++++
gap/gap_accel_da.h | 50 +++
gap/gap_mov_dialog.c | 497 +++++++++++++++++++++++++++--
gap/gap_mov_dialog.h | 20 ++-
gap/gap_mov_exec.c | 861 ++++++++++++++++++++++++++++++++++++++++++++------
9 files changed, 1673 insertions(+), 126 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 9b5d4d7..0fa5428 100755
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2010-02-07 Wolfgang Hofer <hof gimp org>
+
+- implementation for acceleration characteristic support im MovePath
+ (as suggested in #607927)
+
+ * gap/gap_accel_char.c [.h] # NEW files
+ * gap/gap_accel_da.c [.h] # NEW files
+ * gap/Makefile.am
+
+ * gap/gap_mov_exec.c
+ * gap/gap_mov_dialog.c [.h]
+
+
2010-01-16 Wolfgang Hofer <hof gimp org>
- applied patch provided at #607040 that fixes the crash when selcting
controlpoint color.
diff --git a/gap/Makefile.am b/gap/Makefile.am
index c2b8b2f..0a8bb9a 100644
--- a/gap/Makefile.am
+++ b/gap/Makefile.am
@@ -34,6 +34,10 @@ noinst_LIBRARIES = $(LIBGIMPGAP) $(LIBGAPSTORY)
BASE_SOURCES = \
gap-intl.h \
+ gap_accel_char.c \
+ gap_accel_char.h \
+ gap_accel_da.c \
+ gap_accel_da.h \
gap_arr_dialog.c \
gap_arr_dialog.h \
gap_audio_util.c \
diff --git a/gap/gap_accel_char.c b/gap/gap_accel_char.c
new file mode 100644
index 0000000..9ff6fe9
--- /dev/null
+++ b/gap/gap_accel_char.c
@@ -0,0 +1,82 @@
+/* gap_accel_char.c
+ *
+ * This module handles GAP acceleration characteristics calculation.
+ */
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* revision history:
+ * version 2.7.0; 2010/02/06 hof: created
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+#include "gap_accel_char.h"
+
+
+/* ---------------------------------------
+ * gap_accelMixFactor
+ * ---------------------------------------
+ * this proecdure implements hardcoded acceleration characteristics.
+ *
+ * accelCharacteristic:
+ * 0 is used to turn off acceleration
+ * 1 specified constant speed
+ *
+ * positive values > 1 represent acceleration,
+ + negative values < -1 for deceleration
+ *
+ * orig_factor: a positive gdouble in the range 0.0 to 1.0
+ * returns modified mix_factor in the range 0.0 to 1.0 according to specified accelCharacteristic
+ * the returned value is equal to orig_factor for accelCharacteristic -1, 0 amd 1
+ */
+gdouble
+gap_accelMixFactor(gdouble orig_factor, gint accelCharacteristic)
+{
+ gdouble mix;
+ gdouble accelPower;
+
+ switch (accelCharacteristic)
+ {
+ case 0:
+ case 1:
+ case -1:
+ mix = orig_factor;
+ break;
+ default:
+ if (accelCharacteristic > 0)
+ {
+ accelPower = 1 + ((accelCharacteristic -1) / 10.0);
+ mix = pow(orig_factor, accelPower);
+ }
+ else
+ {
+ accelPower = 1 + (((0 - accelCharacteristic) -1) / 10.0);
+ mix = 1.0 - pow((1.0 - orig_factor), accelPower);
+ }
+ break;
+ }
+
+ return (mix);
+} /* end gap_accelMixFactor */
diff --git a/gap/gap_accel_char.h b/gap/gap_accel_char.h
new file mode 100644
index 0000000..5249748
--- /dev/null
+++ b/gap/gap_accel_char.h
@@ -0,0 +1,48 @@
+/* gap_accel_char.h
+ *
+ * This module handles GAP acceleration characteristics calculation.
+ */
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* revision history:
+ * version 2.7.0; 2010/02/06 hof: created
+ */
+
+#ifndef _GAP_ACCEL_CHAR_H
+#define _GAP_ACCEL_CHAR_H
+
+#include <gtk/gtk.h>
+#include <libgimp/gimp.h>
+
+
+/* ---------------------------------------
+ * gap_accelMixFactor
+ * ---------------------------------------
+ * this proecdure implements hardcoded acceleration characteristics.
+ *
+ * accelCharacteristic: 0 and 1 for linear, positive values for acceleration, negative values for deceleration
+ *
+ * orig_factor: a positive gdouble in the range 0.0 to 1.0
+ * returns modified mix_factor in the range 0.0 to 1.0 according to specified accelCharacteristic
+ */
+gdouble
+gap_accelMixFactor(gdouble orig_factor, gint accelCharacteristic);
+
+
+#endif
diff --git a/gap/gap_accel_da.c b/gap/gap_accel_da.c
new file mode 100644
index 0000000..54d1281
--- /dev/null
+++ b/gap/gap_accel_da.c
@@ -0,0 +1,224 @@
+/* gap_accel_da.c
+ *
+ * This module handles GAP acceleration characteristics drawing area.
+ */
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* revision history:
+ * version 2.7.0; 2010/02/06 hof: created
+ */
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+
+#include <gtk/gtk.h>
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+#include "gap_accel_char.h"
+#include "gap_accel_da.h"
+#include "gap-intl.h"
+#include "gap_lib_common_defs.h"
+
+
+extern int gap_debug; /* 1 == print debug infos , 0 dont print debug infos */
+
+
+#define MIX_CHANNEL(b, a, m) (((a * m) + (b * (255 - m))) / 255)
+#define PREVIEW_BG_GRAY1 80
+#define PREVIEW_BG_GRAY2 180
+
+#define PREVIEW_BG_GRAY1_GDK 0x505050
+#define PREVIEW_BG_GRAY2_GDK 0xb4b4b4
+
+
+#define GRAPH_RADIUS 3
+
+
+static gint gap_accel_repaint (GtkWidget *, GdkEvent *,
+ GapAccelWidget *);
+
+/* ------------------------------
+ * gap_pview_new
+ * ------------------------------
+ * pv_check_size is checkboard size in pixels
+ * (for transparent pixels)
+ */
+GapAccelWidget *
+gap_accel_new(gint width, gint height, gint accelerationCharacteristic)
+{
+ GapAccelWidget *accel_ptr;
+
+
+ accel_ptr = g_malloc0(sizeof(GapAccelWidget));
+
+ accel_ptr->accelerationCharacteristic = accelerationCharacteristic;
+ accel_ptr->width = width;
+ accel_ptr->height = height;
+ accel_ptr->pixWidth = accel_ptr->width + GRAPH_RADIUS * 4;
+ accel_ptr->pixHeight = accel_ptr->height+ GRAPH_RADIUS * 4;
+
+
+ accel_ptr->da_widget = gtk_drawing_area_new ();
+ gtk_widget_set_size_request (accel_ptr->da_widget
+ , accel_ptr->pixWidth
+ , accel_ptr->pixHeight
+ );
+
+ gtk_widget_set_events (accel_ptr->da_widget, GDK_EXPOSURE_MASK);
+
+/*
+ gtk_container_add (GTK_CONTAINER (abox), accel_ptr->da_widget);
+ gtk_widget_show (accel_ptr->da_widget);
+*/
+
+ g_signal_connect (accel_ptr->da_widget, "event",
+ G_CALLBACK (gap_accel_repaint),
+ accel_ptr);
+
+
+
+
+ return(accel_ptr);
+} /* end gap_pview_new */
+
+
+
+/* ------------------------------
+ * gap_accel_render
+ * ------------------------------
+ */
+void
+gap_accel_render (GapAccelWidget *accel_ptr, gint accelerationCharacteristic)
+{
+ accel_ptr->accelerationCharacteristic = accelerationCharacteristic;
+ gap_accel_repaint(NULL, NULL, accel_ptr);
+}
+
+/* ------------------------------
+ * gap_accel_repaint
+ * ------------------------------
+ */
+static gint
+gap_accel_repaint(GtkWidget *wgt, GdkEvent *evt,
+ GapAccelWidget *accel_ptr)
+{
+ GtkStyle *graph_style;
+ gint i;
+
+ if(accel_ptr->da_widget == NULL)
+ {
+ if(gap_debug)
+ {
+ printf("gap_accel_repaint: drawing area graph is NULL (render request ignored\n");
+ }
+ return (FALSE);
+ }
+ if(accel_ptr->da_widget->window == NULL)
+ {
+ if(gap_debug)
+ {
+ printf("gap_accel_repaint: window pointer is NULL (render request ignored\n");
+ }
+ return (FALSE);
+ }
+
+
+ graph_style = gtk_widget_get_style (accel_ptr->da_widget);
+
+
+ /* Clear the pixmap */
+ gdk_draw_rectangle (accel_ptr->da_widget->window, graph_style->bg_gc[GTK_STATE_NORMAL],
+ TRUE, 0, 0, accel_ptr->pixWidth, accel_ptr->pixHeight);
+
+
+ /* Draw the grid lines (or just outline if acceleration is not active */
+ for (i = 0; i < 5; i++)
+ {
+ if ((i == 0) || (i==4) || (accel_ptr->accelerationCharacteristic != 0))
+ {
+ gdouble xf;
+ gdouble yf;
+ gint xi;
+ gint yi;
+
+ xf = (gdouble)i * ((gdouble)accel_ptr->width / 4.0);
+ yf = (gdouble)i * ((gdouble)accel_ptr->height / 4.0);
+ xi = xf;
+ yi = yf;
+
+ gdk_draw_line (accel_ptr->da_widget->window, graph_style->dark_gc[GTK_STATE_NORMAL],
+ GRAPH_RADIUS, yi + GRAPH_RADIUS,
+ accel_ptr->width + GRAPH_RADIUS, yi + GRAPH_RADIUS);
+ gdk_draw_line (accel_ptr->da_widget->window, graph_style->dark_gc[GTK_STATE_NORMAL],
+ xi + GRAPH_RADIUS, GRAPH_RADIUS,
+ xi + GRAPH_RADIUS, accel_ptr->height + GRAPH_RADIUS);
+
+ }
+ }
+
+
+ /* Draw the the acceleration curve according to accelerationCharacteristic
+ * when acceleration is active
+ */
+ if(accel_ptr->accelerationCharacteristic != 0)
+ {
+ gdouble xFactor;
+ gdouble yFactor;
+ gdouble yF;
+
+ /* Draw the active curve */
+ for (i = 0; i < accel_ptr->width; i++)
+ {
+ gint cx, cy, px, py;
+
+ xFactor = (gdouble)i / (MAX(1.0, (gdouble)accel_ptr->width));
+ yFactor = gap_accelMixFactor(xFactor, accel_ptr->accelerationCharacteristic);
+ yF = (gdouble)accel_ptr->height * yFactor;
+
+
+ cx = i + GRAPH_RADIUS;
+ cy = (accel_ptr->height) - yF + GRAPH_RADIUS;
+
+ if(gap_debug)
+ {
+ printf("point[%03d] x:%04d y:%04d xf:%f yf:%f\n"
+ ,(int)i
+ ,(int)cx
+ ,(int)cy
+ ,(float)xFactor
+ ,(float)yFactor
+ );
+ }
+ if(i>0)
+ {
+ gdk_draw_line (accel_ptr->da_widget->window, graph_style->black_gc,
+ px, py,
+ cx, cy
+ );
+ }
+ px = cx;
+ py = cy;
+ }
+ }
+
+ return FALSE;
+
+} /* end gap_accel_repaint */
diff --git a/gap/gap_accel_da.h b/gap/gap_accel_da.h
new file mode 100644
index 0000000..546da08
--- /dev/null
+++ b/gap/gap_accel_da.h
@@ -0,0 +1,50 @@
+/* gap_accel_da.h
+ *
+ * This module handles GAP acceleration characteristics drawing area.
+ */
+/* The GIMP -- an image manipulation program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/* revision history:
+ * version 2.7.0; 2010/02/06 hof: created
+ */
+
+#ifndef _GAP_ACCEL_DA_H
+#define _GAP_ACCEL_DA_H
+
+#include <gtk/gtk.h>
+#include <libgimp/gimp.h>
+#include <libgimp/gimpui.h>
+
+
+typedef struct GapAccelWidget
+{
+ GtkWidget *da_widget; /* the graph drawing_area */
+ gint accelerationCharacteristic;
+ gint width;
+ gint height;
+ gint pixWidth;
+ gint pixHeight;
+
+} GapAccelWidget;
+
+GapAccelWidget *gap_accel_new(gint width, gint height, gint accelerationCharacteristic);
+
+void gap_accel_render (GapAccelWidget *accel_ptr, gint accelerationCharacteristic);
+
+#endif
diff --git a/gap/gap_mov_dialog.c b/gap/gap_mov_dialog.c
index 5d2dbb9..675ba49 100755
--- a/gap/gap_mov_dialog.c
+++ b/gap/gap_mov_dialog.c
@@ -125,6 +125,7 @@
#include "gap_arr_dialog.h"
#include "gap_pview_da.h"
+#include "gap_accel_da.h"
#include "gap_stock.h"
@@ -220,6 +221,14 @@ typedef struct
GtkAdjustment *trace_opacity_initial_adj;
GtkAdjustment *trace_opacity_desc_adj;
GtkAdjustment *tween_steps_adj;
+
+ GtkAdjustment *accPosition_adj;
+ GtkAdjustment *accOpacity_adj;
+ GtkAdjustment *accSize_adj;
+ GtkAdjustment *accRotation_adj;
+ GtkAdjustment *accPerspective_adj;
+ GtkAdjustment *accSelFeatherRadius_adj;
+
gchar point_index_text[POINT_INDEX_LABEL_LENGTH];
GtkWidget *point_index_frame;
@@ -238,6 +247,14 @@ typedef struct
gdouble tbry; /* 0.0 upto 10.0 transform y bot right */
gdouble sel_feather_radius;
+ /* acceleration characteristics */
+ gint accPosition;
+ gint accOpacity;
+ gint accSize;
+ gint accRotation;
+ gint accPerspective;
+ gint accSelFeatherRadius;
+
gint keyframe_abs;
gint max_frame;
@@ -266,6 +283,8 @@ typedef struct
long gap_mov_dlg_move_dialog (GapMovData *mov_ptr);
static void p_update_point_index_text (t_mov_gui_stuff *mgp);
+static void p_set_sensitivity_by_adjustment(GtkAdjustment *adj, gboolean sensitive);
+static void p_accel_widget_sensitivity(t_mov_gui_stuff *mgp);
static void p_points_from_tab (t_mov_gui_stuff *mgp);
static void p_points_to_tab (t_mov_gui_stuff *mgp);
static void p_point_refresh (t_mov_gui_stuff *mgp);
@@ -283,6 +302,7 @@ static gint mov_dialog ( GimpDrawable *drawable, t_mov_gui_stuff *mgp,
gint min, gint max);
static GtkWidget * mov_modify_tab_create (t_mov_gui_stuff *mgp);
static GtkWidget * mov_trans_tab_create (t_mov_gui_stuff *mgp);
+static GtkWidget * mov_acc_tab_create (t_mov_gui_stuff *mgp);
static GtkWidget * mov_selection_handling_tab_create (t_mov_gui_stuff *mgp);
static void mov_path_prevw_create ( GimpDrawable *drawable,
@@ -302,9 +322,11 @@ static void mov_instant_double_adjustment_update (GtkObject *obj, gpointe
static void mov_path_colorbutton_update ( GimpColorButton *widget, t_mov_gui_stuff *mgp);
static void mov_path_keycolorbutton_clicked ( GimpColorButton *widget, t_mov_gui_stuff *mgp);
static void mov_path_keycolorbutton_changed ( GimpColorButton *widget, t_mov_gui_stuff *mgp);
+static void mov_path_keyframe_update ( GtkWidget *widget, t_mov_gui_stuff *mgp );
static void mov_path_x_adjustment_update ( GtkWidget *widget, gpointer data );
static void mov_path_y_adjustment_update ( GtkWidget *widget, gpointer data );
static void mov_path_tfactor_adjustment_update( GtkWidget *widget, gdouble *val);
+static void mov_path_acceleration_adjustment_update( GtkWidget *widget, gint *val);
static void mov_path_feather_adjustment_update( GtkWidget *widget, gdouble *val );
static void mov_selmode_menu_callback (GtkWidget *widget, t_mov_gui_stuff *mgp);
@@ -395,6 +417,25 @@ p_mov_spinbutton_new(GtkTable *table
,gchar *tooltip_text
,gchar *privatetip
);
+GtkObject *
+p_mov_acc_spinbutton_new(GtkTable *table
+ ,gint col
+ ,gint row
+ ,gchar *label_text
+ ,gint scale_width /* dummy, not used */
+ ,gint spinbutton_width
+ ,gdouble initial_val
+ ,gdouble lower /* dummy, not used */
+ ,gdouble upper /* dummy, not used */
+ ,gdouble sstep
+ ,gdouble pagestep
+ ,gint digits
+ ,gboolean constrain
+ ,gdouble umin
+ ,gdouble umax
+ ,gchar *tooltip_text
+ ,gchar *privatetip
+ );
static void mov_fit_initial_shell_window(t_mov_gui_stuff *mgp);
static void mov_shell_window_size_allocate (GtkWidget *widget,
GtkAllocation *allocation,
@@ -1172,6 +1213,13 @@ p_copy_point(gint to_idx, gint from_idx)
pvals->point[to_idx].tbry = pvals->point[from_idx].tbry;
pvals->point[to_idx].sel_feather_radius = pvals->point[from_idx].sel_feather_radius;
+ pvals->point[to_idx].accPosition = pvals->point[from_idx].accPosition;
+ pvals->point[to_idx].accOpacity = pvals->point[from_idx].accOpacity;
+ pvals->point[to_idx].accSize = pvals->point[from_idx].accSize;
+ pvals->point[to_idx].accRotation = pvals->point[from_idx].accRotation;
+ pvals->point[to_idx].accPerspective = pvals->point[from_idx].accPerspective;
+ pvals->point[to_idx].accSelFeatherRadius = pvals->point[from_idx].accSelFeatherRadius;
+
/* do not copy keyframe */
pvals->point[to_idx].keyframe_abs = 0;
pvals->point[to_idx].keyframe = 0;
@@ -2026,6 +2074,20 @@ p_point_refresh(t_mov_gui_stuff *mgp)
gtk_adjustment_set_value (mgp->sel_feather_radius_adj,
(gdouble)mgp->sel_feather_radius);
+
+ gtk_adjustment_set_value (mgp->accPosition_adj,
+ (gdouble)mgp->accPosition);
+ gtk_adjustment_set_value (mgp->accOpacity_adj,
+ (gdouble)mgp->accOpacity);
+ gtk_adjustment_set_value (mgp->accSize_adj,
+ (gdouble)mgp->accSize);
+ gtk_adjustment_set_value (mgp->accRotation_adj,
+ (gdouble)mgp->accRotation);
+ gtk_adjustment_set_value (mgp->accPerspective_adj,
+ (gdouble)mgp->accPerspective);
+ gtk_adjustment_set_value (mgp->accSelFeatherRadius_adj,
+ (gdouble)mgp->accSelFeatherRadius);
+
mgp->in_call = FALSE;
} /* end p_point_refresh */
@@ -2459,6 +2521,72 @@ mov_instant_apply_callback(GtkWidget *widget, t_mov_gui_stuff *mgp)
} /* end mov_instant_apply_callback */
+
+/* ------------------------------------------
+ * p_set_sensitivity_by_adjustment
+ * ------------------------------------------
+ * get the optional attached spinbutton and scale
+ * and set the specified sensitivity when attached widget is present.
+ */
+static void
+p_set_sensitivity_by_adjustment(GtkAdjustment *adj, gboolean sensitive)
+{
+ if(adj != NULL)
+ {
+ GtkWidget *spinbutton;
+ GtkWidget *scale;
+
+ spinbutton = GTK_WIDGET(g_object_get_data (G_OBJECT (adj), "spinbutton"));
+ if(spinbutton)
+ {
+ gtk_widget_set_sensitive(spinbutton, sensitive);
+ }
+ scale = GTK_WIDGET(g_object_get_data (G_OBJECT (adj), "scale"));
+ if(scale)
+ {
+ gtk_widget_set_sensitive(scale, sensitive);
+ }
+ }
+} /* end p_set_sensitivity_by_adjustment */
+
+
+/* ----------------------------------
+ * p_accel_widget_sensitivity
+ * ----------------------------------
+ * set sensitivity for all acceleration characteristic widgets
+ * Those widgets are sensitive for the first conrolpoint
+ * and for keframes that are NOT the last controlpoint.
+ */
+static void
+p_accel_widget_sensitivity(t_mov_gui_stuff *mgp)
+{
+ gboolean sensitive;
+
+ sensitive = FALSE;
+ if(pvals->point_idx == 0)
+ {
+ sensitive = TRUE;
+ }
+ else
+ {
+ if ((pvals->point_idx != pvals->point_idx_max)
+ && ((pvals->point[pvals->point_idx].keyframe > 0) || (mgp->keyframe_abs > 0)))
+ {
+ sensitive = TRUE;
+ }
+ }
+
+ p_set_sensitivity_by_adjustment(mgp->accPosition_adj, sensitive);
+ p_set_sensitivity_by_adjustment(mgp->accOpacity_adj, sensitive);
+ p_set_sensitivity_by_adjustment(mgp->accSize_adj, sensitive);
+ p_set_sensitivity_by_adjustment(mgp->accRotation_adj, sensitive);
+ p_set_sensitivity_by_adjustment(mgp->accPerspective_adj, sensitive);
+ p_set_sensitivity_by_adjustment(mgp->accSelFeatherRadius_adj, sensitive);
+
+
+} /* end p_accel_widget_sensitivity */
+
+
/* ============================================================================
* procedures to handle POINTS - TABLE
* ============================================================================
@@ -2468,9 +2596,6 @@ mov_instant_apply_callback(GtkWidget *widget, t_mov_gui_stuff *mgp)
static void
p_points_from_tab(t_mov_gui_stuff *mgp)
{
- GtkWidget *scale;
- GtkWidget *spinbutton;
-
mgp->p_x = pvals->point[pvals->point_idx].p_x;
mgp->p_y = pvals->point[pvals->point_idx].p_y;
mgp->opacity = pvals->point[pvals->point_idx].opacity;
@@ -2488,36 +2613,27 @@ p_points_from_tab(t_mov_gui_stuff *mgp)
mgp->sel_feather_radius = pvals->point[pvals->point_idx].sel_feather_radius;
mgp->keyframe_abs = pvals->point[pvals->point_idx].keyframe_abs;
+ mgp->accPosition = pvals->point[pvals->point_idx].accPosition;
+ mgp->accOpacity = pvals->point[pvals->point_idx].accOpacity;
+ mgp->accSize = pvals->point[pvals->point_idx].accSize;
+ mgp->accRotation = pvals->point[pvals->point_idx].accRotation;
+ mgp->accPerspective = pvals->point[pvals->point_idx].accPerspective;
+ mgp->accSelFeatherRadius = pvals->point[pvals->point_idx].accSelFeatherRadius;
+
+
if(( mgp->keyframe_adj != NULL) && (mgp->startup != TRUE))
{
- /* findout the gtk_widgets (scale and spinbutton) connected
- * to mgp->keyframe_adj
- * and set_sensitive to TRUE or FALSE
- */
- scale = GTK_WIDGET(g_object_get_data (G_OBJECT (mgp->keyframe_adj), "scale"));
- spinbutton = GTK_WIDGET(g_object_get_data (G_OBJECT (mgp->keyframe_adj), "spinbutton"));
-
- if(spinbutton == NULL)
- {
- return;
- }
- if(gap_debug)
- {
- printf("p_points_from_tab: scale %x spinbutton %x\n",
- (int)scale, (int)spinbutton);
- }
+ gboolean sensitive;
+
+ sensitive = TRUE;
if((pvals->point_idx == 0) || (pvals->point_idx == pvals->point_idx_max))
{
- gtk_widget_set_sensitive(spinbutton, FALSE);
- if(scale)
- gtk_widget_set_sensitive(scale, FALSE);
- }
- else
- {
- gtk_widget_set_sensitive(spinbutton, TRUE);
- if(scale)
- gtk_widget_set_sensitive(scale, TRUE);
+ sensitive = FALSE;
}
+ p_set_sensitivity_by_adjustment(mgp->keyframe_adj, sensitive);
+
+ p_accel_widget_sensitivity(mgp);
+
}
}
@@ -2542,6 +2658,14 @@ p_points_to_tab(t_mov_gui_stuff *mgp)
pvals->point[pvals->point_idx].tbry = mgp->tbry;
pvals->point[pvals->point_idx].sel_feather_radius = mgp->sel_feather_radius;
pvals->point[pvals->point_idx].keyframe_abs = mgp->keyframe_abs;
+
+ pvals->point[pvals->point_idx].accPosition = mgp->accPosition;
+ pvals->point[pvals->point_idx].accOpacity = mgp->accOpacity;
+ pvals->point[pvals->point_idx].accSize = mgp->accSize;
+ pvals->point[pvals->point_idx].accRotation = mgp->accRotation;
+ pvals->point[pvals->point_idx].accPerspective = mgp->accPerspective;
+ pvals->point[pvals->point_idx].accSelFeatherRadius = mgp->accSelFeatherRadius;
+
if((mgp->keyframe_abs > 0)
&& (pvals->point_idx != 0)
&& (pvals->point_idx != pvals->point_idx_max))
@@ -2571,7 +2695,7 @@ p_update_point_index_text(t_mov_gui_stuff *mgp)
/* ============================================================================
* p_clear_one_point
- * Init point table with identical 2 Points
+ * clear one controlpoint to default values.
* ============================================================================
*/
void
@@ -2595,6 +2719,14 @@ p_clear_one_point(gint idx)
pvals->point[idx].sel_feather_radius = 0.0;
pvals->point[idx].keyframe = 0; /* 0: controlpoint is not fixed to keyframe */
pvals->point[idx].keyframe_abs = 0; /* 0: controlpoint is not fixed to keyframe */
+
+ pvals->point[idx].accPosition = 0; /* 0: linear (e.g NO acceleration) is default */
+ pvals->point[idx].accOpacity = 0; /* 0: linear (e.g NO acceleration) is default */
+ pvals->point[idx].accSize = 0; /* 0: linear (e.g NO acceleration) is default */
+ pvals->point[idx].accRotation = 0; /* 0: linear (e.g NO acceleration) is default */
+ pvals->point[idx].accPerspective = 0; /* 0: linear (e.g NO acceleration) is default */
+ pvals->point[idx].accSelFeatherRadius = 0; /* 0: linear (e.g NO acceleration) is default */
+
}
} /* end p_clear_one_point */
@@ -2635,6 +2767,16 @@ p_mix_one_point(gint idx, gint ref1, gint ref2, gdouble mix_factor)
pvals->point[idx].sel_feather_radius = MIX_VALUE(mix_factor, pvals->point[ref1].sel_feather_radius, pvals->point[ref2].sel_feather_radius);
+
+ pvals->point[idx].accPosition = MIX_VALUE(mix_factor, pvals->point[ref1].accPosition, pvals->point[ref2].accPosition);
+ pvals->point[idx].accOpacity = MIX_VALUE(mix_factor, pvals->point[ref1].accOpacity, pvals->point[ref2].accOpacity);
+ pvals->point[idx].accSize = MIX_VALUE(mix_factor, pvals->point[ref1].accSize, pvals->point[ref2].accSize);
+ pvals->point[idx].accRotation = MIX_VALUE(mix_factor, pvals->point[ref1].accRotation, pvals->point[ref2].accRotation);
+ pvals->point[idx].accPerspective = MIX_VALUE(mix_factor, pvals->point[ref1].accPerspective, pvals->point[ref2].accPerspective);
+ pvals->point[idx].accSelFeatherRadius = MIX_VALUE(mix_factor, pvals->point[ref1].accSelFeatherRadius, pvals->point[ref2].accSelFeatherRadius);
+
+
+
pvals->point[idx].keyframe = 0; /* 0: controlpoint is not fixed to keyframe */
pvals->point[idx].keyframe_abs = 0; /* 0: controlpoint is not fixed to keyframe */
}
@@ -3874,6 +4016,159 @@ mov_trans_tab_create (t_mov_gui_stuff *mgp)
} /* end mov_trans_tab_create */
+
+/* -----------------------------------------
+ * mov_acc_tab_create
+ * ----------------------------------------
+ * Create VBox with the acceleration characteristics and return it.
+ * The VBox contains
+ * - Transform 8x spinbutton (0.01 upto 10.0) 4-point perspective transformation
+ */
+static GtkWidget *
+mov_acc_tab_create (t_mov_gui_stuff *mgp)
+{
+ GtkWidget *vbox;
+ GtkWidget *table;
+ GtkObject *adj;
+
+#define ACC_MIN -100
+#define ACC_MAX 100
+
+ /* the vbox */
+ vbox = gtk_vbox_new (FALSE, 3);
+ gtk_container_set_border_width (GTK_CONTAINER (vbox), 2);
+
+ /* the table (2 rows) */
+ table = gtk_table_new ( 2, 9, FALSE );
+ gtk_container_set_border_width (GTK_CONTAINER (table), 2 );
+ gtk_table_set_row_spacings (GTK_TABLE (table), 2);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 4);
+ gtk_box_pack_start (GTK_BOX (vbox), table, TRUE, TRUE, 0);
+
+
+ /* accelaration characteristic for Position (e.g. movement) */
+ adj = p_mov_acc_spinbutton_new( GTK_TABLE (table), 0, 0, /* table col, row */
+ _("Movement:"), /* label text */
+ SCALE_WIDTH, ENTRY_WIDTH, /* scalesize spinsize */
+ (gdouble)mgp->accPosition, /* initial value */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper */
+ 1, 10, /* step, page */
+ 0, /* digits */
+ FALSE, /* constrain */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper (unconstrained) */
+ _("acceleration characteristic for movement (1 for constant speed, positive: acceleration, negative: deceleration)"),
+ NULL); /* tooltip privatetip */
+ g_object_set_data(G_OBJECT(adj), "mgp", mgp);
+ g_signal_connect (G_OBJECT (adj), "value_changed",
+ G_CALLBACK (mov_path_acceleration_adjustment_update),
+ &mgp->accPosition);
+ mgp->accPosition_adj = GTK_ADJUSTMENT(adj);
+
+
+
+ /* accelaration characteristic */
+ adj = p_mov_acc_spinbutton_new( GTK_TABLE (table), 0, 1, /* table col, row */
+ _("Opacity:"), /* label text */
+ SCALE_WIDTH, ENTRY_WIDTH, /* scalesize spinsize */
+ (gdouble)mgp->accOpacity, /* initial value */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper */
+ 1, 10, /* step, page */
+ 0, /* digits */
+ FALSE, /* constrain */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper (unconstrained) */
+ _("acceleration characteristic for opacity (1 for constant speed, positive: acceleration, negative: deceleration)"),
+ NULL); /* tooltip privatetip */
+ g_object_set_data(G_OBJECT(adj), "mgp", mgp);
+ g_signal_connect (G_OBJECT (adj), "value_changed",
+ G_CALLBACK (mov_path_acceleration_adjustment_update),
+ &mgp->accOpacity);
+ mgp->accOpacity_adj = GTK_ADJUSTMENT(adj);
+
+
+
+
+ /* accelaration characteristic for Size (e.g. Zoom) */
+ adj = p_mov_acc_spinbutton_new( GTK_TABLE (table), 3, 0, /* table col, row */
+ _("Scale:"), /* label text */
+ SCALE_WIDTH, ENTRY_WIDTH, /* scalesize spinsize */
+ (gdouble)mgp->accSize, /* initial value */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper */
+ 1, 10, /* step, page */
+ 0, /* digits */
+ FALSE, /* constrain */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper (unconstrained) */
+ _("acceleration characteristic for zoom (1 for constant speed, positive: acceleration, negative: deceleration)"),
+ NULL); /* tooltip privatetip */
+ g_object_set_data(G_OBJECT(adj), "mgp", mgp);
+ g_signal_connect (G_OBJECT (adj), "value_changed",
+ G_CALLBACK (mov_path_acceleration_adjustment_update),
+ &mgp->accSize);
+ mgp->accSize_adj = GTK_ADJUSTMENT(adj);
+
+
+ /* accelaration characteristic for Rotation */
+ adj = p_mov_acc_spinbutton_new( GTK_TABLE (table), 3, 1, /* table col, row */
+ _("Rotation:"), /* label text */
+ SCALE_WIDTH, ENTRY_WIDTH, /* scalesize spinsize */
+ (gdouble)mgp->accRotation, /* initial value */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper */
+ 1, 10, /* step, page */
+ 0, /* digits */
+ FALSE, /* constrain */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper (unconstrained) */
+ _("acceleration characteristic for rotation (1 for constant speed, positive: acceleration, negative: deceleration)"),
+ NULL); /* tooltip privatetip */
+ g_object_set_data(G_OBJECT(adj), "mgp", mgp);
+ g_signal_connect (G_OBJECT (adj), "value_changed",
+ G_CALLBACK (mov_path_acceleration_adjustment_update),
+ &mgp->accRotation);
+ mgp->accRotation_adj = GTK_ADJUSTMENT(adj);
+
+ /* accelaration characteristic for Perspective */
+ adj = p_mov_acc_spinbutton_new( GTK_TABLE (table), 6, 0, /* table col, row */
+ _("Perspective:"), /* label text */
+ SCALE_WIDTH, ENTRY_WIDTH, /* scalesize spinsize */
+ (gdouble)mgp->accPerspective, /* initial value */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper */
+ 1, 10, /* step, page */
+ 0, /* digits */
+ FALSE, /* constrain */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper (unconstrained) */
+ _("acceleration characteristic for perspective (1 for constant speed, positive: acceleration, negative: deceleration)"),
+ NULL); /* tooltip privatetip */
+ g_object_set_data(G_OBJECT(adj), "mgp", mgp);
+ g_signal_connect (G_OBJECT (adj), "value_changed",
+ G_CALLBACK (mov_path_acceleration_adjustment_update),
+ &mgp->accPerspective);
+ mgp->accPerspective_adj = GTK_ADJUSTMENT(adj);
+
+
+ /* accelaration characteristic for feather radius */
+ adj = p_mov_acc_spinbutton_new( GTK_TABLE (table), 6, 1, /* table col, row */
+ _("FeatherRadius:"), /* label text */
+ SCALE_WIDTH, ENTRY_WIDTH, /* scalesize spinsize */
+ (gdouble)mgp->accSelFeatherRadius, /* initial value */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper */
+ 1, 10, /* step, page */
+ 0, /* digits */
+ FALSE, /* constrain */
+ (gdouble)ACC_MIN, (gdouble)ACC_MAX, /* lower, upper (unconstrained) */
+ _("acceleration characteristic for feather radius (1 for constant speed, positive: acceleration, negative: deceleration)"),
+ NULL); /* tooltip privatetip */
+ g_object_set_data(G_OBJECT(adj), "mgp", mgp);
+ g_signal_connect (G_OBJECT (adj), "value_changed",
+ G_CALLBACK (mov_path_acceleration_adjustment_update),
+ &mgp->accSelFeatherRadius);
+ mgp->accSelFeatherRadius_adj = GTK_ADJUSTMENT(adj);
+
+
+ gtk_widget_show(table);
+ gtk_widget_show(vbox);
+
+ return vbox;
+} /* end mov_acc_tab_create */
+
+
/* ============================================================================
* Create VBox with the selection handling widgets and return it.
* ============================================================================
@@ -3913,7 +4208,7 @@ mov_selection_handling_tab_create (t_mov_gui_stuff *mgp)
, NULL);
gtk_widget_show(combo);
- /* ttlx transformfactor */
+ /* Feather Radius */
adj = gimp_scale_entry_new( GTK_TABLE (table), 0, 1, /* table col, row */
_("Selection Feather Radius:"), /* label text */
SCALE_WIDTH, ENTRY_WIDTH, /* scalesize spinsize */
@@ -4064,8 +4359,8 @@ mov_path_prevw_create ( GimpDrawable *drawable, t_mov_gui_stuff *mgp, gboolean v
_("Fix controlpoint to keyframe number where 0 == no keyframe"),
NULL); /* tooltip privatetip */
g_signal_connect (G_OBJECT (adj), "value_changed",
- G_CALLBACK (gimp_int_adjustment_update),
- &mgp->keyframe_abs);
+ G_CALLBACK (mov_path_keyframe_update),
+ mgp);
mgp->keyframe_adj = GTK_ADJUSTMENT(adj);
@@ -4075,6 +4370,7 @@ mov_path_prevw_create ( GimpDrawable *drawable, t_mov_gui_stuff *mgp, gboolean v
{
GtkWidget *modify_table;
GtkWidget *transform_table;
+ GtkWidget *acceleration_table;
GtkWidget *selhandling_table;
/* set of modifier widgets for the current controlpoint */
@@ -4082,6 +4378,9 @@ mov_path_prevw_create ( GimpDrawable *drawable, t_mov_gui_stuff *mgp, gboolean v
/* set of perspective transformation widgets for the current controlpoint */
transform_table = mov_trans_tab_create(mgp);
+
+ /* set of acceleration characteristic widgets for the current controlpoint */
+ acceleration_table = mov_acc_tab_create(mgp);
/* set of perspective transformation widgets for the current controlpoint */
selhandling_table = mov_selection_handling_tab_create(mgp);
@@ -4098,13 +4397,19 @@ mov_path_prevw_create ( GimpDrawable *drawable, t_mov_gui_stuff *mgp, gboolean v
, gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 1)
, label
);
-
gtk_container_add (GTK_CONTAINER (notebook), selhandling_table);
label = gtk_label_new(_("Selection Handling"));
gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook)
, gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 2)
, label
);
+ gtk_container_add (GTK_CONTAINER (notebook), acceleration_table);
+ label = gtk_label_new(_("Acceleration"));
+ gtk_notebook_set_tab_label (GTK_NOTEBOOK (notebook)
+ , gtk_notebook_get_nth_page (GTK_NOTEBOOK (notebook), 3)
+ , label
+ );
+
}
gtk_table_attach(GTK_TABLE(table), notebook, 3, 4 /* column */
, 0, 3 /* all rows */
@@ -4684,6 +4989,15 @@ mov_path_keycolorbutton_changed( GimpColorButton *widget,
}
} /* end mov_path_keycolorbutton_changed */
+
+static void
+mov_path_keyframe_update ( GtkWidget *widget, t_mov_gui_stuff *mgp)
+{
+ gimp_int_adjustment_update(GTK_ADJUSTMENT(widget), &mgp->keyframe_abs);
+ p_accel_widget_sensitivity(mgp);
+}
+
+
/*
* mov_path_xy_adjustment_update
*/
@@ -4734,6 +5048,11 @@ mov_path_y_adjustment_update( GtkWidget *widget,
}
}
+/* -----------------------------------------
+ * mov_path_tfactor_adjustment_update
+ * ----------------------------------------
+ * update value for one of the perspective transformation factors
+ */
static void
mov_path_tfactor_adjustment_update( GtkWidget *widget,
gdouble *val )
@@ -4758,6 +5077,43 @@ mov_path_tfactor_adjustment_update( GtkWidget *widget,
}
} /* end mov_path_tfactor_adjustment_update */
+/* -----------------------------------------
+ * mov_path_acceleration_adjustment_update
+ * ----------------------------------------
+ * update value for one of the acceleration characteristic values
+ */
+static void
+mov_path_acceleration_adjustment_update(GtkWidget *widget,
+ gint *val )
+{
+ gint old_val;
+ t_mov_gui_stuff *mgp;
+ GapAccelWidget *accel_ptr;
+
+ mgp = g_object_get_data( G_OBJECT(widget), "mgp" );
+
+ if(mgp == NULL) return;
+ old_val = *val;
+ gimp_int_adjustment_update(GTK_ADJUSTMENT(widget), (gpointer)val);
+
+ accel_ptr = g_object_get_data ( G_OBJECT(widget), "accel_ptr" );
+
+ if(accel_ptr == NULL)
+ {
+ if(gap_debug)
+ {
+ printf("accel_ptr is NULL\n");
+ }
+ }
+
+ gap_accel_render (accel_ptr, *val);
+
+ return;
+
+} /* end mov_path_acceleration_adjustment_update */
+
+
+
static void
mov_path_feather_adjustment_update( GtkWidget *widget,
gdouble *val )
@@ -5097,6 +5453,14 @@ p_get_prevw_drawable (t_mov_gui_stuff *mgp)
l_curr.currTBRY = (gdouble)mgp->tbry;
l_curr.currSelFeatherRadius = (gdouble)mgp->sel_feather_radius;
+ l_curr.accPosition = (gdouble)mgp->accPosition;
+ l_curr.accOpacity = (gdouble)mgp->accOpacity;
+ l_curr.accSize = (gdouble)mgp->accSize;
+ l_curr.accRotation = (gdouble)mgp->accRotation;
+ l_curr.accPerspective = (gdouble)mgp->accPerspective;
+ l_curr.accSelFeatherRadius = (gdouble)mgp->accSelFeatherRadius;
+
+
l_curr.src_layer_idx = 0;
l_curr.src_layers = gimp_image_get_layers (pvals->src_image_id, &l_nlayers);
@@ -5260,6 +5624,73 @@ p_mov_spinbutton_new(GtkTable *table
return(adj);
} /* end p_mov_spinbutton_new */
+/* ----------------------------------
+ * p_mov_acc_spinbutton_new
+ * ----------------------------------
+ * create label and spinbutton and add to table
+ * return the adjustment of the spinbutton
+ * (for compatible parameters to gimp_scale_entry_new
+ * there are some unused dummy parameters)
+ */
+GtkObject *
+p_mov_acc_spinbutton_new(GtkTable *table
+ ,gint col
+ ,gint row
+ ,gchar *label_text
+ ,gint scale_width /* dummy, not used */
+ ,gint spinbutton_width
+ ,gdouble initial_val
+ ,gdouble lower /* dummy, not used */
+ ,gdouble upper /* dummy, not used */
+ ,gdouble sstep
+ ,gdouble pagestep
+ ,gint digits
+ ,gboolean constrain
+ ,gdouble umin
+ ,gdouble umax
+ ,gchar *tooltip_text
+ ,gchar *privatetip
+ )
+{
+ GtkObject *adj;
+ GapAccelWidget *accel_ptr;
+ gint accelerationCharacteristic;
+
+#define ACC_WGT_WIDTH 28
+#define ACC_WGT_HEIGHT 26
+
+ adj = p_mov_spinbutton_new(table
+ ,col
+ ,row
+ ,label_text
+ ,scale_width
+ ,spinbutton_width
+ ,initial_val
+ ,lower
+ ,upper
+ ,sstep
+ ,pagestep
+ ,digits
+ ,constrain
+ ,umin
+ ,umax
+ ,tooltip_text
+ ,privatetip
+ );
+
+ accelerationCharacteristic = (int)initial_val;
+ accel_ptr = gap_accel_new(ACC_WGT_WIDTH, ACC_WGT_HEIGHT, accelerationCharacteristic);
+
+
+ gtk_table_attach( GTK_TABLE(table), accel_ptr->da_widget, col+2, col+3, row, row+1,
+ GTK_FILL, 0, 4, 0 );
+ gtk_widget_show (accel_ptr->da_widget);
+
+ g_object_set_data (G_OBJECT (adj), "accel_ptr", accel_ptr);
+
+ return(adj);
+} /* end p_mov_acc_spinbutton_new */
+
/* --------------------------
* mov_fit_initial_shell_window
diff --git a/gap/gap_mov_dialog.h b/gap/gap_mov_dialog.h
old mode 100644
new mode 100755
index ea2bb77..a37ec08
--- a/gap/gap_mov_dialog.h
+++ b/gap/gap_mov_dialog.h
@@ -111,6 +111,15 @@ typedef struct {
gdouble currTBRY; /* transform y bot right */
gdouble currSelFeatherRadius;
+
+ /* acceleration characteristics */
+ gint accPosition;
+ gint accOpacity;
+ gint accSize;
+ gint accRotation;
+ gint accPerspective;
+ gint accSelFeatherRadius;
+
} GapMovCurrent;
@@ -134,8 +143,17 @@ typedef struct {
gdouble tbrx; /* 0.0 upto 10.0 transform x bot right */
gdouble tbry; /* 0.0 upto 10.0 transform y bot right */
- /* 4-point transform distortion (perspective) */
+ /* feather radius for selection handling */
gdouble sel_feather_radius;
+
+ /* acceleration characteristics */
+ gint accPosition;
+ gint accOpacity;
+ gint accSize;
+ gint accRotation;
+ gint accPerspective;
+ gint accSelFeatherRadius;
+
} GapMovPoint;
#define GAP_MOV_MAX_POINT 1024
diff --git a/gap/gap_mov_exec.c b/gap/gap_mov_exec.c
old mode 100644
new mode 100755
index f561cac..22275f7
--- a/gap/gap_mov_exec.c
+++ b/gap/gap_mov_exec.c
@@ -73,6 +73,7 @@
#include "gap_mov_render.h"
#include "gap_pdb_calls.h"
#include "gap_arr_dialog.h"
+#include "gap_accel_char.h"
extern int gap_debug; /* ==0 ... dont print debug infos */
@@ -85,6 +86,41 @@ static gdouble p_calc_angle(gint p1x, gint p1y, gint p2x, gint p2y);
static gdouble p_rotatate_less_than_180(gdouble angle, gdouble angle_new, gint *turns);
+static gint p_calculate_relframe_nr_at_index(GapMovValues *val_ptr, gint index, gint frames);
+static gint p_findEndOfSegmentIndex(GapMovValues *val_ptr, gint startOfSegmentIndex, gint points);
+static gdouble p_calculate_LineLength(GapMovValues *val_ptr, gint idx);
+static gdouble p_calculate_path_segment_length(GapMovValues *val_ptr
+ , gint startOfSegmentIndex, gint endOfSegmentIndex);
+static gint p_pick_controlpoint_at_curr_length(GapMovValues *val_ptr
+ , gint startOfSegmentIndex, gint endOfSegmentIndex, gdouble pathSegmentLength
+ , gint accelerationCharacteristic, gdouble lengthFactorLinear
+ , gdouble *flt_posfactor
+ );
+static gdouble p_calculate_posFactor_from_FrameTweens(gdouble frameTweensInSegment
+ , gdouble currFrameTweenInSegment
+ , gint accelerationCharacteristic
+ );
+static gint p_calculate_settings_for_current_FrameTween(
+ GapMovValues *val_ptr
+ , GapMovCurrent *cur_ptr
+ , gdouble framesPerLine
+ , long currFrameIndex /* relative frame number where the first handled frame is 0
+ * Note that the first fame is already processed outside the loop
+ * therefore this procedure is typically called first time with
+ * currFrameIndex value 1.
+ */
+ , long currPtidx /* current controlpoint index for processing without acceleration characteristic */
+ , gdouble flt_posfactor /* current position factor within one line between controlpoints
+ * (relevant for processing without acceleration characteristic)
+ */
+ , gdouble affectedFrames /* number of affected frames (in the whole Move patch operation) */
+ , long availableCtrlPoints /* number of available controlpoints */
+ , gint startOfSegmentIndex
+ , gint endOfSegmentIndex
+ );
+
+
+
/* ============================================================================
* p_add_tween_and_trace
* ============================================================================
@@ -638,6 +674,486 @@ p_mov_advance_src_frame(GapMovCurrent *cur_ptr, GapMovValues *pvals)
} /* end p_advance_src_frame */
+
+
+
+
+/* -----------------------------------
+ * p_calculate_relframe_nr_at_index
+ * -----------------------------------
+ * IN points is the number of processing relevant controlpoints
+ * returns the index of the last controlpoint in the path segment that starts at specified index
+ * Note that path segment includes all controlpoints up to the next keyframe inclusive. If no keyframe
+ * present ther is only one big segment from first to last controlpoint.
+ */
+static gint
+p_calculate_relframe_nr_at_index(GapMovValues *val_ptr, gint index, gint frames)
+{
+ if (index <= 0)
+ {
+ return (1);
+ }
+
+ if(index < val_ptr->point_idx_max )
+ {
+ if (val_ptr->point[index].keyframe > 0)
+ {
+ return (1 + val_ptr->point[index].keyframe);
+ }
+ }
+
+ return (frames);
+
+} /* end p_calculate_relframe_nr_at_index */
+
+
+/* -----------------------------------
+ * p_findEndOfSegmentIndex
+ * -----------------------------------
+ * IN points is the number of processing relevant controlpoints
+ * returns the index of the last controlpoint in the segment that starts
+ * at specified startOfSegmentIndex.
+ * the segment ends at next KEYFRAME or at the last controlpoint (that is an implicite keyframe)
+ */
+static gint
+p_findEndOfSegmentIndex(GapMovValues *val_ptr, gint startOfSegmentIndex, gint points)
+{
+ gint ii;
+
+ for (ii= startOfSegmentIndex +1; ii < points; ii++)
+ {
+ if (val_ptr->point[ii].keyframe > 0)
+ {
+ /* checked controlpoint is a keyframe */
+ return (ii);
+ }
+ }
+
+ return (points -1);
+} /* end p_findEndOfSegmentIndex */
+
+
+/* -----------------------------------
+ * p_calculate_LineLength
+ * -----------------------------------
+ * returns the length (in pixels) between the controlpont at the specified index idx
+ * and the next controlpoint at idx +1
+ * returns 0 in case the specified index is out of valid range
+ */
+static gdouble
+p_calculate_LineLength(GapMovValues *val_ptr, gint idx)
+{
+ gdouble dx;
+ gdouble dy;
+ gdouble len;
+
+ if ((idx < 0) || (idx >= val_ptr->point_idx_max))
+ {
+ return (0.0);
+ }
+
+ dx = abs (val_ptr->point[idx].p_x - val_ptr->point[idx +1].p_x);
+ dy = abs (val_ptr->point[idx].p_y - val_ptr->point[idx +1].p_y);
+
+ len = sqrt((dx * dx) + (dy * dy));
+
+ return (len);
+
+} /* end p_calculate_LineLength */
+
+
+/* -----------------------------------
+ * p_calculate_path_segment_length
+ * -----------------------------------
+ *
+ */
+static gdouble
+p_calculate_path_segment_length(GapMovValues *val_ptr
+ , gint startOfSegmentIndex, gint endOfSegmentIndex)
+{
+ gint idx;
+ gdouble lenSum;
+
+ lenSum = 0;
+ for(idx=startOfSegmentIndex; idx < endOfSegmentIndex; idx++)
+ {
+ lenSum += p_calculate_LineLength(val_ptr, idx);
+ }
+ return (lenSum);
+} /* end p_calculate_path_segment_length */
+
+
+/* -----------------------------------
+ * p_pick_controlpoint_at_curr_length
+ * -----------------------------------
+ * returns the relevant controlpoint index
+ * at specified currentLen in pixels (eg. current position length within the specified
+ * path segment that starts at controlpoint startOfSegmentIndex)
+ *
+ * IN: startOfSegmentIndex
+ * IN: endOfSegmentIndex
+ * IN: pathSegmentLength length in pixels (0 at stastOfSegment, upto segment length)
+ * IN:
+ * OUT: flt_posfactor
+ */
+static gint
+p_pick_controlpoint_at_curr_length(GapMovValues *val_ptr
+ , gint startOfSegmentIndex, gint endOfSegmentIndex, gdouble pathSegmentLength
+ , gint accelerationCharacteristic, gdouble lengthFactorLinear
+ , gdouble *flt_posfactor
+ )
+{
+ gint idx;
+ gdouble lenSum;
+ gdouble lenSumPrev;
+ gdouble currentLen;
+ gdouble lengthFactorAcc; /* 0.0 at begin of segment 1.0 at end of segment position */
+
+ /* calculate length factor (0.0 to 1.0) respecting position specific acceleartion characteristic */
+ lengthFactorAcc = gap_accelMixFactor(lengthFactorLinear, accelerationCharacteristic);
+ currentLen = pathSegmentLength * lengthFactorAcc;
+
+
+
+
+ lenSum = 0;
+ lenSumPrev = 0;
+
+ for(idx = startOfSegmentIndex; idx <= endOfSegmentIndex; idx++)
+ {
+ gdouble lineLen;
+
+ lineLen = p_calculate_LineLength(val_ptr, idx);
+ lenSum += lineLen;
+
+ if(lenSum >= currentLen)
+ {
+ gdouble l_flt_posfactor;
+ l_flt_posfactor = (currentLen - lenSumPrev) / MAX(1.0, lineLen);
+
+ if(gap_debug)
+ {
+ printf(" p_pick_controlpoint_at_curr_length[%d] lenSum:%f currentLen:%f lengthFactorAcc:%f\n"
+ ,(int)idx
+ ,(float) lenSum
+ ,(float) currentLen
+ ,(float) lengthFactorAcc
+ );
+ }
+
+
+ *flt_posfactor = CLAMP (l_flt_posfactor, 0.0, 1.0);
+ return (idx);
+ }
+ lenSumPrev = lenSum;
+ }
+
+ *flt_posfactor = 0;
+ return (endOfSegmentIndex);
+
+} /* end p_pick_controlpoint_at_curr_length */
+
+/* --------------------------------------
+ * p_calculate_posFactor_from_FrameTweens
+ * --------------------------------------
+ * returns the relevant positionFactor for the
+ * specified currFrameTweenInSegment and frameTweensInSegment
+ * respecting the specified acceleration characteristic
+ *
+ */
+static gdouble
+p_calculate_posFactor_from_FrameTweens(gdouble frameTweensInSegment
+ , gdouble currFrameTweenInSegment
+ , gint accelerationCharacteristic
+ )
+{
+ gdouble factorLinear; /* 0.0 at begin of segment 1.0 at end of segment */
+ gdouble posFactorAcc; /* 0.0 at begin of segment 1.0 at end of segment */
+
+ factorLinear = currFrameTweenInSegment / (MAX (1.0, frameTweensInSegment));
+ factorLinear = CLAMP (factorLinear, 0.0, 1.0);
+
+ /* calculate length factor (0.0 to 1.0) respecting position specific acceleartion characteristic */
+ posFactorAcc = gap_accelMixFactor(factorLinear, accelerationCharacteristic);
+
+
+ return (posFactorAcc);
+
+} /* end p_calculate_posFactor_from_FrameTweens */
+
+
+/* -------------------------------------------
+ * p_calculate_settings_for_current_FrameTween
+ * -------------------------------------------
+ * calculate settings for the currently processed
+ * Frame (or tween) according to the controlpoints.
+ * supports older behavior of GIMP-GAP-2.6 and prior
+ * and the extended variant with accerlaration characteristics
+ * per path segment.
+ * mode without acceleration characteristic (GIMP-GAP-2.6 behvior)
+ * ========================================
+ * This mode is selected by acceleration characteristic value 0.
+ * In this mode the flt_posfactor specifies the position within one line
+ * between the controlpoints with index [l_ptidx -1] and [l_ptidx]
+ *
+ * Mode with acceleration characteristic:
+ * ========================================
+ * a Path segment includes all controlpoints between two keyframes
+ * (e.g controlpoints where keyframe > 0) Note that first and last contolpoint
+ * are implicite keyframes.
+ * In case none of the contolpoints has keyframe > 0, all controlpoints
+ * are in just one segment that starts at first and ends at last controlpoint.
+ *
+ * The current movement position depends on the length of the current
+ * path segment and on the specified acceleration characteristic for movement.
+ * acc characteristic 1 is constant speed mode, 2 or more is acceleration, -2 or less deceleration
+ * The line within the path segment is calculated by picking
+ * the relevant ctrlPtidx.
+ *
+ * in case acceleration characteristic values != 0 are used for any other settings than position,
+ * then all controlpoints that are NON keyframes are ignored for other settings than position (x,y).
+ * Those settings (opacity, size ...) are then calculated from the
+ * controlpoint at start and end of the path segment.
+ * (note that first and last controlpoint are
+ * implicite keyframes and therefore always relevant)
+ */
+static gint
+p_calculate_settings_for_current_FrameTween(
+ GapMovValues *val_ptr
+ , GapMovCurrent *cur_ptr
+ , gdouble framesPerLine
+ , long currFrameIndex /* relative frame number where the first handled frame is 0
+ * Note that the first fame is already processed outside the loop
+ * therefore this procedure is typically called first time with
+ * currFrameIndex value 1.
+ */
+ , long currPtidx /* current controlpoint index for processing without acceleration characteristic */
+ , gdouble flt_posfactor /* current position factor within one line between controlpoints
+ * (relevant for processing without acceleration characteristic)
+ */
+ , gdouble affectedFrames /* number of affected frames (in the whole Move patch operation) */
+ , long availableCtrlPoints /* number of available controlpoints */
+ , gint startOfSegmentIndex
+ , gint endOfSegmentIndex
+ )
+{
+/* MIX_VALUE 0.0 <= factor <= 1.0
+ * result is a for factor 0.0
+ * b for factor 1.0
+ * mix for factors inbetween
+ */
+#define MIX_VALUE(factor, a, b) ((a * (1.0 - factor)) + (b * factor))
+
+ gdouble tweenMultiplicator;
+ gint frameNrAtEndOfSegment;
+ gdouble lengthFactorLinear; /* 0.0 at begin of segment 1.0 at end of segment position */
+ gdouble frameTweensInSegment;
+ gdouble currFrameTweenInSegment; /* frame number relative to 0 at each starting point of a new segment
+ * tweens can have non integer frame number like 1.5 or 1.3333 or 1.25 etc....
+ */
+ gdouble pathSegmentLength;
+
+ gdouble posFactor;
+
+ posFactor = 0.0;
+
+ tweenMultiplicator = 1.0;
+ if(val_ptr->tween_steps > 1.0)
+ {
+ tweenMultiplicator = val_ptr->tween_steps +1;
+ }
+
+ frameNrAtEndOfSegment = p_calculate_relframe_nr_at_index(val_ptr, endOfSegmentIndex, affectedFrames);
+
+ frameTweensInSegment = abs ( frameNrAtEndOfSegment
+ - p_calculate_relframe_nr_at_index(val_ptr, startOfSegmentIndex, affectedFrames)
+ ) + 1;
+ frameTweensInSegment *= tweenMultiplicator;
+
+
+
+ currFrameTweenInSegment =
+ tweenMultiplicator * (abs (currFrameIndex - val_ptr->point[startOfSegmentIndex].keyframe)); /// TODO check for reverse order processing ???
+ currFrameTweenInSegment += (val_ptr->tween_steps - val_ptr->twix);
+
+ /* calculate length factor respecting position in the path segment where 0 is at begin 1 at end */
+ lengthFactorLinear = currFrameTweenInSegment / MAX(frameTweensInSegment, 1);
+
+ pathSegmentLength = p_calculate_path_segment_length(val_ptr, startOfSegmentIndex, endOfSegmentIndex);
+
+ /* calculate Movement settings for the currently processed Frame (or tween)
+ * position dependent acceleration processing requires a path segment length > 0
+ * AND accPosition != 0
+ */
+ if ((val_ptr->point[startOfSegmentIndex].accPosition != 0)
+ && (pathSegmentLength > 0))
+ {
+ /* acceleration characteristic processing */
+ gint segmPtidx; /* calculated controlpoint index of relevant line begin with current segment */
+
+ segmPtidx = p_pick_controlpoint_at_curr_length(val_ptr
+ , startOfSegmentIndex, endOfSegmentIndex, pathSegmentLength
+ , val_ptr->point[startOfSegmentIndex].accPosition
+ , lengthFactorLinear
+ , &posFactor
+ );
+
+ cur_ptr->currX = MIX_VALUE(posFactor, (gdouble)val_ptr->point[segmPtidx].p_x, (gdouble)val_ptr->point[segmPtidx +1].p_x);
+ cur_ptr->currY = MIX_VALUE(posFactor, (gdouble)val_ptr->point[segmPtidx].p_y, (gdouble)val_ptr->point[segmPtidx +1].p_y);
+
+
+ if(gap_debug)
+ {
+ printf("p_mov_execute: currFrameIndex:%d Position, start/endOfSegmentIndex=%d/%d currFrameTweenInSegment=%d frameTweensInSegment=%d\n"
+ , (int)currFrameIndex
+ , (int)startOfSegmentIndex
+ , (int)endOfSegmentIndex
+ , (int)currFrameTweenInSegment
+ , (int)frameTweensInSegment
+ );
+ printf("p_mov_execute: Position, frameNrAtEndOfSegment=%d\n", (int)frameNrAtEndOfSegment);
+ printf("p_mov_execute: Position, lengthFactorLinear=%f\n", (float)lengthFactorLinear);
+ printf("p_mov_execute: Position, pathSegmentLength=%f\n", (float)pathSegmentLength);
+ printf("p_mov_execute: Position, posFactor=%f segmPtidx=%d\n"
+ , (float)posFactor
+ , (int)segmPtidx
+ );
+ }
+ }
+ else
+ {
+ /* No acceleration characteristic specified for movement (compatible to GAP 2.6.x release behavior) */
+ if(gap_debug)
+ {
+ printf("p_mov_execute: framesPerLine=%f, flt_posfactor=%f\n"
+ , (float)framesPerLine
+ , (float)flt_posfactor
+ );
+ }
+
+
+ cur_ptr->currX = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].p_x, (gdouble)val_ptr->point[currPtidx].p_x);
+ cur_ptr->currY = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].p_y, (gdouble)val_ptr->point[currPtidx].p_y);
+ }
+
+
+ /* calculate Opacity settings for the currently processed Frame (or tween) */
+ if ((val_ptr->point[startOfSegmentIndex].accOpacity != 0)
+ && (frameTweensInSegment > 0))
+ {
+ /* acceleration characteristic processing for opacity */
+ posFactor = p_calculate_posFactor_from_FrameTweens(frameTweensInSegment
+ , currFrameTweenInSegment
+ , val_ptr->point[startOfSegmentIndex].accOpacity
+ );
+ cur_ptr->currOpacity = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].opacity, (gdouble)val_ptr->point[endOfSegmentIndex].opacity);
+ }
+ else
+ {
+ /* No acceleration characteristic specified for opacity (compatible to GAP 2.6.x release behavior) */
+ cur_ptr->currOpacity = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].opacity, (gdouble)val_ptr->point[currPtidx].opacity);
+ }
+
+
+ /* calculate Zoom (e.g. Size) settings for the currently processed Frame (or tween) */
+ if ((val_ptr->point[startOfSegmentIndex].accSize != 0)
+ && (frameTweensInSegment > 0))
+ {
+ /* acceleration characteristic processing for opacity */
+ posFactor = p_calculate_posFactor_from_FrameTweens(frameTweensInSegment
+ , currFrameTweenInSegment
+ , val_ptr->point[startOfSegmentIndex].accSize
+ );
+ cur_ptr->currWidth = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].w_resize, (gdouble)val_ptr->point[endOfSegmentIndex].w_resize);
+ cur_ptr->currHeight = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].h_resize, (gdouble)val_ptr->point[endOfSegmentIndex].h_resize);
+ }
+ else
+ {
+ cur_ptr->currWidth = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].w_resize, (gdouble)val_ptr->point[currPtidx].w_resize);
+ cur_ptr->currHeight = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].h_resize, (gdouble)val_ptr->point[currPtidx].h_resize);
+ }
+
+
+ /* calculate Rotation settings for the currently processed Frame (or tween) */
+ if ((val_ptr->point[startOfSegmentIndex].accRotation != 0)
+ && (frameTweensInSegment > 0))
+ {
+ /* acceleration characteristic processing for rotation */
+ posFactor = p_calculate_posFactor_from_FrameTweens(frameTweensInSegment
+ , currFrameTweenInSegment
+ , val_ptr->point[startOfSegmentIndex].accRotation
+ );
+ cur_ptr->currRotation = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].rotation, (gdouble)val_ptr->point[endOfSegmentIndex].rotation);
+ }
+ else
+ {
+ cur_ptr->currRotation = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].rotation, (gdouble)val_ptr->point[currPtidx].rotation);
+
+ if(gap_debug)
+ {
+ printf("p_mov_execute: framesPerLine=%f, flt_posfactor=%f\n"
+ , (float)framesPerLine
+ , (float)flt_posfactor
+ );
+ printf("ROTATE [%02d] %f [%02d] %f MIX: %f\n"
+ , (int)currPtidx-1, (float)val_ptr->point[currPtidx -1].rotation
+ , (int)currPtidx, (float)val_ptr->point[currPtidx].rotation
+ , (float)cur_ptr->currRotation);
+ }
+
+ }
+
+ /* calculate Perspective settings for the currently processed Frame (or tween) */
+ if ((val_ptr->point[startOfSegmentIndex].accPerspective != 0)
+ && (frameTweensInSegment > 0))
+ {
+ /* acceleration characteristic processing for rotation */
+ posFactor = p_calculate_posFactor_from_FrameTweens(frameTweensInSegment
+ , currFrameTweenInSegment
+ , val_ptr->point[startOfSegmentIndex].accPerspective
+ );
+ cur_ptr->currTTLX = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttlx, (gdouble)val_ptr->point[endOfSegmentIndex].ttlx);
+ cur_ptr->currTTLY = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttly, (gdouble)val_ptr->point[endOfSegmentIndex].ttly);
+ cur_ptr->currTTRX = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttrx, (gdouble)val_ptr->point[endOfSegmentIndex].ttrx);
+ cur_ptr->currTTRY = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].ttry, (gdouble)val_ptr->point[endOfSegmentIndex].ttry);
+ cur_ptr->currTBLX = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tblx, (gdouble)val_ptr->point[endOfSegmentIndex].tblx);
+ cur_ptr->currTBLY = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tbly, (gdouble)val_ptr->point[endOfSegmentIndex].tbly);
+ cur_ptr->currTBRX = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tbrx, (gdouble)val_ptr->point[endOfSegmentIndex].tbrx);
+ cur_ptr->currTBRY = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].tbry, (gdouble)val_ptr->point[endOfSegmentIndex].tbry);
+ }
+ else
+ {
+ cur_ptr->currTTLX = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttlx, (gdouble)val_ptr->point[currPtidx].ttlx);
+ cur_ptr->currTTLY = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttly, (gdouble)val_ptr->point[currPtidx].ttly);
+ cur_ptr->currTTRX = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttrx, (gdouble)val_ptr->point[currPtidx].ttrx);
+ cur_ptr->currTTRY = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].ttry, (gdouble)val_ptr->point[currPtidx].ttry);
+ cur_ptr->currTBLX = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tblx, (gdouble)val_ptr->point[currPtidx].tblx);
+ cur_ptr->currTBLY = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tbly, (gdouble)val_ptr->point[currPtidx].tbly);
+ cur_ptr->currTBRX = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tbrx, (gdouble)val_ptr->point[currPtidx].tbrx);
+ cur_ptr->currTBRY = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].tbry, (gdouble)val_ptr->point[currPtidx].tbry);
+ }
+
+ /* calculate Selection Feather Radius settings for the currently processed Frame (or tween) */
+ if ((val_ptr->point[startOfSegmentIndex].accSelFeatherRadius != 0)
+ && (frameTweensInSegment > 0))
+ {
+ /* acceleration characteristic processing for rotation */
+ posFactor = p_calculate_posFactor_from_FrameTweens(frameTweensInSegment
+ , currFrameTweenInSegment
+ , val_ptr->point[startOfSegmentIndex].accSelFeatherRadius
+ );
+ cur_ptr->currSelFeatherRadius = MIX_VALUE(posFactor, (gdouble)val_ptr->point[startOfSegmentIndex].sel_feather_radius, (gdouble)val_ptr->point[endOfSegmentIndex].sel_feather_radius);
+ }
+ else
+ {
+ cur_ptr->currSelFeatherRadius = MIX_VALUE(flt_posfactor, (gdouble)val_ptr->point[currPtidx -1].sel_feather_radius, (gdouble)val_ptr->point[currPtidx].sel_feather_radius);
+ }
+
+ return(frameNrAtEndOfSegment);
+} /* end p_calculate_settings_for_current_FrameTween */
+
+
+
/* ============================================================================
* p_mov_execute
* Copy layer(s) from Sourceimage to given destination frame range,
@@ -652,20 +1168,13 @@ p_mov_advance_src_frame(GapMovCurrent *cur_ptr, GapMovValues *pvals)
long
p_mov_execute(GapMovData *mov_ptr)
{
-/* MIX_VALUE 0.0 <= factor <= 1.0
- * result is a for factor 0.0
- * b for factor 1.0
- * mix for factors inbetween
- */
-#define MIX_VALUE(factor, a, b) ((a * (1.0 - factor)) + (b * factor))
- gint l_idx;
+ gint l_idx;
GapMovCurrent l_current_data;
GapMovCurrent *cur_ptr;
GapMovValues *val_ptr;
gdouble l_percentage;
gdouble l_fpl; /* frames_per_line */
- gdouble l_flt_posfactor;
long l_frame_step;
gdouble l_frames;
long l_cnt;
@@ -681,6 +1190,10 @@ p_mov_execute(GapMovData *mov_ptr)
gint l_apv_layerstack;
gdouble l_flt_timing[GAP_MOV_MAX_POINT]; /* timing table in relative frame numbers (0.0 == the first handled frame) */
+ gint startOfSegmentIndex;
+ gint endOfSegmentIndex;
+ gint frameNrAtEndOfSegment;
+
if(mov_ptr->val_ptr->src_image_id < 0)
{
@@ -690,6 +1203,7 @@ p_mov_execute(GapMovData *mov_ptr)
return -1;
}
+ frameNrAtEndOfSegment = 0;
l_apv_layerstack = 0;
l_percentage = 0.0;
if(mov_ptr->dst_ainfo_ptr->run_mode == GIMP_RUN_INTERACTIVE)
@@ -744,6 +1258,13 @@ p_mov_execute(GapMovData *mov_ptr)
printf("tbrx[%d] :%.3f\n", l_idx, (float)mov_ptr->val_ptr->point[l_idx].tbrx);
printf("tbry[%d] :%.3f\n", l_idx, (float)mov_ptr->val_ptr->point[l_idx].tbry);
+ printf("accPosition [%d] :%d\n", l_idx, (int)mov_ptr->val_ptr->point[l_idx].accPosition);
+ printf("accOpacity [%d] :%d\n", l_idx, (int)mov_ptr->val_ptr->point[l_idx].accOpacity);
+ printf("accSize [%d] :%d\n", l_idx, (int)mov_ptr->val_ptr->point[l_idx].accSize);
+ printf("accRotation [%d] :%d\n", l_idx, (int)mov_ptr->val_ptr->point[l_idx].accRotation);
+ printf("accPerspective [%d] :%d\n", l_idx, (int)mov_ptr->val_ptr->point[l_idx].accPerspective);
+ printf("accSelFeatherRadius[%d] :%d\n", l_idx, (int)mov_ptr->val_ptr->point[l_idx].accSelFeatherRadius);
+
printf("keyframe[%d] :%d\n", l_idx, mov_ptr->val_ptr->point[l_idx].keyframe);
printf("keyframe_abs[%d] :%d\n", l_idx, mov_ptr->val_ptr->point[l_idx].keyframe_abs);
}
@@ -792,7 +1313,7 @@ p_mov_execute(GapMovData *mov_ptr)
{
/* copy point[0] to point [1] because we need at least 2
* points for the algorithms below to work.
- * (simulates a line with lenght 0, to move along)
+ * (simulates a line with length 0, to move along)
*/
if(gap_debug) printf("p_mov_execute: added a 2nd Point\n");
val_ptr->point[1].p_x = val_ptr->point[0].p_x;
@@ -811,9 +1332,18 @@ p_mov_execute(GapMovData *mov_ptr)
val_ptr->point[1].tbry = val_ptr->point[0].tbry;
val_ptr->point[1].sel_feather_radius = val_ptr->point[0].sel_feather_radius;
+ val_ptr->point[1].accPosition = val_ptr->point[0].accPosition;
+ val_ptr->point[1].accOpacity = val_ptr->point[0].accOpacity;
+ val_ptr->point[1].accSize = val_ptr->point[0].accSize;
+ val_ptr->point[1].accRotation = val_ptr->point[0].accRotation;
+ val_ptr->point[1].accPerspective = val_ptr->point[0].accPerspective;
+ val_ptr->point[1].accSelFeatherRadius = val_ptr->point[0].accSelFeatherRadius;
+
l_points = 2;
}
+ startOfSegmentIndex = 0;
+ endOfSegmentIndex = l_points -1; /* initial value in case all points are in only 1 segment */
cur_ptr->dst_frame_nr = val_ptr->dst_range_start;
cur_ptr->src_layers = NULL;
@@ -859,7 +1389,7 @@ p_mov_execute(GapMovData *mov_ptr)
}
}
cur_ptr->src_last_layer = l_nlayers -1; /* index of last layer */
- }
+ }
else
{
/* for FRAME stepmodes we use flattened Sorce frames
@@ -895,6 +1425,15 @@ p_mov_execute(GapMovData *mov_ptr)
cur_ptr->currTBRY = (gdouble)val_ptr->point[0].tbry;
cur_ptr->currSelFeatherRadius = (gdouble)val_ptr->point[0].sel_feather_radius;
+ cur_ptr->accPosition = val_ptr->point[0].accPosition;
+ cur_ptr->accOpacity = val_ptr->point[0].accOpacity;
+ cur_ptr->accSize = val_ptr->point[0].accSize;
+ cur_ptr->accRotation = val_ptr->point[0].accRotation;
+ cur_ptr->accPerspective = val_ptr->point[0].accPerspective;
+ cur_ptr->accSelFeatherRadius = val_ptr->point[0].accSelFeatherRadius;
+
+
+
val_ptr->tween_image_id = -1;
val_ptr->tween_layer_id = -1;
val_ptr->trace_image_id = -1;
@@ -1006,7 +1545,7 @@ p_mov_execute(GapMovData *mov_ptr)
}
}
-
+
/* loop for each frame within the range (may step up or down) */
l_ptidx = 1;
cur_ptr->dst_frame_nr = val_ptr->dst_range_start;
@@ -1052,48 +1591,37 @@ p_mov_execute(GapMovData *mov_ptr)
*/
for (val_ptr->twix = val_ptr->tween_steps; val_ptr->twix >= 0; val_ptr->twix--)
{
+ gdouble l_flt_posfactor;
+
if(l_fpl != 0.0)
{
- l_flt_posfactor = ( (((gdouble)l_fridx * l_tw_cnt) - (gdouble)val_ptr->twix)
+ l_flt_posfactor = ( (((gdouble)l_fridx * l_tw_cnt) - (gdouble)val_ptr->twix)
- (l_flt_timing[l_ptidx -1] * l_tw_cnt)
) / (l_fpl * l_tw_cnt);
}
else
{
- l_flt_posfactor = 1.0;
- if(gap_debug) printf("p_mov_execute: ** ERROR l_fpl is 0.0 frames per line\n");
+ l_flt_posfactor = 1.0;
+ if(gap_debug) printf("p_mov_execute: ** ERROR l_fpl is 0.0 frames per line\n");
}
-
-
- if(gap_debug) printf("p_mov_execute: l_fpl=%f, l_flt_posfactor=%f\n", (float)l_fpl, (float)l_flt_posfactor);
-
+
l_flt_posfactor = CLAMP (l_flt_posfactor, 0.0, 1.0);
+
+ endOfSegmentIndex = p_findEndOfSegmentIndex(val_ptr, startOfSegmentIndex, l_points);
+
+ frameNrAtEndOfSegment = p_calculate_settings_for_current_FrameTween(val_ptr, cur_ptr
+ , l_fpl
+ , l_fridx
+ , l_ptidx
+ , l_flt_posfactor
+ , l_frames
+ , l_points
+ , startOfSegmentIndex
+ , endOfSegmentIndex
+ );
- cur_ptr->currX = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].p_x, (gdouble)val_ptr->point[l_ptidx].p_x);
- cur_ptr->currY = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].p_y, (gdouble)val_ptr->point[l_ptidx].p_y);
- cur_ptr->currOpacity = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].opacity, (gdouble)val_ptr->point[l_ptidx].opacity);
- cur_ptr->currWidth = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].w_resize, (gdouble)val_ptr->point[l_ptidx].w_resize);
- cur_ptr->currHeight = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].h_resize, (gdouble)val_ptr->point[l_ptidx].h_resize);
- cur_ptr->currRotation = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].rotation, (gdouble)val_ptr->point[l_ptidx].rotation);
- cur_ptr->currTTLX = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].ttlx, (gdouble)val_ptr->point[l_ptidx].ttlx);
- cur_ptr->currTTLY = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].ttly, (gdouble)val_ptr->point[l_ptidx].ttly);
- cur_ptr->currTTRX = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].ttrx, (gdouble)val_ptr->point[l_ptidx].ttrx);
- cur_ptr->currTTRY = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].ttry, (gdouble)val_ptr->point[l_ptidx].ttry);
- cur_ptr->currTBLX = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].tblx, (gdouble)val_ptr->point[l_ptidx].tblx);
- cur_ptr->currTBLY = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].tbly, (gdouble)val_ptr->point[l_ptidx].tbly);
- cur_ptr->currTBRX = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].tbrx, (gdouble)val_ptr->point[l_ptidx].tbrx);
- cur_ptr->currTBRY = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].tbry, (gdouble)val_ptr->point[l_ptidx].tbry);
- cur_ptr->currSelFeatherRadius = MIX_VALUE(l_flt_posfactor, (gdouble)val_ptr->point[l_ptidx -1].sel_feather_radius, (gdouble)val_ptr->point[l_ptidx].sel_feather_radius);
- if(gap_debug)
- {
- printf("ROTATE [%02d] %f [%02d] %f MIX: %f\n"
- , (int)l_ptidx-1, (float)val_ptr->point[l_ptidx -1].rotation
- , (int)l_ptidx, (float)val_ptr->point[l_ptidx].rotation
- , (float)cur_ptr->currRotation);
- }
-
if(val_ptr->src_stepmode < GAP_STEP_FRAME )
{
/* advance settings for next src layer */
@@ -1119,6 +1647,12 @@ p_mov_execute(GapMovData *mov_ptr)
l_rc = p_mov_call_render(mov_ptr, cur_ptr, l_apv_layerstack);
} /* end tweenindex subloop */
+
+ /* advance to next path segment */
+ if(l_fridx >= frameNrAtEndOfSegment)
+ {
+ startOfSegmentIndex = endOfSegmentIndex;
+ }
/* show progress */
if(mov_ptr->dst_ainfo_ptr->run_mode == GIMP_RUN_INTERACTIVE)
@@ -1414,9 +1948,10 @@ gap_mov_exec_conv_keyframe_to_abs(gint rel_keyframe, GapMovValues *pvals)
}
-/* ============================================================================
+
+/* ----------------------------------
* gap_mov_exec_gap_save_pointfile
- * ============================================================================
+ * ----------------------------------
*/
gint
gap_mov_exec_gap_save_pointfile(char *filename, GapMovValues *pvals)
@@ -1436,7 +1971,14 @@ gap_mov_exec_gap_save_pointfile(char *filename, GapMovValues *pvals)
fprintf(l_fp, "# x y width height opacity rotation feather_radius number_of_optional_params [8 perspective transform factors] [rel_keyframe]\n");
for(l_idx = 0; l_idx <= pvals->point_idx_max; l_idx++)
{
- gint num_optional_params;
+ gint optional_params_indicator;
+ gboolean writePerspective;
+ gboolean writeAccelerationCharacteristics;
+ gboolean writeKeyframe;
+
+ writePerspective = FALSE;
+ writeAccelerationCharacteristics = FALSE;
+ writeKeyframe = FALSE;
fprintf(l_fp, "%04d %04d "
, (int)pvals->point[l_idx].p_x
@@ -1448,7 +1990,7 @@ gap_mov_exec_gap_save_pointfile(char *filename, GapMovValues *pvals)
gap_base_fprintf_gdouble(l_fp, pvals->point[l_idx].rotation, 3, 3, " ");
gap_base_fprintf_gdouble(l_fp, pvals->point[l_idx].sel_feather_radius, 3, 3, " ");
- num_optional_params = 0;
+ optional_params_indicator = 0;
/* conditional write transformation (only if there is any) */
if(pvals->point[l_idx].ttlx != 1.0
@@ -1461,18 +2003,49 @@ gap_mov_exec_gap_save_pointfile(char *filename, GapMovValues *pvals)
|| pvals->point[l_idx].tbry != 1.0
)
{
- num_optional_params = 8;
+ optional_params_indicator += 8;
+ writePerspective = TRUE;
}
+
+ /* conditional write acceleration characteristics
+ * relevant information can occur at first controlpoint
+ * or on keyframes but never for the last controlpoint)
+ */
+ if (pvals->point[l_idx].accPosition != 0)
+ {
+ if (l_idx == 0)
+ {
+ writeAccelerationCharacteristics = TRUE;
+ }
+ else
+ {
+ if ((l_idx < pvals->point_idx_max)
+ && ((int)pvals->point[l_idx].keyframe > 0))
+ {
+ writeAccelerationCharacteristics = TRUE;
+ }
+ }
+
+ if (writeAccelerationCharacteristics == TRUE)
+ {
+ optional_params_indicator += 6;
+ }
+ }
+
+ /* check for writing keyframe
+ * (the implicite keyframes at first and last controlpoints are not written to file)
+ */
if((l_idx > 0)
&& (l_idx < pvals->point_idx_max)
&& ((int)pvals->point[l_idx].keyframe > 0))
{
- num_optional_params++;
+ optional_params_indicator++;
+ writeKeyframe = TRUE;
}
- fprintf(l_fp, " %02d ", (int)num_optional_params);
+ fprintf(l_fp, " %02d ", (int)optional_params_indicator);
- if(num_optional_params >= 8)
+ if(writePerspective == TRUE)
{
fprintf(l_fp, " ");
gap_base_fprintf_gdouble(l_fp, pvals->point[l_idx].ttlx, 2, 3, " ");
@@ -1488,10 +2061,21 @@ gap_mov_exec_gap_save_pointfile(char *filename, GapMovValues *pvals)
gap_base_fprintf_gdouble(l_fp, pvals->point[l_idx].tbry, 2, 3, " ");
}
+
+ if(writeAccelerationCharacteristics == TRUE)
+ {
+ fprintf(l_fp, " %02d %02d %02d %02d %02d %02d"
+ , (int)pvals->point[l_idx].accPosition
+ , (int)pvals->point[l_idx].accOpacity
+ , (int)pvals->point[l_idx].accSize
+ , (int)pvals->point[l_idx].accRotation
+ , (int)pvals->point[l_idx].accPerspective
+ , (int)pvals->point[l_idx].accSelFeatherRadius
+ );
+ }
+
/* conditional write keyframe */
- if((l_idx > 0)
- && (l_idx < pvals->point_idx_max)
- && ((int)pvals->point[l_idx].keyframe > 0))
+ if(writeKeyframe == TRUE)
{
fprintf(l_fp, " %d"
, (int)gap_mov_exec_conv_keyframe_to_rel(pvals->point[l_idx].keyframe_abs, pvals)
@@ -1508,9 +2092,9 @@ gap_mov_exec_gap_save_pointfile(char *filename, GapMovValues *pvals)
-/* ============================================================================
+/* ----------------------------------
* gap_mov_exec_gap_load_pointfile
- * ============================================================================
+ * ----------------------------------
* return 0 if Load was OK,
* return -2 when load has read inconsistent pointfile
* and the pointtable needs to be reset (dialog has to call p_reset_points)
@@ -1519,7 +2103,7 @@ gint
gap_mov_exec_gap_load_pointfile(char *filename, GapMovValues *pvals)
{
#define POINT_REC_MAX 512
-#define MAX_NUMVALUES_PER_LINE 17
+#define MAX_NUMVALUES_PER_LINE 23
FILE *l_fp;
gint l_idx;
char l_buff[POINT_REC_MAX +1 ];
@@ -1549,38 +2133,34 @@ gap_mov_exec_gap_load_pointfile(char *filename, GapMovValues *pvals)
l_cnt = gap_base_sscan_flt_numbers(l_ptr, &l_farr[0], MAX_NUMVALUES_PER_LINE);
l_i1 = (gint)l_farr[0];
l_i2 = (gint)l_farr[1];
+
+ if(gap_debug)
+ {
+ gint ii;
+
+ printf("scanned %d numbers\n", l_cnt);
+ for(ii=0; ii < l_cnt; ii++)
+ {
+ printf(" value[%02d] : %f\n", (int)ii, (float)l_farr[ii]);
+ }
+ }
if(l_idx == -1)
{
if((l_cnt < 2) || (l_i2 > GAP_MOV_MAX_POINT) || (l_i1 > l_i2))
{
break;
- }
+ }
pvals->point_idx = l_i1;
pvals->point_idx_max = l_i2 -1;
l_idx = 0;
}
else
{
- gdouble num_optional_params;
+ gint optional_params_indicator;
gint key_idx;
- /* the older format used in GAP.1.2 has 6 or 7 integer numbers per line
- * and should be compatible and readable by this code.
- *
- * the new format has 2 integer values (p_x, p_y)
- * and 5 float values (w_resize, h_resize, opacity, rotation, feather_radius)
- * and 1 int value num_optional_params (telling how much will follow)
- * the rest of the line is optional
- * 8 additional float values (transformation factors) 7th upto 14th parameter
- * 1 integer values (keyframe) as 7th parameter
- * or as 15th parameter (if transformation factors are present too)
- */
- if((l_cnt != 6) && (l_cnt != 7) /* for compatibility to old format */
- && (l_cnt != 8) && (l_cnt != 9) && (l_cnt != 16) && (l_cnt != 17))
- {
- /* invalid pointline format detected */
- l_rc = -2; /* have to call p_reset_points() when called from dialog window */
- break;
- }
+ gint acc_idx;
+ gint perspective_idx;
+
pvals->point[l_idx].keyframe_abs = 0;
pvals->point[l_idx].keyframe = 0;
pvals->point[l_idx].p_x = l_i1;
@@ -1598,23 +2178,104 @@ gap_mov_exec_gap_load_pointfile(char *filename, GapMovValues *pvals)
pvals->point[l_idx].opacity = l_farr[4];
pvals->point[l_idx].rotation = l_farr[5];
pvals->point[l_idx].sel_feather_radius = 0.0;
+
+ pvals->point[l_idx].accPosition = 0;
+ pvals->point[l_idx].accOpacity = 0;
+ pvals->point[l_idx].accSize = 0;
+ pvals->point[l_idx].accRotation = 0;
+ pvals->point[l_idx].accPerspective = 0;
+ pvals->point[l_idx].accSelFeatherRadius = 0;
+
+ /* the older format used in GAP.1.2 has 6 or 7 integer numbers per line
+ * and is still readable by this code.
+ *
+ * the new format has 2 integer values (p_x, p_y)
+ * and 5 float values (w_resize, h_resize, opacity, rotation, feather_radius)
+ * and 1 int value optional_params_indicator (telling how much and what kind of parameter will follow)
+ * possible optional parameter(s) are:
+ * (if all of them are present, then in the order as listed below)
+ *
+ * 8 float values for the transformation factors
+ * 6 int values for acceleration characteristics (since GIMP_GAP 2.7.x)
+ * 1 int value for keyframe information (not present at first and last controlpoint)
+ */
+ if((l_cnt != 6) && (l_cnt != 7) /* for compatibility to old format */
+ && (l_cnt != 8) && (l_cnt != 9) && (l_cnt != 16) && (l_cnt != 17) /* for GAP 2.6.x format */
+ && (l_cnt != 14) && (l_cnt != 15) && (l_cnt != 22) && (l_cnt != 23) )
+ {
+ /* invalid pointline format detected */
+ l_rc = -2; /* have to call p_reset_points() when called from dialog window */
+
+ printf("invalid move path pointfile %d numbers per line are not supported\n", (int)l_cnt);
+ break;
+ }
+
+ optional_params_indicator = 0;
+ key_idx = -1;
+ acc_idx = -1;
+ perspective_idx = -1;
+
if(l_cnt >= 8)
{
pvals->point[l_idx].sel_feather_radius = l_farr[6];
- num_optional_params = l_farr[7];
+ optional_params_indicator = l_farr[7];
}
- if(l_cnt >= 16)
+
+
+ if(gap_debug)
{
- pvals->point[l_idx].ttlx = l_farr[8];
- pvals->point[l_idx].ttly = l_farr[9];
- pvals->point[l_idx].ttrx = l_farr[10];
- pvals->point[l_idx].ttry = l_farr[11];
- pvals->point[l_idx].tblx = l_farr[12];
- pvals->point[l_idx].tbly = l_farr[13];
- pvals->point[l_idx].tbrx = l_farr[14];
- pvals->point[l_idx].tbry = l_farr[15];
+ printf("gap_mov_exec_gap_load_pointfile optional_params_indicator:%d\n", optional_params_indicator);
}
- key_idx = -1;
+
+
+ switch (optional_params_indicator)
+ {
+ case 0:
+ break;
+ case 1:
+ /* have one keyframe value */
+ key_idx = 8;
+ break;
+ case 6:
+ /* have six accelerate characteristic values */
+ acc_idx = 8;
+ break;
+ case 7:
+ /* have six accelerate characteristic values
+ * and one keyframe value
+ */
+ acc_idx = 8;
+ key_idx = 8 + 6;
+ break;
+ case 8:
+ /* have eight perspective values */
+ perspective_idx = 8;
+ break;
+ case 9:
+ /* have eight perspective values
+ * and one keyframe value
+ */
+ perspective_idx = 8;
+ key_idx = 8 + 8;
+ break;
+ case 14:
+ /* have eight perspective values
+ * and six accelerate characteristic values
+ */
+ perspective_idx = 8;
+ acc_idx = 8 + 8;
+ break;
+ case 15:
+ /* have eight perspective values
+ * and six accelerate characteristic values
+ * and one keyframe value
+ */
+ perspective_idx = 8;
+ acc_idx = 8 + 8;
+ key_idx = 8 + 8 + 6;
+ break;
+ }
+
if(l_idx > 0)
{
switch(l_cnt)
@@ -1622,14 +2283,30 @@ gap_mov_exec_gap_load_pointfile(char *filename, GapMovValues *pvals)
case 7:
key_idx = 6; /* for compatibilty with old format */
break;
- case 9:
- key_idx = 8;
- break;
- case 17:
- key_idx = 16;
- break;
}
}
+
+ if(perspective_idx >= 0)
+ {
+ pvals->point[l_idx].ttlx = l_farr[perspective_idx];
+ pvals->point[l_idx].ttly = l_farr[perspective_idx +1];
+ pvals->point[l_idx].ttrx = l_farr[perspective_idx +2];
+ pvals->point[l_idx].ttry = l_farr[perspective_idx +3];
+ pvals->point[l_idx].tblx = l_farr[perspective_idx +4];
+ pvals->point[l_idx].tbly = l_farr[perspective_idx +5];
+ pvals->point[l_idx].tbrx = l_farr[perspective_idx +6];
+ pvals->point[l_idx].tbry = l_farr[perspective_idx +7];
+ }
+ if(acc_idx >= 0)
+ {
+ pvals->point[l_idx].accPosition = l_farr[acc_idx];
+ pvals->point[l_idx].accOpacity = l_farr[acc_idx +1];
+ pvals->point[l_idx].accSize = l_farr[acc_idx +2];
+ pvals->point[l_idx].accRotation = l_farr[acc_idx +3];
+ pvals->point[l_idx].accPerspective = l_farr[acc_idx +4];
+ pvals->point[l_idx].accSelFeatherRadius = l_farr[acc_idx +5];
+ }
+
if(key_idx > 0)
{
pvals->point[l_idx].keyframe = l_farr[key_idx];
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]