tracking.c 85 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899
  1. /*
  2. * ***** BEGIN GPL LICENSE BLOCK *****
  3. *
  4. * This program is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License
  6. * as published by the Free Software Foundation; either version 2
  7. * of the License, or (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program; if not, write to the Free Software Foundation,
  16. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  17. *
  18. * The Original Code is Copyright (C) 2011 Blender Foundation.
  19. * All rights reserved.
  20. *
  21. * Contributor(s): Blender Foundation,
  22. * Sergey Sharybin
  23. * Keir Mierle
  24. *
  25. * ***** END GPL LICENSE BLOCK *****
  26. */
  27. /** \file blender/blenkernel/intern/tracking.c
  28. * \ingroup bke
  29. */
  30. #include <stddef.h>
  31. #include <limits.h>
  32. #include <math.h>
  33. #include <memory.h>
  34. #include "MEM_guardedalloc.h"
  35. #include "DNA_anim_types.h"
  36. #include "DNA_gpencil_types.h"
  37. #include "DNA_camera_types.h"
  38. #include "DNA_movieclip_types.h"
  39. #include "DNA_object_types.h" /* SELECT */
  40. #include "DNA_scene_types.h"
  41. #include "BLI_utildefines.h"
  42. #include "BLI_bitmap_draw_2d.h"
  43. #include "BLI_ghash.h"
  44. #include "BLI_math.h"
  45. #include "BLI_math_base.h"
  46. #include "BLI_listbase.h"
  47. #include "BLI_string.h"
  48. #include "BLI_string_utils.h"
  49. #include "BLI_threads.h"
  50. #include "BLT_translation.h"
  51. #include "BKE_fcurve.h"
  52. #include "BKE_tracking.h"
  53. #include "BKE_library.h"
  54. #include "BKE_movieclip.h"
  55. #include "BKE_object.h"
  56. #include "BKE_scene.h"
  57. #include "IMB_imbuf_types.h"
  58. #include "IMB_imbuf.h"
  59. #include "RNA_access.h"
  60. #include "libmv-capi.h"
  61. #include "tracking_private.h"
  62. typedef struct MovieDistortion {
  63. struct libmv_CameraIntrinsics *intrinsics;
  64. /* Parameters needed for coordinates normalization. */
  65. float principal[2];
  66. float pixel_aspect;
  67. float focal;
  68. } MovieDistortion;
  69. static struct {
  70. ListBase tracks;
  71. } tracking_clipboard;
  72. /*********************** Common functions *************************/
  73. /* Free the whole list of tracks, list's head and tail are set to NULL. */
  74. static void tracking_tracks_free(ListBase *tracks)
  75. {
  76. MovieTrackingTrack *track;
  77. for (track = tracks->first; track; track = track->next) {
  78. BKE_tracking_track_free(track);
  79. }
  80. BLI_freelistN(tracks);
  81. }
  82. /* Free the whole list of plane tracks, list's head and tail are set to NULL. */
  83. static void tracking_plane_tracks_free(ListBase *plane_tracks)
  84. {
  85. MovieTrackingPlaneTrack *plane_track;
  86. for (plane_track = plane_tracks->first; plane_track; plane_track = plane_track->next) {
  87. BKE_tracking_plane_track_free(plane_track);
  88. }
  89. BLI_freelistN(plane_tracks);
  90. }
  91. /* Free reconstruction structures, only frees contents of a structure,
  92. * (if structure is allocated in heap, it shall be handled outside).
  93. *
  94. * All the pointers inside structure becomes invalid after this call.
  95. */
  96. static void tracking_reconstruction_free(MovieTrackingReconstruction *reconstruction)
  97. {
  98. if (reconstruction->cameras)
  99. MEM_freeN(reconstruction->cameras);
  100. }
  101. /* Free memory used by tracking object, only frees contents of the structure,
  102. * (if structure is allocated in heap, it shall be handled outside).
  103. *
  104. * All the pointers inside structure becomes invalid after this call.
  105. */
  106. static void tracking_object_free(MovieTrackingObject *object)
  107. {
  108. tracking_tracks_free(&object->tracks);
  109. tracking_plane_tracks_free(&object->plane_tracks);
  110. tracking_reconstruction_free(&object->reconstruction);
  111. }
  112. /* Free list of tracking objects, list's head and tail is set to NULL. */
  113. static void tracking_objects_free(ListBase *objects)
  114. {
  115. MovieTrackingObject *object;
  116. /* Free objects contents. */
  117. for (object = objects->first; object; object = object->next)
  118. tracking_object_free(object);
  119. /* Free objects themselves. */
  120. BLI_freelistN(objects);
  121. }
  122. /* Free memory used by a dopesheet, only frees dopesheet contents.
  123. * leaving dopesheet crystal clean for further usage.
  124. */
  125. static void tracking_dopesheet_free(MovieTrackingDopesheet *dopesheet)
  126. {
  127. MovieTrackingDopesheetChannel *channel;
  128. /* Free channel's sergments. */
  129. channel = dopesheet->channels.first;
  130. while (channel) {
  131. if (channel->segments) {
  132. MEM_freeN(channel->segments);
  133. }
  134. channel = channel->next;
  135. }
  136. /* Free lists themselves. */
  137. BLI_freelistN(&dopesheet->channels);
  138. BLI_freelistN(&dopesheet->coverage_segments);
  139. /* Ensure lists are clean. */
  140. BLI_listbase_clear(&dopesheet->channels);
  141. BLI_listbase_clear(&dopesheet->coverage_segments);
  142. dopesheet->tot_channel = 0;
  143. }
  144. /* Free tracking structure, only frees structure contents
  145. * (if structure is allocated in heap, it shall be handled outside).
  146. *
  147. * All the pointers inside structure becomes invalid after this call.
  148. */
  149. void BKE_tracking_free(MovieTracking *tracking)
  150. {
  151. tracking_tracks_free(&tracking->tracks);
  152. tracking_plane_tracks_free(&tracking->plane_tracks);
  153. tracking_reconstruction_free(&tracking->reconstruction);
  154. tracking_objects_free(&tracking->objects);
  155. if (tracking->camera.intrinsics)
  156. BKE_tracking_distortion_free(tracking->camera.intrinsics);
  157. tracking_dopesheet_free(&tracking->dopesheet);
  158. }
  159. /* Copy the whole list of tracks. */
  160. static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_src, GHash *tracks_mapping)
  161. {
  162. MovieTrackingTrack *track_dst, *track_src;
  163. BLI_listbase_clear(tracks_dst);
  164. BLI_ghash_clear(tracks_mapping, NULL, NULL);
  165. for (track_src = tracks_src->first; track_src != NULL; track_src = track_src->next) {
  166. track_dst = MEM_dupallocN(track_src);
  167. if (track_src->markers) {
  168. track_dst->markers = MEM_dupallocN(track_src->markers);
  169. }
  170. id_us_plus(&track_dst->gpd->id);
  171. BLI_addtail(tracks_dst, track_dst);
  172. BLI_ghash_insert(tracks_mapping, track_src, track_dst);
  173. }
  174. }
  175. /* copy the whole list of plane tracks (need whole MovieTracking structures due to embedded pointers to tracks).
  176. * WARNING: implies tracking_[dst/src] and their tracks have already been copied. */
  177. static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, const ListBase *plane_tracks_src, GHash *tracks_mapping)
  178. {
  179. MovieTrackingPlaneTrack *plane_track_dst, *plane_track_src;
  180. BLI_listbase_clear(plane_tracks_dst);
  181. for (plane_track_src = plane_tracks_src->first; plane_track_src != NULL; plane_track_src = plane_track_src->next) {
  182. plane_track_dst = MEM_dupallocN(plane_tracks_src);
  183. if (plane_track_src->markers) {
  184. plane_track_dst->markers = MEM_dupallocN(plane_track_src->markers);
  185. }
  186. plane_track_dst->point_tracks = MEM_mallocN(sizeof(*plane_track_dst->point_tracks) * plane_track_dst->point_tracksnr, __func__);
  187. for (int i = 0; i < plane_track_dst->point_tracksnr; i++) {
  188. plane_track_dst->point_tracks[i] = BLI_ghash_lookup(tracks_mapping, plane_track_src->point_tracks[i]);
  189. }
  190. id_us_plus(&plane_track_dst->image->id);
  191. BLI_addtail(plane_tracks_dst, plane_track_dst);
  192. }
  193. }
  194. /* Copy reconstruction structure. */
  195. static void tracking_reconstruction_copy(
  196. MovieTrackingReconstruction *reconstruction_dst, const MovieTrackingReconstruction *reconstruction_src)
  197. {
  198. *reconstruction_dst = *reconstruction_src;
  199. if (reconstruction_src->cameras) {
  200. reconstruction_dst->cameras = MEM_dupallocN(reconstruction_src->cameras);
  201. }
  202. }
  203. /* Copy stabilization structure. */
  204. static void tracking_stabilization_copy(
  205. MovieTrackingStabilization *stabilization_dst, const MovieTrackingStabilization *stabilization_src)
  206. {
  207. *stabilization_dst = *stabilization_src;
  208. }
  209. /* Copy tracking object. */
  210. static void tracking_object_copy(
  211. MovieTrackingObject *object_dst, const MovieTrackingObject *object_src, GHash *tracks_mapping)
  212. {
  213. *object_dst = *object_src;
  214. tracking_tracks_copy(&object_dst->tracks, &object_src->tracks, tracks_mapping);
  215. tracking_plane_tracks_copy(&object_dst->plane_tracks, &object_src->plane_tracks, tracks_mapping);
  216. tracking_reconstruction_copy(&object_dst->reconstruction, &object_src->reconstruction);
  217. }
  218. /* Copy list of tracking objects. */
  219. static void tracking_objects_copy(ListBase *objects_dst, const ListBase *objects_src, GHash *tracks_mapping)
  220. {
  221. MovieTrackingObject *object_dst, *object_src;
  222. BLI_listbase_clear(objects_dst);
  223. for (object_src = objects_src->first; object_src != NULL; object_src = object_src->next) {
  224. object_dst = MEM_mallocN(sizeof(*object_dst), __func__);
  225. tracking_object_copy(object_dst, object_src, tracks_mapping);
  226. BLI_addtail(objects_dst, object_dst);
  227. }
  228. }
  229. /* Copy tracking structure content. */
  230. void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *tracking_src)
  231. {
  232. GHash *tracks_mapping = BLI_ghash_ptr_new(__func__);
  233. *tracking_dst = *tracking_src;
  234. tracking_tracks_copy(&tracking_dst->tracks, &tracking_src->tracks, tracks_mapping);
  235. tracking_plane_tracks_copy(&tracking_dst->plane_tracks, &tracking_src->plane_tracks, tracks_mapping);
  236. tracking_reconstruction_copy(&tracking_dst->reconstruction, &tracking_src->reconstruction);
  237. tracking_stabilization_copy(&tracking_dst->stabilization, &tracking_src->stabilization);
  238. if (tracking_src->act_track) {
  239. tracking_dst->act_track = BLI_ghash_lookup(tracks_mapping, tracking_src->act_track);
  240. }
  241. if (tracking_src->act_plane_track) {
  242. MovieTrackingPlaneTrack *plane_track_src, *plane_track_dst;
  243. for (plane_track_src = tracking_src->plane_tracks.first, plane_track_dst = tracking_dst->plane_tracks.first;
  244. !ELEM(NULL, plane_track_src, plane_track_dst);
  245. plane_track_src = plane_track_src->next, plane_track_dst = plane_track_dst->next)
  246. {
  247. if (plane_track_src == tracking_src->act_plane_track) {
  248. tracking_dst->act_plane_track = plane_track_dst;
  249. break;
  250. }
  251. }
  252. }
  253. /* Warning! Will override tracks_mapping. */
  254. tracking_objects_copy(&tracking_dst->objects, &tracking_src->objects, tracks_mapping);
  255. /* Those remaining are runtime data, they will be reconstructed as needed, do not bother copying them. */
  256. tracking_dst->dopesheet.ok = false;
  257. BLI_listbase_clear(&tracking_dst->dopesheet.channels);
  258. BLI_listbase_clear(&tracking_dst->dopesheet.coverage_segments);
  259. tracking_dst->camera.intrinsics = NULL;
  260. tracking_dst->stats = NULL;
  261. BLI_ghash_free(tracks_mapping, NULL, NULL);
  262. }
  263. /* Initialize motion tracking settings to default values,
  264. * used when new movie clip datablock is created.
  265. */
  266. void BKE_tracking_settings_init(MovieTracking *tracking)
  267. {
  268. tracking->camera.sensor_width = 35.0f;
  269. tracking->camera.pixel_aspect = 1.0f;
  270. tracking->camera.units = CAMERA_UNITS_MM;
  271. tracking->settings.default_motion_model = TRACK_MOTION_MODEL_TRANSLATION;
  272. tracking->settings.default_minimum_correlation = 0.75;
  273. tracking->settings.default_pattern_size = 21;
  274. tracking->settings.default_search_size = 71;
  275. tracking->settings.default_algorithm_flag |= TRACK_ALGORITHM_FLAG_USE_BRUTE;
  276. tracking->settings.default_weight = 1.0f;
  277. tracking->settings.dist = 1;
  278. tracking->settings.object_distance = 1;
  279. tracking->stabilization.scaleinf = 1.0f;
  280. tracking->stabilization.anchor_frame = 1;
  281. zero_v2(tracking->stabilization.target_pos);
  282. tracking->stabilization.target_rot = 0.0f;
  283. tracking->stabilization.scale = 1.0f;
  284. tracking->stabilization.act_track = 0;
  285. tracking->stabilization.act_rot_track = 0;
  286. tracking->stabilization.tot_track = 0;
  287. tracking->stabilization.tot_rot_track = 0;
  288. tracking->stabilization.scaleinf = 1.0f;
  289. tracking->stabilization.locinf = 1.0f;
  290. tracking->stabilization.rotinf = 1.0f;
  291. tracking->stabilization.maxscale = 2.0f;
  292. tracking->stabilization.filter = TRACKING_FILTER_BILINEAR;
  293. tracking->stabilization.flag |= TRACKING_SHOW_STAB_TRACKS;
  294. BKE_tracking_object_add(tracking, "Camera");
  295. }
  296. /* Get list base of active object's tracks. */
  297. ListBase *BKE_tracking_get_active_tracks(MovieTracking *tracking)
  298. {
  299. MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
  300. if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
  301. return &object->tracks;
  302. }
  303. return &tracking->tracks;
  304. }
  305. /* Get list base of active object's plane tracks. */
  306. ListBase *BKE_tracking_get_active_plane_tracks(MovieTracking *tracking)
  307. {
  308. MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
  309. if (object && (object->flag & TRACKING_OBJECT_CAMERA) == 0) {
  310. return &object->plane_tracks;
  311. }
  312. return &tracking->plane_tracks;
  313. }
  314. /* Get reconstruction data of active object. */
  315. MovieTrackingReconstruction *BKE_tracking_get_active_reconstruction(MovieTracking *tracking)
  316. {
  317. MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
  318. return BKE_tracking_object_get_reconstruction(tracking, object);
  319. }
  320. /* Get transformation matrix for a given object which is used
  321. * for parenting motion tracker reconstruction to 3D world.
  322. */
  323. void BKE_tracking_get_camera_object_matrix(Scene *scene, Object *ob, float mat[4][4])
  324. {
  325. if (!ob) {
  326. if (scene->camera)
  327. ob = scene->camera;
  328. else
  329. ob = BKE_scene_camera_find(scene);
  330. }
  331. if (ob)
  332. BKE_object_where_is_calc_mat4(scene, ob, mat);
  333. else
  334. unit_m4(mat);
  335. }
  336. /* Get projection matrix for camera specified by given tracking object
  337. * and frame number.
  338. *
  339. * NOTE: frame number should be in clip space, not scene space
  340. */
  341. void BKE_tracking_get_projection_matrix(MovieTracking *tracking, MovieTrackingObject *object,
  342. int framenr, int winx, int winy, float mat[4][4])
  343. {
  344. MovieReconstructedCamera *camera;
  345. float lens = tracking->camera.focal * tracking->camera.sensor_width / (float)winx;
  346. float viewfac, pixsize, left, right, bottom, top, clipsta, clipend;
  347. float winmat[4][4];
  348. float ycor = 1.0f / tracking->camera.pixel_aspect;
  349. float shiftx, shifty, winside = (float)min_ii(winx, winy);
  350. BKE_tracking_camera_shift_get(tracking, winx, winy, &shiftx, &shifty);
  351. clipsta = 0.1f;
  352. clipend = 1000.0f;
  353. if (winx >= winy)
  354. viewfac = (lens * winx) / tracking->camera.sensor_width;
  355. else
  356. viewfac = (ycor * lens * winy) / tracking->camera.sensor_width;
  357. pixsize = clipsta / viewfac;
  358. left = -0.5f * (float)winx + shiftx * winside;
  359. bottom = -0.5f * (ycor) * (float)winy + shifty * winside;
  360. right = 0.5f * (float)winx + shiftx * winside;
  361. top = 0.5f * (ycor) * (float)winy + shifty * winside;
  362. left *= pixsize;
  363. right *= pixsize;
  364. bottom *= pixsize;
  365. top *= pixsize;
  366. perspective_m4(winmat, left, right, bottom, top, clipsta, clipend);
  367. camera = BKE_tracking_camera_get_reconstructed(tracking, object, framenr);
  368. if (camera) {
  369. float imat[4][4];
  370. invert_m4_m4(imat, camera->mat);
  371. mul_m4_m4m4(mat, winmat, imat);
  372. }
  373. else {
  374. copy_m4_m4(mat, winmat);
  375. }
  376. }
  377. /*********************** clipboard *************************/
  378. /* Free clipboard by freeing memory used by all tracks in it. */
  379. void BKE_tracking_clipboard_free(void)
  380. {
  381. MovieTrackingTrack *track = tracking_clipboard.tracks.first, *next_track;
  382. while (track) {
  383. next_track = track->next;
  384. BKE_tracking_track_free(track);
  385. MEM_freeN(track);
  386. track = next_track;
  387. }
  388. BLI_listbase_clear(&tracking_clipboard.tracks);
  389. }
  390. /* Copy selected tracks from specified object to the clipboard. */
  391. void BKE_tracking_clipboard_copy_tracks(MovieTracking *tracking, MovieTrackingObject *object)
  392. {
  393. ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
  394. MovieTrackingTrack *track = tracksbase->first;
  395. /* First drop all tracks from current clipboard. */
  396. BKE_tracking_clipboard_free();
  397. /* Then copy all selected visible tracks to it. */
  398. while (track) {
  399. if (TRACK_SELECTED(track) && (track->flag & TRACK_HIDDEN) == 0) {
  400. MovieTrackingTrack *new_track = BKE_tracking_track_duplicate(track);
  401. BLI_addtail(&tracking_clipboard.tracks, new_track);
  402. }
  403. track = track->next;
  404. }
  405. }
  406. /* Check whether there're any tracks in the clipboard. */
  407. bool BKE_tracking_clipboard_has_tracks(void)
  408. {
  409. return (BLI_listbase_is_empty(&tracking_clipboard.tracks) == false);
  410. }
  411. /* Paste tracks from clipboard to specified object.
  412. *
  413. * Names of new tracks in object are guaranteed to
  414. * be unique here.
  415. */
  416. void BKE_tracking_clipboard_paste_tracks(MovieTracking *tracking, MovieTrackingObject *object)
  417. {
  418. ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
  419. MovieTrackingTrack *track = tracking_clipboard.tracks.first;
  420. while (track) {
  421. MovieTrackingTrack *new_track = BKE_tracking_track_duplicate(track);
  422. if (track->prev == NULL) {
  423. tracking->act_track = new_track;
  424. }
  425. BLI_addtail(tracksbase, new_track);
  426. BKE_tracking_track_unique_name(tracksbase, new_track);
  427. track = track->next;
  428. }
  429. }
  430. /*********************** Tracks *************************/
  431. /* Add new track to a specified tracks base.
  432. *
  433. * Coordinates are expected to be in normalized 0..1 space,
  434. * frame number is expected to be in clip space.
  435. *
  436. * Width and height are clip's dimension used to scale track's
  437. * pattern and search regions.
  438. */
  439. MovieTrackingTrack *BKE_tracking_track_add(MovieTracking *tracking, ListBase *tracksbase, float x, float y,
  440. int framenr, int width, int height)
  441. {
  442. MovieTrackingTrack *track;
  443. MovieTrackingMarker marker;
  444. MovieTrackingSettings *settings = &tracking->settings;
  445. float half_pattern = (float)settings->default_pattern_size / 2.0f;
  446. float half_search = (float)settings->default_search_size / 2.0f;
  447. float pat[2], search[2];
  448. pat[0] = half_pattern / (float)width;
  449. pat[1] = half_pattern / (float)height;
  450. search[0] = half_search / (float)width;
  451. search[1] = half_search / (float)height;
  452. track = MEM_callocN(sizeof(MovieTrackingTrack), "add_marker_exec track");
  453. strcpy(track->name, "Track");
  454. /* fill track's settings from default settings */
  455. track->motion_model = settings->default_motion_model;
  456. track->minimum_correlation = settings->default_minimum_correlation;
  457. track->margin = settings->default_margin;
  458. track->pattern_match = settings->default_pattern_match;
  459. track->frames_limit = settings->default_frames_limit;
  460. track->flag = settings->default_flag;
  461. track->algorithm_flag = settings->default_algorithm_flag;
  462. track->weight = settings->default_weight;
  463. track->weight_stab = settings->default_weight;
  464. memset(&marker, 0, sizeof(marker));
  465. marker.pos[0] = x;
  466. marker.pos[1] = y;
  467. marker.framenr = framenr;
  468. marker.pattern_corners[0][0] = -pat[0];
  469. marker.pattern_corners[0][1] = -pat[1];
  470. marker.pattern_corners[1][0] = pat[0];
  471. marker.pattern_corners[1][1] = -pat[1];
  472. negate_v2_v2(marker.pattern_corners[2], marker.pattern_corners[0]);
  473. negate_v2_v2(marker.pattern_corners[3], marker.pattern_corners[1]);
  474. copy_v2_v2(marker.search_max, search);
  475. negate_v2_v2(marker.search_min, search);
  476. BKE_tracking_marker_insert(track, &marker);
  477. BLI_addtail(tracksbase, track);
  478. BKE_tracking_track_unique_name(tracksbase, track);
  479. return track;
  480. }
  481. /* Duplicate the specified track, result will no belong to any list. */
  482. MovieTrackingTrack *BKE_tracking_track_duplicate(MovieTrackingTrack *track)
  483. {
  484. MovieTrackingTrack *new_track;
  485. new_track = MEM_callocN(sizeof(MovieTrackingTrack), "tracking_track_duplicate new_track");
  486. *new_track = *track;
  487. new_track->next = new_track->prev = NULL;
  488. new_track->markers = MEM_dupallocN(new_track->markers);
  489. /* Orevent duplicate from being used for 2D stabilization.
  490. * If necessary, it shall be added explicitly.
  491. */
  492. new_track->flag &= ~TRACK_USE_2D_STAB;
  493. new_track->flag &= ~TRACK_USE_2D_STAB_ROT;
  494. return new_track;
  495. }
  496. /* Ensure specified track has got unique name,
  497. * if it's not name of specified track will be changed
  498. * keeping names of all other tracks unchanged.
  499. */
  500. void BKE_tracking_track_unique_name(ListBase *tracksbase, MovieTrackingTrack *track)
  501. {
  502. BLI_uniquename(tracksbase, track, CTX_DATA_(BLT_I18NCONTEXT_ID_MOVIECLIP, "Track"), '.',
  503. offsetof(MovieTrackingTrack, name), sizeof(track->name));
  504. }
  505. /* Free specified track, only frees contents of a structure
  506. * (if track is allocated in heap, it shall be handled outside).
  507. *
  508. * All the pointers inside track becomes invalid after this call.
  509. */
  510. void BKE_tracking_track_free(MovieTrackingTrack *track)
  511. {
  512. if (track->markers)
  513. MEM_freeN(track->markers);
  514. }
  515. /* Set flag for all specified track's areas.
  516. *
  517. * area - which part of marker should be selected. see TRACK_AREA_* constants.
  518. * flag - flag to be set for areas.
  519. */
  520. void BKE_tracking_track_flag_set(MovieTrackingTrack *track, int area, int flag)
  521. {
  522. if (area == TRACK_AREA_NONE)
  523. return;
  524. if (area & TRACK_AREA_POINT)
  525. track->flag |= flag;
  526. if (area & TRACK_AREA_PAT)
  527. track->pat_flag |= flag;
  528. if (area & TRACK_AREA_SEARCH)
  529. track->search_flag |= flag;
  530. }
  531. /* Clear flag from all specified track's areas.
  532. *
  533. * area - which part of marker should be selected. see TRACK_AREA_* constants.
  534. * flag - flag to be cleared for areas.
  535. */
  536. void BKE_tracking_track_flag_clear(MovieTrackingTrack *track, int area, int flag)
  537. {
  538. if (area == TRACK_AREA_NONE)
  539. return;
  540. if (area & TRACK_AREA_POINT)
  541. track->flag &= ~flag;
  542. if (area & TRACK_AREA_PAT)
  543. track->pat_flag &= ~flag;
  544. if (area & TRACK_AREA_SEARCH)
  545. track->search_flag &= ~flag;
  546. }
  547. /* Check whether track has got marker at specified frame.
  548. *
  549. * NOTE: frame number should be in clip space, not scene space.
  550. */
  551. bool BKE_tracking_track_has_marker_at_frame(MovieTrackingTrack *track, int framenr)
  552. {
  553. return BKE_tracking_marker_get_exact(track, framenr) != NULL;
  554. }
  555. /* Check whether track has got enabled marker at specified frame.
  556. *
  557. * NOTE: frame number should be in clip space, not scene space.
  558. */
  559. bool BKE_tracking_track_has_enabled_marker_at_frame(MovieTrackingTrack *track, int framenr)
  560. {
  561. MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, framenr);
  562. return marker && (marker->flag & MARKER_DISABLED) == 0;
  563. }
  564. /* Clear track's path:
  565. *
  566. * - If action is TRACK_CLEAR_REMAINED path from ref_frame+1 up to
  567. * end will be clear.
  568. *
  569. * - If action is TRACK_CLEAR_UPTO path from the beginning up to
  570. * ref_frame-1 will be clear.
  571. *
  572. * - If action is TRACK_CLEAR_ALL only marker at frame ref_frame will remain.
  573. *
  574. * NOTE: frame number should be in clip space, not scene space
  575. */
  576. void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int action)
  577. {
  578. int a;
  579. if (action == TRACK_CLEAR_REMAINED) {
  580. a = 1;
  581. while (a < track->markersnr) {
  582. if (track->markers[a].framenr > ref_frame) {
  583. track->markersnr = a;
  584. track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
  585. break;
  586. }
  587. a++;
  588. }
  589. if (track->markersnr)
  590. tracking_marker_insert_disabled(track, &track->markers[track->markersnr - 1], false, true);
  591. }
  592. else if (action == TRACK_CLEAR_UPTO) {
  593. a = track->markersnr - 1;
  594. while (a >= 0) {
  595. if (track->markers[a].framenr <= ref_frame) {
  596. memmove(track->markers, track->markers + a, (track->markersnr - a) * sizeof(MovieTrackingMarker));
  597. track->markersnr = track->markersnr - a;
  598. track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
  599. break;
  600. }
  601. a--;
  602. }
  603. if (track->markersnr)
  604. tracking_marker_insert_disabled(track, &track->markers[0], true, true);
  605. }
  606. else if (action == TRACK_CLEAR_ALL) {
  607. MovieTrackingMarker *marker, marker_new;
  608. marker = BKE_tracking_marker_get(track, ref_frame);
  609. marker_new = *marker;
  610. MEM_freeN(track->markers);
  611. track->markers = NULL;
  612. track->markersnr = 0;
  613. BKE_tracking_marker_insert(track, &marker_new);
  614. tracking_marker_insert_disabled(track, &marker_new, true, true);
  615. tracking_marker_insert_disabled(track, &marker_new, false, true);
  616. }
  617. }
  618. void BKE_tracking_tracks_join(MovieTracking *tracking, MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track)
  619. {
  620. int i = 0, a = 0, b = 0, tot;
  621. MovieTrackingMarker *markers;
  622. tot = dst_track->markersnr + src_track->markersnr;
  623. markers = MEM_callocN(tot * sizeof(MovieTrackingMarker), "tmp tracking joined tracks");
  624. while (a < src_track->markersnr || b < dst_track->markersnr) {
  625. if (b >= dst_track->markersnr) {
  626. markers[i] = src_track->markers[a++];
  627. }
  628. else if (a >= src_track->markersnr) {
  629. markers[i] = dst_track->markers[b++];
  630. }
  631. else if (src_track->markers[a].framenr < dst_track->markers[b].framenr) {
  632. markers[i] = src_track->markers[a++];
  633. }
  634. else if (src_track->markers[a].framenr > dst_track->markers[b].framenr) {
  635. markers[i] = dst_track->markers[b++];
  636. }
  637. else {
  638. if ((src_track->markers[a].flag & MARKER_DISABLED) == 0) {
  639. if ((dst_track->markers[b].flag & MARKER_DISABLED) == 0) {
  640. /* both tracks are enabled on this frame, so find the whole segment
  641. * on which tracks are intersecting and blend tracks using linear
  642. * interpolation to prevent jumps
  643. */
  644. MovieTrackingMarker *marker_a, *marker_b;
  645. int start_a = a, start_b = b, len = 0, frame = src_track->markers[a].framenr;
  646. int j, inverse = 0;
  647. inverse = (b == 0) ||
  648. (dst_track->markers[b - 1].flag & MARKER_DISABLED) ||
  649. (dst_track->markers[b - 1].framenr != frame - 1);
  650. /* find length of intersection */
  651. while (a < src_track->markersnr && b < dst_track->markersnr) {
  652. marker_a = &src_track->markers[a];
  653. marker_b = &dst_track->markers[b];
  654. if (marker_a->flag & MARKER_DISABLED || marker_b->flag & MARKER_DISABLED)
  655. break;
  656. if (marker_a->framenr != frame || marker_b->framenr != frame)
  657. break;
  658. frame++;
  659. len++;
  660. a++;
  661. b++;
  662. }
  663. a = start_a;
  664. b = start_b;
  665. /* linear interpolation for intersecting frames */
  666. for (j = 0; j < len; j++) {
  667. float fac = 0.5f;
  668. if (len > 1)
  669. fac = 1.0f / (len - 1) * j;
  670. if (inverse)
  671. fac = 1.0f - fac;
  672. marker_a = &src_track->markers[a];
  673. marker_b = &dst_track->markers[b];
  674. markers[i] = dst_track->markers[b];
  675. interp_v2_v2v2(markers[i].pos, marker_b->pos, marker_a->pos, fac);
  676. a++;
  677. b++;
  678. i++;
  679. }
  680. /* this values will be incremented at the end of the loop cycle */
  681. a--; b--; i--;
  682. }
  683. else {
  684. markers[i] = src_track->markers[a];
  685. }
  686. }
  687. else {
  688. markers[i] = dst_track->markers[b];
  689. }
  690. a++;
  691. b++;
  692. }
  693. i++;
  694. }
  695. MEM_freeN(dst_track->markers);
  696. dst_track->markers = MEM_callocN(i * sizeof(MovieTrackingMarker), "tracking joined tracks");
  697. memcpy(dst_track->markers, markers, i * sizeof(MovieTrackingMarker));
  698. dst_track->markersnr = i;
  699. MEM_freeN(markers);
  700. BKE_tracking_dopesheet_tag_update(tracking);
  701. }
  702. MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name)
  703. {
  704. ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
  705. MovieTrackingTrack *track = tracksbase->first;
  706. while (track) {
  707. if (STREQ(track->name, name))
  708. return track;
  709. track = track->next;
  710. }
  711. return NULL;
  712. }
  713. MovieTrackingTrack *BKE_tracking_track_get_indexed(MovieTracking *tracking, int tracknr, ListBase **r_tracksbase)
  714. {
  715. MovieTrackingObject *object;
  716. int cur = 1;
  717. object = tracking->objects.first;
  718. while (object) {
  719. ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
  720. MovieTrackingTrack *track = tracksbase->first;
  721. while (track) {
  722. if (track->flag & TRACK_HAS_BUNDLE) {
  723. if (cur == tracknr) {
  724. *r_tracksbase = tracksbase;
  725. return track;
  726. }
  727. cur++;
  728. }
  729. track = track->next;
  730. }
  731. object = object->next;
  732. }
  733. *r_tracksbase = NULL;
  734. return NULL;
  735. }
  736. MovieTrackingTrack *BKE_tracking_track_get_active(MovieTracking *tracking)
  737. {
  738. ListBase *tracksbase;
  739. if (!tracking->act_track)
  740. return NULL;
  741. tracksbase = BKE_tracking_get_active_tracks(tracking);
  742. /* check that active track is in current tracks list */
  743. if (BLI_findindex(tracksbase, tracking->act_track) != -1)
  744. return tracking->act_track;
  745. return NULL;
  746. }
  747. static bGPDlayer *track_mask_gpencil_layer_get(MovieTrackingTrack *track)
  748. {
  749. bGPDlayer *layer;
  750. if (!track->gpd)
  751. return NULL;
  752. layer = track->gpd->layers.first;
  753. while (layer) {
  754. if (layer->flag & GP_LAYER_ACTIVE) {
  755. bGPDframe *frame = layer->frames.first;
  756. bool ok = false;
  757. while (frame) {
  758. if (frame->strokes.first) {
  759. ok = true;
  760. break;
  761. }
  762. frame = frame->next;
  763. }
  764. if (ok)
  765. return layer;
  766. }
  767. layer = layer->next;
  768. }
  769. return NULL;
  770. }
  771. typedef struct TrackMaskSetPixelData {
  772. float *mask;
  773. int mask_width;
  774. int mask_height;
  775. } TrackMaskSetPixelData;
  776. static void track_mask_set_pixel_cb(int x, int x_end, int y, void *user_data)
  777. {
  778. TrackMaskSetPixelData *data = (TrackMaskSetPixelData *)user_data;
  779. size_t index = (size_t)y * data->mask_width + x;
  780. size_t index_end = (size_t)y * data->mask_width + x_end;
  781. do {
  782. data->mask[index] = 1.0f;
  783. } while (++index != index_end);
  784. }
  785. static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height,
  786. const float region_min[2],
  787. bGPDlayer *layer,
  788. float *mask,
  789. int mask_width,
  790. int mask_height)
  791. {
  792. bGPDframe *frame = layer->frames.first;
  793. TrackMaskSetPixelData data;
  794. data.mask = mask;
  795. data.mask_width = mask_width;
  796. data.mask_height = mask_height;
  797. while (frame) {
  798. bGPDstroke *stroke = frame->strokes.first;
  799. while (stroke) {
  800. bGPDspoint *stroke_points = stroke->points;
  801. if (stroke->flag & GP_STROKE_2DSPACE) {
  802. int *mask_points, *point;
  803. point = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(int),
  804. "track mask rasterization points");
  805. for (int i = 0; i < stroke->totpoints; i++, point += 2) {
  806. point[0] = stroke_points[i].x * frame_width - region_min[0];
  807. point[1] = stroke_points[i].y * frame_height - region_min[1];
  808. }
  809. /* TODO: add an option to control whether AA is enabled or not */
  810. BLI_bitmap_draw_2d_poly_v2i_n(
  811. 0, 0, mask_width, mask_height,
  812. (const int (*)[2])mask_points, stroke->totpoints,
  813. track_mask_set_pixel_cb, &data);
  814. MEM_freeN(mask_points);
  815. }
  816. stroke = stroke->next;
  817. }
  818. frame = frame->next;
  819. }
  820. }
  821. /* Region is in pixel space, relative to marker's center. */
  822. float *tracking_track_get_mask_for_region(int frame_width, int frame_height,
  823. const float region_min[2],
  824. const float region_max[2],
  825. MovieTrackingTrack *track)
  826. {
  827. float *mask = NULL;
  828. bGPDlayer *layer = track_mask_gpencil_layer_get(track);
  829. if (layer != NULL) {
  830. const int mask_width = region_max[0] - region_min[0];
  831. const int mask_height = region_max[1] - region_min[1];
  832. mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
  833. track_mask_gpencil_layer_rasterize(frame_width, frame_height,
  834. region_min,
  835. layer,
  836. mask,
  837. mask_width, mask_height);
  838. }
  839. return mask;
  840. }
  841. float *BKE_tracking_track_get_mask(int frame_width, int frame_height,
  842. MovieTrackingTrack *track,
  843. MovieTrackingMarker *marker)
  844. {
  845. /* Convert normalized space marker's search area to pixel-space region. */
  846. const float region_min[2] = {marker->search_min[0] * frame_width,
  847. marker->search_min[1] * frame_height};
  848. const float region_max[2] = {marker->search_max[0] * frame_width,
  849. marker->search_max[1] * frame_height};
  850. return tracking_track_get_mask_for_region(frame_width, frame_height,
  851. region_min,
  852. region_max,
  853. track);
  854. }
  855. float BKE_tracking_track_get_weight_for_marker(MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker)
  856. {
  857. FCurve *weight_fcurve;
  858. float weight = track->weight;
  859. weight_fcurve = id_data_find_fcurve(&clip->id, track, &RNA_MovieTrackingTrack,
  860. "weight", 0, NULL);
  861. if (weight_fcurve) {
  862. int scene_framenr =
  863. BKE_movieclip_remap_clip_to_scene_frame(clip, marker->framenr);
  864. weight = evaluate_fcurve(weight_fcurve, scene_framenr);
  865. }
  866. return weight;
  867. }
  868. /* area - which part of marker should be selected. see TRACK_AREA_* constants */
  869. void BKE_tracking_track_select(ListBase *tracksbase, MovieTrackingTrack *track, int area, bool extend)
  870. {
  871. if (extend) {
  872. BKE_tracking_track_flag_set(track, area, SELECT);
  873. }
  874. else {
  875. MovieTrackingTrack *cur = tracksbase->first;
  876. while (cur) {
  877. if ((cur->flag & TRACK_HIDDEN) == 0) {
  878. if (cur == track) {
  879. BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
  880. BKE_tracking_track_flag_set(cur, area, SELECT);
  881. }
  882. else {
  883. BKE_tracking_track_flag_clear(cur, TRACK_AREA_ALL, SELECT);
  884. }
  885. }
  886. cur = cur->next;
  887. }
  888. }
  889. }
  890. void BKE_tracking_track_deselect(MovieTrackingTrack *track, int area)
  891. {
  892. BKE_tracking_track_flag_clear(track, area, SELECT);
  893. }
  894. void BKE_tracking_tracks_deselect_all(ListBase *tracksbase)
  895. {
  896. MovieTrackingTrack *track;
  897. for (track = tracksbase->first; track; track = track->next) {
  898. if ((track->flag & TRACK_HIDDEN) == 0) {
  899. BKE_tracking_track_flag_clear(track, TRACK_AREA_ALL, SELECT);
  900. }
  901. }
  902. }
  903. /*********************** Marker *************************/
  904. MovieTrackingMarker *BKE_tracking_marker_insert(MovieTrackingTrack *track, MovieTrackingMarker *marker)
  905. {
  906. MovieTrackingMarker *old_marker = NULL;
  907. if (track->markersnr)
  908. old_marker = BKE_tracking_marker_get_exact(track, marker->framenr);
  909. if (old_marker) {
  910. /* simply replace settings for already allocated marker */
  911. *old_marker = *marker;
  912. return old_marker;
  913. }
  914. else {
  915. int a = track->markersnr;
  916. /* find position in array where to add new marker */
  917. while (a--) {
  918. if (track->markers[a].framenr < marker->framenr)
  919. break;
  920. }
  921. track->markersnr++;
  922. if (track->markers)
  923. track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
  924. else
  925. track->markers = MEM_callocN(sizeof(MovieTrackingMarker), "MovieTracking markers");
  926. /* shift array to "free" space for new marker */
  927. memmove(track->markers + a + 2, track->markers + a + 1,
  928. (track->markersnr - a - 2) * sizeof(MovieTrackingMarker));
  929. /* put new marker */
  930. track->markers[a + 1] = *marker;
  931. track->last_marker = a + 1;
  932. return &track->markers[a + 1];
  933. }
  934. }
  935. void BKE_tracking_marker_delete(MovieTrackingTrack *track, int framenr)
  936. {
  937. int a = 0;
  938. while (a < track->markersnr) {
  939. if (track->markers[a].framenr == framenr) {
  940. if (track->markersnr > 1) {
  941. memmove(track->markers + a, track->markers + a + 1,
  942. (track->markersnr - a - 1) * sizeof(MovieTrackingMarker));
  943. track->markersnr--;
  944. track->markers = MEM_reallocN(track->markers, sizeof(MovieTrackingMarker) * track->markersnr);
  945. }
  946. else {
  947. MEM_freeN(track->markers);
  948. track->markers = NULL;
  949. track->markersnr = 0;
  950. }
  951. break;
  952. }
  953. a++;
  954. }
  955. }
  956. void BKE_tracking_marker_clamp(MovieTrackingMarker *marker, int event)
  957. {
  958. int a;
  959. float pat_min[2], pat_max[2];
  960. BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
  961. if (event == CLAMP_PAT_DIM) {
  962. for (a = 0; a < 2; a++) {
  963. /* search shouldn't be resized smaller than pattern */
  964. marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]);
  965. marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]);
  966. }
  967. }
  968. else if (event == CLAMP_PAT_POS) {
  969. float dim[2];
  970. sub_v2_v2v2(dim, pat_max, pat_min);
  971. for (a = 0; a < 2; a++) {
  972. int b;
  973. /* pattern shouldn't be moved outside of search */
  974. if (pat_min[a] < marker->search_min[a]) {
  975. for (b = 0; b < 4; b++)
  976. marker->pattern_corners[b][a] += marker->search_min[a] - pat_min[a];
  977. }
  978. if (pat_max[a] > marker->search_max[a]) {
  979. for (b = 0; b < 4; b++)
  980. marker->pattern_corners[b][a] -= pat_max[a] - marker->search_max[a];
  981. }
  982. }
  983. }
  984. else if (event == CLAMP_SEARCH_DIM) {
  985. for (a = 0; a < 2; a++) {
  986. /* search shouldn't be resized smaller than pattern */
  987. marker->search_min[a] = min_ff(pat_min[a], marker->search_min[a]);
  988. marker->search_max[a] = max_ff(pat_max[a], marker->search_max[a]);
  989. }
  990. }
  991. else if (event == CLAMP_SEARCH_POS) {
  992. float dim[2];
  993. sub_v2_v2v2(dim, marker->search_max, marker->search_min);
  994. for (a = 0; a < 2; a++) {
  995. /* search shouldn't be moved inside pattern */
  996. if (marker->search_min[a] > pat_min[a]) {
  997. marker->search_min[a] = pat_min[a];
  998. marker->search_max[a] = marker->search_min[a] + dim[a];
  999. }
  1000. if (marker->search_max[a] < pat_max[a]) {
  1001. marker->search_max[a] = pat_max[a];
  1002. marker->search_min[a] = marker->search_max[a] - dim[a];
  1003. }
  1004. }
  1005. }
  1006. }
  1007. MovieTrackingMarker *BKE_tracking_marker_get(MovieTrackingTrack *track, int framenr)
  1008. {
  1009. int a = track->markersnr - 1;
  1010. if (!track->markersnr)
  1011. return NULL;
  1012. /* approximate pre-first framenr marker with first marker */
  1013. if (framenr < track->markers[0].framenr)
  1014. return &track->markers[0];
  1015. if (track->last_marker < track->markersnr)
  1016. a = track->last_marker;
  1017. if (track->markers[a].framenr <= framenr) {
  1018. while (a < track->markersnr && track->markers[a].framenr <= framenr) {
  1019. if (track->markers[a].framenr == framenr) {
  1020. track->last_marker = a;
  1021. return &track->markers[a];
  1022. }
  1023. a++;
  1024. }
  1025. /* if there's no marker for exact position, use nearest marker from left side */
  1026. return &track->markers[a - 1];
  1027. }
  1028. else {
  1029. while (a >= 0 && track->markers[a].framenr >= framenr) {
  1030. if (track->markers[a].framenr == framenr) {
  1031. track->last_marker = a;
  1032. return &track->markers[a];
  1033. }
  1034. a--;
  1035. }
  1036. /* if there's no marker for exact position, use nearest marker from left side */
  1037. return &track->markers[a];
  1038. }
  1039. return NULL;
  1040. }
  1041. MovieTrackingMarker *BKE_tracking_marker_get_exact(MovieTrackingTrack *track, int framenr)
  1042. {
  1043. MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
  1044. if (marker->framenr != framenr)
  1045. return NULL;
  1046. return marker;
  1047. }
  1048. MovieTrackingMarker *BKE_tracking_marker_ensure(MovieTrackingTrack *track, int framenr)
  1049. {
  1050. MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
  1051. if (marker->framenr != framenr) {
  1052. MovieTrackingMarker marker_new;
  1053. marker_new = *marker;
  1054. marker_new.framenr = framenr;
  1055. BKE_tracking_marker_insert(track, &marker_new);
  1056. marker = BKE_tracking_marker_get(track, framenr);
  1057. }
  1058. return marker;
  1059. }
  1060. void BKE_tracking_marker_pattern_minmax(const MovieTrackingMarker *marker, float min[2], float max[2])
  1061. {
  1062. INIT_MINMAX2(min, max);
  1063. minmax_v2v2_v2(min, max, marker->pattern_corners[0]);
  1064. minmax_v2v2_v2(min, max, marker->pattern_corners[1]);
  1065. minmax_v2v2_v2(min, max, marker->pattern_corners[2]);
  1066. minmax_v2v2_v2(min, max, marker->pattern_corners[3]);
  1067. }
  1068. void BKE_tracking_marker_get_subframe_position(MovieTrackingTrack *track, float framenr, float pos[2])
  1069. {
  1070. MovieTrackingMarker *marker = BKE_tracking_marker_get(track, (int) framenr);
  1071. MovieTrackingMarker *marker_last = track->markers + (track->markersnr - 1);
  1072. if (marker != marker_last) {
  1073. MovieTrackingMarker *marker_next = marker + 1;
  1074. if (marker_next->framenr == marker->framenr + 1) {
  1075. /* currently only do subframing inside tracked ranges, do not extrapolate tracked segments
  1076. * could be changed when / if mask parent would be interpolating position in-between
  1077. * tracked segments
  1078. */
  1079. float fac = (framenr - (int) framenr) / (marker_next->framenr - marker->framenr);
  1080. interp_v2_v2v2(pos, marker->pos, marker_next->pos, fac);
  1081. }
  1082. else {
  1083. copy_v2_v2(pos, marker->pos);
  1084. }
  1085. }
  1086. else {
  1087. copy_v2_v2(pos, marker->pos);
  1088. }
  1089. /* currently track offset is always wanted to be applied here, could be made an option later */
  1090. add_v2_v2(pos, track->offset);
  1091. }
  1092. /*********************** Plane Track *************************/
  1093. /* Creates new plane track out of selected point tracks */
  1094. MovieTrackingPlaneTrack *BKE_tracking_plane_track_add(MovieTracking *tracking, ListBase *plane_tracks_base,
  1095. ListBase *tracks, int framenr)
  1096. {
  1097. MovieTrackingPlaneTrack *plane_track;
  1098. MovieTrackingPlaneMarker plane_marker;
  1099. MovieTrackingTrack *track;
  1100. float tracks_min[2], tracks_max[2];
  1101. int track_index, num_selected_tracks = 0;
  1102. (void) tracking; /* Ignored. */
  1103. /* Use bounding box of selected markers as an initial size of plane. */
  1104. INIT_MINMAX2(tracks_min, tracks_max);
  1105. for (track = tracks->first; track; track = track->next) {
  1106. if (TRACK_SELECTED(track)) {
  1107. MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr);
  1108. float pattern_min[2], pattern_max[2];
  1109. BKE_tracking_marker_pattern_minmax(marker, pattern_min, pattern_max);
  1110. add_v2_v2(pattern_min, marker->pos);
  1111. add_v2_v2(pattern_max, marker->pos);
  1112. minmax_v2v2_v2(tracks_min, tracks_max, pattern_min);
  1113. minmax_v2v2_v2(tracks_min, tracks_max, pattern_max);
  1114. num_selected_tracks++;
  1115. }
  1116. }
  1117. if (num_selected_tracks < 4) {
  1118. return NULL;
  1119. }
  1120. /* Allocate new plane track. */
  1121. plane_track = MEM_callocN(sizeof(MovieTrackingPlaneTrack), "new plane track");
  1122. /* Use some default name. */
  1123. strcpy(plane_track->name, "Plane Track");
  1124. plane_track->image_opacity = 1.0f;
  1125. /* Use selected tracks from given list as a plane. */
  1126. plane_track->point_tracks =
  1127. MEM_mallocN(sizeof(MovieTrackingTrack *) * num_selected_tracks, "new plane tracks array");
  1128. for (track = tracks->first, track_index = 0; track; track = track->next) {
  1129. if (TRACK_SELECTED(track)) {
  1130. plane_track->point_tracks[track_index] = track;
  1131. track_index++;
  1132. }
  1133. }
  1134. plane_track->point_tracksnr = num_selected_tracks;
  1135. /* Setup new plane marker and add it to the track. */
  1136. plane_marker.framenr = framenr;
  1137. plane_marker.flag = 0;
  1138. copy_v2_v2(plane_marker.corners[0], tracks_min);
  1139. copy_v2_v2(plane_marker.corners[2], tracks_max);
  1140. plane_marker.corners[1][0] = tracks_max[0];
  1141. plane_marker.corners[1][1] = tracks_min[1];
  1142. plane_marker.corners[3][0] = tracks_min[0];
  1143. plane_marker.corners[3][1] = tracks_max[1];
  1144. BKE_tracking_plane_marker_insert(plane_track, &plane_marker);
  1145. /* Put new plane track to the list, ensure it's name is unique. */
  1146. BLI_addtail(plane_tracks_base, plane_track);
  1147. BKE_tracking_plane_track_unique_name(plane_tracks_base, plane_track);
  1148. return plane_track;
  1149. }
  1150. void BKE_tracking_plane_track_unique_name(ListBase *plane_tracks_base, MovieTrackingPlaneTrack *plane_track)
  1151. {
  1152. BLI_uniquename(plane_tracks_base, plane_track, CTX_DATA_(BLT_I18NCONTEXT_ID_MOVIECLIP, "Plane Track"), '.',
  1153. offsetof(MovieTrackingPlaneTrack, name), sizeof(plane_track->name));
  1154. }
  1155. /* Free specified plane track, only frees contents of a structure
  1156. * (if track is allocated in heap, it shall be handled outside).
  1157. *
  1158. * All the pointers inside track becomes invalid after this call.
  1159. */
  1160. void BKE_tracking_plane_track_free(MovieTrackingPlaneTrack *plane_track)
  1161. {
  1162. if (plane_track->markers) {
  1163. MEM_freeN(plane_track->markers);
  1164. }
  1165. MEM_freeN(plane_track->point_tracks);
  1166. }
  1167. MovieTrackingPlaneTrack *BKE_tracking_plane_track_get_named(MovieTracking *tracking,
  1168. MovieTrackingObject *object,
  1169. const char *name)
  1170. {
  1171. ListBase *plane_tracks_base = BKE_tracking_object_get_plane_tracks(tracking, object);
  1172. MovieTrackingPlaneTrack *plane_track;
  1173. for (plane_track = plane_tracks_base->first;
  1174. plane_track;
  1175. plane_track = plane_track->next)
  1176. {
  1177. if (STREQ(plane_track->name, name)) {
  1178. return plane_track;
  1179. }
  1180. }
  1181. return NULL;
  1182. }
  1183. MovieTrackingPlaneTrack *BKE_tracking_plane_track_get_active(struct MovieTracking *tracking)
  1184. {
  1185. ListBase *plane_tracks_base;
  1186. if (tracking->act_plane_track == NULL) {
  1187. return NULL;
  1188. }
  1189. plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
  1190. /* Check that active track is in current plane tracks list */
  1191. if (BLI_findindex(plane_tracks_base, tracking->act_plane_track) != -1) {
  1192. return tracking->act_plane_track;
  1193. }
  1194. return NULL;
  1195. }
  1196. void BKE_tracking_plane_tracks_deselect_all(ListBase *plane_tracks_base)
  1197. {
  1198. MovieTrackingPlaneTrack *plane_track;
  1199. for (plane_track = plane_tracks_base->first; plane_track; plane_track = plane_track->next) {
  1200. plane_track->flag &= ~SELECT;
  1201. }
  1202. }
  1203. bool BKE_tracking_plane_track_has_point_track(MovieTrackingPlaneTrack *plane_track,
  1204. MovieTrackingTrack *track)
  1205. {
  1206. int i;
  1207. for (i = 0; i < plane_track->point_tracksnr; i++) {
  1208. if (plane_track->point_tracks[i] == track) {
  1209. return true;
  1210. }
  1211. }
  1212. return false;
  1213. }
  1214. bool BKE_tracking_plane_track_remove_point_track(MovieTrackingPlaneTrack *plane_track,
  1215. MovieTrackingTrack *track)
  1216. {
  1217. int i, track_index;
  1218. MovieTrackingTrack **new_point_tracks;
  1219. if (plane_track->point_tracksnr <= 4) {
  1220. return false;
  1221. }
  1222. new_point_tracks = MEM_mallocN(sizeof(*new_point_tracks) * (plane_track->point_tracksnr - 1),
  1223. "new point tracks array");
  1224. for (i = 0, track_index = 0; i < plane_track->point_tracksnr; i++) {
  1225. if (plane_track->point_tracks[i] != track) {
  1226. new_point_tracks[track_index++] = plane_track->point_tracks[i];
  1227. }
  1228. }
  1229. MEM_freeN(plane_track->point_tracks);
  1230. plane_track->point_tracks = new_point_tracks;
  1231. plane_track->point_tracksnr--;
  1232. return true;
  1233. }
  1234. void BKE_tracking_plane_tracks_remove_point_track(MovieTracking *tracking,
  1235. MovieTrackingTrack *track)
  1236. {
  1237. MovieTrackingPlaneTrack *plane_track, *next_plane_track;
  1238. ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
  1239. for (plane_track = plane_tracks_base->first;
  1240. plane_track;
  1241. plane_track = next_plane_track)
  1242. {
  1243. next_plane_track = plane_track->next;
  1244. if (BKE_tracking_plane_track_has_point_track(plane_track, track)) {
  1245. if (!BKE_tracking_plane_track_remove_point_track(plane_track, track)) {
  1246. /* Delete planes with less than 3 point tracks in it. */
  1247. BKE_tracking_plane_track_free(plane_track);
  1248. BLI_freelinkN(plane_tracks_base, plane_track);
  1249. }
  1250. }
  1251. }
  1252. }
  1253. void BKE_tracking_plane_track_replace_point_track(MovieTrackingPlaneTrack *plane_track,
  1254. MovieTrackingTrack *old_track,
  1255. MovieTrackingTrack *new_track)
  1256. {
  1257. int i;
  1258. for (i = 0; i < plane_track->point_tracksnr; i++) {
  1259. if (plane_track->point_tracks[i] == old_track) {
  1260. plane_track->point_tracks[i] = new_track;
  1261. break;
  1262. }
  1263. }
  1264. }
  1265. void BKE_tracking_plane_tracks_replace_point_track(MovieTracking *tracking,
  1266. MovieTrackingTrack *old_track,
  1267. MovieTrackingTrack *new_track)
  1268. {
  1269. MovieTrackingPlaneTrack *plane_track;
  1270. ListBase *plane_tracks_base = BKE_tracking_get_active_plane_tracks(tracking);
  1271. for (plane_track = plane_tracks_base->first;
  1272. plane_track;
  1273. plane_track = plane_track->next)
  1274. {
  1275. if (BKE_tracking_plane_track_has_point_track(plane_track, old_track)) {
  1276. BKE_tracking_plane_track_replace_point_track(plane_track,
  1277. old_track,
  1278. new_track);
  1279. }
  1280. }
  1281. }
  1282. /*********************** Plane Marker *************************/
  1283. MovieTrackingPlaneMarker *BKE_tracking_plane_marker_insert(MovieTrackingPlaneTrack *plane_track,
  1284. MovieTrackingPlaneMarker *plane_marker)
  1285. {
  1286. MovieTrackingPlaneMarker *old_plane_marker = NULL;
  1287. if (plane_track->markersnr)
  1288. old_plane_marker = BKE_tracking_plane_marker_get_exact(plane_track, plane_marker->framenr);
  1289. if (old_plane_marker) {
  1290. /* Simply replace settings in existing marker. */
  1291. *old_plane_marker = *plane_marker;
  1292. return old_plane_marker;
  1293. }
  1294. else {
  1295. int a = plane_track->markersnr;
  1296. /* Find position in array where to add new marker. */
  1297. /* TODO(sergey): we coud use bisect to speed things up. */
  1298. while (a--) {
  1299. if (plane_track->markers[a].framenr < plane_marker->framenr) {
  1300. break;
  1301. }
  1302. }
  1303. plane_track->markersnr++;
  1304. plane_track->markers = MEM_reallocN(plane_track->markers,
  1305. sizeof(MovieTrackingPlaneMarker) * plane_track->markersnr);
  1306. /* Shift array to "free" space for new marker. */
  1307. memmove(plane_track->markers + a + 2, plane_track->markers + a + 1,
  1308. (plane_track->markersnr - a - 2) * sizeof(MovieTrackingPlaneMarker));
  1309. /* Put new marker to an array. */
  1310. plane_track->markers[a + 1] = *plane_marker;
  1311. plane_track->last_marker = a + 1;
  1312. return &plane_track->markers[a + 1];
  1313. }
  1314. }
  1315. void BKE_tracking_plane_marker_delete(MovieTrackingPlaneTrack *plane_track, int framenr)
  1316. {
  1317. int a = 0;
  1318. while (a < plane_track->markersnr) {
  1319. if (plane_track->markers[a].framenr == framenr) {
  1320. if (plane_track->markersnr > 1) {
  1321. memmove(plane_track->markers + a, plane_track->markers + a + 1,
  1322. (plane_track->markersnr - a - 1) * sizeof(MovieTrackingPlaneMarker));
  1323. plane_track->markersnr--;
  1324. plane_track->markers = MEM_reallocN(plane_track->markers,
  1325. sizeof(MovieTrackingMarker) * plane_track->markersnr);
  1326. }
  1327. else {
  1328. MEM_freeN(plane_track->markers);
  1329. plane_track->markers = NULL;
  1330. plane_track->markersnr = 0;
  1331. }
  1332. break;
  1333. }
  1334. a++;
  1335. }
  1336. }
  1337. /* TODO(sergey): The next couple of functions are really quite the same as point marker version,
  1338. * would be nice to de-duplicate them somehow..
  1339. */
  1340. /* Get a plane marker at given frame,
  1341. * If there's no such marker, closest one from the left side will be returned.
  1342. */
  1343. MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get(MovieTrackingPlaneTrack *plane_track, int framenr)
  1344. {
  1345. int a = plane_track->markersnr - 1;
  1346. if (!plane_track->markersnr)
  1347. return NULL;
  1348. /* Approximate pre-first framenr marker with first marker. */
  1349. if (framenr < plane_track->markers[0].framenr) {
  1350. return &plane_track->markers[0];
  1351. }
  1352. if (plane_track->last_marker < plane_track->markersnr) {
  1353. a = plane_track->last_marker;
  1354. }
  1355. if (plane_track->markers[a].framenr <= framenr) {
  1356. while (a < plane_track->markersnr && plane_track->markers[a].framenr <= framenr) {
  1357. if (plane_track->markers[a].framenr == framenr) {
  1358. plane_track->last_marker = a;
  1359. return &plane_track->markers[a];
  1360. }
  1361. a++;
  1362. }
  1363. /* If there's no marker for exact position, use nearest marker from left side. */
  1364. return &plane_track->markers[a - 1];
  1365. }
  1366. else {
  1367. while (a >= 0 && plane_track->markers[a].framenr >= framenr) {
  1368. if (plane_track->markers[a].framenr == framenr) {
  1369. plane_track->last_marker = a;
  1370. return &plane_track->markers[a];
  1371. }
  1372. a--;
  1373. }
  1374. /* If there's no marker for exact position, use nearest marker from left side. */
  1375. return &plane_track->markers[a];
  1376. }
  1377. return NULL;
  1378. }
  1379. /* Get a plane marker at exact given frame, if there's no marker at the frame,
  1380. * NULL will be returned.
  1381. */
  1382. MovieTrackingPlaneMarker *BKE_tracking_plane_marker_get_exact(MovieTrackingPlaneTrack *plane_track, int framenr)
  1383. {
  1384. MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
  1385. if (plane_marker->framenr != framenr) {
  1386. return NULL;
  1387. }
  1388. return plane_marker;
  1389. }
  1390. /* Ensure there's a marker for the given frame. */
  1391. MovieTrackingPlaneMarker *BKE_tracking_plane_marker_ensure(MovieTrackingPlaneTrack *plane_track, int framenr)
  1392. {
  1393. MovieTrackingPlaneMarker *plane_marker = BKE_tracking_plane_marker_get(plane_track, framenr);
  1394. if (plane_marker->framenr != framenr) {
  1395. MovieTrackingPlaneMarker plane_marker_new;
  1396. plane_marker_new = *plane_marker;
  1397. plane_marker_new.framenr = framenr;
  1398. plane_marker = BKE_tracking_plane_marker_insert(plane_track, &plane_marker_new);
  1399. }
  1400. return plane_marker;
  1401. }
  1402. void BKE_tracking_plane_marker_get_subframe_corners(MovieTrackingPlaneTrack *plane_track,
  1403. float framenr,
  1404. float corners[4][2])
  1405. {
  1406. MovieTrackingPlaneMarker *marker = BKE_tracking_plane_marker_get(plane_track, (int)framenr);
  1407. MovieTrackingPlaneMarker *marker_last = plane_track->markers + (plane_track->markersnr - 1);
  1408. int i;
  1409. if (marker != marker_last) {
  1410. MovieTrackingPlaneMarker *marker_next = marker + 1;
  1411. if (marker_next->framenr == marker->framenr + 1) {
  1412. float fac = (framenr - (int) framenr) / (marker_next->framenr - marker->framenr);
  1413. for (i = 0; i < 4; ++i) {
  1414. interp_v2_v2v2(corners[i], marker->corners[i],
  1415. marker_next->corners[i], fac);
  1416. }
  1417. }
  1418. else {
  1419. for (i = 0; i < 4; ++i) {
  1420. copy_v2_v2(corners[i], marker->corners[i]);
  1421. }
  1422. }
  1423. }
  1424. else {
  1425. for (i = 0; i < 4; ++i) {
  1426. copy_v2_v2(corners[i], marker->corners[i]);
  1427. }
  1428. }
  1429. }
  1430. /*********************** Object *************************/
  1431. MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char *name)
  1432. {
  1433. MovieTrackingObject *object = MEM_callocN(sizeof(MovieTrackingObject), "tracking object");
  1434. if (tracking->tot_object == 0) {
  1435. /* first object is always camera */
  1436. BLI_strncpy(object->name, "Camera", sizeof(object->name));
  1437. object->flag |= TRACKING_OBJECT_CAMERA;
  1438. }
  1439. else {
  1440. BLI_strncpy(object->name, name, sizeof(object->name));
  1441. }
  1442. BLI_addtail(&tracking->objects, object);
  1443. tracking->tot_object++;
  1444. tracking->objectnr = BLI_listbase_count(&tracking->objects) - 1;
  1445. object->scale = 1.0f;
  1446. object->keyframe1 = 1;
  1447. object->keyframe2 = 30;
  1448. BKE_tracking_object_unique_name(tracking, object);
  1449. BKE_tracking_dopesheet_tag_update(tracking);
  1450. return object;
  1451. }
  1452. bool BKE_tracking_object_delete(MovieTracking *tracking, MovieTrackingObject *object)
  1453. {
  1454. MovieTrackingTrack *track;
  1455. int index = BLI_findindex(&tracking->objects, object);
  1456. if (index == -1)
  1457. return false;
  1458. if (object->flag & TRACKING_OBJECT_CAMERA) {
  1459. /* object used for camera solving can't be deleted */
  1460. return false;
  1461. }
  1462. track = object->tracks.first;
  1463. while (track) {
  1464. if (track == tracking->act_track)
  1465. tracking->act_track = NULL;
  1466. track = track->next;
  1467. }
  1468. tracking_object_free(object);
  1469. BLI_freelinkN(&tracking->objects, object);
  1470. tracking->tot_object--;
  1471. if (index != 0)
  1472. tracking->objectnr = index - 1;
  1473. else
  1474. tracking->objectnr = 0;
  1475. BKE_tracking_dopesheet_tag_update(tracking);
  1476. return true;
  1477. }
  1478. void BKE_tracking_object_unique_name(MovieTracking *tracking, MovieTrackingObject *object)
  1479. {
  1480. BLI_uniquename(&tracking->objects, object, DATA_("Object"), '.',
  1481. offsetof(MovieTrackingObject, name), sizeof(object->name));
  1482. }
  1483. MovieTrackingObject *BKE_tracking_object_get_named(MovieTracking *tracking, const char *name)
  1484. {
  1485. MovieTrackingObject *object = tracking->objects.first;
  1486. while (object) {
  1487. if (STREQ(object->name, name))
  1488. return object;
  1489. object = object->next;
  1490. }
  1491. return NULL;
  1492. }
  1493. MovieTrackingObject *BKE_tracking_object_get_active(MovieTracking *tracking)
  1494. {
  1495. return BLI_findlink(&tracking->objects, tracking->objectnr);
  1496. }
  1497. MovieTrackingObject *BKE_tracking_object_get_camera(MovieTracking *tracking)
  1498. {
  1499. MovieTrackingObject *object = tracking->objects.first;
  1500. while (object) {
  1501. if (object->flag & TRACKING_OBJECT_CAMERA)
  1502. return object;
  1503. object = object->next;
  1504. }
  1505. return NULL;
  1506. }
  1507. ListBase *BKE_tracking_object_get_tracks(MovieTracking *tracking, MovieTrackingObject *object)
  1508. {
  1509. if (object->flag & TRACKING_OBJECT_CAMERA) {
  1510. return &tracking->tracks;
  1511. }
  1512. return &object->tracks;
  1513. }
  1514. ListBase *BKE_tracking_object_get_plane_tracks(MovieTracking *tracking, MovieTrackingObject *object)
  1515. {
  1516. if (object->flag & TRACKING_OBJECT_CAMERA) {
  1517. return &tracking->plane_tracks;
  1518. }
  1519. return &object->plane_tracks;
  1520. }
  1521. MovieTrackingReconstruction *BKE_tracking_object_get_reconstruction(MovieTracking *tracking,
  1522. MovieTrackingObject *object)
  1523. {
  1524. if (object->flag & TRACKING_OBJECT_CAMERA) {
  1525. return &tracking->reconstruction;
  1526. }
  1527. return &object->reconstruction;
  1528. }
  1529. /*********************** Camera *************************/
  1530. static int reconstructed_camera_index_get(MovieTrackingReconstruction *reconstruction, int framenr, bool nearest)
  1531. {
  1532. MovieReconstructedCamera *cameras = reconstruction->cameras;
  1533. int a = 0, d = 1;
  1534. if (!reconstruction->camnr)
  1535. return -1;
  1536. if (framenr < cameras[0].framenr) {
  1537. if (nearest)
  1538. return 0;
  1539. else
  1540. return -1;
  1541. }
  1542. if (framenr > cameras[reconstruction->camnr - 1].framenr) {
  1543. if (nearest)
  1544. return reconstruction->camnr - 1;
  1545. else
  1546. return -1;
  1547. }
  1548. if (reconstruction->last_camera < reconstruction->camnr)
  1549. a = reconstruction->last_camera;
  1550. if (cameras[a].framenr >= framenr)
  1551. d = -1;
  1552. while (a >= 0 && a < reconstruction->camnr) {
  1553. int cfra = cameras[a].framenr;
  1554. /* check if needed framenr was "skipped" -- no data for requested frame */
  1555. if (d > 0 && cfra > framenr) {
  1556. /* interpolate with previous position */
  1557. if (nearest)
  1558. return a - 1;
  1559. else
  1560. break;
  1561. }
  1562. if (d < 0 && cfra < framenr) {
  1563. /* interpolate with next position */
  1564. if (nearest)
  1565. return a;
  1566. else
  1567. break;
  1568. }
  1569. if (cfra == framenr) {
  1570. reconstruction->last_camera = a;
  1571. return a;
  1572. }
  1573. a += d;
  1574. }
  1575. return -1;
  1576. }
  1577. static void reconstructed_camera_scale_set(MovieTrackingObject *object, float mat[4][4])
  1578. {
  1579. if ((object->flag & TRACKING_OBJECT_CAMERA) == 0) {
  1580. float smat[4][4];
  1581. scale_m4_fl(smat, 1.0f / object->scale);
  1582. mul_m4_m4m4(mat, mat, smat);
  1583. }
  1584. }
  1585. /* converts principal offset from center to offset of blender's camera */
  1586. void BKE_tracking_camera_shift_get(MovieTracking *tracking, int winx, int winy, float *shiftx, float *shifty)
  1587. {
  1588. /* indeed in both of cases it should be winx -- it's just how camera shift works for blender's camera */
  1589. *shiftx = (0.5f * winx - tracking->camera.principal[0]) / winx;
  1590. *shifty = (0.5f * winy - tracking->camera.principal[1]) / winx;
  1591. }
  1592. void BKE_tracking_camera_to_blender(MovieTracking *tracking, Scene *scene, Camera *camera, int width, int height)
  1593. {
  1594. float focal = tracking->camera.focal;
  1595. camera->sensor_x = tracking->camera.sensor_width;
  1596. camera->sensor_fit = CAMERA_SENSOR_FIT_AUTO;
  1597. camera->lens = focal * camera->sensor_x / width;
  1598. scene->r.xsch = width * tracking->camera.pixel_aspect;
  1599. scene->r.ysch = height;
  1600. scene->r.xasp = 1.0f;
  1601. scene->r.yasp = 1.0f;
  1602. BKE_tracking_camera_shift_get(tracking, width, height, &camera->shiftx, &camera->shifty);
  1603. }
  1604. MovieReconstructedCamera *BKE_tracking_camera_get_reconstructed(MovieTracking *tracking,
  1605. MovieTrackingObject *object, int framenr)
  1606. {
  1607. MovieTrackingReconstruction *reconstruction;
  1608. int a;
  1609. reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
  1610. a = reconstructed_camera_index_get(reconstruction, framenr, false);
  1611. if (a == -1)
  1612. return NULL;
  1613. return &reconstruction->cameras[a];
  1614. }
  1615. void BKE_tracking_camera_get_reconstructed_interpolate(MovieTracking *tracking, MovieTrackingObject *object,
  1616. float framenr, float mat[4][4])
  1617. {
  1618. MovieTrackingReconstruction *reconstruction;
  1619. MovieReconstructedCamera *cameras;
  1620. int a;
  1621. reconstruction = BKE_tracking_object_get_reconstruction(tracking, object);
  1622. cameras = reconstruction->cameras;
  1623. a = reconstructed_camera_index_get(reconstruction, (int)framenr, true);
  1624. if (a == -1) {
  1625. unit_m4(mat);
  1626. return;
  1627. }
  1628. if (cameras[a].framenr != framenr && a < reconstruction->camnr - 1) {
  1629. float t = ((float)framenr - cameras[a].framenr) / (cameras[a + 1].framenr - cameras[a].framenr);
  1630. blend_m4_m4m4(mat, cameras[a].mat, cameras[a + 1].mat, t);
  1631. }
  1632. else {
  1633. copy_m4_m4(mat, cameras[a].mat);
  1634. }
  1635. reconstructed_camera_scale_set(object, mat);
  1636. }
  1637. /*********************** Distortion/Undistortion *************************/
  1638. MovieDistortion *BKE_tracking_distortion_new(MovieTracking *tracking,
  1639. int calibration_width, int calibration_height)
  1640. {
  1641. MovieDistortion *distortion;
  1642. libmv_CameraIntrinsicsOptions camera_intrinsics_options;
  1643. tracking_cameraIntrinscisOptionsFromTracking(tracking,
  1644. calibration_width,
  1645. calibration_height,
  1646. &camera_intrinsics_options);
  1647. distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
  1648. distortion->intrinsics = libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
  1649. const MovieTrackingCamera *camera = &tracking->camera;
  1650. copy_v2_v2(distortion->principal, camera->principal);
  1651. distortion->pixel_aspect = camera->pixel_aspect;
  1652. distortion->focal = camera->focal;
  1653. return distortion;
  1654. }
  1655. void BKE_tracking_distortion_update(MovieDistortion *distortion, MovieTracking *tracking,
  1656. int calibration_width, int calibration_height)
  1657. {
  1658. libmv_CameraIntrinsicsOptions camera_intrinsics_options;
  1659. tracking_cameraIntrinscisOptionsFromTracking(tracking,
  1660. calibration_width,
  1661. calibration_height,
  1662. &camera_intrinsics_options);
  1663. const MovieTrackingCamera *camera = &tracking->camera;
  1664. copy_v2_v2(distortion->principal, camera->principal);
  1665. distortion->pixel_aspect = camera->pixel_aspect;
  1666. distortion->focal = camera->focal;
  1667. libmv_cameraIntrinsicsUpdate(&camera_intrinsics_options, distortion->intrinsics);
  1668. }
  1669. void BKE_tracking_distortion_set_threads(MovieDistortion *distortion, int threads)
  1670. {
  1671. libmv_cameraIntrinsicsSetThreads(distortion->intrinsics, threads);
  1672. }
  1673. MovieDistortion *BKE_tracking_distortion_copy(MovieDistortion *distortion)
  1674. {
  1675. MovieDistortion *new_distortion;
  1676. new_distortion = MEM_callocN(sizeof(MovieDistortion), "BKE_tracking_distortion_create");
  1677. *new_distortion = *distortion;
  1678. new_distortion->intrinsics = libmv_cameraIntrinsicsCopy(distortion->intrinsics);
  1679. return new_distortion;
  1680. }
  1681. ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking *tracking, ImBuf *ibuf,
  1682. int calibration_width, int calibration_height, float overscan, bool undistort)
  1683. {
  1684. ImBuf *resibuf;
  1685. BKE_tracking_distortion_update(distortion, tracking, calibration_width, calibration_height);
  1686. resibuf = IMB_dupImBuf(ibuf);
  1687. if (ibuf->rect_float) {
  1688. if (undistort) {
  1689. libmv_cameraIntrinsicsUndistortFloat(distortion->intrinsics,
  1690. ibuf->rect_float,
  1691. ibuf->x, ibuf->y,
  1692. overscan,
  1693. ibuf->channels,
  1694. resibuf->rect_float);
  1695. }
  1696. else {
  1697. libmv_cameraIntrinsicsDistortFloat(distortion->intrinsics,
  1698. ibuf->rect_float,
  1699. ibuf->x, ibuf->y,
  1700. overscan,
  1701. ibuf->channels,
  1702. resibuf->rect_float);
  1703. }
  1704. if (ibuf->rect)
  1705. imb_freerectImBuf(ibuf);
  1706. }
  1707. else {
  1708. if (undistort) {
  1709. libmv_cameraIntrinsicsUndistortByte(distortion->intrinsics,
  1710. (unsigned char *)ibuf->rect,
  1711. ibuf->x, ibuf->y,
  1712. overscan,
  1713. ibuf->channels,
  1714. (unsigned char *)resibuf->rect);
  1715. }
  1716. else {
  1717. libmv_cameraIntrinsicsDistortByte(distortion->intrinsics,
  1718. (unsigned char *)ibuf->rect,
  1719. ibuf->x, ibuf->y,
  1720. overscan,
  1721. ibuf->channels,
  1722. (unsigned char *)resibuf->rect);
  1723. }
  1724. }
  1725. return resibuf;
  1726. }
  1727. void BKE_tracking_distortion_distort_v2(MovieDistortion *distortion,
  1728. const float co[2],
  1729. float r_co[2])
  1730. {
  1731. const float aspy = 1.0f / distortion->pixel_aspect;
  1732. /* Normalize coords. */
  1733. float inv_focal = 1.0f / distortion->focal;
  1734. double x = (co[0] - distortion->principal[0]) * inv_focal,
  1735. y = (co[1] - distortion->principal[1] * aspy) * inv_focal;
  1736. libmv_cameraIntrinsicsApply(distortion->intrinsics, x, y, &x, &y);
  1737. /* Result is in image coords already. */
  1738. r_co[0] = x;
  1739. r_co[1] = y;
  1740. }
  1741. void BKE_tracking_distortion_undistort_v2(MovieDistortion *distortion,
  1742. const float co[2],
  1743. float r_co[2])
  1744. {
  1745. double x = co[0], y = co[1];
  1746. libmv_cameraIntrinsicsInvert(distortion->intrinsics, x, y, &x, &y);
  1747. const float aspy = 1.0f / distortion->pixel_aspect;
  1748. r_co[0] = (float)x * distortion->focal + distortion->principal[0];
  1749. r_co[1] = (float)y * distortion->focal + distortion->principal[1] * aspy;
  1750. }
  1751. void BKE_tracking_distortion_free(MovieDistortion *distortion)
  1752. {
  1753. libmv_cameraIntrinsicsDestroy(distortion->intrinsics);
  1754. MEM_freeN(distortion);
  1755. }
  1756. void BKE_tracking_distort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
  1757. {
  1758. const MovieTrackingCamera *camera = &tracking->camera;
  1759. const float aspy = 1.0f / tracking->camera.pixel_aspect;
  1760. libmv_CameraIntrinsicsOptions camera_intrinsics_options;
  1761. tracking_cameraIntrinscisOptionsFromTracking(tracking,
  1762. 0, 0,
  1763. &camera_intrinsics_options);
  1764. libmv_CameraIntrinsics *intrinsics =
  1765. libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
  1766. /* Normalize coordinates. */
  1767. double x = (co[0] - camera->principal[0]) / camera->focal,
  1768. y = (co[1] - camera->principal[1] * aspy) / camera->focal;
  1769. libmv_cameraIntrinsicsApply(intrinsics, x, y, &x, &y);
  1770. libmv_cameraIntrinsicsDestroy(intrinsics);
  1771. /* Result is in image coords already. */
  1772. r_co[0] = x;
  1773. r_co[1] = y;
  1774. }
  1775. void BKE_tracking_undistort_v2(MovieTracking *tracking, const float co[2], float r_co[2])
  1776. {
  1777. const MovieTrackingCamera *camera = &tracking->camera;
  1778. const float aspy = 1.0f / tracking->camera.pixel_aspect;
  1779. libmv_CameraIntrinsicsOptions camera_intrinsics_options;
  1780. tracking_cameraIntrinscisOptionsFromTracking(tracking,
  1781. 0, 0,
  1782. &camera_intrinsics_options);
  1783. libmv_CameraIntrinsics *intrinsics =
  1784. libmv_cameraIntrinsicsNew(&camera_intrinsics_options);
  1785. double x = co[0], y = co[1];
  1786. libmv_cameraIntrinsicsInvert(intrinsics, x, y, &x, &y);
  1787. libmv_cameraIntrinsicsDestroy(intrinsics);
  1788. r_co[0] = (float)x * camera->focal + camera->principal[0];
  1789. r_co[1] = (float)y * camera->focal + camera->principal[1] * aspy;
  1790. }
  1791. ImBuf *BKE_tracking_undistort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width,
  1792. int calibration_height, float overscan)
  1793. {
  1794. MovieTrackingCamera *camera = &tracking->camera;
  1795. if (camera->intrinsics == NULL) {
  1796. camera->intrinsics = BKE_tracking_distortion_new(tracking, calibration_width, calibration_height);
  1797. }
  1798. return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
  1799. calibration_height, overscan, true);
  1800. }
  1801. ImBuf *BKE_tracking_distort_frame(MovieTracking *tracking, ImBuf *ibuf, int calibration_width,
  1802. int calibration_height, float overscan)
  1803. {
  1804. MovieTrackingCamera *camera = &tracking->camera;
  1805. if (camera->intrinsics == NULL) {
  1806. camera->intrinsics = BKE_tracking_distortion_new(tracking, calibration_width, calibration_height);
  1807. }
  1808. return BKE_tracking_distortion_exec(camera->intrinsics, tracking, ibuf, calibration_width,
  1809. calibration_height, overscan, false);
  1810. }
  1811. void BKE_tracking_max_distortion_delta_across_bound(MovieTracking *tracking, rcti *rect,
  1812. bool undistort, float delta[2])
  1813. {
  1814. int a;
  1815. float pos[2], warped_pos[2];
  1816. const int coord_delta = 5;
  1817. void (*apply_distortion) (MovieTracking *tracking,
  1818. const float pos[2], float out[2]);
  1819. if (undistort) {
  1820. apply_distortion = BKE_tracking_undistort_v2;
  1821. }
  1822. else {
  1823. apply_distortion = BKE_tracking_distort_v2;
  1824. }
  1825. delta[0] = delta[1] = -FLT_MAX;
  1826. for (a = rect->xmin; a <= rect->xmax + coord_delta; a += coord_delta) {
  1827. if (a > rect->xmax)
  1828. a = rect->xmax;
  1829. /* bottom edge */
  1830. pos[0] = a;
  1831. pos[1] = rect->ymin;
  1832. apply_distortion(tracking, pos, warped_pos);
  1833. delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
  1834. delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
  1835. /* top edge */
  1836. pos[0] = a;
  1837. pos[1] = rect->ymax;
  1838. apply_distortion(tracking, pos, warped_pos);
  1839. delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
  1840. delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
  1841. if (a >= rect->xmax)
  1842. break;
  1843. }
  1844. for (a = rect->ymin; a <= rect->ymax + coord_delta; a += coord_delta) {
  1845. if (a > rect->ymax)
  1846. a = rect->ymax;
  1847. /* left edge */
  1848. pos[0] = rect->xmin;
  1849. pos[1] = a;
  1850. apply_distortion(tracking, pos, warped_pos);
  1851. delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
  1852. delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
  1853. /* right edge */
  1854. pos[0] = rect->xmax;
  1855. pos[1] = a;
  1856. apply_distortion(tracking, pos, warped_pos);
  1857. delta[0] = max_ff(delta[0], fabsf(pos[0] - warped_pos[0]));
  1858. delta[1] = max_ff(delta[1], fabsf(pos[1] - warped_pos[1]));
  1859. if (a >= rect->ymax)
  1860. break;
  1861. }
  1862. }
  1863. /*********************** Image sampling *************************/
  1864. static void disable_imbuf_channels(ImBuf *ibuf, MovieTrackingTrack *track, bool grayscale)
  1865. {
  1866. BKE_tracking_disable_channels(ibuf, track->flag & TRACK_DISABLE_RED,
  1867. track->flag & TRACK_DISABLE_GREEN,
  1868. track->flag & TRACK_DISABLE_BLUE, grayscale);
  1869. }
  1870. ImBuf *BKE_tracking_sample_pattern(int frame_width, int frame_height, ImBuf *search_ibuf,
  1871. MovieTrackingTrack *track, MovieTrackingMarker *marker,
  1872. bool from_anchor, bool use_mask, int num_samples_x, int num_samples_y,
  1873. float pos[2])
  1874. {
  1875. ImBuf *pattern_ibuf;
  1876. double src_pixel_x[5], src_pixel_y[5];
  1877. double warped_position_x, warped_position_y;
  1878. float *mask = NULL;
  1879. if (num_samples_x <= 0 || num_samples_y <= 0)
  1880. return NULL;
  1881. pattern_ibuf = IMB_allocImBuf(num_samples_x, num_samples_y,
  1882. 32,
  1883. search_ibuf->rect_float ? IB_rectfloat : IB_rect);
  1884. tracking_get_marker_coords_for_tracking(frame_width, frame_height, marker, src_pixel_x, src_pixel_y);
  1885. /* from_anchor means search buffer was obtained for an anchored position,
  1886. * which means applying track offset rounded to pixel space (we could not
  1887. * store search buffer with sub-pixel precision)
  1888. *
  1889. * in this case we need to alter coordinates a bit, to compensate rounded
  1890. * fractional part of offset
  1891. */
  1892. if (from_anchor) {
  1893. int a;
  1894. for (a = 0; a < 5; a++) {
  1895. src_pixel_x[a] += (double) ((track->offset[0] * frame_width) - ((int) (track->offset[0] * frame_width)));
  1896. src_pixel_y[a] += (double) ((track->offset[1] * frame_height) - ((int) (track->offset[1] * frame_height)));
  1897. /* when offset is negative, rounding happens in opposite direction */
  1898. if (track->offset[0] < 0.0f)
  1899. src_pixel_x[a] += 1.0;
  1900. if (track->offset[1] < 0.0f)
  1901. src_pixel_y[a] += 1.0;
  1902. }
  1903. }
  1904. if (use_mask) {
  1905. mask = BKE_tracking_track_get_mask(frame_width, frame_height, track, marker);
  1906. }
  1907. if (search_ibuf->rect_float) {
  1908. libmv_samplePlanarPatchFloat(search_ibuf->rect_float,
  1909. search_ibuf->x, search_ibuf->y, 4,
  1910. src_pixel_x, src_pixel_y,
  1911. num_samples_x, num_samples_y,
  1912. mask,
  1913. pattern_ibuf->rect_float,
  1914. &warped_position_x,
  1915. &warped_position_y);
  1916. }
  1917. else {
  1918. libmv_samplePlanarPatchByte((unsigned char *) search_ibuf->rect,
  1919. search_ibuf->x, search_ibuf->y, 4,
  1920. src_pixel_x, src_pixel_y,
  1921. num_samples_x, num_samples_y,
  1922. mask,
  1923. (unsigned char *) pattern_ibuf->rect,
  1924. &warped_position_x,
  1925. &warped_position_y);
  1926. }
  1927. if (pos) {
  1928. pos[0] = warped_position_x;
  1929. pos[1] = warped_position_y;
  1930. }
  1931. if (mask) {
  1932. MEM_freeN(mask);
  1933. }
  1934. return pattern_ibuf;
  1935. }
  1936. ImBuf *BKE_tracking_get_pattern_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
  1937. bool anchored, bool disable_channels)
  1938. {
  1939. ImBuf *pattern_ibuf, *search_ibuf;
  1940. float pat_min[2], pat_max[2];
  1941. int num_samples_x, num_samples_y;
  1942. BKE_tracking_marker_pattern_minmax(marker, pat_min, pat_max);
  1943. num_samples_x = (pat_max[0] - pat_min[0]) * ibuf->x;
  1944. num_samples_y = (pat_max[1] - pat_min[1]) * ibuf->y;
  1945. search_ibuf = BKE_tracking_get_search_imbuf(ibuf, track, marker, anchored, disable_channels);
  1946. if (search_ibuf) {
  1947. pattern_ibuf = BKE_tracking_sample_pattern(ibuf->x, ibuf->y, search_ibuf, track, marker,
  1948. anchored, false, num_samples_x, num_samples_y, NULL);
  1949. IMB_freeImBuf(search_ibuf);
  1950. }
  1951. else {
  1952. pattern_ibuf = NULL;
  1953. }
  1954. return pattern_ibuf;
  1955. }
  1956. ImBuf *BKE_tracking_get_search_imbuf(ImBuf *ibuf, MovieTrackingTrack *track, MovieTrackingMarker *marker,
  1957. bool anchored, bool disable_channels)
  1958. {
  1959. ImBuf *searchibuf;
  1960. int x, y, w, h;
  1961. float search_origin[2];
  1962. tracking_get_search_origin_frame_pixel(ibuf->x, ibuf->y, marker, search_origin);
  1963. x = search_origin[0];
  1964. y = search_origin[1];
  1965. if (anchored) {
  1966. x += track->offset[0] * ibuf->x;
  1967. y += track->offset[1] * ibuf->y;
  1968. }
  1969. w = (marker->search_max[0] - marker->search_min[0]) * ibuf->x;
  1970. h = (marker->search_max[1] - marker->search_min[1]) * ibuf->y;
  1971. if (w <= 0 || h <= 0)
  1972. return NULL;
  1973. searchibuf = IMB_allocImBuf(w, h, 32, ibuf->rect_float ? IB_rectfloat : IB_rect);
  1974. IMB_rectcpy(searchibuf, ibuf, 0, 0, x, y, w, h);
  1975. if (disable_channels) {
  1976. if ((track->flag & TRACK_PREVIEW_GRAYSCALE) ||
  1977. (track->flag & TRACK_DISABLE_RED) ||
  1978. (track->flag & TRACK_DISABLE_GREEN) ||
  1979. (track->flag & TRACK_DISABLE_BLUE))
  1980. {
  1981. disable_imbuf_channels(searchibuf, track, true);
  1982. }
  1983. }
  1984. return searchibuf;
  1985. }
  1986. /* zap channels from the imbuf that are disabled by the user. this can lead to
  1987. * better tracks sometimes. however, instead of simply zeroing the channels
  1988. * out, do a partial grayscale conversion so the display is better.
  1989. */
  1990. void BKE_tracking_disable_channels(ImBuf *ibuf, bool disable_red, bool disable_green, bool disable_blue,
  1991. bool grayscale)
  1992. {
  1993. int x, y;
  1994. float scale;
  1995. if (!disable_red && !disable_green && !disable_blue && !grayscale)
  1996. return;
  1997. /* if only some components are selected, it's important to rescale the result
  1998. * appropriately so that e.g. if only blue is selected, it's not zeroed out.
  1999. */
  2000. scale = (disable_red ? 0.0f : 0.2126f) +
  2001. (disable_green ? 0.0f : 0.7152f) +
  2002. (disable_blue ? 0.0f : 0.0722f);
  2003. for (y = 0; y < ibuf->y; y++) {
  2004. for (x = 0; x < ibuf->x; x++) {
  2005. int pixel = ibuf->x * y + x;
  2006. if (ibuf->rect_float) {
  2007. float *rrgbf = ibuf->rect_float + pixel * 4;
  2008. float r = disable_red ? 0.0f : rrgbf[0];
  2009. float g = disable_green ? 0.0f : rrgbf[1];
  2010. float b = disable_blue ? 0.0f : rrgbf[2];
  2011. if (grayscale) {
  2012. float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
  2013. rrgbf[0] = rrgbf[1] = rrgbf[2] = gray;
  2014. }
  2015. else {
  2016. rrgbf[0] = r;
  2017. rrgbf[1] = g;
  2018. rrgbf[2] = b;
  2019. }
  2020. }
  2021. else {
  2022. char *rrgb = (char *)ibuf->rect + pixel * 4;
  2023. char r = disable_red ? 0 : rrgb[0];
  2024. char g = disable_green ? 0 : rrgb[1];
  2025. char b = disable_blue ? 0 : rrgb[2];
  2026. if (grayscale) {
  2027. float gray = (0.2126f * r + 0.7152f * g + 0.0722f * b) / scale;
  2028. rrgb[0] = rrgb[1] = rrgb[2] = gray;
  2029. }
  2030. else {
  2031. rrgb[0] = r;
  2032. rrgb[1] = g;
  2033. rrgb[2] = b;
  2034. }
  2035. }
  2036. }
  2037. }
  2038. if (ibuf->rect_float)
  2039. ibuf->userflags |= IB_RECT_INVALID;
  2040. }
  2041. /*********************** Dopesheet functions *************************/
  2042. /* ** Channels sort comparators ** */
  2043. static int channels_alpha_sort(const void *a, const void *b)
  2044. {
  2045. const MovieTrackingDopesheetChannel *channel_a = a;
  2046. const MovieTrackingDopesheetChannel *channel_b = b;
  2047. if (BLI_strcasecmp(channel_a->track->name, channel_b->track->name) > 0)
  2048. return 1;
  2049. else
  2050. return 0;
  2051. }
  2052. static int channels_total_track_sort(const void *a, const void *b)
  2053. {
  2054. const MovieTrackingDopesheetChannel *channel_a = a;
  2055. const MovieTrackingDopesheetChannel *channel_b = b;
  2056. if (channel_a->total_frames > channel_b->total_frames)
  2057. return 1;
  2058. else
  2059. return 0;
  2060. }
  2061. static int channels_longest_segment_sort(const void *a, const void *b)
  2062. {
  2063. const MovieTrackingDopesheetChannel *channel_a = a;
  2064. const MovieTrackingDopesheetChannel *channel_b = b;
  2065. if (channel_a->max_segment > channel_b->max_segment)
  2066. return 1;
  2067. else
  2068. return 0;
  2069. }
  2070. static int channels_average_error_sort(const void *a, const void *b)
  2071. {
  2072. const MovieTrackingDopesheetChannel *channel_a = a;
  2073. const MovieTrackingDopesheetChannel *channel_b = b;
  2074. if (channel_a->track->error > channel_b->track->error)
  2075. return 1;
  2076. else
  2077. return 0;
  2078. }
  2079. static int channels_alpha_inverse_sort(const void *a, const void *b)
  2080. {
  2081. if (channels_alpha_sort(a, b))
  2082. return 0;
  2083. else
  2084. return 1;
  2085. }
  2086. static int channels_total_track_inverse_sort(const void *a, const void *b)
  2087. {
  2088. if (channels_total_track_sort(a, b))
  2089. return 0;
  2090. else
  2091. return 1;
  2092. }
  2093. static int channels_longest_segment_inverse_sort(const void *a, const void *b)
  2094. {
  2095. if (channels_longest_segment_sort(a, b))
  2096. return 0;
  2097. else
  2098. return 1;
  2099. }
  2100. static int channels_average_error_inverse_sort(const void *a, const void *b)
  2101. {
  2102. const MovieTrackingDopesheetChannel *channel_a = a;
  2103. const MovieTrackingDopesheetChannel *channel_b = b;
  2104. if (channel_a->track->error < channel_b->track->error)
  2105. return 1;
  2106. else
  2107. return 0;
  2108. }
  2109. /* Calculate frames segments at which track is tracked continuously. */
  2110. static void tracking_dopesheet_channels_segments_calc(MovieTrackingDopesheetChannel *channel)
  2111. {
  2112. MovieTrackingTrack *track = channel->track;
  2113. int i, segment;
  2114. channel->tot_segment = 0;
  2115. channel->max_segment = 0;
  2116. channel->total_frames = 0;
  2117. /* TODO(sergey): looks a bit code-duplicated, need to look into
  2118. * logic de-duplication here.
  2119. */
  2120. /* count */
  2121. i = 0;
  2122. while (i < track->markersnr) {
  2123. MovieTrackingMarker *marker = &track->markers[i];
  2124. if ((marker->flag & MARKER_DISABLED) == 0) {
  2125. int prev_fra = marker->framenr, len = 0;
  2126. i++;
  2127. while (i < track->markersnr) {
  2128. marker = &track->markers[i];
  2129. if (marker->framenr != prev_fra + 1)
  2130. break;
  2131. if (marker->flag & MARKER_DISABLED)
  2132. break;
  2133. prev_fra = marker->framenr;
  2134. len++;
  2135. i++;
  2136. }
  2137. channel->tot_segment++;
  2138. }
  2139. i++;
  2140. }
  2141. if (!channel->tot_segment)
  2142. return;
  2143. channel->segments = MEM_callocN(2 * sizeof(int) * channel->tot_segment, "tracking channel segments");
  2144. /* create segments */
  2145. i = 0;
  2146. segment = 0;
  2147. while (i < track->markersnr) {
  2148. MovieTrackingMarker *marker = &track->markers[i];
  2149. if ((marker->flag & MARKER_DISABLED) == 0) {
  2150. MovieTrackingMarker *start_marker = marker;
  2151. int prev_fra = marker->framenr, len = 0;
  2152. i++;
  2153. while (i < track->markersnr) {
  2154. marker = &track->markers[i];
  2155. if (marker->framenr != prev_fra + 1)
  2156. break;
  2157. if (marker->flag & MARKER_DISABLED)
  2158. break;
  2159. prev_fra = marker->framenr;
  2160. channel->total_frames++;
  2161. len++;
  2162. i++;
  2163. }
  2164. channel->segments[2 * segment] = start_marker->framenr;
  2165. channel->segments[2 * segment + 1] = start_marker->framenr + len;
  2166. channel->max_segment = max_ii(channel->max_segment, len);
  2167. segment++;
  2168. }
  2169. i++;
  2170. }
  2171. }
  2172. /* Create channels for tracks and calculate tracked segments for them. */
  2173. static void tracking_dopesheet_channels_calc(MovieTracking *tracking)
  2174. {
  2175. MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
  2176. MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
  2177. MovieTrackingTrack *track;
  2178. MovieTrackingReconstruction *reconstruction =
  2179. BKE_tracking_object_get_reconstruction(tracking, object);
  2180. ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
  2181. bool sel_only = (dopesheet->flag & TRACKING_DOPE_SELECTED_ONLY) != 0;
  2182. bool show_hidden = (dopesheet->flag & TRACKING_DOPE_SHOW_HIDDEN) != 0;
  2183. for (track = tracksbase->first; track; track = track->next) {
  2184. MovieTrackingDopesheetChannel *channel;
  2185. if (!show_hidden && (track->flag & TRACK_HIDDEN) != 0)
  2186. continue;
  2187. if (sel_only && !TRACK_SELECTED(track))
  2188. continue;
  2189. channel = MEM_callocN(sizeof(MovieTrackingDopesheetChannel), "tracking dopesheet channel");
  2190. channel->track = track;
  2191. if (reconstruction->flag & TRACKING_RECONSTRUCTED) {
  2192. BLI_snprintf(channel->name, sizeof(channel->name), "%s (%.4f)", track->name, track->error);
  2193. }
  2194. else {
  2195. BLI_strncpy(channel->name, track->name, sizeof(channel->name));
  2196. }
  2197. tracking_dopesheet_channels_segments_calc(channel);
  2198. BLI_addtail(&dopesheet->channels, channel);
  2199. dopesheet->tot_channel++;
  2200. }
  2201. }
  2202. /* Sot dopesheet channels using given method (name, average error, total coverage,
  2203. * longest tracked segment) and could also inverse the list if it's enabled.
  2204. */
  2205. static void tracking_dopesheet_channels_sort(MovieTracking *tracking, int sort_method, bool inverse)
  2206. {
  2207. MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
  2208. if (inverse) {
  2209. if (sort_method == TRACKING_DOPE_SORT_NAME) {
  2210. BLI_listbase_sort(&dopesheet->channels, channels_alpha_inverse_sort);
  2211. }
  2212. else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
  2213. BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_inverse_sort);
  2214. }
  2215. else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
  2216. BLI_listbase_sort(&dopesheet->channels, channels_total_track_inverse_sort);
  2217. }
  2218. else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
  2219. BLI_listbase_sort(&dopesheet->channels, channels_average_error_inverse_sort);
  2220. }
  2221. }
  2222. else {
  2223. if (sort_method == TRACKING_DOPE_SORT_NAME) {
  2224. BLI_listbase_sort(&dopesheet->channels, channels_alpha_sort);
  2225. }
  2226. else if (sort_method == TRACKING_DOPE_SORT_LONGEST) {
  2227. BLI_listbase_sort(&dopesheet->channels, channels_longest_segment_sort);
  2228. }
  2229. else if (sort_method == TRACKING_DOPE_SORT_TOTAL) {
  2230. BLI_listbase_sort(&dopesheet->channels, channels_total_track_sort);
  2231. }
  2232. else if (sort_method == TRACKING_DOPE_SORT_AVERAGE_ERROR) {
  2233. BLI_listbase_sort(&dopesheet->channels, channels_average_error_sort);
  2234. }
  2235. }
  2236. }
  2237. static int coverage_from_count(int count)
  2238. {
  2239. /* Values are actually arbitrary here, probably need to be tweaked. */
  2240. if (count < 8)
  2241. return TRACKING_COVERAGE_BAD;
  2242. else if (count < 16)
  2243. return TRACKING_COVERAGE_ACCEPTABLE;
  2244. return TRACKING_COVERAGE_OK;
  2245. }
  2246. /* Calculate coverage of frames with tracks, this information
  2247. * is used to highlight dopesheet background depending on how
  2248. * many tracks exists on the frame.
  2249. */
  2250. static void tracking_dopesheet_calc_coverage(MovieTracking *tracking)
  2251. {
  2252. MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
  2253. MovieTrackingObject *object = BKE_tracking_object_get_active(tracking);
  2254. ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object);
  2255. MovieTrackingTrack *track;
  2256. int frames, start_frame = INT_MAX, end_frame = -INT_MAX;
  2257. int *per_frame_counter;
  2258. int prev_coverage, last_segment_frame;
  2259. /* find frame boundaries */
  2260. for (track = tracksbase->first; track; track = track->next) {
  2261. start_frame = min_ii(start_frame, track->markers[0].framenr);
  2262. end_frame = max_ii(end_frame, track->markers[track->markersnr - 1].framenr);
  2263. }
  2264. frames = end_frame - start_frame + 1;
  2265. /* this is a per-frame counter of markers (how many markers belongs to the same frame) */
  2266. per_frame_counter = MEM_callocN(sizeof(int) * frames, "per frame track counter");
  2267. /* find per-frame markers count */
  2268. for (track = tracksbase->first; track; track = track->next) {
  2269. for (int i = 0; i < track->markersnr; i++) {
  2270. MovieTrackingMarker *marker = &track->markers[i];
  2271. /* TODO: perhaps we need to add check for non-single-frame track here */
  2272. if ((marker->flag & MARKER_DISABLED) == 0)
  2273. per_frame_counter[marker->framenr - start_frame]++;
  2274. }
  2275. }
  2276. /* convert markers count to coverage and detect segments with the same coverage */
  2277. prev_coverage = coverage_from_count(per_frame_counter[0]);
  2278. last_segment_frame = start_frame;
  2279. /* means only disabled tracks in the beginning, could be ignored */
  2280. if (!per_frame_counter[0])
  2281. prev_coverage = TRACKING_COVERAGE_OK;
  2282. for (int i = 1; i < frames; i++) {
  2283. int coverage = coverage_from_count(per_frame_counter[i]);
  2284. /* means only disabled tracks in the end, could be ignored */
  2285. if (i == frames - 1 && !per_frame_counter[i])
  2286. coverage = TRACKING_COVERAGE_OK;
  2287. if (coverage != prev_coverage || i == frames - 1) {
  2288. MovieTrackingDopesheetCoverageSegment *coverage_segment;
  2289. int end_segment_frame = i - 1 + start_frame;
  2290. if (end_segment_frame == last_segment_frame)
  2291. end_segment_frame++;
  2292. coverage_segment = MEM_callocN(sizeof(MovieTrackingDopesheetCoverageSegment), "tracking coverage segment");
  2293. coverage_segment->coverage = prev_coverage;
  2294. coverage_segment->start_frame = last_segment_frame;
  2295. coverage_segment->end_frame = end_segment_frame;
  2296. BLI_addtail(&dopesheet->coverage_segments, coverage_segment);
  2297. last_segment_frame = end_segment_frame;
  2298. }
  2299. prev_coverage = coverage;
  2300. }
  2301. MEM_freeN(per_frame_counter);
  2302. }
  2303. /* Tag dopesheet for update, actual update will happen later
  2304. * when it'll be actually needed.
  2305. */
  2306. void BKE_tracking_dopesheet_tag_update(MovieTracking *tracking)
  2307. {
  2308. MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
  2309. dopesheet->ok = false;
  2310. }
  2311. /* Do dopesheet update, if update is not needed nothing will happen. */
  2312. void BKE_tracking_dopesheet_update(MovieTracking *tracking)
  2313. {
  2314. MovieTrackingDopesheet *dopesheet = &tracking->dopesheet;
  2315. short sort_method = dopesheet->sort_method;
  2316. bool inverse = (dopesheet->flag & TRACKING_DOPE_SORT_INVERSE) != 0;
  2317. if (dopesheet->ok)
  2318. return;
  2319. tracking_dopesheet_free(dopesheet);
  2320. /* channels */
  2321. tracking_dopesheet_channels_calc(tracking);
  2322. tracking_dopesheet_channels_sort(tracking, sort_method, inverse);
  2323. /* frame coverage */
  2324. tracking_dopesheet_calc_coverage(tracking);
  2325. dopesheet->ok = true;
  2326. }