Dealing with the camera [Solved, my solution included]

In my game you are supposed to view your avatar like in tomb raider, 3rd person.

So I base.disableMouse() and indirectly reparent the camera to the avatar. It works fine.

Unfortunately, walls block the camera very often and I wanted to provide a key that enables/disables a free view (the camera stands still respect to your avatar, but it’s movable with the mouse)

Then for that ‘magic’ key I put enablemouse() and reparent camera to the render again. It gets a mess don’t know why, it don’t let me come back to normal.

I would thank advices about this, how do you manage the camera in a simple way to get what I want?

I don’t have the answer to your question-- however I did notice that the Roaming Ralph tutorial seems to handle this. You might want to take a look at it.

If it works nice then why you don’t create any empty node that is normally parented to the avatar. The camera then looks at this node. If there is something blocking your sight, take your empty node and move it around in your world. If you disable the god mode, reparent the node back to the avatar.

@Anya
Do you think there is someone in these forums who don’t examine ralph for inspiration first? :confused: In Ralph there are no walls, so no camera blocking.

@Azraiyl
If something block my sight? How I know it? Maybe some ray and collision detection but that’s not a quick fix, and how I’m supposed to know where to move the camera for a clear view? More rays I suppose. I actually expected not to mess with that.

Thanks for the replies, I think I’ll keep thinking about this and in case it can’t be done in a simple way I’ll pass up the feature

Actually I didn’t look at Roaming Ralph till I saw people talking about it on the forums. I went to the manual first, checked out a few samples, and tried to go from there to understand how to work with Panda. Roaming Ralph is inspirational, but there is nothing screaming at you from the manual or front page saying, “Check out this particular sample first!” So it may not be as uncommon as you think.

You’re talking about your “Line of Sight”. Therefore you need to build this line of sight, if there is anything blocking your sight. I don’t know if moving around your camera is good idea anway. What if you are in grand canyon scenario? What position should you be able to move your camera to?

Here are two ideas stolen from games:

Sacred: Divide your level in mutiple floors. Based on what position our main character stands enable or disable this floors.

DungeonSiege: Create a line between your main character and the eye. Look if there is a collision to a model. Based on this collision disable the models. A house e.g. is divided into a floor and a roof. The floor is never removed, but the roof is “removed” if it collides with the line of sight. Because you are only interested in collision (not exact collision points) it should be not that hard to setup a traverser and use its output.

Incoming wall of text:

A possible solution to this (never actually done it), but I think it seems plausible too add some kind of collisionsphere around the camera, and making the walls “push” the camera such that it cant go pass it and block your view. So when your camera wants to be X units away from the avatar looking at it, the wall will actually push the camera towards the avatar until the avatar gets far enough away so that the camera can stop being pushed.

EDIT: Ray casting scares me for this situation; especially seems like a ton of code wrapped around the ray cast to make sure its actually a wall between the avatar and the camera. But then once u find that out: not sure where to go from there.

EDIT2: When you call enableMouse, i believe you lose control of the camera IE, you could not call base.camera.lookAt(avatarNode), because it gets overridden by the enableMouse stuff. If you need a button to disable the “roaming ralph” feel, you will need to write your own camera handling functions such that you can manipulate the camera around and call a lookAt(avatarNode) at the end of this (likely a task). If you need some help with this code send me a PM :slight_smile:.

Look into Pushers and Collisions in the manual, hopefully that will be of some help. If anyone else has some examples of this to help Eric48k out, it would be really nice; i am only theorizing here :slight_smile:.

-R

@Anya

The first thing I did after installing Panda3d was running and playing every sample program in the box. I remember I though you can do this with so few lines of code? wow I just though everybody would have felt the same curiosity.

@Azraiyl

Sorry in advance, only problems to answer your post:
Grand canyon scenario is not in my game, but I get your point, I suppose auto-placing the camera would be pretty hard. I wanted to let the user to move the camera for such cases.

Sacred style: mine is not a pro game, just two floors and most time stuck in the 1st

DungeonSiege style: I like this approach, I think this way can work very well. The only drawback is that I would need to rework my building models to split rooms into 4 walls, add the ray and probably some more changes I don’t see now. A good choice if I had had it in mind from the start.

@rwhughst Hmm, if geometry stops the camera from following the hero, then I think the hero could go out of frame, or if the camera is left too much behind it would have to ‘leap’ forward.

Maybe I try with some little task helping to move the camera in troublesome spots.

Thanks

Parenting camera to the avatar doesn’t seem necessary. You can just as easily put the camera in the global root, for example. The important part is writing a controller/task that, each frame, figures out where the camera should be, where it is, and makes it move in the right direction. Where the camera should be is determined not only by a desired location behind the avatar (which could be a node parented to the avatar), but also by one or more ray casts or capsule sweeps from some point that you know you want visible (say, the back of the avatar’s head) towards the desired position. If there’s something in the way, you have to adjust what you think the desired position is.

After some changes here and there, I’ve found a very simple solution that seems to work pretty fine. It’s still under tests but no problem so far. Since it’s tiny enough to write it down, I post it here for curious fellows or people facing the same problem in the future.

This is my normal camera mode code (3rd person + follow the avatar)

base.disableMouse()
self.mouseCam=0
self.CameraNode.reparentTo(myAvatar)
self.CameraNode.setPos(myAvatar,Point3(0,-30,20))
self.CameraNode.setHpr(VBase3(0,0,0))
base.camera.reparentTo(self.CameraNode)
base.camera.setPos(0,0,0)
base.camera.lookAt(myAvatar)
base.camera.setP(-10)

and my free camera mode - camera stands in place while avatar moves

if self.mouseCam==0:
    #free cam
    mat=Mat4(camera.getMat())
    mat.invertInPlace()
    base.mouseInterfaceNode.setMat(mat)
    posRender=base.camera.getPos(render)
    self.CameraNode.reparentTo(render)
    self.CameraNode.setPos(posRender)
    temp=myAvatar.getHpr()
    self.CameraNode.setHpr(temp)
    base.camera.reparentTo(self.CameraNode)
    base.enableMouse()
    self.mouseCam=1
    base.camera.setP(-10)

I call one or another depending on different keys for each camera mode. The trick is having a cameraNode to mess with instead of setting the position of base.camera directly, as that cause conflicts with internal mouse/camera code (so I think)