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:
authorBastien Montagne <montagne29@wanadoo.fr>2016-06-07 10:58:27 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2016-06-07 10:59:26 +0300
commit24d29f2e500771257cc962e899630edaccb01cfe (patch)
tree600780f0dab7f3efe5477eb24d59c533bc2abdc6 /source/blender/render
parent11af9e9a5bd1caff1ec46794bda2934a01ce5035 (diff)
parent3054e33d67c8f524dae915c8f1f016a7bfa63ab0 (diff)
Merge branch 'master' into blender2.8
Conflicts: source/blender/blenkernel/intern/particle.c source/blender/editors/transform/transform_snap_object.c
Diffstat (limited to 'source/blender/render')
-rw-r--r--source/blender/render/intern/include/rayintersection.h5
-rw-r--r--source/blender/render/intern/raytrace/rayobject.cpp149
-rw-r--r--source/blender/render/intern/source/render_result.c76
3 files changed, 78 insertions, 152 deletions
diff --git a/source/blender/render/intern/include/rayintersection.h b/source/blender/render/intern/include/rayintersection.h
index 3607e66a237..1935e4ef59c 100644
--- a/source/blender/render/intern/include/rayintersection.h
+++ b/source/blender/render/intern/include/rayintersection.h
@@ -38,6 +38,8 @@
extern "C" {
#endif
+#include "BLI_math_geom.h"
+
struct RayObject;
/* Ray Hints */
@@ -101,6 +103,9 @@ typedef struct Isect {
#ifdef RE_RAYCOUNTER
RayCounter *raycounter;
#endif
+
+ /* Precalculated coefficients for watertight intersection check. */
+ struct IsectRayPrecalc isect_precalc;
} Isect;
/* ray types */
diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp
index de6b9139363..f511042749e 100644
--- a/source/blender/render/intern/raytrace/rayobject.cpp
+++ b/source/blender/render/intern/raytrace/rayobject.cpp
@@ -138,80 +138,29 @@ MALWAYS_INLINE int vlr_check_bake(Isect *is, ObjectInstanceRen *obi, VlakRen *UN
/* Ray Triangle/Quad Intersection */
-MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, float uv[2], float *lambda)
+MALWAYS_INLINE int isec_tri_quad(float start[3], const struct IsectRayPrecalc *isect_precalc, RayFace *face, float r_uv[2], float *lambda)
{
- float co1[3], co2[3], co3[3], co4[3];
- float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1, l;
- int quad;
-
- quad = RE_rayface_isQuad(face);
-
- copy_v3_v3(co1, face->v1);
- copy_v3_v3(co2, face->v2);
- copy_v3_v3(co3, face->v3);
-
- copy_v3_v3(r, dir);
-
- /* intersect triangle */
- sub_v3_v3v3(t0, co3, co2);
- sub_v3_v3v3(t1, co3, co1);
-
- cross_v3_v3v3(x, r, t1);
- divdet = dot_v3v3(t0, x);
-
- sub_v3_v3v3(m, start, co3);
- det1 = dot_v3v3(m, x);
-
- if (divdet != 0.0f) {
- divdet = 1.0f / divdet;
- v = det1 * divdet;
-
- if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
- float cros[3];
-
- cross_v3_v3v3(cros, m, t0);
- u = divdet * dot_v3v3(cros, r);
-
- if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
- l = divdet * dot_v3v3(cros, t1);
-
- /* check if intersection is within ray length */
- if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
- uv[0] = u;
- uv[1] = v;
- *lambda = l;
- return 1;
- }
- }
+ float uv[2], l;
+
+ if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v2, face->v3, &l, uv)) {
+ /* check if intersection is within ray length */
+ if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
+ r_uv[0] = uv[0];
+ r_uv[1] = uv[1];
+ *lambda = l;
+ return 1;
}
}
/* intersect second triangle in quad */
- if (quad) {
- copy_v3_v3(co4, face->v4);
- sub_v3_v3v3(t0, co3, co4);
- divdet = dot_v3v3(t0, x);
-
- if (divdet != 0.0f) {
- divdet = 1.0f / divdet;
- v = det1 * divdet;
-
- if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
- float cros[3];
-
- cross_v3_v3v3(cros, m, t0);
- u = divdet * dot_v3v3(cros, r);
-
- if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON)) {
- l = divdet * dot_v3v3(cros, t1);
-
- if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
- uv[0] = u;
- uv[1] = -(1.0f + v + u);
- *lambda = l;
- return 2;
- }
- }
+ if (RE_rayface_isQuad(face)) {
+ if (isect_ray_tri_watertight_v3(start, isect_precalc, face->v1, face->v3, face->v4, &l, uv)) {
+ /* check if intersection is within ray length */
+ if (l > -RE_RAYTRACE_EPSILON && l < *lambda) {
+ r_uv[0] = uv[0];
+ r_uv[1] = uv[1];
+ *lambda = l;
+ return 2;
}
}
}
@@ -223,62 +172,23 @@ MALWAYS_INLINE int isec_tri_quad(float start[3], float dir[3], RayFace *face, fl
MALWAYS_INLINE int isec_tri_quad_neighbour(float start[3], float dir[3], RayFace *face)
{
- float co1[3], co2[3], co3[3], co4[3];
- float t0[3], t1[3], x[3], r[3], m[3], u, v, divdet, det1;
- int quad;
-
- quad = RE_rayface_isQuad(face);
+ float r[3];
+ struct IsectRayPrecalc isect_precalc;
+ float uv[2], l;
- copy_v3_v3(co1, face->v1);
- copy_v3_v3(co2, face->v2);
- copy_v3_v3(co3, face->v3);
negate_v3_v3(r, dir); /* note, different than above function */
- /* intersect triangle */
- sub_v3_v3v3(t0, co3, co2);
- sub_v3_v3v3(t1, co3, co1);
-
- cross_v3_v3v3(x, r, t1);
- divdet = dot_v3v3(t0, x);
-
- sub_v3_v3v3(m, start, co3);
- det1 = dot_v3v3(m, x);
-
- if (divdet != 0.0f) {
- divdet = 1.0f / divdet;
- v = det1 * divdet;
-
- if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
- float cros[3];
-
- cross_v3_v3v3(cros, m, t0);
- u = divdet * dot_v3v3(cros, r);
+ isect_ray_tri_watertight_v3_precalc(&isect_precalc, r);
- if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
- return 1;
- }
+ if (isect_ray_tri_watertight_v3(start, &isect_precalc, face->v1, face->v2, face->v3, &l, uv)) {
+ return 1;
}
/* intersect second triangle in quad */
- if (quad) {
- copy_v3_v3(co4, face->v4);
- sub_v3_v3v3(t0, co3, co4);
- divdet = dot_v3v3(t0, x);
-
- if (divdet != 0.0f) {
- divdet = 1.0f / divdet;
- v = det1 * divdet;
-
- if (v < RE_RAYTRACE_EPSILON && v > -(1.0f + RE_RAYTRACE_EPSILON)) {
- float cros[3];
-
- cross_v3_v3v3(cros, m, t0);
- u = divdet * dot_v3v3(cros, r);
-
- if (u < RE_RAYTRACE_EPSILON && (v + u) > -(1.0f + RE_RAYTRACE_EPSILON))
- return 2;
- }
+ if (RE_rayface_isQuad(face)) {
+ if (isect_ray_tri_watertight_v3(start, &isect_precalc, face->v1, face->v3, face->v4, &l, uv)) {
+ return 2;
}
}
@@ -317,7 +227,7 @@ MALWAYS_INLINE int intersect_rayface(RayObject *hit_obj, RayFace *face, Isect *i
RE_RC_COUNT(is->raycounter->faces.test);
dist = is->dist;
- ok = isec_tri_quad(is->start, is->dir, face, uv, &dist);
+ ok = isec_tri_quad(is->start, &is->isect_precalc, face, uv, &dist);
if (ok) {
@@ -389,6 +299,9 @@ int RE_rayobject_raycast(RayObject *r, Isect *isec)
{
int i;
+ /* Pre-calculate orientation for watertight intersection checks. */
+ isect_ray_tri_watertight_v3_precalc(&isec->isect_precalc, isec->dir);
+
RE_RC_COUNT(isec->raycounter->raycast.test);
/* setup vars used on raycast */
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index 2d26fcf4905..bddd84c45d7 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -359,102 +359,109 @@ static const char *name_from_passtype(int passtype, int channel)
return "Unknown";
}
-static int passtype_from_name(const char *str)
+static int passtype_from_name(const char *str, int passflag)
{
+ /* We do not really support several pass of the same types, so in case we are opening an EXR file with several pass
+ * names detected as same pass type, only return that pass type the first time, and return 'uknown' for the others.
+ * See T48466. */
+#define RETURN_PASS(_passtype) return (passflag & (_passtype)) ? 0 : (_passtype)
+
if (STRPREFIX(str, "Combined"))
- return SCE_PASS_COMBINED;
+ RETURN_PASS(SCE_PASS_COMBINED);
if (STRPREFIX(str, "Depth"))
- return SCE_PASS_Z;
+ RETURN_PASS(SCE_PASS_Z);
if (STRPREFIX(str, "Vector"))
- return SCE_PASS_VECTOR;
+ RETURN_PASS(SCE_PASS_VECTOR);
if (STRPREFIX(str, "Normal"))
- return SCE_PASS_NORMAL;
+ RETURN_PASS(SCE_PASS_NORMAL);
if (STRPREFIX(str, "UV"))
- return SCE_PASS_UV;
+ RETURN_PASS(SCE_PASS_UV);
if (STRPREFIX(str, "Color"))
- return SCE_PASS_RGBA;
+ RETURN_PASS(SCE_PASS_RGBA);
if (STRPREFIX(str, "Emit"))
- return SCE_PASS_EMIT;
+ RETURN_PASS(SCE_PASS_EMIT);
if (STRPREFIX(str, "Diffuse"))
- return SCE_PASS_DIFFUSE;
+ RETURN_PASS(SCE_PASS_DIFFUSE);
if (STRPREFIX(str, "Spec"))
- return SCE_PASS_SPEC;
+ RETURN_PASS(SCE_PASS_SPEC);
if (STRPREFIX(str, "Shadow"))
- return SCE_PASS_SHADOW;
+ RETURN_PASS(SCE_PASS_SHADOW);
if (STRPREFIX(str, "AO"))
- return SCE_PASS_AO;
+ RETURN_PASS(SCE_PASS_AO);
if (STRPREFIX(str, "Env"))
- return SCE_PASS_ENVIRONMENT;
+ RETURN_PASS(SCE_PASS_ENVIRONMENT);
if (STRPREFIX(str, "Indirect"))
- return SCE_PASS_INDIRECT;
+ RETURN_PASS(SCE_PASS_INDIRECT);
if (STRPREFIX(str, "Reflect"))
- return SCE_PASS_REFLECT;
+ RETURN_PASS(SCE_PASS_REFLECT);
if (STRPREFIX(str, "Refract"))
- return SCE_PASS_REFRACT;
+ RETURN_PASS(SCE_PASS_REFRACT);
if (STRPREFIX(str, "IndexOB"))
- return SCE_PASS_INDEXOB;
+ RETURN_PASS(SCE_PASS_INDEXOB);
if (STRPREFIX(str, "IndexMA"))
- return SCE_PASS_INDEXMA;
+ RETURN_PASS(SCE_PASS_INDEXMA);
if (STRPREFIX(str, "Mist"))
- return SCE_PASS_MIST;
+ RETURN_PASS(SCE_PASS_MIST);
if (STRPREFIX(str, "RayHits"))
- return SCE_PASS_RAYHITS;
+ RETURN_PASS(SCE_PASS_RAYHITS);
if (STRPREFIX(str, "DiffDir"))
- return SCE_PASS_DIFFUSE_DIRECT;
+ RETURN_PASS(SCE_PASS_DIFFUSE_DIRECT);
if (STRPREFIX(str, "DiffInd"))
- return SCE_PASS_DIFFUSE_INDIRECT;
+ RETURN_PASS(SCE_PASS_DIFFUSE_INDIRECT);
if (STRPREFIX(str, "DiffCol"))
- return SCE_PASS_DIFFUSE_COLOR;
+ RETURN_PASS(SCE_PASS_DIFFUSE_COLOR);
if (STRPREFIX(str, "GlossDir"))
- return SCE_PASS_GLOSSY_DIRECT;
+ RETURN_PASS(SCE_PASS_GLOSSY_DIRECT);
if (STRPREFIX(str, "GlossInd"))
- return SCE_PASS_GLOSSY_INDIRECT;
+ RETURN_PASS(SCE_PASS_GLOSSY_INDIRECT);
if (STRPREFIX(str, "GlossCol"))
- return SCE_PASS_GLOSSY_COLOR;
+ RETURN_PASS(SCE_PASS_GLOSSY_COLOR);
if (STRPREFIX(str, "TransDir"))
- return SCE_PASS_TRANSM_DIRECT;
+ RETURN_PASS(SCE_PASS_TRANSM_DIRECT);
if (STRPREFIX(str, "TransInd"))
- return SCE_PASS_TRANSM_INDIRECT;
+ RETURN_PASS(SCE_PASS_TRANSM_INDIRECT);
if (STRPREFIX(str, "TransCol"))
- return SCE_PASS_TRANSM_COLOR;
+ RETURN_PASS(SCE_PASS_TRANSM_COLOR);
if (STRPREFIX(str, "SubsurfaceDir"))
- return SCE_PASS_SUBSURFACE_DIRECT;
+ RETURN_PASS(SCE_PASS_SUBSURFACE_DIRECT);
if (STRPREFIX(str, "SubsurfaceInd"))
- return SCE_PASS_SUBSURFACE_INDIRECT;
+ RETURN_PASS(SCE_PASS_SUBSURFACE_INDIRECT);
if (STRPREFIX(str, "SubsurfaceCol"))
- return SCE_PASS_SUBSURFACE_COLOR;
+ RETURN_PASS(SCE_PASS_SUBSURFACE_COLOR);
return 0;
+
+#undef RETURN_PASS
}
@@ -838,8 +845,9 @@ static void ml_addpass_cb(void *base, void *lay, const char *str, float *rect, i
BLI_addtail(&rl->passes, rpass);
rpass->channels = totchan;
- rpass->passtype = passtype_from_name(str);
- if (rpass->passtype == 0) printf("unknown pass %s\n", str);
+ rpass->passtype = passtype_from_name(str, rl->passflag);
+ if (rpass->passtype == 0)
+ printf("unknown pass %s\n", str);
rl->passflag |= rpass->passtype;
/* channel id chars */