/************************************************************************ * This is the recursive ray tracer - you need to implement this! * You should decide what arguments to use. ************************************************************************/ RGB_float recursive_ray_trace(Point &pos, Vector &ray, int num, bool inside=false) { IntersectionInfo end; const Object *s = getClosestObject(pos, ray, end); if (s == nullptr) { return background_clr; } Vector norm = s->getNormal(end); if (inside) { norm *= -1; } RGB_float color = phong(end.pos, ray, norm, s); if (num <= step_max) { Vector h; RGB_float ref({0,0,0}); RGB_float ract({0,0,0}); if (!inside && reflect_on) { h = vec_reflect(ray, norm); ref = recursive_ray_trace(end.pos, h, num + 1); } if (stochdiff_on) { RGB_float diff = {0,0,0}; std::default_random_engine generator; std::uniform_int_distribution<int> distribution(-10,10); for (int i = 0; i < STOCH_RAYS; ++i) { h = vec_reflect(ray, norm); h = RotateX(distribution(generator)) * RotateY(distribution(generator)) * RotateZ(distribution(generator)) * h; diff += recursive_ray_trace(end.pos, h, num+1); } diff /= 6; color += (diff*s->reflectance); } if (refract_on) { if (inside) { h = vec_refract(ray, norm, 1.5, 1); } else { h = vec_refract(ray, norm, 1, 1.5); } ract = recursive_ray_trace(end.pos, h, num + 1, !inside); } float reflectWeight = s->reflectance; float refractWeight = 0; if (refract_on && s->transparency > 0) { refractWeight = s->transparency; reflectWeight = (1-refractWeight)*s->reflectance; } color += (ref * reflectWeight + ract * refractWeight); } return color; }
/********************************************************************* * Phong illumination - you need to implement this! *********************************************************************/ RGB_float phong(const Point &q, Vector v, const Vector &norm, const Object *sph) { float ip[3] = {0,0,0}; Vector lm = get_vec(q, light1); float dist = length(lm); lm = normalize(lm); IntersectionInfo end; bool indirect = false; const Object *o = getClosestObject(q, lm, end); // If shadows are off we still don't allow light to pass through to the // backside of an object. if (o != nullptr && (shadow_on || o == sph)) { indirect = true; } Vector r = normalize(vec_reflect(lm, norm)); v = normalize(v); float decay = 1/(decay_a + decay_b * dist + decay_c * dist * dist); for (int i = 0; i < 3; ++i) { ip[i] += global_ambient[i] * sph->mat_ambient[i]; ip[i] += sph->mat_ambient[i] * light1_ambient[i]; float ds = 0; if (!indirect) { ds += light1_diffuse[i] * sph->getDiffuse(q, i) * dot(lm, norm); ds += light1_specular[i] * sph->mat_specular[i] * pow(dot(r, v), sph->mat_shineness); ip[i] += ds * decay; } } RGB_float color = {ip[0], ip[1], ip[2]}; return color; }
void CalibWidget::drawRectAndLED(QImage *_qimg, const calib::LEDCalibContainer &container, const calib::LEDCalibSample &sample, const Camera *cam) { const std::vector<cv::Point2f> &image_points = sample.image_points; // draw the found markers on the image drawMarkers(_qimg, image_points); /************************************************************** * Get the vectors from the LED calibrator **************************************************************/ std::vector<cv::Point3f> objectPoints; calib::LEDCalibPattern::getLEDObjectPoints(container.circleSpacing, objectPoints); Eigen::Matrix4d transformation; // compute the transformation matrix calib::LEDCalibPattern::makeTransformationMatrix(cam->getIntrisicMatrix(), cam->getDistortion(), sample.image_points, objectPoints, transformation); // compute the normal Eigen::Vector3d eig_normal; calib::LEDCalibPattern::computeNormal(transformation, eig_normal); // the vector from the camera centre to the intersection point const Eigen::Vector3d vec_inters = calib::computeIntersectionPoint(sample.glint, objectPoints, eig_normal, transformation, *cam); if(vec_inters(0) == 0 && vec_inters(1) == 0 && vec_inters(2) == 0) { return; } // the vector reflected with respect to the intersection vector. Eigen::Vector3d vec_reflect = calib::computeReflectionPoint(eig_normal, vec_inters); /************************************************************** * Get and draw the glint **************************************************************/ const cv::Point2d &glint = sample.glint; { QPainter painter(_qimg); painter.drawArc(glint.x - 3, glint.y - 3, 6, 6, 0, 16*360); /************************************************************** * Map the reflected vector to 2D and draw it **************************************************************/ double c = 3*container.circleSpacing; cv::Point3d p3DStart; p3DStart.x = vec_inters(0); p3DStart.y = vec_inters(1); p3DStart.z = vec_inters(2); double uStart, vStart; cam->worldToPix(p3DStart, &uStart, &vStart); cv::Point3d p3DEnd; p3DEnd.x = vec_inters(0) + c*vec_reflect(0); p3DEnd.y = vec_inters(1) + c*vec_reflect(1); p3DEnd.z = vec_inters(2) + c*vec_reflect(2); double uEnd, vEnd; cam->worldToPix(p3DEnd, &uEnd, &vEnd); painter.setPen(Qt::red); painter.drawLine((int)(uStart + 0.5), (int)(vStart + 0.5), (int)(uEnd + 0.5), (int)(vEnd + 0.5)); /******************************************************************************* * Map the normal vector to 2D and draw it *******************************************************************************/ p3DEnd.x = vec_inters(0) + c*eig_normal(0); p3DEnd.y = vec_inters(1) + c*eig_normal(1); p3DEnd.z = vec_inters(2) + c*eig_normal(2); cam->worldToPix(p3DEnd, &uEnd, &vEnd); painter.setPen(Qt::blue); painter.drawLine((int)(uStart + 0.5), (int)(vStart + 0.5), (int)(uEnd + 0.5), (int)(vEnd + 0.5)); } /************************************************** * Compute the transformed object points **************************************************/ // get the normalised object points const std::vector<cv::Point3f> &norm_object_points = container.normalisedObjectPoints; // define the transformed object points std::vector<cv::Point3f> trans_obj_points(norm_object_points.size()); // compute the transformed object points computeTransormedPoints(norm_object_points, container.circleSpacing, transformation, trans_obj_points); { QPainter painter(_qimg); painter.setPen(Qt::yellow); int x = 10; int y = 15; for(size_t i = 0; i < trans_obj_points.size(); ++i) { const cv::Point3f &curPoint = trans_obj_points[i]; QString str; str.sprintf("%d: (%.2f, %.2f, %.2f)", (int)i, curPoint.x, curPoint.y, curPoint.z); painter.drawText(x, y, str); y += 20; } } }