Welcome to mirror list, hosted at ThFree Co, Russian Federation.

COM_domain.hh « realtime_compositor « compositor « blender « source - git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 54d712f7578285d59afbc4d7d006d2fa0ac9ceab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* SPDX-License-Identifier: GPL-2.0-or-later */

#pragma once

#include <cstdint>

#include "BLI_float3x3.hh"
#include "BLI_math_vec_types.hh"

namespace blender::realtime_compositor {

/* Possible interpolations to use when realizing an input result of some domain on another domain.
 * See the RealizationOptions struct for more information. */
enum class Interpolation : uint8_t {
  Nearest,
  Bilinear,
  Bicubic,
};

/* ------------------------------------------------------------------------------------------------
 * Realization Options
 *
 * The options that describe how an input result prefer to be realized on some other domain. This
 * is used by the Realize On Domain Operation to identify the appropriate method of realization.
 * See the Domain class for more information. */
struct RealizationOptions {
  /* The interpolation method that should be used when performing realization. Since realizing a
   * result involves projecting it on a different domain, which in turn, involves sampling the
   * result at arbitrary locations, the interpolation identifies the method used for computing the
   * value at those arbitrary locations. */
  Interpolation interpolation = Interpolation::Nearest;
  /* If true, the result will be repeated infinitely along the horizontal axis when realizing the
   * result. If false, regions outside of bounds of the result along the horizontal axis will be
   * filled with zeros. */
  bool repeat_x = false;
  /* If true, the result will be repeated infinitely along the vertical axis when realizing the
   * result. If false, regions outside of bounds of the result along the vertical axis will be
   * filled with zeros. */
  bool repeat_y = false;
};

/* ------------------------------------------------------------------------------------------------
 * Domain
 *
 * The compositor is designed in such a way as to allow compositing in an infinite virtual
 * compositing space. Consequently, any result of an operation is not only represented by its image
 * output, but also by its transformation in that virtual space. The transformation of the result
 * together with the dimension of its image is stored and represented by a Domain. In the figure
 * below, two results of different domains are illustrated on the virtual compositing space. One of
 * the results is centered in space with an image dimension of 800px × 600px, and the other result
 * is scaled down and translated such that it lies in the upper right quadrant of the space with an
 * image dimension of 800px × 400px. The position of the domain is in pixel space, and the domain
 * is considered centered if it has an identity transformation. Note that both results have the
 * same resolution, but occupy different areas of the virtual compositing space.
 *
 *                                          y
 *                                          ^
 *                           800px x 600px  |
 *                    .---------------------|---------------------.
 *                    |                     |    800px x 600px    |
 *                    |                     |   .-------------.   |
 *                    |                     |   |             |   |
 *                    |                     |   '-------------'   |
 *              ------|---------------------|---------------------|------> x
 *                    |                     |                     |
 *                    |                     |                     |
 *                    |                     |                     |
 *                    |                     |                     |
 *                    '---------------------|---------------------'
 *                                          |
 *
 * By default, results have domains of identity transformations, that is, they are centered in
 * space, but a transformation operation like the rotate, translate, or transform operations will
 * adjust the transformation to make the result reside somewhere different in space. The domain of
 * a single value result is irrelevant and always set to an identity domain.
 *
 * An operation is typically only concerned about a subset of the virtual compositing space, this
 * subset is represented by a domain which is called the Operation Domain. It follows that before
 * the operation itself is executed, inputs will typically be realized on the operation domain to
 * be in the same domain and have the same dimension as that of the operation domain. This process
 * is called Domain Realization and is implemented using an operation called the Realize On Domain
 * Operation. Realization involves projecting the result onto the target domain, copying the area
 * of the result that intersects the target domain, and filling the rest with zeros or repetitions
 * of the result depending on the realization options that can be set by the user. Consequently,
 * operations can generally expect their inputs to have the same dimension and can operate on them
 * directly and transparently. For instance, if an operation takes both results illustrated in
 * the figure above, and the operation has an operation domain that matches the bigger domain, the
 * result with the bigger domain will not need to be realized because it already has a domain that
 * matches that of the operation domain, but the result with the smaller domain will have to be
 * realized into a new result that has the same domain as the domain of the bigger result. Assuming
 * no repetition, the output of the realization will be an all zeros image with dimension 800px ×
 * 600px with a small scaled version of the smaller result copied into the upper right quadrant of
 * the image. The following figure illustrates the realization process on a different set of
 * results
 *
 *                                   Realized Result
 *             +-------------+       +-------------+
 *             |  Operation  |       |             |
 *             |   Domain    |       |    Zeros    |
 *             |             | ----> |             |
 *       +-----|-----+       |       |-----+       |
 *       |     |  C  |       |       |  C  |       |
 *       |     +-----|-------+       +-----'-------+
 *       | Domain Of |
 *       |   Input   |
 *       +-----------+
 *
 * An operation can operate in an arbitrary operation domain, but in most cases, the operation
 * domain is inferred from the inputs of the operation. In particular, one of the inputs is said to
 * be the Domain Input of the operation and the operation domain is inferred from its domain. It
 * follows that this particular input will not need realization, because it already has the correct
 * domain. The domain input selection mechanism is as follows. Each of the inputs are assigned a
 * value by the developer called the Domain Priority, the domain input is then chosen as the
 * non-single value input with the highest domain priority, zero being the highest priority. See
 * Operation::compute_domain for more information.
 *
 * The aforementioned logic for operation domain computation is only a default that works for most
 * cases, but an operation can override the compute_domain method to implement a different logic.
 * For instance, output nodes have an operation domain the same size as the viewport and with an
 * identity transformation, their operation domain doesn't depend on the inputs at all.
 *
 * For instance, a filter operation has two inputs, a factor and a color, the latter of which is
 * assigned a domain priority of 0 and the former is assigned a domain priority of 1. If the color
 * input is not a single value input, then the color input is considered to be the domain input of
 * the operation and the operation domain is computed to be the same domain as the color input,
 * because it has the highest priority. It follows that if the factor input has a different domain
 * than the computed domain of the operation, it will be projected and realized on it to have the
 * same domain as described above. On the other hand, if the color input is a single value input,
 * then the factor input is considered to be the domain input and the operation domain will be the
 * same as the domain of the factor input, because it has the second highest domain priority.
 * Finally, if both inputs are single value inputs, the operation domain will be an identity domain
 * and is irrelevant, because the output will be a domain-less single value. */
class Domain {
 public:
  /* The size of the domain in pixels. */
  int2 size;
  /* The 2D transformation of the domain defining its translation in pixels, rotation, and scale in
   * the virtual compositing space. */
  float3x3 transformation;
  /* The options that describe how this domain prefer to be realized on some other domain. See the
   * RealizationOptions struct for more information. */
  RealizationOptions realization_options;

 public:
  /* A size only constructor that sets the transformation to identity. */
  Domain(int2 size);

  Domain(int2 size, float3x3 transformation);

  /* Transform the domain by the given transformation. This effectively pre-multiply the given
   * transformation by the current transformation of the domain. */
  void transform(const float3x3 &input_transformation);

  /* Returns a domain of size 1x1 and an identity transformation. */
  static Domain identity();
};

/* Compare the size and transformation of the domain. The realization_options are not compared
 * because they only describe the method of realization on another domain, which is not technically
 * a property of the domain itself. */
bool operator==(const Domain &a, const Domain &b);

/* Inverse of the above equality operator. */
bool operator!=(const Domain &a, const Domain &b);

}  // namespace blender::realtime_compositor