Question - Logic Behind the Camera Actuator

Hey guys,

So I’m looking to re-create what the camera actuator does, when it’s damping is set to 0.0, and I was hoping I could get help from people who understand how it works (Zero damping = camera doesn’t orbit around the player when player rotates)

Basically, I’m looking to get a grasp of what the logic behind it is, and how it could be re-created in python (or any other language for that matter) purely cause I genuinely love what that actuator does, and I want to know how it does it.

The way I see it: It sets position based on min/max distance somewhere in the world (this is what I want to look into), & tracks to player (rotates) like a simple track-to actuator.

So, to be more specific:

I’m only looking to get the position-part of it. Don’t care about tracking (rotating) to the object.

So, camera moves when player is too far, or too close, and it should try to find a position in the world that still fits the distance criteria.

Thanks for looking guys, if you can help me out, please do leave a comment!

lol

I haven’t noticed the Damping parameter until this thread.

I would expect it tells the camera how fast (or slow) it moves/tracks the target pose. But it seam to result in different distances. Interestingly as higher that value is as more far away the camera moves - but only if the target moves. On a turn it gets even more distance. Both are not within the desired limits if damping is larger than 1.0.

I have no idea what that behavior is supposed to do. To me it looks not correct (Blender 2.73).

I like the idea of the camera actuator. Unfortunately it does not avoid obstacles. Therefore it is possible it passes through walls. Using it with a physics object (that would collide with a wall) did not result in nice positioning.

I created a Python controller that constantly pushes an object towards a known location (the preferred location.) The force depends on the distance. So it behaves like a rubber-band. [The object gets a gravity counter-force to allow floating (which is independent from the other behavior).]

But this is towards a point not towards an area. It should be not that difficult to calculate the “bring me back to my preferred position”-force dependent on a min/max distance.

I hope you get the idea.

Indeed, something’s up with the damping, that’s why I always leave it at 0. It does mess up angles and distances. Leaving it at 0 means you don’t have to worry about the camera turning with the player.

When damping > 0: It seems to act like a simple slow parent (depending on the damping value), and orbits around the player to the selected Axis, when player rotates.

When damping = 0: Camera ignores axis, and stays at original position when player rotates, and only moves when player gets too close or too far.

One thing I noticed is that:

When player gets too close, the camera kinda moves out the way in various directions (including X, Y, Z, -X, -Y, -Z) - rather than just being pushed to one specific axis. That’s what I’m looking to re-create. I’m assuming straight away this will be running on an Always (True) sensor -> Python module.

Then constantly getDistanceTo player

If distance is greater than property cam [ 'MaxDist' ] -> move towards player

If distance is less than cam [ 'MinDist' ] -> move out of the way

Now, just before I jump right at it, do you think the direction the camera moves in using the “Camera” actuator depend on the camera’s orientation?

Reason:

I was looking to do the camera movement first (position), and then just set up the track-to bit (rotation), so that it also looks at the player. However, I’m starting to think that the rotation of the camera might change the angle it moves in?

Thank you for looking, and apologies about the long post, I just want to gather as much info as I can before I attempt to do this.

Pete

Usually the preferred location depends on the target. So it stays behind it (or left, or right). The direction of the camera is always towards the target like the trackTo actuator does.

So the camera moves towards the preferred location but looks at the target (two different directions).

lol!

I had a look at the KX_CameraActuator source code and found this:



        /* The rules:                                                            */
 205         /* CONSTRAINT 1: not implemented */
 206         /* CONSTRAINT 2: can camera see actor?              */
 207         /* CONSTRAINT 3: fixed height relative to floor below actor.             */
 208         /* CONSTRAINT 4: camera rotates behind actor                              */
 209         /* CONSTRAINT 5: minimum / maximum distance                             */
 210         /* CONSTRAINT 6: again: fixed height relative to floor below actor        */
 211         /* CONSTRAINT 7: track to floor below actor                               */
 212         /* CONSTRAINT 8: look a little bit left or right, depending on how the

it seems a “visibility test was in mind”, but was never implemented:


 229         /* C1: not checked... is a future option                                 */
 230 
 231         /* C2: blender test_visibility function. Can this be a ray-test?         */
 232 
 233         /* C3: fixed height  */

I guess it was never implemented as it is not defined what should happen when the target is not visible.

I can’t understand parts of the remaining code as I have no idea what “fp1”, “fp2”, “rc”, “inp”, “fac”, “distsq” is supposed to be. Unfortunately another example that cryptic abbreviations are cool for a week only.

Wow, good stuff Monster! Never ever looked into Blender’s or the BGE’s source myself… maybe I’m taking on a task that’s beyond my capabilities?! Ah well…

Challenge accepted :slight_smile:

Btw, I do think (now) that the camera’s rotation affects where the camera moves (when player changes position). So the whole thing seems to come down to alignAxis, in my understanding. I’m gonna start experimenting with it this weekend! I’ve got some ideas to try out…

hard to understand where can be the mistake
the suspect is some conflict with that “parent phantom” (the setup of brick should contain all infos without any “offset”)

Getting there!

I’m not exactly happy about having to move the camera on it’s local Z axis back and forth, and separately set the worldPosition.z because it seems to have a bit of a stuttering effect. It doesn’t feel like the most efficient way atm, so any feedback / ideas are welcome.

Here’s what I have so far: [ATTACH]374018[/ATTACH]

I’ve set up a few things that should help debugging / seeing what happens outside of the main camera view.

So, what do you guys think?! If you care to weight in with some helpful information, please do!

I was thinking, instead of applyMovement(), maybe get a direction from cam - to - player and somehow move the camera along that direction, but ignoring the world Z axis (no up/down movement, just left/right & back/forth) so camera would have a fixed “height” without having to set it’s worldPosition.z separately. Is this possible?

Thanks guys,

Pete

yes, should be this :


def movecam(camera, target, mindist, maxdist, height):
    clamp = lambda v,mn,mx: mn if v<mn else mx if v>mx else v


    C = camera.worldPosition
    T = target.worldPosition
    
    vec = C - T  


    vec.z = 0.0
    vec.magnitude = clamp(vec.magnitude, mindist, maxdist)
    vec.z = height


    cam_position_right = T + vec  # correct position (without interpolation)
    camera.worldPosition = cam_position_right