Esempio n. 1
0
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;
}
Esempio n. 2
0
/** 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