| 
									
										
										
										
											2011-02-23 10:52:22 +00:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  |  * $Id$ | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** BEGIN GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is free software; you can redistribute it and/or | 
					
						
							|  |  |  |  * modify it under the terms of the GNU General Public License | 
					
						
							|  |  |  |  * as published by the Free Software Foundation; either version 2 | 
					
						
							|  |  |  |  * of the License, or (at your option) any later version.  | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * This program is distributed in the hope that it will be useful, | 
					
						
							|  |  |  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
					
						
							|  |  |  |  * GNU General Public License for more details. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  |  * along with this program; if not, write to the Free Software Foundation, | 
					
						
							| 
									
										
										
										
											2010-02-12 13:34:04 +00:00
										 |  |  |  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  |  * | 
					
						
							|  |  |  |  * The Original Code is Copyright (C) 2008 Blender Foundation. | 
					
						
							|  |  |  |  * All rights reserved. | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  *  | 
					
						
							|  |  |  |  * Contributor(s): Joshua Leung | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * ***** END GPL LICENSE BLOCK ***** | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2011-02-27 20:29:51 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /** \file blender/editors/animation/anim_draw.c
 | 
					
						
							|  |  |  |  *  \ingroup edanimation | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-08-31 11:31:21 +00:00
										 |  |  | #include "BLO_sys_types.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-20 11:07:42 +00:00
										 |  |  | #include "DNA_anim_types.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | #include "DNA_object_types.h"
 | 
					
						
							|  |  |  | #include "DNA_scene_types.h"
 | 
					
						
							| 
									
										
										
										
											2010-01-26 09:25:32 +00:00
										 |  |  | #include "BLI_math.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "BKE_context.h"
 | 
					
						
							| 
									
										
										
										
											2009-06-23 13:25:31 +00:00
										 |  |  | #include "BKE_nla.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-21 03:14:01 +00:00
										 |  |  | #include "BKE_object.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | #include "ED_anim_api.h"
 | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | #include "ED_keyframes_edit.h"
 | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | #include "RNA_access.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | #include "BIF_gl.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include "UI_interface.h"
 | 
					
						
							|  |  |  | #include "UI_resources.h"
 | 
					
						
							|  |  |  | #include "UI_view2d.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-21 03:14:01 +00:00
										 |  |  | /* XXX */ | 
					
						
							|  |  |  | extern void ui_rasterpos_safe(float x, float y, float aspect); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | /* *************************************************** */ | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | /* TIME CODE FORMATTING */ | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | /* Generate timecode/frame number string and store in the supplied string 
 | 
					
						
							|  |  |  |  * 	- buffer: must be at least 13 chars long  | 
					
						
							|  |  |  |  *	- power: special setting for View2D grid drawing,  | 
					
						
							|  |  |  |  *	  used to specify how detailed we need to be | 
					
						
							|  |  |  |  *	- timecodes: boolean specifying whether timecodes or | 
					
						
							|  |  |  |  *	  frame numbers get drawn | 
					
						
							|  |  |  |  *	- cfra: time in frames or seconds, consistent with the values shown by timecodes | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | // TODO: have this in kernel instead under scene?
 | 
					
						
							|  |  |  | void ANIM_timecode_string_from_frame (char *str, Scene *scene, int power, short timecodes, float cfra) | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 	if (timecodes) { | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 		int hours=0, minutes=0, seconds=0, frames=0; | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 		float raw_seconds= cfra; | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 		char neg[2]= ""; | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 		/* get cframes */ | 
					
						
							|  |  |  | 		if (cfra < 0) { | 
					
						
							|  |  |  | 			/* correction for negative cfraues */ | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 			sprintf(neg, "-"); | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 			cfra = -cfra; | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 		if (cfra >= 3600) { | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 			/* hours */ | 
					
						
							|  |  |  | 			/* XXX should we only display a single digit for hours since clips are 
 | 
					
						
							|  |  |  | 			 * 	   VERY UNLIKELY to be more than 1-2 hours max? However, that would  | 
					
						
							|  |  |  | 			 *	   go against conventions... | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 			hours= (int)cfra / 3600; | 
					
						
							|  |  |  | 			cfra= (float)fmod(cfra, 3600); | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 		if (cfra >= 60) { | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 			/* minutes */ | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 			minutes= (int)cfra / 60; | 
					
						
							|  |  |  | 			cfra= (float)fmod(cfra, 60); | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 		if (power <= 0) { | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 			/* seconds + frames
 | 
					
						
							|  |  |  | 			 *	Frames are derived from 'fraction' of second. We need to perform some additional rounding | 
					
						
							|  |  |  | 			 *	to cope with 'half' frames, etc., which should be fine in most cases | 
					
						
							|  |  |  | 			 */ | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 			seconds= (int)cfra; | 
					
						
							| 
									
										
										
										
											2011-03-27 17:22:04 +00:00
										 |  |  | 			frames= (int)floor( (((double)cfra - (double)seconds) * FPS) + 0.5 ); | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			/* seconds (with pixel offset rounding) */ | 
					
						
							|  |  |  | 			seconds= (int)floor(cfra + 0.375f); | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | 		switch (U.timecode_style) { | 
					
						
							|  |  |  | 			case USER_TIMECODE_MINIMAL:  | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/*	- In general, minutes and seconds should be shown, as most clips will be
 | 
					
						
							|  |  |  | 				 *	  within this length. Hours will only be included if relevant. | 
					
						
							|  |  |  | 				 *	- Only show frames when zoomed in enough for them to be relevant  | 
					
						
							|  |  |  | 				 *	  (using separator of '+' for frames). | 
					
						
							|  |  |  | 				 *	  When showing frames, use slightly different display to avoid confusion with mm:ss format | 
					
						
							|  |  |  | 				 */ | 
					
						
							|  |  |  | 				if (power <= 0) { | 
					
						
							|  |  |  | 					/* include "frames" in display */ | 
					
						
							|  |  |  | 					if (hours) sprintf(str, "%s%02d:%02d:%02d+%02d", neg, hours, minutes, seconds, frames); | 
					
						
							|  |  |  | 					else if (minutes) sprintf(str, "%s%02d:%02d+%02d", neg, minutes, seconds, frames); | 
					
						
							|  |  |  | 					else sprintf(str, "%s%d+%02d", neg, seconds, frames); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 				else { | 
					
						
							|  |  |  | 					/* don't include 'frames' in display */ | 
					
						
							|  |  |  | 					if (hours) sprintf(str, "%s%02d:%02d:%02d", neg, hours, minutes, seconds); | 
					
						
							|  |  |  | 					else sprintf(str, "%s%02d:%02d", neg, minutes, seconds); | 
					
						
							|  |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 			case USER_TIMECODE_SMPTE_MSF: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* reduced SMPTE format that always shows minutes, seconds, frames. Hours only shown as needed. */ | 
					
						
							|  |  |  | 				if (hours) sprintf(str, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames); | 
					
						
							|  |  |  | 				else sprintf(str, "%s%02d:%02d:%02d", neg, minutes, seconds, frames); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			case USER_TIMECODE_MILLISECONDS: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* reduced SMPTE. Instead of frames, milliseconds are shown */ | 
					
						
							|  |  |  | 				int ms_dp= (power <= 0) ? (1 - power) : 1; /* precision of decimal part */ | 
					
						
							|  |  |  | 				int s_pad= ms_dp+3;	/* to get 2 digit whole-number part for seconds display (i.e. 3 is for 2 digits + radix, on top of full length) */ | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 				if (hours) sprintf(str, "%s%02d:%02d:%0*.*f", neg, hours, minutes, s_pad, ms_dp, cfra); | 
					
						
							|  |  |  | 				else sprintf(str, "%s%02d:%0*.*f", neg, minutes, s_pad,  ms_dp, cfra); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 				 | 
					
						
							|  |  |  | 			case USER_TIMECODE_SECONDS_ONLY: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* only show the original seconds display */ | 
					
						
							|  |  |  | 				/* round to whole numbers if power is >= 1 (i.e. scale is coarse) */ | 
					
						
							|  |  |  | 				if (power <= 0) sprintf(str, "%.*f", 1-power, raw_seconds); | 
					
						
							|  |  |  | 				else sprintf(str, "%d", (int)floor(raw_seconds + 0.375f)); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			case USER_TIMECODE_SMPTE_FULL: | 
					
						
							|  |  |  | 			default: | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* full SMPTE format */ | 
					
						
							|  |  |  | 				sprintf(str, "%s%02d:%02d:%02d:%02d", neg, hours, minutes, seconds, frames); | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 				break; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	else { | 
					
						
							|  |  |  | 		/* round to whole numbers if power is >= 1 (i.e. scale is coarse) */ | 
					
						
							|  |  |  | 		if (power <= 0) sprintf(str, "%.*f", 1-power, cfra); | 
					
						
							|  |  |  | 		else sprintf(str, "%d", (int)floor(cfra + 0.375f)); | 
					
						
							| 
									
										
										
										
											2009-06-08 02:33:24 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2010-01-30 04:43:36 +00:00
										 |  |  | }  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* *************************************************** */ | 
					
						
							|  |  |  | /* CURRENT FRAME DRAWING */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Draw current frame number in a little green box beside the current frame indicator */ | 
					
						
							|  |  |  | static void draw_cfra_number (Scene *scene, View2D *v2d, float cfra, short time) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	float xscale, yscale, x, y; | 
					
						
							|  |  |  | 	char str[32] = "    t";	/* t is the character to start replacing from */ | 
					
						
							|  |  |  | 	short slen; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* because the frame number text is subject to the same scaling as the contents of the view */ | 
					
						
							|  |  |  | 	UI_view2d_getscale(v2d, &xscale, &yscale); | 
					
						
							|  |  |  | 	glScalef(1.0f/xscale, 1.0f, 1.0f); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* get timecode string 
 | 
					
						
							|  |  |  | 	 *	- padding on str-buf passed so that it doesn't sit on the frame indicator | 
					
						
							|  |  |  | 	 *	- power = 0, gives 'standard' behaviour for time | 
					
						
							|  |  |  | 	 *	  but power = 1 is required for frames (to get integer frames) | 
					
						
							|  |  |  | 	 */ | 
					
						
							|  |  |  | 	if (time) | 
					
						
							|  |  |  | 		ANIM_timecode_string_from_frame(&str[4], scene, 0, time, FRA2TIME(cfra)); | 
					
						
							|  |  |  | 	else	 | 
					
						
							|  |  |  | 		ANIM_timecode_string_from_frame(&str[4], scene, 1, time, cfra); | 
					
						
							| 
									
										
										
										
											2009-04-10 16:30:28 +00:00
										 |  |  | 	slen= (short)UI_GetStringWidth(str) - 1; | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* get starting coordinates for drawing */ | 
					
						
							|  |  |  | 	x= cfra * xscale; | 
					
						
							| 
									
										
										
										
											2008-12-21 03:14:01 +00:00
										 |  |  | 	y= 18; | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* draw green box around/behind text */ | 
					
						
							| 
									
										
										
										
											2009-11-18 08:50:09 +00:00
										 |  |  | 	UI_ThemeColorShade(TH_CFRAME, 0); | 
					
						
							| 
									
										
										
										
											2008-12-21 03:14:01 +00:00
										 |  |  | 	glRectf(x, y,  x+slen,  y+15); | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* draw current frame number - black text */ | 
					
						
							|  |  |  | 	UI_ThemeColor(TH_TEXT); | 
					
						
							| 
									
										
										
										
											2009-11-18 08:50:09 +00:00
										 |  |  | 	UI_DrawString(x-5, y+3, str); | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* restore view transform */ | 
					
						
							| 
									
										
										
										
											2008-12-21 03:14:01 +00:00
										 |  |  | 	glScalef(xscale, 1.0, 1.0); | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-10-20 12:04:56 +00:00
										 |  |  | /* General call for drawing current frame indicator in animation editor */ | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | void ANIM_draw_cfra (const bContext *C, View2D *v2d, short flag) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Scene *scene= CTX_data_scene(C); | 
					
						
							|  |  |  | 	float vec[2]; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* Draw a light green line to indicate current frame */ | 
					
						
							|  |  |  | 	vec[0]= (float)(scene->r.cfra * scene->r.framelen); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	UI_ThemeColor(TH_CFRAME); | 
					
						
							| 
									
										
										
										
											2011-07-12 12:13:23 +00:00
										 |  |  | 	if (flag & DRAWCFRA_WIDE) | 
					
						
							|  |  |  | 		glLineWidth(3.0); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		glLineWidth(2.0); | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	glBegin(GL_LINE_STRIP); | 
					
						
							| 
									
										
										
										
											2009-07-02 18:12:46 +00:00
										 |  |  | 		vec[1]= v2d->cur.ymin-500.0f;	/* XXX arbitrary... want it go to bottom */ | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 		glVertex2fv(vec); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		vec[1]= v2d->cur.ymax; | 
					
						
							|  |  |  | 		glVertex2fv(vec); | 
					
						
							|  |  |  | 	glEnd(); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* Draw dark green line if slow-parenting/time-offset is enabled */ | 
					
						
							|  |  |  | 	if (flag & DRAWCFRA_SHOW_TIMEOFS) { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 		Object *ob= OBACT; | 
					
						
							| 
									
										
										
										
											2010-05-03 15:56:44 +00:00
										 |  |  | 		if(ob) { | 
					
						
							|  |  |  | 			float timeoffset= give_timeoffset(ob); | 
					
						
							|  |  |  | 			// XXX ob->ipoflag is depreceated!
 | 
					
						
							|  |  |  | 			if ((ob->ipoflag & OB_OFFS_OB) && (timeoffset != 0.0f)) { | 
					
						
							|  |  |  | 				vec[0]-= timeoffset; /* could avoid calling twice */ | 
					
						
							| 
									
										
										
										
											2011-07-12 12:04:27 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											2010-05-03 15:56:44 +00:00
										 |  |  | 				UI_ThemeColorShade(TH_CFRAME, -30); | 
					
						
							| 
									
										
										
										
											2011-07-12 12:04:27 +00:00
										 |  |  | 				 | 
					
						
							| 
									
										
										
										
											2010-05-03 15:56:44 +00:00
										 |  |  | 				glBegin(GL_LINE_STRIP); | 
					
						
							|  |  |  | 					/*vec[1]= v2d->cur.ymax;*/ // this is set already. this line is only included
 | 
					
						
							|  |  |  | 					glVertex2fv(vec); | 
					
						
							| 
									
										
										
										
											2011-07-12 12:04:27 +00:00
										 |  |  | 					 | 
					
						
							| 
									
										
										
										
											2010-05-03 15:56:44 +00:00
										 |  |  | 					vec[1]= v2d->cur.ymin; | 
					
						
							|  |  |  | 					glVertex2fv(vec); | 
					
						
							|  |  |  | 				glEnd(); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	glLineWidth(1.0); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* Draw current frame number in a little box */ | 
					
						
							|  |  |  | 	if (flag & DRAWCFRA_SHOW_NUMBOX) { | 
					
						
							| 
									
										
										
										
											2010-10-14 01:22:14 +00:00
										 |  |  | 		UI_view2d_view_orthoSpecial(CTX_wm_region(C), v2d, 1); | 
					
						
							| 
									
										
										
										
											2008-12-22 09:43:29 +00:00
										 |  |  | 		draw_cfra_number(scene, v2d, vec[0], (flag & DRAWCFRA_UNIT_SECONDS)); | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* *************************************************** */ | 
					
						
							|  |  |  | /* PREVIEW RANGE 'CURTAINS' */ | 
					
						
							| 
									
										
										
										
											2008-12-27 05:24:03 +00:00
										 |  |  | /* Note: 'Preview Range' tools are defined in anim_ops.c */ | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | /* Draw preview range 'curtains' for highlighting where the animation data is */ | 
					
						
							|  |  |  | void ANIM_draw_previewrange (const bContext *C, View2D *v2d) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	Scene *scene= CTX_data_scene(C); | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* only draw this if preview range is set */ | 
					
						
							| 
									
										
										
										
											2010-01-19 20:30:04 +00:00
										 |  |  | 	if (PRVRANGEON) { | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | 
					
						
							|  |  |  | 		glEnable(GL_BLEND); | 
					
						
							|  |  |  | 		glColor4f(0.0f, 0.0f, 0.0f, 0.4f); | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* only draw two separate 'curtains' if there's no overlap between them */ | 
					
						
							|  |  |  | 		if (PSFRA < PEFRA) { | 
					
						
							| 
									
										
										
										
											2009-01-02 00:56:48 +00:00
										 |  |  | 			glRectf(v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax); | 
					
						
							|  |  |  | 			glRectf((float)PEFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);	 | 
					
						
							| 
									
										
										
										
											2008-12-20 08:24:24 +00:00
										 |  |  | 		}  | 
					
						
							|  |  |  | 		else { | 
					
						
							|  |  |  | 			glRectf(v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax); | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		glDisable(GL_BLEND); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* *************************************************** */ | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | /* NLA-MAPPING UTILITIES (required for drawing and also editing keyframes)  */ | 
					
						
							| 
									
										
										
										
											2008-12-22 08:13:25 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-23 13:25:31 +00:00
										 |  |  | /* Obtain the AnimData block providing NLA-mapping for the given channel (if applicable) */ | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | // TODO: do not supply return this if the animdata tells us that there is no mapping to perform
 | 
					
						
							| 
									
										
										
										
											2009-06-23 13:25:31 +00:00
										 |  |  | AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale) | 
					
						
							| 
									
										
										
										
											2008-12-22 08:13:25 +00:00
										 |  |  | { | 
					
						
							|  |  |  | 	/* sanity checks */ | 
					
						
							|  |  |  | 	if (ac == NULL) | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* handling depends on the type of animation-context we've got */ | 
					
						
							| 
									
										
										
										
											2009-07-28 06:50:30 +00:00
										 |  |  | 	if (ale) | 
					
						
							|  |  |  | 		return ale->adt; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return NULL; | 
					
						
							| 
									
										
										
										
											2008-12-22 08:13:25 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | /* ------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-23 13:25:31 +00:00
										 |  |  | /* helper function for ANIM_nla_mapping_apply_fcurve() -> "restore", i.e. mapping points back to action-time */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | static short bezt_nlamapping_restore(KeyframeEditData *ked, BezTriple *bezt) | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-15 10:34:39 +00:00
										 |  |  | 	/* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | 	AnimData *adt= (AnimData *)ked->data; | 
					
						
							|  |  |  | 	short only_keys= (short)ked->i1; | 
					
						
							| 
									
										
										
										
											2010-01-15 10:34:39 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* adjust BezTriple handles only if allowed to */ | 
					
						
							|  |  |  | 	if (only_keys == 0) { | 
					
						
							|  |  |  | 		bezt->vec[0][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_UNMAP); | 
					
						
							|  |  |  | 		bezt->vec[2][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_UNMAP); | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	bezt->vec[1][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_UNMAP); | 
					
						
							| 
									
										
										
										
											2009-01-03 10:03:26 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-23 13:25:31 +00:00
										 |  |  | /* helper function for ANIM_nla_mapping_apply_fcurve() -> "apply", i.e. mapping points to NLA-mapped global time */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | static short bezt_nlamapping_apply(KeyframeEditData *ked, BezTriple *bezt) | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2009-06-23 13:25:31 +00:00
										 |  |  | 	/* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | 	AnimData *adt= (AnimData*)ked->data; | 
					
						
							|  |  |  | 	short only_keys= (short)ked->i1; | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* adjust BezTriple handles only if allowed to */ | 
					
						
							|  |  |  | 	if (only_keys == 0) { | 
					
						
							| 
									
										
										
										
											2009-06-28 07:32:00 +00:00
										 |  |  | 		bezt->vec[0][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_MAP); | 
					
						
							|  |  |  | 		bezt->vec[2][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_MAP); | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2009-06-23 13:25:31 +00:00
										 |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-06-28 07:32:00 +00:00
										 |  |  | 	bezt->vec[1][0]= BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_MAP); | 
					
						
							| 
									
										
										
										
											2009-01-03 10:03:26 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-01-20 11:07:42 +00:00
										 |  |  | /* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve 
 | 
					
						
							|  |  |  |  *	- restore = whether to map points back to non-mapped time  | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  |  * 	- only_keys = whether to only adjust the location of the center point of beztriples | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2010-01-15 10:34:39 +00:00
										 |  |  | void ANIM_nla_mapping_apply_fcurve (AnimData *adt, FCurve *fcu, short restore, short only_keys) | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2011-02-13 10:52:18 +00:00
										 |  |  | 	KeyframeEditData ked= {{NULL}}; | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | 	KeyframeEditFunc map_cb; | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* init edit data 
 | 
					
						
							| 
									
										
										
										
											2009-06-23 13:25:31 +00:00
										 |  |  | 	 *	- AnimData is stored in 'data' | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | 	 *	- only_keys is stored in 'i1' | 
					
						
							|  |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | 	ked.data= (void *)adt; | 
					
						
							|  |  |  | 	ked.i1= (int)only_keys; | 
					
						
							| 
									
										
										
										
											2009-01-03 06:01:11 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* get editing callback */ | 
					
						
							|  |  |  | 	if (restore) | 
					
						
							|  |  |  | 		map_cb= bezt_nlamapping_restore; | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		map_cb= bezt_nlamapping_apply; | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2009-01-20 11:07:42 +00:00
										 |  |  | 	/* apply to F-Curve */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | 	ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, map_cb, NULL); | 
					
						
							| 
									
										
										
										
											2009-09-27 06:14:42 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* *************************************************** */ | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | /* UNITS CONVERSION MAPPING (required for drawing and editing keyframes) */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Get unit conversion factor for given ID + F-Curve */ | 
					
						
							|  |  |  | float ANIM_unit_mapping_get_factor (Scene *scene, ID *id, FCurve *fcu, short restore) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	/* sanity checks */ | 
					
						
							|  |  |  | 	if (id && fcu && fcu->rna_path)  | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		PointerRNA ptr, id_ptr; | 
					
						
							|  |  |  | 		PropertyRNA *prop; | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | 		/* get RNA property that F-Curve affects */ | 
					
						
							|  |  |  | 		RNA_id_pointer_create(id, &id_ptr); | 
					
						
							|  |  |  | 		if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop))  | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			/* rotations: radians <-> degrees? */ | 
					
						
							|  |  |  | 			if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				/* if the radians flag is not set, default to using degrees which need conversions */ | 
					
						
							| 
									
										
										
										
											2010-11-18 14:10:09 +00:00
										 |  |  | 				if ((scene) && (scene->unit.system_rotation == USER_UNIT_ROT_RADIANS) == 0) { | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 					if (restore) | 
					
						
							| 
									
										
										
										
											2011-03-27 17:22:04 +00:00
										 |  |  | 						return M_PI / 180.0;	/* degrees to radians */ | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 					else | 
					
						
							| 
									
										
										
										
											2011-03-27 17:22:04 +00:00
										 |  |  | 						return 180.0 / M_PI;	/* radians to degrees */ | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 				} | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 			 | 
					
						
							|  |  |  | 			// TODO: other rotation types here as necessary
 | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* no mapping needs to occur... */ | 
					
						
							|  |  |  | 	return 1.0f; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* ----------------------- */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* helper function for ANIM_unit_mapping_apply_fcurve -> mapping callback for unit mapping */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | static short bezt_unit_mapping_apply (KeyframeEditData *ked, BezTriple *bezt) | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-01-26 09:25:32 +00:00
										 |  |  | 	/* mapping factor is stored in f1, flags are stored in i1 */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | 	short only_keys= (ked->i1 & ANIM_UNITCONV_ONLYKEYS); | 
					
						
							|  |  |  | 	short sel_vs= (ked->i1 & ANIM_UNITCONV_SELVERTS); | 
					
						
							|  |  |  | 	float fac= ked->f1; | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* adjust BezTriple handles only if allowed to */ | 
					
						
							|  |  |  | 	if (only_keys == 0) { | 
					
						
							| 
									
										
										
										
											2010-01-26 09:25:32 +00:00
										 |  |  | 		if ((sel_vs==0) || (bezt->f1 & SELECT))  | 
					
						
							|  |  |  | 			bezt->vec[0][1] *= fac; | 
					
						
							|  |  |  | 		if ((sel_vs==0) || (bezt->f3 & SELECT))  | 
					
						
							|  |  |  | 			bezt->vec[2][1] *= fac; | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	 | 
					
						
							| 
									
										
										
										
											2010-01-26 09:25:32 +00:00
										 |  |  | 	if ((sel_vs == 0) || (bezt->f2 & SELECT)) | 
					
						
							|  |  |  | 		bezt->vec[1][1] *= fac; | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	return 0; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* Apply/Unapply units conversions to keyframes */ | 
					
						
							| 
									
										
										
										
											2010-01-26 09:25:32 +00:00
										 |  |  | void ANIM_unit_mapping_apply_fcurve (Scene *scene, ID *id, FCurve *fcu, short flag) | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | 	KeyframeEditData ked; | 
					
						
							|  |  |  | 	KeyframeEditFunc sel_cb; | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 	float fac; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* calculate mapping factor, and abort if nothing to change */ | 
					
						
							| 
									
										
										
										
											2010-01-26 09:25:32 +00:00
										 |  |  | 	fac= ANIM_unit_mapping_get_factor(scene, id, fcu, (flag & ANIM_UNITCONV_RESTORE)); | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 	if (fac == 1.0f) | 
					
						
							|  |  |  | 		return; | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | 	/* init edit data 
 | 
					
						
							|  |  |  | 	 *	- mapping factor is stored in f1 | 
					
						
							| 
									
										
										
										
											2010-01-26 09:25:32 +00:00
										 |  |  | 	 *	- flags are stored in 'i1' | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 	 */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | 	memset(&ked, 0, sizeof(KeyframeEditData)); | 
					
						
							|  |  |  | 	ked.f1= (float)fac; | 
					
						
							|  |  |  | 	ked.i1= (int)flag; | 
					
						
							| 
									
										
										
										
											2010-01-26 09:25:32 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* only selected? */ | 
					
						
							|  |  |  | 	if (flag & ANIM_UNITCONV_ONLYSEL) | 
					
						
							|  |  |  | 		sel_cb= ANIM_editkeyframes_ok(BEZT_OK_SELECTED); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		sel_cb= NULL; | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	/* apply to F-Curve */ | 
					
						
							| 
									
										
										
										
											2010-04-02 12:02:39 +00:00
										 |  |  | 	ANIM_fcurve_keyframes_loop(&ked, fcu, sel_cb, bezt_unit_mapping_apply, NULL); | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 	 | 
					
						
							|  |  |  | 	// FIXME: loop here for samples should be generalised
 | 
					
						
							| 
									
										
										
										
											2010-01-26 09:25:32 +00:00
										 |  |  | 	// TODO: only sel?
 | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 	if (fcu->fpt) { | 
					
						
							|  |  |  | 		FPoint *fpt; | 
					
						
							| 
									
										
										
										
											2011-02-27 08:31:10 +00:00
										 |  |  | 		unsigned int i; | 
					
						
							| 
									
										
										
										
											2010-01-26 03:16:14 +00:00
										 |  |  | 		 | 
					
						
							|  |  |  | 		for (i=0, fpt=fcu->fpt; i < fcu->totvert; i++, fpt++) { | 
					
						
							|  |  |  | 			/* apply unit mapping */ | 
					
						
							|  |  |  | 			fpt->vec[1] *= fac; | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /* *************************************************** */ |