Blender V4.3
distortion_grid.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include <cstdint>
6#include <memory>
7
8#include "BLI_array.hh"
9#include "BLI_hash.hh"
10#include "BLI_index_range.hh"
12#include "BLI_task.hh"
13
14#include "DNA_defaults.h"
15#include "DNA_movieclip_types.h"
16#include "DNA_tracking_types.h"
17
18#include "GPU_texture.hh"
19
20#include "BKE_movieclip.h"
21#include "BKE_tracking.h"
22
23#include "COM_context.hh"
25#include "COM_result.hh"
26
28
29/* --------------------------------------------------------------------
30 * Distortion Grid Key.
31 */
32
34 int2 size,
35 DistortionType type,
36 int2 calibration_size)
37 : camera(camera), size(size), type(type), calibration_size(calibration_size)
38{
39}
40
46
48{
49 return BKE_tracking_camera_distortion_equal(&a.camera, &b.camera) && a.size == b.size &&
50 a.type == b.type && a.calibration_size == b.calibration_size;
51}
52
53/* --------------------------------------------------------------------
54 * Distortion Grid.
55 */
56
58 Context &context, MovieClip *movie_clip, int2 size, DistortionType type, int2 calibration_size)
59{
61 &movie_clip->tracking, calibration_size.x, calibration_size.y);
62
63 Array<float2> distortion_grid(size.x * size.y);
64 threading::parallel_for(IndexRange(size.y), 1, [&](const IndexRange sub_y_range) {
65 for (const int64_t y : sub_y_range) {
66 for (const int64_t x : IndexRange(size.x)) {
67 /* The tracking distortion functions expect the coordinates to be in the space of the image
68 * where the tracking camera was calibrated. So we first remap the coordinates into that
69 * space, apply the distortion, then remap back to the original coordinates space. This is
70 * done by dividing the by the size then multiplying by the calibration size, making sure
71 * to add 0.5 to evaluate at the center of pixels. */
72 float2 coordinates = ((float2(x, y) + 0.5f) / float2(size)) * float2(calibration_size);
73
74 if (type == DistortionType::Undistort) {
75 BKE_tracking_distortion_undistort_v2(distortion, coordinates, coordinates);
76 }
77 else {
78 BKE_tracking_distortion_distort_v2(distortion, coordinates, coordinates);
79 }
80
81 /* Note that we should remap the coordinates back into the original size by dividing by the
82 * calibration size and multiplying by the size, however, we skip the latter to store the
83 * coordinates in normalized form, since this is what the shader expects. */
84 distortion_grid[y * size.x + x] = coordinates / float2(calibration_size);
85 }
86 }
87 });
88
90
91 texture_ = GPU_texture_create_2d(
92 "Distortion Grid",
93 size.x,
94 size.y,
95 1,
96 Result::gpu_texture_format(ResultType::Float2, context.get_precision()),
98 *distortion_grid.data());
99}
100
101DistortionGrid::~DistortionGrid()
102{
103 GPU_texture_free(texture_);
104}
105
106void DistortionGrid::bind_as_texture(GPUShader *shader, const char *texture_name) const
107{
108 const int texture_image_unit = GPU_shader_get_sampler_binding(shader, texture_name);
109 GPU_texture_bind(texture_, texture_image_unit);
110}
111
112void DistortionGrid::unbind_as_texture() const
113{
114 GPU_texture_unbind(texture_);
115}
116
117/* --------------------------------------------------------------------
118 * Distortion Grid Container.
119 */
120
121void DistortionGridContainer::reset()
122{
123 /* First, delete all resources that are no longer needed. */
124 map_.remove_if([](auto item) { return !item.value->needed; });
125
126 /* Second, reset the needed status of the remaining resources to false to ready them to track
127 * their needed status for the next evaluation. */
128 for (auto &value : map_.values()) {
129 value->needed = false;
130 }
131}
132
133static int2 get_movie_clip_size(MovieClip *movie_clip, int frame_number)
134{
136 BKE_movieclip_user_set_frame(&user, frame_number);
137
138 int2 size;
139 BKE_movieclip_get_size(movie_clip, &user, &size.x, &size.y);
140
141 return size;
142}
143
144DistortionGrid &DistortionGridContainer::get(
145 Context &context, MovieClip *movie_clip, int2 size, DistortionType type, int frame_number)
146{
147 const int2 calibration_size = get_movie_clip_size(movie_clip, frame_number);
148
149 const DistortionGridKey key(movie_clip->tracking.camera, size, type, calibration_size);
150
151 auto &distortion_grid = *map_.lookup_or_add_cb(key, [&]() {
152 return std::make_unique<DistortionGrid>(context, movie_clip, size, type, calibration_size);
153 });
154
155 distortion_grid.needed = true;
156 return distortion_grid;
157}
158
159} // namespace blender::realtime_compositor
void BKE_movieclip_user_set_frame(struct MovieClipUser *user, int framenr)
void BKE_movieclip_get_size(struct MovieClip *clip, const struct MovieClipUser *user, int *r_width, int *r_height)
bool BKE_tracking_camera_distortion_equal(const struct MovieTrackingCamera *a, const struct MovieTrackingCamera *b)
void BKE_tracking_distortion_free(struct MovieDistortion *distortion)
Definition tracking.cc:2414
uint64_t BKE_tracking_camera_distortion_hash(const struct MovieTrackingCamera *camera)
struct MovieDistortion * BKE_tracking_distortion_new(struct MovieTracking *tracking, int calibration_width, int calibration_height)
Definition tracking.cc:2263
#define DNA_struct_default_get(struct_name)
int GPU_shader_get_sampler_binding(GPUShader *shader, const char *name)
void GPU_texture_bind(GPUTexture *texture, int unit)
GPUTexture * GPU_texture_create_2d(const char *name, int width, int height, int mip_len, eGPUTextureFormat format, eGPUTextureUsage usage, const float *data)
void GPU_texture_free(GPUTexture *texture)
void GPU_texture_unbind(GPUTexture *texture)
@ GPU_TEXTURE_USAGE_SHADER_READ
struct GPUShader GPUShader
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
DistortionGridKey(const MovieTrackingCamera &camera, int2 size, DistortionType type, int2 calibration_size)
DistortionGrid(Context &context, MovieClip *movie_clip, int2 size, DistortionType type, int2 calibration_size)
static eGPUTextureFormat gpu_texture_format(ResultType type, ResultPrecision precision)
Definition result.cc:29
local_group_size(16, 16) .push_constant(Type b
bool operator==(const BokehKernelKey &a, const BokehKernelKey &b)
static int2 get_movie_clip_size(MovieClip *movie_clip, int frame_number)
void parallel_for(const IndexRange range, const int64_t grain_size, const Function &function, const TaskSizeHints &size_hints=detail::TaskSizeHints_Static(1))
Definition BLI_task.hh:95
uint64_t get_default_hash(const T &v)
Definition BLI_hash.hh:219
unsigned __int64 uint64_t
Definition stdint.h:90
struct MovieTracking tracking
MovieTrackingCamera camera