void init(){
	char inp_delims[] = "|"; //for delimiting multiple inputs
	char const * lTheOpenFileName;
		
	lTheOpenFileName = tinyfd_openFileDialog ( "Select Files to Alter",	NULL,	0, NULL, NULL, 1);
	if(lTheOpenFileName == NULL) exit(0);
	
	list_attribs LA;
	list_attribs* p_LA = &LA;
	
    std::vector<std::string> multi_file_vec;
    multi_file_vec.clear();
    p_LA->file_paths.clear();
	
    token_arr aggr_file_names_token = token_arr_init(lTheOpenFileName, inp_delims);
	
    while(*next_token( &aggr_file_names_token )){
    	p_LA->file_paths.push_back(aggr_file_names_token.output);
    }
	
	free_token_arr( &aggr_file_names_token );
	
	std::stack<Operation> undo_stack;
	std::stack<Operation> redo_stack;
	
	Dynamic_File_List DFL;
	Dynamic_File_List* p_DFL = &DFL;
	
	list_setup(p_DFL, p_LA, &undo_stack, &redo_stack);	
}
Esempio n. 2
0
	std::wstring* FileDialog::OpenFile (std::wstring* title, std::wstring* filter, std::wstring* defaultPath) {

		#ifdef HX_WINDOWS

		std::wstring temp (L"*.");
		const wchar_t* filters[] = { filter ? (temp + *filter).c_str () : NULL };

		const wchar_t* path = tinyfd_openFileDialogW (title ? title->c_str () : 0, defaultPath ? defaultPath->c_str () : 0, filter ? 1 : 0, filter ? filters : NULL, NULL, 0);

		if (path) {

			std::wstring* _path = new std::wstring (path);
			return _path;

		}

		#else

		std::string* _title = wstring_to_string (title);
		std::string* _filter = wstring_to_string (filter);
		std::string* _defaultPath = wstring_to_string (defaultPath);

		const char* filters[] = { NULL };

		if (_filter) {

			_filter->insert (0, "*.");
			filters[0] = _filter->c_str ();

		}

		const char* path = tinyfd_openFileDialog (_title ? _title->c_str () : NULL, _defaultPath ? _defaultPath->c_str () : NULL, _filter ? 1 : 0, _filter ? filters : NULL, NULL, 0);

		if (_title) delete _title;
		if (_filter) delete _filter;
		if (_defaultPath) delete _defaultPath;

		if (path) {

			std::string _path = std::string (path);
			std::wstring* __path = new std::wstring (_path.begin (), _path.end ());
			return __path;

		}

		#endif

		return 0;

	}
Esempio n. 3
0
  std::tuple<std::vector<std::string>, Window::DialogStatus, std::string> WindowManager::openDialogSync(
      Window::DialogMode mode,
      const std::string& title,
      const std::string& defaultFilePath,
      const std::vector<std::string> filters
  )
  {
    std::vector<std::string> paths;
    Window::DialogStatus status;
    const char* outPath = NULL;

    const char* f[256];
    for(int i = 0; i < filters.size(); i++) {
      f[i] = filters[i].c_str();
    }

    switch(mode) {
      case Window::DialogMode::FILE_DIALOG_OPEN_MULTIPLE:
      case Window::DialogMode::FILE_DIALOG_OPEN:
        outPath = tinyfd_openFileDialog(&title[0], &defaultFilePath[0], filters.size(), &f[0], NULL, mode == Window::DialogMode::FILE_DIALOG_OPEN_MULTIPLE);
        break;
      case Window::DialogMode::FILE_DIALOG_OPEN_FOLDER:
        outPath = tinyfd_selectFolderDialog(&title[0], &defaultFilePath[0]);
        break;
      case Window::DialogMode::FILE_DIALOG_SAVE:
        outPath = tinyfd_saveFileDialog(&title[0], &defaultFilePath[0], filters.size(), &f[0], NULL);
        break;
    }

    std::stringstream err;

    if(outPath == NULL) {
      return std::make_tuple(paths, Window::DialogStatus::CANCEL, "");
    }

    paths = split(std::string(outPath), '|');
    return std::make_tuple(paths, Window::DialogStatus::OKAY, "");
  }
