Exemple #1
0
/* get memory buffer for first uncached frame within prefetch frame range */
static unsigned char *prefetch_thread_next_frame(
        PrefetchQueue *queue, MovieClip *clip,
        size_t *r_size, int *r_current_frame)
{
	unsigned char *mem = NULL;

	BLI_spin_lock(&queue->spin);
	if (!*queue->stop && !check_prefetch_break() &&
	    IN_RANGE_INCL(queue->current_frame, queue->start_frame, queue->end_frame))
	{
		int current_frame;

		if (queue->forward) {
			current_frame = prefetch_find_uncached_frame(clip, queue->current_frame + 1, queue->end_frame,
			                                             queue->render_size, queue->render_flag, 1);
			/* switch direction if read frames from current up to scene end frames */
			if (current_frame > queue->end_frame) {
				queue->current_frame = queue->initial_frame;
				queue->forward = false;
			}
		}

		if (!queue->forward) {
			current_frame = prefetch_find_uncached_frame(clip, queue->current_frame - 1, queue->start_frame,
			                                             queue->render_size, queue->render_flag, -1);
		}

		if (IN_RANGE_INCL(current_frame, queue->start_frame, queue->end_frame)) {
			int frames_processed;

			mem = prefetch_read_file_to_memory(clip, current_frame, queue->render_size,
			                                   queue->render_flag, r_size);

			*r_current_frame = current_frame;

			queue->current_frame = current_frame;

			if (queue->forward) {
				frames_processed = queue->current_frame - queue->initial_frame;
			}
			else {
				frames_processed = (queue->end_frame - queue->initial_frame) +
				                   (queue->initial_frame - queue->current_frame);
			}

			*queue->do_update = 1;
			*queue->progress = (float)frames_processed / (queue->end_frame - queue->start_frame);
		}
	}
	BLI_spin_unlock(&queue->spin);

	return mem;
}
static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos, short channelLocked)
{
	ActKeyColumn *ak;
	ActKeyBlock *ab;
	float alpha;
	float xscale;
	float iconsize = U.widget_unit / 4.0f;
	glEnable(GL_BLEND);
	
	/* get View2D scaling factor */
	UI_view2d_scale_get(v2d, &xscale, NULL);
	
	/* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
	/* TODO: allow this opacity factor to be themed? */
	alpha = (channelLocked) ? 0.25f : 1.0f;
	
	/* draw keyblocks */
	if (blocks) {
		float sel_color[4], unsel_color[4];
		
		/* cache colours first */
		UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color);
		UI_GetThemeColor4fv(TH_STRIP, unsel_color);
		
		sel_color[3]   *= alpha;
		unsel_color[3] *= alpha;
		
		/* NOTE: the tradeoff for changing colors between each draw is dwarfed by the cost of checking validity */
		for (ab = blocks->first; ab; ab = ab->next) {
			if (actkeyblock_is_valid(ab, keys)) {
				/* draw block */
				if (ab->sel)
					glColor4fv(sel_color);
				else
					glColor4fv(unsel_color);
				
				glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize);
			}
		}
	}
	
	/* draw keys */
	if (keys) {
		for (ak = keys->first; ak; ak = ak->next) {
			/* optimization: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw
			 *	- this might give some improvements, since we current have to flip between view/region matrices
			 */
			if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax) == 0)
				continue;
			
			/* draw using OpenGL - uglier but faster */
			/* NOTE1: a previous version of this didn't work nice for some intel cards
			 * NOTE2: if we wanted to go back to icons, these are  icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */
			draw_keyframe_shape(ak->cfra, ypos, xscale, iconsize, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, alpha);
		}
	}

	glDisable(GL_BLEND);
}
Exemple #3
0
static void voronoi_clampEdgeVertex(int width, int height, float *coord, float *other_coord)
{
  const float corners[4][2] = {
      {0.0f, 0.0f}, {width - 1, 0.0f}, {width - 1, height - 1}, {0.0f, height - 1}};
  int i;

  if (IN_RANGE_INCL(coord[0], 0, width - 1) && IN_RANGE_INCL(coord[1], 0, height - 1)) {
    return;
  }

  for (i = 0; i < 4; i++) {
    float v1[2], v2[2];
    float p[2];

    copy_v2_v2(v1, corners[i]);

    if (i == 3) {
      copy_v2_v2(v2, corners[0]);
    }
    else {
      copy_v2_v2(v2, corners[i + 1]);
    }

    if (isect_seg_seg_v2_point(v1, v2, coord, other_coord, p) == 1) {
      if (i == 0 && coord[1] > p[1]) {
        continue;
      }
      if (i == 1 && coord[0] < p[0]) {
        continue;
      }
      if (i == 2 && coord[1] < p[1]) {
        continue;
      }
      if (i == 3 && coord[0] > p[0]) {
        continue;
      }

      copy_v2_v2(coord, p);
    }
  }
}
void KeyingScreenOperation::executePixel(float output[4], int x, int y, void *data)
{
	output[0] = 0.0f;
	output[1] = 0.0f;
	output[2] = 0.0f;
	output[3] = 1.0f;

	if (this->m_movieClip && data) {
		TriangulationData *triangulation = this->m_cachedTriangulation;
		TileData *tile_data = (TileData *) data;
		int i;
		float co[2] = {(float) x, (float) y};

		for (i = 0; i < tile_data->triangles_total; i++) {
			int triangle_idx = tile_data->triangles[i];
			rctf *rect = &triangulation->triangles_AABB[triangle_idx];

			if (IN_RANGE_INCL(x, rect->xmin, rect->xmax) && IN_RANGE_INCL(y, rect->ymin, rect->ymax)) {
				int *triangle = triangulation->triangles[triangle_idx];
				VoronoiTriangulationPoint *a = &triangulation->triangulated_points[triangle[0]],
				                          *b = &triangulation->triangulated_points[triangle[1]],
				                          *c = &triangulation->triangulated_points[triangle[2]];
				float w[3];

				if (barycentric_coords_v2(a->co, b->co, c->co, co, w)) {
					if (barycentric_inside_triangle_v2(w)) {
						output[0] = a->color[0] * w[0] + b->color[0] * w[1] + c->color[0] * w[2];
						output[1] = a->color[1] * w[0] + b->color[1] * w[1] + c->color[1] * w[2];
						output[2] = a->color[2] * w[0] + b->color[2] * w[1] + c->color[2] * w[2];

						break;
					}
				}
			}
		}
	}
}
Exemple #5
0
/* Try to find NLA Strip to use for action layer up/down tool */
static NlaStrip *action_layer_get_nlastrip(ListBase *strips, float ctime)
{
	NlaStrip *strip;
	
	for (strip = strips->first; strip; strip = strip->next) {
		/* Can we use this? */
		if (IN_RANGE_INCL(ctime, strip->start, strip->end)) {
			/* in range - use this one */
			return strip;
		}
		else if ((ctime < strip->start) && (strip->prev == NULL)) {
			/* before first - use this one */
			return strip;
		}
		else if ((ctime > strip->end) && (strip->next == NULL)) {
			/* after last - use this one */
			return strip;
		}
	}
	
	/* nothing suitable found... */
	return NULL;
}
static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, float *r_offset)
{
	float factor = 1.0f, offset = 0.0f;

	if (flag & ANIM_UNITCONV_RESTORE) {
		if (r_offset)
			*r_offset = fcu->prev_offset;

		return 1.0f / fcu->prev_norm_factor;
	}

	if (flag & ANIM_UNITCONV_NORMALIZE_FREEZE) {
		if (r_offset)
			*r_offset = fcu->prev_offset;
		if (fcu->prev_norm_factor == 0.0f) {
			/* Happens when Auto Normalize was disabled before
			 * any curves were displayed.
			 */
			return 1.0f;
		}
		return fcu->prev_norm_factor;
	}

	if (G.moving & G_TRANSFORM_FCURVES) {
		if (r_offset)
			*r_offset = fcu->prev_offset;
		if (fcu->prev_norm_factor == 0.0f) {
			/* Same as above. */
			return 1.0f;
		}
		return fcu->prev_norm_factor;
	}

	fcu->prev_norm_factor = 1.0f;
	if (fcu->bezt) {
		BezTriple *bezt;
		int i;
		float max_coord = -FLT_MAX;
		float min_coord = FLT_MAX;
		float range;

		if (fcu->totvert < 1) {
			return 1.0f;
		}

		if (PRVRANGEON) {
			for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
				if (IN_RANGE_INCL(bezt->vec[1][0], scene->r.psfra, scene->r.pefra)) {
					max_coord = max_ff(max_coord, bezt->vec[0][1]);
					max_coord = max_ff(max_coord, bezt->vec[1][1]);
					max_coord = max_ff(max_coord, bezt->vec[2][1]);

					min_coord = min_ff(min_coord, bezt->vec[0][1]);
					min_coord = min_ff(min_coord, bezt->vec[1][1]);
					min_coord = min_ff(min_coord, bezt->vec[2][1]);
				}
			}
		}
		else {
			for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
				max_coord = max_ff(max_coord, bezt->vec[0][1]);
				max_coord = max_ff(max_coord, bezt->vec[1][1]);
				max_coord = max_ff(max_coord, bezt->vec[2][1]);

				min_coord = min_ff(min_coord, bezt->vec[0][1]);
				min_coord = min_ff(min_coord, bezt->vec[1][1]);
				min_coord = min_ff(min_coord, bezt->vec[2][1]);
			}
		}

		range = max_coord - min_coord;

		if (range > FLT_EPSILON) {
			factor = 2.0f / range;
		}
		offset = -min_coord - range / 2.0f;
	}
	BLI_assert(factor != 0.0f);
	if (r_offset) {
		*r_offset = offset;
	}

	fcu->prev_norm_factor = factor;
	fcu->prev_offset = offset;
	return factor;
}
KeyingScreenOperation::TriangulationData *KeyingScreenOperation::buildVoronoiTriangulation()
{
	MovieClipUser user = {0};
	TriangulationData *triangulation;
	MovieTracking *tracking = &this->m_movieClip->tracking;
	MovieTrackingTrack *track;
	VoronoiSite *sites, *site;
	ImBuf *ibuf;
	ListBase *tracksbase;
	ListBase edges = {NULL, NULL};
	int sites_total;
	int i;
	int width = this->getWidth();
	int height = this->getHeight();
	int clip_frame = BKE_movieclip_remap_scene_to_clip_frame(this->m_movieClip, this->m_framenumber);

	if (this->m_trackingObject[0]) {
		MovieTrackingObject *object = BKE_tracking_object_get_named(tracking, this->m_trackingObject);

		if (!object)
			return NULL;

		tracksbase = BKE_tracking_object_get_tracks(tracking, object);
	}
	else
		tracksbase = BKE_tracking_get_active_tracks(tracking);

	/* count sites */
	for (track = (MovieTrackingTrack *) tracksbase->first, sites_total = 0; track; track = track->next) {
		MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame);
		float pos[2];

		if (marker->flag & MARKER_DISABLED)
			continue;

		add_v2_v2v2(pos, marker->pos, track->offset);

		if (!IN_RANGE_INCL(pos[0], 0.0f, 1.0f) ||
		    !IN_RANGE_INCL(pos[1], 0.0f, 1.0f))
		{
			continue;
		}

		sites_total++;
	}

	if (!sites_total)
		return NULL;

	BKE_movieclip_user_set_frame(&user, clip_frame);
	ibuf = BKE_movieclip_get_ibuf(this->m_movieClip, &user);

	if (!ibuf)
		return NULL;

	triangulation = (TriangulationData *) MEM_callocN(sizeof(TriangulationData), "keying screen triangulation data");

	sites = (VoronoiSite *) MEM_callocN(sizeof(VoronoiSite) * sites_total, "keyingscreen voronoi sites");
	track = (MovieTrackingTrack *) tracksbase->first;
	for (track = (MovieTrackingTrack *) tracksbase->first, site = sites; track; track = track->next) {
		MovieTrackingMarker *marker = BKE_tracking_marker_get(track, clip_frame);
		ImBuf *pattern_ibuf;
		int j;
		float pos[2];

		if (marker->flag & MARKER_DISABLED)
			continue;

		add_v2_v2v2(pos, marker->pos, track->offset);

		if (!IN_RANGE_INCL(pos[0], 0.0f, 1.0f) ||
		    !IN_RANGE_INCL(pos[1], 0.0f, 1.0f))
		{
			continue;
		}

		pattern_ibuf = BKE_tracking_get_pattern_imbuf(ibuf, track, marker, TRUE, FALSE);

		zero_v3(site->color);

		if (pattern_ibuf) {
			for (j = 0; j < pattern_ibuf->x * pattern_ibuf->y; j++) {
				if (pattern_ibuf->rect_float) {
					add_v3_v3(site->color, &pattern_ibuf->rect_float[4 * j]);
				}
				else {
					unsigned char *rrgb = (unsigned char *)pattern_ibuf->rect;

					site->color[0] += srgb_to_linearrgb((float)rrgb[4 * j + 0] / 255.0f);
					site->color[1] += srgb_to_linearrgb((float)rrgb[4 * j + 1] / 255.0f);
					site->color[2] += srgb_to_linearrgb((float)rrgb[4 * j + 2] / 255.0f);
				}
			}

			mul_v3_fl(site->color, 1.0f / (pattern_ibuf->x * pattern_ibuf->y));
			IMB_freeImBuf(pattern_ibuf);
		}

		site->co[0] = pos[0] * width;
		site->co[1] = pos[1] * height;

		site++;
	}

	IMB_freeImBuf(ibuf);

	BLI_voronoi_compute(sites, sites_total, width, height, &edges);

	BLI_voronoi_triangulate(sites, sites_total, &edges, width, height,
	                        &triangulation->triangulated_points, &triangulation->triangulated_points_total,
	                        &triangulation->triangles, &triangulation->triangles_total);

	MEM_freeN(sites);
	BLI_freelistN(&edges);

	if (triangulation->triangles_total) {
		rctf *rect;
		rect = triangulation->triangles_AABB =
			(rctf *) MEM_callocN(sizeof(rctf) * triangulation->triangles_total, "voronoi triangulation AABB");

		for (i = 0; i < triangulation->triangles_total; i++, rect++) {
			int *triangle = triangulation->triangles[i];
			VoronoiTriangulationPoint *a = &triangulation->triangulated_points[triangle[0]],
			                          *b = &triangulation->triangulated_points[triangle[1]],
			                          *c = &triangulation->triangulated_points[triangle[2]];

			float min[2], max[2];

			INIT_MINMAX2(min, max);

			minmax_v2v2_v2(min, max, a->co);
			minmax_v2v2_v2(min, max, b->co);
			minmax_v2v2_v2(min, max, c->co);

			rect->xmin = min[0];
			rect->ymin = min[1];

			rect->xmax = max[0];
			rect->ymax = max[1];
		}
	}

	return triangulation;
}
Exemple #8
0
static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, float *r_offset)
{
	float factor = 1.0f, offset = 0.0f;

	if (flag & ANIM_UNITCONV_RESTORE) {
		if (r_offset)
			*r_offset = fcu->prev_offset;

		return 1.0f / fcu->prev_norm_factor;
	}

	if (flag & ANIM_UNITCONV_NORMALIZE_FREEZE) {
		if (r_offset)
			*r_offset = fcu->prev_offset;
		if (fcu->prev_norm_factor == 0.0f) {
			/* Happens when Auto Normalize was disabled before
			 * any curves were displayed.
			 */
			return 1.0f;
		}
		return fcu->prev_norm_factor;
	}

	if (G.moving & G_TRANSFORM_FCURVES) {
		if (r_offset)
			*r_offset = fcu->prev_offset;
		if (fcu->prev_norm_factor == 0.0f) {
			/* Same as above. */
			return 1.0f;
		}
		return fcu->prev_norm_factor;
	}

	fcu->prev_norm_factor = 1.0f;
	if (fcu->bezt) {
		const bool use_preview_only = PRVRANGEON;
		const BezTriple *bezt;
		int i;
		float max_coord = -FLT_MAX;
		float min_coord = FLT_MAX;
		float range;

		if (fcu->totvert < 1) {
			return 1.0f;
		}

		for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
			if (use_preview_only && !IN_RANGE_INCL(bezt->vec[1][0],
			                                       scene->r.psfra,
			                                       scene->r.pefra))
			{
				continue;
			}

			if (i == 0) {
				/* We ignore extrapolation flags and handle here, and use the
				 * control point position only. so we normalize "interesting"
				 * part of the curve.
				 *
				 * Here we handle left extrapolation.
				 */
				max_coord = max_ff(max_coord, bezt->vec[1][1]);

				min_coord = min_ff(min_coord, bezt->vec[1][1]);
			}
			else {
				const BezTriple *prev_bezt = bezt - 1;
				if (prev_bezt->ipo == BEZT_IPO_CONST) {
					/* Constant interpolation: previous CV value is used up
					 * to the current keyframe.
					 */
					max_coord = max_ff(max_coord, bezt->vec[1][1]);
					min_coord = min_ff(min_coord, bezt->vec[1][1]);
				}
				else if (prev_bezt->ipo == BEZT_IPO_LIN) {
					/* Linear interpolation: min/max using both previous and
					 * and current CV.
					 */
					max_coord = max_ff(max_coord, bezt->vec[1][1]);
					min_coord = min_ff(min_coord, bezt->vec[1][1]);
					max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
					min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
				}
				else if (prev_bezt->ipo == BEZT_IPO_BEZ) {
					const int resol = fcu->driver
					        ? 32
					        : min_ii((int)(5.0f * len_v2v2(bezt->vec[1], prev_bezt->vec[1])), 32);
					if (resol < 2) {
						max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
						min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
					}
					else {
						float data[120];
						float v1[2], v2[2], v3[2], v4[2];

						v1[0] = prev_bezt->vec[1][0];
						v1[1] = prev_bezt->vec[1][1];
						v2[0] = prev_bezt->vec[2][0];
						v2[1] = prev_bezt->vec[2][1];

						v3[0] = bezt->vec[0][0];
						v3[1] = bezt->vec[0][1];
						v4[0] = bezt->vec[1][0];
						v4[1] = bezt->vec[1][1];

						correct_bezpart(v1, v2, v3, v4);

						BKE_curve_forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
						BKE_curve_forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);

						for (int j = 0; j <= resol; ++j) {
							const float *fp = &data[j * 3];
							max_coord = max_ff(max_coord, fp[1]);
							min_coord = min_ff(min_coord, fp[1]);
						}
					}
				}
			}
		}

		if (max_coord > min_coord) {
			range = max_coord - min_coord;
			if (range > FLT_EPSILON) {
				factor = 2.0f / range;
			}
			offset = -min_coord - range / 2.0f;
		}
		else if (max_coord == min_coord) {
			factor = 1.0f;
			offset = -min_coord;
		}
	}
	BLI_assert(factor != 0.0f);
	if (r_offset) {
		*r_offset = offset;
	}

	fcu->prev_norm_factor = factor;
	fcu->prev_offset = offset;
	return factor;
}