Commit: 8d297394ba51246f2db0d503df7f4cae19ca6e92
Author: Dalai Felinto
Date:   Wed May 21 15:04:59 2014 -0300
https://developer.blender.org/rB8d297394ba51246f2db0d503df7f4cae19ca6e92

Bake API: partial fix T40156 (applyRotation issues)

This fixes most of the cases, the only situation not addressed is when
the highpoly object(s) has non-uniform scale.

mul_transposed_mat3_m4_v3() should take care of non-uniform scales so
I'm a bit confused on why it doesn't work. The lowpoly object can have
any transformation, the only issue is if the highpoly object has
non-uniform scale.

Test file of the remaining issue:
https://developer.blender.org/file/info/PHID-FILE-tpw2xgddyzxtpg3e7xzs/

Reference reading:
http://www.unknownroad.com/rtfm/graphics/rt_normals.html

===================================================================

M       source/blender/editors/object/object_bake_api.c
M       source/blender/render/extern/include/RE_bake.h
M       source/blender/render/intern/source/bake_api.c

===================================================================

diff --git a/source/blender/editors/object/object_bake_api.c 
b/source/blender/editors/object/object_bake_api.c
index b344bf3..8a946e3 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -610,8 +610,9 @@ static int bake(
                        highpoly[i].ob->restrictflag &= ~OB_RESTRICT_RENDER;
 
                        /* lowpoly to highpoly transformation matrix */
-                       invert_m4_m4(highpoly[i].mat_lowtohigh, 
highpoly[i].ob->obmat);
-                       mul_m4_m4m4(highpoly[i].mat_lowtohigh, 
highpoly[i].mat_lowtohigh, mat_low);
+                       copy_m4_m4(highpoly[i].mat_high, highpoly[i].ob->obmat);
+                       invert_m4_m4(highpoly[i].imat_high, 
highpoly[i].mat_high);
+                       highpoly[i].scale = mat4_to_scale(highpoly[i].mat_high);
 
                        i++;
                }
