Esempio n. 1
0
bool
SimpleRenderer::get_inverse_matrix (Matrix44 &result, ustring to, float time)
{
    if (to == u_camera || to == u_screen || to == u_NDC || to == u_raster) {
        Matrix44 M = m_world_to_camera;
        if (to == u_screen || to == u_NDC || to == u_raster) {
            // arbitrary clip planes because renderer doesn't do any clipping
            float yon = 0.01f;
            float hither = 1e5f;
            float depthrange = yon - hither;
            float tanhalffov = tanf (m_fov * float(M_PI/360.0));
            Matrix44 camera_to_screen (1/tanhalffov, 0, 0, 0,
                                       0, 1/tanhalffov, 0, 0,
                                       0, 0, yon/depthrange, 1,
                                       0, 0, -yon*hither/depthrange, 0);
            M = M * camera_to_screen;
            if (to == u_NDC || to == u_raster) {
                Matrix44 screen_to_ndc (0.5f, 0, 0, 0,
                                        0, 0.5f, 0, 0,
                                        0, 0, 1.0f, 0,
                                        -0.5f, -0.5f, 0, 1);
                M = M * screen_to_ndc;
                if (to == u_raster) {
                    Matrix44 ndc_to_raster (m_xres, 0, 0, 0,
                                            0, m_yres, 0, 0,
                                            0, 0, 1, 0,
                                            0, 0, 0, 1);
                    M = M * ndc_to_raster;
                }
            }
        }
        result = M;
        return true;
    }

    TransformMap::const_iterator found = m_named_xforms.find (to);
    if (found == m_named_xforms.end())
        return false;
    result = found->second;
    result.invert();
    return true;
}
Esempio n. 2
0
void test_d_camera_to_screen() {
    auto pos = Vector3f{0, 0, 0};
    auto look = Vector3f{0, 0, 1};
    auto up = Vector3f{0, 1, 0};
    Matrix3x3f n2c = Matrix3x3f::identity();
    Matrix3x3f c2n = Matrix3x3f::identity();
    Camera camera{1, 1,
        &pos[0],
        &look[0],
        &up[0],
        &n2c.data[0][0],
        &c2n.data[0][0],
        1e-2f,
        false};
    auto pt = Vector3{0.5, 0.5, 1.0};
    auto dx = Real(1);
    auto dy = Real(1);
    auto d_camera = DCameraInst{};
    auto d_pt = Vector3{0, 0, 0};
    d_camera_to_screen(camera, pt, dx, dy, d_camera, d_pt);
    // Compare with central difference
    auto finite_delta = Real(1e-6);
    for (int i = 0; i < 3; i++) {
        auto delta_pos = pos;
        delta_pos[i] += finite_delta;
        auto delta_camera = Camera{
            1, 1,
            &delta_pos[0],
            &look[0],
            &up[0],
            &n2c.data[0][0],
            &c2n.data[0][0],
            1e-2f,
            false};
        auto pxy = camera_to_screen(delta_camera, pt);
        delta_pos[i] -= 2 * finite_delta;
        delta_camera = Camera{
            1, 1,
            &delta_pos[0],
            &look[0],
            &up[0],
            &n2c.data[0][0],
            &c2n.data[0][0],
            1e-2f,
            false};
        auto nxy = camera_to_screen(delta_camera, pt);
        auto diff = (sum(pxy - nxy)) / (2 * finite_delta);
        equal_or_error(__FILE__, __LINE__, (Real)diff, (Real)d_camera.position[i]);
    }
    for (int i = 0; i < 3; i++) {
        auto delta_look = look;
        delta_look[i] += finite_delta;
        auto delta_camera = Camera{
            1, 1,
            &pos[0],
            &delta_look[0],
            &up[0],
            &n2c.data[0][0],
            &c2n.data[0][0],
            1e-2f,
            false};
        auto pxy = camera_to_screen(delta_camera, pt);
        delta_look[i] -= 2 * finite_delta;
        delta_camera = Camera{
            1, 1,
            &pos[0],
            &delta_look[0],
            &up[0],
            &n2c.data[0][0],
            &c2n.data[0][0],
            1e-2f,
            false};
        auto nxy = camera_to_screen(delta_camera, pt);
        auto diff = (sum(pxy - nxy)) / (2 * finite_delta);
        equal_or_error(__FILE__, __LINE__, (Real)diff, (Real)d_camera.look[i]);
    }
    for (int i = 0; i < 3; i++) {
        auto delta_up = up;
        delta_up[i] += finite_delta;
        auto delta_camera = Camera{
            1, 1,
            &pos[0],
            &look[0],
            &delta_up[0],
            &n2c.data[0][0],
            &c2n.data[0][0],
            1e-2f,
            false};
        auto pxy = camera_to_screen(delta_camera, pt);
        delta_up[i] -= 2 * finite_delta;
        delta_camera = Camera{
            1, 1,
            &pos[0],
            &look[0],
            &delta_up[0],
            &n2c.data[0][0],
            &c2n.data[0][0],
            1e-2f,
            false};
        auto nxy = camera_to_screen(delta_camera, pt);
        auto diff = (sum(pxy - nxy)) / (2 * finite_delta);
        equal_or_error(__FILE__, __LINE__, (Real)diff, (Real)d_camera.up[i]);
    }
    for (int i = 0; i < 3; i++) {
        for (int j = 0; j < 3; j++) {
            auto delta_camera = camera;
            delta_camera.cam_to_ndc(i, j) += finite_delta;
            auto pxy = camera_to_screen(delta_camera, pt);
            delta_camera.cam_to_ndc(i, j) -= 2 * finite_delta;
            auto nxy = camera_to_screen(delta_camera, pt);
            auto diff = sum(pxy - nxy) / (2 * finite_delta);
            equal_or_error(__FILE__, __LINE__, (Real)diff, (Real)d_camera.cam_to_ndc(i, j));
        }
    }
}