void ScreenLensDistortionOperation::executePixel(float output[4], int x, int y, void *data)
{
	MemoryBuffer *buffer = (MemoryBuffer *)data;
	float xy[2] = { (float)x, (float)y };
	float uv[2];
	get_uv(xy, uv);
	float uv_dot = len_squared_v2(uv);

	int count[3] = { 0, 0, 0 };
	float delta[3][2];
	float sum[4] = { 0, 0, 0, 0 };

	bool valid_r = get_delta(uv_dot, m_k4[0], uv, delta[0]);
	bool valid_g = get_delta(uv_dot, m_k4[1], uv, delta[1]);
	bool valid_b = get_delta(uv_dot, m_k4[2], uv, delta[2]);

	if (valid_r && valid_g && valid_b) {
		accumulate(buffer, 0, 1, uv_dot, uv, delta, sum, count);
		accumulate(buffer, 1, 2, uv_dot, uv, delta, sum, count);
		
		if (count[0]) output[0] = 2.0f * sum[0] / (float)count[0];
		if (count[1]) output[1] = 2.0f * sum[1] / (float)count[1];
		if (count[2]) output[2] = 2.0f * sum[2] / (float)count[2];
		
		/* set alpha */
		output[3] = 1.0f;
	}
	else {
		zero_v4(output);
	}
}
void ScreenLensDistortionOperation::determineUV(float result[6], float x, float y) const
{
	const float xy[2] = {x, y};
	float uv[2];
	get_uv(xy, uv);
	float uv_dot = len_squared_v2(uv);
	
	copy_v2_v2(result + 0, xy);
	copy_v2_v2(result + 2, xy);
	copy_v2_v2(result + 4, xy);
	get_delta(uv_dot, m_k4[0], uv, result + 0);
	get_delta(uv_dot, m_k4[1], uv, result + 2);
	get_delta(uv_dot, m_k4[2], uv, result + 4);
}
Beispiel #3
0
void paint_calculate_rake_rotation(UnifiedPaintSettings *ups, const float mouse_pos[2])
{
	const float u = 0.5f;
	const float r = RAKE_THRESHHOLD;

	float dpos[2];
	sub_v2_v2v2(dpos, ups->last_rake, mouse_pos);

	if (len_squared_v2(dpos) >= r * r) {
		ups->brush_rotation = atan2(dpos[0], dpos[1]);

		interp_v2_v2v2(ups->last_rake, ups->last_rake,
		               mouse_pos, u);
	}
}
/**
 * only called from #ok_bezier_region_circle
 */
