ofxBullet + second window disables object grabbing

Hello - I am just getting started with OF and C++ (migrating from Processing). I am not new to programming. I am using ofxBullet (and in this example ofxGui). As soon as I instantiate a second window, enableGrabbing() stops working. As far as I can tell, everything else in the physics works fine.

main.cpp

#include "ofMain.h"
#include "ofApp.h"
#include "GuiApp.h"
#include "ofAppGLFWWindow.h"

//========================================================================
int main( ){
	ofGLFWWindowSettings settings;

	settings.setSize(1920, 1080);
	settings.setPosition(glm::vec2(1920, 0));
	settings.resizable = true;
	shared_ptr<ofAppBaseWindow> mainWindow = ofCreateWindow(settings);


	settings.setSize(300, 300);
	settings.setPosition(glm::vec2(0, 0));
	settings.resizable = true;
	shared_ptr<ofAppBaseWindow> guiWindow = ofCreateWindow(settings);


	shared_ptr<GuiApp> guiApp(new GuiApp);
	shared_ptr<ofApp> mainApp(new ofApp);
	mainApp->gui = guiApp;


	ofRunApp(guiWindow, guiApp);
	ofRunApp(mainWindow, mainApp);
	ofRunMainLoop();

}

ofApp.h

#pragma once

#include "ofMain.h"
#include "ofxBullet.h"
#include "GuiApp.h"

class ofApp : public ofBaseApp{

	public:
		void setup();
		void update();
		void draw();

		void keyPressed(int key);
		void keyReleased(int key);
		void mouseMoved(int x, int y );
		void mouseDragged(int x, int y, int button);
		void mousePressed(int x, int y, int button);
		void mouseReleased(int x, int y, int button);
		void mouseEntered(int x, int y);
		void mouseExited(int x, int y);
		void windowResized(int w, int h);
		void dragEvent(ofDragInfo dragInfo);
		void gotMessage(ofMessage msg);

		ofxBulletWorldRigid			world;
		ofxBulletBox				ground;

		ofxBulletSphere*			sphere;

		ofCamera					camera;

		shared_ptr<GuiApp>			gui;
		
};

ofApp.cpp

#include "ofApp.h"

//--------------------------------------------------------------
void ofApp::setup(){

	ofSetFrameRate(60);
	ofSetVerticalSync(true);

	ofBackground(0);

	camera.setPosition(ofVec3f(0.f, -40.f, -60.f));
	camera.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, -1, 0));

	world.setup();
	world.enableGrabbing();

	world.setCamera(&camera);
	world.setGravity(glm::uvec3(0., 60., 0.));

	ground.create(world.world, ofVec3f(0., 0., 0.), 0., 100.f, 1.f, 100.f);
	ground.setProperties(.25, .95);
	ground.add();

	sphere = new ofxBulletSphere();
	sphere->create(world.world, ofVec3f(0, -30, 0), 1., 2.5);
	sphere->add();

}

//--------------------------------------------------------------
void ofApp::update(){

	world.update();
	ofSetWindowTitle(ofToString(ofGetFrameRate(), 0));

}

//--------------------------------------------------------------
void ofApp::draw(){

	ofEnableDepthTest();
	camera.begin();
	
	ofSetColor(150);
	ground.draw();

	ofSetColor(0, 225, 0);
	sphere->draw();

	camera.end();

}

GuiApp.h

#pragma once

#include "ofMain.h"
#include "ofxGui.h"

class GuiApp : public ofBaseApp
{
public:
	void setup();
	void update();
	void draw();

	ofxPanel gui;

};

GuiApp.cpp

#include "GuiApp.h"

void GuiApp::setup() {

	ofBackground(0);
	ofSetVerticalSync(false);
}

void GuiApp::update() {

}

void GuiApp::draw() {

	ofSetColor(255);
	stringstream ss;
	ss << "framerate: " << ofToString(ofGetFrameRate(), 0) << endl;
	ofDrawBitmapString(ss.str().c_str(), 20, 20);

	gui.draw();
}
1 Like

