Blender V4.3
view3d_project.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2008 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
9#include "DNA_camera_types.h"
10#include "DNA_object_types.h"
11#include "DNA_scene_types.h"
12#include "DNA_screen_types.h"
13#include "DNA_view3d_types.h"
14
15#include "BLI_sys_types.h" /* int64_t */
16
17#include "BLI_math_geom.h"
18#include "BLI_math_matrix.h"
19#include "BLI_math_rotation.h"
20#include "BLI_math_vector.h"
21
22#include "BKE_camera.h"
23#include "BKE_screen.hh"
24
25#include "GPU_matrix.hh"
26
27#include "ED_view3d.hh" /* own include */
28
29#define BL_ZERO_CLIP 0.001
30
31/* Non Clipping Projection Functions
32 * ********************************* */
33
35 const float co[3],
36 const blender::float4x4 &mat)
37{
38 float vec4[4];
39
40 copy_v3_v3(vec4, co);
41 vec4[3] = 1.0;
42 // r_co[0] = IS_CLIPPED; /* Always overwritten. */
43
44 mul_m4_v4(mat.ptr(), vec4);
45
46 blender::float2 r_co;
47 if (vec4[3] > FLT_EPSILON) {
48 r_co[0] = float(region->winx / 2.0f) + (region->winx / 2.0f) * vec4[0] / vec4[3];
49 r_co[1] = float(region->winy / 2.0f) + (region->winy / 2.0f) * vec4[1] / vec4[3];
50 }
51 else {
52 zero_v2(r_co);
53 }
54 return r_co;
55}
56
58 const float co[3],
59 float r_co[3],
60 const float mat[4][4])
61{
62 float vec4[4];
63
64 copy_v3_v3(vec4, co);
65 vec4[3] = 1.0;
66 // r_co[0] = IS_CLIPPED; /* Always overwritten. */
67
68 mul_m4_v4(mat, vec4);
69
70 if (vec4[3] > FLT_EPSILON) {
71 r_co[0] = float(region->winx / 2.0f) + (region->winx / 2.0f) * vec4[0] / vec4[3];
72 r_co[1] = float(region->winy / 2.0f) + (region->winy / 2.0f) * vec4[1] / vec4[3];
73 r_co[2] = vec4[2] / vec4[3];
74 }
75 else {
76 zero_v3(r_co);
77 }
78}
79
80/* Clipping Projection Functions
81 * ***************************** */
82
83eV3DProjStatus ED_view3d_project_base(const ARegion *region, Base *base, float r_co[2])
84{
86 region, base->object->object_to_world().location(), r_co, V3D_PROJ_TEST_CLIP_DEFAULT);
87
88 /* Prevent uninitialized values when projection fails,
89 * although the callers should check the return value. */
90 if (ret != V3D_PROJ_RET_OK) {
91 r_co[0] = -1.0;
92 r_co[1] = -1.0;
93 }
94
95 return ret;
96}
97
104 const float perspmat[4][4],
105 const bool is_local, /* normally hidden */
106 const float co[3],
107 float r_co[2],
108 const eV3DProjTest flag)
109{
110 float vec4[4];
111
112 /* check for bad flags */
114
116 const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
117 if (rv3d->rflag & RV3D_CLIPPING) {
118 if (ED_view3d_clipping_test(rv3d, co, is_local)) {
120 }
121 }
122 }
123
124 copy_v3_v3(vec4, co);
125 vec4[3] = 1.0;
126 mul_m4_v4(perspmat, vec4);
127 const float w = fabsf(vec4[3]);
128
129 if ((flag & V3D_PROJ_TEST_CLIP_ZERO) && (w <= float(BL_ZERO_CLIP))) {
131 }
132
133 if ((flag & V3D_PROJ_TEST_CLIP_NEAR) && (vec4[2] <= -w)) {
135 }
136
137 if ((flag & V3D_PROJ_TEST_CLIP_FAR) && (vec4[2] >= w)) {
139 }
140
141 const float scalar = (w != 0.0f) ? (1.0f / w) : 0.0f;
142 const float fx = (float(region->winx) / 2.0f) * (1.0f + (vec4[0] * scalar));
143 const float fy = (float(region->winy) / 2.0f) * (1.0f + (vec4[1] * scalar));
144
146 (fx <= 0.0f || fy <= 0.0f || fx >= float(region->winx) || fy >= float(region->winy)))
147 {
149 }
150
151 r_co[0] = fx;
152 r_co[1] = fy;
153
154 return V3D_PROJ_RET_OK;
155}
156
158 float perspmat[4][4],
159 const bool is_local,
160 const float co[3],
161 short r_co[2],
162 const eV3DProjTest flag)
163{
164 float tvec[2];
165 eV3DProjStatus ret = ed_view3d_project__internal(region, perspmat, is_local, co, tvec, flag);
166 if (ret == V3D_PROJ_RET_OK) {
167 if ((tvec[0] > -32700.0f && tvec[0] < 32700.0f) && (tvec[1] > -32700.0f && tvec[1] < 32700.0f))
168 {
169 r_co[0] = short(floorf(tvec[0]));
170 r_co[1] = short(floorf(tvec[1]));
171 }
172 else {
174 }
175 }
176 return ret;
177}
178
180 float perspmat[4][4],
181 const bool is_local,
182 const float co[3],
183 int r_co[2],
184 const eV3DProjTest flag)
185{
186 float tvec[2];
187 eV3DProjStatus ret = ed_view3d_project__internal(region, perspmat, is_local, co, tvec, flag);
188 if (ret == V3D_PROJ_RET_OK) {
189 if ((tvec[0] > -2140000000.0f && tvec[0] < 2140000000.0f) &&
190 (tvec[1] > -2140000000.0f && tvec[1] < 2140000000.0f))
191 {
192 r_co[0] = int(floorf(tvec[0]));
193 r_co[1] = int(floorf(tvec[1]));
194 }
195 else {
197 }
198 }
199 return ret;
200}
201
203 float perspmat[4][4],
204 const bool is_local,
205 const float co[3],
206 float r_co[2],
207 const eV3DProjTest flag)
208{
209 float tvec[2];
210 eV3DProjStatus ret = ed_view3d_project__internal(region, perspmat, is_local, co, tvec, flag);
211 if (ret == V3D_PROJ_RET_OK) {
212 if (isfinite(tvec[0]) && isfinite(tvec[1])) {
213 copy_v2_v2(r_co, tvec);
214 }
215 else {
217 }
218 }
219 return ret;
220}
221
223 const float co[3],
224 short r_co[2],
225 const eV3DProjTest flag)
226{
227 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
228 return ED_view3d_project_short_ex(region, rv3d->persmat, false, co, r_co, flag);
229}
231 const float co[3],
232 short r_co[2],
233 const eV3DProjTest flag)
234{
235 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
237 return ED_view3d_project_short_ex(region, rv3d->persmatob, true, co, r_co, flag);
238}
239
241 const float co[3],
242 int r_co[2],
243 const eV3DProjTest flag)
244{
245 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
246 return ED_view3d_project_int_ex(region, rv3d->persmat, false, co, r_co, flag);
247}
249 const float co[3],
250 int r_co[2],
251 const eV3DProjTest flag)
252{
253 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
255 return ED_view3d_project_int_ex(region, rv3d->persmatob, true, co, r_co, flag);
256}
257
259 const float co[3],
260 float r_co[2],
261 const eV3DProjTest flag)
262{
263 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
264 return ED_view3d_project_float_ex(region, rv3d->persmat, false, co, r_co, flag);
265}
267 const float co[3],
268 float r_co[2],
269 const eV3DProjTest flag)
270{
271 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
273 return ED_view3d_project_float_ex(region, rv3d->persmatob, true, co, r_co, flag);
274}
275
276/* More Generic Window/Ray/Vector projection functions
277 * *************************************************** */
278
279float ED_view3d_pixel_size(const RegionView3D *rv3d, const float co[3])
280{
281 return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize * U.pixelsize;
282}
283
284float ED_view3d_pixel_size_no_ui_scale(const RegionView3D *rv3d, const float co[3])
285{
286 return mul_project_m4_v3_zfac(rv3d->persmat, co) * rv3d->pixsize;
287}
288
289float ED_view3d_calc_zfac_ex(const RegionView3D *rv3d, const float co[3], bool *r_flip)
290{
291 float zfac = mul_project_m4_v3_zfac(rv3d->persmat, co);
292
293 if (r_flip) {
294 *r_flip = (zfac < 0.0f);
295 }
296
297 /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that
298 * (accounting for near zero values) */
299 if (zfac < 1.e-6f && zfac > -1.e-6f) {
300 zfac = 1.0f;
301 }
302
303 /* Negative zfac means x, y, z was behind the camera (in perspective).
304 * This gives flipped directions, so revert back to ok default case. */
305 if (zfac < 0.0f) {
306 zfac = -zfac;
307 }
308
309 return zfac;
310}
311
312float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3])
313{
314 return ED_view3d_calc_zfac_ex(rv3d, co, nullptr);
315}
316
317float ED_view3d_calc_depth_for_comparison(const RegionView3D *rv3d, const float co[3])
318{
319 if (rv3d->is_persp) {
320 return ED_view3d_calc_zfac(rv3d, co);
321 }
322 return -dot_v3v3(rv3d->viewinv[2], co);
323}
324
325static void view3d_win_to_ray_segment(const Depsgraph *depsgraph,
326 const ARegion *region,
327 const View3D *v3d,
328 const float mval[2],
329 float r_ray_co[3],
330 float r_ray_dir[3],
331 float r_ray_start[3],
332 float r_ray_end[3])
333{
334 const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
335 float _ray_co[3], _ray_dir[3], start_offset, end_offset;
336
337 if (!r_ray_co) {
338 r_ray_co = _ray_co;
339 }
340 if (!r_ray_dir) {
341 r_ray_dir = _ray_dir;
342 }
343
344 ED_view3d_win_to_origin(region, mval, r_ray_co);
345 ED_view3d_win_to_vector(region, mval, r_ray_dir);
346
347 if ((rv3d->is_persp == false) && (rv3d->persp != RV3D_CAMOB)) {
348 end_offset = v3d->clip_end / 2.0f;
349 start_offset = -end_offset;
350 }
351 else {
352 ED_view3d_clip_range_get(depsgraph, v3d, rv3d, false, &start_offset, &end_offset);
353 }
354
355 if (r_ray_start) {
356 madd_v3_v3v3fl(r_ray_start, r_ray_co, r_ray_dir, start_offset);
357 }
358 if (r_ray_end) {
359 madd_v3_v3v3fl(r_ray_end, r_ray_co, r_ray_dir, end_offset);
360 }
361}
362
363bool ED_view3d_clip_segment(const RegionView3D *rv3d, float ray_start[3], float ray_end[3])
364{
365 if ((rv3d->rflag & RV3D_CLIPPING) &&
366 (clip_segment_v3_plane_n(ray_start, ray_end, rv3d->clip, 6, ray_start, ray_end) == false))
367 {
368 return false;
369 }
370 return true;
371}
372
374 const ARegion *region,
375 const View3D *v3d,
376 const float mval[2],
377 const bool do_clip_planes,
378 float r_ray_co[3],
379 float r_ray_normal[3],
380 float r_ray_start[3],
381 float r_ray_end[3])
382{
384 depsgraph, region, v3d, mval, r_ray_co, r_ray_normal, r_ray_start, r_ray_end);
385
386 /* bounds clipping */
387 if (do_clip_planes) {
389 static_cast<const RegionView3D *>(region->regiondata), r_ray_start, r_ray_end);
390 }
391
392 return true;
393}
394
396 const ARegion *region,
397 const View3D *v3d,
398 const float mval[2],
399 float r_ray_start[3],
400 float r_ray_normal[3],
401 const bool do_clip_planes)
402{
403 float ray_end_dummy[3];
405 region,
406 v3d,
407 mval,
408 do_clip_planes,
409 nullptr,
410 r_ray_normal,
411 r_ray_start,
412 ray_end_dummy);
413}
414
415void ED_view3d_win_to_ray(const ARegion *region,
416 const float mval[2],
417 float r_ray_start[3],
418 float r_ray_normal[3])
419{
420 ED_view3d_win_to_origin(region, mval, r_ray_start);
421 ED_view3d_win_to_vector(region, mval, r_ray_normal);
422}
423
424void ED_view3d_global_to_vector(const RegionView3D *rv3d, const float coord[3], float r_out[3])
425{
426 if (rv3d->is_persp) {
427 float p1[4], p2[4];
428
429 copy_v3_v3(p1, coord);
430 p1[3] = 1.0f;
431 copy_v3_v3(p2, p1);
432 p2[3] = 1.0f;
433 mul_m4_v4(rv3d->viewmat, p2);
434
435 mul_v3_fl(p2, 2.0f);
436
437 mul_m4_v4(rv3d->viewinv, p2);
438
439 sub_v3_v3v3(r_out, p1, p2);
440 }
441 else {
442 copy_v3_v3(r_out, rv3d->viewinv[2]);
443 }
444 normalize_v3(r_out);
445}
446
447/* very similar to ED_view3d_win_to_3d() but has no advantage, de-duplicating */
448#if 0
449bool view3d_get_view_aligned_coordinate(ARegion *region,
450 float fp[3],
451 const int mval[2],
452 const bool do_fallback)
453{
454 RegionView3D *rv3d = region->regiondata;
455 float dvec[3];
456 int mval_cpy[2];
458
459 ret = ED_view3d_project_int_global(region, fp, mval_cpy, V3D_PROJ_TEST_NOP);
460
461 if (ret == V3D_PROJ_RET_OK) {
462 const float mval_f[2] = {float(mval_cpy[0] - mval[0]), float(mval_cpy[1] - mval[1])};
463 const float zfac = ED_view3d_calc_zfac(rv3d, fp);
464 ED_view3d_win_to_delta(region, mval_f, zfac, dvec);
465 sub_v3_v3(fp, dvec);
466
467 return true;
468 }
469 else {
470 /* fallback to the view center */
471 if (do_fallback) {
472 negate_v3_v3(fp, rv3d->ofs);
473 return view3d_get_view_aligned_coordinate(region, fp, mval, false);
474 }
475 else {
476 return false;
477 }
478 }
479}
480#endif
481
483 const ARegion *region,
484 const float depth_pt[3],
485 const float mval[2],
486 float r_out[3])
487{
488 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
489
490 float ray_origin[3];
491 float ray_direction[3];
492 float lambda;
493
494 if (rv3d->is_persp) {
495 copy_v3_v3(ray_origin, rv3d->viewinv[3]);
496 ED_view3d_win_to_vector(region, mval, ray_direction);
497
498 /* NOTE: we could use #isect_line_plane_v3()
499 * however we want the intersection to be in front of the view no matter what,
500 * so apply the unsigned factor instead. */
501 isect_ray_plane_v3_factor(ray_origin, ray_direction, depth_pt, rv3d->viewinv[2], &lambda);
502
503 lambda = fabsf(lambda);
504 }
505 else {
506 float dx = (2.0f * mval[0] / float(region->winx)) - 1.0f;
507 float dy = (2.0f * mval[1] / float(region->winy)) - 1.0f;
508
509 if (rv3d->persp == RV3D_CAMOB) {
510 /* ortho camera needs offset applied */
511 const Camera *cam = static_cast<const Camera *>(v3d->camera->data);
512 const int sensor_fit = BKE_camera_sensor_fit(cam->sensor_fit, region->winx, region->winy);
513 const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 4.0f;
514 const float aspx = region->winx / float(region->winy);
515 const float aspy = region->winy / float(region->winx);
516 const float shiftx = cam->shiftx * 0.5f *
517 (sensor_fit == CAMERA_SENSOR_FIT_HOR ? 1.0f : aspy);
518 const float shifty = cam->shifty * 0.5f *
519 (sensor_fit == CAMERA_SENSOR_FIT_HOR ? aspx : 1.0f);
520
521 dx += (rv3d->camdx + shiftx) * zoomfac;
522 dy += (rv3d->camdy + shifty) * zoomfac;
523 }
524 ray_origin[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
525 ray_origin[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
526 ray_origin[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2];
527
528 copy_v3_v3(ray_direction, rv3d->viewinv[2]);
529 lambda = ray_point_factor_v3(depth_pt, ray_origin, ray_direction);
530 }
531
532 madd_v3_v3v3fl(r_out, ray_origin, ray_direction, lambda);
533}
534
536 const ARegion *region,
537 const float depth_pt[3],
538 const int mval[2],
539 float r_out[3])
540{
541 const float mval_fl[2] = {float(mval[0]), float(mval[1])};
542 ED_view3d_win_to_3d(v3d, region, depth_pt, mval_fl, r_out);
543}
544
546 const float plane[4],
547 const float mval[2],
548 const bool do_clip,
549 float r_out[3])
550{
551 const RegionView3D *rv3d = static_cast<const RegionView3D *>(region->regiondata);
552 const bool ray_co_is_centered = rv3d->is_persp == false && rv3d->persp != RV3D_CAMOB;
553 const bool do_clip_ray_plane = do_clip && !ray_co_is_centered;
554 float ray_co[3], ray_no[3];
555 ED_view3d_win_to_origin(region, mval, ray_co);
556 ED_view3d_win_to_vector(region, mval, ray_no);
557 float lambda;
558 if (isect_ray_plane_v3(ray_co, ray_no, plane, &lambda, do_clip_ray_plane)) {
559 madd_v3_v3v3fl(r_out, ray_co, ray_no, lambda);
560
561 /* Handle clipping with an orthographic view differently,
562 * check if the resulting point is behind the view instead of clipping the ray. */
563 if (do_clip && (do_clip_ray_plane == false)) {
564 /* The offset is unit length where over 1.0 is beyond the views clip-plane (near and far)
565 * as non-camera orthographic views only use far distance in both directions.
566 * Multiply `r_out` by `persmat` (with translation), and get it's Z value. */
567 const float z_offset = fabsf(dot_m4_v3_row_z(rv3d->persmat, r_out) + rv3d->persmat[3][2]);
568 if (z_offset > 1.0f) {
569 return false;
570 }
571 }
572 return true;
573 }
574 return false;
575}
576
578 const float plane[4],
579 const int mval[2],
580 const bool do_clip,
581 float r_out[3])
582{
583 const float mval_fl[2] = {float(mval[0]), float(mval[1])};
584 return ED_view3d_win_to_3d_on_plane(region, plane, mval_fl, do_clip, r_out);
585}
586
588 const float plane[4],
589 const float mval[2],
590 const bool do_clip,
591 const float plane_fallback[4],
592 float r_out[3])
593{
594 float isect_co[3], isect_no[3];
595 if (!isect_plane_plane_v3(plane, plane_fallback, isect_co, isect_no)) {
596 return false;
597 }
598 normalize_v3(isect_no);
599
600 /* Construct matrix to transform `plane_fallback` onto `plane`. */
601 float mat4[4][4];
602 {
603 float mat3[3][3];
604 rotation_between_vecs_to_mat3(mat3, plane, plane_fallback);
605 copy_m4_m3(mat4, mat3);
606 transform_pivot_set_m4(mat4, isect_co);
607 }
608
609 float co[3];
610 if (!ED_view3d_win_to_3d_on_plane(region, plane_fallback, mval, do_clip, co)) {
611 return false;
612 }
613 mul_m4_v3(mat4, co);
614
615 /* While the point is already on the plane, there may be some small in-precision
616 * so ensure the point is exactly on the plane. */
617 closest_to_plane_v3(r_out, plane, co);
618
619 return true;
620}
621
623 const float xy_delta[2],
624 const float zfac,
625 float r_out[3])
626{
627 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
628 float dx, dy;
629
630 dx = 2.0f * xy_delta[0] * zfac / region->winx;
631 dy = 2.0f * xy_delta[1] * zfac / region->winy;
632
633 r_out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy);
634 r_out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy);
635 r_out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy);
636}
637
638void ED_view3d_win_to_origin(const ARegion *region, const float mval[2], float r_out[3])
639{
640 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
641 if (rv3d->is_persp) {
642 copy_v3_v3(r_out, rv3d->viewinv[3]);
643 }
644 else {
645 r_out[0] = 2.0f * mval[0] / region->winx - 1.0f;
646 r_out[1] = 2.0f * mval[1] / region->winy - 1.0f;
647
648 if (rv3d->persp == RV3D_CAMOB) {
649 r_out[2] = -1.0f;
650 }
651 else {
652 r_out[2] = 0.0f;
653 }
654
655 mul_project_m4_v3(rv3d->persinv, r_out);
656 }
657}
658
659void ED_view3d_win_to_vector(const ARegion *region, const float mval[2], float r_out[3])
660{
661 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
662
663 if (rv3d->is_persp) {
664 r_out[0] = 2.0f * (mval[0] / region->winx) - 1.0f;
665 r_out[1] = 2.0f * (mval[1] / region->winy) - 1.0f;
666 r_out[2] = -0.5f;
667 mul_project_m4_v3(rv3d->persinv, r_out);
668 sub_v3_v3(r_out, rv3d->viewinv[3]);
669 }
670 else {
671 negate_v3_v3(r_out, rv3d->viewinv[2]);
672 }
673 normalize_v3(r_out);
674}
675
677 const ARegion *region,
678 const View3D *v3d,
679 const float mval[2],
680 float r_ray_start[3],
681 float r_ray_end[3],
682 const bool do_clip_planes)
683{
685 depsgraph, region, v3d, mval, nullptr, nullptr, r_ray_start, r_ray_end);
686
687 /* bounds clipping */
688 if (do_clip_planes) {
689 return ED_view3d_clip_segment((RegionView3D *)region->regiondata, r_ray_start, r_ray_end);
690 }
691
692 return true;
693}
694
695/* -------------------------------------------------------------------- */
700{
701 float vmat[4][4];
702 blender::float4x4 r_pmat;
703
704 mul_m4_m4m4(vmat, rv3d->viewmat, ob->object_to_world().ptr());
705 mul_m4_m4m4(r_pmat.ptr(), rv3d->winmat, vmat);
706 return r_pmat;
707}
708
714
715void ED_view3d_project_v3(const ARegion *region, const float world[3], float r_region_co[3])
716{
717 /* Viewport is set up to make coordinates relative to the region, not window. */
718 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
719 const int viewport[4] = {0, 0, region->winx, region->winy};
720 GPU_matrix_project_3fv(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co);
721}
722
723void ED_view3d_project_v2(const ARegion *region, const float world[3], float r_region_co[2])
724{
725 /* Viewport is set up to make coordinates relative to the region, not window. */
726 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
727 const int viewport[4] = {0, 0, region->winx, region->winy};
728 GPU_matrix_project_2fv(world, rv3d->viewmat, rv3d->winmat, viewport, r_region_co);
729}
730
732 const ARegion *region, float regionx, float regiony, float regionz, float world[3])
733{
734 RegionView3D *rv3d = static_cast<RegionView3D *>(region->regiondata);
735 const int viewport[4] = {0, 0, region->winx, region->winy};
736 const float region_co[3] = {regionx, regiony, regionz};
737
738 return GPU_matrix_unproject_3fv(region_co, rv3d->viewinv, rv3d->winmat, viewport, world);
739}
740
Camera data-block and utility functions.
int BKE_camera_sensor_fit(int sensor_fit, float sizex, float sizey)
float BKE_screen_view3d_zoom_to_fac(float camzoom)
Definition screen.cc:998
#define BLI_assert(a)
Definition BLI_assert.h:50
bool clip_segment_v3_plane_n(const float p1[3], const float p2[3], const float plane_array[][4], int plane_num, float r_p1[3], float r_p2[3])
bool isect_ray_plane_v3(const float ray_origin[3], const float ray_direction[3], const float plane[4], float *r_lambda, bool clip)
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
float ray_point_factor_v3(const float p[3], const float ray_origin[3], const float ray_direction[3])
bool isect_ray_plane_v3_factor(const float ray_origin[3], const float ray_direction[3], const float plane_co[3], const float plane_no[3], float *r_lambda)
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
Definition math_geom.cc:433
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void copy_m4_m3(float m1[4][4], const float m2[3][3])
void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
void mul_project_m4_v3(const float mat[4][4], float vec[3])
void mul_m4_v3(const float M[4][4], float r[3])
void mul_m4_v4(const float mat[4][4], float r[4])
void rotation_between_vecs_to_mat3(float m[3][3], const float v1[3], const float v2[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 float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float dot_m4_v3_row_z(const float M[4][4], const float a[3]) ATTR_WARN_UNUSED_RESULT
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])
MINLINE float normalize_v3(float n[3])
@ CAMERA_SENSOR_FIT_HOR
Object is a sort of wrapper for general info.
@ RV3D_CLIPPING
@ RV3D_CAMOB
void ED_view3d_check_mats_rv3d(RegionView3D *rv3d)
eV3DProjTest
Definition ED_view3d.hh:265
@ V3D_PROJ_TEST_CLIP_FAR
Definition ED_view3d.hh:270
@ V3D_PROJ_TEST_CLIP_NEAR
Definition ED_view3d.hh:269
@ V3D_PROJ_TEST_CLIP_ZERO
Definition ED_view3d.hh:271
@ V3D_PROJ_TEST_NOP
Definition ED_view3d.hh:266
@ V3D_PROJ_TEST_CLIP_WIN
Definition ED_view3d.hh:268
@ V3D_PROJ_TEST_CLIP_BB
Definition ED_view3d.hh:267
eV3DProjStatus
Definition ED_view3d.hh:242
@ V3D_PROJ_RET_CLIP_WIN
Definition ED_view3d.hh:258
@ V3D_PROJ_RET_CLIP_BB
Definition ED_view3d.hh:256
@ V3D_PROJ_RET_CLIP_FAR
Definition ED_view3d.hh:247
@ V3D_PROJ_RET_CLIP_ZERO
Definition ED_view3d.hh:254
@ V3D_PROJ_RET_CLIP_NEAR
Definition ED_view3d.hh:245
@ V3D_PROJ_RET_OVERFLOW
Definition ED_view3d.hh:260
@ V3D_PROJ_RET_OK
Definition ED_view3d.hh:243
bool ED_view3d_clip_range_get(const Depsgraph *depsgraph, const View3D *v3d, const RegionView3D *rv3d, bool use_ortho_factor, float *r_clip_start, float *r_clip_end)
#define V3D_PROJ_TEST_CLIP_DEFAULT
Definition ED_view3d.hh:296
#define V3D_PROJ_TEST_ALL
Definition ED_view3d.hh:298
bool ED_view3d_clipping_test(const RegionView3D *rv3d, const float co[3], bool is_local)
void GPU_matrix_project_2fv(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float r_win[2])
bool GPU_matrix_unproject_3fv(const float win[3], const float model_inverted[4][4], const float proj[4][4], const int view[4], float r_world[3])
void GPU_matrix_project_3fv(const float world[3], const float model[4][4], const float proj[4][4], const int view[4], float r_win[3])
unsigned int U
Definition btGjkEpa3.h:78
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition btQuadWord.h:119
const Depsgraph * depsgraph
#define floorf(x)
#define fabsf(x)
draw_view in_light_buf[] float
draw_view push_constant(Type::INT, "radiance_src") .push_constant(Type capture_info_buf storage_buf(1, Qualifier::READ, "ObjectBounds", "bounds_buf[]") .push_constant(Type draw_view int
velocity_obj_prev_buf[] vec4
MatView< float, 4, 4, 4, 4, 0, 0, alignof(float)> float4x4_view
return ret
struct Object * object
char sensor_fit
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]
struct Object * camera
const c_style_mat & ptr() const
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(const Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], float r_ray_start[3], float r_ray_end[3], const bool do_clip_planes)
blender::float2 ED_view3d_project_float_v2_m4(const ARegion *region, const float co[3], const blender::float4x4 &mat)
void ED_view3d_project_float_v3_m4(const ARegion *region, const float co[3], float r_co[3], const float mat[4][4])
void ED_view3d_win_to_ray(const ARegion *region, const float mval[2], float r_ray_start[3], float r_ray_normal[3])
void ED_view3d_global_to_vector(const RegionView3D *rv3d, const float coord[3], float r_out[3])
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)
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 xy_delta[2], const float zfac, float r_out[3])
float ED_view3d_calc_depth_for_comparison(const RegionView3D *rv3d, const float co[3])
bool ED_view3d_win_to_ray_clipped(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)
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)
void ED_view3d_project_v2(const ARegion *region, const float world[3], float r_region_co[2])
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)
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)
blender::float4x4 ED_view3d_ob_project_mat_get(const RegionView3D *rv3d, const Object *ob)
bool ED_view3d_unproject_v3(const ARegion *region, float regionx, float regiony, float regionz, float world[3])
float ED_view3d_calc_zfac_ex(const RegionView3D *rv3d, const float co[3], bool *r_flip)
void ED_view3d_win_to_origin(const ARegion *region, const float mval[2], float r_out[3])
static void view3d_win_to_ray_segment(const 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])
float ED_view3d_calc_zfac(const RegionView3D *rv3d, const float co[3])
#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)
bool ED_view3d_win_to_ray_clipped_ex(Depsgraph *depsgraph, const ARegion *region, const View3D *v3d, const float mval[2], const bool do_clip_planes, float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], float r_ray_end[3])
eV3DProjStatus ED_view3d_project_short_object(const ARegion *region, const float co[3], short r_co[2], const eV3DProjTest flag)
void ED_view3d_project_v3(const ARegion *region, const float world[3], float r_region_co[3])
eV3DProjStatus ED_view3d_project_base(const ARegion *region, Base *base, float r_co[2])
blender::float4x4 ED_view3d_ob_project_mat_get_from_obmat(const RegionView3D *rv3d, const blender::float4x4 &obmat)
void ED_view3d_win_to_vector(const ARegion *region, const float mval[2], float r_out[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_3d_on_plane_int(const ARegion *region, const float plane[4], const int mval[2], const bool do_clip, float r_out[3])
uint8_t flag
Definition wm_window.cc:138