ProjectCubemapToGeometryPass::ProjectCubemapToGeometryPass(std::string flyvr_basepath,
                               osg::TextureCubeMap* texture,
                               osg::Uniform::Callback* observer_position_cb,
                               DisplaySurfaceGeometry* geometry_parameters,
                               unsigned int tex_width,
                               unsigned int tex_height) :
  _geometry_parameters( geometry_parameters), _tex_width(tex_width), _tex_height(tex_height), _observer_position_callback(observer_position_cb)
 {
   flyvr_assert( texture!=NULL );
   flyvr_assert( geometry_parameters!=NULL );

   set_flyvr_base_path(flyvr_basepath);
   set_plugin_path(flyvr_basepath,false);

  _top = new osg::Group;
  _top->addDescription("ProjectCubemapToGeometryPass top node");
  _in_texture_cubemap = texture;

  create_output_texture();

  _camera = new osg::Camera;
  setup_camera();
  _geometry = create_textured_geometry();
  _camera->addChild( _geometry.get() );
  _top->addChild( _camera );

  set_shader( "ProjectCubemapToGeometryPass.vert",
              "ProjectCubemapToGeometryPass.frag");
}
void StimulusCylinderGrating_centered_bw::receive_json_message(const std::string& topic_name, const std::string& json_message)
{
    json_t *root;
    json_error_t error;

    root = json_loads(json_message.c_str(), 0, &error);
    flyvr_assert(root != NULL);

    if (topic_name=="grating_info") {
        GratingParams new_values;
        json_t *data_json;

        //data_json = json_object_get(root, "grating0");
        //new_values = parse_grating_info(data_json);
        new_values = parse_grating_info(root);
        set_grating_info(0,new_values);

        //data_json = json_object_get(root, "grating1");
        //new_values = parse_grating_info(data_json);
        //set_grating_info(1,new_values);
    } else {
        throw std::runtime_error("unknown topic name");
    }

    json_decref(root);
}
GratingParams parse_grating_info(const json_t * const root) {
    GratingParams result;

    json_t *data_json;

    data_json = json_object_get(root, "reset_phase_position");
    flyvr_assert(data_json != NULL);
    flyvr_assert(json_is_boolean(data_json));
    result.reset_phase_position = json_is_true( data_json );

    data_json = json_object_get(root, "phase_position");
    flyvr_assert(data_json != NULL);
    flyvr_assert(json_is_real(data_json));
    result.phase_position = json_real_value( data_json );

    data_json = json_object_get(root, "phase_velocity");
    flyvr_assert(data_json != NULL);
    flyvr_assert(json_is_real(data_json));
    result.phase_velocity = json_real_value( data_json );

    data_json = json_object_get(root, "wavelength");
    flyvr_assert(data_json != NULL);
    flyvr_assert(json_is_real(data_json));
    result.wavelength = json_real_value( data_json );

    data_json = json_object_get(root, "contrast");
    flyvr_assert(data_json != NULL);
    flyvr_assert(json_is_real(data_json));
    result.contrast = json_real_value( data_json );

    data_json = json_object_get(root, "orientation");
    flyvr_assert(data_json != NULL);
    flyvr_assert(json_is_real(data_json));
    result.orientation = json_real_value( data_json );

    return result;
}
void StimulusCylinderGrating_centered_bw::init_cyl(CylInfo& cyl) {

    osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints;
    hints->setDetailRatio(2.0f);
    hints->setCreateTop(false);
    hints->setCreateBottom(false);

    osg::Vec3 center = osg::Vec3(0.0f,0.0f,0.0f);
    float radius = 1.0f;
    float height = 3.0;

    cyl.cylinder = new osg::Cylinder(center,radius,height);
    cyl.shape = new osg::ShapeDrawable(cyl.cylinder, hints.get());

    const char* phase_position_name;
    const char* wavelength_name;
    const char* contrast_name;
    const char* orientation_name;

    for (int i=0; i<NUM_GRATINGS; i++) {
        GratingParams new_values;
        new_values.phase_position = 0.0;
        new_values.phase_velocity = 360*D2R;
        new_values.wavelength = 20*D2R;
        new_values.contrast = 1.0;
      new_values.orientation = 0;

        if (i==0) {
            phase_position_name="phase_position0";
            wavelength_name="wavelength0";
            contrast_name="contrast0";
            orientation_name="orientation0";
        } else {
            flyvr_assert(false);
        }

        cyl.gratings[i].u_phase_position = new osg::Uniform( osg::Uniform::FLOAT, phase_position_name );
        cyl.gratings[i].u_wavelength = new osg::Uniform( osg::Uniform::FLOAT, wavelength_name );
        cyl.gratings[i].u_contrast = new osg::Uniform( osg::Uniform::FLOAT, contrast_name );
        cyl.gratings[i].u_orientation = new osg::Uniform( osg::Uniform::FLOAT, orientation_name );

        set_grating_info( i, new_values);
    }

    cyl.geode = new osg::Geode;
    cyl.geode->addDrawable(cyl.shape.get());

    cyl.program = new osg::Program;
    cyl.program->setName( "cylinder_shader" );

    cyl.vertex_shader = new osg::Shader( osg::Shader::VERTEX );
    cyl.fragment_shader = new osg::Shader( osg::Shader::FRAGMENT );

    cyl.program->addShader(cyl.vertex_shader);
    cyl.program->addShader(cyl.fragment_shader);

    load_shader_source( cyl.vertex_shader, "grating_blended_centered.vert" );
    load_shader_source( cyl.fragment_shader, "grating_blended_centered.frag" );

    cyl.state_set = cyl.shape->getOrCreateStateSet();

    cyl.state_set->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
    cyl.state_set->setMode(GL_BLEND, osg::StateAttribute::ON);

    cyl.state_set->setAttributeAndModes( cyl.program, osg::StateAttribute::ON);

    for (int i=0;i<NUM_GRATINGS;i++) {
        cyl.state_set->addUniform( cyl.gratings[i].u_phase_position );
        cyl.state_set->addUniform( cyl.gratings[i].u_wavelength );
        cyl.state_set->addUniform( cyl.gratings[i].u_contrast );
        cyl.state_set->addUniform( cyl.gratings[i].u_orientation );
    }

}