@@ -626,7 +627,7 @@ static int bake(
                /* populate the pixel arrays with the corresponding face data 
for each high poly object */
                RE_bake_pixels_populate_from_objects(
                        me_low, pixel_array_low, highpoly, tot_highpoly,
-                       num_pixels, cage_extrusion);
+                       num_pixels, cage_extrusion, mat_low);
 
                /* the baking itself */
                for (i = 0; i < tot_highpoly; i++) {
@@ -697,7 +698,7 @@ static int bake(
                        case R_BAKE_SPACE_TANGENT:
                        {
                                if (is_highpoly) {
-                                       
RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, 
me_low, normal_swizzle);
+                                       
RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, 
me_low, normal_swizzle, ob_low->obmat);
                                }
                                else {
                                        /* from multiresolution */
@@ -715,7 +716,7 @@ static int bake(
                                        me_nores = 
BKE_mesh_new_from_object(bmain, scene, ob_low, 1, 2, 1, 0);
                                        RE_bake_pixels_populate(me_nores, 
pixel_array_low, num_pixels, &bake_images);
 
-                                       
RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, 
me_nores, normal_swizzle);
+                                       
RE_bake_normal_world_to_tangent(pixel_array_low, num_pixels, depth, result, 
me_nores, normal_swizzle, ob_low->obmat);
                                        BKE_libblock_free(bmain, me_nores);
 
                                        if (md)
diff --git a/source/blender/render/extern/include/RE_bake.h 
b/source/blender/render/extern/include/RE_bake.h
index d59819c..6ae8300 100644
--- a/source/blender/render/extern/include/RE_bake.h
+++ b/source/blender/render/extern/include/RE_bake.h
@@ -61,7 +61,9 @@ typedef struct BakeHighPolyData {
        struct ModifierData *tri_mod;
        struct Mesh *me;
        char restrict_flag;
-       float mat_lowtohigh[4][4];
+       float mat_high[4][4];
+       float imat_high[4][4];
+       float scale;
 } BakeHighPolyData;
 
 /* external_engine.c */
@@ -80,7 +82,7 @@ bool RE_bake_internal(
 void RE_bake_pixels_populate_from_objects(
         struct Mesh *me_low, BakePixel pixel_array_from[],
         BakeHighPolyData highpoly[], const int tot_highpoly, const int 
num_pixels,
-        const float cage_extrusion);
+        const float cage_extrusion, float mat_low[4][4]);
 
 void RE_bake_pixels_populate(
         struct Mesh *me, struct BakePixel *pixel_array,
@@ -95,7 +97,7 @@ void RE_bake_normal_world_to_object(
         struct Object *ob, const BakeNormalSwizzle normal_swizzle[3]);
 void RE_bake_normal_world_to_tangent(
         const BakePixel pixel_array[], const int num_pixels, const int depth, 
float result[],
-        struct Mesh *me, const BakeNormalSwizzle normal_swizzle[3]);
+        struct Mesh *me, const BakeNormalSwizzle normal_swizzle[3], float 
mat[4][4]);
 void RE_bake_normal_world_to_world(
         const BakePixel pixel_array[], const int num_pixels, const int depth, 
float result[],
         const BakeNormalSwizzle normal_swizzle[3]);
diff --git a/source/blender/render/intern/source/bake_api.c 
b/source/blender/render/intern/source/bake_api.c
index 258208e..375ab30 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -189,7 +189,7 @@ static void calc_point_from_barycentric(
        add_v3_v3(coord, cage);
 
        normalize_v3_v3(dir, dir);
-       mul_v3_fl(dir, -1.0f);
+       negate_v3(dir);
 
        copy_v3_v3(r_co, coord);
        copy_v3_v3(r_dir, dir);
@@ -215,7 +215,7 @@ static void calc_barycentric_from_point(
  */
 static bool cast_ray_highpoly(
         BVHTreeFromMesh *treeData, TriTessFace *triangles[], BakeHighPolyData 
*highpoly,
-        float const co_low[3], const float dir[3], const int pixel_id, const 
int tot_highpoly,
+        const float co[3], const float dir[3], const int pixel_id, const int 
tot_highpoly,
         const float du_dx, const float du_dy, const float dv_dx, const float 
dv_dy)
 {
        int i;
@@ -228,26 +228,30 @@ static bool cast_ray_highpoly(
        hits = MEM_mallocN(sizeof(BVHTreeRayHit) * tot_highpoly, "Bake Highpoly 
to Lowpoly: BVH Rays");
 
        for (i = 0; i < tot_highpoly; i++) {
-               float co_high[3];
+               float co_high[3], dir_high[3];
+
                hits[i].index = -1;
                /* TODO: we should use FLT_MAX here, but sweepsphere code isn't 
prepared for that */
                hits[i].dist = 10000.0f;
 
-               copy_v3_v3(co_high, co_low);
+               /* transform the ray from the world space to the highpoly space 
*/
+               mul_v3_m4v3(co_high, highpoly[i].imat_high, co);
 
-               /* transform the ray from the lowpoly to the highpoly space */
-               mul_m4_v3(highpoly[i].mat_lowtohigh, co_high);
+               copy_v3_v3(dir_high, dir);
+               mul_transposed_mat3_m4_v3(highpoly[i].mat_high, dir_high);
+               normalize_v3(dir_high);
 
                /* cast ray */
-               BLI_bvhtree_ray_cast(treeData[i].tree, co_high, dir, 0.0f, 
&hits[i], treeData[i].raycast_callback, &treeData[i]);
+               BLI_bvhtree_ray_cast(treeData[i].tree, co_high, dir_high, 0.0f, 
&hits[i], treeData[i].raycast_callback, &treeData[i]);
 
                if (hits[i].index != -1) {
                        /* cull backface */
-                       const float dot = dot_v3v3(dir, hits[i].no);
+                       const float dot = dot_v3v3(dir_high, hits[i].no);
                        if (dot < 0.0f) {
-                               if (hits[i].dist < hit_distance) {
+                               float distance = hits[i].dist * 
highpoly[i].scale;
+                               if (distance < hit_distance) {
                                        hit_mesh = i;
-                                       hit_distance = hits[i].dist;
+                                       hit_distance = distance;
                                }
                        }
                }
@@ -370,11 +374,12 @@ static void mesh_calc_tri_tessface(
 void RE_bake_pixels_populate_from_objects(
         struct Mesh *me_low, BakePixel pixel_array_from[],
         BakeHighPolyData highpoly[], const int tot_highpoly, const int 
num_pixels,
-        const float cage_extrusion)
+        const float cage_extrusion, float mat_low[4][4])
 {
        int i;
        int primitive_id;
        float u, v;
+       float imat_low [4][4];
 
        DerivedMesh **dm_highpoly;
        BVHTreeFromMesh *treeData;
@@ -393,6 +398,8 @@ void RE_bake_pixels_populate_from_objects(
 
        mesh_calc_tri_tessface(tris_low, me_low, false, NULL);
 
+       invert_m4_m4(imat_low, mat_low);
+
        for (i = 0; i < tot_highpoly; i++) {
                tris_high[i] = MEM_callocN(sizeof(TriTessFace) * 
highpoly[i].me->totface, "MVerts Highpoly Mesh");
                mesh_calc_tri_tessface(tris_high[i], highpoly[i].me, false, 
NULL);
@@ -428,6 +435,11 @@ void RE_bake_pixels_populate_from_objects(
                /* calculate from low poly mesh cage */
                calc_point_from_barycentric(tris_low, primitive_id, u, v, 
cage_extrusion, co, dir);
 
+               /* convert from local to world space */
+               mul_m4_v3(mat_low, co);
+               mul_transposed_mat3_m4_v3(imat_low, dir);
+               normalize_v3(dir);
+
                /* cast ray */
                if (!cast_ray_highpoly(treeData, tris_high, highpoly, co, dir, 
i, tot_highpoly,
                                       pixel_array_from[i].du_dx, 
pixel_array_from[i].du_dy,
@@ -601,7 +613,8 @@ static void normal_compress(float out[3], const float 
in[3], const BakeNormalSwi
  */
 void RE_bake_normal_world_to_tangent(
         const BakePixel pixel_array[], const int num_pixels, const int depth,
-        float result[], Mesh *me, const BakeNormalSwizzle normal_swizzle[3])
+        float result[], Mesh *me, const BakeNormalSwizzle normal_swizzle[3],
+        float mat[4][4])
 {
        int i;
 
@@ -689,6 +702,9 @@ void RE_bake_normal_world_to_tangent(
                /* texture values */
                normal_uncompress(nor, &result[offset]);
 
+               /* converts from world space to local space */
+               mul_transposed_mat3_m4_v3(mat, nor);
+
                invert_m3_m3(itsm, tsm);
                mul_m3_v3(itsm, nor);
                normalize_v3(nor);

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to