Hey @rgthings I’m still hoping that someone with more knowledge about ofxBullet will reply with some helpful thoughts.

But I did play around with it a bit today. Maybe try reversing the order in which the windows are created. I think this might have something to do with how the mouse works and which window the mouse ends up interacting with. There might be a better way to do this with setting a focus, or some of the other GLFWWindowSettings variables.

I modified /ofxBullet/SimpleExample with the following main.cpp, and added your GuiApp class and files. Here is my main.cpp:

int main( ){
    ofGLFWWindowSettings settings;

    // make guiWindow first
    settings.setSize(300, 300);
    settings.setPosition(glm::vec2(30, 30));
    settings.resizable = true;
    shared_ptr<ofAppBaseWindow> guiWindow = ofCreateWindow(settings);

    // the make a window for ofApp
    settings.setSize(1920, 1080);
    settings.setPosition(glm::vec2(0, 0));
    settings.resizable = true;
    shared_ptr<ofAppBaseWindow> mainWindow = ofCreateWindow(settings);

    // keep the order the same for the rest of main.cpp, just in case it matters
    shared_ptr<GuiApp> guiApp(new GuiApp);
    shared_ptr<ofApp> mainApp(new ofApp);
    mainApp->gui = guiApp;

    ofRunApp(guiWindow, guiApp);
    ofRunApp(mainWindow, mainApp);
    ofRunMainLoop();
}

Edit:
This thread might be relevant:

But I’m not sure how to make a GLFWwindow* from a shared_ptr<ofAppBaseWindow> in order to call glfwFocusWindow() with it.

1 Like

Well TimChi, I made the changes to main.cpp that you suggested and it worked! I am going to follow up with the thread you cited as well when I get some more time so again, I say thank you. I also added some parameter controls to the second window and they do respond to the mouse so it would seem that all is well once again.

After more goofing around, this should make a GLFWwindow*:

    auto window = ((ofAppGLFWWindow*)ofGetAppPtr())->getGLFWWindow();

But using it with glfwFocusWindow() segfaults. Ugh.

This thread might be helpful too:

There might be some more threads lurking the forum about setting the window focus. You could also start a new one again if can’t find something that works.

1 Like

Hi @rgthings,
The mouse picking was tied to ofEvents(), which is tied to the first window created. So when you swapped the order of window creation as @TimChi suggested; makes sense that it worked. :slight_smile: I pushed up some changes to ofxBullet to allow for different window events ( so that you don’t have to worry about what order you created them ).
For the code example in your first post; ofApp is tied to the window via ofRunnApp( mainWindow, mainApp ); So you can query the active window ( returning mainWindow ) and then set the events in ofApp::setup().
If you update ofxBullet from git, you should now be able to do the following in ofApp::setup:

//--------------------------------------------------------------
void ofApp::setup(){
	
	ofSetFrameRate(60);
	ofSetVerticalSync(true);
	
	ofBackground(0);
	
	camera.setPosition(ofVec3f(0.f, -40.f, -60.f));
	camera.lookAt(ofVec3f(0, 0, 0), ofVec3f(0, -1, 0));
	
	world.setup();
	world.enableGrabbing();
	
	world.setCamera(&camera);
	world.setGravity(glm::uvec3(0., 60., 0.));
	
	ground.create(world.world, ofVec3f(0., 0., 0.), 0., 100.f, 1.f, 100.f);
	ground.setProperties(.25, .95);
	ground.add();
	
	sphere = new ofxBulletSphere();
	sphere->create(world.world, ofVec3f(0, -30, 0), 1., 2.5);
	sphere->add();
	// added the setEvents function 
	auto currentWindow = ofGetCurrentWindow();
	world.setEvents(currentWindow->events());
	
}
2 Likes

thank you Nick - tried it and it works.

1 Like