Inherit from CollisionNode


#14

oh yea!
Thank for your explanations!!!

But i don’t understand why is there not a manual section in which there’s explanation this!!!
:smiley:


#15

These interfaces are thoroughly explained in the Panda source code files of the respective interfaces.


#16

i try to inherit from CollisionNode but my code doesn’t work!

#include "pandaFramework.h"
#include "pandaSystem.h"
#include <collisionNode.h>
#include <collisionSphere.h>
#include <collisionRay.h>
#include <collisionTraverser.h>
#include <collisionHandlerQueue.h>
 
PandaFramework framework;
CollisionTraverser trav;
CollisionHandlerQueue* queue;
CollisionRay* ray;

class MyObject : public CollisionNode {
public:
        MyObject(string name) : CollisionNode(name) {
        }

        static TypeHandle get_class_type() {
            return _type_handle;
        }

        static void init_type() {
            CollisionNode::init_type();
            register_type(_type_handle, "MyObject", CollisionNode::get_class_type());
        }
        
        
        virtual TypeHandle get_type() const {
            return get_class_type();
        }

        virtual TypeHandle force_init_type() {
            init_type();
            return get_class_type();
        }



    private:
        static TypeHandle _type_handle;
};

TypeHandle MyObject::_type_handle;

void clickOnObject(const Event* ev, void* data) {
    WindowFramework* win = framework.get_window(0);
    float x = (2 * win->get_graphics_window()->get_pointer(0).get_x()) / ((float)win->get_graphics_window()->get_x_size())- 1;
    float y = (2 * win->get_graphics_window()->get_pointer(0).get_y()) / ((float)win->get_graphics_window()->get_y_size())- 1;
    ray->set_from_lens(framework.get_window(0)->get_camera(0), x, y);
    trav.traverse(framework.get_window(0)->get_render());
    cout << queue->get_num_entries() << endl;
}

int main(int argc, char *argv[]) {
    framework.open_framework(argc, argv);
    framework.set_window_title("My Panda3D Window");
    WindowFramework *window = framework.open_window();
    framework.get_window(0)->enable_keyboard();
    
    MyObject* obj = new MyObject("hi");
    obj->add_solid(new CollisionSphere(0, 0, 0, 2));
    obj->set_into_collide_mask(BitMask32::all_on());
    
    NodePath path(obj);
    path.reparent_to(window->get_render());
    path.set_pos(-10, -10, -10);
    path.show();
    window->get_camera_group().look_at(path);
    
    
    queue = new CollisionHandlerQueue();
    CollisionNode* cnode= new CollisionNode("ray");
    ray = new CollisionRay();
    cnode->add_solid(ray);
    NodePath cpath(cnode);
    cpath.reparent_to(window->get_camera_group());
    trav.add_collider(cpath, queue);
    
    framework.define_key("mouse1", "click", clickOnObject, NULL);
 
    framework.main_loop();
    framework.close_framework();
    return (0);
}

If i replace this line

MyObject* obj = new MyObject("hi");

with this

CollisionNode* obj = new CollisionNode("hi");

it work!!

why??

thanks!!


#17

As David already said, you should use this:

PT(MyObject) obj = new MyObject("hi");

I’m not sure if that is the problem here though, because you haven’t elaborated on “doesn’t work”. What doesn’t work? Does it crash? Does it show an error?


#18

the problem isn’t resolved if i use PT instead of *.

There’re no crash. this’s not work: if i click on the sphere, in the terminal is printed 0. if i use CollisionNode instead of MyObject, in the terminal is printed 1…
why?


#19

I also don’t see you initialise the type properly using init_type().


#20

Do I call MyObject::init_type() in main function?

int main(...) {
   ...
   MyObject::init_type();
   ...
}

If i do it, the problem’s not resolved!

Excuse me … I don’t understand what you tell me

PS: ok, i understand but it doesn’t work… i try to move MyObject::init_type method at the beginning of the main and than of open_framework call, but the problem’s not resolved… where am i wrong?
PS2: and is not a register problem: i print obj->get_type().get_name() and it is “MyObject”. and obj->get_type().get_parent_class(0).get_name() is “CollisionNode”.


#21

It is important that obj->is_of_type(CollisionNode::get_class_type()) returns true, which ought to be the case if you have called init_type(). But you can verify this.

