1
0
Fork 0
mirror of https://git.coom.tech/drummyfish/raycastlib.git synced 2024-11-24 20:59:58 +01:00

Fix ceiling

This commit is contained in:
Miloslav Číž 2018-09-13 11:16:28 +02:00
parent 6c35be3177
commit 8cf9617abf

View file

@ -766,25 +766,22 @@ Unit adjustDistance(Unit distance, Camera *camera, Ray *ray)
void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray) void _columnFunction(HitResult *hits, uint16_t hitCount, uint16_t x, Ray ray)
{ {
// last written Y position, can never go backwards
int_maybe32_t fPosY = _camera.resolution.y;
int_maybe32_t cPosY = -1;
#if 1 // world coordinates
Unit fZ1World = _startFloorHeight;
Unit cZ1World = _startCeilHeight;
// last written Y position, can never go backwards PixelInfo p;
int_maybe32_t fPosY = _camera.resolution.y; p.position.x = x;
int_maybe32_t cPosY = -1;
// world coordinates int_maybe32_t i;
Unit fZ1World = _startFloorHeight;
Unit cZ1World = _startCeilHeight;
PixelInfo p; // we'll be simulatenously drawing the floor and the ceiling now
p.position.x = x; for (uint_maybe32_t j = 0; j <= hitCount; ++j)
{ // ^ = add extra iteration for horizon plane
int_maybe32_t i;
// we'll be simulatenously drawing the floor and the ceiling now
for (uint_maybe32_t j = 0; j <= hitCount; ++j)
{ // ^ = add extra iteration for horizon plane
int8_t drawingHorizon = j == hitCount; int8_t drawingHorizon = j == hitCount;
HitResult hit; HitResult hit;
@ -849,11 +846,14 @@ for (uint_maybe32_t j = 0; j <= hitCount; ++j)
drawHorizontal(f,cPosY + 1,_camera.resolution.y,>,-) drawHorizontal(f,cPosY + 1,_camera.resolution.y,>,-)
// ^ purposfully allow outside screen bounds here // ^ purposfully allow outside screen bounds here
if (_ceilFunction != 0 || drawingHorizon)
{
// draw ceiling until wall // draw ceiling until wall
p.isFloor = 0; p.isFloor = 0;
p.depth = (cPosY - _cHorizontalDepthStart) * _horizontalDepthStep; p.depth = (cPosY - _cHorizontalDepthStart) * _horizontalDepthStep;
drawHorizontal(c,-1,fPosY - 1,<,+) drawHorizontal(c,-1,fPosY - 1,<,+)
// ^ purposfully allow outside screen bounds here // ^ purposfully allow outside screen bounds here
}
#undef drawHorizontal #undef drawHorizontal
#undef VERTICAL_DEPTH_MULTIPLY #undef VERTICAL_DEPTH_MULTIPLY
@ -893,7 +893,7 @@ for (uint_maybe32_t j = 0; j <= hitCount; ++j)
// draw ceiling wall // draw ceiling wall
if (cPosY < _camResYLimit) // still pixels left? if (_ceilFunction != 0 && cPosY < _camResYLimit) // still pixels left?
{ {
p.isFloor = 0; p.isFloor = 0;
drawVertical(c,-1,fPosY - 1,<,+) drawVertical(c,-1,fPosY - 1,<,+)
@ -901,266 +901,7 @@ for (uint_maybe32_t j = 0; j <= hitCount; ++j)
#undef drawVertical #undef drawVertical
} }
/*
if (fPosY > 0) // still pixels left undrawn?
{
// draw floor wall
p.isWall = 1;
p.depth = dist;
p.isFloor = 1;
limit = clamp(fZ2Screen,0,_camera.resolution.y);
// ^ allow outside screen at bottom
for (i = fPosY - 1; i >= limit; --i)
{
p.position.y = i;
p.hit = hit;
_pixelFunction(&p);
} }
if (limit < fPosY)
fPosY = limit;
fZ1World = fZ2World; // move to the next level for the next iteration
}
*/
}
#else
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
Unit worldZPrev = _startFloorHeight;
Unit worldZPrevCeil = _startCeilHeight;
PixelInfo p;
p.position.x = x;
#define VERTICAL_DEPTH_MULTIPLY 2
// we'll be simulatenously drawing the floor and the ceiling now
for (uint_maybe32_t j = 0; j < hitCount; ++j)
{
HitResult hit = hits[j];
Unit dist = adjustDistance(hit.distance,&_camera,&ray);
Unit wallHeight = _floorFunction(hit.square.x,hit.square.y);
Unit worldZ2 = wallHeight - _camera.height;
int_maybe32_t z1Screen = _middleRow - perspectiveScale(
(worldZPrev * _camera.resolution.y) / UNITS_PER_SQUARE,dist);
int_maybe32_t z2Screen = _middleRow - perspectiveScale(
(worldZ2 * _camera.resolution.y) / UNITS_PER_SQUARE,dist);
int8_t skipFloorWall = ((z1Screen < 0 && z2Screen < 0) ||
(z1Screen > _camResYLimit && z2Screen > _camResYLimit));
int_maybe32_t z1ScreenNoClamp = z1Screen;
z1Screen = clamp(z1Screen,0,_camResYLimit);
z1Screen = z1Screen > y2 ? z1Screen : y2;
int_maybe32_t wallScreenHeightNoClamp = z1ScreenNoClamp - z2Screen + 1;
wallScreenHeightNoClamp = wallScreenHeightNoClamp == 0 ? 1 :
wallScreenHeightNoClamp;
z2Screen = clamp(z2Screen,0,_camResYLimit);
z2Screen = z2Screen > y2 ? z2Screen : y2;
int_maybe32_t zTop = z1Screen < z2Screen ? z1Screen : z2Screen;
// make the same variables for ceiling
Unit wallHeightCeil = 0;
Unit worldZ2Ceil = 0;
int_maybe32_t z1ScreenCeil = 0;
int_maybe32_t z1ScreenCeilNoClamp = 0;
int_maybe32_t z2ScreenCeil = 0;
int_maybe32_t wallScreenHeightCeilNoClamp = 0;
int_maybe32_t zBottomCeil = y2;
int8_t skipCeilingWall = 1;
if (_ceilFunction != 0)
{
wallHeightCeil = _ceilFunction != 0 ?
_ceilFunction(hit.square.x,hit.square.y) : 0;
worldZ2Ceil = wallHeightCeil - _camera.height;
z1ScreenCeil = _middleRow - perspectiveScale(
(worldZPrevCeil * _camera.resolution.y) / UNITS_PER_SQUARE,dist);
z2ScreenCeil = _middleRow - perspectiveScale(
(worldZ2Ceil * _camera.resolution.y) / UNITS_PER_SQUARE,dist);
skipCeilingWall = ((z1ScreenCeil < 0 && z2ScreenCeil < 0) ||
(z1ScreenCeil > _camResYLimit && z2ScreenCeil > _camResYLimit));
z1ScreenCeilNoClamp = z1ScreenCeil;
z1ScreenCeil = clamp(z1ScreenCeil,0,_camResYLimit);
z1ScreenCeil = z1ScreenCeil < y ? z1ScreenCeil : y;
wallScreenHeightCeilNoClamp =
z2ScreenCeil - z1ScreenCeilNoClamp;
wallScreenHeightCeilNoClamp = wallScreenHeightCeilNoClamp != 0 ?
wallScreenHeightCeilNoClamp : 1;
z2ScreenCeil = clamp(z2ScreenCeil,0,_camResYLimit);
z2ScreenCeil = z2ScreenCeil < y ? z2ScreenCeil : y;
zBottomCeil = z1ScreenCeil > z2ScreenCeil ?
z1ScreenCeil : z2ScreenCeil;
}
if (zTop <= zBottomCeil)
zBottomCeil = zTop; // walls on ceiling and floor met
// draw floor until wall
p.isWall = 0;
p.isFloor = 1;
p.isHorizon = 0;
Unit floorCameraDiff = absVal(worldZPrev) * VERTICAL_DEPTH_MULTIPLY;
for (int_maybe32_t i = y; i > z1Screen; --i)
{
p.position.y = i;
p.depth = (_fHorizontalDepthStart - i) * _horizontalDepthStep + floorCameraDiff;
_pixelFunction(&p);
}
if (z1Screen < y)
y = z1Screen;
// draw ceiling until wall
p.isFloor = 0;
if (_ceilFunction != 0)
{
Unit ceilCameraDiff = absVal(worldZPrevCeil) * VERTICAL_DEPTH_MULTIPLY;
for (int_maybe32_t i = y2; i < z1ScreenCeil; ++i)
{
p.position.y = i;
p.depth = (i - _cHorizontalDepthStart) * _horizontalDepthStep + ceilCameraDiff;
_pixelFunction(&p);
}
if (z1ScreenCeil > y2)
y2 = z1ScreenCeil;
}
// draw floor wall
p.isWall = 1;
p.depth = dist;
p.isFloor = 1;
int_maybe32_t iTo;
if (!skipFloorWall)
{
iTo = y2 < zTop ? zTop : y2;
for (int_maybe32_t i = y; i >= iTo; --i)
{
p.position.y = i;
p.hit = hit;
if (_computeTextureCoords)
p.textureCoordY = UNITS_PER_SQUARE - 1 - ((z1ScreenNoClamp - i) *
UNITS_PER_SQUARE) / wallScreenHeightNoClamp;
_pixelFunction(&p);
}
}
// draw ceiling wall
p.isFloor = 0;
if (!skipCeilingWall)
{
iTo = y > zBottomCeil ? zBottomCeil : y;
for (int_maybe32_t i = y2; i < iTo; ++i)
{
p.position.y = i;
p.hit = hit;
if (_computeTextureCoords)
p.textureCoordY = ((i - z1ScreenCeilNoClamp) *
UNITS_PER_SQUARE) / wallScreenHeightCeilNoClamp;
_pixelFunction(&p);
}
}
y = y > zTop ? zTop : y;
worldZPrev = worldZ2;
y2 = y2 < zBottomCeil ? zBottomCeil : y2;
worldZPrevCeil = worldZ2Ceil;
if (y <= y2)
break; // walls on ceiling and floor met
}
// draw floor until horizon
p.isWall = 0;
p.isFloor = 1;
p.isHorizon = 1;
Unit floorCameraDiff = absVal(worldZPrev) * VERTICAL_DEPTH_MULTIPLY;
Unit horizon = (y2 < _middleRow || _ceilFunction == 0) ? _middleRow : y2;
horizon = clamp(horizon,0,_camera.resolution.y);
horizon += horizon > y2 ? 0 : 1; // bug workaround
for (int_maybe32_t i = y; i >= horizon; --i)
{
p.position.y = i;
p.depth = (_fHorizontalDepthStart - i) * _horizontalDepthStep + floorCameraDiff;
_pixelFunction(&p);
}
y = horizon < y ? horizon : y;
// draw ceiling until horizon
p.isFloor = 0;
Unit ceilCameraDiff =
_ceilFunction != 0 ?
absVal(worldZPrevCeil) * VERTICAL_DEPTH_MULTIPLY : UNITS_PER_SQUARE;
for (int_maybe32_t i = y2; i < y; ++i)
{
p.position.y = i;
p.depth = (i - _cHorizontalDepthStart) * _horizontalDepthStep + ceilCameraDiff;
_pixelFunction(&p);
}
#undef VERTICAL_DEPTH_MULTIPLY
#endif
} }
void _columnFunctionSimple(HitResult *hits, uint16_t hitCount, uint16_t x, void _columnFunctionSimple(HitResult *hits, uint16_t hitCount, uint16_t x,