Game Development Community

RTSCamera that doesn't bounce to terrain height

by BillF · 02/10/2008 (10:36 am) · 4 comments

While working on a water based RTS game I wanted to shut off the RTSCamera feature that adjusts the camera current height by a factor of the current camera position's underlying terrain height. In my case, the camera was adjusting to the bottom of the ocean which didn't make to much sense.

The code that performs the height adjustment in RTSCamera.cc makes use of the method getTerrHeight which returns the terrain height of the camera's current position, and adds it to the cameras current normal height.

The new code that allows this this features to be turned off just checks a new RTSCamera flag mAdjustToTerrainHeight, and then either adds the terrain height to the normal height or doesn't. I added a new method getAdjustedHeight that wraps the common task of getting the datablock, checking the flag, and calculating the height based on the flag and keeps this change a little less intrusive.

Here are the changes.

In RTSCamera.h

after

F32 mMaxAngle;

add

bool mAdjustToTerrainHeight;

then after
F32 getTerrHeight(Point2F lamePos);

add

F32 getAdjustedHeight(Point2F CurrentPos, F32 NormalHeight);


in RTSCamera.cc

in RTSCameraData::RTSCameraData

after

mAngleStep = 5;

add

mAdjustToTerrainHeight = true;

NOTE: We're defaulting to the standard behavior. The camera's datablock in the script will shut it off.

in RTSCameraData::packData

after

stream->write(mOrbitStep);

add

stream->writeFlag(mAdjustToTerrainHeight);

in RTSCameraData::unpackData

after

stream->read(&mOrbitStep);

add

mAdjustToTerrainHeight = stream->readFlag();

in RTSCameraData::initPersistFields

after

addField("minAngle",      TypeF32, Offset(mMinAngle,      RTSCameraData));

add

addField("AdjustToTerrainHeight", TypeBool, Offset(mAdjustToTerrainHeight, RTSCameraData));

in RTSCamera::onAdd

after

mTargetPos.y = getPosition().y;

add

RTSCameraData* data = (RTSCameraData*)mDataBlock;
   if (!data->mAdjustToTerrainHeight)
   {
    mCurrHeight = (mDataBlock->mMaxOrbitHeight + mDataBlock->mMinOrbitHeight)/2;
   }

in RTSCamera::setCameraPosition

replace

F32 realHeight = getTerrHeight(pos) + mCurrHeight;

with

F32 realHeight = getAdjustedHeight(pos, mCurrHeight);

replace

endPos.z = getTerrHeight(Point2F(endPos.x, endPos.y)) + mCurrHeight;

with

endPos.z = getAdjustedHeight(Point2F(endPos.x, endPos.y), mCurrHeight);


in RTSCamera::getViewableRect

NOTE: This isn't actually required but I think it makes the selection box in the hudmap look a little more accurate in both configurations.

replace

F32 height = mCurrHeight;

with

F32 height = mCurrHeight/2;

(back to the required changes...)

in RTSCamera::processTick

replace

pos.z = getTerrHeight(mTargetPos) + mCurrHeight;

with

pos.z = getAdjustedHeight(mTargetPos, mCurrHeight);

replace

pos.z = getTerrHeight(Point2F(pos.x, pos.y)) + interpHeight;

with

pos.z = getAdjustedHeight(Point2F(pos.x, pos.y), interpHeight);

after the method RTSCamera::getTerrHeight

add the new method

F32 RTSCamera::getAdjustedHeight(Point2F CurrentPos, F32 NormalHeight)
{
   RTSCameraData *pDB = (RTSCameraData*)mDataBlock;
   return NormalHeight + (pDB->mAdjustToTerrainHeight?getTerrHeight(CurrentPos):0);
}


Then finally in the scripts \server\scripts\items\camera.cs

after

minAngle = 20;

add

AdjustToTerrainHeight = false;

NOTE: You will probably need to increase both

maxHeight = 50.0;
   minHeight = 5.0;

to appropriate values for your map. Previously these values meant "height above terrain", and now they are the actual world height, so be sure to set the min and max above the highest terrain point possible in the map.

About the author

Recent Blogs


#1
02/10/2008 (4:30 pm)
Bill, I just finished reading the whole changes guide. Awesome job man, I'll try to add this to an stock codebase for testing, and we'll see if we can include this on the next iteration of the kit port as an standard feature!


Next assingnment: particles on the units... (sorry, you should never have mention it... XD )
#2
02/10/2008 (5:17 pm)
Wicked Bill. Thanks for sharing :D
#3
02/10/2008 (6:04 pm)
Thanks guys!

Novak, I should be able to post the damage particle emitters this week. Let's see if I can put them in the right spot this time :)
#4
04/11/2008 (6:01 am)
Hi :)

I made a little modification to getAdjustedHeight, so i don't have to adjust the max-/minHeight.
The disadvatage is that the initial Point (firstheight) should be arround a usable Terrainheight.
It also takes care about the cam getting under the terrain:

F32 RTSCamera::getAdjustedHeight(Point2F CurrentPos, F32 NormalHeight)
{
   static F32 firstHeight = -1;

   RTSCameraData *pDB = (RTSCameraData*)mDataBlock;
   F32 terrHeight = getTerrHeight(CurrentPos);

    if (firstHeight < 0 ) 
		firstHeight = terrHeight;
    

   if ( pDB->mAdjustToTerrainHeight ) 
		return NormalHeight + terrHeight;

   if (NormalHeight + firstHeight < terrHeight) 
			return terrHeight+ pDB->mMinOrbitHeight;

   return NormalHeight + firstHeight;
}