Changeset View
Changeset View
Standalone View
Standalone View
source/blender/render/intern/bake.c
| Show First 20 Lines • Show All 86 Lines • ▼ Show 20 Lines | |||||
| * struct wrapping up tangent space data | * struct wrapping up tangent space data | ||||
| */ | */ | ||||
| typedef struct TSpace { | typedef struct TSpace { | ||||
| float tangent[3]; | float tangent[3]; | ||||
| float sign; | float sign; | ||||
| } TSpace; | } TSpace; | ||||
| typedef struct TriTessFace { | typedef struct TriTessFace { | ||||
| const MVert *mverts[3]; | const float *positions[3]; | ||||
| const float *vert_normals[3]; | const float *vert_normals[3]; | ||||
| const TSpace *tspace[3]; | const TSpace *tspace[3]; | ||||
| const float *loop_normal[3]; | const float *loop_normal[3]; | ||||
| float normal[3]; /* for flat faces */ | float normal[3]; /* for flat faces */ | ||||
| bool is_smooth; | bool is_smooth; | ||||
| } TriTessFace; | } TriTessFace; | ||||
| static void store_bake_pixel(void *handle, int x, int y, float u, float v) | static void store_bake_pixel(void *handle, int x, int y, float u, float v) | ||||
| ▲ Show 20 Lines • Show All 85 Lines • ▼ Show 20 Lines | |||||
| int i; | int i; | ||||
| TriTessFace *triangle[2]; | TriTessFace *triangle[2]; | ||||
| triangle[0] = &triangles_low[primitive_id]; | triangle[0] = &triangles_low[primitive_id]; | ||||
| triangle[1] = &triangles_cage[primitive_id]; | triangle[1] = &triangles_cage[primitive_id]; | ||||
| for (i = 0; i < 2; i++) { | for (i = 0; i < 2; i++) { | ||||
| copy_v3_v3(data[i][0], triangle[i]->mverts[0]->co); | copy_v3_v3(data[i][0], triangle[i]->positions[0]); | ||||
| copy_v3_v3(data[i][1], triangle[i]->mverts[1]->co); | copy_v3_v3(data[i][1], triangle[i]->positions[1]); | ||||
| copy_v3_v3(data[i][2], triangle[i]->mverts[2]->co); | copy_v3_v3(data[i][2], triangle[i]->positions[2]); | ||||
| interp_barycentric_tri_v3(data[i], u, v, coord[i]); | interp_barycentric_tri_v3(data[i], u, v, coord[i]); | ||||
| } | } | ||||
| /* convert from local to world space */ | /* convert from local to world space */ | ||||
| mul_m4_v3(mat_low, coord[0]); | mul_m4_v3(mat_low, coord[0]); | ||||
| mul_m4_v3(mat_cage, coord[1]); | mul_m4_v3(mat_cage, coord[1]); | ||||
| sub_v3_v3v3(dir, coord[0], coord[1]); | sub_v3_v3v3(dir, coord[0], coord[1]); | ||||
| Show All 23 Lines | |||||
| float coord[3]; | float coord[3]; | ||||
| float dir[3]; | float dir[3]; | ||||
| float cage[3]; | float cage[3]; | ||||
| bool is_smooth; | bool is_smooth; | ||||
| TriTessFace *triangle = &triangles[primitive_id]; | TriTessFace *triangle = &triangles[primitive_id]; | ||||
| is_smooth = triangle->is_smooth || is_cage; | is_smooth = triangle->is_smooth || is_cage; | ||||
| copy_v3_v3(data[0], triangle->mverts[0]->co); | copy_v3_v3(data[0], triangle->positions[0]); | ||||
| copy_v3_v3(data[1], triangle->mverts[1]->co); | copy_v3_v3(data[1], triangle->positions[1]); | ||||
| copy_v3_v3(data[2], triangle->mverts[2]->co); | copy_v3_v3(data[2], triangle->positions[2]); | ||||
| interp_barycentric_tri_v3(data, u, v, coord); | interp_barycentric_tri_v3(data, u, v, coord); | ||||
| if (is_smooth) { | if (is_smooth) { | ||||
| copy_v3_v3(data[0], triangle->vert_normals[0]); | copy_v3_v3(data[0], triangle->vert_normals[0]); | ||||
| copy_v3_v3(data[1], triangle->vert_normals[1]); | copy_v3_v3(data[1], triangle->vert_normals[1]); | ||||
| copy_v3_v3(data[2], triangle->vert_normals[2]); | copy_v3_v3(data[2], triangle->vert_normals[2]); | ||||
| ▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | |||||
| /* ray direction in high poly object space */ | /* ray direction in high poly object space */ | ||||
| float dir_high[3]; | float dir_high[3]; | ||||
| mul_v3_mat3_m4v3(dir_high, highpoly[hit_mesh].imat, dir); | mul_v3_mat3_m4v3(dir_high, highpoly[hit_mesh].imat, dir); | ||||
| normalize_v3(dir_high); | normalize_v3(dir_high); | ||||
| /* compute position differentials on low poly object */ | /* compute position differentials on low poly object */ | ||||
| float duco_low[3], dvco_low[3], dxco[3], dyco[3]; | float duco_low[3], dvco_low[3], dxco[3], dyco[3]; | ||||
| sub_v3_v3v3(duco_low, triangle_low->mverts[0]->co, triangle_low->mverts[2]->co); | sub_v3_v3v3(duco_low, triangle_low->positions[0], triangle_low->positions[2]); | ||||
| sub_v3_v3v3(dvco_low, triangle_low->mverts[1]->co, triangle_low->mverts[2]->co); | sub_v3_v3v3(dvco_low, triangle_low->positions[1], triangle_low->positions[2]); | ||||
| mul_v3_v3fl(dxco, duco_low, pixel_low->du_dx); | mul_v3_v3fl(dxco, duco_low, pixel_low->du_dx); | ||||
| madd_v3_v3fl(dxco, dvco_low, pixel_low->dv_dx); | madd_v3_v3fl(dxco, dvco_low, pixel_low->dv_dx); | ||||
| mul_v3_v3fl(dyco, duco_low, pixel_low->du_dy); | mul_v3_v3fl(dyco, duco_low, pixel_low->du_dy); | ||||
| madd_v3_v3fl(dyco, dvco_low, pixel_low->dv_dy); | madd_v3_v3fl(dyco, dvco_low, pixel_low->dv_dy); | ||||
| /* transform from low poly to high poly object space */ | /* transform from low poly to high poly object space */ | ||||
| mul_mat3_m4_v3(mat_low, dxco); | mul_mat3_m4_v3(mat_low, dxco); | ||||
| mul_mat3_m4_v3(mat_low, dyco); | mul_mat3_m4_v3(mat_low, dyco); | ||||
| mul_mat3_m4_v3(highpoly[hit_mesh].imat, dxco); | mul_mat3_m4_v3(highpoly[hit_mesh].imat, dxco); | ||||
| mul_mat3_m4_v3(highpoly[hit_mesh].imat, dyco); | mul_mat3_m4_v3(highpoly[hit_mesh].imat, dyco); | ||||
| /* transfer position differentials */ | /* transfer position differentials */ | ||||
| float tmp[3]; | float tmp[3]; | ||||
| mul_v3_v3fl(tmp, dir_high, 1.0f / dot_v3v3(dir_high, triangle_high->normal)); | mul_v3_v3fl(tmp, dir_high, 1.0f / dot_v3v3(dir_high, triangle_high->normal)); | ||||
| madd_v3_v3fl(dxco, tmp, -dot_v3v3(dxco, triangle_high->normal)); | madd_v3_v3fl(dxco, tmp, -dot_v3v3(dxco, triangle_high->normal)); | ||||
| madd_v3_v3fl(dyco, tmp, -dot_v3v3(dyco, triangle_high->normal)); | madd_v3_v3fl(dyco, tmp, -dot_v3v3(dyco, triangle_high->normal)); | ||||
| /* compute barycentric differentials from position differentials */ | /* compute barycentric differentials from position differentials */ | ||||
| barycentric_differentials_from_position(hits[hit_mesh].co, | barycentric_differentials_from_position(hits[hit_mesh].co, | ||||
| triangle_high->mverts[0]->co, | triangle_high->positions[0], | ||||
| triangle_high->mverts[1]->co, | triangle_high->positions[1], | ||||
| triangle_high->mverts[2]->co, | triangle_high->positions[2], | ||||
| dxco, | dxco, | ||||
| dyco, | dyco, | ||||
| triangle_high->normal, | triangle_high->normal, | ||||
| true, | true, | ||||
| &pixel_high->uv[0], | &pixel_high->uv[0], | ||||
| &pixel_high->uv[1], | &pixel_high->uv[1], | ||||
| &pixel_high->du_dx, | &pixel_high->du_dx, | ||||
| &pixel_high->dv_dx, | &pixel_high->dv_dx, | ||||
| Show All 25 Lines | |||||
| const int tottri = poly_to_tri_count(me->totpoly, me->totloop); | const int tottri = poly_to_tri_count(me->totpoly, me->totloop); | ||||
| MLoopTri *looptri; | MLoopTri *looptri; | ||||
| TriTessFace *triangles; | TriTessFace *triangles; | ||||
| /* calculate normal for each polygon only once */ | /* calculate normal for each polygon only once */ | ||||
| unsigned int mpoly_prev = UINT_MAX; | unsigned int mpoly_prev = UINT_MAX; | ||||
| float no[3]; | float no[3]; | ||||
| const MVert *verts = BKE_mesh_verts(me); | const float(*positions)[3] = BKE_mesh_positions(me); | ||||
| const MPoly *polys = BKE_mesh_polys(me); | const MPoly *polys = BKE_mesh_polys(me); | ||||
| const MLoop *loops = BKE_mesh_loops(me); | const MLoop *loops = BKE_mesh_loops(me); | ||||
| looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); | looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); | ||||
| triangles = MEM_callocN(sizeof(TriTessFace) * tottri, __func__); | triangles = MEM_callocN(sizeof(TriTessFace) * tottri, __func__); | ||||
| const float(*precomputed_normals)[3] = BKE_mesh_poly_normals_are_dirty(me) ? | const float(*precomputed_normals)[3] = BKE_mesh_poly_normals_are_dirty(me) ? | ||||
| NULL : | NULL : | ||||
| BKE_mesh_poly_normals_ensure(me); | BKE_mesh_poly_normals_ensure(me); | ||||
| const bool calculate_normal = precomputed_normals ? false : true; | const bool calculate_normal = precomputed_normals ? false : true; | ||||
| if (precomputed_normals != NULL) { | if (precomputed_normals != NULL) { | ||||
| BKE_mesh_recalc_looptri_with_normals( | BKE_mesh_recalc_looptri_with_normals( | ||||
| loops, polys, verts, me->totloop, me->totpoly, looptri, precomputed_normals); | loops, polys, positions, me->totloop, me->totpoly, looptri, precomputed_normals); | ||||
| } | } | ||||
| else { | else { | ||||
| BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); | BKE_mesh_recalc_looptri(loops, polys, positions, me->totloop, me->totpoly, looptri); | ||||
| } | } | ||||
| const TSpace *tspace = NULL; | const TSpace *tspace = NULL; | ||||
| const float(*loop_normals)[3] = NULL; | const float(*loop_normals)[3] = NULL; | ||||
| if (tangent) { | if (tangent) { | ||||
| BKE_mesh_ensure_normals_for_display(me_eval); | BKE_mesh_ensure_normals_for_display(me_eval); | ||||
| BKE_mesh_calc_normals_split(me_eval); | BKE_mesh_calc_normals_split(me_eval); | ||||
| BKE_mesh_calc_loop_tangents(me_eval, true, NULL, 0); | BKE_mesh_calc_loop_tangents(me_eval, true, NULL, 0); | ||||
| tspace = CustomData_get_layer(&me_eval->ldata, CD_TANGENT); | tspace = CustomData_get_layer(&me_eval->ldata, CD_TANGENT); | ||||
| BLI_assert(tspace); | BLI_assert(tspace); | ||||
| loop_normals = CustomData_get_layer(&me_eval->ldata, CD_NORMAL); | loop_normals = CustomData_get_layer(&me_eval->ldata, CD_NORMAL); | ||||
| } | } | ||||
| const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me); | const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(me); | ||||
| for (i = 0; i < tottri; i++) { | for (i = 0; i < tottri; i++) { | ||||
| const MLoopTri *lt = &looptri[i]; | const MLoopTri *lt = &looptri[i]; | ||||
| const MPoly *mp = &polys[lt->poly]; | const MPoly *mp = &polys[lt->poly]; | ||||
| triangles[i].mverts[0] = &verts[loops[lt->tri[0]].v]; | triangles[i].positions[0] = positions[loops[lt->tri[0]].v]; | ||||
| triangles[i].mverts[1] = &verts[loops[lt->tri[1]].v]; | triangles[i].positions[1] = positions[loops[lt->tri[1]].v]; | ||||
| triangles[i].mverts[2] = &verts[loops[lt->tri[2]].v]; | triangles[i].positions[2] = positions[loops[lt->tri[2]].v]; | ||||
| triangles[i].vert_normals[0] = vert_normals[loops[lt->tri[0]].v]; | triangles[i].vert_normals[0] = vert_normals[loops[lt->tri[0]].v]; | ||||
| triangles[i].vert_normals[1] = vert_normals[loops[lt->tri[1]].v]; | triangles[i].vert_normals[1] = vert_normals[loops[lt->tri[1]].v]; | ||||
| triangles[i].vert_normals[2] = vert_normals[loops[lt->tri[2]].v]; | triangles[i].vert_normals[2] = vert_normals[loops[lt->tri[2]].v]; | ||||
| triangles[i].is_smooth = (mp->flag & ME_SMOOTH) != 0; | triangles[i].is_smooth = (mp->flag & ME_SMOOTH) != 0; | ||||
| if (tangent) { | if (tangent) { | ||||
| triangles[i].tspace[0] = &tspace[lt->tri[0]]; | triangles[i].tspace[0] = &tspace[lt->tri[0]]; | ||||
| triangles[i].tspace[1] = &tspace[lt->tri[1]]; | triangles[i].tspace[1] = &tspace[lt->tri[1]]; | ||||
| triangles[i].tspace[2] = &tspace[lt->tri[2]]; | triangles[i].tspace[2] = &tspace[lt->tri[2]]; | ||||
| } | } | ||||
| if (loop_normals) { | if (loop_normals) { | ||||
| triangles[i].loop_normal[0] = loop_normals[lt->tri[0]]; | triangles[i].loop_normal[0] = loop_normals[lt->tri[0]]; | ||||
| triangles[i].loop_normal[1] = loop_normals[lt->tri[1]]; | triangles[i].loop_normal[1] = loop_normals[lt->tri[1]]; | ||||
| triangles[i].loop_normal[2] = loop_normals[lt->tri[2]]; | triangles[i].loop_normal[2] = loop_normals[lt->tri[2]]; | ||||
| } | } | ||||
| if (calculate_normal) { | if (calculate_normal) { | ||||
| if (lt->poly != mpoly_prev) { | if (lt->poly != mpoly_prev) { | ||||
| BKE_mesh_calc_poly_normal(mp, &loops[mp->loopstart], verts, no); | BKE_mesh_calc_poly_normal(mp, &loops[mp->loopstart], positions, no); | ||||
| mpoly_prev = lt->poly; | mpoly_prev = lt->poly; | ||||
| } | } | ||||
| copy_v3_v3(triangles[i].normal, no); | copy_v3_v3(triangles[i].normal, no); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(triangles[i].normal, precomputed_normals[lt->poly]); | copy_v3_v3(triangles[i].normal, precomputed_normals[lt->poly]); | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| for (int i = 0; i < targets->images_num; i++) { | for (int i = 0; i < targets->images_num; i++) { | ||||
| zbuf_alloc_span(&bd.zspan[i], targets->images[i].width, targets->images[i].height); | zbuf_alloc_span(&bd.zspan[i], targets->images[i].width, targets->images[i].height); | ||||
| } | } | ||||
| const int tottri = poly_to_tri_count(me->totpoly, me->totloop); | const int tottri = poly_to_tri_count(me->totpoly, me->totloop); | ||||
| MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); | MLoopTri *looptri = MEM_mallocN(sizeof(*looptri) * tottri, __func__); | ||||
| const MVert *verts = BKE_mesh_verts(me); | const float(*positions)[3] = BKE_mesh_positions(me); | ||||
| const MPoly *polys = BKE_mesh_polys(me); | const MPoly *polys = BKE_mesh_polys(me); | ||||
| const MLoop *loops = BKE_mesh_loops(me); | const MLoop *loops = BKE_mesh_loops(me); | ||||
| BKE_mesh_recalc_looptri(loops, polys, verts, me->totloop, me->totpoly, looptri); | BKE_mesh_recalc_looptri(loops, polys, positions, me->totloop, me->totpoly, looptri); | ||||
| const int *material_indices = BKE_mesh_material_indices(me); | const int *material_indices = BKE_mesh_material_indices(me); | ||||
| for (int i = 0; i < tottri; i++) { | for (int i = 0; i < tottri; i++) { | ||||
| const MLoopTri *lt = &looptri[i]; | const MLoopTri *lt = &looptri[i]; | ||||
| bd.primitive_id = i; | bd.primitive_id = i; | ||||
| ▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines | |||||