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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormano-wii <germano.costa@ig.com.br>2019-03-22 04:23:09 +0300
committermano-wii <germano.costa@ig.com.br>2019-03-22 04:23:50 +0300
commit6a65bb4955c0b86cb152d0e15a8ce69bf39bead7 (patch)
treee099dca4b1a773c44b82c86768c4d7ecf1680a1c /source/blender/gpu
parent2b42b8b779cd29dd1d4531103cee6aa69643ac7b (diff)
GPU Matrix: Increase precision of GPU_matrix_unproject.
Diffstat (limited to 'source/blender/gpu')
-rw-r--r--source/blender/gpu/intern/gpu_matrix.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/source/blender/gpu/intern/gpu_matrix.c b/source/blender/gpu/intern/gpu_matrix.c
index b5bee35350e..5ed0f2ee406 100644
--- a/source/blender/gpu/intern/gpu_matrix.c
+++ b/source/blender/gpu/intern/gpu_matrix.c
@@ -453,39 +453,57 @@ void GPU_matrix_project(const float world[3], const float model[4][4], const flo
bool GPU_matrix_unproject(const float win[3], const float model[4][4], const float proj[4][4], const int view[4], float world[3])
{
- float pm[4][4];
- float in[4];
- float out[4];
+ float in[3];
+ float viewinv[4][4];
- mul_m4_m4m4(pm, proj, model);
-
- if (!invert_m4(pm)) {
+ if (!invert_m4_m4(viewinv, model)) {
zero_v3(world);
return false;
}
- in[0] = win[0];
- in[1] = win[1];
- in[2] = win[2];
- in[3] = 1;
+ copy_v3_v3(in, win);
/* Map x and y from window coordinates */
in[0] = (in[0] - view[0]) / view[2];
in[1] = (in[1] - view[1]) / view[3];
+#if 0
+ float projinv[4][4];
+
+ if (!invert_m4_m4(projinv, proj)) {
+ zero_v3(world);
+ return false;
+ }
+
/* Map to range -1 to +1 */
in[0] = 2 * in[0] - 1;
in[1] = 2 * in[1] - 1;
in[2] = 2 * in[2] - 1;
- mul_v4_m4v3(out, pm, in);
+ mul_project_m4_v3(projinv, in);
+#else
+ float left, right, bottom, top, near, far;
+ bool is_persp = proj[3][3] == 0.0f;
+
+ projmat_dimensions(
+ proj, &left, &right, &bottom, &top, &near, &far);
- if (out[3] == 0.0f) {
- copy_v3_v3(world, out);
- return false;
+ in[0] = left + in[0] * (right - left);
+ in[1] = bottom + in[1] * (top - bottom);
+
+ if (is_persp) {
+ in[2] = far * near / (far + in[2] * (near - far));
+ in[0] *= in[2];
+ in[1] *= in[2];
}
+ else {
+ in[2] = near + in[2] * (far - near);
+ }
+
+ in[2] *= -1;
+#endif
- mul_v3_v3fl(world, out, 1.0f / out[3]);
+ mul_v3_m4v3(world, viewinv, in);
return true;
}