OSG::UniformBufferObjChunkTransitPtr create_light_state(const VecLightsT& vLights)
{
    OSG::UniformBufferObjChunkRefPtr ubo = OSG::UniformBufferObjChunk::create();

    ubo->setBlockName("Lights");
    ubo->setUsage(GL_STREAM_DRAW);

    for (std::size_t i = 0; i < vLights.size(); ++i) {
        std::stringstream stream;
        stream << "Lights.light[" << i << "]." << std::flush;
        std::string name;

        name = stream.str() + "type";               ubo->addIVec3(name);
        name = stream.str() + "position";           ubo->addVec3 (name);
        name = stream.str() + "spot_direction";     ubo->addVec3 (name);
        name = stream.str() + "Ia";                 ubo->addVec3 (name);
        name = stream.str() + "Id";                 ubo->addVec3 (name);
        name = stream.str() + "Is";                 ubo->addVec3 (name);
        name = stream.str() + "attenuation";        ubo->addVec3 (name);
        name = stream.str() + "spot_cos_cutoff";    ubo->addFloat(name);
        name = stream.str() + "spot_exponent";      ubo->addFloat(name);
    }

    update_light_state(ubo, vLights);

    return OSG::UniformBufferObjChunkTransitPtr(ubo);
}
int pwm_init(void)
{

#if MYNEWT_VAL(PWM_0)
	init_pwm_dev(&pwm0, "pwm0", &led1_conf);
#endif

#if MYNEWT_VAL(PWM_1)
	init_pwm_dev(&pwm1, "pwm1", &led2_conf);
#endif

#if MYNEWT_VAL(PWM_2)
	init_pwm_dev(&pwm2, "pwm2", &led3_conf);
#endif

#if MYNEWT_VAL(PWM_3)
	init_pwm_dev(&pwm3, "pwm3", &led4_conf);
#endif

	if (!pwm0) {
		return 0;
	}

	top_val = (uint16_t) pwm_get_top_value(pwm0);
	update_light_state();

	return 0;
}
int light_model_gen_level_set(struct bt_mesh_model *model, s16_t level)
{
	gen_level_state = level;
	if ((u16_t)gen_level_state > 0x0000) {
		gen_onoff_state = 1;
	}
	if ((u16_t)gen_level_state == 0x0000) {
		gen_onoff_state = 0;
	}
	update_light_state();
	return 0;
}
int light_model_init(void)
{
#if MYNEWT_VAL(BLE_MESH_SHELL_MODELS)
	int rc;
#if (!MYNEWT_VAL(USE_NEOPIXEL))
	rc = pwm_init();
	assert(rc == 0);
#else
	rc = ws2812_init();
	assert(rc == 0);
	update_light_state();
#endif
	return rc;
#else
	return 0;
#endif
}
//
// redraw the window
//
void display(void)
{
    // light spot direction and light position must be provided in eye space
    update_light_state(ubo_light_state, lights);

    // create the matrix
    OSG::Matrix m;
    OSG::Real32 t = glutGet(GLUT_ELAPSED_TIME );
    
    // set the transforms' matrices
    m.setTransform(OSG::Vec3f(0, 0, OSG::osgSin(t / 1000.f) * 1.5),
                   OSG::Quaternion( OSG::Vec3f (1, 0, 0), t / 500.f));

    cyltrans->setMatrix(m);
    
    m.setTransform(OSG::Vec3f(OSG::osgSin(t / 1000.f), 0, 0),
                   OSG::Quaternion( OSG::Vec3f (0, 0, 1), t / 1000.f));

    tortrans->setMatrix(m);

    OSG::commitChanges();
    
    mgr->redraw();
}
int light_model_gen_onoff_set(struct bt_mesh_model *model, u8_t state)
{
	gen_onoff_state = state;
	update_light_state();
	return 0;
}