/* Sync rigid body and object transformations */ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) { RigidBodyOb *rbo = ob->rigidbody_object; /* keep original transform for kinematic and passive objects */ if (ELEM(NULL, rbw, rbo) || rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE) return; /* use rigid body transform after cache start frame if objects is not being transformed */ if (BKE_rigidbody_check_sim_running(rbw, ctime) && !(ob->flag & SELECT && G.moving & G_TRANSFORM_OBJ)) { float mat[4][4], size_mat[4][4], size[3]; normalize_qt(rbo->orn); // RB_TODO investigate why quaternion isn't normalized at this point quat_to_mat4(mat, rbo->orn); copy_v3_v3(mat[3], rbo->pos); mat4_to_size(size, ob->obmat); size_to_mat4(size_mat, size); mul_m4_m4m4(mat, mat, size_mat); copy_m4_m4(ob->obmat, mat); } /* otherwise set rigid body transform to current obmat */ else { mat4_to_loc_quat(rbo->pos, rbo->orn, ob->obmat); } }
/* Only allowed for Poses with identical channels */ static void game_blend_poses(bPose *dst, bPose *src, float srcweight, short mode) { bPoseChannel *dchan; const bPoseChannel *schan; bConstraint *dcon, *scon; float dstweight; int i; if (mode == BL_Action::ACT_BLEND_BLEND) { dstweight = 1.0f - srcweight; } else if (mode == BL_Action::ACT_BLEND_ADD) { dstweight = 1.0f; } else { dstweight = 1.0f; } schan= (bPoseChannel *)src->chanbase.first; for (dchan = (bPoseChannel *)dst->chanbase.first; dchan; dchan=(bPoseChannel *)dchan->next, schan= (bPoseChannel *)schan->next) { // always blend on all channels since we don't know which one has been set /* quat interpolation done separate */ if (schan->rotmode == ROT_MODE_QUAT) { float dquat[4], squat[4]; copy_qt_qt(dquat, dchan->quat); copy_qt_qt(squat, schan->quat); if (mode==BL_Action::ACT_BLEND_BLEND) interp_qt_qtqt(dchan->quat, dquat, squat, srcweight); else { mul_fac_qt_fl(squat, srcweight); mul_qt_qtqt(dchan->quat, dquat, squat); } normalize_qt(dchan->quat); } for (i=0; i<3; i++) { /* blending for loc and scale are pretty self-explanatory... */ dchan->loc[i] = (dchan->loc[i]*dstweight) + (schan->loc[i]*srcweight); dchan->size[i] = 1.0f + ((dchan->size[i]-1.0f)*dstweight) + ((schan->size[i]-1.0f)*srcweight); /* euler-rotation interpolation done here instead... */ // FIXME: are these results decent? if (schan->rotmode) dchan->eul[i] = (dchan->eul[i]*dstweight) + (schan->eul[i]*srcweight); } for (dcon= (bConstraint *)dchan->constraints.first, scon= (bConstraint *)schan->constraints.first; dcon && scon; dcon = dcon->next, scon = scon->next) { /* no 'add' option for constraint blending */ dcon->enforce= dcon->enforce*(1.0f-srcweight) + scon->enforce*srcweight; } } /* this pose is now in src time */ dst->ctime= src->ctime; }
static PyObject *Quaternion_normalize(QuaternionObject *self) { if (BaseMath_ReadCallback(self) == -1) return NULL; normalize_qt(self->quat); (void)BaseMath_WriteCallback(self); Py_RETURN_NONE; }
/* axis is using another define!!! */ static int calc_curve_deform(Scene *scene, Object *par, float co[3], const short axis, CurveDeform *cd, float quat_r[4]) { Curve *cu = par->data; float fac, loc[4], dir[3], new_quat[4], radius; short index; const int is_neg_axis = (axis > 2); /* to be sure, mostly after file load */ if (cu->path == NULL) { BKE_displist_make_curveTypes(scene, par, 0); if (cu->path == NULL) return 0; // happens on append... } /* options */ if (is_neg_axis) { index = axis - 3; if (cu->flag & CU_STRETCH) fac = (-co[index] - cd->dmax[index]) / (cd->dmax[index] - cd->dmin[index]); else fac = -(co[index] - cd->dmax[index]) / (cu->path->totdist); } else { index = axis; if (cu->flag & CU_STRETCH) fac = (co[index] - cd->dmin[index]) / (cd->dmax[index] - cd->dmin[index]); else fac = +(co[index] - cd->dmin[index]) / (cu->path->totdist); } if (where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */ float quat[4], cent[3]; if (cd->no_rot_axis) { /* set by caller */ /* this is not exactly the same as 2.4x, since the axis is having rotation removed rather than * changing the axis before calculating the tilt but serves much the same purpose */ float dir_flat[3] = {0, 0, 0}, q[4]; copy_v3_v3(dir_flat, dir); dir_flat[cd->no_rot_axis - 1] = 0.0f; normalize_v3(dir); normalize_v3(dir_flat); rotation_between_vecs_to_quat(q, dir, dir_flat); /* Could this be done faster? */ mul_qt_qtqt(new_quat, q, new_quat); } /* Logic for 'cent' orientation * * * The way 'co' is copied to 'cent' may seem to have no meaning, but it does. * * Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark. * view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise * Notice X,Y,Z Up all have light colors and each ordered CCW. * * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell * * note: moved functions into quat_apply_track/vec_apply_track * */ copy_qt_qt(quat, new_quat); copy_v3_v3(cent, co); /* zero the axis which is not used, * the big block of text above now applies to these 3 lines */ quat_apply_track(quat, axis, (axis == 0 || axis == 2) ? 1 : 0); /* up flag is a dummy, set so no rotation is done */ vec_apply_track(cent, axis); cent[index] = 0.0f; /* scale if enabled */ if (cu->flag & CU_PATH_RADIUS) mul_v3_fl(cent, radius); /* local rotation */ normalize_qt(quat); mul_qt_v3(quat, cent); /* translation */ add_v3_v3v3(co, cent, loc); if (quat_r) copy_qt_qt(quat_r, quat); return 1; } return 0; }
static void rna_MetaBall_update_rotation(Main *bmain, Scene *scene, PointerRNA *ptr) { MetaElem *ml = ptr->data; normalize_qt(ml->quat); rna_MetaBall_update_data(bmain, scene, ptr); }
/* calculate a curve-deform path for a curve * - only called from displist.c -> do_makeDispListCurveTypes */ void calc_curvepath(Object *ob) { BevList *bl; BevPoint *bevp, *bevpn, *bevpfirst, *bevplast; PathPoint *pp; Curve *cu; Nurb *nu; Path *path; float *fp, *dist, *maxdist, xyz[3]; float fac, d=0, fac1, fac2; int a, tot, cycl=0; ListBase *nurbs; /* in a path vertices are with equal differences: path->len = number of verts */ /* NOW WITH BEVELCURVE!!! */ if (ob==NULL || ob->type != OB_CURVE) return; cu= ob->data; nurbs= BKE_curve_nurbs(cu); nu= nurbs->first; if (cu->path) free_path(cu->path); cu->path= NULL; bl= cu->bev.first; if (bl==NULL || !bl->nr) return; cu->path=path= MEM_callocN(sizeof(Path), "calc_curvepath"); /* if POLY: last vertice != first vertice */ cycl= (bl->poly!= -1); if (cycl) tot= bl->nr; else tot= bl->nr-1; path->len= tot+1; /* exception: vector handle paths and polygon paths should be subdivided at least a factor resolu */ if (path->len<nu->resolu*SEGMENTSU(nu)) path->len= nu->resolu*SEGMENTSU(nu); dist= (float *)MEM_mallocN((tot+1)*4, "calcpathdist"); /* all lengths in *dist */ bevp= bevpfirst= (BevPoint *)(bl+1); fp= dist; *fp= 0; for (a=0; a<tot; a++) { fp++; if (cycl && a==tot-1) sub_v3_v3v3(xyz, bevpfirst->vec, bevp->vec); else sub_v3_v3v3(xyz, (bevp+1)->vec, bevp->vec); *fp= *(fp-1)+len_v3(xyz); bevp++; } path->totdist= *fp; /* the path verts in path->data */ /* now also with TILT value */ pp= path->data = (PathPoint *)MEM_callocN(sizeof(PathPoint)*path->len, "pathdata"); bevp= bevpfirst; bevpn= bevp+1; bevplast= bevpfirst + (bl->nr-1); fp= dist+1; maxdist= dist+tot; fac= 1.0f/((float)path->len-1.0f); fac = fac * path->totdist; for (a=0; a<path->len; a++) { d= ((float)a)*fac; /* we're looking for location (distance) 'd' in the array */ while ((d>= *fp) && fp<maxdist) { fp++; if (bevp<bevplast) bevp++; bevpn= bevp+1; if (bevpn>bevplast) { if (cycl) bevpn= bevpfirst; else bevpn= bevplast; } } fac1= *(fp)- *(fp-1); fac2= *(fp)-d; fac1= fac2/fac1; fac2= 1.0f-fac1; interp_v3_v3v3(pp->vec, bevp->vec, bevpn->vec, fac2); pp->vec[3]= fac1*bevp->alfa + fac2*bevpn->alfa; pp->radius= fac1*bevp->radius + fac2*bevpn->radius; pp->weight= fac1*bevp->weight + fac2*bevpn->weight; interp_qt_qtqt(pp->quat, bevp->quat, bevpn->quat, fac2); normalize_qt(pp->quat); pp++; } MEM_freeN(dist); }
/* axis is using another define!!! */ static int calc_curve_deform(Scene *scene, Object *par, float *co, short axis, CurveDeform *cd, float *quatp) { Curve *cu= par->data; float fac, loc[4], dir[3], new_quat[4], radius; short /*upflag, */ index; index= axis-1; if(index>2) index -= 3; /* negative */ /* to be sure, mostly after file load */ if(cu->path==NULL) { makeDispListCurveTypes(scene, par, 0); if(cu->path==NULL) return 0; // happens on append... } /* options */ if(ELEM3(axis, OB_NEGX+1, OB_NEGY+1, OB_NEGZ+1)) { /* OB_NEG# 0-5, MOD_CURVE_POS# 1-6 */ if(cu->flag & CU_STRETCH) fac= (-co[index]-cd->dmax[index])/(cd->dmax[index] - cd->dmin[index]); else fac= (cd->dloc[index])/(cu->path->totdist) - (co[index]-cd->dmax[index])/(cu->path->totdist); } else { if(cu->flag & CU_STRETCH) fac= (co[index]-cd->dmin[index])/(cd->dmax[index] - cd->dmin[index]); else fac= (cd->dloc[index])/(cu->path->totdist) + (co[index]-cd->dmin[index])/(cu->path->totdist); } #if 0 // XXX old animation system /* we want the ipo to work on the default 100 frame range, because there's no actual time involved in path position */ // huh? by WHY!!!!???? - Aligorith if(cu->ipo) { fac*= 100.0f; if(calc_ipo_spec(cu->ipo, CU_SPEED, &fac)==0) fac/= 100.0; } #endif // XXX old animation system if( where_on_path_deform(par, fac, loc, dir, new_quat, &radius)) { /* returns OK */ float quat[4], cent[3]; #if 0 // XXX - 2.4x Z-Up, Now use bevel tilt. if(cd->no_rot_axis) /* set by caller */ dir[cd->no_rot_axis-1]= 0.0f; /* -1 for compatibility with old track defines */ vec_to_quat( quat,dir, axis-1, upflag); /* the tilt */ if(loc[3]!=0.0) { normalize_v3(dir); q[0]= (float)cos(0.5*loc[3]); fac= (float)sin(0.5*loc[3]); q[1]= -fac*dir[0]; q[2]= -fac*dir[1]; q[3]= -fac*dir[2]; mul_qt_qtqt(quat, q, quat); } #endif if(cd->no_rot_axis) { /* set by caller */ /* this is not exactly the same as 2.4x, since the axis is having rotation removed rather than * changing the axis before calculating the tilt but serves much the same purpose */ float dir_flat[3]={0,0,0}, q[4]; copy_v3_v3(dir_flat, dir); dir_flat[cd->no_rot_axis-1]= 0.0f; normalize_v3(dir); normalize_v3(dir_flat); rotation_between_vecs_to_quat(q, dir, dir_flat); /* Could this be done faster? */ mul_qt_qtqt(new_quat, q, new_quat); } /* Logic for 'cent' orientation * * * The way 'co' is copied to 'cent' may seem to have no meaning, but it does. * * Use a curve modifier to stretch a cube out, color each side RGB, positive side light, negative dark. * view with X up (default), from the angle that you can see 3 faces RGB colors (light), anti-clockwise * Notice X,Y,Z Up all have light colors and each ordered CCW. * * Now for Neg Up XYZ, the colors are all dark, and ordered clockwise - Campbell * * note: moved functions into quat_apply_track/vec_apply_track * */ copy_qt_qt(quat, new_quat); copy_v3_v3(cent, co); /* zero the axis which is not used, * the big block of text above now applies to these 3 lines */ quat_apply_track(quat, axis-1, (axis==1 || axis==3) ? 1:0); /* up flag is a dummy, set so no rotation is done */ vec_apply_track(cent, axis-1); cent[axis < 4 ? axis-1 : axis-4]= 0.0f; /* scale if enabled */ if(cu->flag & CU_PATH_RADIUS) mul_v3_fl(cent, radius); /* local rotation */ normalize_qt(quat); mul_qt_v3(quat, cent); /* translation */ add_v3_v3v3(co, cent, loc); if(quatp) copy_qt_qt(quatp, quat); return 1; } return 0; }