예제 #1
0
static void draw_tracks_error_curves(SpaceClip *sc)
{
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	TrackErrorCurveUserData data;

	data.clip = clip;
	data.tracking = tracking;
	data.tracking_object = BKE_tracking_object_get_active(tracking);
	data.active_track = BKE_tracking_track_get_active(tracking);
	data.matrix_initialized = false;
	BKE_movieclip_get_size(clip, &sc->user, &data.width, &data.height);
	data.aspy = 1.0f / tracking->camera.pixel_aspect;

	if (!data.width || !data.height) {
		return;
	}

	clip_graph_tracking_values_iterate(sc,
	                                   (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
	                                   (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
	                                   &data,
	                                   tracking_error_segment_point_cb,
	                                   tracking_error_segment_start_cb,
	                                   tracking_error_segment_end_cb);
}
예제 #2
0
static int set_origin_exec(bContext *C, wmOperator *op)
{
  SpaceClip *sc = CTX_wm_space_clip(C);
  MovieClip *clip = ED_space_clip_get_clip(sc);
  MovieTracking *tracking = &clip->tracking;
  Scene *scene = CTX_data_scene(C);
  Object *camera = get_camera_with_movieclip(scene, clip);
  int selected_count = count_selected_bundles(C);

  if (selected_count == 0) {
    BKE_report(op->reports,
               RPT_ERROR,
               "At least one track with bundle should be selected to "
               "define origin position");

    return OPERATOR_CANCELLED;
  }

  Object *object = get_orientation_object(C);
  if (object == NULL) {
    BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
    return OPERATOR_CANCELLED;
  }

  MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
  ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);

  float median[3] = {0.0f, 0.0f, 0.0f};
  zero_v3(median);
  for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) {
    if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) {
      add_v3_v3(median, track->bundle_pos);
    }
  }
  mul_v3_fl(median, 1.0f / selected_count);

  float mat[4][4], vec[3];
  BKE_tracking_get_camera_object_matrix(scene, camera, mat);
  mul_v3_m4v3(vec, mat, median);

  if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
    sub_v3_v3(object->loc, vec);
  }
  else {
    object_solver_inverted_matrix(scene, object, mat);
    mul_v3_m4v3(vec, mat, vec);
    copy_v3_v3(object->loc, vec);
  }

  DEG_id_tag_update(&clip->id, 0);
  DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM);

  WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
  WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);

  return OPERATOR_FINISHED;
}
예제 #3
0
static bool apply_solution_scale_poll(bContext *C)
{
  SpaceClip *sc = CTX_wm_space_clip(C);
  if (sc != NULL) {
    MovieClip *clip = ED_space_clip_get_clip(sc);
    if (clip != NULL) {
      MovieTracking *tracking = &clip->tracking;
      MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
      return (tracking_object->flag & TRACKING_OBJECT_CAMERA) != 0;
    }
  }
  return 0;
}
예제 #4
0
static int set_axis_exec(bContext *C, wmOperator *op)
{
    SpaceClip *sc = CTX_wm_space_clip(C);
    MovieClip *clip = ED_space_clip_get_clip(sc);
    MovieTracking *tracking = &clip->tracking;
    MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
    Scene *scene = CTX_data_scene(C);
    Object *object;
    int axis = RNA_enum_get(op->ptr, "axis");

    if (count_selected_bundles(C) != 1) {
        BKE_report(op->reports,
                   RPT_ERROR,
                   "Single track with bundle should be selected to define axis");
        return OPERATOR_CANCELLED;
    }

    object = get_orientation_object(C);
    if (object == NULL) {
        BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
        return OPERATOR_CANCELLED;
    }

    ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking,
                           tracking_object);
    MovieTrackingTrack *track = tracksbase->first;
    while (track) {
        if (TRACK_VIEW_SELECTED(sc, track) &&
                (track->flag & TRACK_HAS_BUNDLE))
        {
            break;
        }
        track = track->next;
    }

    set_axis(scene, object, clip, tracking_object, track, axis == 0 ? 'X' : 'Y');

    DAG_id_tag_update(&clip->id, 0);
    DAG_id_tag_update(&object->id, OB_RECALC_OB);

    WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
    WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);

    return OPERATOR_FINISHED;
}
예제 #5
0
static bool mouse_select_curve(bContext *C, float co[2], bool extend)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingTrack *act_track = BKE_tracking_track_get_active(tracking);
	MouseSelectUserData userdata;

	mouse_select_init_data(&userdata, co);
	clip_graph_tracking_values_iterate(sc,
	                                   (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
	                                   (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
	                                   &userdata, find_nearest_tracking_segment_cb,
	                                   NULL, find_nearest_tracking_segment_end_cb);

	if (userdata.track) {
		if (extend) {
			if (act_track == userdata.track) {
				/* currently only single curve can be selected (selected curve represents active track) */
				act_track = NULL;
			}
		}
		else if (act_track != userdata.track) {
			SelectUserData selectdata = {SEL_DESELECT};
			MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);

			tracking->act_track = userdata.track;
			if ((sc->flag & SC_SHOW_GRAPH_SEL_ONLY) == 0) {
				ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
				BKE_tracking_track_select(tracksbase, userdata.track, TRACK_AREA_ALL, false);
			}

			/* deselect all knots on newly selected curve */
			clip_graph_tracking_iterate(sc,
			                            (sc->flag & SC_SHOW_GRAPH_SEL_ONLY) != 0,
			                            (sc->flag & SC_SHOW_GRAPH_HIDDEN) != 0,
			                            &selectdata, toggle_selection_cb);
		}

		return true;
	}

	return false;
}
static int dopesheet_select_channel_exec(bContext *C, wmOperator *op)
{
	SpaceClip *sc = CTX_wm_space_clip(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
	MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
	MovieTrackingDopesheetChannel *channel;
	ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
	float location[2];
	const bool extend = RNA_boolean_get(op->ptr, "extend");
	int current_channel_index = 0, channel_index;
	const bool show_selected_only = (dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY) != 0;

	RNA_float_get_array(op->ptr, "location", location);
	channel_index = -(location[1] - (CHANNEL_FIRST + CHANNEL_HEIGHT_HALF)) / CHANNEL_STEP;

	for (channel = dopesheet->channels.first; channel; channel = channel->next) {
		MovieTrackingTrack *track = channel->track;

		if (current_channel_index == channel_index) {
			if (extend)
				track->flag ^= TRACK_DOPE_SEL;
			else
				track->flag |= TRACK_DOPE_SEL;

			if (track->flag & TRACK_DOPE_SEL) {
				tracking->act_track = track;
				BKE_tracking_track_select(tracksbase, track, TRACK_AREA_ALL, true);
			}
			else if (show_selected_only == false) {
				BKE_tracking_track_deselect(track, TRACK_AREA_ALL);
			}
		}
		else if (!extend)
			track->flag &= ~TRACK_DOPE_SEL;

		current_channel_index++;
	}

	WM_event_add_notifier(C, NC_GEOM | ND_SELECT, NULL);

	return OPERATOR_FINISHED;
}
예제 #7
0
static bool set_orientation_poll(bContext *C)
{
  SpaceClip *sc = CTX_wm_space_clip(C);
  if (sc != NULL) {
    ViewLayer *view_layer = CTX_data_view_layer(C);
    MovieClip *clip = ED_space_clip_get_clip(sc);
    if (clip != NULL) {
      MovieTracking *tracking = &clip->tracking;
      MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
      if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
        return true;
      }
      else {
        return OBACT(view_layer) != NULL;
      }
    }
  }
  return false;
}
예제 #8
0
static Object *get_orientation_object(bContext *C)
{
    Scene *scene = CTX_data_scene(C);
    SpaceClip *sc = CTX_wm_space_clip(C);
    MovieClip *clip = ED_space_clip_get_clip(sc);
    MovieTracking *tracking = &clip->tracking;
    MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
    Object *object = NULL;

    if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
        object = get_camera_with_movieclip(scene, clip);
    }
    else {
        object = OBACT;
    }

    if (object != NULL && object->parent != NULL) {
        object = object->parent;
    }

    return object;
}
예제 #9
0
static int mask_parent_set_exec(bContext *C, wmOperator *UNUSED(op))
{
	Mask *mask = CTX_data_edit_mask(C);
	MaskLayer *masklay;

	/* parent info */
	SpaceClip *sc = CTX_wm_space_clip(C);
	MovieClip *clip = ED_space_clip_get_clip(sc);
	MovieTracking *tracking;
	MovieTrackingTrack *track;
	MovieTrackingPlaneTrack *plane_track;
	MovieTrackingObject *tracking_object;
	/* done */

	int framenr, parent_type;
	float parmask_pos[2], orig_corners[4][2];
	char *sub_parent_name;

	if (ELEM(NULL, sc, clip)) {
		return OPERATOR_CANCELLED;
	}

	framenr = ED_space_clip_get_clip_frame_number(sc);

	tracking = &clip->tracking;
	tracking_object = BKE_tracking_object_get_active(&clip->tracking);

	if (tracking_object == NULL) {
		return OPERATOR_CANCELLED;
	}

	if ((track = BKE_tracking_track_get_active(tracking)) != NULL) {
		MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
		float marker_pos_ofs[2];

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

		BKE_mask_coord_from_movieclip(clip, &sc->user, parmask_pos, marker_pos_ofs);

		sub_parent_name = track->name;
		parent_type = MASK_PARENT_POINT_TRACK;
		memset(orig_corners, 0, sizeof(orig_corners));
	}
	else if ((plane_track = BKE_tracking_plane_track_get_active(tracking)) != NULL) {
		MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);

		zero_v2(parmask_pos);
		sub_parent_name = plane_track->name;
		parent_type = MASK_PARENT_PLANE_TRACK;
		memcpy(orig_corners, plane_marker->corners, sizeof(orig_corners));
	}
	else {
		return OPERATOR_CANCELLED;
	}

	for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
		MaskSpline *spline;
		int i;

		if (masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) {
			continue;
		}

		for (spline = masklay->splines.first; spline; spline = spline->next) {
			for (i = 0; i < spline->tot_point; i++) {
				MaskSplinePoint *point = &spline->points[i];

				if (MASKPOINT_ISSEL_ANY(point)) {
					point->parent.id_type = ID_MC;
					point->parent.id = &clip->id;
					point->parent.type = parent_type;
					BLI_strncpy(point->parent.parent, tracking_object->name, sizeof(point->parent.parent));
					BLI_strncpy(point->parent.sub_parent, sub_parent_name, sizeof(point->parent.sub_parent));

					copy_v2_v2(point->parent.parent_orig, parmask_pos);
					memcpy(point->parent.parent_corners_orig, orig_corners, sizeof(point->parent.parent_corners_orig));
				}
			}
		}
	}

	WM_event_add_notifier(C, NC_MASK | ND_DATA, mask);
	DAG_id_tag_update(&mask->id, 0);

	return OPERATOR_FINISHED;
}
예제 #10
0
static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Scene *scene)
{
	float x;
	int *points, totseg, i, a;
	float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1);
	MovieTracking *tracking = &clip->tracking;
	MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking);
	MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking);
	MovieTrackingPlaneTrack *act_plane_track = BKE_tracking_plane_track_get_active(&clip->tracking);
	MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking);

	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

	/* cache background */
	ED_region_cache_draw_background(ar);

	/* cached segments -- could be usefu lto debug caching strategies */
	BKE_movieclip_get_cache_segments(clip, &sc->user, &totseg, &points);
	ED_region_cache_draw_cached_segments(ar, totseg, points, sfra, efra);

	/* track */
	if (act_track || act_plane_track) {
		for (i = sfra - clip->start_frame + 1, a = 0; i <= efra - clip->start_frame + 1; i++) {
			int framenr;
			int markersnr = generic_track_get_markersnr(act_track, act_plane_track);

			while (a < markersnr) {
				int marker_framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);

				if (marker_framenr >= i)
					break;

				if (a < markersnr - 1 && generic_track_get_marker_framenr(act_track, act_plane_track, a + 1) > i)
					break;

				a++;
			}

			a = min_ii(a, markersnr - 1);

			if (generic_track_is_marker_enabled(act_track, act_plane_track, a)) {
				framenr = generic_track_get_marker_framenr(act_track, act_plane_track, a);

				if (framenr != i)
					glColor4ub(128, 128, 0, 96);
				else if (generic_track_is_marker_keyframed(act_track, act_plane_track, a))
					glColor4ub(255, 255, 0, 196);
				else
					glColor4ub(255, 255, 0, 96);

				glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 4 * UI_DPI_FAC);
			}
		}
	}

	/* failed frames */
	if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
		int n = reconstruction->camnr;
		MovieReconstructedCamera *cameras = reconstruction->cameras;

		glColor4ub(255, 0, 0, 96);

		for (i = sfra, a = 0; i <= efra; i++) {
			bool ok = false;

			while (a < n) {
				if (cameras[a].framenr == i) {
					ok = true;
					break;
				}
				else if (cameras[a].framenr > i) {
					break;
				}

				a++;
			}

			if (!ok)
				glRecti((i - sfra + clip->start_frame - 1) * framelen, 0, (i - sfra + clip->start_frame) * framelen, 8 * UI_DPI_FAC);
		}
	}

	glDisable(GL_BLEND);

	/* current frame */
	x = (sc->user.framenr - sfra) / (efra - sfra + 1) * ar->winx;

	UI_ThemeColor(TH_CFRAME);
	glRecti(x, 0, x + ceilf(framelen), 8 * UI_DPI_FAC);

	ED_region_cache_draw_curfra_label(sc->user.framenr, x, 8.0f * UI_DPI_FAC);

	/* solver keyframes */
	glColor4ub(175, 255, 0, 255);
	draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2);
	draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2);

	/* movie clip animation */
	if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) {
		ED_mask_draw_frames(sc->mask_info.mask, ar, CFRA, sfra, efra);
	}
}
예제 #11
0
/* Draw all kind of tracks. */
static void draw_tracking_tracks(SpaceClip *sc, Scene *scene, ARegion *ar, MovieClip *clip,
                                 int width, int height, float zoomx, float zoomy)
{
	float x, y;
	MovieTracking *tracking = &clip->tracking;
	ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
	ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
	MovieTrackingTrack *track, *act_track;
	MovieTrackingPlaneTrack *plane_track, *active_plane_track;
	MovieTrackingMarker *marker;
	int framenr = ED_space_clip_get_clip_frame_number(sc);
	int undistort = sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT;
	float *marker_pos = NULL, *fp, *active_pos = NULL, cur_pos[2];

	/* ** find window pixel coordinates of origin ** */

	/* UI_view2d_view_to_region_no_clip return integer values, this could
	 * lead to 1px flickering when view is locked to selection during playbeck.
	 * to avoid this flickering, calculate base point in the same way as it happens
	 * in UI_view2d_view_to_region_no_clip, but do it in floats here */

	UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);

	glPushMatrix();
	glTranslatef(x, y, 0);

	glPushMatrix();
	glScalef(zoomx, zoomy, 0);
	glMultMatrixf(sc->stabmat);
	glScalef(width, height, 0);

	act_track = BKE_tracking_track_get_active(tracking);

	/* Draw plane tracks */
	active_plane_track = BKE_tracking_plane_track_get_active(tracking);
	for (plane_track = plane_tracks_base->first;
	     plane_track;
	     plane_track = plane_track->next)
	{
		if ((plane_track->flag & PLANE_TRACK_HIDDEN) == 0) {
			draw_plane_track(sc, scene, plane_track, framenr, plane_track == active_plane_track, width, height);
		}
	}

	if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) {
		int count = 0;

		/* count */
		track = tracksbase->first;
		while (track) {
			if ((track->flag & TRACK_HIDDEN) == 0) {
				marker = BKE_tracking_marker_get(track, framenr);

				if (MARKER_VISIBLE(sc, track, marker))
					count++;
			}

			track = track->next;
		}

		/* undistort */
		if (count) {
			marker_pos = MEM_callocN(2 * sizeof(float) * count, "draw_tracking_tracks marker_pos");

			track = tracksbase->first;
			fp = marker_pos;
			while (track) {
				if ((track->flag & TRACK_HIDDEN) == 0) {
					marker = BKE_tracking_marker_get(track, framenr);

					if (MARKER_VISIBLE(sc, track, marker)) {
						ED_clip_point_undistorted_pos(sc, marker->pos, fp);

						if (track == act_track)
							active_pos = fp;

						fp += 2;
					}
				}

				track = track->next;
			}
		}
	}

	if (sc->flag & SC_SHOW_TRACK_PATH) {
		track = tracksbase->first;
		while (track) {
			if ((track->flag & TRACK_HIDDEN) == 0)
				draw_track_path(sc, clip, track);

			track = track->next;
		}
	}

	/* markers outline and non-selected areas */
	track = tracksbase->first;
	fp = marker_pos;
	while (track) {
		if ((track->flag & TRACK_HIDDEN) == 0) {
			marker = BKE_tracking_marker_get(track, framenr);

			if (MARKER_VISIBLE(sc, track, marker)) {
				copy_v2_v2(cur_pos, fp ? fp : marker->pos);

				draw_marker_outline(sc, track, marker, cur_pos, width, height);
				draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 0);
				draw_marker_slide_zones(sc, track, marker, cur_pos, 1, 0, 0, width, height);
				draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 0, 0, width, height);

				if (fp)
					fp += 2;
			}
		}

		track = track->next;
	}

	/* selected areas only, so selection wouldn't be overlapped by
	 * non-selected areas */
	track = tracksbase->first;
	fp = marker_pos;
	while (track) {
		if ((track->flag & TRACK_HIDDEN) == 0) {
			int act = track == act_track;
			marker = BKE_tracking_marker_get(track, framenr);

			if (MARKER_VISIBLE(sc, track, marker)) {
				if (!act) {
					copy_v2_v2(cur_pos, fp ? fp : marker->pos);

					draw_marker_areas(sc, track, marker, cur_pos, width, height, 0, 1);
					draw_marker_slide_zones(sc, track, marker, cur_pos, 0, 1, 0, width, height);
				}

				if (fp)
					fp += 2;
			}
		}

		track = track->next;
	}

	/* active marker would be displayed on top of everything else */
	if (act_track) {
		if ((act_track->flag & TRACK_HIDDEN) == 0) {
			marker = BKE_tracking_marker_get(act_track, framenr);

			if (MARKER_VISIBLE(sc, act_track, marker)) {
				copy_v2_v2(cur_pos, active_pos ? active_pos : marker->pos);

				draw_marker_areas(sc, act_track, marker, cur_pos, width, height, 1, 1);
				draw_marker_slide_zones(sc, act_track, marker, cur_pos, 0, 1, 1, width, height);
			}
		}
	}

	if (sc->flag & SC_SHOW_BUNDLES) {
		MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
		float pos[4], vec[4], mat[4][4], aspy;

		glEnable(GL_POINT_SMOOTH);
		glPointSize(3.0f);

		aspy = 1.0f / clip->tracking.camera.pixel_aspect;
		BKE_tracking_get_projection_matrix(tracking, object, framenr, width, height, mat);

		track = tracksbase->first;
		while (track) {
			if ((track->flag & TRACK_HIDDEN) == 0 && track->flag & TRACK_HAS_BUNDLE) {
				marker = BKE_tracking_marker_get(track, framenr);

				if (MARKER_VISIBLE(sc, track, marker)) {
					float npos[2];
					copy_v3_v3(vec, track->bundle_pos);
					vec[3] = 1;

					mul_v4_m4v4(pos, mat, vec);

					pos[0] = (pos[0] / (pos[3] * 2.0f) + 0.5f) * width;
					pos[1] = (pos[1] / (pos[3] * 2.0f) + 0.5f) * height * aspy;

					BKE_tracking_distort_v2(tracking, pos, npos);

					if (npos[0] >= 0.0f && npos[1] >= 0.0f && npos[0] <= width && npos[1] <= height * aspy) {
						vec[0] = (marker->pos[0] + track->offset[0]) * width;
						vec[1] = (marker->pos[1] + track->offset[1]) * height * aspy;

						sub_v2_v2(vec, npos);

						if (len_squared_v2(vec) < (3.0f * 3.0f))
							glColor3f(0.0f, 1.0f, 0.0f);
						else
							glColor3f(1.0f, 0.0f, 0.0f);

						glBegin(GL_POINTS);
						if (undistort)
							glVertex3f(pos[0] / width, pos[1] / (height * aspy), 0);
						else
							glVertex3f(npos[0] / width, npos[1] / (height * aspy), 0);
						glEnd();
					}
				}
			}

			track = track->next;
		}

		glPointSize(1.0f);
		glDisable(GL_POINT_SMOOTH);
	}

	glPopMatrix();

	if (sc->flag & SC_SHOW_NAMES) {
		/* scaling should be cleared before drawing texts, otherwise font would also be scaled */
		track = tracksbase->first;
		fp = marker_pos;
		while (track) {
			if ((track->flag & TRACK_HIDDEN) == 0) {
				marker = BKE_tracking_marker_get(track, framenr);

				if (MARKER_VISIBLE(sc, track, marker)) {
					int act = track == act_track;

					copy_v2_v2(cur_pos, fp ? fp : marker->pos);

					draw_marker_texts(sc, track, marker, cur_pos, act, width, height, zoomx, zoomy);

					if (fp)
						fp += 2;
				}
			}

			track = track->next;
		}
	}

	glPopMatrix();

	if (marker_pos)
		MEM_freeN(marker_pos);
}
예제 #12
0
static int do_set_scale(bContext *C, wmOperator *op, bool scale_solution, bool apply_scale)
{
  SpaceClip *sc = CTX_wm_space_clip(C);
  MovieClip *clip = ED_space_clip_get_clip(sc);
  MovieTracking *tracking = &clip->tracking;
  MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
  MovieTrackingTrack *track;
  Scene *scene = CTX_data_scene(C);
  Object *object = NULL;
  Object *camera = get_camera_with_movieclip(scene, clip);
  ListBase *tracksbase = BKE_tracking_get_active_tracks(tracking);
  int tot = 0;
  float vec[2][3], mat[4][4], scale;
  float dist = RNA_float_get(op->ptr, "distance");

  if (count_selected_bundles(C) != 2) {
    BKE_report(op->reports, RPT_ERROR, "Two tracks with bundles should be selected to set scale");
    return OPERATOR_CANCELLED;
  }

  if (!scale_solution && !apply_scale) {
    object = get_orientation_object(C);
    if (object == NULL) {
      BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
      return OPERATOR_CANCELLED;
    }
  }

  BKE_tracking_get_camera_object_matrix(scene, camera, mat);

  track = tracksbase->first;
  while (track) {
    if (TRACK_VIEW_SELECTED(sc, track)) {
      mul_v3_m4v3(vec[tot], mat, track->bundle_pos);
      tot++;
    }
    track = track->next;
  }

  sub_v3_v3(vec[0], vec[1]);

  if (len_v3(vec[0]) > 1e-5f) {
    scale = dist / len_v3(vec[0]);
    if (apply_scale) {
      /* Apply scale on reconstructed scene itself. */
      MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(
          tracking);
      MovieReconstructedCamera *reconstructed_cameras;
      int i;

      for (track = tracksbase->first; track; track = track->next) {
        mul_v3_fl(track->bundle_pos, scale);
      }

      reconstructed_cameras = reconstruction->cameras;
      for (i = 0; i < reconstruction->camnr; i++) {
        mul_v3_fl(reconstructed_cameras[i].mat[3], scale);
      }

      WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
      WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
    }
    else {
      if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
        mul_v3_fl(object->scale, scale);
        mul_v3_fl(object->loc, scale);
      }
      else if (!scale_solution) {
        Object *solver_camera = object_solver_camera(scene, object);

        object->scale[0] = object->scale[1] = object->scale[2] = 1.0f / scale;

        if (solver_camera) {
          object->scale[0] /= solver_camera->scale[0];
          object->scale[1] /= solver_camera->scale[1];
          object->scale[2] /= solver_camera->scale[2];
        }
      }
      else {
        tracking_object->scale = scale;
      }

      DEG_id_tag_update(&clip->id, 0);

      if (object) {
        DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM);
      }

      WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
      WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);
    }
  }

  return OPERATOR_FINISHED;
}
예제 #13
0
static int set_plane_exec(bContext *C, wmOperator *op)
{
  SpaceClip *sc = CTX_wm_space_clip(C);
  MovieClip *clip = ED_space_clip_get_clip(sc);
  Scene *scene = CTX_data_scene(C);
  MovieTracking *tracking = &clip->tracking;
  MovieTrackingObject *tracking_object;
  MovieTrackingTrack *track, *axis_track = NULL, *act_track;
  ListBase *tracksbase;
  Object *object;
  Object *camera = get_camera_with_movieclip(scene, clip);
  Depsgraph *depsgraph = CTX_data_depsgraph(C);
  int tot = 0;
  float vec[3][3], mat[4][4], obmat[4][4], newmat[4][4], orig[3] = {0.0f, 0.0f, 0.0f};
  int plane = RNA_enum_get(op->ptr, "plane");
  float rot[4][4] = {
      {0.0f, 0.0f, -1.0f, 0.0f},
      {0.0f, 1.0f, 0.0f, 0.0f},
      {1.0f, 0.0f, 0.0f, 0.0f},
      {0.0f, 0.0f, 0.0f, 1.0f},
  }; /* 90 degrees Y-axis rotation matrix */

  if (count_selected_bundles(C) != 3) {
    BKE_report(op->reports, RPT_ERROR, "Three tracks with bundles are needed to orient the floor");

    return OPERATOR_CANCELLED;
  }

  tracking_object = BKE_tracking_object_get_active(tracking);
  tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object);
  act_track = BKE_tracking_track_get_active(tracking);

  object = get_orientation_object(C);
  if (object == NULL) {
    BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on");
    return OPERATOR_CANCELLED;
  }

  BKE_tracking_get_camera_object_matrix(scene, camera, mat);

  /* Get 3 bundles to use as reference. */
  track = tracksbase->first;
  while (track && tot < 3) {
    if (track->flag & TRACK_HAS_BUNDLE && TRACK_VIEW_SELECTED(sc, track)) {
      mul_v3_m4v3(vec[tot], mat, track->bundle_pos);
      if (tot == 0 || track == act_track) {
        copy_v3_v3(orig, vec[tot]);
      }
      else {
        axis_track = track;
      }
      tot++;
    }
    track = track->next;
  }

  sub_v3_v3(vec[1], vec[0]);
  sub_v3_v3(vec[2], vec[0]);

  /* Construct ortho-normal basis. */
  unit_m4(mat);
  if (plane == 0) { /* floor */
    cross_v3_v3v3(mat[0], vec[1], vec[2]);
    copy_v3_v3(mat[1], vec[1]);
    cross_v3_v3v3(mat[2], mat[0], mat[1]);
  }
  else if (plane == 1) { /* wall */
    cross_v3_v3v3(mat[2], vec[1], vec[2]);
    copy_v3_v3(mat[1], vec[1]);
    cross_v3_v3v3(mat[0], mat[1], mat[2]);
  }

  normalize_v3(mat[0]);
  normalize_v3(mat[1]);
  normalize_v3(mat[2]);

  /* Move to origin point. */
  mat[3][0] = orig[0];
  mat[3][1] = orig[1];
  mat[3][2] = orig[2];

  if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
    invert_m4(mat);

    BKE_object_to_mat4(object, obmat);
    mul_m4_m4m4(mat, mat, obmat);
    mul_m4_m4m4(newmat, rot, mat);
    BKE_object_apply_mat4(object, newmat, 0, 0);

    /* Make camera have positive z-coordinate. */
    if (object->loc[2] < 0) {
      invert_m4(rot);
      mul_m4_m4m4(newmat, rot, mat);
      BKE_object_apply_mat4(object, newmat, 0, 0);
    }
  }
  else {
    BKE_object_apply_mat4(object, mat, 0, 0);
  }

  BKE_object_where_is_calc(depsgraph, scene, object);
  set_axis(scene, object, clip, tracking_object, axis_track, 'X');

  DEG_id_tag_update(&clip->id, 0);
  DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM);

  WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip);
  WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL);

  return OPERATOR_FINISHED;
}