Other than that, I don’t know what’s wrong. Maybe you can get a clue if you set “notify-level-collide spam” in your Config.prc file, and compare the output from the CollisionNode vs. the MyObject cases.

David


#22

with MyObject there’s in the terminal

:collide(debug): Recomputing viz for sphere, c (0 0 0), r 2
:collide(spam):   Considering render
  Comparing 0: bline, (-0.593575 -0.558208 -0.580267) - (-1.18696 -1.11624 -1.16035) to bsphere, infinite, is_in = 1
:collide(spam):   render has 1 interested colliders ( 0. ray )
:collide(spam):     Considering render/camera_group
    Comparing 0: bline, (-0.593575 -0.558208 -0.580267) - (-1.18696 -1.11624 -1.16035) to bsphere, infinite, is_in = 1
:collide(spam):     render/camera_group has 1 interested colliders ( 0. ray )
:collide(spam):       Considering render/camera_group/camera
:collide(spam):       render/camera_group/camera has 0 interested colliders ( )
:collide(spam):       Considering render/camera_group/ray
      Not comparing 0 to render/camera_group/ray (same node)
:collide(spam):       render/camera_group/ray has 0 interested colliders ( )
:collide(spam):     Considering render/ciao
    Comparing 0: bline, (-0.593575 -0.558208 -0.580267) - (-1.18696 -1.11624 -1.16035) to bsphere, c (-10 -10 -10), r 2, is_in = 1
:collide(spam):     render/ciao has 1 interested colliders ( 0. ray )
0

with collisionNode there’s

:collide(debug): Recomputing viz for sphere, c (0 0 0), r 2
:collide(spam):   Considering render
  Comparing 0: bline, (-0.567779 -0.585463 -0.578809) - (-1.13551 -1.17088 -1.15757) to bsphere, infinite, is_in = 1
:collide(spam):   render has 1 interested colliders ( 0. ray )
:collide(spam):     Considering render/camera_group
    Comparing 0: bline, (-0.567779 -0.585463 -0.578809) - (-1.13551 -1.17088 -1.15757) to bsphere, infinite, is_in = 1
:collide(spam):     render/camera_group has 1 interested colliders ( 0. ray )
:collide(spam):       Considering render/camera_group/camera
:collide(spam):       render/camera_group/camera has 0 interested colliders ( )
:collide(spam):       Considering render/camera_group/ray
      Not comparing 0 to render/camera_group/ray (same node)
:collide(spam):       render/camera_group/ray has 0 interested colliders ( )
:collide(spam):     Considering render/ciao
    Comparing 0: bline, (-0.567779 -0.585463 -0.578809) - (-1.13551 -1.17088 -1.15757) to bsphere, c (-10 -10 -10), r 2, is_in = 1
:collide(spam):     render/ciao has 1 interested colliders ( 0. ray )
:collide(spam): Colliding against CollisionNode 0x10d5808:5 which has 1 collision solids.
:collide(debug): intersection detected from render/camera_group/ray into render/ciao

thanks for your patience!

i don’t tell I use develop skd… in ubuntu 11.10 64bit


#23

Oh, hmm, I see the problem. The CollisionTraverser has a check for is_exact_type(CollisionNode::get_class_type()). That is, it doesn’t support subclassing of CollisionNode.

I can put in an easy fix for this.

David


#24

Thanks a lot!! :slight_smile:
Will it be fixed?


#25

The fix is committed. You’ll have to either get the source and build it yourself, or wait for the buildbot to update the 1.8.0 version.

David


#26

You hate me now… :slight_smile:
Is the version 1.8 the same of the develop version? If not, where can i download this?
thanks a lot!

PS: now it works!!

thankssssss!!! :smiley: :smiley: :smiley: :smiley: :smiley:


#27

Uhm… i have another problem…

#include "pandaFramework.h"
#include "pandaSystem.h"
#include "aiCharacter.h"
#include "typeHandle.h"

#include "genericAsyncTask.h"
#include "asyncTaskManager.h"

#include <collisionRay.h>
#include <collisionHandlerQueue.h>
#include <collisionTraverser.h>
#include <collisionSphere.h>
#include <nodePathCollection.h>
 
PandaFramework framework;
WindowFramework* window;
PT(AsyncTaskManager) taskMgr = AsyncTaskManager::get_global_ptr();

CollisionTraverser trav;
CollisionHandlerQueue* queue;
CollisionRay* ray;
NodePathCollection coll;

