Game Development Community

Slopes and XY axis - Bounding Box Rotation

by Swaroop Reddy · in RTS Starter Kit · 10/22/2007 (4:34 pm) · 7 replies

Does any one have any idea how to get RTS units to rotate along the X and Y axis when ther are one a hill slope. The Racing starter kit shows that the vehicle bounding box rotates in the approrate direction along the X and Y axis when it is on a slope. How can this be implemented on an RTS unit. For bipeds this is not an issue but for animals such as horses it is a MAJOR draw back. Imagine a horse climbing up a hill without rotating its body to match the slope - NOT VERY PLEASANT. I havent seen this addresed anywhere in the forums.

#1
10/22/2007 (8:40 pm)
One option could be to calculate the slope angle with raycasts and then apply that rotation to the model. That could be problematic though, coz the permantly raycasting of units. This is the second time in two weeks that I quote the same phrase from Johnathan Moore:
Quote:"...you could put in a method containing two raycasts onto the terrain in front and behind the unit, then get the angle between the two contact points."
A better idea could be to use some pathfinding mechanism wich in some nodes set a flag to activate the use of the raycasting.

And a second option could be to directly store the angle info in each node of your pathfinding hexagonal grid. You would do the calcs only once, on map generation. Then the units should be rotated accordingly to that stored value.
#2
10/22/2007 (9:00 pm)
Animals follow the slope perfectly in the game Wildlife Tycoon: Venture Africa. Both of the methods above will tell me when and how much to rotate the unit. BUT RTS units DO NOT rotate along the X or Y axis even if you use setTransform(). They only rotate along Z axis. There must tbe some way to rotate them.
#3
10/22/2007 (10:15 pm)
Ahh! now i see what you mean. I didnt know that, if i have time ill try to look around.
#4
10/28/2007 (3:34 am)
The link below shows how it is done for the player class. I am not sure how to implement for RTSUnit class.

www.garagegames.com/index.php?sec=mg&mod=resource&page=view&qid=3148
#5
11/11/2007 (1:04 pm)
IT WORKS!!! I trimmed the above code a bit for the RTS engine.

Just follow the modifications below for player.cc and player.h

NOW YOUR RTS UNITS WILL LOOK COOL GOING UP THE HILL.

In player.cc
-----------------------------------------------------------------------------------------
At the bottom of PlayerData::PlayerData() add:
conformToGround = true;

At the bottom of PlayerData::initPersistFields() add:
addField("conformToGround", TypeBool, Offset(conformToGround, PlayerData));


At the bottom of PlayerData::packData(BitStream* stream) add:
stream->write(conformToGround);


At the bottom of PlayerData::unpackData(BitStream* stream) add:
stream->read(&conformToGround);


To Player::setPosition(const Point3F& pos,const Point3F& rot) add the following code to the end of the "else" clause:
if (mDataBlock && mDataBlock->conformToGround)
{
RayInfo surfaceInfo;
Point3F above = Point3F(pos.x,pos.y,pos.z + 0.5f);
Point3F below = Point3F(pos.x,pos.y,pos.z - 100.0f);
if (gClientContainer.castRay(above,below,TerrainObjectType | InteriorObjectType,&surfaceInfo))
{
Point3F x,y,z;
z = surfaceInfo.normal;
z.normalize();
mat.getColumn(1,&y);
mCross(y,z,&x);
x.normalize();
mCross(z,x,&y);
mat.setColumn(0,x);
mat.setColumn(1,y);
mat.setColumn(2,z);
}
}

To Player::setRenderPosition(const Point3F& pos, const Point3F& rot, F32 dt) add the following code to the end of the outer else clause:
if (mDataBlock && mDataBlock->conformToGround)
{
RayInfo surfaceInfo;
Point3F above = Point3F(pos.x,pos.y,pos.z + 0.5f);
Point3F below = Point3F(pos.x,pos.y,pos.z - 100.0f);
if (gClientContainer.castRay(above,below,TerrainObjectType | InteriorObjectType,&surfaceInfo))
{
Point3F x,y,z;
z = surfaceInfo.normal;
z.normalize();
mat.getColumn(1,&y);
mCross(y,z,&x);
x.normalize();
mCross(z,x,&y);
mat.setColumn(0,x);
mat.setColumn(1,y);
mat.setColumn(2,z);
}
}

In player.h add the following lines to the bottom of the PlayerData struct:
-------------------------------------------------------------------------------------------
bool conformToGround;

Now you can add the following field to the RTSunit datablock if needed:

conformToGround = 0; // or 1 by default
#6
11/11/2007 (1:57 pm)
Well done! I'll give it a try as soonas I can.
#7
11/11/2007 (3:38 pm)
I wish I could get the unit to only tilt along the slope on the forward vector. I dont like the way that the unit tilts to the side.

Novack, if you figure it out how to do it, let me know please.

Thanks.