Esempio n. 4
0
void CAppWindow::AskOpenInput()
{
    const char *filters[] = { "*.txt" };
    char const *result = tinyfd_openFileDialog("Select input file", "", 1, filters, "", false);
    // Пользователь отменил выбор файла.
    if (result == nullptr)
    {
        return;
    }
    m_graph = std::make_unique<CBoostGraph>();
    m_graph->SetStepHandler(std::bind(&CAppWindow::OnGraphAlgorithmStep, this, std::placeholders::_1));

    std::ifstream in(result);
    if (!in.is_open() || !m_graph->ReadText(in))
    {
        m_graph.reset();
        tinyfd_messageBox("Error", "I/O error when reading input file", "ok", "error", 1);
    }
    else
    {
        RunAlgorithmDemo();
    }
}
Esempio n. 5
0
void FileDialog_import(EditorState *state)
{
	std::string path = getSaveLoadDirectory(state->settings->get("save_directory"),
			state->isInstalled);

	const char* filters[] = {"*.nbe"};
	const char *cfile = tinyfd_openFileDialog("Import Nodes",
			path.c_str(), 1, filters, 0);

	if (!cfile)
		return;

	std::string file = cfile;

	if (file == "")
		return;


	std::cerr << file.c_str() << std::endl;

	// Get file parser
	FileFormat *parser = getFromType(FILE_FORMAT_NBE, state);
	if (!parser) {
		state->device->getGUIEnvironment()->addMessageBox(L"Unable to open",
		L"File format does not exist.");
		return;
	}

	// Get directory, and load
	std::cerr << "Reading from " << file << std::endl;
	Project *tmp = parser->read(file, state->project);
	if (tmp) {
		state->project->remesh();
	} else {
		switch(parser->error_code) {
		case EFFE_IO_ERROR:
			state->device->getGUIEnvironment()->addMessageBox(L"Unable to open",
					L"Failed to open the file\n\t(Does it not exist, or is it readonly?)");
			break;
		case EFFE_READ_OLD_VERSION:
			state->device->getGUIEnvironment()->addMessageBox(L"Unable to open",
				L"This file is outdated and is not supported");
			break;
		case EFFE_READ_NEW_VERSION:
			state->device->getGUIEnvironment()->addMessageBox(L"Unable to open",
				L"This file was created with a new version of NBE\n\t(Update your copy)");
			break;
		case EFFE_READ_PARSE_ERROR:
			state->device->getGUIEnvironment()->addMessageBox(L"Unable to open",
				L"An error occurred while reading the file - it may be corrupted\n\t(This should never happen)");
			break;
		case EFFE_READ_WRONG_TYPE:
			state->device->getGUIEnvironment()->addMessageBox(L"Unable to open",
				L"The file is not in the correct format\n\t(Are you opening the wrong type of file?)");
			break;
		default:
			state->device->getGUIEnvironment()->addMessageBox(L"Unable to open",
				L"Unknown error");
			break;
		}
		delete parser;
		parser = NULL;
	}
}
Esempio n. 6
0
	void FileDialog::OpenFiles (std::vector<std::wstring*>* files, std::wstring* title, std::wstring* filter, std::wstring* defaultPath) {

		std::wstring* __paths = 0;

		#ifdef HX_WINDOWS

		std::wstring temp (L"*.");
		const wchar_t* filters[] = { filter ? (temp + *filter).c_str () : NULL };

		const wchar_t* paths = tinyfd_openFileDialogW (title ? title->c_str () : 0, defaultPath ? defaultPath->c_str () : 0, filter ? 1 : 0, filter ? filters : NULL, NULL, 1);

		if (paths) {

			__paths = new std::wstring (paths);

		}

		#else

		std::string* _title = wstring_to_string (title);
		std::string* _filter = wstring_to_string (filter);
		std::string* _defaultPath = wstring_to_string (defaultPath);

		const char* filters[] = { NULL };

		if (_filter) {

			_filter->insert (0, "*.");
			filters[0] = _filter->c_str ();

		}

		const char* paths = tinyfd_openFileDialog (_title ? _title->c_str () : NULL, _defaultPath ? _defaultPath->c_str () : NULL, _filter ? 1 : 0, _filter ? filters : NULL, NULL, 1);

		if (_title) delete _title;
		if (_filter) delete _filter;
		if (_defaultPath) delete _defaultPath;

		if (paths) {

			std::string _paths = std::string (paths);
			__paths = new std::wstring (_paths.begin (), _paths.end ());

		}

		#endif

		if (__paths) {

			std::wstring sep = L"|";

			std::size_t start = 0, end = 0;

			while ((end = __paths->find (sep, start)) != std::wstring::npos) {

				files->push_back (new std::wstring (__paths->substr (start, end - start).c_str ()));
				start = end + 1;

			}

			files->push_back (new std::wstring (__paths->substr (start).c_str ()));

		}

	}
