2023-08-16 00:20:26 +10:00
|
|
|
/* SPDX-FileCopyrightText: 2011 Blender Authors
|
2023-05-31 16:19:06 +02:00
|
|
|
*
|
|
|
|
|
* SPDX-License-Identifier: GPL-2.0-or-later */
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-02-18 08:08:12 +11:00
|
|
|
/** \file
|
|
|
|
|
* \ingroup bke
|
2011-11-07 12:55:18 +00:00
|
|
|
*/
|
|
|
|
|
|
2023-07-22 11:27:25 +10:00
|
|
|
#include <climits>
|
|
|
|
|
#include <cmath>
|
|
|
|
|
#include <cstddef>
|
2023-06-07 14:45:46 +02:00
|
|
|
#include <cstdint>
|
2011-11-07 12:55:18 +00:00
|
|
|
#include <memory.h>
|
|
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
2013-10-26 13:22:38 +00:00
|
|
|
#include "DNA_anim_types.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "DNA_camera_types.h"
|
2022-11-18 17:15:13 +01:00
|
|
|
#include "DNA_defaults.h"
|
2023-03-13 10:42:51 +01:00
|
|
|
#include "DNA_gpencil_legacy_types.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "DNA_movieclip_types.h"
|
2012-06-10 19:59:02 +00:00
|
|
|
#include "DNA_object_types.h" /* SELECT */
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
|
|
2016-10-26 20:11:09 +11:00
|
|
|
#include "BLI_bitmap_draw_2d.h"
|
2016-07-29 23:13:31 +02:00
|
|
|
#include "BLI_ghash.h"
|
2023-06-07 14:45:46 +02:00
|
|
|
#include "BLI_hash.hh"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_listbase.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "BLI_math_base.h"
|
Cleanup: reduce amount of math-related includes
Using ClangBuildAnalyzer on the whole Blender build, it was pointing
out that BLI_math.h is the heaviest "header hub" (i.e. non tiny file
that is included a lot).
However, there's very little (actually zero) source files in Blender
that need "all the math" (base, colors, vectors, matrices,
quaternions, intersection, interpolation, statistics, solvers and
time). A common use case is source files needing just vectors, or
just vectors & matrices, or just colors etc. Actually, 181 files
were including the whole math thing without needing it at all.
This change removes BLI_math.h completely, and instead in all the
places that need it, includes BLI_math_vector.h or BLI_math_color.h
and so on.
Change from that:
- BLI_math_color.h was included 1399 times -> now 408 (took 114.0sec
to parse -> now 36.3sec)
- BLI_simd.h 1403 -> 418 (109.7sec -> 34.9sec).
Full rebuild of Blender (Apple M1, Xcode, RelWithDebInfo) is not
affected much (342sec -> 334sec). Most of benefit would be when
someone's changing BLI_simd.h or BLI_math_color.h or similar files,
that now there's 3x fewer files result in a recompile.
Pull Request #110944
2023-08-09 11:39:20 +03:00
|
|
|
#include "BLI_math_geom.h"
|
|
|
|
|
#include "BLI_math_matrix.h"
|
2023-06-07 14:45:46 +02:00
|
|
|
#include "BLI_math_vector.h"
|
|
|
|
|
#include "BLI_math_vector_types.hh"
|
Assorted camera tracker improvements
- Add support for refining the camera's intrinsic parameters
during a solve. Currently, refining supports only the following
combinations of intrinsic parameters:
f
f, cx, cy
f, cx, cy, k1, k2
f, k1
f, k1, k2
This is not the same as autocalibration, since the user must
still make a reasonable initial guess about the focal length and
other parameters, whereas true autocalibration would eliminate
the need for the user specify intrinsic parameters at all.
However, the solver works well with only rough guesses for the
focal length, so perhaps full autocalibation is not that
important.
Adding support for the last two combinations, (f, k1) and (f,
k1, k2) required changes to the library libmv depends on for
bundle adjustment, SSBA. These changes should get ported
upstream not just to libmv but to SSBA as well.
- Improved the region of convergence for bundle adjustment by
increasing the number of Levenberg-Marquardt iterations from 50
to 500. This way, the solver is able to crawl out of the bad
local minima it gets stuck in when changing from, for example,
bundling k1 and k2 to just k1 and resetting k2 to 0.
- Add several new region tracker implementations. A region tracker
is a libmv concept, which refers to tracking a template image
pattern through frames. The impact to end users is that tracking
should "just work better". I am reserving a more detailed
writeup, and maybe a paper, for later.
- Other libmv tweaks, such as detecting that a tracker is headed
outside of the image bounds.
This includes several changes made directly to the libmv extern
code rather expecting to get those changes through normal libmv
channels, because I, the libmv BDFL, decided it was faster to work
on libmv directly in Blender, then later reverse-port the libmv
changes from Blender back into libmv trunk. The interesting part
is that I added a full Levenberg-Marquardt loop to the region
tracking code, which should lead to a more stable solutions. I
also added a hacky implementation of "Efficient Second-Order
Minimization" for tracking, which works nicely. A more detailed
quantitative evaluation will follow.
Original patch by Keir, cleaned a bit by myself.
2011-11-14 06:41:23 +00:00
|
|
|
#include "BLI_string.h"
|
2023-10-18 17:15:30 +02:00
|
|
|
#include "BLI_string_utils.hh"
|
2011-12-13 10:07:22 +00:00
|
|
|
#include "BLI_threads.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BLI_utildefines.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2015-08-16 17:32:01 +10:00
|
|
|
#include "BLT_translation.h"
|
2012-10-26 17:32:50 +00:00
|
|
|
|
2013-10-26 13:22:38 +00:00
|
|
|
#include "BKE_fcurve.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_layer.h"
|
2020-02-10 12:58:59 +01:00
|
|
|
#include "BKE_lib_id.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "BKE_movieclip.h"
|
2023-10-09 23:41:53 +02:00
|
|
|
#include "BKE_object.hh"
|
2011-11-07 12:55:18 +00:00
|
|
|
#include "BKE_scene.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "BKE_tracking.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
#include "IMB_imbuf.h"
|
2020-03-19 09:33:03 +01:00
|
|
|
#include "IMB_imbuf_types.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2023-08-10 22:40:27 +02:00
|
|
|
#include "RNA_access.hh"
|
2022-03-14 16:54:46 +01:00
|
|
|
#include "RNA_prototypes.h"
|
2013-10-26 13:22:38 +00:00
|
|
|
|
2013-05-12 22:17:37 +00:00
|
|
|
#include "libmv-capi.h"
|
2013-12-30 17:03:59 +06:00
|
|
|
#include "tracking_private.h"
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2023-07-02 19:37:19 +10:00
|
|
|
struct MovieDistortion {
|
2023-06-03 08:36:28 +10:00
|
|
|
libmv_CameraIntrinsics *intrinsics;
|
2016-01-26 11:42:55 +01:00
|
|
|
/* Parameters needed for coordinates normalization. */
|
2022-11-18 17:15:13 +01:00
|
|
|
float principal_px[2];
|
2016-01-26 11:42:55 +01:00
|
|
|
float pixel_aspect;
|
|
|
|
|
float focal;
|
2023-07-02 19:37:19 +10:00
|
|
|
};
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-01-09 20:18:48 +00:00
|
|
|
static struct {
|
|
|
|
|
ListBase tracks;
|
|
|
|
|
} tracking_clipboard;
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Common functions.
|
|
|
|
|
*/
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
/* Free the whole list of tracks, list's head and tail are set to nullptr. */
|
2012-06-15 11:03:23 +00:00
|
|
|
static void tracking_tracks_free(ListBase *tracks)
|
|
|
|
|
{
|
2020-02-07 12:51:18 +01:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks) {
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_track_free(track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_freelistN(tracks);
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
/* Free the whole list of plane tracks, list's head and tail are set to nullptr. */
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
static void tracking_plane_tracks_free(ListBase *plane_tracks)
|
|
|
|
|
{
|
2020-02-07 12:51:18 +01:00
|
|
|
LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks) {
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
BKE_tracking_plane_track_free(plane_track);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_freelistN(plane_tracks);
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Free reconstruction structures, only frees contents of a structure,
|
|
|
|
|
* (if structure is allocated in heap, it shall be handled outside).
|
|
|
|
|
*
|
|
|
|
|
* All the pointers inside structure becomes invalid after this call.
|
|
|
|
|
*/
|
2012-06-15 11:03:23 +00:00
|
|
|
static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
|
|
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (reconstruction->cameras) {
|
2012-06-15 11:03:23 +00:00
|
|
|
MEM_freeN(reconstruction->cameras);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Free memory used by tracking object, only frees contents of the structure,
|
|
|
|
|
* (if structure is allocated in heap, it shall be handled outside).
|
|
|
|
|
*
|
|
|
|
|
* All the pointers inside structure becomes invalid after this call.
|
|
|
|
|
*/
|
2022-10-05 18:01:29 +02:00
|
|
|
static void tracking_object_free(MovieTrackingObject *tracking_object)
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
tracking_tracks_free(&tracking_object->tracks);
|
|
|
|
|
tracking_plane_tracks_free(&tracking_object->plane_tracks);
|
|
|
|
|
tracking_reconstruction_free(&tracking_object->reconstruction);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
/* Free list of tracking objects, list's head and tail is set to nullptr. */
|
2012-06-15 11:03:23 +00:00
|
|
|
static void tracking_objects_free(ListBase *objects)
|
|
|
|
|
{
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Free objects contents. */
|
2020-02-07 12:51:18 +01:00
|
|
|
LISTBASE_FOREACH (MovieTrackingObject *, object, objects) {
|
2012-06-15 11:03:23 +00:00
|
|
|
tracking_object_free(object);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Free objects themselves. */
|
2012-06-15 11:03:23 +00:00
|
|
|
BLI_freelistN(objects);
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Free memory used by a dopesheet, only frees dopesheet contents.
|
|
|
|
|
* leaving dopesheet crystal clean for further usage.
|
|
|
|
|
*/
|
2012-06-15 11:03:23 +00:00
|
|
|
static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingDopesheetChannel *channel;
|
|
|
|
|
|
2020-02-21 10:49:58 +01:00
|
|
|
/* Free channel's segments. */
|
2023-03-01 12:32:15 +01:00
|
|
|
channel = static_cast<MovieTrackingDopesheetChannel *>(dopesheet->channels.first);
|
2012-06-15 11:03:23 +00:00
|
|
|
while (channel) {
|
|
|
|
|
if (channel->segments) {
|
|
|
|
|
MEM_freeN(channel->segments);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
channel = channel->next;
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Free lists themselves. */
|
2012-06-15 11:03:23 +00:00
|
|
|
BLI_freelistN(&dopesheet->channels);
|
2013-02-22 10:13:15 +00:00
|
|
|
BLI_freelistN(&dopesheet->coverage_segments);
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Ensure lists are clean. */
|
2014-02-08 06:07:10 +11:00
|
|
|
BLI_listbase_clear(&dopesheet->channels);
|
|
|
|
|
BLI_listbase_clear(&dopesheet->coverage_segments);
|
2012-06-15 11:03:23 +00:00
|
|
|
dopesheet->tot_channel = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_free(MovieTracking *tracking)
|
|
|
|
|
{
|
|
|
|
|
tracking_objects_free(&tracking->objects);
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (tracking->camera.intrinsics) {
|
2023-03-01 12:32:15 +01:00
|
|
|
BKE_tracking_distortion_free(static_cast<MovieDistortion *>(tracking->camera.intrinsics));
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
tracking_dopesheet_free(&tracking->dopesheet);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-02 19:37:19 +10:00
|
|
|
struct TrackingCopyContext {
|
2022-10-06 16:52:23 +02:00
|
|
|
/* Map from point and plane track pointer from the source object to the destination object. */
|
|
|
|
|
GHash *old_to_new_track_map;
|
|
|
|
|
GHash *old_to_new_plane_track_map;
|
2023-07-02 19:37:19 +10:00
|
|
|
};
|
2022-10-06 16:52:23 +02:00
|
|
|
|
2023-07-02 19:37:22 +10:00
|
|
|
static TrackingCopyContext tracking_copy_context_new()
|
2022-10-06 16:52:23 +02:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
TrackingCopyContext ctx = {};
|
|
|
|
|
ctx.old_to_new_track_map = BLI_ghash_ptr_new(__func__);
|
|
|
|
|
ctx.old_to_new_plane_track_map = BLI_ghash_ptr_new(__func__);
|
2022-10-06 16:52:23 +02:00
|
|
|
return ctx;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void tracking_copy_context_delete(TrackingCopyContext *ctx)
|
|
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
BLI_ghash_free(ctx->old_to_new_track_map, nullptr, nullptr);
|
|
|
|
|
BLI_ghash_free(ctx->old_to_new_plane_track_map, nullptr, nullptr);
|
2022-10-06 16:52:23 +02:00
|
|
|
}
|
|
|
|
|
|
2016-07-29 23:13:31 +02:00
|
|
|
/* Copy the whole list of tracks. */
|
2022-10-06 16:52:23 +02:00
|
|
|
static void tracking_tracks_copy(TrackingCopyContext *ctx,
|
|
|
|
|
ListBase *tracks_dst,
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
const ListBase *tracks_src,
|
|
|
|
|
const int flag)
|
2016-07-29 23:13:31 +02:00
|
|
|
{
|
|
|
|
|
BLI_listbase_clear(tracks_dst);
|
|
|
|
|
|
2020-02-07 12:51:18 +01:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track_src, tracks_src) {
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingTrack *track_dst = MEM_cnew<MovieTrackingTrack>(__func__, *track_src);
|
2016-07-29 23:13:31 +02:00
|
|
|
if (track_src->markers) {
|
2023-03-01 12:32:15 +01:00
|
|
|
track_dst->markers = static_cast<MovieTrackingMarker *>(MEM_dupallocN(track_src->markers));
|
2016-07-29 23:13:31 +02:00
|
|
|
}
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
|
|
|
|
|
id_us_plus(&track_dst->gpd->id);
|
|
|
|
|
}
|
2016-07-29 23:13:31 +02:00
|
|
|
BLI_addtail(tracks_dst, track_dst);
|
2022-10-06 16:52:23 +02:00
|
|
|
|
|
|
|
|
BLI_ghash_insert(ctx->old_to_new_track_map, track_src, track_dst);
|
2016-07-29 23:13:31 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-27 12:07:07 +10:00
|
|
|
/* Copy the whole list of plane tracks
|
|
|
|
|
* (need whole MovieTracking structures due to embedded pointers to tracks).
|
2016-07-29 23:13:31 +02:00
|
|
|
* WARNING: implies tracking_[dst/src] and their tracks have already been copied. */
|
2022-10-06 16:52:23 +02:00
|
|
|
static void tracking_plane_tracks_copy(TrackingCopyContext *ctx,
|
|
|
|
|
ListBase *plane_tracks_list_dst,
|
2018-08-13 13:47:06 +02:00
|
|
|
const ListBase *plane_tracks_list_src,
|
|
|
|
|
const int flag)
|
2016-07-29 23:13:31 +02:00
|
|
|
{
|
2018-08-13 13:47:06 +02:00
|
|
|
BLI_listbase_clear(plane_tracks_list_dst);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-02-07 12:51:18 +01:00
|
|
|
LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track_src, plane_tracks_list_src) {
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingPlaneTrack *plane_track_dst = MEM_cnew(__func__, *plane_track_src);
|
2016-07-29 23:13:31 +02:00
|
|
|
if (plane_track_src->markers) {
|
2023-03-01 12:32:15 +01:00
|
|
|
plane_track_dst->markers = static_cast<MovieTrackingPlaneMarker *>(
|
|
|
|
|
MEM_dupallocN(plane_track_src->markers));
|
2016-07-29 23:13:31 +02:00
|
|
|
}
|
2023-03-01 12:32:15 +01:00
|
|
|
plane_track_dst->point_tracks = MEM_cnew_array<MovieTrackingTrack *>(
|
2016-07-29 23:13:31 +02:00
|
|
|
sizeof(*plane_track_dst->point_tracks) * plane_track_dst->point_tracksnr, __func__);
|
|
|
|
|
for (int i = 0; i < plane_track_dst->point_tracksnr; i++) {
|
2023-03-01 12:32:15 +01:00
|
|
|
plane_track_dst->point_tracks[i] = static_cast<MovieTrackingTrack *>(
|
|
|
|
|
BLI_ghash_lookup(ctx->old_to_new_track_map, plane_track_src->point_tracks[i]));
|
|
|
|
|
BLI_assert(plane_track_dst->point_tracks[i] != nullptr);
|
2016-07-29 23:13:31 +02:00
|
|
|
}
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
if ((flag & LIB_ID_CREATE_NO_USER_REFCOUNT) == 0) {
|
|
|
|
|
id_us_plus(&plane_track_dst->image->id);
|
|
|
|
|
}
|
2018-08-13 13:47:06 +02:00
|
|
|
BLI_addtail(plane_tracks_list_dst, plane_track_dst);
|
2022-10-06 16:52:23 +02:00
|
|
|
|
|
|
|
|
BLI_ghash_insert(ctx->old_to_new_plane_track_map, plane_track_src, plane_track_dst);
|
2016-07-29 23:13:31 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy reconstruction structure. */
|
2023-03-01 12:32:15 +01:00
|
|
|
static void tracking_reconstruction_copy(TrackingCopyContext * /*ctx*/,
|
2022-10-06 16:52:23 +02:00
|
|
|
MovieTrackingReconstruction *reconstruction_dst,
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
const MovieTrackingReconstruction *reconstruction_src,
|
2023-03-01 12:32:15 +01:00
|
|
|
const int /*flag*/)
|
2016-07-29 23:13:31 +02:00
|
|
|
{
|
|
|
|
|
*reconstruction_dst = *reconstruction_src;
|
|
|
|
|
if (reconstruction_src->cameras) {
|
2023-03-01 12:32:15 +01:00
|
|
|
reconstruction_dst->cameras = static_cast<MovieReconstructedCamera *>(
|
|
|
|
|
MEM_dupallocN(reconstruction_src->cameras));
|
2016-07-29 23:13:31 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy stabilization structure. */
|
2022-10-04 17:39:57 +02:00
|
|
|
static void tracking_stabilization_copy(MovieTrackingStabilization *stabilization_dst,
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
const MovieTrackingStabilization *stabilization_src,
|
2023-03-01 12:32:15 +01:00
|
|
|
const int /*flag*/)
|
2016-07-29 23:13:31 +02:00
|
|
|
{
|
|
|
|
|
*stabilization_dst = *stabilization_src;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy tracking object. */
|
2022-10-05 18:01:29 +02:00
|
|
|
static void tracking_object_copy(MovieTrackingObject *tracking_object_dst,
|
|
|
|
|
const MovieTrackingObject *tracking_object_src,
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
const int flag)
|
2016-07-29 23:13:31 +02:00
|
|
|
{
|
2022-10-06 16:52:23 +02:00
|
|
|
TrackingCopyContext ctx = tracking_copy_context_new();
|
|
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
*tracking_object_dst = *tracking_object_src;
|
|
|
|
|
|
|
|
|
|
tracking_tracks_copy(&ctx, &tracking_object_dst->tracks, &tracking_object_src->tracks, flag);
|
|
|
|
|
tracking_plane_tracks_copy(
|
|
|
|
|
&ctx, &tracking_object_dst->plane_tracks, &tracking_object_src->plane_tracks, flag);
|
2022-10-06 16:52:23 +02:00
|
|
|
tracking_reconstruction_copy(
|
2022-10-05 18:01:29 +02:00
|
|
|
&ctx, &tracking_object_dst->reconstruction, &tracking_object_src->reconstruction, flag);
|
2022-10-06 16:52:23 +02:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
if (tracking_object_src->active_track) {
|
2023-03-01 12:32:15 +01:00
|
|
|
tracking_object_dst->active_track = static_cast<MovieTrackingTrack *>(
|
|
|
|
|
BLI_ghash_lookup(ctx.old_to_new_track_map, tracking_object_src->active_track));
|
|
|
|
|
BLI_assert(tracking_object_dst->active_track != nullptr);
|
2022-10-04 17:39:57 +02:00
|
|
|
}
|
2022-10-05 18:01:29 +02:00
|
|
|
if (tracking_object_src->active_plane_track) {
|
2023-03-01 12:32:15 +01:00
|
|
|
tracking_object_dst->active_plane_track = static_cast<MovieTrackingPlaneTrack *>(
|
|
|
|
|
BLI_ghash_lookup(ctx.old_to_new_plane_track_map, tracking_object_src->active_plane_track));
|
|
|
|
|
BLI_assert(tracking_object_dst->active_plane_track != nullptr);
|
2022-10-04 17:39:57 +02:00
|
|
|
}
|
|
|
|
|
|
2022-10-06 16:52:23 +02:00
|
|
|
tracking_copy_context_delete(&ctx);
|
2016-07-29 23:13:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Copy list of tracking objects. */
|
2022-10-05 18:01:29 +02:00
|
|
|
static void tracking_objects_copy(ListBase *tracking_objects_dst,
|
|
|
|
|
const ListBase *tracking_objects_src,
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
const int flag)
|
2016-07-29 23:13:31 +02:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
BLI_listbase_clear(tracking_objects_dst);
|
2016-07-29 23:13:31 +02:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingObject *, tracking_object_src, tracking_objects_src) {
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingObject *tracking_object_dst = MEM_cnew<MovieTrackingObject>(__func__);
|
2022-10-05 18:01:29 +02:00
|
|
|
tracking_object_copy(tracking_object_dst, tracking_object_src, flag);
|
|
|
|
|
BLI_addtail(tracking_objects_dst, tracking_object_dst);
|
2016-07-29 23:13:31 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
Refactor ID copying (and to some extent, ID freeing).
This will allow much finer controll over how we copy data-blocks, from
full copy in Main database, to "lighter" ones (out of Main, inside an
already allocated datablock, etc.).
This commit also transfers a llot of what was previously handled by
per-ID-type custom code to generic ID handling code in BKE_library.
Hopefully will avoid in future inconsistencies and missing bits we had
all over the codebase in the past.
It also adds missing copying handling for a few types, most notably
Scene (which where using a fully customized handling previously).
Note that the type of allocation used during copying (regular in Main,
allocated but outside of Main, or not allocated by ID handling code at
all) is stored in ID's, which allows to handle them correctly when
freeing. This needs to be taken care of with caution when doing 'weird'
unusual things with ID copying and/or allocation!
As a final note, while rather noisy, this commit will hopefully not
break too much existing branches, old 'API' has been kept for the main
part, as a wrapper around new code. Cleaning it up will happen later.
Design task : T51804
Phab Diff: D2714
2017-08-07 16:39:55 +02:00
|
|
|
void BKE_tracking_copy(MovieTracking *tracking_dst,
|
|
|
|
|
const MovieTracking *tracking_src,
|
|
|
|
|
const int flag)
|
2016-07-29 23:13:31 +02:00
|
|
|
{
|
|
|
|
|
*tracking_dst = *tracking_src;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-10-04 17:39:57 +02:00
|
|
|
tracking_stabilization_copy(&tracking_dst->stabilization, &tracking_src->stabilization, flag);
|
2022-10-06 16:52:23 +02:00
|
|
|
|
|
|
|
|
tracking_objects_copy(&tracking_dst->objects, &tracking_src->objects, flag);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-27 12:07:07 +10:00
|
|
|
/* Those remaining are runtime data, they will be reconstructed as needed,
|
|
|
|
|
* do not bother copying them. */
|
2016-07-29 23:13:31 +02:00
|
|
|
tracking_dst->dopesheet.ok = false;
|
|
|
|
|
BLI_listbase_clear(&tracking_dst->dopesheet.channels);
|
|
|
|
|
BLI_listbase_clear(&tracking_dst->dopesheet.coverage_segments);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
tracking_dst->camera.intrinsics = nullptr;
|
|
|
|
|
tracking_dst->stats = nullptr;
|
2016-07-29 23:13:31 +02:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
void BKE_tracking_settings_init(MovieTracking *tracking)
|
|
|
|
|
{
|
|
|
|
|
tracking->camera.sensor_width = 35.0f;
|
|
|
|
|
tracking->camera.pixel_aspect = 1.0f;
|
|
|
|
|
tracking->camera.units = CAMERA_UNITS_MM;
|
|
|
|
|
|
|
|
|
|
tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION;
|
|
|
|
|
tracking->settings.default_minimum_correlation = 0.75;
|
2014-02-19 18:50:24 +06:00
|
|
|
tracking->settings.default_pattern_size = 21;
|
|
|
|
|
tracking->settings.default_search_size = 71;
|
2013-02-05 13:10:26 +00:00
|
|
|
tracking->settings.default_algorithm_flag |= TRACK_ALGORITHM_FLAG_USE_BRUTE;
|
2014-02-19 18:42:32 +06:00
|
|
|
tracking->settings.default_weight = 1.0f;
|
2012-06-15 11:03:23 +00:00
|
|
|
tracking->settings.dist = 1;
|
|
|
|
|
tracking->settings.object_distance = 1;
|
2020-10-21 10:53:13 +02:00
|
|
|
tracking->settings.refine_camera_intrinsics = REFINE_NO_INTRINSICS;
|
2012-06-15 11:03:23 +00:00
|
|
|
|
Rework 2D stabilizator
See this page for motivation and description of concepts:
https://github.com/Ichthyostega/blender/wiki
See this video for UI explanation and demonstration of usage
http://vimeo.com/blenderHack/stabilizerdemo
This proposal attempts to improve usability of Blender's image stabilization
feature for real-world footage esp. with moving and panning camera. It builds
upon the feature tracking to get a measurement of 2D image movement.
- Use a weighted average of movement contributions (instead of a median).
- Allow for rotation compensation and zoom (image scale) compensation.
- Allow to pick a different set of tracks for translation and for
rotation/zoom.
- Treat translation / rotation / zoom contributions systematically in a
similar way.
- Improve handling of partial tracking data with gaps and varying
start / end points.
- Have a user definable anchor frame and interpolate / extrapolate data to
avoid jumping back to "neutral" position when no tracking data is available.
- Support for travelling and panning shots by including an //intended//
position/rotation/zoom ("target position"). The idea is for these parameters
to be //animated// by the user, in order to supply an smooth, intended
camera movement. This way, we can keep the image content roughly in frame
even when moving completely away from the initial view.
A known shortcoming is that the pivot point for rotation compensation is set to
the translation compensated image center. This can produce spurious rotation on
travelling shots, which needs to be compensated manually (by animating the
target rotation parameter). There are several possible ways to address that
problem, yet all of them are considered beyond the scope of this improvement
proposal for now.
Own modifications:
- Restrict line length, it's really handy for split-view editing
- In motion tracking we prefer fully human-readable comments, meaning we
don't use doxygen with it's weird markup and comments are supposed to
start with capital and end with a full stop,
- Add explicit comparison of pointer to NULL.
Reviewers: sergey
Subscribers: kusi, kdawg, forest-house, mardy, Samoth, plasmasolutions, willolis, sebastian_k, hype, enetheru, sunboy, jta, leon_cheung
Maniphest Tasks: T49036
Differential Revision: https://developer.blender.org/D583
2016-08-16 10:32:55 +02:00
|
|
|
tracking->stabilization.scaleinf = 1.0f;
|
2016-08-22 17:29:19 +02:00
|
|
|
tracking->stabilization.anchor_frame = 1;
|
Rework 2D stabilizator
See this page for motivation and description of concepts:
https://github.com/Ichthyostega/blender/wiki
See this video for UI explanation and demonstration of usage
http://vimeo.com/blenderHack/stabilizerdemo
This proposal attempts to improve usability of Blender's image stabilization
feature for real-world footage esp. with moving and panning camera. It builds
upon the feature tracking to get a measurement of 2D image movement.
- Use a weighted average of movement contributions (instead of a median).
- Allow for rotation compensation and zoom (image scale) compensation.
- Allow to pick a different set of tracks for translation and for
rotation/zoom.
- Treat translation / rotation / zoom contributions systematically in a
similar way.
- Improve handling of partial tracking data with gaps and varying
start / end points.
- Have a user definable anchor frame and interpolate / extrapolate data to
avoid jumping back to "neutral" position when no tracking data is available.
- Support for travelling and panning shots by including an //intended//
position/rotation/zoom ("target position"). The idea is for these parameters
to be //animated// by the user, in order to supply an smooth, intended
camera movement. This way, we can keep the image content roughly in frame
even when moving completely away from the initial view.
A known shortcoming is that the pivot point for rotation compensation is set to
the translation compensated image center. This can produce spurious rotation on
travelling shots, which needs to be compensated manually (by animating the
target rotation parameter). There are several possible ways to address that
problem, yet all of them are considered beyond the scope of this improvement
proposal for now.
Own modifications:
- Restrict line length, it's really handy for split-view editing
- In motion tracking we prefer fully human-readable comments, meaning we
don't use doxygen with it's weird markup and comments are supposed to
start with capital and end with a full stop,
- Add explicit comparison of pointer to NULL.
Reviewers: sergey
Subscribers: kusi, kdawg, forest-house, mardy, Samoth, plasmasolutions, willolis, sebastian_k, hype, enetheru, sunboy, jta, leon_cheung
Maniphest Tasks: T49036
Differential Revision: https://developer.blender.org/D583
2016-08-16 10:32:55 +02:00
|
|
|
zero_v2(tracking->stabilization.target_pos);
|
|
|
|
|
tracking->stabilization.target_rot = 0.0f;
|
|
|
|
|
tracking->stabilization.scale = 1.0f;
|
|
|
|
|
|
|
|
|
|
tracking->stabilization.act_track = 0;
|
|
|
|
|
tracking->stabilization.act_rot_track = 0;
|
|
|
|
|
tracking->stabilization.tot_track = 0;
|
|
|
|
|
tracking->stabilization.tot_rot_track = 0;
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
tracking->stabilization.scaleinf = 1.0f;
|
|
|
|
|
tracking->stabilization.locinf = 1.0f;
|
|
|
|
|
tracking->stabilization.rotinf = 1.0f;
|
|
|
|
|
tracking->stabilization.maxscale = 2.0f;
|
2013-04-08 11:26:56 +00:00
|
|
|
tracking->stabilization.filter = TRACKING_FILTER_BILINEAR;
|
2016-08-16 14:25:55 +02:00
|
|
|
tracking->stabilization.flag |= TRACKING_SHOW_STAB_TRACKS;
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2022-06-14 17:34:49 +02:00
|
|
|
/* Descending order of average error: tracks with the highest error are on top. */
|
|
|
|
|
tracking->dopesheet.sort_method = TRACKING_DOPE_SORT_AVERAGE_ERROR;
|
|
|
|
|
tracking->dopesheet.flag |= TRACKING_DOPE_SORT_INVERSE;
|
|
|
|
|
|
2022-06-15 17:14:13 +02:00
|
|
|
BKE_tracking_object_add(tracking, DATA_("Camera"));
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2020-02-10 12:40:54 +01:00
|
|
|
void BKE_tracking_get_camera_object_matrix(Object *camera_object, float mat[4][4])
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
BLI_assert(camera_object != nullptr);
|
2020-02-10 12:46:01 +01:00
|
|
|
/* NOTE: Construct matrix from scratch rather than using obmat because the camera object here
|
|
|
|
|
* will have camera solver constraint taken into account. But here we do not want or need it:
|
|
|
|
|
* object is solved in camera space (as in, camera is stationary and object is moving).
|
|
|
|
|
*
|
|
|
|
|
* This will include animation applied on the camera, but not possible camera rig. This isn't
|
|
|
|
|
* an issue in practice due to the way how VFX is constructed.
|
|
|
|
|
*
|
|
|
|
|
* If we ever need to support crazy setups like that one possible solution would be to use
|
|
|
|
|
* final camera matrix and multiple it by an inverse of solved camera matrix at the current
|
|
|
|
|
* frame. */
|
2020-02-10 12:40:54 +01:00
|
|
|
BKE_object_where_is_calc_mat4(camera_object, mat);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_get_projection_matrix(MovieTracking *tracking,
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object,
|
2012-06-16 09:18:00 +00:00
|
|
|
int framenr,
|
|
|
|
|
int winx,
|
|
|
|
|
int winy,
|
|
|
|
|
float mat[4][4])
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
|
|
|
|
MovieReconstructedCamera *camera;
|
2023-03-03 23:27:50 +11:00
|
|
|
float lens = tracking->camera.focal * tracking->camera.sensor_width / float(winx);
|
2012-06-15 11:03:23 +00:00
|
|
|
float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
|
|
|
|
|
float winmat[4][4];
|
|
|
|
|
float ycor = 1.0f / tracking->camera.pixel_aspect;
|
2023-03-03 23:27:50 +11:00
|
|
|
float shiftx, shifty, winside = float(min_ii(winx, winy));
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
BKE_tracking_camera_shift_get(tracking, winx, winy, &shiftx, &shifty);
|
|
|
|
|
|
|
|
|
|
clipsta = 0.1f;
|
|
|
|
|
clipend = 1000.0f;
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (winx >= winy) {
|
2012-06-15 11:03:23 +00:00
|
|
|
viewfac = (lens * winx) / tracking->camera.sensor_width;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2012-06-15 11:03:23 +00:00
|
|
|
viewfac = (ycor * lens * winy) / tracking->camera.sensor_width;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
pixsize = clipsta / viewfac;
|
|
|
|
|
|
2023-03-03 23:27:50 +11:00
|
|
|
left = -0.5f * float(winx) + shiftx * winside;
|
|
|
|
|
bottom = -0.5f * (ycor) * float(winy) + shifty * winside;
|
|
|
|
|
right = 0.5f * float(winx) + shiftx * winside;
|
|
|
|
|
top = 0.5f * (ycor) * float(winy) + shifty * winside;
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
left *= pixsize;
|
|
|
|
|
right *= pixsize;
|
|
|
|
|
bottom *= pixsize;
|
|
|
|
|
top *= pixsize;
|
|
|
|
|
|
|
|
|
|
perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
|
|
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
camera = BKE_tracking_camera_get_reconstructed(tracking, tracking_object, framenr);
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
if (camera) {
|
|
|
|
|
float imat[4][4];
|
|
|
|
|
|
|
|
|
|
invert_m4_m4(imat, camera->mat);
|
2013-05-26 18:36:25 +00:00
|
|
|
mul_m4_m4m4(mat, winmat, imat);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2013-03-09 03:46:30 +00:00
|
|
|
else {
|
|
|
|
|
copy_m4_m4(mat, winmat);
|
|
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Clipboard.
|
|
|
|
|
*/
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2023-07-02 19:37:22 +10:00
|
|
|
void BKE_tracking_clipboard_free()
|
2011-11-28 13:26:46 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingTrack *track = static_cast<MovieTrackingTrack *>(tracking_clipboard.tracks.first),
|
|
|
|
|
*next_track;
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
while (track) {
|
|
|
|
|
next_track = track->next;
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_track_free(track);
|
|
|
|
|
MEM_freeN(track);
|
2011-12-05 18:57:17 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
track = next_track;
|
|
|
|
|
}
|
2012-09-03 01:05:04 +00:00
|
|
|
|
2014-02-08 06:07:10 +11:00
|
|
|
BLI_listbase_clear(&tracking_clipboard.tracks);
|
2011-11-28 13:26:46 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
void BKE_tracking_clipboard_copy_tracks(MovieTracking * /*tracking*/,
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2013-05-12 16:04:08 +00:00
|
|
|
/* First drop all tracks from current clipboard. */
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_clipboard_free();
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Then copy all selected visible tracks to it. */
|
2022-10-05 18:01:29 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
2012-06-15 11:03:23 +00:00
|
|
|
if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
|
2013-12-30 17:03:59 +06:00
|
|
|
MovieTrackingTrack *new_track = BKE_tracking_track_duplicate(track);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
BLI_addtail(&tracking_clipboard.tracks, new_track);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-02 19:37:22 +10:00
|
|
|
bool BKE_tracking_clipboard_has_tracks()
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2014-02-08 06:07:10 +11:00
|
|
|
return (BLI_listbase_is_empty(&tracking_clipboard.tracks) == false);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
void BKE_tracking_clipboard_paste_tracks(MovieTracking * /*tracking*/,
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object)
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2022-10-05 15:56:08 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_clipboard.tracks) {
|
2013-12-30 17:03:59 +06:00
|
|
|
MovieTrackingTrack *new_track = BKE_tracking_track_duplicate(track);
|
2022-10-04 17:39:57 +02:00
|
|
|
|
|
|
|
|
/* TODO(sergey): Preserve active track from before the copy. */
|
2023-03-01 12:32:15 +01:00
|
|
|
if (track->prev == nullptr) {
|
2022-10-05 18:01:29 +02:00
|
|
|
tracking_object->active_track = new_track;
|
2014-09-26 14:49:06 +06:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
BLI_addtail(&tracking_object->tracks, new_track);
|
|
|
|
|
BKE_tracking_track_unique_name(&tracking_object->tracks, new_track);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Tracks.
|
|
|
|
|
*/
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2020-11-20 15:06:25 +01:00
|
|
|
MovieTrackingTrack *BKE_tracking_track_add_empty(MovieTracking *tracking, ListBase *tracks_list)
|
|
|
|
|
{
|
|
|
|
|
const MovieTrackingSettings *settings = &tracking->settings;
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingTrack *track = MEM_cnew<MovieTrackingTrack>("add_marker_exec track");
|
2023-06-19 20:06:55 +10:00
|
|
|
STRNCPY(track->name, "Track");
|
2020-11-20 15:06:25 +01:00
|
|
|
|
|
|
|
|
/* Fill track's settings from default settings. */
|
|
|
|
|
track->motion_model = settings->default_motion_model;
|
|
|
|
|
track->minimum_correlation = settings->default_minimum_correlation;
|
|
|
|
|
track->margin = settings->default_margin;
|
|
|
|
|
track->pattern_match = settings->default_pattern_match;
|
|
|
|
|
track->frames_limit = settings->default_frames_limit;
|
|
|
|
|
track->flag = settings->default_flag;
|
|
|
|
|
track->algorithm_flag = settings->default_algorithm_flag;
|
|
|
|
|
track->weight = settings->default_weight;
|
|
|
|
|
track->weight_stab = settings->default_weight;
|
|
|
|
|
|
|
|
|
|
BLI_addtail(tracks_list, track);
|
|
|
|
|
BKE_tracking_track_unique_name(tracks_list, track);
|
|
|
|
|
|
|
|
|
|
return track;
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking,
|
|
|
|
|
ListBase *tracksbase,
|
|
|
|
|
float x,
|
|
|
|
|
float y,
|
2012-03-25 23:19:21 +00:00
|
|
|
int framenr,
|
|
|
|
|
int width,
|
|
|
|
|
int height)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2020-11-20 15:18:33 +01:00
|
|
|
const MovieTrackingSettings *settings = &tracking->settings;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-11-28 11:14:32 +01:00
|
|
|
MovieTrackingTrack *track = BKE_tracking_track_add_empty(tracking, tracksbase);
|
|
|
|
|
MovieTrackingMarker marker;
|
|
|
|
|
|
2020-11-20 15:18:33 +01:00
|
|
|
const float half_pattern_px = settings->default_pattern_size / 2.0f;
|
|
|
|
|
const float half_search_px = settings->default_search_size / 2.0f;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2020-11-20 15:18:33 +01:00
|
|
|
const float pattern_size[2] = {half_pattern_px / width, half_pattern_px / height};
|
|
|
|
|
const float search_size[2] = {half_search_px / width, half_search_px / height};
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
memset(&marker, 0, sizeof(marker));
|
2012-03-25 23:19:21 +00:00
|
|
|
marker.pos[0] = x;
|
|
|
|
|
marker.pos[1] = y;
|
|
|
|
|
marker.framenr = framenr;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2020-11-20 15:18:33 +01:00
|
|
|
marker.pattern_corners[0][0] = -pattern_size[0];
|
|
|
|
|
marker.pattern_corners[0][1] = -pattern_size[1];
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2020-11-20 15:18:33 +01:00
|
|
|
marker.pattern_corners[1][0] = pattern_size[0];
|
|
|
|
|
marker.pattern_corners[1][1] = -pattern_size[1];
|
2011-11-07 12:55:18 +00:00
|
|
|
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
negate_v2_v2(marker.pattern_corners[2], marker.pattern_corners[0]);
|
|
|
|
|
negate_v2_v2(marker.pattern_corners[3], marker.pattern_corners[1]);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2020-11-20 15:18:33 +01:00
|
|
|
copy_v2_v2(marker.search_max, search_size);
|
|
|
|
|
negate_v2_v2(marker.search_min, search_size);
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_marker_insert(track, &marker);
|
2011-11-28 13:26:46 +00:00
|
|
|
|
2011-11-07 12:55:18 +00:00
|
|
|
return track;
|
|
|
|
|
}
|
|
|
|
|
|
2013-12-30 17:03:59 +06:00
|
|
|
MovieTrackingTrack *BKE_tracking_track_duplicate(MovieTrackingTrack *track)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingTrack *new_track;
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
new_track = MEM_cnew<MovieTrackingTrack>("tracking_track_duplicate new_track");
|
2013-12-30 17:03:59 +06:00
|
|
|
|
|
|
|
|
*new_track = *track;
|
2023-03-01 12:32:15 +01:00
|
|
|
new_track->next = new_track->prev = nullptr;
|
2013-12-30 17:03:59 +06:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
new_track->markers = static_cast<MovieTrackingMarker *>(MEM_dupallocN(new_track->markers));
|
2013-12-30 17:03:59 +06:00
|
|
|
|
2020-03-11 21:39:56 +11:00
|
|
|
/* Prevent duplicate from being used for 2D stabilization.
|
Rework 2D stabilizator
See this page for motivation and description of concepts:
https://github.com/Ichthyostega/blender/wiki
See this video for UI explanation and demonstration of usage
http://vimeo.com/blenderHack/stabilizerdemo
This proposal attempts to improve usability of Blender's image stabilization
feature for real-world footage esp. with moving and panning camera. It builds
upon the feature tracking to get a measurement of 2D image movement.
- Use a weighted average of movement contributions (instead of a median).
- Allow for rotation compensation and zoom (image scale) compensation.
- Allow to pick a different set of tracks for translation and for
rotation/zoom.
- Treat translation / rotation / zoom contributions systematically in a
similar way.
- Improve handling of partial tracking data with gaps and varying
start / end points.
- Have a user definable anchor frame and interpolate / extrapolate data to
avoid jumping back to "neutral" position when no tracking data is available.
- Support for travelling and panning shots by including an //intended//
position/rotation/zoom ("target position"). The idea is for these parameters
to be //animated// by the user, in order to supply an smooth, intended
camera movement. This way, we can keep the image content roughly in frame
even when moving completely away from the initial view.
A known shortcoming is that the pivot point for rotation compensation is set to
the translation compensated image center. This can produce spurious rotation on
travelling shots, which needs to be compensated manually (by animating the
target rotation parameter). There are several possible ways to address that
problem, yet all of them are considered beyond the scope of this improvement
proposal for now.
Own modifications:
- Restrict line length, it's really handy for split-view editing
- In motion tracking we prefer fully human-readable comments, meaning we
don't use doxygen with it's weird markup and comments are supposed to
start with capital and end with a full stop,
- Add explicit comparison of pointer to NULL.
Reviewers: sergey
Subscribers: kusi, kdawg, forest-house, mardy, Samoth, plasmasolutions, willolis, sebastian_k, hype, enetheru, sunboy, jta, leon_cheung
Maniphest Tasks: T49036
Differential Revision: https://developer.blender.org/D583
2016-08-16 10:32:55 +02:00
|
|
|
* If necessary, it shall be added explicitly.
|
|
|
|
|
*/
|
|
|
|
|
new_track->flag &= ~TRACK_USE_2D_STAB;
|
|
|
|
|
new_track->flag &= ~TRACK_USE_2D_STAB_ROT;
|
|
|
|
|
|
2013-12-30 17:03:59 +06:00
|
|
|
return new_track;
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
void BKE_tracking_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2015-08-16 17:32:01 +10:00
|
|
|
BLI_uniquename(tracksbase,
|
|
|
|
|
track,
|
|
|
|
|
CTX_DATA_(BLT_I18NCONTEXT_ID_MOVIECLIP, "Track"),
|
|
|
|
|
'.',
|
2013-03-25 08:29:06 +00:00
|
|
|
offsetof(MovieTrackingTrack, name),
|
|
|
|
|
sizeof(track->name));
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
void BKE_tracking_track_free(MovieTrackingTrack *track)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (track->markers) {
|
2012-06-15 11:03:23 +00:00
|
|
|
MEM_freeN(track->markers);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2019-11-28 11:14:32 +01:00
|
|
|
void BKE_tracking_track_first_last_frame_get(const MovieTrackingTrack *track,
|
|
|
|
|
int *r_first_frame,
|
|
|
|
|
int *r_last_frame)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(track->markersnr > 0);
|
|
|
|
|
const int last_marker_index = track->markersnr - 1;
|
|
|
|
|
*r_first_frame = track->markers[0].framenr;
|
|
|
|
|
*r_last_frame = track->markers[last_marker_index].framenr;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_tracks_first_last_frame_minmax(/*const*/ MovieTrackingTrack **tracks,
|
|
|
|
|
const int num_tracks,
|
|
|
|
|
int *r_first_frame,
|
|
|
|
|
int *r_last_frame)
|
|
|
|
|
{
|
|
|
|
|
*r_first_frame = INT_MAX;
|
|
|
|
|
*r_last_frame = INT_MIN;
|
|
|
|
|
for (int i = 0; i < num_tracks; ++i) {
|
2023-06-03 08:36:28 +10:00
|
|
|
const MovieTrackingTrack *track = tracks[i];
|
2019-11-28 11:14:32 +01:00
|
|
|
int track_first_frame, track_last_frame;
|
|
|
|
|
BKE_tracking_track_first_last_frame_get(track, &track_first_frame, &track_last_frame);
|
|
|
|
|
*r_first_frame = min_ii(*r_first_frame, track_first_frame);
|
|
|
|
|
*r_last_frame = max_ii(*r_last_frame, track_last_frame);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BKE_tracking_count_selected_tracks_in_list(const ListBase *tracks_list)
|
|
|
|
|
{
|
|
|
|
|
int num_selected_tracks = 0;
|
|
|
|
|
LISTBASE_FOREACH (const MovieTrackingTrack *, track, tracks_list) {
|
|
|
|
|
if (TRACK_SELECTED(track)) {
|
|
|
|
|
++num_selected_tracks;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return num_selected_tracks;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int BKE_tracking_count_selected_tracks_in_active_object(/*const*/ MovieTracking *tracking)
|
|
|
|
|
{
|
2022-10-07 11:32:21 +02:00
|
|
|
const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
|
|
|
|
|
return BKE_tracking_count_selected_tracks_in_list(&tracking_object->tracks);
|
2019-11-28 11:14:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MovieTrackingTrack **BKE_tracking_selected_tracks_in_active_object(MovieTracking *tracking,
|
|
|
|
|
int *r_num_tracks)
|
|
|
|
|
{
|
|
|
|
|
*r_num_tracks = 0;
|
|
|
|
|
|
2022-10-07 11:32:21 +02:00
|
|
|
const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
|
2019-11-28 11:14:32 +01:00
|
|
|
|
|
|
|
|
/* Initialize input. */
|
|
|
|
|
const int num_selected_tracks = BKE_tracking_count_selected_tracks_in_active_object(tracking);
|
|
|
|
|
if (num_selected_tracks == 0) {
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2019-11-28 11:14:32 +01:00
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingTrack **source_tracks = MEM_cnew_array<MovieTrackingTrack *>(
|
|
|
|
|
num_selected_tracks, "selected tracks array");
|
2019-11-28 11:14:32 +01:00
|
|
|
int source_track_index = 0;
|
2022-10-07 11:32:21 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
2019-11-28 11:14:32 +01:00
|
|
|
if (!TRACK_SELECTED(track)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
source_tracks[source_track_index] = track;
|
|
|
|
|
++source_track_index;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*r_num_tracks = num_selected_tracks;
|
|
|
|
|
|
|
|
|
|
return source_tracks;
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
void BKE_tracking_track_flag_set(MovieTrackingTrack *track, int area, int flag)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (area == TRACK_AREA_NONE) {
|
2012-06-15 11:03:23 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (area & TRACK_AREA_POINT) {
|
2012-06-15 11:03:23 +00:00
|
|
|
track->flag |= flag;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (area & TRACK_AREA_PAT) {
|
2012-06-15 11:03:23 +00:00
|
|
|
track->pat_flag |= flag;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (area & TRACK_AREA_SEARCH) {
|
2012-06-15 11:03:23 +00:00
|
|
|
track->search_flag |= flag;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (area == TRACK_AREA_NONE) {
|
2012-06-15 11:03:23 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (area & TRACK_AREA_POINT) {
|
2012-06-15 11:03:23 +00:00
|
|
|
track->flag &= ~flag;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (area & TRACK_AREA_PAT) {
|
2012-06-15 11:03:23 +00:00
|
|
|
track->pat_flag &= ~flag;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (area & TRACK_AREA_SEARCH) {
|
2012-06-15 11:03:23 +00:00
|
|
|
track->search_flag &= ~flag;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:36 +00:00
|
|
|
bool BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
return BKE_tracking_marker_get_exact(track, framenr) != nullptr;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:36 +00:00
|
|
|
bool BKE_tracking_track_has_enabled_marker_at_frame(MovieTrackingTrack *track, int framenr)
|
2012-01-25 13:37:11 +00:00
|
|
|
{
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
|
2012-01-25 13:37:11 +00:00
|
|
|
|
|
|
|
|
return marker && (marker->flag & MARKER_DISABLED) == 0;
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
static void path_clear_remained(MovieTrackingTrack *track, const int ref_frame)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2022-05-12 10:16:33 +02:00
|
|
|
for (int a = 1; a < track->markersnr; a++) {
|
|
|
|
|
if (track->markers[a].framenr > ref_frame) {
|
|
|
|
|
track->markersnr = a;
|
2023-03-01 12:32:15 +01:00
|
|
|
track->markers = static_cast<MovieTrackingMarker *>(
|
|
|
|
|
MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
if (track->markersnr) {
|
|
|
|
|
tracking_marker_insert_disabled(track, &track->markers[track->markersnr - 1], false, true);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
static void path_clear_up_to(MovieTrackingTrack *track, const int ref_frame)
|
|
|
|
|
{
|
|
|
|
|
for (int a = track->markersnr - 1; a >= 0; a--) {
|
|
|
|
|
if (track->markers[a].framenr <= ref_frame) {
|
|
|
|
|
memmove(track->markers,
|
|
|
|
|
track->markers + a,
|
|
|
|
|
(track->markersnr - a) * sizeof(MovieTrackingMarker));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
track->markersnr = track->markersnr - a;
|
2023-03-01 12:32:15 +01:00
|
|
|
track->markers = static_cast<MovieTrackingMarker *>(
|
|
|
|
|
MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
break;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2022-05-12 10:16:33 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
if (track->markersnr) {
|
|
|
|
|
tracking_marker_insert_disabled(track, &track->markers[0], true, true);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2022-05-12 10:16:33 +02:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
static void path_clear_all(MovieTrackingTrack *track, const int ref_frame)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingMarker *marker, marker_new;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
marker = BKE_tracking_marker_get(track, ref_frame);
|
|
|
|
|
marker_new = *marker;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
MEM_freeN(track->markers);
|
2023-03-01 12:32:15 +01:00
|
|
|
track->markers = nullptr;
|
2022-05-12 10:16:33 +02:00
|
|
|
track->markersnr = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:16:33 +02:00
|
|
|
BKE_tracking_marker_insert(track, &marker_new);
|
|
|
|
|
|
|
|
|
|
tracking_marker_insert_disabled(track, &marker_new, true, true);
|
|
|
|
|
tracking_marker_insert_disabled(track, &marker_new, false, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_track_path_clear(MovieTrackingTrack *track,
|
|
|
|
|
const int ref_frame,
|
|
|
|
|
const eTrackClearAction action)
|
|
|
|
|
{
|
|
|
|
|
switch (action) {
|
|
|
|
|
case TRACK_CLEAR_REMAINED:
|
|
|
|
|
path_clear_remained(track, ref_frame);
|
|
|
|
|
break;
|
|
|
|
|
case TRACK_CLEAR_UPTO:
|
|
|
|
|
path_clear_up_to(track, ref_frame);
|
|
|
|
|
break;
|
|
|
|
|
case TRACK_CLEAR_ALL:
|
|
|
|
|
path_clear_all(track, ref_frame);
|
|
|
|
|
break;
|
|
|
|
|
};
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2012-10-15 10:43:10 +00:00
|
|
|
void BKE_tracking_tracks_join(MovieTracking *tracking,
|
|
|
|
|
MovieTrackingTrack *dst_track,
|
|
|
|
|
MovieTrackingTrack *src_track)
|
2019-04-17 06:17:24 +02:00
|
|
|
{
|
2012-03-25 23:19:21 +00:00
|
|
|
int i = 0, a = 0, b = 0, tot;
|
2011-11-07 12:55:18 +00:00
|
|
|
MovieTrackingMarker *markers;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-03-25 23:19:21 +00:00
|
|
|
tot = dst_track->markersnr + src_track->markersnr;
|
2023-03-01 12:32:15 +01:00
|
|
|
markers = MEM_cnew_array<MovieTrackingMarker>(tot, "tmp tracking joined tracks");
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-25 23:19:21 +00:00
|
|
|
while (a < src_track->markersnr || b < dst_track->markersnr) {
|
|
|
|
|
if (b >= dst_track->markersnr) {
|
|
|
|
|
markers[i] = src_track->markers[a++];
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-03-25 23:19:21 +00:00
|
|
|
else if (a >= src_track->markersnr) {
|
|
|
|
|
markers[i] = dst_track->markers[b++];
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-03-25 23:19:21 +00:00
|
|
|
else if (src_track->markers[a].framenr < dst_track->markers[b].framenr) {
|
|
|
|
|
markers[i] = src_track->markers[a++];
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-03-25 23:19:21 +00:00
|
|
|
else if (src_track->markers[a].framenr > dst_track->markers[b].framenr) {
|
|
|
|
|
markers[i] = dst_track->markers[b++];
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2012-03-25 23:19:21 +00:00
|
|
|
if ((src_track->markers[a].flag & MARKER_DISABLED) == 0) {
|
2012-05-07 08:53:59 +00:00
|
|
|
if ((dst_track->markers[b].flag & MARKER_DISABLED) == 0) {
|
2012-03-21 17:21:27 +00:00
|
|
|
/* both tracks are enabled on this frame, so find the whole segment
|
2012-03-25 23:19:21 +00:00
|
|
|
* on which tracks are intersecting and blend tracks using linear
|
|
|
|
|
* interpolation to prevent jumps
|
2019-04-17 06:17:24 +02:00
|
|
|
*/
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2012-06-10 19:59:02 +00:00
|
|
|
MovieTrackingMarker *marker_a, *marker_b;
|
|
|
|
|
int start_a = a, start_b = b, len = 0, frame = src_track->markers[a].framenr;
|
2020-02-07 12:20:05 +01:00
|
|
|
int inverse = 0;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-05-07 08:53:59 +00:00
|
|
|
inverse = (b == 0) || (dst_track->markers[b - 1].flag & MARKER_DISABLED) ||
|
2011-11-07 12:55:18 +00:00
|
|
|
(dst_track->markers[b - 1].framenr != frame - 1);
|
|
|
|
|
|
2012-03-25 23:19:21 +00:00
|
|
|
/* find length of intersection */
|
2012-03-21 17:21:27 +00:00
|
|
|
while (a < src_track->markersnr && b < dst_track->markersnr) {
|
2011-11-07 12:55:18 +00:00
|
|
|
marker_a = &src_track->markers[a];
|
2012-03-21 17:21:27 +00:00
|
|
|
marker_b = &dst_track->markers[b];
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (marker_a->flag & MARKER_DISABLED || marker_b->flag & MARKER_DISABLED) {
|
2012-03-25 23:19:21 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (marker_a->framenr != frame || marker_b->framenr != frame) {
|
2012-05-07 08:53:59 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-10 19:59:02 +00:00
|
|
|
frame++;
|
2019-04-17 06:17:24 +02:00
|
|
|
len++;
|
|
|
|
|
a++;
|
|
|
|
|
b++;
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-03-21 17:21:27 +00:00
|
|
|
a = start_a;
|
2011-11-07 12:55:18 +00:00
|
|
|
b = start_b;
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
/* linear interpolation for intersecting frames */
|
2020-02-07 12:20:05 +01:00
|
|
|
for (int j = 0; j < len; j++) {
|
2012-03-21 17:21:27 +00:00
|
|
|
float fac = 0.5f;
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (len > 1) {
|
2012-03-21 17:21:27 +00:00
|
|
|
fac = 1.0f / (len - 1) * j;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-03-21 17:21:27 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (inverse) {
|
2012-03-21 17:21:27 +00:00
|
|
|
fac = 1.0f - fac;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-03-21 17:21:27 +00:00
|
|
|
|
2012-03-25 23:19:21 +00:00
|
|
|
marker_a = &src_track->markers[a];
|
2012-03-21 17:21:27 +00:00
|
|
|
marker_b = &dst_track->markers[b];
|
|
|
|
|
|
|
|
|
|
markers[i] = dst_track->markers[b];
|
|
|
|
|
interp_v2_v2v2(markers[i].pos, marker_b->pos, marker_a->pos, fac);
|
2019-04-17 06:17:24 +02:00
|
|
|
a++;
|
|
|
|
|
b++;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
2012-03-21 17:21:27 +00:00
|
|
|
|
|
|
|
|
/* this values will be incremented at the end of the loop cycle */
|
2019-04-17 06:17:24 +02:00
|
|
|
a--;
|
|
|
|
|
b--;
|
|
|
|
|
i--;
|
|
|
|
|
}
|
2012-03-21 17:21:27 +00:00
|
|
|
else {
|
|
|
|
|
markers[i] = src_track->markers[a];
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2012-03-21 17:21:27 +00:00
|
|
|
markers[i] = dst_track->markers[b];
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-03-21 17:21:27 +00:00
|
|
|
|
|
|
|
|
a++;
|
|
|
|
|
b++;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-03-21 17:21:27 +00:00
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
MEM_freeN(dst_track->markers);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
dst_track->markers = MEM_cnew_array<MovieTrackingMarker>(i, "tracking joined tracks");
|
2011-11-07 12:55:18 +00:00
|
|
|
memcpy(dst_track->markers, markers, i * sizeof(MovieTrackingMarker));
|
2012-03-16 14:06:43 +00:00
|
|
|
|
|
|
|
|
dst_track->markersnr = i;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
|
|
|
|
MEM_freeN(markers);
|
|
|
|
|
|
2012-10-15 10:43:10 +00:00
|
|
|
BKE_tracking_dopesheet_tag_update(tracking);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2019-11-28 11:14:32 +01:00
|
|
|
static void accumulate_marker(MovieTrackingMarker *dst_marker,
|
|
|
|
|
const MovieTrackingMarker *src_marker)
|
|
|
|
|
{
|
|
|
|
|
BLI_assert(dst_marker->framenr == src_marker->framenr);
|
|
|
|
|
|
|
|
|
|
if (src_marker->flag & MARKER_DISABLED) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
add_v2_v2(dst_marker->pos, src_marker->pos);
|
|
|
|
|
for (int corner = 0; corner < 4; ++corner) {
|
|
|
|
|
add_v2_v2(dst_marker->pattern_corners[corner], src_marker->pattern_corners[corner]);
|
|
|
|
|
}
|
|
|
|
|
add_v2_v2(dst_marker->search_min, src_marker->search_min);
|
|
|
|
|
add_v2_v2(dst_marker->search_max, src_marker->search_max);
|
|
|
|
|
|
|
|
|
|
BLI_assert(is_finite_v2(src_marker->search_min));
|
|
|
|
|
BLI_assert(is_finite_v2(src_marker->search_max));
|
|
|
|
|
|
|
|
|
|
dst_marker->flag &= ~MARKER_DISABLED;
|
|
|
|
|
if ((src_marker->flag & MARKER_TRACKED) == 0) {
|
|
|
|
|
dst_marker->flag &= ~MARKER_TRACKED;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void multiply_marker(MovieTrackingMarker *marker, const float multiplier)
|
|
|
|
|
{
|
|
|
|
|
mul_v2_fl(marker->pos, multiplier);
|
|
|
|
|
for (int corner = 0; corner < 4; ++corner) {
|
|
|
|
|
mul_v2_fl(marker->pattern_corners[corner], multiplier);
|
|
|
|
|
}
|
|
|
|
|
mul_v2_fl(marker->search_min, multiplier);
|
|
|
|
|
mul_v2_fl(marker->search_max, multiplier);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-20 13:59:35 +01:00
|
|
|
/* Helper function for BKE_tracking_tracks_average which takes care of averaging fields of
|
|
|
|
|
* markers (position, patterns, ...). */
|
|
|
|
|
static void tracking_average_markers(MovieTrackingTrack *dst_track,
|
|
|
|
|
/*const*/ MovieTrackingTrack **src_tracks,
|
|
|
|
|
const int num_src_tracks)
|
2019-11-28 11:14:32 +01:00
|
|
|
{
|
|
|
|
|
/* Get global range of frames within which averaging would happen. */
|
|
|
|
|
int first_frame, last_frame;
|
|
|
|
|
BKE_tracking_tracks_first_last_frame_minmax(
|
|
|
|
|
src_tracks, num_src_tracks, &first_frame, &last_frame);
|
|
|
|
|
if (last_frame < first_frame) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
const int num_frames = last_frame - first_frame + 1;
|
|
|
|
|
|
|
|
|
|
/* Allocate temporary array where averaging will happen into. */
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingMarker *accumulator = MEM_cnew_array<MovieTrackingMarker>(
|
|
|
|
|
num_frames, "tracks average accumulator");
|
|
|
|
|
int *counters = MEM_cnew_array<int>(num_frames, "tracks accumulator counters");
|
2019-11-28 11:14:32 +01:00
|
|
|
for (int frame = first_frame; frame <= last_frame; ++frame) {
|
|
|
|
|
const int frame_index = frame - first_frame;
|
|
|
|
|
accumulator[frame_index].framenr = frame;
|
|
|
|
|
accumulator[frame_index].flag |= (MARKER_DISABLED | MARKER_TRACKED);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Accumulate track markers. */
|
|
|
|
|
for (int track_index = 0; track_index < num_src_tracks; ++track_index) {
|
|
|
|
|
/*const*/ MovieTrackingTrack *track = src_tracks[track_index];
|
|
|
|
|
for (int frame = first_frame; frame <= last_frame; ++frame) {
|
|
|
|
|
MovieTrackingMarker interpolated_marker;
|
|
|
|
|
if (!BKE_tracking_marker_get_interpolated(track, frame, &interpolated_marker)) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
const int frame_index = frame - first_frame;
|
|
|
|
|
accumulate_marker(&accumulator[frame_index], &interpolated_marker);
|
|
|
|
|
++counters[frame_index];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Average and store the result. */
|
|
|
|
|
for (int frame = first_frame; frame <= last_frame; ++frame) {
|
|
|
|
|
/* Average. */
|
|
|
|
|
const int frame_index = frame - first_frame;
|
|
|
|
|
if (!counters[frame_index]) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
2023-03-03 23:27:50 +11:00
|
|
|
const float multiplier = 1.0f / float(counters[frame_index]);
|
2019-11-28 11:14:32 +01:00
|
|
|
multiply_marker(&accumulator[frame_index], multiplier);
|
|
|
|
|
/* Store the result. */
|
|
|
|
|
BKE_tracking_marker_insert(dst_track, &accumulator[frame_index]);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Free memory. */
|
|
|
|
|
MEM_freeN(accumulator);
|
|
|
|
|
MEM_freeN(counters);
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-20 13:59:35 +01:00
|
|
|
/* Helper function for BKE_tracking_tracks_average which takes care of averaging fields of
|
|
|
|
|
* tracks (track for example, offset). */
|
|
|
|
|
static void tracking_average_tracks(MovieTrackingTrack *dst_track,
|
|
|
|
|
/*const*/ MovieTrackingTrack **src_tracks,
|
|
|
|
|
const int num_src_tracks)
|
|
|
|
|
{
|
|
|
|
|
/* TODO(sergey): Consider averaging weight, stabilization weight, maybe even bundle position. */
|
|
|
|
|
zero_v2(dst_track->offset);
|
|
|
|
|
for (int track_index = 0; track_index < num_src_tracks; track_index++) {
|
|
|
|
|
add_v2_v2(dst_track->offset, src_tracks[track_index]->offset);
|
|
|
|
|
}
|
|
|
|
|
mul_v2_fl(dst_track->offset, 1.0f / num_src_tracks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_tracks_average(MovieTrackingTrack *dst_track,
|
|
|
|
|
/*const*/ MovieTrackingTrack **src_tracks,
|
|
|
|
|
const int num_src_tracks)
|
|
|
|
|
{
|
|
|
|
|
if (num_src_tracks == 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tracking_average_markers(dst_track, src_tracks, num_src_tracks);
|
|
|
|
|
tracking_average_tracks(dst_track, src_tracks, num_src_tracks);
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-17 15:15:53 +02:00
|
|
|
MovieTrackingTrack *BKE_tracking_track_get_for_selection_index(MovieTracking *tracking,
|
|
|
|
|
int selection_index,
|
|
|
|
|
ListBase **r_tracksbase)
|
2011-12-05 18:57:17 +00:00
|
|
|
{
|
2012-06-15 11:03:23 +00:00
|
|
|
int cur = 1;
|
2011-12-05 18:57:17 +00:00
|
|
|
|
2022-10-05 15:56:08 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingObject *, object, &tracking->objects) {
|
|
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, &object->tracks) {
|
2012-06-15 11:03:23 +00:00
|
|
|
if (track->flag & TRACK_HAS_BUNDLE) {
|
2022-10-17 15:15:53 +02:00
|
|
|
if (cur == selection_index) {
|
2022-10-05 15:56:08 +02:00
|
|
|
*r_tracksbase = &object->tracks;
|
2012-06-15 11:03:23 +00:00
|
|
|
return track;
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
cur++;
|
|
|
|
|
}
|
2012-05-03 17:52:34 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
*r_tracksbase = nullptr;
|
2012-05-03 17:52:34 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2012-04-30 16:19:20 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
static bGPDlayer *track_mask_gpencil_layer_get(const MovieTrackingTrack *track)
|
2012-01-09 20:18:48 +00:00
|
|
|
{
|
2012-06-15 11:03:23 +00:00
|
|
|
bGPDlayer *layer;
|
2012-01-09 20:18:48 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!track->gpd) {
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-01-09 20:18:48 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
layer = static_cast<bGPDlayer *>(track->gpd->layers.first);
|
2012-01-09 20:18:48 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
while (layer) {
|
|
|
|
|
if (layer->flag & GP_LAYER_ACTIVE) {
|
2023-03-01 12:32:15 +01:00
|
|
|
bGPDframe *frame = static_cast<bGPDframe *>(layer->frames.first);
|
2013-05-12 16:04:08 +00:00
|
|
|
bool ok = false;
|
2012-01-09 20:18:48 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
while (frame) {
|
|
|
|
|
if (frame->strokes.first) {
|
2013-05-12 16:04:08 +00:00
|
|
|
ok = true;
|
|
|
|
|
break;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2012-05-03 17:02:33 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
frame = frame->next;
|
|
|
|
|
}
|
2012-01-09 20:18:48 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (ok) {
|
2012-06-15 11:03:23 +00:00
|
|
|
return layer;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-01-09 20:18:48 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
layer = layer->next;
|
2012-01-09 20:18:48 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2012-01-09 20:18:48 +00:00
|
|
|
}
|
|
|
|
|
|
2023-07-02 19:37:19 +10:00
|
|
|
struct TrackMaskSetPixelData {
|
2016-01-08 16:24:36 +05:00
|
|
|
float *mask;
|
|
|
|
|
int mask_width;
|
|
|
|
|
int mask_height;
|
2023-07-02 19:37:19 +10:00
|
|
|
};
|
2016-01-08 16:24:36 +05:00
|
|
|
|
2016-01-08 23:29:42 +11:00
|
|
|
static void track_mask_set_pixel_cb(int x, int x_end, int y, void *user_data)
|
2016-01-08 16:24:36 +05:00
|
|
|
{
|
|
|
|
|
TrackMaskSetPixelData *data = (TrackMaskSetPixelData *)user_data;
|
2023-03-03 23:27:50 +11:00
|
|
|
size_t index = size_t(y) * data->mask_width + x;
|
|
|
|
|
size_t index_end = size_t(y) * data->mask_width + x_end;
|
2016-01-08 23:29:42 +11:00
|
|
|
do {
|
|
|
|
|
data->mask[index] = 1.0f;
|
|
|
|
|
} while (++index != index_end);
|
2016-01-08 16:24:36 +05:00
|
|
|
}
|
|
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
static void track_mask_gpencil_layer_rasterize(const int frame_width,
|
|
|
|
|
const int frame_height,
|
2017-05-26 15:21:15 +02:00
|
|
|
const float region_min[2],
|
2022-10-04 16:57:16 +02:00
|
|
|
const bGPDlayer *layer,
|
2017-05-26 15:21:15 +02:00
|
|
|
float *mask,
|
2022-10-04 16:57:16 +02:00
|
|
|
const int mask_width,
|
|
|
|
|
const int mask_height)
|
2012-01-09 20:18:48 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const bGPDframe *frame = static_cast<const bGPDframe *>(layer->frames.first);
|
2016-01-08 16:24:36 +05:00
|
|
|
TrackMaskSetPixelData data;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2016-01-08 16:24:36 +05:00
|
|
|
data.mask = mask;
|
|
|
|
|
data.mask_width = mask_width;
|
|
|
|
|
data.mask_height = mask_height;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
while (frame) {
|
2023-03-01 12:32:15 +01:00
|
|
|
const bGPDstroke *stroke = static_cast<const bGPDstroke *>(frame->strokes.first);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
while (stroke) {
|
2022-10-04 16:57:16 +02:00
|
|
|
const bGPDspoint *stroke_points = stroke->points;
|
2012-06-15 11:03:23 +00:00
|
|
|
if (stroke->flag & GP_STROKE_2DSPACE) {
|
2016-01-08 16:25:19 +05:00
|
|
|
int *mask_points, *point;
|
2023-03-01 12:32:15 +01:00
|
|
|
point = mask_points = MEM_cnew_array<int>(2 * stroke->totpoints,
|
|
|
|
|
"track mask rasterization points");
|
2016-01-08 16:25:19 +05:00
|
|
|
for (int i = 0; i < stroke->totpoints; i++, point += 2) {
|
2017-05-26 15:21:15 +02:00
|
|
|
point[0] = stroke_points[i].x * frame_width - region_min[0];
|
|
|
|
|
point[1] = stroke_points[i].y * frame_height - region_min[1];
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2012-07-26 17:41:09 +00:00
|
|
|
/* TODO: add an option to control whether AA is enabled or not */
|
2016-10-26 20:14:48 +11:00
|
|
|
BLI_bitmap_draw_2d_poly_v2i_n(0,
|
|
|
|
|
0,
|
|
|
|
|
mask_width,
|
|
|
|
|
mask_height,
|
|
|
|
|
(const int(*)[2])mask_points,
|
|
|
|
|
stroke->totpoints,
|
|
|
|
|
track_mask_set_pixel_cb,
|
|
|
|
|
&data);
|
2012-06-15 11:03:23 +00:00
|
|
|
MEM_freeN(mask_points);
|
|
|
|
|
}
|
|
|
|
|
stroke = stroke->next;
|
|
|
|
|
}
|
|
|
|
|
frame = frame->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
float *tracking_track_get_mask_for_region(const int frame_width,
|
|
|
|
|
const int frame_height,
|
2017-05-26 15:21:15 +02:00
|
|
|
const float region_min[2],
|
|
|
|
|
const float region_max[2],
|
2022-10-04 16:57:16 +02:00
|
|
|
const MovieTrackingTrack *track)
|
2011-11-27 19:17:59 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
float *mask = nullptr;
|
2022-10-04 16:57:16 +02:00
|
|
|
const bGPDlayer *layer = track_mask_gpencil_layer_get(track);
|
2023-03-01 12:32:15 +01:00
|
|
|
if (layer != nullptr) {
|
2017-05-26 15:21:15 +02:00
|
|
|
const int mask_width = region_max[0] - region_min[0];
|
|
|
|
|
const int mask_height = region_max[1] - region_min[1];
|
2023-03-01 12:32:15 +01:00
|
|
|
mask = MEM_cnew_array<float>(mask_width * mask_height, "track mask");
|
2017-05-26 15:21:15 +02:00
|
|
|
track_mask_gpencil_layer_rasterize(
|
|
|
|
|
frame_width, frame_height, region_min, layer, mask, mask_width, mask_height);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
return mask;
|
2011-11-27 19:17:59 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
float *BKE_tracking_track_get_mask(const int frame_width,
|
|
|
|
|
const int frame_height,
|
|
|
|
|
const MovieTrackingTrack *track,
|
|
|
|
|
const MovieTrackingMarker *marker)
|
2017-05-26 15:21:15 +02:00
|
|
|
{
|
|
|
|
|
/* Convert normalized space marker's search area to pixel-space region. */
|
2019-04-18 17:17:32 +02:00
|
|
|
const float region_min[2] = {
|
|
|
|
|
marker->search_min[0] * frame_width,
|
|
|
|
|
marker->search_min[1] * frame_height,
|
|
|
|
|
};
|
|
|
|
|
const float region_max[2] = {
|
|
|
|
|
marker->search_max[0] * frame_width,
|
|
|
|
|
marker->search_max[1] * frame_height,
|
|
|
|
|
};
|
2017-05-26 15:21:15 +02:00
|
|
|
return tracking_track_get_mask_for_region(
|
|
|
|
|
frame_width, frame_height, region_min, region_max, track);
|
|
|
|
|
}
|
|
|
|
|
|
2014-01-28 18:01:03 +06:00
|
|
|
float BKE_tracking_track_get_weight_for_marker(MovieClip *clip,
|
|
|
|
|
MovieTrackingTrack *track,
|
|
|
|
|
MovieTrackingMarker *marker)
|
|
|
|
|
{
|
|
|
|
|
FCurve *weight_fcurve;
|
|
|
|
|
float weight = track->weight;
|
|
|
|
|
|
|
|
|
|
weight_fcurve = id_data_find_fcurve(
|
2023-03-01 12:32:15 +01:00
|
|
|
&clip->id, track, &RNA_MovieTrackingTrack, "weight", 0, nullptr);
|
2014-01-28 18:01:03 +06:00
|
|
|
|
|
|
|
|
if (weight_fcurve) {
|
|
|
|
|
int scene_framenr = BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);
|
|
|
|
|
weight = evaluate_fcurve(weight_fcurve, scene_framenr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return weight;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:36 +00:00
|
|
|
void BKE_tracking_track_select(ListBase *tracksbase,
|
|
|
|
|
MovieTrackingTrack *track,
|
|
|
|
|
int area,
|
|
|
|
|
bool extend)
|
2011-11-27 19:17:59 +00:00
|
|
|
{
|
2012-06-15 11:03:23 +00:00
|
|
|
if (extend) {
|
|
|
|
|
BKE_tracking_track_flag_set(track, area, SELECT);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingTrack *cur = static_cast<MovieTrackingTrack *>(tracksbase->first);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
while (cur) {
|
|
|
|
|
if ((cur->flag & TRACK_HIDDEN) == 0) {
|
|
|
|
|
if (cur == track) {
|
|
|
|
|
BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
|
|
|
|
|
BKE_tracking_track_flag_set(cur, area, SELECT);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
cur = cur->next;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area)
|
2011-11-27 19:17:59 +00:00
|
|
|
{
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_track_flag_clear(track, area, SELECT);
|
|
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
void BKE_tracking_tracks_deselect_all(ListBase *tracksbase)
|
|
|
|
|
{
|
2020-02-07 12:51:18 +01:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, tracksbase) {
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
if ((track->flag & TRACK_HIDDEN) == 0) {
|
|
|
|
|
BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Marker.
|
|
|
|
|
*/
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track,
|
|
|
|
|
MovieTrackingMarker *marker)
|
|
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingMarker *old_marker = nullptr;
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (track->markersnr) {
|
2012-06-15 11:03:23 +00:00
|
|
|
old_marker = BKE_tracking_marker_get_exact(track, marker->framenr);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
if (old_marker) {
|
|
|
|
|
/* simply replace settings for already allocated marker */
|
|
|
|
|
*old_marker = *marker;
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
return old_marker;
|
2012-03-24 06:18:31 +00:00
|
|
|
}
|
2011-12-05 18:57:17 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
int a = track->markersnr;
|
|
|
|
|
|
|
|
|
|
/* find position in array where to add new marker */
|
|
|
|
|
while (a--) {
|
|
|
|
|
if (track->markers[a].framenr < marker->framenr) {
|
|
|
|
|
break;
|
2011-12-05 18:57:17 +00:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
}
|
2011-12-05 18:57:17 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
track->markersnr++;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
if (track->markers) {
|
2023-03-01 12:32:15 +01:00
|
|
|
track->markers = static_cast<MovieTrackingMarker *>(
|
|
|
|
|
MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr));
|
2020-08-07 12:30:43 +02:00
|
|
|
}
|
|
|
|
|
else {
|
2023-03-01 12:32:15 +01:00
|
|
|
track->markers = MEM_cnew<MovieTrackingMarker>("MovieTracking markers");
|
2020-08-07 12:30:43 +02:00
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
/* shift array to "free" space for new marker */
|
|
|
|
|
memmove(track->markers + a + 2,
|
|
|
|
|
track->markers + a + 1,
|
|
|
|
|
(track->markersnr - a - 2) * sizeof(MovieTrackingMarker));
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
/* put new marker */
|
|
|
|
|
track->markers[a + 1] = *marker;
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
return &track->markers[a + 1];
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr)
|
|
|
|
|
{
|
|
|
|
|
int a = 0;
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
while (a < track->markersnr) {
|
|
|
|
|
if (track->markers[a].framenr == framenr) {
|
|
|
|
|
if (track->markersnr > 1) {
|
|
|
|
|
memmove(track->markers + a,
|
|
|
|
|
track->markers + a + 1,
|
|
|
|
|
(track->markersnr - a - 1) * sizeof(MovieTrackingMarker));
|
|
|
|
|
track->markersnr--;
|
2023-03-01 12:32:15 +01:00
|
|
|
track->markers = static_cast<MovieTrackingMarker *>(
|
|
|
|
|
MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr));
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MEM_freeN(track->markers);
|
2023-03-01 12:32:15 +01:00
|
|
|
track->markers = nullptr;
|
2012-06-15 11:03:23 +00:00
|
|
|
track->markersnr = 0;
|
2011-11-27 19:17:59 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
a++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2022-05-12 10:58:22 +02:00
|
|
|
void BKE_tracking_marker_clamp_pattern_position(MovieTrackingMarker *marker)
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
|
|
|
|
float pat_min[2], pat_max[2];
|
|
|
|
|
BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:58:22 +02:00
|
|
|
for (int a = 0; a < 2; a++) {
|
|
|
|
|
if (pat_min[a] < marker->search_min[a]) {
|
|
|
|
|
for (int b = 0; b < 4; b++) {
|
|
|
|
|
marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a];
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2022-05-12 10:58:22 +02:00
|
|
|
}
|
|
|
|
|
if (pat_max[a] > marker->search_max[a]) {
|
|
|
|
|
for (int b = 0; b < 4; b++) {
|
|
|
|
|
marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a];
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
}
|
2022-05-12 10:58:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_marker_clamp_search_size(MovieTrackingMarker *marker)
|
|
|
|
|
{
|
|
|
|
|
float pat_min[2], pat_max[2];
|
|
|
|
|
BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
|
|
|
|
|
|
|
|
|
|
for (int a = 0; a < 2; a++) {
|
|
|
|
|
marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]);
|
|
|
|
|
marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2022-05-12 10:58:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_marker_clamp_search_position(MovieTrackingMarker *marker)
|
|
|
|
|
{
|
|
|
|
|
float pat_min[2], pat_max[2];
|
|
|
|
|
BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:58:22 +02:00
|
|
|
float dim[2];
|
|
|
|
|
sub_v2_v2v2(dim, marker->search_max, marker->search_min);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-05-12 10:58:22 +02:00
|
|
|
for (int a = 0; a < 2; a++) {
|
|
|
|
|
if (marker->search_min[a] > pat_min[a]) {
|
|
|
|
|
marker->search_min[a] = pat_min[a];
|
|
|
|
|
marker->search_max[a] = marker->search_min[a] + dim[a];
|
|
|
|
|
}
|
|
|
|
|
if (marker->search_max[a] < pat_max[a]) {
|
|
|
|
|
marker->search_max[a] = pat_max[a];
|
|
|
|
|
marker->search_min[a] = marker->search_max[a] - dim[a];
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
|
2011-11-27 19:17:59 +00:00
|
|
|
{
|
2020-11-25 10:40:17 +01:00
|
|
|
const int num_markers = track->markersnr;
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2020-11-25 10:40:17 +01:00
|
|
|
if (num_markers == 0) {
|
2021-07-15 18:23:28 +10:00
|
|
|
BLI_assert_msg(0, "Detected degenerated track, should never happen.");
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2020-11-25 10:40:17 +01:00
|
|
|
int left_boundary = 0;
|
|
|
|
|
int right_boundary = num_markers;
|
|
|
|
|
while (left_boundary < right_boundary) {
|
|
|
|
|
const int median_index = (left_boundary + right_boundary) / 2;
|
|
|
|
|
MovieTrackingMarker *marker = &track->markers[median_index];
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2020-11-25 10:40:17 +01:00
|
|
|
if (marker->framenr == framenr) {
|
|
|
|
|
return marker;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2021-01-18 14:21:24 -06:00
|
|
|
|
|
|
|
|
if (marker->framenr < framenr) {
|
2020-11-25 10:40:17 +01:00
|
|
|
left_boundary = median_index + 1;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
BLI_assert(marker->framenr > framenr);
|
|
|
|
|
right_boundary = median_index - 1;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2020-11-25 10:40:17 +01:00
|
|
|
const int closest_index = clamp_i(right_boundary, 0, num_markers - 1);
|
2020-08-07 12:30:43 +02:00
|
|
|
|
2020-11-25 10:40:17 +01:00
|
|
|
return &track->markers[closest_index];
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingMarker *BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (marker->framenr != framenr) {
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
return marker;
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingMarker *BKE_tracking_marker_ensure(MovieTrackingTrack *track, int framenr)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
if (marker->framenr != framenr) {
|
|
|
|
|
MovieTrackingMarker marker_new;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
marker_new = *marker;
|
|
|
|
|
marker_new.framenr = framenr;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_marker_insert(track, &marker_new);
|
|
|
|
|
marker = BKE_tracking_marker_get(track, framenr);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
return marker;
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2020-12-28 17:28:28 +01:00
|
|
|
static const MovieTrackingMarker *get_usable_marker_for_interpolation(
|
2023-06-03 08:36:28 +10:00
|
|
|
MovieTrackingTrack *track, const MovieTrackingMarker *anchor_marker, const int direction)
|
2020-12-28 17:28:28 +01:00
|
|
|
{
|
2022-03-09 09:35:37 +11:00
|
|
|
BLI_assert(ELEM(direction, -1, 1));
|
2020-12-28 17:28:28 +01:00
|
|
|
|
|
|
|
|
const MovieTrackingMarker *last_marker = track->markers + track->markersnr - 1;
|
|
|
|
|
const MovieTrackingMarker *current_marker = anchor_marker;
|
|
|
|
|
|
|
|
|
|
while (current_marker >= track->markers && current_marker <= last_marker) {
|
|
|
|
|
if ((current_marker->flag & MARKER_DISABLED) == 0) {
|
|
|
|
|
return current_marker;
|
|
|
|
|
}
|
|
|
|
|
current_marker += direction;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2020-12-28 17:28:28 +01:00
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
bool BKE_tracking_marker_get_interpolated(MovieTrackingTrack *track,
|
2020-12-28 17:28:28 +01:00
|
|
|
const int framenr,
|
2023-06-03 08:36:28 +10:00
|
|
|
MovieTrackingMarker *r_marker)
|
2020-12-28 17:28:28 +01:00
|
|
|
{
|
|
|
|
|
const MovieTrackingMarker *closest_marker = BKE_tracking_marker_get(track, framenr);
|
2023-03-01 12:32:15 +01:00
|
|
|
if (closest_marker == nullptr) {
|
2020-12-28 17:28:28 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (closest_marker->framenr == framenr && (closest_marker->flag & MARKER_DISABLED) == 0) {
|
|
|
|
|
*r_marker = *closest_marker;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const MovieTrackingMarker *left_marker = get_usable_marker_for_interpolation(
|
|
|
|
|
track, closest_marker, -1);
|
2023-03-01 12:32:15 +01:00
|
|
|
if (left_marker == nullptr) {
|
2020-12-28 17:28:28 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const MovieTrackingMarker *right_marker = get_usable_marker_for_interpolation(
|
|
|
|
|
track, closest_marker + 1, 1);
|
2023-03-01 12:32:15 +01:00
|
|
|
if (right_marker == nullptr) {
|
2020-12-28 17:28:28 +01:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (left_marker == right_marker) {
|
|
|
|
|
*r_marker = *left_marker;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-03 23:27:50 +11:00
|
|
|
const float factor = float(framenr - left_marker->framenr) /
|
2020-12-28 17:28:28 +01:00
|
|
|
(right_marker->framenr - left_marker->framenr);
|
|
|
|
|
|
|
|
|
|
interp_v2_v2v2(r_marker->pos, left_marker->pos, right_marker->pos, factor);
|
|
|
|
|
|
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
|
interp_v2_v2v2(r_marker->pattern_corners[i],
|
|
|
|
|
left_marker->pattern_corners[i],
|
|
|
|
|
right_marker->pattern_corners[i],
|
|
|
|
|
factor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interp_v2_v2v2(r_marker->search_min, left_marker->search_min, right_marker->search_min, factor);
|
|
|
|
|
interp_v2_v2v2(r_marker->search_max, left_marker->search_max, right_marker->search_max, factor);
|
|
|
|
|
|
|
|
|
|
r_marker->framenr = framenr;
|
|
|
|
|
r_marker->flag = 0;
|
|
|
|
|
|
|
|
|
|
if (framenr == left_marker->framenr) {
|
|
|
|
|
r_marker->flag = left_marker->flag;
|
|
|
|
|
}
|
|
|
|
|
else if (framenr == right_marker->framenr) {
|
|
|
|
|
r_marker->flag = right_marker->flag;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker,
|
|
|
|
|
float min[2],
|
|
|
|
|
float max[2])
|
|
|
|
|
{
|
|
|
|
|
INIT_MINMAX2(min, max);
|
2011-11-27 19:17:59 +00:00
|
|
|
|
2012-11-15 22:20:18 +00:00
|
|
|
minmax_v2v2_v2(min, max, marker->pattern_corners[0]);
|
|
|
|
|
minmax_v2v2_v2(min, max, marker->pattern_corners[1]);
|
|
|
|
|
minmax_v2v2_v2(min, max, marker->pattern_corners[2]);
|
|
|
|
|
minmax_v2v2_v2(min, max, marker->pattern_corners[3]);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-07-27 10:12:58 +00:00
|
|
|
void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track,
|
|
|
|
|
float framenr,
|
|
|
|
|
float pos[2])
|
|
|
|
|
{
|
2023-03-03 23:27:50 +11:00
|
|
|
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, int(framenr));
|
2012-07-27 10:12:58 +00:00
|
|
|
MovieTrackingMarker *marker_last = track->markers + (track->markersnr - 1);
|
|
|
|
|
|
|
|
|
|
if (marker != marker_last) {
|
|
|
|
|
MovieTrackingMarker *marker_next = marker + 1;
|
|
|
|
|
|
|
|
|
|
if (marker_next->framenr == marker->framenr + 1) {
|
2023-03-07 14:58:15 +11:00
|
|
|
/* Currently only do sub-framing inside tracked ranges, do not extrapolate tracked segments
|
2012-07-27 10:12:58 +00:00
|
|
|
* could be changed when / if mask parent would be interpolating position in-between
|
2023-03-07 14:58:15 +11:00
|
|
|
* tracked segments. */
|
2012-07-27 10:12:58 +00:00
|
|
|
|
2023-03-03 23:27:50 +11:00
|
|
|
float fac = (framenr - int(framenr)) / (marker_next->framenr - marker->framenr);
|
2012-07-27 10:12:58 +00:00
|
|
|
|
|
|
|
|
interp_v2_v2v2(pos, marker->pos, marker_next->pos, fac);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_v2_v2(pos, marker->pos);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_v2_v2(pos, marker->pos);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* currently track offset is always wanted to be applied here, could be made an option later */
|
|
|
|
|
add_v2_v2(pos, track->offset);
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Plane track.
|
|
|
|
|
*/
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
|
|
|
|
MovieTrackingPlaneTrack *BKE_tracking_plane_track_add(MovieTracking *tracking,
|
|
|
|
|
ListBase *plane_tracks_base,
|
|
|
|
|
ListBase *tracks,
|
|
|
|
|
int framenr)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingPlaneTrack *plane_track;
|
|
|
|
|
MovieTrackingPlaneMarker plane_marker;
|
|
|
|
|
float tracks_min[2], tracks_max[2];
|
2020-02-07 12:51:18 +01:00
|
|
|
int num_selected_tracks = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
(void)tracking; /* Ignored. */
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
/* Use bounding box of selected markers as an initial size of plane. */
|
|
|
|
|
INIT_MINMAX2(tracks_min, tracks_max);
|
2020-02-07 12:51:18 +01:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks) {
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
if (TRACK_SELECTED(track)) {
|
|
|
|
|
MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
|
|
|
|
|
float pattern_min[2], pattern_max[2];
|
|
|
|
|
BKE_tracking_marker_pattern_minmax(marker, pattern_min, pattern_max);
|
|
|
|
|
add_v2_v2(pattern_min, marker->pos);
|
|
|
|
|
add_v2_v2(pattern_max, marker->pos);
|
|
|
|
|
minmax_v2v2_v2(tracks_min, tracks_max, pattern_min);
|
|
|
|
|
minmax_v2v2_v2(tracks_min, tracks_max, pattern_max);
|
|
|
|
|
num_selected_tracks++;
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
if (num_selected_tracks < 4) {
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
/* Allocate new plane track. */
|
2023-03-01 12:32:15 +01:00
|
|
|
plane_track = MEM_cnew<MovieTrackingPlaneTrack>("new plane track");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
/* Use some default name. */
|
2023-06-19 20:06:55 +10:00
|
|
|
STRNCPY(plane_track->name, "Plane Track");
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-11-29 23:26:57 +06:00
|
|
|
plane_track->image_opacity = 1.0f;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
/* Use selected tracks from given list as a plane. */
|
2023-03-01 12:32:15 +01:00
|
|
|
plane_track->point_tracks = MEM_cnew_array<MovieTrackingTrack *>(num_selected_tracks,
|
|
|
|
|
"new plane tracks array");
|
2020-02-07 12:51:18 +01:00
|
|
|
int track_index = 0;
|
|
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, tracks) {
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
if (TRACK_SELECTED(track)) {
|
|
|
|
|
plane_track->point_tracks[track_index] = track;
|
|
|
|
|
track_index++;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
|
|
|
|
plane_track->point_tracksnr = num_selected_tracks;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
/* Setup new plane marker and add it to the track. */
|
|
|
|
|
plane_marker.framenr = framenr;
|
|
|
|
|
plane_marker.flag = 0;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
copy_v2_v2(plane_marker.corners[0], tracks_min);
|
|
|
|
|
copy_v2_v2(plane_marker.corners[2], tracks_max);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
plane_marker.corners[1][0] = tracks_max[0];
|
|
|
|
|
plane_marker.corners[1][1] = tracks_min[1];
|
|
|
|
|
plane_marker.corners[3][0] = tracks_min[0];
|
|
|
|
|
plane_marker.corners[3][1] = tracks_max[1];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
BKE_tracking_plane_marker_insert(plane_track, &plane_marker);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
/* Put new plane track to the list, ensure its name is unique. */
|
|
|
|
|
BLI_addtail(plane_tracks_base, plane_track);
|
|
|
|
|
BKE_tracking_plane_track_unique_name(plane_tracks_base, plane_track);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
return plane_track;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
void BKE_tracking_plane_track_unique_name(ListBase *plane_tracks_base,
|
|
|
|
|
MovieTrackingPlaneTrack *plane_track)
|
|
|
|
|
{
|
2015-08-16 17:32:01 +10:00
|
|
|
BLI_uniquename(plane_tracks_base,
|
|
|
|
|
plane_track,
|
|
|
|
|
CTX_DATA_(BLT_I18NCONTEXT_ID_MOVIECLIP, "Plane Track"),
|
|
|
|
|
'.',
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
offsetof(MovieTrackingPlaneTrack, name),
|
|
|
|
|
sizeof(plane_track->name));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_plane_track_free(MovieTrackingPlaneTrack *plane_track)
|
|
|
|
|
{
|
|
|
|
|
if (plane_track->markers) {
|
|
|
|
|
MEM_freeN(plane_track->markers);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(plane_track->point_tracks);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_plane_tracks_deselect_all(ListBase *plane_tracks_base)
|
|
|
|
|
{
|
2020-02-07 12:51:18 +01:00
|
|
|
LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, plane_tracks_base) {
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
plane_track->flag &= ~SELECT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-22 01:54:45 +05:00
|
|
|
bool BKE_tracking_plane_track_has_point_track(MovieTrackingPlaneTrack *plane_track,
|
|
|
|
|
MovieTrackingTrack *track)
|
|
|
|
|
{
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int i = 0; i < plane_track->point_tracksnr; i++) {
|
2015-04-22 01:54:45 +05:00
|
|
|
if (plane_track->point_tracks[i] == track) {
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool BKE_tracking_plane_track_remove_point_track(MovieTrackingPlaneTrack *plane_track,
|
|
|
|
|
MovieTrackingTrack *track)
|
|
|
|
|
{
|
|
|
|
|
if (plane_track->point_tracksnr <= 4) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingTrack **new_point_tracks = MEM_cnew_array<MovieTrackingTrack *>(
|
|
|
|
|
plane_track->point_tracksnr - 1, "new point tracks array");
|
2015-04-22 01:54:45 +05:00
|
|
|
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int i = 0, track_index = 0; i < plane_track->point_tracksnr; i++) {
|
2015-04-22 01:54:45 +05:00
|
|
|
if (plane_track->point_tracks[i] != track) {
|
|
|
|
|
new_point_tracks[track_index++] = plane_track->point_tracks[i];
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(plane_track->point_tracks);
|
|
|
|
|
plane_track->point_tracks = new_point_tracks;
|
|
|
|
|
plane_track->point_tracksnr--;
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_plane_tracks_remove_point_track(MovieTracking *tracking,
|
|
|
|
|
MovieTrackingTrack *track)
|
|
|
|
|
{
|
2022-10-07 11:32:21 +02:00
|
|
|
MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
|
|
|
|
|
LISTBASE_FOREACH_MUTABLE (MovieTrackingPlaneTrack *, plane_track, &tracking_object->plane_tracks)
|
|
|
|
|
{
|
2015-04-22 01:54:45 +05:00
|
|
|
if (BKE_tracking_plane_track_has_point_track(plane_track, track)) {
|
|
|
|
|
if (!BKE_tracking_plane_track_remove_point_track(plane_track, track)) {
|
|
|
|
|
/* Delete planes with less than 3 point tracks in it. */
|
|
|
|
|
BKE_tracking_plane_track_free(plane_track);
|
2022-10-07 11:32:21 +02:00
|
|
|
BLI_freelinkN(&tracking_object->plane_tracks, plane_track);
|
2015-04-22 01:54:45 +05:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2015-04-22 02:10:13 +05:00
|
|
|
void BKE_tracking_plane_track_replace_point_track(MovieTrackingPlaneTrack *plane_track,
|
|
|
|
|
MovieTrackingTrack *old_track,
|
|
|
|
|
MovieTrackingTrack *new_track)
|
|
|
|
|
{
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int i = 0; i < plane_track->point_tracksnr; i++) {
|
2015-04-22 02:10:13 +05:00
|
|
|
if (plane_track->point_tracks[i] == old_track) {
|
|
|
|
|
plane_track->point_tracks[i] = new_track;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_plane_tracks_replace_point_track(MovieTracking *tracking,
|
|
|
|
|
MovieTrackingTrack *old_track,
|
|
|
|
|
MovieTrackingTrack *new_track)
|
|
|
|
|
{
|
2022-10-07 11:32:21 +02:00
|
|
|
const MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
|
|
|
|
|
LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking_object->plane_tracks) {
|
2015-04-22 02:10:13 +05:00
|
|
|
if (BKE_tracking_plane_track_has_point_track(plane_track, old_track)) {
|
|
|
|
|
BKE_tracking_plane_track_replace_point_track(plane_track, old_track, new_track);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Plane marker.
|
|
|
|
|
*/
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
|
|
|
|
MovieTrackingPlaneMarker *BKE_tracking_plane_marker_insert(MovieTrackingPlaneTrack *plane_track,
|
|
|
|
|
MovieTrackingPlaneMarker *plane_marker)
|
|
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingPlaneMarker *old_plane_marker = nullptr;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (plane_track->markersnr) {
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
old_plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, plane_marker->framenr);
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
|
|
|
|
if (old_plane_marker) {
|
|
|
|
|
/* Simply replace settings in existing marker. */
|
|
|
|
|
*old_plane_marker = *plane_marker;
|
|
|
|
|
|
|
|
|
|
return old_plane_marker;
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
int a = plane_track->markersnr;
|
|
|
|
|
|
|
|
|
|
/* Find position in array where to add new marker. */
|
|
|
|
|
/* TODO(sergey): we could use bisect to speed things up. */
|
|
|
|
|
while (a--) {
|
|
|
|
|
if (plane_track->markers[a].framenr < plane_marker->framenr) {
|
|
|
|
|
break;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
}
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
plane_track->markersnr++;
|
2023-03-01 12:32:15 +01:00
|
|
|
plane_track->markers = static_cast<MovieTrackingPlaneMarker *>(MEM_reallocN(
|
|
|
|
|
plane_track->markers, sizeof(MovieTrackingPlaneMarker) * plane_track->markersnr));
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
/* Shift array to "free" space for new marker. */
|
|
|
|
|
memmove(plane_track->markers + a + 2,
|
|
|
|
|
plane_track->markers + a + 1,
|
|
|
|
|
(plane_track->markersnr - a - 2) * sizeof(MovieTrackingPlaneMarker));
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
/* Put new marker to an array. */
|
|
|
|
|
plane_track->markers[a + 1] = *plane_marker;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
return &plane_track->markers[a + 1];
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_plane_marker_delete(MovieTrackingPlaneTrack *plane_track, int framenr)
|
|
|
|
|
{
|
|
|
|
|
int a = 0;
|
|
|
|
|
|
|
|
|
|
while (a < plane_track->markersnr) {
|
|
|
|
|
if (plane_track->markers[a].framenr == framenr) {
|
|
|
|
|
if (plane_track->markersnr > 1) {
|
|
|
|
|
memmove(plane_track->markers + a,
|
|
|
|
|
plane_track->markers + a + 1,
|
|
|
|
|
(plane_track->markersnr - a - 1) * sizeof(MovieTrackingPlaneMarker));
|
|
|
|
|
plane_track->markersnr--;
|
2023-03-01 12:32:15 +01:00
|
|
|
plane_track->markers = static_cast<MovieTrackingPlaneMarker *>(MEM_reallocN(
|
|
|
|
|
plane_track->markers, sizeof(MovieTrackingMarker) * plane_track->markersnr));
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
MEM_freeN(plane_track->markers);
|
2023-03-01 12:32:15 +01:00
|
|
|
plane_track->markers = nullptr;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
plane_track->markersnr = 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* TODO(sergey): The next couple of functions are really quite the same as point marker version,
|
|
|
|
|
* would be nice to de-duplicate them somehow..
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get(MovieTrackingPlaneTrack *plane_track,
|
|
|
|
|
int framenr)
|
|
|
|
|
{
|
|
|
|
|
int a = plane_track->markersnr - 1;
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!plane_track->markersnr) {
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
|
|
|
|
/* Approximate pre-first framenr marker with first marker. */
|
|
|
|
|
if (framenr < plane_track->markers[0].framenr) {
|
|
|
|
|
return &plane_track->markers[0];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (plane_track->last_marker < plane_track->markersnr) {
|
|
|
|
|
a = plane_track->last_marker;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (plane_track->markers[a].framenr <= framenr) {
|
|
|
|
|
while (a < plane_track->markersnr && plane_track->markers[a].framenr <= framenr) {
|
|
|
|
|
if (plane_track->markers[a].framenr == framenr) {
|
|
|
|
|
plane_track->last_marker = a;
|
|
|
|
|
|
|
|
|
|
return &plane_track->markers[a];
|
|
|
|
|
}
|
|
|
|
|
a++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* If there's no marker for exact position, use nearest marker from left side. */
|
|
|
|
|
return &plane_track->markers[a - 1];
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
while (a >= 0 && plane_track->markers[a].framenr >= framenr) {
|
|
|
|
|
if (plane_track->markers[a].framenr == framenr) {
|
|
|
|
|
plane_track->last_marker = a;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
return &plane_track->markers[a];
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
a--;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
/* If there's no marker for exact position, use nearest marker from left side. */
|
|
|
|
|
return &plane_track->markers[a];
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get_exact(MovieTrackingPlaneTrack *plane_track,
|
|
|
|
|
int framenr)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
|
|
|
|
|
|
|
|
|
|
if (plane_marker->framenr != framenr) {
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
Merge plane track feature from tomato branch
This commit includes all the changes made for plane tracker
in tomato branch.
Movie clip editor changes:
- Artist might create a plane track out of multiple point
tracks which belongs to the same track (minimum amount of
point tracks is 4, maximum is not actually limited).
When new plane track is added, it's getting "tracked"
across all point tracks, which makes it stick to the same
plane point tracks belong to.
- After plane track was added, it need to be manually adjusted
in a way it covers feature one might to mask/replace.
General transform tools (G, R, S) or sliding corners with
a mouse could be sued for this. Plane corner which
corresponds to left bottom image corner has got X/Y axis
on it (red is for X axis, green for Y).
- Re-adjusting plane corners makes plane to be "re-tracked"
for the frames sequence between current frame and next
and previous keyframes.
- Kayframes might be removed from the plane, using Shit-X
(Marker Delete) operator. However, currently manual
re-adjustment or "re-track" trigger is needed.
Compositor changes:
- Added new node called Plane Track Deform.
- User selects which plane track to use (for this he need
to select movie clip datablock, object and track names).
- Node gets an image input, which need to be warped into
the plane.
- Node outputs:
* Input image warped into the plane.
* Plane, rasterized to a mask.
Masking changes:
- Mask points might be parented to a plane track, which
makes this point deforming in a way as if it belongs
to the tracked plane.
Some video tutorials are available:
- Coder video: http://www.youtube.com/watch?v=vISEwqNHqe4
- Artist video: https://vimeo.com/71727578
This is mine and Keir's holiday code project :)
2013-08-16 09:46:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return plane_marker;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MovieTrackingPlaneMarker *BKE_tracking_plane_marker_ensure(MovieTrackingPlaneTrack *plane_track,
|
|
|
|
|
int framenr)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
|
|
|
|
|
|
|
|
|
|
if (plane_marker->framenr != framenr) {
|
|
|
|
|
MovieTrackingPlaneMarker plane_marker_new;
|
|
|
|
|
|
|
|
|
|
plane_marker_new = *plane_marker;
|
|
|
|
|
plane_marker_new.framenr = framenr;
|
|
|
|
|
|
|
|
|
|
plane_marker = BKE_tracking_plane_marker_insert(plane_track, &plane_marker_new);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return plane_marker;
|
|
|
|
|
}
|
|
|
|
|
|
2014-11-18 15:29:03 +01:00
|
|
|
void BKE_tracking_plane_marker_get_subframe_corners(MovieTrackingPlaneTrack *plane_track,
|
|
|
|
|
float framenr,
|
|
|
|
|
float corners[4][2])
|
|
|
|
|
{
|
2023-03-03 23:27:50 +11:00
|
|
|
MovieTrackingPlaneMarker *marker = BKE_tracking_plane_marker_get(plane_track, int(framenr));
|
2014-11-18 15:29:03 +01:00
|
|
|
MovieTrackingPlaneMarker *marker_last = plane_track->markers + (plane_track->markersnr - 1);
|
|
|
|
|
if (marker != marker_last) {
|
|
|
|
|
MovieTrackingPlaneMarker *marker_next = marker + 1;
|
|
|
|
|
if (marker_next->framenr == marker->framenr + 1) {
|
2023-03-03 23:27:50 +11:00
|
|
|
float fac = (framenr - int(framenr)) / (marker_next->framenr - marker->framenr);
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int i = 0; i < 4; i++) {
|
2014-11-18 15:29:03 +01:00
|
|
|
interp_v2_v2v2(corners[i], marker->corners[i], marker_next->corners[i], fac);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-11-18 15:29:03 +01:00
|
|
|
}
|
|
|
|
|
else {
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int i = 0; i < 4; i++) {
|
2014-11-18 15:29:03 +01:00
|
|
|
copy_v2_v2(corners[i], marker->corners[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else {
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int i = 0; i < 4; i++) {
|
2014-11-18 15:29:03 +01:00
|
|
|
copy_v2_v2(corners[i], marker->corners[i]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Object.
|
|
|
|
|
*/
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name)
|
|
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingObject *tracking_object = MEM_cnew<MovieTrackingObject>("tracking object");
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
if (tracking->tot_object == 0) {
|
|
|
|
|
/* first object is always camera */
|
2023-05-09 12:50:37 +10:00
|
|
|
STRNCPY(tracking_object->name, "Camera");
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
tracking_object->flag |= TRACKING_OBJECT_CAMERA;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2023-05-09 12:50:37 +10:00
|
|
|
STRNCPY(tracking_object->name, name);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
BLI_addtail(&tracking->objects, tracking_object);
|
2011-12-27 10:52:23 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
tracking->tot_object++;
|
2014-11-16 13:57:58 +01:00
|
|
|
tracking->objectnr = BLI_listbase_count(&tracking->objects) - 1;
|
2011-12-27 10:52:23 +00:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
tracking_object->scale = 1.0f;
|
|
|
|
|
tracking_object->keyframe1 = 1;
|
|
|
|
|
tracking_object->keyframe2 = 30;
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
BKE_tracking_object_unique_name(tracking, tracking_object);
|
2013-03-06 18:01:24 +00:00
|
|
|
BKE_tracking_dopesheet_tag_update(tracking);
|
2011-12-13 10:07:22 +00:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
return tracking_object;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
bool BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *tracking_object)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
const int index = BLI_findindex(&tracking->objects, tracking_object);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (index == -1) {
|
2013-09-05 13:37:36 +00:00
|
|
|
return false;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
|
2012-06-15 11:03:23 +00:00
|
|
|
/* object used for camera solving can't be deleted */
|
2013-09-05 13:37:36 +00:00
|
|
|
return false;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2012-06-12 11:13:53 +00:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
tracking_object_free(tracking_object);
|
|
|
|
|
BLI_freelinkN(&tracking->objects, tracking_object);
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
tracking->tot_object--;
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (index != 0) {
|
2012-06-15 11:03:23 +00:00
|
|
|
tracking->objectnr = index - 1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
else {
|
2012-06-15 11:03:23 +00:00
|
|
|
tracking->objectnr = 0;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-03-06 18:01:24 +00:00
|
|
|
|
|
|
|
|
BKE_tracking_dopesheet_tag_update(tracking);
|
|
|
|
|
|
2013-09-05 13:37:36 +00:00
|
|
|
return true;
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *tracking_object)
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
2013-03-25 08:29:06 +00:00
|
|
|
BLI_uniquename(&tracking->objects,
|
2022-10-05 18:01:29 +02:00
|
|
|
tracking_object,
|
2013-03-25 08:29:06 +00:00
|
|
|
DATA_("Object"),
|
|
|
|
|
'.',
|
2012-06-15 11:03:23 +00:00
|
|
|
offsetof(MovieTrackingObject, name),
|
2022-10-05 18:01:29 +02:00
|
|
|
sizeof(tracking_object->name));
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MovieTrackingObject *BKE_tracking_object_get_named(MovieTracking *tracking, const char *name)
|
|
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingObject *, tracking_object, &tracking->objects) {
|
|
|
|
|
if (STREQ(tracking_object->name, name)) {
|
|
|
|
|
return tracking_object;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
MovieTrackingObject *BKE_tracking_object_get_active(const MovieTracking *tracking)
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
return static_cast<MovieTrackingObject *>(BLI_findlink(&tracking->objects, tracking->objectnr));
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
MovieTrackingObject *BKE_tracking_object_get_camera(const MovieTracking *tracking)
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingObject *, tracking_object, &tracking->objects) {
|
|
|
|
|
if (tracking_object->flag & TRACKING_OBJECT_CAMERA) {
|
|
|
|
|
return tracking_object;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-07 09:46:11 +02:00
|
|
|
MovieTrackingTrack *BKE_tracking_object_find_track_with_name(MovieTrackingObject *tracking_object,
|
|
|
|
|
const char *name)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
|
|
|
|
if (STREQ(track->name, name)) {
|
|
|
|
|
return track;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2022-10-07 09:46:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MovieTrackingPlaneTrack *BKE_tracking_object_find_plane_track_with_name(
|
|
|
|
|
MovieTrackingObject *tracking_object, const char *name)
|
|
|
|
|
{
|
|
|
|
|
LISTBASE_FOREACH (MovieTrackingPlaneTrack *, plane_track, &tracking_object->plane_tracks) {
|
|
|
|
|
if (STREQ(plane_track->name, name)) {
|
|
|
|
|
return plane_track;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2022-10-07 09:46:11 +02:00
|
|
|
}
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Camera.
|
|
|
|
|
*/
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstruction,
|
|
|
|
|
int framenr,
|
|
|
|
|
bool nearest)
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
|
|
|
|
MovieReconstructedCamera *cameras = reconstruction->cameras;
|
|
|
|
|
int a = 0, d = 1;
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!reconstruction->camnr) {
|
2012-06-15 11:03:23 +00:00
|
|
|
return -1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
if (framenr < cameras[0].framenr) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (nearest) {
|
2012-06-15 11:03:23 +00:00
|
|
|
return 0;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return -1;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (framenr > cameras[reconstruction->camnr - 1].framenr) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (nearest) {
|
2012-06-15 11:03:23 +00:00
|
|
|
return reconstruction->camnr - 1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return -1;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (reconstruction->last_camera < reconstruction->camnr) {
|
2012-06-15 11:03:23 +00:00
|
|
|
a = reconstruction->last_camera;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (cameras[a].framenr >= framenr) {
|
2012-06-15 11:03:23 +00:00
|
|
|
d = -1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
while (a >= 0 && a < reconstruction->camnr) {
|
|
|
|
|
int cfra = cameras[a].framenr;
|
|
|
|
|
|
|
|
|
|
/* check if needed framenr was "skipped" -- no data for requested frame */
|
|
|
|
|
|
|
|
|
|
if (d > 0 && cfra > framenr) {
|
|
|
|
|
/* interpolate with previous position */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (nearest) {
|
2012-06-15 11:03:23 +00:00
|
|
|
return a - 1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
break;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (d < 0 && cfra < framenr) {
|
|
|
|
|
/* interpolate with next position */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (nearest) {
|
2012-06-15 11:03:23 +00:00
|
|
|
return a;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
break;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (cfra == framenr) {
|
|
|
|
|
reconstruction->last_camera = a;
|
|
|
|
|
|
|
|
|
|
return a;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
a += d;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
static void reconstructed_camera_scale_set(const MovieTrackingObject *tracking_object,
|
|
|
|
|
float mat[4][4])
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
if ((tracking_object->flag & TRACKING_OBJECT_CAMERA) == 0) {
|
2012-06-15 11:03:23 +00:00
|
|
|
float smat[4][4];
|
|
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
scale_m4_fl(smat, 1.0f / tracking_object->scale);
|
2013-05-26 18:36:25 +00:00
|
|
|
mul_m4_m4m4(mat, mat, smat);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_camera_shift_get(
|
|
|
|
|
MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
|
|
|
|
|
{
|
2022-11-18 17:15:13 +01:00
|
|
|
float principal_px[2];
|
|
|
|
|
tracking_principal_point_normalized_to_pixel(
|
|
|
|
|
tracking->camera.principal_point, winx, winy, principal_px);
|
|
|
|
|
|
2019-04-27 12:07:07 +10:00
|
|
|
/* Indeed in both of cases it should be winx -
|
|
|
|
|
* it's just how camera shift works for blender's camera. */
|
2022-11-18 17:15:13 +01:00
|
|
|
*shiftx = (0.5f * winx - principal_px[0]) / winx;
|
|
|
|
|
*shifty = (0.5f * winy - principal_px[1]) / winx;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_camera_to_blender(
|
|
|
|
|
MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
|
|
|
|
|
{
|
|
|
|
|
float focal = tracking->camera.focal;
|
|
|
|
|
|
|
|
|
|
camera->sensor_x = tracking->camera.sensor_width;
|
2023-11-15 10:53:30 +01:00
|
|
|
camera->sensor_fit = CAMERA_SENSOR_FIT_HOR;
|
2012-06-15 11:03:23 +00:00
|
|
|
camera->lens = focal * camera->sensor_x / width;
|
|
|
|
|
|
2018-09-24 16:23:45 +02:00
|
|
|
scene->r.xsch = width;
|
2012-06-15 11:03:23 +00:00
|
|
|
scene->r.ysch = height;
|
|
|
|
|
|
2018-09-24 16:23:45 +02:00
|
|
|
scene->r.xasp = tracking->camera.pixel_aspect;
|
2012-06-15 11:03:23 +00:00
|
|
|
scene->r.yasp = 1.0f;
|
|
|
|
|
|
|
|
|
|
BKE_tracking_camera_shift_get(tracking, width, height, &camera->shiftx, &camera->shifty);
|
|
|
|
|
}
|
|
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTracking * /*tracking*/, MovieTrackingObject *tracking_object, int framenr)
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingReconstruction *reconstruction = &tracking_object->reconstruction;
|
2022-10-05 15:56:08 +02:00
|
|
|
int a = reconstructed_camera_index_get(reconstruction, framenr, false);
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (a == -1) {
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
return &reconstruction->cameras[a];
|
|
|
|
|
}
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking * /*tracking*/,
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object,
|
2015-07-13 18:17:07 +02:00
|
|
|
float framenr,
|
|
|
|
|
float mat[4][4])
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingReconstruction *reconstruction = &tracking_object->reconstruction;
|
2022-10-05 15:56:08 +02:00
|
|
|
MovieReconstructedCamera *cameras = reconstruction->cameras;
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2023-03-03 23:27:50 +11:00
|
|
|
int a = reconstructed_camera_index_get(reconstruction, int(framenr), true);
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
if (a == -1) {
|
|
|
|
|
unit_m4(mat);
|
2011-11-07 12:55:18 +00:00
|
|
|
return;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2015-07-13 18:17:07 +02:00
|
|
|
if (cameras[a].framenr != framenr && a < reconstruction->camnr - 1) {
|
2023-03-03 23:27:50 +11:00
|
|
|
float t = (float(framenr) - cameras[a].framenr) /
|
2012-06-15 11:03:23 +00:00
|
|
|
(cameras[a + 1].framenr - cameras[a].framenr);
|
|
|
|
|
blend_m4_m4m4(mat, cameras[a].mat, cameras[a + 1].mat, t);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
copy_m4_m4(mat, cameras[a].mat);
|
|
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
reconstructed_camera_scale_set(tracking_object, mat);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void BKE_tracking_camera_principal_point_pixel_get(MovieClip *clip,
|
2022-11-18 17:15:13 +01:00
|
|
|
float r_principal_point_pixel[2])
|
|
|
|
|
{
|
|
|
|
|
const MovieTrackingCamera *camera = &clip->tracking.camera;
|
|
|
|
|
|
|
|
|
|
int frame_width, frame_height;
|
|
|
|
|
MovieClipUser user = *DNA_struct_default_get(MovieClipUser);
|
|
|
|
|
BKE_movieclip_get_size(clip, &user, &frame_width, &frame_height);
|
|
|
|
|
|
|
|
|
|
tracking_principal_point_normalized_to_pixel(
|
|
|
|
|
camera->principal_point, frame_width, frame_height, r_principal_point_pixel);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void BKE_tracking_camera_principal_point_pixel_set(MovieClip *clip,
|
2022-11-18 17:15:13 +01:00
|
|
|
const float principal_point_pixel[2])
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingCamera *camera = &clip->tracking.camera;
|
|
|
|
|
|
|
|
|
|
int frame_width, frame_height;
|
|
|
|
|
MovieClipUser user = *DNA_struct_default_get(MovieClipUser);
|
|
|
|
|
BKE_movieclip_get_size(clip, &user, &frame_width, &frame_height);
|
|
|
|
|
|
|
|
|
|
tracking_principal_point_pixel_to_normalized(
|
|
|
|
|
principal_point_pixel, frame_width, frame_height, camera->principal_point);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-07 14:45:46 +02:00
|
|
|
bool BKE_tracking_camera_distortion_equal(const MovieTrackingCamera *a,
|
|
|
|
|
const MovieTrackingCamera *b)
|
|
|
|
|
{
|
|
|
|
|
if (a->pixel_aspect != b->pixel_aspect || a->focal != b->focal ||
|
|
|
|
|
!equals_v2v2(a->principal_point, b->principal_point))
|
|
|
|
|
{
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (a->distortion_model != b->distortion_model) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
switch (a->distortion_model) {
|
|
|
|
|
case TRACKING_DISTORTION_MODEL_POLYNOMIAL:
|
|
|
|
|
return a->k1 == b->k1 && a->k2 == b->k2 && a->k3 == b->k3;
|
|
|
|
|
case TRACKING_DISTORTION_MODEL_DIVISION:
|
|
|
|
|
return a->division_k1 == b->division_k1 && a->division_k2 == b->division_k2;
|
|
|
|
|
case TRACKING_DISTORTION_MODEL_NUKE:
|
|
|
|
|
return a->nuke_k1 == b->nuke_k1 && a->nuke_k2 == b->nuke_k2;
|
|
|
|
|
case TRACKING_DISTORTION_MODEL_BROWN:
|
|
|
|
|
return a->brown_k1 == b->brown_k1 && a->brown_k2 == b->brown_k2 &&
|
|
|
|
|
a->brown_k3 == b->brown_k3 && a->brown_k4 == b->brown_k4 &&
|
|
|
|
|
a->brown_p1 == b->brown_p1 && a->brown_p2 == b->brown_p2;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_assert_unreachable();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uint64_t BKE_tracking_camera_distortion_hash(const MovieTrackingCamera *camera)
|
|
|
|
|
{
|
|
|
|
|
using namespace blender;
|
|
|
|
|
switch (camera->distortion_model) {
|
|
|
|
|
case TRACKING_DISTORTION_MODEL_POLYNOMIAL:
|
|
|
|
|
return get_default_hash_4(camera->distortion_model,
|
|
|
|
|
float2(camera->pixel_aspect, camera->focal),
|
|
|
|
|
float2(camera->principal_point),
|
|
|
|
|
float3(camera->k1, camera->k2, camera->k3));
|
|
|
|
|
case TRACKING_DISTORTION_MODEL_DIVISION:
|
|
|
|
|
return get_default_hash_4(camera->distortion_model,
|
|
|
|
|
float2(camera->pixel_aspect, camera->focal),
|
|
|
|
|
float2(camera->principal_point),
|
|
|
|
|
float2(camera->division_k1, camera->division_k2));
|
|
|
|
|
case TRACKING_DISTORTION_MODEL_NUKE:
|
|
|
|
|
return get_default_hash_4(camera->distortion_model,
|
|
|
|
|
float2(camera->pixel_aspect, camera->focal),
|
|
|
|
|
float2(camera->principal_point),
|
|
|
|
|
float2(camera->nuke_k1, camera->nuke_k2));
|
|
|
|
|
case TRACKING_DISTORTION_MODEL_BROWN:
|
|
|
|
|
return get_default_hash_4(
|
|
|
|
|
float2(camera->pixel_aspect, camera->focal),
|
|
|
|
|
float2(camera->principal_point),
|
|
|
|
|
float4(camera->brown_k1, camera->brown_k2, camera->brown_k3, camera->brown_k4),
|
|
|
|
|
float2(camera->brown_p1, camera->brown_p2));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
BLI_assert_unreachable();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* (Un)distortion.
|
|
|
|
|
*/
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2014-02-20 19:41:05 +06:00
|
|
|
MovieDistortion *BKE_tracking_distortion_new(MovieTracking *tracking,
|
|
|
|
|
int calibration_width,
|
|
|
|
|
int calibration_height)
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
|
|
|
|
MovieDistortion *distortion;
|
2014-02-20 19:41:05 +06:00
|
|
|
libmv_CameraIntrinsicsOptions camera_intrinsics_options;
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2014-02-20 19:41:05 +06:00
|
|
|
tracking_cameraIntrinscisOptionsFromTracking(
|
|
|
|
|
tracking, calibration_width, calibration_height, &camera_intrinsics_options);
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
distortion = MEM_cnew<MovieDistortion>("BKE_tracking_distortion_create");
|
2014-02-20 19:41:05 +06:00
|
|
|
distortion->intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
|
2013-03-15 11:59:46 +00:00
|
|
|
|
2016-01-26 11:42:55 +01:00
|
|
|
const MovieTrackingCamera *camera = &tracking->camera;
|
2022-11-18 17:15:13 +01:00
|
|
|
tracking_principal_point_normalized_to_pixel(tracking->camera.principal_point,
|
|
|
|
|
calibration_width,
|
|
|
|
|
calibration_height,
|
|
|
|
|
distortion->principal_px);
|
2016-01-26 11:42:55 +01:00
|
|
|
distortion->pixel_aspect = camera->pixel_aspect;
|
|
|
|
|
distortion->focal = camera->focal;
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
return distortion;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_distortion_update(MovieDistortion *distortion,
|
|
|
|
|
MovieTracking *tracking,
|
|
|
|
|
int calibration_width,
|
|
|
|
|
int calibration_height)
|
|
|
|
|
{
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_CameraIntrinsicsOptions camera_intrinsics_options;
|
2012-12-10 16:38:28 +00:00
|
|
|
|
2014-02-20 19:41:05 +06:00
|
|
|
tracking_cameraIntrinscisOptionsFromTracking(
|
|
|
|
|
tracking, calibration_width, calibration_height, &camera_intrinsics_options);
|
2012-12-10 16:38:28 +00:00
|
|
|
|
2016-01-26 11:42:55 +01:00
|
|
|
const MovieTrackingCamera *camera = &tracking->camera;
|
2022-11-18 17:15:13 +01:00
|
|
|
tracking_principal_point_normalized_to_pixel(tracking->camera.principal_point,
|
|
|
|
|
calibration_width,
|
|
|
|
|
calibration_height,
|
|
|
|
|
distortion->principal_px);
|
2016-01-26 11:42:55 +01:00
|
|
|
distortion->pixel_aspect = camera->pixel_aspect;
|
|
|
|
|
distortion->focal = camera->focal;
|
|
|
|
|
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_cameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2013-03-15 11:59:46 +00:00
|
|
|
void BKE_tracking_distortion_set_threads(MovieDistortion *distortion, int threads)
|
|
|
|
|
{
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_cameraIntrinsicsSetThreads(distortion->intrinsics, threads);
|
2013-03-15 11:59:46 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
|
|
|
|
|
{
|
|
|
|
|
MovieDistortion *new_distortion;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
new_distortion = MEM_cnew<MovieDistortion>("BKE_tracking_distortion_create");
|
2016-01-26 11:42:55 +01:00
|
|
|
*new_distortion = *distortion;
|
2013-07-31 13:48:12 +00:00
|
|
|
new_distortion->intrinsics = libmv_cameraIntrinsicsCopy(distortion->intrinsics);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
return new_distortion;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion,
|
|
|
|
|
MovieTracking *tracking,
|
|
|
|
|
ImBuf *ibuf,
|
2013-09-05 13:37:36 +00:00
|
|
|
int calibration_width,
|
|
|
|
|
int calibration_height,
|
|
|
|
|
float overscan,
|
|
|
|
|
bool undistort)
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
|
|
|
|
ImBuf *resibuf;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_distortion_update(distortion, tracking, calibration_width, calibration_height);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
resibuf = IMB_dupImBuf(ibuf);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
if (ibuf->float_buffer.data) {
|
2012-06-15 11:03:23 +00:00
|
|
|
if (undistort) {
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_cameraIntrinsicsUndistortFloat(distortion->intrinsics,
|
2023-05-18 10:19:01 +02:00
|
|
|
ibuf->float_buffer.data,
|
2014-09-25 17:01:06 +06:00
|
|
|
ibuf->x,
|
|
|
|
|
ibuf->y,
|
|
|
|
|
overscan,
|
|
|
|
|
ibuf->channels,
|
2023-05-18 10:19:01 +02:00
|
|
|
resibuf->float_buffer.data);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_cameraIntrinsicsDistortFloat(distortion->intrinsics,
|
2023-05-18 10:19:01 +02:00
|
|
|
ibuf->float_buffer.data,
|
2014-09-25 17:01:06 +06:00
|
|
|
ibuf->x,
|
|
|
|
|
ibuf->y,
|
|
|
|
|
overscan,
|
|
|
|
|
ibuf->channels,
|
2023-05-18 10:19:01 +02:00
|
|
|
resibuf->float_buffer.data);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
imb_freerectImBuf(ibuf);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
if (undistort) {
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_cameraIntrinsicsUndistortByte(distortion->intrinsics,
|
2023-05-18 10:19:01 +02:00
|
|
|
ibuf->byte_buffer.data,
|
2014-09-25 17:01:06 +06:00
|
|
|
ibuf->x,
|
|
|
|
|
ibuf->y,
|
|
|
|
|
overscan,
|
|
|
|
|
ibuf->channels,
|
2023-05-18 10:19:01 +02:00
|
|
|
resibuf->byte_buffer.data);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_cameraIntrinsicsDistortByte(distortion->intrinsics,
|
2023-05-18 10:19:01 +02:00
|
|
|
ibuf->byte_buffer.data,
|
2014-09-25 17:01:06 +06:00
|
|
|
ibuf->x,
|
|
|
|
|
ibuf->y,
|
|
|
|
|
overscan,
|
|
|
|
|
ibuf->channels,
|
2023-05-18 10:19:01 +02:00
|
|
|
resibuf->byte_buffer.data);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
return resibuf;
|
|
|
|
|
}
|
|
|
|
|
|
2016-01-26 11:42:55 +01:00
|
|
|
void BKE_tracking_distortion_distort_v2(MovieDistortion *distortion,
|
|
|
|
|
const float co[2],
|
|
|
|
|
float r_co[2])
|
|
|
|
|
{
|
|
|
|
|
const float aspy = 1.0f / distortion->pixel_aspect;
|
|
|
|
|
|
|
|
|
|
/* Normalize coords. */
|
|
|
|
|
float inv_focal = 1.0f / distortion->focal;
|
2022-11-18 17:15:13 +01:00
|
|
|
double x = (co[0] - distortion->principal_px[0]) * inv_focal,
|
|
|
|
|
y = (co[1] - distortion->principal_px[1] * aspy) * inv_focal;
|
2016-01-26 11:42:55 +01:00
|
|
|
|
|
|
|
|
libmv_cameraIntrinsicsApply(distortion->intrinsics, x, y, &x, &y);
|
|
|
|
|
|
|
|
|
|
/* Result is in image coords already. */
|
|
|
|
|
r_co[0] = x;
|
|
|
|
|
r_co[1] = y;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void BKE_tracking_distortion_undistort_v2(MovieDistortion *distortion,
|
|
|
|
|
const float co[2],
|
|
|
|
|
float r_co[2])
|
|
|
|
|
{
|
|
|
|
|
double x = co[0], y = co[1];
|
|
|
|
|
libmv_cameraIntrinsicsInvert(distortion->intrinsics, x, y, &x, &y);
|
|
|
|
|
|
|
|
|
|
const float aspy = 1.0f / distortion->pixel_aspect;
|
2023-03-03 23:27:50 +11:00
|
|
|
r_co[0] = float(x) * distortion->focal + distortion->principal_px[0];
|
|
|
|
|
r_co[1] = float(y) * distortion->focal + distortion->principal_px[1] * aspy;
|
2016-01-26 11:42:55 +01:00
|
|
|
}
|
|
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
void BKE_tracking_distortion_free(MovieDistortion *distortion)
|
|
|
|
|
{
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_cameraIntrinsicsDestroy(distortion->intrinsics);
|
2012-06-15 11:03:23 +00:00
|
|
|
|
|
|
|
|
MEM_freeN(distortion);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-17 16:51:00 +02:00
|
|
|
void BKE_tracking_distort_v2(
|
|
|
|
|
MovieTracking *tracking, int image_width, int image_height, const float co[2], float r_co[2])
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2016-01-26 11:42:55 +01:00
|
|
|
const MovieTrackingCamera *camera = &tracking->camera;
|
|
|
|
|
const float aspy = 1.0f / tracking->camera.pixel_aspect;
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_CameraIntrinsicsOptions camera_intrinsics_options;
|
2020-04-17 16:51:00 +02:00
|
|
|
tracking_cameraIntrinscisOptionsFromTracking(
|
|
|
|
|
tracking, image_width, image_height, &camera_intrinsics_options);
|
2016-01-26 11:42:55 +01:00
|
|
|
libmv_CameraIntrinsics *intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
|
2012-12-10 16:38:28 +00:00
|
|
|
|
2022-11-18 17:15:13 +01:00
|
|
|
float principal_px[2];
|
|
|
|
|
tracking_principal_point_normalized_to_pixel(
|
|
|
|
|
tracking->camera.principal_point, image_width, image_height, principal_px);
|
|
|
|
|
|
2016-01-26 11:42:55 +01:00
|
|
|
/* Normalize coordinates. */
|
2022-11-18 17:15:13 +01:00
|
|
|
double x = (co[0] - principal_px[0]) / camera->focal,
|
|
|
|
|
y = (co[1] - principal_px[1] * aspy) / camera->focal;
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2016-01-26 11:42:55 +01:00
|
|
|
libmv_cameraIntrinsicsApply(intrinsics, x, y, &x, &y);
|
|
|
|
|
libmv_cameraIntrinsicsDestroy(intrinsics);
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2016-01-26 11:42:55 +01:00
|
|
|
/* Result is in image coords already. */
|
2012-07-31 22:01:44 +00:00
|
|
|
r_co[0] = x;
|
|
|
|
|
r_co[1] = y;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
2020-04-17 16:51:00 +02:00
|
|
|
void BKE_tracking_undistort_v2(
|
|
|
|
|
MovieTracking *tracking, int image_width, int image_height, const float co[2], float r_co[2])
|
2012-06-15 11:03:23 +00:00
|
|
|
{
|
2016-01-26 11:42:55 +01:00
|
|
|
const MovieTrackingCamera *camera = &tracking->camera;
|
|
|
|
|
const float aspy = 1.0f / tracking->camera.pixel_aspect;
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2013-07-31 13:48:12 +00:00
|
|
|
libmv_CameraIntrinsicsOptions camera_intrinsics_options;
|
2020-04-17 16:51:00 +02:00
|
|
|
tracking_cameraIntrinscisOptionsFromTracking(
|
|
|
|
|
tracking, image_width, image_height, &camera_intrinsics_options);
|
2016-01-26 11:42:55 +01:00
|
|
|
libmv_CameraIntrinsics *intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
|
2012-12-10 16:38:28 +00:00
|
|
|
|
2016-01-26 11:42:55 +01:00
|
|
|
double x = co[0], y = co[1];
|
|
|
|
|
libmv_cameraIntrinsicsInvert(intrinsics, x, y, &x, &y);
|
|
|
|
|
libmv_cameraIntrinsicsDestroy(intrinsics);
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2022-11-18 17:15:13 +01:00
|
|
|
float principal_px[2];
|
|
|
|
|
tracking_principal_point_normalized_to_pixel(
|
|
|
|
|
tracking->camera.principal_point, image_width, image_height, principal_px);
|
|
|
|
|
|
2023-03-03 23:27:50 +11:00
|
|
|
r_co[0] = float(x) * camera->focal + principal_px[0];
|
|
|
|
|
r_co[1] = float(y) * camera->focal + principal_px[1] * aspy;
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
ImBuf *BKE_tracking_undistort_frame(MovieTracking *tracking,
|
|
|
|
|
ImBuf *ibuf,
|
|
|
|
|
int calibration_width,
|
|
|
|
|
int calibration_height,
|
|
|
|
|
float overscan)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingCamera *camera = &tracking->camera;
|
2012-03-25 23:19:21 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
if (camera->intrinsics == nullptr) {
|
2014-02-20 19:41:05 +06:00
|
|
|
camera->intrinsics = BKE_tracking_distortion_new(
|
|
|
|
|
tracking, calibration_width, calibration_height);
|
|
|
|
|
}
|
2012-04-07 16:59:06 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
return BKE_tracking_distortion_exec(static_cast<MovieDistortion *>(camera->intrinsics),
|
|
|
|
|
tracking,
|
|
|
|
|
ibuf,
|
|
|
|
|
calibration_width,
|
|
|
|
|
calibration_height,
|
|
|
|
|
overscan,
|
|
|
|
|
true);
|
2012-06-15 11:03:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImBuf *BKE_tracking_distort_frame(MovieTracking *tracking,
|
|
|
|
|
ImBuf *ibuf,
|
|
|
|
|
int calibration_width,
|
|
|
|
|
int calibration_height,
|
|
|
|
|
float overscan)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingCamera *camera = &tracking->camera;
|
|
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
if (camera->intrinsics == nullptr) {
|
2014-02-20 19:41:05 +06:00
|
|
|
camera->intrinsics = BKE_tracking_distortion_new(
|
|
|
|
|
tracking, calibration_width, calibration_height);
|
|
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
return BKE_tracking_distortion_exec(static_cast<MovieDistortion *>(camera->intrinsics),
|
|
|
|
|
tracking,
|
|
|
|
|
ibuf,
|
|
|
|
|
calibration_width,
|
|
|
|
|
calibration_height,
|
|
|
|
|
overscan,
|
|
|
|
|
false);
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-11 19:33:01 +06:00
|
|
|
void BKE_tracking_max_distortion_delta_across_bound(MovieTracking *tracking,
|
2020-04-17 16:51:00 +02:00
|
|
|
int image_width,
|
|
|
|
|
int image_height,
|
2014-09-11 19:33:01 +06:00
|
|
|
rcti *rect,
|
|
|
|
|
bool undistort,
|
|
|
|
|
float delta[2])
|
2013-02-18 10:12:44 +00:00
|
|
|
{
|
|
|
|
|
float pos[2], warped_pos[2];
|
|
|
|
|
const int coord_delta = 5;
|
2020-04-17 16:51:00 +02:00
|
|
|
void (*apply_distortion)(MovieTracking * tracking,
|
|
|
|
|
int image_width,
|
|
|
|
|
int image_height,
|
|
|
|
|
const float pos[2],
|
|
|
|
|
float out[2]);
|
2014-09-11 19:33:01 +06:00
|
|
|
|
|
|
|
|
if (undistort) {
|
|
|
|
|
apply_distortion = BKE_tracking_undistort_v2;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
apply_distortion = BKE_tracking_distort_v2;
|
|
|
|
|
}
|
2013-02-18 10:12:44 +00:00
|
|
|
|
|
|
|
|
delta[0] = delta[1] = -FLT_MAX;
|
|
|
|
|
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int a = rect->xmin; a <= rect->xmax + coord_delta; a += coord_delta) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (a > rect->xmax) {
|
2013-02-18 10:12:44 +00:00
|
|
|
a = rect->xmax;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-02-18 10:12:44 +00:00
|
|
|
|
|
|
|
|
/* bottom edge */
|
|
|
|
|
pos[0] = a;
|
|
|
|
|
pos[1] = rect->ymin;
|
|
|
|
|
|
2020-04-17 16:51:00 +02:00
|
|
|
apply_distortion(tracking, image_width, image_height, pos, warped_pos);
|
2013-02-18 10:12:44 +00:00
|
|
|
|
2013-09-01 14:32:51 +00:00
|
|
|
delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
|
|
|
|
|
delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
|
2013-02-18 10:12:44 +00:00
|
|
|
|
|
|
|
|
/* top edge */
|
|
|
|
|
pos[0] = a;
|
|
|
|
|
pos[1] = rect->ymax;
|
|
|
|
|
|
2020-04-17 16:51:00 +02:00
|
|
|
apply_distortion(tracking, image_width, image_height, pos, warped_pos);
|
2013-02-18 10:12:44 +00:00
|
|
|
|
2013-09-01 14:32:51 +00:00
|
|
|
delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
|
|
|
|
|
delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
|
2013-02-18 10:12:44 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (a >= rect->xmax) {
|
2013-02-18 10:12:44 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-02-18 10:12:44 +00:00
|
|
|
}
|
|
|
|
|
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int a = rect->ymin; a <= rect->ymax + coord_delta; a += coord_delta) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (a > rect->ymax) {
|
2013-02-18 10:12:44 +00:00
|
|
|
a = rect->ymax;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-02-18 10:12:44 +00:00
|
|
|
|
|
|
|
|
/* left edge */
|
|
|
|
|
pos[0] = rect->xmin;
|
|
|
|
|
pos[1] = a;
|
|
|
|
|
|
2020-04-17 16:51:00 +02:00
|
|
|
apply_distortion(tracking, image_width, image_height, pos, warped_pos);
|
2013-02-18 10:12:44 +00:00
|
|
|
|
2013-09-01 14:32:51 +00:00
|
|
|
delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
|
|
|
|
|
delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
|
2013-02-18 10:12:44 +00:00
|
|
|
|
|
|
|
|
/* right edge */
|
|
|
|
|
pos[0] = rect->xmax;
|
|
|
|
|
pos[1] = a;
|
|
|
|
|
|
2020-04-17 16:51:00 +02:00
|
|
|
apply_distortion(tracking, image_width, image_height, pos, warped_pos);
|
2013-02-18 10:12:44 +00:00
|
|
|
|
2013-09-01 14:32:51 +00:00
|
|
|
delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
|
|
|
|
|
delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
|
2013-02-18 10:12:44 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (a >= rect->ymax) {
|
2013-02-18 10:12:44 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-02-18 10:12:44 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Image sampling.
|
|
|
|
|
*/
|
2012-06-15 11:03:23 +00:00
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
static void disable_imbuf_channels(ImBuf *ibuf,
|
|
|
|
|
const MovieTrackingTrack *track,
|
|
|
|
|
const bool grayscale)
|
2012-01-15 13:31:58 +00:00
|
|
|
{
|
2012-06-15 11:03:23 +00:00
|
|
|
BKE_tracking_disable_channels(ibuf,
|
|
|
|
|
track->flag & TRACK_DISABLE_RED,
|
2012-06-16 09:18:00 +00:00
|
|
|
track->flag & TRACK_DISABLE_GREEN,
|
|
|
|
|
track->flag & TRACK_DISABLE_BLUE,
|
|
|
|
|
grayscale);
|
2012-01-15 13:31:58 +00:00
|
|
|
}
|
|
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
ImBuf *BKE_tracking_sample_pattern(const int frame_width,
|
|
|
|
|
const int frame_height,
|
|
|
|
|
const ImBuf *search_ibuf,
|
|
|
|
|
const MovieTrackingTrack *track,
|
|
|
|
|
const MovieTrackingMarker *marker,
|
|
|
|
|
const bool from_anchor,
|
|
|
|
|
const bool use_mask,
|
|
|
|
|
const int num_samples_x,
|
|
|
|
|
const int num_samples_y,
|
2012-06-16 09:18:00 +00:00
|
|
|
float pos[2])
|
2011-11-07 12:55:18 +00:00
|
|
|
{
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
ImBuf *pattern_ibuf;
|
|
|
|
|
double src_pixel_x[5], src_pixel_y[5];
|
|
|
|
|
double warped_position_x, warped_position_y;
|
2023-03-01 12:32:15 +01:00
|
|
|
float *mask = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (num_samples_x <= 0 || num_samples_y <= 0) {
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-10 21:14:36 +06:00
|
|
|
pattern_ibuf = IMB_allocImBuf(
|
2023-05-18 10:19:01 +02:00
|
|
|
num_samples_x, num_samples_y, 32, search_ibuf->float_buffer.data ? IB_rectfloat : IB_rect);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-12-30 17:03:59 +06:00
|
|
|
tracking_get_marker_coords_for_tracking(
|
|
|
|
|
frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-04 18:30:48 +00:00
|
|
|
/* from_anchor means search buffer was obtained for an anchored position,
|
|
|
|
|
* which means applying track offset rounded to pixel space (we could not
|
|
|
|
|
* store search buffer with sub-pixel precision)
|
|
|
|
|
*
|
|
|
|
|
* in this case we need to alter coordinates a bit, to compensate rounded
|
|
|
|
|
* fractional part of offset
|
|
|
|
|
*/
|
|
|
|
|
if (from_anchor) {
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int a = 0; a < 5; a++) {
|
2023-03-03 23:27:50 +11:00
|
|
|
src_pixel_x[a] += double((track->offset[0] * frame_width) -
|
|
|
|
|
int(track->offset[0] * frame_width));
|
|
|
|
|
src_pixel_y[a] += double((track->offset[1] * frame_height) -
|
|
|
|
|
int(track->offset[1] * frame_height));
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2013-03-04 18:30:48 +00:00
|
|
|
/* when offset is negative, rounding happens in opposite direction */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (track->offset[0] < 0.0f) {
|
2014-04-10 21:14:36 +06:00
|
|
|
src_pixel_x[a] += 1.0;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (track->offset[1] < 0.0f) {
|
2013-03-06 02:52:34 +00:00
|
|
|
src_pixel_y[a] += 1.0;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2012-06-12 11:13:53 +00:00
|
|
|
if (use_mask) {
|
2013-03-04 18:30:48 +00:00
|
|
|
mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
if (search_ibuf->float_buffer.data) {
|
|
|
|
|
libmv_samplePlanarPatchFloat(search_ibuf->float_buffer.data,
|
2012-11-07 11:18:42 +00:00
|
|
|
search_ibuf->x,
|
|
|
|
|
search_ibuf->y,
|
2019-04-17 06:17:24 +02:00
|
|
|
4,
|
2014-04-10 21:14:36 +06:00
|
|
|
src_pixel_x,
|
2013-03-06 02:52:34 +00:00
|
|
|
src_pixel_y,
|
2012-06-15 11:03:23 +00:00
|
|
|
num_samples_x,
|
|
|
|
|
num_samples_y,
|
|
|
|
|
mask,
|
2023-05-18 10:19:01 +02:00
|
|
|
pattern_ibuf->float_buffer.data,
|
2014-04-10 21:14:36 +06:00
|
|
|
&warped_position_x,
|
|
|
|
|
&warped_position_y);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2014-04-10 21:14:36 +06:00
|
|
|
else {
|
2023-05-18 10:19:01 +02:00
|
|
|
libmv_samplePlanarPatchByte(search_ibuf->byte_buffer.data,
|
2014-09-25 17:01:06 +06:00
|
|
|
search_ibuf->x,
|
|
|
|
|
search_ibuf->y,
|
|
|
|
|
4,
|
|
|
|
|
src_pixel_x,
|
|
|
|
|
src_pixel_y,
|
|
|
|
|
num_samples_x,
|
|
|
|
|
num_samples_y,
|
|
|
|
|
mask,
|
2023-05-18 10:19:01 +02:00
|
|
|
pattern_ibuf->byte_buffer.data,
|
2014-09-25 17:01:06 +06:00
|
|
|
&warped_position_x,
|
|
|
|
|
&warped_position_y);
|
2014-04-10 21:14:36 +06:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-10 21:14:36 +06:00
|
|
|
if (pos) {
|
|
|
|
|
pos[0] = warped_position_x;
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
pos[1] = warped_position_y;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2012-06-12 11:13:53 +00:00
|
|
|
if (mask) {
|
2012-03-16 14:06:43 +00:00
|
|
|
MEM_freeN(mask);
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2014-04-10 21:14:36 +06:00
|
|
|
return pattern_ibuf;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
ImBuf *BKE_tracking_get_pattern_imbuf(const ImBuf *ibuf,
|
|
|
|
|
const MovieTrackingTrack *track,
|
|
|
|
|
const MovieTrackingMarker *marker,
|
|
|
|
|
const bool anchored,
|
|
|
|
|
const bool disable_channels)
|
2019-04-17 06:17:24 +02:00
|
|
|
{
|
2014-04-10 21:14:36 +06:00
|
|
|
ImBuf *pattern_ibuf, *search_ibuf;
|
|
|
|
|
float pat_min[2], pat_max[2];
|
|
|
|
|
int num_samples_x, num_samples_y;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-10 21:14:36 +06:00
|
|
|
BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-10 21:14:36 +06:00
|
|
|
num_samples_x = (pat_max[0] - pat_min[0]) * ibuf->x;
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
num_samples_y = (pat_max[1] - pat_min[1]) * ibuf->y;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2014-04-10 21:14:36 +06:00
|
|
|
search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-11-07 11:18:42 +00:00
|
|
|
if (search_ibuf) {
|
2014-04-10 21:14:36 +06:00
|
|
|
pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x,
|
2019-04-17 06:17:24 +02:00
|
|
|
ibuf->y,
|
2014-04-10 21:14:36 +06:00
|
|
|
search_ibuf,
|
2019-04-17 06:17:24 +02:00
|
|
|
track,
|
|
|
|
|
marker,
|
2014-04-10 21:14:36 +06:00
|
|
|
anchored,
|
2019-04-17 06:17:24 +02:00
|
|
|
false,
|
2014-04-10 21:14:36 +06:00
|
|
|
num_samples_x,
|
|
|
|
|
num_samples_y,
|
2023-03-01 12:32:15 +01:00
|
|
|
nullptr);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-12 11:13:53 +00:00
|
|
|
IMB_freeImBuf(search_ibuf);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
else {
|
2023-03-01 12:32:15 +01:00
|
|
|
pattern_ibuf = nullptr;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
return pattern_ibuf;
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2022-10-04 16:57:16 +02:00
|
|
|
ImBuf *BKE_tracking_get_search_imbuf(const ImBuf *ibuf,
|
|
|
|
|
const MovieTrackingTrack *track,
|
|
|
|
|
const MovieTrackingMarker *marker,
|
|
|
|
|
const bool anchored,
|
|
|
|
|
const bool disable_channels)
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
{
|
|
|
|
|
ImBuf *searchibuf;
|
|
|
|
|
int x, y, w, h;
|
|
|
|
|
float search_origin[2];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
tracking_get_search_origin_frame_pixel(ibuf->x, ibuf->y, marker, search_origin);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
x = search_origin[0];
|
|
|
|
|
y = search_origin[1];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
if (anchored) {
|
|
|
|
|
x += track->offset[0] * ibuf->x;
|
|
|
|
|
y += track->offset[1] * ibuf->y;
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x;
|
|
|
|
|
h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (w <= 0 || h <= 0) {
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
searchibuf = IMB_allocImBuf(w, h, 32, ibuf->float_buffer.data ? IB_rectfloat : IB_rect);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
if (disable_channels) {
|
|
|
|
|
if ((track->flag & TRACK_PREVIEW_GRAYSCALE) || (track->flag & TRACK_DISABLE_RED) ||
|
|
|
|
|
(track->flag & TRACK_DISABLE_GREEN) || (track->flag & TRACK_DISABLE_BLUE))
|
|
|
|
|
{
|
|
|
|
|
disable_imbuf_channels(searchibuf, track, true);
|
2012-11-07 11:18:42 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
|
|
|
|
|
return searchibuf;
|
|
|
|
|
}
|
|
|
|
|
|
2022-06-28 16:03:35 +02:00
|
|
|
BLI_INLINE int plane_marker_size_len_in_pixels(const float a[2],
|
|
|
|
|
const float b[2],
|
|
|
|
|
const int frame_width,
|
|
|
|
|
const int frame_height)
|
|
|
|
|
{
|
|
|
|
|
const float a_px[2] = {a[0] * frame_width, a[1] * frame_height};
|
|
|
|
|
const float b_px[2] = {b[0] * frame_width, b[1] * frame_height};
|
|
|
|
|
|
|
|
|
|
return ceilf(len_v2v2(a_px, b_px));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ImBuf *BKE_tracking_get_plane_imbuf(const ImBuf *frame_ibuf,
|
|
|
|
|
const MovieTrackingPlaneMarker *plane_marker)
|
|
|
|
|
{
|
|
|
|
|
/* Alias for corners, allowing shorter access to coordinates. */
|
|
|
|
|
const float(*corners)[2] = plane_marker->corners;
|
|
|
|
|
|
|
|
|
|
/* Dimensions of the frame image in pixels. */
|
|
|
|
|
const int frame_width = frame_ibuf->x;
|
|
|
|
|
const int frame_height = frame_ibuf->y;
|
|
|
|
|
|
|
|
|
|
/* Lengths of left and right edges of the plane marker, in pixels. */
|
|
|
|
|
const int left_side_len_px = plane_marker_size_len_in_pixels(
|
|
|
|
|
corners[0], corners[3], frame_width, frame_height);
|
|
|
|
|
const int right_side_len_px = plane_marker_size_len_in_pixels(
|
|
|
|
|
corners[1], corners[2], frame_width, frame_height);
|
|
|
|
|
|
|
|
|
|
/* Lengths of top and bottom edges of the plane marker, in pixels. */
|
|
|
|
|
const int top_side_len_px = plane_marker_size_len_in_pixels(
|
|
|
|
|
corners[3], corners[2], frame_width, frame_height);
|
|
|
|
|
const int bottom_side_len_px = plane_marker_size_len_in_pixels(
|
|
|
|
|
corners[0], corners[1], frame_width, frame_height);
|
|
|
|
|
|
|
|
|
|
/* Choose the number of samples as a maximum of the corresponding sides in pixels. */
|
|
|
|
|
const int num_samples_x = max_ii(top_side_len_px, bottom_side_len_px);
|
|
|
|
|
const int num_samples_y = max_ii(left_side_len_px, right_side_len_px);
|
|
|
|
|
|
|
|
|
|
/* Create new result image with the same type of content as the original. */
|
|
|
|
|
ImBuf *plane_ibuf = IMB_allocImBuf(
|
2023-05-18 10:19:01 +02:00
|
|
|
num_samples_x, num_samples_y, 32, frame_ibuf->float_buffer.data ? IB_rectfloat : IB_rect);
|
2022-06-28 16:03:35 +02:00
|
|
|
|
2022-07-04 15:16:24 +10:00
|
|
|
/* Calculate corner coordinates in pixel space, as separate X/Y arrays. */
|
2022-06-28 16:03:35 +02:00
|
|
|
const double src_pixel_x[4] = {corners[0][0] * frame_width,
|
|
|
|
|
corners[1][0] * frame_width,
|
|
|
|
|
corners[2][0] * frame_width,
|
|
|
|
|
corners[3][0] * frame_width};
|
|
|
|
|
const double src_pixel_y[4] = {corners[0][1] * frame_height,
|
|
|
|
|
corners[1][1] * frame_height,
|
|
|
|
|
corners[2][1] * frame_height,
|
|
|
|
|
corners[3][1] * frame_height};
|
|
|
|
|
|
|
|
|
|
/* Warped Position is unused but is expected to be provided by the API. */
|
|
|
|
|
double warped_position_x, warped_position_y;
|
|
|
|
|
|
|
|
|
|
/* Actual sampling. */
|
2023-05-18 10:19:01 +02:00
|
|
|
if (frame_ibuf->float_buffer.data != nullptr) {
|
|
|
|
|
libmv_samplePlanarPatchFloat(frame_ibuf->float_buffer.data,
|
2022-06-28 16:03:35 +02:00
|
|
|
frame_ibuf->x,
|
|
|
|
|
frame_ibuf->y,
|
|
|
|
|
4,
|
|
|
|
|
src_pixel_x,
|
|
|
|
|
src_pixel_y,
|
|
|
|
|
num_samples_x,
|
|
|
|
|
num_samples_y,
|
2023-03-01 12:32:15 +01:00
|
|
|
nullptr,
|
2023-05-18 10:19:01 +02:00
|
|
|
plane_ibuf->float_buffer.data,
|
2022-06-28 16:03:35 +02:00
|
|
|
&warped_position_x,
|
|
|
|
|
&warped_position_y);
|
|
|
|
|
}
|
|
|
|
|
else {
|
2023-05-18 10:19:01 +02:00
|
|
|
libmv_samplePlanarPatchByte(frame_ibuf->byte_buffer.data,
|
2022-06-28 16:03:35 +02:00
|
|
|
frame_ibuf->x,
|
|
|
|
|
frame_ibuf->y,
|
|
|
|
|
4,
|
|
|
|
|
src_pixel_x,
|
|
|
|
|
src_pixel_y,
|
|
|
|
|
num_samples_x,
|
|
|
|
|
num_samples_y,
|
2023-03-01 12:32:15 +01:00
|
|
|
nullptr,
|
2023-05-18 10:19:01 +02:00
|
|
|
plane_ibuf->byte_buffer.data,
|
2022-06-28 16:03:35 +02:00
|
|
|
&warped_position_x,
|
|
|
|
|
&warped_position_y);
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-23 15:55:42 +02:00
|
|
|
plane_ibuf->byte_buffer.colorspace = frame_ibuf->byte_buffer.colorspace;
|
|
|
|
|
plane_ibuf->float_buffer.colorspace = frame_ibuf->float_buffer.colorspace;
|
2022-06-28 16:03:35 +02:00
|
|
|
|
|
|
|
|
return plane_ibuf;
|
|
|
|
|
}
|
|
|
|
|
|
2013-09-05 13:37:36 +00:00
|
|
|
void BKE_tracking_disable_channels(
|
|
|
|
|
ImBuf *ibuf, bool disable_red, bool disable_green, bool disable_blue, bool grayscale)
|
Planar tracking support for motion tracking
===========================================
Major list of changes done in tomato branch:
- Add a planar tracking implementation to libmv
This adds a new planar tracking implementation to libmv. The
tracker is based on Ceres[1], the new nonlinear minimizer that
myself and Sameer released from Google as open source. Since
the motion model is more involved, the interface is
different than the RegionTracker interface used previously
in Blender.
The start of a C API in libmv-capi.{cpp,h} is also included.
- Migrate from pat_{min,max} for markers to 4 corners representation
Convert markers in the movie clip editor / 2D tracker from using
pat_min and pat_max notation to using the a more general, 4-corner
representation.
There is still considerable porting work to do; in particular
sliding from preview widget does not work correct for rotated
markers.
All other areas should be ported to new representation:
* Added support of sliding individual corners. LMB slide + Ctrl
would scale the whole pattern
* S would scale the whole marker, S-S would scale pattern only
* Added support of marker's rotation which is currently rotates
only patterns around their centers or all markers around median,
Rotation or other non-translation/scaling transformation of search
area doesn't make sense.
* Track Preview widget would display transformed pattern which
libmv actually operates with.
- "Efficient Second-order Minimization" for the planar tracker
This implements the "Efficient Second-order Minimization"
scheme, as supported by the existing translation tracker.
This increases the amount of per-iteration work, but
decreases the number of iterations required to converge and
also increases the size of the basin of attraction for the
optimization.
- Remove the use of the legacy RegionTracker API from Blender,
and replaces it with the new TrackRegion API. This also
adds several features to the planar tracker in libmv:
* Do a brute-force initialization of tracking similar to "Hybrid"
mode in the stable release, but using all floats. This is slower
but more accurate. It is still necessary to evaluate if the
performance loss is worth it. In particular, this change is
necessary to support high bit depth imagery.
* Add support for masks over the search window. This is a step
towards supporting user-defined tracker masks. The tracker masks
will make it easy for users to make a mask for e.g. a ball.
Not exposed into interface yet/
* Add Pearson product moment correlation coefficient checking (aka
"Correlation" in the UI. This causes tracking failure if the
tracked patch is not linearly related to the template.
* Add support for warping a few points in addition to the supplied
points. This is useful because the tracking code deliberately
does not expose the underlying warp representation. Instead,
warps are specified in an aparametric way via the correspondences.
- Replace the old style tracker configuration panel with the
new planar tracking panel. From a users perspective, this means:
* The old "tracking algorithm" picker is gone. There is only 1
algorithm now. We may revisit this later, but I would much
prefer to have only 1 algorithm. So far no optimization work
has been done so the speed is not there yet.
* There is now a dropdown to select the motion model. Choices:
* Translation
* Translation, rotation
* Translation, scale
* Translation, rotation, scale
* Affine
* Perspective
* The old "Hybrid" mode is gone; instead there is a toggle to
enable or disable translation-only tracker initialization. This
is the equivalent of the hyrbid mode before, but rewritten to work
with the new planar tracking modes.
* The pyramid levels setting is gone. At a future date, the planar
tracker will decide to use pyramids or not automatically. The
pyramid setting was ultimately a mistake; with the brute force
initialization it is unnecessary.
- Add light-normalized tracking
Added the ability to normalize patterns by their average value while
tracking, to make them invariant to global illumination changes.
Additional details could be found at wiki page [2]
[1] http://code.google.com/p/ceres-solver
[2] http://wiki.blender.org/index.php/Dev:Ref/Release_Notes/2.64/Motion_Tracker
2012-06-10 15:28:19 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!disable_red && !disable_green && !disable_blue && !grayscale) {
|
2012-06-15 11:03:23 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
/* if only some components are selected, it's important to rescale the result
|
|
|
|
|
* appropriately so that e.g. if only blue is selected, it's not zeroed out.
|
|
|
|
|
*/
|
2020-02-07 12:00:57 +01:00
|
|
|
float scale = (disable_red ? 0.0f : 0.2126f) + (disable_green ? 0.0f : 0.7152f) +
|
|
|
|
|
(disable_blue ? 0.0f : 0.0722f);
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2020-02-07 12:00:57 +01:00
|
|
|
for (int y = 0; y < ibuf->y; y++) {
|
|
|
|
|
for (int x = 0; x < ibuf->x; x++) {
|
2012-06-15 11:03:23 +00:00
|
|
|
int pixel = ibuf->x * y + x;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
if (ibuf->float_buffer.data) {
|
|
|
|
|
float *rrgbf = ibuf->float_buffer.data + pixel * 4;
|
2012-06-15 11:03:23 +00:00
|
|
|
float r = disable_red ? 0.0f : rrgbf[0];
|
|
|
|
|
float g = disable_green ? 0.0f : rrgbf[1];
|
|
|
|
|
float b = disable_blue ? 0.0f : rrgbf[2];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
if (grayscale) {
|
|
|
|
|
float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
rrgbf[0] = r;
|
|
|
|
|
rrgbf[1] = g;
|
|
|
|
|
rrgbf[2] = b;
|
|
|
|
|
}
|
2012-06-12 11:13:53 +00:00
|
|
|
}
|
2012-06-15 11:03:23 +00:00
|
|
|
else {
|
2023-05-18 10:19:01 +02:00
|
|
|
uchar *rrgb = ibuf->byte_buffer.data + pixel * 4;
|
|
|
|
|
uchar r = disable_red ? 0 : rrgb[0];
|
|
|
|
|
uchar g = disable_green ? 0 : rrgb[1];
|
|
|
|
|
uchar b = disable_blue ? 0 : rrgb[2];
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
if (grayscale) {
|
|
|
|
|
float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-06-15 11:03:23 +00:00
|
|
|
rrgb[0] = rrgb[1] = rrgb[2] = gray;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
rrgb[0] = r;
|
|
|
|
|
rrgb[1] = g;
|
|
|
|
|
rrgb[2] = b;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2011-12-04 12:58:31 +00:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-05-18 10:19:01 +02:00
|
|
|
if (ibuf->float_buffer.data) {
|
2012-06-15 11:03:23 +00:00
|
|
|
ibuf->userflags |= IB_RECT_INVALID;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2011-11-07 12:55:18 +00:00
|
|
|
}
|
|
|
|
|
|
2022-05-12 09:54:16 +02:00
|
|
|
/* --------------------------------------------------------------------
|
|
|
|
|
* Dopesheet functions.
|
|
|
|
|
*/
|
2012-04-30 16:19:20 +00:00
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* ** Channels sort comparators ** */
|
|
|
|
|
|
2014-09-23 01:28:46 +10:00
|
|
|
static int channels_alpha_sort(const void *a, const void *b)
|
2012-04-30 16:19:20 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const MovieTrackingDopesheetChannel *channel_a =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(a);
|
|
|
|
|
const MovieTrackingDopesheetChannel *channel_b =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(b);
|
2012-04-30 16:19:20 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (BLI_strcasecmp(channel_a->track->name, channel_b->track->name) > 0) {
|
2012-04-30 16:19:20 +00:00
|
|
|
return 1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return 0;
|
2012-04-30 16:19:20 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-23 01:28:46 +10:00
|
|
|
static int channels_total_track_sort(const void *a, const void *b)
|
2012-05-03 19:28:41 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const MovieTrackingDopesheetChannel *channel_a =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(a);
|
|
|
|
|
const MovieTrackingDopesheetChannel *channel_b =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(b);
|
2012-05-03 19:28:41 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (channel_a->total_frames > channel_b->total_frames) {
|
2012-05-03 19:28:41 +00:00
|
|
|
return 1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return 0;
|
2012-05-03 19:28:41 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-23 01:28:46 +10:00
|
|
|
static int channels_longest_segment_sort(const void *a, const void *b)
|
2012-05-03 19:28:41 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const MovieTrackingDopesheetChannel *channel_a =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(a);
|
|
|
|
|
const MovieTrackingDopesheetChannel *channel_b =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(b);
|
2012-05-03 19:28:41 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (channel_a->max_segment > channel_b->max_segment) {
|
2012-05-03 19:28:41 +00:00
|
|
|
return 1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return 0;
|
2012-05-03 19:28:41 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-23 01:28:46 +10:00
|
|
|
static int channels_average_error_sort(const void *a, const void *b)
|
2012-06-08 16:42:24 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const MovieTrackingDopesheetChannel *channel_a =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(a);
|
|
|
|
|
const MovieTrackingDopesheetChannel *channel_b =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(b);
|
2012-06-08 16:42:24 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (channel_a->track->error > channel_b->track->error) {
|
2012-06-08 16:42:24 +00:00
|
|
|
return 1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
2022-06-14 17:32:15 +02:00
|
|
|
if (channel_a->track->error == channel_b->track->error) {
|
|
|
|
|
return channels_alpha_sort(a, b);
|
|
|
|
|
}
|
|
|
|
|
|
2020-08-07 12:30:43 +02:00
|
|
|
return 0;
|
2012-06-08 16:42:24 +00:00
|
|
|
}
|
|
|
|
|
|
2021-10-01 12:35:00 +02:00
|
|
|
static int compare_firstlast_putting_undefined_first(
|
|
|
|
|
bool inverse, bool a_markerless, int a_value, bool b_markerless, int b_value)
|
|
|
|
|
{
|
|
|
|
|
if (a_markerless && b_markerless) {
|
|
|
|
|
/* Neither channel has not-disabled markers, return whatever. */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (a_markerless) {
|
|
|
|
|
/* Put the markerless channel first. */
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
if (b_markerless) {
|
|
|
|
|
/* Put the markerless channel first. */
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Both channels have markers. */
|
|
|
|
|
|
|
|
|
|
if (inverse) {
|
|
|
|
|
if (a_value < b_value) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (a_value > b_value) {
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int channels_start_sort(const void *a, const void *b)
|
|
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const MovieTrackingDopesheetChannel *channel_a =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(a);
|
|
|
|
|
const MovieTrackingDopesheetChannel *channel_b =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(b);
|
2021-10-01 12:35:00 +02:00
|
|
|
|
|
|
|
|
return compare_firstlast_putting_undefined_first(false,
|
|
|
|
|
channel_a->tot_segment == 0,
|
|
|
|
|
channel_a->first_not_disabled_marker_framenr,
|
|
|
|
|
channel_b->tot_segment == 0,
|
|
|
|
|
channel_b->first_not_disabled_marker_framenr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int channels_end_sort(const void *a, const void *b)
|
|
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const MovieTrackingDopesheetChannel *channel_a =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(a);
|
|
|
|
|
const MovieTrackingDopesheetChannel *channel_b =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(b);
|
2021-10-01 12:35:00 +02:00
|
|
|
|
|
|
|
|
return compare_firstlast_putting_undefined_first(false,
|
|
|
|
|
channel_a->tot_segment == 0,
|
|
|
|
|
channel_a->last_not_disabled_marker_framenr,
|
|
|
|
|
channel_b->tot_segment == 0,
|
|
|
|
|
channel_b->last_not_disabled_marker_framenr);
|
|
|
|
|
}
|
|
|
|
|
|
2014-09-23 01:28:46 +10:00
|
|
|
static int channels_alpha_inverse_sort(const void *a, const void *b)
|
2012-05-03 19:28:41 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (channels_alpha_sort(a, b)) {
|
2012-05-03 19:28:41 +00:00
|
|
|
return 0;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return 1;
|
2012-05-03 19:28:41 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-23 01:28:46 +10:00
|
|
|
static int channels_total_track_inverse_sort(const void *a, const void *b)
|
2012-05-03 19:28:41 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (channels_total_track_sort(a, b)) {
|
2012-05-03 19:28:41 +00:00
|
|
|
return 0;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return 1;
|
2012-05-03 19:28:41 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-23 01:28:46 +10:00
|
|
|
static int channels_longest_segment_inverse_sort(const void *a, const void *b)
|
2012-05-03 19:28:41 +00:00
|
|
|
{
|
2019-04-22 09:39:35 +10:00
|
|
|
if (channels_longest_segment_sort(a, b)) {
|
2012-05-03 19:28:41 +00:00
|
|
|
return 0;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return 1;
|
2012-05-03 19:28:41 +00:00
|
|
|
}
|
|
|
|
|
|
2014-09-23 01:28:46 +10:00
|
|
|
static int channels_average_error_inverse_sort(const void *a, const void *b)
|
2012-06-08 16:42:24 +00:00
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const MovieTrackingDopesheetChannel *channel_a =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(a);
|
|
|
|
|
const MovieTrackingDopesheetChannel *channel_b =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(b);
|
2012-06-08 16:42:24 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (channel_a->track->error < channel_b->track->error) {
|
2012-06-08 16:42:24 +00:00
|
|
|
return 1;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
|
|
|
|
|
return 0;
|
2012-06-08 16:42:24 +00:00
|
|
|
}
|
|
|
|
|
|
2021-10-01 12:35:00 +02:00
|
|
|
static int channels_start_inverse_sort(const void *a, const void *b)
|
|
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const MovieTrackingDopesheetChannel *channel_a =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(a);
|
|
|
|
|
const MovieTrackingDopesheetChannel *channel_b =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(b);
|
2021-10-01 12:35:00 +02:00
|
|
|
|
|
|
|
|
return compare_firstlast_putting_undefined_first(true,
|
|
|
|
|
channel_a->tot_segment == 0,
|
|
|
|
|
channel_a->first_not_disabled_marker_framenr,
|
|
|
|
|
channel_b->tot_segment == 0,
|
|
|
|
|
channel_b->first_not_disabled_marker_framenr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int channels_end_inverse_sort(const void *a, const void *b)
|
|
|
|
|
{
|
2023-03-01 12:32:15 +01:00
|
|
|
const MovieTrackingDopesheetChannel *channel_a =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(a);
|
|
|
|
|
const MovieTrackingDopesheetChannel *channel_b =
|
|
|
|
|
static_cast<const MovieTrackingDopesheetChannel *>(b);
|
2021-10-01 12:35:00 +02:00
|
|
|
|
|
|
|
|
return compare_firstlast_putting_undefined_first(true,
|
|
|
|
|
channel_a->tot_segment == 0,
|
|
|
|
|
channel_a->last_not_disabled_marker_framenr,
|
|
|
|
|
channel_b->tot_segment == 0,
|
|
|
|
|
channel_b->last_not_disabled_marker_framenr);
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Calculate frames segments at which track is tracked continuously. */
|
|
|
|
|
static void tracking_dopesheet_channels_segments_calc(MovieTrackingDopesheetChannel *channel)
|
2012-05-03 17:52:34 +00:00
|
|
|
{
|
|
|
|
|
MovieTrackingTrack *track = channel->track;
|
|
|
|
|
int i, segment;
|
2021-10-01 12:35:00 +02:00
|
|
|
bool first_not_disabled_marker_framenr_set;
|
2012-05-03 17:52:34 +00:00
|
|
|
|
|
|
|
|
channel->tot_segment = 0;
|
|
|
|
|
channel->max_segment = 0;
|
|
|
|
|
channel->total_frames = 0;
|
|
|
|
|
|
2021-10-01 12:35:00 +02:00
|
|
|
channel->first_not_disabled_marker_framenr = 0;
|
|
|
|
|
channel->last_not_disabled_marker_framenr = 0;
|
|
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* TODO(sergey): looks a bit code-duplicated, need to look into
|
|
|
|
|
* logic de-duplication here.
|
|
|
|
|
*/
|
|
|
|
|
|
2012-05-03 17:52:34 +00:00
|
|
|
/* count */
|
|
|
|
|
i = 0;
|
2021-10-01 12:35:00 +02:00
|
|
|
first_not_disabled_marker_framenr_set = false;
|
2012-05-03 17:52:34 +00:00
|
|
|
while (i < track->markersnr) {
|
|
|
|
|
MovieTrackingMarker *marker = &track->markers[i];
|
|
|
|
|
|
|
|
|
|
if ((marker->flag & MARKER_DISABLED) == 0) {
|
|
|
|
|
int prev_fra = marker->framenr, len = 0;
|
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
while (i < track->markersnr) {
|
|
|
|
|
marker = &track->markers[i];
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (marker->framenr != prev_fra + 1) {
|
2012-05-03 17:52:34 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (marker->flag & MARKER_DISABLED) {
|
2012-05-03 17:52:34 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-05-03 17:52:34 +00:00
|
|
|
|
2021-10-01 12:35:00 +02:00
|
|
|
if (!first_not_disabled_marker_framenr_set) {
|
|
|
|
|
channel->first_not_disabled_marker_framenr = marker->framenr;
|
|
|
|
|
first_not_disabled_marker_framenr_set = true;
|
|
|
|
|
}
|
|
|
|
|
channel->last_not_disabled_marker_framenr = marker->framenr;
|
|
|
|
|
|
2012-05-03 17:52:34 +00:00
|
|
|
prev_fra = marker->framenr;
|
|
|
|
|
len++;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
channel->tot_segment++;
|
2023-03-28 12:14:16 +11:00
|
|
|
(void)len; /* Quiet set-but-unused warning (may be removed). */
|
2012-05-03 17:52:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!channel->tot_segment) {
|
2012-05-03 17:52:34 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-05-03 17:52:34 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
channel->segments = MEM_cnew_array<int>(2 * channel->tot_segment, "tracking channel segments");
|
2012-05-03 17:52:34 +00:00
|
|
|
|
|
|
|
|
/* create segments */
|
|
|
|
|
i = 0;
|
|
|
|
|
segment = 0;
|
|
|
|
|
while (i < track->markersnr) {
|
|
|
|
|
MovieTrackingMarker *marker = &track->markers[i];
|
|
|
|
|
|
|
|
|
|
if ((marker->flag & MARKER_DISABLED) == 0) {
|
|
|
|
|
MovieTrackingMarker *start_marker = marker;
|
|
|
|
|
int prev_fra = marker->framenr, len = 0;
|
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
while (i < track->markersnr) {
|
|
|
|
|
marker = &track->markers[i];
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (marker->framenr != prev_fra + 1) {
|
2012-05-03 17:52:34 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
|
|
|
|
if (marker->flag & MARKER_DISABLED) {
|
2012-05-03 17:52:34 +00:00
|
|
|
break;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-05-03 17:52:34 +00:00
|
|
|
|
|
|
|
|
prev_fra = marker->framenr;
|
|
|
|
|
channel->total_frames++;
|
|
|
|
|
len++;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
channel->segments[2 * segment] = start_marker->framenr;
|
|
|
|
|
channel->segments[2 * segment + 1] = start_marker->framenr + len;
|
|
|
|
|
|
2012-10-23 16:21:55 +00:00
|
|
|
channel->max_segment = max_ii(channel->max_segment, len);
|
2012-05-03 17:52:34 +00:00
|
|
|
segment++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Create channels for tracks and calculate tracked segments for them. */
|
|
|
|
|
static void tracking_dopesheet_channels_calc(MovieTracking *tracking)
|
|
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
|
2013-05-12 16:04:08 +00:00
|
|
|
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingReconstruction *reconstruction = &tracking_object->reconstruction;
|
2013-05-12 16:04:08 +00:00
|
|
|
|
2014-03-31 15:24:23 +06:00
|
|
|
bool sel_only = (dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY) != 0;
|
|
|
|
|
bool show_hidden = (dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN) != 0;
|
2013-05-12 16:04:08 +00:00
|
|
|
|
2022-10-05 18:01:29 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0) {
|
2013-05-12 16:04:08 +00:00
|
|
|
continue;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-05-12 16:04:08 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (sel_only && !TRACK_SELECTED(track)) {
|
2013-05-12 16:04:08 +00:00
|
|
|
continue;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-05-12 16:04:08 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
MovieTrackingDopesheetChannel *channel = MEM_cnew<MovieTrackingDopesheetChannel>(
|
|
|
|
|
"tracking dopesheet channel");
|
2013-05-12 16:04:08 +00:00
|
|
|
channel->track = track;
|
|
|
|
|
|
|
|
|
|
if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
|
2023-05-09 12:50:37 +10:00
|
|
|
SNPRINTF(channel->name, "%s (%.4f)", track->name, track->error);
|
2013-05-12 16:04:08 +00:00
|
|
|
}
|
|
|
|
|
else {
|
2023-05-09 12:50:37 +10:00
|
|
|
STRNCPY(channel->name, track->name);
|
2013-05-12 16:04:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tracking_dopesheet_channels_segments_calc(channel);
|
|
|
|
|
|
|
|
|
|
BLI_addtail(&dopesheet->channels, channel);
|
|
|
|
|
dopesheet->tot_channel++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Sot dopesheet channels using given method (name, average error, total coverage,
|
|
|
|
|
* longest tracked segment) and could also inverse the list if it's enabled.
|
|
|
|
|
*/
|
2013-09-05 13:37:36 +00:00
|
|
|
static void tracking_dopesheet_channels_sort(MovieTracking *tracking,
|
|
|
|
|
int sort_method,
|
|
|
|
|
bool inverse)
|
2012-05-03 23:15:01 +00:00
|
|
|
{
|
|
|
|
|
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2012-05-03 23:15:01 +00:00
|
|
|
if (inverse) {
|
2012-06-12 17:10:24 +00:00
|
|
|
if (sort_method == TRACKING_DOPE_SORT_NAME) {
|
2014-11-16 13:57:58 +01:00
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_alpha_inverse_sort);
|
2012-05-03 23:15:01 +00:00
|
|
|
}
|
2012-06-12 17:10:24 +00:00
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
|
2014-11-16 13:57:58 +01:00
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_inverse_sort);
|
2012-05-03 23:15:01 +00:00
|
|
|
}
|
2012-06-12 17:10:24 +00:00
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
|
2014-11-16 13:57:58 +01:00
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_total_track_inverse_sort);
|
2012-05-03 23:15:01 +00:00
|
|
|
}
|
2012-06-12 17:10:24 +00:00
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
|
2014-11-16 13:57:58 +01:00
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_average_error_inverse_sort);
|
2012-05-03 23:15:01 +00:00
|
|
|
}
|
2021-10-01 12:35:00 +02:00
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_START) {
|
|
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_start_inverse_sort);
|
|
|
|
|
}
|
|
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_END) {
|
|
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_end_inverse_sort);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
2012-05-03 23:15:01 +00:00
|
|
|
else {
|
2012-06-12 17:10:24 +00:00
|
|
|
if (sort_method == TRACKING_DOPE_SORT_NAME) {
|
2014-11-16 13:57:58 +01:00
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_alpha_sort);
|
2012-05-03 23:15:01 +00:00
|
|
|
}
|
2012-06-12 17:10:24 +00:00
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
|
2014-11-16 13:57:58 +01:00
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_sort);
|
2012-05-03 23:15:01 +00:00
|
|
|
}
|
2012-06-12 17:10:24 +00:00
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
|
2014-11-16 13:57:58 +01:00
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_total_track_sort);
|
2012-05-03 23:15:01 +00:00
|
|
|
}
|
2012-06-12 17:10:24 +00:00
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
|
2014-11-16 13:57:58 +01:00
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_average_error_sort);
|
2012-06-08 16:42:24 +00:00
|
|
|
}
|
2021-10-01 12:35:00 +02:00
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_START) {
|
|
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_start_sort);
|
|
|
|
|
}
|
|
|
|
|
else if (sort_method == TRACKING_DOPE_SORT_END) {
|
|
|
|
|
BLI_listbase_sort(&dopesheet->channels, channels_end_sort);
|
|
|
|
|
}
|
2012-05-03 23:15:01 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-22 10:13:15 +00:00
|
|
|
static int coverage_from_count(int count)
|
|
|
|
|
{
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Values are actually arbitrary here, probably need to be tweaked. */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (count < 8) {
|
2013-02-22 10:13:15 +00:00
|
|
|
return TRACKING_COVERAGE_BAD;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2020-08-07 12:30:43 +02:00
|
|
|
if (count < 16) {
|
2013-02-22 10:13:15 +00:00
|
|
|
return TRACKING_COVERAGE_ACCEPTABLE;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-02-22 10:13:15 +00:00
|
|
|
return TRACKING_COVERAGE_OK;
|
|
|
|
|
}
|
|
|
|
|
|
2013-05-12 16:04:08 +00:00
|
|
|
/* Calculate coverage of frames with tracks, this information
|
|
|
|
|
* is used to highlight dopesheet background depending on how
|
|
|
|
|
* many tracks exists on the frame.
|
|
|
|
|
*/
|
2013-02-22 10:13:15 +00:00
|
|
|
static void tracking_dopesheet_calc_coverage(MovieTracking *tracking)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking);
|
2013-02-22 10:13:15 +00:00
|
|
|
int frames, start_frame = INT_MAX, end_frame = -INT_MAX;
|
|
|
|
|
int *per_frame_counter;
|
|
|
|
|
int prev_coverage, last_segment_frame;
|
|
|
|
|
|
|
|
|
|
/* find frame boundaries */
|
2022-10-05 18:01:29 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
2013-02-22 10:13:15 +00:00
|
|
|
start_frame = min_ii(start_frame, track->markers[0].framenr);
|
|
|
|
|
end_frame = max_ii(end_frame, track->markers[track->markersnr - 1].framenr);
|
|
|
|
|
}
|
|
|
|
|
|
2021-03-29 14:42:52 +02:00
|
|
|
if (start_frame > end_frame) {
|
|
|
|
|
/* There are no markers at all, nothing to calculate coverage from. */
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2013-02-22 10:13:15 +00:00
|
|
|
frames = end_frame - start_frame + 1;
|
|
|
|
|
|
|
|
|
|
/* this is a per-frame counter of markers (how many markers belongs to the same frame) */
|
2023-03-01 12:32:15 +01:00
|
|
|
per_frame_counter = MEM_cnew_array<int>(frames, "per frame track counter");
|
2013-02-22 10:13:15 +00:00
|
|
|
|
|
|
|
|
/* find per-frame markers count */
|
2022-10-05 18:01:29 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingTrack *, track, &tracking_object->tracks) {
|
2015-11-23 11:27:02 +11:00
|
|
|
for (int i = 0; i < track->markersnr; i++) {
|
2013-02-22 10:13:15 +00:00
|
|
|
MovieTrackingMarker *marker = &track->markers[i];
|
|
|
|
|
|
|
|
|
|
/* TODO: perhaps we need to add check for non-single-frame track here */
|
2019-04-22 09:39:35 +10:00
|
|
|
if ((marker->flag & MARKER_DISABLED) == 0) {
|
2013-02-22 10:13:15 +00:00
|
|
|
per_frame_counter[marker->framenr - start_frame]++;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-02-22 10:13:15 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* convert markers count to coverage and detect segments with the same coverage */
|
|
|
|
|
prev_coverage = coverage_from_count(per_frame_counter[0]);
|
|
|
|
|
last_segment_frame = start_frame;
|
|
|
|
|
|
|
|
|
|
/* means only disabled tracks in the beginning, could be ignored */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (!per_frame_counter[0]) {
|
2013-02-22 10:13:15 +00:00
|
|
|
prev_coverage = TRACKING_COVERAGE_OK;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-02-22 10:13:15 +00:00
|
|
|
|
2015-11-23 11:27:02 +11:00
|
|
|
for (int i = 1; i < frames; i++) {
|
2013-02-22 10:13:15 +00:00
|
|
|
int coverage = coverage_from_count(per_frame_counter[i]);
|
|
|
|
|
|
|
|
|
|
/* means only disabled tracks in the end, could be ignored */
|
2019-04-22 09:39:35 +10:00
|
|
|
if (i == frames - 1 && !per_frame_counter[i]) {
|
2013-02-22 10:13:15 +00:00
|
|
|
coverage = TRACKING_COVERAGE_OK;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-02-22 10:13:15 +00:00
|
|
|
|
|
|
|
|
if (coverage != prev_coverage || i == frames - 1) {
|
|
|
|
|
MovieTrackingDopesheetCoverageSegment *coverage_segment;
|
|
|
|
|
int end_segment_frame = i - 1 + start_frame;
|
|
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (end_segment_frame == last_segment_frame) {
|
2013-02-22 10:13:15 +00:00
|
|
|
end_segment_frame++;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2013-02-22 10:13:15 +00:00
|
|
|
|
2023-03-01 12:32:15 +01:00
|
|
|
coverage_segment = MEM_cnew<MovieTrackingDopesheetCoverageSegment>(
|
|
|
|
|
"tracking coverage segment");
|
2013-02-22 10:13:15 +00:00
|
|
|
coverage_segment->coverage = prev_coverage;
|
|
|
|
|
coverage_segment->start_frame = last_segment_frame;
|
|
|
|
|
coverage_segment->end_frame = end_segment_frame;
|
|
|
|
|
|
|
|
|
|
BLI_addtail(&dopesheet->coverage_segments, coverage_segment);
|
|
|
|
|
|
|
|
|
|
last_segment_frame = end_segment_frame;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
prev_coverage = coverage;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MEM_freeN(per_frame_counter);
|
|
|
|
|
}
|
|
|
|
|
|
2012-05-03 23:15:01 +00:00
|
|
|
void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
|
|
|
|
|
{
|
|
|
|
|
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
|
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
dopesheet->ok = false;
|
2012-05-03 23:15:01 +00:00
|
|
|
}
|
|
|
|
|
|
2012-06-12 17:10:24 +00:00
|
|
|
void BKE_tracking_dopesheet_update(MovieTracking *tracking)
|
2012-04-30 16:19:20 +00:00
|
|
|
{
|
|
|
|
|
MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
|
2012-06-12 17:11:00 +00:00
|
|
|
|
2012-06-12 17:10:24 +00:00
|
|
|
short sort_method = dopesheet->sort_method;
|
2013-09-05 13:37:36 +00:00
|
|
|
bool inverse = (dopesheet->flag & TRACKING_DOPE_SORT_INVERSE) != 0;
|
2012-04-30 16:19:20 +00:00
|
|
|
|
2019-04-22 09:39:35 +10:00
|
|
|
if (dopesheet->ok) {
|
2012-05-03 23:15:01 +00:00
|
|
|
return;
|
2019-04-22 09:39:35 +10:00
|
|
|
}
|
2012-05-03 23:15:01 +00:00
|
|
|
|
2012-05-03 17:52:34 +00:00
|
|
|
tracking_dopesheet_free(dopesheet);
|
2012-04-30 16:19:20 +00:00
|
|
|
|
2013-02-22 10:13:15 +00:00
|
|
|
/* channels */
|
2013-05-12 16:04:08 +00:00
|
|
|
tracking_dopesheet_channels_calc(tracking);
|
|
|
|
|
tracking_dopesheet_channels_sort(tracking, sort_method, inverse);
|
2012-05-03 19:28:41 +00:00
|
|
|
|
2013-02-22 10:13:15 +00:00
|
|
|
/* frame coverage */
|
|
|
|
|
tracking_dopesheet_calc_coverage(tracking);
|
|
|
|
|
|
2014-04-01 11:34:00 +11:00
|
|
|
dopesheet->ok = true;
|
2012-04-30 16:19:20 +00:00
|
|
|
}
|
2017-12-19 12:10:42 +01:00
|
|
|
|
2017-12-19 12:18:52 +01:00
|
|
|
MovieTrackingObject *BKE_tracking_find_object_for_track(const MovieTracking *tracking,
|
|
|
|
|
const MovieTrackingTrack *track)
|
2017-12-19 12:10:42 +01:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingObject *, tracking_object, &tracking->objects) {
|
|
|
|
|
if (BLI_findindex(&tracking_object->tracks, track) != -1) {
|
|
|
|
|
return tracking_object;
|
2017-12-19 12:10:42 +01:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2017-12-19 12:10:42 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2017-12-19 12:18:52 +01:00
|
|
|
MovieTrackingObject *BKE_tracking_find_object_for_plane_track(
|
|
|
|
|
const MovieTracking *tracking, const MovieTrackingPlaneTrack *plane_track)
|
|
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
LISTBASE_FOREACH (MovieTrackingObject *, tracking_object, &tracking->objects) {
|
|
|
|
|
if (BLI_findindex(&tracking_object->plane_tracks, plane_track) != -1) {
|
|
|
|
|
return tracking_object;
|
2017-12-19 12:18:52 +01:00
|
|
|
}
|
|
|
|
|
}
|
2023-03-01 12:32:15 +01:00
|
|
|
return nullptr;
|
2017-12-19 12:18:52 +01:00
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void BKE_tracking_get_rna_path_for_track(const MovieTracking *tracking,
|
|
|
|
|
const MovieTrackingTrack *track,
|
2017-12-19 12:45:23 +01:00
|
|
|
char *rna_path,
|
2023-05-09 15:02:12 +10:00
|
|
|
size_t rna_path_maxncpy)
|
2017-12-19 12:45:23 +01:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object = BKE_tracking_find_object_for_track(tracking, track);
|
2017-12-19 12:45:23 +01:00
|
|
|
char track_name_esc[MAX_NAME * 2];
|
2020-12-10 13:25:49 +11:00
|
|
|
BLI_str_escape(track_name_esc, track->name, sizeof(track_name_esc));
|
2023-03-01 12:32:15 +01:00
|
|
|
if (tracking_object == nullptr) {
|
2023-05-09 15:02:12 +10:00
|
|
|
BLI_snprintf(rna_path, rna_path_maxncpy, "tracking.tracks[\"%s\"]", track_name_esc);
|
2017-12-19 12:45:23 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
char object_name_esc[MAX_NAME * 2];
|
2022-10-05 18:01:29 +02:00
|
|
|
BLI_str_escape(object_name_esc, tracking_object->name, sizeof(object_name_esc));
|
2017-12-19 12:45:23 +01:00
|
|
|
BLI_snprintf(rna_path,
|
2023-05-09 15:02:12 +10:00
|
|
|
rna_path_maxncpy,
|
2017-12-19 12:45:23 +01:00
|
|
|
"tracking.objects[\"%s\"].tracks[\"%s\"]",
|
|
|
|
|
object_name_esc,
|
|
|
|
|
track_name_esc);
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
}
|
|
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void BKE_tracking_get_rna_path_prefix_for_track(const MovieTracking *tracking,
|
|
|
|
|
const MovieTrackingTrack *track,
|
2017-12-19 13:09:39 +01:00
|
|
|
char *rna_path,
|
2023-05-09 15:02:12 +10:00
|
|
|
size_t rna_path_maxncpy)
|
2017-12-19 13:09:39 +01:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object = BKE_tracking_find_object_for_track(tracking, track);
|
2023-03-01 12:32:15 +01:00
|
|
|
if (tracking_object == nullptr) {
|
2023-05-09 15:02:12 +10:00
|
|
|
BLI_strncpy(rna_path, "tracking.tracks", rna_path_maxncpy);
|
2017-12-19 13:09:39 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
char object_name_esc[MAX_NAME * 2];
|
2022-10-05 18:01:29 +02:00
|
|
|
BLI_str_escape(object_name_esc, tracking_object->name, sizeof(object_name_esc));
|
2023-05-09 15:02:12 +10:00
|
|
|
BLI_snprintf(rna_path, rna_path_maxncpy, "tracking.objects[\"%s\"]", object_name_esc);
|
2017-12-19 13:09:39 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-17 06:17:24 +02:00
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void BKE_tracking_get_rna_path_for_plane_track(const MovieTracking *tracking,
|
|
|
|
|
const MovieTrackingPlaneTrack *plane_track,
|
2017-12-19 12:45:23 +01:00
|
|
|
char *rna_path,
|
2023-05-09 15:02:12 +10:00
|
|
|
size_t rna_path_maxncpy)
|
2017-12-19 12:45:23 +01:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object = BKE_tracking_find_object_for_plane_track(tracking,
|
|
|
|
|
plane_track);
|
2017-12-19 12:45:23 +01:00
|
|
|
char track_name_esc[MAX_NAME * 2];
|
2020-12-10 13:25:49 +11:00
|
|
|
BLI_str_escape(track_name_esc, plane_track->name, sizeof(track_name_esc));
|
2023-03-01 12:32:15 +01:00
|
|
|
if (tracking_object == nullptr) {
|
2023-05-09 15:02:12 +10:00
|
|
|
BLI_snprintf(rna_path, rna_path_maxncpy, "tracking.plane_tracks[\"%s\"]", track_name_esc);
|
2017-12-19 12:45:23 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
char object_name_esc[MAX_NAME * 2];
|
2022-10-05 18:01:29 +02:00
|
|
|
BLI_str_escape(object_name_esc, tracking_object->name, sizeof(object_name_esc));
|
2017-12-19 12:45:23 +01:00
|
|
|
BLI_snprintf(rna_path,
|
2023-05-09 15:02:12 +10:00
|
|
|
rna_path_maxncpy,
|
2017-12-19 12:45:23 +01:00
|
|
|
"tracking.objects[\"%s\"].plane_tracks[\"%s\"]",
|
|
|
|
|
object_name_esc,
|
|
|
|
|
track_name_esc);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-12-19 13:09:39 +01:00
|
|
|
|
2023-06-03 08:36:28 +10:00
|
|
|
void BKE_tracking_get_rna_path_prefix_for_plane_track(const MovieTracking *tracking,
|
|
|
|
|
const MovieTrackingPlaneTrack *plane_track,
|
|
|
|
|
char *rna_path,
|
|
|
|
|
size_t rna_path_maxncpy)
|
2017-12-19 13:09:39 +01:00
|
|
|
{
|
2022-10-05 18:01:29 +02:00
|
|
|
MovieTrackingObject *tracking_object = BKE_tracking_find_object_for_plane_track(tracking,
|
|
|
|
|
plane_track);
|
2023-03-01 12:32:15 +01:00
|
|
|
if (tracking_object == nullptr) {
|
2023-05-09 15:02:12 +10:00
|
|
|
BLI_strncpy(rna_path, "tracking.plane_tracks", rna_path_maxncpy);
|
2017-12-19 13:09:39 +01:00
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
char object_name_esc[MAX_NAME * 2];
|
2022-10-05 18:01:29 +02:00
|
|
|
BLI_str_escape(object_name_esc, tracking_object->name, sizeof(object_name_esc));
|
2023-05-09 15:02:12 +10:00
|
|
|
BLI_snprintf(
|
|
|
|
|
rna_path, rna_path_maxncpy, "tracking.objects[\"%s\"].plane_tracks", object_name_esc);
|
2017-12-19 13:09:39 +01:00
|
|
|
}
|
|
|
|
|
}
|