void DRW_debug_line_v3v3(const float v1[3], const float v2[3], const float color[4]) { DRWDebugLine *line = MEM_mallocN(sizeof(DRWDebugLine), "DRWDebugLine"); mul_v3_m4v3(line->pos[0], g_modelmat, v1); mul_v3_m4v3(line->pos[1], g_modelmat, v2); copy_v4_v4(line->color, color); BLI_LINKS_PREPEND(DST.debug.lines, line); }
static int set_origin_exec(bContext *C, wmOperator *op) { SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; Scene *scene = CTX_data_scene(C); Object *camera = get_camera_with_movieclip(scene, clip); int selected_count = count_selected_bundles(C); if (selected_count == 0) { BKE_report(op->reports, RPT_ERROR, "At least one track with bundle should be selected to " "define origin position"); return OPERATOR_CANCELLED; } Object *object = get_orientation_object(C); if (object == NULL) { BKE_report(op->reports, RPT_ERROR, "No object to apply orientation on"); return OPERATOR_CANCELLED; } MovieTrackingObject *tracking_object = BKE_tracking_object_get_active(tracking); ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, tracking_object); float median[3] = {0.0f, 0.0f, 0.0f}; zero_v3(median); for (MovieTrackingTrack *track = tracksbase->first; track != NULL; track = track->next) { if (TRACK_VIEW_SELECTED(sc, track) && (track->flag & TRACK_HAS_BUNDLE)) { add_v3_v3(median, track->bundle_pos); } } mul_v3_fl(median, 1.0f / selected_count); float mat[4][4], vec[3]; BKE_tracking_get_camera_object_matrix(scene, camera, mat); mul_v3_m4v3(vec, mat, median); if (tracking_object->flag & TRACKING_OBJECT_CAMERA) { sub_v3_v3(object->loc, vec); } else { object_solver_inverted_matrix(scene, object, mat); mul_v3_m4v3(vec, mat, vec); copy_v3_v3(object->loc, vec); } DEG_id_tag_update(&clip->id, 0); DEG_id_tag_update(&object->id, ID_RECALC_TRANSFORM); WM_event_add_notifier(C, NC_MOVIECLIP | NA_EVALUATED, clip); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; }
static void drawObjectConstraint(TransInfo *t) { /* Draw the first one lighter because that's the one who controls the others. * Meaning the transformation is projected on that one and just copied on the others * constraint space. * In a nutshell, the object with light axis is controlled by the user and the others follow. * Without drawing the first light, users have little clue what they are doing. */ short options = DRAWLIGHT; TransData *td = t->data; int i; float tmp_axismtx[3][3]; for (i = 0; i < t->total; i++, td++) { float co[3]; float (*axismtx)[3]; if (t->flag & T_PROP_EDIT) { /* we're sorted, so skip the rest */ if (td->factor == 0.0f) { break; } } if (t->flag & T_OBJECT) { copy_v3_v3(co, td->ob->obmat[3]); axismtx = td->axismtx; } else if (t->flag & T_EDIT) { mul_v3_m4v3(co, t->obedit->obmat, td->center); mul_m3_m3m3(tmp_axismtx, t->obedit_mat, td->axismtx); axismtx = tmp_axismtx; } else if (t->flag & T_POSE) { mul_v3_m4v3(co, t->poseobj->obmat, td->center); axismtx = td->axismtx; } else { copy_v3_v3(co, td->center); axismtx = td->axismtx; } if (t->con.mode & CON_AXIS0) { drawLine(t, co, axismtx[0], 'X', options); } if (t->con.mode & CON_AXIS1) { drawLine(t, co, axismtx[1], 'Y', options); } if (t->con.mode & CON_AXIS2) { drawLine(t, co, axismtx[2], 'Z', options); } options &= ~DRAWLIGHT; } }
static void edit_text_cache_populate_boxes(void *vedata, Object *ob) { EDIT_TEXT_StorageList *stl = ((EDIT_TEXT_Data *)vedata)->stl; const Curve *cu = ob->data; DRWCallBuffer *callbufs[] = { stl->g_data->box_active_shgrp, stl->g_data->box_shgrp, }; float vec[3], vec1[3], vec2[3]; for (int i = 0; i < cu->totbox; i++) { TextBox *tb = &cu->tb[i]; if ((tb->w == 0.0f) && (tb->h == 0.0f)) { continue; } const bool is_active = i == (cu->actbox - 1); DRWCallBuffer *callbuf = callbufs[is_active ? 0 : 1]; vec[0] = cu->xof + tb->x; vec[1] = cu->yof + tb->y + cu->fsize_realtime; vec[2] = 0.001; mul_v3_m4v3(vec1, ob->obmat, vec); vec[0] += tb->w; mul_v3_m4v3(vec2, ob->obmat, vec); DRW_buffer_add_entry(callbuf, vec1); DRW_buffer_add_entry(callbuf, vec2); vec[1] -= tb->h; copy_v3_v3(vec1, vec2); mul_v3_m4v3(vec2, ob->obmat, vec); DRW_buffer_add_entry(callbuf, vec1); DRW_buffer_add_entry(callbuf, vec2); vec[0] -= tb->w; copy_v3_v3(vec1, vec2); mul_v3_m4v3(vec2, ob->obmat, vec); DRW_buffer_add_entry(callbuf, vec1); DRW_buffer_add_entry(callbuf, vec2); vec[1] += tb->h; copy_v3_v3(vec1, vec2); mul_v3_m4v3(vec2, ob->obmat, vec); DRW_buffer_add_entry(callbuf, vec1); DRW_buffer_add_entry(callbuf, vec2); } }
static bool stroke_elem_project_fallback( const struct CurveDrawData *cdd, const int mval_i[2], const float mval_fl[2], const float surface_offset, const float radius, const float location_fallback_depth[3], float r_location_world[3], float r_location_local[3], float r_normal_world[3], float r_normal_local[3]) { bool is_depth_found = stroke_elem_project( cdd, mval_i, mval_fl, surface_offset, radius, r_location_world, r_normal_world); if (is_depth_found == false) { ED_view3d_win_to_3d(cdd->vc.v3d, cdd->vc.ar, location_fallback_depth, mval_fl, r_location_world); zero_v3(r_normal_local); } mul_v3_m4v3(r_location_local, cdd->vc.obedit->imat, r_location_world); if (!is_zero_v3(r_normal_world)) { copy_v3_v3(r_normal_local, r_normal_world); mul_transposed_mat3_m4_v3(cdd->vc.obedit->obmat, r_normal_local); normalize_v3(r_normal_local); } else { zero_v3(r_normal_local); } return is_depth_found; }
static void hook_co_apply(struct HookData_cb *hd, const int j) { float *co = hd->vertexCos[j]; float fac; if (hd->use_falloff) { float len_sq; if (hd->use_uniform) { float co_uniform[3]; mul_v3_m3v3(co_uniform, hd->mat_uniform, co); len_sq = len_squared_v3v3(hd->cent, co_uniform); } else { len_sq = len_squared_v3v3(hd->cent, co); } fac = hook_falloff(hd, len_sq); } else { fac = hd->fac_orig; } if (fac) { if (hd->dvert) { fac *= defvert_find_weight(&hd->dvert[j], hd->defgrp_index); } if (fac) { float co_tmp[3]; mul_v3_m4v3(co_tmp, hd->mat, co); interp_v3_v3v3(co, co, co_tmp, fac); } } }
static void update_position(Object *ob, MirrorGpencilModifierData *mmd, bGPDstroke *gps, int axis) { int i; bGPDspoint *pt; float factor[3] = {1.0f, 1.0f, 1.0f}; factor[axis] = -1.0f; float clear[3] = {0.0f, 0.0f, 0.0f}; clear[axis] = 1.0f; float ob_origin[3]; float pt_origin[3]; if (mmd->object) { float inv_mat[4][4]; invert_m4_m4(inv_mat, mmd->object->obmat); mul_v3_m4v3(ob_origin, inv_mat, ob->obmat[3]); } else { copy_v3_v3(ob_origin, ob->obmat[3]); } /* only works with current axis */ mul_v3_v3(ob_origin, clear); mul_v3_v3fl(pt_origin, ob_origin, -2.0f); for (i = 0, pt = gps->points; i < gps->totpoints; i++, pt++) { mul_v3_v3(&pt->x, factor); if (mmd->object) { add_v3_v3(&pt->x, pt_origin); } } }
/* Adopted from BM_loop_interp_from_face(), * * Transform matrix is used in cases when target coordinate needs * to be converted to source space (namely when interpolating * boolean result loops from second operand). * * TODO(sergey): Consider making it a generic function in DerivedMesh.c. */ static void DM_loop_interp_from_poly(DerivedMesh *source_dm, MVert *source_mverts, MLoop *source_mloops, MPoly *source_poly, DerivedMesh *target_dm, MVert *target_mverts, MLoop *target_mloop, float transform[4][4], int target_loop_index) { float (*cos_3d)[3] = BLI_array_alloca(cos_3d, source_poly->totloop); int *source_indices = BLI_array_alloca(source_indices, source_poly->totloop); float *weights = BLI_array_alloca(weights, source_poly->totloop); int i; int target_vert_index = target_mloop[target_loop_index].v; float coord[3]; for (i = 0; i < source_poly->totloop; ++i) { MLoop *mloop = &source_mloops[source_poly->loopstart + i]; source_indices[i] = source_poly->loopstart + i; copy_v3_v3(cos_3d[i], source_mverts[mloop->v].co); } if (transform) { mul_v3_m4v3(coord, transform, target_mverts[target_vert_index].co); } else { copy_v3_v3(coord, target_mverts[target_vert_index].co); } interp_weights_poly_v3(weights, cos_3d, source_poly->totloop, coord); DM_interp_loop_data(source_dm, target_dm, source_indices, weights, source_poly->totloop, target_loop_index); }
/* Set coordinate of vertex with given index. */ static void exporter_SetVert(ExportMeshData *export_data, int vert_index, float coord[3], int which_orig_mesh, int orig_vert_index) { DerivedMesh *dm = export_data->dm; DerivedMesh *dm_orig; MVert *mvert = export_data->mvert; BLI_assert(vert_index >= 0 && vert_index <= dm->getNumVerts(dm)); dm_orig = which_dm(export_data, which_orig_mesh); if (dm_orig) { BLI_assert(orig_vert_index >= 0 && orig_vert_index < dm_orig->getNumVerts(dm_orig)); mvert[vert_index] = which_mvert(export_data, which_orig_mesh)[orig_vert_index]; CustomData_copy_data(&dm_orig->vertData, &dm->vertData, orig_vert_index, vert_index, 1); } /* Set original index of the vertex. */ if (export_data->vert_origindex) { if (which_orig_mesh == CARVE_MESH_LEFT) { export_data->vert_origindex[vert_index] = orig_vert_index; } else { export_data->vert_origindex[vert_index] = ORIGINDEX_NONE; } } mul_v3_m4v3(mvert[vert_index].co, export_data->obimat, coord); }
void ED_clip_point_stable_pos(SpaceClip *sc, ARegion *ar, float x, float y, float *xr, float *yr) { int sx, sy, width, height; float zoomx, zoomy, pos[3], imat[4][4]; ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy); ED_space_clip_get_size(sc, &width, &height); UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &sx, &sy); pos[0] = (x - sx) / zoomx; pos[1] = (y - sy) / zoomy; pos[2] = 0.0f; invert_m4_m4(imat, sc->stabmat); mul_v3_m4v3(pos, imat, pos); *xr = pos[0] / width; *yr = pos[1] / height; if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; float aspy = 1.0f / tracking->camera.pixel_aspect; float tmp[2] = {*xr * width, *yr * height * aspy}; BKE_tracking_distort_v2(tracking, tmp, tmp); *xr = tmp[0] / width; *yr = tmp[1] / (height * aspy); } }
/** * Convert point to parent space * * \param pt: Original point * \param diff_mat: Matrix with the difference between original parent matrix * \param[out] r_pt Pointer to new point after apply matrix */ void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt) { float fpt[3]; mul_v3_m4v3(fpt, diff_mat, &pt->x); copy_v3_v3(&r_pt->x, fpt); }
/* v3d and rv3d are allowed to be NULL */ void add_primitive_bone(Scene *scene, View3D *v3d, RegionView3D *rv3d) { Object *obedit = scene->obedit; // XXX get from context bArmature *arm = obedit->data; float obmat[3][3], curs[3], viewmat[3][3], totmat[3][3], imat[3][3]; EditBone *bone; /* Get inverse point for head and orientation for tail */ invert_m4_m4(obedit->imat, obedit->obmat); mul_v3_m4v3(curs, obedit->imat, give_cursor(scene, v3d)); if (rv3d && (U.flag & USER_ADD_VIEWALIGNED)) copy_m3_m4(obmat, rv3d->viewmat); else unit_m3(obmat); copy_m3_m4(viewmat, obedit->obmat); mul_m3_m3m3(totmat, obmat, viewmat); invert_m3_m3(imat, totmat); ED_armature_deselect_all(obedit, 0); /* Create a bone */ bone = ED_armature_edit_bone_add(arm, "Bone"); arm->act_edbone = bone; copy_v3_v3(bone->head, curs); if (rv3d && (U.flag & USER_ADD_VIEWALIGNED)) add_v3_v3v3(bone->tail, bone->head, imat[1]); // bone with unit length 1 else add_v3_v3v3(bone->tail, bone->head, imat[2]); // bone with unit length 1, pointing up Z }
static void InterpCSGFace( DerivedMesh *dm, DerivedMesh *orig_dm, int index, int orig_index, int nr, float mapmat[][4]) { float obco[3], *co[4], *orig_co[4], w[4][4]; MFace *mface, *orig_mface; int j; mface = CDDM_get_face(dm, index); orig_mface = orig_dm->getFaceArray(orig_dm) + orig_index; // get the vertex coordinates from the original mesh orig_co[0] = (orig_dm->getVertArray(orig_dm) + orig_mface->v1)->co; orig_co[1] = (orig_dm->getVertArray(orig_dm) + orig_mface->v2)->co; orig_co[2] = (orig_dm->getVertArray(orig_dm) + orig_mface->v3)->co; orig_co[3] = (orig_mface->v4)? (orig_dm->getVertArray(orig_dm) + orig_mface->v4)->co: NULL; // get the vertex coordinates from the new derivedmesh co[0] = CDDM_get_vert(dm, mface->v1)->co; co[1] = CDDM_get_vert(dm, mface->v2)->co; co[2] = CDDM_get_vert(dm, mface->v3)->co; co[3] = (nr == 4)? CDDM_get_vert(dm, mface->v4)->co: NULL; for (j = 0; j < nr; j++) { // get coordinate into the space of the original mesh if (mapmat) mul_v3_m4v3(obco, mapmat, co[j]); else copy_v3_v3(obco, co[j]); interp_weights_face_v3( w[j],orig_co[0], orig_co[1], orig_co[2], orig_co[3], obco); } CustomData_interp(&orig_dm->faceData, &dm->faceData, &orig_index, NULL, (float*)w, 1, index); }
bool BKE_mball_minmax_ex(MetaBall *mb, float min[3], float max[3], float obmat[4][4], const short flag) { const float scale = obmat ? mat4_to_scale(obmat) : 1.0f; MetaElem *ml; bool changed = false; float centroid[3], vec[3]; INIT_MINMAX(min, max); for (ml = mb->elems.first; ml; ml = ml->next) { if ((ml->flag & flag) == flag) { const float scale_mb = (ml->rad * 0.5f) * scale; int i; if (obmat) { mul_v3_m4v3(centroid, obmat, &ml->x); } else { copy_v3_v3(centroid, &ml->x); } /* TODO, non circle shapes cubes etc, probably nobody notices - campbell */ for (i = -1; i != 3; i += 2) { copy_v3_v3(vec, centroid); add_v3_fl(vec, scale_mb * i); minmax_v3v3_v3(min, max, vec); } changed = true; } } return changed; }
static void generate_vert_coordinates( DerivedMesh *dm, Object *ob, Object *ob_center, const float offset[3], const int num_verts, float (*r_cos)[3], float r_size[3]) { float min_co[3], max_co[3]; float diff[3]; bool do_diff = false; INIT_MINMAX(min_co, max_co); dm->getVertCos(dm, r_cos); /* Get size (i.e. deformation of the spheroid generating normals), either from target object, or own geometry. */ if (ob_center) { /* Not we are not interested in signs here - they are even troublesome actually, due to security clamping! */ abs_v3_v3(r_size, ob_center->size); } else { minmax_v3v3_v3_array(min_co, max_co, r_cos, num_verts); /* Set size. */ sub_v3_v3v3(r_size, max_co, min_co); } /* Error checks - we do not want one or more of our sizes to be null! */ if (is_zero_v3(r_size)) { r_size[0] = r_size[1] = r_size[2] = 1.0f; } else { CLAMP_MIN(r_size[0], FLT_EPSILON); CLAMP_MIN(r_size[1], FLT_EPSILON); CLAMP_MIN(r_size[2], FLT_EPSILON); } if (ob_center) { float inv_obmat[4][4]; /* Translate our coordinates so that center of ob_center is at (0, 0, 0). */ /* Get ob_center (world) coordinates in ob local coordinates. * No need to take into account ob_center's space here, see T44027. */ invert_m4_m4(inv_obmat, ob->obmat); mul_v3_m4v3(diff, inv_obmat, ob_center->obmat[3]); negate_v3(diff); do_diff = true; } else if (!is_zero_v3(offset)) { negate_v3_v3(diff, offset); do_diff = true; } /* Else, no need to change coordinates! */ if (do_diff) { int i = num_verts; while (i--) { add_v3_v3(r_cos[i], diff); } } }
/* Get 3D coordinate of vertex with given index. */ static void importer_GetVertCoord(ImportMeshData *import_data, int vert_index, float coord[3]) { MVert *mvert = import_data->mvert; BLI_assert(vert_index >= 0 && vert_index < import_data->dm->getNumVerts(import_data->dm)); mul_v3_m4v3(coord, import_data->obmat, mvert[vert_index].co); }
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 project_from_view_ortho(float target[2], float source[3], float rotmat[4][4]) { float pv[3]; mul_v3_m4v3(pv, rotmat, source); /* ortho projection */ target[0] = -pv[0]; target[1] = pv[2]; }
static void particle_system_minmax(Scene *scene, Object *object, ParticleSystem *psys, float radius, float min[3], float max[3]) { const float size[3] = {radius, radius, radius}; const float cfra = BKE_scene_frame_get(scene); ParticleSettings *part = psys->part; ParticleSimulationData sim = {NULL}; ParticleData *pa = NULL; int i; int total_particles; float mat[4][4], imat[4][4]; INIT_MINMAX(min, max); if (part->type == PART_HAIR) { /* TOOD(sergey): Not supported currently. */ return; } unit_m4(mat); psys_render_set(object, psys, mat, mat, 1, 1, 0); sim.scene = scene; sim.ob = object; sim.psys = psys; sim.psmd = psys_get_modifier(object, psys); invert_m4_m4(imat, object->obmat); total_particles = psys->totpart + psys->totchild; psys->lattice_deform_data = psys_create_lattice_deform_data(&sim); for (i = 0, pa = psys->particles; i < total_particles; i++, pa++) { float co_object[3], co_min[3], co_max[3]; ParticleKey state; state.time = cfra; if (!psys_get_particle_state(&sim, i, &state, 0)) { continue; } mul_v3_m4v3(co_object, imat, state.co); sub_v3_v3v3(co_min, co_object, size); add_v3_v3v3(co_max, co_object, size); minmax_v3v3_v3(min, max, co_min); minmax_v3v3_v3(min, max, co_max); } if (psys->lattice_deform_data) { end_latt_deform(psys->lattice_deform_data); psys->lattice_deform_data = NULL; } psys_render_restore(object, psys); }
static void curve_draw_stroke_from_operator_elem( wmOperator *op, PointerRNA *itemptr) { struct CurveDrawData *cdd = op->customdata; struct StrokeElem *selem = BLI_mempool_calloc(cdd->stroke_elem_pool); RNA_float_get_array(itemptr, "mouse", selem->mval); RNA_float_get_array(itemptr, "location", selem->location_world); mul_v3_m4v3(selem->location_local, cdd->vc.obedit->imat, selem->location_world); selem->pressure = RNA_float_get(itemptr, "pressure"); }
/** * Change point position relative to parent object */ void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt) { /* undo matrix */ float diff_mat[4][4]; float inverse_diff_mat[4][4]; float fpt[3]; ED_gpencil_parent_location(gpl, diff_mat); invert_m4_m4(inverse_diff_mat, diff_mat); mul_v3_m4v3(fpt, inverse_diff_mat, &pt->x); copy_v3_v3(&pt->x, fpt); }
static void stroke_elem_pressure_set(const struct CurveDrawData *cdd, struct StrokeElem *selem, float pressure) { if ((cdd->project.surface_offset != 0.0f) && !cdd->project.use_surface_offset_absolute && !is_zero_v3(selem->normal_local)) { const float adjust = stroke_elem_radius_from_pressure(cdd, pressure) - stroke_elem_radius_from_pressure(cdd, selem->pressure); madd_v3_v3fl(selem->location_local, selem->normal_local, adjust); mul_v3_m4v3(selem->location_world, cdd->vc.obedit->obmat, selem->location_local); } selem->pressure = pressure; }
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); } }
/** * Returns the real distance between a vertex and another reference object. * Note that it works in final world space (i.e. with constraints etc. applied). */ static void get_vert2ob_distance(int numVerts, float (*v_cos)[3], float *dist, Object *ob, Object *obr) { /* Vertex and ref object coordinates. */ float v_wco[3]; unsigned int i = numVerts; while (i-- > 0) { /* Get world-coordinates of the vertex (constraints and anim included). */ mul_v3_m4v3(v_wco, ob->obmat, v_cos[i]); /* Return distance between both coordinates. */ dist[i] = len_v3v3(v_wco, obr->obmat[3]); } }
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); } }
static void add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob, int mode) { ModifierData *md=NULL; HookModifierData *hmd = NULL; float cent[3]; int tot, ok, *indexar; char name[32]; ok = object_hook_index_array(obedit, &tot, &indexar, name, cent); if (!ok) return; // XXX error("Requires selected vertices or active Vertex Group"); if (mode==OBJECT_ADDHOOK_NEWOB && !ob) { ob = add_hook_object_new(scene, obedit); /* transform cent to global coords for loc */ mul_v3_m4v3(ob->loc, obedit->obmat, cent); } md = obedit->modifiers.first; while (md && modifierType_getInfo(md->type)->type==eModifierTypeType_OnlyDeform) { md = md->next; } hmd = (HookModifierData*) modifier_new(eModifierType_Hook); BLI_insertlinkbefore(&obedit->modifiers, md, hmd); BLI_snprintf(hmd->modifier.name, sizeof(hmd->modifier.name), "Hook-%s", ob->id.name+2); modifier_unique_name(&obedit->modifiers, (ModifierData*)hmd); hmd->object= ob; hmd->indexar= indexar; copy_v3_v3(hmd->cent, cent); hmd->totindex= tot; BLI_strncpy(hmd->name, name, sizeof(hmd->name)); /* matrix calculus */ /* vert x (obmat x hook->imat) x hook->obmat x ob->imat */ /* (parentinv ) */ where_is_object(scene, ob); invert_m4_m4(ob->imat, ob->obmat); /* apparently this call goes from right to left... */ mul_serie_m4(hmd->parentinv, ob->imat, obedit->obmat, NULL, NULL, NULL, NULL, NULL, NULL); DAG_scene_sort(bmain, scene); }
static bool selected_boundbox(SpaceClip *sc, float min[2], float max[2]) { MovieClip *clip = ED_space_clip_get_clip(sc); MovieTrackingTrack *track; int width, height; bool ok = false; ListBase *tracksbase = BKE_tracking_get_active_tracks(&clip->tracking); int framenr = ED_space_clip_get_clip_frame_number(sc); INIT_MINMAX2(min, max); ED_space_clip_get_size(sc, &width, &height); track = tracksbase->first; while (track) { if (TRACK_VIEW_SELECTED(sc, track)) { MovieTrackingMarker *marker = BKE_tracking_marker_get(track, framenr); if (marker) { float pos[3]; pos[0] = marker->pos[0] + track->offset[0]; pos[1] = marker->pos[1] + track->offset[1]; pos[2] = 0.0f; /* undistortion happens for normalized coords */ if (sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT) { /* undistortion happens for normalized coords */ ED_clip_point_undistorted_pos(sc, pos, pos); } pos[0] *= width; pos[1] *= height; mul_v3_m4v3(pos, sc->stabmat, pos); minmax_v2v2_v2(min, max, pos); ok = true; } } track = track->next; } return ok; }
float paint_calc_object_space_radius(ViewContext *vc, const float center[3], float pixel_radius) { Object *ob = vc->obact; float delta[3], scale, loc[3]; const float mval_f[2] = {pixel_radius, 0.0f}; float zfac; mul_v3_m4v3(loc, ob->obmat, center); zfac = ED_view3d_calc_zfac(vc->rv3d, loc, NULL); ED_view3d_win_to_delta(vc->ar, mval_f, delta, zfac); scale = fabsf(mat4_to_scale(ob->obmat)); scale = (scale == 0.0f) ? 1.0f : scale; return len_v3(delta) / scale; }
static void VertexIt_Fill(CSG_IteratorPtr it, CSG_IVertex *vert) { VertexIt * iterator = (VertexIt *)it; MVert *verts = iterator->dm->getVertArray(iterator->dm); float global_pos[3]; /* boolean happens in global space, transform both with obmat */ mul_v3_m4v3( global_pos, iterator->ob->obmat, verts[iterator->pos].co ); vert->position[0] = global_pos[0]; vert->position[1] = global_pos[1]; vert->position[2] = global_pos[2]; }
static void object_warp_calc_view_matrix(float r_mat_view[4][4], float r_center_view[3], Object *obedit, float viewmat[4][4], const float center[3], const float offset_angle) { float mat_offset[4][4]; float viewmat_roll[4][4]; /* apply the rotation offset by rolling the view */ unit_m4(mat_offset); rotate_m4(mat_offset, 'Z', offset_angle); mul_m4_m4m4(viewmat_roll, mat_offset, viewmat); /* apply the view and the object matrix */ mul_m4_m4m4(r_mat_view, viewmat_roll, obedit->obmat); /* get the view-space cursor */ mul_v3_m4v3(r_center_view, viewmat_roll, center); }