Cleanup: Move SpaceTransform helpers from `BKE_shrinkwrap` to `BLI_math_matrix`.

This commit is contained in:
Bastien Montagne 2014-08-01 16:28:31 +02:00
parent c11777b211
commit 3c9e11df37
8 changed files with 95 additions and 97 deletions

View File

@ -31,43 +31,6 @@
* \ingroup bke
*/
/* SpaceTransform stuff */
/*
* TODO: move this somewhere else
*
* this structs encapsulates all needed data to convert between 2 coordinate spaces
* (where conversion can be represented by a matrix multiplication)
*
* This is used to reduce the number of arguments to pass to functions that need to perform
* this kind of operation and make it easier for the coder, as he/she doenst needs to recode
* the matrix calculation.
*
* A SpaceTransform is initialized using:
* SPACE_TRANSFORM_SETUP( &data, ob1, ob2 )
*
* After that the following calls can be used:
* space_transform_apply (&data, co); //converts a coordinate in ob1 coords space to the corresponding ob2 coords
* space_transform_invert(&data, co); //converts a coordinate in ob2 coords space to the corresponding ob1 coords
*
* //Same Concept as space_transform_apply and space_transform_invert, but no is normalized after conversion
* space_transform_apply_normal (&data, &no);
* space_transform_invert_normal(&data, &no);
*
*/
struct Object;
typedef struct SpaceTransform {
float local2target[4][4];
float target2local[4][4];
} SpaceTransform;
void space_transform_from_matrixs(struct SpaceTransform *data, float local[4][4], float target[4][4]);
void space_transform_apply(const struct SpaceTransform *data, float co[3]);
void space_transform_invert(const struct SpaceTransform *data, float co[3]);
#define SPACE_TRANSFORM_SETUP(data, local, target) space_transform_from_matrixs(data, (local)->obmat, (target)->obmat)
/* Shrinkwrap stuff */
#include "BKE_bvhutils.h"
@ -91,6 +54,7 @@ struct MDeformVert;
struct ShrinkwrapModifierData;
struct MDeformVert;
struct BVHTree;
struct SpaceTransform;
typedef struct ShrinkwrapCalcData {
@ -106,7 +70,7 @@ typedef struct ShrinkwrapCalcData {
int vgroup; //Vertex group num
struct DerivedMesh *target; //mesh we are shrinking to
SpaceTransform local2target; //transform to move between local and target space
struct SpaceTransform local2target; //transform to move between local and target space
float keepDist; //Distance to keep above target surface (units are in local space)
@ -127,7 +91,7 @@ void shrinkwrapModifier_deform(struct ShrinkwrapModifierData *smd, struct Object
*/
bool BKE_shrinkwrap_project_normal(
char options, const float vert[3], const float dir[3],
const SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit,
const struct SpaceTransform *transf, BVHTree *tree, BVHTreeRayHit *hit,
BVHTree_RayCastCallback callback, void *userdata);
/*

View File

@ -3375,7 +3375,7 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
unit_m4(ct->matrix);
if (target != NULL) {
space_transform_from_matrixs(&transform, cob->matrix, ct->tar->obmat);
BLI_space_transform_from_matrices(&transform, cob->matrix, ct->tar->obmat);
switch (scon->shrinkType) {
case MOD_SHRINKWRAP_NEAREST_SURFACE:
@ -3397,7 +3397,7 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
break;
}
space_transform_apply(&transform, co);
BLI_space_transform_apply(&transform, co);
BLI_bvhtree_find_nearest(treeData.tree, co, &nearest, treeData.nearest_callback, &treeData);
@ -3405,7 +3405,7 @@ static void shrinkwrap_get_tarmat(bConstraint *con, bConstraintOb *cob, bConstra
if (dist != 0.0f) {
interp_v3_v3v3(co, co, nearest.co, (dist - scon->dist) / dist); /* linear interpolation */
}
space_transform_invert(&transform, co);
BLI_space_transform_invert(&transform, co);
break;
}
case MOD_SHRINKWRAP_PROJECT:

View File

@ -66,37 +66,6 @@
/* Util macros */
#define OUT_OF_MEMORY() ((void)printf("Shrinkwrap: Out of memory\n"))
/* Space transform */
void space_transform_from_matrixs(SpaceTransform *data, float local[4][4], float target[4][4])
{
float itarget[4][4];
invert_m4_m4(itarget, target);
mul_m4_m4m4(data->local2target, itarget, local);
invert_m4_m4(data->target2local, data->local2target);
}
void space_transform_apply(const SpaceTransform *data, float co[3])
{
mul_v3_m4v3(co, ((SpaceTransform *)data)->local2target, co);
}
void space_transform_invert(const SpaceTransform *data, float co[3])
{
mul_v3_m4v3(co, ((SpaceTransform *)data)->target2local, co);
}
static void space_transform_apply_normal(const SpaceTransform *data, float no[3])
{
mul_mat3_m4_v3(((SpaceTransform *)data)->local2target, no);
normalize_v3(no); /* TODO: could we just determine de scale value from the matrix? */
}
static void space_transform_invert_normal(const SpaceTransform *data, float no[3])
{
mul_mat3_m4_v3(((SpaceTransform *)data)->target2local, no);
normalize_v3(no); /* TODO: could we just determine de scale value from the matrix? */
}
/*
* Shrinkwrap to the nearest vertex
*
@ -139,7 +108,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
else {
copy_v3_v3(tmp_co, co);
}
space_transform_apply(&calc->local2target, tmp_co);
BLI_space_transform_apply(&calc->local2target, tmp_co);
/* Use local proximity heuristics (to reduce the nearest search)
*
@ -165,7 +134,7 @@ static void shrinkwrap_calc_nearest_vertex(ShrinkwrapCalcData *calc)
/* Convert the coordinates back to mesh coordinates */
copy_v3_v3(tmp_co, nearest.co);
space_transform_invert(&calc->local2target, tmp_co);
BLI_space_transform_invert(&calc->local2target, tmp_co);
interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
}
@ -204,11 +173,11 @@ bool BKE_shrinkwrap_project_normal(
/* Apply space transform (TODO readjust dist) */
if (transf) {
copy_v3_v3(tmp_co, vert);
space_transform_apply(transf, tmp_co);
BLI_space_transform_apply(transf, tmp_co);
co = tmp_co;
copy_v3_v3(tmp_no, dir);
space_transform_apply_normal(transf, tmp_no);
BLI_space_transform_apply_normal(transf, tmp_no);
no = tmp_no;
#ifdef USE_DIST_CORRECT
@ -227,7 +196,7 @@ bool BKE_shrinkwrap_project_normal(
if (hit_tmp.index != -1) {
/* invert the normal first so face culling works on rotated objects */
if (transf) {
space_transform_invert_normal(transf, hit_tmp.no);
BLI_space_transform_invert_normal(transf, hit_tmp.no);
}
if (options & (MOD_SHRINKWRAP_CULL_TARGET_FRONTFACE | MOD_SHRINKWRAP_CULL_TARGET_BACKFACE)) {
@ -242,7 +211,7 @@ bool BKE_shrinkwrap_project_normal(
if (transf) {
/* Inverting space transform (TODO make coeherent with the initial dist readjust) */
space_transform_invert(transf, hit_tmp.co);
BLI_space_transform_invert(transf, hit_tmp.co);
#ifdef USE_DIST_CORRECT
hit_tmp.dist = len_v3v3(vert, hit_tmp.co);
#endif
@ -307,7 +276,7 @@ static void shrinkwrap_calc_normal_projection(ShrinkwrapCalcData *calc, bool for
auxMesh = object_get_derived_final(calc->smd->auxTarget, for_render);
if (!auxMesh)
return;
SPACE_TRANSFORM_SETUP(&local2aux, calc->ob, calc->smd->auxTarget);
BLI_SPACE_TRANSFORM_SETUP(&local2aux, calc->ob, calc->smd->auxTarget);
}
/* After sucessufuly build the trees, start projection vertexs */
@ -441,7 +410,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
else {
copy_v3_v3(tmp_co, co);
}
space_transform_apply(&calc->local2target, tmp_co);
BLI_space_transform_apply(&calc->local2target, tmp_co);
/* Use local proximity heuristics (to reduce the nearest search)
*
@ -475,7 +444,7 @@ static void shrinkwrap_calc_nearest_surface_point(ShrinkwrapCalcData *calc)
}
/* Convert the coordinates back to mesh coordinates */
space_transform_invert(&calc->local2target, tmp_co);
BLI_space_transform_invert(&calc->local2target, tmp_co);
interp_v3_v3v3(co, co, tmp_co, weight); /* linear interpolation */
}
}
@ -518,7 +487,7 @@ void shrinkwrapModifier_deform(ShrinkwrapModifierData *smd, Object *ob, DerivedM
/* TODO there might be several "bugs" on non-uniform scales matrixs
* because it will no longer be nearest surface, not sphere projection
* because space has been deformed */
SPACE_TRANSFORM_SETUP(&calc.local2target, ob, smd->target);
BLI_SPACE_TRANSFORM_SETUP(&calc.local2target, ob, smd->target);
/* TODO: smd->keepDist is in global units.. must change to local */
calc.keepDist = smd->keepDist;

View File

@ -224,6 +224,22 @@ bool is_negative_m4(float mat[4][4]);
bool is_zero_m3(float mat[3][3]);
bool is_zero_m4(float mat[4][4]);
/* SpaceTransform helper */
typedef struct SpaceTransform {
float local2target[4][4];
float target2local[4][4];
} SpaceTransform;
void BLI_space_transform_from_matrices(struct SpaceTransform *data, float local[4][4], float target[4][4]);
void BLI_space_transform_apply(const struct SpaceTransform *data, float co[3]);
void BLI_space_transform_invert(const struct SpaceTransform *data, float co[3]);
void BLI_space_transform_apply_normal(const struct SpaceTransform *data, float no[3]);
void BLI_space_transform_invert_normal(const struct SpaceTransform *data, float no[3]);
#define BLI_SPACE_TRANSFORM_SETUP(data, local, target) \
BLI_space_transform_from_matrices((data), (local)->obmat, (target)->obmat)
/*********************************** Other ***********************************/
void print_m3(const char *str, float M[3][3]);

View File

@ -2215,3 +2215,51 @@ void invert_m4_m4_safe(float Ainv[4][4], float A[4][4])
}
}
}
/**
* SpaceTransform struct encapsulates all needed data to convert between two coordinate spaces
* (where conversion can be represented by a matrix multiplication).
*
* A SpaceTransform is initialized using:
* BLI_SPACE_TRANSFORM_SETUP(&data, ob1, ob2)
*
* After that the following calls can be used:
* BLI_space_transform_apply(&data, co); // converts a coordinate in ob1 space to the corresponding ob2 space
* BLI_space_transform_invert(&data, co); // converts a coordinate in ob2 space to the corresponding ob1 space
*
* Same concept as BLI_space_transform_apply and BLI_space_transform_invert, but no is normalized after conversion
* (and not translated at all!):
* BLI_space_transform_apply_normal(&data, no);
* BLI_space_transform_invert_normal(&data, no);
*
*/
void BLI_space_transform_from_matrices(SpaceTransform *data, float local[4][4], float target[4][4])
{
float itarget[4][4];
invert_m4_m4(itarget, target);
mul_m4_m4m4(data->local2target, itarget, local);
invert_m4_m4(data->target2local, data->local2target);
}
void BLI_space_transform_apply(const SpaceTransform *data, float co[3])
{
mul_v3_m4v3(co, ((SpaceTransform *)data)->local2target, co);
}
void BLI_space_transform_invert(const SpaceTransform *data, float co[3])
{
mul_v3_m4v3(co, ((SpaceTransform *)data)->target2local, co);
}
void BLI_space_transform_apply_normal(const SpaceTransform *data, float no[3])
{
mul_mat3_m4_v3(((SpaceTransform *)data)->local2target, no);
normalize_v3(no);
}
void BLI_space_transform_invert_normal(const SpaceTransform *data, float no[3])
{
mul_mat3_m4_v3(((SpaceTransform *)data)->target2local, no);
normalize_v3(no);
}

View File

@ -37,6 +37,7 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"

View File

@ -42,7 +42,6 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_modifier.h"
#include "BKE_deform.h"
#include "BKE_shrinkwrap.h"
#include "depsgraph_private.h"
@ -166,7 +165,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object
/* Calculate matrixs do convert between coordinate spaces */
if (smd->origin) {
transf = &tmp_transf;
space_transform_from_matrixs(transf, ob->obmat, smd->origin->obmat);
BLI_SPACE_TRANSFORM_SETUP(transf, ob, smd->origin);
}
/* Setup vars,
@ -182,7 +181,9 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object
float tmp[3];
copy_v3_v3(tmp, vertexCos[i]);
if (transf) space_transform_apply(transf, tmp);
if (transf) {
BLI_space_transform_apply(transf, tmp);
}
lower = min_ff(lower, tmp[limit_axis]);
upper = max_ff(upper, tmp[limit_axis]);
@ -220,7 +221,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object
float co[3], dcut[3] = {0.0f, 0.0f, 0.0f};
if (transf) {
space_transform_apply(transf, vertexCos[i]);
BLI_space_transform_apply(transf, vertexCos[i]);
}
copy_v3_v3(co, vertexCos[i]);
@ -236,7 +237,7 @@ static void SimpleDeformModifier_do(SimpleDeformModifierData *smd, struct Object
interp_v3_v3v3(vertexCos[i], vertexCos[i], co, weight); /* Use vertex weight has coef of linear interpolation */
if (transf) {
space_transform_invert(transf, vertexCos[i]);
BLI_space_transform_invert(transf, vertexCos[i]);
}
}
}

View File

@ -43,7 +43,6 @@
#include "BKE_deform.h"
#include "BKE_library.h"
#include "BKE_modifier.h"
#include "BKE_shrinkwrap.h" /* For SpaceTransform stuff. */
#include "BKE_texture.h" /* Texture masking. */
#include "depsgraph_private.h"
@ -73,12 +72,12 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3],
DerivedMesh *target, const SpaceTransform *loc2trgt)
{
int i;
BVHTreeFromMesh treeData_v = NULL_BVHTreeFromMesh;
BVHTreeFromMesh treeData_e = NULL_BVHTreeFromMesh;
BVHTreeFromMesh treeData_f = NULL_BVHTreeFromMesh;
BVHTreeNearest nearest_v = NULL_BVHTreeNearest;
BVHTreeNearest nearest_e = NULL_BVHTreeNearest;
BVHTreeNearest nearest_f = NULL_BVHTreeNearest;
BVHTreeFromMesh treeData_v = {0};
BVHTreeFromMesh treeData_e = {0};
BVHTreeFromMesh treeData_f = {0};
BVHTreeNearest nearest_v = {0};
BVHTreeNearest nearest_e = {0};
BVHTreeNearest nearest_f = {0};
if (dist_v) {
/* Create a bvh-tree of the given target's verts. */
@ -120,7 +119,7 @@ static void get_vert2geom_distance(int numVerts, float (*v_cos)[3],
/* Convert the vertex to tree coordinates. */
copy_v3_v3(tmp_co, v_cos[i]);
space_transform_apply(loc2trgt, tmp_co);
BLI_space_transform_apply(loc2trgt, tmp_co);
/* Use local proximity heuristics (to reduce the nearest search).
*
@ -484,7 +483,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
float *dists_e = use_trgt_edges ? MEM_mallocN(sizeof(float) * numIdx, "dists_e") : NULL;
float *dists_f = use_trgt_faces ? MEM_mallocN(sizeof(float) * numIdx, "dists_f") : NULL;
SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
BLI_SPACE_TRANSFORM_SETUP(&loc2trgt, ob, obr);
get_vert2geom_distance(numIdx, v_cos, dists_v, dists_e, dists_f,
target_dm, &loc2trgt);
for (i = 0; i < numIdx; i++) {