1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/raycastlib.git synced 2024-11-23 20:49:57 +01:00

Improve ceiling drawing

This commit is contained in:
Miloslav Číž 2018-09-03 08:14:36 +02:00
parent 31c84a27af
commit d1aa2658ee

View file

@ -214,6 +214,11 @@ Unit clamp(Unit value, Unit valueMin, Unit valueMax)
return value; return value;
} }
inline Unit absVal(Unit value)
{
return value < 0 ? -1 * value : value;
}
// Bhaskara's cosine approximation formula // Bhaskara's cosine approximation formula
#define trigHelper(x) (((Unit) UNITS_PER_SQUARE) *\ #define trigHelper(x) (((Unit) UNITS_PER_SQUARE) *\
(UNITS_PER_SQUARE / 2 * UNITS_PER_SQUARE / 2 - 4 * (x) * (x)) /\ (UNITS_PER_SQUARE / 2 * UNITS_PER_SQUARE / 2 - 4 * (x) * (x)) /\
@ -529,17 +534,17 @@ uint16_t _middleRow = 0;
void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray) void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
{ {
int_maybe32_t y = _camResYLimit; // on screen y, will only go upwards int_maybe32_t y = _camResYLimit; // screen y (for floor), will only go up
int_maybe32_t y2 = 0; // screen y (for ceil), will only fo down
int_maybe32_t y2 = 0;
Unit worldZPrev = _startHeight; Unit worldZPrev = _startHeight;
Unit worldZPrevCeil = UNITS_PER_SQUARE * 5 + _startHeight; Unit worldZPrevCeil = UNITS_PER_SQUARE * 5 + _startHeight;
PixelInfo p; PixelInfo p;
p.position.x = x; p.position.x = x;
// we'll be simulatenously drawing the floor and the ceiling now
for (uint_maybe32_t j = 0; j < hitCount; ++j) for (uint_maybe32_t j = 0; j < hitCount; ++j)
{ {
HitResult hit = hits[j]; HitResult hit = hits[j];
@ -559,82 +564,63 @@ Unit worldZPrevCeil = UNITS_PER_SQUARE * 5 + _startHeight;
Unit worldZ2 = wallHeight - _camera.height; Unit worldZ2 = wallHeight - _camera.height;
Unit worldZ2Ceil = (UNITS_PER_SQUARE * 5 - wallHeight) - _camera.height; Unit worldZ2Ceil = (UNITS_PER_SQUARE * 5 - wallHeight) - _camera.height;
int16_t z1Screen = _middleRow - int16_t z1Screen = _middleRow - perspectiveScale(
perspectiveScale( (worldZPrev * _camera.resolution.y) / UNITS_PER_SQUARE,dist,1);
(worldZPrev * _camera.resolution.y) / UNITS_PER_SQUARE,
dist,1);
z1Screen = clamp(z1Screen,0,_camResYLimit); z1Screen = clamp(z1Screen,0,_camResYLimit);
int16_t z1ScreenCeil = _middleRow - int16_t z1ScreenCeil = _middleRow - perspectiveScale(
perspectiveScale( (worldZPrevCeil * _camera.resolution.y) / UNITS_PER_SQUARE,dist,1);
(worldZPrevCeil * _camera.resolution.y) / UNITS_PER_SQUARE,
dist,1);
z1ScreenCeil = clamp(z1ScreenCeil,0,_camResYLimit); z1ScreenCeil = clamp(z1ScreenCeil,0,_camResYLimit);
int16_t z2Screen = _middleRow - int16_t z2Screen = _middleRow - perspectiveScale(
perspectiveScale( (worldZ2 * _camera.resolution.y) / UNITS_PER_SQUARE,dist,1);
(worldZ2 * _camera.resolution.y) / UNITS_PER_SQUARE,
dist,1);
z2Screen = clamp(z2Screen,0,_camResYLimit); z2Screen = clamp(z2Screen,0,_camResYLimit);
int16_t z2ScreenCeil = _middleRow - int16_t z2ScreenCeil = _middleRow - perspectiveScale(
perspectiveScale( (worldZ2Ceil * _camera.resolution.y) / UNITS_PER_SQUARE,dist,1);
(worldZ2Ceil * _camera.resolution.y) / UNITS_PER_SQUARE,
dist,1);
z2ScreenCeil = clamp(z2ScreenCeil,0,_camResYLimit);
z2ScreenCeil = clamp(z2ScreenCeil,0,_camResYLimit);
Unit zTop = z1Screen < z2Screen ? z1Screen : z2Screen; Unit zTop = z1Screen < z2Screen ? z1Screen : z2Screen;
Unit zBottomCeil = z1ScreenCeil > z2ScreenCeil ?
z1ScreenCeil : z2ScreenCeil;
Unit zBottomCeil = z1ScreenCeil > z2ScreenCeil ? z1ScreenCeil : z2ScreenCeil; if (zTop <= zBottomCeil)
zBottomCeil = zTop; // walls on ceiling and floor met
// draw floor until wall
if (zTop <= zBottomCeil)
zBottomCeil = zTop;
// draw floor until the wall
p.isWall = 0; p.isWall = 0;
Unit floorCameraDiff = _camera.height - worldZPrev; Unit floorCameraDiff = absVal(worldZPrev) * 4;
for (int_maybe32_t i = y; i > z1Screen; --i) for (int_maybe32_t i = y; i > z1Screen; --i)
{ {
p.position.y = i; p.position.y = i;
p.depth = (_camera.resolution.y - i) * _floorDepthStep + p.depth = (_camera.resolution.y - i) * _floorDepthStep + floorCameraDiff;
floorCameraDiff * 2;
_pixelFunction(p); _pixelFunction(p);
} }
// draw ceiling until wall
Unit ceilCameraDiff = worldZPrevCeil - _camera.height; Unit ceilCameraDiff = absVal(worldZPrevCeil) * 4;
for (int_maybe32_t i = y2; i < z1ScreenCeil; ++i) for (int_maybe32_t i = y2; i < z1ScreenCeil; ++i)
{ {
p.position.y = i; p.position.y = i;
p.depth = i * _floorDepthStep + ceilCameraDiff;
_pixelFunction(p);
}
p.depth = i * _floorDepthStep + ceilCameraDiff * 2; // draw wall
_pixelFunction(p);
}
// draw the wall
p.isWall = 1; p.isWall = 1;
p.depth = 1;
p.depth = dist; p.depth = dist;
for (int_maybe32_t i = z1Screen < y ? z1Screen : y; i > z2Screen; --i) for (int_maybe32_t i = z1Screen < y ? z1Screen : y; i > z2Screen; --i)
@ -644,54 +630,55 @@ p.depth = 1;
_pixelFunction(p); _pixelFunction(p);
} }
for (int_maybe32_t i = z1ScreenCeil > y2 ? z1ScreenCeil : y2; i < z2ScreenCeil; ++i) // draw ceiling wall
{
p.position.y = i; for (int_maybe32_t i = z1ScreenCeil > y2 ? z1ScreenCeil : y2;
p.hit = hit; i < z2ScreenCeil; ++i)
_pixelFunction(p); {
} p.position.y = i;
p.hit = hit;
_pixelFunction(p);
}
y = y > zTop ? zTop : y; y = y > zTop ? zTop : y;
worldZPrev = worldZ2; worldZPrev = worldZ2;
y2 = y2 < zBottomCeil ? zBottomCeil : y2; y2 = y2 < zBottomCeil ? zBottomCeil : y2;
worldZPrevCeil = worldZ2Ceil;
if (y <= y2) worldZPrevCeil = worldZ2Ceil;
break;
if (y <= y2)
break; // walls on ceiling and floor met
} }
// draw floor until horizon // draw floor until horizon
p.isWall = 0; p.isWall = 0;
Unit floorCameraDiff = _camera.height - worldZPrev; Unit floorCameraDiff = absVal(worldZPrev) * 4;
uint16_t horizon = y <= y2 ? y : _middleRow; uint16_t horizon = y <= y2 ? y : _middleRow;
for (int_maybe32_t i = y; i >= horizon; --i) for (int_maybe32_t i = y; i >= horizon; --i)
{ {
p.position.y = i; p.position.y = i;
p.depth = (_camera.resolution.y - i) * _floorDepthStep + p.depth = (_camera.resolution.y - i) * _floorDepthStep + floorCameraDiff;
floorCameraDiff * 2;
_pixelFunction(p); _pixelFunction(p);
} }
/* // draw ceiling until horizon
Unit ceilCameraDiff = worldZPrevCeil - _camera.height;
for (int_maybe32_t i = y2; i < horizon; ++i) Unit ceilCameraDiff = absVal(worldZPrevCeil) * 4;
{
p.position.y = i; for (int_maybe32_t i = y2; i < horizon; ++i)
p.depth = (_camera.resolution.y - i) * _floorDepthStep + {
floorCameraDiff * 2; p.position.y = i;
p.depth = i * _floorDepthStep + ceilCameraDiff;
_pixelFunction(p);
}
_pixelFunction(p);
}
*/
} }
void render(Camera cam, ArrayFunction arrayFunc, PixelFunction pixelFunc, void render(Camera cam, ArrayFunction arrayFunc, PixelFunction pixelFunc,