bool CustomSliceModel::initialize(FibSliceModel& slice,bool is_qsdr,const std::vector<std::string>& files) { terminated = true; ended = true; gz_nifti nifti; center_point = slice.center_point; // QSDR loaded, use MNI transformation instead if(is_qsdr && files.size() == 1 && nifti.load_from_file(files[0])) { loadLPS(nifti); std::vector<float> t(nifti.get_transformation(), nifti.get_transformation()+12),inv_trans(16); transform.resize(16); t.resize(16); t[15] = 1.0; image::matrix::inverse(slice.handle->trans_to_mni.begin(),inv_trans.begin(),image::dim<4,4>()); image::matrix::product(inv_trans.begin(),t.begin(),transform.begin(),image::dim<4,4>(),image::dim<4,4>()); invT.resize(16); image::matrix::inverse(transform.begin(),invT.begin(),image::dim<4, 4>()); } else { if(files.size() == 1 && nifti.load_from_file(files[0])) loadLPS(nifti); else { image::io::bruker_2dseq bruker; if(files.size() == 1 && bruker.load_from_file(files[0].c_str())) load(bruker); else { image::io::volume volume; if(volume.load_from_files(files,files.size())) load(volume); else return false; } } // same dimension, no registration required. if(source_images.geometry() == slice.source_images.geometry()) { transform.resize(16); transform[0] = transform[5] = transform[10] = transform[15] = 1.0; invT.resize(16); invT[0] = invT[5] = invT[10] = invT[15] = 1.0; } } roi_image.resize(slice.handle->dim); roi_image_buf = &*roi_image.begin(); if(transform.empty()) { from = slice.source_images; arg_min.scaling[0] = slice.voxel_size[0] / voxel_size[0]; arg_min.scaling[1] = slice.voxel_size[1] / voxel_size[1]; arg_min.scaling[2] = slice.voxel_size[2] / voxel_size[2]; thread.reset(new boost::thread(&CustomSliceModel::argmin,this,image::reg::rigid_body)); // handle views transform.resize(16); invT.resize(16); } else update_roi(); return true; }
/** Returns information on the parameters needed to hit a target kart moving * at constant velocity and direction for a given speed in the XZ-plane. * \param origin Location of the kart shooting the item. * \param target_kart Which kart to target. * \param item_xz_speed Speed of the item projected in XZ plane. * \param gravity The gravity used for this item. * \param forw_offset How far ahead of the kart the item is shot (so that * the item does not originate inside of the shooting kart. * \param fire_angle Returns the angle to fire the item at. * \param up_velocity Returns the upwards velocity to use for the item. */ void Flyable::getLinearKartItemIntersection (const Vec3 &origin, const AbstractKart *target_kart, float item_XZ_speed, float gravity, float forw_offset, float *fire_angle, float *up_velocity) { // Transform the target into the firing kart's frame of reference btTransform inv_trans = m_owner->getTrans().inverse(); Vec3 relative_target_kart_loc = inv_trans(target_kart->getXYZ()); // Find the direction target is moving in btTransform trans = target_kart->getTrans(); Vec3 target_direction(trans.getBasis().getColumn(2)); // Now rotate it to the firing kart's frame of reference btQuaternion inv_rotate = inv_trans.getRotation(); target_direction = target_direction.rotate(inv_rotate.getAxis(), inv_rotate.getAngle()); // Now we try to find the angle to aim at to hit the target. // Warning : Funky math stuff going on below. To understand, see answer by // Jeffrey Hantin here : // http://stackoverflow.com/questions/2248876/2d-game-fire-at-a-moving-target-by-predicting-intersection-of-projectile-and-u float target_x_speed = target_direction.getX()*target_kart->getSpeed(); float target_z_speed = target_direction.getZ()*target_kart->getSpeed(); float target_y_speed = target_direction.getY()*target_kart->getSpeed(); float a = (target_x_speed*target_x_speed) + (target_z_speed*target_z_speed) - (item_XZ_speed*item_XZ_speed); float b = 2 * (target_x_speed * (relative_target_kart_loc.getX()) + target_z_speed * (relative_target_kart_loc.getZ())); float c = relative_target_kart_loc.getX()*relative_target_kart_loc.getX() + relative_target_kart_loc.getZ()*relative_target_kart_loc.getZ(); float discriminant = b*b - 4 * a*c; if (discriminant < 0) discriminant = 0; float t1 = (-b + sqrt(discriminant)) / (2 * a); float t2 = (-b - sqrt(discriminant)) / (2 * a); float time; if (t1 >= 0 && t1<t2) time = t1; else time = t2; //createPhysics offset time -= forw_offset / item_XZ_speed; float aimX = time*target_x_speed + relative_target_kart_loc.getX(); float aimZ = time*target_z_speed + relative_target_kart_loc.getZ(); assert(time!=0); float angle = atan2f(aimX, aimZ); *fire_angle = angle; // Now find the up_velocity. This is an application of newton's equation. *up_velocity = (0.5f * time * gravity) + (relative_target_kart_loc.getY() / time) + ( target_y_speed); } // getLinearKartItemIntersection