[SOLVED] My own Camera

hi,

I am experimenting a bit with the camera functionality of Panda and after digging around in the forum I tried this code.

	PerspectiveLens* pLens = new PerspectiveLens();
	PT(Camera) pCamera = new Camera("BaseCamera", pLens);

	NodePath cameras = gTheWindow->get_camera_group();
	NodePath defaultCam = cameras.get_child(0);
	defaultCam.detach_node();

	NodePath mCameraNode = cameras.attach_new_node(pCamera); 
	pCamera->set_scene(gTheWindow->get_render());
	mCameraNode.set_pos(50.0f,100.0f,100.0f);
	mCameraNode.look_at(0,0,0);

	NodePath sampleScene = gTheWindow->load_model(gTheFramework.get_models(), "TestScene");
	sampleScene.reparent_to(mCameraNode);
        //I tried also to reparent it to gTheWindow->get_render();
	sampleScene.set_pos(0, 0, 0);
	sampleScene.flatten_strong();
	sampleScene.show();

is this what I should be doing to disable the default camera and set my own to work ?
This code doesn’t show my model anymore whereas if I leave the default camera it shows the model as usual.

Chrys

Hi

I know if you parent your scene to the camera then your scene’s origin will be translated to 50.0f,100.0f,100.0f, the position you set your camera to, and then you look at 0,0,0; you may not see anything. But now you said you didn’t see it when you parented it to render either…

Do you really need to not use the default camera ? You can use the default and still set your own Lens with gTheWindow->get_camera(0)->set_lens(pLens);

yeah as I said I I would like to play around with cameras a bit.
As mentioned in the comment above I’ve tried to reparent to the render node as well but nothing shows. :frowning:

I’ve tried to activate the camera

pCamera->set_active(true);

still nothing is visible. :angry:

try to set a fov on your lens, I thought there should be a default, but … maybe not; I’ve always set a fov on any lens I create myself.

I have tried to set the lense and other stuff but nothing renders.

I’ve tried to just set the position of the standard camera and NOT call the “Setup_trackball” function but now the collision ray doesn’t seem to be hitting my custom nodes anymore. By looking at the code I think it has something to do with the Transform2SG that the trackball setup seems to be using. I hope one of the developers can shed some light into this please :frowning:

I’m not sure what you’re asking. Are you asking for help aiming your camera and setting up your scene so that the items in your scene are actually in front of the camera?

David

Hi drwr,

ok I’ll try to explain what I am actually trying to do.

Firstly, the source code I posted above is meant to setup my own camera. Can you tell me what I am doing wrong there ?

Scondly, I’ve tried to leave the standard camera enabled and not calling

   gWindow->setup_trackball();

if I do this then I’ve got the problem that my collision traverser doesn’t pickup the correct nodes anymore (where as if I leave the setup_trackball enabled it all works fine - when I click on certain objects tagged with “selectable” it returns me the correct nodes).

here is how I initialise stuff

	mCamera = pMyGameWindow->get_camera_group();

	mPickerRay = new CollisionRay();
	PT(CollisionNode) pickerNode = new CollisionNode("MousePicker");
	pickerNode->add_solid(mPickerRay);
	pickerNode->set_from_collide_mask(GeomNode::get_default_collide_mask());
	mPickerNodePath = mCamera.attach_new_node(pickerNode);

	mMouseWatcher = (MouseWatcher*)pMyGameWindow->get_mouse().node();

	mCollisionHQ = new CollisionHandlerQueue();
	mpCollisionTraverser = new CollisionTraverser("CollisionTraverser");
	mpCollisionTraverser->add_collider(mPickerNodePath, mCollisionHQ);

and here is what I do in the “OnMouseClick” event

// This gives up the screen coordinates of the mouse.   
	const LPoint2f& mpos = MyMouseWatcher()->get_mouse();

	// This makes the ray's origin the camera and makes the ray point    
	// to the screen coordinates of the mouse.
	MyCollisionRay()->set_from_lens(pMyGameWindow->get_camera(0), mpos.get_x(), mpos.get_y());

	MyCollisionTraverser()->traverse(myRootNode);

	PT(CollisionHandlerQueue) collisionHQ = MyCollisionHQ();

	if(collisionHQ->get_num_entries() > 0)
	{
		collisionHQ->sort_entries();

		NodePath pickedObj = collisionHQ->get_entry(0)->get_into_node_path();
		pickedObj = pickedObj.find_net_tag("Selectable");

		if(!pickedObj.is_empty())
		{
                  // do something
		}
	}

