Blender  V2.93
view3d_project.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2008 Blender Foundation.
17  * All rights reserved.
18  */
19 
24 #include "DNA_camera_types.h"
25 #include "DNA_object_types.h"
26 #include "DNA_scene_types.h"
27 #include "DNA_screen_types.h"
28 #include "DNA_view3d_types.h"
29 
30 #include "BLI_sys_types.h" /* int64_t */
31 
32 #include "BLI_math_vector.h"
33 
34 #include "BKE_camera.h"
35 #include "BKE_screen.h"
36 
37 #include "GPU_matrix.h"
38 
39 #include "ED_view3d.h" /* own include */
40 
41 #define BL_ZERO_CLIP 0.001
42 
43 /* Non Clipping Projection Functions
44  * ********************************* */
45 
50  const float co[3],
51  float r_co[2],
52  float mat[4][4])
53 {
54  float vec4[4];
55 
56  copy_v3_v3(vec4, co);
57  vec4[3] = 1.0;
58  /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
59 
60  mul_m4_v4(mat, vec4);
61 
62  if (vec4[3] > FLT_EPSILON) {
63  r_co[0] = (float)(region->winx / 2.0f) + (region->winx / 2.0f) * vec4[0] / vec4[3];
64  r_co[1] = (float)(region->winy / 2.0f) + (region->winy / 2.0f) * vec4[1] / vec4[3];
65  }
66  else {
67  zero_v2(r_co);
68  }
69 }
70 
75  const float co[3],
76  float r_co[3],
77  float mat[4][4])
78 {
79  float vec4[4];
80 
81  copy_v3_v3(vec4, co);
82  vec4[3] = 1.0;
83  /* r_co[0] = IS_CLIPPED; */ /* always overwritten */
84 
85  mul_m4_v4(mat, vec4);
86 
87  if (vec4[3] > FLT_EPSILON) {
88  r_co[0] = (float)(region->winx / 2.0f) + (region->winx / 2.0f) * vec4[0] / vec4[3];
89  r_co[1] = (float)(region->winy / 2.0f) + (region->winy / 2.0f) * vec4[1] / vec4[3];
90  r_co[2] = vec4[2] / vec4[3];
91  }
92  else {
93  zero_v3(r_co);
94  }
95 }
96 
97 /* Clipping Projection Functions
98  * ***************************** */
99 
100 eV3DProjStatus ED_view3d_project_base(const struct ARegion *region, struct Base *base)
101 {
103  region, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT);
104 
105  if (ret != V3D_PROJ_RET_OK) {
106  base->sx = IS_CLIPPED;
107  base->sy = 0;
108  }
109 
110  return ret;
111 }
112 
113 /* perspmat is typically...
114  * - 'rv3d->perspmat', is_local == false
115  * - 'rv3d->persmatob', is_local == true
116  */
118  const float perspmat[4][4],
119  const bool is_local, /* normally hidden */
120  const float co[3],
121  float r_co[2],
122  const eV3DProjTest flag)
123 {
124  float vec4[4];
125 
126  /* check for bad flags */
127  BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag);
128 
129  if (flag & V3D_PROJ_TEST_CLIP_BB) {
130  RegionView3D *rv3d = region->regiondata;
131  if (rv3d->rflag & RV3D_CLIPPING) {
132  if (ED_view3d_clipping_test(rv3d, co, is_local)) {
133  return V3D_PROJ_RET_CLIP_BB;
134  }
135  }
136  }
137 
138  copy_v3_v3(vec4, co);
139  vec4[3] = 1.0;
140  mul_m4_v4(perspmat, vec4);
141  const float w = fabsf(vec4[3]);
142 
143  if ((flag & V3D_PROJ_TEST_CLIP_ZERO) && (w <= (float)BL_ZERO_CLIP)) {
144  return V3D_PROJ_RET_CLIP_ZERO;
145  }
146 
147  if ((flag & V3D_PROJ_TEST_CLIP_NEAR) && (vec4[2] <= -w)) {
148  return V3D_PROJ_RET_CLIP_NEAR;
149  }
150 
151  if ((flag & V3D_PROJ_TEST_CLIP_FAR) && (vec4[2] >= w)) {
152  return V3D_PROJ_RET_CLIP_FAR;
153  }
154 
155  const float scalar = (w != 0.0f) ? (1.0f / w) : 0.0f;
156  const float fx = ((float)region->winx / 2.0f) * (1.0f + (vec4[0] * scalar));
157  const float fy = ((float)region->winy / 2.0f) * (1.0f + (vec4[1] * scalar));
158 
159  if ((flag & V3D_PROJ_TEST_CLIP_WIN) &&
160  (fx <= 0.0f || fy <= 0.0f || fx >= (float)region->winx || fy >= (float)region->winy)) {
161  return V3D_PROJ_RET_CLIP_WIN;
162  }
163 
164  r_co[0] = fx;
165  r_co[1] = fy;
166 
167  return V3D_PROJ_RET_OK;
168 }
169 
171  float perspmat[4][4],
172  const bool is_local,
173  const float co[3],
174  short r_co[2],
175  const eV3DProjTest flag)
176 {
177  float tvec[2];
178  eV3DProjStatus ret = ed_view3d_project__internal(region, perspmat, is_local, co, tvec, flag);
179  if (ret == V3D_PROJ_RET_OK) {
180  if ((tvec[0] > -32700.0f && tvec[0] < 32700.0f) &&
181  (tvec[1] > -32700.0f && tvec[1] < 32700.0f)) {
182  r_co[0] = (short)floorf(tvec[0]);
183  r_co[1] = (short)floorf(tvec[1]);
184  }
185  else {
187  }
188  }
189  return ret;
190 }
191 
193  float perspmat[4][4],
194  const bool is_local,
195  const float co[3],
196  int r_co[2],
197  const eV3DProjTest flag)
198 {
199  float tvec[2];
200  eV3DProjStatus ret = ed_view3d_project__internal(region, perspmat, is_local, co, tvec, flag);
201  if (ret == V3D_PROJ_RET_OK) {
202  if ((tvec[0] > -2140000000.0f && tvec[0] < 2140000000.0f) &&
203  (tvec[1] > -2140000000.0f && tvec[1] < 2140000000.0f)) {
204  r_co[0] = (int)floorf(tvec[0]);
205  r_co[1] = (int)floorf(tvec[1]);
206  }
207  else {
209  }
210  }
211  return ret;
212 }
213 
215  float perspmat[4][4],
216  const bool is_local,
217  const float co[3],
218  float r_co[2],
219  const eV3DProjTest flag)
220 {
221  float tvec[2];
222  eV3DProjStatus ret = ed_view3d_project__internal(region, perspmat, is_local, co, tvec, flag);
223  if (ret == V3D_PROJ_RET_OK) {
224  if (isfinite(tvec[0]) && isfinite(tvec[1])) {
225  copy_v2_v2(r_co, tvec);
226  }
227  else {
229  }
230  }
231  return ret;
232 }
233 
234 /* --- short --- */
236  const float co[3],
237  short r_co[2],
238  const eV3DProjTest flag)
239 {
240  RegionView3D *rv3d = region->regiondata;
241  return ED_view3d_project_short_ex(region, rv3d->persmat, false, co, r_co, flag);
242 }
243 /* object space, use ED_view3d_init_mats_rv3d before calling */
245  const float co[3],
246  short r_co[2],
247  const eV3DProjTest flag)
248 {
249  RegionView3D *rv3d = region->regiondata;
251  return ED_view3d_project_short_ex(region, rv3d->persmatob, true, co, r_co, flag);
252 }
253 
254 /* --- int --- */
256  const float co[3],
257  int r_co[2],
258  const eV3DProjTest flag)
259 {
260  RegionView3D *rv3d = region->regiondata;
261  return ED_view3d_project_int_ex(region, rv3d->persmat, false, co, r_co, flag);
262 }
263 /* object space, use ED_view3d_init_mats_rv3d before calling */
265  const float co[3],
266  int r_co[2],
267  const eV3DProjTest flag)
268 {
269  RegionView3D *rv3d = region->regiondata;
271  return ED_view3d_project_int_ex(region, rv3d->persmatob, true, co, r_co, flag);
272 }
273 
274 /* --- float --- */
276  const float co[3],
277  float r_co[2],
278  const eV3DProjTest flag)
279 {
280  RegionView3D *rv3d = region->regiondata;
281  return ED_view3d_project_float_ex(region, rv3d->persmat, false, co, r_co, flag);
282 }
283 /* object space, use ED_view3d_init_mats_rv3d before calling */
285  const float co[3],
286  float r_co[2],
287  const eV3DProjTest flag)
288 {
289  RegionView3D *rv3d = region->regiondata;
291  return ED_view3d_project_float_ex(region, rv3d->persmatob, true, co, r_co, flag);
292 }
293 
294 /* More Generic Window/Ray/Vector projection functions
295  * *************************************************** */
296 
297 float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
298 {
299  return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
300 }
301 
302 float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[3])
303 {
304  return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize;
305 }
306 
310 float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip)
311 {
312  float zfac = mul_project_m4_v3_zfac(rv3d->persmat, co);
313 
314  if (r_flip) {
315  *r_flip = (zfac < 0.0f);
316  }
317 
318  /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that
319  * (accounting for near zero values) */
320  if (zfac < 1.e-6f && zfac > -1.e-6f) {
321  zfac = 1.0f;
322  }
323 
324  /* Negative zfac means x, y, z was behind the camera (in perspective).
325  * This gives flipped directions, so revert back to ok default case. */
326  if (zfac < 0.0f) {
327  zfac = -zfac;
328  }
329 
330  return zfac;
331 }
332 
334  const ARegion *region,
335  const View3D *v3d,
336  const float mval[2],
337  float r_ray_co[3],
338  float r_ray_dir[3],
339  float r_ray_start[3],
340  float r_ray_end[3])
341 {
342  RegionView3D *rv3d = region->regiondata;
343  float _ray_co[3], _ray_dir[3], start_offset, end_offset;
344 
345  if (!r_ray_co) {
346  r_ray_co = _ray_co;
347  }
348  if (!r_ray_dir) {
349  r_ray_dir = _ray_dir;
350  }
351 
352  ED_view3d_win_to_origin(region, mval, r_ray_co);
353  ED_view3d_win_to_vector(region, mval, r_ray_dir);
354 
355  if ((rv3d->is_persp == false) && (rv3d->persp != RV3D_CAMOB)) {
356  end_offset = v3d->clip_end / 2.0f;
357  start_offset = -end_offset;
358  }
359  else {
360  ED_view3d_clip_range_get(depsgraph, v3d, rv3d, &start_offset, &end_offset, false);
361  }
362 
363  if (r_ray_start) {
364  madd_v3_v3v3fl(r_ray_start, r_ray_co, r_ray_dir, start_offset);
365  }
366  if (r_ray_end) {
367  madd_v3_v3v3fl(r_ray_end, r_ray_co, r_ray_dir, end_offset);
368  }
369 }
370 
371 bool ED_view3d_clip_segment(const RegionView3D *rv3d, float ray_start[3], float ray_end[3])
372 {
373  if ((rv3d->rflag & RV3D_CLIPPING) &&
374  (clip_segment_v3_plane_n(ray_start, ray_end, rv3d->clip, 6, ray_start, ray_end) == false)) {
375  return false;
376  }
377  return true;
378 }
379 
397  const ARegion *region,
398  const View3D *v3d,
399  const float mval[2],
400  float r_ray_co[3],
401  float r_ray_normal[3],
402  float r_ray_start[3],
403  bool do_clip_planes)
404 {
405  float ray_end[3];
406 
408  depsgraph, region, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, ray_end);
409 
410  /* bounds clipping */
411  if (do_clip_planes) {
412  return ED_view3d_clip_segment(region->regiondata, r_ray_start, ray_end);
413  }
414 
415  return true;
416 }
417 
432  const ARegion *region,
433  const View3D *v3d,
434  const float mval[2],
435  float r_ray_start[3],
436  float r_ray_normal[3],
437  const bool do_clip_planes)
438 {
440  depsgraph, region, v3d, mval, NULL, r_ray_normal, r_ray_start, do_clip_planes);
441 }
442 
454 void ED_view3d_win_to_ray(const ARegion *region,
455  const float mval[2],
456  float r_ray_start[3],
457  float r_ray_normal[3])
458 {
459  ED_view3d_win_to_origin(region, mval, r_ray_start);
460  ED_view3d_win_to_vector(region, mval, r_ray_normal);
461 }
462 
470 void ED_view3d_global_to_vector(const RegionView3D *rv3d, const float coord[3], float vec[3])
471 {
472  if (rv3d->is_persp) {
473  float p1[4], p2[4];
474 
475  copy_v3_v3(p1, coord);
476  p1[3] = 1.0f;
477  copy_v3_v3(p2, p1);
478  p2[3] = 1.0f;
479  mul_m4_v4(rv3d->viewmat, p2);
480 
481  mul_v3_fl(p2, 2.0f);
482 
483  mul_m4_v4(rv3d->viewinv, p2);
484 
485  sub_v3_v3v3(vec, p1, p2);
486  }
487  else {
488  copy_v3_v3(vec, rv3d->viewinv[2]);
489  }
490  normalize_v3(vec);
491 }
492 
493 /* very similar to ED_view3d_win_to_3d() but has no advantage, de-duplicating */
494 #if 0
495 bool view3d_get_view_aligned_coordinate(ARegion *region,
496  float fp[3],
497  const int mval[2],
498  const bool do_fallback)
499 {
500  RegionView3D *rv3d = region->regiondata;
501  float dvec[3];
502  int mval_cpy[2];
504 
505  ret = ED_view3d_project_int_global(region, fp, mval_cpy, V3D_PROJ_TEST_NOP);
506 
507  if (ret == V3D_PROJ_RET_OK) {
508  const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]), (float)(mval_cpy[1] - mval[1])};
509  const float zfac = ED_view3d_calc_zfac(rv3d, fp, NULL);
510  ED_view3d_win_to_delta(region, mval_f, dvec, zfac);
511  sub_v3_v3(fp, dvec);
512 
513  return true;
514  }
515  else {
516  /* fallback to the view center */
517  if (do_fallback) {
518  negate_v3_v3(fp, rv3d->ofs);
519  return view3d_get_view_aligned_coordinate(region, fp, mval, false);
520  }
521  else {
522  return false;
523  }
524  }
525 }
526 #endif
527 
535 void ED_view3d_win_to_3d(const View3D *v3d,
536  const ARegion *region,
537  const float depth_pt[3],
538  const float mval[2],
539  float r_out[3])
540 {
541  RegionView3D *rv3d = region->regiondata;
542 
543  float ray_origin[3];
544  float ray_direction[3];
545  float lambda;
546 
547  if (rv3d->is_persp) {
548  float plane[4];
549 
550  copy_v3_v3(ray_origin, rv3d->viewinv[3]);
551  ED_view3d_win_to_vector(region, mval, ray_direction);
552 
553  /* Note: we could use #isect_line_plane_v3()
554  * however we want the intersection to be in front of the view no matter what,
555  * so apply the unsigned factor instead. */
556  plane_from_point_normal_v3(plane, depth_pt, rv3d->viewinv[2]);
557 
558  isect_ray_plane_v3(ray_origin, ray_direction, plane, &lambda, false);
559  lambda = fabsf(lambda);
560  }
561  else {
562  float dx = (2.0f * mval[0] / (float)region->winx) - 1.0f;
563  float dy = (2.0f * mval[1] / (float)region->winy) - 1.0f;
564 
565  if (rv3d->persp == RV3D_CAMOB) {
566  /* ortho camera needs offset applied */
567  const Camera *cam = v3d->camera->data;
568  const int sensor_fit = BKE_camera_sensor_fit(cam->sensor_fit, region->winx, region->winy);
569  const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 4.0f;
570  const float aspx = region->winx / (float)region->winy;
571  const float aspy = region->winy / (float)region->winx;
572  const float shiftx = cam->shiftx * 0.5f *
573  (sensor_fit == CAMERA_SENSOR_FIT_HOR ? 1.0f : aspy);
574  const float shifty = cam->shifty * 0.5f *
575  (sensor_fit == CAMERA_SENSOR_FIT_HOR ? aspx : 1.0f);
576 
577  dx += (rv3d->camdx + shiftx) * zoomfac;
578  dy += (rv3d->camdy + shifty) * zoomfac;
579  }
580  ray_origin[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
581  ray_origin[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
582  ray_origin[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2];
583 
584  copy_v3_v3(ray_direction, rv3d->viewinv[2]);
585  lambda = ray_point_factor_v3(depth_pt, ray_origin, ray_direction);
586  }
587 
588  madd_v3_v3v3fl(r_out, ray_origin, ray_direction, lambda);
589 }
590 
592  const ARegion *region,
593  const float depth_pt[3],
594  const int mval[2],
595  float r_out[3])
596 {
597  const float mval_fl[2] = {mval[0], mval[1]};
598  ED_view3d_win_to_3d(v3d, region, depth_pt, mval_fl, r_out);
599 }
600 
602  const float plane[4],
603  const float mval[2],
604  const bool do_clip,
605  float r_out[3])
606 {
607  float ray_co[3], ray_no[3];
608  ED_view3d_win_to_origin(region, mval, ray_co);
609  ED_view3d_win_to_vector(region, mval, ray_no);
610  float lambda;
611  if (isect_ray_plane_v3(ray_co, ray_no, plane, &lambda, do_clip)) {
612  madd_v3_v3v3fl(r_out, ray_co, ray_no, lambda);
613  return true;
614  }
615  return false;
616 }
617 
619  const float plane[4],
620  const int mval[2],
621  const bool do_clip,
622  float r_out[3])
623 {
624  const float mval_fl[2] = {mval[0], mval[1]};
625  return ED_view3d_win_to_3d_on_plane(region, plane, mval_fl, do_clip, r_out);
626 }
627 
636  const float plane[4],
637  const float mval[2],
638  const bool do_clip,
639  const float plane_fallback[4],
640  float r_out[3])
641 {
642  float isect_co[3], isect_no[3];
643  if (!isect_plane_plane_v3(plane, plane_fallback, isect_co, isect_no)) {
644  return false;
645  }
646  normalize_v3(isect_no);
647 
648  /* Construct matrix to transform `plane_fallback` onto `plane`. */
649  float mat4[4][4];
650  {
651  float mat3[3][3];
652  rotation_between_vecs_to_mat3(mat3, plane, plane_fallback);
653  copy_m4_m3(mat4, mat3);
654  transform_pivot_set_m4(mat4, isect_co);
655  }
656 
657  float co[3];
658  if (!ED_view3d_win_to_3d_on_plane(region, plane_fallback, mval, do_clip, co)) {
659  return false;
660  }
661  mul_m4_v3(mat4, co);
662 
663  /* While the point is already on the plane, there may be some small in-precision
664  * so ensure the point is exactly on the plane. */
665  closest_to_plane_v3(r_out, plane, co);
666 
667  return true;
668 }
669 
678 void ED_view3d_win_to_delta(const ARegion *region,
679  const float mval[2],
680  float out[3],
681  const float zfac)
682 {
683  RegionView3D *rv3d = region->regiondata;
684  float dx, dy;
685 
686  dx = 2.0f * mval[0] * zfac / region->winx;
687  dy = 2.0f * mval[1] * zfac / region->winy;
688 
689  out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
690  out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
691  out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
692 }
693 
704 void ED_view3d_win_to_origin(const ARegion *region, const float mval[2], float out[3])
705 {
706  RegionView3D *rv3d = region->regiondata;
707  if (rv3d->is_persp) {
708  copy_v3_v3(out, rv3d->viewinv[3]);
709  }
710  else {
711  out[0] = 2.0f * mval[0] / region->winx - 1.0f;
712  out[1] = 2.0f * mval[1] / region->winy - 1.0f;
713 
714  if (rv3d->persp == RV3D_CAMOB) {
715  out[2] = -1.0f;
716  }
717  else {
718  out[2] = 0.0f;
719  }
720 
721  mul_project_m4_v3(rv3d->persinv, out);
722  }
723 }
724 
738 void ED_view3d_win_to_vector(const ARegion *region, const float mval[2], float out[3])
739 {
740  RegionView3D *rv3d = region->regiondata;
741 
742  if (rv3d->is_persp) {
743  out[0] = 2.0f * (mval[0] / region->winx) - 1.0f;
744  out[1] = 2.0f * (mval[1] / region->winy) - 1.0f;
745  out[2] = -0.5f;
746  mul_project_m4_v3(rv3d->persinv, out);
747  sub_v3_v3(out, rv3d->viewinv[3]);
748  }
749  else {
750  negate_v3_v3(out, rv3d->viewinv[2]);
751  }
752  normalize_v3(out);
753 }
754 
770  const ARegion *region,
771  View3D *v3d,
772  const float mval[2],
773  float r_ray_start[3],
774  float r_ray_end[3],
775  const bool do_clip_planes)
776 {
777  view3d_win_to_ray_segment(depsgraph, region, v3d, mval, NULL, NULL, r_ray_start, r_ray_end);
778 
779  /* bounds clipping */
780  if (do_clip_planes) {
781  return ED_view3d_clip_segment((RegionView3D *)region->regiondata, r_ray_start, r_ray_end);
782  }
783 
784  return true;
785 }
786 
787 /* -------------------------------------------------------------------- */
791 void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float r_pmat[4][4])
792 {
793  float vmat[4][4];
794 
795  mul_m4_m4m4(vmat, rv3d->viewmat, ob->obmat);
796  mul_m4_m4m4(r_pmat, rv3d->winmat, vmat);
797 }
798 
800  const float obmat[4][4],
801  float r_pmat[4][4])
802 {
803  float vmat[4][4];
804 
805  mul_m4_m4m4(vmat, rv3d->viewmat, obmat);
806  mul_m4_m4m4(r_pmat, rv3d->winmat, vmat);
807 }
808 
812 void ED_view3d_project(const struct ARegion *region, const float world[3], float r_region_co[3])
813 {
814  /* Viewport is set up to make coordinates relative to the region, not window. */
815  RegionView3D *rv3d = region->regiondata;
816  const int viewport[4] = {0, 0, region->winx, region->winy};
817 
818  GPU_matrix_project(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co);
819 }
820 
822  const struct ARegion *region, float regionx, float regiony, float regionz, float world[3])
823 {
824  RegionView3D *rv3d = region->regiondata;
825  const int viewport[4] = {0, 0, region->winx, region->winy};
826  const float region_co[3] = {regionx, regiony, regionz};
827 
828  return GPU_matrix_unproject(region_co, rv3d->viewmat, rv3d->winmat, viewport, world);
829 }
830 
typedef float(TangentPoint)[2]
Camera data-block and utility functions.
int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
Definition: camera.c:252
float BKE_screen_view3d_zoom_to_fac(float camzoom)
Definition: screen.c:1080
#define BLI_assert(a)
Definition: BLI_assert.h:58
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:243
bool isect_plane_plane_v3(const float plane_a[4], const float plane_b[4], float r_isect_co[3], float r_isect_no[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_geom.c:2265
float ray_point_factor_v3(const float p[3], const float ray_origin[3], const float ray_direction[3])
Definition: math_geom.c:3420
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:405
bool clip_segment_v3_plane_n(const float p1[3], const float p2[3], const float plane_array[][4], const int plane_tot, float r_p1[3], float r_p2[3])
Definition: math_geom.c:3679
bool isect_ray_plane_v3(const float ray_origin[3], const float ray_direction[3], const float plane[4], float *r_lambda, const bool clip)
Definition: math_geom.c:1808
void mul_project_m4_v3(const float M[4][4], float vec[3])
Definition: math_matrix.c:824
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
Definition: math_matrix.c:262
void mul_m4_v4(const float M[4][4], float r[4])
Definition: math_matrix.c:866
void copy_m4_m3(float m1[4][4], const float m2[3][3])
Definition: math_matrix.c:120
void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
Definition: math_matrix.c:2411
void mul_m4_v3(const float M[4][4], float r[3])
Definition: math_matrix.c:732
void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[3])
MINLINE float normalize_v3(float r[3])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void negate_v3_v3(float r[3], const float a[3])
MINLINE void zero_v2(float r[2])
MINLINE float mul_project_m4_v3_zfac(const float mat[4][4], const float co[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3v3fl(float r[3], const float a[3], const float b[3], float f)
MINLINE void zero_v3(float r[3])
struct Depsgraph Depsgraph
Definition: DEG_depsgraph.h:51
@ CAMERA_SENSOR_FIT_HOR
Object is a sort of wrapper for general info.
#define RV3D_CAMOB
#define RV3D_CLIPPING
eV3DProjTest
Definition: ED_view3d.h:192
@ V3D_PROJ_TEST_CLIP_FAR
Definition: ED_view3d.h:197
@ V3D_PROJ_TEST_CLIP_NEAR
Definition: ED_view3d.h:196
@ V3D_PROJ_TEST_CLIP_ZERO
Definition: ED_view3d.h:198
@ V3D_PROJ_TEST_NOP
Definition: ED_view3d.h:193
@ V3D_PROJ_TEST_CLIP_WIN
Definition: ED_view3d.h:195
@ V3D_PROJ_TEST_CLIP_BB
Definition: ED_view3d.h:194
eV3DProjStatus
Definition: ED_view3d.h:175
@ V3D_PROJ_RET_CLIP_WIN
Definition: ED_view3d.h:186
@ V3D_PROJ_RET_CLIP_BB
Definition: ED_view3d.h:184
@ V3D_PROJ_RET_CLIP_FAR
Definition: ED_view3d.h:180
@ V3D_PROJ_RET_CLIP_ZERO
Definition: ED_view3d.h:182
@ V3D_PROJ_RET_CLIP_NEAR
Definition: ED_view3d.h:178
@ V3D_PROJ_RET_OVERFLOW
Definition: ED_view3d.h:188
@ V3D_PROJ_RET_OK
Definition: ED_view3d.h:176
#define IS_CLIPPED
Definition: ED_view3d.h:172
#define V3D_PROJ_TEST_CLIP_DEFAULT
Definition: ED_view3d.h:201
bool ED_view3d_clip_range_get(struct Depsgraph *depsgraph, const struct View3D *v3d, const struct RegionView3D *rv3d, float *r_clipsta, float *r_clipend, const bool use_ortho_factor)
#define V3D_PROJ_TEST_ALL
Definition: ED_view3d.h:203
bool ED_view3d_clipping_test(const struct RegionView3D *rv3d, const float co[3], const bool is_local)
#define ED_view3d_check_mats_rv3d(rv3d)
Definition: ED_view3d.h:583
void GPU_matrix_project(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float r_win[3])
Definition: gpu_matrix.cc:477
bool GPU_matrix_unproject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float r_world[3])
Definition: gpu_matrix.cc:572
unsigned int U
Definition: btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
World world
const Depsgraph * depsgraph
#define floorf(x)
#define fabsf(x)
bool isfinite(uchar)
Definition: image.cpp:44
return ret
void * regiondata
short sy
struct Object * object
short sx
char sensor_fit
float shiftx
float shifty
float obmat[4][4]
void * data
float persmat[4][4]
float clip[6][4]
float persinv[4][4]
float viewmat[4][4]
float persmatob[4][4]
float viewinv[4][4]
float winmat[4][4]
float clip_end
struct Object * camera
bool ED_view3d_win_to_3d_on_plane(const ARegion *region, const float plane[4], const float mval[2], const bool do_clip, float r_out[3])
bool ED_view3d_win_to_segment_clipped(struct Depsgraph *depsgraph, const ARegion *region, View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], const bool do_clip_planes)
void ED_view3d_win_to_ray(const ARegion *region, const float mval[2], float r_ray_start[3], float r_ray_normal[3])
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3], bool *r_flip)
eV3DProjStatus ED_view3d_project_base(const struct ARegion *region, struct Base *base)
eV3DProjStatus ED_view3d_project_short_ex(const ARegion *region, float perspmat[4][4], const bool is_local, const float co[3], short r_co[2], const eV3DProjTest flag)
eV3DProjStatus ED_view3d_project_float_object(const ARegion *region, const float co[3], float r_co[2], const eV3DProjTest flag)
static void view3d_win_to_ray_segment(struct Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_co[3], float r_ray_dir[3], float r_ray_start[3], float r_ray_end[3])
bool ED_view3d_win_to_3d_on_plane_with_fallback(const ARegion *region, const float plane[4], const float mval[2], const bool do_clip, const float plane_fallback[4], float r_out[3])
void ED_view3d_win_to_3d_int(const View3D *v3d, const ARegion *region, const float depth_pt[3], const int mval[2], float r_out[3])
float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[3])
void ED_view3d_win_to_3d(const View3D *v3d, const ARegion *region, const float depth_pt[3], const float mval[2], float r_out[3])
void ED_view3d_win_to_delta(const ARegion *region, const float mval[2], float out[3], const float zfac)
void ED_view3d_project_float_v3_m4(const ARegion *region, const float co[3], float r_co[3], float mat[4][4])
float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
bool ED_view3d_clip_segment(const RegionView3D *rv3d, float ray_start[3], float ray_end[3])
eV3DProjStatus ED_view3d_project_float_global(const ARegion *region, const float co[3], float r_co[2], const eV3DProjTest flag)
eV3DProjStatus ED_view3d_project_int_object(const ARegion *region, const float co[3], int r_co[2], const eV3DProjTest flag)
eV3DProjStatus ED_view3d_project_short_global(const ARegion *region, const float co[3], short r_co[2], const eV3DProjTest flag)
void ED_view3d_win_to_origin(const ARegion *region, const float mval[2], float out[3])
eV3DProjStatus ED_view3d_project_int_ex(const ARegion *region, float perspmat[4][4], const bool is_local, const float co[3], int r_co[2], const eV3DProjTest flag)
void ED_view3d_win_to_vector(const ARegion *region, const float mval[2], float out[3])
void ED_view3d_project_float_v2_m4(const ARegion *region, const float co[3], float r_co[2], float mat[4][4])
bool ED_view3d_win_to_ray_clipped(struct Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_normal[3], const bool do_clip_planes)
void ED_view3d_project(const struct ARegion *region, const float world[3], float r_region_co[3])
void ED_view3d_global_to_vector(const RegionView3D *rv3d, const float coord[3], float vec[3])
void ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d, const float obmat[4][4], float r_pmat[4][4])
#define BL_ZERO_CLIP
eV3DProjStatus ED_view3d_project_float_ex(const ARegion *region, float perspmat[4][4], const bool is_local, const float co[3], float r_co[2], const eV3DProjTest flag)
void ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, Object *ob, float r_pmat[4][4])
eV3DProjStatus ED_view3d_project_short_object(const ARegion *region, const float co[3], short r_co[2], const eV3DProjTest flag)
bool ED_view3d_unproject(const struct ARegion *region, float regionx, float regiony, float regionz, float world[3])
eV3DProjStatus ED_view3d_project_int_global(const ARegion *region, const float co[3], int r_co[2], const eV3DProjTest flag)
static eV3DProjStatus ed_view3d_project__internal(const ARegion *region, const float perspmat[4][4], const bool is_local, const float co[3], float r_co[2], const eV3DProjTest flag)
bool ED_view3d_win_to_ray_clipped_ex(struct Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], bool do_clip_planes)
bool ED_view3d_win_to_3d_on_plane_int(const ARegion *region, const float plane[4], const int mval[2], const bool do_clip, float r_out[3])