// FUNCTION ====== setup void setup(){ //---- SDL initialization if ( SDL_Init(SDL_INIT_VIDEO) != 0 ) { printf("Unable to initialize SDL: %s\n", SDL_GetError()); getchar() ; } SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); //screen = SDL_SetVideoMode( WIDTH, HEIGHT, COLDEPTH, SDL_OPENGL | SDL_SWSURFACE ); screen = SDL_SetVideoMode( WIDTH, HEIGHT, COLDEPTH, SDL_OPENGL ); if(!screen) { printf("Couldn't set %dx%d GL video mode: %s\n", WIDTH,HEIGHT, SDL_GetError()); SDL_Quit(); exit(2); } SDL_WM_SetCaption(" Prokop's test SDL+ OpenGL", "SDL+ OpenGL"); //materialy float ambient [] = { 0.10f, 0.15f, 0.25f, 1.0f}; glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, ambient); float diffuse [] = { 0.50f, 0.50f, 0.50f, 1.0f}; glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffuse); float specular [] = { 0.00f, 0.00f, 0.00f, 1.0f}; glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, specular); float shininess[] = { 0.0f }; glMaterialfv (GL_FRONT_AND_BACK, GL_SHININESS, shininess); glEnable (GL_LIGHT0); float light0_pos [] = { 1000.0f, 0.0f, 0.0f, 1.00f}; glLightfv (GL_LIGHT0, GL_POSITION, light0_pos ); float light0_color[] = { 0.8f, 0.5f, 0.5f, 1.00f}; glLightfv (GL_LIGHT0, GL_DIFFUSE, light0_color); glEnable (GL_LIGHT1); float light1_pos [] = { 0.0f, 1000.0f, 0.0f, 1.00f}; glLightfv (GL_LIGHT1, GL_POSITION, light1_pos ); float light1_color[] = { 0.5f, 0.8f, 0.5f, 1.00f}; glLightfv (GL_LIGHT1, GL_DIFFUSE, light1_color); glEnable (GL_LIGHT2); float light2_pos [] = { 0.0f, 0.0f, 1000.0f, 1.00f}; glLightfv (GL_LIGHT2, GL_POSITION, light2_pos ); float light2_color[] = { 0.5f, 0.5f, 0.8f, 1.00f}; glLightfv (GL_LIGHT2, GL_DIFFUSE, light2_color); glEnable (GL_LIGHTING); glEnable (GL_COLOR_MATERIAL); glEnable (GL_NORMALIZE); glEnable (GL_DEPTH_TEST); //glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //glEnable(GL_BLEND) ; //glBlendFunc (GL_SRC_ALPHA, GL_SRC_ALPHA); glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); glShadeModel(GL_SMOOTH); glPolygonMode(GL_FRONT_AND_BACK,GL_FILL); glClearColor( 0.9, 0.9, 0.9, 0.0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); srand(1234); trackball (qCamera, 0, 0, 0, 0); // qCameraOld[3] = 1.0; printf( "1\n" ); body.pos.set( 1,1,1 ); body.vel.set( 1,-1,1 ); //const int len = 6; //double masses[len] = { 1,1, 1,1, 1,1 }; //Vec3d poss[len] = { {-1,0,0}, {+1,0,0}, {0,-2,0}, {0,+2,0}, {0,0,-3}, {0,0,+3} } //printf( " %f %f \n", poss[0].x, poss_[0] ); printf( "2\n" ); int boxList = makeBoxList( -1,1, -2,2, -3, 3, 0.9, 0.9, 0.9 ); //rbody.shape = boxList; rbody.from_mass_points( len, masses, poss ); //rbody.qrot.setOne(); printf( "3\n" ); rbody.qrot.set(4,-3,2,-1); rbody.qrot.normalize(); //rbody.pos.add( 5.0d,5.0d,5.0d ); printf( "4\n" ); rbody.vel.set(0.0); //rbody.L .set(10,10,10); rbody.init( ); rbody.shape = shapePointsCenter( len, poss, rbody.pos, 0.5 ); printf( "5\n" ); rbody2.shape = boxList; rbody2.from_mass_points( len, masses, poss ); rbody2.qrot.setOne(); rbody2.vel.set(0.0); //rbody2.L .set(10,10,10); rbody2.init( ); constrain1 = new SpringConstrain( 20, &rbody, &rbody2, {-1,-2,-3}, {1,2,3} ); //Vec3d p1,p2; p1.set(-1,-2,-3); p2.set(1,2,3); //constrain1 = new SpringConstrain( 20, &rbody, &rbody2, p1, p2 ); printf("mass: %f invMass %f \n", rbody.mass, rbody.invMass ); printf("Ibody\n"); printMat(rbody.Ibody); printf("invIbody\n"); printMat(rbody.invIbody); }
void drawContext::addQuaternion(double p1x, double p1y, double p2x, double p2y) { double quat[4]; trackball(quat, p1x, p1y, p2x, p2y); add_quats(quat, _quaternion, _quaternion); }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); // setup scene gua::SceneGraph graph("main_scenegraph"); gua::TriMeshLoader loader; auto teapot_mat(gua::MaterialShaderDatabase::instance() ->lookup("gua_default_material") ->make_new_material()); teapot_mat->set_render_wireframe(false); teapot_mat->set_show_back_faces(false); auto transform = graph.add_node<gua::node::TransformNode>("/", "transform"); auto teapot(loader.create_geometry_from_file( "teapot", "data/objects/teapot.obj", teapot_mat, gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE) ); graph.add_node("/transform", teapot); teapot->set_draw_bounding_box(true); auto portal = graph.add_node<gua::node::TexturedQuadNode>("/", "portal"); portal->data.set_size(gua::math::vec2(1.2f, 0.8f)); portal->data.set_texture("portal"); portal->translate(0.5f, 0.f, -0.2f); portal->rotate(-30, 0.f, 1.f, 0.f); auto light2 = graph.add_node<gua::node::LightNode>("/", "light2"); light2->data.set_type(gua::node::LightNode::Type::POINT); light2->data.brightness = 150.0f; light2->scale(12.f); light2->translate(-3.f, 5.f, 5.f); auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen"); screen->data.set_size(gua::math::vec2(1.92f, 1.08f)); screen->translate(0, 0, 1.0); auto portal_screen = graph.add_node<gua::node::ScreenNode>("/", "portal_screen"); portal_screen->translate(0.0, 0.0, 5.0); portal_screen->rotate(90, 0.0, 1.0, 0.0); portal_screen->data.set_size(gua::math::vec2(1.2f, 0.8f)); // add mouse interaction gua::utils::Trackball trackball(0.01, 0.002, 0.2); // setup rendering pipeline and window auto resolution = gua::math::vec2ui(1920, 1080); auto portal_camera = graph.add_node<gua::node::CameraNode>("/portal_screen", "portal_cam"); portal_camera->translate(0, 0, 2.0); portal_camera->config.set_resolution(gua::math::vec2ui(1200, 800)); portal_camera->config.set_screen_path("/portal_screen"); portal_camera->config.set_scene_graph_name("main_scenegraph"); portal_camera->config.set_output_texture_name("portal"); portal_camera->config.set_enable_stereo(false); auto portal_pipe = std::make_shared<gua::PipelineDescription>(); portal_pipe->add_pass(std::make_shared<gua::TriMeshPassDescription>()); portal_pipe->add_pass( std::make_shared<gua::LightVisibilityPassDescription>()); auto resolve_pass = std::make_shared<gua::ResolvePassDescription>(); resolve_pass->background_mode( gua::ResolvePassDescription::BackgroundMode::QUAD_TEXTURE); resolve_pass->tone_mapping_exposure(1.0f); portal_pipe->add_pass(resolve_pass); portal_pipe->add_pass(std::make_shared<gua::DebugViewPassDescription>()); portal_camera->set_pipeline_description(portal_pipe); auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam"); camera->translate(0, 0, 2.0); camera->config.set_resolution(resolution); camera->config.set_screen_path("/screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("main_window"); camera->config.set_enable_stereo(false); camera->set_pre_render_cameras({portal_camera}); camera->get_pipeline_description()->get_resolve_pass()->tone_mapping_exposure( 1.0f); camera->get_pipeline_description()->add_pass( std::make_shared<gua::DebugViewPassDescription>()); auto window = std::make_shared<gua::GlfwWindow>(); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_size(resolution); window->config.set_resolution(resolution); window->config.set_stereo_mode(gua::StereoMode::MONO); window->on_resize.connect([&](gua::math::vec2ui const& new_size) { window->config.set_resolution(new_size); camera->config.set_resolution(new_size); screen->data.set_size( gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y)); }); window->on_move_cursor.connect( [&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); }); window->on_button_press.connect( std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); gua::Renderer renderer; // application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0 / 500.0); ticker.on_tick.connect([&]() { // apply trackball matrix to object gua::math::mat4 modelmatrix = scm::math::make_translation(trackball.shiftx(), trackball.shifty(), trackball.distance()) * gua::math::mat4(trackball.rotation()); transform->set_transform(modelmatrix); if (window->should_close()) { renderer.stop(); window->close(); loop.stop(); } else { renderer.queue_draw({&graph}); } }); loop.start(); return 0; }
void EDA_3D_CANVAS::SetView3D( int keycode ) { int ii; double delta_move = 0.7 * GetPrm3DVisu().m_Zoom; switch( keycode ) { case WXK_LEFT: m_draw3dOffset.x -= delta_move; break; case WXK_RIGHT: m_draw3dOffset.x += delta_move; break; case WXK_UP: m_draw3dOffset.y += delta_move; break; case WXK_DOWN: m_draw3dOffset.y -= delta_move; break; case WXK_HOME: GetPrm3DVisu().m_Zoom = 1.0; m_draw3dOffset.x = m_draw3dOffset.y = 0; trackball( GetPrm3DVisu().m_Quat, 0.0, 0.0, 0.0, 0.0 ); break; case WXK_END: break; case WXK_F1: GetPrm3DVisu().m_Zoom /= 1.4; if( GetPrm3DVisu().m_Zoom <= 0.01 ) GetPrm3DVisu().m_Zoom = 0.01; break; case WXK_F2: GetPrm3DVisu().m_Zoom *= 1.4; break; case '+': break; case '-': break; case 'r': case 'R': m_draw3dOffset.x = m_draw3dOffset.y = 0; for( ii = 0; ii < 4; ii++ ) GetPrm3DVisu().m_Rot[ii] = 0.0; trackball( GetPrm3DVisu().m_Quat, 0.0, 0.0, 0.0, 0.0 ); break; case 'x': for( ii = 0; ii < 4; ii++ ) GetPrm3DVisu().m_Rot[ii] = 0.0; trackball( GetPrm3DVisu().m_Quat, 0.0, 0.0, 0.0, 0.0 ); GetPrm3DVisu().m_ROTZ = -90; GetPrm3DVisu().m_ROTX = -90; break; case 'X': for( ii = 0; ii < 4; ii++ ) GetPrm3DVisu().m_Rot[ii] = 0.0; trackball( GetPrm3DVisu().m_Quat, 0.0, 0.0, 0.0, 0.0 ); GetPrm3DVisu().m_ROTZ = 90; GetPrm3DVisu().m_ROTX = -90; break; case 'y': for( ii = 0; ii < 4; ii++ ) GetPrm3DVisu().m_Rot[ii] = 0.0; trackball( GetPrm3DVisu().m_Quat, 0.0, 0.0, 0.0, 0.0 ); GetPrm3DVisu().m_ROTX = -90; break; case 'Y': for( ii = 0; ii < 4; ii++ ) GetPrm3DVisu().m_Rot[ii] = 0.0; trackball( GetPrm3DVisu().m_Quat, 0.0, 0.0, 0.0, 0.0 ); GetPrm3DVisu().m_ROTX = -90; GetPrm3DVisu().m_ROTZ = -180; break; case 'z': for( ii = 0; ii < 4; ii++ ) GetPrm3DVisu().m_Rot[ii] = 0.0; trackball( GetPrm3DVisu().m_Quat, 0.0, 0.0, 0.0, 0.0 ); break; case 'Z': for( ii = 0; ii < 4; ii++ ) GetPrm3DVisu().m_Rot[ii] = 0.0; trackball( GetPrm3DVisu().m_Quat, 0.0, 0.0, 0.0, 0.0 ); GetPrm3DVisu().m_ROTX = -180; break; default: return; } DisplayStatus(); Refresh( false ); }
void Camera::dragMouse( int x, int y ) { Vec3f mouseDelta = Vec3f(x,y,0.0f) - mLastMousePosition; switch(mCurrentMouseAction) { case kActionTranslate: { // Determine mouse movement double xTrack = -mouseDelta[0] * kMouseTranslationXSensitivity; double yTrack = mouseDelta[1] * kMouseTranslationYSensitivity; // Recalculate stuff if needed if (m_bDirtyTransform) { updateTransform(); } // Determine directions of motion in scene space Vec3f direction = m_vPosition - m_vLookAt; Vec3f transXAxis = m_vUpVector ^ direction; transXAxis /= sqrt((transXAxis*transXAxis)); Vec3f transYAxis = direction ^ transXAxis; transYAxis /= sqrt((transYAxis*transYAxis)); // Move the camera's look-at point setLookAt(getLookAt() + transXAxis*xTrack + transYAxis*yTrack); break; } case kActionRotate: { // Store the rotation in this quarternion float quat[4]; // Get the mouse coordinates in a range between -1.0 and 1.0 float viewHalfWidth = (m_iViewportWidth / 2.f), viewHalfHeight = (m_iViewportHeight / 2.f); float oldX = mLastMousePosition[0] * 2.f / (m_iViewportWidth - 1) - 1.f, oldY = mLastMousePosition[1] * 2.f / (m_iViewportHeight - 1) - 1.f, newX = x * 2.f / (m_iViewportWidth - 1) - 1.f, newY = y * 2.f / (m_iViewportHeight - 1) - 1.f; // Get the quaternion to rotate around, from the trackball code. trackball( quat, oldX, -oldY, newX, -newY ); // Add the new quaternion to the current one. float oldQuat[4]; memcpy(oldQuat, m_fQuat, sizeof(float) * 4); //add_quats(oldQuat, quat, m_fQuat); add_quats(quat, oldQuat, m_fQuat); // Update the transform parameters. updateTransform(); break; } case kActionZoom: { // Determine dolly movement. float fDollyDelta = -mouseDelta[1] * kMouseZoomSensitivity; // Add to dolly setDolly(getDolly() + fDollyDelta); updateTransform(); break; } case kActionTwist: { break; } default: break; } mLastMousePosition = Vec3f(x,y,0.0f); }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); // setup scene gua::SceneGraph graph("main_scenegraph"); gua::TriMeshLoader loader; auto add_mesh = [&](int x, int y, int z) { auto t = graph.add_node<gua::node::TransformNode>("/", "mesh_" + std::to_string(x) + "_" + std::to_string(y)); t->scale(0.5); t->translate((x - COUNT * 0.5 + 0.5) / 2, (y - COUNT * 0.5 + 0.5) / 2, (z - COUNT * 0.5 + 0.5) / 2); auto mesh(loader.create_geometry_from_file("teapot", "data/objects/teapot.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE)); t->add_child(mesh); }; for(int x(0); x < COUNT; ++x) { for(int y(0); y < COUNT; ++y) { for(int z(0); z < COUNT; ++z) { add_mesh(x, y, z); } } } auto resolution = gua::math::vec2ui(1920, 1080); auto light = graph.add_node<gua::node::LightNode>("/", "light"); light->data.set_type(gua::node::LightNode::Type::POINT); light->scale(4.4f); light->translate(1.f, 0.f, 2.f); auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen"); screen->data.set_size(gua::math::vec2(0.001 * resolution.x, 0.001 * resolution.y)); screen->translate(0, 0, 1.0); auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam"); camera->translate(0, 0, 2.0); camera->config.set_resolution(resolution); camera->config.set_screen_path("/screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("main_window"); camera->get_pipeline_description()->get_resolve_pass()->tone_mapping_exposure(0.8f); auto plane_transform = graph.add_node<gua::node::TransformNode>("/", "plane_transform"); auto add_clipping_plane = [&](gua::math::vec3 const& pos, gua::math::vec4 const& rot) { auto clipping_plane = graph.add_node<gua::node::ClippingPlaneNode>("/plane_transform", "clipping_plane"); clipping_plane->rotate(rot.x, rot.y, rot.z, rot.w); clipping_plane->translate(pos); auto plane(loader.create_geometry_from_file("plane", "data/objects/plane.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE)); plane->rotate(-90, 1, 0, 0); // clipping_plane->add_child(plane); }; add_clipping_plane(gua::math::vec3(0, 0, -0.5), gua::math::vec4(180, 1, 0, 0)); add_clipping_plane(gua::math::vec3(0, 0, 0.5), gua::math::vec4(0, 0, 0, 0)); add_clipping_plane(gua::math::vec3(0, 0.5, 0), gua::math::vec4(-90, 1, 0, 0)); add_clipping_plane(gua::math::vec3(0, -0.5, 0), gua::math::vec4(90, 1, 0, 0)); add_clipping_plane(gua::math::vec3(-0.5, 0, 0), gua::math::vec4(-90, 0, 1, 0)); add_clipping_plane(gua::math::vec3(0.5, 0, 0), gua::math::vec4(90, 0, 1, 0)); // auto clipping_plane_2 = graph.add_node<gua::node::ClippingPlaneNode>("/plane_transform", "clipping_plane_2"); // clipping_plane_2->rotate(90, 1, 0, 0); // clipping_plane_2->translate(0, 0.5, 0); // add mouse interaction gua::utils::Trackball trackball(0.01, 0.002, 0.2); auto window = std::make_shared<gua::GlfwWindow>(); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(true); window->config.set_size(resolution); window->config.set_resolution(resolution); window->on_resize.connect([&](gua::math::vec2ui const& new_size) { window->config.set_resolution(new_size); camera->config.set_resolution(new_size); screen->data.set_size(gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y)); }); window->on_move_cursor.connect([&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); }); window->on_button_press.connect(std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); window->open(); gua::Renderer renderer; // application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0 / 500.0); ticker.on_tick.connect([&]() { // apply trackball matrix to object gua::math::mat4 modelmatrix = scm::math::make_translation(gua::math::float_t(trackball.shiftx()), gua::math::float_t(trackball.shifty()), gua::math::float_t(trackball.distance())) * gua::math::mat4(trackball.rotation()); plane_transform->set_transform(modelmatrix); window->process_events(); if(window->should_close()) { renderer.stop(); window->close(); loop.stop(); } else { renderer.queue_draw({&graph}); } }); loop.start(); return 0; }
static gint show_lwobject(const char *lwobject_name) { GtkWidget *window, *frame, *glarea; mesh_info *info; lwObject *lwobject; /* read lightwave object */ if (!lw_is_lwobject(lwobject_name)) { g_print("%s is not a LightWave 3D object\n", lwobject_name); return FALSE; } lwobject = lw_object_read(lwobject_name); if (lwobject == NULL) { g_print("Can't read LightWave 3D object %s\n", lwobject_name); return FALSE; } lw_object_scale(lwobject, 10.0 / lw_object_radius(lwobject)); /* create aspect frame */ frame = gtk_aspect_frame_new(NULL, 0.5,0.5, VIEW_ASPECT, FALSE); /* create new OpenGL widget */ glarea = gtk_drawing_area_new(); if (glarea == NULL) { lw_object_free(lwobject); g_print("Can't create GtkDrawingArea widget\n"); return FALSE; } /* Set OpenGL-capability to the widget. */ gtk_widget_set_gl_capability(GTK_WIDGET (glarea), glconfig, NULL, TRUE, GDK_GL_RGBA_TYPE); /* set up events and signals for OpenGL widget */ gtk_widget_set_events(glarea, GDK_EXPOSURE_MASK| GDK_BUTTON_PRESS_MASK| GDK_BUTTON_RELEASE_MASK| GDK_POINTER_MOTION_MASK| GDK_POINTER_MOTION_HINT_MASK); g_signal_connect(G_OBJECT(glarea), "draw", G_CALLBACK(draw), NULL); g_signal_connect(G_OBJECT(glarea), "motion_notify_event", G_CALLBACK(motion_notify), NULL); g_signal_connect(G_OBJECT(glarea), "button_press_event", G_CALLBACK(button_press), NULL); g_signal_connect(G_OBJECT(glarea), "button_release_event", G_CALLBACK(button_release), NULL); g_signal_connect(G_OBJECT(glarea), "configure_event", G_CALLBACK(configure), NULL); g_signal_connect(G_OBJECT (glarea), "map_event", G_CALLBACK (map_event), NULL); g_signal_connect(G_OBJECT (glarea), "unmap_event", G_CALLBACK (unmap_event), NULL); g_signal_connect(G_OBJECT (glarea), "visibility_notify_event", G_CALLBACK (visibility_notify_event), NULL); g_signal_connect(G_OBJECT(glarea), "destroy", G_CALLBACK(destroy), NULL); gtk_widget_set_size_request(glarea, 200,200/VIEW_ASPECT); /* minimum size */ /* set up mesh info */ info = (mesh_info*)g_malloc(sizeof(mesh_info)); info->do_init = TRUE; info->lwobject = lwobject; info->beginx = 0; info->beginy = 0; info->dx = 0; info->dy = 0; info->quat[0] = 0; info->quat[1] = 0; info->quat[2] = 0; info->quat[3] = 1; info->dquat[0] = 0; info->dquat[1] = 0; info->dquat[2] = 0; info->dquat[3] = 1; info->zoom = 45; info->animate = FALSE; info->timeout_id = 0; trackball(info->quat , 0.0, 0.0, 0.0, 0.0); g_object_set_data(G_OBJECT(glarea), "mesh_info", info); /* create new top level window */ window = gtk_window_new( GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), lwobject_name); gtk_container_set_border_width(GTK_CONTAINER(window), 10); gtk_container_set_reallocate_redraws(GTK_CONTAINER (window), TRUE); create_popup_menu(window); /* add popup menu to window */ /* key_press_event handler for top-level window */ g_signal_connect_swapped(G_OBJECT (window), "key_press_event", G_CALLBACK (key_press_event), glarea); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(window_destroy), NULL); window_count++; /* put glarea into window and show it all */ gtk_container_add(GTK_CONTAINER(window), frame); gtk_container_add(GTK_CONTAINER(frame),glarea); gtk_widget_show(glarea); gtk_widget_show(frame); gtk_widget_show(window); return TRUE; }
virtual void initEvent() { vl::Log::print(appletInfo()); // disable trackball and ghost camera manipulator trackball()->setEnabled(false); ghostCameraManipulator()->setEnabled(false); // camera setup rendering()->as<vl::Rendering>()->setNearFarClippingPlanesOptimized(false); rendering()->as<vl::Rendering>()->camera()->setProjectionAsOrtho2D(); // reset view matrix to I rendering()->as<vl::Rendering>()->camera()->setViewMatrix( vl::mat4() ); // load images used later as textures // load colorful pattern & substitute black with transparent blue vl::ref<vl::Image> pattern = vl::loadImage("/images/pattern.bmp"); pattern->substituteColorRGB_RGBA(0x000000,0x0000FFAA); // load transparent star vl::ref<vl::Image> star = vl::loadImage("/images/star.png"); // colorize the point to green and black vl::ref<vl::Image> circle16_bg = vl::loadImage("/images/circle16.png"); circle16_bg->substituteColorGreenKey(0x00FF00,0x000000); // colorize the point to yellow and red vl::ref<vl::Image> circle16_yr = vl::loadImage("/images/circle16.png"); circle16_yr->substituteColorGreenKey(0xFFFF00,0xFF0000); // generate the color spectrums vl::ref<vl::Image> spectrum1 = vl::makeColorSpectrum(128, vl::blue, vl::green, vl::yellow, vl::red); vl::ref<vl::Image> spectrum2 = vl::makeColorSpectrum(128, vl::black, vl::white, vl::gray, vl::black); // add a new VectorGraphics to our SceneManagerVectorGraphics vl::ref<vl::VectorGraphics> vg = new vl::VectorGraphics; vl::ref<vl::SceneManagerVectorGraphics> vgscene = new vl::SceneManagerVectorGraphics; vgscene->vectorGraphicObjects()->push_back(vg.get()); rendering()->as<vl::Rendering>()->sceneManagers()->push_back(vgscene.get()); // start drawing with our new VectorGraphics object! vg->startDrawing(); // clear the viewport vg->clearColor(vl::white); // ###### textured quad rendering ###### vg->setImage(pattern.get()); // this way the texels are perfectly centered on the pixels vg->translate(-0.5f,-0.5f); vg->pushMatrix(); // textured quad #1 repeat texturing vg->translate(10,110); vg->setTextureMode(vl::TextureMode_Repeat); vg->fillQuad( 0,0 , pattern->width()*3.0f,pattern->height()*3.0f ); // textured quad #2 stretch texturing vg->translate(100,0); vg->setTextureMode(vl::TextureMode_Clamp); vg->fillQuad( 0,0 , pattern->width()*3.0f,pattern->height()*3.0f ); // textured quad #3 stretch texturing vg->translate(100,0); vg->setImage(spectrum2.get()); vg->setTextureMode(vl::TextureMode_Clamp); vg->fillQuad( 0,0 , pattern->width()*3.0f,pattern->height()*3.0f ); vg->popMatrix(); // ###### line rendering ###### vg->setImage(NULL); vg->setLineWidth(1.0f); vg->setColor(vl::black); vg->resetMatrix(); vg->translate(10,250); vg->setLineStipple(vl::LineStipple_Dash); vg->drawLine(0,0, 200,0); vg->translate(0,10); vg->setLineStipple(vl::LineStipple_Dash4); vg->drawLine(0,0, 200,0); vg->translate(0,10); vg->setLineStipple(vl::LineStipple_Dash8); vg->drawLine(0,0, 200,0); vg->translate(0,10); vg->setLineStipple(vl::LineStipple_DashDot); vg->drawLine(0,0, 200,0); vg->translate(0,10); vg->setLineStipple(vl::LineStipple_DashDotDot); vg->drawLine(0,0, 200,0); vg->translate(0,10); vg->setLineStipple(vl::LineStipple_Dot); vg->drawLine(0,0, 200,0); vg->translate(0,10); vg->setLineStipple(vl::LineStipple_Solid); vg->drawLine(0,0, 200,0); vg->resetMatrix(); vg->translate(10,350); for(int x=0; x<=100; x+=4) vg->drawLine(x,0,x,100); for(int y=0; y<=100; y+=4) vg->drawLine(0,y,100,y); // ###### textured point rendering + scissor ###### // with the Scissor we can clip the rendering against a specific rectangular area int scissor_w = 200; int scissor_h = 200; vg->setScissor(256-scissor_w/2,256+128-scissor_h/2,scissor_w,scissor_h); vg->setColor(vl::fvec4(1,1,1,0.5f)); // transparent white vg->setPoint(circle16_bg.get()); // the same as setImage(image) + setPointSize(image->width()) vg->resetMatrix(); vg->translate(256,256+128); // generate the points std::vector<vl::dvec2> points; for(int i=0; i<1000; ++i) { points.push_back(vl::dvec2(rand()%128-64,rand()%128-64)); points[i].normalize(); points[i] *= (rand()%1280) / 10.0f; // snap to integer coordinates to avoid aliasing problems points[i] = vl::trunc(points[i]); } // draw the points vg->drawPoints(points); vg->setPoint(circle16_yr.get()); // the same as setImage(image) + setPointSize(image->width()) points.clear(); for(int i=0; i<200; ++i) { points.push_back(vl::dvec2(rand()%128-64,rand()%128-64)); points[i].normalize(); points[i] *= (rand()%1280) / 10.0f; // snap to integer coordinates to avoid aliasing problems points[i] = vl::trunc(points[i]); } // draw the points vg->drawPoints(points); vg->removeScissor(); // ###### rounded point rendering ###### vg->setImage(NULL); vg->setPointSize(7); vg->setPointSmoothing(true); /* default value */ vg->setColor(vl::crimson); vg->translate(196,64); points.clear(); for(int i=0; i<100; ++i) { points.push_back(vl::dvec2(rand()%128-64,rand()%128-64)); points[i].normalize(); points[i] *= (rand()%640) / 10.0f; // snap to integer coordinates to avoid aliasing problems points[i] = vl::trunc(points[i]); } vg->drawPoints(points); // ###### squared point rendering ###### vg->setImage(NULL); vg->setPointSize(5); vg->setPointSmoothing(false); vg->setColor(vl::green); vg->translate(0,-128); points.clear(); for(int i=0; i<100; ++i) { points.push_back(vl::dvec2(rand()%128-64,rand()%128-64)); points[i].normalize(); points[i] *= (rand()%640) / 10.0f; // snap to integer coordinates to avoid aliasing problems points[i] = vl::trunc(points[i]); } vg->drawPoints(points); // ###### stencil buffer rendering ###### // reset states vg->resetMatrix(); vg->setColor(vl::white); vg->setImage(NULL); // clear the stencil buffer vg->clearStencil(0); // enable stencil test vg->setStencilTestEnabled(true); // setup stencil test: writes 0x01 on the stencil buffer when rendering polygons, lines etc. vg->setStencilFunc(vl::FU_NOTEQUAL, 0x01, 0x01); vg->setStencilOp(vl::SO_REPLACE, vl::SO_REPLACE, vl::SO_REPLACE); // ###### render the rose on the stencil buffer ###### // rose create and bind transform mRoseTransform = new vl::Transform; rendering()->as<vl::Rendering>()->transform()->addChild(mRoseTransform.get()); // draw our rotating rose as a set of 4 filled ellipses and bind them to mRoseTransform vg->fillEllipse(0,0 , 150,25)->setTransform(mRoseTransform.get()); vg->pushMatrix(); vg->rotate(45); vg->fillEllipse(0,0 , 150,25)->setTransform(mRoseTransform.get()); vg->rotate(45); vg->fillEllipse(0,0 , 150,25)->setTransform(mRoseTransform.get()); vg->rotate(45); vg->fillEllipse(0,0 , 150,25)->setTransform(mRoseTransform.get()); vg->popMatrix(); // ###### fill the rose with color ###### // setup stencil test: renders only where the stencil buffer is set to 0x01 vg->setStencilFunc(vl::FU_EQUAL, 0x01, 0x01); vg->setStencilOp(vl::SO_KEEP, vl::SO_KEEP, vl::SO_KEEP); // make sure our matrix is clean vg->resetMatrix(); // render random blue ellipses vg->setColor(vl::blue); for(int i=0; i<400; ++i) vg->drawEllipse(rand()%512,rand()%512 , rand()%20+10,rand()%20+10); // renders concentric red circles vg->setColor(vl::red); for(int i=0; i<256/4; ++i) vg->drawEllipse(256,256 , i*8,i*8); // finish with the stencil vg->setStencilTestEnabled(false); // render text following our rotating rose vg->setFont("/font/bitstream-vera/Vera.ttf", 14, false); vg->setColor(vl::black); // note that the 2D text is not transformed by mRoseTransform but just follows an idea point transformed by mRoseTransform. vg->drawText("Stencil buffer in action here!", vl::AlignHCenter|vl::AlignVCenter)->setTransform(mRoseTransform.get()); // ###### draws a rotated text ###### vg->setColor(vl::black); vg->setFont("/font/bitstream-vera/VeraMono.ttf", 14, true); vg->pushMatrix(); vg->rotate(45); vg->drawText(256, 256, "Rotated Text", vl::AlignHCenter|vl::AlignVCenter); vg->popMatrix(); // ###### transparent star image ###### vg->pushState(); vg->setColor(vl::fvec4(1,1,1,0.75f)); // transparent white vg->setImage(star.get()); vg->translate(-star->width()/2,-star->height()/2); // center the quad vl::Actor* rota_star = vg->fillQuad(0,0,star->width(),star->height()); mStarTransform = new vl::Transform; rota_star->setTransform( mStarTransform.get() ); rendering()->as<vl::Rendering>()->transform()->addChild( mStarTransform.get() ); vg->popState(); // ###### how to instance multiple times the same object ###### // generate 5 corner star: line loop primitive std::vector<vl::dvec2> star_line_loop; for(int i=0; i<5; ++i) { vl::dvec3 v = vl::dmat4::getRotation(90.0+i*360.0/5.0*2.0 , 0,0,1) * vl::dvec3(50.0,0,0); // snap to integer coordinates to avoid aliasing v = vl::trunc(v); star_line_loop.push_back(v.xy()); } // ###### generate 5 corner star: lines primitive ###### std::vector<vl::dvec2> star_lines; for(int i=0; i<5; ++i) { vl::dvec3 v1 = vl::dmat4::getRotation(90.0+i*360.0/5.0*2.0 , 0,0,1) * vl::dvec3(50.0,0,0); vl::dvec3 v2 = vl::dmat4::getRotation(90.0+((i+1)%5)*360.0/5.0*2.0 , 0,0,1) * vl::dvec3(50.0,0,0); // snap to integer coordinates to avoid aliasing v1 = vl::trunc(v1); v2 = vl::trunc(v2); star_lines.push_back(v1.xy()); star_lines.push_back(v2.xy()); } // star1 vg->setLineWidth(4.0f); vg->setColor(vl::gold); vl::Actor* star1 = vg->drawLineLoop(star_line_loop); // star2 - recycle the geometry from star1 vg->setLineWidth(2.0f); vg->setColor(vl::red); vl::Actor* star2 = vg->drawActorCopy(star1); // star3 - recycle the geometry from star1 vg->setLineWidth(1.0f); vg->setLineStipple(vl::LineStipple_DashDotDot); vl::Actor* star3 = vg->drawActorCopy(star1); // star4 - texturing #1 vg->setColor(vl::white); // make sure color is white so that the texture color is not filtered vg->setImage(spectrum1.get()); vg->setLineWidth(2.0f); vg->setLineStipple(vl::LineStipple_Solid); // Here we call drawLineLoop() because we need to create a new geometry instance // so that VL can generate appropriate UV texture coordinates that are dependent // on the currently active Image. vl::Actor* star4 = vg->drawLineLoop(star_line_loop); // star5 - texturing #2 // Here we draw the star using drawLines() instead or drawLineLoop(). // Note how drawLines() and drawLineLoop() generate different texturing effects. vl::Actor* star5 = vg->drawLines(star_lines); // render the 4 instances in 4 different points star1->setTransform( new vl::Transform ); star2->setTransform( new vl::Transform ); star3->setTransform( new vl::Transform ); star4->setTransform( new vl::Transform ); star5->setTransform( new vl::Transform ); star1->transform()->setLocalMatrix( vl::mat4::getTranslation(50,50,0) ); star2->transform()->setLocalMatrix( vl::mat4::getTranslation(150,50,0) ); star3->transform()->setLocalMatrix( vl::mat4::getTranslation(250,50,0) ); star4->transform()->setLocalMatrix( vl::mat4::getTranslation(350,50,0) ); star5->transform()->setLocalMatrix( vl::mat4::getTranslation(450,50,0) ); // Since they are not animated we can setup the matrices without binding it to the Rendering's root Transform star1->transform()->computeWorldMatrix(); star2->transform()->computeWorldMatrix(); star3->transform()->computeWorldMatrix(); star4->transform()->computeWorldMatrix(); star5->transform()->computeWorldMatrix(); vg->endDrawing(); }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); // setup scene gua::SceneGraph graph("main_scenegraph"); gua::math::vec4 iron(0.560, 0.570, 0.580, 1); gua::math::vec4 silver(0.972, 0.960, 0.915, 1); gua::math::vec4 aluminium(0.913, 0.921, 0.925, 1); gua::math::vec4 gold(1.000, 0.766, 0.336, 1); gua::math::vec4 copper(0.955, 0.637, 0.538, 1); gua::math::vec4 chromium(0.550, 0.556, 0.554, 1); gua::math::vec4 nickel(0.660, 0.609, 0.526, 1); gua::math::vec4 titanium(0.542, 0.497, 0.449, 1); gua::math::vec4 cobalt(0.662, 0.655, 0.634, 1); gua::math::vec4 platinum(0.672, 0.637, 0.585, 1); auto pbrMat(gua::MaterialShaderDatabase::instance() ->lookup("gua_default_material") ->make_new_material()); // pbrMat.set_uniform("Color", chromium); // pbrMat.set_uniform("Roughness", 0.2f); // pbrMat.set_uniform("Metalness", 1.0f); std::string directory("/opt/3d_models/Cerberus_by_Andrew_Maximov/Textures/"); pbrMat->set_uniform("ColorMap", directory + "Cerberus_A.tga"); pbrMat->set_uniform("MetalnessMap", directory + "Cerberus_M.tga"); pbrMat->set_uniform("RoughnessMap", directory + "Cerberus_R.tga"); pbrMat->set_uniform("NormalMap", directory + "Cerberus_N.negated_green.tga"); gua::TriMeshLoader loader; auto transform = graph.add_node<gua::node::TransformNode>("/", "transform"); auto cerberus(loader.create_geometry_from_file( "cerberus", "/opt/3d_models/Cerberus_by_Andrew_Maximov/Cerberus_LP.3ds", pbrMat, gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE)); graph.add_node("/transform", cerberus); cerberus->set_draw_bounding_box(true); cerberus->rotate(90, 0.f, 1.f, 0.f); cerberus->rotate(90, 0.f, 0.f, 1.f); auto pointLight = graph.add_node<gua::node::LightNode>("/", "pointLight"); pointLight->data.set_type(gua::node::LightNode::Type::POINT); pointLight->data.color = gua::utils::Color3f(1.0f, 1.0f, 1.0f); pointLight->data.brightness = 150.0f; // lm pointLight->scale(9.f); pointLight->translate(-2.f, 3.f, 5.f); auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen"); screen->data.set_size(gua::math::vec2(1.92f, 1.08f)); screen->translate(0, 0, 1.0); // add mouse interaction gua::utils::Trackball trackball(0.01, 0.002, 0.2); // setup rendering pipeline and window // auto resolution = gua::math::vec2ui(1920, 1080); auto resolution = gua::math::vec2ui(2560, 1440); std::string skymaps_dir("/opt/guacamole/resources/skymaps/"); for (auto const& file : {std::string(directory + "Cerberus_A.tga"), std::string(directory + "Cerberus_M.tga"), std::string(directory + "Cerberus_R.tga"), std::string(directory + "Cerberus_N.negated_green.tga"), std::string(skymaps_dir + "skymap.jpg")}) { gua::TextureDatabase::instance()->load(file); } auto tiledPipe(std::make_shared<gua::PipelineDescription>()); tiledPipe->add_pass(std::make_shared<gua::TriMeshPassDescription>()); tiledPipe->add_pass(std::make_shared<gua::LightVisibilityPassDescription>()); tiledPipe->add_pass(std::make_shared<gua::ResolvePassDescription>()); auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam"); camera->translate(0, 0, 2.0); camera->config.set_resolution(resolution); camera->config.set_screen_path("/screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("main_window"); camera->config.set_enable_stereo(false); camera->set_pipeline_description(tiledPipe); auto window = std::make_shared<gua::GlfwWindow>(); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_size(resolution); window->config.set_resolution(resolution); window->config.set_stereo_mode(gua::StereoMode::MONO); window->on_resize.connect([&](gua::math::vec2ui const& new_size) { window->config.set_resolution(new_size); camera->config.set_resolution(new_size); screen->data.set_size( gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y)); }); window->on_move_cursor.connect( [&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); }); window->on_button_press.connect( std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); window->open(); gua::Renderer renderer; // application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0 / 500.0); size_t ctr{}; ticker.on_tick.connect([&]() { // apply trackball matrix to object gua::math::mat4 modelmatrix = scm::math::make_translation(gua::math::float_t(trackball.shiftx()), gua::math::float_t(trackball.shifty()), gua::math::float_t(trackball.distance())) * gua::math::mat4(trackball.rotation()); transform->set_transform(modelmatrix); if (ctr++ % 150 == 0) gua::Logger::LOG_WARNING << "Frame time: " << 1000.f / window->get_rendering_fps() << " ms, fps: " << window->get_rendering_fps() << std::endl; window->process_events(); if (window->should_close()) { renderer.stop(); window->close(); loop.stop(); } else { renderer.queue_draw({&graph}); } }); loop.start(); return 0; }
static gboolean motion_notify(GtkWidget *widget, GdkEventMotion *event) { GtkAllocation allocation; GdkModifierType state = 0; int x = 0; int y = 0; float width, height; gboolean redraw = FALSE; mesh_info *info = (mesh_info*)g_object_get_data(G_OBJECT(widget), "mesh_info"); gtk_widget_get_allocation (widget, &allocation); if (event->is_hint) { // fix this! #if !defined(WIN32) gdk_window_get_pointer(event->window, &x, &y, &state); #endif } else { x = event->x; y = event->y; state = event->state; } width = allocation.width; height = allocation.height; if (state & GDK_BUTTON1_MASK) { /* drag in progress, simulate trackball */ trackball( info->dquat, (2.0*info->beginx - width) / width, ( height - 2.0*info->beginy) / height, ( 2.0*x - width) / width, ( height - 2.0*y) / height ); info->dx = x - info->beginx; info->dy = y - info->beginy; /* orientation has changed, redraw mesh */ redraw = TRUE; } if (state & GDK_BUTTON2_MASK) { /* zooming drag */ info->zoom -= ((y - info->beginy) / height) * 40.0; if (info->zoom < 5.0) info->zoom = 5.0; if (info->zoom > 120.0) info->zoom = 120.0; /* zoom has changed, redraw mesh */ redraw = TRUE; } info->beginx = x; info->beginy = y; if (redraw && !info->animate) { gtk_widget_get_allocation (widget, &allocation); gdk_window_invalidate_rect (gtk_widget_get_window (widget), &allocation, FALSE); } return TRUE; }
bool CameraManipulator::calcMovement() { // mouse scroll is only a single event if (_ga_t0.get()==NULL) return false; float dx=0.0f; float dy=0.0f; unsigned int buttonMask=osgGA::GUIEventAdapter::NONE; if (_ga_t0->getEventType()==osgGA::GUIEventAdapter::SCROLL) { switch (_ga_t0->getScrollingMotion()) { case osgGA::GUIEventAdapter::SCROLL_UP: dy = -_zoomDelta; break; case osgGA::GUIEventAdapter::SCROLL_DOWN: dy = _zoomDelta; break; case osgGA::GUIEventAdapter::SCROLL_LEFT: case osgGA::GUIEventAdapter::SCROLL_RIGHT: // pass break; case osgGA::GUIEventAdapter::SCROLL_2D: // normalize scrolling delta dx = _ga_t0->getScrollingDeltaX() / ((_ga_t0->getXmax()-_ga_t0->getXmin()) * 0.5f); dy = _ga_t0->getScrollingDeltaY() / ((_ga_t0->getYmax()-_ga_t0->getYmin()) * 0.5f); dx *= _zoomDelta; dy *= _zoomDelta; break; default: break; } buttonMask=osgGA::GUIEventAdapter::SCROLL; } else { if (_ga_t1.get()==NULL) return false; dx = _ga_t0->getXnormalized()-_ga_t1->getXnormalized(); dy = _ga_t0->getYnormalized()-_ga_t1->getYnormalized(); float distance = sqrtf(dx*dx + dy*dy); // return if movement is too fast, indicating an error in event values or change in screen. if (distance>0.5) { return false; } // return if there is no movement. if (distance==0.0f) { return false; } buttonMask = _ga_t1->getButtonMask(); } double throwScale = (_thrown && _ga_t0.valid() && _ga_t1.valid()) ? _delta_frame_time / (_ga_t0->getTime() - _ga_t1->getTime()) : 1.0; if (buttonMask==osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) { // rotate camera. osg::Vec3 axis; float angle; float px0 = _ga_t0->getXnormalized(); float py0 = _ga_t0->getYnormalized(); float px1 = _ga_t1->getXnormalized(); float py1 = _ga_t1->getYnormalized(); trackball(axis,angle,px1,py1,px0,py0); osg::Quat new_rotate; new_rotate.makeRotate(angle * throwScale,axis); _rotation = _rotation*new_rotate; return true; } else if (buttonMask==(osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON|osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON)) { // pan model. float scale = -0.3f * _distance * throwScale; osg::Matrix rotation_matrix; rotation_matrix.makeRotate(_rotation); osg::Vec3 dv(dx*scale,dy*scale,0.0f); _center += dv*rotation_matrix; return true; } else if (buttonMask==osgGA::GUIEventAdapter::SCROLL) { // zoom model. float fd = _distance; float scale = 1.0f+ dy * throwScale; if (fd*scale>_modelScale*_minimumZoomScale) { if (_distance * scale < 10000) _distance *= scale; } return true; } return false; }
void tbInit(GLuint button) { tb_button = button; trackball(curquat, 0.0, 0.0, 0.0, 0.0); }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); // setup scene gua::SceneGraph graph("main_scenegraph"); gua::TriMeshLoader loader; auto transform = graph.add_node<gua::node::TransformNode>("/", "transform"); auto cube(loader.create_geometry_from_file( "cube", "data/objects/cube.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE | gua::TriMeshLoader::MAKE_PICKABLE) ); graph.add_node("/transform", cube); scm::math::vec3d cube_translation(0.0, 0.0, -3.0); cube->set_draw_bounding_box(true); auto ray_geometry(loader.create_geometry_from_file( "ray_geometry", "data/objects/cylinder.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE) ); graph.add_node("/", ray_geometry); ray_geometry->scale(0.02, 0.02, 0.1); auto light2 = graph.add_node<gua::node::LightNode>("/", "light2"); light2->data.set_type(gua::node::LightNode::Type::POINT); light2->data.brightness = 150.0f; light2->scale(12.f); light2->translate(-3.f, 5.f, 5.f); auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen"); screen->data.set_size(gua::math::vec2(1.92f, 1.08f)); screen->translate(0, 0, 1.0); // add mouse interaction gua::utils::Trackball trackball(0.01, 0.002, 0.2); // setup rendering pipeline and window auto resolution = gua::math::vec2ui(1920, 1080); auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam"); camera->translate(0, 0, 2.0); camera->config.set_resolution(resolution); camera->config.set_screen_path("/screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("Picking Example"); camera->config.set_enable_stereo(false); camera->get_pipeline_description()->get_resolve_pass()->tone_mapping_exposure( 1.0f); camera->get_pipeline_description()->add_pass( std::make_shared<gua::DebugViewPassDescription>()); auto window = std::make_shared<gua::GlfwWindow>(); gua::WindowDatabase::instance()->add("Picking Example", window); window->config.set_enable_vsync(false); window->config.set_size(resolution); window->config.set_resolution(resolution); window->config.set_stereo_mode(gua::StereoMode::MONO); window->on_resize.connect([&](gua::math::vec2ui const& new_size) { window->config.set_resolution(new_size); camera->config.set_resolution(new_size); screen->data.set_size( gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y)); }); window->on_move_cursor.connect( [&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); }); window->on_button_press.connect( std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); gua::Renderer renderer; // application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0 / 500.0); scm::math::vec3d camera_positon(0.0, 0.0, 2.0); scm::math::vec3d negative_z_viewing_direction(0.0, 0.0, -100.0); scm::math::vec3d::value_type t_max(200.0); //create ray that is located in the origin of the current screen and looks along the negative z-axis (pick ray is seen as circle) gua::Ray ray_from_camera_position(camera_positon, negative_z_viewing_direction, t_max); size_t frame_count = 0; ticker.on_tick.connect([&]() { // apply trackball matrix to object gua::math::mat4 modelmatrix = scm::math::make_translation(cube_translation[0], cube_translation[1], cube_translation[2]) * scm::math::make_translation(trackball.shiftx(), trackball.shifty(), trackball.distance()) * gua::math::mat4(trackball.rotation()); transform->set_transform(modelmatrix); if (window->should_close()) { renderer.stop(); window->close(); loop.stop(); } else { //std::set<gua::PickResult> pick_results; //cube->ray_test_impl(ray_from_camera_position, gua::PickResult::Options::PICK_ONLY_FIRST_FACE, gua::Mask(), pick_results); auto pick_results = graph.ray_test(ray_from_camera_position, gua::PickResult::Options::PICK_ONLY_FIRST_FACE | gua::PickResult::Options::GET_WORLD_POSITIONS); if(0 == (++frame_count) % 100) { if(pick_results.size()) { //print first picked face world position result std::cout << "World space intersection position: " << pick_results.begin()->world_position << "\n"; } } renderer.queue_draw({&graph}); } }); loop.start(); return 0; }
/* Reset the trackball to the default unrotated state. */ void gltrackball_reset (trackball_state *ts) { memset (ts, 0, sizeof(*ts)); trackball (ts->q, 0, 0, 0, 0); }
int main(int argc, char** argv) { // initialize guacamole gua::init(argc, argv); auto load_mat = [](std::string const& file){ gua::MaterialShaderDescription desc; desc.load_from_file(file); auto shader(std::make_shared<gua::MaterialShader>(file, std::make_shared<gua::MaterialShaderDescription>(desc))); gua::MaterialShaderDatabase::instance()->add(shader); return shader->make_new_material(); }; // setup scene gua::SceneGraph graph("main_scenegraph"); gua::TriMeshLoader loader; auto transform = graph.add_node<gua::node::TransformNode>("/", "transform"); // load material and create monkey geometry auto projective_material(load_mat("data/materials/Projective_Texture_Material.gmd")); projective_material->set_uniform("projective_texture", std::string("data/textures/smiley.jpg")); auto monkey(loader.create_geometry_from_file("monkey", "data/objects/monkey.obj", projective_material, gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::NORMALIZE_SCALE)); monkey->scale(3); monkey->translate(0.0, 0.0, -1.0); graph.add_node("/transform", monkey); auto light2 = graph.add_node<gua::node::LightNode>("/", "light2"); light2->data.set_type(gua::node::LightNode::Type::POINT); light2->data.brightness = 150.0f; light2->scale(12.f); light2->translate(-3.f, 5.f, 5.f); auto screen = graph.add_node<gua::node::ScreenNode>("/", "screen"); screen->data.set_size(gua::math::vec2(1.92f, 1.08f)); screen->translate(0, 0, 1.0); // add mouse interaction gua::utils::Trackball trackball(0.01, 0.002, 0.2); // setup rendering pipeline and window auto resolution = gua::math::vec2ui(1920, 1080); auto camera = graph.add_node<gua::node::CameraNode>("/screen", "cam"); camera->translate(0, 0, 2.0); camera->config.set_resolution(resolution); camera->config.set_screen_path("/screen"); camera->config.set_scene_graph_name("main_scenegraph"); camera->config.set_output_window_name("main_window"); camera->config.set_enable_stereo(false); camera->get_pipeline_description()->add_pass(std::make_shared<gua::DebugViewPassDescription>()); // projector transform node, screen and transform node auto projector_transform = graph.add_node<gua::node::TransformNode>("/", "projector_transform"); projector_transform->translate(0.7, 0.0, 0.7); projector_transform->rotate(45.0, 0.0, 1.0, 0.0); graph.add_node("/", projector_transform); auto projector_screen = graph.add_node<gua::node::ScreenNode>("/projector_transform", "projector_screen"); projector_screen->data.set_size(gua::math::vec2(0.5f, 0.5f)); projector_screen->translate(0.0, 0.0, -1.0); graph.add_node("/projector_transform", projector_screen); auto projector_geometry(loader.create_geometry_from_file("projector_geometry", "data/objects/projector.obj", gua::TriMeshLoader::NORMALIZE_POSITION | gua::TriMeshLoader::LOAD_MATERIALS)); projector_geometry->scale(0.1); graph.add_node("/projector_transform", projector_geometry); auto window = std::make_shared<gua::GlfwWindow>(); gua::WindowDatabase::instance()->add("main_window", window); window->config.set_enable_vsync(false); window->config.set_size(resolution); window->config.set_resolution(resolution); window->config.set_stereo_mode(gua::StereoMode::MONO); window->on_resize.connect([&](gua::math::vec2ui const& new_size) { window->config.set_resolution(new_size); camera->config.set_resolution(new_size); screen->data.set_size(gua::math::vec2(0.001 * new_size.x, 0.001 * new_size.y)); }); window->on_move_cursor.connect([&](gua::math::vec2 const& pos) { trackball.motion(pos.x, pos.y); }); window->on_button_press.connect(std::bind(mouse_button, std::ref(trackball), std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); window->open(); gua::Renderer renderer; // application loop gua::events::MainLoop loop; gua::events::Ticker ticker(loop, 1.0/500.0); ticker.on_tick.connect([&]() { // apply trackball matrix to object gua::math::mat4 modelmatrix = scm::math::make_translation(gua::math::float_t(trackball.shiftx()), gua::math::float_t(trackball.shifty()), gua::math::float_t(trackball.distance())) * gua::math::mat4(trackball.rotation()); projector_transform->set_transform(modelmatrix); // use the guacamole frustum to calculate a view mat and projection mat for the projection auto projection_frustum = gua::Frustum::perspective(projector_transform->get_world_transform(), projector_screen->get_scaled_world_transform(), 0.1f, 1000.0f); auto projection_mat = projection_frustum.get_projection(); auto view_mat = projection_frustum.get_view(); // set these matrices as uniforms for the projection material projective_material->set_uniform("projective_texture_matrix", gua::math::mat4f(projection_mat * view_mat)); projective_material->set_uniform("view_texture_matrix", gua::math::mat4f(view_mat)); window->process_events(); if (window->should_close()) { renderer.stop(); window->close(); loop.stop(); } else { renderer.queue_draw({&graph}); } }); loop.start(); return 0; }