getting set_from_lens to work in C++

i read about this nifty function that is especially useful for what i’m trying to do but can’t seem to get the camera for it’s first parameter.

this is roughly the way i declared my camera

NodePath    cam = window->get_camera_group();

NodePath    player;
//loaded the player model and set it's scale after this.

//created a np to handle the rotations of the mouse controlled camera
//hpr for this np updated every frame with mouse's movement
NodePath    camAngle = player.attach_new_node("camAngle");

cam.set_pos(0,48,17);
cam.reparent_to(camAngle);

and then i starting doing the collision stuff

pickRay = new CollisionRay();

PT(LensNode) camera = window->get_camera(0);  //window is a pointer to WindowFramework in main
pickRay->set_from_lens(camera, 400,300);

pickRay_CNode = new CollisionNode("pickRay");
pickRay_CNode->add_solid(pickRay);
pickRay_CNode->set_from_collide_mask(BitMask32::bit(0));
pickRay_CNode->set_into_collide_mask(BitMask32::all_off());

pickRay_NP = cam.attach_new_node(pickRay_CNode);

pick_handler = new CollisionHandlerQueue();

c_trav.add_collider(pickRay_NP, pick_handler);
c_trav.traverse(window->get_render());

well i ain’t quite sure what went wrong but after this, when i checked pick_handler->get_num_entries(), it always returned me a 0. So i gave the NodePath cam a name “mainCamera” and i checked it against the name of the node returned by window->get_camera(0) and it gave me “camera”. I’ve only got 1 camera running in my application (checked with get_camera in render which returned me 1) :confused:

-Edit: :open_mouth: seems like “camera”, returned by window->get_camera(0), is actually a child of “mainCamera” but the picking still dosen’t work any ideas why? -

an alternative i had in mind was to parent this collisionRay to the cam variable parented to player such that the collisionRay’s origin will always be the camera’s origin.

(Q1) is this as simple as pickRay_NP.reparent_to(player) ?
(Q2) how would i be able to obtain the direction of the ray? A camera would have this vector but i’m not exactly sure if i’m able to obtain this from the NodePath cam

This is the right idea. CollisionRay::set_from_lens() assumes that the ray will be parented to the same node as the camera itself (or a node in the same transform space, such as the parent node of the camera). But, it looks like you have already done this, with the line:

pickRay_NP = cam.attach_new_node(pickRay_CNode); 

This will reparent the pickRay to the player, not to the camera. If the camera has any local transform other than identity, the result will be incorrect.

Not sure what you’re getting at here. You can ask CollisionRay::get_direction() to return the direction vector of your ray. It will be in the collision ray’s local coordinate space, which should also be the local coordinate space of your camera. Thus, it will generally have a positive Y direction.

One problem I see immediately in your code is the point passed to set_from_lens(). From the comment for this function:

////////////////////////////////////////////////////////////////////
//     Function: CollisionRay::set_from_lens
//       Access: Public
//  Description: Accepts a LensNode and a 2-d point in the range
//               [-1,1].  Sets the CollisionRay so that it begins at
//               the LensNode's near plane and extends to
//               infinity, making it suitable for picking objects from
//               the screen given a camera and a mouse location.
////////////////////////////////////////////////////////////////////

Thus, 400, 300 is way, way outside the normal range of [-1, 1]. That is, the set_from_lens() function wants normalized coordinates, not pixel values.

David

  • edit: found out and problem solved thanks for help :slight_smile: -