Change water simulation settings using keyboard?

Home Forums AR Sandbox Forum Change water simulation settings using keyboard?

This topic contains 3 replies, has 2 voices, and was last updated by  elisek 7 months, 3 weeks ago.

Viewing 4 posts - 1 through 4 (of 4 total)
  • Author
    Posts
  • #103185

    liudr
    Participant

    Is there any way to assign keyboard keys to change water simulation settings?

    #103205

    elisek
    Participant

    I cannot be 100% sure but having a look at the code the water simulation settings as controlled in the main menu (when you right click on the sandbox) are created using the GLMotif library and so I don’t know to what extend they can be simply assigned keys the way some other menu items like global water tool or DEM tool can be assigned keys.

    I’m sure however you can create a Tool class that you can use to assign keys to these functions. I’d recommend having a look at GlobalWaterTool.cpp if you want to have an idea of how to create a simple class like that.

    #103222

    liudr
    Participant

    elisek,

    Thanks for the pointer. I took a look at the .cpp, but felt a bit lost. Too much dependence on libraries. I’ll have to hack and see how it goes. Maybe spend sometime with the VRui project hopefully it has good documentation. I thought that adding these features will make the sandbox more interactive in a computer-techie free space, where users just turn big knobs instead of using mice and keyboards.

    #103226

    elisek
    Participant

    (For some reason my post disappeared after editing, if I am double posting apologies and feel free to remove the duplicate)

    Yes, there is a bit of dependence on the libraries and a lot is hidden through the inheritance. It can be very daunting code when you first look at it that’s why I recommended GlobalWaterTool.cpp (or LocalWaterTool.cpp) which is relatively simple.

    I’ve been working on some templates for simple functionality in the sandbox. In a Tool you can link either buttons or “valuators” and if you use buttons then it’s relatively simple (I’ll explain what little I know about valuators towards the end). Here is my TemplateTool class:

    TemplateTool.h

    #ifndef TEMPLATETOOL_INCLUDED
    #define TEMPLATETOOL_INCLUDED
    
    #include <Vrui/Tool.h>
    #include <Vrui/GenericToolFactory.h>
    #include <Vrui/Application.h>
    
    /* Forward declarations: */
    class Sandbox;
    class TemplateTool;
    typedef Vrui::GenericToolFactory<TemplateTool> TemplateToolFactory;
    
    class TemplateTool:public Vrui::Tool,public Vrui::Application::Tool<Sandbox>
    	{
    	friend class Vrui::GenericToolFactory<TemplateTool>;
    	
    	/* Elements: */
    	private:
    	static TemplateToolFactory* factory; // Pointer to the factory object for this class
    	
    	/* Constructors and destructors: */
    	public:
    	static TemplateToolFactory* initClass(Vrui::ToolManager& toolManager);
    	TemplateTool(const Vrui::ToolFactory* factory,const Vrui::ToolInputAssignment& inputAssignment);
    	virtual ~TemplateTool(void);
    	
    	/* Methods from class Vrui::Tool: */
    	virtual const Vrui::ToolFactory* getFactory(void) const;
    	virtual void buttonCallback(int buttonSlotIndex,Vrui::InputDevice::ButtonCallbackData* cbData);
    	};
    
    #endif

    If you’re not using any complicated code analysis the above is all you need, just replace “Template” with the name of your tool.

    As for the .cpp file it is this:

    #include "TemplateTool.h"
    #include <Vrui/ToolManager.h>
    
    /* Include dependent classes if used */
    #include "Sandbox.h" 
    
    /****************************************
    Static elements of class GlobalWaterTool:
    ****************************************/
    
    TemplateToolFactory* TemplateTool::factory=0;
    
    /********************************
    Methods of class GlobalWaterTool:
    ********************************/
    
    TemplateToolFactory* TemplateTool::initClass(Vrui::ToolManager& toolManager)
    	{
    	/* Create the tool factory: */
        /* TemplateToolFactory(config name, menu name, ??, global tool manager to link) */
    	factory=new TemplateToolFactory("TemplateTool","Manage Water",0,toolManager);
    	
    	/* Set up the tool class' input layout: */
    	/* Layout refers to all input devices i.e. buttons and valuators */   
        /* Number of input functons */
    	factory->setNumButtons(2);
        /* Define input functions */
    	factory->setButtonFunction(0,"Behaviour 1");
    	factory->setButtonFunction(1,"Behaviour 2");
    	
    	/* Register and return the factory: */
    	toolManager.addClass(factory,Vrui::ToolManager::defaultToolFactoryDestructor);
    	return factory;
    	}
    
    /* Constructor, leave empty unless there are objects/values to initialise */
    TemplateTool::TemplateTool(const Vrui::ToolFactory* factory,const Vrui::ToolInputAssignment& inputAssignment)
    	:Vrui::Tool(factory,inputAssignment)
    	{
    	}
    
    /* Deconstructor, leave empty unless need to destroy objects */
    TemplateTool::~TemplateTool(void)
    	{
    	}
    
    /* Leave as is */
    const Vrui::ToolFactory* TemplateTool::getFactory(void) const
    	{
    	return factory;
    	}
    
    /* Called when button state is changed (ie pressed AND released) */
    void TemplateTool::buttonCallback(int buttonSlotIndex,Vrui::InputDevice::ButtonCallbackData* cbData)
    	{
    	/* Check whether button is pressed DOWN */
    	if(cbData->newButtonState)
    		;/* Insert code */
        /* Check which button is pressed, refer back to your tool factory settings */
    	if(buttonSlotIndex==1)
    		;/* Insert code */
    	}

    2 important things here are initClass() where you define the number of tool functions, their names and equivalent indices and buttonCallback() where you define the Tool behaviour. ‘cbData->newButtonState’ means that the button has been pressed (negate this for release) and ‘int buttonSlotIndex’ represents your button (function) index. You can then hard-code the buttons/input devices for these in the config file if you need to.

    If you want to access data of a different class you can either pass that object through the constructor or you can access the Sandbox object through ‘application’ i.e. ‘application->methodInSandboxClass()’.

    In this simple version, it will change the settings only when you press down or release and nothing will happen whilst the button is pressed down. Alternatively, you could add to that a ‘void frame()’ method which is called every frame and have flags that say when a button is pressed down or not.

    If you want to use knobs for this I’d recommend looking at the Tool.cpp class itself (in the Vrui-4.2/Vrui folder) and potentially ToolInputLayout.cpp. What you’d need is ‘factory->setNumValuators(number of knobs)’ in ‘initClass()’ and ‘valuatorCallback(int,InputDevice::ValuatorCallbackData*)’. Then I’d look at how the ValuatorCallbackData is structured (in InputDevice.h).

    Hope this helps. Good luck 🙂

Viewing 4 posts - 1 through 4 (of 4 total)

You must be logged in to reply to this topic.

Comments are closed.