Inherit from CollisionNode


#6

Replace that line with this:

add_child(model.node());

Note that you need to call MyObject::init_type() at static init time (or in any case, before you start using your object) to initialise the type system properly.


#7

thanks!!
but now nothing appears on the screen!
i print all node with render.ls() method. this is the output:

PandaNode render S:(CullFaceAttrib RescaleNormalAttrib ShadeModelAttrib)
  PandaNode camera_group
    Camera camera ( PerspectiveLens )
      PerspectiveLens fov = 39.3201 30
  none myObject (0 solids) T:(pos 0 10 0) (hidden)
    ModelRoot smiley.egg
      GeomNode  (1 geoms: S:(TextureAttrib))

I resolve this inserting path.show() line in main function. But… why do i have to add this line? Why is this imply?

thanks for your helps!


#8

CollisionNodes are hidden by default. You’ll need to call show_through() on the child node if you want to make it show up anyway. Alternatively, you can call show() on the node itself, but this’ll make the debug visualisation for the solids show up too.


#9

thanks!!!
And are there consequence on the performance?


#10

I don’t see how calling show_through() could noticeably affect your performance.


#11

oki thanks!!!


#12

What’s the different between PT(MyObject) and MyObject* ? and DCAST(MyObject, node) and dynamic_cast<MyObject*>(node)?


#13

PT() is an automatic pointer for objects that inherit from ReferenceCount. It automatically increases the reference count when you create one and it decreases it when it goes out of scope, making sure that objects automatically get cleaned up when there are no references to them anymore. You should use them to refer to reference counted objects (including PandaNode derivatives). Be sure not to attempt to delete objects that inherit from ReferenceCount.

DCAST is a macro for objects that inherit from TypedObject that performs safe typecasting.


#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