Blender  V3.3
uvproject.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
7 #include <math.h>
8 
9 #include "MEM_guardedalloc.h"
10 
11 #include "DNA_camera_types.h"
12 #include "DNA_object_types.h"
13 
14 #include "BLI_math.h"
15 #include "BLI_uvproject.h"
16 
17 typedef struct ProjCameraInfo {
18  float camangle;
19  float camsize;
20  float xasp, yasp;
21  float shiftx, shifty;
22  float rotmat[4][4];
23  float caminv[4][4];
26 
27 void BLI_uvproject_from_camera(float target[2], float source[3], ProjCameraInfo *uci)
28 {
29  float pv4[4];
30 
31  copy_v3_v3(pv4, source);
32  pv4[3] = 1.0;
33 
34  /* rotmat is the object matrix in this case */
35  if (uci->do_rotmat) {
36  mul_m4_v4(uci->rotmat, pv4);
37  }
38 
39  /* caminv is the inverse camera matrix */
40  mul_m4_v4(uci->caminv, pv4);
41 
42  if (uci->do_pano) {
43  float angle = atan2f(pv4[0], -pv4[2]) / ((float)M_PI * 2.0f); /* angle around the camera */
44  if (uci->do_persp == false) {
45  target[0] = angle; /* no correct method here, just map to 0-1 */
46  target[1] = pv4[1] / uci->camsize;
47  }
48  else {
49  float vec2d[2]; /* 2D position from the camera */
50  vec2d[0] = pv4[0];
51  vec2d[1] = pv4[2];
52  target[0] = angle * ((float)M_PI / uci->camangle);
53  target[1] = pv4[1] / (len_v2(vec2d) * (uci->camsize * 2.0f));
54  }
55  }
56  else {
57  if (pv4[2] == 0.0f) {
58  pv4[2] = 0.00001f; /* don't allow div by 0 */
59  }
60 
61  if (uci->do_persp == false) {
62  target[0] = (pv4[0] / uci->camsize);
63  target[1] = (pv4[1] / uci->camsize);
64  }
65  else {
66  target[0] = (-pv4[0] * ((1.0f / uci->camsize) / pv4[2])) / 2.0f;
67  target[1] = (-pv4[1] * ((1.0f / uci->camsize) / pv4[2])) / 2.0f;
68  }
69  }
70 
71  target[0] *= uci->xasp;
72  target[1] *= uci->yasp;
73 
74  /* adds camera shift + 0.5 */
75  target[0] += uci->shiftx;
76  target[1] += uci->shifty;
77 }
78 
79 void BLI_uvproject_from_view(float target[2],
80  float source[3],
81  float persmat[4][4],
82  float rotmat[4][4],
83  float winx,
84  float winy)
85 {
86  float pv4[4], x = 0.0, y = 0.0;
87 
88  copy_v3_v3(pv4, source);
89  pv4[3] = 1.0;
90 
91  /* rotmat is the object matrix in this case */
92  mul_m4_v4(rotmat, pv4);
93 
94  /* almost ED_view3d_project_short */
95  mul_m4_v4(persmat, pv4);
96  if (fabsf(pv4[3]) > 0.00001f) { /* avoid division by zero */
97  target[0] = winx / 2.0f + (winx / 2.0f) * pv4[0] / pv4[3];
98  target[1] = winy / 2.0f + (winy / 2.0f) * pv4[1] / pv4[3];
99  }
100  else {
101  /* scaling is lost but give a valid result */
102  target[0] = winx / 2.0f + (winx / 2.0f) * pv4[0];
103  target[1] = winy / 2.0f + (winy / 2.0f) * pv4[1];
104  }
105 
106  /* v3d->persmat seems to do this funky scaling */
107  if (winx > winy) {
108  y = (winx - winy) / 2.0f;
109  winy = winx;
110  }
111  else {
112  x = (winy - winx) / 2.0f;
113  winx = winy;
114  }
115 
116  target[0] = (x + target[0]) / winx;
117  target[1] = (y + target[1]) / winy;
118 }
119 
120 ProjCameraInfo *BLI_uvproject_camera_info(Object *ob, float rotmat[4][4], float winx, float winy)
121 {
122  ProjCameraInfo uci;
123  Camera *camera = ob->data;
124 
125  uci.do_pano = (camera->type == CAM_PANO);
126  uci.do_persp = (camera->type == CAM_PERSP);
127 
128  uci.camangle = focallength_to_fov(camera->lens, camera->sensor_x) / 2.0f;
129  uci.camsize = uci.do_persp ? tanf(uci.camangle) : camera->ortho_scale;
130 
131  /* account for scaled cameras */
132  copy_m4_m4(uci.caminv, ob->obmat);
133  normalize_m4(uci.caminv);
134 
135  if (invert_m4(uci.caminv)) {
136  ProjCameraInfo *uci_pt;
137 
138  /* normal projection */
139  if (rotmat) {
140  copy_m4_m4(uci.rotmat, rotmat);
141  uci.do_rotmat = true;
142  }
143  else {
144  uci.do_rotmat = false;
145  }
146 
147  /* also make aspect ratio adjustment factors */
148  if (winx > winy) {
149  uci.xasp = 1.0f;
150  uci.yasp = winx / winy;
151  }
152  else {
153  uci.xasp = winy / winx;
154  uci.yasp = 1.0f;
155  }
156 
157  /* include 0.5f here to move the UVs into the center */
158  uci.shiftx = 0.5f - (camera->shiftx * uci.xasp);
159  uci.shifty = 0.5f - (camera->shifty * uci.yasp);
160 
161  uci_pt = MEM_mallocN(sizeof(ProjCameraInfo), "ProjCameraInfo");
162  *uci_pt = uci;
163  return uci_pt;
164  }
165 
166  return NULL;
167 }
168 
169 void BLI_uvproject_from_view_ortho(float target[2], float source[3], const float rotmat[4][4])
170 {
171  float pv[3];
172 
173  mul_v3_m4v3(pv, rotmat, source);
174 
175  /* ortho projection */
176  target[0] = -pv[0];
177  target[1] = pv[2];
178 }
179 
180 void BLI_uvproject_camera_info_scale(ProjCameraInfo *uci, float scale_x, float scale_y)
181 {
182  uci->xasp *= scale_x;
183  uci->yasp *= scale_y;
184 }
typedef float(TangentPoint)[2]
#define M_PI
Definition: BLI_math_base.h:20
bool invert_m4(float R[4][4])
Definition: math_matrix.c:1206
void mul_m4_v4(const float M[4][4], float r[4])
Definition: math_matrix.c:862
void copy_m4_m4(float m1[4][4], const float m2[4][4])
Definition: math_matrix.c:77
void mul_v3_m4v3(float r[3], const float M[4][4], const float v[3])
Definition: math_matrix.c:739
void normalize_m4(float R[4][4]) ATTR_NONNULL()
Definition: math_matrix.c:1945
float focallength_to_fov(float focal_length, float sensor)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float len_v2(const float a[2]) ATTR_WARN_UNUSED_RESULT
@ CAM_PERSP
@ CAM_PANO
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint y
Read Guarded memory(de)allocation.
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Sky Generate a procedural sky texture Noise Generate fractal Perlin noise Wave Generate procedural bands or rings with noise Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between camera
SIMD_FORCE_INLINE btScalar angle(const btVector3 &v) const
Return the angle between this and another vector.
Definition: btVector3.h:356
#define tanf(x)
Definition: cuda/compat.h:104
GREAL2 vec2d[2]
Double vector 2D.
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
#define atan2f(x, y)
Definition: metal/compat.h:227
#define fabsf(x)
Definition: metal/compat.h:219
float obmat[4][4]
void * data
bool do_rotmat
Definition: uvproject.c:24
float shiftx
Definition: uvproject.c:21
float rotmat[4][4]
Definition: uvproject.c:22
float camsize
Definition: uvproject.c:19
float shifty
Definition: uvproject.c:21
float caminv[4][4]
Definition: uvproject.c:23
float camangle
Definition: uvproject.c:18
void BLI_uvproject_from_view(float target[2], float source[3], float persmat[4][4], float rotmat[4][4], float winx, float winy)
Definition: uvproject.c:79
void BLI_uvproject_from_camera(float target[2], float source[3], ProjCameraInfo *uci)
Definition: uvproject.c:27
void BLI_uvproject_camera_info_scale(ProjCameraInfo *uci, float scale_x, float scale_y)
Definition: uvproject.c:180
struct ProjCameraInfo ProjCameraInfo
void BLI_uvproject_from_view_ortho(float target[2], float source[3], const float rotmat[4][4])
Definition: uvproject.c:169
ProjCameraInfo * BLI_uvproject_camera_info(Object *ob, float rotmat[4][4], float winx, float winy)
Definition: uvproject.c:120