Rewrite map_Height so that the height it reports matches with what the terrain renderer shows.
git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@6838 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
da04dd5173
commit
380c32bb33
197
src/map.c
197
src/map.c
|
@ -1817,146 +1817,105 @@ BOOL mapShutdown(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return linear interpolated height of x,y */
|
/// The height of the terrain at the specified world coordinates
|
||||||
extern SWORD map_Height(int x, int y)
|
extern SWORD map_Height(int x, int y)
|
||||||
{
|
{
|
||||||
int retVal, tileX, tileY, tileYOffset, tileX2, tileY2Offset, dx, dy, ox, oy;
|
int tileX, tileY;
|
||||||
int h0, hx, hy, hxy, wTL = 0, wTR = 0, wBL = 0, wBR = 0;
|
int i, j;
|
||||||
BOOL bWaterTile = false;
|
float height[2][2], center;
|
||||||
|
float onTileX, onTileY;
|
||||||
|
float left, right, middle;
|
||||||
|
float onBottom, result;
|
||||||
|
float towardsCenter, towardsRight;
|
||||||
|
|
||||||
ASSERT(x >= 0, "map_Height: Negative x value");
|
// make sure we have valid coordinates
|
||||||
ASSERT(y >= 0, "map_Height: Negative y value");
|
if (x < 0 ||
|
||||||
|
y < 0 ||
|
||||||
|
x >= world_coord(mapWidth-1) ||
|
||||||
|
y >= world_coord(mapHeight-1))
|
||||||
|
{
|
||||||
|
// we don't so give an arbitrary height
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
x = (x >= world_coord(mapWidth) ? world_coord(mapWidth - 1) : x);
|
// on which tile are these coords?
|
||||||
y = (y >= world_coord(mapHeight) ? world_coord(mapHeight - 1) : y);
|
|
||||||
|
|
||||||
/* Turn into tile coordinates */
|
|
||||||
tileX = map_coord(x);
|
tileX = map_coord(x);
|
||||||
tileY = map_coord(y);
|
tileY = map_coord(y);
|
||||||
|
|
||||||
/* Inter tile comp */
|
// where on the tile? (scale to (0,1))
|
||||||
ox = map_round(x);
|
onTileX = (x - world_coord(tileX))/(float)world_coord(1);
|
||||||
oy = map_round(y);
|
onTileY = (y - world_coord(tileY))/(float)world_coord(1);
|
||||||
|
|
||||||
if (terrainType(mapTile(tileX,tileY)) == TER_WATER)
|
// get the height for the corners and center
|
||||||
|
center = 0;
|
||||||
|
for (i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
bWaterTile = true;
|
for (j = 0; j < 2; j++)
|
||||||
wTL = environGetValue(tileX,tileY)/2;
|
|
||||||
wTR = environGetValue(tileX+1,tileY)/2;
|
|
||||||
wBL = environGetValue(tileX,tileY+1)/2;
|
|
||||||
wBR = environGetValue(tileX+1,tileY+1)/2;
|
|
||||||
}
|
|
||||||
|
|
||||||
// to account for the border of the map
|
|
||||||
if(tileX + 1 < mapWidth)
|
|
||||||
{
|
|
||||||
tileX2 = tileX + 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tileX2 = tileX;
|
|
||||||
}
|
|
||||||
tileYOffset = (tileY * mapWidth);
|
|
||||||
if(tileY + 1 < mapHeight)
|
|
||||||
{
|
|
||||||
tileY2Offset = tileYOffset + mapWidth;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tileY2Offset = tileYOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
ASSERT( ox < TILE_UNITS, "mapHeight: x offset too big" );
|
|
||||||
ASSERT( oy < TILE_UNITS, "mapHeight: y offset too big" );
|
|
||||||
ASSERT( ox >= 0, "mapHeight: x offset too small" );
|
|
||||||
ASSERT( oy >= 0, "mapHeight: y offset too small" );
|
|
||||||
|
|
||||||
//different code for 4 different triangle cases
|
|
||||||
if (psMapTiles[tileX + tileYOffset].texture & TILE_TRIFLIP)
|
|
||||||
{
|
|
||||||
if ((ox + oy) > TILE_UNITS)//tile split top right to bottom left object if in bottom right half
|
|
||||||
{
|
{
|
||||||
ox = TILE_UNITS - ox;
|
height[i][j] = map_TileHeight(tileX+i, tileY+j);
|
||||||
oy = TILE_UNITS - oy;
|
center += height[i][j];
|
||||||
hy = psMapTiles[tileX + tileY2Offset].height;
|
|
||||||
hx = psMapTiles[tileX2 + tileYOffset].height;
|
|
||||||
hxy= psMapTiles[tileX2 + tileY2Offset].height;
|
|
||||||
if(bWaterTile)
|
|
||||||
{
|
|
||||||
hy+=wBL;
|
|
||||||
hx+=wTR;
|
|
||||||
hxy+=wBR;
|
|
||||||
}
|
|
||||||
|
|
||||||
dx = ((hy - hxy) * ox )/ TILE_UNITS;
|
|
||||||
dy = ((hx - hxy) * oy )/ TILE_UNITS;
|
|
||||||
|
|
||||||
retVal = (SDWORD)(((hxy + dx + dy)) * ELEVATION_SCALE);
|
|
||||||
ASSERT( retVal<MAX_HEIGHT,"Map height's gone weird!!!" );
|
|
||||||
return ((SWORD)retVal);
|
|
||||||
}
|
}
|
||||||
else //tile split top right to bottom left object if in top left half
|
}
|
||||||
|
center /= 4;
|
||||||
|
|
||||||
|
// we have:
|
||||||
|
// y ->
|
||||||
|
// x 0,0 A 0,1
|
||||||
|
// |
|
||||||
|
// V D center B
|
||||||
|
//
|
||||||
|
// 1,0 C 1,1
|
||||||
|
|
||||||
|
// get heights for left and right corners and the distances
|
||||||
|
if (onTileY > onTileX)
|
||||||
|
{
|
||||||
|
if (onTileY < 1 - onTileX)
|
||||||
{
|
{
|
||||||
h0 = psMapTiles[tileX + tileYOffset].height;
|
// A
|
||||||
hy = psMapTiles[tileX + tileY2Offset].height;
|
right = height[0][0];
|
||||||
hx = psMapTiles[tileX2 + tileYOffset].height;
|
left = height[0][1];
|
||||||
|
towardsCenter = onTileX;
|
||||||
if(bWaterTile)
|
towardsRight = 1 - onTileY;
|
||||||
{
|
}
|
||||||
h0+=wTL;
|
else
|
||||||
hy+=wBL;
|
{
|
||||||
hx+=wTR;
|
// B
|
||||||
}
|
right = height[0][1];
|
||||||
dx = ((hx - h0) * ox )/ TILE_UNITS;
|
left = height[1][1];
|
||||||
dy = ((hy - h0) * oy )/ TILE_UNITS;
|
towardsCenter = 1 - onTileY;
|
||||||
|
towardsRight = 1 - onTileX;
|
||||||
retVal = (SDWORD)((h0 + dx + dy) * ELEVATION_SCALE);
|
|
||||||
ASSERT( retVal<MAX_HEIGHT,"Map height's gone weird!!!" );
|
|
||||||
return ((SWORD)retVal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ox > oy) //tile split topleft to bottom right object if in top right half
|
if (onTileX > 1 - onTileY)
|
||||||
{
|
{
|
||||||
h0 = psMapTiles[tileX + tileYOffset].height;
|
// C
|
||||||
hx = psMapTiles[tileX2 + tileYOffset].height;
|
right = height[1][1];
|
||||||
ASSERT( tileX2 + tileY2Offset < mapWidth*mapHeight, "array out of bounds");
|
left = height[1][0];
|
||||||
hxy= psMapTiles[tileX2 + tileY2Offset].height;
|
towardsCenter = 1 - onTileX;
|
||||||
|
towardsRight = onTileY;
|
||||||
if(bWaterTile)
|
|
||||||
{
|
|
||||||
h0+=wTL;
|
|
||||||
hx+=wTR;
|
|
||||||
hxy+=wBR;
|
|
||||||
}
|
|
||||||
dx = ((hx - h0) * ox )/ TILE_UNITS;
|
|
||||||
dy = ((hxy - hx) * oy )/ TILE_UNITS;
|
|
||||||
retVal = (SDWORD)(((h0 + dx + dy)) * ELEVATION_SCALE);
|
|
||||||
ASSERT( retVal<MAX_HEIGHT,"Map height's gone weird!!!" );
|
|
||||||
return ((SWORD)retVal);
|
|
||||||
}
|
}
|
||||||
else //tile split topleft to bottom right object if in bottom left half
|
else
|
||||||
{
|
{
|
||||||
h0 = psMapTiles[tileX + tileYOffset].height;
|
// D
|
||||||
hy = psMapTiles[tileX + tileY2Offset].height;
|
right = height[1][0];
|
||||||
hxy = psMapTiles[tileX2 + tileY2Offset].height;
|
left = height[0][0];
|
||||||
|
towardsCenter = onTileY;
|
||||||
if(bWaterTile)
|
towardsRight = onTileX;
|
||||||
{
|
|
||||||
h0+=wTL;
|
|
||||||
hy+=wBL;
|
|
||||||
hxy+=wBR;
|
|
||||||
}
|
|
||||||
dx = ((hxy - hy) * ox )/ TILE_UNITS;
|
|
||||||
dy = ((hy - h0) * oy )/ TILE_UNITS;
|
|
||||||
|
|
||||||
retVal = (SDWORD)((h0 + dx + dy) * ELEVATION_SCALE);
|
|
||||||
ASSERT( retVal<MAX_HEIGHT,"Map height's gone weird!!!" );
|
|
||||||
return ((SWORD)retVal);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
ASSERT(towardsCenter <= 0.5, "towardsCenter is too high");
|
||||||
|
|
||||||
|
// now we have:
|
||||||
|
// center
|
||||||
|
// left m right
|
||||||
|
|
||||||
|
middle = (left + right)/2;
|
||||||
|
onBottom = left * (1 - towardsRight) + right * towardsRight;
|
||||||
|
result = onBottom + (center - middle) * towardsCenter * 2;
|
||||||
|
|
||||||
|
return (SDWORD)(result+0.5f);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns true if object is above ground */
|
/* returns true if object is above ground */
|
||||||
|
|
Loading…
Reference in New Issue