static bool bezier_region_circle_test(
        const struct KeyframeEdit_CircleData *data_circle,
        const float xy[2])
{
	if (BLI_rctf_isect_pt_v(data_circle->rectf_scaled, xy)) {
		float xy_view[2];

		BLI_rctf_transform_pt_v(data_circle->rectf_view, data_circle->rectf_scaled, xy_view, xy);

		xy_view[0] = xy_view[0] - data_circle->mval[0];
		xy_view[1] = xy_view[1] - data_circle->mval[1];
		return len_squared_v2(xy_view) < data_circle->radius_squared;
	}
	
	return false;
}
static void find_nearest_tracking_knot_cb(void *userdata, MovieTrackingTrack *track,
                                          MovieTrackingMarker *marker, int coord, int scene_framenr, float val)
{
	MouseSelectUserData *data = userdata;
	float mdiff[2] = {scene_framenr - data->mouse_co[0], val - data->mouse_co[1]};
	float dist_sq = len_squared_v2(mdiff);

	if (data->marker == NULL || dist_sq < data->min_dist_sq) {
		float co[2] = {scene_framenr, val};

		data->track = track;
		data->marker = marker;
		data->min_dist_sq = dist_sq;
		data->coord = coord;
		copy_v2_v2(data->min_co, co);
	}

}
float BLI_dial_angle(Dial *dial, float current_position[2])
{
	float current_direction[2];
	
	sub_v2_v2v2(current_direction, current_position, dial->center);

	/* only update when we have enough precision, by having the mouse adequately away from center */
	if (len_squared_v2(current_direction) > dial->threshold_squared) {
		float angle;
		float cosval, sinval;

		normalize_v2(current_direction);

		if (!dial->initialized) {
			copy_v2_v2(dial->initial_direction, current_direction);
			dial->initialized = true;
		}
		
		/* calculate mouse angle between initial and final mouse position */
		cosval = dot_v2v2(current_direction, dial->initial_direction);
		sinval = cross_v2v2(current_direction, dial->initial_direction);
		
		/* clamp to avoid nans in acos */
		angle = atan2f(sinval, cosval);
		
		/* change of sign, we passed the 180 degree threshold. This means we need to add a turn.
		 * to distinguish between transition from 0 to -1 and -PI to +PI, use comparison with PI/2 */
		if ((angle * dial->last_angle < 0.0f) &&
		    (fabsf(dial->last_angle) > (float)M_PI_2))
		{
			if (dial->last_angle < 0.0f)
				dial->rotations--;
			else
				dial->rotations++;
		}
		dial->last_angle = angle;
		
		return angle + 2.0f * (float)M_PI * dial->rotations;
	}
	
	return dial->last_angle;
}
Beispiel #7
0
void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
{
  float rand_pos[2];
  float spread;
  int diameter;

  do {
    rand_pos[0] = BLI_rng_get_float(brush_rng) - 0.5f;
    rand_pos[1] = BLI_rng_get_float(brush_rng) - 0.5f;
  } while (len_squared_v2(rand_pos) > SQUARE(0.5f));

  if (brush->flag & BRUSH_ABSOLUTE_JITTER) {
    diameter = 2 * brush->jitter_absolute;
    spread = 1.0;
  }
  else {
    diameter = 2 * BKE_brush_size_get(scene, brush);
    spread = brush->jitter;
  }
  /* find random position within a circle of diameter 1 */
  jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * spread;
  jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * spread;
}
Beispiel #8
0
void BKE_brush_jitter_pos(const Scene *scene, Brush *brush, const float pos[2], float jitterpos[2])
{
	int use_jitter = (brush->flag & BRUSH_ABSOLUTE_JITTER) ?
		(brush->jitter_absolute != 0) : (brush->jitter != 0);

	/* jitter-ed brush gives weird and unpredictable result for this
	 * kinds of stroke, so manually disable jitter usage (sergey) */
	use_jitter &= (brush->flag & (BRUSH_DRAG_DOT | BRUSH_ANCHORED)) == 0;

	if (use_jitter) {
		float rand_pos[2];
		float spread;
		int diameter;

		do {
			rand_pos[0] = BLI_rng_get_float(brush_rng) - 0.5f;
			rand_pos[1] = BLI_rng_get_float(brush_rng) - 0.5f;
		} while (len_squared_v2(rand_pos) > (0.5f * 0.5f));


		if (brush->flag & BRUSH_ABSOLUTE_JITTER) {
			diameter = 2 * brush->jitter_absolute;
			spread = 1.0;
		}
		else {
			diameter = 2 * BKE_brush_size_get(scene, brush);
			spread = brush->jitter;
		}
		/* find random position within a circle of diameter 1 */
		jitterpos[0] = pos[0] + 2 * rand_pos[0] * diameter * spread;
		jitterpos[1] = pos[1] + 2 * rand_pos[1] * diameter * spread;
	}
	else {
		copy_v2_v2(jitterpos, pos);
	}
}
Beispiel #9
0
/**
 * Takes a vector and computes 2 orthogonal directions.
 *
 * \note if \a n is n unit length, computed values will be too.
 */
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3])
{
	const float eps = FLT_EPSILON;
	const float f = len_squared_v2(n);

	if (f > eps) {
		const float d = 1.0f / sqrtf(f);

		BLI_assert(finite(d));

		r_n1[0] =  n[1] * d;
		r_n1[1] = -n[0] * d;
		r_n1[2] =  0.0f;
		r_n2[0] = -n[2] * r_n1[1];
		r_n2[1] =  n[2] * r_n1[0];
		r_n2[2] =  n[0] * r_n1[1] - n[1] * r_n1[0];
	}
	else {
		/* degenerate case */
		r_n1[0] = (n[2] < 0.0f) ? -1.0f : 1.0f;
		r_n1[1] = r_n1[2] = r_n2[0] = r_n2[2] = 0.0f;
		r_n2[1] = 1.0f;
	}
}
Beispiel #10
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);
}
Beispiel #11
0
static void set_axis(Scene *scene,
                     Object *ob,
                     MovieClip *clip,
                     MovieTrackingObject *tracking_object,
                     MovieTrackingTrack *track,
                     char axis)
{
  Object *camera = get_camera_with_movieclip(scene, clip);
  const bool is_camera = (tracking_object->flag & TRACKING_OBJECT_CAMERA) != 0;
  bool flip = false;
  float mat[4][4], vec[3], obmat[4][4], dvec[3];

  BKE_object_to_mat4(ob, obmat);

  BKE_tracking_get_camera_object_matrix(scene, camera, mat);
  mul_v3_m4v3(vec, mat, track->bundle_pos);
  copy_v3_v3(dvec, vec);

  if (!is_camera) {
    float imat[4][4];

    object_solver_inverted_matrix(scene, ob, imat);
    mul_v3_m4v3(vec, imat, vec);

    invert_m4_m4(imat, obmat);
    mul_v3_m4v3(dvec, imat, vec);

    sub_v3_v3(vec, obmat[3]);
  }

  if (len_squared_v2(vec) < (1e-3f * 1e-3f)) {
    return;
  }

  unit_m4(mat);

  if (axis == 'X') {
    if (fabsf(dvec[1]) < 1e-3f) {
      flip = true;

      mat[0][0] = -1.0f;
      mat[0][1] = 0.0f;
      mat[0][2] = 0.0f;
      mat[1][0] = 0.0f;
      mat[1][1] = -1.0f;
      mat[1][2] = 0.0f;
      mat[2][0] = 0.0f;
      mat[2][1] = 0.0f;
      mat[2][2] = 1.0f;
    }
    else {
      copy_v3_v3(mat[0], vec);

      if (is_camera || fabsf(vec[2]) < 1e-3f) {
        mat[0][2] = 0.0f;
        mat[2][0] = 0.0f;
        mat[2][1] = 0.0f;
        mat[2][2] = 1.0f;
        cross_v3_v3v3(mat[1], mat[2], mat[0]);
      }
      else {
        vec[2] = 0.0f;

        cross_v3_v3v3(mat[1], mat[0], vec);
        cross_v3_v3v3(mat[2], mat[0], mat[1]);
      }
    }
  }
  else {
    if (fabsf(dvec[0]) < 1e-3f) {
      flip = true;

      mat[0][0] = -1.0f;
      mat[0][1] = 0.0f;
      mat[0][2] = 0.0f;
      mat[1][0] = 0.0f;
      mat[1][1] = -1.0f;
      mat[1][2] = 0.0f;
      mat[2][0] = 0.0f;
      mat[2][1] = 0.0f;
      mat[2][2] = 1.0f;
    }
    else {
      copy_v3_v3(mat[1], vec);

      if (is_camera || fabsf(vec[2]) < 1e-3f) {
        mat[1][2] = 0.0f;
        mat[2][0] = 0.0f;
        mat[2][1] = 0.0f;
        mat[2][2] = 1.0f;
        cross_v3_v3v3(mat[0], mat[1], mat[2]);
      }
      else {
        vec[2] = 0.0f;

        cross_v3_v3v3(mat[0], vec, mat[1]);
        cross_v3_v3v3(mat[2], mat[0], mat[1]);
      }
    }
  }

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

  if (is_camera) {
    invert_m4(mat);

    mul_m4_m4m4(mat, mat, obmat);
  }
  else {
    if (!flip) {
      float lmat[4][4], ilmat[4][4], rmat[3][3];

      BKE_object_rot_to_mat3(ob, rmat, true);
      invert_m3(rmat);
      mul_m4_m4m3(mat, mat, rmat);

      unit_m4(lmat);
      copy_v3_v3(lmat[3], obmat[3]);
      invert_m4_m4(ilmat, lmat);

      mul_m4_series(mat, lmat, mat, ilmat, obmat);
    }
    else {
      mul_m4_m4m4(mat, obmat, mat);
    }
  }

  BKE_object_apply_mat4(ob, mat, 0, 0);
}