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:
authorAlexander Gavrilov <angavrilov@gmail.com>2018-10-03 19:09:43 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2018-10-17 17:55:34 +0300
commite5b18390fa591c8b37b9ef9884611b2888bab188 (patch)
tree78c9feebbe3d266f6c2960d9b6259743d51f60ed /source/blender/blenkernel/intern/constraint.c
parentd31ea3b89aa8d583a6d089f96dff46c0759f8c8a (diff)
Shrinkwrap: implement the use of smooth normals in constraint & modifier.
- Use smooth normals to displace in Above Surface mode. - Add an option to align an axis to the normal in the constraint. I've seen people request the alignment feature, and it seems useful. For the actual aligning I use the damped track logic. In order to conveniently keep mesh data needed for normal computation together, a new data structure is introduced. Reviewers: mont29 Differential Revision: https://developer.blender.org/D3762
Diffstat (limited to 'source/blender/blenkernel/intern/constraint.c')
-rw-r--r--source/blender/blenkernel/intern/constraint.c104
1 files changed, 57 insertions, 47 deletions
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 8e85cc39321..f343a62eaf7 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -107,6 +107,8 @@
* type-info structs.
*/
+static void damptrack_do_transform(float matrix[4][4], const float tarvec[3], int track_axis);
+
/* -------------- Naming -------------- */
/* Find the first available, non-duplicate name for a given constraint */
@@ -3417,15 +3419,18 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
bool fail = false;
float co[3] = {0.0f, 0.0f, 0.0f};
+ bool track_normal = false;
+ float track_no[3] = {0.0f, 0.0f, 0.0f};
SpaceTransform transform;
Mesh *target_eval = mesh_get_eval_final(depsgraph, DEG_get_input_scene(depsgraph), ct->tar, CD_MASK_BAREMESH);
- BVHTreeFromMesh treeData = {NULL};
+ copy_m4_m4(ct->matrix, cob->matrix);
- unit_m4(ct->matrix);
+ bool do_track_normal = (scon->flag & CON_SHRINKWRAP_TRACK_NORMAL) != 0;
+ ShrinkwrapTreeData tree;
- if (target_eval != NULL) {
+ if (BKE_shrinkwrap_init_tree(&tree, target_eval, scon->shrinkType, scon->shrinkMode, do_track_normal)) {
BLI_space_transform_from_matrices(&transform, cob->matrix, ct->tar->obmat);
switch (scon->shrinkType) {
@@ -3437,19 +3442,10 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
nearest.index = -1;
nearest.dist_sq = FLT_MAX;
- if (scon->shrinkType == MOD_SHRINKWRAP_NEAREST_VERTEX)
- BKE_bvhtree_from_mesh_get(&treeData, target_eval, BVHTREE_FROM_VERTS, 2);
- else
- BKE_bvhtree_from_mesh_get(&treeData, target_eval, BVHTREE_FROM_LOOPTRI, 2);
-
- if (treeData.tree == NULL) {
- fail = true;
- break;
- }
-
BLI_space_transform_apply(&transform, co);
- BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
+ BVHTreeFromMesh *treeData = &tree.treeData;
+ BLI_bvhtree_find_nearest(treeData->tree, co, &nearest, treeData->nearest_callback, treeData);
if (nearest.index < 0) {
fail = true;
@@ -3457,7 +3453,13 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
}
if (scon->shrinkType == MOD_SHRINKWRAP_NEAREST_SURFACE) {
- BKE_shrinkwrap_snap_point_to_surface(scon->shrinkMode, nearest.co, nearest.no, scon->dist, co, co);
+ if (do_track_normal) {
+ track_normal = true;
+ BKE_shrinkwrap_compute_smooth_normal(&tree, NULL, nearest.index, nearest.co, nearest.no, track_no);
+ BLI_space_transform_invert_normal(&transform, track_no);
+ }
+
+ BKE_shrinkwrap_snap_point_to_surface(&tree, NULL, scon->shrinkMode, nearest.index, nearest.co, nearest.no, scon->dist, co, co);
}
else {
const float dist = len_v3v3(co, nearest.co);
@@ -3504,16 +3506,9 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
break;
}
- BKE_bvhtree_from_mesh_get(&treeData, target_eval, BVHTREE_FROM_LOOPTRI, 4);
- if (treeData.tree == NULL) {
- fail = true;
- break;
- }
-
char cull_mode = scon->flag & CON_SHRINKWRAP_PROJECT_CULL_MASK;
- BKE_shrinkwrap_project_normal(cull_mode, co, no, 0.0f, &transform, treeData.tree,
- &hit, treeData.raycast_callback, &treeData);
+ BKE_shrinkwrap_project_normal(cull_mode, co, no, 0.0f, &transform, &tree, &hit);
if (scon->flag & CON_SHRINKWRAP_PROJECT_OPPOSITE) {
float inv_no[3];
@@ -3523,8 +3518,7 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
cull_mode ^= CON_SHRINKWRAP_PROJECT_CULL_MASK;
}
- BKE_shrinkwrap_project_normal(cull_mode, co, inv_no, 0.0f, &transform, treeData.tree,
- &hit, treeData.raycast_callback, &treeData);
+ BKE_shrinkwrap_project_normal(cull_mode, co, inv_no, 0.0f, &transform, &tree, &hit);
}
if (hit.index < 0) {
@@ -3532,12 +3526,17 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
break;
}
- BKE_shrinkwrap_snap_point_to_surface(scon->shrinkMode, hit.co, hit.no, scon->dist, co, co);
+ if (do_track_normal) {
+ track_normal = true;
+ BKE_shrinkwrap_compute_smooth_normal(&tree, &transform, hit.index, hit.co, hit.no, track_no);
+ }
+
+ BKE_shrinkwrap_snap_point_to_surface(&tree, &transform, scon->shrinkMode, hit.index, hit.co, hit.no, scon->dist, co, co);
break;
}
}
- free_bvhtree_from_mesh(&treeData);
+ BKE_shrinkwrap_free_tree(&tree);
if (fail == true) {
/* Don't move the point */
@@ -3547,6 +3546,11 @@ static void shrinkwrap_get_tarmat(struct Depsgraph *depsgraph, bConstraint *con,
/* co is in local object coordinates, change it to global and update target position */
mul_m4_v3(cob->matrix, co);
copy_v3_v3(ct->matrix[3], co);
+
+ if (track_normal) {
+ mul_mat3_m4_v3(cob->matrix, track_no);
+ damptrack_do_transform(ct->matrix, track_no, scon->trackAxis);
+ }
}
}
}
@@ -3557,7 +3561,7 @@ static void shrinkwrap_evaluate(bConstraint *UNUSED(con), bConstraintOb *cob, Li
/* only evaluate if there is a target */
if (VALID_CONS_TARGET(ct)) {
- copy_v3_v3(cob->matrix[3], ct->matrix[3]);
+ copy_m4_m4(cob->matrix, ct->matrix);
}
}
@@ -3631,7 +3635,22 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
bConstraintTarget *ct = targets->first;
if (VALID_CONS_TARGET(ct)) {
- float obvec[3], tarvec[3], obloc[3];
+ float tarvec[3];
+
+ /* find the (unit) direction vector going from the owner to the target */
+ sub_v3_v3v3(tarvec, ct->matrix[3], cob->matrix[3]);
+
+ damptrack_do_transform(cob->matrix, tarvec, data->trackflag);
+ }
+}
+
+static void damptrack_do_transform(float matrix[4][4], const float tarvec_in[3], int track_axis)
+{
+ /* find the (unit) direction vector going from the owner to the target */
+ float tarvec[3];
+
+ if (normalize_v3_v3(tarvec, tarvec_in) != 0.0f) {
+ float obvec[3], obloc[3];
float raxis[3], rangle;
float rmat[3][3], tmat[4][4];
@@ -3640,24 +3659,15 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
* - the normalization step at the end should take care of any unwanted scaling
* left over in the 3x3 matrix we used
*/
- copy_v3_v3(obvec, track_dir_vecs[data->trackflag]);
- mul_mat3_m4_v3(cob->matrix, obvec);
+ copy_v3_v3(obvec, track_dir_vecs[track_axis]);
+ mul_mat3_m4_v3(matrix, obvec);
if (normalize_v3(obvec) == 0.0f) {
/* exceptional case - just use the track vector as appropriate */
- copy_v3_v3(obvec, track_dir_vecs[data->trackflag]);
+ copy_v3_v3(obvec, track_dir_vecs[track_axis]);
}
- /* find the (unit) direction vector going from the owner to the target */
- copy_v3_v3(obloc, cob->matrix[3]);
- sub_v3_v3v3(tarvec, ct->matrix[3], obloc);
-
- if (normalize_v3(tarvec) == 0.0f) {
- /* the target is sitting on the owner, so just make them use the same direction vectors */
- /* FIXME: or would it be better to use the pure direction vector? */
- copy_v3_v3(tarvec, obvec);
- //copy_v3_v3(tarvec, track_dir_vecs[data->trackflag]);
- }
+ copy_v3_v3(obloc, matrix[3]);
/* determine the axis-angle rotation, which represents the smallest possible rotation
* between the two rotation vectors (i.e. the 'damping' referred to in the name)
@@ -3690,8 +3700,8 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
}
rangle = M_PI;
- copy_v3_v3(tmpvec, track_dir_vecs[(data->trackflag + 1) % 6]);
- mul_mat3_m4_v3(cob->matrix, tmpvec);
+ copy_v3_v3(tmpvec, track_dir_vecs[(track_axis + 1) % 6]);
+ mul_mat3_m4_v3(matrix, tmpvec);
cross_v3_v3v3(raxis, obvec, tmpvec);
if (normalize_v3(raxis) == 0.0f) {
@@ -3709,10 +3719,10 @@ static void damptrack_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t
* we may have destroyed that in the process of multiplying the matrix
*/
unit_m4(tmat);
- mul_m4_m3m4(tmat, rmat, cob->matrix); // m1, m3, m2
+ mul_m4_m3m4(tmat, rmat, matrix); // m1, m3, m2
- copy_m4_m4(cob->matrix, tmat);
- copy_v3_v3(cob->matrix[3], obloc);
+ copy_m4_m4(matrix, tmat);
+ copy_v3_v3(matrix[3], obloc);
}
}