Accepting Events

I there somewhere where I can find an explanation of event handling in C++? From what I understand, it’s not at all consistent with the Python version of Panda. I looked through Roaming Ralph, but it didn’t really explain anything very well.

Hey, welcome to the forums!

I advise searching the forums for ‘define_key’, that should turn up helpful results.

Well, that I get. What I want to know is how to accept non-keyboard events.

For example, just like I define keys:

define_key ("arrow_up", "", [] (const Event* e, void* data)
{
	std::cout << "It appears the up arrow has been pressed\n";
}, nullptr);

Can I define event callbacks this way?

define_event_acception ("foo-into-bar", "", [] (const CollisionHandlerEvent* event, void* data)
{
  std::cout << "It appears foo has collided into bar.\n";
}, nullptr);

I think that should work through the define_key interface, too.

Oh, I guess it does. Well, the description in the documentation was kind of misleading.

One more thing. I’m having trouble defining collision events, and nothing I can find on the forum (or especially the documentation) is helping.

NodePath foo = window->load_model (get_models (), "foo.egg");
CollisionHandlerEvent* chandler = new CollisionHandlerEvent;
chandler->add_in_pattern ("into-%in");
define_key ("into-foo.egg", "", exit, nullptr);

However, nothing happens when something collides with foo.

Try calling ls() on the NodePath to print out the node structure, and you can find the proper name of the CollisionNode (which is probably not foo.egg in this case).

foo.egg was just a placeholder in the post.

This is what was printed. I was using “ship.egg” as the name. Is this correct?

ModelRoot ship.egg
  PandaNode 
    PandaNode RootFrame T:m(hpr 0 90 0 scale 1 1 -1)
      PandaNode Plane T:m(hpr 0 -90 0 scale 0.05)
        GeomNode  (1 geoms: S:(MaterialAttrib TextureAttrib TransparencyAttrib))
  ModelRoot gun.egg T:(pos -0.065 -0.005 0)
    PandaNode 
      PandaNode RootFrame T:m(hpr 0 90 0 scale 1 1 -1)
        PandaNode Circle_001 T:m(hpr 0 -90 0 scale 0.05)
          GeomNode  (1 geoms: S:(MaterialAttrib TextureAttrib TransparencyAttrib))
  ModelRoot gun.egg T:(pos 0.065 -0.005 0)
    PandaNode 
      PandaNode RootFrame T:m(hpr 0 90 0 scale 1 1 -1)
        PandaNode Circle_001 T:m(hpr 0 -90 0 scale 0.05)
          GeomNode  (1 geoms: S:(MaterialAttrib TextureAttrib TransparencyAttrib))

Here’s a minimal example. What am I doing wrong?

#include <pandaFramework.h>
#include <collisionHandlerEvent.h>

PandaFramework framework;
WindowFramework* window;
CollisionHandlerEvent* chandler;
NodePath foo, bar;

void move_foo (const Event* event, void* data) {foo.set_z (foo.get_z () - 0.1);}
void quit (const Event* event, void* data) {exit (0);}

void init ()
{
	window = framework.open_window ();
	window->setup_trackball ();
	window->set_lighting (true);
	window->enable_keyboard ();
	
	chandler = new CollisionHandlerEvent ();
	
	foo = window->load_model (framework.get_models (), "foo");
	bar = window->load_model (framework.get_models (), "bar");
	foo.reparent_to (window->get_render ());
	bar.reparent_to (window->get_render ());
}

int main (int argc, char** argv)
{
	framework.open_framework (argc, argv);
	
	init ();
	
	foo.set_z (3);
	bar.set_z (-3);
	
	chandler->add_in_pattern ("%in-into-%fn");
	framework.define_key ("arrow_down-repeat", "", move_foo, NULL);
	framework.define_key (foo.get_name () + "-into-" + bar.get_name (),
		"Quit", quit, NULL);
	
	framework.main_loop ();
}

Neither of the models has any collision geometry or collision solids. I don’t understand how you’re trying to collide two pieces of visible geometry with each other.

How would I go about making a model have collision geometry?

Please check out the section about collisions in the manual.

I did, but it doesn’t seem to explain how I would use the same mesh as the visible geometry.

You can set up a model to be used as ‘into’ geometry by calling set_collide_mask on the NodePath. (That’s the inefficient way. The more efficient way would be to put a tag in the .egg file so that it is automatically converted to collision geometry when loaded. There are many resources on the forums about this).

However, you can’t collide two mesh geometries with each other. You’ll need to let a collision solid collide into a mesh geometry, or a solid into a solid.