diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_customdata.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_data_transfer.h (renamed from source/blender/blenkernel/BKE_object_data_transfer.h) | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/CMakeLists.txt | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/armature.c | 52 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/constraint.c | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/data_transfer.c (renamed from source/blender/blenkernel/intern/object_data_transfer.c) | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/deform.c | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_evaluate.c | 7 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 91 |
9 files changed, 153 insertions, 20 deletions
diff --git a/source/blender/blenkernel/BKE_customdata.h b/source/blender/blenkernel/BKE_customdata.h index 08edde1cec0..f11aad27e4b 100644 --- a/source/blender/blenkernel/BKE_customdata.h +++ b/source/blender/blenkernel/BKE_customdata.h @@ -373,10 +373,10 @@ void CustomData_external_reload(struct CustomData *data, /* Mesh-to-mesh transfer data. */ struct MeshPairRemap; -typedef struct CustomDataTransferLayerMap CustomDataTransferLayerMap; +struct CustomDataTransferLayerMap; typedef void (*cd_datatransfer_interp)( - const CustomDataTransferLayerMap *laymap, void *dest, + const struct CustomDataTransferLayerMap *laymap, void *dest, void **sources, const float *weights, const int count, const float mix_factor); /** @@ -423,7 +423,7 @@ enum { }; typedef struct CustomDataTransferLayerMap { - CustomDataTransferLayerMap *next, *prev; + struct CustomDataTransferLayerMap *next, *prev; int data_type; int mix_mode; diff --git a/source/blender/blenkernel/BKE_object_data_transfer.h b/source/blender/blenkernel/BKE_data_transfer.h index fe218901201..07ef16e8161 100644 --- a/source/blender/blenkernel/BKE_object_data_transfer.h +++ b/source/blender/blenkernel/BKE_data_transfer.h @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/blenkernel/BKE_object_data_transfer.h +/** \file blender/blenkernel/BKE_data_transfer.h * \ingroup bke */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 31e28f9e51b..c71595e7a3e 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -85,6 +85,7 @@ set(SRC intern/curve.c intern/customdata.c intern/customdata_file.c + intern/data_transfer.c intern/deform.c intern/depsgraph.c intern/displist.c @@ -130,7 +131,6 @@ set(SRC intern/nla.c intern/node.c intern/object.c - intern/object_data_transfer.c intern/object_deform.c intern/object_dupli.c intern/ocean.c @@ -203,6 +203,7 @@ set(SRC BKE_curve.h BKE_customdata.h BKE_customdata_file.h + BKE_data_transfer.h BKE_deform.h BKE_depsgraph.h BKE_displist.h @@ -239,7 +240,6 @@ set(SRC BKE_nla.h BKE_node.h BKE_object.h - BKE_object_data_transfer.h BKE_object_deform.h BKE_ocean.h BKE_packedFile.h diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index df57db21e3b..03372b97049 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -2166,9 +2166,9 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o mul_v3_fl(poseMat[2], scale); break; } - case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC: + case CONSTRAINT_SPLINEIK_XZS_INVERSE: { - /* 'volume preservation' */ + /* old 'volume preservation' method using the inverse scale */ float scale; /* calculate volume preservation factor which is @@ -2189,6 +2189,54 @@ static void splineik_evaluate_bone(tSplineIK_Tree *tree, Scene *scene, Object *o mul_v3_fl(poseMat[2], scale); break; } + case CONSTRAINT_SPLINEIK_XZS_VOLUMETRIC: + { + /* improved volume preservation based on the Stretch To constraint */ + float final_scale; + + /* as the basis for volume preservation, we use the inverse scale factor... */ + if (fabsf(scaleFac) != 0.0f) { + /* NOTE: The method here is taken wholesale from the Stretch To constraint */ + float bulge = powf(1.0f / fabsf(scaleFac), ikData->bulge); + + if (bulge > 1.0f) { + if (ikData->flag & STRETCHTOCON_USE_BULGE_MAX) { + float bulge_max = max_ff(ikData->bulge_max, 1.0f); + float hard = min_ff(bulge, bulge_max); + + float range = bulge_max - 1.0f; + float scale = (range > 0.0f) ? 1.0f / range : 0.0f; + float soft = 1.0f + range * atanf((bulge - 1.0f) * scale) / (0.5f * M_PI); + + bulge = interpf(soft, hard, ikData->bulge_smooth); + } + } + if (bulge < 1.0f) { + if (ikData->flag & STRETCHTOCON_USE_BULGE_MIN) { + float bulge_min = CLAMPIS(ikData->bulge_min, 0.0f, 1.0f); + float hard = max_ff(bulge, bulge_min); + + float range = 1.0f - bulge_min; + float scale = (range > 0.0f) ? 1.0f / range : 0.0f; + float soft = 1.0f - range * atanf((1.0f - bulge) * scale) / (0.5f * M_PI); + + bulge = interpf(soft, hard, ikData->bulge_smooth); + } + } + + /* compute scale factor for xz axes from this value */ + final_scale = sqrt(bulge); + } + else { + /* no scaling, so scale factor is simple */ + final_scale = 1.0f; + } + + /* apply the scaling (assuming normalised scale) */ + mul_v3_fl(poseMat[0], final_scale); + mul_v3_fl(poseMat[2], final_scale); + break; + } } /* finally, multiply the x and z scaling by the radius of the curve too, diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c index 9072acd8b02..f591fe857f8 100644 --- a/source/blender/blenkernel/intern/constraint.c +++ b/source/blender/blenkernel/intern/constraint.c @@ -2722,7 +2722,7 @@ static void stretchto_evaluate(bConstraint *con, bConstraintOb *cob, ListBase *t } if (bulge < 1.0f) { if (data->flag & STRETCHTOCON_USE_BULGE_MIN) { - float bulge_min = CLAMPIS(data->bulge_max, 0.0f, 1.0f); + float bulge_min = CLAMPIS(data->bulge_min, 0.0f, 1.0f); float hard = max_ff(bulge, bulge_min); float range = 1.0f - bulge_min; @@ -3698,6 +3698,9 @@ static void splineik_new_data(void *cdata) bSplineIKConstraint *data = (bSplineIKConstraint *)cdata; data->chainlen = 1; + data->bulge = 1.0; + data->bulge_max = 1.0f; + data->bulge_min = 1.0f; } static void splineik_id_looper(bConstraint *con, ConstraintIDFunc func, void *userdata) diff --git a/source/blender/blenkernel/intern/object_data_transfer.c b/source/blender/blenkernel/intern/data_transfer.c index 78a293c644e..b573d621052 100644 --- a/source/blender/blenkernel/intern/object_data_transfer.c +++ b/source/blender/blenkernel/intern/data_transfer.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/blenkernel/intern/object_data_transfer.c +/** \file blender/blenkernel/intern/data_transfer.c * \ingroup bke */ @@ -44,7 +44,7 @@ #include "BKE_context.h" #include "BKE_customdata.h" -#include "BKE_object_data_transfer.h" +#include "BKE_data_transfer.h" #include "BKE_deform.h" #include "BKE_DerivedMesh.h" #include "BKE_mesh_mapping.h" diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c index 4ed9278ab26..80db62801d6 100644 --- a/source/blender/blenkernel/intern/deform.c +++ b/source/blender/blenkernel/intern/deform.c @@ -52,7 +52,7 @@ #include "BLF_translation.h" #include "BKE_customdata.h" -#include "BKE_object_data_transfer.h" +#include "BKE_data_transfer.h" #include "BKE_deform.h" /* own include */ #include "BKE_mesh_mapping.h" #include "BKE_object_deform.h" diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 4c9e44682c3..915abdb6766 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -896,13 +896,6 @@ float BKE_mesh_calc_poly_area(MPoly *mpoly, MLoop *loopstart, mvarray[loopstart[2].v].co ); } - else if (mpoly->totloop == 4) { - return area_quad_v3(mvarray[loopstart[0].v].co, - mvarray[loopstart[1].v].co, - mvarray[loopstart[2].v].co, - mvarray[loopstart[3].v].co - ); - } else { int i; MLoop *l_iter = loopstart; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b158f7bec96..fb6b65d7a00 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -3507,6 +3507,88 @@ int BKE_object_is_modified(Scene *scene, Object *ob) return flag; } +/* Check of objects moves in time. */ +/* NOTE: This function is currently optimized for usage in combination + * with mti->canDeform, so modifiers can quickly check if their target + * objects moves (causing deformation motion blur) or not. + * + * This makes it possible to give some degree of false-positives here, + * but it's currently an acceptable tradeof between complexity and check + * speed. In combination with checks of modifier stack and real life usage + * percentage of false-positives shouldn't be that hight. + */ +static bool object_moves_in_time(Object *object) +{ + AnimData *adt = object->adt; + if (adt != NULL) { + /* If object has any sort of animation data assume it is moving. */ + if (adt->action != NULL || + !BLI_listbase_is_empty(&adt->nla_tracks) || + !BLI_listbase_is_empty(&adt->drivers) || + !BLI_listbase_is_empty(&adt->overrides)) + { + return true; + } + } + if (!BLI_listbase_is_empty(&object->constraints)) { + return true; + } + if (object->parent != NULL) { + /* TODO(sergey): Do recursive check here? */ + return true; + } + return false; +} + +static bool constructive_modifier_is_deform_modified(ModifierData *md) +{ + /* TODO(sergey): Consider generalizing this a bit so all modifier logic + * is concentrated in MOD_{modifier}.c file, + */ + if (md->type == eModifierType_Array) { + ArrayModifierData *amd = (ArrayModifierData *)md; + /* TODO(sergey): Check if curve is deformed. */ + return (amd->start_cap != NULL && object_moves_in_time(amd->start_cap)) || + (amd->end_cap != NULL && object_moves_in_time(amd->end_cap)) || + (amd->curve_ob != NULL && object_moves_in_time(amd->curve_ob)) || + (amd->offset_ob != NULL && object_moves_in_time(amd->offset_ob)); + } + else if (md->type == eModifierType_Mirror) { + MirrorModifierData *mmd = (MirrorModifierData *)md; + return mmd->mirror_ob != NULL && object_moves_in_time(mmd->mirror_ob); + } + else if (md->type == eModifierType_Screw) { + ScrewModifierData *smd = (ScrewModifierData *)md; + return smd->ob_axis != NULL && object_moves_in_time(smd->ob_axis); + } + return false; +} + +static bool modifiers_has_animation_check(Object *ob) +{ + /* TODO(sergey): This is a bit code duplication with depsgraph, but + * would be nicer to solve this as a part of new dependency graph + * work, so we avoid conflicts and so. + */ + if (ob->adt != NULL) { + AnimData *adt = ob->adt; + FCurve *fcu; + if (adt->action != NULL) { + for (fcu = adt->action->curves.first; fcu; fcu = fcu->next) { + if (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")) { + return true; + } + } + } + for (fcu = adt->drivers.first; fcu; fcu = fcu->next) { + if (fcu->rna_path && strstr(fcu->rna_path, "modifiers[")) { + return true; + } + } + } + return false; +} + /* test if object is affected by deforming modifiers (for motion blur). again * most important is to avoid false positives, this is to skip computations * and we can still if there was actual deformation afterwards */ @@ -3515,6 +3597,7 @@ int BKE_object_is_deform_modified(Scene *scene, Object *ob) ModifierData *md; VirtualModifierData virtualModifierData; int flag = 0; + const bool is_modifier_animated = modifiers_has_animation_check(ob); if (BKE_key_from_object(ob)) flag |= eModifierMode_Realtime | eModifierMode_Render; @@ -3525,8 +3608,14 @@ int BKE_object_is_deform_modified(Scene *scene, Object *ob) md = md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); + bool can_deform = mti->type == eModifierTypeType_OnlyDeform || + is_modifier_animated; + + if (!can_deform) { + can_deform = constructive_modifier_is_deform_modified(md); + } - if (mti->type == eModifierTypeType_OnlyDeform) { + if (can_deform) { if (!(flag & eModifierMode_Render) && modifier_isEnabled(scene, md, eModifierMode_Render)) flag |= eModifierMode_Render; |