Esempio n. 7
0
void MeshViewerWindow::frame(double deltaTime) 
{
	static bool withNormalMap = true;
	static bool withColorMap = true;

	//GUI
	ImGuiWindowFlags flags = 0;
	flags |= ImGuiWindowFlags_NoCollapse;
	flags |= ImGuiWindowFlags_NoMove;
	flags |= ImGuiWindowFlags_NoResize;
	flags |= ImGuiWindowFlags_NoTitleBar;
	flags |= ImGuiWindowFlags_HorizontalScrollbar;
	float infoWidth = 280.0f;
	ImGui::SetNextWindowPos(ImVec2(m_windowWidth - infoWidth - 20.0f, 20.0f), ImGuiSetCond_Always);
	ImGui::SetNextWindowSize(ImVec2(infoWidth, m_windowHeight - 240.0f), ImGuiSetCond_Always);
	if (ImGui::Begin("Options", nullptr, flags))
	{
		ImGui::Text("Options");
		ImGui::Separator(); ImGui::Spacing();
		
		const char * textureFilterPatterns[3] = { "*.png", "*.tga", "*.jpg" };

		//TODO: Load Textures
		const char * normalMapBtnFormat = "Set NormalMap %s";
		const char * colorMapBtnFormat = "Set ColorMap %s";

		ImGui::Checkbox("Toggle Normal Map", &withNormalMap);
		ImGui::Checkbox("Toggle Color Map", &withColorMap);
		ImGui::Spacing();

		for (auto & texturedShape : m_texturedShapes)
		{
			char normalMapBtnText[1024];
			sprintf(normalMapBtnText, normalMapBtnFormat, texturedShape.name.c_str());
			if (ImGui::Button(normalMapBtnText))
			{
				const char * texFilePath = tinyfd_openFileDialog("Set Normal Map", "./", 3, textureFilterPatterns, NULL, 0);
				gtf::Texture2D normalMapResource;
				gtf::Texture2DLoader tex2DLoader;
				if (texFilePath && tex2DLoader.loadFromFile(texFilePath, normalMapResource))
				{
					gtf::RHITextureInfo info;
					gtf::fillRHITextureInfo(normalMapResource, info);
					texturedShape.normalMap.reset(gtf::GRHI->createTexture());
					texturedShape.normalMap->setup(info, normalMapResource.getData());
				}
			}

			char colorMapBtnText[1024];
			sprintf(colorMapBtnText, colorMapBtnFormat, texturedShape.name.c_str());
			if (ImGui::Button(colorMapBtnText))
			{
				const char * texFilePath = tinyfd_openFileDialog("Set Color Map", "./", 3, textureFilterPatterns, NULL, 0);
				gtf::Texture2D colorMapResource;
				gtf::Texture2DLoader tex2DLoader;
				if (texFilePath && tex2DLoader.loadFromFile(texFilePath, colorMapResource))
				{
					gtf::RHITextureInfo info;
					gtf::fillRHITextureInfo(colorMapResource, info);
					texturedShape.colorMap.reset(gtf::GRHI->createTexture());
					texturedShape.colorMap->setup(info, colorMapResource.getData());
				}
			}

			ImGui::Spacing();
		}
	}
	ImGui::End();

	ImGui::SetNextWindowPos(ImVec2(m_windowWidth - infoWidth - 20.0f, m_windowHeight - 200.0f), ImGuiSetCond_Always);
	ImGui::SetNextWindowSize(ImVec2(infoWidth, 180.0f), ImGuiSetCond_Always);
	if (ImGui::Begin("Info", nullptr, flags))
	{
		ImGui::Text("Info");
		ImGui::Separator(); ImGui::Spacing();
		ImGui::Text("Drag and Drop a FBX or OBJ mesh\nfile into this window."); ImGui::Spacing();
		ImGui::Text("Left click and drag to rotate."); ImGui::Spacing();
		ImGui::Text("Right click and drag to translate."); ImGui::Spacing();
		ImGui::Text("Use mouse wheel to scale."); ImGui::Spacing();
	}
	ImGui::End();

	//MESH TRANSFORM WITH MOUSE
	if (!ImGui::GetIO().WantCaptureMouse)
	{
		if (ImGui::IsMouseDown(0))
		{
			m_frame.rotAccelX += ImGui::GetIO().MouseDelta.y * float(deltaTime) * 3.0f;
			m_frame.rotAccelY += ImGui::GetIO().MouseDelta.x * float(deltaTime) * 3.0f;
			
		}
		else if (ImGui::IsMouseDown(1))
		{
			m_frame.viewPosition.x += ImGui::GetIO().MouseDelta.x * 0.025f;
			m_frame.viewPosition.y -= ImGui::GetIO().MouseDelta.y * 0.025f;
		}

		m_frame.rotation.y += m_frame.rotAccelY * float(deltaTime);
		m_frame.rotation.x += m_frame.rotAccelX * float(deltaTime);
		m_frame.rotAccelX -= m_frame.rotAccelX * float(deltaTime) * 3.0f;
		m_frame.rotAccelY -= m_frame.rotAccelY * float(deltaTime) * 3.0f;
        
        m_frame.scale = glm::max(0.01f, m_frame.scale + (ImGui::GetIO().MouseWheel * float(deltaTime) * m_frame.scaleFactor) * 3.0f);
	}
	
	
		
	//update transform
	
	m_modelMatrix = glm::scale(glm::mat4(), glm::vec3(m_frame.scale));
	m_modelMatrix = glm::translate(m_modelMatrix, m_frame.position);
	m_viewMatrix = glm::translate(glm::mat4(), glm::vec3(m_frame.viewPosition.x, m_frame.viewPosition.y, 0.0f));
	m_viewMatrix = glm::translate(m_viewMatrix, glm::vec3(0.0f, 0.0f, m_frame.viewPosition.z));
	m_viewMatrix = glm::rotate(m_viewMatrix, m_frame.rotation.x, glm::vec3(1.0f, 0.0f, 0.0f));
	m_viewMatrix = glm::rotate(m_viewMatrix, m_frame.rotation.y, glm::vec3(0.0f, 1.0f, 0.0f));

	//active shader program
	m_gfx.renderMeshProgram->active();
	m_gfx.renderMeshProgram->setUniform4x4m("uProjectionMatrix", glm::value_ptr(m_projectionMatrix));
	m_gfx.renderMeshProgram->setUniform4x4m("uModelMatrix", glm::value_ptr(m_modelMatrix));
	m_gfx.renderMeshProgram->setUniform4x4m("uViewMatrix", glm::value_ptr(m_viewMatrix));



	//render
	gtf::GRHI->viewport(0, 0, m_windowWidth, m_windowHeight);
	gtf::GRHI->clearColorAndDepthBuffers();
	gtf::GRHI->setDepthTest(true);

	for (auto & texturedShape : m_texturedShapes)
	{
		if (texturedShape.normalMap && withNormalMap)
		{
			texturedShape.normalMap->bindAt(0);
			m_gfx.renderMeshProgram->setUniform1i("uNormalMap", 0);
			m_gfx.renderMeshProgram->setUniform1ui("uWithNormalMap", 1);
		}
		else
		{
			m_gfx.renderMeshProgram->setUniform1ui("uWithNormalMap", 0);
		}

		if (texturedShape.colorMap && withColorMap)
		{
			texturedShape.colorMap->bindAt(1);
			m_gfx.renderMeshProgram->setUniform1i("uColorMap", 1);
			m_gfx.renderMeshProgram->setUniform1ui("uWithColorMap", 1);
		}
		else
		{
			m_gfx.renderMeshProgram->setUniform1ui("uWithColorMap", 0);
		}

		texturedShape.vao->render();
	}
}
Esempio n. 8
0
void canvas_menu(int num)
{
    if (num == 0)
        exit(0);
    else if (num == 1)
        scene.objects.push_back(new boxhdl(1.0, 1.0, 1.0));
    else if (num == 2)
        scene.objects.push_back(new cylinderhdl(1.0, 1.0, 20));
    else if (num == 3)
        scene.objects.push_back(new spherehdl(1.0, 10, 20));
    else if (num == 4)
        scene.objects.push_back(new pyramidhdl(1.0, 1.0, 20));
    else if (num == 5)
    {
        const char* filters[1];
        filters[0] = "*.obj";
        const char *path = tinyfd_openFileDialog("Load a Model", "", 1, filters, 0);
        if (path != NULL && strlen(path) > 0)
            scene.objects.push_back(new modelhdl(path));
    }
    // TODO Assignment 3: uncomment this
    /*else if (num == 6)
    	scene.render_lights = !scene.render_lights;
    else if (num == 7)
    {
    	scene.lights.push_back(new directionalhdl());
    	scene.objects.push_back(new cylinderhdl(0.25, 1.0, 8));
    	for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
    		for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
    		{
    			swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
    			scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
    			swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
    			scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
    		}
    	swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
    	swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);
    	scene.lights.back()->model = scene.objects.back();
    }
    else if (num == 8)
    {
    	scene.lights.push_back(new pointhdl());
    	scene.objects.push_back(new spherehdl(0.25, 4, 8));
    	scene.lights.back()->model = scene.objects.back();
    }
    else if (num == 9)
    {
    	scene.lights.push_back(new spothdl());
    	scene.objects.push_back(new pyramidhdl(0.25, 1.0, 8));
    	for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
    		for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
    		{
    			swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
    			scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
    			swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
    			scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
    		}
    	swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
    	swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);
    	scene.lights.back()->model = scene.objects.back();
    }*/
    else if (num == 10)
        manipulator = manipulate::fovy;
    else if (num == 11)
        manipulator = manipulate::aspect;
    else if (num == 12)
        manipulator = manipulate::width;
    else if (num == 13)
        manipulator = manipulate::height;
    else if (num == 14)
        manipulator = manipulate::front;
    else if (num == 15)
        manipulator = manipulate::back;
    else if (num == 16)
        scene.render_cameras = !scene.render_cameras;
    else if (num == 17 && scene.active_camera_valid())
        scene.cameras[scene.active_camera]->focus = NULL;
    else if (num == 18)
    {
        scene.cameras.push_back(new orthohdl());
        scene.objects.push_back(new pyramidhdl(1.0, 1.0, 8));
        for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
            for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
            {
                swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
                scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
                swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
                scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
            }
        swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
        swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);

        scene.cameras.back()->model = scene.objects.back();
        if (!scene.active_camera_valid())
        {
            scene.active_camera = scene.cameras.size()-1;
            scene.cameras[scene.active_camera]->project(&canvas);
        }
    }
    else if (num == 19)
    {
        scene.cameras.push_back(new frustumhdl());
        scene.objects.push_back(new pyramidhdl(1.0, 1.0, 8));
        for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
            for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
            {
                swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
                scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
                swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
                scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
            }
        swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
        swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);

        scene.cameras.back()->model = scene.objects.back();
        if (!scene.active_camera_valid())
        {
            scene.active_camera = scene.cameras.size()-1;
            scene.cameras[scene.active_camera]->project(&canvas);
        }
    }
    else if (num == 20)
    {
        scene.cameras.push_back(new perspectivehdl());
        scene.objects.push_back(new pyramidhdl(1.0, 1.0, 8));
        for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
            for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
            {
                swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
                scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
                swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
                scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
            }
        swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
        swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);

        scene.cameras.back()->model = scene.objects.back();
        if (!scene.active_camera_valid())
        {
            scene.active_camera = scene.cameras.size()-1;
            scene.cameras[scene.active_camera]->project(&canvas);
        }
    }
    else if (num == 21)
        canvas.polygon_mode = canvashdl::point;
    else if (num == 22)
        canvas.polygon_mode = canvashdl::line;
    else if (num == 23)
        canvas.polygon_mode = canvashdl::fill;
    // TODO Assignment 3: uncomment this
    //else if (num == 25)
    //	canvas.shade_model = canvashdl::flat;
    //else if (num == 26)
    //	canvas.shade_model = canvashdl::smooth;
    else if (num == 28)
        canvas.culling = canvashdl::disable;
    else if (num == 29)
        canvas.culling = canvashdl::backface;
    else if (num == 30)
        canvas.culling = canvashdl::frontface;
    else if (num == 31)
        scene.render_normals = scenehdl::none;
    else if (num == 32)
        scene.render_normals = scenehdl::face;
    else if (num == 33)
        scene.render_normals = scenehdl::vertex;

    glutPostRedisplay();
}
Esempio n. 9
0
void canvas_menu(int num)
{
	if (num == 0)
		exit(0);
	else if (num == 1)
		scene.objects.push_back(new boxhdl(1.0, 1.0, 1.0));
	else if (num == 2)
		scene.objects.push_back(new cylinderhdl(1.0, 1.0, 20));
	else if (num == 3)
		scene.objects.push_back(new spherehdl(1.0, 10, 20));
	else if (num == 4)
		scene.objects.push_back(new pyramidhdl(1.0, 1.0, 20));
	else if (num == 5)
	{
		const char* filters[2];
		filters[0] = "*.obj";
		filters[1] = "*.wrl";
		const char *path = tinyfd_openFileDialog("Load a Model", "", 2, filters, 0);
		if (path != NULL && path[0] != '\0')
		{
			string pathstr = path;
			scene.objects.push_back(new modelhdl(path));
		}
	}
	else if (num == 6)
		scene.render_lights = !scene.render_lights;
	else if (num == 7)
	{
		scene.lights.push_back(new directionalhdl());
		scene.objects.push_back(new cylinderhdl(0.25, 1.0, 8));
		for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
			for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
			{
				swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
				scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
				swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
				scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
			}
		swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
		swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);
		scene.lights.back()->model = scene.objects.back();
	}
	else if (num == 8)
	{
		scene.lights.push_back(new pointhdl());
		scene.objects.push_back(new spherehdl(0.25, 4, 8));
		scene.lights.back()->model = scene.objects.back();
	}
	else if (num == 9)
	{
		scene.lights.push_back(new spothdl());
		scene.objects.push_back(new pyramidhdl(0.25, 1.0, 8));
		for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
			for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
			{
				swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
				scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
				swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
				scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
			}
		swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
		swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);
		scene.lights.back()->model = scene.objects.back();
	}
	else if (num == 10)
		manipulator = manipulate::fovy;
	else if (num == 11)
		manipulator = manipulate::aspect;
	else if (num == 12)
		manipulator = manipulate::width;
	else if (num == 13)
		manipulator = manipulate::height;
	else if (num == 14)
		manipulator = manipulate::front;
	else if (num == 15)
		manipulator = manipulate::back;
	else if (num == 16)
		scene.render_cameras = !scene.render_cameras;
	else if (num == 17 && scene.active_camera_valid())
		scene.cameras[scene.active_camera]->focus = NULL;
	else if (num == 18)
	{
		scene.cameras.push_back(new orthohdl());
		scene.objects.push_back(new pyramidhdl(1.0, 1.0, 8));
		for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
			for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
			{
				swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
				scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
				swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
				scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
			}
		swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
		swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);

		scene.cameras.back()->model = scene.objects.back();
		if (!scene.active_camera_valid())
		{
			scene.active_camera = scene.cameras.size()-1;
			scene.cameras[scene.active_camera]->project();
		}
	}
	else if (num == 19)
	{
		scene.cameras.push_back(new frustumhdl());
		scene.objects.push_back(new pyramidhdl(1.0, 1.0, 8));
		for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
			for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
			{
				swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
				scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
				swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
				scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
			}
		swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
		swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);

		scene.cameras.back()->model = scene.objects.back();
		if (!scene.active_camera_valid())
		{
			scene.active_camera = scene.cameras.size()-1;
			scene.cameras[scene.active_camera]->project();
		}
	}
	else if (num == 20)
	{
		scene.cameras.push_back(new perspectivehdl());
		scene.objects.push_back(new pyramidhdl(1.0, 1.0, 8));
		for (int k = 0; k < scene.objects.back()->rigid.size(); k++)
			for (int i = 0; i < scene.objects.back()->rigid[k].geometry.size(); i++)
			{
				swap(scene.objects.back()->rigid[k].geometry[i][1], scene.objects.back()->rigid[k].geometry[i][2]);
				scene.objects.back()->rigid[k].geometry[i][1] *= -1.0;
				swap(scene.objects.back()->rigid[k].geometry[i][4], scene.objects.back()->rigid[k].geometry[i][5]);
				scene.objects.back()->rigid[k].geometry[i][4] *= -1.0;
			}
		swap(scene.objects.back()->bound[2], scene.objects.back()->bound[4]);
		swap(scene.objects.back()->bound[3], scene.objects.back()->bound[5]);

		scene.cameras.back()->model = scene.objects.back();
		if (!scene.active_camera_valid())
		{
			scene.active_camera = scene.cameras.size()-1;
			scene.cameras[scene.active_camera]->project();
		}
	}
	else if (num == 21)
		glPolygonMode(GL_FRONT_AND_BACK, GL_POINT);
	else if (num == 22)
		glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
	else if (num == 23)
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	else if (num == 28)
		glDisable(GL_CULL_FACE);
	else if (num == 29)
	{
		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);
	}
	else if (num == 30)
	{
		glEnable(GL_CULL_FACE);
		glCullFace(GL_FRONT);
	}
	else if (num == 31)
		scene.render_normals = scenehdl::none;
	else if (num == 32)
		scene.render_normals = scenehdl::face;
	else if (num == 33)
		scene.render_normals = scenehdl::vertex;

	glutPostRedisplay();
}
		static FS::path OpenFileDialog(const char* title, const char* defaultPathAndFile = "", const int numberOfFilterPatterns = 0, const char * const * filterPatterns = nullptr, const bool multiSelect = false)
		{
			const auto path = tinyfd_openFileDialog(title, defaultPathAndFile, numberOfFilterPatterns, filterPatterns, "", multiSelect);
			return path == nullptr ? "" : path;
		}