class MyObject : public CollisionNode {
public:
    AICharacter* c;
    
    MyObject() : CollisionNode("MyObject") {
    }
    
        static TypeHandle get_class_type() {
            return _type_handle;
        }

        static void init_type() {
            TypedObject::init_type();
            register_type(_type_handle, "MyObject", TypedObject::get_class_type());
        }
        
        
        virtual TypeHandle get_type() const {
            return MyObject::get_class_type();
        }
        virtual TypeHandle force_init_type() {
            init_type();
            return MyObject::get_class_type();
        }
                
    private:        
        static TypeHandle _type_handle;
};
TypeHandle MyObject::_type_handle;

void select(const Event* ev, void* data) {
        float x = (2 * window->get_graphics_window()->get_pointer(0).get_x()) / ((float) window->get_graphics_window()->get_x_size()) - 1;
        float y = (2 * window->get_graphics_window()->get_pointer(0).get_y()) / ((float) window->get_graphics_window()->get_y_size()) - 1;
    ray->set_from_lens(window->get_camera(0), x, -y);
    trav.traverse(window->get_render());
    coll.clear();
    for (int i =0; i < queue->get_num_entries(); i++)
        coll.add_path(queue->get_entry(i)->get_into_node_path());
    cout << "num: " << queue->get_num_entries() << endl;
}

void print(const Event* ev, void* data) {
    for(int i =0; i < coll.get_num_paths(); i++) {
        cout << i << " " << coll[i] <<  endl;
        if (coll[i].node()->is_of_type(MyObject::get_class_type())) {
            cout << DCAST(MyObject, coll[i].node())->c << endl;
        }
    }
}

int main(int argc, char *argv[]) {
    framework.open_framework(argc, argv);
    framework.set_window_title("My Panda3D Window");
    window = framework.open_window();
    framework.get_window(0)->enable_keyboard();
    
    PT(MyObject) obj = new MyObject();
    obj->add_solid(new CollisionSphere(0, 0, 0, 3));
    NodePath path (obj);
    path.show();
    obj->c = new AICharacter("char", path, 60, 0.05, 15);
    path.reparent_to(window->get_render());
    path.set_pos(-10, -10, -10);
    window->get_camera_group().look_at(path);
    
    ray = new CollisionRay();
    queue = new CollisionHandlerQueue();
    CollisionNode* n = new CollisionNode("ray");
    n->add_solid(ray);
    NodePath p = window->get_camera_group().attach_new_node(n);
    trav.add_collider(p, queue);
    
    framework.define_key("mouse1", "select", &select, (void*)NULL);
    
    framework.define_key("mouse3", "print", &print, (void*)NULL);
    framework.main_loop();
    framework.close_framework();
    return (0);
}

when i click on the collision sphere with the mouse1 button, it’s printed “num1”. but when i click with the mouse3 button it’s printed

0 render/MyObject
Type

and the program is blocked here. I must kill it with Ctrl+C…
Why?
Where am i wrong?

thanks a lot for your patience!


#28

I don’t know; that’s strange. What do you see on the stack if you break into the program with the debugger once it is blocked?

David


#29

If i use this

void print(const Event* ev, void* data) {
    cout << DCAST(MyObject, coll[0].node())->c << endl;
}

as print function, the program works perfectly.

but with this, the program doesn’t work

void print(const Event* ev, void* data) {
    cout << DCAST(MyObject, coll[0].node())->c << endl;
    cout << "type: " << coll[0].node()->is_of_type(MyObject::get_class_type()) << endl;
}

I suppose that the error is in the calling of is_of_type method. or in MyObject::get_class_type method.


#30

I don’t see anything obviously wrong. If something is indeed broken, it must be something subtle. Have you found any more information recently?

David


#31

I have shown that i call typedobject::unit_type instead of collisionnode::init_type. But this doesn’t resolve the problem! I don’t understand why it’s printed "Type " in the terminal!
Than i try to run it in a debugger to understand where the program is blocked!


#32

Ah, and also make sure you correct this:

register_type(_type_handle, "MyObject", TypedObject::get_class_type());

To this:

register_type(_type_handle, "MyObject", CollisionNode::get_class_type());

That will be an important fix. I’m still not sure why it’s getting locked up, though.

David


#33

yes. i also have changed it… but the problem persists!

thanks for your attention!

I remember that i use ubuntu 11.10 with Devel version of panda3d. using gcc 4.4 of course!