I think the issue is related to what the trackball actually does …see the windows framework code

////////////////////////////////////////////////////////////////////
//     Function: WindowFramework::setup_trackball
//       Access: Public
//  Description: Sets up the mouse to trackball around the camera.
////////////////////////////////////////////////////////////////////
void WindowFramework::
setup_trackball() {
  if (_got_trackball) {
    return;
  }

  if (_window->is_of_type(GraphicsWindow::get_class_type()) &&
      DCAST(GraphicsWindow, _window)->get_num_input_devices() > 0) {
    NodePath mouse = get_mouse();
    NodePath camera = get_camera_group();

    _trackball = new Trackball("trackball");
    _trackball->set_pos(LVector3f::forward() * 50.0);
    mouse.attach_new_node(_trackball);

    PT(Transform2SG) tball2cam = new Transform2SG("tball2cam");
    tball2cam->set_node(camera.node());
    _trackball->add_child(tball2cam);
  }

  _got_trackball = true;
}

and here the class description of trackball

////////////////////////////////////////////////////////////////////
//       Class : Trackball
// Description : Trackball acts like Performer in trackball mode.  It
//               can either spin around a piece of geometry directly,
//               or it can spin around a camera with the inverse
//               transform to make it appear that the whole world is
//               spinning.
//
//               The Trackball object actually just places a transform
//               in the data graph; parent a Transform2SG node under
//               it to actually transform objects (or cameras) in the
//               world.
////////////////////////////////////////////////////////////////////

the Transform2SG sounds like something I would have to do as well with any camera that I want to use to setup my collision traversers for picking nodes ?
If it is related could you explain me how to setup my own camera with it ?
I’ve read the panda manual and searched google about it but I couldn’t quite figure out what needs to be done and where those nodes need to be attached to.

A Trackball has absolutely nothing to do with collisions. It’s just a tool for controlling the direction the camera is looking. All that stuff about Transform2SG refers to the way to tell the Trackball which camera you want it to aim.

Now that I look at your code more closely, I think you’ve tricked yourself. You haven’t finished creating a new camera, because you haven’t created a DisplayRegion to show the results of your camera. So the empty window you’re looking it must be coming from the old camera. Note that calling defaultCam.detach_node() doesn’t stop the camera from rendering, it just takes it out of the scene graph and puts it in a scene graph all by itself, where there’s nothing interesting to look at (so all you will see is a gray screen).

Other things that aren’t necessarily related to your problem, but which deserve pointing out:

PerspectiveLens* pLens = new PerspectiveLens();

This line should be:

PT(PerspectiveLens) pLens = new PerspectiveLens(); 

because PerspectiveLens inherits from ReferenceCount, and therefore it requires being stored in a PT() object instead of an ordinary pointer, or you risk it being automatically destructed out from under you. The PT() object doesn’t automatically upcast like an ordinary pointer does, though, so it means you need to pass it to the Camera constructor as pLens.p().

pCamera->set_scene(gTheWindow->get_render());

It’s usually a bad idea to call set_scene(); it only leads to confusion. I wish we had never added this function. You don’t need to call it; if you don’t call it, the camera will render whatever scene graph it is attached to. (If you do call it, it will render the specified scene graph even if it’s not attached to it, which is weird and causes nothing but trouble.)

sampleScene.reparent_to(mCameraNode);

You shouldn’t attach a scene that you expect to be looking at to the camera. It’s rather like putting an object in your eye instead of on the table. A camera can’t see something that’s inside it, so if you parent your scene to the camera, it probably won’t be able to see it. Parent it to render instead.

thanks for your really helpfull answer.

here my patched up code. The camera is now working.

	NodePath cameras = gTheWindow->get_camera_group();
	NodePath defaultCam = cameras.get_child(0);
	Camera* pDefaultCam = DCAST(Camera, defaultCam.node());
	pDefaultCam->set_active(false);
	defaultCam.remove_node();

	PT(PerspectiveLens) pLens = new PerspectiveLens();
	PT(Camera) pCamera = new Camera("BaseCamera", pLens);
	gCameraNode = gTheWindow->get_render().attach_new_node(pCamera);
	gTheWindow->get_display_region_3d()->set_camera(gCameraNode);
	pCamera->set_active(true);
	pCamera->show_frustum();
	gCameraNode.set_pos(200.0f,0.0f,100.0f);
	gCameraNode.look_at(0,0,0);
	gCameraNode.show();