Smoothing a parented camera

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
timetokill
Posts: 74
Joined: Tue Jul 22, 2008 4:28 am
Location: Los Angeles

Smoothing a parented camera

Post by timetokill »

Hello,

This is a kind of specific question so I will try to be as clear as possible.

To start off: In my game, the character runs in a circle, and the camera view it from the outside, following alongside the character. In this sense, the action has a sort of 2D feel... the character can only move left and right (and jump) but he can't move in or out from the camera.

On to the problem.

My camera system is set up where I have the camera parented to the character it follows, but it also has a series of targets that the camera can look at simultaneously. The way I am doing this is by making the camera look at the midpoint between the target objects. In practice it works pretty well if things are moving. I have a setup now where as the character runs he casts a target point ahead of himself, and the camera turns to look at the point. The faster the character runs, the more the camera turns to look ahead of him.

The problem I have, however, is when I do a jump and hit the ground, the camera "snaps" very quickly and jarringly to the newest orientation. I want to smoothly interpolate between the camera view targets but I can't seem to pull it off. I've tried lerping but I don't seem to be getting it. Any help would be greatly appreciated. Here's some sample code of what I'm working on:

Code: Select all

vector3df Camera::calculateMultiLookVector(irr::u32 numberOfObjects = 0)
	{
		if(hasTarget)
		{
			u32 pTotal = 0;			//local var for number of objects to look at

			//check to make sure we're looking at an appropriate number of objects
			if(numberOfObjects == 0)
				pTotal = targetList.size();
			else
				pTotal = numberOfObjects;


			//if(pTotal < 2)
			//	return primaryTarget->getPosition();		//break out if we don't have anything to look at, returning the main target's position

			//our return variable, start with the main target's position
			vector3df midPoint = targetList[0]->getPosition();

			if(pTotal > 1)
			{
				for(u32 i = 1; i < pTotal-1; i++)		//start at 1 because 0 is our primary target position, which we already have
				{
					line3d<f32> iLine;
					iLine.start = midPoint;
					iLine.end = targetList[i]->getPosition();

					midPoint = iLine.getMiddle();
				}
			}

			if(hasLookPoint)
			{
				//now, if we have an extra point to look at, we need to consider it as well!
				line3d<f32> jLine;
				jLine.start = midPoint;
				jLine.end = lookPoint;

				if(jLine.end.Y < 0.0f)
					jLine.end.Y = 0.0f;

				midPoint = jLine.getMiddle();
			}

			//we're done!  let's return the midpoint
			return midPoint;
		}

		return vector3df(0.0f,0.0f,0.0f);			//return the origin if we don't have any target to look at
	}

In my code, the jLine is drawn between where the character is and the velocity point the character casts out in front of himself as he runs. If the character is just running ahead, it works spectacularly. It even works fine in mid-jump!

The main problem is when the character hits the ground, and where the camera needs to look is vastly different from the previous frame (because the velocity point is suddenly now at the character instead of like 10 feet in front of him). I tried using lerp to go between large values but then the camera work gets really jittery and seems to basically fall apart. I'm probably using lerp wrong :?

Any help would be greatly appreciated! :)
Apoptyzm
Posts: 19
Joined: Tue Sep 23, 2008 7:53 pm

Post by Apoptyzm »

maybe You should use for example 1/10 length of a line in each frame and not always half of a line. Or 1/xx of length where xx depends on last movement of the object compared to last position.
rogerborg
Admin
Posts: 3590
Joined: Mon Oct 09, 2006 9:36 am
Location: Scotland - gonnae no slag aff mah Engleesh
Contact:

Post by rogerborg »

Do I understand the situation correctly?

Image

In 1) the character is starting to jump, so the velocity and look-point move up. In 2) the character is mid jump, and the velocity is all horizontal. In 3) the character is falling and about to hit the ground, so its vertical velocity is at a (negative) maximum, and in 4) the character has hit the ground and his velocity immediately becomes horizontal.

What you want to avoid is the big difference between the last moment of phase 3 and the first moment of phase 4?

Offhand, I'd suggest that you get the "ground" height under the character by (e.g.) projecting a vector straight down and colliding it with the level geometry, or getting the terrain height at its X,Z position, or an appropriate method for your "ground".

Then bump that height up so that it's at the 'eye' height of the character (i.e. the height if it were moving horizontally at that position), and raise the end point of the velocity vector (if necessary) to match that height.

That should naturally smooth out the look vector as the character comes in to land.

Of course, I may have completely misinterpreted the problem. For one thing, I'm not sure why you wouldn't get the same problem at the start of the jump, when the velocity is at its positive maximum.
Please upload candidate patches to the tracker.
Need help now? IRC to #irrlicht on irc.freenode.net
How To Ask Questions The Smart Way
timetokill
Posts: 74
Joined: Tue Jul 22, 2008 4:28 am
Location: Los Angeles

Post by timetokill »

Roger, you've got the problem down perfectly. I wish I'd have thought of making that handy picture!

I'm going to try your method but I am also considering that I should probably have not mounted the camera to the character in the first place. What you are saying makes sense so it should solve the problem on the landing condition.

To answer your question about why it wasn't happening at the start of the jump, it was because I didn't really have "jump" properly implemented -- I was adding a force as much as I wanted (and so it started slowly, and kept incrementing) instead of applying one big force at the beginning of the jump. Your comment led me to try the forceful jump and it had the camera movement problem, as expected.

Overall I think parenting the camera is a bad idea for character movement so I'll probably just switch it to one where code drives the camera movement. But first I will attempt your solution to verify :)

Thanks, I'll update with my findings.


Edit: The problem was on its way to being resolved. I tried getting the camera to stop at the end point of the velocity vector at the point of the ground instead of below it, and it helped immensely. Of course, there were other problems (such as the initial jump as well!)

I decided to use a version of Vitek's code (posted at: http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=17033) that has been modified to fit my application.

Thanks again roger, you were a huge help :D
Post Reply