Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/object.c
| Show First 20 Lines • Show All 851 Lines • ▼ Show 20 Lines | if (ELEM(ob->type, OB_LAMP, OB_CAMERA, OB_SPEAKER)) { | ||||
| ob->trackflag = OB_NEGZ; | ob->trackflag = OB_NEGZ; | ||||
| ob->upflag = OB_POSY; | ob->upflag = OB_POSY; | ||||
| } | } | ||||
| else { | else { | ||||
| ob->trackflag = OB_POSY; | ob->trackflag = OB_POSY; | ||||
| ob->upflag = OB_POSZ; | ob->upflag = OB_POSZ; | ||||
| } | } | ||||
| ob->dupon = 1; ob->dupoff = 0; | |||||
| ob->dupsta = 1; ob->dupend = 100; | |||||
| ob->dupfacesca = 1.0; | ob->dupfacesca = 1.0; | ||||
| ob->col_group = 0x01; | ob->col_group = 0x01; | ||||
| ob->col_mask = 0xffff; | ob->col_mask = 0xffff; | ||||
| ob->preview = NULL; | ob->preview = NULL; | ||||
| ob->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT | OB_DUPLI_FLAG_RENDER; | ob->duplicator_visibility_flag = OB_DUPLI_FLAG_VIEWPORT | OB_DUPLI_FLAG_RENDER; | ||||
| /* NT fluid sim defaults */ | /* NT fluid sim defaults */ | ||||
| ▲ Show 20 Lines • Show All 1,040 Lines • ▼ Show 20 Lines | else { | ||||
| copy_m4_m4(mat, ob->obmat); | copy_m4_m4(mat, ob->obmat); | ||||
| } | } | ||||
| } | } | ||||
| /** | /** | ||||
| * \param depsgraph: Used for dupli-frame time. | * \param depsgraph: Used for dupli-frame time. | ||||
| * \return success if \a mat is set. | * \return success if \a mat is set. | ||||
| */ | */ | ||||
| static bool ob_parcurve(Object *ob, Object *par, | static bool ob_parcurve(Object *ob, Object *par, float mat[4][4]) | ||||
| float dupli_ctime, int dupli_transflag, float mat[4][4]) | |||||
| { | { | ||||
| Curve *cu = par->data; | Curve *cu = par->data; | ||||
| float vec[4], dir[3], quat[4], radius, ctime; | float vec[4], dir[3], quat[4], radius, ctime; | ||||
| /* NOTE: Curve cache is supposed to be evaluated here already, however there | /* NOTE: Curve cache is supposed to be evaluated here already, however there | ||||
| * are cases where we can not guarantee that. This includes, for example, | * are cases where we can not guarantee that. This includes, for example, | ||||
| * dependency cycles. We can't correct anything from here, since that would | * dependency cycles. We can't correct anything from here, since that would | ||||
| * cause a threading conflicts. | * cause a threading conflicts. | ||||
| * | * | ||||
| * TODO(sergey): Somce of the legit looking cases like T56619 need to be | * TODO(sergey): Somce of the legit looking cases like T56619 need to be | ||||
| * looked into, and maybe curve cache (and other dependencies) are to be | * looked into, and maybe curve cache (and other dependencies) are to be | ||||
| * evaluated prior to conversion. */ | * evaluated prior to conversion. */ | ||||
| if (par->runtime.curve_cache == NULL) { | if (par->runtime.curve_cache == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| if (par->runtime.curve_cache->path == NULL) { | if (par->runtime.curve_cache->path == NULL) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| /* catch exceptions: curve paths used as a duplicator */ | |||||
| if ((dupli_transflag & OB_DUPLINOSPEED) == 0) { | |||||
| /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated, | /* ctime is now a proper var setting of Curve which gets set by Animato like any other var that's animated, | ||||
| * but this will only work if it actually is animated... | * but this will only work if it actually is animated... | ||||
| * | * | ||||
| * we divide the curvetime calculated in the previous step by the length of the path, to get a time | * we divide the curvetime calculated in the previous step by the length of the path, to get a time | ||||
| * factor, which then gets clamped to lie within 0.0 - 1.0 range | * factor, which then gets clamped to lie within 0.0 - 1.0 range | ||||
| */ | */ | ||||
| if (cu->pathlen) { | if (cu->pathlen) { | ||||
| ctime = cu->ctime / cu->pathlen; | ctime = cu->ctime / cu->pathlen; | ||||
| } | } | ||||
| else { | else { | ||||
| ctime = cu->ctime; | ctime = cu->ctime; | ||||
| } | } | ||||
| CLAMP(ctime, 0.0f, 1.0f); | CLAMP(ctime, 0.0f, 1.0f); | ||||
| } | |||||
| else { | |||||
| ctime = dupli_ctime; | |||||
| if (cu->pathlen) { | |||||
| ctime /= cu->pathlen; | |||||
| } | |||||
| CLAMP(ctime, 0.0f, 1.0f); | |||||
| } | |||||
| unit_m4(mat); | unit_m4(mat); | ||||
| /* vec: 4 items! */ | /* vec: 4 items! */ | ||||
| if (where_on_path(par, ctime, vec, dir, (cu->flag & CU_FOLLOW) ? quat : NULL, &radius, NULL)) { | if (where_on_path(par, ctime, vec, dir, (cu->flag & CU_FOLLOW) ? quat : NULL, &radius, NULL)) { | ||||
| if (cu->flag & CU_FOLLOW) { | if (cu->flag & CU_FOLLOW) { | ||||
| quat_apply_track(quat, ob->trackflag, ob->upflag); | quat_apply_track(quat, ob->trackflag, ob->upflag); | ||||
| normalize_qt(quat); | normalize_qt(quat); | ||||
| ▲ Show 20 Lines • Show All 170 Lines • ▼ Show 20 Lines | if (OB_TYPE_SUPPORT_PARVERT(par->type)) { | ||||
| mid_v3_v3v3v3(mat[3], v1, v2, v3); | mid_v3_v3v3v3(mat[3], v1, v2, v3); | ||||
| } | } | ||||
| else { | else { | ||||
| unit_m4(mat); | unit_m4(mat); | ||||
| } | } | ||||
| } | } | ||||
| void BKE_object_get_parent_matrix_for_dupli(Object *ob, Object *par, | void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4]) | ||||
| float dupli_ctime, int dupli_transflag, | |||||
| float parentmat[4][4]) | |||||
| { | { | ||||
| float tmat[4][4]; | float tmat[4][4]; | ||||
| float vec[3]; | float vec[3]; | ||||
| bool ok; | bool ok; | ||||
| switch (ob->partype & PARTYPE) { | switch (ob->partype & PARTYPE) { | ||||
| case PAROBJECT: | case PAROBJECT: | ||||
| ok = 0; | ok = 0; | ||||
| if (par->type == OB_CURVE) { | if (par->type == OB_CURVE) { | ||||
| if ((((Curve *)par->data)->flag & CU_PATH) && | if ((((Curve *)par->data)->flag & CU_PATH) && | ||||
| (ob_parcurve(ob, par, dupli_ctime, dupli_transflag, tmat))) | (ob_parcurve(ob, par, tmat))) | ||||
| { | { | ||||
| ok = 1; | ok = 1; | ||||
| } | } | ||||
| } | } | ||||
| if (ok) mul_m4_m4m4(parentmat, par->obmat, tmat); | if (ok) mul_m4_m4m4(parentmat, par->obmat, tmat); | ||||
| else copy_m4_m4(parentmat, par->obmat); | else copy_m4_m4(parentmat, par->obmat); | ||||
| Show All 13 Lines | case PARVERT3: | ||||
| mul_m4_m4m4(parentmat, par->obmat, tmat); | mul_m4_m4m4(parentmat, par->obmat, tmat); | ||||
| break; | break; | ||||
| case PARSKEL: | case PARSKEL: | ||||
| copy_m4_m4(parentmat, par->obmat); | copy_m4_m4(parentmat, par->obmat); | ||||
| break; | break; | ||||
| } | } | ||||
| } | |||||
| void BKE_object_get_parent_matrix(Object *ob, Object *par, float parentmat[4][4]) | |||||
| { | |||||
| BKE_object_get_parent_matrix_for_dupli(ob, par, 0, 0, parentmat); | |||||
| } | } | ||||
| /** | /** | ||||
| * \param r_originmat: Optional matrix that stores the space the object is in (without its own matrix applied) | * \param r_originmat: Optional matrix that stores the space the object is in (without its own matrix applied) | ||||
| */ | */ | ||||
| static void solve_parenting(Object *ob, Object *par, float obmat[4][4], float slowmat[4][4], | static void solve_parenting(Object *ob, Object *par, float obmat[4][4], | ||||
| float r_originmat[3][3], const bool set_origin, | float r_originmat[3][3], const bool set_origin) | ||||
| float dupli_ctime, int dupli_transflag) | |||||
| { | { | ||||
| float totmat[4][4]; | float totmat[4][4]; | ||||
| float tmat[4][4]; | float tmat[4][4]; | ||||
| float locmat[4][4]; | float locmat[4][4]; | ||||
| BKE_object_to_mat4(ob, locmat); | BKE_object_to_mat4(ob, locmat); | ||||
| if (ob->partype & PARSLOW) copy_m4_m4(slowmat, obmat); | BKE_object_get_parent_matrix(ob, par, totmat); | ||||
| BKE_object_get_parent_matrix_for_dupli(ob, par, dupli_ctime, dupli_transflag, totmat); | |||||
| /* total */ | /* total */ | ||||
| mul_m4_m4m4(tmat, totmat, ob->parentinv); | mul_m4_m4m4(tmat, totmat, ob->parentinv); | ||||
| mul_m4_m4m4(obmat, tmat, locmat); | mul_m4_m4m4(obmat, tmat, locmat); | ||||
| if (r_originmat) { | if (r_originmat) { | ||||
| /* usable originmat */ | /* usable originmat */ | ||||
| copy_m3_m4(r_originmat, tmat); | copy_m3_m4(r_originmat, tmat); | ||||
| } | } | ||||
| /* origin, for help line */ | /* origin, for help line */ | ||||
| if (set_origin) { | if (set_origin) { | ||||
| if ((ob->partype & PARTYPE) == PARSKEL) { | if ((ob->partype & PARTYPE) == PARSKEL) { | ||||
| copy_v3_v3(ob->orig, par->obmat[3]); | copy_v3_v3(ob->orig, par->obmat[3]); | ||||
| } | } | ||||
| else { | else { | ||||
| copy_v3_v3(ob->orig, totmat[3]); | copy_v3_v3(ob->orig, totmat[3]); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static bool where_is_object_parslow(Object *ob, float obmat[4][4], float slowmat[4][4]) | |||||
| { | |||||
| float *fp1, *fp2; | |||||
| float fac1, fac2; | |||||
| int a; | |||||
| /* include framerate */ | |||||
| fac1 = (1.0f / (1.0f + fabsf(ob->sf))); | |||||
| if (fac1 >= 1.0f) return false; | |||||
| fac2 = 1.0f - fac1; | |||||
| fp1 = obmat[0]; | |||||
| fp2 = slowmat[0]; | |||||
| for (a = 0; a < 16; a++, fp1++, fp2++) { | |||||
| fp1[0] = fac1 * fp1[0] + fac2 * fp2[0]; | |||||
| } | |||||
| return true; | |||||
| } | |||||
| /* note, scene is the active scene while actual_scene is the scene the object resides in */ | /* note, scene is the active scene while actual_scene is the scene the object resides in */ | ||||
| void BKE_object_where_is_calc_time_ex( | void BKE_object_where_is_calc_time_ex( | ||||
| Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime, int dupli_transflag, | Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime, | ||||
| RigidBodyWorld *rbw, float r_originmat[3][3]) | RigidBodyWorld *rbw, float r_originmat[3][3]) | ||||
| { | { | ||||
| if (ob == NULL) return; | if (ob == NULL) return; | ||||
| /* execute drivers only, as animation has already been done */ | /* execute drivers only, as animation has already been done */ | ||||
| BKE_animsys_evaluate_animdata(depsgraph, scene, &ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS); | BKE_animsys_evaluate_animdata(depsgraph, scene, &ob->id, ob->adt, ctime, ADT_RECALC_DRIVERS); | ||||
sergey: Is this still needed? | |||||
| if (ob->parent) { | if (ob->parent) { | ||||
| Object *par = ob->parent; | Object *par = ob->parent; | ||||
| float slowmat[4][4]; | |||||
| /* calculate parent matrix */ | /* calculate parent matrix */ | ||||
| solve_parenting(ob, par, ob->obmat, slowmat, r_originmat, true, | solve_parenting(ob, par, ob->obmat, r_originmat, true); | ||||
| ctime, dupli_transflag); | |||||
| /* "slow parent" is definitely not threadsafe, and may also give bad results jumping around | |||||
| * An old-fashioned hack which probably doesn't really cut it anymore | |||||
| */ | |||||
| if (ob->partype & PARSLOW) { | |||||
| if (!where_is_object_parslow(ob, ob->obmat, slowmat)) | |||||
| return; | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| BKE_object_to_mat4(ob, ob->obmat); | BKE_object_to_mat4(ob, ob->obmat); | ||||
| } | } | ||||
| /* try to fall back to the scene rigid body world if none given */ | /* try to fall back to the scene rigid body world if none given */ | ||||
| rbw = rbw ? rbw : scene->rigidbody_world; | rbw = rbw ? rbw : scene->rigidbody_world; | ||||
| /* read values pushed into RBO from sim/cache... */ | /* read values pushed into RBO from sim/cache... */ | ||||
| Show All 9 Lines | void BKE_object_where_is_calc_time_ex( | ||||
| /* set negative scale flag in object */ | /* set negative scale flag in object */ | ||||
| if (is_negative_m4(ob->obmat)) ob->transflag |= OB_NEG_SCALE; | if (is_negative_m4(ob->obmat)) ob->transflag |= OB_NEG_SCALE; | ||||
| else ob->transflag &= ~OB_NEG_SCALE; | else ob->transflag &= ~OB_NEG_SCALE; | ||||
| } | } | ||||
| void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime) | void BKE_object_where_is_calc_time(Depsgraph *depsgraph, Scene *scene, Object *ob, float ctime) | ||||
| { | { | ||||
| BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, ctime, 0, NULL, NULL); | BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, ctime, NULL, NULL); | ||||
| } | } | ||||
| void BKE_object_where_is_calc_time_for_dupli( | |||||
| Depsgraph *depsgraph, Scene *scene, struct Object *ob, float ctime, int dupli_transflag) | |||||
| { | |||||
| BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, ctime, dupli_transflag, NULL, NULL); | |||||
| } | |||||
| /* get object transformation matrix without recalculating dependencies and | /* get object transformation matrix without recalculating dependencies and | ||||
| * constraints -- assume dependencies are already solved by depsgraph. | * constraints -- assume dependencies are already solved by depsgraph. | ||||
| * no changes to object and it's parent would be done. | * no changes to object and it's parent would be done. | ||||
| * used for bundles orientation in 3d space relative to parented blender camera */ | * used for bundles orientation in 3d space relative to parented blender camera */ | ||||
| void BKE_object_where_is_calc_mat4(Object *ob, float obmat[4][4]) | void BKE_object_where_is_calc_mat4(Object *ob, float obmat[4][4]) | ||||
| { | { | ||||
| if (ob->parent) { | if (ob->parent) { | ||||
| float slowmat[4][4]; | |||||
| Object *par = ob->parent; | Object *par = ob->parent; | ||||
| solve_parenting(ob, par, obmat, NULL, false); | |||||
| solve_parenting(ob, par, obmat, slowmat, NULL, false, 0.0f, 0); | |||||
| if (ob->partype & PARSLOW) | |||||
| where_is_object_parslow(ob, obmat, slowmat); | |||||
| } | } | ||||
| else { | else { | ||||
| BKE_object_to_mat4(ob, obmat); | BKE_object_to_mat4(ob, obmat); | ||||
| } | } | ||||
| } | } | ||||
| void BKE_object_where_is_calc_ex(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3]) | void BKE_object_where_is_calc_ex(Depsgraph *depsgraph, Scene *scene, RigidBodyWorld *rbw, Object *ob, float r_originmat[3][3]) | ||||
| { | { | ||||
| BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), 0, rbw, r_originmat); | BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), rbw, r_originmat); | ||||
| } | } | ||||
| void BKE_object_where_is_calc(Depsgraph *depsgraph, Scene *scene, Object *ob) | void BKE_object_where_is_calc(Depsgraph *depsgraph, Scene *scene, Object *ob) | ||||
| { | { | ||||
| BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), 0, NULL, NULL); | BKE_object_where_is_calc_time_ex(depsgraph, scene, ob, DEG_get_ctime(depsgraph), NULL, NULL); | ||||
| } | } | ||||
| /** | /** | ||||
| * For calculation of the inverse parent transform, only used for editor. | * For calculation of the inverse parent transform, only used for editor. | ||||
| * | * | ||||
| * It assumes the object parent is already in the depsgraph. | * It assumes the object parent is already in the depsgraph. | ||||
| * Otherwise, after changing ob->parent you need to call: | * Otherwise, after changing ob->parent you need to call: | ||||
| * - #DEG_relations_tag_update(bmain); | * - #DEG_relations_tag_update(bmain); | ||||
| ▲ Show 20 Lines • Show All 1,767 Lines • Show Last 20 Lines | |||||
Is this still needed?