Reading camera position?

So i’ve run into what appears to be a very common problem, but I’m not finding a clear answer to it.

it looks as though if you want to set the camera position yourself, you must invoke

self.disableMouse()

to do so, and that in fact works, but then of course you lose the built-in camera. i did find a thread that said basically you need to write your own camera control, i.e. it’s NOT possible to set the initial position for the built-in camera. Is that still true ?

my other problem, is that i’m unsure what my camera position should be to see my scene. However it’s pretty easy for me to use the default camera and then move to where I want, so if you could then print out the camera settings, problem solved.

I looked through the help, but I can’t seem to find a way to do that. Is there a way ?

Thanks,

Indeed: the camera is a node like any other, and thus you should be able to call “getPos” to return its position.

However! Under the default camera control, the camera is presumably parented beneath some or other node, and the actual movement is done by either that node or some other even further above. Since the camera remains at the same position relative to this parent-node, a simple call to “getPos” therefore just keeps returning a position of (0, 0, 0).

To circumvent this, we instead specify in our call to “getPos” that we want the camera’s position relative to render. This is done by passing in “render” as a parameter to “getPos”.

So, something like this:

print (base.cam.getPos(render))
2 Likes

If you want to keep using the built-in camera control, then you can do:

base.cam.set_pos(0., -10., 0.)

to set the initial camera position.
You can also set its orientation with e.g.:

base.cam.set_hpr(30., -20., -40.)

but in general this changes the point the camera looks at. If you don’t like that, it may be better to use:

base.mouseInterfaceNode.set_hpr(30., -20., -40.)

as this will orbit the camera around its center of rotation.

1 Like

No

self.trackball.node().set_pos(0, 30, 0)

1 Like

Thanks very much everyone !

@serega-kkz your suggestion did not work. :frowning: it didn’t cause an error, it just didn’t shift the viewpoint.

both base.cam.set_pos AND base.cam.setPos worked.

Is there any difference between the two function calls ? They appeared to work exactly the same.

Also thanks to @Thaumaturge, that print worked perfectly after i set up a task so that i could actually print the position after moving the camera :slight_smile: That was a very nice exercise in creating a task. Luckily the asteroids demo is perfect example of how to do it and so it was easy. That asteroids demo is really, really useful :slight_smile:

1 Like

@tungsten And if you compare?

A:

from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
      
        # Load the environment model.
        self.scene = self.loader.loadModel("models/environment")
        # Reparent the model to render.
        self.scene.reparentTo(self.render)
        # Apply scale and position transforms on the model.
        self.scene.setScale(0.25, 0.25, 0.25)
        self.scene.setPos(-8, 42, 0)

app = MyApp()
app.run() 

B:

from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)
        
        self.trackball.node().set_pos(0, 300, 0)

        # Load the environment model.
        self.scene = self.loader.loadModel("models/environment")
        # Reparent the model to render.
        self.scene.reparentTo(self.render)
        # Apply scale and position transforms on the model.
        self.scene.setScale(0.25, 0.25, 0.25)
        self.scene.setPos(-8, 42, 0)

app = MyApp()
app.run()

oh. i found the problem (btw, i couldn’t make self.scene work, because i don’t think i’m setting up the scene as what your code is doing. for reference, this is the hex drawing code from the other thread. also, too, noob alert…).

when i use base.cam.set_pos or base.com.setPos, i used the following:

base.com.setPos(0, -50, 0)

My first try with trackball was,

self.trackball.node().set_pos(0,-50,0)

however, as i experimented with what the camera node was telling me I noticed that i could bring the scene into view, i just had to move the camera farther than expected, so I tried

self.trackball.node().set_pos(0,50,0)

and that worked.

So for whatever reason, which i’m sure will become apparent if i can find the documentation for all of this, is that base.cam.setPos and trackball.node().set_pos seem to need the opposite sign on the coordinate.

I ran it a couple of times to be sure and verified they do require the opposite sign.

So the good news is i have two different ways to set the camera position. However, which one should I be using ?

You need to use this self.camera.set_pos(0, 30, 0)


Example of getting a camera transformation.
from direct.showbase.ShowBase import ShowBase

class MyApp(ShowBase):

    def __init__(self):
        ShowBase.__init__(self)

        self.trackball.node().set_pos(0, 300, 0)

        # Load the environment model.
        self.scene = self.loader.loadModel("models/environment")
        # Reparent the model to render.
        self.scene.reparentTo(self.render)
        # Apply scale and position transforms on the model.
        self.scene.setScale(0.25, 0.25, 0.25)
        self.scene.setPos(-8, 42, 0)
        
        self.accept('enter', self.get_camera_pos)

    def get_camera_pos(self):
        print("Pos ", self.camera.get_pos())
        print("Hpr ", self.camera.get_hpr())

app = MyApp()
app.run()

As for the reverse sign, I also noticed this, but this is a question for @rdb

base.cam.setPos and base.cam.set_pos

This is the same thing, just a different style of code CaMeL outdated, and the new style of the s_n_a_k_e.

1 Like

The section about re-enabling mouse control in the manual lists the following code:

mat = Mat4(camera.getMat())
mat.invertInPlace()
base.mouseInterfaceNode.setMat(mat)
base.enableMouse()

which seems to suggest that the trackball (whose node mouseInterfaceNode refers to) uses the inverse camera transformation.
Indeed, when I look at the Trackball API, its description mentions:

it can spin around a camera with the inverse transform to make it appear that the whole world is spinning.

and when I call base.mouseInterfaceNode.get_invert(), it effectively returns True.

IIRC, some time ago the devs mentioned that the use of camelCase might eventually be phased out in favor of snake_case, which is why I use the latter to make my code more “future-proof”.

Thanks very much for the doc links and the explanation.
snake_case it is.