I’m shooting a CollisionRay to be able to pick up objects in my tool. It works perfectly in a 800x600 window.
But when the window is stretched, as in a wide screen laptop, the collision ray is offset to the left when the mouse moves right and vice-versa. It seems reasonably allright near the middle.
wide screen window - mouse to the right
wide screen window - mouse to the left
I can’t figure out what the problem is. I tried resetting the collision ray each time the window is re-sized, but I haven’t found anything yet.
We’d need to see your code where you set up your ray and how you make it extrude from the camera.
I’m betting you made a confusion between render2d and aspect2d.
This is a small part of a fairly big project I’m working on. Most of the code here is not mine, but is from a batch of students who worked on this before me. So understanding the code might be a little difficult
But here goes, the required file is here:
The line in which the camera ray is initialized is: Line No. 398. It’s then used in Line 1100 and Line 1137.
All the files are available from this link:
If you want to install and play with the tool (which we are still polishing), it can be downloaded and installed from:
This is not a render2d problem, we made sure to use aspect2d when we started making modifications.
Aspect2d isn’t always the right choice. Certain operations–particular converting the mouse coordinates to 3-d coordinates for picking–require render2d, not aspect2d. If you get the wrong one, you get symptoms very like what you are describing.
I don’t know what’s going wrong specifically in your case, and I don’t have time right now to download a large program and pore through it, but I propose the following simple test: put “aspect-ratio 1” in your Config.prc file, which will make your aspect ratio be 1.0, and make aspect2d have the same scale as render2d. This will distort your scene, but if it also solves the clicking problem, it would seem to indicate that you have used aspect2d where you should have used render2d, or vice-versa.
Putting in “aspect-ratio 1” in the config.prc file stretched everything out, but solved the clicking problem.
So as I understand it, do I have to change render2d to aspect2d?
No, you have to use the correct node for each particular case. The correct node is not always render2d, nor is it always aspect2d. It depends on the case.
When you are dealing with a coordinate position that should be scaled for the window shape, you should use aspect2d. When you are dealing with a coordinate position that should be in the range 1…1 regardless of the window shape, you should use render2d.
The mouse input is in the range 1…1 regardless of the window shape,so when you are dealing with mouse coordinates, you should generally use render2d.
Maybe I did not search hard enough, but I cannot find anyway that we can attach the mouse to render2d.
to get the mouse position. Is there any other way of getting the mouse position?
No, that is the mouse position, in the -1…1 space.
But when you do the picking operation, you create a CollisionRay, and that CollisionRay has to be attached to the scene graph somewhere. Because you (presumably) initialize the CollisionRay with coordinates in the -1…1 space, it is important to attach the CollisionRay to render2d, and not to aspect2d.
I have been trying to attach the CollisionRay to render2d for the past several days and also looking at the various examples for picking objects. I have been largely unsuccessful. Here’s the code I’m using to initialize the CollisionRay:
self.lens = self.camera
self.pickerRay = CollisionRay()
self.picker = CollisionTraverser()
self.queue = CollisionHandlerQueue()
self.pickerNode = CollisionNode('mouseRay')
self.pickerNP = camera.attachNewNode(self.pickerNode)
I’m using the ray like this:
self.pickerRay.setFromLens(self.camera.node(), x, y)
if (self.queue.getNumEntries() > 0): # pick the first object
obj = self.queue.getEntry(0).getIntoNodePath()
self.floorPosition = self.queue.getEntry(0).getSurfacePoint(obj)
I have found no reference to parenting it to render2d. How can I do this? Just attaching the CollisionRay or the pickerNode to render2d does not work, as expected.
You’re right, I apologize profusely. I’ve been steering you wrong this whole time. There is no involvement with the 2-d scene graph in the picker ray, and no chance for confusion between aspect2d and render2d.
So, it must be something else. Is self.camera the same node as base.camera? When the user drags the window wider, ShowBase automatically adjusts the lens in base.camera with the new aspect ratio, but it won’t be able to adjust any other camera objects you might have created on your own. Thus, if self.camera is a different node, it will no longer match the lens in base.camera, and you will get this sort of problem.
Thanks for your guidance! self.camera was some other user-defined camera. After changing that, it worked like I wanted! I learned something new and fixed something bothering me for sometime.
Now… on to regression testing to fix whatever I broke fixing this!