BL_ArmatureConstraint::BL_ArmatureConstraint( BL_ArmatureObject *armature, bPoseChannel *posechannel, bConstraint *constraint, KX_GameObject* target, KX_GameObject* subtarget) : PyObjectPlus(), m_constraint(constraint), m_posechannel(posechannel), m_armature(armature) { m_target = target; m_blendtarget = (target) ? target->GetBlenderObject() : NULL; m_subtarget = subtarget; m_blendsubtarget = (subtarget) ? subtarget->GetBlenderObject() : NULL; m_pose = m_subpose = NULL; if (m_blendtarget) { copy_m4_m4(m_blendmat, m_blendtarget->obmat); if (m_blendtarget->type == OB_ARMATURE) m_pose = m_blendtarget->pose; } if (m_blendsubtarget) { copy_m4_m4(m_blendsubmat, m_blendsubtarget->obmat); if (m_blendsubtarget->type == OB_ARMATURE) m_subpose = m_blendsubtarget->pose; } if (m_target) m_target->RegisterObject(m_armature); if (m_subtarget) m_subtarget->RegisterObject(m_armature); BLI_snprintf(m_name, sizeof(m_name), "%s:%s", m_posechannel->name, m_constraint->name); }
static void copy_pose_channel_data(bPoseChannel *pchan, const bPoseChannel *chan) { bConstraint *pcon, *con; copy_v3_v3(pchan->loc, chan->loc); copy_v3_v3(pchan->size, chan->size); copy_v3_v3(pchan->eul, chan->eul); copy_v3_v3(pchan->rotAxis, chan->rotAxis); pchan->rotAngle = chan->rotAngle; copy_qt_qt(pchan->quat, chan->quat); pchan->rotmode = chan->rotmode; copy_m4_m4(pchan->chan_mat, (float(*)[4])chan->chan_mat); copy_m4_m4(pchan->pose_mat, (float(*)[4])chan->pose_mat); pchan->flag = chan->flag; pchan->roll1 = chan->roll1; pchan->roll2 = chan->roll2; pchan->curveInX = chan->curveInX; pchan->curveInY = chan->curveInY; pchan->curveOutX = chan->curveOutX; pchan->curveOutY = chan->curveOutY; pchan->scaleIn = chan->scaleIn; pchan->scaleOut = chan->scaleOut; con = chan->constraints.first; for (pcon = pchan->constraints.first; pcon && con; pcon = pcon->next, con = con->next) { pcon->enforce = con->enforce; pcon->headtail = con->headtail; } }
static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[4][4], int lay, int persistent_id[MAX_DUPLI_RECUR], int level, int index, int type, short flag) { DupliObject *dob = MEM_callocN(sizeof(DupliObject), "dupliobject"); int i; BLI_addtail(lb, dob); dob->ob = ob; copy_m4_m4(dob->mat, mat); copy_m4_m4(dob->omat, ob->obmat); dob->origlay = ob->lay; dob->type = type; dob->animated = (type == OB_DUPLIGROUP) && (flag & DUPLILIST_ANIMATED); ob->lay = lay; /* set persistent id, which is an array with a persistent index for each level * (particle number, vertex number, ..). by comparing this we can find the same * dupli object between frames, which is needed for motion blur. last level * goes first in the array. */ dob->persistent_id[0] = index; for (i = 1; i < level; i++) dob->persistent_id[i] = persistent_id[level - 1 - i]; /* metaballs never draw in duplis, they are instead merged into one by the basis * mball outside of the group. this does mean that if that mball is not in the * scene, they will not show up at all, limitation that should be solved once. */ if (ob->type == OB_MBALL) dob->no_draw = TRUE; return dob; }
DupliApplyData *duplilist_apply(Object *ob, Scene *scene, ListBase *duplilist) { DupliApplyData *apply_data = NULL; int num_objects = BLI_listbase_count(duplilist); if (num_objects > 0) { DupliObject *dob; int i; apply_data = MEM_mallocN(sizeof(DupliApplyData), "DupliObject apply data"); apply_data->num_objects = num_objects; apply_data->extra = MEM_mallocN(sizeof(DupliExtraData) * (size_t) num_objects, "DupliObject apply extra data"); for (dob = duplilist->first, i = 0; dob; dob = dob->next, ++i) { /* copy obmat from duplis */ copy_m4_m4(apply_data->extra[i].obmat, dob->ob->obmat); /* make sure derivedmesh is calculated once, before drawing */ if (scene && !(dob->ob->transflag & OB_DUPLICALCDERIVED) && dob->ob->type == OB_MESH) { mesh_get_derived_final(scene, dob->ob, scene->customdata_mask); dob->ob->transflag |= OB_DUPLICALCDERIVED; } copy_m4_m4(dob->ob->obmat, dob->mat); /* copy layers from the main duplicator object */ apply_data->extra[i].lay = dob->ob->lay; dob->ob->lay = ob->lay; } } return apply_data; }
void env_rotate_scene(Render *re, float mat[4][4], int do_rotate) { GroupObject *go; ObjectRen *obr; ObjectInstanceRen *obi; LampRen *lar = NULL; HaloRen *har = NULL; float imat[3][3], mat_inverse[4][4], smat[4][4], tmat[4][4], cmat[3][3], tmpmat[4][4]; int a; if (do_rotate == 0) { invert_m4_m4(tmat, mat); copy_m3_m4(imat, tmat); copy_m4_m4(mat_inverse, mat); } else { copy_m4_m4(tmat, mat); copy_m3_m4(imat, mat); invert_m4_m4(mat_inverse, tmat); } for (obi = re->instancetable.first; obi; obi = obi->next) { /* append or set matrix depending on dupli */ if (obi->flag & R_DUPLI_TRANSFORMED) { copy_m4_m4(tmpmat, obi->mat); mul_m4_m4m4(obi->mat, tmat, tmpmat); } else if (do_rotate == 1) copy_m4_m4(obi->mat, tmat); else unit_m4(obi->mat); copy_m3_m4(cmat, obi->mat); invert_m3_m3(obi->nmat, cmat); transpose_m3(obi->nmat); /* indicate the renderer has to use transform matrices */ if (do_rotate == 0) obi->flag &= ~R_ENV_TRANSFORMED; else { obi->flag |= R_ENV_TRANSFORMED; copy_m4_m4(obi->imat, mat_inverse); } } for (obr = re->objecttable.first; obr; obr = obr->next) { for (a = 0; a < obr->tothalo; a++) { if ((a & 255) == 0) har = obr->bloha[a >> 8]; else har++; mul_m4_v3(tmat, har->co); } /* imat_ren is needed for correct texture coordinates */ mul_m4_m4m4(obr->ob->imat_ren, re->viewmat, obr->ob->obmat); invert_m4(obr->ob->imat_ren); }
static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { DupliObject *dob; Group *group; GroupObject *go; float mat[4][4], tmat[4][4], id; if (ob->dup_group == NULL) return; group = ob->dup_group; /* simple preventing of too deep nested groups */ if (level > MAX_DUPLI_RECUR) return; /* handles animated groups, and */ /* we need to check update for objects that are not in scene... */ if (flag & DUPLILIST_DO_UPDATE) { /* note: update is optional because we don't always need object * transformations to be correct. Also fixes bug [#29616]. */ group_handle_recalc_and_update(scene, ob, group); } if (group_is_animated(ob, group)) flag |= DUPLILIST_ANIMATED; for (go = group->gobject.first, id = 0; go; go = go->next, id++) { /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ if (go->ob != ob) { /* group dupli offset, should apply after everything else */ if (!is_zero_v3(group->dupli_ofs)) { copy_m4_m4(tmat, go->ob->obmat); sub_v3_v3v3(tmat[3], tmat[3], group->dupli_ofs); mult_m4_m4m4(mat, ob->obmat, tmat); } else { mult_m4_m4m4(mat, ob->obmat, go->ob->obmat); } dob = new_dupli_object(lb, go->ob, mat, ob->lay, persistent_id, level, id, OB_DUPLIGROUP, flag); /* check the group instance and object layers match, also that the object visible flags are ok. */ if ((dob->origlay & group->layer) == 0 || ((G.is_rendering == FALSE) && dob->ob->restrictflag & OB_RESTRICT_VIEW) || ((G.is_rendering == TRUE) && dob->ob->restrictflag & OB_RESTRICT_RENDER)) { dob->no_draw = TRUE; } if (go->ob->transflag & OB_DUPLI) { copy_m4_m4(dob->ob->obmat, dob->mat); object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, persistent_id, level + 1, id, flag); copy_m4_m4(dob->ob->obmat, dob->omat); } } } }
void mesh_deform_bind(Scene *scene, MeshDeformModifierData *mmd, float *vertexcos, int totvert, float cagemat[][4]) { MeshDeformBind mdb; MVert *mvert; int a; waitcursor(1); start_progress_bar(); memset(&mdb, 0, sizeof(MeshDeformBind)); /* get mesh and cage mesh */ mdb.vertexcos= MEM_callocN(sizeof(float)*3*totvert, "MeshDeformCos"); mdb.totvert= totvert; mdb.cagedm= mesh_create_derived_no_deform(scene, mmd->object, NULL, CD_MASK_BAREMESH); mdb.totcagevert= mdb.cagedm->getNumVerts(mdb.cagedm); mdb.cagecos= MEM_callocN(sizeof(*mdb.cagecos)*mdb.totcagevert, "MeshDeformBindCos"); copy_m4_m4(mdb.cagemat, cagemat); mvert= mdb.cagedm->getVertArray(mdb.cagedm); for(a=0; a<mdb.totcagevert; a++) copy_v3_v3(mdb.cagecos[a], mvert[a].co); for(a=0; a<mdb.totvert; a++) mul_v3_m4v3(mdb.vertexcos[a], mdb.cagemat, vertexcos + a*3); /* solve */ #if 0 if(mmd->mode == MOD_MDEF_VOLUME) harmonic_coordinates_bind(scene, mmd, &mdb); else heat_weighting_bind(scene, dm, mmd, &mdb); #else harmonic_coordinates_bind(scene, mmd, &mdb); #endif /* assign bind variables */ mmd->bindcagecos= (float*)mdb.cagecos; mmd->totvert= mdb.totvert; mmd->totcagevert= mdb.totcagevert; copy_m4_m4(mmd->bindmat, mmd->object->obmat); /* transform bindcagecos to world space */ for(a=0; a<mdb.totcagevert; a++) mul_m4_v3(mmd->object->obmat, mmd->bindcagecos+a*3); /* free */ mdb.cagedm->release(mdb.cagedm); MEM_freeN(mdb.vertexcos); /* compact weights */ modifier_mdef_compact_influences((ModifierData*)mmd); end_progress_bar(); waitcursor(0); }
void ArmatureExporter::add_bone_transform(Object *ob_arm, Bone *bone, COLLADASW::Node &node) { // bPoseChannel *pchan = BKE_pose_channel_find_name(ob_arm->pose, bone->name); float mat[4][4]; float bone_rest_mat[4][4]; /* derived from bone->arm_mat */ float parent_rest_mat[4][4]; /* derived from bone->parent->arm_mat */ bool has_restmat = bc_get_property_matrix(bone, "rest_mat", mat); if (!has_restmat) { /* Have no restpose matrix stored, try old style <= Blender 2.78 */ bc_create_restpose_mat(this->export_settings, bone, bone_rest_mat, bone->arm_mat, true); if (is_export_root(bone)) { copy_m4_m4(mat, bone_rest_mat); } else { Matrix parent_inverse; bc_create_restpose_mat( this->export_settings, bone->parent, parent_rest_mat, bone->parent->arm_mat, true); invert_m4_m4(parent_inverse, parent_rest_mat); mul_m4_m4m4(mat, parent_inverse, bone_rest_mat); } // OPEN_SIM_COMPATIBILITY if (export_settings.get_open_sim()) { // Remove rotations vs armature from transform // parent_rest_rot * mat * irest_rot Matrix workmat; copy_m4_m4(workmat, bone_rest_mat); workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f; invert_m4(workmat); mul_m4_m4m4(mat, mat, workmat); if (!is_export_root(bone)) { copy_m4_m4(workmat, parent_rest_mat); workmat[3][0] = workmat[3][1] = workmat[3][2] = 0.0f; mul_m4_m4m4(mat, workmat, mat); } } } if (this->export_settings.get_limit_precision()) { bc_sanitize_mat(mat, LIMITTED_PRECISION); } TransformWriter::add_joint_transform(node, mat, NULL, this->export_settings, has_restmat); }
/* For the calculation of the effects of an Action at the given frame on an object * This is currently only used for the Action Constraint */ void what_does_obaction (Object *ob, Object *workob, bPose *pose, bAction *act, char groupname[], float cframe) { bActionGroup *agrp= action_groups_find_named(act, groupname); /* clear workob */ clear_workob(workob); /* init workob */ copy_m4_m4(workob->obmat, ob->obmat); copy_m4_m4(workob->parentinv, ob->parentinv); copy_m4_m4(workob->constinv, ob->constinv); workob->parent= ob->parent; workob->rotmode= ob->rotmode; workob->trackflag= ob->trackflag; workob->upflag= ob->upflag; workob->partype= ob->partype; workob->par1= ob->par1; workob->par2= ob->par2; workob->par3= ob->par3; workob->constraints.first = ob->constraints.first; workob->constraints.last = ob->constraints.last; workob->pose= pose; /* need to set pose too, since this is used for both types of Action Constraint */ BLI_strncpy(workob->parsubstr, ob->parsubstr, sizeof(workob->parsubstr)); BLI_strncpy(workob->id.name, "OB<ConstrWorkOb>", sizeof(workob->id.name)); /* we don't use real object name, otherwise RNA screws with the real thing */ /* if we're given a group to use, it's likely to be more efficient (though a bit more dangerous) */ if (agrp) { /* specifically evaluate this group only */ PointerRNA id_ptr; /* get RNA-pointer for the workob's ID */ RNA_id_pointer_create(&workob->id, &id_ptr); /* execute action for this group only */ animsys_evaluate_action_group(&id_ptr, act, agrp, NULL, cframe); } else { AnimData adt= {NULL}; /* init animdata, and attach to workob */ workob->adt= &adt; adt.recalc= ADT_RECALC_ANIM; adt.action= act; /* execute effects of Action on to workob (or it's PoseChannels) */ BKE_animsys_evaluate_animdata(NULL, &workob->id, &adt, cframe, ADT_RECALC_ANIM); } }
static void group_duplilist(ListBase *lb, Scene *scene, Object *ob, int level, int animated) { DupliObject *dob; Group *group; GroupObject *go; float mat[4][4], tmat[4][4]; if (ob->dup_group==NULL) return; group= ob->dup_group; /* simple preventing of too deep nested groups */ if (level>MAX_DUPLI_RECUR) return; /* handles animated groups, and */ /* we need to check update for objects that are not in scene... */ group_handle_recalc_and_update(scene, ob, group); animated= animated || group_is_animated(ob, group); for (go= group->gobject.first; go; go= go->next) { /* note, if you check on layer here, render goes wrong... it still deforms verts and uses parent imat */ if (go->ob!=ob) { /* group dupli offset, should apply after everything else */ if (!is_zero_v3(group->dupli_ofs)) { copy_m4_m4(tmat, go->ob->obmat); sub_v3_v3v3(tmat[3], tmat[3], group->dupli_ofs); mult_m4_m4m4(mat, ob->obmat, tmat); } else { mult_m4_m4m4(mat, ob->obmat, go->ob->obmat); } dob= new_dupli_object(lb, go->ob, mat, ob->lay, 0, OB_DUPLIGROUP, animated); /* check the group instance and object layers match, also that the object visible flags are ok. */ if ( (dob->origlay & group->layer)==0 || (G.rendering==0 && dob->ob->restrictflag & OB_RESTRICT_VIEW) || (G.rendering && dob->ob->restrictflag & OB_RESTRICT_RENDER) ) { dob->no_draw= 1; } else { dob->no_draw= 0; } if (go->ob->transflag & OB_DUPLI) { copy_m4_m4(dob->ob->obmat, dob->mat); object_duplilist_recursive(&group->id, scene, go->ob, lb, ob->obmat, level+1, animated); copy_m4_m4(dob->ob->obmat, dob->omat); } } } }
static void bundle_midpoint(Scene *scene, Object *ob, float vec[3]) { MovieClip *clip = BKE_object_movieclip_get(scene, ob, false); MovieTracking *tracking; MovieTrackingObject *object; bool ok = false; float min[3], max[3], mat[4][4], pos[3], cammat[4][4]; if (!clip) return; tracking = &clip->tracking; copy_m4_m4(cammat, ob->obmat); BKE_tracking_get_camera_object_matrix(scene, ob, mat); INIT_MINMAX(min, max); for (object = tracking->objects.first; object; object = object->next) { ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); MovieTrackingTrack *track = tracksbase->first; float obmat[4][4]; if (object->flag & TRACKING_OBJECT_CAMERA) { copy_m4_m4(obmat, mat); } else { float imat[4][4]; BKE_tracking_camera_get_reconstructed_interpolate(tracking, object, scene->r.cfra, imat); invert_m4(imat); mul_m4_m4m4(obmat, cammat, imat); } while (track) { if ((track->flag & TRACK_HAS_BUNDLE) && TRACK_SELECTED(track)) { ok = 1; mul_v3_m4v3(pos, obmat, track->bundle_pos); minmax_v3v3_v3(min, max, pos); } track = track->next; } } if (ok) { mid_v3_v3v3(vec, min, max); } }
void BL_ArmatureConstraint::RestoreTarget() { if (m_constraint && !(m_constraint->flag&CONSTRAINT_OFF) && (!m_blendtarget || m_target)) { if (m_blendtarget) { copy_m4_m4(m_blendtarget->obmat, m_blendmat); if (m_pose) m_blendtarget->pose = m_pose; } if (m_blendsubtarget && m_subtarget) { copy_m4_m4(m_blendsubtarget->obmat, m_blendsubmat); if (m_subpose) m_blendsubtarget->pose = m_subpose; } } }
/* 'rotmat' can be obedit->obmat when uv project is used. * 'winx' and 'winy' can be from scene->r.xsch/ysch */ UvCameraInfo *project_camera_info(Object *ob, float (*rotmat)[4], float winx, float winy) { UvCameraInfo uci; Camera *camera= ob->data; uci.do_pano = (camera->flag & CAM_PANORAMA); uci.do_persp = (camera->type==CAM_PERSP); uci.camangle= lens_to_angle(camera->lens) / 2.0f; uci.camsize= uci.do_persp ? tanf(uci.camangle) : camera->ortho_scale; /* account for scaled cameras */ copy_m4_m4(uci.caminv, ob->obmat); normalize_m4(uci.caminv); if (invert_m4(uci.caminv)) { UvCameraInfo *uci_pt; /* normal projection */ if(rotmat) { copy_m4_m4(uci.rotmat, rotmat); uci.do_rotmat= 1; } else { uci.do_rotmat= 0; } /* also make aspect ratio adjustment factors */ if (winx > winy) { uci.xasp= 1.0f; uci.yasp= winx / winy; } else { uci.xasp= winy / winx; uci.yasp= 1.0f; } /* include 0.5f here to move the UVs into the center */ uci.shiftx = 0.5f - (camera->shiftx * uci.xasp); uci.shifty = 0.5f - (camera->shifty * uci.yasp); uci_pt= MEM_mallocN(sizeof(UvCameraInfo), "UvCameraInfo"); *uci_pt= uci; return uci_pt; } return NULL; }
static void vertex_dupli__mapFunc(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]) { DupliObject *dob; vertexDupliData *vdd= userData; float vec[3], q2[4], mat[3][3], tmat[4][4], obmat[4][4]; int origlay; mul_v3_m4v3(vec, vdd->pmat, co); sub_v3_v3(vec, vdd->pmat[3]); add_v3_v3(vec, vdd->obmat[3]); copy_m4_m4(obmat, vdd->obmat); copy_v3_v3(obmat[3], vec); if (vdd->par->transflag & OB_DUPLIROT) { if (no_f) { vec[0]= -no_f[0]; vec[1]= -no_f[1]; vec[2]= -no_f[2]; } else if (no_s) { vec[0]= -no_s[0]; vec[1]= -no_s[1]; vec[2]= -no_s[2]; } vec_to_quat( q2,vec, vdd->ob->trackflag, vdd->ob->upflag); quat_to_mat3( mat,q2); copy_m4_m4(tmat, obmat); mul_m4_m4m3(obmat, tmat, mat); } origlay = vdd->ob->lay; dob= new_dupli_object(vdd->lb, vdd->ob, obmat, vdd->par->lay, index, OB_DUPLIVERTS, vdd->animated); /* restore the original layer so that each dupli will have proper dob->origlay */ vdd->ob->lay = origlay; if (vdd->orco) copy_v3_v3(dob->orco, vdd->orco[index]); if (vdd->ob->transflag & OB_DUPLI) { float tmpmat[4][4]; copy_m4_m4(tmpmat, vdd->ob->obmat); copy_m4_m4(vdd->ob->obmat, obmat); /* pretend we are really this mat */ object_duplilist_recursive((ID *)vdd->id, vdd->scene, vdd->ob, vdd->lb, obmat, vdd->level+1, vdd->animated); copy_m4_m4(vdd->ob->obmat, tmpmat); } }
/* Convert a given matrix from a space to another (using the object and/or a bone as reference). */ static void rna_Object_mat_convert_space(Object *ob, ReportList *reports, bPoseChannel *pchan, float *mat, float *mat_ret, int from, int to) { copy_m4_m4((float(*)[4])mat_ret, (float(*)[4])mat); /* Error in case of invalid from/to values when pchan is NULL */ if (pchan == NULL) { if (ELEM(from, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) { const char *identifier = NULL; RNA_enum_identifier(space_items, from, &identifier); BKE_reportf(reports, RPT_ERROR, "'from_space' '%s' is invalid when no pose bone is given!", identifier); return; } if (ELEM(to, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL)) { const char *identifier = NULL; RNA_enum_identifier(space_items, to, &identifier); BKE_reportf(reports, RPT_ERROR, "'to_space' '%s' is invalid when no pose bone is given!", identifier); return; } } BKE_constraint_mat_convertspace(ob, pchan, (float(*)[4])mat_ret, from, to, false); }
/* NOTE: based on solve_parenting(), but with the cruft stripped out */ void BKE_object_eval_parent(EvaluationContext *UNUSED(eval_ctx), Scene *scene, Object *ob) { Object *par = ob->parent; float totmat[4][4]; float tmat[4][4]; float locmat[4][4]; DEBUG_PRINT("%s on %s\n", __func__, ob->id.name); /* get local matrix (but don't calculate it, as that was done already!) */ // XXX: redundant? copy_m4_m4(locmat, ob->obmat); /* get parent effect matrix */ BKE_object_get_parent_matrix(scene, ob, par, totmat); /* total */ mul_m4_m4m4(tmat, totmat, ob->parentinv); mul_m4_m4m4(ob->obmat, tmat, locmat); /* origin, for help line */ if ((ob->partype & PARTYPE) == PARSKEL) { copy_v3_v3(ob->orig, par->obmat[3]); } else { copy_v3_v3(ob->orig, totmat[3]); } }
void AnimationExporter::calc_ob_mat_at_time(Object *ob, float ctime , float mat[][4]) { ListBase *conlist = get_active_constraints(ob); bConstraint *con; for (con = (bConstraint *)conlist->first; con; con = con->next) { ListBase targets = {NULL, NULL}; bConstraintTypeInfo *cti = BKE_constraint_typeinfo_get(con); if (cti && cti->get_constraint_targets) { bConstraintTarget *ct; Object *obtar; cti->get_constraint_targets(con, &targets); for (ct = (bConstraintTarget *)targets.first; ct; ct = ct->next) { obtar = ct->tar; if (obtar) { BKE_animsys_evaluate_animdata(scene, &obtar->id, obtar->adt, ctime, ADT_RECALC_ANIM); BKE_object_where_is_calc_time(scene, obtar, ctime); } } if (cti->flush_constraint_targets) cti->flush_constraint_targets(con, &targets, 1); } } BKE_object_where_is_calc_time(scene, ob, ctime); copy_m4_m4(mat, ob->obmat); }
static DupliObject *new_dupli_object(ListBase *lb, Object *ob, float mat[][4], int lay, int index, int type, int animated) { DupliObject *dob= MEM_callocN(sizeof(DupliObject), "dupliobject"); BLI_addtail(lb, dob); dob->ob= ob; copy_m4_m4(dob->mat, mat); copy_m4_m4(dob->omat, ob->obmat); dob->origlay= ob->lay; dob->index= index; dob->type= type; dob->animated= (type == OB_DUPLIGROUP) && animated; ob->lay= lay; return dob; }
void TransformReader::get_node_mat(float mat[4][4], COLLADAFW::Node *node, std::map<COLLADAFW::UniqueId, Animation> *animation_map, Object *ob, float parent_mat[4][4]) { float cur[4][4]; float copy[4][4]; unit_m4(mat); for (unsigned int i = 0; i < node->getTransformations().getCount(); i++) { COLLADAFW::Transformation *tm = node->getTransformations()[i]; COLLADAFW::Transformation::TransformationType type = tm->getTransformationType(); switch (type) { case COLLADAFW::Transformation::MATRIX: // When matrix AND Trans/Rot/Scale are defined for a node, // then this is considered as redundant information. // So if we find a Matrix we use that and return. dae_matrix_to_mat4(tm, mat); if (parent_mat) { mul_m4_m4m4(mat, parent_mat, mat); } return; case COLLADAFW::Transformation::TRANSLATE: dae_translate_to_mat4(tm, cur); break; case COLLADAFW::Transformation::ROTATE: dae_rotate_to_mat4(tm, cur); break; case COLLADAFW::Transformation::SCALE: dae_scale_to_mat4(tm, cur); break; case COLLADAFW::Transformation::LOOKAT: fprintf(stderr, "|! LOOKAT transformations are not supported yet.\n"); break; case COLLADAFW::Transformation::SKEW: fprintf(stderr, "|! SKEW transformations are not supported yet.\n"); break; } copy_m4_m4(copy, mat); mul_m4_m4m4(mat, copy, cur); if (animation_map) { // AnimationList that drives this Transformation const COLLADAFW::UniqueId &anim_list_id = tm->getAnimationList(); // store this so later we can link animation data with ob Animation anim = {ob, node, tm}; (*animation_map)[anim_list_id] = anim; } } if (parent_mat) { mul_m4_m4m4(mat, parent_mat, mat); } }
BL_SkinDeformer::BL_SkinDeformer( BL_DeformableGameObject *gameobj, struct Object *bmeshobj_old, // Blender object that owns the new mesh struct Object *bmeshobj_new, // Blender object that owns the original mesh class RAS_MeshObject *mesh, bool release_object, bool recalc_normal, BL_ArmatureObject* arma) : BL_MeshDeformer(gameobj, bmeshobj_old, mesh), m_armobj(arma), m_lastArmaUpdate(-1), //m_defbase(&bmeshobj_old->defbase), m_releaseobject(release_object), m_recalcNormal(recalc_normal), m_copyNormals(false), m_dfnrToPC(NULL) { // this is needed to ensure correct deformation of mesh: // the deformation is done with Blender's armature_deform_verts() function // that takes an object as parameter and not a mesh. The object matrice is used // in the calculation, so we must use the matrix of the original object to // simulate a pure replacement of the mesh. copy_m4_m4(m_obmat, bmeshobj_new->obmat); m_deformflags = get_deformflags(bmeshobj_new); }
/* unlike VIEW3D_OT_view_selected this is for framing a render and not * meant to take into account vertex/bone selection for eg. */ static int view3d_camera_to_view_selected_exec(bContext *C, wmOperator *UNUSED(op)) { Scene *scene= CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); Object *camera_ob= v3d->camera; float r_co[3]; /* the new location to apply */ /* this function does all the important stuff */ if (camera_view_frame_fit_to_scene(scene, v3d, camera_ob, r_co)) { ObjectTfmProtectedChannels obtfm; float obmat_new[4][4]; copy_m4_m4(obmat_new, camera_ob->obmat); copy_v3_v3(obmat_new[3], r_co); /* only touch location */ object_tfm_protected_backup(camera_ob, &obtfm); object_apply_mat4(camera_ob, obmat_new, TRUE, TRUE); object_tfm_protected_restore(camera_ob, &obtfm, OB_LOCK_SCALE | OB_LOCK_ROT4D); /* notifiers */ DAG_id_tag_update(&camera_ob->id, OB_RECALC_OB); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, camera_ob); return OPERATOR_FINISHED; } else { return OPERATOR_CANCELLED; } }
static void envmap_transmatrix(float mat[4][4], int part) { float tmat[4][4], eul[3], rotmat[4][4]; eul[0] = eul[1] = eul[2] = 0.0; if (part == 0) { /* neg z */ /* pass */ } else if (part == 1) { /* pos z */ eul[0] = M_PI; } else if (part == 2) { /* pos y */ eul[0] = M_PI / 2.0; } else if (part == 3) { /* neg x */ eul[0] = M_PI / 2.0; eul[2] = M_PI / 2.0; } else if (part == 4) { /* neg y */ eul[0] = M_PI / 2.0; eul[2] = M_PI; } else { /* pos x */ eul[0] = M_PI / 2.0; eul[2] = -M_PI / 2.0; } copy_m4_m4(tmat, mat); eul_to_mat4(rotmat, eul); mul_m4_m4m4(mat, tmat, rotmat); }
void BKE_object_eval_uber_transform(EvaluationContext *UNUSED(eval_ctx), Scene *UNUSED(scene), Object *ob) { /* TODO(sergey): Currently it's a duplicate of logic in BKE_object_handle_update_ex(). */ // XXX: it's almost redundant now... /* Handle proxy copy for target, */ if (ob->id.lib && ob->proxy_from) { if (ob->proxy_from->proxy_group) { /* Transform proxy into group space. */ Object *obg = ob->proxy_from->proxy_group; float imat[4][4]; invert_m4_m4(imat, obg->obmat); mul_m4_m4m4(ob->obmat, imat, ob->proxy_from->obmat); /* Should always be true. */ if (obg->dup_group) { add_v3_v3(ob->obmat[3], obg->dup_group->dupli_ofs); } } else copy_m4_m4(ob->obmat, ob->proxy_from->obmat); } ob->recalc &= ~(OB_RECALC_OB | OB_RECALC_TIME); if (ob->data == NULL) { ob->recalc &= ~OB_RECALC_DATA; } }
/* copy current render */ static Render *envmap_render_copy(Render *re, EnvMap *env) { Render *envre; float viewscale; int cuberes; envre = RE_NewRender("Envmap"); env->lastsize = re->r.size; cuberes = (env->cuberes * re->r.size) / 100; cuberes &= 0xFFFC; /* this flag has R_ZTRA in it for example */ envre->flag = re->flag; /* set up renderdata */ envre->r = re->r; envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR); envre->r.layers.first = envre->r.layers.last = NULL; envre->r.filtertype = 0; envre->r.tilex = envre->r.xsch / 2; envre->r.tiley = envre->r.ysch / 2; envre->r.size = 100; envre->r.yasp = envre->r.xasp = 1; RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL); envre->main = re->main; envre->scene = re->scene; /* unsure about this... */ envre->scene_color_manage = re->scene_color_manage; envre->lay = re->lay; /* view stuff in env render */ viewscale = (env->type == ENV_PLANE) ? env->viewscale : 1.0f; RE_SetEnvmapCamera(envre, env->object, viewscale, env->clipsta, env->clipend); copy_m4_m4(envre->viewmat_orig, re->viewmat_orig); /* callbacks */ envre->display_draw = re->display_draw; envre->ddh = re->ddh; envre->test_break = re->test_break; envre->tbh = re->tbh; /* and for the evil stuff; copy the database... */ envre->totvlak = re->totvlak; envre->totvert = re->totvert; envre->tothalo = re->tothalo; envre->totstrand = re->totstrand; envre->totlamp = re->totlamp; envre->sortedhalos = re->sortedhalos; envre->lights = re->lights; envre->objecttable = re->objecttable; envre->customdata_names = re->customdata_names; envre->raytree = re->raytree; envre->totinstance = re->totinstance; envre->instancetable = re->instancetable; envre->objectinstance = re->objectinstance; envre->qmcsamplers = re->qmcsamplers; return envre; }
void BKE_pose_eval_bone(EvaluationContext *UNUSED(eval_ctx), Scene *scene, Object *ob, bPoseChannel *pchan) { DEG_debug_print_eval_subdata( __func__, ob->id.name, ob, "pchan", pchan->name, pchan); BLI_assert(ob->type == OB_ARMATURE); bArmature *arm = (bArmature *)ob->data; if (arm->edbo || (arm->flag & ARM_RESTPOS)) { Bone *bone = pchan->bone; if (bone) { copy_m4_m4(pchan->pose_mat, bone->arm_mat); copy_v3_v3(pchan->pose_head, bone->arm_head); copy_v3_v3(pchan->pose_tail, bone->arm_tail); } } else { /* TODO(sergey): Currently if there are constraints full transform is being * evaluated in BKE_pose_constraints_evaluate. */ if (pchan->constraints.first == NULL) { if (pchan->flag & POSE_IKTREE || pchan->flag & POSE_IKSPLINE) { /* pass */ } else { if ((pchan->flag & POSE_DONE) == 0) { /* TODO(sergey): Use time source node for time. */ float ctime = BKE_scene_frame_get(scene); /* not accurate... */ BKE_pose_where_is_bone(scene, ob, pchan, ctime, 1); } } } } }
void TransformWriter::add_node_transform(COLLADASW::Node& node, float mat[4][4], float parent_mat[4][4]) { float loc[3], rot[3], scale[3]; float local[4][4]; if (parent_mat) { float invpar[4][4]; invert_m4_m4(invpar, parent_mat); mul_m4_m4m4(local, invpar, mat); } else { copy_m4_m4(local, mat); } double dmat[4][4]; UnitConverter *converter = new UnitConverter(); converter->mat4_to_dae_double(dmat, local); TransformBase::decompose(local, loc, rot, NULL, scale); if (node.getType() == COLLADASW::Node::JOINT) { // XXX Why are joints handled differently ? node.addMatrix("transform", dmat); } else { add_transform(node, loc, rot, scale); } }
/* 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); } }
/* both poses should be in sync */ bool BKE_pose_copy_result(bPose *to, bPose *from) { bPoseChannel *pchanto, *pchanfrom; if (to == NULL || from == NULL) { printf("Pose copy error, pose to:%p from:%p\n", (void *)to, (void *)from); /* debug temp */ return false; } if (to == from) { printf("BKE_pose_copy_result source and target are the same\n"); return false; } for (pchanfrom = from->chanbase.first; pchanfrom; pchanfrom = pchanfrom->next) { pchanto = BKE_pose_channel_find_name(to, pchanfrom->name); if (pchanto) { copy_m4_m4(pchanto->pose_mat, pchanfrom->pose_mat); copy_m4_m4(pchanto->chan_mat, pchanfrom->chan_mat); /* used for local constraints */ copy_v3_v3(pchanto->loc, pchanfrom->loc); copy_qt_qt(pchanto->quat, pchanfrom->quat); copy_v3_v3(pchanto->eul, pchanfrom->eul); copy_v3_v3(pchanto->size, pchanfrom->size); copy_v3_v3(pchanto->pose_head, pchanfrom->pose_head); copy_v3_v3(pchanto->pose_tail, pchanfrom->pose_tail); pchanto->roll1 = pchanfrom->roll1; pchanto->roll2 = pchanfrom->roll2; pchanto->curveInX = pchanfrom->curveInX; pchanto->curveInY = pchanfrom->curveInY; pchanto->curveOutX = pchanfrom->curveOutX; pchanto->curveOutY = pchanfrom->curveOutY; pchanto->scaleIn = pchanfrom->scaleIn; pchanto->scaleOut = pchanfrom->scaleOut; pchanto->rotmode = pchanfrom->rotmode; pchanto->flag = pchanfrom->flag; pchanto->protectflag = pchanfrom->protectflag; pchanto->bboneflag = pchanfrom->bboneflag; } } return true; }
/* called from drawview.c, as an extra per-window draw option */ void drawPropCircle(const struct bContext *C, TransInfo *t) { if (t->flag & T_PROP_EDIT) { RegionView3D *rv3d = CTX_wm_region_view3d(C); float tmat[4][4], imat[4][4]; int depth_test_enabled; if (t->spacetype == SPACE_VIEW3D && rv3d != NULL) { copy_m4_m4(tmat, rv3d->viewmat); invert_m4_m4(imat, tmat); } else { unit_m4(tmat); unit_m4(imat); } GPU_matrix_push(); if (t->spacetype == SPACE_VIEW3D) { /* pass */ } else if (t->spacetype == SPACE_IMAGE) { GPU_matrix_scale_2f(1.0f / t->aspect[0], 1.0f / t->aspect[1]); } else if (ELEM(t->spacetype, SPACE_GRAPH, SPACE_ACTION)) { /* only scale y */ rcti *mask = &t->ar->v2d.mask; rctf *datamask = &t->ar->v2d.cur; float xsize = BLI_rctf_size_x(datamask); float ysize = BLI_rctf_size_y(datamask); float xmask = BLI_rcti_size_x(mask); float ymask = BLI_rcti_size_y(mask); GPU_matrix_scale_2f(1.0f, (ysize / xsize) * (xmask / ymask)); } depth_test_enabled = GPU_depth_test_enabled(); if (depth_test_enabled) { GPU_depth_test(false); } uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 3, GPU_FETCH_FLOAT); immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR); immUniformThemeColor(TH_GRID); set_inverted_drawing(1); imm_drawcircball(t->center_global, t->prop_size, imat, pos); set_inverted_drawing(0); immUnbindProgram(); if (depth_test_enabled) { GPU_depth_test(true); } GPU_matrix_pop(); } }
static void font_duplilist(ListBase *lb, Scene *scene, Object *par, int level, int animated) { Object *ob, *obar[256]= {NULL}; Curve *cu; struct chartrans *ct, *chartransdata; float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof; int slen, a; /* simple preventing of too deep nested groups */ if (level>MAX_DUPLI_RECUR) return; copy_m4_m4(pmat, par->obmat); /* in par the family name is stored, use this to find the other objects */ chartransdata= BKE_text_to_curve(G.main, scene, par, FO_DUPLI); if (chartransdata==NULL) return; cu= par->data; slen= strlen(cu->str); fsize= cu->fsize; xof= cu->xof; yof= cu->yof; ct= chartransdata; for (a=0; a<slen; a++, ct++) { ob= find_family_object(obar, cu->family, cu->str[a]); if (ob) { vec[0]= fsize*(ct->xof - xof); vec[1]= fsize*(ct->yof - yof); vec[2]= 0.0; mul_m4_v3(pmat, vec); copy_m4_m4(obmat, par->obmat); copy_v3_v3(obmat[3], vec); new_dupli_object(lb, ob, obmat, par->lay, a, OB_DUPLIVERTS, animated); } } MEM_freeN(chartransdata); }