/** * Return true if the 2x axis are both aligned when projected into the view. * In this case, we can't usefully project the cursor onto the plane. */ static bool isPlaneProjectionViewAligned(const TransInfo *t) { const float eps = 0.001f; const float *constraint_vector[2]; int n = 0; for (int i = 0; i < 3; i++) { if (t->con.mode & (CON_AXIS0 << i)) { constraint_vector[n++] = t->con.mtx[i]; if (n == 2) { break; } } } BLI_assert(n == 2); float view_to_plane[3], plane_normal[3]; getViewVector(t, t->center_global, view_to_plane); cross_v3_v3v3(plane_normal, constraint_vector[0], constraint_vector[1]); normalize_v3(plane_normal); float factor = dot_v3v3(plane_normal, view_to_plane); return fabsf(factor) < eps; }
static void selectViews ( CameraParameters &cameraParams, int imgWidth, int imgHeight, bool viewSel ) { vector<Camera> cameras = cameraParams.cameras; Camera ref = cameras[cameraParams.idRef]; int x = imgWidth / 2; int y = imgHeight / 2; cameraParams.viewSelectionSubset.clear (); Vec3f viewVectorRef = getViewVector ( ref, x, y); // TODO hardcoded value makes it a parameter float minimum_angle_degree = 10; float maximum_angle_degree = 30; float minimum_angle_radians = minimum_angle_degree * M_PI / 180.0f; float maximum_angle_radians = maximum_angle_degree * M_PI / 180.0f; printf("Accepted intersection angle of central rays is %f to %f degrees\n", minimum_angle_degree, maximum_angle_degree); for ( size_t i = 0; i < cameras.size (); i++ ) { //if ( i == cameraParams.idRef && !cameraParams.rectified ) // continue; if ( !viewSel ) { //select all views, dont perform selection cameraParams.viewSelectionSubset.push_back ( i ); continue; } Vec3f vec = getViewVector ( cameras[i], x, y); float angle = getAngle ( viewVectorRef, vec ); if ( angle > minimum_angle_radians && angle < maximum_angle_radians ) //0.6 select if angle between 5.7 and 34.8 (0.6) degrees (10 and 30 degrees suggested by some paper) { cameraParams.viewSelectionSubset.push_back ( i ); printf("Accepting camera %ld with angle\t %f degree (%f radians)\n", i, angle*180.0f/M_PI, angle); } else printf("Discarding camera %ld with angle\t %f degree (%f radians)\n", i, angle*180.0f/M_PI, angle); } }
static void planeProjection(TransInfo *t, float in[3], float out[3]) { float vec[3], factor, norm[3]; add_v3_v3v3(vec, in, t->con.center); getViewVector(t, vec, norm); sub_v3_v3v3(vec, out, in); factor = dot_v3v3(vec, norm); if (fabs(factor) <= 0.001) { return; /* prevent divide by zero */ } factor = dot_v3v3(vec, vec) / factor; VECCOPY(vec, norm); mul_v3_fl(vec, factor); add_v3_v3v3(out, in, vec); }
static void planeProjection(const TransInfo *t, const float in[3], float out[3]) { float vec[3], factor, norm[3]; add_v3_v3v3(vec, in, t->center_global); getViewVector(t, vec, norm); sub_v3_v3v3(vec, out, in); factor = dot_v3v3(vec, norm); if (fabsf(factor) <= 0.001f) { return; /* prevent divide by zero */ } factor = dot_v3v3(vec, vec) / factor; copy_v3_v3(vec, norm); mul_v3_fl(vec, factor); add_v3_v3v3(out, in, vec); }
static void axisProjection(TransInfo *t, const float axis[3], const float in[3], float out[3]) { float norm[3], vec[3], factor, angle; float t_con_center[3]; if (is_zero_v3(in)) { return; } copy_v3_v3(t_con_center, t->center_global); /* checks for center being too close to the view center */ viewAxisCorrectCenter(t, t_con_center); angle = fabsf(angle_v3v3(axis, t->viewinv[2])); if (angle > (float)M_PI_2) { angle = (float)M_PI - angle; } angle = RAD2DEGF(angle); /* For when view is parallel to constraint... will cause NaNs otherwise * So we take vertical motion in 3D space and apply it to the * constraint axis. Nice for camera grab + MMB */ if (angle < 5.0f) { project_v3_v3v3(vec, in, t->viewinv[1]); factor = dot_v3v3(t->viewinv[1], vec) * 2.0f; /* since camera distance is quite relative, use quadratic relationship. holding shift can compensate */ if (factor < 0.0f) factor *= -factor; else factor *= factor; copy_v3_v3(out, axis); normalize_v3(out); mul_v3_fl(out, -factor); /* -factor makes move down going backwards */ } else { float v[3], i1[3], i2[3]; float v2[3], v4[3]; float norm_center[3]; float plane[3]; getViewVector(t, t_con_center, norm_center); cross_v3_v3v3(plane, norm_center, axis); project_v3_v3v3(vec, in, plane); sub_v3_v3v3(vec, in, vec); add_v3_v3v3(v, vec, t_con_center); getViewVector(t, v, norm); /* give arbitrary large value if projection is impossible */ factor = dot_v3v3(axis, norm); if (1.0f - fabsf(factor) < 0.0002f) { copy_v3_v3(out, axis); if (factor > 0) { mul_v3_fl(out, 1000000000.0f); } else { mul_v3_fl(out, -1000000000.0f); } } else { add_v3_v3v3(v2, t_con_center, axis); add_v3_v3v3(v4, v, norm); isect_line_line_v3(t_con_center, v2, v, v4, i1, i2); sub_v3_v3v3(v, i2, v); sub_v3_v3v3(out, i1, t_con_center); /* possible some values become nan when * viewpoint and object are both zero */ if (!finite(out[0])) out[0] = 0.0f; if (!finite(out[1])) out[1] = 0.0f; if (!finite(out[2])) out[2] = 0.0f; } } }